2014-12-07 19:09:38 -05:00
|
|
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
2014-05-22 14:14:52 -04:00
|
|
|
|
2015-06-10 10:57:15 -04:00
|
|
|
#include "AnimGraphRuntimePrivatePCH.h"
|
|
|
|
|
#include "BoneControllers/AnimNode_HandIKRetargeting.h"
|
2014-05-22 14:14:52 -04:00
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
|
|
|
// FAnimNode_HandIKRetargeting
|
|
|
|
|
|
|
|
|
|
FAnimNode_HandIKRetargeting::FAnimNode_HandIKRetargeting()
|
|
|
|
|
: HandFKWeight(0.5f)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FAnimNode_HandIKRetargeting::GatherDebugData(FNodeDebugData& DebugData)
|
|
|
|
|
{
|
|
|
|
|
FString DebugLine = DebugData.GetNodeName(this);
|
|
|
|
|
|
|
|
|
|
DebugLine += "(";
|
|
|
|
|
AddDebugNodeData(DebugLine);
|
2014-08-06 16:12:41 -04:00
|
|
|
DebugLine += FString::Printf(TEXT(" HandFKWeight: %f)"), HandFKWeight);
|
2014-05-22 14:14:52 -04:00
|
|
|
for (int32 BoneIndex = 0; BoneIndex < IKBonesToMove.Num(); BoneIndex++)
|
|
|
|
|
{
|
|
|
|
|
DebugLine += FString::Printf(TEXT(", %s)"), *IKBonesToMove[BoneIndex].BoneName.ToString());
|
|
|
|
|
}
|
|
|
|
|
DebugLine += FString::Printf(TEXT(")"));
|
|
|
|
|
DebugData.AddDebugItem(DebugLine);
|
|
|
|
|
|
|
|
|
|
ComponentPose.GatherDebugData(DebugData);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-19 06:19:22 -04:00
|
|
|
void FAnimNode_HandIKRetargeting::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms)
|
2014-05-22 14:14:52 -04:00
|
|
|
{
|
|
|
|
|
checkSlow(OutBoneTransforms.Num() == 0);
|
|
|
|
|
|
2015-05-19 06:19:22 -04:00
|
|
|
const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer();
|
2014-05-22 14:14:52 -04:00
|
|
|
// Get component space transforms for all of our IK and FK bones.
|
2015-05-19 06:19:22 -04:00
|
|
|
const FTransform& RightHandFKTM = MeshBases.GetComponentSpaceTransform(RightHandFK.GetCompactPoseIndex(BoneContainer));
|
|
|
|
|
const FTransform& LeftHandFKTM = MeshBases.GetComponentSpaceTransform(LeftHandFK.GetCompactPoseIndex(BoneContainer));
|
|
|
|
|
const FTransform& RightHandIKTM = MeshBases.GetComponentSpaceTransform(RightHandIK.GetCompactPoseIndex(BoneContainer));
|
|
|
|
|
const FTransform& LeftHandIKTM = MeshBases.GetComponentSpaceTransform(LeftHandIK.GetCompactPoseIndex(BoneContainer));
|
2014-05-22 14:14:52 -04:00
|
|
|
|
|
|
|
|
// Compute weight FK and IK hand location. And translation from IK to FK.
|
|
|
|
|
FVector const FKLocation = FMath::Lerp<FVector>(LeftHandFKTM.GetTranslation(), RightHandFKTM.GetTranslation(), HandFKWeight);
|
|
|
|
|
FVector const IKLocation = FMath::Lerp<FVector>(LeftHandIKTM.GetTranslation(), RightHandIKTM.GetTranslation(), HandFKWeight);
|
|
|
|
|
FVector const IK_To_FK_Translation = FKLocation - IKLocation;
|
|
|
|
|
|
|
|
|
|
// If we're not translating, don't send any bones to update.
|
|
|
|
|
if (!IK_To_FK_Translation.IsNearlyZero())
|
|
|
|
|
{
|
|
|
|
|
// Move desired bones
|
2015-05-19 12:08:12 -04:00
|
|
|
for (const FBoneReference& BoneReference : IKBonesToMove)
|
2014-05-22 14:14:52 -04:00
|
|
|
{
|
2015-05-19 06:19:22 -04:00
|
|
|
if (BoneReference.IsValid(BoneContainer))
|
2014-05-22 14:14:52 -04:00
|
|
|
{
|
2015-05-19 06:19:22 -04:00
|
|
|
FCompactPoseBoneIndex BoneIndex = BoneReference.GetCompactPoseIndex(BoneContainer);
|
|
|
|
|
FTransform BoneTransform = MeshBases.GetComponentSpaceTransform(BoneIndex);
|
2014-05-22 14:14:52 -04:00
|
|
|
BoneTransform.AddToTranslation(IK_To_FK_Translation);
|
|
|
|
|
|
2015-05-19 06:19:22 -04:00
|
|
|
OutBoneTransforms.Add(FBoneTransform(BoneIndex, BoneTransform));
|
2014-05-22 14:14:52 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-01 14:45:04 -04:00
|
|
|
bool FAnimNode_HandIKRetargeting::IsValidToEvaluate(const USkeleton* Skeleton, const FBoneContainer& RequiredBones)
|
2014-05-22 14:14:52 -04:00
|
|
|
{
|
|
|
|
|
if (RightHandFK.IsValid(RequiredBones)
|
|
|
|
|
&& LeftHandFK.IsValid(RequiredBones)
|
|
|
|
|
&& RightHandIK.IsValid(RequiredBones)
|
|
|
|
|
&& LeftHandIK.IsValid(RequiredBones))
|
|
|
|
|
{
|
|
|
|
|
// we need at least one bone to move valid.
|
|
|
|
|
for (int32 BoneIndex = 0; BoneIndex < IKBonesToMove.Num(); BoneIndex++)
|
|
|
|
|
{
|
|
|
|
|
if (IKBonesToMove[BoneIndex].IsValid(RequiredBones))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-01 14:45:04 -04:00
|
|
|
void FAnimNode_HandIKRetargeting::InitializeBoneReferences(const FBoneContainer& RequiredBones)
|
2014-05-22 14:14:52 -04:00
|
|
|
{
|
|
|
|
|
RightHandFK.Initialize(RequiredBones);
|
|
|
|
|
LeftHandFK.Initialize(RequiredBones);
|
|
|
|
|
RightHandIK.Initialize(RequiredBones);
|
|
|
|
|
LeftHandIK.Initialize(RequiredBones);
|
|
|
|
|
|
|
|
|
|
for (int32 BoneIndex = 0; BoneIndex < IKBonesToMove.Num(); BoneIndex++)
|
|
|
|
|
{
|
|
|
|
|
IKBonesToMove[BoneIndex].Initialize(RequiredBones);
|
|
|
|
|
}
|
|
|
|
|
}
|