fixed outliner + reverse matrix per model + update ssbo only if needed

This commit is contained in:
4sval 2023-02-14 23:34:32 +01:00
parent a01ef4a792
commit ffd871b755
6 changed files with 50 additions and 49 deletions

View File

@ -98,6 +98,8 @@ public class PickingTexture : IDisposable
return pixel;
}
public IntPtr GetPointer() => (IntPtr) _pickingTexture;
public void WindowResized(int width, int height)
{
_width = width;

View File

@ -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<Sequence>();
InvertedBonesMatrix = Array.Empty<Matrix4x4>();
}
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()

View File

@ -0,0 +1,7 @@
namespace FModel.Views.Snooper.Models.Animations;
public struct BoneIndice
{
public int Index;
public int ParentIndex;
}

View File

@ -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
};
}
}

View File

@ -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<string, BoneIndice> BonesIndicesByLoweredName;
public readonly Dictionary<int, Transform> 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<string, BoneIndice>();
BonesTransformByIndex = new Dictionary<int, Transform>();
InvertedBonesMatrix = Array.Empty<Matrix4x4>();
}
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<Matrix4x4>(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();

View File

@ -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)
{