Files
integration/Source/Integration/ScriptedAnimation.cpp

178 lines
5.0 KiB
C++
Raw Normal View History

#include "ScriptedAnimation.h"
////////////////////////////////////////////////////////////
//
// Routines to calculate the current state of an FlxScriptedAnimation.
//
////////////////////////////////////////////////////////////
double FlxScriptedAnimation::CalculateFade(double Offset, double Fade)
{
if (Offset < 0.0)
{
return 0.0;
}
if (Fade > 0.001)
{
return FMath::Min(Offset / Fade, 1.0);
}
return 1.0;
}
double FlxScriptedAnimation::UnclampedElapsedTime(double CurrentTime) const
{
return CurrentTime - StartTime;
}
double FlxScriptedAnimation::UnclampedTimeLeft(double CurrentTime) const
{
return EndTime - CurrentTime;
}
double FlxScriptedAnimation::ClampedElapsedTime(double CurrentTime) const
{
return FMath::Max(0.0, CurrentTime - StartTime);
}
double FlxScriptedAnimation::ClampedTimeLeft(double CurrentTime) const
{
return FMath::Max(0.0, EndTime - CurrentTime);
}
double FlxScriptedAnimation::CalcFadeInAlpha(double CurrentTime) const
{
return CalculateFade(UnclampedElapsedTime(CurrentTime), FadeInDuration);
}
double FlxScriptedAnimation::CalcFadeOutAlpha(double CurrentTime) const
{
return CalculateFade(UnclampedTimeLeft(CurrentTime), FadeOutDuration);
}
double FlxScriptedAnimation::CalcFadeInOutAlpha(double CurrentTime) const
{
return FMath::Min(CalcFadeInAlpha(CurrentTime), CalcFadeOutAlpha(CurrentTime));
}
void FlxScriptedAnimation::InitiateFadeOut(double CurrentTime, double AllowedFade)
{
// We only need to truncate if we aren't already fading out,
// or if the in-progress fadeout isn't sufficiently fast.
//
double FadeOutAlpha = CalcFadeOutAlpha(CurrentTime);
if ((FadeOutAlpha >= 1.0) || (FadeOutDuration > AllowedFade))
{
double CurrentAlpha = FMath::Min(CalcFadeInAlpha(CurrentTime), FadeOutAlpha);
double NewFadeOutDuration = FMath::Min(AllowedFade, FadeOutDuration);
double NewTimeLeft = NewFadeOutDuration * CurrentAlpha;
EndTime = CurrentTime + NewTimeLeft;
FadeOutDuration = NewFadeOutDuration;
}
}
void UlxScriptedAnimations::Keep(int n)
{
if (n < 0) n = 0;
if (Animations.Num() > n)
{
Animations.SetNum(n);
}
}
void UlxScriptedAnimations::AddAnimation(
UObject* WorldContextObject, UAnimSequenceBase* Sequence, double FadeInTime, double FadeOutTime, int64 AqHash)
{
check(KeepCount >= 1);
FlxScriptedAnimation Result;
// Get World Time
UWorld* World = GEngine->GetWorldFromContextObjectChecked(WorldContextObject);
double WorldTime = World ? World->GetTimeSeconds() : 0.0;
// Get the animation Length.
double Length = (Sequence ? static_cast<double>(Sequence->GetPlayLength()) : 0.0);
// Fill the static setup fields
Result.Sequence = Sequence;
Result.AqHash = AqHash;
Result.FadeInDuration = FadeInTime;
Result.FadeOutDuration = FadeOutTime;
Result.StartTime = WorldTime;
Result.EndTime = WorldTime + Length;
Keep(KeepCount - 1);
Animations.Insert(Result, 0);
}
void UlxScriptedAnimations::FadeGarbage(TArray<int32> Hashes, double CurrentTime)
{
for (int i = 0; i < Animations.Num(); i++)
{
FlxScriptedAnimation &Anim = Animations[i];
if ((Anim.AqHash != 0) && (!Hashes.Contains(Anim.AqHash)))
{
Anim.InitiateFadeOut(CurrentTime, 0.2);
}
}
}
void UlxScriptedAnimationLibrary::ScriptedAnimationEvaluatorData(const UlxScriptedAnimations *Animations, double CurrentTime,
UAnimSequenceBase *&Sequence0, float &ExplicitTime0,
UAnimSequenceBase *&Sequence1, float &ExplicitTime1,
UAnimSequenceBase *&Sequence2, float &ExplicitTime2,
float &BaseAlpha, float &Sequence0Alpha, float &Sequence1Alpha, float &Sequence2Alpha)
{
Sequence0 = nullptr;
Sequence1 = nullptr;
Sequence2 = nullptr;
ExplicitTime0 = 0.0;
ExplicitTime1 = 0.0;
ExplicitTime2 = 0.0;
BaseAlpha = 0.0;
Sequence0Alpha = 0.0;
Sequence1Alpha = 0.0;
Sequence2Alpha = 0.0;
if (Animations != nullptr)
{
const TArray<FlxScriptedAnimation> &Anims = Animations->GetAnimations();
if (Anims.Num() > 0)
{
const FlxScriptedAnimation &Anim = Anims[0];
Sequence0 = Anim.Sequence;
ExplicitTime0 = Anim.ClampedElapsedTime(CurrentTime);
Sequence0Alpha = Anim.CalcFadeInOutAlpha(CurrentTime);
}
if (Anims.Num() > 1)
{
const FlxScriptedAnimation &Anim = Anims[1];
Sequence1 = Anim.Sequence;
ExplicitTime1 = Anim.ClampedElapsedTime(CurrentTime);
Sequence1Alpha = Anim.CalcFadeInOutAlpha(CurrentTime);
}
if (Anims.Num() > 2)
{
const FlxScriptedAnimation &Anim = Anims[2];
Sequence2 = Anim.Sequence;
ExplicitTime2 = Anim.ClampedElapsedTime(CurrentTime);
Sequence2Alpha = Anim.CalcFadeInOutAlpha(CurrentTime);
}
}
double AlphaTotal = Sequence0Alpha + Sequence1Alpha + Sequence2Alpha;
if (AlphaTotal > 1.0)
{
double Scale = 1.0 / AlphaTotal;
Sequence0Alpha *= Scale;
Sequence1Alpha *= Scale;
Sequence2Alpha *= Scale;
BaseAlpha = 0.0;
}
else
{
BaseAlpha = 1.0 - AlphaTotal;
}
}