Files
UnrealEngineUWP/Engine/Source/Runtime/AnimGraphRuntime/Private/AnimNodes/AnimNode_PoseHandler.cpp
Thomas Sarkanen 1dee2903c0 Added schematic view of animation graphs
Initial basic implementation, more features to follow.
Accessed via the context menu of a graph track.
Shows anim graph nodes in a linearized tree similar to ShowDebug ANIMATION.
Select a node to 'pin' all the properties that it traced (multi select supported) to the bottom of the window.
Scrub the timeline to see those properties change over time.
Asset references use clickable hyperlinks to go to the specified asset editor.

#rb Jurre.deBaare

[CL 11041140 by Thomas Sarkanen in Dev-Core branch]
2020-01-17 03:32:34 -05:00

109 lines
3.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "AnimNodes/AnimNode_PoseHandler.h"
#include "Animation/AnimInstanceProxy.h"
#include "Animation/AnimTrace.h"
/////////////////////////////////////////////////////
// FAnimPoseByNameNode
void FAnimNode_PoseHandler::Initialize_AnyThread(const FAnimationInitializeContext& Context)
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(Initialize_AnyThread)
FAnimNode_AssetPlayerBase::Initialize_AnyThread(Context);
UpdatePoseAssetProperty(Context.AnimInstanceProxy);
}
void FAnimNode_PoseHandler::CacheBones_AnyThread(const FAnimationCacheBonesContext& Context)
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(CacheBones_AnyThread)
FAnimNode_AssetPlayerBase::CacheBones_AnyThread(Context);
BoneBlendWeights.Reset();
// this has to update bone blending weight
if (CurrentPoseAsset.IsValid())
{
const UPoseAsset* CurrentAsset = CurrentPoseAsset.Get();
const TArray<FName>& TrackNames = CurrentAsset->GetTrackNames();
const FBoneContainer& BoneContainer = Context.AnimInstanceProxy->GetRequiredBones();
const TArray<FBoneIndexType>& RequiredBoneIndices = BoneContainer.GetBoneIndicesArray();
BoneBlendWeights.AddZeroed(RequiredBoneIndices.Num());
for (const auto& TrackName : TrackNames)
{
int32 MeshBoneIndex = BoneContainer.GetPoseBoneIndexForBoneName(TrackName);
FCompactPoseBoneIndex CompactBoneIndex = BoneContainer.MakeCompactPoseIndex(FMeshPoseBoneIndex(MeshBoneIndex));
if (CompactBoneIndex != INDEX_NONE)
{
BoneBlendWeights[CompactBoneIndex.GetInt()] = 1.f;
}
}
RebuildPoseList(BoneContainer, CurrentAsset);
}
else
{
PoseExtractContext.PoseCurves.Reset();
}
}
void FAnimNode_PoseHandler::RebuildPoseList(const FBoneContainer& InBoneContainer, const UPoseAsset* InPoseAsset)
{
PoseExtractContext.PoseCurves.Reset();
const TArray<FSmartName>& PoseNames = InPoseAsset->GetPoseNames();
const int32 TotalPoseNum = PoseNames.Num();
if (TotalPoseNum > 0)
{
TArray<uint16> const& LUTIndex = InBoneContainer.GetUIDToArrayLookupTable();
for (int32 PoseIndex = 0; PoseIndex < PoseNames.Num(); ++PoseIndex)
{
const FSmartName& PoseName = PoseNames[PoseIndex];
if (ensure(LUTIndex.IsValidIndex(PoseName.UID)) && LUTIndex[PoseName.UID] != MAX_uint16)
{
// we keep pose index as that is the fastest way to search when extracting pose asset
PoseExtractContext.PoseCurves.Add(FPoseCurve(PoseIndex, PoseName.UID, 0.f));
}
}
}
}
void FAnimNode_PoseHandler::UpdateAssetPlayer(const FAnimationUpdateContext& Context)
{
GetEvaluateGraphExposedInputs().Execute(Context);
// update pose asset if it's not valid
if (CurrentPoseAsset.IsValid() == false || CurrentPoseAsset.Get() != PoseAsset)
{
UpdatePoseAssetProperty(Context.AnimInstanceProxy);
}
TRACE_ANIM_NODE_VALUE(Context, TEXT("Name"), CurrentPoseAsset.IsValid() ? *CurrentPoseAsset.Get()->GetName() : TEXT("None"));
TRACE_ANIM_NODE_VALUE(Context, TEXT("Pose Asset"), CurrentPoseAsset.IsValid() ? *CurrentPoseAsset.Get()->GetName() : TEXT("None"));
}
void FAnimNode_PoseHandler::OverrideAsset(UAnimationAsset* NewAsset)
{
if(UPoseAsset* NewPoseAsset = Cast<UPoseAsset>(NewAsset))
{
PoseAsset = NewPoseAsset;
}
}
void FAnimNode_PoseHandler::GatherDebugData(FNodeDebugData& DebugData)
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(GatherDebugData)
FString DebugLine = DebugData.GetNodeName(this);
DebugLine += FString::Printf(TEXT("('%s')"), *GetNameSafe(PoseAsset));
DebugData.AddDebugItem(DebugLine, true);
}
void FAnimNode_PoseHandler::UpdatePoseAssetProperty(struct FAnimInstanceProxy* InstanceProxy)
{
CurrentPoseAsset = PoseAsset;
CacheBones_AnyThread(FAnimationCacheBonesContext(InstanceProxy));
}