You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#rb none KNOWN BROKEN DO NOT SYNC #lockdown rolando.caloca [CL 4827063 by Marcus Wassmer in Dev-Rendering branch]
181 lines
6.0 KiB
C++
181 lines
6.0 KiB
C++
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "BoneControllers/AnimNode_SkeletalControlBase.h"
|
|
#include "Animation/AnimInstanceProxy.h"
|
|
#include "Engine/SkeletalMeshSocket.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Socket Reference
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void FSocketReference::InitializeSocketInfo(const FAnimInstanceProxy* InAnimInstanceProxy)
|
|
{
|
|
CachedSocketMeshBoneIndex = INDEX_NONE;
|
|
CachedSocketCompactBoneIndex = FCompactPoseBoneIndex(INDEX_NONE);
|
|
|
|
if (SocketName != NAME_None)
|
|
{
|
|
const USkeletalMeshComponent* OwnerMeshComponent = InAnimInstanceProxy->GetSkelMeshComponent();
|
|
if (OwnerMeshComponent && OwnerMeshComponent->DoesSocketExist(SocketName))
|
|
{
|
|
USkeletalMeshSocket const* const Socket = OwnerMeshComponent->GetSocketByName(SocketName);
|
|
if (Socket)
|
|
{
|
|
CachedSocketLocalTransform = Socket->GetSocketLocalTransform();
|
|
// cache mesh bone index, so that we know this is valid information to follow
|
|
CachedSocketMeshBoneIndex = OwnerMeshComponent->GetBoneIndex(Socket->BoneName);
|
|
|
|
ensureMsgf(CachedSocketMeshBoneIndex != INDEX_NONE, TEXT("%s : socket has invalid bone."), *SocketName.ToString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// @todo : move to graph node warning
|
|
UE_LOG(LogAnimation, Warning, TEXT("%s: socket doesn't exist"), *SocketName.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
void FSocketReference::InitialzeCompactBoneIndex(const FBoneContainer& RequiredBones)
|
|
{
|
|
if (CachedSocketMeshBoneIndex != INDEX_NONE)
|
|
{
|
|
const int32 SocketBoneSkeletonIndex = RequiredBones.GetPoseToSkeletonBoneIndexArray()[CachedSocketMeshBoneIndex];
|
|
CachedSocketCompactBoneIndex = RequiredBones.GetCompactPoseIndexFromSkeletonIndex(SocketBoneSkeletonIndex);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////
|
|
// FAnimNode_SkeletalControlBase
|
|
|
|
void FAnimNode_SkeletalControlBase::Initialize_AnyThread(const FAnimationInitializeContext& Context)
|
|
{
|
|
FAnimNode_Base::Initialize_AnyThread(Context);
|
|
|
|
ComponentPose.Initialize(Context);
|
|
|
|
AlphaBoolBlend.Reinitialize();
|
|
AlphaScaleBiasClamp.Reinitialize();
|
|
}
|
|
|
|
void FAnimNode_SkeletalControlBase::CacheBones_AnyThread(const FAnimationCacheBonesContext& Context)
|
|
{
|
|
FAnimNode_Base::CacheBones_AnyThread(Context);
|
|
InitializeBoneReferences(Context.AnimInstanceProxy->GetRequiredBones());
|
|
ComponentPose.CacheBones(Context);
|
|
}
|
|
|
|
void FAnimNode_SkeletalControlBase::UpdateInternal(const FAnimationUpdateContext& Context)
|
|
{
|
|
}
|
|
|
|
void FAnimNode_SkeletalControlBase::UpdateComponentPose_AnyThread(const FAnimationUpdateContext& Context)
|
|
{
|
|
ComponentPose.Update(Context);
|
|
}
|
|
|
|
void FAnimNode_SkeletalControlBase::Update_AnyThread(const FAnimationUpdateContext& Context)
|
|
{
|
|
UpdateComponentPose_AnyThread(Context);
|
|
|
|
ActualAlpha = 0.f;
|
|
if (IsLODEnabled(Context.AnimInstanceProxy))
|
|
{
|
|
GetEvaluateGraphExposedInputs().Execute(Context);
|
|
|
|
// Apply the skeletal control if it's valid
|
|
switch (AlphaInputType)
|
|
{
|
|
case EAnimAlphaInputType::Float :
|
|
ActualAlpha = AlphaScaleBias.ApplyTo(AlphaScaleBiasClamp.ApplyTo(Alpha, Context.GetDeltaTime()));
|
|
break;
|
|
case EAnimAlphaInputType::Bool :
|
|
ActualAlpha = AlphaBoolBlend.ApplyTo(bAlphaBoolEnabled, Context.GetDeltaTime());
|
|
break;
|
|
case EAnimAlphaInputType::Curve :
|
|
if (UAnimInstance* AnimInstance = Cast<UAnimInstance>(Context.AnimInstanceProxy->GetAnimInstanceObject()))
|
|
{
|
|
ActualAlpha = AlphaScaleBiasClamp.ApplyTo(AnimInstance->GetCurveValue(AlphaCurveName), Context.GetDeltaTime());
|
|
}
|
|
break;
|
|
};
|
|
|
|
// Make sure Alpha is clamped between 0 and 1.
|
|
ActualAlpha = FMath::Clamp<float>(ActualAlpha, 0.f, 1.f);
|
|
|
|
if (FAnimWeight::IsRelevant(ActualAlpha) && IsValidToEvaluate(Context.AnimInstanceProxy->GetSkeleton(), Context.AnimInstanceProxy->GetRequiredBones()))
|
|
{
|
|
UpdateInternal(Context);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ContainsNaN(const TArray<FBoneTransform> & BoneTransforms)
|
|
{
|
|
for (int32 i = 0; i < BoneTransforms.Num(); ++i)
|
|
{
|
|
if (BoneTransforms[i].Transform.ContainsNaN())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FAnimNode_SkeletalControlBase::EvaluateComponentPose_AnyThread(FComponentSpacePoseContext& Output)
|
|
{
|
|
// Evaluate the input
|
|
ComponentPose.EvaluateComponentSpace(Output);
|
|
}
|
|
|
|
void FAnimNode_SkeletalControlBase::EvaluateComponentSpaceInternal(FComponentSpacePoseContext& Context)
|
|
{
|
|
}
|
|
|
|
void FAnimNode_SkeletalControlBase::EvaluateComponentSpace_AnyThread(FComponentSpacePoseContext& Output)
|
|
{
|
|
EvaluateComponentPose_AnyThread(Output);
|
|
|
|
#if WITH_EDITORONLY_DATA
|
|
// save current pose before applying skeletal control to compute the exact gizmo location in AnimGraphNode
|
|
ForwardedPose.CopyPose(Output.Pose);
|
|
#endif // #if WITH_EDITORONLY_DATA
|
|
|
|
#if DO_CHECK
|
|
// this is to ensure Source data does not contain NaN
|
|
ensure(Output.ContainsNaN() == false);
|
|
#endif
|
|
|
|
// Apply the skeletal control if it's valid
|
|
if (FAnimWeight::IsRelevant(ActualAlpha) && IsValidToEvaluate(Output.AnimInstanceProxy->GetSkeleton(), Output.AnimInstanceProxy->GetRequiredBones()))
|
|
{
|
|
EvaluateComponentSpaceInternal(Output);
|
|
|
|
BoneTransforms.Reset(BoneTransforms.Num());
|
|
EvaluateSkeletalControl_AnyThread(Output, BoneTransforms);
|
|
|
|
if (BoneTransforms.Num() > 0)
|
|
{
|
|
const float BlendWeight = FMath::Clamp<float>(ActualAlpha, 0.f, 1.f);
|
|
Output.Pose.LocalBlendCSBoneTransforms(BoneTransforms, BlendWeight);
|
|
}
|
|
|
|
// we check NaN when you get out of this function in void FComponentSpacePoseLink::EvaluateComponentSpace(FComponentSpacePoseContext& Output)
|
|
}
|
|
}
|
|
|
|
void FAnimNode_SkeletalControlBase::AddDebugNodeData(FString& OutDebugData)
|
|
{
|
|
OutDebugData += FString::Printf(TEXT("Alpha: %.1f%%"), ActualAlpha*100.f);
|
|
}
|
|
|
|
void FAnimNode_SkeletalControlBase::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseContext& Output, TArray<FBoneTransform>& OutBoneTransforms)
|
|
{
|
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
|
// Call legacy implementation for backwards compatibility
|
|
EvaluateBoneTransforms(Output.AnimInstanceProxy->GetSkelMeshComponent(), Output.Pose, OutBoneTransforms);
|
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
|
}
|
|
|