diff --git a/CUE4Parse b/CUE4Parse
index 24c816df..4514f1ac 160000
--- a/CUE4Parse
+++ b/CUE4Parse
@@ -1 +1 @@
-Subproject commit 24c816dfd462a95e087344419486a8f8008f77f5
+Subproject commit 4514f1acd51c9d3458eb0eda0abf37bb77453d2b
diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj
index 34e7e4e1..dc171282 100644
--- a/FModel/FModel.csproj
+++ b/FModel/FModel.csproj
@@ -156,7 +156,6 @@
-
@@ -168,6 +167,7 @@
+
diff --git a/FModel/Framework/ImGuiController.cs b/FModel/Framework/ImGuiController.cs
index 66dd6f47..6bd5c620 100644
--- a/FModel/Framework/ImGuiController.cs
+++ b/FModel/Framework/ImGuiController.cs
@@ -3,12 +3,12 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Numerics;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using FModel.Settings;
using ImGuiNET;
+using ImGuizmoNET;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.GraphicsLibraryFramework;
@@ -54,11 +54,12 @@ public class ImGuiController : IDisposable
int major = GL.GetInteger(GetPName.MajorVersion);
int minor = GL.GetInteger(GetPName.MinorVersion);
-
KHRDebugAvailable = (major == 4 && minor >= 3) || IsExtensionSupported("KHR_debug");
IntPtr context = ImGui.CreateContext();
ImGui.SetCurrentContext(context);
+ IntPtr imguiCtx = ImGui.CreateContext();
+ ImGui.SetCurrentContext(imguiCtx);
var io = ImGui.GetIO();
unsafe
@@ -69,32 +70,24 @@ public class ImGuiController : IDisposable
FontNormal = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeui.ttf", 16 * DpiScale);
FontBold = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeuib.ttf", 16 * DpiScale);
FontSemiBold = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\seguisb.ttf", 16 * DpiScale);
+ io.Fonts.AddFontDefault();
+ io.Fonts.Build(); // Build font atlas
io.BackendFlags |= ImGuiBackendFlags.RendererHasVtxOffset;
io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags.DockingEnable;
- io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable;
io.Fonts.Flags |= ImFontAtlasFlags.NoBakedLines;
- // io.ConfigDockingWithShift = true;
+ io.ConfigDockingWithShift = true;
io.ConfigWindowsMoveFromTitleBarOnly = true;
+ io.BackendRendererUserData = 0;
CreateDeviceResources();
-
- SetPerFrameImGuiData(1f / 60f);
-
- ImGui.NewFrame();
- _frameBegun = true;
}
+ public void Normal() => PushFont(FontNormal);
public void Bold() => PushFont(FontBold);
public void SemiBold() => PushFont(FontSemiBold);
- public void PopFont()
- {
- ImGui.PopFont();
- PushFont(FontNormal);
- }
-
private void PushFont(ImFontPtr ptr) => ImGui.PushFont(ptr);
public void WindowResized(int width, int height)
@@ -132,34 +125,42 @@ public class ImGuiController : IDisposable
RecreateFontDeviceTexture();
- string VertexSource = @"#version 460 core
+ string VertexSource = @"#version 330 core
+
uniform mat4 projection_matrix;
+
layout(location = 0) in vec2 in_position;
layout(location = 1) in vec2 in_texCoord;
layout(location = 2) in vec4 in_color;
+
out vec4 color;
out vec2 texCoord;
+
void main()
{
-gl_Position = projection_matrix * vec4(in_position, 0, 1);
-color = in_color;
-texCoord = in_texCoord;
+ gl_Position = projection_matrix * vec4(in_position, 0, 1);
+ color = in_color;
+ texCoord = in_texCoord;
}";
- string FragmentSource = @"#version 460 core
+ string FragmentSource = @"#version 330 core
+
uniform sampler2D in_fontTexture;
+
in vec4 color;
in vec2 texCoord;
+
out vec4 outputColor;
+
void main()
{
-outputColor = color * texture(in_fontTexture, texCoord);
+ outputColor = color * texture(in_fontTexture, texCoord);
}";
_shader = CreateProgram("ImGui", VertexSource, FragmentSource);
_shaderProjectionMatrixLocation = GL.GetUniformLocation(_shader, "projection_matrix");
_shaderFontTextureLocation = GL.GetUniformLocation(_shader, "in_fontTexture");
- int stride = Unsafe.SizeOf();
+ int stride = Marshal.SizeOf();
GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, stride, 0);
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, stride, 8);
GL.VertexAttribPointer(2, 4, VertexAttribPointerType.UnsignedByte, true, stride, 16);
@@ -225,7 +226,6 @@ outputColor = color * texture(in_fontTexture, texCoord);
ImGui.Render();
RenderImDrawData(ImGui.GetDrawData());
}
- CheckGLError("End of frame");
}
///
@@ -243,6 +243,7 @@ outputColor = color * texture(in_fontTexture, texCoord);
_frameBegun = true;
ImGui.NewFrame();
+ ImGuizmo.BeginFrame();
}
///
@@ -252,7 +253,6 @@ outputColor = color * texture(in_fontTexture, texCoord);
private void SetPerFrameImGuiData(float deltaSeconds)
{
ImGuiIOPtr io = ImGui.GetIO();
- // if (io.WantSaveIniSettings) ImGui.SaveIniSettingsToDisk(_iniPath);
io.DisplaySize = new Vector2(
_windowWidth / _scaleFactor.X,
_windowHeight / _scaleFactor.Y);
@@ -265,6 +265,7 @@ outputColor = color * texture(in_fontTexture, texCoord);
private void UpdateImGuiInput(GameWindow wnd)
{
ImGuiIOPtr io = ImGui.GetIO();
+
var mState = wnd.MouseState;
var kState = wnd.KeyboardState;
@@ -276,7 +277,7 @@ outputColor = color * texture(in_fontTexture, texCoord);
io.AddMouseButtonEvent(4, mState[MouseButton.Button2]);
io.AddMouseWheelEvent(mState.ScrollDelta.X, mState.ScrollDelta.Y);
- foreach (Keys key in Enum.GetValues(typeof(Keys)))
+ foreach (Keys key in Enum.GetValues())
{
if (key == Keys.Unknown) continue;
io.AddKeyEvent(TranslateKey(key), kState.IsKeyDown(key));
@@ -294,7 +295,7 @@ outputColor = color * texture(in_fontTexture, texCoord);
io.KeySuper = kState.IsKeyDown(Keys.LeftSuper) || kState.IsKeyDown(Keys.RightSuper);
}
- public void PressChar(char keyChar)
+ internal void PressChar(char keyChar)
{
PressedChars.Add(keyChar);
}
@@ -340,7 +341,7 @@ outputColor = color * texture(in_fontTexture, texCoord);
{
ImDrawListPtr cmd_list = draw_data.CmdLists[i];
- int vertexSize = cmd_list.VtxBuffer.Size * Unsafe.SizeOf();
+ int vertexSize = cmd_list.VtxBuffer.Size * Marshal.SizeOf();
if (vertexSize > _vertexBufferSize)
{
int newSize = (int)Math.Max(_vertexBufferSize * 1.5f, vertexSize);
@@ -390,7 +391,7 @@ outputColor = color * texture(in_fontTexture, texCoord);
{
ImDrawListPtr cmd_list = draw_data.CmdLists[n];
- GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Unsafe.SizeOf(), cmd_list.VtxBuffer.Data);
+ GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Marshal.SizeOf(), cmd_list.VtxBuffer.Data);
CheckGLError($"Data Vert {n}");
GL.BufferSubData(BufferTarget.ElementArrayBuffer, IntPtr.Zero, cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data);
@@ -544,16 +545,16 @@ outputColor = color * texture(in_fontTexture, texCoord);
public static ImGuiKey TranslateKey(Keys key)
{
- if (key is >= Keys.D0 and <= Keys.D9)
+ if (key >= Keys.D0 && key <= Keys.D9)
return key - Keys.D0 + ImGuiKey._0;
- if (key is >= Keys.A and <= Keys.Z)
+ if (key >= Keys.A && key <= Keys.Z)
return key - Keys.A + ImGuiKey.A;
- if (key is >= Keys.KeyPad0 and <= Keys.KeyPad9)
+ if (key >= Keys.KeyPad0 && key <= Keys.KeyPad9)
return key - Keys.KeyPad0 + ImGuiKey.Keypad0;
- if (key is >= Keys.F1 and <= Keys.F24)
+ if (key >= Keys.F1 && key <= Keys.F24)
return key - Keys.F1 + ImGuiKey.F24;
return key switch
@@ -596,7 +597,7 @@ outputColor = color * texture(in_fontTexture, texCoord);
Keys.KeyPadAdd => ImGuiKey.KeypadAdd,
Keys.KeyPadEnter => ImGuiKey.KeypadEnter,
Keys.KeyPadEqual => ImGuiKey.KeypadEqual,
- Keys.LeftShift => ImGuiKey.LeftShift,
+ Keys.LeftShift => ImGuiKey.ModShift,
Keys.LeftControl => ImGuiKey.LeftCtrl,
Keys.LeftAlt => ImGuiKey.LeftAlt,
Keys.LeftSuper => ImGuiKey.LeftSuper,
diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs
index 2ae406d7..be379030 100644
--- a/FModel/ViewModels/CUE4ParseViewModel.cs
+++ b/FModel/ViewModels/CUE4ParseViewModel.cs
@@ -390,6 +390,12 @@ public class CUE4ParseViewModel : ViewModel
FLogger.Text("Additive animations have their reference pose stripped, which will lead to inaccurate preview and export", Constants.WHITE, true));
}
+ if (Provider.Versions.Game is EGame.GAME_UE4_LATEST or EGame.GAME_UE5_LATEST && !Provider.ProjectName.Equals("FortniteGame", StringComparison.OrdinalIgnoreCase)) // ignore fortnite globally
+ {
+ FLogger.Append(ELog.Warning, () =>
+ FLogger.Text($"Experimental UE version selected, likely unsuitable for '{Provider.GameDisplayName ?? Provider.ProjectName}'", Constants.WHITE, true));
+ }
+
return Task.CompletedTask;
}
@@ -578,7 +584,7 @@ public class CUE4ParseViewModel : ViewModel
case "manifest":
case "uplugin":
case "archive":
- case "vmodule":
+ case "vmodule":
case "uparam": // Steel Hunters
case "verse":
case "html":
diff --git a/FModel/Views/Snooper/Models/SkeletalModel.cs b/FModel/Views/Snooper/Models/SkeletalModel.cs
index 8804bb93..fcc25ac8 100644
--- a/FModel/Views/Snooper/Models/SkeletalModel.cs
+++ b/FModel/Views/Snooper/Models/SkeletalModel.cs
@@ -174,6 +174,7 @@ public class SkeletalModel : UModel
public void Render(Shader shader)
{
shader.SetUniform("uMorphTime", MorphTime);
+ shader.SetUniform("uIsSpline", false);
Skeleton.Render(shader);
}
diff --git a/FModel/Views/Snooper/Models/UModel.cs b/FModel/Views/Snooper/Models/UModel.cs
index 603a2189..a600d796 100644
--- a/FModel/Views/Snooper/Models/UModel.cs
+++ b/FModel/Views/Snooper/Models/UModel.cs
@@ -373,6 +373,7 @@ public abstract class UModel : IRenderableModel
MatrixVbo = new BufferObject(TransformsCount, BufferTarget.ArrayBuffer);
for (int instance = 0; instance < TransformsCount; instance++)
{
+ Transforms[instance].Save();
MatrixVbo.Update(instance, Transforms[instance].Matrix);
}
Vao.BindInstancing(); // VertexAttributePointer
diff --git a/FModel/Views/Snooper/Shading/Material.cs b/FModel/Views/Snooper/Shading/Material.cs
index a3e58d49..729aa766 100644
--- a/FModel/Views/Snooper/Shading/Material.cs
+++ b/FModel/Views/Snooper/Shading/Material.cs
@@ -343,7 +343,7 @@ public class Material : IDisposable
var texture = GetSelectedTexture() ?? icons["noimage"];
ImGui.Image(texture.GetPointer(),
new Vector2(ImGui.GetContentRegionAvail().X - ImGui.GetScrollX()),
- Vector2.Zero, Vector2.One, Vector4.One, new Vector4(1.0f, 1.0f, 1.0f, 0.25f));
+ Vector2.Zero, Vector2.One);
return ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(ImGuiMouseButton.Left);
}
diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs
index e01ef3d7..191f95b6 100644
--- a/FModel/Views/Snooper/SnimGui.cs
+++ b/FModel/Views/Snooper/SnimGui.cs
@@ -11,6 +11,7 @@ using FModel.Settings;
using FModel.Views.Snooper.Animations;
using FModel.Views.Snooper.Models;
using FModel.Views.Snooper.Shading;
+using ImGuizmoNET;
using OpenTK.Graphics.OpenGL4;
namespace FModel.Views.Snooper;
@@ -67,7 +68,9 @@ public class SnimGui
private Vector2 _outlinerSize;
private bool _tiOpen;
+ private bool _transformOpen;
private bool _viewportFocus;
+ private OPERATION _guizmoOperation;
private readonly Vector4 _accentColor = new (0.125f, 0.42f, 0.831f, 1.0f);
private readonly Vector4 _alertColor = new (0.831f, 0.573f, 0.125f, 1.0f);
@@ -82,14 +85,14 @@ public class SnimGui
_renderer = GL.GetString(StringName.Renderer);
_version = "OpenGL " + GL.GetString(StringName.Version);
_tableWidth = 17 * Controller.DpiScale;
+ _guizmoOperation = OPERATION.TRANSLATE;
Theme();
}
public void Render(Snooper s)
{
- Controller.SemiBold();
- DrawDockSpace(s.ClientSize);
+ ImGui.DockSpaceOverViewport(_dockspaceId, ImGui.GetMainViewport(), ImGuiDockNodeFlags.PassthruCentralNode);
SectionWindow("Material Inspector", s.Renderer, DrawMaterialInspector, false);
AnimationWindow("Timeline", s.Renderer, (icons, tracker, animations) =>
@@ -249,22 +252,6 @@ public class SnimGui
}
}
- private void DrawDockSpace(OpenTK.Mathematics.Vector2i size)
- {
- const ImGuiWindowFlags flags =
- ImGuiWindowFlags.MenuBar | ImGuiWindowFlags.NoDocking |
- ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoResize |
- ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoMove |
- ImGuiWindowFlags.NoBringToFrontOnFocus | ImGuiWindowFlags.NoNavFocus;
-
- ImGui.SetNextWindowPos(new Vector2(0, 0));
- ImGui.SetNextWindowSize(new Vector2(size.X, size.Y));
- ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
- ImGui.Begin("Oui oui", flags);
- ImGui.PopStyleVar();
- ImGui.DockSpace(_dockspaceId);
- }
-
private void DrawNavbar()
{
if (!ImGui.BeginMainMenuBar()) return;
@@ -604,14 +591,43 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
ImGui.EndTabItem();
}
- if (ImGui.BeginTabItem("Transform"))
+ _transformOpen = ImGui.BeginTabItem("Transform");
+ if (_transformOpen)
{
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);
ImGui.EndDisabled(); ImGui.PopID();
- model.Transforms[model.SelectedInstance].ImGuiTransform(s.Renderer.CameraOp.Speed / 100f);
+ if (ImGui.BeginTable("guizmo_controls", 2, ImGuiTableFlags.SizingStretchProp))
+ {
+ var t = model.Transforms[model.SelectedInstance];
+ var c = _guizmoOperation switch
+ {
+ OPERATION.TRANSLATE => 0,
+ OPERATION.ROTATE => 1,
+ OPERATION.SCALE => 2,
+ _ => 3
+ };
+
+ Layout("Operation ");
+ ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X * 0.6f);
+ ImGui.PushID(1);ImGui.Combo("", ref c, "Translate\0Rotate\0Scale\0");
+ ImGui.PopID();ImGui.SameLine();if (ImGui.Button("Reset All")) t.Reset();
+ Layout("Position");ImGui.Text(t.Position.ToString());
+ Layout("Rotation");ImGui.Text(t.Rotation.ToString());
+ Layout("Scale");ImGui.Text(t.Scale.ToString());
+
+ _guizmoOperation = c switch
+ {
+ 0 => OPERATION.TRANSLATE,
+ 1 => OPERATION.ROTATE,
+ 2 => OPERATION.SCALE,
+ _ => OPERATION.UNIVERSAL
+ };
+
+ ImGui.EndTable();
+ }
ImGui.EndTabItem();
}
@@ -719,8 +735,8 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
{
(model.Materials[section.MaterialIndex].GetSelectedTexture() ?? s.Renderer.Options.Icons["noimage"]).ImGuiTextureInspector();
}
- ImGui.End(); // if window is collapsed
}
+ ImGui.End();
}
private void DrawSkeletonTree(Snooper s)
@@ -741,8 +757,8 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
ImGui.EndTable();
}
}
- ImGui.End(); // if window is collapsed
}
+ ImGui.End();
ImGui.PopStyleVar();
}
@@ -756,41 +772,54 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
largest.Y -= ImGui.GetScrollY();
var size = new Vector2(largest.X, largest.Y);
+ var pos = ImGui.GetWindowPos();
+ var fHeight = ImGui.GetFrameHeight();
+
s.Renderer.CameraOp.AspectRatio = size.X / size.Y;
- ImGui.Image(s.Framebuffer.GetPointer(), size, new Vector2(0, 1), new Vector2(1, 0), Vector4.One);
+ ImGui.Image(s.Framebuffer.GetPointer(), size, new Vector2(0, 1), new Vector2(1, 0));
- if (ImGui.IsItemHovered())
+ if (_transformOpen)
{
- // if left button down while mouse is hover viewport
- if (ImGui.IsMouseDown(ImGuiMouseButton.Left) && !_viewportFocus)
- {
- _viewportFocus = true;
- s.CursorState = CursorState.Grabbed;
- }
- if (ImGui.IsMouseClicked(ImGuiMouseButton.Right))
- {
- var guid = s.Renderer.Picking.ReadPixel(ImGui.GetMousePos(), ImGui.GetCursorScreenPos(), size);
- s.Renderer.Options.SelectModel(guid);
- ImGui.SetWindowFocus("Outliner");
- ImGui.SetWindowFocus("Details");
- }
+ ImGuizmo.SetDrawlist(ImGui.GetWindowDrawList());
+ ImGuizmo.SetRect(pos.X, pos.Y + fHeight, size.X, size.Y);
+ DrawGuizmo(s);
}
- if (ImGui.IsMouseDragging(ImGuiMouseButton.Left) && _viewportFocus)
+ if (!ImGuizmo.IsUsing())
{
- s.Renderer.CameraOp.Modify(ImGui.GetIO().MouseDelta);
- }
+ if (ImGui.IsItemHovered())
+ {
+ // if left button down while mouse is hover viewport
+ if (ImGui.IsMouseDown(ImGuiMouseButton.Left) && !_viewportFocus)
+ {
+ _viewportFocus = true;
+ s.CursorState = CursorState.Grabbed;
+ }
+ if (ImGui.IsMouseClicked(ImGuiMouseButton.Right))
+ {
+ var guid = s.Renderer.Picking.ReadPixel(ImGui.GetMousePos(), ImGui.GetCursorScreenPos(), size);
+ s.Renderer.Options.SelectModel(guid);
+ ImGui.SetWindowFocus("Outliner");
+ ImGui.SetWindowFocus("Details");
+ }
+ }
- // if left button up and mouse was in viewport
- if (ImGui.IsMouseReleased(ImGuiMouseButton.Left) && _viewportFocus)
- {
- _viewportFocus = false;
- s.CursorState = CursorState.Normal;
+ if (_viewportFocus && ImGui.IsMouseDragging(ImGuiMouseButton.Left))
+ {
+ s.Renderer.CameraOp.Modify(ImGui.GetIO().MouseDelta);
+ }
+
+ // if left button up and mouse was in viewport
+ if (_viewportFocus && ImGui.IsMouseReleased(ImGuiMouseButton.Left))
+ {
+ _viewportFocus = false;
+ s.CursorState = CursorState.Normal;
+ }
}
const float margin = 7.5f;
var buttonWidth = 14.0f * ImGui.GetWindowDpiScale();
- var basePos = new Vector2( size.X - buttonWidth - margin * 2, ImGui.GetFrameHeight() + margin);
+ var basePos = new Vector2( size.X - buttonWidth - margin * 2, fHeight + margin);
ImGui.SetCursorPos(basePos);
ImGui.PushStyleColor(ImGuiCol.Button, Vector4.Zero);
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0.2f));
@@ -821,6 +850,26 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
ImGui.PopStyleVar();
}
+ private void DrawGuizmo(Snooper s)
+ {
+ var enableGuizmo = s.Renderer.Options.TryGetModel(out var selected) && selected.IsVisible;
+ if (enableGuizmo)
+ {
+ var view = s.Renderer.CameraOp.GetViewMatrix();
+ var proj = s.Renderer.CameraOp.GetProjectionMatrix();
+ var transform = selected.Transforms[selected.SelectedInstance];
+ var matrix = transform.Matrix;
+
+ if (ImGuizmo.Manipulate(ref view.M11, ref proj.M11, _guizmoOperation, MODE.LOCAL, ref matrix.M11) &&
+ Matrix4x4.Invert(transform.Relation, out var invRelation)) // matrix * invRelation = local matrix
+ {
+ // ^ long story short: there was issues with other transformation methods
+ // that's one way of modifying root elements without breaking the world matrix
+ transform.ModifyLocal(matrix * invRelation);
+ }
+ }
+ }
+
public static void Popup(Action content)
{
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, new Vector2(4f));
@@ -850,12 +899,13 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
{
if (ImGui.Begin(name, ImGuiWindowFlags.NoScrollbar))
{
- Controller.PopFont();
+ Controller.Normal();
if (styled) PushStyleCompact();
content();
if (styled) PopStyleCompact();
- ImGui.End();
+ ImGui.PopFont();
}
+ ImGui.End();
}
private void MeshWindow(string name, Renderer renderer, Action, UModel> content, bool styled = true)
@@ -908,7 +958,7 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
ImGui.GetCursorPosY() + (region.Y - size.Y) / 2));
Controller.Bold();
ImGui.TextColored(color, text);
- Controller.PopFont();
+ ImGui.PopFont();
}
public static void Layout(string name, bool tooltip = false)
@@ -1027,7 +1077,7 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
style.Colors[(int) ImGuiCol.TableRowBgAlt] = new Vector4(1.00f, 1.00f, 1.00f, 0.06f);
style.Colors[(int) ImGuiCol.TextSelectedBg] = new Vector4(0.26f, 0.59f, 0.98f, 0.35f);
style.Colors[(int) ImGuiCol.DragDropTarget] = new Vector4(1.00f, 1.00f, 0.00f, 0.90f);
- style.Colors[(int) ImGuiCol.NavHighlight] = new Vector4(0.26f, 0.59f, 0.98f, 1.00f);
+ style.Colors[(int) ImGuiCol.NavCursor] = new Vector4(0.26f, 0.59f, 0.98f, 1.00f);
style.Colors[(int) ImGuiCol.NavWindowingHighlight] = new Vector4(1.00f, 1.00f, 1.00f, 0.70f);
style.Colors[(int) ImGuiCol.NavWindowingDimBg] = new Vector4(0.80f, 0.80f, 0.80f, 0.20f);
style.Colors[(int) ImGuiCol.ModalWindowDimBg] = new Vector4(0.80f, 0.80f, 0.80f, 0.35f);
diff --git a/FModel/Views/Snooper/Transform.cs b/FModel/Views/Snooper/Transform.cs
index a36ba7a1..ec9d270a 100644
--- a/FModel/Views/Snooper/Transform.cs
+++ b/FModel/Views/Snooper/Transform.cs
@@ -1,6 +1,5 @@
using System.Numerics;
using CUE4Parse.UE4.Objects.Core.Math;
-using ImGuiNET;
namespace FModel.Views.Snooper;
@@ -16,63 +15,37 @@ public class Transform
public FQuat Rotation = FQuat.Identity;
public FVector Scale = FVector.OneVector;
- public Matrix4x4 LocalMatrix =>
- Matrix4x4.CreateScale(Scale.X, Scale.Z, Scale.Y) *
- Matrix4x4.CreateFromQuaternion(Quaternion.Normalize(new Quaternion(Rotation.X, Rotation.Z, Rotation.Y, -Rotation.W))) *
- Matrix4x4.CreateTranslation(Position.X, Position.Z, Position.Y);
+ private Matrix4x4? _saved;
+ public Matrix4x4 LocalMatrix => Matrix4x4.CreateScale(Scale.X, Scale.Z, Scale.Y) *
+ Matrix4x4.CreateFromQuaternion(Quaternion.Normalize(new Quaternion(Rotation.X, Rotation.Z, Rotation.Y, -Rotation.W))) *
+ Matrix4x4.CreateTranslation(Position.X, Position.Z, Position.Y);
public Matrix4x4 Matrix => LocalMatrix * Relation;
- public void ImGuiTransform(float speed)
+ public void Save()
{
- const float width = 100f;
+ _saved = LocalMatrix;
+ }
- ImGui.SetNextItemOpen(true, ImGuiCond.Appearing);
- if (ImGui.TreeNode("Location"))
- {
- ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("X", ref Position.X, speed, 0f, 0f, "%.2f m");
+ public void ModifyLocal(Matrix4x4 matrix)
+ {
+ Matrix4x4.Decompose(matrix, out var scale, out var rotation, out var position);
- ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Y", ref Position.Z, speed, 0f, 0f, "%.2f m");
+ Scale.X = scale.X;
+ Scale.Y = scale.Z;
+ Scale.Z = scale.Y;
+ Rotation.X = rotation.X;
+ Rotation.Y = rotation.Z;
+ Rotation.Z = rotation.Y;
+ Rotation.W = -rotation.W;
+ Position.X = position.X;
+ Position.Z = position.Y;
+ Position.Y = position.Z;
+ }
- ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Z", ref Position.Y, speed, 0f, 0f, "%.2f m");
-
- ImGui.TreePop();
- }
-
- ImGui.SetNextItemOpen(true, ImGuiCond.Appearing);
- if (ImGui.TreeNode("Rotation"))
- {
- ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("W", ref Rotation.W, .005f, 0f, 0f, "%.3f rad");
-
- ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("X", ref Rotation.X, .005f, 0f, 0f, "%.3f rad");
-
- ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Y", ref Rotation.Z, .005f, 0f, 0f, "%.3f rad");
-
- ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Z", ref Rotation.Y, .005f, 0f, 0f, "%.3f rad");
-
- ImGui.TreePop();
- }
-
- ImGui.SetNextItemOpen(true, ImGuiCond.Appearing);
- if (ImGui.TreeNode("Scale"))
- {
- ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("X", ref Scale.X, speed, 0f, 0f, "%.3f");
-
- ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Y", ref Scale.Z, speed, 0f, 0f, "%.3f");
-
- ImGui.SetNextItemWidth(width);
- ImGui.DragFloat("Z", ref Scale.Y, speed, 0f, 0f, "%.3f");
-
- ImGui.TreePop();
- }
+ public void Reset()
+ {
+ if (!_saved.HasValue) return;
+ ModifyLocal(_saved.Value);
}
public override string ToString() => Matrix.Translation.ToString();