UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Utilities.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Chaos/Core.h"
6#include "Chaos/Matrix.h"
7#include "Chaos/Transform.h"
8#include "Chaos/UniformGrid.h"
9#include "Chaos/Vector.h"
10#include "Chaos/Triangle.h"
11
12//#include "ChaosFlesh/FleshCollectionUtility.h"
13#include "Math/NumericLimits.h"
15#include "Chaos/Plane.h"
17#include "Chaos/Matrix.h"
18
19namespace Chaos
20{
21 namespace Utilities
22 {
23
24 inline void GetTetFaces(
25 const FIntVector4& Tet,
30 const bool invert)
31 {
32 const int32 i = Tet[0];
33 const int32 j = Tet[1];
34 const int32 k = Tet[2];
35 const int32 l = Tet[3];
36 if (invert)
37 {
38 Face1 = { i, k, j };
39 Face2 = { i, j, l };
40 Face3 = { i, l, k };
41 Face4 = { j, k, l };
42 }
43 else
44 {
45 Face1 = { i, j, k };
46 Face2 = { i, l, j };
47 Face3 = { i, k, l };
48 Face4 = { j, l, k };
49 }
50 }
51
52 inline int32
54 {
55 return FMath::Min3(V[0], V[1], V[2]);
56 }
57 inline int32
59 {
60 const int32 X = V[0]; const int32 Y = V[1]; const int32 Z = V[2];
61 const int32 XmY = X - Y;
62 const int32 YmZ = Y - Z;
63 const int32 XmZ = X - Z;
64 return (XmY * YmZ > -1 ? Y : XmY * XmZ < 1 ? X : Z);
65 }
66 inline int32
68 {
69 return FMath::Max3(V[0], V[1], V[2]);
70 }
71 inline FIntVector3
73 {
74 return FIntVector3(GetMin(V), GetMid(V), GetMax(V));
75 }
76 inline FIntVector4
78 {
79 TArray<int32> VA = { V[0], V[1], V[2], V[3] };
80 VA.Sort();
81 return FIntVector4(VA[0], VA[1], VA[2], VA[3]);
82 }
83
84 inline void
87 TArray<FIntVector3>& SurfaceElements,
88 const bool KeepInteriorFaces = false,
89 const bool InvertFaces = false)
90 {
91 FIntVector3 Faces[4];
92
94 {
95 SurfaceElements.Reserve(Tets.Num() * 4);
96 for (const FIntVector4& Tet : Tets)
97 {
98 GetTetFaces(Tet, Faces[0], Faces[1], Faces[2], Faces[3], InvertFaces);
99 for (int i = 0; i < 4; i++)
100 SurfaceElements.Add(Faces[i]);
101 }
102 }
103 else
104 {
107 typedef TMap<int32, YToZ> XToY;
109
110 int32 Idx = -1;
111 int32 Count = 0;
112 for (const FIntVector4& Tet : Tets)
113 {
114 ++Idx;
115 if (!(Tet[0] != Tet[1] &&
116 Tet[0] != Tet[2] &&
117 Tet[0] != Tet[3] &&
118 Tet[1] != Tet[2] &&
119 Tet[1] != Tet[3] &&
120 Tet[2] != Tet[3]))
121 {
122 //UE_LOG(LogChaosFlesh, Display, TEXT("Skipping degenerate tet %d of %d."), Idx, Tets.Num());
123 continue;
124 }
125
126 GetTetFaces(Tet, Faces[0], Faces[1], Faces[2], Faces[3], InvertFaces);
127 for (int i = 0; i < 4; i++)
128 {
129 const FIntVector3 OFace = GetOrdered(Faces[i]);
130 check(OFace[0] <= OFace[1] && OFace[1] <= OFace[2]);
131 const int32 OA = OFace[0];
132 const int32 OB = OFace[1];
133 const int32 OC = OFace[2];
134
135 auto& zc = CoordToCount.FindOrAdd(OFace[0]).FindOrAdd(OFace[1]);
136 auto zcIt = zc.Find(OFace[2]);
137 if (zcIt == nullptr)
138 {
139 zc.Add(OFace[2], TPair<uint8, FIntVector3>((uint8)1, Faces[i]));
140 // Increment our count of lone faces.
141 Count++;
142 }
143 else
144 {
145 zcIt->Key++;
146 // Since we're talking about shared faces, the only way we'd
147 // get a face instanced more than twice is if we had a degenerate
148 // tet mesh.
149 Count--;
150 }
151 }
152 }
153
154 size_t nonManifold = 0;
155 SurfaceElements.Reserve(Count);
156 for (auto& xyIt : CoordToCount)
157 {
158 const YToZ& yz = xyIt.Value;
159 for (auto& yzIt : yz)
160 {
161 const ZToCount& zc = yzIt.Value;
162 for (auto& zcIt : zc)
163 {
164 const uint8 FaceCount = zcIt.Value.Key;
165 if (FaceCount == 1)
166 {
167 SurfaceElements.Add(zcIt.Value.Value);
168 }
169 else if (FaceCount > 2)
170 {
171 //UE_LOG(LogChaosFlesh, Display, TEXT("WARNING: Non-manifold tetrahedral mesh detected (face [%d, %d, %d] use count %d)."), zcIt->second.second[0], zcIt->second.second[1], zcIt->second.second[2], FaceCount);
172 nonManifold++;
173 }
174 }
175 }
176 }
177 //if (nonManifold)
178 // UE_LOG(LogChaosFlesh, Display, TEXT("WARNING: Encountered %d non-manifold tetrahedral mesh faces."), nonManifold);
179 }
180 }
181
182
185 const TArray<FIntVector3>& SurfaceElements,
188 TArray<TVector<FRealSingle, 3>>& BarycentricWeights,
189 const FRealSingle BoxSize = FRealSingle(10.))
190 {
191 SurfaceTriangleIndices.Init(-1, Positions.Num());
192 BarycentricWeights.Init(TVector<FRealSingle, 3>(0.), Positions.Num());
196 TArray<uint16> MaterialIndices;
197 //auto TriangleMesh = MakeUnique<Chaos::FTriangleMeshImplicitObject>(MoveTemp(TriangleParticles), MoveTemp(SurfaceElementsTemp), MoveTemp(MaterialIndices));
198 //Chaos::FTriangleMeshImplicitObject TriangleMeshImplicit(MoveTemp(TriangleParticles), MoveTemp(SurfaceElementsTemp), MoveTemp(TArray<uint16>()));
199 TArray<TVec3<int32>> Elements;
200 Elements.Init(TVec3<int32>(0), SurfaceElements.Num());
201 for (int32 i = 0; i < SurfaceElements.Num(); i++)
202 {
203 Elements[i] = TVec3<int32>(SurfaceElements[i][0], SurfaceElements[i][1], SurfaceElements[i][2]);
204 }
205 auto TriangleMesh = MakeUnique<FTriangleMeshImplicitObject>(MoveTemp(TriangleParticles), MoveTemp(Elements), MoveTemp(MaterialIndices));
206
207 for (int32 p = 0; p < Positions.Num(); p++)
208 {
209 TVector<FReal, 3> MinCorner = { Positions[p][0] - BoxSize / (FReal)2., Positions[p][1] - BoxSize / (FReal)2. , Positions[p][2] - BoxSize / (FReal)2. };
210 TVector<FReal, 3> MaxCorner = { Positions[p][0] + BoxSize / (FReal)2., Positions[p][1] + BoxSize / (FReal)2. , Positions[p][2] + BoxSize / (FReal)2. };
211
212 Chaos::FAABB3 QueryBox(MinCorner, MaxCorner);
213
215 FRealSingle ClosestDistance = (FRealSingle)1e6;
217 TriangleMesh->VisitTriangles(QueryBox, Chaos::FRigidTransform3(FMatrix44d::Identity), [&](const FTriangle& Triangle, const int32 TriangleIndex, const int32 VertexIndex0, const int32 VertexIndex1, const int32 VertexIndex2)
218 {
221 FRealSingle CurrentDistance = (Positions[p] - ClosestPoint).Size();
222 if (CurrentDistance < ClosestDistance)
223 {
224 ClosestDistance = CurrentDistance;
225 MinTriangleIndex = TriangleIndex;
226 ClosestBary = Bary;
227 }
228
229 });
230 BarycentricWeights[p] = ClosestBary;
232 }
233 }
234
235 }
236}
#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
UE::Math::TIntVector3< int32 > FIntVector3
Definition MathFwd.h:92
UE::Math::TIntVector4< int32 > FIntVector4
Definition MathFwd.h:93
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Size
Definition VulkanMemory.cpp:4034
uint8_t uint8
Definition binka_ue_file_header.h:8
Definition Particles.h:32
Definition Vector.h:1000
Definition Vector.h:41
int32 Num() const
Definition Vector.h:150
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
void Init(const ElementType &Element, SizeType Number)
Definition Array.h:3043
UE_FORCEINLINE_HINT void Reserve(SizeType Number)
Definition Array.h:3016
Definition UnrealString.h.inl:34
int32 GetMid(const FIntVector3 &V)
Definition Utilities.h:58
int32 GetMax(const FIntVector3 &V)
Definition Utilities.h:67
void FindClosestTriangle(const TArray< TVector< FRealSingle, 3 > > &Positions, const TArray< FIntVector3 > &SurfaceElements, const TArray< TVector< FRealSingle, 3 > > &TrianglePositions, TArray< int32 > &SurfaceTriangleIndices, TArray< TVector< FRealSingle, 3 > > &BarycentricWeights, const FRealSingle BoxSize=FRealSingle(10.))
Definition Utilities.h:183
void GetTetFaces(const FIntVector4 &Tet, FIntVector3 &Face1, FIntVector3 &Face2, FIntVector3 &Face3, FIntVector3 &Face4, const bool invert)
Definition Utilities.h:24
void GetSurfaceElements(const TArray< FIntVector4 > &Tets, TArray< FIntVector3 > &SurfaceElements, const bool KeepInteriorFaces=false, const bool InvertFaces=false)
Definition Utilities.h:85
FIntVector3 GetOrdered(const FIntVector3 &V)
Definition Utilities.h:72
int32 GetMin(const FIntVector3 &V)
Definition Utilities.h:53
Definition SkeletalMeshComponent.h:307
@ Y
Definition SimulationModuleBase.h:153
@ X
Definition SimulationModuleBase.h:152
FRealDouble FReal
Definition Real.h:22
TVector< T, d > FindClosestPointAndBaryOnTriangle(const TVector< T, d > &P0, const TVector< T, d > &P1, const TVector< T, d > &P2, const TVector< T, d > &P, TVector< T, 3 > &Bary)
Definition Plane.h:220
float FRealSingle
Definition Real.h:14
static constexpr UE_FORCEINLINE_HINT T Min3(const T A, const T B, const T C)
Definition UnrealMathUtility.h:558
static constexpr UE_FORCEINLINE_HINT T Max3(const T A, const T B, const T C)
Definition UnrealMathUtility.h:551
Definition Tuple.h:652
static CORE_API const TMatrix Identity
Definition Matrix.h:52