mirror of
https://github.com/4sval/FModel.git
synced 2026-03-24 18:54:42 -05:00
animate loaded model
This commit is contained in:
parent
d78df4a953
commit
591a2d2336
|
|
@ -12,6 +12,7 @@ namespace FModel.Views.Snooper.Animations;
|
|||
public class Animation : IDisposable
|
||||
{
|
||||
public readonly UObject Export;
|
||||
public readonly CAnimSet AnimSet;
|
||||
public readonly string Path;
|
||||
public readonly string Name;
|
||||
public readonly Sequence[] Sequences;
|
||||
|
|
@ -23,6 +24,8 @@ public class Animation : IDisposable
|
|||
public int CurrentSequence;
|
||||
public int FrameInSequence; // Current Sequence's Frame to Display
|
||||
|
||||
public string Label =>
|
||||
$"Retarget: {TargetSkeleton}\nSequences: {CurrentSequence + 1}/{Sequences.Length}\nFrames: {FrameInSequence}/{Sequences[CurrentSequence].EndFrame}";
|
||||
public bool IsActive;
|
||||
public bool IsSelected;
|
||||
|
||||
|
|
@ -39,15 +42,16 @@ public class Animation : IDisposable
|
|||
|
||||
public Animation(UObject export, CAnimSet animSet) : this(export)
|
||||
{
|
||||
TargetSkeleton = animSet.OriginalAnim.Name;
|
||||
AnimSet = animSet;
|
||||
TargetSkeleton = AnimSet.OriginalAnim.Name;
|
||||
|
||||
Sequences = new Sequence[animSet.Sequences.Count];
|
||||
Sequences = new Sequence[AnimSet.Sequences.Count];
|
||||
for (int i = 0; i < Sequences.Length; i++)
|
||||
{
|
||||
Sequences[i] = new Sequence(animSet.Sequences[i]);
|
||||
Sequences[i] = new Sequence(AnimSet.Sequences[i]);
|
||||
|
||||
EndTime = Sequences[i].EndTime;
|
||||
TotalElapsedTime += animSet.Sequences[i].NumFrames * Sequences[i].TimePerFrame;
|
||||
TotalElapsedTime += AnimSet.Sequences[i].NumFrames * Sequences[i].TimePerFrame;
|
||||
}
|
||||
|
||||
if (Sequences.Length > 0)
|
||||
|
|
@ -95,7 +99,7 @@ public class Animation : IDisposable
|
|||
var p2 = new Vector2(timelineP0.X + EndTime * timeRatio.X - t, y + timeStep.Y - t);
|
||||
|
||||
ImGui.SetCursorScreenPos(p1);
|
||||
ImGui.InvisibleButton($"timeline_sequencetracker_{Name}", new Vector2(EndTime * timeRatio.X - t, timeStep.Y - t), ImGuiButtonFlags.MouseButtonLeft);
|
||||
ImGui.InvisibleButton($"timeline_sequencetracker_{Name}##{i}", new Vector2(EndTime * timeRatio.X - t, timeStep.Y - t), ImGuiButtonFlags.MouseButtonLeft);
|
||||
IsActive = ImGui.IsItemActive();
|
||||
IsSelected = s.Renderer.Options.SelectedAnimation == i;
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
|
|
@ -105,6 +109,19 @@ public class Animation : IDisposable
|
|||
SnimGui.Popup(() =>
|
||||
{
|
||||
s.Renderer.Options.SelectedAnimation = i;
|
||||
if (ImGui.BeginMenu("Animate"))
|
||||
{
|
||||
foreach ((var guid, var model) in s.Renderer.Options.Models)
|
||||
{
|
||||
if (ImGui.MenuItem(model.Name, model.HasSkeleton && !AttachedModels.Contains(guid)))
|
||||
{
|
||||
AttachedModels.Add(guid);
|
||||
model.Skeleton.ResetAnimatedData(true);
|
||||
model.Skeleton.Animate(AnimSet, s.Renderer.AnimateWithRotationOnly);
|
||||
}
|
||||
}
|
||||
ImGui.EndMenu();
|
||||
}
|
||||
if (ImGui.Selectable("Save"))
|
||||
{
|
||||
s.WindowShouldFreeze(true);
|
||||
|
|
@ -116,9 +133,10 @@ public class Animation : IDisposable
|
|||
});
|
||||
|
||||
drawList.AddRectFilled(p1, p2, IsSelected ? 0xFF48B048 : 0xFF175F17, 5.0f, ImDrawFlags.RoundCornersTop);
|
||||
drawList.PushClipRect(p1, p2, true);
|
||||
drawList.AddText(p1, 0xFF000000, $"{TargetSkeleton} - {CurrentSequence + 1}/{Sequences.Length} - {FrameInSequence}/{Sequences[CurrentSequence].EndFrame}");
|
||||
drawList.PopClipRect();
|
||||
for (int j = 0; j < Sequences.Length; j++)
|
||||
{
|
||||
Sequences[j].DrawSequence(drawList, timelineP0.X, p2, timeStep, timeRatio, t);
|
||||
}
|
||||
|
||||
drawList.PushClipRect(treeP0 with { Y = p1.Y }, treeP1 with { Y = p2.Y }, true);
|
||||
drawList.AddText(treeP0 with { Y = y + timeStep.Y / 4.0f }, 0xFFFFFFFF, Name);
|
||||
|
|
|
|||
|
|
@ -28,15 +28,13 @@ public class Sequence
|
|||
IsAdditive = sequence.bAdditive;
|
||||
}
|
||||
|
||||
private readonly float _height = 20.0f;
|
||||
public void DrawSequence(ImDrawListPtr drawList, float x, float y, Vector2 ratio, int index, uint col)
|
||||
public void DrawSequence(ImDrawListPtr drawList, float x, Vector2 p2, Vector2 timeStep, Vector2 timeRatio, float t)
|
||||
{
|
||||
var height = _height * (index % 2);
|
||||
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();
|
||||
var q1 = new Vector2(x + StartTime * timeRatio.X + t, p2.Y - timeStep.Y / 2.0f);
|
||||
var q2 = p2 with { X = x + EndTime * timeRatio.X - t - t };
|
||||
|
||||
drawList.AddLine(new Vector2(q1.X, q2.Y), q1, 0x50FFFFFF, 1.0f);
|
||||
drawList.AddLine(q1, new Vector2(q2.X, q1.Y), 0x50FFFFFF, 1.0f);
|
||||
drawList.AddLine(new Vector2(q2.X, q1.Y), q2, 0x50FFFFFF, 1.0f);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,6 +148,15 @@ public class TimeTracker : IDisposable
|
|||
DrawSeparator(drawList, timelineP0, y + _timeStep.Y, animations[i].EndTime * timeRatio.X, ETrackerType.End);
|
||||
}
|
||||
|
||||
for (int i = 0; i < animations.Count; i++)
|
||||
{
|
||||
var y = timelineP0.Y + _timeBarHeight + _timeStep.Y * i;
|
||||
for (int j = 0; j < animations[i].Sequences.Length - 1; j++)
|
||||
{
|
||||
DrawSeparator(drawList, timelineP0, y + _timeStep.Y - _thickness, animations[i].Sequences[j].EndTime * timeRatio.X - 1.0f, ETrackerType.InBetween);
|
||||
}
|
||||
}
|
||||
|
||||
DrawSeparator(drawList, timelineP0, timelineP1.Y, ElapsedTime * timeRatio.X, ETrackerType.Frame);
|
||||
|
||||
drawList.PopClipRect();
|
||||
|
|
@ -162,6 +171,7 @@ public class TimeTracker : IDisposable
|
|||
{
|
||||
ETrackerType.Frame => new Vector2(origin.X + time, origin.Y + _timeBarHeight),
|
||||
ETrackerType.End => origin with { X = origin.X + time },
|
||||
ETrackerType.InBetween => origin with { X = origin.X + time },
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(separatorType), separatorType, null)
|
||||
};
|
||||
var p2 = p1 with { Y = y };
|
||||
|
|
@ -170,6 +180,7 @@ public class TimeTracker : IDisposable
|
|||
{
|
||||
ETrackerType.Frame => 0xFF6F6F6F,
|
||||
ETrackerType.End => 0xFF2E3E82,
|
||||
ETrackerType.InBetween => 0x50FFFFFF,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(separatorType), separatorType, null)
|
||||
};
|
||||
|
||||
|
|
@ -186,6 +197,7 @@ public class TimeTracker : IDisposable
|
|||
drawList.AddTriangleFilled(new Vector2(xl, yb), new Vector2(xr, yb), p1, color);
|
||||
break;
|
||||
case ETrackerType.End:
|
||||
case ETrackerType.InBetween:
|
||||
drawList.AddTriangleFilled(p1, p1 with { X = p1.X - size }, p1 with { Y = p1.Y + size }, color);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user