Files
UnrealEngineUWP/Engine/Source/Runtime/AnimGraphRuntime/Private/AnimNodes/AnimNode_CopyPoseFromMesh.cpp
Ben Marsh 20bf0eb6a1 Updating copyright notices to 2017 (copying from //Tasks/UE4/Dev-Copyright-2017).
#rb none
#lockdown Nick.Penwarden

[CL 3226823 by Ben Marsh in Main branch]
2016-12-08 08:52:44 -05:00

107 lines
3.8 KiB
C++

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "AnimNodes/AnimNode_CopyPoseFromMesh.h"
#include "Animation/AnimInstanceProxy.h"
/////////////////////////////////////////////////////
// FAnimNode_CopyPoseFromMesh
FAnimNode_CopyPoseFromMesh::FAnimNode_CopyPoseFromMesh()
{
}
void FAnimNode_CopyPoseFromMesh::Initialize(const FAnimationInitializeContext& Context)
{
FAnimNode_Base::Initialize(Context);
ReinitializeMeshComponent(Context.AnimInstanceProxy);
}
void FAnimNode_CopyPoseFromMesh::CacheBones(const FAnimationCacheBonesContext& Context)
{
}
void FAnimNode_CopyPoseFromMesh::Update(const FAnimationUpdateContext& Context)
{
EvaluateGraphExposedInputs.Execute(Context);
if (CurrentlyUsedSourceMeshComponent.IsValid() && CurrentlyUsedSourceMeshComponent.Get() != SourceMeshComponent)
{
ReinitializeMeshComponent(Context.AnimInstanceProxy);
}
else if (!CurrentlyUsedSourceMeshComponent.IsValid() && SourceMeshComponent)
{
ReinitializeMeshComponent(Context.AnimInstanceProxy);
}
}
void FAnimNode_CopyPoseFromMesh::Evaluate(FPoseContext& Output)
{
FCompactPose& OutPose = Output.Pose;
OutPose.ResetToRefPose();
USkeletalMeshComponent* CurrentMeshComponent = CurrentlyUsedSourceMeshComponent.IsValid()? CurrentlyUsedSourceMeshComponent.Get() : nullptr;
if (CurrentMeshComponent && CurrentMeshComponent->SkeletalMesh && CurrentMeshComponent->IsRegistered())
{
const FBoneContainer& RequiredBones = OutPose.GetBoneContainer();
for(FCompactPoseBoneIndex PoseBoneIndex : OutPose.ForEachBoneIndex())
{
const int32& SkeletonBoneIndex = RequiredBones.GetSkeletonIndex(PoseBoneIndex);
const int32& MeshBoneIndex = RequiredBones.GetSkeletonToPoseBoneIndexArray()[SkeletonBoneIndex];
const int32* Value = BoneMapToSource.Find(MeshBoneIndex);
if(Value && *Value!=INDEX_NONE)
{
const int32 SourceBoneIndex = *Value;
const int32 ParentIndex = CurrentMeshComponent->SkeletalMesh->RefSkeleton.GetParentIndex(SourceBoneIndex);
const FCompactPoseBoneIndex MyParentIndex = RequiredBones.GetParentBoneIndex(PoseBoneIndex);
// only apply if I also have parent, otherwise, it should apply the space bases
if (ParentIndex != INDEX_NONE && MyParentIndex != INDEX_NONE)
{
const FTransform& ParentTransform = CurrentMeshComponent->GetComponentSpaceTransforms()[ParentIndex];
const FTransform& ChildTransform = CurrentMeshComponent->GetComponentSpaceTransforms()[SourceBoneIndex];
OutPose[PoseBoneIndex] = ChildTransform.GetRelativeTransform(ParentTransform);
}
else
{
OutPose[PoseBoneIndex] = CurrentMeshComponent->GetComponentSpaceTransforms()[SourceBoneIndex];
}
}
}
}
}
void FAnimNode_CopyPoseFromMesh::GatherDebugData(FNodeDebugData& DebugData)
{
}
void FAnimNode_CopyPoseFromMesh::ReinitializeMeshComponent(FAnimInstanceProxy* AnimInstanceProxy)
{
CurrentlyUsedSourceMeshComponent = SourceMeshComponent;
BoneMapToSource.Reset();
if (SourceMeshComponent && SourceMeshComponent->SkeletalMesh && !SourceMeshComponent->IsPendingKill())
{
USkeletalMeshComponent* TargetMeshComponent = AnimInstanceProxy->GetSkelMeshComponent();
if (TargetMeshComponent)
{
USkeletalMesh* SourceSkelMesh = SourceMeshComponent->SkeletalMesh;
USkeletalMesh* TargetSkelMesh = TargetMeshComponent->SkeletalMesh;
if (SourceSkelMesh == TargetSkelMesh)
{
for(int32 ComponentSpaceBoneId = 0; ComponentSpaceBoneId < SourceSkelMesh->RefSkeleton.GetNum(); ++ComponentSpaceBoneId)
{
BoneMapToSource.Add(ComponentSpaceBoneId, ComponentSpaceBoneId);
}
}
else
{
for (int32 ComponentSpaceBoneId=0; ComponentSpaceBoneId<TargetSkelMesh->RefSkeleton.GetNum(); ++ComponentSpaceBoneId)
{
FName BoneName = TargetSkelMesh->RefSkeleton.GetBoneName(ComponentSpaceBoneId);
BoneMapToSource.Add(ComponentSpaceBoneId, SourceSkelMesh->RefSkeleton.FindBoneIndex(BoneName));
}
}
}
}
}