This commit is contained in:
Lucas 2024-12-04 01:49:59 +01:00
parent e159e81585
commit 163dda96b8
2 changed files with 127 additions and 117 deletions

View file

@ -1,7 +1,7 @@
{ {
"FileVersion": 3, "FileVersion": 3,
"Version": 1, "Version": 2,
"VersionName": "2.0", "VersionName": "3.0",
"FriendlyName": "Mirror Animation System", "FriendlyName": "Mirror Animation System",
"Description": "Incorporates functionalities that allow the mirroring of animations with their root motion at runtime, as well as inside the editor.", "Description": "Incorporates functionalities that allow the mirroring of animations with their root motion at runtime, as well as inside the editor.",
"Category": "Animation", "Category": "Animation",
@ -10,7 +10,7 @@
"DocsURL": "https://github.com/Rexocrates/Mirror_Animation_System/blob/main/Mirror%20Animation%20System%20Documentation.pdf", "DocsURL": "https://github.com/Rexocrates/Mirror_Animation_System/blob/main/Mirror%20Animation%20System%20Documentation.pdf",
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/36b1fe6319794a25ab6dfffb82e1b29b", "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/36b1fe6319794a25ab6dfffb82e1b29b",
"SupportURL": "https://github.com/Rexocrates/Mirror_Animation_System/issues", "SupportURL": "https://github.com/Rexocrates/Mirror_Animation_System/issues",
"EngineVersion": "4.27.0", "EngineVersion": "5.4.0",
"CanContainContent": false, "CanContainContent": false,
"Installed": true, "Installed": true,
"Modules": [ "Modules": [
@ -18,19 +18,19 @@
"Name": "MirrorAnimationSystem", "Name": "MirrorAnimationSystem",
"Type": "Runtime", "Type": "Runtime",
"LoadingPhase": "PreDefault", "LoadingPhase": "PreDefault",
"WhitelistPlatforms": [ "Win64", "Win32", "PS4", "XboxOne", "Mac" ] "WhitelistPlatforms": [ "Win64" ]
}, },
{ {
"Name": "MirrorAnimationSystemDev", "Name": "MirrorAnimationSystemDev",
"Type": "DeveloperTool", "Type": "DeveloperTool",
"LoadingPhase": "PreDefault", "LoadingPhase": "PreDefault",
"WhitelistPlatforms": [ "Win64", "Win32", "PS4", "XboxOne", "Mac" ] "WhitelistPlatforms": [ "Win64" ]
}, },
{ {
"Name": "MirrorAnimationSystemEditor", "Name": "MirrorAnimationSystemEditor",
"Type": "Editor", "Type": "Editor",
"LoadingPhase": "PreDefault", "LoadingPhase": "PreDefault",
"WhitelistPlatforms": [ "Win64", "Win32", "PS4", "XboxOne", "Mac" ] "WhitelistPlatforms": [ "Win64" ]
} }
] ]
} }

View file

