POC frame interpolation

This commit is contained in:
Asval 2023-08-01 23:06:16 +02:00
parent 993726c681
commit 6ed335d483
5 changed files with 42 additions and 19 deletions

View File

@ -24,6 +24,8 @@ public class Animation : IDisposable
public int CurrentSequence;
public int FrameInSequence; // Current Sequence's Frame to Display
public int NextFrameInSequence;
public float LerpAmount;
public string Label =>
$"Retarget: {TargetSkeleton}\nSequences: {CurrentSequence + 1}/{Sequences.Length}\nFrames: {FrameInSequence}/{Sequences[CurrentSequence].EndFrame}";
@ -80,12 +82,17 @@ public class Animation : IDisposable
for (int s = 0; s < CurrentSequence; s++)
lastEndTime = Sequences[s].EndTime;
FrameInSequence = Math.Min(((elapsedTime - lastEndTime) / Sequences[CurrentSequence].TimePerFrame).FloorToInt(), Sequences[CurrentSequence].EndFrame);
var exactFrameAtThisTime = (elapsedTime - lastEndTime) / Sequences[CurrentSequence].TimePerFrame;
FrameInSequence = Math.Min(exactFrameAtThisTime.FloorToInt(), Sequences[CurrentSequence].EndFrame);
NextFrameInSequence = Math.Min(FrameInSequence + 1, Sequences[CurrentSequence].EndFrame);
LerpAmount = Math.Clamp(exactFrameAtThisTime - FrameInSequence, 0, 1);
}
private void Reset()
{
FrameInSequence = 0;
NextFrameInSequence = 0;
LerpAmount = 0.0f;
CurrentSequence = 0;
}

View File

@ -18,8 +18,6 @@ public class Skeleton : IDisposable
public string Name;
public readonly Dictionary<string, Bone> BonesByLoweredName;
private int _previousAnimationSequence;
private int _previousSequenceFrame;
private Transform[][][] _animatedBonesTransform; // [sequence][bone][frame]
private readonly Matrix4x4[] _invertedBonesMatrix;
public int BoneCount => _invertedBonesMatrix.Length;
@ -210,26 +208,23 @@ public class Skeleton : IDisposable
_ssbo.UpdateRange(BoneCount, Matrix4x4.Identity);
}
public void UpdateAnimationMatrices(int currentSequence, int frameInSequence)
public void UpdateAnimationMatrices(int currentSequence, int frameInSequence, int nextFrameInSequence, float lerp)
{
if (!IsAnimated) return;
_previousAnimationSequence = currentSequence;
if (_previousSequenceFrame == frameInSequence) return;
_previousSequenceFrame = frameInSequence;
_ssbo.Bind();
for (int boneIndex = 0; boneIndex < BoneCount; boneIndex++) // interpolate here
_ssbo.Update(boneIndex, _invertedBonesMatrix[boneIndex] * _animatedBonesTransform[_previousAnimationSequence][boneIndex][_previousSequenceFrame].Matrix);
for (int boneIndex = 0; boneIndex < BoneCount; boneIndex++)
{
var matrix = Matrix4x4.Lerp(
_animatedBonesTransform[currentSequence][boneIndex][frameInSequence].Matrix,
_animatedBonesTransform[currentSequence][boneIndex][nextFrameInSequence].Matrix,
lerp);
_ssbo.Update(boneIndex, _invertedBonesMatrix[boneIndex] * matrix);
}
_ssbo.Unbind();
}
public Matrix4x4 GetBoneMatrix(Bone bone)
{
return IsAnimated
? _animatedBonesTransform[_previousAnimationSequence][bone.Index][_previousSequenceFrame].Matrix
: bone.Rest.Matrix;
}
public Matrix4x4 GetBoneMatrix(Bone bone) => IsAnimated ? bone.Rest.Matrix * _ssbo.Get(bone.Index) : bone.Rest.Matrix;
public void Render()
{

View File

@ -43,6 +43,17 @@ public class BufferObject<TDataType> : IDisposable where TDataType : unmanaged
GL.BufferSubData(_bufferTarget, IntPtr.Zero, data.Length * sizeof(TDataType), data);
}
public unsafe TDataType Get(int offset)
{
TDataType data = default;
Bind();
GL.GetBufferSubData(_bufferTarget, (IntPtr) (offset * sizeof(TDataType)), sizeof(TDataType), ref data);
Unbind();
return data;
}
public void Bind()
{
GL.BindBuffer(_bufferTarget, _handle);

View File

@ -370,9 +370,17 @@ public class Model : IDisposable
_vao.Unbind();
}
for (int section = 0; section < Sections.Length; section++)
if (options.Models.Count == 1 && Sections.All(x => !x.Show))
{
if (!Show) Show = Sections[section].Show;
Show = true;
foreach (var section in Sections)
{
section.Show = true;
}
}
else foreach (var section in Sections)
{
if (!Show) Show = section.Show;
}
IsSetup = true;

View File

@ -234,7 +234,9 @@ public class Renderer : IDisposable
animation.TimeCalculation(Options.Tracker.ElapsedTime);
foreach (var guid in animation.AttachedModels.Where(guid => Options.Models[guid].HasSkeleton))
{
Options.Models[guid].Skeleton.UpdateAnimationMatrices(animation.CurrentSequence, animation.FrameInSequence);
Options.Models[guid].Skeleton.UpdateAnimationMatrices(
animation.CurrentSequence, animation.FrameInSequence,
animation.NextFrameInSequence, animation.LerpAmount);
}
}