Skip to content

Commit

Permalink
everything is now time based
Browse files Browse the repository at this point in the history
  • Loading branch information
4sval committed Feb 14, 2023
1 parent 144cf0e commit 62e619d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 55 deletions.
77 changes: 31 additions & 46 deletions FModel/Views/Snooper/Models/Animations/Animation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ namespace FModel.Views.Snooper.Models.Animations;

public enum AnimSeparatorType
{
Start,
Frame,
InBetween,
End
}

public class Animation : IDisposable
{
public float ElapsedTime;
public int Frame;
public int FrameInSequence;
public float ElapsedTime; // Animation Elapsed Time
public int FrameInSequence; // Current Sequence's Frame to Display

public bool IsPaused;
public readonly int TotalFrames;
public readonly int EndFrame;
public readonly float MaxElapsedTime;
public readonly float EndTime; // Animation End Time
public readonly float TotalElapsedTime; // Animation Max Time

public int CurrentSequence;
public readonly Sequence[] Sequences;
Expand All @@ -32,9 +32,8 @@ public Animation()
Reset();

IsPaused = false;
TotalFrames = 0;
EndFrame = 0;
MaxElapsedTime = 0.0f;
EndTime = 0.0f;
TotalElapsedTime = 0.0f;
Sequences = Array.Empty<Sequence>();
}

Expand All @@ -45,9 +44,8 @@ public Animation(Skeleton skeleton, CAnimSet anim, bool rotationOnly) : this()
{
Sequences[i] = new Sequence(anim.Sequences[i], skeleton, rotationOnly);

TotalFrames += Sequences[i].MaxFrame;
MaxElapsedTime += anim.Sequences[i].NumFrames * Sequences[i].TimePerFrame;
EndFrame += (Sequences[i].Duration / Sequences[i].TimePerFrame).FloorToInt();
TotalElapsedTime += anim.Sequences[i].NumFrames * Sequences[i].TimePerFrame;
EndTime = Sequences[i].EndTime;
}

if (Sequences.Length > 0)
Expand All @@ -62,43 +60,35 @@ public void Update(float deltaSeconds)
TimeCalculation();
}

public Matrix4x4 InterpolateBoneTransform(int boneIndex)
{
// interpolate here
return Sequences[CurrentSequence].BonesTransform[boneIndex][FrameInSequence].Matrix;
}

private void TimeCalculation()
{
CurrentSequence = SequencesCount;
for (int i = 0; i < Sequences.Length; i++)
{
if (ElapsedTime < Sequences[i].EndTime)
if (ElapsedTime < Sequences[i].EndTime && ElapsedTime >= Sequences[i].StartTime)
{
CurrentSequence = i;
break;
}
}
if (CurrentSequence >= SequencesCount)
Reset();

Frame = Math.Min((ElapsedTime / Sequences[CurrentSequence].TimePerFrame).FloorToInt(), TotalFrames);
if (ElapsedTime >= TotalElapsedTime) Reset();

var baseFrame = 0;
var lastEndTime = 0.0f;
for (int s = 0; s < CurrentSequence; s++)
{
baseFrame += Sequences[s].MaxFrame;
}
FrameInSequence = Math.Min(Frame - baseFrame, Sequences[CurrentSequence].MaxFrame);
}

lastEndTime = Sequences[s].EndTime;

public Matrix4x4 InterpolateBoneTransform(int boneIndex)
{
// interpolate here
return Sequences[CurrentSequence].BonesTransform[boneIndex][FrameInSequence].Matrix;
FrameInSequence = Math.Min(((ElapsedTime - lastEndTime) / Sequences[CurrentSequence].TimePerFrame).FloorToInt(), Sequences[CurrentSequence].UsableEndFrame);
}

private void Reset()
{
ElapsedTime = 0.0f;
Frame = 0;
FrameInSequence = 0;

CurrentSequence = 0;
}

Expand All @@ -110,7 +100,7 @@ public void ImGuiTimeline(ImFontPtr fontPtr)
var canvasP0 = ImGui.GetCursorScreenPos();
var canvasSize = ImGui.GetContentRegionAvail();
var canvasP1 = new Vector2(canvasP0.X + canvasSize.X, canvasP0.Y + canvasSize.Y);
var ratio = canvasSize / TotalFrames;
var timeRatio = canvasSize / TotalElapsedTime;

var drawList = ImGui.GetWindowDrawList();

Expand All @@ -119,33 +109,28 @@ public void ImGuiTimeline(ImFontPtr fontPtr)
if (IsPaused && ImGui.IsMouseDragging(ImGuiMouseButton.Left))
{
var mousePosCanvas = io.MousePos - canvasP0;
ElapsedTime = Math.Clamp(mousePosCanvas.X / canvasSize.X * MaxElapsedTime, 0, MaxElapsedTime);
ElapsedTime = Math.Clamp(mousePosCanvas.X / canvasSize.X * TotalElapsedTime, 0, TotalElapsedTime);
TimeCalculation();
}

drawList.AddRectFilled(canvasP0, canvasP1 with { Y = canvasP0.Y + _timeBarHeight }, 0xFF181818);
drawList.PushClipRect(canvasP0, canvasP1 with { Y = canvasP0.Y + _timeBarHeight }, true);
{
for (float x = 0; x < canvasSize.X; x += ratio.X * 10f)
for (float x = 0; x < canvasSize.X; x += timeRatio.X * TotalElapsedTime / canvasSize.X * 50.0f)
{
drawList.AddLine(new Vector2(canvasP0.X + x, canvasP0.Y + _timeHeight + 2.5f), canvasP1 with { X = canvasP0.X + x }, 0xA0FFFFFF);
drawList.AddText(fontPtr, 14, new Vector2(canvasP0.X + x + 4, canvasP0.Y + 7.5f), 0x50FFFFFF, (x / ratio.X).FloorToInt().ToString());
drawList.AddText(fontPtr, 14, new Vector2(canvasP0.X + x + 4, canvasP0.Y + 7.5f), 0x50FFFFFF, $"{x / timeRatio.X:F1}s");
}
}
drawList.PopClipRect();

