Files
UnrealEngineUWP/Engine/Source/Runtime/AnimGraphRuntime/Private/SequenceEvaluatorLibrary.cpp
aaron cox e3f123688b Animation Locomotion Library: Common techniques for driving locomotion based character animation.
Included features in this changelist:
 * Capture a snapshot of common movement properties (velocity, speed, etc) that are used to drive animation
 * Character movement component for stop/pivot location
 * Library of anim node functions for Distance Matching
 * Template anim node that can advance by distance traveled rather than by time
 * Template anim node that's driven by distance to a target rather than by time
 * Animation modifier that generates distance curves based on root motion
 * Turn in place functionality for keeping the capsule from spinning the pose when it rotates by applying an offset, includes functionality for turn on spot animations to compenstate for the offset

#preflight 61446e46599fd80001c250e2
[at]Koray.Hagen, [at]Thomas.Sarkanen, [at]Fernando.Coello
[FYI] Laurent.Delayen

#ROBOMERGE-AUTHOR: aaron.cox
#ROBOMERGE-SOURCE: CL 17551436 in //UE5/Main/...
#ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v870-17433530)

[CL 17551464 by aaron cox in ue5-release-engine-test branch]
2021-09-17 09:44:41 -04:00

102 lines
4.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "SequenceEvaluatorLibrary.h"
#include "Animation/AnimNode_Inertialization.h"
#include "AnimNodes/AnimNode_SequenceEvaluator.h"
DEFINE_LOG_CATEGORY_STATIC(LogSequenceEvaluatorLibrary, Verbose, All);
FSequenceEvaluatorReference USequenceEvaluatorLibrary::ConvertToSequenceEvaluator(const FAnimNodeReference& Node, EAnimNodeReferenceConversionResult& Result)
{
return FAnimNodeReference::ConvertToType<FSequenceEvaluatorReference>(Node, Result);
}
FSequenceEvaluatorReference USequenceEvaluatorLibrary::SetExplicitTime(const FSequenceEvaluatorReference& SequenceEvaluator, float Time)
{
SequenceEvaluator.CallAnimNodeFunction<FAnimNode_SequenceEvaluator>(
TEXT("SetExplicitTime"),
[Time](FAnimNode_SequenceEvaluator& InSequenceEvaluator)
{
if(!InSequenceEvaluator.SetExplicitTime(Time))
{
UE_LOG(LogSequenceEvaluatorLibrary, Warning, TEXT("Could not set explicit time on sequence evaluator, value is not dynamic. Set it as Always Dynamic."));
}
});
return SequenceEvaluator;
}
FSequenceEvaluatorReference USequenceEvaluatorLibrary::AdvanceTime(const FAnimUpdateContext& UpdateContext, const FSequenceEvaluatorReference& SequenceEvaluator, float PlayRate)
{
SequenceEvaluator.CallAnimNodeFunction<FAnimNode_SequenceEvaluator>(
TEXT("AdvanceTime"),
[&UpdateContext, PlayRate](FAnimNode_SequenceEvaluator& InSequenceEvaluator)
{
if (const FAnimationUpdateContext* AnimationUpdateContext = UpdateContext.GetContext())
{
float ExplicitTime = InSequenceEvaluator.GetExplicitTime();
FAnimationRuntime::AdvanceTime(InSequenceEvaluator.GetShouldLoop(), AnimationUpdateContext->GetDeltaTime() * PlayRate, ExplicitTime, InSequenceEvaluator.GetCurrentAssetLength());
if (!InSequenceEvaluator.SetExplicitTime(ExplicitTime))
{
UE_LOG(LogSequenceEvaluatorLibrary, Warning, TEXT("Could not advance time on sequence evaluator, ExplicitTime is not dynamic. Set it as Always Dynamic."));
}
}
else
{
UE_LOG(LogSequenceEvaluatorLibrary, Warning, TEXT("AdvanceTime called with invalid context"));
}
});
return SequenceEvaluator;
}
FSequenceEvaluatorReference USequenceEvaluatorLibrary::SetSequence(const FSequenceEvaluatorReference& SequenceEvaluator, UAnimSequenceBase* Sequence)
{
SequenceEvaluator.CallAnimNodeFunction<FAnimNode_SequenceEvaluator>(
TEXT("SetSequence"),
[Sequence](FAnimNode_SequenceEvaluator& InSequenceEvaluator)
{
if(!InSequenceEvaluator.SetSequence(Sequence))
{
UE_LOG(LogSequenceEvaluatorLibrary, Warning, TEXT("Could not set sequence on sequence evaluator, value is not dynamic. Set it as Always Dynamic."));
}
});
return SequenceEvaluator;
}
FSequenceEvaluatorReference USequenceEvaluatorLibrary::SetSequenceWithInertialBlending(const FAnimUpdateContext& UpdateContext, const FSequenceEvaluatorReference& SequenceEvaluator, UAnimSequenceBase* Sequence, float BlendTime)
{
SequenceEvaluator.CallAnimNodeFunction<FAnimNode_SequenceEvaluator>(
TEXT("SetSequenceWithInterialBlending"),
[Sequence, &UpdateContext, BlendTime](FAnimNode_SequenceEvaluator& InSequenceEvaluator)
{
const UAnimSequenceBase* CurrentSequence = InSequenceEvaluator.GetSequence();
const bool bAnimSequenceChanged = (CurrentSequence != Sequence);
if(!InSequenceEvaluator.SetSequence(Sequence))
{
UE_LOG(LogSequenceEvaluatorLibrary, Warning, TEXT("Could not set sequence on sequence evaluator, value is not dynamic. Set it as Always Dynamic."));
}
if(bAnimSequenceChanged && BlendTime > 0.0f)
{
if (const FAnimationUpdateContext* AnimationUpdateContext = UpdateContext.GetContext())
{
if (UE::Anim::IInertializationRequester* InertializationRequester = AnimationUpdateContext->GetMessage<UE::Anim::IInertializationRequester>())
{
InertializationRequester->RequestInertialization(BlendTime);
}
}
else
{
UE_LOG(LogSequenceEvaluatorLibrary, Warning, TEXT("SetSequenceWithInterialBlending called with invalid context"));
}
}
});
return SequenceEvaluator;
}