UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PBDWeightMap.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "Chaos/Core.h"
8#include "ChaosStats.h"
9
11
12namespace Chaos::Softs
13{
14
19{
20public:
21
25 inline FPBDWeightMap(
28 int32 ParticleCount = 0, // A value of 0 also disables the map
29 int32 TableSize = 16); // Size of the lookup table, can't be more than 256 values, the larger the table the longer it takes to apply changes to the stiffness values;
30
34 template<int32 Valence>
35 inline FPBDWeightMap(
39 int32 ParticleOffset = INDEX_NONE, // Constraints have usually a particle offset added to them compared to the weight maps that always starts at index 0
40 int32 ParticleCount = 0, // A value of 0 also disables the map
41 int32 TableSize = 16, // Size of the lookup table, can't be more than 256 values, the larger the table the longer it takes to apply changes to the stiffness values
42 typename TEnableIf<Valence >= 2 && Valence <= 4>::Type* = nullptr); // Prevents incorrect valence, the value is actually unused
43
44 virtual ~FPBDWeightMap() = default;
45
46 FPBDWeightMap(const FPBDWeightMap&) = default;
50
52 int32 Num() const { return Indices.Num(); }
53
55 bool HasWeightMap() const { return Table.Num() > 1 && FMath::Abs(WeightedValue[0] - WeightedValue[1]) > UE_KINDA_SMALL_NUMBER; }
56
63
68 const FSolverVec2& GetWeightedValue() const { return WeightedValue; }
69
71 void ApplyValues(bool* bOutUpdated = nullptr) { ApplyValues([](FSolverReal Value)->FSolverReal { return Value; }, bOutUpdated); }
72
78
80 FSolverReal GetLow() const { return Table[0]; }
81
83 FSolverReal GetHigh() const { return Table.Last(); }
84
86 explicit operator FSolverReal() const { return GetLow(); }
87
89 {
90 if (HasWeightMap())
91 {
92 return (*this)[Index];
93 }
94 return GetLow();
95 }
96
99
102
105
106protected:
107 template<typename FunctorType>
108 inline void ApplyValues(FunctorType&& MappingFunction, bool* bOutUpdated = nullptr);
109
110 TArray<uint8> Indices; // Per particle/constraints array of index to the stiffness table
111 TArray<FSolverReal> Table; // Fixed lookup table of stiffness values, use uint8 indexation
113 bool bIsDirty = true; // Whether the values have changed and the table needs updating
114};
115
119 int32 ParticleCount,
120 int32 TableSize)
121 : WeightedValue(InWeightedValue)
122{
123 check(TableSize > 0 && TableSize < 256); // The Stiffness lookup table is restricted to uint8 sized indices
124
125 if (Multipliers.Num() == ParticleCount && ParticleCount > 0)
126 {
127 // Convert the weight maps into an array of lookup indices to the stiffness table
128 Indices.AddUninitialized(ParticleCount);
129
130 const FRealSingle TableScale = (FRealSingle)(TableSize - 1);
131
132 for (int32 Index = 0; Index < ParticleCount; ++Index)
133 {
135 }
136
137 // Initialize empty table until ApplyValues is called
138 Table.AddZeroed(TableSize);
139 }
140 else
141 {
142 // Initialize with a one element table until ApplyValues is called
144 Table.AddZeroed(1);
145 }
146}
147
148template<int32 Valence>
153 int32 ParticleOffset,
154 int32 ParticleCount,
155 int32 TableSize,
156 typename TEnableIf<Valence >= 2 && Valence <= 4>::Type*)
157 : WeightedValue(InWeightedValue)
158{
159 check(TableSize > 0 && TableSize < 256); // The Stiffness lookup table is restricted to uint8 sized indices
160
161 const int32 ConstraintCount = Constraints.Num();
162
163 if (Multipliers.Num() == ParticleCount && ParticleCount > 0 && ConstraintCount > 0)
164 {
165 // Convert the weight maps into an array of lookup indices to the stiffness table
167
168 const FRealSingle TableScale = (FRealSingle)(TableSize - 1);
169
170 for (int32 ConstraintIndex = 0; ConstraintIndex < ConstraintCount; ++ConstraintIndex)
171 {
172 const TVector<int32, Valence>& Constraint = Constraints[ConstraintIndex];
173
174 FRealSingle Weight = 0.f;
175 for (int32 Index = 0; Index < Valence; ++Index)
176 {
177 Weight += FMath::Clamp(Multipliers[Constraint[Index] - ParticleOffset], (FRealSingle)0., (FRealSingle)1.);
178 }
180
181 Indices[ConstraintIndex] = (uint8)(Weight * TableScale);
182 }
183
184 // Initialize empty table until ApplyValues is called
185 Table.AddZeroed(TableSize);
186 }
187 else
188 {
189 // Initialize with a one element table until ApplyValues is called
191 Table.AddZeroed(1);
192 }
193}
194
195template<typename FunctorType>
197{
199 if (bOutUpdated)
200 {
201 *bOutUpdated = true;
202 }
203 if (bIsDirty)
204 {
206 const FSolverReal Range = WeightedValue[1] - WeightedValue[0];
207 const int32 TableSize = Table.Num();
208 const FSolverReal WeightIncrement = (TableSize > 1) ? (FSolverReal)1. / (FSolverReal)(TableSize - 1) : (FSolverReal)1.; // Must allow full range from 0 to 1 included
209 for (int32 Index = 0; Index < TableSize; ++Index)
210 {
213 }
214
215 bIsDirty = false;
216 }
217}
218
237
238} // End namespace Chaos::Softs
#define check(expr)
Definition AssertionMacros.h:314
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define DECLARE_CYCLE_STAT(CounterName, StatId, GroupId)
Definition Stats.h:669
#define SCOPE_CYCLE_COUNTER(Stat)
Definition Stats.h:650
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Offset
Definition VulkanMemory.cpp:4033
uint8_t uint8
Definition binka_ue_file_header.h:8
Definition PBDWeightMap.h:19
FSolverReal GetValue(int32 Index) const
Definition PBDWeightMap.h:88
FSolverReal GetLow() const
Definition PBDWeightMap.h:80
TArray< uint8 > Indices
Definition PBDWeightMap.h:110
void ApplyValues(bool *bOutUpdated=nullptr)
Definition PBDWeightMap.h:71
FSolverReal GetHigh() const
Definition PBDWeightMap.h:83
const FSolverVec2 & GetWeightedValue() const
Definition PBDWeightMap.h:68
FPBDWeightMap(const FPBDWeightMap &)=default
virtual ~FPBDWeightMap()=default
FPBDWeightMap & operator=(const FPBDWeightMap &)=default
void SetWeightedValue(const FSolverVec2 &InWeightedValue)
Definition PBDWeightMap.h:62
bool HasWeightMap() const
Definition PBDWeightMap.h:55
FSolverReal operator[](int32 Index) const
Definition PBDWeightMap.h:77
TArray< FSolverReal > Table
Definition PBDWeightMap.h:111
FPBDWeightMap(const FSolverVec2 &InWeightedValue, const TConstArrayView< FRealSingle > &Multipliers=TConstArrayView< FRealSingle >(), int32 ParticleCount=0, int32 TableSize=16)
Definition PBDWeightMap.h:116
bool bIsDirty
Definition PBDWeightMap.h:113
FPBDWeightMap(FPBDWeightMap &&)=default
FSolverVec2 WeightedValue
Definition PBDWeightMap.h:112
int32 Num() const
Definition PBDWeightMap.h:52
TConstArrayView< FSolverReal > GetTable() const
Definition PBDWeightMap.h:101
TConstArrayView< uint8 > GetIndices() const
Definition PBDWeightMap.h:98
void ReorderIndices(const TArray< int32 > &OrigToReorderedIndices)
Definition PBDWeightMap.h:219
FPBDWeightMap & operator=(FPBDWeightMap &&)=default
Definition Constraints.Build.cs:6
Definition Array.h:670
UE_FORCEINLINE_HINT SizeType AddUninitialized()
Definition Array.h:1664
UE_REWRITE SizeType Num() const
Definition Array.h:1144
UE_NODEBUG UE_FORCEINLINE_HINT ElementType & Last(SizeType IndexFromTheEnd=0) UE_LIFETIMEBOUND
Definition Array.h:1263
SizeType AddZeroed()
Definition Array.h:2755
void SetNumUninitialized(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2369
Definition EnableIf.h:20
Definition CollectionEmbeddedSpringConstraintFacade.cpp:6
FRealSingle FSolverReal
Definition PBDSoftsEvolutionFwd.h:31
float FRealSingle
Definition Real.h:14
U16 Index
Definition radfft.cpp:71
static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
Definition UnrealMathUtility.h:592