2016-01-07 08:17:16 -05:00
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
# include "AnimGraphPrivatePCH.h"
2014-04-24 08:49:31 -04:00
# include "AnimGraphNode_ModifyBone.h"
2015-06-17 15:28:02 -04:00
# include "CompilerResultsLog.h"
2014-03-14 14:13:41 -04:00
/////////////////////////////////////////////////////
// UAnimGraphNode_ModifyBone
2014-04-23 18:30:37 -04:00
# define LOCTEXT_NAMESPACE "A3Nodes"
2014-10-14 10:29:11 -04:00
UAnimGraphNode_ModifyBone : : UAnimGraphNode_ModifyBone ( const FObjectInitializer & ObjectInitializer )
: Super ( ObjectInitializer )
2014-03-14 14:13:41 -04:00
{
2014-11-14 10:55:42 -05:00
CurWidgetMode = ( int32 ) FWidget : : WM_Rotate ;
2014-03-14 14:13:41 -04:00
}
2015-06-17 15:28:02 -04:00
void UAnimGraphNode_ModifyBone : : ValidateAnimNodeDuringCompilation ( USkeleton * ForSkeleton , FCompilerResultsLog & MessageLog )
{
if ( ForSkeleton - > GetReferenceSkeleton ( ) . FindBoneIndex ( Node . BoneToModify . BoneName ) = = INDEX_NONE )
{
MessageLog . Warning ( * LOCTEXT ( " NoBoneToModify " , " @@ - You must pick a bone to modify " ) . ToString ( ) , this ) ;
}
if ( ( Node . TranslationMode = = BMM_Ignore ) & & ( Node . RotationMode = = BMM_Ignore ) & & ( Node . ScaleMode = = BMM_Ignore ) )
{
MessageLog . Warning ( * LOCTEXT ( " NothingToModify " , " @@ - No components to modify selected. Either Rotation, Translation, or Scale should be set to something other than Ignore " ) . ToString ( ) , this ) ;
}
Super : : ValidateAnimNodeDuringCompilation ( ForSkeleton , MessageLog ) ;
}
2014-04-23 18:30:37 -04:00
FText UAnimGraphNode_ModifyBone : : GetControllerDescription ( ) const
2014-03-14 14:13:41 -04:00
{
2014-04-23 18:30:37 -04:00
return LOCTEXT ( " TransformModifyBone " , " Transform (Modify) Bone " ) ;
2014-03-14 14:13:41 -04:00
}
2014-09-03 18:14:09 -04:00
FText UAnimGraphNode_ModifyBone : : GetTooltipText ( ) const
2014-03-14 14:13:41 -04:00
{
2014-09-03 18:14:09 -04:00
return LOCTEXT ( " AnimGraphNode_ModifyBone_Tooltip " , " The Transform Bone node alters the transform - i.e. Translation, Rotation, or Scale - of the bone " ) ;
2014-03-14 14:13:41 -04:00
}
2014-04-23 18:30:37 -04:00
FText UAnimGraphNode_ModifyBone : : GetNodeTitle ( ENodeTitleType : : Type TitleType ) const
2014-03-14 14:13:41 -04:00
{
2014-09-16 15:01:38 -04:00
if ( ( TitleType = = ENodeTitleType : : ListView | | TitleType = = ENodeTitleType : : MenuTitle ) & & ( Node . BoneToModify . BoneName = = NAME_None ) )
2014-09-04 11:25:05 -04:00
{
return GetControllerDescription ( ) ;
}
2014-09-24 14:15:13 -04:00
// @TODO: the bone can be altered in the property editor, so we have to
// choose to mark this dirty when that happens for this to properly work
2015-04-02 11:16:23 -04:00
else //if (!CachedNodeTitles.IsTitleCached(TitleType, this))
2014-09-04 11:25:05 -04:00
{
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " ControllerDescription " ) , GetControllerDescription ( ) ) ;
Args . Add ( TEXT ( " BoneName " ) , FText : : FromName ( Node . BoneToModify . BoneName ) ) ;
2014-04-23 18:30:37 -04:00
2014-09-04 11:25:05 -04:00
// FText::Format() is slow, so we cache this to save on performance
2014-09-16 15:01:38 -04:00
if ( TitleType = = ENodeTitleType : : ListView | | TitleType = = ENodeTitleType : : MenuTitle )
2014-08-21 18:50:33 -04:00
{
2015-04-02 11:16:23 -04:00
CachedNodeTitles . SetCachedTitle ( TitleType , FText : : Format ( LOCTEXT ( " AnimGraphNode_ModifyBone_ListTitle " , " {ControllerDescription} - Bone: {BoneName} " ) , Args ) , this ) ;
2014-09-04 11:25:05 -04:00
}
else
{
2015-04-02 11:16:23 -04:00
CachedNodeTitles . SetCachedTitle ( TitleType , FText : : Format ( LOCTEXT ( " AnimGraphNode_ModifyBone_Title " , " {ControllerDescription} \n Bone: {BoneName} " ) , Args ) , this ) ;
2014-08-21 18:50:33 -04:00
}
2014-04-23 18:30:37 -04:00
}
2014-09-04 11:25:05 -04:00
return CachedNodeTitles [ TitleType ] ;
2014-03-14 14:13:41 -04:00
}
2014-04-23 18:30:37 -04:00
2015-06-25 17:57:56 -04:00
int32 UAnimGraphNode_ModifyBone : : GetWidgetCoordinateSystem ( const USkeletalMeshComponent * SkelComp )
{
EBoneControlSpace Space = BCS_BoneSpace ;
switch ( CurWidgetMode )
{
case FWidget : : WM_Rotate :
Space = Node . RotationSpace ;
break ;
case FWidget : : WM_Translate :
Space = Node . TranslationSpace ;
break ;
case FWidget : : WM_Scale :
Space = Node . ScaleSpace ;
break ;
}
switch ( Space )
{
default :
case BCS_ParentBoneSpace :
//@TODO: No good way of handling this one
return COORD_World ;
case BCS_BoneSpace :
return COORD_Local ;
case BCS_ComponentSpace :
case BCS_WorldSpace :
return COORD_World ;
}
}
2014-11-14 05:00:37 -05:00
FVector UAnimGraphNode_ModifyBone : : GetWidgetLocation ( const USkeletalMeshComponent * SkelComp , FAnimNode_SkeletalControlBase * AnimNode )
{
2015-06-17 15:28:02 -04:00
USkeleton * Skeleton = SkelComp - > SkeletalMesh - > Skeleton ;
2014-11-14 05:00:37 -05:00
FVector WidgetLoc = FVector : : ZeroVector ;
// if the current widget mode is translate, then shows the widget according to translation space
if ( CurWidgetMode = = FWidget : : WM_Translate )
{
2015-05-19 06:19:22 -04:00
FCSPose < FCompactPose > & MeshBases = AnimNode - > ForwardedPose ;
2015-02-18 03:59:11 -05:00
WidgetLoc = ConvertWidgetLocation ( SkelComp , MeshBases , Node . BoneToModify . BoneName , GetNodeValue ( FString ( " Translation " ) , Node . Translation ) , Node . TranslationSpace ) ;
2014-11-14 05:00:37 -05:00
2015-05-19 06:19:22 -04:00
if ( MeshBases . GetPose ( ) . IsValid ( ) & & Node . TranslationMode = = BMM_Additive )
2014-11-14 05:00:37 -05:00
{
if ( Node . TranslationSpace = = EBoneControlSpace : : BCS_WorldSpace | |
Node . TranslationSpace = = EBoneControlSpace : : BCS_ComponentSpace )
{
2015-05-19 06:19:22 -04:00
const FMeshPoseBoneIndex MeshBoneIndex ( SkelComp - > GetBoneIndex ( Node . BoneToModify . BoneName ) ) ;
const FCompactPoseBoneIndex BoneIndex = MeshBases . GetPose ( ) . GetBoneContainer ( ) . MakeCompactPoseIndex ( MeshBoneIndex ) ;
if ( BoneIndex ! = INDEX_NONE )
2014-11-14 05:00:37 -05:00
{
2015-05-19 06:19:22 -04:00
const FTransform & BoneTM = MeshBases . GetComponentSpaceTransform ( BoneIndex ) ;
2014-11-14 05:00:37 -05:00
WidgetLoc + = BoneTM . GetLocation ( ) ;
}
}
}
}
else // if the current widget mode is not translate mode, then show the widget on the bone to modify
{
int32 MeshBoneIndex = SkelComp - > GetBoneIndex ( Node . BoneToModify . BoneName ) ;
if ( MeshBoneIndex ! = INDEX_NONE )
{
const FTransform BoneTM = SkelComp - > GetBoneTransform ( MeshBoneIndex ) ;
WidgetLoc = BoneTM . GetLocation ( ) ;
}
}
return WidgetLoc ;
}
2014-11-14 10:55:42 -05:00
EBoneModificationMode UAnimGraphNode_ModifyBone : : GetBoneModificationMode ( int32 InWidgetMode )
2014-11-14 05:00:37 -05:00
{
2014-11-14 10:55:42 -05:00
FWidget : : EWidgetMode InMode = ( FWidget : : EWidgetMode ) InWidgetMode ;
2014-11-14 05:00:37 -05:00
switch ( InMode )
{
case FWidget : : WM_Translate :
return Node . TranslationMode ;
break ;
case FWidget : : WM_Rotate :
return Node . RotationMode ;
break ;
case FWidget : : WM_Scale :
return Node . ScaleMode ;
break ;
2015-03-31 20:12:31 -04:00
case FWidget : : WM_TranslateRotateZ :
2015-04-08 14:46:25 -04:00
case FWidget : : WM_2D :
2015-03-31 20:12:31 -04:00
break ;
2014-11-14 05:00:37 -05:00
}
return EBoneModificationMode : : BMM_Ignore ;
}
2014-11-14 10:55:42 -05:00
int32 UAnimGraphNode_ModifyBone : : GetNextWidgetMode ( int32 InWidgetMode )
2014-11-14 05:00:37 -05:00
{
2014-11-14 10:55:42 -05:00
FWidget : : EWidgetMode InMode = ( FWidget : : EWidgetMode ) InWidgetMode ;
2014-11-14 05:00:37 -05:00
switch ( InMode )
{
case FWidget : : WM_Translate :
return FWidget : : WM_Rotate ;
case FWidget : : WM_Rotate :
return FWidget : : WM_Scale ;
case FWidget : : WM_Scale :
return FWidget : : WM_Translate ;
2015-03-31 20:12:31 -04:00
case FWidget : : WM_TranslateRotateZ :
2015-04-08 14:46:25 -04:00
case FWidget : : WM_2D :
2015-03-31 20:12:31 -04:00
break ;
2014-11-14 05:00:37 -05:00
}
2014-11-14 10:55:42 -05:00
return ( int32 ) FWidget : : WM_None ;
2014-11-14 05:00:37 -05:00
}
2014-11-14 10:55:42 -05:00
int32 UAnimGraphNode_ModifyBone : : FindValidWidgetMode ( int32 InWidgetMode )
2014-11-14 05:00:37 -05:00
{
2014-11-14 10:55:42 -05:00
FWidget : : EWidgetMode InMode = ( FWidget : : EWidgetMode ) InWidgetMode ;
2014-11-14 05:00:37 -05:00
FWidget : : EWidgetMode ValidMode = InMode ;
if ( InMode = = FWidget : : WM_None )
{ // starts from Rotate mode
ValidMode = FWidget : : WM_Rotate ;
}
// find from current widget mode and loop 1 cycle until finding a valid mode
for ( int32 Index = 0 ; Index < 3 ; Index + + )
{
if ( GetBoneModificationMode ( ValidMode ) ! = BMM_Ignore )
{
return ValidMode ;
}
2014-11-14 10:55:42 -05:00
ValidMode = ( FWidget : : EWidgetMode ) GetNextWidgetMode ( ValidMode ) ;
2014-11-14 05:00:37 -05:00
}
// if couldn't find a valid mode, returns None
ValidMode = FWidget : : WM_None ;
2014-11-14 10:55:42 -05:00
return ( int32 ) ValidMode ;
2014-11-14 05:00:37 -05:00
}
2014-11-14 10:55:42 -05:00
int32 UAnimGraphNode_ModifyBone : : GetWidgetMode ( const USkeletalMeshComponent * SkelComp )
2014-11-14 05:00:37 -05:00
{
int32 BoneIndex = SkelComp - > GetBoneIndex ( Node . BoneToModify . BoneName ) ;
if ( BoneIndex ! = INDEX_NONE )
{
CurWidgetMode = FindValidWidgetMode ( CurWidgetMode ) ;
return CurWidgetMode ;
}
2014-11-14 10:55:42 -05:00
return ( int32 ) FWidget : : WM_None ;
2014-11-14 05:00:37 -05:00
}
2014-12-01 21:27:36 -05:00
int32 UAnimGraphNode_ModifyBone : : ChangeToNextWidgetMode ( const USkeletalMeshComponent * SkelComp , int32 InCurWidgetMode )
2014-11-14 05:00:37 -05:00
{
2014-11-14 10:55:42 -05:00
int32 NextWidgetMode = GetNextWidgetMode ( InCurWidgetMode ) ;
2014-11-14 05:00:37 -05:00
CurWidgetMode = FindValidWidgetMode ( NextWidgetMode ) ;
return CurWidgetMode ;
}
2014-12-01 21:27:36 -05:00
bool UAnimGraphNode_ModifyBone : : SetWidgetMode ( const USkeletalMeshComponent * SkelComp , int32 InWidgetMode )
{
// if InWidgetMode is available
if ( FindValidWidgetMode ( InWidgetMode ) = = InWidgetMode )
{
CurWidgetMode = InWidgetMode ;
return true ;
}
return false ;
}
2014-11-14 05:00:37 -05:00
FName UAnimGraphNode_ModifyBone : : FindSelectedBone ( )
{
return Node . BoneToModify . BoneName ;
}
void UAnimGraphNode_ModifyBone : : DoTranslation ( const USkeletalMeshComponent * SkelComp , FVector & Drag , FAnimNode_Base * InOutAnimNode )
{
FAnimNode_ModifyBone * ModifyBone = static_cast < FAnimNode_ModifyBone * > ( InOutAnimNode ) ;
if ( ModifyBone - > TranslationMode ! = EBoneModificationMode : : BMM_Ignore )
{
FVector Offset = ConvertCSVectorToBoneSpace ( SkelComp , Drag , ModifyBone - > ForwardedPose , Node . BoneToModify . BoneName , Node . TranslationSpace ) ;
ModifyBone - > Translation + = Offset ;
Node . Translation = ModifyBone - > Translation ;
}
}
void UAnimGraphNode_ModifyBone : : DoRotation ( const USkeletalMeshComponent * SkelComp , FRotator & Rotation , FAnimNode_Base * InOutAnimNode )
{
FAnimNode_ModifyBone * ModifyBone = static_cast < FAnimNode_ModifyBone * > ( InOutAnimNode ) ;
if ( Node . RotationMode ! = EBoneModificationMode : : BMM_Ignore )
{
FQuat DeltaQuat = ConvertCSRotationToBoneSpace ( SkelComp , Rotation , ModifyBone - > ForwardedPose , Node . BoneToModify . BoneName , Node . RotationSpace ) ;
FQuat PrevQuat ( ModifyBone - > Rotation ) ;
FQuat NewQuat = DeltaQuat * PrevQuat ;
ModifyBone - > Rotation = NewQuat . Rotator ( ) ;
Node . Rotation = ModifyBone - > Rotation ;
}
}
void UAnimGraphNode_ModifyBone : : DoScale ( const USkeletalMeshComponent * SkelComp , FVector & Scale , FAnimNode_Base * InOutAnimNode )
{
FAnimNode_ModifyBone * ModifyBone = static_cast < FAnimNode_ModifyBone * > ( InOutAnimNode ) ;
if ( Node . ScaleMode ! = EBoneModificationMode : : BMM_Ignore )
{
FVector Offset = Scale ;
ModifyBone - > Scale + = Offset ;
Node . Scale = ModifyBone - > Scale ;
}
}
void UAnimGraphNode_ModifyBone : : CopyNodeDataTo ( FAnimNode_Base * OutAnimNode )
{
FAnimNode_ModifyBone * ModifyBone = static_cast < FAnimNode_ModifyBone * > ( OutAnimNode ) ;
// copies Pin values from the internal node to get data which are not compiled yet
2015-02-18 03:59:11 -05:00
ModifyBone - > Translation = GetNodeValue ( FString ( " Translation " ) , Node . Translation ) ;
ModifyBone - > Rotation = GetNodeValue ( FString ( " Rotation " ) , Node . Rotation ) ;
ModifyBone - > Scale = GetNodeValue ( FString ( " Scale " ) , Node . Scale ) ;
2014-11-14 05:00:37 -05:00
// copies Modes
ModifyBone - > TranslationMode = Node . TranslationMode ;
ModifyBone - > RotationMode = Node . RotationMode ;
ModifyBone - > ScaleMode = Node . ScaleMode ;
// copies Spaces
ModifyBone - > TranslationSpace = Node . TranslationSpace ;
ModifyBone - > RotationSpace = Node . RotationSpace ;
ModifyBone - > ScaleSpace = Node . ScaleSpace ;
}
void UAnimGraphNode_ModifyBone : : CopyNodeDataFrom ( const FAnimNode_Base * InNewAnimNode )
{
const FAnimNode_ModifyBone * ModifyBone = static_cast < const FAnimNode_ModifyBone * > ( InNewAnimNode ) ;
2015-02-18 03:59:11 -05:00
switch ( CurWidgetMode )
{
case FWidget : : WM_Translate :
SetNodeValue ( FString ( " Translation " ) , Node . Translation , ModifyBone - > Translation ) ;
break ;
case FWidget : : WM_Rotate :
SetNodeValue ( FString ( " Rotation " ) , Node . Rotation , ModifyBone - > Rotation ) ;
break ;
case FWidget : : WM_Scale :
SetNodeValue ( FString ( " Scale " ) , Node . Scale , ModifyBone - > Scale ) ;
break ;
}
2014-11-14 05:00:37 -05:00
}
2014-04-23 18:30:37 -04:00
# undef LOCTEXT_NAMESPACE