UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
VelocityField.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
11
12namespace Chaos::Softs
13{
14
15// Velocity field used solely for aerodynamics effects, use Chaos Fields for other types of fields.
17{
18public:
21 static constexpr FSolverReal DefaultFluidDensity = (FSolverReal)1.225;
22 static constexpr FSolverReal MinCoefficient = (FSolverReal)0.; // Applies to both drag and lift
23 static constexpr FSolverReal MaxCoefficient = (FSolverReal)10.; //
26
34
57
59 const FSolverParticlesRange& Particles,
60 const FTriangleMesh* TriangleMesh,
63 FSolverReal WorldScale)
65 , OuterLift(GetWeightedFloatOuterLift(PropertyCollection, FSolverVec2(Lift.GetLow(), Lift.GetHigh())).ClampAxes(MinCoefficient, MaxCoefficient))
67 , OuterDrag(GetWeightedFloatOuterDrag(PropertyCollection, FSolverVec2(Drag.GetLow(), Drag.GetHigh())).ClampAxes(MinCoefficient, MaxCoefficient))
70 , QuarterRho(Rho* (FSolverReal)0.25f)
81 {
82 SetGeometry(Particles, TriangleMesh);
83 SetMultipliers(PropertyCollection, Weightmaps);
84 InitColor(Particles);
85 }
86
87 // Construct an uninitialized field. Mesh, properties, and velocity will have to be set for this field to be valid.
89 : Offset(INDEX_NONE)
90 , NumParticles(0)
91 , Lift(FSolverVec2(0.))
92 , OuterLift(FSolverVec2(0.))
93 , Drag(FSolverVec2(0.))
94 , OuterDrag(FSolverVec2(0.))
95 , Pressure(FSolverVec2(0.))
96 , Rho((FSolverReal)0.)
97 , QuarterRho(Rho* (FSolverReal)0.25f)
98 , TurbulenceRatio(DefaultTurbulenceRatio)
108 {
109 }
110
112
114
115 inline void Apply(FSolverParticles& InParticles, const FSolverReal Dt, const int32 Index) const
116 {
117 checkSlow(Index >= Offset && Index < Offset + NumParticles); // The index should always match the original triangle mesh range
118
119 const TArray<int32>& ElementIndices = PointToTriangleMap[Index];
120 for (const int32 ElementIndex : ElementIndices)
121 {
122 InParticles.Acceleration(Index) += InParticles.InvM(Index) * Forces[ElementIndex];
123 }
124 }
125
127
128 // This version will not load WindVelocity from the config. Call SetVelocity to set it explicitly.
132 FSolverReal WorldScale,
134
135 // This version will load WindVelocity from the config
136 // Provide LocalSpaceRotation and/or ReferenceSpaceRotation to convert WindVelocity to solver space based on WindVelocitySpace
140 FSolverReal WorldScale,
142 const FSolverVec3& SolverWind,
143 const FRotation3& LocalSpaceRotation = FRotation3::Identity,
144 const FRotation3& ReferenceSpaceRotation = FRotation3::Identity);
145
147 const FSolverVec2& Drag,
148 const FSolverVec2& OuterDrag,
149 const FSolverVec2& Lift,
150 const FSolverVec2& OuterLift,
152 const FSolverVec2& Pressure = FSolverVec2::ZeroVector,
153 FSolverReal WorldScale = 1.f);
154
155 bool IsActive() const
156 {
157 return Pressure.GetLow() != (FSolverReal)0. || Pressure.GetHigh() != (FSolverReal)0. ||
158 (AreAerodynamicsEnabled() && (
159 Drag.GetLow() > (FSolverReal)0. || Drag.GetOffsetRange()[1] != (FSolverReal)0. || // Note: range can be a negative value (although not when Lift or Drag base is zero)
160 OuterDrag.GetLow() > (FSolverReal)0. || OuterDrag.GetOffsetRange()[1] != (FSolverReal)0. ||
161 Lift.GetLow() > (FSolverReal)0. || Lift.GetOffsetRange()[1] != (FSolverReal)0. ||
162 OuterLift.GetLow() > (FSolverReal)0. || OuterLift.GetOffsetRange()[1] != (FSolverReal)0.));
163 }
164
166 const FTriangleMesh* TriangleMesh,
169 FSolverReal WorldScale);
170
172 const FTriangleMesh* TriangleMesh,
178
179 UE_DEPRECATED(5.5, "Use SetGeometry with OuterDrag and OuterLift multipliers")
188
189 void SetVelocity(const FSolverVec3& InVelocity) { Velocity = InVelocity; }
190
191 const FSolverVec3& GetVelocity() const { return Velocity; }
192
195
196 // This method is currently used for debug drawing.
198
208
209private:
210 bool AreAerodynamicsEnabled() const { return QuarterRho > (FSolverReal)0.; }
211
212 CHAOS_API void InitColor(const FSolverParticlesRange& InParticles);
213 CHAOS_API void ResetColor(); // Used when setting geometry without Particles
214
215 CHAOS_API void SetGeometry(const FSolverParticlesRange& Particles, const FTriangleMesh* TriangleMesh);
216 CHAOS_API void SetGeometry(const FTriangleMesh* TriangleMesh);
217
219
220 CHAOS_API void SetMultipliers(
226
227
229 {
230 const TVec3<int32>& Element = Elements[ElementIndex];
231
232 // Calculate the normal and the area of the surface exposed to the flow
233 FSolverVec3 N = FSolverVec3::CrossProduct(
234 Xs[Element[2]] - Xs[Element[0]],
235 Xs[Element[1]] - Xs[Element[0]]);
236 const FSolverReal DoubleArea = N.SafeNormalize();
237
238 // Calculate the direction and the relative velocity of the triangle to the flow
239 const FSolverVec3& SurfaceVelocity = (FSolverReal)(1. / 3.) * (
240 Vs[Element[0]] +
241 Vs[Element[1]] +
242 Vs[Element[2]]);
244
245 // Set the aerodynamic forces
246 const FSolverReal VDotN = FSolverVec3::DotProduct(V, N);
247 const FSolverReal VSquare = FSolverVec3::DotProduct(V, V);
248
249 const FSolverReal TurbulenceFactor = VSquare > UE_SMALL_NUMBER ? ((1.f - TurbulenceRatio) / FMath::Sqrt(VSquare) + TurbulenceRatio) : 1.f;
250
251 return QuarterRho * DoubleArea * TurbulenceFactor * (VDotN >= (FSolverReal)0. ? // The flow can hit either side of the triangle, so the normal might need to be reversed
252 (CdI - ClI) * VDotN * V + ClI * VSquare * N :
253 (ClO - CdO) * VDotN * V - ClO * VSquare * N) + DoubleArea * (FSolverReal)0.5 * Cp * N;
254 }
255
256 void UpdateField(const FSolverParticles& InParticles, int32 ElementIndex, const FSolverVec3& InVelocity, const FSolverReal CdI, const FSolverReal CdO, const FSolverReal ClI, const FSolverReal ClO, const FSolverReal Cp)
257 {
258 Forces[ElementIndex] = CalculateForce(TConstArrayView<FSolverVec3>(InParticles.XArray()), TConstArrayView<FSolverVec3>(InParticles.GetV()), ElementIndex, InVelocity, CdI, CdO, ClI, ClO, Cp);
259 }
260
262 {
264
265 const TVec3<int32>& Element = Elements[ElementIndex];
266
267 // Calculate the normal and the area of the surface exposed to the flow
268 FSolverVec3 N = FSolverVec3::CrossProduct(
269 Xs[Element[2]] - Xs[Element[0]],
270 Xs[Element[1]] - Xs[Element[0]]);
271 const FSolverReal DoubleArea = N.SafeNormalize();
272
273 // Calculate the direction and the relative velocity of the triangle to the flow
274 const FSolverVec3& SurfaceVelocity = (FSolverReal)(1. / 3.) * (
275 Vs[Element[0]] +
276 Vs[Element[1]] +
277 Vs[Element[2]]);
279
280 // Clamp the velocity
281 const FSolverReal RelVelocitySquared = V.SquaredLength();
283 {
284 V *= FMath::Sqrt(MaxVelocitySquared / RelVelocitySquared);
285 }
286
287 // Set the aerodynamic forces
288 const FSolverReal VDotN = FSolverVec3::DotProduct(V, N);
289 const FSolverReal VSquare = FSolverVec3::DotProduct(V, V);
290 const FSolverReal TurbulenceFactor = VSquare > UE_SMALL_NUMBER ? ((1.f - TurbulenceRatio) / FMath::Sqrt(VSquare) + TurbulenceRatio) : 1.f;
291
292 return QuarterRho * DoubleArea * TurbulenceFactor * (VDotN >= (FSolverReal)0. ? // The flow can hit either side of the triangle, so the normal might need to be reversed
293 (CdI - ClI) * VDotN * V + ClI * VSquare * N :
294 (ClO - CdO) * VDotN * V - ClO * VSquare * N) + DoubleArea * (FSolverReal)0.5 * Cp * N;
295 }
296
297 void UpdateField(const FSolverParticles& InParticles, int32 ElementIndex, const FSolverVec3& InVelocity, const FSolverReal CdI, const FSolverReal CdO, const FSolverReal ClI, const FSolverReal ClO, const FSolverReal Cp, const FSolverReal MaxVelocitySquared)
298 {
300 }
301
302private:
303 int32 Offset;
304 int32 NumParticles;
305 TConstArrayView<TArray<int32>> PointToTriangleMap; // Points use global indexing. May point to PointToTriangleMapLocal or data in the original FTriangleMesh
306 TConstArrayView<TVec3<int32>> Elements; // May point to ElementsLocal or data in the original FTriangleMesh
307 TArray<TArray<int32>> PointToTriangleMapLocal; // Points use local indexing. Only used with ElementsLocal.
308 TArray<TVec3<int32>> ElementsLocal; // Local copy of the triangle mesh's elements. Kinematic faces have been removed, and may be reordered by coloring.
309 TArray<int32> ConstraintsPerColorStartIndex; // Constraints are ordered so each batch is contiguous. This is ColorNum + 1 length so it can be used as start and end.
310 FPBDFlatWeightMap Lift;
311 FPBDFlatWeightMap OuterLift;
312 FPBDFlatWeightMap Drag;
313 FPBDFlatWeightMap OuterDrag;
314 FPBDFlatWeightMap Pressure;
315
316 TArray<FSolverVec3> Forces;
317 FSolverVec3 Velocity;
318 FSolverReal Rho;
319 FSolverReal QuarterRho;
320 FSolverReal TurbulenceRatio = 1.f;
321
331};
332
333} // End namespace Chaos::Softs
334
335#if !defined(CHAOS_VELOCITY_FIELD_ISPC_ENABLED_DEFAULT)
336#define CHAOS_VELOCITY_FIELD_ISPC_ENABLED_DEFAULT 1
337#endif
338
339#if !defined(USE_ISPC_KERNEL_CONSOLE_VARIABLES_IN_SHIPPING)
340#define USE_ISPC_KERNEL_CONSOLE_VARIABLES_IN_SHIPPING 0
341#endif
342
343// Support run-time toggling on supported platforms in non-shipping configurations
344#if !INTEL_ISPC || (UE_BUILD_SHIPPING && !USE_ISPC_KERNEL_CONSOLE_VARIABLES_IN_SHIPPING)
345static constexpr bool bChaos_VelocityField_ISPC_Enabled = INTEL_ISPC && CHAOS_VELOCITY_FIELD_ISPC_ENABLED_DEFAULT;
346#else
347extern CHAOS_API bool bChaos_VelocityField_ISPC_Enabled;
348#endif
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define UE_CHAOS_DECLARE_INDEXED_PROPERTYCOLLECTION_NAME(PropertyName, Type)
Definition CollectionPropertyFacade.h:893
@ INDEX_NONE
Definition CoreMiscDefines.h:150
@ ForceInit
Definition CoreMiscDefines.h:155
#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
EChaosSoftsSimulationSpace
Definition SoftsSimulationSpace.h:9
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
#define CHAOS_VELOCITY_FIELD_ISPC_ENABLED_DEFAULT
Definition VelocityField.h:336
Definition TriangleMesh.h:24
Definition CollectionPropertyFacade.h:49
FSolverReal GetHigh() const
Definition PBDFlatWeightMap.h:159
FSolverReal GetLow() const
Definition PBDFlatWeightMap.h:156
const FSolverVec2 & GetOffsetRange() const
Definition PBDFlatWeightMap.h:147
Definition SoftsSolverParticlesRange.h:12
Definition PBDSoftsSolverParticles.h:20
Definition VelocityField.h:17
UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(Lift, float)
static constexpr FSolverReal DefaultTurbulenceRatio
Definition VelocityField.h:25
static constexpr EChaosSoftsSimulationSpace DefaultWindVelocitySpace
Definition VelocityField.h:24
CHAOS_API void UpdateForces(const FSolverParticles &InParticles, const FSolverReal)
Definition VelocityField.cpp:427
UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(OuterLift, float)
UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(WindVelocity, FVector3f)
static constexpr FSolverReal DefaultFluidDensity
Definition VelocityField.h:21
UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(WindVelocitySpace, int32)
TConstArrayView< FSolverVec3 > GetForces() const
Definition VelocityField.h:194
static constexpr FSolverReal DefaultDragCoefficient
Definition VelocityField.h:19
const FSolverVec3 & GetVelocity() const
Definition VelocityField.h:191
UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(Drag, float)
bool IsActive() const
Definition VelocityField.h:155
static constexpr FSolverReal MinCoefficient
Definition VelocityField.h:22
FVelocityAndPressureField(const FSolverParticlesRange &Particles, const FTriangleMesh *TriangleMesh, const FCollectionPropertyConstFacade &PropertyCollection, const TMap< FString, TConstArrayView< FRealSingle > > &Weightmaps, FSolverReal WorldScale)
Definition VelocityField.h:58
void SetVelocity(const FSolverVec3 &InVelocity)
Definition VelocityField.h:189
UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(Pressure, float)
TConstArrayView< TVector< int32, 3 > > GetElements() const
Definition VelocityField.h:193
UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(TurbulenceRatio, float)
CHAOS_API FSolverVec3 CalculateForce(const TConstArrayView< FSolverVec3 > &Xs, const TConstArrayView< FSolverVec3 > &Vs, int32 ElementIndex) const
Definition VelocityField.cpp:415
void Apply(FSolverParticles &InParticles, const FSolverReal Dt, const int32 Index) const
Definition VelocityField.h:115
FVelocityAndPressureField(const FCollectionPropertyConstFacade &PropertyCollection)
Definition VelocityField.h:35
static bool IsEnabled(const FCollectionPropertyConstFacade &PropertyCollection)
Definition VelocityField.h:27
CHAOS_API void SetGeometry(const FTriangleMesh *TriangleMesh, const FCollectionPropertyConstFacade &PropertyCollection, const TMap< FString, TConstArrayView< FRealSingle > > &Weightmaps, FSolverReal WorldScale)
Definition VelocityField.cpp:217
~FVelocityAndPressureField()
Definition VelocityField.h:111
CHAOS_API void SetPropertiesAndWind(const FCollectionPropertyConstFacade &PropertyCollection, const TMap< FString, TConstArrayView< FRealSingle > > &Weightmaps, FSolverReal WorldScale, bool bEnableAerodynamics, const FSolverVec3 &SolverWind, const FRotation3 &LocalSpaceRotation=FRotation3::Identity, const FRotation3 &ReferenceSpaceRotation=FRotation3::Identity)
Definition VelocityField.cpp:169
UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(OuterDrag, float)
static constexpr FSolverReal MaxCoefficient
Definition VelocityField.h:23
FVelocityAndPressureField()
Definition VelocityField.h:88
static constexpr FSolverReal DefaultLiftCoefficient
Definition VelocityField.h:20
CHAOS_API void SetProperties(const FCollectionPropertyConstFacade &PropertyCollection, const TMap< FString, TConstArrayView< FRealSingle > > &Weightmaps, FSolverReal WorldScale, bool bEnableAerodynamics)
Definition VelocityField.cpp:27
UE_CHAOS_DECLARE_INDEXLESS_PROPERTYCOLLECTION_NAME(FluidDensity, float)
Definition Vector.h:1000
Definition Array.h:670
Definition UnrealString.h.inl:34
Definition CollectionEmbeddedSpringConstraintFacade.cpp:6
FRealSingle FSolverReal
Definition PBDSoftsEvolutionFwd.h:31
TVector< FSolverReal, 3 > FSolverVec3
Definition PBDSoftsEvolutionFwd.h:33
FRealSingle FSolverReal
Definition SolverBody.h:38
float FRealSingle
Definition Real.h:14
U16 Index
Definition radfft.cpp:71
Definition UnrealMathUtility.h:270