2021-03-03 08:23:59 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "AnimNodes/AnimNode_Mirror.h"
# include "Animation/AnimInstanceProxy.h"
# include "Animation/AnimNode_Inertialization.h"
2022-02-01 13:38:41 -05:00
# include "Animation/AnimTrace.h"
2021-03-03 08:23:59 -04:00
# include "AnimationRuntime.h"
2021-05-06 08:43:56 -04:00
# include "Animation/AttributesRuntime.h"
2021-03-18 16:18:00 -04:00
# include "Animation/MirrorSyncScope.h"
2021-03-03 08:23:59 -04:00
2022-09-24 13:57:58 -04:00
# include UE_INLINE_GENERATED_CPP_BY_NAME(AnimNode_Mirror)
2021-03-03 08:23:59 -04:00
# define LOCTEXT_NAMESPACE "AnimNode_Mirror"
2021-11-13 12:57:14 -05:00
FAnimNode_MirrorBase : : FAnimNode_MirrorBase ( )
: bMirrorState ( false )
2021-03-03 08:23:59 -04:00
, bMirrorStateIsValid ( false )
{
}
2021-11-13 12:57:14 -05:00
UMirrorDataTable * FAnimNode_MirrorBase : : GetMirrorDataTable ( ) const
2021-03-03 08:23:59 -04:00
{
2021-11-13 12:57:14 -05:00
return nullptr ;
2021-03-03 08:23:59 -04:00
}
2021-11-13 12:57:14 -05:00
bool FAnimNode_MirrorBase : : SetMirrorDataTable ( UMirrorDataTable * MirrorTable )
{
return false ;
}
bool FAnimNode_MirrorBase : : GetMirror ( ) const
{
return false ;
}
2022-02-01 13:38:41 -05:00
2021-11-13 12:57:14 -05:00
float FAnimNode_MirrorBase : : GetBlendTimeOnMirrorStateChange ( ) const
{
return 0.0 ;
}
bool FAnimNode_MirrorBase : : GetBoneMirroring ( ) const
{
return false ;
}
bool FAnimNode_MirrorBase : : GetCurveMirroring ( ) const
{
return false ;
}
bool FAnimNode_MirrorBase : : GetAttributeMirroring ( ) const
{
return false ;
}
bool FAnimNode_MirrorBase : : GetResetChildOnMirrorStateChange ( ) const
{
return false ;
}
bool FAnimNode_MirrorBase : : SetMirror ( bool bInMirror )
{
return false ;
}
bool FAnimNode_MirrorBase : : SetBlendTimeOnMirrorStateChange ( float InBlendTime )
{
return false ;
}
bool FAnimNode_MirrorBase : : SetBoneMirroring ( bool bInBoneMirroring )
{
return false ;
}
bool FAnimNode_MirrorBase : : SetCurveMirroring ( bool bInCurveMirroring )
{
return false ;
}
bool FAnimNode_MirrorBase : : SetAttributeMirroring ( bool bInAttributeMirroring )
{
return false ;
}
bool FAnimNode_MirrorBase : : SetResetChildOnMirrorStateChange ( bool bInResetChildOnMirrorStateChange )
{
return false ;
}
void FAnimNode_MirrorBase : : SetSourceLinkNode ( FAnimNode_Base * NewLinkNode )
{
Source . SetLinkNode ( NewLinkNode ) ;
}
FAnimNode_Base * FAnimNode_MirrorBase : : GetSourceLinkNode ( )
{
return Source . GetLinkNode ( ) ;
}
void FAnimNode_MirrorBase : : Initialize_AnyThread ( const FAnimationInitializeContext & Context )
2021-03-03 08:23:59 -04:00
{
FAnimNode_Base : : Initialize_AnyThread ( Context ) ;
Source . Initialize ( Context ) ;
}
2021-11-13 12:57:14 -05:00
void FAnimNode_MirrorBase : : CacheBones_AnyThread ( const FAnimationCacheBonesContext & Context )
2021-03-03 08:23:59 -04:00
{
Source . CacheBones ( Context ) ;
DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE ( CacheBones_AnyThread )
Super : : CacheBones_AnyThread ( Context ) ;
2021-05-19 17:50:40 -04:00
const FBoneContainer & BoneContainer = Context . AnimInstanceProxy - > GetRequiredBones ( ) ;
FillCompactPoseAndComponentRefRotations ( BoneContainer ) ;
}
2021-03-03 08:23:59 -04:00
2021-11-13 12:57:14 -05:00
void FAnimNode_MirrorBase : : FillCompactPoseAndComponentRefRotations ( const FBoneContainer & BoneContainer )
2021-05-19 17:50:40 -04:00
{
2021-11-13 12:57:14 -05:00
UMirrorDataTable * MirrorDataTable = GetMirrorDataTable ( ) ;
2021-05-19 17:50:40 -04:00
if ( MirrorDataTable )
2021-03-03 08:23:59 -04:00
{
2022-01-06 17:27:03 -05:00
MirrorDataTable - > FillCompactPoseAndComponentRefRotations (
BoneContainer ,
CompactPoseMirrorBones ,
ComponentSpaceRefRotations ) ;
2021-03-03 08:23:59 -04:00
}
else
{
CompactPoseMirrorBones . Reset ( ) ;
2021-05-19 17:50:40 -04:00
ComponentSpaceRefRotations . Reset ( ) ;
2021-03-03 08:23:59 -04:00
}
}
2021-11-13 12:57:14 -05:00
void FAnimNode_MirrorBase : : Update_AnyThread ( const FAnimationUpdateContext & Context )
2021-03-03 08:23:59 -04:00
{
GetEvaluateGraphExposedInputs ( ) . Execute ( Context ) ;
2021-11-13 12:57:14 -05:00
bool bMirror = GetMirror ( ) ;
2021-03-03 08:23:59 -04:00
if ( bMirrorStateIsValid & & bMirrorState ! = bMirror )
{
2021-11-13 12:57:14 -05:00
if ( GetBlendTimeOnMirrorStateChange ( ) > SMALL_NUMBER )
2021-03-03 08:23:59 -04:00
{
// Inertialize when switching between mirrored and unmirrored states to smooth out the pose discontinuity
UE : : Anim : : IInertializationRequester * InertializationRequester = Context . GetMessage < UE : : Anim : : IInertializationRequester > ( ) ;
if ( InertializationRequester )
{
2022-02-25 00:11:37 -05:00
InertializationRequester - > RequestInertialization ( GetBlendTimeOnMirrorStateChange ( ) ) ;
2021-03-03 08:23:59 -04:00
InertializationRequester - > AddDebugRecord ( * Context . AnimInstanceProxy , Context . GetCurrentNodeId ( ) ) ;
}
else
{
FAnimNode_Inertialization : : LogRequestError ( Context , Source ) ;
}
}
// Optionally reinitialize the source when the mirror state changes
2021-11-13 12:57:14 -05:00
if ( GetResetChildOnMirrorStateChange ( ) )
2021-03-03 08:23:59 -04:00
{
2021-04-15 14:54:07 -04:00
FAnimationInitializeContext ReinitializeContext ( Context . AnimInstanceProxy , Context . SharedContext ) ;
2021-03-03 08:23:59 -04:00
Source . Initialize ( ReinitializeContext ) ;
}
}
2021-11-13 12:57:14 -05:00
UMirrorDataTable * MirrorDataTable = GetMirrorDataTable ( ) ;
2021-03-18 16:18:00 -04:00
UE : : Anim : : TOptionalScopedGraphMessage < UE : : Anim : : FMirrorSyncScope > Message ( bMirror , Context , Context , MirrorDataTable ) ;
2021-11-13 12:57:14 -05:00
2021-03-03 08:23:59 -04:00
bMirrorState = bMirror ;
bMirrorStateIsValid = true ;
Source . Update ( Context ) ;
2022-02-01 13:38:41 -05:00
TRACE_ANIM_NODE_VALUE ( Context , TEXT ( " Mirrored " ) , bMirrorState ) ;
2021-03-03 08:23:59 -04:00
}
2021-11-13 12:57:14 -05:00
void FAnimNode_MirrorBase : : Evaluate_AnyThread ( FPoseContext & Output )
2021-03-03 08:23:59 -04:00
{
Source . Evaluate ( Output ) ;
2021-11-13 12:57:14 -05:00
UMirrorDataTable * MirrorDataTable = GetMirrorDataTable ( ) ;
2021-03-03 08:23:59 -04:00
if ( bMirrorState & & MirrorDataTable )
{
2021-11-13 12:57:14 -05:00
if ( GetBoneMirroring ( ) )
2021-05-06 08:43:56 -04:00
{
2022-11-22 11:03:35 -05:00
if ( Output . ExpectsAdditivePose ( ) )
2021-05-19 17:50:40 -04:00
{
2022-11-22 11:03:35 -05:00
FText Message = FText : : Format ( LOCTEXT ( " AdditiveMirrorWarning " , " Trying to mirror an additive animation pose is not supported in anim instance '{0}' " ) , FText : : FromString ( Output . AnimInstanceProxy - > GetAnimInstanceName ( ) ) ) ;
Output . LogMessage ( EMessageSeverity : : Warning , Message ) ;
// Force a bind pose to make it obvious
Output . Pose . ResetToAdditiveIdentity ( ) ;
}
else
{
const FBoneContainer & BoneContainer = Output . Pose . GetBoneContainer ( ) ;
const TArray < FBoneIndexType > & RequiredBoneIndices = BoneContainer . GetBoneIndicesArray ( ) ;
int32 NumReqBones = RequiredBoneIndices . Num ( ) ;
if ( CompactPoseMirrorBones . Num ( ) ! = NumReqBones )
{
FillCompactPoseAndComponentRefRotations ( BoneContainer ) ;
}
FAnimationRuntime : : MirrorPose ( Output . Pose , MirrorDataTable - > MirrorAxis , CompactPoseMirrorBones , ComponentSpaceRefRotations ) ;
2021-05-19 17:50:40 -04:00
}
2021-05-06 08:43:56 -04:00
}
2021-11-13 12:57:14 -05:00
if ( GetCurveMirroring ( ) )
2021-05-06 08:43:56 -04:00
{
FAnimationRuntime : : MirrorCurves ( Output . Curve , * MirrorDataTable ) ;
}
2021-11-13 12:57:14 -05:00
if ( GetAttributeMirroring ( ) )
2021-05-06 08:43:56 -04:00
{
2023-02-07 13:42:31 -05:00
UE : : Anim : : Attributes : : MirrorAttributes ( Output . CustomAttributes , * MirrorDataTable , CompactPoseMirrorBones ) ;
2021-05-06 08:43:56 -04:00
}
2021-03-03 08:23:59 -04:00
}
}
2021-11-13 12:57:14 -05:00
void FAnimNode_MirrorBase : : GatherDebugData ( FNodeDebugData & DebugData )
2021-03-03 08:23:59 -04:00
{
FString DebugLine = DebugData . GetNodeName ( this ) ;
DebugLine + = FString : : Printf ( TEXT ( " (Mirrored: %s) " ) , ( bMirrorState ) ? TEXT ( " true " ) : TEXT ( " false " ) ) ;
DebugData . AddDebugItem ( DebugLine ) ;
Source . GatherDebugData ( DebugData ) ;
}
2021-11-13 12:57:14 -05:00
FAnimNode_Mirror : : FAnimNode_Mirror ( )
{
}
UMirrorDataTable * FAnimNode_Mirror : : GetMirrorDataTable ( ) const
{
return GET_ANIM_NODE_DATA ( TObjectPtr < UMirrorDataTable > , MirrorDataTable ) ;
}
bool FAnimNode_Mirror : : SetMirrorDataTable ( UMirrorDataTable * InMirrorTable )
{
# if WITH_EDITORONLY_DATA
MirrorDataTable = InMirrorTable ;
GET_MUTABLE_ANIM_NODE_DATA ( TObjectPtr < UMirrorDataTable > , MirrorDataTable ) = InMirrorTable ;
# endif
if ( TObjectPtr < UMirrorDataTable > * InMirrorTablePtr = GET_INSTANCE_ANIM_NODE_DATA_PTR ( TObjectPtr < UMirrorDataTable > , MirrorDataTable ) )
{
* InMirrorTablePtr = InMirrorTable ;
return true ;
}
return false ;
}
bool FAnimNode_Mirror : : GetMirror ( ) const
{
return GET_ANIM_NODE_DATA ( bool , bMirror ) ;
}
float FAnimNode_Mirror : : GetBlendTimeOnMirrorStateChange ( ) const
{
2022-02-01 13:38:41 -05:00
return GET_ANIM_NODE_DATA ( float , BlendTime ) ;
2021-11-13 12:57:14 -05:00
}
bool FAnimNode_Mirror : : GetBoneMirroring ( ) const
{
return GET_ANIM_NODE_DATA ( bool , bBoneMirroring ) ;
}
bool FAnimNode_Mirror : : GetCurveMirroring ( ) const
{
return GET_ANIM_NODE_DATA ( bool , bCurveMirroring ) ;
}
bool FAnimNode_Mirror : : GetAttributeMirroring ( ) const
{
return GET_ANIM_NODE_DATA ( bool , bAttributeMirroring ) ;
}
bool FAnimNode_Mirror : : GetResetChildOnMirrorStateChange ( ) const
{
2022-02-01 13:38:41 -05:00
return GET_ANIM_NODE_DATA ( bool , bResetChild ) ;
2021-11-13 12:57:14 -05:00
}
bool FAnimNode_Mirror : : SetMirror ( bool bInMirror )
{
# if WITH_EDITORONLY_DATA
bMirror = bInMirror ;
# endif
if ( bool * bMirrorPtr = GET_INSTANCE_ANIM_NODE_DATA_PTR ( bool , bMirror ) )
{
* bMirrorPtr = bInMirror ;
return true ;
}
return false ;
}
bool FAnimNode_Mirror : : SetBlendTimeOnMirrorStateChange ( float InBlendTime )
{
# if WITH_EDITORONLY_DATA
2022-02-01 13:38:41 -05:00
BlendTime = InBlendTime ;
2021-11-13 12:57:14 -05:00
# endif
2022-02-01 13:38:41 -05:00
if ( float * BlendTimePtr = GET_INSTANCE_ANIM_NODE_DATA_PTR ( float , BlendTime ) )
2021-11-13 12:57:14 -05:00
{
* BlendTimePtr = InBlendTime ;
return true ;
}
return false ;
}
bool FAnimNode_Mirror : : SetBoneMirroring ( bool bInBoneMirroring )
{
# if WITH_EDITORONLY_DATA
bBoneMirroring = bInBoneMirroring ;
# endif
if ( bool * bBoneMirroringPtr = GET_INSTANCE_ANIM_NODE_DATA_PTR ( bool , bBoneMirroring ) )
{
* bBoneMirroringPtr = bInBoneMirroring ;
return true ;
}
return false ;
}
bool FAnimNode_Mirror : : SetCurveMirroring ( bool bInCurveMirroring )
{
# if WITH_EDITORONLY_DATA
bCurveMirroring = bInCurveMirroring ;
# endif
if ( bool * bCurveMirroringPtr = GET_INSTANCE_ANIM_NODE_DATA_PTR ( bool , bCurveMirroring ) )
{
* bCurveMirroringPtr = bInCurveMirroring ;
return true ;
}
return false ;
}
bool FAnimNode_Mirror : : SetAttributeMirroring ( bool bInAttributeMirroring )
{
# if WITH_EDITORONLY_DATA
bAttributeMirroring = bInAttributeMirroring ;
# endif
if ( bool * bAttributeMirroringPtr = GET_INSTANCE_ANIM_NODE_DATA_PTR ( bool , bAttributeMirroring ) )
{
* bAttributeMirroringPtr = bInAttributeMirroring ;
return true ;
}
return false ;
}
bool FAnimNode_Mirror : : SetResetChildOnMirrorStateChange ( bool bInResetChildOnMirrorStateChange )
{
# if WITH_EDITORONLY_DATA
2022-02-01 13:38:41 -05:00
bResetChild = bInResetChildOnMirrorStateChange ;
2021-11-13 12:57:14 -05:00
# endif
2022-02-01 13:38:41 -05:00
if ( bool * bResetChildPtr = GET_INSTANCE_ANIM_NODE_DATA_PTR ( bool , bResetChild ) )
2021-11-13 12:57:14 -05:00
{
2022-02-01 13:38:41 -05:00
* bResetChildPtr = bInResetChildOnMirrorStateChange ;
2021-11-13 12:57:14 -05:00
return true ;
}
return false ;
}
FAnimNode_Mirror_Standalone : : FAnimNode_Mirror_Standalone ( )
{
}
UMirrorDataTable * FAnimNode_Mirror_Standalone : : GetMirrorDataTable ( ) const
{
return MirrorDataTable . Get ( ) ;
}
bool FAnimNode_Mirror_Standalone : : SetMirrorDataTable ( UMirrorDataTable * MirrorTable )
{
MirrorDataTable = MirrorTable ;
return true ;
}
bool FAnimNode_Mirror_Standalone : : GetMirror ( ) const
{
return bMirror ;
}
float FAnimNode_Mirror_Standalone : : GetBlendTimeOnMirrorStateChange ( ) const
{
2022-02-01 13:38:41 -05:00
return BlendTime ;
2021-11-13 12:57:14 -05:00
}
bool FAnimNode_Mirror_Standalone : : GetBoneMirroring ( ) const
{
return bBoneMirroring ;
}
bool FAnimNode_Mirror_Standalone : : GetCurveMirroring ( ) const
{
return bCurveMirroring ;
}
bool FAnimNode_Mirror_Standalone : : GetAttributeMirroring ( ) const
{
return bAttributeMirroring ;
}
bool FAnimNode_Mirror_Standalone : : GetResetChildOnMirrorStateChange ( ) const
{
2022-02-01 13:38:41 -05:00
return bResetChild ;
2021-11-13 12:57:14 -05:00
}
bool FAnimNode_Mirror_Standalone : : SetMirror ( bool bInMirror )
{
bMirror = bInMirror ;
return true ;
}
bool FAnimNode_Mirror_Standalone : : SetBlendTimeOnMirrorStateChange ( float InBlendTime )
{
2022-02-01 13:38:41 -05:00
BlendTime = InBlendTime ;
2021-11-13 12:57:14 -05:00
return true ;
}
bool FAnimNode_Mirror_Standalone : : SetBoneMirroring ( bool bInBoneMirroring )
{
bBoneMirroring = bInBoneMirroring ;
return true ;
}
bool FAnimNode_Mirror_Standalone : : SetCurveMirroring ( bool bInCurveMirroring )
{
bCurveMirroring = bInCurveMirroring ;
return true ;
}
bool FAnimNode_Mirror_Standalone : : SetAttributeMirroring ( bool bInAttributeMirroring )
{
bAttributeMirroring = bInAttributeMirroring ;
return true ;
}
bool FAnimNode_Mirror_Standalone : : SetResetChildOnMirrorStateChange ( bool bInResetChildOnMirrorStateChange )
{
2022-02-01 13:38:41 -05:00
bResetChild = bInResetChildOnMirrorStateChange ;
2021-11-13 12:57:14 -05:00
return true ;
}
2021-03-03 08:23:59 -04:00
# undef LOCTEXT_NAMESPACE
2022-09-24 13:57:58 -04:00