I thought it was working but no

This commit is contained in:
4sval
2022-09-04 18:26:50 +02:00
parent 355b7f0c3d
commit c63c1d8434
8 changed files with 189 additions and 67 deletions

View File

@@ -4,6 +4,8 @@ layout (location = 0) in vec3 vPos;
layout (location = 1) in vec3 vNormal;
layout (location = 2) in vec2 vTexCoords;
layout (location = 3) in vec4 vColor;
layout (location = 4) in ivec4 vBoneIds;
layout (location = 5) in vec4 vWeights;
uniform mat4 uModel;
uniform mat4 uView;

View File

@@ -12,7 +12,7 @@ public class Camera
public float Yaw { get; set; } = -90f;
public float Pitch { get; set; } = 0f;
public float Zoom { get; set; } = 45f;
public float Speed { get; } = 1f;
public float Speed { get; set; } = 1f;
public float Near { get; } = 0.01f;
public float Far { get; } = 100f;
public float AspectRatio => 16f / 9f;

View File

@@ -0,0 +1,67 @@
using CUE4Parse.UE4.Assets.Exports.Material;
namespace FModel.Views.Snooper;
public class Cube : Model
{
public Cube(string name, string type, UMaterialInterface unrealMaterial) : base(name, type)
{
Indices = new uint[]
{
0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16,
17, 18, 19, 20, 21,
22, 23, 24, 25, 26,
27, 28, 29, 30, 31,
32, 33, 34, 35
};
Vertices = new float[] {
//X Y Z Normals U V
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
Sections = new Section[1];
Sections[0] = new Section(unrealMaterial.Name, 0, (uint) Indices.Length, 0, unrealMaterial);
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CUE4Parse_Conversion.Meshes.PSK;
using Silk.NET.OpenGL;
@@ -21,10 +22,13 @@ public class Model : IDisposable
private readonly uint[] _facesIndex = { 1, 0, 2 };
public readonly string Name;
public readonly string Type;
public readonly bool HasVertexColors;
public readonly uint[] Indices;
public readonly float[] Vertices;
public readonly Section[] Sections;
public readonly bool HasBones;
public uint[] Indices;
public float[] Vertices;
public Section[] Sections;
public readonly List<CSkelMeshBone> Skeleton;
public readonly Transform Transforms = Transform.Identity;
public readonly string[] TransformsLabels = {
@@ -33,13 +37,23 @@ public class Model : IDisposable
"X Scale", "Y", "Z"
};
public bool DisplayVertexColors;
public bool DisplayBones;
public Model(string name, CBaseMeshLod lod, CMeshVertex[] vertices)
protected Model(string name, string type)
{
Name = name;
Type = type;
}
public Model(string name, string type, CBaseMeshLod lod, CMeshVertex[] vertices, List<CSkelMeshBone> skeleton = null) : this(name, type)
{
HasVertexColors = lod.VertexColors != null;
if (HasVertexColors) _vertexSize += 4; // + Color
Skeleton = skeleton;
HasBones = Skeleton != null;
if (HasBones) _vertexSize += 8; // + BoneIds + BoneWeights
var sections = lod.Sections.Value;
Sections = new Section[sections.Length];
Indices = new uint[sections.Sum(section => section.NumFaces * _faceSize)];
@@ -53,27 +67,43 @@ public class Model : IDisposable
{
foreach (var f in _facesIndex)
{
var count = 0;
var i = face * _faceSize + f;
var index = section.FirstIndex + i;
var indice = lod.Indices.Value[index];
var vert = vertices[indice];
Vertices[index * _vertexSize] = vert.Position.X * Constants.SCALE_DOWN_RATIO;
Vertices[index * _vertexSize + 1] = vert.Position.Z * Constants.SCALE_DOWN_RATIO;
Vertices[index * _vertexSize + 2] = vert.Position.Y * Constants.SCALE_DOWN_RATIO;
Vertices[index * _vertexSize + 3] = vert.Normal.X;
Vertices[index * _vertexSize + 4] = vert.Normal.Z;
Vertices[index * _vertexSize + 5] = vert.Normal.Y;
Vertices[index * _vertexSize + 6] = vert.UV.U;
Vertices[index * _vertexSize + 7] = vert.UV.V;
Vertices[index * _vertexSize + count++] = vert.Position.X * Constants.SCALE_DOWN_RATIO;
Vertices[index * _vertexSize + count++] = vert.Position.Z * Constants.SCALE_DOWN_RATIO;
Vertices[index * _vertexSize + count++] = vert.Position.Y * Constants.SCALE_DOWN_RATIO;
Vertices[index * _vertexSize + count++] = vert.Normal.X;
Vertices[index * _vertexSize + count++] = vert.Normal.Z;
Vertices[index * _vertexSize + count++] = vert.Normal.Y;
Vertices[index * _vertexSize + count++] = vert.UV.U;
Vertices[index * _vertexSize + count++] = vert.UV.V;
if (HasVertexColors)
{
var color = lod.VertexColors[indice];
Vertices[index * _vertexSize + 8] = color.R;
Vertices[index * _vertexSize + 9] = color.G;
Vertices[index * _vertexSize + 10] = color.B;
Vertices[index * _vertexSize + 11] = color.A;
Vertices[index * _vertexSize + count++] = color.R;
Vertices[index * _vertexSize + count++] = color.G;
Vertices[index * _vertexSize + count++] = color.B;
Vertices[index * _vertexSize + count++] = color.A;
}
if (HasBones)
{
var skelVert = (CSkelMeshVertex) vert;
var weightsHash = skelVert.UnpackWeights();
Vertices[index * _vertexSize + count++] = skelVert.Bone[0];
Vertices[index * _vertexSize + count++] = skelVert.Bone[1];
Vertices[index * _vertexSize + count++] = skelVert.Bone[2];
Vertices[index * _vertexSize + count++] = skelVert.Bone[3];
Vertices[index * _vertexSize + count++] = weightsHash[0];
Vertices[index * _vertexSize + count++] = weightsHash[1];
Vertices[index * _vertexSize + count++] = weightsHash[2];
Vertices[index * _vertexSize + count++] = weightsHash[3];
}
Indices[index] = i;
@@ -98,6 +128,8 @@ public class Model : IDisposable
_vao.VertexAttributePointer(1, 3, VertexAttribPointerType.Float, _vertexSize, 3); // normal
_vao.VertexAttributePointer(2, 2, VertexAttribPointerType.Float, _vertexSize, 6); // uv
_vao.VertexAttributePointer(3, 4, VertexAttribPointerType.Float, _vertexSize, 8); // color
_vao.VertexAttributePointer(4, 4, VertexAttribPointerType.Int, _vertexSize, 12); // boneids
_vao.VertexAttributePointer(5, 4, VertexAttribPointerType.Float, _vertexSize, 16); // boneweights
for (int section = 0; section < Sections.Length; section++)
{

View File

@@ -37,18 +37,13 @@ public class Section : IDisposable
public bool HasSpecularMap;
public bool HasDiffuseColor;
public Section(string name, int index, uint facesCount, int firstFaceIndex, CMeshSection section)
private Section(string name, int index, uint facesCount, int firstFaceIndex)
{
Name = name;
Index = index;
FacesCount = facesCount;
FirstFaceIndex = firstFaceIndex;
Parameters = new CMaterialParams();
if (section.Material != null && section.Material.TryLoad(out var material) && material is UMaterialInterface unrealMaterial)
{
Name = unrealMaterial.Name;
unrealMaterial.GetParams(Parameters);
}
Show = true;
Textures = new Texture[4];
@@ -59,6 +54,20 @@ public class Section : IDisposable
_game = ApplicationService.ApplicationView.CUE4Parse.Game;
}
public Section(string name, int index, uint facesCount, int firstFaceIndex, CMeshSection section) : this(name, index, facesCount, firstFaceIndex)
{
if (section.Material != null && section.Material.TryLoad(out var material) && material is UMaterialInterface unrealMaterial)
{
Name = unrealMaterial.Name;
unrealMaterial.GetParams(Parameters);
}
}
public Section(string name, int index, uint facesCount, int firstFaceIndex, UMaterialInterface unrealMaterial) : this(name, index, facesCount, firstFaceIndex)
{
unrealMaterial.GetParams(Parameters);
}
public void Setup(GL gl)
{
_gl = gl;

View File

@@ -16,6 +16,8 @@ public class SnimGui : IDisposable
{
private readonly ImGuiController _controller;
private readonly GraphicsAPI _api;
private readonly string _renderer;
private readonly string _version;
private readonly Vector2 _outlinerSize;
private readonly Vector2 _outlinerPosition;
@@ -38,6 +40,8 @@ public class SnimGui : IDisposable
var fontConfig = new ImGuiFontConfig("C:\\Windows\\Fonts\\segoeui.ttf", 16);
_controller = new ImGuiController(gl, window, input, fontConfig);
_api = window.API;
_renderer = gl.GetStringS(StringName.Renderer);
_version = gl.GetStringS(StringName.Version);
var style = ImGui.GetStyle();
var viewport = ImGui.GetMainViewport();
@@ -121,10 +125,9 @@ public class SnimGui : IDisposable
ImGui.SetNextWindowPos(_outlinerPosition, _firstUse);
ImGui.Begin("Scene", _noResize | ImGuiWindowFlags.NoCollapse);
ImGui.Text($"{_api.API} {_api.Profile} {_api.Version.MajorVersion}.{_api.Version.MinorVersion}");
var vertices = 0;
var indices = 0;
ImGui.Text($"Platform: {_api.API} {_api.Profile} {_api.Version.MajorVersion}.{_api.Version.MinorVersion}");
ImGui.Text($"Renderer: {_renderer}");
ImGui.Text($"Version: {_version}");
ImGui.SetNextItemOpen(true, ImGuiCond.Appearing);
if (ImGui.TreeNode("Collection"))
@@ -132,8 +135,6 @@ public class SnimGui : IDisposable
for (var i = 0; i < models.Count; i++)
{
var model = models[i];
vertices += model.Vertices.Length;
indices += model.Indices.Length;
ImGui.PushID(i);
if (ImGui.Selectable(model.Name, _selectedModel == i))
_selectedModel = i;
@@ -162,9 +163,6 @@ public class SnimGui : IDisposable
ImGui.TreePop();
}
ImGui.Text($"Vertices: {vertices}");
ImGui.Text($"Indices: {indices}");
ImGui.End();
}
@@ -176,10 +174,14 @@ public class SnimGui : IDisposable
if (_selectedModel < 0) return;
var model = models[_selectedModel];
ImGui.Text($"Type: {model.Type}");
ImGui.Text($"Entity: {model.Name}");
ImGui.BeginDisabled(!model.HasVertexColors);
ImGui.Checkbox("Vertex Colors", ref model.DisplayVertexColors);
ImGui.EndDisabled();
ImGui.BeginDisabled(!model.HasBones);
ImGui.Checkbox("Bones", ref model.DisplayBones);
ImGui.EndDisabled();
if (ImGui.TreeNode("Transform"))
{
@@ -291,7 +293,7 @@ public class SnimGui : IDisposable
if (ImGui.IsItemHovered())
{
ImGui.BeginTooltip();
ImGui.Text($"Type: ({texture.Format}) {texture.Type} \"{texture.Name}\"");
ImGui.Text($"Type: ({texture.Format}) {texture.Type}:{texture.Name}");
ImGui.Text($"Texture: {texture.Path}");
ImGui.Text($"Imported: {texture.ImportedWidth}x{texture.ImportedHeight}");
ImGui.Text($"Mip Used: {texture.Width}x{texture.Height}");

View File

@@ -4,6 +4,7 @@ using System.Numerics;
using System.Runtime.InteropServices;
using System.Windows;
using CUE4Parse.UE4.Assets.Exports;
using CUE4Parse.UE4.Assets.Exports.Material;
using CUE4Parse.UE4.Assets.Exports.SkeletalMesh;
using CUE4Parse.UE4.Assets.Exports.StaticMesh;
using CUE4Parse.UE4.Objects.Core.Math;
@@ -84,25 +85,32 @@ public class Snooper
public void Run(UObject export)
{
_append = false;
switch (export)
{
case UStaticMesh st when st.TryConvert(out var mesh):
{
_models.Add(new Model(st.Name, mesh.LODs[0], mesh.LODs[0].Verts));
_models.Add(new Model(st.Name, st.ExportType, mesh.LODs[0], mesh.LODs[0].Verts));
SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO);
break;
}
case USkeletalMesh sk when sk.TryConvert(out var mesh):
{
_models.Add(new Model(sk.Name, mesh.LODs[0], mesh.LODs[0].Verts));
_models.Add(new Model(sk.Name, sk.ExportType, mesh.LODs[0], mesh.LODs[0].Verts, mesh.RefSkeleton));
SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO);
break;
}
case UMaterialInstance mi:
{
_models.Add(new Cube(mi.Name, mi.ExportType, mi));
_camera = new Camera(new Vector3(0f, 0f, 2f), Vector3.Zero, 0.01f, 0.5f * 50f, 0.5f / 2f);
break;
}
default:
throw new ArgumentOutOfRangeException(nameof(export));
}
// because this calls Reset from an internal class we must recall GL.GetApi(_window) on load
// so basically we can't keep our current scene and we have to setup everything again
_window.Run();
}
@@ -112,11 +120,11 @@ public class Snooper
var center = box.GetCenter();
var position = new Vector3(0f, center.Z, box.Max.Y * 3);
var speed = far / 2f;
if (speed > _previousSpeed)
{
if (_camera == null)
_camera = new Camera(position, center, 0.01f, far * 50f, speed);
_previousSpeed = _camera.Speed;
}
else if (speed > _previousSpeed)
_camera.Speed = _previousSpeed = speed;
}
private void OnLoad()
@@ -124,29 +132,22 @@ public class Snooper
_window.SetWindowIcon(ref _icon);
_window.Center();
if (_append)
var input = _window.CreateInput();
_keyboard = input.Keyboards[0];
_mouse = input.Mice[0];
_gl = GL.GetApi(_window);
_gl.Enable(EnableCap.Multisample);
_imGui = new SnimGui(_gl, _window, input);
_framebuffer.Setup(_gl);
_skybox.Setup(_gl);
_grid.Setup(_gl);
foreach (var model in _models)
{
_models[^1].Setup(_gl);
}
else
{
var input = _window.CreateInput();
_keyboard = input.Keyboards[0];
_mouse = input.Mice[0];
_gl = GL.GetApi(_window);
_gl.Enable(EnableCap.Multisample);
_imGui = new SnimGui(_gl, _window, input);
_framebuffer.Setup(_gl);
_skybox.Setup(_gl);
_grid.Setup(_gl);
foreach (var model in _models)
{
model.Setup(_gl);
}
model.Setup(_gl);
}
}
@@ -219,8 +220,6 @@ public class Snooper
private void OnClose()
{
if (_append) // don't dispose anything, especially _models
return;
_framebuffer.Dispose();
_grid.Dispose();
_skybox.Dispose();
@@ -228,8 +227,11 @@ public class Snooper
{
model.Dispose();
}
_models.Clear();
_previousSpeed = 0f;
if (!_append)
{
_models.Clear();
_previousSpeed = 0f;
}
_imGui.Dispose();
_window.Dispose();
_gl.Dispose();

View File

@@ -20,7 +20,15 @@ public class VertexArrayObject<TVertexType, TIndexType> : IDisposable where TVer
public unsafe void VertexAttributePointer(uint index, int count, VertexAttribPointerType type, uint vertexSize, int offSet)
{
_gl.VertexAttribPointer(index, count, type, false, vertexSize * (uint) sizeof(TVertexType), (void*) (offSet * sizeof(TVertexType)));
switch (type)
{
case VertexAttribPointerType.Int:
_gl.VertexAttribIPointer(index, count, VertexAttribIType.Int, vertexSize * (uint) sizeof(TVertexType), (void*) (offSet * sizeof(TVertexType)));
break;
default:
_gl.VertexAttribPointer(index, count, type, false, vertexSize * (uint) sizeof(TVertexType), (void*) (offSet * sizeof(TVertexType)));
break;
}
_gl.EnableVertexAttribArray(index);
}