mirror of
https://github.com/4sval/FModel.git
synced 2026-04-25 07:21:54 -05:00
mock-up bone hierarchy
This commit is contained in:
parent
7d698ea8dd
commit
1aa45b1b88
|
|
@ -31,6 +31,7 @@ public class Bone
|
||||||
public bool IsMapped => SkeletonIndex > -1;
|
public bool IsMapped => SkeletonIndex > -1;
|
||||||
public bool IsAnimated => AnimatedBySequences.Count > 0;
|
public bool IsAnimated => AnimatedBySequences.Count > 0;
|
||||||
public bool IsNative => Index == SkeletonIndex;
|
public bool IsNative => Index == SkeletonIndex;
|
||||||
|
public uint Color => !IsMapped || !IsAnimated ? 0xFFA0A0A0 : 0xFF48B048;
|
||||||
|
|
||||||
public override string ToString() => $"Mesh Ref '{Index}' is Skel Ref '{SkeletonIndex}'";
|
public override string ToString() => $"Mesh Ref '{Index}' is Skel Ref '{SkeletonIndex}'";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,14 @@ public class Skeleton : IDisposable
|
||||||
private BufferObject<Matrix4x4> _rest;
|
private BufferObject<Matrix4x4> _rest;
|
||||||
private BufferObject<Matrix4x4> _ssbo;
|
private BufferObject<Matrix4x4> _ssbo;
|
||||||
private Matrix4x4[] _boneMatriceAtFrame;
|
private Matrix4x4[] _boneMatriceAtFrame;
|
||||||
|
private readonly List<string> _breadcrumb;
|
||||||
|
|
||||||
public string Name;
|
public string Name;
|
||||||
public readonly string RootBoneName;
|
|
||||||
public readonly Dictionary<string, Bone> BonesByLoweredName;
|
public readonly Dictionary<string, Bone> BonesByLoweredName;
|
||||||
|
|
||||||
public readonly int BoneCount;
|
public readonly int BoneCount;
|
||||||
public int AdditionalBoneCount;
|
private int _additionalBoneCount;
|
||||||
public int TotalBoneCount => BoneCount + AdditionalBoneCount;
|
private int TotalBoneCount => BoneCount + _additionalBoneCount;
|
||||||
|
|
||||||
public bool IsAnimated { get; private set; }
|
public bool IsAnimated { get; private set; }
|
||||||
public string SelectedBone;
|
public string SelectedBone;
|
||||||
|
|
@ -33,6 +33,7 @@ public class Skeleton : IDisposable
|
||||||
public Skeleton()
|
public Skeleton()
|
||||||
{
|
{
|
||||||
BonesByLoweredName = new Dictionary<string, Bone>();
|
BonesByLoweredName = new Dictionary<string, Bone>();
|
||||||
|
_breadcrumb = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Skeleton(FReferenceSkeleton referenceSkeleton) : this()
|
public Skeleton(FReferenceSkeleton referenceSkeleton) : this()
|
||||||
|
|
@ -58,7 +59,7 @@ public class Skeleton : IDisposable
|
||||||
parentBone.LoweredChildNames.Add(boneName);
|
parentBone.LoweredChildNames.Add(boneName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boneIndex == 0) RootBoneName = boneName;
|
if (boneIndex == 0) SelectedBone = boneName;
|
||||||
BonesByLoweredName[boneName] = bone;
|
BonesByLoweredName[boneName] = bone;
|
||||||
}
|
}
|
||||||
_boneMatriceAtFrame = new Matrix4x4[BoneCount];
|
_boneMatriceAtFrame = new Matrix4x4[BoneCount];
|
||||||
|
|
@ -73,7 +74,7 @@ public class Skeleton : IDisposable
|
||||||
|
|
||||||
if (!BonesByLoweredName.TryGetValue(boneName, out var bone))
|
if (!BonesByLoweredName.TryGetValue(boneName, out var bone))
|
||||||
{
|
{
|
||||||
bone = new Bone(BoneCount + AdditionalBoneCount, info.ParentIndex, new Transform
|
bone = new Bone(BoneCount + _additionalBoneCount, info.ParentIndex, new Transform
|
||||||
{
|
{
|
||||||
Rotation = referenceSkeleton.FinalRefBonePose[boneIndex].Rotation,
|
Rotation = referenceSkeleton.FinalRefBonePose[boneIndex].Rotation,
|
||||||
Position = referenceSkeleton.FinalRefBonePose[boneIndex].Translation * Constants.SCALE_DOWN_RATIO,
|
Position = referenceSkeleton.FinalRefBonePose[boneIndex].Translation * Constants.SCALE_DOWN_RATIO,
|
||||||
|
|
@ -90,10 +91,10 @@ public class Skeleton : IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
BonesByLoweredName[boneName] = bone;
|
BonesByLoweredName[boneName] = bone;
|
||||||
AdditionalBoneCount++;
|
_additionalBoneCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_boneMatriceAtFrame = new Matrix4x4[BoneCount + AdditionalBoneCount];
|
_boneMatriceAtFrame = new Matrix4x4[TotalBoneCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Setup()
|
public void Setup()
|
||||||
|
|
@ -135,7 +136,7 @@ public class Skeleton : IDisposable
|
||||||
{
|
{
|
||||||
bone.AnimatedBySequences.Add(s);
|
bone.AnimatedBySequences.Add(s);
|
||||||
}
|
}
|
||||||
sequence.Retarget(animation.Skeleton);
|
sequence.RetargetTracks(animation.Skeleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
@ -238,22 +239,56 @@ public class Skeleton : IDisposable
|
||||||
_rest.BindBufferBase(2);
|
_rest.BindBufferBase(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ImGuiBoneBreadcrumb()
|
||||||
|
{
|
||||||
|
for (int i = _breadcrumb.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var boneName = _breadcrumb[i];
|
||||||
|
ImGui.SameLine();
|
||||||
|
var clicked = ImGui.SmallButton(boneName);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.Text(">");
|
||||||
|
|
||||||
|
if (clicked)
|
||||||
|
{
|
||||||
|
SelectedBone = boneName;
|
||||||
|
_breadcrumb.RemoveRange(0, i + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void ImGuiBoneHierarchy()
|
public void ImGuiBoneHierarchy()
|
||||||
{
|
{
|
||||||
DrawBoneTree(RootBoneName, BonesByLoweredName[RootBoneName]);
|
DrawBoneTree(SelectedBone, BonesByLoweredName[SelectedBone]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawBoneTree(string boneName, Bone bone)
|
private void DrawBoneTree(string boneName, Bone bone)
|
||||||
{
|
{
|
||||||
var flags = ImGuiTreeNodeFlags.OpenOnArrow | ImGuiTreeNodeFlags.OpenOnDoubleClick | ImGuiTreeNodeFlags.SpanAvailWidth;
|
ImGui.PushID(bone.Index);
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
var flags = ImGuiTreeNodeFlags.OpenOnArrow | ImGuiTreeNodeFlags.SpanFullWidth;
|
||||||
if (boneName == SelectedBone) flags |= ImGuiTreeNodeFlags.Selected;
|
if (boneName == SelectedBone) flags |= ImGuiTreeNodeFlags.Selected;
|
||||||
if (bone.IsVirtual) flags |= ImGuiTreeNodeFlags.Leaf;
|
if (bone.IsVirtual) flags |= ImGuiTreeNodeFlags.Leaf;
|
||||||
else if (!bone.IsDaron) flags |= ImGuiTreeNodeFlags.Bullet;
|
else if (!bone.IsDaron) flags |= ImGuiTreeNodeFlags.Bullet;
|
||||||
|
|
||||||
ImGui.SetNextItemOpen(bone.LoweredChildNames.Count <= 1, ImGuiCond.Appearing);
|
ImGui.SetNextItemOpen(bone.LoweredChildNames.Count <= 1 || flags.HasFlag(ImGuiTreeNodeFlags.Selected), ImGuiCond.Appearing);
|
||||||
var open = ImGui.TreeNodeEx(boneName, flags);
|
var open = ImGui.TreeNodeEx(boneName, flags);
|
||||||
if (ImGui.IsItemClicked() && !ImGui.IsItemToggledOpen())
|
if (ImGui.IsItemClicked() && !ImGui.IsItemToggledOpen())
|
||||||
|
{
|
||||||
SelectedBone = boneName;
|
SelectedBone = boneName;
|
||||||
|
_breadcrumb.Clear();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
_breadcrumb.Add(boneName);
|
||||||
|
boneName = BonesByLoweredName[boneName].LoweredParentName;
|
||||||
|
} while (boneName != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TextColored(ImGui.ColorConvertU32ToFloat4(bone.Color), bone.SkeletonIndex.ToString());
|
||||||
|
|
||||||
if (open)
|
if (open)
|
||||||
{
|
{
|
||||||
|
|
@ -263,6 +298,7 @@ public class Skeleton : IDisposable
|
||||||
}
|
}
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
}
|
}
|
||||||
|
ImGui.PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
||||||
|
|
@ -104,10 +104,11 @@ public class SnimGui
|
||||||
Draw3DViewport(s);
|
Draw3DViewport(s);
|
||||||
DrawNavbar();
|
DrawNavbar();
|
||||||
|
|
||||||
DrawModals(s);
|
|
||||||
|
|
||||||
if (_ti_open) DrawTextureInspector(s);
|
if (_ti_open) DrawTextureInspector(s);
|
||||||
if (_bh_open) DrawBoneHierarchy(s);
|
if (_bh_open) DrawBoneHierarchy(s);
|
||||||
|
|
||||||
|
DrawModals(s);
|
||||||
|
|
||||||
Controller.Render();
|
Controller.Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -722,11 +723,19 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
|
||||||
|
|
||||||
private void DrawBoneHierarchy(Snooper s)
|
private void DrawBoneHierarchy(Snooper s)
|
||||||
{
|
{
|
||||||
|
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
|
||||||
if (ImGui.Begin("Bone Hierarchy", ref _bh_open, ImGuiWindowFlags.NoScrollbar) && s.Renderer.Options.TryGetModel(out var model))
|
if (ImGui.Begin("Bone Hierarchy", ref _bh_open, ImGuiWindowFlags.NoScrollbar) && s.Renderer.Options.TryGetModel(out var model))
|
||||||
{
|
{
|
||||||
model.Skeleton.ImGuiBoneHierarchy();
|
model.Skeleton.ImGuiBoneBreadcrumb();
|
||||||
|
if (ImGui.BeginTable("bone_hierarchy", 2, ImGuiTableFlags.NoSavedSettings | ImGuiTableFlags.RowBg, ImGui.GetContentRegionAvail(), ImGui.GetWindowWidth()))
|
||||||
|
{
|
||||||
|
ImGui.TableSetupColumn("Bone", ImGuiTableColumnFlags.WidthStretch);
|
||||||
|
ImGui.TableSetupColumn("", ImGuiTableColumnFlags.NoHeaderWidth | ImGuiTableColumnFlags.WidthFixed, _tableWidth);
|
||||||
|
model.Skeleton.ImGuiBoneHierarchy();
|
||||||
|
ImGui.EndTable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui.End(); // if window is collapsed
|
ImGui.PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Draw3DViewport(Snooper s)
|
private void Draw3DViewport(Snooper s)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user