UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PBDBendingConstraintsBase.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
10
11namespace Chaos::Softs
12{
13
15{
16public:
23
35 bool bTrimKinematicConstraints = false,
38 , ConstraintSharedEdges(ExtractConstraintSharedEdges(Constraints))
40 , ParticleCount(InParticles.GetRangeSize())
41 , Stiffness(
47 FPBDStiffness::DefaultTableSize,
48 FPBDStiffness::DefaultParameterFitBase,
49 MaxStiffness)
51 InBucklingRatio.ClampAxes((FSolverReal)0., (FSolverReal)1.),
62 FPBDStiffness::DefaultTableSize,
63 FPBDStiffness::DefaultParameterFitBase,
64 MaxStiffness)
68 {
70 }
71
72 UE_DEPRECATED(5.5, "Use a constructor with BucklingRatioMultipliers.")
84 FSolverReal MaxStiffness = FPBDStiffness::DefaultPBDMaxStiffness)
89 TConstArrayView<float>(),
98 MaxStiffness)
99 {}
100
114 bool bTrimKinematicConstraints = false,
117 , ConstraintSharedEdges(ExtractConstraintSharedEdges(Constraints))
120 , Stiffness(
126 FPBDStiffness::DefaultTableSize,
127 FPBDStiffness::DefaultParameterFitBase,
128 MaxStiffness)
130 InBucklingRatio.ClampAxes((FSolverReal)0., (FSolverReal)1.),
141 FPBDStiffness::DefaultTableSize,
142 FPBDStiffness::DefaultParameterFitBase,
143 MaxStiffness)
147 {
149 }
150
151 UE_DEPRECATED(5.5, "Use a constructor with BucklingRatioMultipliers.")
165 FSolverReal MaxStiffness = FPBDStiffness::DefaultPBDMaxStiffness)
181 MaxStiffness)
182 {
183 }
184
185 UE_DEPRECATED(5.5, "Use a constructor with BucklingRatioMultipliers.")
202
204
205 // Update stiffness values
215
216 UE_DEPRECATED(5.5, "Use version with FSolverVec2 InBucklingRatio.")
221
222 // Update stiffness table, as well as the simulation stiffness exponent
223 void ApplyProperties(const FSolverReal Dt, const int32 NumIterations)
224 {
225 Stiffness.ApplyPBDValues(Dt, NumIterations);
227 BucklingStiffness.ApplyPBDValues(Dt, NumIterations);
228 }
229
230 template<typename SolverParticlesOrRange>
232 {
233 const TVec4<int32>& Constraint = Constraints[i];
234 const FSolverVec3& P1 = InParticles.P(Constraint[0]);
235 const FSolverVec3& P2 = InParticles.P(Constraint[1]);
236 const FSolverVec3& P3 = InParticles.P(Constraint[2]);
237 const FSolverVec3& P4 = InParticles.P(Constraint[3]);
238
239 return CalcGradients(P1, P2, P3, P4);
240 }
241
242 template<typename SolverParticlesOrRange>
244 {
245 const TVec4<int32>& Constraint = Constraints[i];
246 const int32 i1 = Constraint[0];
247 const int32 i2 = Constraint[1];
248 const int32 i3 = Constraint[2];
249 const int32 i4 = Constraint[3];
250 const FSolverVec3& P1 = InParticles.P(i1);
251 const FSolverVec3& P2 = InParticles.P(i2);
252 const FSolverVec3& P3 = InParticles.P(i3);
253 const FSolverVec3& P4 = InParticles.P(i4);
254 const FSolverReal Angle = CalcAngle(P1, P2, P3, P4);
255 const FSolverReal Denom = (InParticles.InvM(i1) * Grads[0].SizeSquared() + InParticles.InvM(i2) * Grads[1].SizeSquared() + InParticles.InvM(i3) * Grads[2].SizeSquared() + InParticles.InvM(i4) * Grads[3].SizeSquared());
256
258
259 constexpr FSolverReal SingleStepAngleLimit = (FSolverReal)(UE_PI * .25f); // this constraint is very non-linear. taking large steps is not accurate
261 return SafeDivide(Delta, Denom);
262 }
263
264 static FSolverReal CalcAngle(const FSolverVec3& P1, const FSolverVec3& P2, const FSolverVec3& P3, const FSolverVec3& P4)
265 {
266 const FSolverVec3 Normal1 = FSolverVec3::CrossProduct(P1 - P3, P2 - P3).GetSafeNormal();
267 const FSolverVec3 Normal2 = FSolverVec3::CrossProduct(P2 - P4, P1 - P4).GetSafeNormal();
268
269 const FSolverVec3 SharedEdge = (P2 - P1).GetSafeNormal();
270
271 const FSolverReal CosPhi = FMath::Clamp(FSolverVec3::DotProduct(Normal1, Normal2), (FSolverReal)-1, (FSolverReal)1);
272 const FSolverReal SinPhi = FMath::Clamp(FSolverVec3::DotProduct(FSolverVec3::CrossProduct(Normal2, Normal1), SharedEdge), (FSolverReal)-1, (FSolverReal)1);
273 return FMath::Atan2(SinPhi, CosPhi);
274 }
275
276 UE_DEPRECATED(5.5, "This version is deprecated and will produce the incorrect result if BucklingRatio is weighted. Use version that takes a ConstraintIndex instead.")
277 bool AngleIsBuckled(const FSolverReal Angle, const FSolverReal RestAngle) const
278 {
279 // Angle is 0 when completely flat. This is easier to think of in terms of Angle' = (PI - |Angle|), which is 0 when completely folded.
280 // Consider buckled when Angle' <= BucklingRatio * RestAngle', and use buckling stiffness instead of stiffness.
281 return UE_PI - FMath::Abs(Angle) < (FSolverReal)BucklingRatioWeighted * (UE_PI - FMath::Abs(RestAngle));
282 }
283
284 bool AngleIsBuckled(const FSolverReal Angle, const int32 ConstraintIndex) const
285 {
286 // Angle is 0 when completely flat. This is easier to think of in terms of Angle' = (PI - |Angle|), which is 0 when completely folded.
287 // Consider buckled when Angle' <= BucklingRatio * RestAngle', and use buckling stiffness instead of stiffness.
288 return UE_PI - FMath::Abs(Angle) < BucklingRatioWeighted.GetValue(ConstraintIndex) * (UE_PI - FMath::Abs(RestAngles[ConstraintIndex]));
289 }
290
291 template<typename SolverParticlesOrRange>
293
296 const TArray<bool>& GetIsBuckled() const { return IsBuckled; }
297
298protected:
299 template<class TNum>
300 static TNum SafeDivide(const TNum& Numerator, const FSolverReal& Denominator)
301 {
302 if (Denominator > SMALL_NUMBER)
303 return Numerator / Denominator;
304 return TNum(0);
305 }
306
308 {
310 // Calculated using Phi = atan2(SinPhi, CosPhi)
311 // where SinPhi = (Normal1 ^ Normal2)*SharedEdgeNormalized, CosPhi = Normal1 * Normal2
312 // Full gradients are calculated here, i.e., no simplifying assumptions around things like edge lengths being constant.
313 const FSolverVec3 SharedEdgeNormalized = (P2 - P1).GetSafeNormal();
314 const FSolverVec3 P13CrossP23 = FSolverVec3::CrossProduct(P1 - P3, P2 - P3);
315 const FSolverReal Normal1Len = P13CrossP23.Size();
317 const FSolverVec3 P24CrossP14 = FSolverVec3::CrossProduct(P2 - P4, P1 - P4);
318 const FSolverReal Normal2Len = P24CrossP14.Size();
320
321 const FSolverVec3 N2CrossN1 = FSolverVec3::CrossProduct(Normal2, Normal1);
322
323 const FSolverReal CosPhi = FMath::Clamp(FSolverVec3::DotProduct(Normal1, Normal2), (FSolverReal)-1, (FSolverReal)1);
324 const FSolverReal SinPhi = FMath::Clamp(FSolverVec3::DotProduct(N2CrossN1, SharedEdgeNormalized), (FSolverReal)-1, (FSolverReal)1);
325
328
329 const FSolverVec3 DPhiDP13 = FSolverVec3::CrossProduct(P2 - P3, DPhiDN1_OverNormal1Len);
330 const FSolverVec3 DPhiDP23 = FSolverVec3::CrossProduct(DPhiDN1_OverNormal1Len, P1 - P3);
331 const FSolverVec3 DPhiDP24 = FSolverVec3::CrossProduct(P1 - P4, DPhiDN2_OverNormal2Len);
332 const FSolverVec3 DPhiDP14 = FSolverVec3::CrossProduct(DPhiDN2_OverNormal2Len, P2 - P4);
333
334 Grads[0] = DPhiDP13 + DPhiDP14;
335 Grads[1] = DPhiDP23 + DPhiDP24;
336 Grads[2] = -DPhiDP13 - DPhiDP23;
337 Grads[3] = -DPhiDP14 - DPhiDP24;
338
339 if (OutAngle)
340 {
341 *OutAngle = FMath::Atan2(SinPhi, CosPhi);
342 }
343
344 return Grads;
345 }
346
353
354private:
355 template<typename SolverParticlesOrRange>
356 static TArray<TVec4<int32>> TrimKinematicConstraints(const TArray<TVec4<int32>>& InConstraints, const SolverParticlesOrRange& InParticles)
357 {
360 for (const TVec4<int32>& Constraint : InConstraints)
361 {
362 if (InParticles.InvM(Constraint[0]) != (FSolverReal)0. || InParticles.InvM(Constraint[1]) != (FSolverReal)0. || InParticles.InvM(Constraint[2]) != (FSolverReal)0. || InParticles.InvM(Constraint[3]) != (FSolverReal)0.)
363 {
364 TrimmedConstraints.Add(Constraint);
365 }
366 }
367 TrimmedConstraints.Shrink();
368 return TrimmedConstraints;
369 }
370
371 static TArray<TVec2<int32>> ExtractConstraintSharedEdges(const TArray<TVec4<int32>>& Constraints)
372 {
375 for (const TVec4<int32>& Constraint : Constraints)
376 {
377 ExtractedEdges.Emplace(Constraint[0], Constraint[1]);
378 }
379 return ExtractedEdges;
380 }
381
382protected:
384 TArray<TVec2<int32>> ConstraintSharedEdges; // Only shared edges are used for calculating weighted stiffnesses.
385
388
392
395
396 UE_DEPRECATED(5.5, "Scalar Buckling Ratio has been deprecated. Use BucklingRatioWeighted instead.")
398};
399
400} // End namespace Chaos::Softs
401
402#if !defined(CHAOS_BENDING_ISPC_ENABLED_DEFAULT)
403#define CHAOS_BENDING_ISPC_ENABLED_DEFAULT 1
404#endif
405
406#if !defined(USE_ISPC_KERNEL_CONSOLE_VARIABLES_IN_SHIPPING)
407#define USE_ISPC_KERNEL_CONSOLE_VARIABLES_IN_SHIPPING 0
408#endif
409
410// Support run-time toggling on supported platforms in non-shipping configurations
411#if !INTEL_ISPC || (UE_BUILD_SHIPPING && !USE_ISPC_KERNEL_CONSOLE_VARIABLES_IN_SHIPPING)
412static constexpr bool bChaos_Bending_ISPC_Enabled = INTEL_ISPC && CHAOS_BENDING_ISPC_ENABLED_DEFAULT;
413#else
414extern CHAOS_API bool bChaos_Bending_ISPC_Enabled;
415#endif
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
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 PRAGMA_ENABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:12
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:8
const bool
Definition NetworkReplayStreaming.h:178
#define CHAOS_BENDING_ISPC_ENABLED_DEFAULT
Definition PBDBendingConstraintsBase.h:403
#define UE_PI
Definition UnrealMathUtility.h:129
#define SMALL_NUMBER
Definition UnrealMathUtility.h:66
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint8_t uint8
Definition binka_ue_file_header.h:8
Definition PBDBendingConstraintsBase.h:15
FPBDBendingConstraintsBase(const FSolverParticles &InParticles, int32 InParticleOffset, int32 InParticleCount, TArray< TVec4< int32 > > &&InConstraints, const TConstArrayView< FRealSingle > &StiffnessMultipliers, const TConstArrayView< FRealSingle > &BucklingRatioMultipliers, const TConstArrayView< FRealSingle > &BucklingStiffnessMultipliers, const TConstArrayView< FRealSingle > &RestAngleMap, const FSolverVec2 &InStiffness, const FSolverVec2 &InBucklingRatio, const FSolverVec2 &InBucklingStiffness, const FSolverVec2 &RestAngleValue, ERestAngleConstructionType RestAngleConstructionType, bool bTrimKinematicConstraints=false, FSolverReal MaxStiffness=FPBDStiffness::DefaultPBDMaxStiffness)
Definition PBDBendingConstraintsBase.h:101
const int32 ParticleOffset
Definition PBDBendingConstraintsBase.h:386
ERestAngleConstructionType
Definition PBDBendingConstraintsBase.h:18
TArray< bool > IsBuckled
Definition PBDBendingConstraintsBase.h:394
FSolverReal GetScalingFactor(const SolverParticlesOrRange &InParticles, const int32 i, const TStaticArray< FSolverVec3, 4 > &Grads, const FSolverReal ExpStiffnessValue, const FSolverReal ExpBucklingValue) const
Definition PBDBendingConstraintsBase.h:243
void SetProperties(const FSolverVec2 &InStiffness, const FSolverVec2 &InBucklingRatio, const FSolverVec2 &InBucklingStiffness)
Definition PBDBendingConstraintsBase.h:206
CHAOS_API void CalculateRestAngles(const TConstArrayView< FSolverVec3 > &InPositions, int32 InParticleOffset, int32 InParticleCount, const TConstArrayView< FRealSingle > &RestAngleMap, const FSolverVec2 &RestAngleValue, ERestAngleConstructionType RestAngleConstructionType)
Definition PBDBendingConstraintsBase.cpp:112
static TNum SafeDivide(const TNum &Numerator, const FSolverReal &Denominator)
Definition PBDBendingConstraintsBase.h:300
FSolverReal BucklingRatio
Definition PBDBendingConstraintsBase.h:397
TArray< FSolverReal > RestAngles
Definition PBDBendingConstraintsBase.h:393
const TArray< TVec4< int32 > > & GetConstraints() const
Definition PBDBendingConstraintsBase.h:295
const TArray< FSolverReal > & GetRestAngles() const
Definition PBDBendingConstraintsBase.h:294
CHAOS_API void Init(const SolverParticlesOrRange &InParticles)
bool AngleIsBuckled(const FSolverReal Angle, const int32 ConstraintIndex) const
Definition PBDBendingConstraintsBase.h:284
FPBDStiffness Stiffness
Definition PBDBendingConstraintsBase.h:389
FPBDWeightMap BucklingRatioWeighted
Definition PBDBendingConstraintsBase.h:390
FPBDStiffness BucklingStiffness
Definition PBDBendingConstraintsBase.h:391
FPBDBendingConstraintsBase(const FSolverParticlesRange &InParticles, TArray< TVec4< int32 > > &&InConstraints, const TConstArrayView< FRealSingle > &StiffnessMultipliers, const TConstArrayView< FRealSingle > &BucklingRatioMultipliers, const TConstArrayView< FRealSingle > &BucklingStiffnessMultipliers, const TConstArrayView< FRealSingle > &RestAngleMap, const FSolverVec2 &InStiffness, const FSolverVec2 &InBucklingRatio, const FSolverVec2 &InBucklingStiffness, const FSolverVec2 &RestAngleValue, ERestAngleConstructionType RestAngleConstructionType, bool bTrimKinematicConstraints=false, FSolverReal MaxStiffness=FPBDStiffness::DefaultPBDMaxStiffness)
Definition PBDBendingConstraintsBase.h:24
virtual ~FPBDBendingConstraintsBase()
Definition PBDBendingConstraintsBase.h:203
TStaticArray< FSolverVec3, 4 > GetGradients(const SolverParticlesOrRange &InParticles, const int32 i) const
Definition PBDBendingConstraintsBase.h:231
void ApplyProperties(const FSolverReal Dt, const int32 NumIterations)
Definition PBDBendingConstraintsBase.h:223
static TStaticArray< FSolverVec3, 4 > CalcGradients(const FSolverVec3 &P1, const FSolverVec3 &P2, const FSolverVec3 &P3, const FSolverVec3 &P4, FSolverReal *OutAngle=nullptr)
Definition PBDBendingConstraintsBase.h:307
bool AngleIsBuckled(const FSolverReal Angle, const FSolverReal RestAngle) const
Definition PBDBendingConstraintsBase.h:277
static FSolverReal CalcAngle(const FSolverVec3 &P1, const FSolverVec3 &P2, const FSolverVec3 &P3, const FSolverVec3 &P4)
Definition PBDBendingConstraintsBase.h:264
const int32 ParticleCount
Definition PBDBendingConstraintsBase.h:387
TArray< TVec4< int32 > > Constraints
Definition PBDBendingConstraintsBase.h:383
TArray< TVec2< int32 > > ConstraintSharedEdges
Definition PBDBendingConstraintsBase.h:384
const TArray< bool > & GetIsBuckled() const
Definition PBDBendingConstraintsBase.h:296
Definition PBDStiffness.h:21
void SetWeightedValue(const FSolverVec2 &InWeightedValue, FSolverReal MaxStiffness=DefaultPBDMaxStiffness)
Definition PBDStiffness.h:65
static constexpr FSolverReal DefaultPBDMaxStiffness
Definition PBDStiffness.h:24
void ApplyPBDValues(const FSolverReal Dt, const int32 NumIterations)
Definition PBDStiffness.h:124
Definition PBDWeightMap.h:19
FSolverReal GetValue(int32 Index) const
Definition PBDWeightMap.h:88
void ApplyValues(bool *bOutUpdated=nullptr)
Definition PBDWeightMap.h:71
void SetWeightedValue(const FSolverVec2 &InWeightedValue)
Definition PBDWeightMap.h:62
Definition SoftsSolverParticlesRange.h:12
Definition PBDSoftsSolverParticles.h:20
Definition Vector.h:41
Definition Constraints.Build.cs:6
Definition Array.h:670
UE_FORCEINLINE_HINT void Reserve(SizeType Number)
Definition Array.h:3016
Definition StaticArray.h:26
Definition CollectionEmbeddedSpringConstraintFacade.cpp:6
TVector< FSolverReal, 2 > FSolverVec2
Definition PBDSoftsEvolutionFwd.h:32
FRealSingle FSolverReal
Definition PBDSoftsEvolutionFwd.h:31
float FRealSingle
Definition Real.h:14
@ false
Definition radaudio_common.h:23
static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
Definition UnrealMathUtility.h:592