morphing is back

This commit is contained in:
4sval 2022-11-02 00:03:04 +01:00
parent 3e41fba8b0
commit 216e8b069c
7 changed files with 181 additions and 156 deletions

View File

@ -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);

View File

@ -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
}
/// <param name="cache"></param>
/// <param name="numTexCoords"></param>
/// <param name="array"></param>
/// <param name="top">has at least 1 clearly defined texture</param>
/// <param name="triggers">list of texture parameter names</param>
/// <param name="fallback">fallback texture parameter name</param>
private void Fill(Cache cache, ref Texture[] array, bool top, IReadOnlyList<string[]> triggers, string fallback)
private void Fill(Cache cache, int numTexCoords, ref Texture[] array, bool top, IReadOnlyList<string[]> 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++)

View File

@ -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<Transform>();
}
@ -75,12 +78,13 @@ public class Model : IDisposable
private Model(string name, string type, ResolvedObject[] materials, CBaseMeshLod lod, CMeshVertex[] vertices, Transform transform, List<CSkelMeshBone> 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<Matrix4x4>(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<Matrix4x4>(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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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));

View File

@ -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();
}