58 lines
1.9 KiB
C++
58 lines
1.9 KiB
C++
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
|
#include "GMS_Math.generated.h"
|
|
|
|
UCLASS(Meta = (BlueprintThreadSafe))
|
|
class GENERICMOVEMENTSYSTEM_API UGMS_Math : public UBlueprintFunctionLibrary
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
static constexpr auto Ln2{0.6931471805599453f}; // FMath::Loge(2.0f).
|
|
|
|
public:
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "GMS|Math Utility", Meta = (ReturnDisplayName = "Value"))
|
|
static float Clamp01(float Value);
|
|
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "GMS|Math Utility", Meta = (ReturnDisplayName = "Value"))
|
|
static float LerpClamped(float From, float To, float Ratio);
|
|
|
|
//Output the frame-rate stable alpha used for smoothly lerp current to target.
|
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "GMS|Math Utility", Meta = (ReturnDisplayName = "Alpha"))
|
|
static float DamperExactAlpha(float DeltaTime, float HalfLife);
|
|
|
|
// HalfLife is the time it takes for the distance to the target to be reduced by half.
|
|
template <typename ValueType>
|
|
static ValueType DamperExact(const ValueType& Current, const ValueType& Target, float DeltaTime, float HalfLife);
|
|
};
|
|
|
|
inline float UGMS_Math::Clamp01(const float Value)
|
|
{
|
|
return Value > 0.0f
|
|
? Value < 1.0f
|
|
? Value
|
|
: 1.0f
|
|
: 0.0f;
|
|
}
|
|
|
|
inline float UGMS_Math::LerpClamped(const float From, const float To, const float Ratio)
|
|
{
|
|
return From + (To - From) * Clamp01(Ratio);
|
|
}
|
|
|
|
inline float UGMS_Math::DamperExactAlpha(const float DeltaTime, const float HalfLife)
|
|
{
|
|
// https://theorangeduck.com/page/spring-roll-call#exactdamper
|
|
|
|
return 1.0f - FMath::InvExpApprox(Ln2 / (HalfLife + UE_SMALL_NUMBER) * DeltaTime);
|
|
}
|
|
|
|
template <typename ValueType>
|
|
ValueType UGMS_Math::DamperExact(const ValueType& Current, const ValueType& Target, const float DeltaTime, const float HalfLife)
|
|
{
|
|
return FMath::Lerp(Current, Target, DamperExactAlpha(DeltaTime, HalfLife));
|
|
}
|