UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
XPBDGridBasedCorotatedConstraints.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4// HEADER_UNIT_SKIP - Not included directly
5
8#include "ChaosStats.h"
10#include "Chaos/GraphColoring.h"
12#include "Chaos/MPMTransfer.h"
13#include "Misc/FileHelper.h"
15#include "Misc/Paths.h"
16
17//DECLARE_CYCLE_STAT(TEXT("Chaos XPBD Corotated Constraint"), STAT_XPBD_Spring, STATGROUP_Chaos);
18
19namespace Chaos::Softs
20{
21 template <typename T, typename ParticleType>
23 {
24
28 using Base::Measure;
29 using Base::DmInverse;
30 using Base::Mu;
31 using Base::Init;
32 using Base::Lambda;
33
34 public:
35 //this one only accepts tetmesh input and mesh
37 const ParticleType& InParticles,
39 const T GridDx = (T).1,
40 const bool bRecordMetricIn = true,
41 const T MaxDtIn = (T).1,
42 const T MinDtIn = (T).01,
43 const T CFLCoeffIn = (T).4,
44 const T& EMesh = (T)1000.0,
45 const T& NuMesh = (T).3
46 )
48 {
49 //TMPMGrid<T> MPMGrid(GridN);
50 MPMGrid.UpdateGridFromPositions(InParticles);
51 //TMPMTransfer<T> MPMTrasnfer(MPMGrid);
52 LambdaArray.Init((T)0., 2 * MeshConstraints.Num());
53 DmInverse.Init((T)0., 9 * MeshConstraints.Num());
54 Measure.Init((T)0., MeshConstraints.Num());
55 Lambda = EMesh * NuMesh / (((T)1. + NuMesh) * ((T)1. - (T)2. * NuMesh));
56 Mu = EMesh / ((T)2. * ((T)1. + NuMesh));
57 for (int e = 0; e < InMesh.Num(); e++)
58 {
60 PMatrix<T, 3, 3> DmInv = Dm.Inverse();
61 for (int r = 0; r < 3; r++) {
62 for (int c = 0; c < 3; c++) {
63 DmInverse[(3 * 3) * e + 3 * r + c] = DmInv.GetAt(r, c);
64 }
65 }
66
67 Measure[e] = Dm.Determinant() / (T)6.;
68
69 if (Measure[e] < (T)0.)
70 {
71 Measure[e] = -Measure[e];
72 }
73
74 }
75
77 Init(InParticles, (T)0.);
79 }
80
82 {
83 FString file = FPaths::ProjectDir();
84 //file.Append(TEXT("\HoudiniOuput\Test.geo"));
85 file.Append(TEXT("/HoudiniOutput/GridData.geo"));
86
88
89 for (int32 i = 0; i < MPMGrid.Size(); i++)
90 {
91 if (GridData[i * (MPMTransfer.NTransfer+1)] > T(0.))
92 {
95 }
96 }
97
99
100 // We will use this FileManager to deal with the file.
102 FFileHelper::SaveStringToFile(FString(TEXT("PGEOMETRY V5\r\n")), *file);
103 FString HeaderInfo = FString(TEXT("NPoints ")) + FString::FromInt(Np) + FString(TEXT(" NPrims ")) + FString::FromInt(0) + FString(TEXT("\r\n"));
104 FString MoreHeader = FString(TEXT("NPointGroups 0 NPrimGroups 0\r\nNPointAttrib 0 NVertexAttrib 0 NPrimAttrib 0 NAttrib 0\r\n"));
105
108
109 for (int32 i = 0; i < Np; i++) {
110
111 FString ParticleInfo = FString::SanitizeFloat(ActivatedGridNodes[i][0]) + FString(TEXT(" ")) + FString::SanitizeFloat(ActivatedGridNodes[i][1]) + FString(TEXT(" ")) + FString::SanitizeFloat(ActivatedGridNodes[i][2]) + FString(TEXT(" ")) + FString::FromInt(1) + FString(TEXT("\r\n"));
113
114 }
115
116
119
120 }
121
146
147 void TimeStepPostprocessing(ParticleType& InParticles, const T Dt)
148 {
149 {
150 TRACE_CPUPROFILER_EVENT_SCOPE(STAT_ChaosXPBDGridBasedCorotatedGrid::FinalG2P);
151 FinalG2P(InParticles);
152 }
153
154 {
155 TRACE_CPUPROFILER_EVENT_SCOPE(STAT_ChaosXPBDGridBasedCorotated::GridPositions2GridData);
156 MPMTransfer.GridPositionsToGridData(GridPositions, Dt, GridData);
157 }
158
159 {
160 TRACE_CPUPROFILER_EVENT_SCOPE(STAT_ChaosXPBDGridBasedCorotated::ComputeAArray);
161 MPMTransfer.ComputeAArray(GridData, InParticles);
162 }
163
164 }
165
166 T ComputeCFLDt(const ParticleType& InParticles)
167 {
168 T VMax = (T)-1.;
169 for (int32 p = 0; p < InParticles.Size(); p++)
170 {
171 T VMag = InParticles.V(p).Size();
172 if (VMag > VMax)
173 {
174 VMax = VMag;
175 }
176 }
177
178 if (VMax > 1e5)
179 {
180 return MinDt;
181 }
182 if (VMax < 1e-5)
183 {
184 return MaxDt;
185 }
186
187 T CFLDt = MPMGrid.MDx[0] * CFLCoeff / VMax;
188
189 if (CFLDt > MaxDt)
190 {
191 return MaxDt;
192 }
193
194 if (CFLDt < MinDt)
195 {
196 return MinDt;
197 }
198
199 return CFLDt;
200
201 }
202
207
208 void ApplyPolar(ParticleType& Particles, const T Dt, const int32 ElementIndex)
209 {
210 //step 1: sparse g2p:
211 TVec4<TVector<T, 3>> XPosFromGrid = MPMTransfer.SparseG2P(GridPositions, ElementIndex);
212
213 //step 2: gradient and constraint computation:
214 T C1 = (T)0.;
215 TVec4<TVector<T, 3>> PolarGradient = GetPolarGradient(XPosFromGrid, ElementIndex, C1);
216
217 if (C1 == (T)0.)
218 {
219 return;
220 }
221
222 //step 3 : sparse p2g:
224
225 //step 4: computation for delta:
226 T AlphaTilde = (T)1. / (Dt * Dt * Mu * Measure[ElementIndex]);
227
228 T DeltaLambda = -C1 - AlphaTilde * LambdaArray[2 * ElementIndex + 0];
229 T Denom = AlphaTilde;
230
231 for (int32 k = 0; k < MPMTransfer.ElementGridNodeIncidentElements[ElementIndex].Num(); k++) {
232 T Mass = GridData[(MPMTransfer.NTransfer + 1) * MPMTransfer.ElementGridNodes[ElementIndex][MPMTransfer.ElementGridNodeIncidentElements[ElementIndex][k][0]]];
233 if (Mass != 0) {
234 for (int32 alpha = 0; alpha < 3; alpha++) {
235 Denom += GridGradient[k][alpha] * GridGradient[k][alpha] / Mass;
236 }
237 }
238 }
239
241 LambdaArray[2 * ElementIndex + 0] += DeltaLambda;
242
243 for (int32 k = 0; k < MPMTransfer.ElementGridNodeIncidentElements[ElementIndex].Num(); k++) {
244 int32 CurrentNode = MPMTransfer.ElementGridNodes[ElementIndex][MPMTransfer.ElementGridNodeIncidentElements[ElementIndex][k][0]];
245 T Mass = GridData[(MPMTransfer.NTransfer + 1) * CurrentNode];
246 if (Mass != 0) {
247 for (int32 alpha = 0; alpha < 3; alpha++) {
248 GridPositions[CurrentNode][alpha] += DeltaLambda * GridGradient[k][alpha] / Mass;
249 }
250 }
251 }
252 }
253
254 void ApplyDet(ParticleType& Particles, const T Dt, const int32 ElementIndex)
255 {
256 //TArray<TVector<T, 3>> XPosFromGrid;
257 //XPosFromGrid.SetNum(4);
258 //step 1: sparse g2p:
259 TVec4<TVector<T, 3>> XPosFromGrid = MPMTransfer.SparseG2P(GridPositions, ElementIndex);
260
261 //step 2: gradient and constraint computation:
262 T C2 = (T)0.;
263 TVec4<TVector<T, 3>> DetGradient = GetDetGradient(XPosFromGrid, ElementIndex, C2);
264
265 if (C2 == (T)0.)
266 {
267 return;
268 }
269
270 //step 3 : sparse p2g:
271 TArray<TVector<T, 3>> GridGradient = MPMTransfer.SparseP2G(DetGradient, ElementIndex);
272
273 //step 4: computation for delta:
274 T AlphaTilde = (T)2. / (Dt * Dt * Lambda * Measure[ElementIndex]);
275
276 T DeltaLambda = -C2 - AlphaTilde * LambdaArray[2 * ElementIndex + 1];
277 T Denom = AlphaTilde;
278
279 for (int32 k = 0; k < MPMTransfer.ElementGridNodeIncidentElements[ElementIndex].Num(); k++) {
280 T Mass = GridData[(MPMTransfer.NTransfer + 1) * MPMTransfer.ElementGridNodes[ElementIndex][MPMTransfer.ElementGridNodeIncidentElements[ElementIndex][k][0]]];
281 if (Mass != 0) {
282 for (int32 alpha = 0; alpha < 3; alpha++) {
283 Denom += GridGradient[k][alpha] * GridGradient[k][alpha] / Mass;
284 }
285 }
286 }
287
289 LambdaArray[2 * ElementIndex + 1] += DeltaLambda;
290
291 for (int32 k = 0; k < MPMTransfer.ElementGridNodeIncidentElements[ElementIndex].Num(); k++) {
292 int32 CurrentNode = MPMTransfer.ElementGridNodes[ElementIndex][MPMTransfer.ElementGridNodeIncidentElements[ElementIndex][k][0]];
293 T Mass = GridData[(MPMTransfer.NTransfer + 1) * CurrentNode];
294 if (Mass != 0) {
295 for (int32 alpha = 0; alpha < 3; alpha++) {
296 GridPositions[CurrentNode][alpha] += DeltaLambda * GridGradient[k][alpha] / Mass;
297 }
298 }
299 }
300 }
301
302 void ApplyInParallel(ParticleType& Particles, const T Dt)
303 {
304 for (int32 color = 0; color < ElementsPerSubColors.Num(); color++)
305 {
306 for (int32 subcolor = 0; subcolor < ElementsPerSubColors[color].Num(); subcolor++)
307 {
309 {
310 const int32 ElementIndex = ElementsPerSubColors[color][subcolor][ColorIndex];
311 ApplyPolar(Particles, Dt, ElementIndex);
312 ApplyDet(Particles, Dt, ElementIndex);
313 }, ElementsPerSubColors[color][subcolor].Num() < 30);
314 }
315 }
316 //final G2P to compute particle positions:
317 //FinalG2P(Particles);
318 }
319
320 private:
321
322 PMatrix<T, 3, 3> Ds(const TVec4<TVector<T, 3>>& LocalPositions) const {
323 PMatrix<T, 3, 3> Result((T)0.);
324 for (int i = 0; i < 3; i++) {
325 for (int c = 0; c < 3; c++) {
326 Result.SetAt(c, i, LocalPositions[i+1][c] - LocalPositions[0][c]);
327 }
328 }
329 return Result;
330 }
331
332
333 PMatrix<T, 3, 3> F(const TVec4<TVector<T, 3>>& LocalPositions, const int32 ElementIndex) const
334 {
335 return Base::ElementDmInv(ElementIndex) * Ds(LocalPositions);
336 }
337
338 TVec4<TVector<T, 3>> GetPolarGradient(const TVec4<TVector<T, 3>>& LocalPositions, const int32 ElementIndex, T& Constraint, const T Tol = T(1e-4)) const
339 {
340 PMatrix<T, 3, 3> Fe = F(LocalPositions, ElementIndex);
341 PMatrix<T, 3, 3> Re((T)0.), Se((T)0.);
342
344
345 T C1 = (T)0.;
346 for (int i = 0; i < 3; i++)
347 {
348 for (int j = 0; j < 3; j++)
349 {
350 C1 += FMath::Square((Fe - Re).GetAt(i, j));
351 }
352 }
353 C1 = FMath::Sqrt(C1);
354
355
356 if (C1 < Tol)
357 {
358 Constraint = (T)0.;
359 return TVec4<TVector<T, 3>>(TVector<T, 3>((T)0.));
360 }
361 Constraint = C1;
362
363 PMatrix<T, 3, 3> DmInvT = Base::ElementDmInv(ElementIndex).GetTransposed();
364 TVector<T, 81> dRdF((T)0.);
366 TVec4<TVector<T, 3>> dC1(TVector<T, 3>((T)0.));
367 //dC1 = dC1dF * dFdX
368 for (int alpha = 0; alpha < 3; alpha++) {
369 for (int l = 0; l < 3; l++) {
370
371 dC1[0][alpha] += (DmInvT * Re).GetAt(alpha, l) - (DmInvT * Fe).GetAt(alpha, l);
372
373 }
374 }
375 for (int ie = 0; ie < 3; ie++) {
376 for (int alpha = 0; alpha < 3; alpha++) {
377 dC1[ie + 1][alpha] = (DmInvT * Fe).GetAt(alpha, ie) - (DmInvT * Re).GetAt(alpha, ie);
378 }
379 }
380 //it's really ie-1 here
381 for (int ie = 0; ie < 3; ie++) {
382 for (int alpha = 0; alpha < 3; alpha++) {
383 for (int m = 0; m < 3; m++) {
384 for (int n = 0; n < 3; n++) {
385 for (int j = 0; j < 3; j++) {
386 dC1[ie + 1][alpha] -= (Fe.GetAt(m, n) - Re.GetAt(m, n)) * dRdF[9 * (alpha * 3 + j) + m * 3 + n] * DmInvT.GetAt(j, ie);
387 }
388 }
389 }
390 }
391 }
392 for (int alpha = 0; alpha < 3; alpha++) {
393 for (int m = 0; m < 3; m++) {
394 for (int n = 0; n < 3; n++) {
395 for (int l = 0; l < 3; l++) {
396 for (int j = 0; j < 3; j++) {
397 dC1[0][alpha] += (Fe.GetAt(m, n) - Re.GetAt(m, n)) * dRdF[9 * (alpha * 3 + j) + m * 3 + n] * DmInvT.GetAt(j, l);
398 }
399 }
400 }
401 }
402 }
403
404 if (C1 != 0)
405 {
406 for (int i = 0; i < 4; i++)
407 {
408 for (int j = 0; j < 3; j++)
409 {
410 dC1[i][j] /= C1;
411 }
412 }
413 }
414 return dC1;
415 }
416
417 TVec4<TVector<T, 3>> GetDetGradient(const TVec4<TVector<T, 3>>& LocalPositions, const int32 ElementIndex, T& Constraint, const T Tol = T(1e-4)) const
418 {
419 const PMatrix<T, 3, 3> Fe = F(LocalPositions, ElementIndex);
420 PMatrix<T, 3, 3> DmInvT = Base::ElementDmInv(ElementIndex).GetTransposed();
421
422 T J = Fe.Determinant();
423 if (J - 1 < Tol)
424 {
425 Constraint = (T)0.;
426 return TVec4<TVector<T, 3>>(TVector<T, 3>((T)0.));
427 }
428 Constraint = J - 1;
429
430 TVec4<TVector<T, 3>> dC2(TVector<T, 3>((T)0.));
431
433 JFinvT.SetAt(0, 0, Fe.GetAt(1, 1) * Fe.GetAt(2, 2) - Fe.GetAt(2, 1) * Fe.GetAt(1, 2));
434 JFinvT.SetAt(0, 1, Fe.GetAt(2, 0) * Fe.GetAt(1, 2) - Fe.GetAt(1, 0) * Fe.GetAt(2, 2));
435 JFinvT.SetAt(0, 2, Fe.GetAt(1, 0) * Fe.GetAt(2, 1) - Fe.GetAt(2, 0) * Fe.GetAt(1, 1));
436 JFinvT.SetAt(1, 0, Fe.GetAt(2, 1) * Fe.GetAt(0, 2) - Fe.GetAt(0, 1) * Fe.GetAt(2, 2));
437 JFinvT.SetAt(1, 1, Fe.GetAt(0, 0) * Fe.GetAt(2, 2) - Fe.GetAt(2, 0) * Fe.GetAt(0, 2));
438 JFinvT.SetAt(1, 2, Fe.GetAt(2, 0) * Fe.GetAt(0, 1) - Fe.GetAt(0, 0) * Fe.GetAt(2, 1));
439 JFinvT.SetAt(2, 0, Fe.GetAt(0, 1) * Fe.GetAt(1, 2) - Fe.GetAt(1, 1) * Fe.GetAt(0, 2));
440 JFinvT.SetAt(2, 1, Fe.GetAt(1, 0) * Fe.GetAt(0, 2) - Fe.GetAt(0, 0) * Fe.GetAt(1, 2));
441 JFinvT.SetAt(2, 2, Fe.GetAt(0, 0) * Fe.GetAt(1, 1) - Fe.GetAt(1, 0) * Fe.GetAt(0, 1));
442
444
445 for (int32 ie = 0; ie < 3; ie++) {
446 for (int32 alpha = 0; alpha < 3; alpha++) {
447 dC2[ie + 1][alpha] = JinvTDmInvT.GetAt(alpha, ie);
448 }
449 }
450 for (int32 alpha = 0; alpha < 3; alpha++) {
451 for (int32 l = 0; l < 3; l++) {
452 dC2[0][alpha] -= JinvTDmInvT.GetAt(alpha, l);
453 }
454 }
455 return dC2;
456 }
457
458 //interpolate particle positions from grid positions
459 void FinalG2P(ParticleType& Particles)
460 {
461 PhysicsParallelFor(Particles.Size(), [&](const int32 p)
462 {
463 Particles.P(p) = TVec3<T>((T)0.);
464 for (int32 ii = 0; ii < int32(MPMGrid.NPerDir); ii++)
465 {
466 T Nii = MPMGrid.Nijk(MPMTransfer.Weights[p][0], ii);
467 for (int32 jj = 0; jj < int32(MPMGrid.NPerDir); jj++)
468 {
469 T Njj = MPMGrid.Nijk(MPMTransfer.Weights[p][1], jj);
470 for (int32 kk = 0; kk < int32(MPMGrid.NPerDir); kk++)
471 {
472 T Nkk = MPMGrid.Nijk(MPMTransfer.Weights[p][2], kk);
473 TVector<int32, 3> LocIndex = { ii, jj, kk };
474 TVector<int32, 3> GlobIndex = MPMGrid.Loc2GlobIndex(MPMTransfer.Indices[p], LocIndex);
475 int32 GlobIndexFlat = MPMGrid.FlatIndex(GlobIndex);
476 //G2PHelper(Nii * Njj * Nkk, GridPositions[GlobIndexFlat], p, Particles);
477 Particles.P(p) += Nii * Njj * Nkk * GridPositions[GlobIndexFlat];
478 }
479 }
480 }
481 }, Particles.Size() < 50);
482 }
483
484 protected:
491 UE_DEPRECATED(5.6, "Use PreviousColoringPtr instead")
492 TArray<TArray<int32>>* PreviousColoring = nullptr;
493 TUniquePtr<TArray<TArray<int32>>> PreviousColoringPtr;
494 TArray<TArray<TArray<int32>>> ElementsPerSubColors;
495 TArray<T> GridData;
496 TArray<TVector<T, 3>> GridPositions;
497 bool InitialGridDataWritten = false;
498 };
499
500
501}
OODEFFUNC typedef const char * file
Definition oodle2.h:678
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
#define TEXT(x)
Definition Platform.h:1272
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 TRACE_CPUPROFILER_EVENT_SCOPE(Name)
Definition CpuProfilerTrace.h:528
@ FILEWRITE_Append
Definition FileManager.h:20
@ Num
Definition MetalRHIPrivate.h:234
uint32 Size
Definition VulkanMemory.cpp:4034
static TArray< TArray< int32 > > ComputeGraphColoringAllDynamic(const TArray< TVec4< int32 > > &Graph, const Chaos::TDynamicParticles< T, 3 > &InParticles, const int32 GraphParticlesStart, const int32 GraphParticlesEnd)
Definition GraphColoring.h:40
Definition Matrix.h:21
Definition XPBDCorotatedConstraints.h:20
TArray< T > LambdaArray
Definition XPBDCorotatedConstraints.h:637
TArray< TVector< int32, 4 > > MeshConstraints
Definition XPBDCorotatedConstraints.h:654
TArray< T > Measure
Definition XPBDCorotatedConstraints.h:655
T Lambda
Definition XPBDCorotatedConstraints.h:645
PMatrix< T, 3, 3 > DsInit(const int e, const ParticleType &InParticles) const
Definition XPBDCorotatedConstraints.h:208
virtual void Init() const
Definition XPBDCorotatedConstraints.h:254
TArray< T > DmInverse
Definition XPBDCorotatedConstraints.h:638
PMatrix< T, 3, 3 > ElementDmInv(const int e) const
Definition XPBDCorotatedConstraints.h:234
T Mu
Definition XPBDCorotatedConstraints.h:644
Definition XPBDGridBasedCorotatedConstraints.h:23
T MaxDt
Definition XPBDGridBasedCorotatedConstraints.h:485
const TArray< TArray< int32 > > GetElementsPerColor() const
Definition XPBDGridBasedCorotatedConstraints.h:203
void ApplyInParallel(ParticleType &Particles, const T Dt)
Definition XPBDGridBasedCorotatedConstraints.h:302
void Init(const ParticleType &InParticles, const T Dt)
Definition XPBDGridBasedCorotatedConstraints.h:122
TArray< TArray< int32 > > ElementsPerColor
Definition XPBDGridBasedCorotatedConstraints.h:490
FXPBDGridBasedCorotatedConstraints(const ParticleType &InParticles, const TArray< TVector< int32, 4 > > &InMesh, const T GridDx=(T).1, const bool bRecordMetricIn=true, const T MaxDtIn=(T).1, const T MinDtIn=(T).01, const T CFLCoeffIn=(T).4, const T &EMesh=(T) 1000.0, const T &NuMesh=(T).3)
Definition XPBDGridBasedCorotatedConstraints.h:36
const TMPMTransfer< T > GetMPMTransfer() const
Definition XPBDGridBasedCorotatedConstraints.h:206
void ApplyPolar(ParticleType &Particles, const T Dt, const int32 ElementIndex)
Definition XPBDGridBasedCorotatedConstraints.h:208
TMPMGrid< T > MPMGrid
Definition XPBDGridBasedCorotatedConstraints.h:488
TMPMTransfer< T > MPMTransfer
Definition XPBDGridBasedCorotatedConstraints.h:489
void ApplyDet(ParticleType &Particles, const T Dt, const int32 ElementIndex)
Definition XPBDGridBasedCorotatedConstraints.h:254
void TimeStepPostprocessing(ParticleType &InParticles, const T Dt)
Definition XPBDGridBasedCorotatedConstraints.h:147
const TArray< TArray< TArray< int32 > > > GetElementsPerSubColors() const
Definition XPBDGridBasedCorotatedConstraints.h:205
void WriteGridNodes()
Definition XPBDGridBasedCorotatedConstraints.h:81
const TArray< TArray< int32 > > GetPreviousColoring() const
Definition XPBDGridBasedCorotatedConstraints.h:204
T CFLCoeff
Definition XPBDGridBasedCorotatedConstraints.h:487
TArray< TVector< T, 3 > > GridPositions
Definition XPBDGridBasedCorotatedConstraints.h:496
T ComputeCFLDt(const ParticleType &InParticles)
Definition XPBDGridBasedCorotatedConstraints.h:166
TArray< TArray< TArray< int32 > > > ElementsPerSubColors
Definition XPBDGridBasedCorotatedConstraints.h:494
T MinDt
Definition XPBDGridBasedCorotatedConstraints.h:486
TUniquePtr< TArray< TArray< int32 > > > PreviousColoringPtr
Definition XPBDGridBasedCorotatedConstraints.h:493
TArray< T > GridData
Definition XPBDGridBasedCorotatedConstraints.h:495
Definition UniformGrid.h:315
Definition MPMTransfer.h:15
Definition Vector.h:41
int32 Num() const
Definition Vector.h:150
static CORE_API FString ProjectDir()
Definition Paths.cpp:457
CORE_API IPlatformFile & GetPlatformFile()
Definition PlatformFileManager.cpp:22
static CORE_API FPlatformFileManager & Get()
Definition PlatformFileManager.cpp:185
static CORE_API IFileManager & Get()
Definition FileManagerGeneric.cpp:1072
Definition GenericPlatformFile.h:342
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void Init(const ElementType &Element, SizeType Number)
Definition Array.h:3043
Definition UniquePtr.h:107
Definition CollectionEmbeddedSpringConstraintFacade.cpp:6
void dRdFCorotated(const PMatrix< T, 3, 3 > &F, TVector< T, 81 > &dRdF)
Definition ImplicitQRSVD.h:782
TVector< T, 4 > TVec4
Definition Core.h:44
void CHAOS_API PhysicsParallelFor(int32 InNum, TFunctionRef< void(int32)> InCallable, bool bForceSingleThreaded=false)
Definition Parallel.cpp:55
void PolarDecomposition(const PMatrix< T, 2, 2 > &A, GivensRotation< T > &R, PMatrix< T, 2, 2 > &S_Sym)
2x2 polar decomposition.
Definition ImplicitQRSVD.h:323
void ComputeGridBasedGraphSubColoringPointer(const TArray< TArray< int32 > > &ElementsPerColor, const TMPMGrid< T > &Grid, const int32 GridSize, TArray< TArray< int32 > > *&PreviousColoring, const TArray< TArray< int32 > > &ConstraintsNodesSet, TArray< TArray< TArray< int32 > > > &ElementsPerSubColors)
Definition GraphColoring.h:53
@ false
Definition radaudio_common.h:23
static CORE_API bool SaveStringToFile(FStringView String, const TCHAR *Filename, EEncodingOptions EncodingOptions=EEncodingOptions::AutoDetect, IFileManager *FileManager=&IFileManager::Get(), uint32 WriteFlags=0)
Definition FileHelper.cpp:669
static constexpr UE_FORCEINLINE_HINT T Square(const T A)
Definition UnrealMathUtility.h:578