UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PBDAxialSpringConstraintsBase.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4// HEADER_UNIT_SKIP - Internal
5
10#include "Containers/Array.h"
11
12namespace Chaos::Softs
13{
14
16{
17public:
18
45
74
76
78
79 void ApplyProperties(const FSolverReal Dt, const int32 NumIterations) { Stiffness.ApplyPBDValues(Dt, NumIterations); }
80
82 const TArray<FSolverReal>& GetBarys() const { return Barys; }
83
88
89protected:
90
92 {
93 check(DistsToCompute.Num() == Constraints.Num());
94 for (int32 Index = 0; Index < Constraints.Num(); ++Index)
95 {
96
97 const FSolverVec3& P1 = Positions[Constraints[Index][0]];
98 const FSolverVec3& P2 = Positions[Constraints[Index][1]];
99 const FSolverVec3& P3 = Positions[Constraints[Index][2]];
100 const FSolverVec3 P = (P2 - P3) * Barys[Index] + P3;
101 DistsToCompute[Index] = (P1 - P).Size();
102 }
103 }
104
105 template<typename VectorType>
106 inline VectorType GetSpringDiff(const VectorType& P1, const VectorType& P2, const VectorType& P3, const FSolverReal Bary) const
107 {
108 return P1 - ((P2 - P3) * Bary + P3);
109 }
110
111 template<typename SolverParticlesOrRange>
112 inline FSolverVec3 GetDelta(const SolverParticlesOrRange& Particles, const int32 ConstraintIndex, const FSolverReal ExpStiffnessValue) const
113 {
114 const TVec3<int32>& Constraint = Constraints[ConstraintIndex];
115 const int32 i1 = Constraint[0];
116 const int32 i2 = Constraint[1];
117 const int32 i3 = Constraint[2];
118 const FSolverReal PInvMass = Particles.InvM(i3) * ((FSolverReal)1. - Barys[ConstraintIndex]) + Particles.InvM(i2) * Barys[ConstraintIndex];
119 if (Particles.InvM(i1) == (FSolverReal)0. && PInvMass == (FSolverReal)0.)
120 {
121 return FSolverVec3((FSolverReal)0.);
122 }
123 const FSolverVec3& P1 = Particles.P(i1);
124 const FSolverVec3& P2 = Particles.P(i2);
125 const FSolverVec3& P3 = Particles.P(i3);
126 const FSolverVec3 Difference = GetSpringDiff(P1, P2, P3, Barys[ConstraintIndex]);
127 const FSolverReal Distance = Difference.Size();
129 {
130 return FSolverVec3((FSolverReal)0.);
131 }
132 const FSolverVec3 Direction = Difference / Distance;
133 const FSolverVec3 Delta = (Distance - Dists[ConstraintIndex]) * Direction;
134 const FSolverReal CombinedInvMass = PInvMass + Particles.InvM(i1);
137 }
138
139private:
140 template<typename SolverParticlesOrRange>
141 FSolverReal FindBary(const SolverParticlesOrRange& Particles, const int32 i1, const int32 i2, const int32 i3)
142 {
143 const FSolverVec3& P1 = Particles.GetX(i1);
144 const FSolverVec3& P2 = Particles.GetX(i2);
145 const FSolverVec3& P3 = Particles.GetX(i3);
146 const FSolverVec3& P32 = P3 - P2;
147 const FSolverReal Bary = FSolverVec3::DotProduct(P32, P3 - P1) / P32.SizeSquared();
148 return FMath::Clamp(Bary, (FSolverReal)0., (FSolverReal)1.);
149 }
150
151 template<typename Predicate>
152 TArray<TVec3<int32>> TrimConstraints(const TArray<TVec3<int32>>& InConstraints, Predicate TrimPredicate)
153 {
156
157 for (const TVec3<int32>& Constraint : InConstraints)
158 {
159 const int32 Index0 = Constraint[0];
160 const int32 Index1 = Constraint[1];
161 const int32 Index2 = Constraint[2];
162
163 if (!TrimPredicate(Index0, Index1, Index2))
164 {
166 Index0 <= Index1 ?
167 Index1 <= Index2 ? TVec3<int32>(Index0, Index1, Index2) :
168 Index0 <= Index2 ? TVec3<int32>(Index0, Index2, Index1) :
169 TVec3<int32>(Index2, Index0, Index1) :
170 // Index1 < Index0
171 Index0 <= Index2 ? TVec3<int32>(Index1, Index0, Index2) :
172 Index1 <= Index2 ? TVec3<int32>(Index1, Index2, Index0) :
173 TVec3<int32>(Index2, Index1, Index0));
174 }
175 }
176 return TrimmedConstraints.Array();
177 }
178
179 template<typename SolverParticlesOrRange>
180 void Init(const SolverParticlesOrRange& Particles, bool bTrimKinematicConstraints)
181 {
182 Barys.Reset(Constraints.Num());
183 Dists.Reset(Constraints.Num());
184
185 for (int32 Index = 0; Index < Constraints.Num();)
186 {
187 TVec3<int32>& Constraint = Constraints[Index];
188 int32 i1 = Constraint[0];
189 int32 i2 = Constraint[1];
190 int32 i3 = Constraint[2];
191 // Find Bary closest to 0.5
192 const FSolverReal Bary1 = FindBary(Particles, i1, i2, i3);
193 const FSolverReal Bary2 = FindBary(Particles, i2, i3, i1);
194 const FSolverReal Bary3 = FindBary(Particles, i3, i1, i2);
195 FSolverReal Bary = Bary1;
200 {
201 Constraint[0] = i3;
202 Constraint[1] = i1;
203 Constraint[2] = i2;
204 Bary = Bary3;
205 }
206 else if (Bary2dist < Bary1dist && Bary2dist < Bary3dist)
207 {
208 Constraint[0] = i2;
209 Constraint[1] = i3;
210 Constraint[2] = i1;
211 Bary = Bary2;
212 }
213 // Reset as they may have changed
214 i1 = Constraint[0];
215 i2 = Constraint[1];
216 i3 = Constraint[2];
217 const FSolverVec3& P1 = Particles.GetX(i1);
218 const FSolverVec3& P2 = Particles.GetX(i2);
219 const FSolverVec3& P3 = Particles.GetX(i3);
220 const FSolverVec3 P = (P2 - P3) * Bary + P3;
221
223 {
224 const FSolverReal PInvMass = Particles.InvM(i3) * ((FSolverReal)1. - Bary) + Particles.InvM(i2) * Bary;
225 const FSolverReal CombinedInvMass = PInvMass + Particles.InvM(i1);
227 {
228 Constraints.RemoveAtSwap(Index);
229 continue;
230 }
231 }
232
233 Barys.Add(Bary);
234 Dists.Add((P1 - P).Size());
235 ++Index;
236 }
237 check(Barys.Num() == Constraints.Num());
238 check(Dists.Num() == Constraints.Num());
239 }
240
241protected:
248};
249
250} // End namespace Chaos::Softs
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UNLIKELY(x)
Definition Platform.h:857
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
void Init()
Definition LockFreeList.h:4
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
uint32 Size
Definition VulkanMemory.cpp:4034
Definition PBDAxialSpringConstraintsBase.h:16
FSolverVec3 GetDelta(const SolverParticlesOrRange &Particles, const int32 ConstraintIndex, const FSolverReal ExpStiffnessValue) const
Definition PBDAxialSpringConstraintsBase.h:112
virtual ~FPBDAxialSpringConstraintsBase()
Definition PBDAxialSpringConstraintsBase.h:75
VectorType GetSpringDiff(const VectorType &P1, const VectorType &P2, const VectorType &P3, const FSolverReal Bary) const
Definition PBDAxialSpringConstraintsBase.h:106
FPBDAxialSpringConstraintsBase(const FSolverParticlesRange &Particles, const TArray< TVec3< int32 > > &InConstraints, const TConstArrayView< FRealSingle > &StiffnessMultipliers, const FSolverVec2 &InStiffness, bool bTrimKinematicConstraints, FSolverReal MaxStiffness=FPBDStiffness::DefaultPBDMaxStiffness)
Definition PBDAxialSpringConstraintsBase.h:19
TArray< FSolverReal > Dists
Definition PBDAxialSpringConstraintsBase.h:246
void SetProperties(const FSolverVec2 &InStiffness)
Definition PBDAxialSpringConstraintsBase.h:77
TArray< FSolverReal > Barys
Definition PBDAxialSpringConstraintsBase.h:245
const TArray< TVec3< int32 > > & GetConstraints() const
Definition PBDAxialSpringConstraintsBase.h:81
const int32 ParticleCount
Definition PBDAxialSpringConstraintsBase.h:244
TArray< TVec3< int32 > > Constraints
Definition PBDAxialSpringConstraintsBase.h:242
void ApplyProperties(const FSolverReal Dt, const int32 NumIterations)
Definition PBDAxialSpringConstraintsBase.h:79
void CalculateRestLengths(const TConstArrayView< FSolverVec3 > &Positions, const TArrayView< FSolverReal > &DistsToCompute) const
Definition PBDAxialSpringConstraintsBase.h:91
const TArray< FSolverReal > & GetBarys() const
Definition PBDAxialSpringConstraintsBase.h:82
FPBDStiffness Stiffness
Definition PBDAxialSpringConstraintsBase.h:247
void ResetRestLengths(const TConstArrayView< FSolverVec3 > &Positions)
Definition PBDAxialSpringConstraintsBase.h:84
const int32 ParticleOffset
Definition PBDAxialSpringConstraintsBase.h:243
FPBDAxialSpringConstraintsBase(const FSolverParticles &Particles, int32 InParticleOffset, int32 InParticleCount, const TArray< TVec3< int32 > > &InConstraints, const TConstArrayView< FRealSingle > &StiffnessMultipliers, const FSolverVec2 &InStiffness, bool bTrimKinematicConstraints, FSolverReal MaxStiffness=FPBDStiffness::DefaultPBDMaxStiffness)
Definition PBDAxialSpringConstraintsBase.h:46
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
static constexpr int32 DefaultTableSize
Definition PBDStiffness.h:26
static constexpr FSolverReal DefaultParameterFitBase
Definition PBDStiffness.h:25
Definition SoftsSolverParticlesRange.h:12
FSolverReal InvM(const int32 Index) const
Definition SoftsSolverParticlesRange.h:56
Definition PBDSoftsSolverParticles.h:20
const T InvM(const int32 Index) const
Definition DynamicParticles.h:48
Definition Vector.h:1000
Definition Constraints.Build.cs:6
Definition ArrayView.h:139
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void Reset(SizeType NewSize=0)
Definition Array.h:2246
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
UE_FORCEINLINE_HINT void Reserve(SizeType Number)
Definition Array.h:3016
Definition CollectionEmbeddedSpringConstraintFacade.cpp:6
FRealSingle FSolverReal
Definition PBDSoftsEvolutionFwd.h:31
TVector< FSolverReal, 3 > FSolverVec3
Definition PBDSoftsEvolutionFwd.h:33
int32 P[512]
Definition FieldSystemNoiseAlgo.cpp:11
U16 Index
Definition radfft.cpp:71
static constexpr UE_FORCEINLINE_HINT T Abs(const T A)
Definition GenericPlatformMath.h:949
static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
Definition UnrealMathUtility.h:592