diff --git a/FModel/Views/Snooper/Animations/Skeleton.cs b/FModel/Views/Snooper/Animations/Skeleton.cs index a2cf922f..47bd8f10 100644 --- a/FModel/Views/Snooper/Animations/Skeleton.cs +++ b/FModel/Views/Snooper/Animations/Skeleton.cs @@ -22,6 +22,7 @@ public class Skeleton : IDisposable public readonly int BoneCount; public readonly Dictionary BonesByLoweredName; + private Matrix4x4[] _boneMatriceAtFrame; public Skeleton() { @@ -116,6 +117,12 @@ public class Skeleton : IDisposable _ssbo = new BufferObject(BoneCount, BufferTarget.ShaderStorageBuffer); _ssbo.UpdateRange(BoneCount, Matrix4x4.Identity); + + _boneMatriceAtFrame = new Matrix4x4[BoneCount]; + for (int boneIndex = 0; boneIndex < _boneMatriceAtFrame.Length; boneIndex++) + { + _boneMatriceAtFrame[boneIndex] = Matrix4x4.Identity; + } } public void UpdateAnimationMatrices(Animation animation, bool rotationOnly) @@ -126,7 +133,7 @@ public class Skeleton : IDisposable foreach (var bone in BonesByLoweredName.Values) { - var boneRelation = bone.IsRoot ? bone.Rest.Relation : bone.Rest.LocalMatrix * _ssbo.Get(bone.ParentIndex); + var boneMatrix = bone.IsRoot ? bone.Rest.Relation : bone.Rest.LocalMatrix * _boneMatriceAtFrame[bone.ParentIndex]; if (bone.IsAnimated) { var (s, f) = GetBoneFrameData(bone, animation); @@ -136,18 +143,20 @@ public class Skeleton : IDisposable var boneScale = bone.Rest.Scale; sequence.Tracks[bone.SkeletonIndex].GetBoneTransform(f, sequence.NumFrames, ref boneOrientation, ref bonePosition, ref boneScale); - if (!bone.IsRoot) boneRelation = _ssbo.Get(bone.ParentIndex); + if (!bone.IsRoot) boneMatrix = _boneMatriceAtFrame[bone.ParentIndex]; bonePosition = rotationOnly ? bone.Rest.Position : bonePosition * Constants.SCALE_DOWN_RATIO; - _ssbo.Update(bone.Index, new Transform + boneMatrix = new Transform { - Relation = boneRelation, + Relation = boneMatrix, Rotation = boneOrientation, Position = bonePosition, Scale = boneScale - }.Matrix); + }.Matrix; } - else _ssbo.Update(bone.Index, boneRelation); + + _ssbo.Update(bone.Index, boneMatrix); + _boneMatriceAtFrame[bone.Index] = boneMatrix; } _ssbo.Unbind(); diff --git a/FModel/Views/Snooper/Buffers/BufferObject.cs b/FModel/Views/Snooper/Buffers/BufferObject.cs index 16ad16dc..028b95e0 100644 --- a/FModel/Views/Snooper/Buffers/BufferObject.cs +++ b/FModel/Views/Snooper/Buffers/BufferObject.cs @@ -6,24 +6,26 @@ namespace FModel.Views.Snooper.Buffers; public class BufferObject : IDisposable where TDataType : unmanaged { private readonly int _handle; + private readonly int _sizeOf; private readonly BufferTarget _bufferTarget; - private BufferObject(BufferTarget bufferTarget) + private unsafe BufferObject(BufferTarget bufferTarget) { _bufferTarget = bufferTarget; _handle = GL.GenBuffer(); + _sizeOf = sizeof(TDataType); Bind(); } - public unsafe BufferObject(TDataType[] data, BufferTarget bufferTarget) : this(bufferTarget) + public BufferObject(TDataType[] data, BufferTarget bufferTarget) : this(bufferTarget) { - GL.BufferData(bufferTarget, data.Length * sizeof(TDataType), data, BufferUsageHint.StaticDraw); + GL.BufferData(bufferTarget, data.Length * _sizeOf, data, BufferUsageHint.StaticDraw); } - public unsafe BufferObject(int length, BufferTarget bufferTarget) : this(bufferTarget) + public BufferObject(int length, BufferTarget bufferTarget) : this(bufferTarget) { - GL.BufferData(bufferTarget, length * sizeof(TDataType), IntPtr.Zero, BufferUsageHint.DynamicDraw); + GL.BufferData(bufferTarget, length * _sizeOf, IntPtr.Zero, BufferUsageHint.DynamicDraw); } public void UpdateRange(int count, TDataType data) @@ -33,22 +35,22 @@ public class BufferObject : IDisposable where TDataType : unmanaged Unbind(); } - public unsafe void Update(int offset, TDataType data) + public void Update(int offset, TDataType data) { - GL.BufferSubData(_bufferTarget, (IntPtr) (offset * sizeof(TDataType)), sizeof(TDataType), ref data); + GL.BufferSubData(_bufferTarget, (IntPtr) (offset * _sizeOf), _sizeOf, ref data); } - public unsafe void Update(TDataType[] data) + public void Update(TDataType[] data) { Bind(); - GL.BufferSubData(_bufferTarget, IntPtr.Zero, data.Length * sizeof(TDataType), data); + GL.BufferSubData(_bufferTarget, IntPtr.Zero, data.Length * _sizeOf, data); Unbind(); } - public unsafe TDataType Get(int offset) + public TDataType Get(int offset) { TDataType data = default; - GL.GetBufferSubData(_bufferTarget, (IntPtr) (offset * sizeof(TDataType)), sizeof(TDataType), ref data); + GL.GetBufferSubData(_bufferTarget, (IntPtr) (offset * _sizeOf), _sizeOf, ref data); return data; } diff --git a/FModel/Views/Snooper/Buffers/VertexArrayObject.cs b/FModel/Views/Snooper/Buffers/VertexArrayObject.cs index df3fd7a3..820d1885 100644 --- a/FModel/Views/Snooper/Buffers/VertexArrayObject.cs +++ b/FModel/Views/Snooper/Buffers/VertexArrayObject.cs @@ -7,25 +7,29 @@ namespace FModel.Views.Snooper.Buffers; public class VertexArrayObject : IDisposable where TVertexType : unmanaged where TIndexType : unmanaged { private readonly int _handle; + private readonly int _sizeOfVertex; + private readonly int _sizeOfIndex; - public VertexArrayObject(BufferObject vbo, BufferObject ebo) + public unsafe VertexArrayObject(BufferObject vbo, BufferObject ebo) { _handle = GL.GenVertexArray(); + _sizeOfVertex = sizeof(TVertexType); + _sizeOfIndex = sizeof(TIndexType); Bind(); vbo.Bind(); ebo.Bind(); } - public unsafe void VertexAttributePointer(uint index, int count, VertexAttribPointerType type, int vertexSize, int offset) + public void VertexAttributePointer(uint index, int count, VertexAttribPointerType type, int vertexSize, int offset) { switch (type) { case VertexAttribPointerType.Int: - GL.VertexAttribIPointer(index, count, VertexAttribIntegerType.Int, vertexSize * sizeof(TVertexType), (IntPtr) (offset * sizeof(TVertexType))); + GL.VertexAttribIPointer(index, count, VertexAttribIntegerType.Int, vertexSize * _sizeOfVertex, (IntPtr) (offset * _sizeOfVertex)); break; default: - GL.VertexAttribPointer(index, count, type, false, vertexSize * sizeof(TVertexType), offset * sizeof(TVertexType)); + GL.VertexAttribPointer(index, count, type, false, vertexSize * _sizeOfVertex, offset * _sizeOfVertex); break; } GL.EnableVertexAttribArray(index);