From 216e8b069cfc1377e223fbab3cc0c5e41bbc76cc Mon Sep 17 00:00:00 2001 From: 4sval Date: Wed, 2 Nov 2022 00:03:04 +0100 Subject: [PATCH] morphing is back --- FModel/Views/Snooper/Cube.cs | 76 +++++++-------- FModel/Views/Snooper/Material.cs | 32 +++--- FModel/Views/Snooper/Model.cs | 49 ++++++---- FModel/Views/Snooper/Renderer.cs | 5 +- FModel/Views/Snooper/Section.cs | 2 - FModel/Views/Snooper/SnimGui.cs | 162 +++++++++++++++++-------------- FModel/Views/Snooper/Snooper.cs | 11 +-- 7 files changed, 181 insertions(+), 156 deletions(-) diff --git a/FModel/Views/Snooper/Cube.cs b/FModel/Views/Snooper/Cube.cs index 8b8674a2..c21aad63 100644 --- a/FModel/Views/Snooper/Cube.cs +++ b/FModel/Views/Snooper/Cube.cs @@ -17,52 +17,52 @@ public class Cube : Model 32, 33, 34, 35 }; Vertices = new float[] { - // I X Y Z Normals U V - -1, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, - -1, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, - -1, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, - -1, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, - -1, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, - -1, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, + // I X Y Z Normals U V Layer + -1, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, .5f, + -1, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, .5f, + -1, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, .5f, + -1, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, .5f, + -1, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, .5f, + -1, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, .5f, - -1, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, - -1, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - -1, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, - -1, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, - -1, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - -1, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, + -1, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, .5f, + -1, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, .5f, + -1, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, .5f, + -1, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, .5f, + -1, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, .5f, + -1, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, .5f, - -1, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - -1, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, - -1, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - -1, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - -1, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, - -1, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + -1, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, .5f, + -1, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, .5f, + -1, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, .5f, + -1, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, .5f, + -1, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, .5f, + -1, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, .5f, - -1, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - -1, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, - -1, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - -1, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - -1, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, - -1, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + -1, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, .5f, + -1, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, .5f, + -1, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, .5f, + -1, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, .5f, + -1, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, .5f, + -1, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, .5f, - -1, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, - -1, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, - -1, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, - -1, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, - -1, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, - -1, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, + -1, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, .5f, + -1, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, .5f, + -1, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, .5f, + -1, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, .5f, + -1, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, .5f, + -1, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, .5f, - -1, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, - -1, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, - -1, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, - -1, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, - -1, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, - -1, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f + -1, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, .5f, + -1, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, .5f, + -1, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, .5f, + -1, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, .5f, + -1, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, .5f, + -1, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, .5f }; Materials = new Material[1]; - Materials[0] = new Material(1, unrealMaterial) { IsUsed = true }; + Materials[0] = new Material(unrealMaterial) { IsUsed = true }; Sections = new Section[1]; Sections[0] = new Section(0, Indices.Length, 0); diff --git a/FModel/Views/Snooper/Material.cs b/FModel/Views/Snooper/Material.cs index 179d72f2..02dc5af9 100644 --- a/FModel/Views/Snooper/Material.cs +++ b/FModel/Views/Snooper/Material.cs @@ -12,7 +12,6 @@ public class Material : IDisposable private int _handle; public readonly CMaterialParams2 Parameters; - public readonly int UvNumber; public string Name; public int SelectedChannel; public bool IsUsed; @@ -29,10 +28,9 @@ public class Material : IDisposable private Vector3 _ambientLight; - public Material(int numUvs) + public Material() { Parameters = new CMaterialParams2(); - UvNumber = numUvs; Name = ""; IsUsed = false; @@ -49,7 +47,7 @@ public class Material : IDisposable _ambientLight = Vector3.One; } - public Material(int numUvs, UMaterialInterface unrealMaterial) : this(numUvs) + public Material(UMaterialInterface unrealMaterial) : this() { SwapMaterial(unrealMaterial); } @@ -60,7 +58,7 @@ public class Material : IDisposable unrealMaterial.GetParams(Parameters); } - public void Setup(Cache cache) + public void Setup(Cache cache, int numTexCoords) { _handle = GL.CreateProgram(); @@ -70,12 +68,17 @@ public class Material : IDisposable } else { - Fill(cache, ref Diffuse, Parameters.HasTopDiffuse, CMaterialParams2.Diffuse, CMaterialParams2.FallbackDiffuse); - Fill(cache, ref Normals, true, CMaterialParams2.Normals, CMaterialParams2.FallbackNormals); - Fill(cache, ref SpecularMasks, true, CMaterialParams2.SpecularMasks, CMaterialParams2.FallbackSpecularMasks); - Fill(cache, ref Emissive, true, CMaterialParams2.Emissive, CMaterialParams2.FallbackEmissive); + Fill(cache, numTexCoords, ref Diffuse, Parameters.HasTopDiffuse, CMaterialParams2.Diffuse, CMaterialParams2.FallbackDiffuse); + Fill(cache, numTexCoords, ref Normals, true, CMaterialParams2.Normals, CMaterialParams2.FallbackNormals); + Fill(cache, numTexCoords, ref SpecularMasks, true, CMaterialParams2.SpecularMasks, CMaterialParams2.FallbackSpecularMasks); + Fill(cache, numTexCoords, ref Emissive, true, CMaterialParams2.Emissive, CMaterialParams2.FallbackEmissive); - EmissionColor = new Vector4[UvNumber]; + // if (Parameters.Colors.TryGetValue("ColorMult", out var color) && color is { A: > 0}) + // { + // DiffuseColor = new Vector4(color.R, color.G, color.B, color.A); + // } + + EmissionColor = new Vector4[numTexCoords]; for (int i = 0; i < EmissionColor.Length; i++) { if (Emissive[i] == null) continue; @@ -96,23 +99,20 @@ public class Material : IDisposable } /// + /// /// /// has at least 1 clearly defined texture /// list of texture parameter names /// fallback texture parameter name - private void Fill(Cache cache, ref Texture[] array, bool top, IReadOnlyList triggers, string fallback) + private void Fill(Cache cache, int numTexCoords, ref Texture[] array, bool top, IReadOnlyList triggers, string fallback) { - array = new Texture[UvNumber]; + array = new Texture[numTexCoords]; if (top) { for (int i = 0; i < array.Length; i++) if (Parameters.TryGetTexture2d(out var o, triggers[i]) && cache.TryGetCachedTexture(o, out var t)) array[i] = t; } - // else if (Parameters.Colors.TryGetValue("ColorMult", out var color) && color is { A: > 0}) - // { - // - // } else if (Parameters.Textures.TryGetValue(fallback, out var u) && u is UTexture2D o && cache.TryGetCachedTexture(o, out var t)) { for (int i = 0; i < array.Length; i++) diff --git a/FModel/Views/Snooper/Model.cs b/FModel/Views/Snooper/Model.cs index 436bfbdb..747d1d85 100644 --- a/FModel/Views/Snooper/Model.cs +++ b/FModel/Views/Snooper/Model.cs @@ -30,6 +30,7 @@ public class Model : IDisposable public readonly bool HasVertexColors; public readonly bool HasBones; public readonly bool HasMorphTargets; + public readonly int NumTexCoords; public uint[] Indices; public float[] Vertices; public Section[] Sections; @@ -42,6 +43,7 @@ public class Model : IDisposable public readonly Morph[] Morphs; public bool Show; + public bool Wireframe; public bool IsSetup; public bool IsSelected; public bool DisplayVertexColors; @@ -53,6 +55,7 @@ public class Model : IDisposable { Name = name; Type = type; + NumTexCoords = 1; Transforms = new List(); } @@ -75,12 +78,13 @@ public class Model : IDisposable private Model(string name, string type, ResolvedObject[] materials, CBaseMeshLod lod, CMeshVertex[] vertices, Transform transform, List skeleton = null) : this(name, type) { + NumTexCoords = lod.NumTexCoords; + Materials = new Material[materials.Length]; for (int m = 0; m < Materials.Length; m++) { if ((materials[m]?.TryLoad(out var material) ?? false) && material is UMaterialInterface unrealMaterial) - Materials[m] = new Material(lod.NumTexCoords, unrealMaterial); - else Materials[m] = new Material(1); + Materials[m] = new Material(unrealMaterial); else Materials[m] = new Material(); } if (lod.VertexColors is { Length: > 0}) @@ -158,7 +162,11 @@ public class Model : IDisposable AddInstance(transform); } - public void AddInstance(Transform transform) => Transforms.Add(transform); + public void AddInstance(Transform transform) + { + TransformsCount++; + Transforms.Add(transform); + } public void UpdateMatrix(int instance) { @@ -174,6 +182,15 @@ public class Model : IDisposable _morphVbo.Unbind(); } + public void SetupInstances() + { + var instanceMatrix = new Matrix4x4[TransformsCount]; + for (var i = 0; i < instanceMatrix.Length; i++) + instanceMatrix[i] = Transforms[i].Matrix; + _matrixVbo = new BufferObject(instanceMatrix, BufferTarget.ArrayBuffer); + _vao.BindInstancing(); // VertexAttributePointer 7, 8, 9, 10 + } + public void Setup(Cache cache) { _handle = GL.CreateProgram(); @@ -191,21 +208,13 @@ public class Model : IDisposable _vao.VertexAttributePointer(6, 4, VertexAttribPointerType.Int, _vertexSize, 14); // boneids _vao.VertexAttributePointer(7, 4, VertexAttribPointerType.Float, _vertexSize, 18); // boneweights - { // instanced models transform - TransformsCount = Transforms.Count; - var instanceMatrix = new Matrix4x4[TransformsCount]; - for (var i = 0; i < instanceMatrix.Length; i++) - instanceMatrix[i] = Transforms[i].Matrix; - _matrixVbo = new BufferObject(instanceMatrix, BufferTarget.ArrayBuffer); - _vao.BindInstancing(); // VertexAttributePointer 7, 8, 9, 10 - } + SetupInstances(); // instanced models transform - { // setup all used materials for use in different UV channels - for (var i = 0; i < Materials.Length; i++) - { - if (!Materials[i].IsUsed) continue; - Materials[i].Setup(cache); - } + // setup all used materials for use in different UV channels + for (var i = 0; i < Materials.Length; i++) + { + if (!Materials[i].IsUsed) continue; + Materials[i].Setup(cache, NumTexCoords); } if (HasMorphTargets) @@ -223,7 +232,7 @@ public class Model : IDisposable for (int section = 0; section < Sections.Length; section++) { - if (Sections[section].Show) Show = true; + if (!Show) Show = Sections[section].Show; Sections[section].Setup(); } @@ -241,6 +250,8 @@ public class Model : IDisposable _vao.Bind(); shader.SetUniform("uMorphTime", MorphTime); shader.SetUniform("display_vertex_colors", DisplayVertexColors); + + GL.PolygonMode(MaterialFace.FrontAndBack, Wireframe ? PolygonMode.Line : PolygonMode.Fill); for (int section = 0; section < Sections.Length; section++) { Materials[Sections[section].MaterialIndex].Render(shader); @@ -264,6 +275,8 @@ public class Model : IDisposable _vao.Bind(); shader.Use(); shader.SetUniform("uMorphTime", MorphTime); + + GL.PolygonMode(MaterialFace.FrontAndBack, Wireframe ? PolygonMode.Line : PolygonMode.Fill); for (int section = 0; section < Sections.Length; section++) { if (!Sections[section].Show) continue; diff --git a/FModel/Views/Snooper/Renderer.cs b/FModel/Views/Snooper/Renderer.cs index a5570ca7..5919ecf8 100644 --- a/FModel/Views/Snooper/Renderer.cs +++ b/FModel/Views/Snooper/Renderer.cs @@ -1,5 +1,6 @@ using System; using System.Threading; +using System.Windows; using CUE4Parse_Conversion.Meshes; using CUE4Parse.UE4.Assets.Exports; using CUE4Parse.UE4.Assets.Exports.Material; @@ -48,6 +49,7 @@ public class Renderer : IDisposable !Settings.TryGetSection(model, out var section)) return; model.Materials[section.MaterialIndex].SwapMaterial(unrealMaterial); + Application.Current.Dispatcher.Invoke(() => model.Materials[section.MaterialIndex].Setup(Cache, model.NumTexCoords)); Settings.SwapMaterial(false); } @@ -92,7 +94,7 @@ public class Renderer : IDisposable return new Camera( new Vector3(0f, center.Z, box.Max.Y * 3), new Vector3(center.X, center.Z, center.Y), - 0.01f, far * 50f, far / 2f); + 0.01f, far * 50f, far / 1.5f); } private Camera LoadStaticMesh(UStaticMesh original) @@ -101,6 +103,7 @@ public class Renderer : IDisposable if (Cache.Models.TryGetValue(guid, out var model)) { model.AddInstance(Transform.Identity); + Application.Current.Dispatcher.Invoke(() => model.SetupInstances()); return null; } diff --git a/FModel/Views/Snooper/Section.cs b/FModel/Views/Snooper/Section.cs index 7c3555ca..fb9e899c 100644 --- a/FModel/Views/Snooper/Section.cs +++ b/FModel/Views/Snooper/Section.cs @@ -12,7 +12,6 @@ public class Section : IDisposable public readonly int FirstFaceIndex; public bool Show; - public bool Wireframe; public Section(int index, int facesCount, int firstFaceIndex) { @@ -35,7 +34,6 @@ public class Section : IDisposable public void Render(int instanceCount) { - GL.PolygonMode(MaterialFace.FrontAndBack, Wireframe ? PolygonMode.Line : PolygonMode.Fill); if (Show) GL.DrawArraysInstanced(PrimitiveType.Triangles, FirstFaceIndex, FacesCount, instanceCount); } diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs index 1d06c96b..8a195361 100644 --- a/FModel/Views/Snooper/SnimGui.cs +++ b/FModel/Views/Snooper/SnimGui.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Windows; using CUE4Parse.UE4.Objects.Core.Misc; using FModel.Framework; @@ -14,19 +13,13 @@ namespace FModel.Views.Snooper; public class SnimGui { public readonly ImGuiController Controller; - - private readonly Vector2 _outlinerSize; - private readonly Vector2 _outlinerPosition; - private readonly Vector2 _propertiesSize; - private readonly Vector2 _propertiesPosition; - private readonly Vector2 _viewportSize; - private readonly Vector2 _viewportPosition; - private readonly Vector2 _textureSize; - private readonly Vector2 _texturePosition; private bool _viewportFocus; - private const ImGuiWindowFlags _noResize = ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove; // delete once we have a proper docking branch - private const ImGuiCond _firstUse = ImGuiCond.Appearing; // switch to FirstUseEver once the docking branch will not be useful anymore... + private readonly Vector4 _accentColor = new (32, 107, 212, 1f); + private readonly Vector4 _alertColor = new (212, 146, 32, 1f); + private readonly Vector4 _errorColor = new (194, 43, 43, 1f); + + private const ImGuiCond _firstUse = ImGuiCond.FirstUseEver; // switch to FirstUseEver once the docking branch will not be useful anymore... private const uint _dockspaceId = 1337; public SnimGui(int width, int height) @@ -34,18 +27,6 @@ public class SnimGui Controller = new ImGuiController(width, height); var style = ImGui.GetStyle(); - var viewport = ImGui.GetMainViewport(); - var titleBarHeight = ImGui.GetFontSize() + style.FramePadding.Y * 2; - - // _outlinerSize = new Vector2(400, 300); - // _outlinerPosition = new Vector2(viewport.WorkSize.X - _outlinerSize.X, titleBarHeight); - // _propertiesSize = _outlinerSize with { Y = viewport.WorkSize.Y - _outlinerSize.Y - titleBarHeight }; - // _propertiesPosition = new Vector2(viewport.WorkSize.X - _propertiesSize.X, _outlinerPosition.Y + _outlinerSize.Y); - _viewportSize = new Vector2(width, height); - _viewportPosition = new Vector2(0, titleBarHeight); - // _textureSize = _viewportSize with { Y = viewport.WorkSize.Y - _viewportSize.Y - titleBarHeight }; - // _texturePosition = new Vector2(0, _viewportPosition.Y + _viewportSize.Y); - Theme(style); } @@ -131,9 +112,10 @@ public class SnimGui { PushStyleCompact(); - if (ImGui.BeginTable("Items", 2, ImGuiTableFlags.Borders | ImGuiTableFlags.Resizable)) + if (ImGui.BeginTable("Items", 3, ImGuiTableFlags.Borders | ImGuiTableFlags.Resizable)) { - ImGui.TableSetupColumn("Count", ImGuiTableColumnFlags.NoHeaderWidth | ImGuiTableColumnFlags.WidthFixed); + ImGui.TableSetupColumn("Instance", ImGuiTableColumnFlags.NoHeaderWidth | ImGuiTableColumnFlags.WidthFixed); + ImGui.TableSetupColumn("Channels", ImGuiTableColumnFlags.WidthFixed); ImGui.TableSetupColumn("Name"); ImGui.TableHeadersRow(); @@ -150,6 +132,8 @@ public class SnimGui ImGui.Text(model.TransformsCount.ToString("D")); ImGui.TableNextColumn(); + ImGui.Text(model.NumTexCoords.ToString("D")); + ImGui.TableNextColumn(); model.IsSelected = s.Renderer.Settings.SelectedModel == guid; if (ImGui.Selectable(model.Name, model.IsSelected, ImGuiSelectableFlags.SpanAllColumns)) { @@ -180,13 +164,13 @@ public class SnimGui { if (ImGui.Begin("Details")) { + PushStyleCompact(); var guid = s.Renderer.Settings.SelectedModel; if (s.Renderer.Cache.Models.TryGetValue(guid, out var model)) { ImGui.Text($"Entity: ({model.Type}) {model.Name}"); ImGui.Text($"Guid: {guid.ToString(EGuidFormats.UniqueObjectGuid)}"); - PushStyleCompact(); ImGui.Columns(4, "Actions", false); if (ImGui.Button("Go To")) { @@ -194,58 +178,90 @@ public class SnimGui s.Camera.Position = new Vector3(instancePos.X, instancePos.Z, instancePos.Y); } ImGui.NextColumn(); ImGui.Checkbox("Show", ref model.Show); + ImGui.NextColumn(); ImGui.BeginDisabled(!model.Show); ImGui.Checkbox("Wire", ref model.Wireframe); ImGui.EndDisabled(); ImGui.NextColumn(); ImGui.BeginDisabled(!model.HasVertexColors); ImGui.Checkbox("Colors", ref model.DisplayVertexColors); ImGui.EndDisabled(); - ImGui.NextColumn(); ImGui.BeginDisabled(!model.HasBones); ImGui.Checkbox("Bones", ref model.DisplayBones); ImGui.EndDisabled(); ImGui.Columns(1); - ImGui.Spacing(); ImGui.Separator(); - ImGui.Spacing(); - if (ImGui.BeginTable("Sections", 3, ImGuiTableFlags.Borders | ImGuiTableFlags.Resizable)) + if (ImGui.BeginTabBar("tabbar_details", ImGuiTabBarFlags.None)) { - ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed); - ImGui.TableSetupColumn("Channels", ImGuiTableColumnFlags.WidthFixed); - ImGui.TableSetupColumn("Material"); - ImGui.TableHeadersRow(); - - for (var i = 0; i < model.Sections.Length; i++) + if (ImGui.BeginTabItem("Sections") && ImGui.BeginTable("table_sections", 2, ImGuiTableFlags.Borders | ImGuiTableFlags.Resizable)) { - var section = model.Sections[i]; - var material = model.Materials[section.MaterialIndex]; + ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed); + ImGui.TableSetupColumn("Material"); + ImGui.TableHeadersRow(); - ImGui.PushID(i); - ImGui.TableNextRow(); - ImGui.TableNextColumn(); - if (!section.Show) + for (var i = 0; i < model.Sections.Length; i++) { - ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg0, ImGui.GetColorU32(new Vector4(1, 0, 0, .5f))); + var section = model.Sections[i]; + var material = model.Materials[section.MaterialIndex]; + + ImGui.PushID(i); + ImGui.TableNextRow(); + ImGui.TableNextColumn(); + if (!section.Show) + { + ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg0, ImGui.GetColorU32(new Vector4(1, 0, 0, .5f))); + } + + ImGui.Text(section.MaterialIndex.ToString("D")); + ImGui.TableNextColumn(); + if (ImGui.Selectable(material.Name, s.Renderer.Settings.SelectedSection == i, ImGuiSelectableFlags.SpanAllColumns)) + { + s.Renderer.Settings.SelectSection(i); + } + if (ImGui.BeginPopupContextItem()) + { + s.Renderer.Settings.SelectSection(i); + if (ImGui.Selectable("Swap")) s.Renderer.Settings.SwapMaterial(true); + if (ImGui.Selectable("Copy Name to Clipboard")) Application.Current.Dispatcher.Invoke(() => Clipboard.SetText(material.Name)); + ImGui.EndPopup(); + } + ImGui.PopID(); } - ImGui.Text(section.MaterialIndex.ToString("D")); - ImGui.TableNextColumn(); - ImGui.Text(material.UvNumber.ToString("D")); - ImGui.TableNextColumn(); - if (ImGui.Selectable(material.Name, s.Renderer.Settings.SelectedSection == i, ImGuiSelectableFlags.SpanAllColumns)) - { - s.Renderer.Settings.SelectSection(i); - } - if (ImGui.BeginPopupContextItem()) - { - s.Renderer.Settings.SelectSection(i); - if (ImGui.Selectable("Swap")) s.Renderer.Settings.SwapMaterial(true); - if (ImGui.Selectable("Copy Name to Clipboard")) Application.Current.Dispatcher.Invoke(() => Clipboard.SetText(material.Name)); - ImGui.EndPopup(); - } - ImGui.PopID(); + ImGui.EndTable(); + ImGui.EndTabItem(); } - ImGui.EndTable(); + if (ImGui.BeginTabItem("Morph Targets")) + { + if (model.HasMorphTargets) + { + const float width = 10; + var region = ImGui.GetContentRegionAvail(); + var box = new Vector2(region.X - width, region.Y / 1.5f); + + if (ImGui.BeginListBox("", box)) + { + for (int i = 0; i < model.Morphs.Length; i++) + { + ImGui.PushID(i); + if (ImGui.Selectable(model.Morphs[i].Name, s.Renderer.Settings.SelectedMorph == i)) + { + s.Renderer.Settings.SelectMorph(i, model); + } + ImGui.PopID(); + } + ImGui.EndListBox(); + + ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(2f, 0f)); + ImGui.SameLine(); ImGui.PushID(99); + ImGui.VSliderFloat("", box with { X = width }, ref model.MorphTime, 0.0f, 1.0f, "", ImGuiSliderFlags.AlwaysClamp); + ImGui.PopID(); ImGui.PopStyleVar(); + } + } + else + { + ImGui.TextColored(_errorColor, "mesh has no morph targets"); + } + + ImGui.EndTabItem(); + } } - - PopStyleCompact(); } - + PopStyleCompact(); ImGui.End(); } } @@ -254,12 +270,12 @@ public class SnimGui { if (ImGui.Begin("Transform")) { + PushStyleCompact(); if (s.Renderer.Cache.Models.TryGetValue(s.Renderer.Settings.SelectedModel, out var model)) { const int width = 100; var speed = s.Camera.Speed / 100; - PushStyleCompact(); ImGui.PushID(0); ImGui.BeginDisabled(model.TransformsCount < 2); ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); ImGui.SliderInt("", ref model.SelectedInstance, 0, model.TransformsCount - 1, "Instance %i", ImGuiSliderFlags.AlwaysClamp); @@ -316,9 +332,8 @@ public class SnimGui } model.UpdateMatrix(model.SelectedInstance); - PopStyleCompact(); } - + PopStyleCompact(); ImGui.End(); } } @@ -327,16 +342,16 @@ public class SnimGui { if (ImGui.Begin("UV Channels")) { + PushStyleCompact(); if (s.Renderer.Cache.Models.TryGetValue(s.Renderer.Settings.SelectedModel, out var model) && s.Renderer.Settings.TryGetSection(model, out var section)) { var width = ImGui.GetContentRegionAvail().X; var material = model.Materials[section.MaterialIndex]; - PushStyleCompact(); - ImGui.PushID(0); ImGui.BeginDisabled(material.UvNumber < 2); + ImGui.PushID(0); ImGui.BeginDisabled(model.NumTexCoords < 2); ImGui.SetNextItemWidth(width); - ImGui.SliderInt("", ref material.SelectedChannel, 0, material.UvNumber - 1, "Channel %i", ImGuiSliderFlags.AlwaysClamp); + ImGui.SliderInt("", ref material.SelectedChannel, 0, model.NumTexCoords - 1, "Channel %i", ImGuiSliderFlags.AlwaysClamp); ImGui.EndDisabled(); ImGui.PopID(); ImGui.SetNextItemOpen(true, ImGuiCond.Appearing); @@ -348,10 +363,8 @@ public class SnimGui DrawSquareTexture(material.SpecularMasks[material.SelectedChannel], size); ImGui.SameLine(); DrawSquareTexture(material.Emissive[material.SelectedChannel], size); ImGui.SameLine(); } - - PopStyleCompact(); } - + PopStyleCompact(); ImGui.End(); } } @@ -417,6 +430,7 @@ public class SnimGui ImGui.End(); } + private void PopStyleCompact() => ImGui.PopStyleVar(2); private void PushStyleCompact() { var style = ImGui.GetStyle(); @@ -424,8 +438,6 @@ public class SnimGui ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, style.ItemSpacing with { Y = style.ItemSpacing.Y * 0.6f }); } - private void PopStyleCompact() => ImGui.PopStyleVar(2); - private void DrawSquareTexture(Texture texture, Vector2 size) => ImGui.Image(texture?.GetPointer() ?? IntPtr.Zero, size, Vector2.Zero, Vector2.One, Vector4.One, new Vector4(1, 1, 1, .5f)); diff --git a/FModel/Views/Snooper/Snooper.cs b/FModel/Views/Snooper/Snooper.cs index 5b5b68e0..04d3e13b 100644 --- a/FModel/Views/Snooper/Snooper.cs +++ b/FModel/Views/Snooper/Snooper.cs @@ -99,20 +99,19 @@ public class Snooper : GameWindow if (!IsVisible) return; + ClearWhatHasBeenDrawn(); // clear window background _gui.Controller.Update(this, (float)args.Time); - ClearWhatHasBeenDrawn(); + _gui.Render(this); - Framebuffer.Bind(); - ClearWhatHasBeenDrawn(); + Framebuffer.Bind(); // switch to viewport background + ClearWhatHasBeenDrawn(); // clear viewport background _skybox.Render(Camera); _grid.Render(Camera); Renderer.Render(Camera); Framebuffer.BindMsaa(); - Framebuffer.Bind(0); - - _gui.Render(this); + Framebuffer.Bind(0); // switch to window background SwapBuffers(); }