Files
UnrealEngineUWP/Engine/Source/Runtime/AnimGraphRuntime/Public/AnimSequencerInstanceProxy.h
timothy daoust 7892940082 Fixes for Mirror Node
- remove optimization that can introduce bugs in circumstances with identical joint counts but diferent indexes
  - added constant folding.

#rb thomas.sarkanen
#jira UE-133136
#preflight 618e9b59c83214302dd44368

#ROBOMERGE-AUTHOR: timothy.daoust
#ROBOMERGE-SOURCE: CL 18171394 in //UE5/Release-5.0/... via CL 18179777
#ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v894-18169371)
#ROBOMERGE[STARSHIP]: UE5-Main

[CL 18179861 by timothy daoust in ue5-release-engine-test branch]
2021-11-13 12:57:14 -05:00

150 lines
5.2 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Animation/AnimInstanceProxy.h"
#include "AnimNodes/AnimNode_SequenceEvaluator.h"
#include "AnimNodes/AnimNode_ApplyAdditive.h"
#include "AnimNodes/AnimNode_MultiWayBlend.h"
#include "AnimNodes/AnimNode_PoseSnapshot.h"
#include "AnimNodes/AnimNode_Mirror.h"
#include "AnimSequencerInstanceProxy.generated.h"
/** Base class for all 'players' that can attach to and be blended into a sequencer instance's output */
struct FSequencerPlayerBase
{
public:
FSequencerPlayerBase()
: PoseIndex(INDEX_NONE)
, bAdditive(false)
{}
template<class TType>
bool IsOfType() const
{
return IsOfTypeImpl(TType::GetTypeId());
}
/** Virtual destructor. */
virtual ~FSequencerPlayerBase() { }
public:
/** Index of this players pose in the set of blend slots */
int32 PoseIndex;
/** Whether this pose is additive or not */
bool bAdditive;
protected:
/**
* Checks whether this drag and drop operation can cast safely to the specified type.
*/
virtual bool IsOfTypeImpl(const FName& Type) const
{
return false;
}
};
/** Optional Override To Specify RootMotion*/
struct FRootMotionOverride
{
FRootMotionOverride() :bBlendFirstChildOfRoot(false) {};
/** If true we use the first child of the root, if not we just use the root*/
bool bBlendFirstChildOfRoot;
FTransform RootMotion;
};
/** Quick n dirty RTTI to allow for derived classes to insert nodes of different types */
#define SEQUENCER_INSTANCE_PLAYER_TYPE(TYPE, BASE) \
static const FName& GetTypeId() { static FName Type(TEXT(#TYPE)); return Type; } \
virtual bool IsOfTypeImpl(const FName& Type) const override { return GetTypeId() == Type || BASE::IsOfTypeImpl(Type); }
/** Player type that evaluates a sequence-specified UAnimSequence */
struct FSequencerPlayerAnimSequence : public FSequencerPlayerBase
{
SEQUENCER_INSTANCE_PLAYER_TYPE(FSequencerPlayerAnimSequence, FSequencerPlayerBase)
TOptional<FRootMotionOverride> RootMotion;
FAnimNode_SequenceEvaluator_Standalone PlayerNode;
};
/** Proxy override for this UAnimInstance-derived class */
USTRUCT()
struct ANIMGRAPHRUNTIME_API FAnimSequencerInstanceProxy : public FAnimInstanceProxy
{
GENERATED_BODY()
public:
FAnimSequencerInstanceProxy()
{
}
FAnimSequencerInstanceProxy(UAnimInstance* InAnimInstance)
: FAnimInstanceProxy(InAnimInstance)
{
}
virtual ~FAnimSequencerInstanceProxy();
// FAnimInstanceProxy interface
virtual void Initialize(UAnimInstance* InAnimInstance) override;
virtual bool Evaluate(FPoseContext& Output) override;
virtual void UpdateAnimationNode(const FAnimationUpdateContext& InContext) override;
/** Update an animation sequence player in this instance */
void UpdateAnimTrack(UAnimSequenceBase* InAnimSequence, uint32 SequenceId, float InPosition, float Weight, bool bFireNotifies);
void UpdateAnimTrack(UAnimSequenceBase* InAnimSequence, uint32 SequenceId, TOptional<float> InFromPosition, float InToPosition, float Weight, bool bFireNotifies);
UE_DEPRECATED(5.0, "Please use the UpdateAnimTrackWithRootMotion that takes a MirrorDataTable")
void UpdateAnimTrackWithRootMotion(UAnimSequenceBase* InAnimSequence, int32 SequenceId, const TOptional<FRootMotionOverride>& RootMotion, float InFromPosition, float InToPosition, float Weight, bool bFireNotifies);
void UpdateAnimTrackWithRootMotion(UAnimSequenceBase* InAnimSequence, int32 SequenceId, const TOptional<FRootMotionOverride>& RootMotion, float InFromPosition, float InToPosition, float Weight, bool bFireNotifies, UMirrorDataTable* InMirrorDataTable);
/** Reset all nodes in this instance */
virtual void ResetNodes();
/** Reset the pose in this instance*/
virtual void ResetPose();
/** Construct and link the base part of the blend tree */
virtual void ConstructNodes();
protected:
void UpdateAnimTrack(UAnimSequenceBase* InAnimSequence, uint32 SequenceId, const TOptional<FRootMotionOverride>& RootMomtionOverride, TOptional<float> InFromPosition, float InToPosition, float Weight, bool bFireNotifies, UMirrorDataTable* InMirrorDataTable);
/** Find a player of a specified type */
template<typename Type>
Type* FindPlayer(uint32 SequenceId) const
{
FSequencerPlayerBase* Player = SequencerToPlayerMap.FindRef(SequenceId);
if (Player && Player->IsOfType<Type>())
{
return static_cast<Type*>(Player);
}
return nullptr;
}
/** custom root node for this sequencer player. Didn't want to use RootNode in AnimInstance because it's used with lots of AnimBP functionality */
struct FAnimNode_ApplyAdditive SequencerRootNode;
struct FAnimNode_MultiWayBlend FullBodyBlendNode;
struct FAnimNode_MultiWayBlend AdditiveBlendNode;
struct FAnimNode_PoseSnapshot SnapshotNode;
/** mapping from sequencer index to internal player index */
TMap<uint32, FSequencerPlayerBase*> SequencerToPlayerMap;
/** mapping from sequencer index to internal mirror node index */
TMap<uint32, FAnimNode_Mirror_Standalone*> SequencerToMirrorMap;
/** custom root motion override sent in from sequencer */
TOptional<FRootMotionOverride> RootMotionOverride;
void InitAnimTrack(UAnimSequenceBase* InAnimSequence, uint32 SequenceId);
void EnsureAnimTrack(UAnimSequenceBase* InAnimSequence, uint32 SequenceId);
void ClearSequencePlayerAndMirrorMaps();
};