mirror of
https://github.com/4sval/FModel.git
synced 2026-03-21 17:24:26 -05:00
draw skeleton POC
This commit is contained in:
parent
a1494bf2e1
commit
3c2795cded
|
|
@ -1,23 +1,15 @@
|
|||
#version 460 core
|
||||
|
||||
layout (location = 1) in vec3 vPos;
|
||||
layout (location = 9) in mat4 vInstanceMatrix;
|
||||
layout (location = 0) in vec3 vPos;
|
||||
|
||||
uniform mat4 uView;
|
||||
uniform mat4 uProjection;
|
||||
uniform bool uSocket;
|
||||
uniform mat4 uInstanceMatrix;
|
||||
|
||||
out vec3 fPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
float scale = 0.0075;
|
||||
mat4 result;
|
||||
result[0] = vec4(scale, 0.0, 0.0, 0.0);
|
||||
result[1] = vec4(0.0, scale, 0.0, 0.0);
|
||||
result[2] = vec4(0.0, 0.0, scale, 0.0);
|
||||
result[3] = vInstanceMatrix[3];
|
||||
|
||||
gl_Position = uProjection * uView * result * vec4(vPos, 1.0);
|
||||
fPos = vec3(result * vec4(vPos, 1.0));
|
||||
gl_Position = uProjection * uView * uInstanceMatrix * vec4(vPos, 1.0);
|
||||
fPos = vec3(uInstanceMatrix * vec4(vPos, 1.0));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,13 @@ public class Skeleton : IDisposable
|
|||
private int TotalBoneCount => BoneCount + _additionalBoneCount;
|
||||
|
||||
public bool IsAnimated { get; private set; }
|
||||
public bool DrawAllBones;
|
||||
public string SelectedBone;
|
||||
|
||||
private const int _vertexSize = 6;
|
||||
private BufferObject<float> _vbo;
|
||||
private int vaoHandle;
|
||||
private float[] _vertices;
|
||||
|
||||
public Skeleton()
|
||||
{
|
||||
BonesByLoweredName = new Dictionary<string, Bone>();
|
||||
|
|
@ -40,6 +44,7 @@ public class Skeleton : IDisposable
|
|||
public Skeleton(FReferenceSkeleton referenceSkeleton) : this()
|
||||
{
|
||||
BoneCount = referenceSkeleton.FinalRefBoneInfo.Length;
|
||||
_vertices = new float[_vertexSize * BoneCount];
|
||||
for (int boneIndex = 0; boneIndex < BoneCount; boneIndex++)
|
||||
{
|
||||
var info = referenceSkeleton.FinalRefBoneInfo[boneIndex];
|
||||
|
|
@ -58,6 +63,14 @@ public class Skeleton : IDisposable
|
|||
|
||||
bone.Rest.Relation = parentBone.Rest.Matrix;
|
||||
parentBone.LoweredChildNames.Add(boneName);
|
||||
|
||||
var baseIndex = boneIndex * _vertexSize;
|
||||
_vertices[baseIndex + 0] = bone.Rest.Matrix.Translation.X;
|
||||
_vertices[baseIndex + 1] = bone.Rest.Matrix.Translation.Y;
|
||||
_vertices[baseIndex + 2] = bone.Rest.Matrix.Translation.Z;
|
||||
_vertices[baseIndex + 3] = parentBone.Rest.Matrix.Translation.X;
|
||||
_vertices[baseIndex + 4] = parentBone.Rest.Matrix.Translation.Y;
|
||||
_vertices[baseIndex + 5] = parentBone.Rest.Matrix.Translation.Z;
|
||||
}
|
||||
|
||||
if (boneIndex == 0) SelectedBone = boneName;
|
||||
|
|
@ -104,6 +117,17 @@ public class Skeleton : IDisposable
|
|||
{
|
||||
_handle = GL.CreateProgram();
|
||||
|
||||
_vbo = new BufferObject<float>(_vertices, BufferTarget.ArrayBuffer);
|
||||
|
||||
vaoHandle = GL.GenVertexArray();
|
||||
GL.BindVertexArray(vaoHandle);
|
||||
_vbo.Bind();
|
||||
|
||||
GL.EnableVertexAttribArray(0);
|
||||
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, sizeof(float) * 3, 0);
|
||||
|
||||
GL.BindVertexArray(0);
|
||||
|
||||
_rest = new BufferObject<Matrix4x4>(BoneCount, BufferTarget.ShaderStorageBuffer);
|
||||
foreach (var bone in BonesByLoweredName.Values)
|
||||
{
|
||||
|
|
@ -171,7 +195,6 @@ public class Skeleton : IDisposable
|
|||
if (!IsAnimated) return;
|
||||
|
||||
_ssbo.Bind();
|
||||
|
||||
foreach (var bone in BonesByLoweredName.Values)
|
||||
{
|
||||
var boneMatrix = bone.IsRoot ? bone.Rest.Relation : bone.Rest.LocalMatrix * _boneMatriceAtFrame[bone.ParentIndex];
|
||||
|
|
@ -199,8 +222,23 @@ public class Skeleton : IDisposable
|
|||
_ssbo.Update(bone.Index, boneMatrix);
|
||||
_boneMatriceAtFrame[bone.Index] = boneMatrix;
|
||||
}
|
||||
|
||||
_ssbo.Unbind();
|
||||
|
||||
_vbo.Bind();
|
||||
foreach (var bone in BonesByLoweredName.Values)
|
||||
{
|
||||
var baseIndex = bone.Index * _vertexSize;
|
||||
var boneMatrix = bone.IsRoot ? bone.Rest.Relation : bone.Rest.LocalMatrix * _boneMatriceAtFrame[bone.ParentIndex];
|
||||
var parentBoneMatrix = bone.IsRoot ? bone.Rest.Relation : _boneMatriceAtFrame[bone.ParentIndex];
|
||||
|
||||
_vbo.Update(baseIndex + 0, boneMatrix.Translation.X);
|
||||
_vbo.Update(baseIndex + 1, boneMatrix.Translation.Y);
|
||||
_vbo.Update(baseIndex + 2, boneMatrix.Translation.Z);
|
||||
_vbo.Update(baseIndex + 3, parentBoneMatrix.Translation.X);
|
||||
_vbo.Update(baseIndex + 4, parentBoneMatrix.Translation.Y);
|
||||
_vbo.Update(baseIndex + 5, parentBoneMatrix.Translation.Z);
|
||||
}
|
||||
_vbo.Unbind();
|
||||
}
|
||||
|
||||
private (int, float) GetBoneFrameData(Bone bone, Animation animation)
|
||||
|
|
@ -242,6 +280,17 @@ public class Skeleton : IDisposable
|
|||
_rest.BindBufferBase(2);
|
||||
}
|
||||
|
||||
public void RenderBones()
|
||||
{
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
|
||||
GL.BindVertexArray(vaoHandle);
|
||||
GL.DrawArrays(PrimitiveType.Lines, 0, _vertices.Length);
|
||||
GL.BindVertexArray(0);
|
||||
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
}
|
||||
|
||||
public void ImGuiBoneBreadcrumb()
|
||||
{
|
||||
var p1 = ImGui.GetCursorScreenPos();
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ public class SkeletalModel : UModel
|
|||
public bool HasMorphTargets => Morphs.Count > 0;
|
||||
|
||||
public float MorphTime;
|
||||
public bool DrawSkeleton { get; set; }
|
||||
|
||||
public SkeletalModel(USkeletalMesh export, CSkeletalMesh skeletalMesh, Transform transform = null)
|
||||
: base(export, skeletalMesh.LODs[LodLevel], export.Materials, skeletalMesh.LODs[LodLevel].Verts, skeletalMesh.LODs.Count, transform)
|
||||
|
|
@ -79,6 +80,12 @@ public class SkeletalModel : UModel
|
|||
Skeleton.Render(shader);
|
||||
}
|
||||
|
||||
public void RenderBones(Shader shader)
|
||||
{
|
||||
shader.SetUniform("uInstanceMatrix", GetTransform().Matrix);
|
||||
Skeleton.RenderBones();
|
||||
}
|
||||
|
||||
public void UpdateMorph(int index)
|
||||
{
|
||||
_morphVbo.Update(Morphs[index].Vertices);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public class Renderer : IDisposable
|
|||
private Shader _shader;
|
||||
private Shader _outline;
|
||||
private Shader _light;
|
||||
private Shader _bone;
|
||||
private bool _saveCameraMode;
|
||||
|
||||
public bool ShowSkybox;
|
||||
|
|
@ -221,6 +222,7 @@ public class Renderer : IDisposable
|
|||
_shader = new Shader();
|
||||
_outline = new Shader("outline");
|
||||
_light = new Shader("light");
|
||||
_bone = new Shader("bone");
|
||||
|
||||
Picking.Setup();
|
||||
Options.SetupModelsAndLights();
|
||||
|
|
@ -258,6 +260,14 @@ public class Renderer : IDisposable
|
|||
Options.Lights[i].Render(_light);
|
||||
}
|
||||
|
||||
// bone pass
|
||||
foreach (var model in Options.Models.Values)
|
||||
{
|
||||
if (!model.IsVisible || model is not SkeletalModel { DrawSkeleton: true } skeletalModel) continue;
|
||||
_bone.Render(viewMatrix, projMatrix);
|
||||
skeletalModel.RenderBones(_bone);
|
||||
}
|
||||
|
||||
// outline pass
|
||||
if (Options.TryGetModel(out var selected) && selected.IsVisible)
|
||||
{
|
||||
|
|
@ -563,6 +573,7 @@ public class Renderer : IDisposable
|
|||
_shader?.Dispose();
|
||||
_outline?.Dispose();
|
||||
_light?.Dispose();
|
||||
_bone?.Dispose();
|
||||
Picking?.Dispose();
|
||||
Options?.Dispose();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -428,6 +428,7 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
|
|||
s.Renderer.Options.SelectModel(guid);
|
||||
if (ImGui.MenuItem("Show", null, model.IsVisible)) model.IsVisible = !model.IsVisible;
|
||||
if (ImGui.MenuItem("Wireframe", null, model.ShowWireframe)) model.ShowWireframe = !model.ShowWireframe;
|
||||
if (model is SkeletalModel skeletalModel && ImGui.MenuItem("Draw Skeleton", null, skeletalModel.DrawSkeleton)) skeletalModel.DrawSkeleton = !skeletalModel.DrawSkeleton;
|
||||
ImGui.Separator();
|
||||
if (ImGui.MenuItem("Save"))
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user