From 7231144e36c79a2038653501463f5add628a364a Mon Sep 17 00:00:00 2001 From: Lucas Peter Date: Fri, 7 Feb 2025 15:04:52 +0100 Subject: [PATCH] WIP:Fix sequenc emirror creation +cleanup --- .../Private/MASFunctionLibrary.cpp | 196 +++++++++++------- 1 file changed, 126 insertions(+), 70 deletions(-) diff --git a/Source/MirrorAnimationSystemDev/Private/MASFunctionLibrary.cpp b/Source/MirrorAnimationSystemDev/Private/MASFunctionLibrary.cpp index 97f4119..dd7cc05 100644 --- a/Source/MirrorAnimationSystemDev/Private/MASFunctionLibrary.cpp +++ b/Source/MirrorAnimationSystemDev/Private/MASFunctionLibrary.cpp @@ -28,10 +28,17 @@ UMASFunctionLibrary::UMASFunctionLibrary(const FObjectInitializer& ObjectInitial { } -void UMASFunctionLibrary::BulkMirrorEditorOnly(const TArray SourceAnims, const UMirrorTable* MirrorTable, TArray & OutNewAnims) +void UMASFunctionLibrary::BulkMirrorEditorOnly(const TArray SourceAnims, + const UMirrorTable* MirrorTable, TArray& OutNewAnims) { - if (SourceAnims.Num() == 0) return; - if (MirrorTable == NULL) return; + if (SourceAnims.Num() == 0) + { + return; + } + if (MirrorTable == nullptr) + { + return; + } #if WITH_EDITOR FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked("AssetTools"); @@ -45,13 +52,14 @@ void UMASFunctionLibrary::BulkMirrorEditorOnly(const TArray Sou FString Suffix = TEXT("_Mirrored"); - AssetToolsModule.Get().CreateUniqueAssetName(SourceAnims[i]->GetOutermost()->GetName(), Suffix, /*out*/ PackageName, /*out*/ Name); + AssetToolsModule.Get().CreateUniqueAssetName(SourceAnims[i]->GetOutermost()->GetName(), Suffix, /*out*/ + PackageName, /*out*/ Name); const FString PackagePath = FPackageName::GetLongPackagePath(PackageName); UObject* NewAsset = AssetToolsModule.Get().DuplicateAsset(Name, PackagePath, SourceAnims[i]); - if (NewAsset != NULL) + if (NewAsset != nullptr) { UAnimSequence* MirrorAnimSequence = Cast(NewAsset); CreateMirrorSequenceFromAnimSequence(MirrorAnimSequence, MirrorTable); @@ -64,13 +72,21 @@ void UMASFunctionLibrary::BulkMirrorEditorOnly(const TArray Sou // Display notification so users can quickly access if (GIsEditor) { - FNotificationInfo Info(FText::Format(LOCTEXT("AnimationMirrored", "Successfully Mirrored Animation"), FText::FromString(MirrorAnimSequence->GetName()))); + FNotificationInfo Info(FText::Format( + LOCTEXT("AnimationMirrored", "Successfully Mirrored Animation"), + FText::FromString(MirrorAnimSequence->GetName()))); Info.ExpireDuration = 8.0f; Info.bUseLargeFont = false; //Info.Hyperlink = FSimpleDelegate::CreateLambda([=]() { FAssetEditorManager::Get().OpenEditorForAssets(TArray({ MirrorAnimSequence })); }); - Info.Hyperlink = FSimpleDelegate::CreateLambda([=]() { GEditor->GetEditorSubsystem()->OpenEditorForAssets(TArray({ MirrorAnimSequence })); }); + Info.Hyperlink = FSimpleDelegate::CreateLambda([=]() + { + GEditor->GetEditorSubsystem()->OpenEditorForAssets(TArray({ + MirrorAnimSequence + })); + }); - Info.HyperlinkText = FText::Format(LOCTEXT("OpenNewAnimationHyperlink", "Open {0}"), FText::FromString(MirrorAnimSequence->GetName())); + Info.HyperlinkText = FText::Format( + LOCTEXT("OpenNewAnimationHyperlink", "Open {0}"), FText::FromString(MirrorAnimSequence->GetName())); TSharedPtr Notification = FSlateNotificationManager::Get().AddNotification(Info); if (Notification.IsValid()) { @@ -83,11 +99,18 @@ void UMASFunctionLibrary::BulkMirrorEditorOnly(const TArray Sou } MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::BulkMirror_CS_EditorOnly( - const TArray SourceAnims, - const TEnumAsByte MirrorAxis, const FString Substring_A, const FString Substring_B, const bool Symmetrical, TArray& OutNewAnims) + const TArray SourceAnims, + const TEnumAsByte MirrorAxis, const FString Substring_A, const FString Substring_B, + const bool Symmetrical, TArray& OutNewAnims) { - if (SourceAnims.Num() == 0) return; - if (MirrorAxis == EAxis::None) return; + if (SourceAnims.Num() == 0) + { + return; + } + if (MirrorAxis == EAxis::None) + { + return; + } #if WITH_EDITOR FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked("AssetTools"); @@ -101,16 +124,18 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::BulkMirror_CS_EditorOnly( FString Suffix = TEXT("_Mirrored"); - AssetToolsModule.Get().CreateUniqueAssetName(SourceAnims[i]->GetOutermost()->GetName(), Suffix, /*out*/ PackageName, /*out*/ Name); + AssetToolsModule.Get().CreateUniqueAssetName(SourceAnims[i]->GetOutermost()->GetName(), Suffix, /*out*/ + PackageName, /*out*/ Name); const FString PackagePath = FPackageName::GetLongPackagePath(PackageName); UObject* NewAsset = AssetToolsModule.Get().DuplicateAsset(Name, PackagePath, SourceAnims[i]); - if (NewAsset != NULL) + if (NewAsset != nullptr) { UAnimSequence* MirrorAnimSequence = Cast(NewAsset); - CreateMirrorSequenceFromAnimSequence_CS(MirrorAnimSequence, MirrorAxis, Substring_A, Substring_B, Symmetrical); + CreateMirrorSequenceFromAnimSequence_CS(MirrorAnimSequence, MirrorAxis, Substring_A, Substring_B, + Symmetrical); OutNewAnims.Add(MirrorAnimSequence); @@ -120,13 +145,21 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::BulkMirror_CS_EditorOnly( // Display notification so users can quickly access if (GIsEditor) { - FNotificationInfo Info(FText::Format(LOCTEXT("AnimationMirrored", "Successfully Mirrored Animation"), FText::FromString(MirrorAnimSequence->GetName()))); + FNotificationInfo Info(FText::Format( + LOCTEXT("AnimationMirrored", "Successfully Mirrored Animation"), + FText::FromString(MirrorAnimSequence->GetName()))); Info.ExpireDuration = 8.0f; Info.bUseLargeFont = false; //Info.Hyperlink = FSimpleDelegate::CreateLambda([=]() { FAssetEditorManager::Get().OpenEditorForAssets(TArray({ MirrorAnimSequence })); }); - Info.Hyperlink = FSimpleDelegate::CreateLambda([=]() { GEditor->GetEditorSubsystem()->OpenEditorForAssets(TArray({ MirrorAnimSequence })); }); + Info.Hyperlink = FSimpleDelegate::CreateLambda([=]() + { + GEditor->GetEditorSubsystem()->OpenEditorForAssets(TArray({ + MirrorAnimSequence + })); + }); - Info.HyperlinkText = FText::Format(LOCTEXT("OpenNewAnimationHyperlink", "Open {0}"), FText::FromString(MirrorAnimSequence->GetName())); + Info.HyperlinkText = FText::Format( + LOCTEXT("OpenNewAnimationHyperlink", "Open {0}"), FText::FromString(MirrorAnimSequence->GetName())); TSharedPtr Notification = FSlateNotificationManager::Get().AddNotification(Info); if (Notification.IsValid()) { @@ -140,10 +173,11 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::BulkMirror_CS_EditorOnly( #if WITH_EDITOR -void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* MirrorSequence, const UMirrorTable* MirrorTable) +void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* MirrorSequence, + const UMirrorTable* MirrorTable) { //Check if it's valid - if ((MirrorSequence != NULL) && (MirrorTable != NULL) && (MirrorSequence->GetSkeleton() != NULL)) + if ((MirrorSequence != nullptr) && (MirrorTable != nullptr) && (MirrorSequence->GetSkeleton() != nullptr)) { //Make the duplicate that I will edit //UAnimSequence* MirrorSequence = FromAnimSequence; @@ -153,12 +187,13 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi int NumFrames = MirrorSequence->GetNumberOfFrames(); IAnimationDataController& MirrorSequenceController = MirrorSequence->GetController(); - TArray SourceBoneAnimData = MirrorSequenceController.GetModel()->GetBoneAnimationTracks(); + const TArray& SourceBoneAnimData = MirrorSequenceController.GetModel()-> + GetBoneAnimationTracks(); /************* SourceRawAnimDatas should be replaced by SourceBoneAnimData ************/ // TArray SourceRawAnimDatas = MirrorSequence->GetRawAnimationData(); - - TArray TrackNames; - MirrorSequenceController.GetModel()->GetBoneTrackNames(TrackNames); + + TArray* TrackNames = new TArray; + MirrorSequenceController.GetModel()->GetBoneTrackNames(*TrackNames); for (int i = 0; i < NumMirrorBones; i++) { @@ -176,25 +211,26 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi continue; } - int32 TrackIndex = TrackNames.IndexOfByKey(CurrentBone.BoneName); - int32 TwinTrackIndex = TrackNames.IndexOfByKey(CurrentBone.TwinBoneName); + int32 TrackIndex = TrackNames->IndexOfByKey(CurrentBone.BoneName); + int32 TwinTrackIndex = TrackNames->IndexOfByKey(CurrentBone.TwinBoneName); if (TrackIndex == INDEX_NONE && TwinTrackIndex == INDEX_NONE) { continue; } - TArray MirrorPosKeys; - TArray MirrorRotKeys; - TArray MirrorScaleKeys; + TArray MirrorPosKeys; + TArray MirrorRotKeys; + TArray MirrorScaleKeys; - TArray TwinMirrorPosKeys; - TArray TwinMirrorRotKeys; - TArray TwinMirrorScaleKeys; + TArray TwinMirrorPosKeys; + TArray TwinMirrorRotKeys; + TArray TwinMirrorScaleKeys; // Original Bone if (TrackIndex != INDEX_NONE) { + check(SourceBoneAnimData.Num()>0); auto& MirroredRawTrack = SourceBoneAnimData[TrackIndex]; for (int u = 0; u < NumFrames; u++) @@ -222,8 +258,8 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi } MirrorTM.Mirror(CurrentBone.MirrorAxis, CurrentBone.FlipAxis); - - + + FRotator3f BoneNewRotation = MirrorTM.Rotator(); // quaternion to rotator BoneNewRotation.Yaw += CurrentBone.RotationOffset.Yaw; @@ -353,7 +389,8 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi //MirrorSequence->AddNewRawTrack(CurrentBone.TwinBoneName, &NewTrack); MirrorSequenceController.AddBoneTrack(CurrentBone.TwinBoneName); - MirrorSequenceController.SetBoneTrackKeys(CurrentBone.BoneName,NewTrack.PosKeys,NewTrack.RotKeys,NewTrack.ScaleKeys); + MirrorSequenceController.SetBoneTrackKeys(CurrentBone.BoneName, NewTrack.PosKeys, NewTrack.RotKeys, + NewTrack.ScaleKeys); } // Twin Bone -> Original Bone @@ -365,12 +402,14 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi NewTrack.ScaleKeys = TwinMirrorScaleKeys; MirrorSequenceController.AddBoneTrack(CurrentBone.BoneName); - MirrorSequenceController.SetBoneTrackKeys(CurrentBone.BoneName,NewTrack.PosKeys,NewTrack.RotKeys,NewTrack.ScaleKeys); + MirrorSequenceController.SetBoneTrackKeys(CurrentBone.BoneName, NewTrack.PosKeys, NewTrack.RotKeys, + NewTrack.ScaleKeys); } } else { - int32 TrackIndex = TrackNames.IndexOfByKey(CurrentBone.BoneName); + if (TrackNames) { continue; } + int32 TrackIndex = TrackNames->IndexOfByKey(CurrentBone.BoneName); if (TrackIndex == INDEX_NONE) { @@ -380,9 +419,9 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi FBoneAnimationTrack MirroredRawTrack = SourceBoneAnimData[TrackIndex]; //MirrorAllFrames - TArray MirrorPosKeys; - TArray MirrorRotKeys; - TArray MirrorScaleKeys; + TArray MirrorPosKeys; + TArray MirrorRotKeys; + TArray MirrorScaleKeys; for (int u = 0; u < NumFrames; u++) { @@ -448,7 +487,10 @@ void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence(UAnimSequence* Mi //MirrorSequenceController.AddBoneTrack(CurrentBone.BoneName, &MirroredRawTrack); MirrorSequenceController.AddBoneCurve(CurrentBone.BoneName); - MirrorSequenceController.SetBoneTrackKeys(CurrentBone.BoneName,MirroredRawTrack.InternalTrackData.PosKeys,MirroredRawTrack.InternalTrackData.RotKeys,MirroredRawTrack.InternalTrackData.ScaleKeys); + MirrorSequenceController.SetBoneTrackKeys(CurrentBone.BoneName, + MirroredRawTrack.InternalTrackData.PosKeys, + MirroredRawTrack.InternalTrackData.RotKeys, + MirroredRawTrack.InternalTrackData.ScaleKeys); } } //MirrorSequence->ClearBakedTransformData(); @@ -481,14 +523,13 @@ static FTransform3f GetAnimBoneCSTM(UAnimSequence* AnimSeq, const int32 BoneTree while (true) { const int32 Parent(RefSkeleton.GetParentIndex(CurrBone)); - if (Parent < 0) break; - else + if (Parent < 0) { - - BoneTMWS = BoneTMWS * GetAnimBoneTM(AnimSeq, Parent, AnimTime); - - CurrBone = Parent; + break; } + BoneTMWS = BoneTMWS * GetAnimBoneTM(AnimSeq, Parent, AnimTime); + + CurrBone = Parent; } return BoneTMWS; } @@ -496,8 +537,8 @@ static FTransform3f GetAnimBoneCSTM(UAnimSequence* AnimSeq, const int32 BoneTree MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromAnimSequence_CS( UAnimSequence* MirrorSequence, const TEnumAsByte MirrorAxis, - const FString Substring_A, - const FString Substring_B, + const FString Substring_A, + const FString Substring_B, const bool Symmetrical) { IAnimationDataController& Controller = MirrorSequence->GetController(); @@ -507,14 +548,15 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA USkeleton* Skeleton = MirrorSequence->GetSkeleton(); const auto& RefSkeleton = Skeleton->GetReferenceSkeleton(); - - - TArray Already; Already.SetNumZeroed(Skeleton->GetReferenceSkeleton().GetRawBoneNum()); + + TArray Already; + Already.SetNumZeroed(Skeleton->GetReferenceSkeleton().GetRawBoneNum()); TArray TwinPairs; TArray NonTwinIDs; TArray NonTwinFlipAxis; - FMASUtils::CSMirrorSettings(RefSkeleton, MirrorAxis, Substring_A, Substring_B, TwinPairs, NonTwinIDs, NonTwinFlipAxis); + FMASUtils::CSMirrorSettings(RefSkeleton, MirrorAxis, Substring_A, Substring_B, TwinPairs, NonTwinIDs, + NonTwinFlipAxis); const bool DeltaStep = !Symmetrical; @@ -530,7 +572,7 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA TMap BoneTracks; - + for (int32 i = 0; i < RefSkeleton.GetNum(); i++) { BoneTracks.Add(i, FRawAnimSequenceTrack()); @@ -538,7 +580,8 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA for (int32 j = 0; j < NumFrames; j++) { - TArray NewCSTMs; NewCSTMs.SetNum(RefSkeleton.GetNum()); + TArray NewCSTMs; + NewCSTMs.SetNum(RefSkeleton.GetNum()); for (int32 i = 0; i < NonTwinIDs.Num(); i++) { @@ -550,7 +593,8 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA const int32 ParentIndex = RefSkeleton.GetParentIndex(BoneTreeIndex); if (ParentIndex != INDEX_NONE) { - NewCSTMs[BoneTreeIndex] = FTransform3f(RefSkeleton.GetRefBonePose()[BoneTreeIndex]) * NewCSTMs[ParentIndex]; + NewCSTMs[BoneTreeIndex] = FTransform3f(RefSkeleton.GetRefBonePose()[BoneTreeIndex]) * NewCSTMs[ + ParentIndex]; } else { @@ -576,12 +620,14 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA const FCompactPoseBoneIndex TwinCmptBoneIndex(TwinBoneIndex); - const FTransform3f RefTM = FTransform3f(FAnimationRuntime::GetComponentSpaceTransformRefPose(RefSkeleton, BoneIndex)); - const FTransform3f TwinRefTM = FTransform3f(FAnimationRuntime::GetComponentSpaceTransformRefPose(RefSkeleton, TwinBoneIndex)); + const FTransform3f RefTM = FTransform3f( + FAnimationRuntime::GetComponentSpaceTransformRefPose(RefSkeleton, BoneIndex)); + const FTransform3f TwinRefTM = FTransform3f( + FAnimationRuntime::GetComponentSpaceTransformRefPose(RefSkeleton, TwinBoneIndex)); - const FTransform3f TM = GetAnimBoneCSTM(MirrorSequence, BoneIndex, DT * j); + const FTransform3f TM = GetAnimBoneCSTM(MirrorSequence, BoneIndex, DT * j); //Output.Pose.GetComponentSpaceTransform(CmptBoneIndex); - const FTransform3f TwinTM = GetAnimBoneCSTM(MirrorSequence, TwinBoneIndex, DT * j); + const FTransform3f TwinTM = GetAnimBoneCSTM(MirrorSequence, TwinBoneIndex, DT * j); //Output.Pose.GetComponentSpaceTransform(TwinCmptBoneIndex); const int32 ParentIndex = RefSkeleton.GetParentIndex(BoneIndex); @@ -612,14 +658,16 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA else { const FTransform3f& ParentTwinTM = NewCSTMs[RefSkeleton.GetParentIndex(TwinBoneIndex)]; - const FTransform3f& IParentTM =// Output.Pose.GetComponentSpaceTransform(FCompactPoseBoneIndex(ParentIndex)); + const FTransform3f& IParentTM = + // Output.Pose.GetComponentSpaceTransform(FCompactPoseBoneIndex(ParentIndex)); GetAnimBoneCSTM(MirrorSequence, ParentIndex, DT * j); FTransform3f RefBS = FTransform3f(RefSkeleton.GetRefBonePose()[BoneIndex]) * IParentTM; RefBS = RefBS * TwinMirrorModTM; RefBS.SetRotation(RefBS.GetRotation() * DeltaQuat); RefBS.SetScale3D(TwinTM.GetScale3D()); - MirrTM = (MirrTM.GetRelativeTransform(RefBS) * FTransform3f(RefSkeleton.GetRefBonePose()[TwinBoneIndex])) * ParentTwinTM; + MirrTM = (MirrTM.GetRelativeTransform(RefBS) * FTransform3f( + RefSkeleton.GetRefBonePose()[TwinBoneIndex])) * ParentTwinTM; } } @@ -648,14 +696,17 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA else { const FTransform3f& ParentTM = NewCSTMs[RefSkeleton.GetParentIndex(BoneIndex)]; - const FTransform3f& IParentTwinTM = //Output.Pose.GetComponentSpaceTransform(FCompactPoseBoneIndex(TwinParentIndex)); + const FTransform3f& IParentTwinTM = + //Output.Pose.GetComponentSpaceTransform(FCompactPoseBoneIndex(TwinParentIndex)); GetAnimBoneCSTM(MirrorSequence, TwinParentIndex, DT * j); - FTransform3f TwinRefBS = FTransform3f(RefSkeleton.GetRefBonePose()[TwinBoneIndex]) * IParentTwinTM; + FTransform3f TwinRefBS = FTransform3f(RefSkeleton.GetRefBonePose()[TwinBoneIndex]) * + IParentTwinTM; TwinRefBS = TwinRefBS * TwinMirrorModTM; TwinRefBS.SetRotation(TwinRefBS.GetRotation() * TwinDeltaQuat); TwinRefBS.SetScale3D(TM.GetScale3D()); - TwinMirrTM = (TwinMirrTM.GetRelativeTransform(TwinRefBS) * FTransform3f(RefSkeleton.GetRefBonePose()[BoneIndex]) * ParentTM); + TwinMirrTM = (TwinMirrTM.GetRelativeTransform(TwinRefBS) * FTransform3f( + RefSkeleton.GetRefBonePose()[BoneIndex]) * ParentTM); } } @@ -668,8 +719,14 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA { const int32 ParentIndex = RefSkeleton.GetParentIndex(i); FTransform3f BSTM; - if (ParentIndex != INDEX_NONE) BSTM = NewCSTMs[i].GetRelativeTransform(NewCSTMs[ParentIndex]); - else BSTM = NewCSTMs[i]; + if (ParentIndex != INDEX_NONE) + { + BSTM = NewCSTMs[i].GetRelativeTransform(NewCSTMs[ParentIndex]); + } + else + { + BSTM = NewCSTMs[i]; + } auto& BoneTrack = BoneTracks[i]; BoneTrack.PosKeys.Add(BSTM.GetLocation()); @@ -683,8 +740,7 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA const FName TrackName = Skeleton->GetReferenceSkeleton().GetBoneName(Pair.Key); //MirrorSequence->AddNewRawTrack(TrackName, &Pair.Value); Controller.AddBoneCurve(TrackName); - Controller.SetBoneTrackKeys(TrackName,Pair.Value.PosKeys,Pair.Value.RotKeys,Pair.Value.ScaleKeys); - + Controller.SetBoneTrackKeys(TrackName, Pair.Value.PosKeys, Pair.Value.RotKeys, Pair.Value.ScaleKeys); } // Have to also apply to pelvis and spine_01 @@ -693,4 +749,4 @@ MIRRORANIMATIONSYSTEMDEV_API void UMASFunctionLibrary::CreateMirrorSequenceFromA #endif -#undef LOCTEXT_NAMESPACE \ No newline at end of file +#undef LOCTEXT_NAMESPACE