for (int i = 0; i < Sequences.Length; i++)
{
Sequences[i].DrawSequence(drawList, canvasP0.X, canvasP0.Y + _timeBarHeight, ratio, i);
Sequences[i].DrawSequence(drawList, canvasP0.X, canvasP0.Y + _timeBarHeight, timeRatio, i, i == CurrentSequence ? 0xFF0000FF : 0xFF175F17);
}

DrawSeparator(drawList, canvasP0, canvasP1, Frame * ratio.X, AnimSeparatorType.InBetween);
DrawSeparator(drawList, canvasP0, canvasP1, EndFrame * ratio.X, AnimSeparatorType.End);

// ImGui.Text($"{Sequences[CurrentSequence].Name} > {(CurrentSequence < SequencesCount - 1 ? Sequences[CurrentSequence + 1].Name : Sequences[0].Name)}");
// ImGui.Text($"Frame: {Sequences[CurrentSequence].Frame}/{Sequences[CurrentSequence].MaxFrame}");
// ImGui.Text($"Frame: {Frame}/{TotalFrames}");
// ImGui.Text($"FPS: {Sequences[CurrentSequence].FramesPerSecond}");
DrawSeparator(drawList, canvasP0, canvasP1, ElapsedTime * timeRatio.X, AnimSeparatorType.Frame);
DrawSeparator(drawList, canvasP0, canvasP1, EndTime * timeRatio.X, AnimSeparatorType.End);
}

private void DrawSeparator(ImDrawListPtr drawList, Vector2 origin, Vector2 destination, float time, AnimSeparatorType separatorType)
Expand All @@ -154,23 +139,23 @@ private void DrawSeparator(ImDrawListPtr drawList, Vector2 origin, Vector2 desti

Vector2 p1 = separatorType switch
{
AnimSeparatorType.InBetween => new Vector2(origin.X + time, origin.Y + _timeBarHeight),
AnimSeparatorType.Frame => new Vector2(origin.X + time, origin.Y + _timeBarHeight),
AnimSeparatorType.End => origin with { X = origin.X + time },
_ => throw new ArgumentOutOfRangeException(nameof(separatorType), separatorType, null)
};
var p2 = new Vector2(p1.X, destination.Y);

uint color = separatorType switch
{
AnimSeparatorType.InBetween => 0xFF6F6F6F,
AnimSeparatorType.Frame => 0xFF6F6F6F,
AnimSeparatorType.End => 0xFF2E3E82,
_ => throw new ArgumentOutOfRangeException(nameof(separatorType), separatorType, null)
};

drawList.AddLine(p1, p2, color, 1f);
switch (separatorType)
{
case AnimSeparatorType.InBetween:
case AnimSeparatorType.Frame:
color = 0xFF30478C;
var xl = p1.X - size;
var xr = p1.X + size;
Expand Down
19 changes: 10 additions & 9 deletions FModel/Views/Snooper/Models/Animations/Sequence.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Numerics;
using CUE4Parse_Conversion.Animations;
using CUE4Parse.Utils;
using ImGuiNET;

namespace FModel.Views.Snooper.Models.Animations;
Expand All @@ -13,10 +14,10 @@ public class Sequence : IDisposable
public readonly float StartTime;
public readonly float Duration;
public readonly float EndTime;
public readonly int EndFrame;
public readonly int LoopingCount;

private readonly float _start;
private readonly float _end;
public int UsableEndFrame => EndFrame - 1;

public readonly Transform[][] BonesTransform;

Expand All @@ -28,11 +29,9 @@ public Sequence(CAnimSequence sequence, Skeleton skeleton, bool rotationOnly)
StartTime = sequence.StartPos;
Duration = sequence.AnimEndTime;
EndTime = StartTime + Duration;
EndFrame = (Duration / TimePerFrame).FloorToInt();
LoopingCount = sequence.LoopingCount;

_start = StartTime / TimePerFrame;
_end = EndTime / TimePerFrame;

BonesTransform = new Transform[skeleton.BonesTransformByIndex.Count][];
for (int trackIndex = 0; trackIndex < skeleton.UnrealSkeleton.ReferenceSkeleton.FinalRefBoneInfo.Length; trackIndex++)
{
Expand Down Expand Up @@ -83,13 +82,15 @@ public Sequence(CAnimSequence sequence, Skeleton skeleton, bool rotationOnly)


private readonly float _height = 20.0f;
public void DrawSequence(ImDrawListPtr drawList, float x, float y, Vector2 ratio, int index)
public void DrawSequence(ImDrawListPtr drawList, float x, float y, Vector2 ratio, int index, uint col)
{
var height = _height * (index % 2);
var p1 = new Vector2(x + _start * ratio.X, y + height);
var p2 = new Vector2(x + _end * ratio.X, y + height + _height);
drawList.AddRectFilled(p1, p2, 0xFF175F17);
var p1 = new Vector2(x + StartTime * ratio.X, y + height);
var p2 = new Vector2(x + EndTime * ratio.X, y + height + _height);
drawList.PushClipRect(p1, p2, true);
drawList.AddRectFilled(p1, p2, col);
drawList.AddText(p1 with { X = p1.X + 2.5f }, 0xFF000000, Name);
drawList.PopClipRect();
}

public void Dispose()
Expand Down

0 comments on commit 62e619d

Please sign in to comment.