@ -11,8 +11,7 @@
#if WITH_EDITOR #if WITH_EDITOR
#include "AssetToolsModule.h" #include "AssetToolsModule.h"
#include "AssetRegistryModule.h" #include "AssetRegistry/AssetRegistryModule.h"
#include "Toolkits/AssetEditorManager.h"
#include "Framework/Notifications/NotificationManager.h" #include "Framework/Notifications/NotificationManager.h"
#include "Widgets/Notifications/SNotificationList.h" #include "Widgets/Notifications/SNotificationList.h"
@ -153,8 +152,13 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi
int NumMirrorBones = MirrorTable->MirrorBones.Num(); int NumMirrorBones = MirrorTable->MirrorBones.Num();
int NumFrames = MirrorSequence->GetNumberOfFrames(); int NumFrames = MirrorSequence->GetNumberOfFrames();
TArray<FRawAnimSequenceTrack> SourceRawAnimDatas = MirrorSequence->GetRawAnimationData(); IAnimationDataController& MirrorSequenceController = MirrorSequence->GetController();
const auto& TrackNames = MirrorSequence->GetAnimationTrackNames(); TArray<FBoneAnimationTrack> SourceBoneAnimData = MirrorSequenceController.GetModel()->GetBoneAnimationTracks();
/************* SourceRawAnimDatas should be replaced by SourceBoneAnimData ************/
// TArray<FRawAnimSequenceTrack> SourceRawAnimDatas = MirrorSequence->GetRawAnimationData();
TArray<FName> TrackNames;
MirrorSequenceController.GetModel()->GetBoneTrackNames(TrackNames);
for (int i = 0; i < NumMirrorBones; i++) for (int i = 0; i < NumMirrorBones; i++)
{ {
@ -180,66 +184,67 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi
continue; continue;
} }
TArray <FVector> MirrorPosKeys; TArray <FVector3f> MirrorPosKeys;
TArray <FQuat> MirrorRotKeys; TArray <FQuat4f> MirrorRotKeys;
TArray <FVector> MirrorScaleKeys; TArray <FVector3f> MirrorScaleKeys;
TArray <FVector> TwinMirrorPosKeys; TArray <FVector3f> TwinMirrorPosKeys;
TArray <FQuat> TwinMirrorRotKeys; TArray <FQuat4f> TwinMirrorRotKeys;
TArray <FVector> TwinMirrorScaleKeys; TArray <FVector3f> TwinMirrorScaleKeys;
// Original Bone // Original Bone
if (TrackIndex != INDEX_NONE) if (TrackIndex != INDEX_NONE)
{ {
auto& MirroredRawTrack = SourceRawAnimDatas[TrackIndex]; auto& MirroredRawTrack = SourceBoneAnimData[TrackIndex];
for (int u = 0; u < NumFrames; u++) for (int u = 0; u < NumFrames; u++)
{ {
FTransform MirrorTM; FTransform3f MirrorTM;
bool bSetPos = false; bool bSetPos = false;
bool bSetRot = false; bool bSetRot = false;
bool bSetScale = false; bool bSetScale = false;
if (MirroredRawTrack.PosKeys.IsValidIndex(u)) if (MirroredRawTrack.InternalTrackData.PosKeys.IsValidIndex(u))
{ {
MirrorTM.SetTranslation(MirroredRawTrack.PosKeys[u]); MirrorTM.SetTranslation(MirroredRawTrack.InternalTrackData.PosKeys[u]);
bSetPos = true; bSetPos = true;
} }
if (MirroredRawTrack.RotKeys.IsValidIndex(u)) if (MirroredRawTrack.InternalTrackData.RotKeys.IsValidIndex(u))
{ {
MirrorTM.SetRotation(MirroredRawTrack.RotKeys[u]); MirrorTM.SetRotation(MirroredRawTrack.InternalTrackData.RotKeys[u]);
bSetRot = true; bSetRot = true;
} }
if (MirroredRawTrack.ScaleKeys.IsValidIndex(u)) if (MirroredRawTrack.InternalTrackData.ScaleKeys.IsValidIndex(u))
{ {
MirrorTM.SetScale3D(MirroredRawTrack.ScaleKeys[u]); MirrorTM.SetScale3D(MirroredRawTrack.InternalTrackData.ScaleKeys[u]);
bSetScale = true; bSetScale = true;
} }
MirrorTM.Mirror(CurrentBone.MirrorAxis, CurrentBone.FlipAxis); MirrorTM.Mirror(CurrentBone.MirrorAxis, CurrentBone.FlipAxis);
FRotator BoneNewRotation = MirrorTM.Rotator();
FRotator3f BoneNewRotation = MirrorTM.Rotator(); // quaternion to rotator
BoneNewRotation.Yaw += CurrentBone.RotationOffset.Yaw; BoneNewRotation.Yaw += CurrentBone.RotationOffset.Yaw;
BoneNewRotation.Roll += CurrentBone.RotationOffset.Roll; BoneNewRotation.Roll += CurrentBone.RotationOffset.Roll;
BoneNewRotation.Pitch += CurrentBone.RotationOffset.Pitch; BoneNewRotation.Pitch += CurrentBone.RotationOffset.Pitch;
MirrorTM.SetRotation(FQuat(BoneNewRotation)); MirrorTM.SetRotation(BoneNewRotation.Quaternion());
MirrorTM.SetScale3D(MirrorTM.GetScale3D().GetAbs()); MirrorTM.SetScale3D(MirrorTM.GetScale3D().GetAbs());
MirrorTM.NormalizeRotation(); MirrorTM.NormalizeRotation();
if (bSetPos) if (bSetPos)
{ {
MirrorPosKeys.Add(MirrorTM.GetTranslation()); MirrorPosKeys.Add(FVector3f(MirrorTM.GetTranslation()));
} }
if (bSetRot) if (bSetRot)
{ {
MirrorRotKeys.Add(MirrorTM.GetRotation()); MirrorRotKeys.Add(FQuat4f(MirrorTM.GetRotation()));
} }
if (bSetScale) if (bSetScale)
{ {
MirrorScaleKeys.Add(MirrorTM.GetScale3D()); MirrorScaleKeys.Add(FVector3f(MirrorTM.GetScale3D()));
} }
} }
} }
@ -259,62 +264,62 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi
RefTM.SetScale3D(RefTM.GetScale3D().GetAbs()); RefTM.SetScale3D(RefTM.GetScale3D().GetAbs());
RefTM.NormalizeRotation(); RefTM.NormalizeRotation();
MirrorPosKeys.Add(RefTM.GetTranslation()); MirrorPosKeys.Add(FVector3f(RefTM.GetTranslation()));
MirrorRotKeys.Add(RefTM.GetRotation()); MirrorRotKeys.Add(FQuat4f(RefTM.GetRotation()));
} }
// Twin Bone // Twin Bone
if (TwinTrackIndex != INDEX_NONE) if (TwinTrackIndex != INDEX_NONE)
{ {
auto& TwinMirroredRawTrack = SourceRawAnimDatas[TwinTrackIndex]; auto& TwinMirroredRawTrack = SourceBoneAnimData[TwinTrackIndex];
for (int u = 0; u < NumFrames; u++) for (int u = 0; u < NumFrames; u++)
{ {
FTransform TwinMirrorTM; FTransform3f TwinMirrorTM;
bool TwinbSetPos = false; bool TwinbSetPos = false;
bool TwinbSetRot = false; bool TwinbSetRot = false;
bool TwinbSetScale = false; bool TwinbSetScale = false;
if (TwinMirroredRawTrack.PosKeys.IsValidIndex(u)) if (TwinMirroredRawTrack.InternalTrackData.PosKeys.IsValidIndex(u))
{ {
TwinMirrorTM.SetTranslation(TwinMirroredRawTrack.PosKeys[u]); TwinMirrorTM.SetTranslation(TwinMirroredRawTrack.InternalTrackData.PosKeys[u]);
TwinbSetPos = true; TwinbSetPos = true;
} }
if (TwinMirroredRawTrack.RotKeys.IsValidIndex(u)) if (TwinMirroredRawTrack.InternalTrackData.RotKeys.IsValidIndex(u))
{ {
TwinMirrorTM.SetRotation(TwinMirroredRawTrack.RotKeys[u]); TwinMirrorTM.SetRotation(TwinMirroredRawTrack.InternalTrackData.RotKeys[u]);
TwinbSetRot = true; TwinbSetRot = true;
} }
if (TwinMirroredRawTrack.ScaleKeys.IsValidIndex(u)) if (TwinMirroredRawTrack.InternalTrackData.ScaleKeys.IsValidIndex(u))
{ {
TwinMirrorTM.SetScale3D(TwinMirroredRawTrack.ScaleKeys[u]); TwinMirrorTM.SetScale3D(TwinMirroredRawTrack.InternalTrackData.ScaleKeys[u]);
TwinbSetScale = true; TwinbSetScale = true;
} }
TwinMirrorTM.Mirror(CurrentBone.MirrorAxis, CurrentBone.FlipAxis); TwinMirrorTM.Mirror(CurrentBone.MirrorAxis, CurrentBone.FlipAxis);
FRotator TwinBoneNewRotation = TwinMirrorTM.Rotator(); FRotator3f TwinBoneNewRotation = TwinMirrorTM.Rotator();
TwinBoneNewRotation.Yaw += CurrentBone.RotationOffset.Yaw; TwinBoneNewRotation.Yaw += CurrentBone.RotationOffset.Yaw;
TwinBoneNewRotation.Roll += CurrentBone.RotationOffset.Roll; TwinBoneNewRotation.Roll += CurrentBone.RotationOffset.Roll;
TwinBoneNewRotation.Pitch += CurrentBone.RotationOffset.Pitch; TwinBoneNewRotation.Pitch += CurrentBone.RotationOffset.Pitch;
TwinMirrorTM.SetRotation(FQuat(TwinBoneNewRotation)); TwinMirrorTM.SetRotation(TwinBoneNewRotation.Quaternion());
TwinMirrorTM.SetScale3D(TwinMirrorTM.GetScale3D().GetAbs()); TwinMirrorTM.SetScale3D(TwinMirrorTM.GetScale3D().GetAbs());
TwinMirrorTM.NormalizeRotation(); TwinMirrorTM.NormalizeRotation();
if (TwinbSetPos) if (TwinbSetPos)
{ {
TwinMirrorPosKeys.Add(TwinMirrorTM.GetTranslation()); TwinMirrorPosKeys.Add(FVector3f(TwinMirrorTM.GetTranslation()));
} }
if (TwinbSetRot) if (TwinbSetRot)
{ {
TwinMirrorRotKeys.Add(TwinMirrorTM.GetRotation()); TwinMirrorRotKeys.Add(FQuat4f(TwinMirrorTM.GetRotation()));
} }
if (TwinbSetScale) if (TwinbSetScale)
{ {
TwinMirrorScaleKeys.Add(TwinMirrorTM.GetScale3D()); TwinMirrorScaleKeys.Add(FVector3f(TwinMirrorTM.GetScale3D()));
} }
} }
} }
@ -334,8 +339,8 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi
RefTM.SetScale3D(RefTM.GetScale3D().GetAbs()); RefTM.SetScale3D(RefTM.GetScale3D().GetAbs());
RefTM.NormalizeRotation(); RefTM.NormalizeRotation();
TwinMirrorPosKeys.Add(RefTM.GetTranslation()); TwinMirrorPosKeys.Add(FVector3f(RefTM.GetTranslation()));
TwinMirrorRotKeys.Add(RefTM.GetRotation()); TwinMirrorRotKeys.Add(FQuat4f(RefTM.GetRotation()));
} }
// Original Bone -> Twin Bone // Original Bone -> Twin Bone
@ -346,7 +351,9 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi
NewTrack.RotKeys = MirrorRotKeys; NewTrack.RotKeys = MirrorRotKeys;
NewTrack.ScaleKeys = MirrorScaleKeys; NewTrack.ScaleKeys = MirrorScaleKeys;
MirrorSequence->AddNewRawTrack(CurrentBone.TwinBoneName, &NewTrack); //MirrorSequence->AddNewRawTrack(CurrentBone.TwinBoneName, &NewTrack);
MirrorSequenceController.AddBoneTrack(CurrentBone.TwinBoneName);
MirrorSequenceController.SetBoneTrackKeys(CurrentBone.BoneName,NewTrack.PosKeys,NewTrack.RotKeys,NewTrack.ScaleKeys);
} }
// Twin Bone -> Original Bone // Twin Bone -> Original Bone
@ -357,7 +364,8 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi
NewTrack.RotKeys = TwinMirrorRotKeys; NewTrack.RotKeys = TwinMirrorRotKeys;
NewTrack.ScaleKeys = TwinMirrorScaleKeys; NewTrack.ScaleKeys = TwinMirrorScaleKeys;
MirrorSequence->AddNewRawTrack(CurrentBone.BoneName, &NewTrack); MirrorSequenceController.AddBoneTrack(CurrentBone.BoneName);
MirrorSequenceController.SetBoneTrackKeys(CurrentBone.BoneName,NewTrack.PosKeys,NewTrack.RotKeys,NewTrack.ScaleKeys);
} }
} }
else else
@ -369,47 +377,47 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi
continue; continue;
} }
FRawAnimSequenceTrack MirroredRawTrack = SourceRawAnimDatas[TrackIndex]; FBoneAnimationTrack MirroredRawTrack = SourceBoneAnimData[TrackIndex];
//MirrorAllFrames //MirrorAllFrames
TArray <FVector> MirrorPosKeys; TArray <FVector3f> MirrorPosKeys;
TArray <FQuat> MirrorRotKeys; TArray <FQuat4f> MirrorRotKeys;
TArray <FVector> MirrorScaleKeys; TArray <FVector3f> MirrorScaleKeys;
for (int u = 0; u < NumFrames; u++) for (int u = 0; u < NumFrames; u++)
{ {
//Mirror Transform //Mirror Transform
FTransform MirrorTM; FTransform3f MirrorTM;
bool bSetPos = false; bool bSetPos = false;
bool bSetRot = false; bool bSetRot = false;
bool bSetScale = false; bool bSetScale = false;
if (MirroredRawTrack.PosKeys.IsValidIndex(u)) if (MirroredRawTrack.InternalTrackData.PosKeys.IsValidIndex(u))
{ {
MirrorTM.SetTranslation(MirroredRawTrack.PosKeys[u]); MirrorTM.SetTranslation(MirroredRawTrack.InternalTrackData.PosKeys[u]);
bSetPos = true; bSetPos = true;
} }
if (MirroredRawTrack.RotKeys.IsValidIndex(u)) if (MirroredRawTrack.InternalTrackData.RotKeys.IsValidIndex(u))
{ {
MirrorTM.SetRotation(MirroredRawTrack.RotKeys[u]); MirrorTM.SetRotation(MirroredRawTrack.InternalTrackData.RotKeys[u]);
bSetRot = true; bSetRot = true;
} }
if (MirroredRawTrack.ScaleKeys.IsValidIndex(u)) if (MirroredRawTrack.InternalTrackData.ScaleKeys.IsValidIndex(u))
{ {
MirrorTM.SetScale3D(MirroredRawTrack.ScaleKeys[u]); MirrorTM.SetScale3D(MirroredRawTrack.InternalTrackData.ScaleKeys[u]);
bSetScale = true; bSetScale = true;
} }
MirrorTM.Mirror(CurrentBone.MirrorAxis, CurrentBone.FlipAxis); MirrorTM.Mirror(CurrentBone.MirrorAxis, CurrentBone.FlipAxis);
FRotator BoneNewRotation = MirrorTM.Rotator(); FRotator3f BoneNewRotation = MirrorTM.Rotator();
BoneNewRotation.Yaw += CurrentBone.RotationOffset.Yaw; BoneNewRotation.Yaw += CurrentBone.RotationOffset.Yaw;
BoneNewRotation.Roll += CurrentBone.RotationOffset.Roll; BoneNewRotation.Roll += CurrentBone.RotationOffset.Roll;
BoneNewRotation.Pitch += CurrentBone.RotationOffset.Pitch; BoneNewRotation.Pitch += CurrentBone.RotationOffset.Pitch;
MirrorTM.SetRotation(FQuat(BoneNewRotation)); MirrorTM.SetRotation(BoneNewRotation.Quaternion());
//MirrorTM.NormalizeRotation(); //MirrorTM.NormalizeRotation();
MirrorTM.SetScale3D(MirrorTM.GetScale3D().GetAbs()); MirrorTM.SetScale3D(MirrorTM.GetScale3D().GetAbs());
@ -432,44 +440,43 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi
///////////////////////////////// /////////////////////////////////
} }
MirroredRawTrack.PosKeys = MirrorPosKeys; MirroredRawTrack.InternalTrackData.PosKeys = MirrorPosKeys;
MirroredRawTrack.RotKeys = MirrorRotKeys; MirroredRawTrack.InternalTrackData.RotKeys = MirrorRotKeys;
MirroredRawTrack.ScaleKeys = MirrorScaleKeys; MirroredRawTrack.InternalTrackData.ScaleKeys = MirrorScaleKeys;
//Finally Setting it in the AnimSequence //Finally Setting it in the AnimSequence
MirrorSequence->AddNewRawTrack(CurrentBone.BoneName, &MirroredRawTrack); //MirrorSequenceController.AddBoneTrack(CurrentBone.BoneName, &MirroredRawTrack);
MirrorSequenceController.AddBoneCurve(CurrentBone.BoneName);
MirrorSequenceController.SetBoneTrackKeys(CurrentBone.BoneName,MirroredRawTrack.InternalTrackData.PosKeys,MirroredRawTrack.InternalTrackData.RotKeys,MirroredRawTrack.InternalTrackData.ScaleKeys);
} }
} }
MirrorSequence->ClearBakedTransformData(); //MirrorSequence->ClearBakedTransformData();
MirrorSequence->RawCurveData.TransformCurves.Empty(); MirrorSequenceController.RemoveAllCurvesOfType(ERawCurveTrackTypes::RCT_Transform);
MirrorSequence->bNeedsRebake = false;
MirrorSequence->MarkRawDataAsModified();
MirrorSequence->OnRawDataChanged();
MirrorSequence->MarkPackageDirty(); MirrorSequence->MarkPackageDirty();
} }
} }
static FTransform GetAnimBoneTM(UAnimSequence* AnimSeq, const int32 BoneTreeIndex, const float AnimTime) static FTransform3f GetAnimBoneTM(UAnimSequence* AnimSeq, const int32 BoneTreeIndex, const float AnimTime)
{ {
USkeleton* Skeleton = AnimSeq->GetSkeleton(); USkeleton* Skeleton = AnimSeq->GetSkeleton();
//int32 BoneTreeIndex = Skeleton->GetSkeletonBoneIndexFromMeshBoneIndex(SkelMesh, BoneTreeIndex); //int32 BoneTreeIndex = Skeleton->GetSkeletonBoneIndexFromMeshBoneIndex(SkelMesh, BoneTreeIndex);
int32 BoneTrackIndex = Skeleton->GetRawAnimationTrackIndex(BoneTreeIndex, AnimSeq); int32 BoneTrackIndex = Skeleton->GetRawAnimationTrackIndex(BoneTreeIndex, AnimSeq);
if (BoneTrackIndex == INDEX_NONE) if (BoneTrackIndex == INDEX_NONE)
{ {
return Skeleton->GetReferenceSkeleton().GetRefBonePose()[BoneTreeIndex]; return FTransform3f(Skeleton->GetReferenceSkeleton().GetRefBonePose()[BoneTreeIndex]);
} }
FTransform BoneTM = FTransform::Identity; FTransform BoneTM = FTransform::Identity;
AnimSeq->GetBoneTransform(BoneTM, BoneTrackIndex, AnimTime, true); AnimSeq->GetBoneTransform(BoneTM, BoneTrackIndex, AnimTime, true);
return BoneTM; return FTransform3f(BoneTM);
} }
static FTransform GetAnimBoneCSTM(UAnimSequence* AnimSeq, const int32 BoneTreeIndex, const float AnimTime) static FTransform3f GetAnimBoneCSTM(UAnimSequence* AnimSeq, const int32 BoneTreeIndex, const float AnimTime)
{ {
USkeleton* Skeleton = AnimSeq->GetSkeleton(); USkeleton* Skeleton = AnimSeq->GetSkeleton();
const auto& RefSkeleton = Skeleton->GetReferenceSkeleton(); const auto& RefSkeleton = Skeleton->GetReferenceSkeleton();
FTransform BoneTMWS = GetAnimBoneTM(AnimSeq, BoneTreeIndex, AnimTime); FTransform3f BoneTMWS = GetAnimBoneTM(AnimSeq, BoneTreeIndex, AnimTime);
int32 CurrBone = BoneTreeIndex; int32 CurrBone = BoneTreeIndex;
while (true) while (true)
{ {
@ -493,15 +500,16 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA
const FString Substring_B, const FString Substring_B,
const bool Symmetrical) const bool Symmetrical)
{ {
const int32 NumFrames = MirrorSequence->GetRawNumberOfFrames(); IAnimationDataController& Controller = MirrorSequence->GetController();
const float DT = MirrorSequence->SequenceLength / NumFrames; const int32 NumFrames = Controller.GetModel()->GetNumberOfFrames();
const float DT = MirrorSequence->GetPlayLength() / NumFrames;
USkeleton* Skeleton = MirrorSequence->GetSkeleton(); USkeleton* Skeleton = MirrorSequence->GetSkeleton();
const auto& RefSkeleton = Skeleton->GetReferenceSkeleton(); const auto& RefSkeleton = Skeleton->GetReferenceSkeleton();
TArray <bool> Already; Already.SetNumZeroed(Skeleton->GetBoneTree().Num()); TArray <bool> Already; Already.SetNumZeroed(Skeleton->GetReferenceSkeleton().GetRawBoneNum());
TArray<FIntPoint> TwinPairs; TArray<FIntPoint> TwinPairs;
TArray<int32> NonTwinIDs; TArray<int32> NonTwinIDs;
@ -510,7 +518,7 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA
const bool DeltaStep = !Symmetrical; const bool DeltaStep = !Symmetrical;
FVector TwinMirrorScale = FVector(1.f); FVector3f TwinMirrorScale = FVector3f(1.f);
FVector TargetAxis = FVector::ZeroVector; FVector TargetAxis = FVector::ZeroVector;
check(MirrorAxis != EAxis::None); check(MirrorAxis != EAxis::None);
@ -518,7 +526,7 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA
TwinMirrorScale[MirrorAxis - 1] = -1.f; TwinMirrorScale[MirrorAxis - 1] = -1.f;
TargetAxis[MirrorAxis - 1] = 1.f; TargetAxis[MirrorAxis - 1] = 1.f;
} }
FTransform TwinMirrorModTM(FQuat::Identity, FVector::ZeroVector, TwinMirrorScale); FTransform3f TwinMirrorModTM(FQuat4f::Identity, FVector3f::ZeroVector, TwinMirrorScale);
TMap<int32, FRawAnimSequenceTrack> BoneTracks; TMap<int32, FRawAnimSequenceTrack> BoneTracks;
@ -530,7 +538,7 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA
for (int32 j = 0; j < NumFrames; j++) for (int32 j = 0; j < NumFrames; j++)
{ {
TArray <FTransform> NewCSTMs; NewCSTMs.SetNum(RefSkeleton.GetNum()); TArray <FTransform3f> NewCSTMs; NewCSTMs.SetNum(RefSkeleton.GetNum());
for (int32 i = 0; i < NonTwinIDs.Num(); i++) for (int32 i = 0; i < NonTwinIDs.Num(); i++)
{ {
@ -542,17 +550,17 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA
const int32 ParentIndex = RefSkeleton.GetParentIndex(BoneTreeIndex); const int32 ParentIndex = RefSkeleton.GetParentIndex(BoneTreeIndex);
if (ParentIndex != INDEX_NONE) if (ParentIndex != INDEX_NONE)
{ {
NewCSTMs[BoneTreeIndex] = RefSkeleton.GetRefBonePose()[BoneTreeIndex] * NewCSTMs[ParentIndex]; NewCSTMs[BoneTreeIndex] = FTransform3f(RefSkeleton.GetRefBonePose()[BoneTreeIndex]) * NewCSTMs[ParentIndex];
} }
else else
{ {
NewCSTMs[BoneTreeIndex] = RefSkeleton.GetRefBonePose()[BoneTreeIndex]; NewCSTMs[BoneTreeIndex] = FTransform3f(RefSkeleton.GetRefBonePose()[BoneTreeIndex]);
} }
continue; continue;
} }
FTransform CSTM = GetAnimBoneCSTM(MirrorSequence, BoneTreeIndex, DT * j); FTransform3f CSTM = GetAnimBoneCSTM(MirrorSequence, BoneTreeIndex, DT * j);
CSTM.Mirror(MirrorAxis, NonTwinFlipAxis[i]); CSTM.Mirror(MirrorAxis, NonTwinFlipAxis[i]);
NewCSTMs[BoneTreeIndex] = CSTM; NewCSTMs[BoneTreeIndex] = CSTM;
@ -568,12 +576,12 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA
const FCompactPoseBoneIndex TwinCmptBoneIndex(TwinBoneIndex); const FCompactPoseBoneIndex TwinCmptBoneIndex(TwinBoneIndex);
const FTransform RefTM = FAnimationRuntime::GetComponentSpaceTransformRefPose(RefSkeleton, BoneIndex); const FTransform3f RefTM = FTransform3f(FAnimationRuntime::GetComponentSpaceTransformRefPose(RefSkeleton, BoneIndex));
const FTransform TwinRefTM = FAnimationRuntime::GetComponentSpaceTransformRefPose(RefSkeleton, TwinBoneIndex); const FTransform3f TwinRefTM = FTransform3f(FAnimationRuntime::GetComponentSpaceTransformRefPose(RefSkeleton, TwinBoneIndex));
const FTransform TM = GetAnimBoneCSTM(MirrorSequence, BoneIndex, DT * j); const FTransform3f TM = GetAnimBoneCSTM(MirrorSequence, BoneIndex, DT * j);
//Output.Pose.GetComponentSpaceTransform(CmptBoneIndex); //Output.Pose.GetComponentSpaceTransform(CmptBoneIndex);
const FTransform TwinTM = GetAnimBoneCSTM(MirrorSequence, TwinBoneIndex, DT * j); const FTransform3f TwinTM = GetAnimBoneCSTM(MirrorSequence, TwinBoneIndex, DT * j);
//Output.Pose.GetComponentSpaceTransform(TwinCmptBoneIndex); //Output.Pose.GetComponentSpaceTransform(TwinCmptBoneIndex);
const int32 ParentIndex = RefSkeleton.GetParentIndex(BoneIndex); const int32 ParentIndex = RefSkeleton.GetParentIndex(BoneIndex);
@ -581,49 +589,49 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA
const bool SameParent = ParentIndex == TwinParentIndex; const bool SameParent = ParentIndex == TwinParentIndex;
// twin 1º // twin 1<EFBFBD>
{ {
const FTransform MirrRef = RefTM * TwinMirrorModTM; const UE::Math::TTransform<float> MirrRef = RefTM * TwinMirrorModTM;
const FTransform Delta = TwinRefTM.GetRelativeTransform(MirrRef); const FTransform3f Delta = TwinRefTM.GetRelativeTransform(MirrRef);
const FQuat DeltaQuat = Delta.GetRotation(); const FQuat4f DeltaQuat = Delta.GetRotation();
FTransform MirrTM = TM * TwinMirrorModTM; FTransform3f MirrTM = TM * TwinMirrorModTM;
MirrTM.SetRotation(MirrTM.GetRotation() * DeltaQuat); MirrTM.SetRotation(MirrTM.GetRotation() * FQuat4f(DeltaQuat));
MirrTM.SetScale3D(TwinTM.GetScale3D()); MirrTM.SetScale3D(TwinTM.GetScale3D());
if (DeltaStep) if (DeltaStep)
{ {
if (SameParent) if (SameParent)
{ {
FTransform RefBS = RefTM; FTransform3f RefBS = RefTM;
RefBS = RefBS * TwinMirrorModTM; RefBS = RefBS * TwinMirrorModTM;
const FVector PosDelta = MirrTM.GetLocation() - RefBS.GetLocation(); const FVector3f PosDelta = MirrTM.GetLocation() - RefBS.GetLocation();
MirrTM.SetLocation(TwinRefTM.GetLocation() + PosDelta); MirrTM.SetLocation(FVector3f(TwinRefTM.GetLocation()) + PosDelta);
} }
else else
{ {
const FTransform& ParentTwinTM = NewCSTMs[RefSkeleton.GetParentIndex(TwinBoneIndex)]; const FTransform3f& ParentTwinTM = NewCSTMs[RefSkeleton.GetParentIndex(TwinBoneIndex)];
const FTransform& IParentTM =// Output.Pose.GetComponentSpaceTransform(FCompactPoseBoneIndex(ParentIndex)); const FTransform3f& IParentTM =// Output.Pose.GetComponentSpaceTransform(FCompactPoseBoneIndex(ParentIndex));
GetAnimBoneCSTM(MirrorSequence, ParentIndex, DT * j); GetAnimBoneCSTM(MirrorSequence, ParentIndex, DT * j);
FTransform RefBS = RefSkeleton.GetRefBonePose()[BoneIndex] * IParentTM; FTransform3f RefBS = FTransform3f(RefSkeleton.GetRefBonePose()[BoneIndex]) * IParentTM;
RefBS = RefBS * TwinMirrorModTM; RefBS = RefBS * TwinMirrorModTM;
RefBS.SetRotation(RefBS.GetRotation() * DeltaQuat); RefBS.SetRotation(RefBS.GetRotation() * DeltaQuat);
RefBS.SetScale3D(TwinTM.GetScale3D()); RefBS.SetScale3D(TwinTM.GetScale3D());
MirrTM = (MirrTM.GetRelativeTransform(RefBS) * RefSkeleton.GetRefBonePose()[TwinBoneIndex]) * ParentTwinTM; MirrTM = (MirrTM.GetRelativeTransform(RefBS) * FTransform3f(RefSkeleton.GetRefBonePose()[TwinBoneIndex])) * ParentTwinTM;
} }
} }
NewCSTMs[TwinBoneIndex] = MirrTM; NewCSTMs[TwinBoneIndex] = MirrTM;
} }
// twin 2º // twin 2<EFBFBD>
{ {
FTransform TwinMirrRef = TwinRefTM * TwinMirrorModTM; FTransform3f TwinMirrRef = TwinRefTM * TwinMirrorModTM;
const FQuat TwinDeltaQuat = TwinMirrRef.GetRotation().Inverse() * RefTM.GetRotation(); const FQuat4f TwinDeltaQuat = TwinMirrRef.GetRotation().Inverse() * RefTM.GetRotation();
FTransform TwinMirrTM = TwinTM * TwinMirrorModTM; FTransform3f TwinMirrTM = TwinTM * TwinMirrorModTM;
TwinMirrTM.SetRotation(TwinMirrTM.GetRotation() * TwinDeltaQuat); TwinMirrTM.SetRotation(TwinMirrTM.GetRotation() * TwinDeltaQuat);
TwinMirrTM.SetScale3D(TM.GetScale3D()); TwinMirrTM.SetScale3D(TM.GetScale3D());
@ -632,22 +640,22 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA
{ {
if (SameParent) if (SameParent)
{ {
FTransform TwinRefBS = TwinRefTM; FTransform3f TwinRefBS = TwinRefTM;
TwinRefBS = TwinRefBS * TwinMirrorModTM; TwinRefBS = TwinRefBS * TwinMirrorModTM;
const FVector PosDelta = TwinMirrTM.GetLocation() - TwinRefBS.GetLocation(); const FVector3f PosDelta = TwinMirrTM.GetLocation() - TwinRefBS.GetLocation();
TwinMirrTM.SetLocation(RefTM.GetLocation() + PosDelta); TwinMirrTM.SetLocation(RefTM.GetLocation() + PosDelta);
} }
else else
{ {
const FTransform& ParentTM = NewCSTMs[RefSkeleton.GetParentIndex(BoneIndex)]; const FTransform3f& ParentTM = NewCSTMs[RefSkeleton.GetParentIndex(BoneIndex)];
const FTransform& IParentTwinTM = //Output.Pose.GetComponentSpaceTransform(FCompactPoseBoneIndex(TwinParentIndex)); const FTransform3f& IParentTwinTM = //Output.Pose.GetComponentSpaceTransform(FCompactPoseBoneIndex(TwinParentIndex));
GetAnimBoneCSTM(MirrorSequence, TwinParentIndex, DT * j); GetAnimBoneCSTM(MirrorSequence, TwinParentIndex, DT * j);
FTransform TwinRefBS = RefSkeleton.GetRefBonePose()[TwinBoneIndex] * IParentTwinTM; FTransform3f TwinRefBS = FTransform3f(RefSkeleton.GetRefBonePose()[TwinBoneIndex]) * IParentTwinTM;
TwinRefBS = TwinRefBS * TwinMirrorModTM; TwinRefBS = TwinRefBS * TwinMirrorModTM;
TwinRefBS.SetRotation(TwinRefBS.GetRotation() * TwinDeltaQuat); TwinRefBS.SetRotation(TwinRefBS.GetRotation() * TwinDeltaQuat);
TwinRefBS.SetScale3D(TM.GetScale3D()); TwinRefBS.SetScale3D(TM.GetScale3D());
TwinMirrTM = (TwinMirrTM.GetRelativeTransform(TwinRefBS) * RefSkeleton.GetRefBonePose()[BoneIndex]) * ParentTM; TwinMirrTM = (TwinMirrTM.GetRelativeTransform(TwinRefBS) * FTransform3f(RefSkeleton.GetRefBonePose()[BoneIndex]) * ParentTM);
} }
} }
@ -659,7 +667,7 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA
for (int32 i = 0; i < NewCSTMs.Num(); i++) for (int32 i = 0; i < NewCSTMs.Num(); i++)
{ {
const int32 ParentIndex = RefSkeleton.GetParentIndex(i); const int32 ParentIndex = RefSkeleton.GetParentIndex(i);
FTransform BSTM; FTransform3f BSTM;
if (ParentIndex != INDEX_NONE) BSTM = NewCSTMs[i].GetRelativeTransform(NewCSTMs[ParentIndex]); if (ParentIndex != INDEX_NONE) BSTM = NewCSTMs[i].GetRelativeTransform(NewCSTMs[ParentIndex]);
else BSTM = NewCSTMs[i]; else BSTM = NewCSTMs[i];
@ -673,11 +681,13 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA
for (auto Pair : BoneTracks) for (auto Pair : BoneTracks)
{ {
const FName TrackName = Skeleton->GetReferenceSkeleton().GetBoneName(Pair.Key); const FName TrackName = Skeleton->GetReferenceSkeleton().GetBoneName(Pair.Key);
MirrorSequence->AddNewRawTrack(TrackName, &Pair.Value); //MirrorSequence->AddNewRawTrack(TrackName, &Pair.Value);
Controller.AddBoneCurve(TrackName);
Controller.SetBoneTrackKeys(TrackName,Pair.Value.PosKeys,Pair.Value.RotKeys,Pair.Value.ScaleKeys);
} }
// Have to also apply to pelvis and spine_01 // Have to also apply to pelvis and spine_01
MirrorSequence->MarkRawDataAsModified();
MirrorSequence->OnRawDataChanged();
MirrorSequence->MarkPackageDirty(); MirrorSequence->MarkPackageDirty();
} }