mirror of
https://github.com/sinbad/StevesUEHelpers.git
synced 2025-02-23 17:45:23 +00:00
Add helpful easing functions
This commit is contained in:
parent
5363b0da5a
commit
54a94ea5b1
@ -12,6 +12,7 @@ which makes a bunch of things better:
|
|||||||
* [Debug visualisation](https://www.stevestreeting.com/2021/09/14/ue4-editor-visualisation-helper/)
|
* [Debug visualisation](https://www.stevestreeting.com/2021/09/14/ue4-editor-visualisation-helper/)
|
||||||
* [Better DataTable Row References](https://www.stevestreeting.com/2023/10/06/a-better-unreal-datatable-row-picker/)
|
* [Better DataTable Row References](https://www.stevestreeting.com/2023/10/06/a-better-unreal-datatable-row-picker/)
|
||||||
* [Light Flicker](doc/LightFlicker.md)
|
* [Light Flicker](doc/LightFlicker.md)
|
||||||
|
* [Easing Functions](Source/StevesUEHelpers/Public/StevesEasings.h)
|
||||||
* [Replicated Physics Actor](Source/StevesUEHelpers/Public/StevesReplicatedPhysicsActor.h)
|
* [Replicated Physics Actor](Source/StevesUEHelpers/Public/StevesReplicatedPhysicsActor.h)
|
||||||
* Halton Sequence based random stream
|
* Halton Sequence based random stream
|
||||||
|
|
||||||
|
114
Source/StevesUEHelpers/Private/StevesEasings.cpp
Normal file
114
Source/StevesUEHelpers/Private/StevesEasings.cpp
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#include "StevesEasings.h"
|
||||||
|
|
||||||
|
float UStevesEasings::EaseAlpha(float InAlpha, EStevesEaseFunction Func)
|
||||||
|
{
|
||||||
|
constexpr float BackC1 = 1.70158f;
|
||||||
|
constexpr float BackC2 = BackC1 * 1.525f;
|
||||||
|
constexpr float BackC3 = BackC1 + 1.f;
|
||||||
|
constexpr float ElasticC4 = UE_TWO_PI / 3.f;
|
||||||
|
constexpr float ElasticC5 = UE_TWO_PI / 4.5;
|
||||||
|
|
||||||
|
switch(Func)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case EStevesEaseFunction::Linear:
|
||||||
|
return InAlpha;
|
||||||
|
case EStevesEaseFunction::EaseIn_Sine:
|
||||||
|
return 1.f - FMath::Cos(InAlpha * UE_HALF_PI);
|
||||||
|
case EStevesEaseFunction::EaseOut_Sine:
|
||||||
|
return FMath::Sin(InAlpha * UE_HALF_PI);
|
||||||
|
case EStevesEaseFunction::EaseInOut_Sine:
|
||||||
|
return -(FMath::Cos(UE_PI * InAlpha) - 1.f) / 2.f;
|
||||||
|
case EStevesEaseFunction::EaseIn_Quad:
|
||||||
|
return InAlpha*InAlpha;
|
||||||
|
case EStevesEaseFunction::EaseOut_Quad:
|
||||||
|
return 1.f - (1.f - InAlpha) * (1.f - InAlpha);
|
||||||
|
case EStevesEaseFunction::EaseInOut_Quad:
|
||||||
|
return InAlpha < 0.5f ? 2.f * InAlpha * InAlpha : 1.f - FMath::Pow(-2.f * InAlpha + 2.f, 2.f) / 2.f;
|
||||||
|
case EStevesEaseFunction::EaseIn_Cubic:
|
||||||
|
return FMath::Pow(InAlpha, 3);
|
||||||
|
case EStevesEaseFunction::EaseOut_Cubic:
|
||||||
|
return 1.f - FMath::Pow(1.f - InAlpha, 3);
|
||||||
|
case EStevesEaseFunction::EaseInOut_Cubic:
|
||||||
|
return InAlpha < 0.5f ? 4.f * FMath::Pow(InAlpha, 3) : 1.f - FMath::Pow(-2.f * InAlpha + 2.f, 3) / 2.f;
|
||||||
|
case EStevesEaseFunction::EaseIn_Quart:
|
||||||
|
return FMath::Pow(InAlpha, 4);
|
||||||
|
case EStevesEaseFunction::EaseOut_Quart:
|
||||||
|
return 1 - FMath::Pow(1.f - InAlpha, 4.f);
|
||||||
|
case EStevesEaseFunction::EaseInOut_Quart:
|
||||||
|
return InAlpha < 0.5f ? 8.f * FMath::Pow(InAlpha, 4) : 1.f - FMath::Pow(-2.f * InAlpha + 2.f, 4) / 2.f;
|
||||||
|
case EStevesEaseFunction::EaseIn_Quint:
|
||||||
|
return FMath::Pow(InAlpha, 5);
|
||||||
|
case EStevesEaseFunction::EaseOut_Quint:
|
||||||
|
return 1 - FMath::Pow(1.f - InAlpha, 5);
|
||||||
|
case EStevesEaseFunction::EaseInOut_Quint:
|
||||||
|
return InAlpha < 0.5f ? 16.f * FMath::Pow(InAlpha, 5) : 1.f - FMath::Pow(-2.f * InAlpha + 2.f, 5) / 2.f;
|
||||||
|
case EStevesEaseFunction::EaseIn_Expo:
|
||||||
|
return InAlpha <= 0 ? 0 : FMath::Pow(2.f, 10.f * InAlpha - 10.f);
|
||||||
|
case EStevesEaseFunction::EaseOut_Expo:
|
||||||
|
return InAlpha >= 1.f ? 1.f : 1.f - FMath::Pow(2.f, -10.f * InAlpha);
|
||||||
|
case EStevesEaseFunction::EaseInOut_Expo:
|
||||||
|
if (InAlpha <= 0.f)
|
||||||
|
return 0;
|
||||||
|
if (InAlpha >= 1.f)
|
||||||
|
return 1;
|
||||||
|
return InAlpha < 0.5f
|
||||||
|
? FMath::Pow(2.f, 20.f * InAlpha - 10.f) / 2.f
|
||||||
|
: (2.f - FMath::Pow(2.f, -20.f * InAlpha + 10.f)) / 2.f;
|
||||||
|
case EStevesEaseFunction::EaseIn_Circ:
|
||||||
|
return 1.f - FMath::Sqrt(1.f - FMath::Pow(InAlpha, 2));
|
||||||
|
case EStevesEaseFunction::EaseOut_Circ:
|
||||||
|
return FMath::Sqrt(1.f - FMath::Pow(InAlpha - 1.f, 2));
|
||||||
|
case EStevesEaseFunction::EaseInOut_Circ:
|
||||||
|
return InAlpha < 0.5f
|
||||||
|
? (1.f - FMath::Sqrt(1.f - FMath::Pow(2.f * InAlpha, 2))) / 2.f
|
||||||
|
: (FMath::Sqrt(1.f - FMath::Pow(-2.f * InAlpha + 2.f, 2)) + 1.f) / 2.f;
|
||||||
|
case EStevesEaseFunction::EaseIn_Back:
|
||||||
|
return BackC3 * FMath::Pow(InAlpha, 3) - BackC1 * InAlpha * InAlpha;
|
||||||
|
case EStevesEaseFunction::EaseOut_Back:
|
||||||
|
return 1.f + BackC3 * FMath::Pow(InAlpha - 1.f, 3) + BackC1 * FMath::Pow(InAlpha - 1.f, 2.f);
|
||||||
|
case EStevesEaseFunction::EaseInOut_Back:
|
||||||
|
return InAlpha < 0.5f
|
||||||
|
? (FMath::Pow(2.f * InAlpha, 2) * ((BackC2 + 1.f) * 2.f * InAlpha - BackC2)) / 2.f
|
||||||
|
: (FMath::Pow(2.f * InAlpha - 2.f, 2) * ((BackC2 + 1) * (InAlpha * 2.f - 2.f) + BackC2) + 2.f) / 2.f;
|
||||||
|
case EStevesEaseFunction::EaseIn_Elastic:
|
||||||
|
if (InAlpha <= 0.f)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (InAlpha >= 1.f)
|
||||||
|
return 1;
|
||||||
|
return -FMath::Pow(2.f, 10.f * InAlpha - 10.f) * FMath::Sin((InAlpha * 10.f - 10.75f) * ElasticC4);
|
||||||
|
case EStevesEaseFunction::EaseOut_Elastic:
|
||||||
|
if (InAlpha <= 0.f)
|
||||||
|
return 0;
|
||||||
|
if (InAlpha >= 1.f)
|
||||||
|
return 1;
|
||||||
|
return FMath::Pow(2.f, -10.f * InAlpha) * FMath::Sin((InAlpha * 10.f - 0.75f) * ElasticC4) + 1.f;
|
||||||
|
case EStevesEaseFunction::EaseInOut_Elastic:
|
||||||
|
if (InAlpha <= 0.f)
|
||||||
|
return 0;
|
||||||
|
if (InAlpha >= 1.f)
|
||||||
|
return 1;
|
||||||
|
return InAlpha < 0.5f
|
||||||
|
? -(FMath::Pow(2.f, 20.f * InAlpha - 10.f) * FMath::Sin((20.f * InAlpha - 11.125f) * ElasticC5)) /
|
||||||
|
2.f
|
||||||
|
: (FMath::Pow(2.f, -20.f * InAlpha + 10.f) * FMath::Sin((20.f * InAlpha - 11.125f) * ElasticC5)) /
|
||||||
|
2.f + 1.f;
|
||||||
|
case EStevesEaseFunction::EaseIn_Bounce:
|
||||||
|
return 1 - EaseAlpha(1 - InAlpha, EStevesEaseFunction::EaseOut_Bounce);
|
||||||
|
case EStevesEaseFunction::EaseOut_Bounce:
|
||||||
|
{
|
||||||
|
constexpr float n1 = 7.5625f;
|
||||||
|
constexpr float d1 = 2.75f;
|
||||||
|
|
||||||
|
if (InAlpha < 1.f / d1) { return n1 * InAlpha * InAlpha; }
|
||||||
|
else if (InAlpha < 2.f / d1) { return n1 * (InAlpha -= 1.5f / d1) * InAlpha + 0.75f; }
|
||||||
|
else if (InAlpha < 2.5f / d1) { return n1 * (InAlpha -= 2.25f / d1) * InAlpha + 0.9375f; }
|
||||||
|
else { return n1 * (InAlpha -= 2.625f / d1) * InAlpha + 0.984375f; }
|
||||||
|
}
|
||||||
|
case EStevesEaseFunction::EaseInOut_Bounce:
|
||||||
|
return InAlpha < 0.5f
|
||||||
|
? (1.f - EaseAlpha(1.f - 2.f * InAlpha, EStevesEaseFunction::EaseOut_Bounce)) / 2.f
|
||||||
|
: (1.f + EaseAlpha(2.f * InAlpha - 1.f, EStevesEaseFunction::EaseOut_Bounce)) / 2.f;
|
||||||
|
}
|
||||||
|
}
|
134
Source/StevesUEHelpers/Public/StevesEasings.h
Normal file
134
Source/StevesUEHelpers/Public/StevesEasings.h
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "StevesEasings.generated.h"
|
||||||
|
|
||||||
|
/// Easing functions
|
||||||
|
/// See https://easings.net/
|
||||||
|
/// Could have used UE EEasingFunc but it's missing some nice options like back/elastic
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EStevesEaseFunction : uint8
|
||||||
|
{
|
||||||
|
Linear,
|
||||||
|
EaseIn_Sine,
|
||||||
|
EaseOut_Sine,
|
||||||
|
EaseInOut_Sine,
|
||||||
|
EaseIn_Quad,
|
||||||
|
EaseOut_Quad,
|
||||||
|
EaseInOut_Quad,
|
||||||
|
EaseIn_Cubic,
|
||||||
|
EaseOut_Cubic,
|
||||||
|
EaseInOut_Cubic,
|
||||||
|
EaseIn_Quart,
|
||||||
|
EaseOut_Quart,
|
||||||
|
EaseInOut_Quart,
|
||||||
|
EaseIn_Quint,
|
||||||
|
EaseOut_Quint,
|
||||||
|
EaseInOut_Quint,
|
||||||
|
EaseIn_Expo,
|
||||||
|
EaseOut_Expo,
|
||||||
|
EaseInOut_Expo,
|
||||||
|
EaseIn_Circ,
|
||||||
|
EaseOut_Circ,
|
||||||
|
EaseInOut_Circ,
|
||||||
|
EaseIn_Back,
|
||||||
|
EaseOut_Back,
|
||||||
|
EaseInOut_Back,
|
||||||
|
EaseIn_Elastic,
|
||||||
|
EaseOut_Elastic,
|
||||||
|
EaseInOut_Elastic,
|
||||||
|
EaseIn_Bounce,
|
||||||
|
EaseOut_Bounce,
|
||||||
|
EaseInOut_Bounce
|
||||||
|
};
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class STEVESUEHELPERS_API UStevesEasings : public UBlueprintFunctionLibrary
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a linear alpha value into an eased alpha value using an easing function
|
||||||
|
* @param InAlpha The input linear alpha
|
||||||
|
* @param Func The easing function
|
||||||
|
* @return The eased version of the alpha
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category="StevesEaseMath")
|
||||||
|
static float EaseAlpha(float InAlpha, EStevesEaseFunction Func);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interpolate with easing function support
|
||||||
|
* @param A Input Value from
|
||||||
|
* @param B Input Value to
|
||||||
|
* @param Alpha Value between 0 and 1
|
||||||
|
* @param Func Easing function
|
||||||
|
* @return Interpolated value
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category="StevesEaseMath")
|
||||||
|
static float EaseFloat(float A, float B, float Alpha, EStevesEaseFunction Func)
|
||||||
|
{
|
||||||
|
return A + EaseAlpha(Alpha, Func) * (B - A);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Interpolate with easing function support
|
||||||
|
* @param A Input Value from
|
||||||
|
* @param B Input Value to
|
||||||
|
* @param Alpha Value between 0 and 1
|
||||||
|
* @param Func Easing function
|
||||||
|
* @return Interpolated value
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category="StevesEaseMath")
|
||||||
|
static FVector EaseVector(const FVector& A, const FVector& B, float Alpha, EStevesEaseFunction Func)
|
||||||
|
{
|
||||||
|
return A + EaseAlpha(Alpha, Func) * (B - A);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Interpolate with easing function support
|
||||||
|
* @param A Input Value from
|
||||||
|
* @param B Input Value to
|
||||||
|
* @param Alpha Value between 0 and 1
|
||||||
|
* @param Func Easing function
|
||||||
|
* @return Interpolated value
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category="StevesEaseMath")
|
||||||
|
static FRotator EaseRotator(const FRotator& A, const FRotator& B, float Alpha, EStevesEaseFunction Func, bool bShortest)
|
||||||
|
{
|
||||||
|
if (bShortest)
|
||||||
|
return EaseQuat(FQuat(A), FQuat(B), Alpha, Func).Rotator();
|
||||||
|
|
||||||
|
return A + EaseAlpha(Alpha, Func) * (B - A);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Interpolate with easing function support
|
||||||
|
* @param A Input Value from
|
||||||
|
* @param B Input Value to
|
||||||
|
* @param Alpha Value between 0 and 1
|
||||||
|
* @param Func Easing function
|
||||||
|
* @return Interpolated value
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category="StevesEaseMath")
|
||||||
|
static FQuat EaseQuat(const FQuat& A, const FQuat& B, float Alpha, EStevesEaseFunction Func)
|
||||||
|
{
|
||||||
|
return FQuat::Slerp(A, B, EaseAlpha(Alpha, Func));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Interpolate with easing function support
|
||||||
|
* @param A Input Value from
|
||||||
|
* @param B Input Value to
|
||||||
|
* @param Alpha Value between 0 and 1
|
||||||
|
* @param Func Easing function
|
||||||
|
* @return Interpolated value
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category="StevesEaseMath")
|
||||||
|
static FTransform EaseTransform(const FTransform& A, const FTransform& B, float Alpha, EStevesEaseFunction Func)
|
||||||
|
{
|
||||||
|
return FTransform(
|
||||||
|
EaseQuat(A.GetRotation(), B.GetRotation(), Alpha, Func),
|
||||||
|
EaseVector(A.GetLocation(), B.GetLocation(), Alpha, Func),
|
||||||
|
EaseVector(A.GetScale3D(), B.GetScale3D(), Alpha, Func));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user