UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
TriangleMesh.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "Chaos/Array.h"
5#include "Chaos/Map.h"
6#include "Chaos/Particles.h"
7#include "Chaos/SegmentMesh.h"
9
10#include "AABBTree.h"
11
12namespace Chaos
13{
14 template <typename TPayloadType, typename T> class THierarchicalSpatialHash;
15
16 template<typename T> struct TTriangleCollisionPoint;
17
18 namespace Softs
19 {
20 class FPBDFlatWeightMap;
21 }
22
24 {
25 public:
27 CHAOS_API FTriangleMesh(TArray<TVec3<int32>>&& Elements, const int32 StartIdx = 0, const int32 EndIdx = -1, const bool CullDegenerateElements=true);
31
38 CHAOS_API void Init(TArray<TVec3<int32>>&& Elements, const int32 StartIdx = 0, const int32 EndIdx = -1, const bool CullDegenerateElements=true);
39 CHAOS_API void Init(const TConstArrayView<TVec3<int32>>& Elements, const int32 StartIdx = 0, const int32 EndIdx = -1, const bool CullDegenerateElements = true);
40
42
44
53 {
54 return MStartIdx;
55 }
57 {
58 return MNumIndices;
59 }
60
64 CHAOS_API void GetVertexSet(TSet<int32>& VertexSet) const;
65
67 CHAOS_API void GetVertexSetAsArray(TArray<int32>& VertexSet) const;
68
75 FORCEINLINE void ExpandVertexRange(const int32 StartIdx, const int32 EndIdx)
76 {
78 if (StartIdx <= CurrRange[0] && EndIdx >= CurrRange[1])
79 {
80 MStartIdx = StartIdx;
81 MNumIndices = EndIdx - StartIdx + 1;
82 }
83 }
84
85 FORCEINLINE const TArray<TVec3<int32>>& GetElements() const& { return MElements; }
97
98 FORCEINLINE const TArray<TVec3<int32>>& GetSurfaceElements() const& { return MElements; }
110
111 FORCEINLINE int32 GetNumElements() const { return MElements.Num(); }
112
114 FORCEINLINE const TSet<int32>& GetNeighbors(const int32 Element) const { return GetPointToNeighborsMap()[Element]; }
115
116 CHAOS_API TConstArrayView<TArray<int32>> GetPointToTriangleMap() const; // Return an array view using global indexation. Only elements starting at MStartIdx will be valid!
117 FORCEINLINE const TArray<int32>& GetCoincidentTriangles(const int32 Element) const { return GetPointToTriangleMap()[Element]; }
118
119 FORCEINLINE TSet<int32> GetNRing(const int32 Element, const int32 N) const
120 {
121 TSet<int32> Neighbors;
124 for (auto SubElement : PrevLevelNeighbors)
125 {
126 check(SubElement != Element);
127 Neighbors.Add(SubElement);
128 }
129 for (int32 i = 1; i < N; ++i)
130 {
131 for (auto SubElement : PrevLevelNeighbors)
132 {
133 const auto& SubNeighbors = GetNeighbors(SubElement);
134 for (auto SubSubElement : SubNeighbors)
135 {
136 if (!Neighbors.Contains(SubSubElement) && SubSubElement != Element)
137 {
139 }
140 }
141 }
143 LevelNeighbors.Reset();
144 for (auto SubElement : PrevLevelNeighbors)
145 {
146 if (!Neighbors.Contains(SubElement))
147 {
148 check(SubElement != Element);
149 Neighbors.Add(SubElement);
150 }
151 }
152 }
153 return Neighbors;
154 }
155
160
164 template <typename T>
166 template <typename T>
170
174
181 template <typename T>
183
185
190
206
216
225
231
238 const TArray<int32>& TestIndices,
239 const TConstArrayView<FVec3>& Points);
240
249 const TConstArrayView<FVec3>& Points,
252 const bool RestrictToLocalIndexRange = false);
255 const TConstArrayView<FVec3>& Points,
257 const bool RestrictToLocalIndexRange = false);
258
262
265
266 template <typename T>
268 {
269 const int32 Idx = Particles.Size();
270 Particles.AddParticles(3);
271 // Left handed
272 Particles.X(Idx + 0) = FVec3((T)0., (T)0.8083, (T)0.);
273 Particles.X(Idx + 1) = FVec3((T)0.7, (T)-0.4041, (T)0.);
274 Particles.X(Idx + 2) = FVec3((T)-0.7, (T)-0.4041, (T)0.);
275
276 TArray<TVec3<int32>> Elements;
277 Elements.SetNum(1);
278 Elements[0] = TVec3<int32>(Idx + 0, Idx + 1, Idx + 2);
279
280 TriMesh.Init(MoveTemp(Elements));
281 }
282 template <typename T>
284 {
285 const int32 Idx = Particles.Size();
286 Particles.AddParticles(3);
287 // Left handed
288 Particles.SetX(Idx + 0, FVec3((T)0., (T)0., (T)0.8083));
289 Particles.SetX(Idx + 1, FVec3((T)0., (T)0.7, (T)-0.4041));
290 Particles.SetX(Idx + 2, FVec3((T)0., (T)-0.7, (T)-0.4041));
291
292 TArray<TVec3<int32>> Elements;
293 Elements.SetNum(1);
294 Elements[0] = TVec3<int32>(Idx + 0, Idx + 1, Idx + 2);
295
296 TriMesh.Init(MoveTemp(Elements));
297 }
298
299 // BVH-based collision queries
300 template<typename T>
301 using TBVHType = TAABBTree<int32, TAABBTreeLeafArray<int32, /*bComputeBounds=*/false, T>, /*bMutable=*/true, T>;
302
303 template<typename T>
304 void BuildBVH(const TConstArrayView<TVec3<T>>& Points, TBVHType<T>& BVH) const;
305
306 // NOTE: This method assumes the BVH has already been built/fitted to Points.
307 template<typename T>
308 bool PointProximityQuery(const TBVHType<T>& BVH, const TConstArrayView<TVec3<T>>& Points, const int32 PointIndex, const TVec3<T>& PointPosition, const T PointThickness, const T ThisThickness,
309 TFunctionRef<bool (const int32 PointIndex, const int32 TriangleIndex)> BroadphaseTest, TArray<TTriangleCollisionPoint<T>>& Result) const;
310
311 template<typename T>
312 bool EdgeIntersectionQuery(const TBVHType<T>& BVH, const TConstArrayView<TVec3<T>>& Points, const int32 EdgeIndex, const TVec3<T>& EdgePosition1, const TVec3<T>& EdgePosition2,
313 TFunctionRef<bool(const int32 EdgeIndex, const int32 TriangleIndex)> BroadphaseTest, TArray<TTriangleCollisionPoint<T>>& Result) const;
314
316 template<typename T>
317 bool SmoothProject(const TBVHType<T>& BVH, const TConstArrayView<FVec3>& Points, const TArray<FVec3>& PointNormals,
318 const FVec3& Point, int32& TriangleIndex, FVec3& Weights, const int32 MaxIters=10) const;
319
320 template<typename T>
322
323 // Hierarchy will only go down to lods as small as MinSpatialLodSize.
324 template<typename T>
325 CHAOS_API void BuildSpatialHash(const TConstArrayView<TVec3<T>>& Points, TSpatialHashType<T>& SpatialHash, const T MinSpatialLodSize = (T)0.) const;
326 CHAOS_API void BuildSpatialHash(const TConstArrayView<TVec3<FRealSingle>>& Points, TSpatialHashType<FRealSingle>& SpatialHash, const Softs::FPBDFlatWeightMap& PointThicknesses, int32 ThicknessMapIndexOffset, const FRealSingle MinSpatialLodSize = 0.f) const;
327
328 template<typename T>
329 CHAOS_API bool PointProximityQuery(const TSpatialHashType<T>& SpatialHash, const TConstArrayView<TVec3<T>>& Points, const int32 PointIndex, const TVec3<T>& PointPosition, const T PointThickness, const T ThisThickness,
330 TFunctionRef<bool(const int32 PointIndex, const int32 TriangleIndex)> BroadphaseTest, TArray<TTriangleCollisionPoint<T>>& Result) const;
332 const FRealSingle ThisThicknessExtraMultiplier, int32 ThicknessMapIndexOffset, TFunctionRef<bool(const int32 PointIndex, const int32 TriangleIndex)> BroadphaseTest, TArray<TTriangleCollisionPoint<FRealSingle>>& Result) const;
333
334 template<typename T>
335 CHAOS_API bool PointClosestTriangleQuery(const TSpatialHashType<T>& SpatialHash, const TConstArrayView<TVec3<T>>& Points, const int32 PointIndex, const TVec3<T>& PointPosition, const T PointThickness, const T ThisThickness,
336 TFunctionRef<bool(const int32 PointIndex, const int32 TriangleIndex)> BroadphaseTest, TArray<TTriangleCollisionPoint<T>>& Result) const;
337
338 template<typename T>
339 bool EdgeIntersectionQuery(const TSpatialHashType<T>& SpatialHash, const TConstArrayView<TVec3<T>>& Points, const int32 EdgeIndex, const TVec3<T>& EdgePosition1, const TVec3<T>& EdgePosition2,
340 TFunctionRef<bool(const int32 EdgeIndex, const int32 TriangleIndex)> BroadphaseTest, TArray<TTriangleCollisionPoint<T>>& Result) const;
341
342 private:
343 CHAOS_API void InitHelper(const int32 StartIdx, const int32 EndIdx, const bool CullDegenerateElements=true);
344
345 FORCEINLINE int32 GlobalToLocal(int32 GlobalIdx) const
346 {
347 const int32 LocalIdx = GlobalIdx - MStartIdx;
348 check(LocalIdx >= 0 && LocalIdx < MNumIndices);
349 return LocalIdx;
350 }
351
352 FORCEINLINE int32 LocalToGlobal(int32 LocalIdx) const
353 {
354 const int32 GlobalIdx = LocalIdx + MStartIdx;
355 check(GlobalIdx >= MStartIdx && GlobalIdx < MStartIdx + MNumIndices);
356 return GlobalIdx;
357 }
358
359 TArray<TVec3<int32>> MElements;
360
361 mutable TArray<TArray<int32>> MPointToTriangleMap; // !! Unlike the TArrayView returned by GetPointToTriangleMap, this array starts at 0 for the point of index MStartIdx. Use GlobalToLocal to access with a global index. Note that this array's content is always indexed in global index.
362 mutable TMap<int32, TSet<int32>> MPointToNeighborsMap;
363
364 mutable FSegmentMesh MSegmentMesh;
365 mutable TArray<TVec3<int32>> MFaceToEdges;
366 mutable TArray<TVec2<int32>> MEdgeToFaces;
367
368 int32 MStartIdx;
369 int32 MNumIndices;
370 };
371
372 template <typename T>
374}
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define check(expr)
Definition AssertionMacros.h:314
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
void Init()
Definition LockFreeList.h:4
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
Definition SegmentMesh.h:18
Definition TriangleMesh.h:24
CHAOS_API void ResetAuxiliaryStructures()
Definition TriangleMesh.cpp:226
CHAOS_API TArray< FReal > GetCurvatureOnEdges(const TArray< FVec3 > &faceNormals)
Definition TriangleMesh.cpp:1061
CHAOS_API const TArray< TVec2< int32 > > & GetEdgeToFaces() const
Note that this data is lazily calculated with the SegmentMesh (this method is not threadsafe unless i...
Definition TriangleMesh.cpp:917
CHAOS_API bool PointProximityQuery(const TSpatialHashType< FRealSingle > &SpatialHash, const TConstArrayView< TVec3< FRealSingle > > &Points, const int32 PointIndex, const TVec3< FRealSingle > &PointPosition, const FRealSingle PointThickness, const Softs::FPBDFlatWeightMap &ThisThicknesses, const FRealSingle ThisThicknessExtraMultiplier, int32 ThicknessMapIndexOffset, TFunctionRef< bool(const int32 PointIndex, const int32 TriangleIndex)> BroadphaseTest, TArray< TTriangleCollisionPoint< FRealSingle > > &Result) const
FORCEINLINE TSet< int32 > GetNRing(const int32 Element, const int32 N) const
Definition TriangleMesh.h:119
int32 GetNumIndices() const
Definition TriangleMesh.h:56
CHAOS_API void GetPointNormals(TArrayView< TVec3< T > > PointNormals, const TConstArrayView< TVec3< T > > &FaceNormals, const bool bUseGlobalArray) const
Get per-point normals. This const version of this function requires GetPointToTriangleMap() to be cal...
CHAOS_API TArray< FReal > GetCurvatureOnPoints(const TArray< FReal > &edgeCurvatures)
Definition TriangleMesh.cpp:1090
FORCEINLINE const TArray< TVec3< int32 > > & GetSurfaceElements() const &
Definition TriangleMesh.h:98
bool EdgeIntersectionQuery(const TBVHType< T > &BVH, const TConstArrayView< TVec3< T > > &Points, const int32 EdgeIndex, const TVec3< T > &EdgePosition1, const TVec3< T > &EdgePosition2, TFunctionRef< bool(const int32 EdgeIndex, const int32 TriangleIndex)> BroadphaseTest, TArray< TTriangleCollisionPoint< T > > &Result) const
Definition TriangleMesh.cpp:1675
static FORCEINLINE void InitEquilateralTriangleYZ(FTriangleMesh &TriMesh, TParticles< T, 3 > &Particles)
Definition TriangleMesh.h:283
CHAOS_API TSet< int32 > GetVertices() const
Definition TriangleMesh.cpp:252
CHAOS_API void RemapVertices(const TArray< int32 > &Order)
Reorder vertices according to.
Definition TriangleMesh.cpp:1514
FTriangleMesh(const FTriangleMesh &Other)=delete
CHAOS_API TArray< Chaos::TVec2< int32 > > GetUniqueAdjacentPoints() const
Definition TriangleMesh.cpp:332
CHAOS_API FTriangleMesh()
Definition TriangleMesh.cpp:152
FORCEINLINE int32 GetNumElements() const
Definition TriangleMesh.h:111
CHAOS_API TConstArrayView< TArray< int32 > > GetPointToTriangleMap() const
Definition TriangleMesh.cpp:316
CHAOS_API TMap< int32, int32 > FindCoincidentVertexRemappings(const TArray< int32 > &TestIndices, const TConstArrayView< FVec3 > &Points)
Definition TriangleMesh.cpp:943
CHAOS_API TArray< FVec3 > GetPointNormals(const TConstArrayView< FVec3 > &points, const bool ReturnEmptyOnError=true, const bool bUseGlobalArray=false)
Definition TriangleMesh.cpp:464
CHAOS_API void RemoveDegenerateElements()
Definition TriangleMesh.cpp:1591
static CHAOS_API FTriangleMesh GetConvexHullFromParticles(const TConstArrayView< FVec3 > &points)
Definition TriangleMesh.cpp:650
CHAOS_API ~FTriangleMesh()
Definition TriangleMesh.cpp:169
FORCEINLINE TArray< TVec3< int32 > > GetElements() &&
Definition TriangleMesh.h:96
CHAOS_API TArray< Chaos::TVec4< int32 > > GetUniqueAdjacentElements() const
Definition TriangleMesh.cpp:344
CHAOS_API void Init(TArray< TVec3< int32 > > &&Elements, const int32 StartIdx=0, const int32 EndIdx=-1, const bool CullDegenerateElements=true)
Definition TriangleMesh.cpp:172
FORCEINLINE TArray< TVec3< int32 > > GetSurfaceElements() &&
Definition TriangleMesh.h:109
FORCEINLINE const TArray< int32 > & GetCoincidentTriangles(const int32 Element) const
Definition TriangleMesh.h:117
FORCEINLINE const TSet< int32 > & GetNeighbors(const int32 Element) const
Definition TriangleMesh.h:114
CHAOS_API void BuildSpatialHash(const TConstArrayView< TVec3< T > > &Points, TSpatialHashType< T > &SpatialHash, const T MinSpatialLodSize=(T) 0.) const
static FORCEINLINE void InitEquilateralTriangleXY(FTriangleMesh &TriMesh, TParticles< T, 3 > &Particles)
Definition TriangleMesh.h:267
CHAOS_API const TMap< int32, TSet< int32 > > & GetPointToNeighborsMap() const
Definition TriangleMesh.cpp:289
CHAOS_API bool PointProximityQuery(const TSpatialHashType< T > &SpatialHash, const TConstArrayView< TVec3< T > > &Points, const int32 PointIndex, const TVec3< T > &PointPosition, const T PointThickness, const T ThisThickness, TFunctionRef< bool(const int32 PointIndex, const int32 TriangleIndex)> BroadphaseTest, TArray< TTriangleCollisionPoint< T > > &Result) const
static FORCEINLINE FTriangleMesh GetConvexHullFromParticles(const FParticles &InParticles)
Definition TriangleMesh.h:188
CHAOS_API const TArray< TVec3< int32 > > & GetFaceToEdges() const
Note that this data is lazily calculated with the SegmentMesh (this method is not threadsafe unless i...
Definition TriangleMesh.cpp:911
FORCEINLINE TArray< FVec3 > GetFaceNormals(const FParticles &InParticles, const bool ReturnEmptyOnError=true) const
Definition TriangleMesh.h:168
CHAOS_API void GetVertexSetAsArray(TArray< int32 > &VertexSet) const
Definition TriangleMesh.cpp:269
void BuildBVH(const TConstArrayView< TVec3< T > > &Points, TBVHType< T > &BVH) const
Definition TriangleMesh.cpp:1609
FORCEINLINE const TArray< TVec3< int32 > > & GetElements() const &
Definition TriangleMesh.h:85
CHAOS_API void BuildSpatialHash(const TConstArrayView< TVec3< FRealSingle > > &Points, TSpatialHashType< FRealSingle > &SpatialHash, const Softs::FPBDFlatWeightMap &PointThicknesses, int32 ThicknessMapIndexOffset, const FRealSingle MinSpatialLodSize=0.f) const
FORCEINLINE TArray< FVec3 > GetPointNormals(const FParticles &InParticles, const bool ReturnEmptyOnError=true)
Definition TriangleMesh.h:172
FORCEINLINE void ExpandVertexRange(const int32 StartIdx, const int32 EndIdx)
Definition TriangleMesh.h:75
CHAOS_API bool PointClosestTriangleQuery(const TSpatialHashType< T > &SpatialHash, const TConstArrayView< TVec3< T > > &Points, const int32 PointIndex, const TVec3< T > &PointPosition, const T PointThickness, const T ThisThickness, TFunctionRef< bool(const int32 PointIndex, const int32 TriangleIndex)> BroadphaseTest, TArray< TTriangleCollisionPoint< T > > &Result) const
CHAOS_API TArray< TVec3< T > > GetFaceNormals(const TConstArrayView< TVec3< T > > &Points, const bool ReturnEmptyOnError=true) const
CHAOS_API void GetFaceNormals(TArray< TVec3< T > > &Normals, const TConstArrayView< TVec3< T > > &Points, const bool ReturnEmptyOnError=true) const
CHAOS_API TSet< int32 > GetBoundaryPoints()
Definition TriangleMesh.cpp:924
CHAOS_API const FSegmentMesh & GetSegmentMesh() const
Note that the SegmentMesh is lazily calculated (this method is not threadsafe unless it is known that...
Definition TriangleMesh.cpp:836
bool SmoothProject(const TBVHType< T > &BVH, const TConstArrayView< FVec3 > &Points, const TArray< FVec3 > &PointNormals, const FVec3 &Point, int32 &TriangleIndex, FVec3 &Weights, const int32 MaxIters=10) const
Returns false if Point is outside of the smooth normal cone, where a smooth projection doesn't exist.
Definition TriangleMesh.cpp:1723
bool PointProximityQuery(const TBVHType< T > &BVH, const TConstArrayView< TVec3< T > > &Points, const int32 PointIndex, const TVec3< T > &PointPosition, const T PointThickness, const T ThisThickness, TFunctionRef< bool(const int32 PointIndex, const int32 TriangleIndex)> BroadphaseTest, TArray< TTriangleCollisionPoint< T > > &Result) const
Definition TriangleMesh.cpp:1624
CHAOS_API void RemoveDuplicateElements()
Definition TriangleMesh.cpp:1570
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
CHAOS_API void GetVertexSet(TSet< int32 > &VertexSet) const
Definition TriangleMesh.cpp:259
CHAOS_API TVec2< int32 > GetVertexRange() const
Definition TriangleMesh.cpp:247
int32 GetStartIndex() const
Definition TriangleMesh.h:52
Definition PBDFlatWeightMap.h:98
Definition AABBTree.h:786
uint32 Size() const
Definition ArrayCollection.h:66
Definition HierarchicalSpatialHash.h:214
Definition Particles.h:32
void AddParticles(const int32 Num)
Definition Particles.h:70
const TArrayCollectionArray< TVector< T, d > > & X() const
Definition Particles.h:117
void SetX(const int32 Index, const TVector< T, d > &InX)
Definition Particles.h:161
Definition Vector.h:1000
Definition Vector.h:41
Definition Archive.h:1208
Definition ArrayView.h:139
Definition Array.h:670
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
Definition AssetRegistryState.h:50
Definition UnrealString.h.inl:34
Definition SkeletalMeshComponent.h:307
void Order(int32 &A, int32 &B)
Definition TriangleMesh.cpp:792
float FRealSingle
Definition Real.h:14
TVector< FReal, 3 > FVec3
Definition Core.h:17
Definition AABBTree.h:260
Data returned by TriangleMesh point-triangle and edge-edge queries.
Definition TriangleCollisionPoint.h:17