Files
UnrealEngineUWP/Engine/Plugins/Animation/AnimationWarping/Source/Runtime/Private/AnimationWarpingRuntimeModule.cpp

75 lines
3.1 KiB
C++
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#include "AnimationWarpingRuntimeModule.h"
#include "Animation/AnimRootMotionProvider.h"
#include "Animation/AnimNodeBase.h"
#include "Animation/AnimSequence.h"
#include "Animation/BuiltInAttributeTypes.h"
#include "Modules/ModuleManager.h"
class FAnimationWarpingRuntimeModule : public IAnimationWarpingRuntimeModule
{
};
namespace UE { namespace AnimationWarping {
// Root motion animation attribute data will always be accessible on the root bone's attribute container
static const UE::Anim::FAttributeId RootMotionAttributeId = { UE::Anim::IAnimRootMotionProvider::AttributeName , FCompactPoseBoneIndex(0) };
class FModule : public IModuleInterface, public UE::Anim::IAnimRootMotionProvider
{
public:
virtual void StartupModule() override;
virtual void ShutdownModule() override;
public:
virtual void SampleRootMotion(const FDeltaTimeRecord& SampleRange, const UAnimSequence& Sequence, bool bLoopingSequence, UE::Anim::FStackAttributeContainer& OutAttributes) const override;
virtual bool OverrideRootMotion(const FTransform& RootMotionDelta, UE::Anim::FStackAttributeContainer& OutAttributes) const override;
virtual bool ExtractRootMotion(const UE::Anim::FStackAttributeContainer& Attributes, FTransform& OutRootMotionDelta) const override;
virtual bool HasRootMotion(const UE::Anim::FStackAttributeContainer& Attributes) const override;
};
void FModule::StartupModule()
{
IModularFeatures::Get().RegisterModularFeature(UE::Anim::IAnimRootMotionProvider::ModularFeatureName, this);
}
void FModule::ShutdownModule()
{
IModularFeatures::Get().UnregisterModularFeature(UE::Anim::IAnimRootMotionProvider::ModularFeatureName, this);
}
void FModule::SampleRootMotion(const FDeltaTimeRecord& SampleRange, const UAnimSequence& Sequence, bool bLoopingSequence, UE::Anim::FStackAttributeContainer& OutAttributes) const
{
const FTransform RootMotionTransform = Sequence.ExtractRootMotion(SampleRange.GetPrevious(), SampleRange.Delta, bLoopingSequence);
PoseSearch: Distance-based trajectory indexing - Added support for distanced based trajectory indexing. This feature uses distance offsets to mark where samples are taken, rather than the usual time offsets. - Refactored sampling and indexing process. Previously, poses and root motion were extracted at the known fixed sampling rate, then the indexing process looked up sampled data based on integer offsets. Now the indexing process extracts poses and root motion at time offsets directly from the source data. This made distance sampling simpler to implement, improves the accuracy of velocity sampling, and paves the way for acceleration sampling. - Velocity and acceleration sampling are implemented as symmetric difference quotients. This means for every sample at time t, we also take samples at t-h and t+h. So three pose and root motion extractions are taken at each sample. - Fixed subtle off-by-one sample bugs. Previously the sampling pre-process phase did not guarantee that the end of a clip would be sampled. Now this is guaranteed and index to time conversions clamp to play length. - Fixed bug where a zero trajectory time offset would cause the motion matching goal to not be filled with the current root motion properties. - Fixed normalization divide by zero bug when the variance of a feature is zero. - Fixed pose matching not using normalized search queries. - Added motion matching debug vis options to view goal and match separately. #rb koray.hagen, aaron.cox, jon.bourim #preflight 60b053678bf2eb0001c26dc2 #jira none [CL 16497916 by braeden shosa in ue5-main branch]
2021-05-27 23:25:04 -04:00
FTransformAnimationAttribute* RootMotionAttribute = OutAttributes.FindOrAdd<FTransformAnimationAttribute>(RootMotionAttributeId);
RootMotionAttribute->Value = RootMotionTransform;
}
bool FModule::OverrideRootMotion(const FTransform& RootMotionDelta, UE::Anim::FStackAttributeContainer& OutAttributes) const
{
if (FTransformAnimationAttribute* RootMotionAttribute = OutAttributes.Find<FTransformAnimationAttribute>(RootMotionAttributeId))
{
RootMotionAttribute->Value = RootMotionDelta;
return true;
}
return false;
}
bool FModule::ExtractRootMotion(const UE::Anim::FStackAttributeContainer& Attributes, FTransform& OutRootMotionDelta) const
{
const FTransformAnimationAttribute* RootMotionAttribute = Attributes.Find<FTransformAnimationAttribute>(RootMotionAttributeId);
OutRootMotionDelta = RootMotionAttribute ? RootMotionAttribute->Value : FTransform::Identity;
return !!RootMotionAttribute;
}
bool FModule::HasRootMotion(const UE::Anim::FStackAttributeContainer& Attributes) const
{
return !!Attributes.Find<FTransformAnimationAttribute>(RootMotionAttributeId);
}
}}
IMPLEMENT_MODULE(UE::AnimationWarping::FModule, AnimationWarpingRuntime)