UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
UniformGrid.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "Chaos/Vector.h"
5#include "ChaosCheck.h"
8
9namespace Chaos
10{
11template<class T, int d>
12class TArrayND;
13template<class T, int d>
14class TArrayFaceND;
15
16template<typename T>
18{
19 static_assert(sizeof(T) == 0, "Unsupported grid floating point type");
20};
21
22// Precision limits where our floating point precision breaks down to 1 (each value above this adds more than 1 to the number)
23// Note the F32 limit is actually higher than this point (should be 8.388e6) but kept at 1e7 for legacy reasons
24template<> struct TGridPrecisionLimit<FRealSingle> { static constexpr FRealSingle value = 1e7; };
25template<> struct TGridPrecisionLimit<FRealDouble> { static constexpr FRealDouble value = 4.5035e15; };
26
27template<class T, int d>
29{
30 protected:
34 {
35 for (int32 Axis = 0; Axis < d; ++Axis)
36 {
37 check(MCells[Axis] != 0);
38 }
39
40 // Are corners valid?
41 bool bValidBounds = true;
43 {
44 // This is an Empty AABB
45 bValidBounds = false;
46 }
47 else
48 {
49 for (int32 i = 0; i < d; ++i)
50 {
51 // This is invalid
52 if (!CHAOS_ENSURE(MMaxCorner[i] >= MMinCorner[i])) //TODO convert back to normal ensure once we find out why we hit this.
53 {
54 bValidBounds = false;
55 break;
56 }
57 }
58 }
59
60 if(bValidBounds)
61 {
63 }
64 else
65 {
66 MDx = TVector<T,d>(0);
69 }
70
71 if (GhostCells > 0)
72 {
73 MMinCorner -= MDx * static_cast<T>(GhostCells);
74 MMaxCorner += MDx * static_cast<T>(GhostCells);
75 MCells += TVector<T, d>(2 * static_cast<T>(GhostCells));
76 }
77
78 if (MDx.Min() >= UE_SMALL_NUMBER)
79 {
81 for (int32 Axis = 0; Axis < d; ++Axis)
82 {
83 ensure(FMath::Abs(MinToDXRatio[Axis]) < TGridPrecisionLimit<T>::value); //make sure we have the precision we need
84 }
85 }
86 }
87#if COMPILE_WITHOUT_UNREAL_SUPPORT
88 TUniformGridBase(std::istream& Stream)
90 {
92 }
93#endif
95
96 public:
97#if COMPILE_WITHOUT_UNREAL_SUPPORT
98 void Write(std::ostream& Stream) const
99 {
100 MMinCorner.Write(Stream);
101 MMaxCorner.Write(Stream);
102 MCells.Write(Stream);
103 }
104#endif
106 {
107 Ar << MMinCorner;
108 Ar << MMaxCorner;
109 Ar << MCells;
110 Ar << MDx;
111 }
112
114 {
115 return MDx * Cell + MMinCorner + (MDx / 2);
116 }
118 {
119 return MDx * Face.Second + MMinCorner + (TVector<T, d>(1) - TVector<T, d>::AxisVector(Face.First)) * (MDx / 2);
120 }
121
122 void Reset()
123 {
127 MDx = TVector<T, d>(0);
128 }
129
130#ifdef PLATFORM_COMPILER_CLANG
131 // Disable optimization (-ffast-math) since its currently causing regressions.
132 // freciprocal-math:
133 // x / y = x * rccps(y)
134 // rcpps is faster but less accurate (12 bits of precision), this can causes incorrect CellIdx
136#endif
138 {
140 TVector<int32, d> Result = Delta / MDx;
141 for (int Axis = 0; Axis < d; ++Axis)
142 {
143 if (Delta[Axis] < 0)
144 {
145 Result[Axis] -= 1; //negative snaps to the right which is wrong. Consider -50 x for DX of 100: -50 / 100 = 0 but we actually want -1
146 }
147 }
148 return Result;
149 }
150#ifdef PLATFORM_COMPILER_CLANG
151 // Disable optimization (-ffast-math) since its currently causing regressions.
152 // freciprocal-math:
153 // x / y = x * rccps(y)
154 // rcpps is faster but less accurate (12 bits of precision), this can causes incorrect CellIdx
156#endif
158 {
160 TVector<int32, d> Result = Delta / MDx;
161 for (int Axis = 0; Axis < d; ++Axis)
162 {
163 Result[Axis] = Result[Axis] >= MCells[Axis] ? MCells[Axis] - 1 : (Result[Axis] < 0 ? 0 : Result[Axis]);
164 }
165 return Result;
166 }
167
169 {
170 return Cell(X + (MDx / 2) * TVector<T, d>::AxisVector(Component));
171 }
173 {
174 return (MMaxCorner - MMinCorner);
175 }
176
178 {
179 return MCells.Product();
180 }
181
183 {
184 return (MCells + TVector<int32, 3>(1, 1, 1)).Product();
185 }
186
188 {
190 for (int32 i = 0; i < d; i++)
191 Tmp[i] += MDx[i] * Index[i];
192 return Tmp;
193 }
194
196 {
199 return Node(Index);
200 }
201
203 {
204 bool Interior = true;
205 for (int32 i = 0; i < d && Interior; i++)
206 {
207 if (Index[i] <= 0 || Index[i] >= (MCells[i] - 1))
208 Interior = false;
209 }
210 return Interior;
211 }
212
213 int32 FlatIndex(const TVector<int32, 2>& MIndex, const bool NodeIndex=false) const
214 {
215 return MIndex[0] * (NodeIndex ? MCells[1]+1 : MCells[1]) + MIndex[1];
216 }
217
218 int32 FlatIndex(const TVector<int32, 3>& MIndex, const bool NodeIndex=false) const
219 {
220 return NodeIndex ?
221 MIndex[0] * (MCells[1]+1) * (MCells[2]+1) + MIndex[1] * (MCells[2]+1) + MIndex[2] :
222 MIndex[0] * MCells[1] * MCells[2] + MIndex[1] * MCells[2] + MIndex[2];
223 }
224
225 void FlatToMultiIndex(const int32 FlatIndex, TVector<int32, 2>& MIndex, const bool NodeIndex=false) const
226 {
227 MIndex[0] = FlatIndex / (NodeIndex?MCells[1]+1:MCells[1]);
228 MIndex[1] = FlatIndex % (NodeIndex?MCells[1]+1: MCells[1]);
229 }
230
231 void FlatToMultiIndex(const int32 FlatIndex, TVector<int32, 3>& MIndex, const bool NodeIndex=false) const
232 {
233 if (NodeIndex)
234 {
235 MIndex[0] = FlatIndex / ((MCells[1]+1) * (MCells[2]+1));
236 MIndex[1] = (FlatIndex / (MCells[2]+1)) % (MCells[1]+1);
237 MIndex[2] = FlatIndex % (MCells[2]+1);
238 }
239 else
240 {
241 MIndex[0] = FlatIndex / (MCells[1] * MCells[2]);
242 MIndex[1] = (FlatIndex / MCells[2]) % MCells[1];
243 MIndex[2] = FlatIndex % MCells[2];
244 }
245 }
246
247 template<class T_SCALAR>
252 const TVector<int32, d>& Counts() const { return MCells; }
254 const TVector<T, d>& Dx() const { return MDx; }
255 const TVector<T, d>& MinCorner() const { return MMinCorner; }
256 const TVector<T, d>& MaxCorner() const { return MMaxCorner; }
257
258 protected:
263};
264
265template<class T, int d>
266class TUniformGrid : public TUniformGridBase<T, d>
267{
268 using TUniformGridBase<T, d>::MCells;
271 using TUniformGridBase<T, d>::MDx;
272
273 public:
274 using TUniformGridBase<T, d>::Location;
275
279#if COMPILE_WITHOUT_UNREAL_SUPPORT
280 TUniformGrid(std::istream& Stream)
281 : TUniformGridBase<T, d>(Stream) {}
282#endif
290 {
291 TVector<int32, d> Result;
292 for (int32 i = 0; i < d; ++i)
293 {
294 if (Index[i] >= MCells[i])
295 Result[i] = MCells[i] - 1;
296 else if (Index[i] < 0)
297 Result[i] = 0;
298 else
299 Result[i] = Index[i];
300 }
301 return Result;
302 }
303
304 TVector<T, d> Clamp(const TVector<T, d>& X) const;
306
307 bool IsValid(const TVector<int32, d>& X) const
308 {
309 return X == ClampIndex(X);
310 }
311};
312
313template<class T>
314class TMPMGrid : public TUniformGridBase<T, 3>
315{
316 using TUniformGridBase<T, 3>::MCells;
319 using TUniformGridBase<T, 3>::MDx;
320
321public:
323 using TUniformGridBase<T, 3>::Location;
324
328 TMPMGrid(const int32 GridN) { for (int32 i = 0; i < 3; i++) { MDx[i] = (T)1. / (T)GridN; } }
329 TMPMGrid(const T GridDx) { for (int32 i = 0; i < 3; i++) { MDx[i] = GridDx; } }
330#if COMPILE_WITHOUT_UNREAL_SUPPORT
331 TMPMGrid(std::istream& Stream)
332 : TUniformGridBase<T, 3>(Stream) {}
333#endif
335
337
338 inline T Nijk(T w, int32 ii) const {
339 if (interp == linear)
340 return T(1) - w + T(ii) * (T(2) * w - T(1));
341 else
342 return ((T(1.5) * (w * w - w) - T(0.25)) * (T(ii) - 1) + (T(0.5) * w - T(0.25))) * (T(ii) - 1) - w * w + w + T(0.5);
343 }
344
345 inline void GradNi(const TVector<T, 3>& Ni, const TVector<T, 3>& dNi, TVector<T, 3>& result) const
346 {
347 result[0] = dNi[0] * Ni[1] * Ni[2];
348 result[1] = Ni[0] * dNi[1] * Ni[2];
349 result[2] = Ni[0] * Ni[1] * dNi[2];
350 }
351
352 inline T dNijk(T w, int32 ii, T dx) const {
353 if (interp == linear)
354 return (T(2) * T(ii) - T(1)) / dx;
355 else
356 return ((w - 1) * (T(ii) - 1) * (T(ii) - 2) * T(0.5) + (2 * w - 1) * T(ii) * (T(ii) - 2) + w * T(ii) * (T(ii) - 1) * T(0.5)) / dx;
357 }
358
360 TVector<int32, 3> Result;
361 if (interp == linear) {
362 for (uint32 i = 0; i < 3; ++i)
363 Result[i] = IndexIn[i] + LocalIndexIn[i];
364 }
365 else {
366 for (uint32 i = 0; i < 3; ++i)
367 Result[i] = IndexIn[i] + LocalIndexIn[i] - 1;
368 }
369 return Result;
370 }
371
372 inline int32 Size() const {
373 if (interp == linear)
374 return (MCells[0] * MCells[1] * MCells[2]);
375 else
376 return ((MCells[0] + 1) * (MCells[1] + 1) * (MCells[2] + 1));
377 }
378
380
382 TVector<T, 3> Result((T)0.);
383
384 if (interp == linear) {
385 for (int32 i = 0; i < 3; ++i) {
386 Result[i] = T(IndexIn[i]) * MDx[i] + MMinCorner[i];
387 }
388 }
389 else {
390 for (size_t i = 0; i < 3; ++i) {
391 Result[i] = (T(IndexIn[i]) + T(0.5)) * MDx[i] + MMinCorner[i];
392 }
393 }
394
395 return Result;
396 }
397
399
402 const TVector<int32, 3> GetCells() const { return MCells; }
403 const TVector<T, 3> GetMinCorner() const { return MMinCorner; }
404 const TVector<T, 3>& GetDx() const { return MDx; }
405 void SetDx(const TVector<T, 3> DxIn) { MDx = DxIn; }
407
408 enum InterpType { linear = 1, quadratic = 2 };
410
413
414};
415
416
417template<class T>
418class TUniformGrid<T, 3> : public TUniformGridBase<T, 3>
419{
420 using TUniformGridBase<T, 3>::MCells;
423 using TUniformGridBase<T, 3>::MDx;
424
425 public:
427 using TUniformGridBase<T, 3>::Location;
428 using TUniformGridBase<T, 3>::Node;
429
433#if COMPILE_WITHOUT_UNREAL_SUPPORT
434 TUniformGrid(std::istream& Stream)
435 : TUniformGridBase<T, 3>(Stream) {}
436#endif
441 {
442 return GetNumCells() * 3 + MCells[0] * MCells[1] + MCells[1] * MCells[2] + MCells[0] * MCells[3];
443 }
451 CHAOS_API bool IsValid(const TVector<int32, 3>& X) const;
452
454};
455
456
457template <typename T, int d>
459{
460 Value.Serialize(Ar);
461 return Ar;
462}
463
464#if PLATFORM_MAC || PLATFORM_LINUX
467extern template class CHAOS_API Chaos::TMPMGrid<Chaos::FReal>;
470#endif
471
472}
#define DISABLE_FUNCTION_OPTIMIZATION
Definition AndroidPlatform.h:152
#define check(expr)
Definition AssertionMacros.h:314
#define ensure( InExpression)
Definition AssertionMacros.h:464
#define CHAOS_ENSURE(Condition)
Definition ChaosCheck.h:22
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_SMALL_NUMBER
Definition UnrealMathUtility.h:130
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition ArrayFaceND.h:14
Definition ArrayND.h:194
Definition DynamicParticles.h:11
Definition UniformGrid.h:315
TVector< T, 3 > Node(const TVector< int32, 3 > &IndexIn) const
Definition UniformGrid.h:381
TVector< int32, 3 > Loc2GlobIndex(const TVector< int32, 3 > &IndexIn, const TVector< int32, 3 > &LocalIndexIn) const
Definition UniformGrid.h:359
InterpType interp
Definition UniformGrid.h:411
const TVector< T, 3 > GetMinCorner() const
Definition UniformGrid.h:403
TMPMGrid(const T GridDx)
Definition UniformGrid.h:329
~TMPMGrid()
Definition UniformGrid.h:334
TMPMGrid(const int32 GridN)
Definition UniformGrid.h:328
const TVector< int32, 3 > GetCells() const
Definition UniformGrid.h:402
void BaseNodeIndex(const TVector< T, 3 > &X, TVector< int32, 3 > &Index, TVector< T, 3 > &weights) const
Definition UniformGrid.cpp:265
void SetDx(const TVector< T, 3 > DxIn)
Definition UniformGrid.h:405
TVector< int32, 3 > Lin2MultiIndex(const int32 IndexIn) const
Definition UniformGrid.cpp:296
void GradNi(const TVector< T, 3 > &Ni, const TVector< T, 3 > &dNi, TVector< T, 3 > &result) const
Definition UniformGrid.h:345
uint32 NPerDir
Definition UniformGrid.h:412
int32 FlatIndex(const TVector< int32, 3 > &Index) const
Definition UniformGrid.cpp:274
InterpType
Definition UniformGrid.h:408
@ quadratic
Definition UniformGrid.h:408
@ linear
Definition UniformGrid.h:408
int32 Size() const
Definition UniformGrid.h:372
T Nijk(T w, int32 ii) const
Definition UniformGrid.h:338
const TVector< T, 3 > & GetDx() const
Definition UniformGrid.h:404
TMPMGrid(const TVector< T, 3 > &MinCorner, const TVector< T, 3 > &MaxCorner, const TVector< int32, 3 > &Cells, const uint32 GhostCells=0)
Definition UniformGrid.h:326
void UpdateGridFromPositions(const Chaos::TDynamicParticles< T, 3 > &InParticles)
Definition UniformGrid.cpp:362
void SetInterp(InterpType InterpIn)
Definition UniformGrid.cpp:395
T dNijk(T w, int32 ii, T dx) const
Definition UniformGrid.h:352
TMPMGrid()
Definition UniformGrid.h:325
Definition UniformGrid.h:29
const TVector< int32, d > & Counts() const
Definition UniformGrid.h:252
const TVector< T, d > & MaxCorner() const
Definition UniformGrid.h:256
TVector< int32, d > CellUnsafe(const TVector< T, d > &X) const
Definition UniformGrid.h:137
void FlatToMultiIndex(const int32 FlatIndex, TVector< int32, 3 > &MIndex, const bool NodeIndex=false) const
Definition UniformGrid.h:231
int32 FlatIndex(const TVector< int32, 3 > &MIndex, const bool NodeIndex=false) const
Definition UniformGrid.h:218
const TVector< T, d > & Dx() const
Definition UniformGrid.h:254
TVector< T, d > MMinCorner
Definition UniformGrid.h:259
TVector< T, d > Node(const TVector< int32, d > &Index) const
Definition UniformGrid.h:187
TVector< T, d > DomainSize() const
Definition UniformGrid.h:172
TVector< int32, d > MCells
Definition UniformGrid.h:261
~TUniformGridBase()
Definition UniformGrid.h:94
int32 GetNumCells() const
Definition UniformGrid.h:177
int32 GetNumNodes() const
Definition UniformGrid.h:182
TVector< T, d > Node(const int32 FlatIndex) const
Definition UniformGrid.h:195
TVector< int32, d > Face(const TVector< T, d > &X, const int32 Component) const
Definition UniformGrid.h:168
TUniformGridBase()
Definition UniformGrid.h:31
T_SCALAR LinearlyInterpolate(const TArrayND< T_SCALAR, d > &ScalarN, const TVector< T, d > &X) const
Definition UniformGrid.cpp:44
TVector< T, d > Location(const Pair< int32, TVector< int32, 3 > > &Face) const
Definition UniformGrid.h:117
int32 FlatIndex(const TVector< int32, 2 > &MIndex, const bool NodeIndex=false) const
Definition UniformGrid.h:213
void Serialize(FArchive &Ar)
Definition UniformGrid.h:105
T LinearlyInterpolateComponent(const TArrayND< T, d > &ScalarNComponent, const TVector< T, d > &X, const int32 Axis) const
Definition UniformGrid.cpp:72
void FlatToMultiIndex(const int32 FlatIndex, TVector< int32, 2 > &MIndex, const bool NodeIndex=false) const
Definition UniformGrid.h:225
TVector< T, d > MDx
Definition UniformGrid.h:262
TVector< int32, d > Cell(const TVector< T, d > &X) const
Definition UniformGrid.h:157
TVector< T, d > Location(const TVector< int32, d > &Cell) const
Definition UniformGrid.h:113
const TVector< T, d > & MinCorner() const
Definition UniformGrid.h:255
void Reset()
Definition UniformGrid.h:122
const TVector< int32, d > NodeCounts() const
Definition UniformGrid.h:253
bool InteriorNode(const TVector< int32, d > &Index) const
Definition UniformGrid.h:202
TVector< T, d > MMaxCorner
Definition UniformGrid.h:260
TUniformGridBase(const TVector< T, d > &MinCorner, const TVector< T, d > &MaxCorner, const TVector< int32, d > &Cells, const uint32 GhostCells)
Definition UniformGrid.h:32
TUniformGrid()
Definition UniformGrid.h:430
int32 GetNumFaces() const
Definition UniformGrid.h:440
TUniformGrid(const TVector< T, 3 > &MinCorner, const TVector< T, 3 > &MaxCorner, const TVector< int32, 3 > &Cells, const uint32 GhostCells=0)
Definition UniformGrid.h:431
TVector< T, 3 > Center(const int32 Index) const
Definition UniformGrid.h:444
~TUniformGrid()
Definition UniformGrid.h:437
Definition UniformGrid.h:267
bool IsValid(const TVector< int32, d > &X) const
Definition UniformGrid.h:307
TVector< T, d > ClampMinusHalf(const TVector< T, d > &X) const
Definition UniformGrid.cpp:164
TUniformGrid()
Definition UniformGrid.h:276
TVector< int32, d > ClampIndex(const TVector< int32, d > &Index) const
Definition UniformGrid.h:289
TVector< int32, d > GetIndex(const int32 Index) const
Definition UniformGrid.cpp:130
TUniformGrid(const TVector< T, d > &MinCorner, const TVector< T, d > &MaxCorner, const TVector< int32, d > &Cells, const uint32 GhostCells=0)
Definition UniformGrid.h:277
~TUniformGrid()
Definition UniformGrid.h:283
TVector< T, d > Center(const int32 Index) const
Definition UniformGrid.h:285
Definition Vector.h:41
virtual void Serialize(void *V, int64 Length) override
Definition ArchiveProxy.h:97
Definition Archive.h:1208
Definition SkeletalMeshComponent.h:307
@ X
Definition SimulationModuleBase.h:152
FChaosArchive & operator<<(FChaosArchive &Ar, FRigidParticleControlFlags &Flags)
Definition RigidParticleControlFlags.cpp:15
float FRealSingle
Definition Real.h:14
double FRealDouble
Definition Real.h:13
U16 Index
Definition radfft.cpp:71
Definition Pair.h:8
Definition UniformGrid.h:18
Definition NumericLimits.h:41