mirror of
https://github.com/4sval/FModel.git
synced 2026-03-28 04:35:28 -05:00
morphing is back
This commit is contained in:
parent
3e41fba8b0
commit
216e8b069c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user