#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(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 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 &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; } }