From 1ca18c395815b651c957bcd0eb10f12273e4f5db Mon Sep 17 00:00:00 2001 From: 4sval Date: Wed, 8 Feb 2023 21:23:55 +0100 Subject: [PATCH] play anim sequences consecutively --- CUE4Parse | 2 +- FModel/MainWindow.xaml.cs | 6 ++--- .../Snooper/Models/Animations/Animation.cs | 26 ++++++++++++------- .../Snooper/Models/Animations/Sequence.cs | 24 ++++++++++++++--- .../Snooper/Models/Animations/Skeleton.cs | 1 + 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/CUE4Parse b/CUE4Parse index e69c4c17..8f70ce98 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit e69c4c17cac920a0be25e531562c5cda9e482628 +Subproject commit 8f70ce981ed65ee9dcb4948905a58da2f3730a82 diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs index 8bd01cea..16bb1939 100644 --- a/FModel/MainWindow.xaml.cs +++ b/FModel/MainWindow.xaml.cs @@ -81,9 +81,9 @@ await _threadWorkerView.Begin(cancellationToken => await _threadWorkerView.Begin(cancellationToken => _applicationView.CUE4Parse.Extract(cancellationToken, "MoonMan/Content/DeliverUsTheMoon/Characters/Astronaut/AM_ControllingASE.uasset")); - // await _threadWorkerView.Begin(cancellationToken => - // _applicationView.CUE4Parse.Extract(cancellationToken, - // "Hk_project/Content/Animation/CAT/Jump/CAT_JUMP_L050_H-050.uasset")); + await _threadWorkerView.Begin(cancellationToken => + _applicationView.CUE4Parse.Extract(cancellationToken, + "MoonMan/Content/DeliverUsTheMoon/Characters/Astronaut/AM_OxygenHub_Enter.uasset")); #endif } diff --git a/FModel/Views/Snooper/Models/Animations/Animation.cs b/FModel/Views/Snooper/Models/Animations/Animation.cs index 08db9876..c64a0be4 100644 --- a/FModel/Views/Snooper/Models/Animations/Animation.cs +++ b/FModel/Views/Snooper/Models/Animations/Animation.cs @@ -1,22 +1,18 @@ using System; using System.Numerics; using CUE4Parse_Conversion.Animations; -using CUE4Parse.Utils; using ImGuiNET; namespace FModel.Views.Snooper.Models.Animations; public class Animation : IDisposable { - public float ElapsedTime; - public int CurrentSequence; public readonly Sequence[] Sequences; public int SequencesCount => Sequences.Length; public Animation() { - ElapsedTime = 0; Sequences = Array.Empty(); } @@ -31,8 +27,7 @@ public Animation(Skeleton skeleton, CAnimSet anim, bool rotationOnly) : this() public void Update(float deltaSeconds) { - ElapsedTime += deltaSeconds / Sequences[CurrentSequence].TimePerFrame; - Sequences[CurrentSequence].Frame = ElapsedTime.FloorToInt() % Sequences[CurrentSequence].MaxFrame; + Sequences[CurrentSequence].Update(deltaSeconds); } public Matrix4x4 InterpolateBoneTransform(int trackIndex) @@ -41,11 +36,24 @@ public Matrix4x4 InterpolateBoneTransform(int trackIndex) return Sequences[CurrentSequence].BonesTransform[trackIndex][Sequences[CurrentSequence].Frame].Matrix; } + public void CheckForNextSequence() + { + if (Sequences[CurrentSequence].ElapsedTime > Sequences[CurrentSequence].EndPos) + { + Sequences[CurrentSequence].ElapsedTime = 0; + Sequences[CurrentSequence].Frame = 0; + CurrentSequence++; + } + + if (CurrentSequence >= SequencesCount) + { + CurrentSequence = 0; + } + } + public void ImGuiTimeline() { - ImGui.BeginDisabled(SequencesCount < 2); - ImGui.DragInt("Sequence", ref CurrentSequence, 1, 0, Sequences.Length - 1, Sequences[CurrentSequence].Name); - ImGui.EndDisabled(); + ImGui.Text($"{Sequences[CurrentSequence].Name} > {(CurrentSequence < SequencesCount - 1 ? Sequences[CurrentSequence + 1].Name : Sequences[0].Name)}"); ImGui.Text($"Frame: {Sequences[CurrentSequence].Frame}/{Sequences[CurrentSequence].MaxFrame}"); ImGui.Text($"FPS: {Sequences[CurrentSequence].FramesPerSecond}"); } diff --git a/FModel/Views/Snooper/Models/Animations/Sequence.cs b/FModel/Views/Snooper/Models/Animations/Sequence.cs index a4ecf7d6..4b658d76 100644 --- a/FModel/Views/Snooper/Models/Animations/Sequence.cs +++ b/FModel/Views/Snooper/Models/Animations/Sequence.cs @@ -1,25 +1,37 @@ using System; using CUE4Parse_Conversion.Animations; +using CUE4Parse.Utils; namespace FModel.Views.Snooper.Models.Animations; public class Sequence : IDisposable { public int Frame; + public float ElapsedTime; public readonly string Name; public readonly int MaxFrame; public readonly float FramesPerSecond; + public readonly float StartPos; + public readonly float AnimStartTime; + public readonly float AnimEndTime; + public readonly int LoopingCount; public float TimePerFrame => 1.0f / FramesPerSecond; + public float EndPos => AnimEndTime / TimePerFrame; public readonly Transform[][] BonesTransform; public Sequence(CAnimSequence sequence, Skeleton skeleton, bool rotationOnly) { Frame = 0; + ElapsedTime = 0.0f; Name = sequence.Name; - MaxFrame = sequence.NumFrames; + MaxFrame = sequence.NumFrames - 1; FramesPerSecond = sequence.Rate; + StartPos = sequence.StartPos; + AnimStartTime = sequence.AnimStartTime; + AnimEndTime = sequence.AnimEndTime; + LoopingCount = sequence.LoopingCount; BonesTransform = new Transform[skeleton.BonesTransformByIndex.Count][]; for (int trackIndex = 0; trackIndex < skeleton.UnrealSkeleton.ReferenceSkeleton.FinalRefBoneInfo.Length; trackIndex++) @@ -30,14 +42,14 @@ public Sequence(CAnimSequence sequence, Skeleton skeleton, bool rotationOnly) var originalTransform = skeleton.BonesTransformByIndex[boneIndices.Index]; - BonesTransform[boneIndices.Index] = new Transform[MaxFrame]; + BonesTransform[boneIndices.Index] = new Transform[sequence.NumFrames]; for (int frame = 0; frame < BonesTransform[boneIndices.Index].Length; frame++) { var boneOrientation = originalTransform.Rotation; var bonePosition = originalTransform.Position; var boneScale = originalTransform.Scale; - sequence.Tracks[trackIndex].GetBonePosition(frame, MaxFrame, false, ref bonePosition, ref boneOrientation); + sequence.Tracks[trackIndex].GetBonePosition(frame, sequence.NumFrames, false, ref bonePosition, ref boneOrientation); if (frame < sequence.Tracks[trackIndex].KeyScale.Length) boneScale = sequence.Tracks[trackIndex].KeyScale[frame]; @@ -69,6 +81,12 @@ public Sequence(CAnimSequence sequence, Skeleton skeleton, bool rotationOnly) } } + public void Update(float deltaSeconds) + { + ElapsedTime += deltaSeconds / TimePerFrame; + Frame = Math.Min(ElapsedTime.FloorToInt(), MaxFrame); + } + public void Dispose() { throw new NotImplementedException(); diff --git a/FModel/Views/Snooper/Models/Animations/Skeleton.cs b/FModel/Views/Snooper/Models/Animations/Skeleton.cs index 6ec5a77b..754c549f 100644 --- a/FModel/Views/Snooper/Models/Animations/Skeleton.cs +++ b/FModel/Views/Snooper/Models/Animations/Skeleton.cs @@ -108,6 +108,7 @@ public void SetUniform(Shader shader, float deltaSeconds = 0f, bool update = fal shader.SetUniform($"uFinalBonesMatrix[{boneIndex}]", invertMatrix * Anim.InterpolateBoneTransform(boneIndex)); } + if (update) Anim.CheckForNextSequence(); } }