UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PBDRigidClusteringCollisionParticleAlgo.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
5
6namespace Chaos
7{
8
10 const TArray<FVec3>& Vertices,
11 FAABB3 BBox,
12 const FReal SnapDistance=(FReal)0.01)
13{
14 const int32 NumPoints = Vertices.Num();
15 if (NumPoints <= 1)
16 return TArray<FVec3>(Vertices);
17
18 FReal MaxBBoxDim = BBox.Extents().Max();
20 return TArray<FVec3>(&Vertices[0], 1);
21
22 BBox.Thicken(FMath::Max(SnapDistance/10, (FReal)(UE_KINDA_SMALL_NUMBER*10))); // 0.001
23 MaxBBoxDim = BBox.Extents().Max();
24
25 const FVec3 PointsCenter = BBox.Center();
26 TArray<FVec3> Points(Vertices);
27
28 // Find coincident vertices. We hash to a grid of fine enough resolution such
29 // that if 2 particles hash to the same cell, then we're going to consider them
30 // coincident.
32 OccupiedCells.Reserve(NumPoints);
33
35 Redundant.Reserve(NumPoints); // Excessive, but ensures consistent performance.
36
38 const int64 Resolution = static_cast<int64>(floor(MaxBBoxDim / FMath::Max(SnapDistance,(FReal)UE_KINDA_SMALL_NUMBER)));
39 const FReal CellSize = static_cast<FReal>(static_cast<double>(MaxBBoxDim) / static_cast<double>(Resolution));
40 for (int32 i = 0; i < 2; i++)
41 {
42 Redundant.Reset();
43 OccupiedCells.Reset();
44 // Shift the grid by 1/2 a grid cell the second iteration so that
45 // we don't miss slightly adjacent coincident points across cell
46 // boundaries.
47 const FVec3 GridCenter = FVec3(0) - FVec3(static_cast<FReal>(i) * CellSize / 2);
48 for (int32 j = 0; j < Points.Num(); j++)
49 {
50 const FVec3 Pos = Points[j] - PointsCenter; // Centered at the origin
51 const TVec3<int64> Coord(
52 static_cast<int64>(FMath::Floor((Pos[0] - GridCenter[0]) / CellSize + static_cast<double>(Resolution) / 2)),
53 static_cast<int64>(FMath::Floor((Pos[1] - GridCenter[1]) / CellSize + static_cast<double>(Resolution) / 2)),
54 static_cast<int64>(FMath::Floor((Pos[2] - GridCenter[2]) / CellSize + static_cast<double>(Resolution) / 2)));
55 const int64 FlatIdx =
56 ((Coord[0] * Resolution + Coord[1]) * Resolution) + Coord[2];
57
58 bool AlreadyInSet = false;
60 if (AlreadyInSet)
61 Redundant.Add(j);
62 }
63
64 for (int32 j = Redundant.Num(); j--;)
65 {
66 Points.RemoveAt(Redundant[j]);
67 }
68 }
69
70 // Shrink the array, if appropriate
71 Points.SetNum(Points.Num(), EAllowShrinking::Yes);
72 return Points;
73}
74
76 const TArray<FVec3>& Vertices,
77 const FReal SnapDistance=(FReal)0.01)
78{
79 if (!Vertices.Num())
80 {
81 return TArray<FVec3>();
82 }
84 for (const FVec3& Pt : Vertices)
85 {
86 BBox.GrowToInclude(Pt);
87 }
88 return CleanCollisionParticles(Vertices, BBox, SnapDistance);
89}
90
92 FTriangleMesh &TriMesh,
93 const TArrayView<const FVec3>& Vertices,
94 const FReal Fraction)
95{
97 if (Fraction <= 0.0)
98 return CollisionVertices;
99
100 // If the tri mesh has any open boundaries, see if we can merge any coincident
101 // vertices on the boundary. This makes the importance ordering work much better
102 // as we need the curvature at each edge of the tri mesh, and we can't calculate
103 // curvature on discontiguous triangles.
105 if (BoundaryPoints.Num())
106 {
108 TriMesh.FindCoincidentVertexRemappings(BoundaryPoints.Array(), Vertices);
109 TriMesh.RemapVertices(Remapping);
110 }
111
112 // Get the importance vertex ordering, from most to least. Reorder the
113 // particles accordingly.
116
117 // Particles are ordered from most important to least, with coincident
118 // vertices at the very end.
120
121#if DO_GUARD_SLOW
122 for (int i = NumGoodPoints; i < Ordering.Num(); ++i)
123 {
124 ensure(CoincidentVertices.Contains(Ordering[i])); //make sure all coincident vertices are at the back
125 }
126#endif
127
128 CollisionVertices.AddUninitialized(FMath::Min(NumGoodPoints, static_cast<int32>(ceil(static_cast<FReal>(NumGoodPoints) * Fraction))));
129 for (int i = 0; i < CollisionVertices.Num(); i++)
130 {
131 CollisionVertices[i] = Vertices[Ordering[i]];
132 }
133 return CollisionVertices;
134}
135
137 FTriangleMesh &TriMesh,
138 const TArrayView<const FVec3>& Vertices,
139 const FReal Fraction,
141{
142 ResultingIndices.Reset();
143 if (Fraction <= 0.0)
144 return;
145
149 NumGoodPoints = FMath::Min(NumGoodPoints, static_cast<int32>(ceil(static_cast<FReal>(NumGoodPoints) * Fraction)));
150
152 for (int32 i = 0; i < NumGoodPoints; i++)
153 {
155 }
156}
157
158} // namespace Chaos
#define ensure( InExpression)
Definition AssertionMacros.h:464
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
Definition TriangleMesh.h:24
CHAOS_API void RemapVertices(const TArray< int32 > &Order)
Reorder vertices according to.
Definition TriangleMesh.cpp:1514
CHAOS_API TMap< int32, int32 > FindCoincidentVertexRemappings(const TArray< int32 > &TestIndices, const TConstArrayView< FVec3 > &Points)
Definition TriangleMesh.cpp:943
CHAOS_API TSet< int32 > GetBoundaryPoints()
Definition TriangleMesh.cpp:924
CHAOS_API TArray< int32 > GetVertexImportanceOrdering(const TConstArrayView< FVec3 > &Points, const TArray< FReal > &PointCurvatures, TArray< int32 > *CoincidentVertices=nullptr, const bool RestrictToLocalIndexRange=false)
Definition TriangleMesh.cpp:1180
static FORCEINLINE TAABB< FReal, d > EmptyAABB()
Definition AABB.h:623
Definition Vector.h:1000
Definition ArrayView.h:139
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void RemoveAt(SizeType Index, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2083
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
UE_FORCEINLINE_HINT void Reserve(SizeType Number)
Definition Array.h:3016
Definition UnrealString.h.inl:34
Definition SkeletalMeshComponent.h:307
FRealDouble FReal
Definition Real.h:22
TVector< FReal, 3 > FVec3
Definition Core.h:17
TArray< FVec3 > CleanCollisionParticles(const TArray< FVec3 > &Vertices, FAABB3 BBox, const FReal SnapDistance=(FReal) 0.01)
Definition PBDRigidClusteringCollisionParticleAlgo.h:9
static UE_FORCEINLINE_HINT float Floor(float F)
Definition UnrealMathUtility.h:525