2014-12-07 19:09:38 -05:00
|
|
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
2014-07-08 09:43:39 -04:00
|
|
|
|
2015-06-10 10:57:15 -04:00
|
|
|
#include "AnimGraphRuntimePrivatePCH.h"
|
|
|
|
|
#include "BoneControllers/AnimNode_BoneDrivenController.h"
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
|
|
|
// FAnimNode_BoneDrivenController
|
2014-07-08 09:43:39 -04:00
|
|
|
|
|
|
|
|
FAnimNode_BoneDrivenController::FAnimNode_BoneDrivenController()
|
2015-06-10 10:57:15 -04:00
|
|
|
: SourceComponent(EComponentType::None)
|
|
|
|
|
, Multiplier(1.0f)
|
|
|
|
|
, bUseRange(false)
|
|
|
|
|
, RangeMin(-1.0f)
|
|
|
|
|
, RangeMax(1.0f)
|
2015-06-17 18:54:05 -04:00
|
|
|
, TargetComponent(EComponentType::None)
|
2014-07-08 09:43:39 -04:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FAnimNode_BoneDrivenController::GatherDebugData(FNodeDebugData& DebugData)
|
|
|
|
|
{
|
|
|
|
|
FString DebugLine = DebugData.GetNodeName(this);
|
|
|
|
|
DebugLine += "(";
|
|
|
|
|
AddDebugNodeData(DebugLine);
|
|
|
|
|
DebugLine += FString::Printf(TEXT(" DrivingBone: %s\nDrivenBone: %s"), *SourceBone.BoneName.ToString(), *TargetBone.BoneName.ToString());
|
|
|
|
|
DebugData.AddDebugItem(DebugLine);
|
|
|
|
|
|
|
|
|
|
ComponentPose.GatherDebugData(DebugData);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-19 06:19:22 -04:00
|
|
|
void FAnimNode_BoneDrivenController::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms)
|
2014-07-08 09:43:39 -04:00
|
|
|
{
|
|
|
|
|
check(OutBoneTransforms.Num() == 0);
|
|
|
|
|
|
|
|
|
|
// Early out if we're not driving from or to anything
|
2015-06-17 18:54:05 -04:00
|
|
|
if ((SourceComponent == EComponentType::None) || (TargetComponent == EComponentType::None))
|
2014-07-08 09:43:39 -04:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the Local space transform and the ref pose transform to see how the transform for the source bone has changed
|
2015-05-19 06:19:22 -04:00
|
|
|
const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer();
|
|
|
|
|
const FTransform& SourceOrigRef = BoneContainer.GetRefPoseArray()[SourceBone.BoneIndex];
|
2015-06-17 18:54:05 -04:00
|
|
|
const FTransform SourceCurr = MeshBases.GetLocalSpaceTransform(SourceBone.GetCompactPoseIndex(BoneContainer));
|
2014-07-08 09:43:39 -04:00
|
|
|
|
2015-06-17 18:54:05 -04:00
|
|
|
// Resolve source value
|
|
|
|
|
float SourceValue = 0.0f;
|
|
|
|
|
if (SourceComponent < EComponentType::RotationX)
|
|
|
|
|
{
|
|
|
|
|
const FVector TranslationDiff = SourceCurr.GetLocation() - SourceOrigRef.GetLocation();
|
|
|
|
|
SourceValue = TranslationDiff[(int32)(SourceComponent - EComponentType::TranslationX)];
|
|
|
|
|
}
|
|
|
|
|
else if (SourceComponent < EComponentType::Scale)
|
|
|
|
|
{
|
|
|
|
|
const FVector RotationDiff = (SourceCurr.GetRotation() * SourceOrigRef.GetRotation().Inverse()).Euler();
|
|
|
|
|
SourceValue = RotationDiff[(int32)(SourceComponent - EComponentType::RotationX)];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const FVector CurrentScale = SourceCurr.GetScale3D();
|
|
|
|
|
const FVector RefScale = SourceOrigRef.GetScale3D();
|
|
|
|
|
const float ScaleDiff = FMath::Max3(CurrentScale[0], CurrentScale[1], CurrentScale[2]) - FMath::Max3(RefScale[0], RefScale[1], RefScale[2]);
|
|
|
|
|
SourceValue = ScaleDiff;
|
|
|
|
|
}
|
2014-07-08 09:43:39 -04:00
|
|
|
|
2015-06-17 18:54:05 -04:00
|
|
|
// Determine the resulting value
|
|
|
|
|
float FinalDriverValue = SourceValue;
|
|
|
|
|
if (DrivingCurve != nullptr)
|
|
|
|
|
{
|
|
|
|
|
// Remap thru the curve if set
|
|
|
|
|
FinalDriverValue = DrivingCurve->GetFloatValue(FinalDriverValue);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Apply the fixed function remapping/clamping
|
|
|
|
|
FinalDriverValue *= Multiplier;
|
|
|
|
|
if (bUseRange)
|
|
|
|
|
{
|
|
|
|
|
FinalDriverValue = FMath::Clamp(FinalDriverValue, RangeMin, RangeMax);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-08 09:43:39 -04:00
|
|
|
// Difference to apply after processing
|
|
|
|
|
FVector NewRotDiff(FVector::ZeroVector);
|
|
|
|
|
FVector NewTransDiff(FVector::ZeroVector);
|
|
|
|
|
float NewScaleDiff = 0.0f;
|
|
|
|
|
|
|
|
|
|
// Resolve target value
|
2015-06-17 18:54:05 -04:00
|
|
|
float* DestPtr = nullptr;
|
|
|
|
|
if (TargetComponent < EComponentType::RotationX)
|
2014-07-08 09:43:39 -04:00
|
|
|
{
|
|
|
|
|
DestPtr = &NewTransDiff[(int32)(TargetComponent - EComponentType::TranslationX)];
|
|
|
|
|
}
|
2015-06-17 18:54:05 -04:00
|
|
|
else if (TargetComponent < EComponentType::Scale)
|
2014-07-08 09:43:39 -04:00
|
|
|
{
|
|
|
|
|
DestPtr = &NewRotDiff[(int32)(TargetComponent - EComponentType::RotationX)];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DestPtr = &NewScaleDiff;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-17 18:54:05 -04:00
|
|
|
// Set the value
|
|
|
|
|
*DestPtr = FinalDriverValue;
|
2014-07-08 09:43:39 -04:00
|
|
|
|
|
|
|
|
// Build final transform difference
|
2015-06-17 18:54:05 -04:00
|
|
|
const FTransform FinalDiff(FQuat::MakeFromEuler(NewRotDiff), NewTransDiff, FVector(NewScaleDiff));
|
2015-05-19 06:19:22 -04:00
|
|
|
|
2015-06-17 18:54:05 -04:00
|
|
|
const FCompactPoseBoneIndex TargetBoneIndex = TargetBone.GetCompactPoseIndex(BoneContainer);
|
2015-05-19 06:19:22 -04:00
|
|
|
|
|
|
|
|
// Starting point for the new transform
|
|
|
|
|
FTransform NewLocal = MeshBases.GetLocalSpaceTransform(TargetBoneIndex);
|
2014-07-08 12:09:11 -04:00
|
|
|
NewLocal.AccumulateWithAdditiveScale3D(FinalDiff);
|
2014-07-08 09:43:39 -04:00
|
|
|
|
|
|
|
|
// If we have a parent, concatenate the transform, otherwise just take the new transform
|
2015-06-17 18:54:05 -04:00
|
|
|
const FCompactPoseBoneIndex ParentIndex = MeshBases.GetPose().GetParentBoneIndex(TargetBoneIndex);
|
2015-05-19 06:19:22 -04:00
|
|
|
|
2015-06-17 18:54:05 -04:00
|
|
|
if (ParentIndex != INDEX_NONE)
|
2014-07-08 09:43:39 -04:00
|
|
|
{
|
2015-06-17 18:54:05 -04:00
|
|
|
const FTransform& ParentTM = MeshBases.GetComponentSpaceTransform(ParentIndex);
|
2014-07-08 09:43:39 -04:00
|
|
|
|
2015-05-19 06:19:22 -04:00
|
|
|
OutBoneTransforms.Add(FBoneTransform(TargetBoneIndex, NewLocal * ParentTM));
|
2014-07-08 09:43:39 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-05-19 06:19:22 -04:00
|
|
|
OutBoneTransforms.Add(FBoneTransform(TargetBoneIndex, NewLocal));
|
2014-07-08 09:43:39 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-01 14:45:04 -04:00
|
|
|
bool FAnimNode_BoneDrivenController::IsValidToEvaluate(const USkeleton* Skeleton, const FBoneContainer& RequiredBones)
|
2014-07-08 09:43:39 -04:00
|
|
|
{
|
|
|
|
|
return SourceBone.IsValid(RequiredBones) && TargetBone.IsValid(RequiredBones);
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-01 14:45:04 -04:00
|
|
|
void FAnimNode_BoneDrivenController::InitializeBoneReferences(const FBoneContainer& RequiredBones)
|
2014-07-08 09:43:39 -04:00
|
|
|
{
|
|
|
|
|
SourceBone.Initialize(RequiredBones);
|
|
|
|
|
TargetBone.Initialize(RequiredBones);
|
|
|
|
|
}
|