mirror of
https://github.com/4sval/FModel.git
synced 2026-03-22 01:34:37 -05:00
fixed outliner + reverse matrix per model + update ssbo only if needed
This commit is contained in:
parent
a01ef4a792
commit
ffd871b755
|
|
@ -98,6 +98,8 @@ public class PickingTexture : IDisposable
|
|||
return pixel;
|
||||
}
|
||||
|
||||
public IntPtr GetPointer() => (IntPtr) _pickingTexture;
|
||||
|
||||
public void WindowResized(int width, int height)
|
||||
{
|
||||
_width = width;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
7
FModel/Views/Snooper/Models/Animations/BoneIndice.cs
Normal file
7
FModel/Views/Snooper/Models/Animations/BoneIndice.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace FModel.Views.Snooper.Models.Animations;
|
||||
|
||||
public struct BoneIndice
|
||||
{
|
||||
public int Index;
|
||||
public int ParentIndex;
|
||||
}
|
||||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user