UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PBDTriangleMeshCollisions.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "Chaos/Core.h"
10#include "Templates/PimplPtr.h"
11
12// This does initialization for PBDCollisionSpringConstraints and PBDTriangleMeshIntersections,
13// including intersection detection and global intersection analysis
14//
15namespace Chaos::Softs
16{
18{
19public:
27
28 // Vertices (and Triangles) are assigned FGIAColors by flood-filling global intersection contours.
29 // ContourIndex represents which pair of global contours, up to 31 unique contour pairs--then the contour index will reused.
30 // In practice this seems to be enough unique contours. It's OK if multiple contours have the same index as long
31 // as their intersecting regions don't interact, which is unlikely.
32 // Contours come in pairs representing two regions intersecting (except for "loop" contours where a region of cloth intersects itself--think pinch regions).
33 // These are "Colors" represented by setting the ColorBit to 0 or 1 corresponding with the given contour index.
34 struct FGIAColor
35 {
38
39 static constexpr int32 LoopContourIndex = 0;
40 static constexpr int32 LoopBits = 1 << LoopContourIndex;
41 static constexpr int32 NonLoopMask = ~LoopBits;
42 static constexpr int32 BoundaryContourIndex = 0; // Same as Loop. Loop is ColorA, Boundary is ColorB
43
45 {
46 check(ContourIndex < 32);
48 if (bIsColorB)
49 {
50 ColorBits |= 1 << ContourIndex;
51 }
52 else
53 {
54 ColorBits &= ~(1 << ContourIndex);
55 }
56 }
57
59 {
60 check(ContourIndex < 32);
61 return ContourIndexBits & (1 << ContourIndex);
62 }
63
64 bool IsLoop() const
65 {
67 }
68
69 void SetLoop()
70 {
72 }
73
75 {
77 }
78
79 bool IsBoundary() const
80 {
82 }
83
84 // Because they are opposite colors with a shared contour index. This will cause repulsion forces to attract and fix the intersection.
85 // NOTE: We flip normals if ANY of the TriVertColors are opposite the PointColor or if the TriColor (used for thin regions is flipped). This does a better job for thin features
86 // than only flipping normals if ALL TriVertColors are opposite.
87 static bool ShouldFlipNormal(const FGIAColor& Color0, const FGIAColor& Color1)
88 {
90 const int32 FlippedColorBits = Color0.ColorBits ^ Color1.ColorBits;
92 }
93 };
94
95 // Debug display of intersection contours
101
102 enum struct FContourType : int8
103 {
104 Open = 0,
105 Loop,
108 Contour0,
109 Contour1,
110 Count
111 };
112
114 {
115 public:
117 : FullMesh(InFullMesh)
118 {}
119
120 template<typename SolverParticlesOrRange>
121 void Init(const SolverParticlesOrRange& Particles, const TSet<int32>& DisabledFaces, bool bCollideAgainstAllKinematicVertices, const TSet<int32>& EnabledKinematicFaces, const bool bOnlyCollideKinematics = false);
122
123 void InitAllDynamic();
124
126 {
127 return FullMesh;
128 }
129
131 {
132 return DynamicSubMesh;
133 }
134
136 {
137 return KinematicColliderSubMesh;
138 }
139
141 {
142 return FullMeshToSubMeshIndices[FullMeshIndex].SubMeshType == ESubMeshType::Dynamic;
143 }
144
146 {
147 return FullMeshToSubMeshIndices[FullMeshIndex].SubMeshType == ESubMeshType::Kinematic;
148 }
149
151 {
152 check(FullMeshToSubMeshIndices[FullMeshIndex].SubMeshType != ESubMeshType::Invalid);
153 return FullMeshToSubMeshIndices[FullMeshIndex].SubMeshIndex;
154 }
155
157 {
158 return DynamicSubMeshToFullMeshIndices[DynamicMeshIndex];
159 }
160
162 {
163 return KinematicColliderSubMeshToFullMeshIndices[KinematicMeshIndex];
164 }
165
166 const TArray<int32>& GetDynamicVertices() const { return DynamicVertices; }
167
168
169 private:
170 const FTriangleMesh& FullMesh;
171 FTriangleMesh DynamicSubMesh;
172 FTriangleMesh KinematicColliderSubMesh;
173
174 enum struct ESubMeshType : int32
175 {
176 Invalid = 0,
177 Dynamic = 1,
178 Kinematic = 2
179 };
180 struct FFullToSubMeshIndex
181 {
182 int32 SubMeshIndex : 30;
183 ESubMeshType SubMeshType : 2;
184 };
185 TArray<FFullToSubMeshIndex> FullMeshToSubMeshIndices;
186 TArray<int32> DynamicSubMeshToFullMeshIndices;
187 TArray<int32> KinematicColliderSubMeshToFullMeshIndices;
188 TArray<int32> DynamicVertices; // Will be empty if InitAllDynamic was used to initialize
189 };
190
195
197 const int32 InOffset,
198 const int32 InNumParticles,
199 const TMap<FString, const TSet<int32>*>& FaceSets,
202 )
203 : CollidableSubMesh(InTriangleMesh)
204 , Offset(InOffset)
205 , NumParticles(InNumParticles)
206 , bUseSelfIntersections(GetUseSelfIntersections(PropertyCollection, false))
210 , bUseGlobalPostStepContours(GetUseGlobalPostStepContours(PropertyCollection, true))
212 , bSelfCollideAgainstAllKinematicVertices(GetSelfCollideAgainstAllKinematicVertices(PropertyCollection, false))
213 , bCollidableSubMeshDirty(true)
223 {
225 {
226 DisabledFaces = *InDisabledFaces;
227 }
228 }
229
230 UE_DEPRECATED(5.4, "Use Constructor with FaceSets")
238
240 const int32 InOffset,
241 const int32 InNumParticles,
245 )
246 :CollidableSubMesh(InTriangleMesh)
247 , Offset(InOffset)
248 , NumParticles(InNumParticles)
249 , bUseSelfIntersections(bInGlobalIntersectionAnalysis || bInContourMinimization)
250 , bGlobalIntersectionAnalysis(bInGlobalIntersectionAnalysis)
251 , bContourMinimization(bInContourMinimization)
252 , bOnlyCollideWithKinematics(false)
253 , bSelfCollideAgainstAllKinematicVertices(false)
254 , bCollidableSubMeshDirty(true)
264 {}
265
266 virtual ~FPBDTriangleMeshCollisions() = default;
267
269 const TMap<FString, const TSet<int32>*>& FaceSets)
270 {
273 {
274 bUseSelfIntersections = GetUseSelfIntersections(PropertyCollection);
275 }
276 if (bUseSelfIntersections)
277 {
279 {
280 bGlobalIntersectionAnalysis = GetUseGlobalIntersectionAnalysis(PropertyCollection);
281 }
283 {
284 bContourMinimization = GetUseContourMinimization(PropertyCollection);
285 }
287 {
288 NumContourMinimizationPostSteps = GetNumContourMinimizationPostSteps(PropertyCollection);
289 }
291 {
292 bUseGlobalPostStepContours = GetUseGlobalPostStepContours(PropertyCollection);
293 }
294 }
295 else
296 {
297 bGlobalIntersectionAnalysis = bContourMinimization = false;
298 NumContourMinimizationPostSteps = 0;
299 }
300
302 {
304 if (bNewValue != bOnlyCollideWithKinematics)
305 {
306 bOnlyCollideWithKinematics = bNewValue;
307 bCollidableSubMeshDirty = true;
308 }
309 }
310
312 {
314 if (bNewValue != bSelfCollideAgainstAllKinematicVertices)
315 {
316 bSelfCollideAgainstAllKinematicVertices = bNewValue;
317 bCollidableSubMeshDirty = true;
318 }
319 }
321 {
323 {
324 DisabledFaces = *InDisabledFaces;
325 bCollidableSubMeshDirty = true;
326 }
327 else
328 {
329 if (!DisabledFaces.IsEmpty())
330 {
331 DisabledFaces.Reset();
332 bCollidableSubMeshDirty = true;
333 }
334 }
335 }
337 {
339 {
340 EnabledKinematicFaces = *InEnabledFaces;
341 bCollidableSubMeshDirty = true;
342 }
343 else
344 {
345 if (!EnabledKinematicFaces.IsEmpty())
346 {
347 EnabledKinematicFaces.Reset();
348 bCollidableSubMeshDirty = true;
349 }
350 }
351 }
352 }
353
354 UE_DEPRECATED(5.4, "Use version with FaceSets")
359
360 template<typename SolverParticlesOrRange>
365
366 template<typename SolverParticlesOrRange>
368
369 template<typename SolverParticlesOrRange>
374
375 template<typename SolverParticlesOrRange>
376 CHAOS_API void InitFlesh(const SolverParticlesOrRange& Particles, const FPBDFlatWeightMap& ThicknessMap, const bool bUseFullMesh = false);
377
378 template<typename SolverParticlesOrRange>
380
383
385 {
386 return NumContourMinimizationPostSteps;
387 }
388
389 bool GetCollidableSubMeshDirty() const { return bCollidableSubMeshDirty; }
390
391 const FTriangleSubMesh& GetCollidableSubMesh() const { return CollidableSubMesh; }
392 UE_DEPRECATED(5.4, "Use GetDynamicSpatialHash or GetKinematicColliderSpatialHash")
393 const FTriangleMesh::TSpatialHashType<FSolverReal>& GetSpatialHash() const { return DynamicSubMeshSpatialHash; }
394 const FTriangleMesh::TSpatialHashType<FSolverReal>& GetDynamicSpatialHash() const { return DynamicSubMeshSpatialHash; }
395 const FTriangleMesh::TSpatialHashType<FSolverReal>& GetKinematicColliderSpatialHash() const { return KinematicSubMeshSpatialHash; }
396 const TArray<FContourMinimizationIntersection>& GetContourMinimizationIntersections() const { return ContourMinimizationIntersections; }
397 const TConstArrayView<FGIAColor> GetVertexGIAColors() const { return bGlobalIntersectionAnalysis && VertexGIAColors.Num() == NumParticles ? TConstArrayView<FGIAColor>(VertexGIAColors.GetData() - Offset, NumParticles + Offset) : TConstArrayView<FGIAColor>(); }
398 const TArray<FGIAColor>& GetTriangleGIAColors() const { return TriangleGIAColors; }
399 const TArray<TArray<FBarycentricPoint>>& GetIntersectionContourPoints() const { return IntersectionContourPoints; }
400 const TArray<FContourType>& GetIntersectionContourTypes() const { return IntersectionContourTypes; }
401
402 // Same data but for the post step contour minimization. Just making them separate arrays
403 // for debug draw purposes.
404 const TArray<FContourMinimizationIntersection>& GetPostStepContourMinimizationIntersections() const { return PostStepContourMinimizationIntersections; }
405 const TArray<TArray<FBarycentricPoint>>& GetPostStepIntersectionContourPoints() const { return PostStepIntersectionContourPoints; }
406
407
409private:
410
411 FTriangleSubMesh CollidableSubMesh;
412 int32 Offset;
413 int32 NumParticles;
414 bool bUseSelfIntersections;
415 bool bGlobalIntersectionAnalysis;
416 bool bContourMinimization;
417 int32 NumContourMinimizationPostSteps = 0;
418 bool bUseGlobalPostStepContours = true;
419 bool bOnlyCollideWithKinematics;
420 bool bSelfCollideAgainstAllKinematicVertices;
421 TSet<int32> DisabledFaces;
422 TSet<int32> EnabledKinematicFaces;
423
424 bool bCollidableSubMeshDirty = true;
425
426
427 FTriangleMesh::TSpatialHashType<FSolverReal> DynamicSubMeshSpatialHash;
428 FTriangleMesh::TSpatialHashType<FSolverReal> KinematicSubMeshSpatialHash;
429 TArray<FContourMinimizationIntersection> ContourMinimizationIntersections;
430 TArray<FGIAColor> VertexGIAColors;
431 TArray<FGIAColor> TriangleGIAColors;
432
433 // Scratch buffers used by Init and PostInit. They live here so they can be reused rather than reallocated.
434 struct FScratchBuffers;
435 TPimplPtr<FScratchBuffers> ScratchBuffers;
436
437 // Debug display of intersection contours
438 TArray<TArray<FBarycentricPoint>> IntersectionContourPoints;
439 TArray<FContourType> IntersectionContourTypes;
440
441 // PostStep contour data. Keeping it separate for debug drawing for now.
442 TArray<FContourMinimizationIntersection> PostStepContourMinimizationIntersections;
443 TArray<TArray<FBarycentricPoint>> PostStepIntersectionContourPoints;
444
449 UE_CHAOS_DECLARE_PROPERTYCOLLECTION_NAME(NumContourMinimizationPostSteps, int32);
455};
456
457} // End namespace Chaos::Softs
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define check(expr)
Definition AssertionMacros.h:314
#define UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(PropertyName, Type)
Definition CollectionPropertyFacade.h:853
#define UE_CHAOS_DECLARE_INDEXED_PROPERTYCOLLECTION_NAME(PropertyName, Type)
Definition CollectionPropertyFacade.h:893
#define UE_CHAOS_DECLARE_PROPERTYCOLLECTION_NAME(PropertyName, Type)
Definition CollectionPropertyFacade.h:969
@ ForceInit
Definition CoreMiscDefines.h:155
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
FPlatformTypes::int8 int8
An 8-bit signed integer.
Definition Platform.h:1121
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
return true
Definition ExternalRpcRegistry.cpp:601
void Init()
Definition LockFreeList.h:4
Definition TriangleMesh.h:24
Definition CollectionPropertyFacade.h:49
Definition PBDFlatWeightMap.h:98
Definition PBDTriangleMeshCollisions.h:114
FTriangleSubMesh(const FTriangleMesh &InFullMesh)
Definition PBDTriangleMeshCollisions.h:116
int32 GetSubMeshElementIndex(int32 FullMeshIndex) const
Definition PBDTriangleMeshCollisions.h:150
bool IsElementDynamic(int32 FullMeshIndex) const
Definition PBDTriangleMeshCollisions.h:140
const TArray< int32 > & GetDynamicVertices() const
Definition PBDTriangleMeshCollisions.h:166
bool IsElementKinematicCollider(int32 FullMeshIndex) const
Definition PBDTriangleMeshCollisions.h:145
const FTriangleMesh & GetKinematicColliderSubMesh() const
Definition PBDTriangleMeshCollisions.h:135
int32 GetFullMeshElementIndexFromDynamicElement(int32 DynamicMeshIndex) const
Definition PBDTriangleMeshCollisions.h:156
int32 GetFullMeshElementIndexFromKinematicElement(int32 KinematicMeshIndex) const
Definition PBDTriangleMeshCollisions.h:161
const FTriangleMesh & GetFullMesh() const
Definition PBDTriangleMeshCollisions.h:125
void InitAllDynamic()
Definition PBDTriangleMeshCollisions.cpp:1362
const FTriangleMesh & GetDynamicSubMesh() const
Definition PBDTriangleMeshCollisions.h:130
Definition PBDTriangleMeshCollisions.h:18
UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(UseSelfIntersections, bool)
FPBDTriangleMeshCollisions(const int32 InOffset, const int32 InNumParticles, const TMap< FString, const TSet< int32 > * > &FaceSets, const FTriangleMesh &InTriangleMesh, const FCollectionPropertyConstFacade &PropertyCollection)
Definition PBDTriangleMeshCollisions.h:196
const FTriangleMesh::TSpatialHashType< FSolverReal > & GetKinematicColliderSpatialHash() const
Definition PBDTriangleMeshCollisions.h:395
const FTriangleSubMesh & GetCollidableSubMesh() const
Definition PBDTriangleMeshCollisions.h:391
const TArray< FContourMinimizationIntersection > & GetContourMinimizationIntersections() const
Definition PBDTriangleMeshCollisions.h:396
void InitFlesh(const SolverParticlesOrRange &Particles, const FSolverReal MinProximityQueryRadius=(FSolverReal) 0., const bool bUseFullMesh=false)
Definition PBDTriangleMeshCollisions.h:370
void Init(const SolverParticlesOrRange &Particles, const FSolverReal MinProximityQueryRadius=(FSolverReal) 0.)
Definition PBDTriangleMeshCollisions.h:361
const TArray< FGIAColor > & GetTriangleGIAColors() const
Definition PBDTriangleMeshCollisions.h:398
CHAOS_API void Init(const SolverParticlesOrRange &Particles, const FPBDFlatWeightMap &ThicknessMap)
const FTriangleMesh::TSpatialHashType< FSolverReal > & GetSpatialHash() const
Definition PBDTriangleMeshCollisions.h:393
const TArray< FContourType > & GetIntersectionContourTypes() const
Definition PBDTriangleMeshCollisions.h:400
int32 GetNumContourMinimizationPostSteps() const
Definition PBDTriangleMeshCollisions.h:384
const TArray< TArray< FBarycentricPoint > > & GetIntersectionContourPoints() const
Definition PBDTriangleMeshCollisions.h:399
void SetContourMinimization(bool bInContourMinimization)
Definition PBDTriangleMeshCollisions.h:382
static bool IsEnabled(const FCollectionPropertyConstFacade &PropertyCollection)
Definition PBDTriangleMeshCollisions.h:191
CHAOS_API void InitFlesh(const SolverParticlesOrRange &Particles, const FPBDFlatWeightMap &ThicknessMap, const bool bUseFullMesh=false)
FContourType
Definition PBDTriangleMeshCollisions.h:103
CHAOS_API void PostStepInit(const SolverParticlesOrRange &Particles)
const TConstArrayView< FGIAColor > GetVertexGIAColors() const
Definition PBDTriangleMeshCollisions.h:397
void SetGlobalIntersectionAnalysis(bool bInGlobalIntersectionAnalysis)
Definition PBDTriangleMeshCollisions.h:381
const TArray< FContourMinimizationIntersection > & GetPostStepContourMinimizationIntersections() const
Definition PBDTriangleMeshCollisions.h:404
bool GetCollidableSubMeshDirty() const
Definition PBDTriangleMeshCollisions.h:389
FPBDTriangleMeshCollisions(const int32 InOffset, const int32 InNumParticles, const FTriangleMesh &InTriangleMesh, bool bInGlobalIntersectionAnalysis, bool bInContourMinimization)
Definition PBDTriangleMeshCollisions.h:239
const TArray< TArray< FBarycentricPoint > > & GetPostStepIntersectionContourPoints() const
Definition PBDTriangleMeshCollisions.h:405
const FTriangleMesh::TSpatialHashType< FSolverReal > & GetDynamicSpatialHash() const
Definition PBDTriangleMeshCollisions.h:394
void SetProperties(const FCollectionPropertyConstFacade &PropertyCollection, const TMap< FString, const TSet< int32 > * > &FaceSets)
Definition PBDTriangleMeshCollisions.h:268
Definition HierarchicalSpatialHash.h:214
Definition Vector.h:1000
Definition Vector.h:41
Definition Array.h:670
Definition UnrealString.h.inl:34
Definition CollectionEmbeddedSpringConstraintFacade.cpp:6
TVector< FSolverReal, 2 > FSolverVec2
Definition PBDSoftsEvolutionFwd.h:32
FRealSingle FSolverReal
Definition PBDSoftsEvolutionFwd.h:31
@ Kinematic
Definition ChaosDeformableConstraintsProxy.h:13
@ Dynamic
Definition SpatialAccelerationCollection.h:22
@ false
Definition radaudio_common.h:23
Definition PBDTriangleMeshCollisions.h:97
TVec3< int32 > Vertices
Definition PBDTriangleMeshCollisions.h:99
FSolverVec2 Bary
Definition PBDTriangleMeshCollisions.h:98
TVec3< int32 > FaceVertices
Definition PBDTriangleMeshCollisions.h:23
FSolverVec3 GlobalGradientVector
Definition PBDTriangleMeshCollisions.h:25
FSolverVec3 LocalGradientVector
Definition PBDTriangleMeshCollisions.h:24
TVec2< int32 > EdgeVertices
Definition PBDTriangleMeshCollisions.h:22
Definition PBDTriangleMeshCollisions.h:35
static constexpr int32 LoopBits
Definition PBDTriangleMeshCollisions.h:40
void SetLoop()
Definition PBDTriangleMeshCollisions.h:69
bool IsLoop() const
Definition PBDTriangleMeshCollisions.h:64
static bool ShouldFlipNormal(const FGIAColor &Color0, const FGIAColor &Color1)
Definition PBDTriangleMeshCollisions.h:87
void SetBoundary()
Definition PBDTriangleMeshCollisions.h:74
static constexpr int32 NonLoopMask
Definition PBDTriangleMeshCollisions.h:41
int32 ContourIndexBits
Definition PBDTriangleMeshCollisions.h:36
static constexpr int32 LoopContourIndex
Definition PBDTriangleMeshCollisions.h:39
static constexpr int32 BoundaryContourIndex
Definition PBDTriangleMeshCollisions.h:42
bool HasContourColorSet(int32 ContourIndex) const
Definition PBDTriangleMeshCollisions.h:58
bool IsBoundary() const
Definition PBDTriangleMeshCollisions.h:79
int32 ColorBits
Definition PBDTriangleMeshCollisions.h:37
void SetContourColor(int32 ContourIndex, bool bIsColorB)
Definition PBDTriangleMeshCollisions.h:44
Definition PBDTriangleMeshCollisions.cpp:1273
Definition PimplPtr.h:50