UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SpringInterpolator.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Math/UnrealMath.h"
7#include "SpringInterpolator.generated.h"
8
24
25// Runge-Kutta order 4 integrator
27{
28 template <typename T>
29 struct FRK4State
30 {
33
35 : Position(T(0.f))
36 , Velocity(T(0.f))
37 {}
38
43 };
44
45 template <typename T>
61
62 template <typename T>
63 static T Accelerate(const FRK4State<T>& InCurrentState, const T& InTargetPosition, const FRK4SpringConstants& InSpringConstants)
64 {
65 return (InTargetPosition - InCurrentState.Position) * InSpringConstants.SpringStiffness - InCurrentState.Velocity * InSpringConstants.DampingConstant;
66 }
67
68 template <typename T>
70 {
71 FRK4State<T> NewState;
72 NewState.Position = InCurrentState.Position + InDerivativeState.Velocity * InDeltaTime;
73 NewState.Velocity = InCurrentState.Velocity + InDerivativeState.Acceleration * InDeltaTime;
74
76 NewStateDerivative.Velocity = NewState.Velocity;
77 NewStateDerivative.Acceleration = RK4Integrator::Accelerate(NewState, InTargetPosition, InSpringConstants);
78
79 return NewStateDerivative;
80 }
81
82 template <typename T>
83 static void Integrate(FRK4State<T>& InCurrentState, const T& InTargetPosition, const FRK4SpringConstants& InSpringConstants, const float& InDeltaTime)
84 {
90
91 const T Velocity = (1.0f / 6.0f) * (a.Velocity + 2.0f*(b.Velocity + c.Velocity) + d.Velocity);
92 const T Acceleration = (1.0f / 6.0f) * (a.Acceleration + 2.0f*(b.Acceleration + c.Acceleration) + d.Acceleration);
93
96 }
97}
98
101
102// Max Spring Value to prevent system from exploding and creating NaNs
103#define RK4_SPRING_INTERPOLATOR_MAX_VALUE (1e+16f)
104
105// Tweaked so Spring comes to rest in a reasonable manner.
106#define RK4_SPRING_INTERPOLATOR_POSITION_TOLERANCE 0.001f
107#define RK4_SPRING_INTERPOLATOR_VELOCITY_TOLERANCE 0.01f
108
110{
111 static inline bool IsValidValue(float Value, float MaxAbsoluteValue = RK4_SPRING_INTERPOLATOR_MAX_VALUE)
112 {
113 return FMath::Abs(Value) < MaxAbsoluteValue;
114 }
115
116 static inline bool IsValidValue(FVector Value, float MaxAbsoluteValue = RK4_SPRING_INTERPOLATOR_MAX_VALUE)
117 {
118 return Value.GetAbsMax() < MaxAbsoluteValue;
119 }
120
121 static inline bool AreEqual(float A, float B, float ErrorTolerance = UE_KINDA_SMALL_NUMBER)
122 {
123 return FMath::IsNearlyEqual(A, B, ErrorTolerance);
124 }
125
126 static inline bool AreEqual(FVector A, FVector B, float ErrorTolerance = UE_KINDA_SMALL_NUMBER)
127 {
128 return A.Equals(B, ErrorTolerance);
129 }
130}
131
132template <typename T>
134{
135protected:
138
143
146
147public:
156
163
171
173 {
174 return StiffnessConstant;
175 }
176
177 bool IsInMotion() const
178 {
179 return bIsInMotion;
180 }
181
182 T GetPosition() const
183 {
184 return State.Position;
185 }
186
188 {
189 State.Position = NewPosition;
190 }
191
192 void OffsetPosition(const T& Offset)
193 {
194 State.Position += Offset;
195 }
196
198 {
199 return (State.Position - LastPosition);
200 }
201
202 T GetVelocity() const
203 {
204 return State.Velocity;
205 }
206
207 void SetVelocity(const T& NewVelocity)
208 {
209 State.Velocity = NewVelocity;
211 }
212
213 void OffsetVelocity(const T& Offset)
214 {
215 SetVelocity(State.Velocity + Offset);
216 }
217
218 bool IsPositionEqualTo(const T& OtherPosition) const
219 {
220 return FRK4SpringInterpolatorUtils::AreEqual(GetPosition(), OtherPosition, RK4_SPRING_INTERPOLATOR_POSITION_TOLERANCE);
221 }
222
223 bool IsVelocityZero() const
224 {
225 return FRK4SpringInterpolatorUtils::AreEqual(GetVelocity(), T(0.f), RK4_SPRING_INTERPOLATOR_VELOCITY_TOLERANCE);
226 }
227
228 void Reset(const T& DefaultPosition = T(0.f))
229 {
230 State.Position = DefaultPosition;
231 State.Velocity = T(0.f);
232 bIsInMotion = false;
233 TimeRemaining = 0.f;
234 }
235
236 T Update(const T& InTargetPosition, const float& InDeltaTime)
237 {
238 if (InDeltaTime > 0.f)
239 {
240 LastPosition = State.Position;
242 if (bIsInMotion)
243 {
244 if (!bIsInitialized)
245 {
247 bIsInitialized = true;
248 }
249
250 TimeRemaining = FMath::Min(TimeRemaining + InDeltaTime, 0.1f); // hard cap at 10Hz
251
252 const float StepTime = 1.f / FMath::Max(RK4_SPRING_INTERPOLATOR_UPDATE_RATE, 1.f);
253
254 int32 NumIterations = FMath::Min(FMath::TruncToInt(TimeRemaining / StepTime), RK4_SPRING_INTERPOLATOR_MAX_ITER);
255 TimeRemaining -= float(NumIterations) * StepTime;
256
257 while (NumIterations-- > 0)
258 {
259 RK4Integrator::Integrate(State, InTargetPosition, SpringConstants, StepTime);
260 }
261
262 // See if we can take one last update to have an accurate position this frame
263 if ((TimeRemaining > 0.f) && (TimeRemaining < StepTime))
264 {
265 RK4Integrator::Integrate(State, InTargetPosition, SpringConstants, TimeRemaining);
266 TimeRemaining = 0.f;
267 }
268
270 const bool bVelocityIsZero = IsVelocityZero();
272 || !FRK4SpringInterpolatorUtils::IsValidValue(State.Velocity)
273 || !FRK4SpringInterpolatorUtils::IsValidValue(State.Position))
274 {
276 }
277 }
278 }
279
280 return State.Position;
281 }
282
283 T Update(const T& InNewPosition, const T& InTargetPosition, const float& InDeltaTime)
284 {
287 }
288};
289
291{
292private:
294
295public:
299
303};
304
306{
307private:
309
310public:
314
318};
319
320#if !CPP // begin noexport class
321
322USTRUCT(noexport, BlueprintType)
324{
325 UPROPERTY(EditAnywhere, Category = "FloatRK4SpringInterpolator")
327
329 UPROPERTY(EditAnywhere, Category = "FloatRK4SpringInterpolator")
331
336
338 RK4Integrator::FRK4State<float> State;
339};
340
341USTRUCT(noexport, BlueprintType)
343{
344 UPROPERTY(EditAnywhere, Category = "VectorRK4SpringInterpolator")
346
348 UPROPERTY(EditAnywhere, Category = "VectorRK4SpringInterpolator")
350
355
358};
359
360#endif // end noexport class
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 UPROPERTY(...)
UObject definition macros.
Definition ObjectMacros.h:744
#define USTRUCT(...)
Definition ObjectMacros.h:746
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
#define RK4_SPRING_INTERPOLATOR_VELOCITY_TOLERANCE
Definition SpringInterpolator.h:107
#define RK4_SPRING_INTERPOLATOR_POSITION_TOLERANCE
Definition SpringInterpolator.h:106
ENGINE_API float RK4_SPRING_INTERPOLATOR_UPDATE_RATE
Definition AnimInstance.cpp:97
#define RK4_SPRING_INTERPOLATOR_MAX_VALUE
Definition SpringInterpolator.h:103
ENGINE_API int32 RK4_SPRING_INTERPOLATOR_MAX_ITER
Definition AnimInstance.cpp:100
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
uint32 Offset
Definition VulkanMemory.cpp:4033
FExpressionResult Evaluate(const CharType *InExpression, const TTokenDefinitions< CharType > &InTokenDefinitions, const FExpressionGrammar &InGrammar, const TIOperatorEvaluationEnvironment< CharType > &InEnvironment)
Definition ExpressionParser.cpp:728
Definition SpringInterpolator.h:110
Definition SpringInterpolator.h:27
@ false
Definition radaudio_common.h:23
Definition SpringInterpolator.h:291
float LastPosition
Definition SpringInterpolator.h:337
FRK4SpringConstants SpringConstants
Definition SpringInterpolator.h:335
float TimeRemaining
Definition SpringInterpolator.h:334
bool bIsInMotion
Definition SpringInterpolator.h:333
FFloatRK4SpringInterpolator()
Definition SpringInterpolator.h:296
FFloatRK4SpringInterpolator(const Super &Other)
Definition SpringInterpolator.h:300
bool bIsInitialized
Definition SpringInterpolator.h:332
float StiffnessConstant
Definition SpringInterpolator.h:326
RK4Integrator::FRK4State< float > State
Definition SpringInterpolator.h:338
float DampeningRatio
Definition SpringInterpolator.h:330
static UE_FORCEINLINE_HINT bool IsNearlyEqual(float A, float B, float ErrorTolerance=UE_SMALL_NUMBER)
Definition UnrealMathUtility.h:388
Definition SpringInterpolator.h:10
FRK4SpringConstants(float InSpringStiffness, float InDampingConstant)
Definition SpringInterpolator.h:19
float SpringStiffness
Definition SpringInterpolator.h:11
float DampingConstant
Definition SpringInterpolator.h:12
FRK4SpringConstants()
Definition SpringInterpolator.h:14
Definition SpringInterpolator.h:134
float TimeRemaining
Definition SpringInterpolator.h:141
void SetVelocity(const T &NewVelocity)
Definition SpringInterpolator.h:207
bool IsPositionEqualTo(const T &OtherPosition) const
Definition SpringInterpolator.h:218
bool bIsInitialized
Definition SpringInterpolator.h:139
bool bIsInMotion
Definition SpringInterpolator.h:140
bool IsVelocityZero() const
Definition SpringInterpolator.h:223
T GetLastDeltaPosition() const
Definition SpringInterpolator.h:197
void SetDefaultSpringConstants(const float &InSpringStiffness, const float &InDampeningRatio=1.f)
Definition SpringInterpolator.h:158
T Update(const T &InTargetPosition, const float &InDeltaTime)
Definition SpringInterpolator.h:236
void OffsetPosition(const T &Offset)
Definition SpringInterpolator.h:192
T Update(const T &InNewPosition, const T &InTargetPosition, const float &InDeltaTime)
Definition SpringInterpolator.h:283
void Reset(const T &DefaultPosition=T(0.f))
Definition SpringInterpolator.h:228
T GetVelocity() const
Definition SpringInterpolator.h:202
float DampeningRatio
Definition SpringInterpolator.h:137
FRK4SpringConstants SpringConstants
Definition SpringInterpolator.h:142
void SetPosition(const T &NewPosition)
Definition SpringInterpolator.h:187
float StiffnessConstant
Definition SpringInterpolator.h:136
void SetSpringConstants(const float &InSpringStiffness, const float &InDampeningRatio=1.f)
Definition SpringInterpolator.h:165
float GetDefaultStiffnessConstant() const
Definition SpringInterpolator.h:172
bool IsInMotion() const
Definition SpringInterpolator.h:177
T GetPosition() const
Definition SpringInterpolator.h:182
FRK4SpringInterpolator(float InSpringStiffness=1.f, float InDampeningRatio=1.f)
Definition SpringInterpolator.h:148
RK4Integrator::FRK4State< T > State
Definition SpringInterpolator.h:145
T LastPosition
Definition SpringInterpolator.h:144
void OffsetVelocity(const T &Offset)
Definition SpringInterpolator.h:213
Definition SpringInterpolator.h:306
FVectorRK4SpringInterpolator(const Super &Other)
Definition SpringInterpolator.h:315
FVectorRK4SpringInterpolator()
Definition SpringInterpolator.h:311
Definition SpringInterpolator.h:47
FRK4StateDerivative(T InVelocity, T InAcceleration)
Definition SpringInterpolator.h:56
T Velocity
Definition SpringInterpolator.h:48
FRK4StateDerivative()
Definition SpringInterpolator.h:51
T Acceleration
Definition SpringInterpolator.h:49
Definition SpringInterpolator.h:30
T Position
Definition SpringInterpolator.h:31
FRK4State(T InPosition, T InVelocity)
Definition SpringInterpolator.h:39
FRK4State()
Definition SpringInterpolator.h:34
T Velocity
Definition SpringInterpolator.h:32