diff --git a/CUE4Parse b/CUE4Parse
index 194224af..19dfffa9 160000
--- a/CUE4Parse
+++ b/CUE4Parse
@@ -1 +1 @@
-Subproject commit 194224aff89fa4512edac7557e7a1859b878f3a8
+Subproject commit 19dfffa9e55d0951e7da75789e65c8c4e6e62a3e
diff --git a/FModel/Extensions/ImGuiExtensions.cs b/FModel/Extensions/ImGuiExtensions.cs
index c6ab3b33..f49c63cf 100644
--- a/FModel/Extensions/ImGuiExtensions.cs
+++ b/FModel/Extensions/ImGuiExtensions.cs
@@ -8,7 +8,7 @@ namespace FModel.Extensions;
public static class ImGuiExtensions
{
- public const float PADDING = 2.5f;
+ public const uint DockspaceId = 1337;
private static bool _viewportFocus;
@@ -23,13 +23,19 @@ public static class ImGuiExtensions
ImGui.SetNextWindowPos(new Vector2(0, 0));
ImGui.SetNextWindowSize(new Vector2(size.X, size.Y));
ImGui.Begin("Snooper", flags);
- ImGui.DockSpace(0);
+ ImGui.DockSpace(DockspaceId);
}
public static void DrawNavbar()
{
if (!ImGui.BeginMainMenuBar()) return;
+ if (ImGui.BeginMenu("Window"))
+ {
+ ImGui.MenuItem("Append", "CTRL+A");
+ ImGui.MenuItem("Close", "ESC");
+ ImGui.EndMenu();
+ }
if (ImGui.BeginMenu("Edit"))
{
if (ImGui.MenuItem("Undo", "CTRL+Z")) {}
@@ -48,29 +54,12 @@ public static class ImGuiExtensions
ImGui.EndMainMenuBar();
}
- public static void DrawFPS()
- {
- const ImGuiWindowFlags flags =
- ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.AlwaysAutoResize |
- ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoFocusOnAppearing |
- ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoNav;
- var viewport = ImGui.GetMainViewport();
- var work_pos = viewport.WorkPos;
- var work_size = viewport.WorkSize;
-
- ImGui.SetNextWindowPos(new Vector2(work_pos.X + PADDING, work_pos.Y + work_size.Y - PADDING), ImGuiCond.Always, new Vector2(0, 1));
- if (ImGui.Begin("FPS Overlay", flags))
- {
- float framerate = ImGui.GetIO().Framerate;
- ImGui.Text($"FPS: {framerate:0} ({1000.0f / framerate:0.##} ms)");
- }
- ImGui.End();
- }
-
public static void DrawViewport(FramebufferObject framebuffer, Camera camera, IMouse mouse)
{
const float lookSensitivity = 0.1f;
- const ImGuiWindowFlags flags = ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse;
+ const ImGuiWindowFlags flags =
+ ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse |
+ ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.AlwaysUseWindowPadding;
ImGui.Begin("Viewport", flags);
@@ -87,8 +76,9 @@ public static class ImGuiExtensions
}
var pos = new Vector2(largest.X / 2f - width / 2f + ImGui.GetCursorPosX(), largest.Y / 2f - height / 2f + ImGui.GetCursorPosY());
+ var size = new Vector2(width, height);
ImGui.SetCursorPos(pos);
- ImGui.ImageButton(framebuffer.GetPointer(), new Vector2(width, height), new Vector2(0, 1), new Vector2(1, 0), 0);
+ ImGui.ImageButton(framebuffer.GetPointer(), size, new Vector2(0, 1), new Vector2(1, 0), 0);
// it took me 5 hours to make it work, don't change any of the following code
// basically the Raw cursor doesn't actually freeze the mouse position
@@ -121,6 +111,12 @@ public static class ImGuiExtensions
mouse.Cursor.CursorMode = CursorMode.Normal;
}
+ const float padding = 5f;
+ float framerate = ImGui.GetIO().Framerate;
+ var text = $"FPS: {framerate:0} ({1000.0f / framerate:0.##} ms)";
+ ImGui.SetCursorPos(new Vector2(pos.X + padding, pos.Y + size.Y - ImGui.CalcTextSize(text).Y - padding));
+ ImGui.Text(text);
+
ImGui.End();
}
@@ -130,13 +126,10 @@ public static class ImGuiExtensions
io.ConfigFlags |= ImGuiConfigFlags.DockingEnable;
io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable;
io.ConfigWindowsMoveFromTitleBarOnly = true;
- io.ConfigWindowsResizeFromEdges = false;
+ io.ConfigDockingWithShift = true;
var style = ImGui.GetStyle();
- style.FrameRounding = 2.0f;
- style.GrabRounding = 2.0f;
style.WindowPadding = Vector2.Zero;
-
// style.Colors[(int) ImGuiCol.Text] = new Vector4(0.95f, 0.96f, 0.98f, 1.00f);
// style.Colors[(int) ImGuiCol.TextDisabled] = new Vector4(0.36f, 0.42f, 0.47f, 1.00f);
// style.Colors[(int) ImGuiCol.WindowBg] = new Vector4(0.149f, 0.149f, 0.188f, 0.35f);
diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj
index 1dcb7ee1..ce1ddf6b 100644
--- a/FModel/FModel.csproj
+++ b/FModel/FModel.csproj
@@ -93,8 +93,8 @@
-
-
+
+
@@ -110,8 +110,8 @@
-
-
+
+
diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs
index 563c3b27..f58f8d56 100644
--- a/FModel/MainWindow.xaml.cs
+++ b/FModel/MainWindow.xaml.cs
@@ -79,7 +79,7 @@ public partial class MainWindow
#if DEBUG
await _threadWorkerView.Begin(_ =>
_applicationView.CUE4Parse.Extract(
- "FortniteGame/Content/Environments/Props/Winter/Meshes/SM_ChristmasTree_Llama.uasset"));
+ "Engine/Content/BasicShapes/Cube.uasset"));
#endif
}
diff --git a/FModel/Resources/shader.frag b/FModel/Resources/default.frag
similarity index 100%
rename from FModel/Resources/shader.frag
rename to FModel/Resources/default.frag
diff --git a/FModel/Resources/shader.vert b/FModel/Resources/default.vert
similarity index 100%
rename from FModel/Resources/shader.vert
rename to FModel/Resources/default.vert
diff --git a/FModel/Views/SettingsView.xaml b/FModel/Views/SettingsView.xaml
index a0b22557..fd3b2703 100644
--- a/FModel/Views/SettingsView.xaml
+++ b/FModel/Views/SettingsView.xaml
@@ -189,18 +189,7 @@
-
+
(_gl, Indices, BufferTargetARB.ElementArrayBuffer);
_vbo = new BufferObject(_gl, Vertices, BufferTargetARB.ArrayBuffer);
_vao = new VertexArrayObject(_gl, _vbo, _ebo);
+ _shader = new Shader(_gl, "grid");
+
_vao.VertexAttributePointer(0, 3, VertexAttribPointerType.Float, 3, 0); // position
}
diff --git a/FModel/Views/Snooper/Model.cs b/FModel/Views/Snooper/Model.cs
index b63f329a..9d75b635 100644
--- a/FModel/Views/Snooper/Model.cs
+++ b/FModel/Views/Snooper/Model.cs
@@ -16,6 +16,8 @@ public class Model : IDisposable
private BufferObject _vbo;
private VertexArrayObject _vao;
+ private Shader _shader;
+
private uint _vertexSize = 8; // Position + Normal + UV
private const uint _faceSize = 3; // just so we don't have to do .Length
private readonly uint[] _facesIndex = { 1, 0, 2 };
@@ -26,7 +28,13 @@ public class Model : IDisposable
public readonly float[] Vertices;
public readonly Section[] Sections;
+ private string[] _transforms = {
+ "X Location", "Y", "Z",
+ "X Rotation", "Y", "Z",
+ "X Scale", "Y", "Z"
+ };
private bool _display_vertex_colors;
+ private Transform _transform = Transform.Identity;
public Model(string name, CBaseMeshLod lod, CMeshVertex[] vertices)
{
@@ -82,6 +90,8 @@ public class Model : IDisposable
_handle = _gl.CreateProgram();
+ _shader = new Shader(_gl);
+
_ebo = new BufferObject(_gl, Indices, BufferTargetARB.ElementArrayBuffer);
_vbo = new BufferObject(_gl, Vertices, BufferTargetARB.ArrayBuffer);
_vao = new VertexArrayObject(_gl, _vbo, _ebo);
@@ -97,19 +107,82 @@ public class Model : IDisposable
}
}
- public void Bind(Shader shader)
+ public void Bind(Camera camera)
{
_vao.Bind();
- shader.SetUniform("display_vertex_colors", _display_vertex_colors);
+ _shader.Use();
+
+ _shader.SetUniform("uModel", _transform.Matrix);
+ _shader.SetUniform("uView", camera.GetViewMatrix());
+ _shader.SetUniform("uProjection", camera.GetProjectionMatrix());
+ _shader.SetUniform("viewPos", camera.Position);
+
+ _shader.SetUniform("material.diffuseMap", 0);
+ _shader.SetUniform("material.normalMap", 1);
+ _shader.SetUniform("material.specularMap", 2);
+ _shader.SetUniform("material.emissionMap", 3);
+
+ _shader.SetUniform("light.position", camera.Position);
+
+ _shader.SetUniform("display_vertex_colors", _display_vertex_colors);
+
+ ImGui.Text($"Entity: {Name}");
+ if (ImGui.TreeNode("Transform"))
+ {
+ const int width = 100;
+ var speed = camera.Speed / 100;
+ var index = 0;
+
+ ImGui.SetNextItemWidth(width); ImGui.PushID(index);
+ ImGui.DragFloat(_transforms[index], ref _transform.Position.X, speed, 0f, 0f, "%.2f m");
+ ImGui.PopID();
+
+ index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index);
+ ImGui.DragFloat(_transforms[index], ref _transform.Position.Z, speed, 0f, 0f, "%.2f m");
+ ImGui.PopID();
+
+ index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index);
+ ImGui.DragFloat(_transforms[index], ref _transform.Position.Y, speed, 0f, 0f, "%.2f m");
+ ImGui.PopID();
+
+ ImGui.Spacing();
+
+ index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index);
+ ImGui.DragFloat(_transforms[index], ref _transform.Rotation.X, 1f, 0f, 0f, "%.1f°");
+ ImGui.PopID();
+
+ index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index);
+ ImGui.DragFloat(_transforms[index], ref _transform.Rotation.Z, 1f, 0f, 0f, "%.1f°");
+ ImGui.PopID();
+
+ index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index);
+ ImGui.DragFloat(_transforms[index], ref _transform.Rotation.Y, 1f, 0f, 0f, "%.1f°");
+ ImGui.PopID();
+
+ ImGui.Spacing();
+
+ index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index);
+ ImGui.DragFloat(_transforms[index], ref _transform.Scale.X, speed, 0f, 0f, "%.3f");
+ ImGui.PopID();
+
+ index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index);
+ ImGui.DragFloat(_transforms[index], ref _transform.Scale.Z, speed, 0f, 0f, "%.3f");
+ ImGui.PopID();
+
+ index++; ImGui.SetNextItemWidth(width); ImGui.PushID(index);
+ ImGui.DragFloat(_transforms[index], ref _transform.Scale.Y, speed, 0f, 0f, "%.3f");
+ ImGui.PopID();
+
+ ImGui.TreePop();
+ }
+ if (HasVertexColors) ImGui.Checkbox("Display Vertex Colors", ref _display_vertex_colors);
+ ImGui.Separator();
- DrawImGui();
for (int section = 0; section < Sections.Length; section++)
{
- Sections[section].Bind(shader, Indices.Length);
+ Sections[section].Bind(section, _shader);
}
-
- ImGui.Separator();
}
public void Dispose()
@@ -117,17 +190,11 @@ public class Model : IDisposable
_ebo.Dispose();
_vbo.Dispose();
_vao.Dispose();
+ _shader.Dispose();
for (int section = 0; section < Sections.Length; section++)
{
Sections[section].Dispose();
}
_gl.DeleteProgram(_handle);
}
-
- private void DrawImGui()
- {
- ImGui.Text($"Entity: {Name}");
- if (HasVertexColors)
- ImGui.Checkbox("Display Vertex Colors", ref _display_vertex_colors);
- }
}
diff --git a/FModel/Views/Snooper/Section.cs b/FModel/Views/Snooper/Section.cs
index 760d38de..f11e2a29 100644
--- a/FModel/Views/Snooper/Section.cs
+++ b/FModel/Views/Snooper/Section.cs
@@ -40,6 +40,7 @@ public class Section : IDisposable
private bool _show = true;
private bool _wireframe;
+ private bool _selected;
public Section(string name, int index, uint facesCount, int firstFaceIndex, CMeshSection section)
{
@@ -219,7 +220,7 @@ public class Section : IDisposable
}
}
- public void Bind(Shader shader, float indices)
+ public void Bind(int index, Shader shader)
{
// ImGui.TableNextRow();
//
@@ -249,7 +250,7 @@ public class Section : IDisposable
// ImGui.EndTooltip();
// }
- // DrawImGui();
+ DrawImGui(index);
_diffuseMap?.Bind(TextureUnit.Texture0);
_normalMap?.Bind(TextureUnit.Texture1);
@@ -282,10 +283,14 @@ public class Section : IDisposable
_gl.DeleteProgram(_handle);
}
- private void DrawImGui()
+ private void DrawImGui(int index)
{
- ImGui.Checkbox($"Show {Name}", ref _show);
- ImGui.Checkbox($"Wireframe {Name}", ref _wireframe);
- ImGui.Separator();
+ ImGui.PushID(index);
+ ImGui.Selectable(Name, ref _selected);
+ if (_selected)
+ {
+
+ }
+ ImGui.PopID();
}
}
diff --git a/FModel/Views/Snooper/Shader.cs b/FModel/Views/Snooper/Shader.cs
index cd540d43..89a6623d 100644
--- a/FModel/Views/Snooper/Shader.cs
+++ b/FModel/Views/Snooper/Shader.cs
@@ -11,16 +11,16 @@ public class Shader : IDisposable
private uint _handle;
private GL _gl;
- public Shader(GL gl) : this(gl, "shader.vert", "shader.frag") {}
+ public Shader(GL gl) : this(gl, "default") {}
- public Shader(GL gl, string vertex, string fragment)
+ public Shader(GL gl, string name)
{
_gl = gl;
_handle = _gl.CreateProgram();
- uint v = LoadShader(ShaderType.VertexShader, vertex);
- uint f = LoadShader(ShaderType.FragmentShader, fragment);
+ uint v = LoadShader(ShaderType.VertexShader, $"{name}.vert");
+ uint f = LoadShader(ShaderType.FragmentShader, $"{name}.frag");
_gl.AttachShader(_handle, v);
_gl.AttachShader(_handle, f);
_gl.LinkProgram(_handle);
diff --git a/FModel/Views/Snooper/Skybox.cs b/FModel/Views/Snooper/Skybox.cs
index c23a9797..65c992ff 100644
--- a/FModel/Views/Snooper/Skybox.cs
+++ b/FModel/Views/Snooper/Skybox.cs
@@ -71,13 +71,13 @@ public class Skybox : IDisposable
_handle = _gl.CreateProgram();
- _cubeMap = new Texture(_gl, _textures);
- _shader = new Shader(_gl, "skybox.vert", "skybox.frag");
-
_ebo = new BufferObject(_gl, Indices, BufferTargetARB.ElementArrayBuffer);
_vbo = new BufferObject(_gl, Vertices, BufferTargetARB.ArrayBuffer);
_vao = new VertexArrayObject(_gl, _vbo, _ebo);
+ _cubeMap = new Texture(_gl, _textures);
+ _shader = new Shader(_gl, "skybox");
+
_vao.VertexAttributePointer(0, 3, VertexAttribPointerType.Float, 3, 0); // position
}
diff --git a/FModel/Views/Snooper/Snooper.cs b/FModel/Views/Snooper/Snooper.cs
index 0b7cf1d6..71de4f94 100644
--- a/FModel/Views/Snooper/Snooper.cs
+++ b/FModel/Views/Snooper/Snooper.cs
@@ -37,8 +37,6 @@ public class Snooper
private readonly Grid _grid;
private readonly List _models;
- private Shader _shader;
-
private Vector2D _size;
public Snooper()
@@ -49,7 +47,7 @@ public class Snooper
var options = WindowOptions.Default;
options.Size = _size = new Vector2D(Convert.ToInt32(x * ratio), Convert.ToInt32(y * ratio));
- options.WindowBorder = WindowBorder.Hidden;
+ options.WindowBorder = WindowBorder.Fixed;
options.Title = "Snooper";
_window = Silk.NET.Windowing.Window.Create(options);
@@ -138,7 +136,6 @@ public class Snooper
_skybox.Setup(_gl);
_grid.Setup(_gl);
- _shader = new Shader(_gl);
foreach (var model in _models)
{
model.Setup(_gl);
@@ -165,29 +162,24 @@ public class Snooper
_skybox.Bind(_camera);
_grid.Bind(_camera);
- _shader.Use();
-
- _shader.SetUniform("uModel", Matrix4x4.Identity);
- _shader.SetUniform("uView", _camera.GetViewMatrix());
- _shader.SetUniform("uProjection", _camera.GetProjectionMatrix());
- _shader.SetUniform("viewPos", _camera.Position);
-
- _shader.SetUniform("material.diffuseMap", 0);
- _shader.SetUniform("material.normalMap", 1);
- _shader.SetUniform("material.specularMap", 2);
- _shader.SetUniform("material.emissionMap", 3);
-
- _shader.SetUniform("light.position", _camera.Position);
-
- ImGui.Begin("ImGui.NET");
+ ImGui.Begin("Properties", ImGuiWindowFlags.NoFocusOnAppearing);
+ if (ImGui.TreeNode("Camera"))
+ {
+ ImGui.Text($"Position: {_camera.Position}");
+ ImGui.Text($"Direction: {_camera.Direction}");
+ ImGui.Text($"Speed: {_camera.Speed}");
+ ImGui.Text($"Far: {_camera.Far}");
+ ImGui.Text($"Near: {_camera.Near}");
+ ImGui.Text($"Zoom: {_camera.Zoom}");
+ ImGui.TreePop();
+ }
foreach (var model in _models)
{
- model.Bind(_shader);
+ model.Bind(_camera);
}
ImGui.End();
ImGuiExtensions.DrawViewport(_framebuffer, _camera, _mouse);
- ImGuiExtensions.DrawFPS();
_framebuffer.BindMsaa();
_framebuffer.Bind(0); // switch back to main window
@@ -232,7 +224,6 @@ public class Snooper
_framebuffer.Dispose();
_grid.Dispose();
_skybox.Dispose();
- _shader.Dispose();
foreach (var model in _models)
{
model.Dispose();
diff --git a/FModel/Views/Snooper/Transform.cs b/FModel/Views/Snooper/Transform.cs
index 563fb14d..9fb4476b 100644
--- a/FModel/Views/Snooper/Transform.cs
+++ b/FModel/Views/Snooper/Transform.cs
@@ -4,12 +4,21 @@ namespace FModel.Views.Snooper;
public class Transform
{
- public Vector3 Position { get; set; } = new Vector3(0, 0, 0);
+ public static Transform Identity
+ {
+ get => new ();
+ }
- public float Scale { get; set; } = 1f;
+ public Vector3 Position = Vector3.Zero;
+ public Vector3 Rotation = Vector3.Zero;
+ public Vector3 Scale = Vector3.One;
- public Quaternion Rotation { get; set; } = Quaternion.Identity;
-
- //Note: The order here does matter.
- public Matrix4x4 ViewMatrix => Matrix4x4.Identity * Matrix4x4.CreateFromQuaternion(Rotation) * Matrix4x4.CreateScale(Scale) * Matrix4x4.CreateTranslation(Position);
+ public Matrix4x4 Matrix =>
+ Matrix4x4.Identity *
+ Matrix4x4.CreateFromYawPitchRoll(
+ Helper.DegreesToRadians(Rotation.Y),
+ Helper.DegreesToRadians(Rotation.X),
+ Helper.DegreesToRadians(Rotation.Z)) *
+ Matrix4x4.CreateScale(Scale) *
+ Matrix4x4.CreateTranslation(Position);
}