From 8f9a6927fd87f956faa4b0c7265ffab8c53a8786 Mon Sep 17 00:00:00 2001 From: 4sval Date: Sun, 8 Jan 2023 03:03:26 +0100 Subject: [PATCH] normalize quaternions --- .../Views/Snooper/Buffers/PickingTexture.cs | 2 +- .../Snooper/Models/Animations/Skeleton.cs | 24 ++++++++++++++++++- FModel/Views/Snooper/Models/Model.cs | 14 ++++++++--- FModel/Views/Snooper/Models/Socket.cs | 3 +++ FModel/Views/Snooper/SnimGui.cs | 20 ++++++++++------ FModel/Views/Snooper/Transform.cs | 18 +++++--------- 6 files changed, 57 insertions(+), 24 deletions(-) diff --git a/FModel/Views/Snooper/Buffers/PickingTexture.cs b/FModel/Views/Snooper/Buffers/PickingTexture.cs index 49d867ab..cb56c5a8 100644 --- a/FModel/Views/Snooper/Buffers/PickingTexture.cs +++ b/FModel/Views/Snooper/Buffers/PickingTexture.cs @@ -68,7 +68,7 @@ public void Render(Matrix4x4 viewMatrix, Matrix4x4 projMatrix, IDictionary(); if (UnrealSkeleton == null) return; @@ -38,6 +43,7 @@ public Skeleton(FPackageIndex package) var bone = UnrealSkeleton.ReferenceSkeleton.FinalRefBonePose[parentBoneIndex]; boneTransform = new Transform { + Relation = transform.Matrix, Rotation = bone.Rotation, Position = bone.Translation * Constants.SCALE_DOWN_RATIO, Scale = bone.Scale3D @@ -81,6 +87,22 @@ public void SetAnimation(CAnimSet anim) Anim = new Animation(anim, BonesIndexByName, BonesTransformByIndex); } + public void UpdateSocketsMatrix(Transform t) + { + var m = t.Position; + if (m == _previousMatrix) return; + + var delta = _previousMatrix - m; + Log.Logger.Information("Update {0}", delta); + + // BonesTransformByIndex[0].Relation.Translation += delta; + foreach (var socket in Sockets) + { + socket.Transform.Relation.Translation += delta; + } + _previousMatrix = m; + } + public void SetUniform(Shader shader) { if (!IsLoaded) return; diff --git a/FModel/Views/Snooper/Models/Model.cs b/FModel/Views/Snooper/Models/Model.cs index 6d725cf2..39c2695f 100644 --- a/FModel/Views/Snooper/Models/Model.cs +++ b/FModel/Views/Snooper/Models/Model.cs @@ -105,6 +105,7 @@ public Model(USkeletalMesh export, CSkeletalMesh skeletalMesh) : this(export, sk private Model(UObject export, ResolvedObject[] materials, FPackageIndex skeleton, int numLods, CBaseMeshLod lod, CMeshVertex[] vertices, Transform transform = null) : this(export) { + var t = transform ?? Transform.Identity; var hasCustomUvs = lod.ExtraUV.IsValueCreated; UvCount = hasCustomUvs ? Math.Max(lod.NumTexCoords, numLods) : lod.NumTexCoords; TwoSided = lod.IsTwoSided; @@ -124,7 +125,7 @@ private Model(UObject export, ResolvedObject[] materials, FPackageIndex skeleton if (skeleton != null) { - Skeleton = new Skeleton(skeleton); + Skeleton = new Skeleton(skeleton, t); VertexSize += 8; // + BoneIds + BoneWeights } @@ -186,7 +187,7 @@ private Model(UObject export, ResolvedObject[] materials, FPackageIndex skeleton if (section.IsValid) Sections[s].SetupMaterial(Materials[section.MaterialIndex]); } - AddInstance(transform ?? Transform.Identity); + AddInstance(t); } public void AddInstance(Transform transform) @@ -195,6 +196,13 @@ public void AddInstance(Transform transform) Transforms.Add(transform); } + public void UpdateMatrix() => UpdateMatrix(SelectedInstance); + public void UpdateMatrix(Transform transform) => UpdateMatrix(SelectedInstance, transform); + public void UpdateMatrix(int instance, Transform transform) + { + Transforms[instance] = transform; + UpdateMatrix(instance); + } public void UpdateMatrix(int instance) { _matrixVbo.Bind(); @@ -304,7 +312,7 @@ public void Render(Shader shader, bool outline = false) if (outline) GL.Enable(EnableCap.DepthTest); } - public void SimpleRender(Shader shader) + public void PickingRender(Shader shader) { if (TwoSided) GL.Disable(EnableCap.CullFace); diff --git a/FModel/Views/Snooper/Models/Socket.cs b/FModel/Views/Snooper/Models/Socket.cs index 9b6b3022..a61e453b 100644 --- a/FModel/Views/Snooper/Models/Socket.cs +++ b/FModel/Views/Snooper/Models/Socket.cs @@ -1,5 +1,6 @@ using System; using CUE4Parse.UE4.Assets.Exports.SkeletalMesh; +using CUE4Parse.UE4.Objects.Core.Misc; namespace FModel.Views.Snooper.Models; @@ -9,6 +10,8 @@ public class Socket : IDisposable public readonly string Bone; public readonly Transform Transform; + public FGuid AttachedModel; + public Socket(USkeletalMeshSocket socket) { Name = socket.SocketName.Text; diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs index 4193ee76..f52caca3 100644 --- a/FModel/Views/Snooper/SnimGui.cs +++ b/FModel/Views/Snooper/SnimGui.cs @@ -7,6 +7,7 @@ using OpenTK.Windowing.Common; using System.Numerics; using System.Text; +using CUE4Parse.UE4.Objects.Core.Math; using FModel.Settings; using FModel.Views.Snooper.Models; using FModel.Views.Snooper.Shading; @@ -402,14 +403,18 @@ private void DrawSockets(Snooper s) foreach (var socket in model.Skeleton.Sockets) { ImGui.PushID(i); - ImGui.Text($"{socket.Name} attached to {socket.Bone}"); - ImGui.Text($"P: {socket.Transform.Matrix.M41} | {socket.Transform.Matrix.M42} | {socket.Transform.Matrix.M43}"); - // ImGui.Text($"R: {socket.Transform.Rotation}"); - // ImGui.Text($"S: {socket.Transform.Scale}"); + ImGui.Text($"'{socket.Name}' attached to '{socket.Bone}'"); + ImGui.Text($"P: {socket.Transform.Matrix.Translation.X} | {socket.Transform.Matrix.Translation.Y} | {socket.Transform.Matrix.Translation.Z}"); if (ImGui.Button("Attach") && s.Renderer.Options.TryGetModel(out var selected)) { - selected.Transforms[selected.SelectedInstance] = socket.Transform; - selected.UpdateMatrix(selected.SelectedInstance); + socket.AttachedModel = s.Renderer.Options.SelectedModel; + selected.UpdateMatrix(new Transform + { + Relation = socket.Transform.Matrix, + Position = FVector.ZeroVector, + Rotation = new FQuat(0), + Scale = FVector.OneVector + }); } ImGui.PopID(); i++; @@ -527,7 +532,8 @@ private void DrawDetails(Snooper s) ImGui.EndDisabled(); ImGui.PopID(); model.Transforms[model.SelectedInstance].ImGuiTransform(s.Renderer.CameraOp.Speed / 100f); - model.UpdateMatrix(model.SelectedInstance); + model.UpdateMatrix(); + ImGui.EndTabItem(); } diff --git a/FModel/Views/Snooper/Transform.cs b/FModel/Views/Snooper/Transform.cs index 0d570e3b..cfcc6eb5 100644 --- a/FModel/Views/Snooper/Transform.cs +++ b/FModel/Views/Snooper/Transform.cs @@ -18,18 +18,17 @@ public static Transform Identity public Matrix4x4 Matrix => Matrix4x4.CreateScale(Scale.X, Scale.Z, Scale.Y) * - Matrix4x4.CreateFromQuaternion(new Quaternion(Rotation.X, Rotation.Z, Rotation.Y, -Rotation.W)) * + Matrix4x4.CreateFromQuaternion(Quaternion.Normalize(new Quaternion(Rotation.X, Rotation.Z, Rotation.Y, -Rotation.W))) * Matrix4x4.CreateTranslation(Position.X, Position.Z, Position.Y) * Relation; public void ImGuiTransform(float speed) { - const int width = 100; + const float width = 100f; ImGui.SetNextItemOpen(true, ImGuiCond.Appearing); if (ImGui.TreeNode("Location")) { - ImGui.PushID(1); ImGui.SetNextItemWidth(width); ImGui.DragFloat("X", ref Position.X, speed, 0f, 0f, "%.2f m"); @@ -39,33 +38,29 @@ public void ImGuiTransform(float speed) ImGui.SetNextItemWidth(width); ImGui.DragFloat("Z", ref Position.Y, speed, 0f, 0f, "%.2f m"); - ImGui.PopID(); ImGui.TreePop(); } ImGui.SetNextItemOpen(true, ImGuiCond.Appearing); if (ImGui.TreeNode("Rotation")) { - ImGui.PushID(2); ImGui.SetNextItemWidth(width); - ImGui.DragFloat("X", ref Rotation.X, .5f, 0f, 0f, "%.1f°"); + ImGui.DragFloat("W", ref Rotation.W, .005f, 0f, 0f, "%.3f rad"); ImGui.SetNextItemWidth(width); - ImGui.DragFloat("Y", ref Rotation.Z, .5f, 0f, 0f, "%.1f°"); + ImGui.DragFloat("X", ref Rotation.X, .005f, 0f, 0f, "%.3f rad"); ImGui.SetNextItemWidth(width); - ImGui.DragFloat("Z", ref Rotation.Y, .5f, 0f, 0f, "%.1f°"); + ImGui.DragFloat("Y", ref Rotation.Z, .005f, 0f, 0f, "%.3f rad"); ImGui.SetNextItemWidth(width); - ImGui.DragFloat("W", ref Rotation.W, .5f, 0f, 0f, "%.1f°"); + ImGui.DragFloat("Z", ref Rotation.Y, .005f, 0f, 0f, "%.3f rad"); - ImGui.PopID(); ImGui.TreePop(); } if (ImGui.TreeNode("Scale")) { - ImGui.PushID(3); ImGui.SetNextItemWidth(width); ImGui.DragFloat("X", ref Scale.X, speed, 0f, 0f, "%.3f"); @@ -75,7 +70,6 @@ public void ImGuiTransform(float speed) ImGui.SetNextItemWidth(width); ImGui.DragFloat("Z", ref Scale.Y, speed, 0f, 0f, "%.3f"); - ImGui.PopID(); ImGui.TreePop(); } }