From ffd871b755921fc97f83d8df9257ed91008d41cd Mon Sep 17 00:00:00 2001 From: 4sval Date: Tue, 14 Feb 2023 23:34:32 +0100 Subject: [PATCH] fixed outliner + reverse matrix per model + update ssbo only if needed --- .../Views/Snooper/Buffers/PickingTexture.cs | 2 ++ .../Snooper/Models/Animations/Animation.cs | 23 +----------- .../Snooper/Models/Animations/BoneIndice.cs | 7 ++++ .../Snooper/Models/Animations/Sequence.cs | 30 +++++++++------- .../Snooper/Models/Animations/Skeleton.cs | 35 +++++++++++-------- FModel/Views/Snooper/Models/Model.cs | 2 ++ 6 files changed, 50 insertions(+), 49 deletions(-) create mode 100644 FModel/Views/Snooper/Models/Animations/BoneIndice.cs diff --git a/FModel/Views/Snooper/Buffers/PickingTexture.cs b/FModel/Views/Snooper/Buffers/PickingTexture.cs index cb56c5a8..6a8a0d44 100644 --- a/FModel/Views/Snooper/Buffers/PickingTexture.cs +++ b/FModel/Views/Snooper/Buffers/PickingTexture.cs @@ -98,6 +98,8 @@ public class PickingTexture : IDisposable return pixel; } + public IntPtr GetPointer() => (IntPtr) _pickingTexture; + public void WindowResized(int width, int height) { _width = width; diff --git a/FModel/Views/Snooper/Models/Animations/Animation.cs b/FModel/Views/Snooper/Models/Animations/Animation.cs index cb671646..8d273dca 100644 --- a/FModel/Views/Snooper/Models/Animations/Animation.cs +++ b/FModel/Views/Snooper/Models/Animations/Animation.cs @@ -3,7 +3,6 @@ using System.Numerics; using CUE4Parse_Conversion.Animations; using CUE4Parse.Utils; using ImGuiNET; -using Serilog; namespace FModel.Views.Snooper.Models.Animations; @@ -28,8 +27,6 @@ public class Animation : IDisposable public readonly Sequence[] Sequences; public int SequencesCount => Sequences.Length; - public readonly Matrix4x4[] InvertedBonesMatrix; - public Animation() { Reset(); @@ -38,27 +35,10 @@ public class Animation : IDisposable EndTime = 0.0f; TotalElapsedTime = 0.0f; Sequences = Array.Empty(); - InvertedBonesMatrix = Array.Empty(); } public Animation(Skeleton skeleton, CAnimSet anim, bool rotationOnly) : this() { - InvertedBonesMatrix = new Matrix4x4[skeleton.BoneCount]; - for (int boneIndex = 0; boneIndex < InvertedBonesMatrix.Length; boneIndex++) - { - Matrix4x4.Invert(skeleton.BonesTransformByIndex[boneIndex].Matrix, out var inverted); - InvertedBonesMatrix[boneIndex] = inverted; - } - -#if DEBUG - for (int trackIndex = 0; trackIndex < anim.TrackBonesInfo.Length; trackIndex++) - { - var bone = anim.TrackBonesInfo[trackIndex]; - if (!skeleton.BonesIndicesByLoweredName.TryGetValue(bone.Name.Text.ToLower(), out _)) - Log.Warning($"Bone Mismatch: {bone.Name.Text} ({trackIndex}) is not present in the mesh's reference skeleton"); - } -#endif - Sequences = new Sequence[anim.Sequences.Count]; for (int i = 0; i < Sequences.Length; i++) { @@ -83,8 +63,7 @@ public class Animation : IDisposable public Matrix4x4 InterpolateBoneTransform(int boneIndex) { // interpolate here - return InvertedBonesMatrix[boneIndex] * - Sequences[CurrentSequence].BonesTransform[boneIndex][FrameInSequence].Matrix; + return Sequences[CurrentSequence].BonesTransform[boneIndex][FrameInSequence].Matrix; } private void TimeCalculation() diff --git a/FModel/Views/Snooper/Models/Animations/BoneIndice.cs b/FModel/Views/Snooper/Models/Animations/BoneIndice.cs new file mode 100644 index 00000000..bf820230 --- /dev/null +++ b/FModel/Views/Snooper/Models/Animations/BoneIndice.cs @@ -0,0 +1,7 @@ +namespace FModel.Views.Snooper.Models.Animations; + +public struct BoneIndice +{ + public int Index; + public int ParentIndex; +} diff --git a/FModel/Views/Snooper/Models/Animations/Sequence.cs b/FModel/Views/Snooper/Models/Animations/Sequence.cs index 2f3d88b6..be76e014 100644 --- a/FModel/Views/Snooper/Models/Animations/Sequence.cs +++ b/FModel/Views/Snooper/Models/Animations/Sequence.cs @@ -5,6 +5,7 @@ using CUE4Parse.UE4.Assets.Exports.Animation; using CUE4Parse.UE4.Objects.Core.Math; using CUE4Parse.Utils; using ImGuiNET; +using Serilog; namespace FModel.Views.Snooper.Models.Animations; @@ -34,10 +35,10 @@ public class Sequence : IDisposable public Sequence(Skeleton skeleton, CAnimSet anim, CAnimSequence sequence, bool rotationOnly) : this(sequence) { BonesTransform = new Transform[skeleton.BoneCount][]; + for (int trackIndex = 0; trackIndex < anim.TrackBonesInfo.Length; trackIndex++) { - var bone = anim.TrackBonesInfo[trackIndex]; - if (!skeleton.BonesIndicesByLoweredName.TryGetValue(bone.Name.Text.ToLower(), out var boneIndices)) + if (!skeleton.BonesIndicesByLoweredName.TryGetValue(anim.TrackBonesInfo[trackIndex].Name.Text.ToLower(), out var boneIndices)) continue; var originalTransform = skeleton.BonesTransformByIndex[boneIndices.Index]; @@ -114,21 +115,26 @@ public class Sequence : IDisposable } } - foreach (var boneIndices in skeleton.BonesIndicesByLoweredName.Values) + // TODO: move this out of each fucking sequence + foreach ((var boneName, var boneIndices) in skeleton.BonesIndicesByLoweredName) { - if (BonesTransform[boneIndices.Index] != null) continue; + var boneIndex = boneIndices.Index; + if (BonesTransform[boneIndex] != null) continue; +#if DEBUG + Log.Warning($"Bone Mismatch: {boneName} ({boneIndex}) was not present in {sequence.Name}'s target skeleton"); +#endif - var old = skeleton.BonesTransformByIndex[boneIndices.Index]; + var originalTransform = skeleton.BonesTransformByIndex[boneIndex]; - BonesTransform[boneIndices.Index] = new Transform[sequence.NumFrames]; - for (int frame = 0; frame < BonesTransform[boneIndices.Index].Length; frame++) + BonesTransform[boneIndex] = new Transform[sequence.NumFrames]; + for (int frame = 0; frame < BonesTransform[boneIndex].Length; frame++) { - BonesTransform[boneIndices.Index][frame] = new Transform + BonesTransform[boneIndex][frame] = new Transform { - Relation = BonesTransform[boneIndices.ParentIndex][frame].Matrix, - Rotation = old.Rotation, - Position = old.Position, - Scale = old.Scale + Relation = boneIndices.ParentIndex >= 0 ? BonesTransform[boneIndices.ParentIndex][frame].Matrix : originalTransform.Relation, + Rotation = originalTransform.Rotation, + Position = originalTransform.Position, + Scale = originalTransform.Scale }; } } diff --git a/FModel/Views/Snooper/Models/Animations/Skeleton.cs b/FModel/Views/Snooper/Models/Animations/Skeleton.cs index 9a03d79a..f0834ef7 100644 --- a/FModel/Views/Snooper/Models/Animations/Skeleton.cs +++ b/FModel/Views/Snooper/Models/Animations/Skeleton.cs @@ -8,12 +8,6 @@ using OpenTK.Graphics.OpenGL4; namespace FModel.Views.Snooper.Models.Animations; -public struct BoneIndice -{ - public int Index; - public int ParentIndex; -} - public class Skeleton : IDisposable { private int _handle; @@ -22,7 +16,8 @@ public class Skeleton : IDisposable public string Name; public readonly Dictionary BonesIndicesByLoweredName; public readonly Dictionary BonesTransformByIndex; - public readonly int BoneCount; + public readonly Matrix4x4[] InvertedBonesMatrix; + public int BoneCount => InvertedBonesMatrix.Length; public Animation Anim; public bool HasAnim => Anim != null; @@ -31,6 +26,7 @@ public class Skeleton : IDisposable { BonesIndicesByLoweredName = new Dictionary(); BonesTransformByIndex = new Dictionary(); + InvertedBonesMatrix = Array.Empty(); } public Skeleton(FReferenceSkeleton referenceSkeleton) : this() @@ -41,6 +37,7 @@ public class Skeleton : IDisposable BonesIndicesByLoweredName[info.Name.Text.ToLower()] = new BoneIndice { Index = boneIndex, ParentIndex = info.ParentIndex }; } + InvertedBonesMatrix = new Matrix4x4[BonesIndicesByLoweredName.Count]; foreach (var boneIndices in BonesIndicesByLoweredName.Values) { var bone = referenceSkeleton.FinalRefBonePose[boneIndices.Index]; @@ -58,10 +55,12 @@ public class Skeleton : IDisposable parentTransform = new Transform { Relation = Matrix4x4.Identity }; boneTransform.Relation = parentTransform.Matrix; - BonesTransformByIndex[boneIndices.Index] = boneTransform; - } + Matrix4x4.Invert(boneTransform.Matrix, out var inverted); - BoneCount = BonesTransformByIndex.Count; + + BonesTransformByIndex[boneIndices.Index] = boneTransform; + InvertedBonesMatrix[boneIndices.Index] = inverted; + } } public void SetAnimation(CAnimSet anim, bool rotationOnly) @@ -76,22 +75,28 @@ public class Skeleton : IDisposable _ssbo = new BufferObject(BoneCount, BufferTarget.ShaderStorageBuffer); for (int boneIndex = 0; boneIndex < BoneCount; boneIndex++) _ssbo.Update(boneIndex, Matrix4x4.Identity); - _ssbo.BindBufferBase(1); } + private int _previousFrame; public void UpdateMatrices(float deltaSeconds) { if (!HasAnim) return; - _ssbo.BindBufferBase(1); - Anim.Update(deltaSeconds); - for (int boneIndex = 0; boneIndex < BoneCount; boneIndex++) - _ssbo.Update(boneIndex, Anim.InterpolateBoneTransform(boneIndex)); + if (_previousFrame == Anim.FrameInSequence) return; + _previousFrame = Anim.FrameInSequence; + _ssbo.Bind(); + for (int boneIndex = 0; boneIndex < BoneCount; boneIndex++) + _ssbo.Update(boneIndex, InvertedBonesMatrix[boneIndex] * Anim.InterpolateBoneTransform(boneIndex)); _ssbo.Unbind(); } + public void Render() + { + _ssbo.BindBufferBase(1); + } + public void Dispose() { BonesIndicesByLoweredName.Clear(); diff --git a/FModel/Views/Snooper/Models/Model.cs b/FModel/Views/Snooper/Models/Model.cs index 117e7d06..3e8a7475 100644 --- a/FModel/Views/Snooper/Models/Model.cs +++ b/FModel/Views/Snooper/Models/Model.cs @@ -387,6 +387,7 @@ public class Model : IDisposable _vao.Bind(); shader.SetUniform("uMorphTime", MorphTime); + if (HasSkeleton) Skeleton.Render(); if (!outline) { shader.SetUniform("uUvCount", UvCount); @@ -417,6 +418,7 @@ public class Model : IDisposable _vao.Bind(); shader.SetUniform("uMorphTime", MorphTime); + if (HasSkeleton) Skeleton.Render(); foreach (var section in Sections) {