From 0221405758a2a697e686192040743323394cd689 Mon Sep 17 00:00:00 2001 From: 4sval Date: Fri, 6 Jan 2023 15:14:58 +0100 Subject: [PATCH] I should have persevered with quaternions --- CUE4Parse | 2 +- FModel/Resources/light.vert | 11 +++- FModel/Views/Snooper/Camera.cs | 5 +- FModel/Views/Snooper/Lights/Light.cs | 17 ++--- FModel/Views/Snooper/Lights/PointLight.cs | 2 +- FModel/Views/Snooper/Lights/SpotLight.cs | 2 +- .../Snooper/Models/Animations/Animation.cs | 2 +- .../Snooper/Models/Animations/Skeleton.cs | 65 +++++++------------ FModel/Views/Snooper/Models/Model.cs | 4 +- FModel/Views/Snooper/Models/Socket.cs | 28 ++++---- FModel/Views/Snooper/Renderer.cs | 25 ++++--- FModel/Views/Snooper/Transform.cs | 25 +++---- 12 files changed, 89 insertions(+), 99 deletions(-) diff --git a/CUE4Parse b/CUE4Parse index bfb2b3ce..9579eabc 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit bfb2b3ce34ceee5c9785d845a5da2b594f534493 +Subproject commit 9579eabcde51e8622c79845c26f7f04e29b604e8 diff --git a/FModel/Resources/light.vert b/FModel/Resources/light.vert index 906f947a..06802a1d 100644 --- a/FModel/Resources/light.vert +++ b/FModel/Resources/light.vert @@ -10,6 +10,13 @@ out vec2 fTexCoords; void main() { - gl_Position = uProjection * uView * vInstanceMatrix * vec4(inverse(mat3(uView)) * vPos, 1.0); - fTexCoords = -vPos.xy; + float scale = 0.075; + mat4 result; + result[0] = vec4(scale, 0.0, 0.0, 0.0); + result[1] = vec4(0.0, scale, 0.0, 0.0); + result[2] = vec4(0.0, 0.0, scale, 0.0); + result[3] = vInstanceMatrix[3]; + + gl_Position = uProjection * uView * result * vec4(inverse(mat3(uView)) * vPos, 1.0); + fTexCoords = -vPos.xy * 0.5 + 0.5; // fits the whole rectangle } diff --git a/FModel/Views/Snooper/Camera.cs b/FModel/Views/Snooper/Camera.cs index a0af4c15..e320314f 100644 --- a/FModel/Views/Snooper/Camera.cs +++ b/FModel/Views/Snooper/Camera.cs @@ -39,12 +39,11 @@ public class Camera public void Teleport(FVector instancePos, FBox box, bool updateAll = false) { box.GetCenterAndExtents(out var center, out var extents); - center = center.ToMapVector(); center += instancePos; var distance = extents.AbsMax(); - Position = new Vector3(instancePos.X, center.Y, instancePos.Z + distance * 2); - Direction = new Vector3(center.X, center.Y, center.Z); + Position = new Vector3(instancePos.X, center.Z, instancePos.Y + distance * 2); + Direction = new Vector3(center.X, center.Z, center.Y); if (updateAll) { Far = Math.Max(Far, box.Max.AbsMax() * 50f); diff --git a/FModel/Views/Snooper/Lights/Light.cs b/FModel/Views/Snooper/Lights/Light.cs index f64e0cf6..b87f59ea 100644 --- a/FModel/Views/Snooper/Lights/Light.cs +++ b/FModel/Views/Snooper/Lights/Light.cs @@ -36,14 +36,15 @@ public abstract class Light : IDisposable public float Intensity; public bool IsSetup; - public Light(FGuid model, Texture icon, UObject parent, UObject light, FVector position) + public Light(FGuid model, Texture icon, UObject parent, UObject light, Transform transform) { - var p = light.GetOrDefault("RelativeLocation", parent.GetOrDefault("RelativeLocation", FVector.ZeroVector)); - var r = light.GetOrDefault("RelativeRotation", parent.GetOrDefault("RelativeRotation", FRotator.ZeroRotator)); - - Transform = Transform.Identity; - Transform.Scale = new FVector(0.2f); - Transform.Position = position + r.RotateVector(p.ToMapVector()) * Constants.SCALE_DOWN_RATIO; + Transform = new Transform + { + Relation = transform.Matrix, + Position = light.GetOrDefault("RelativeLocation", parent.GetOrDefault("RelativeLocation", FVector.ZeroVector)) * Constants.SCALE_DOWN_RATIO, + Rotation = light.GetOrDefault("RelativeRotation", parent.GetOrDefault("RelativeRotation", FRotator.ZeroRotator)).Quaternion(), + Scale = light.GetOrDefault("RelativeScale3D", parent.GetOrDefault("RelativeScale3D", FVector.OneVector)) + }; Model = model; Icon = icon; @@ -91,7 +92,7 @@ public abstract class Light : IDisposable public virtual void Render(int i, Shader shader) { shader.SetUniform($"uLights[{i}].Base.Color", Color); - shader.SetUniform($"uLights[{i}].Base.Position", Transform.Position); + shader.SetUniform($"uLights[{i}].Base.Position", Transform.Matrix.Translation); shader.SetUniform($"uLights[{i}].Base.Intensity", Intensity); } diff --git a/FModel/Views/Snooper/Lights/PointLight.cs b/FModel/Views/Snooper/Lights/PointLight.cs index 49787347..14019b24 100644 --- a/FModel/Views/Snooper/Lights/PointLight.cs +++ b/FModel/Views/Snooper/Lights/PointLight.cs @@ -12,7 +12,7 @@ public class PointLight : Light public float Linear; public float Quadratic; - public PointLight(FGuid model, Texture icon, UObject parent, UObject point, FVector position) : base(model, icon, parent, point, position) + public PointLight(FGuid model, Texture icon, UObject parent, UObject point, Transform transform) : base(model, icon, parent, point, transform) { if (!point.TryGetValue(out float radius, "AttenuationRadius", "SourceRadius")) radius = 1.0f; diff --git a/FModel/Views/Snooper/Lights/SpotLight.cs b/FModel/Views/Snooper/Lights/SpotLight.cs index dbba81e1..6c867922 100644 --- a/FModel/Views/Snooper/Lights/SpotLight.cs +++ b/FModel/Views/Snooper/Lights/SpotLight.cs @@ -12,7 +12,7 @@ public class SpotLight : Light public float InnerConeAngle; public float OuterConeAngle; - public SpotLight(FGuid model, Texture icon, UObject parent, UObject spot, FVector position) : base(model, icon, parent, spot, position) + public SpotLight(FGuid model, Texture icon, UObject parent, UObject spot, Transform transform) : base(model, icon, parent, spot, transform) { if (!spot.TryGetValue(out Attenuation, "AttenuationRadius", "SourceRadius")) Attenuation = 1.0f; diff --git a/FModel/Views/Snooper/Models/Animations/Animation.cs b/FModel/Views/Snooper/Models/Animations/Animation.cs index b75f67f7..fc540fc1 100644 --- a/FModel/Views/Snooper/Models/Animations/Animation.cs +++ b/FModel/Views/Snooper/Models/Animations/Animation.cs @@ -53,7 +53,7 @@ public class Animation : IDisposable FinalBonesMatrix[boneIndex] = Matrix4x4.CreateFromQuaternion(boneOrientation) * - Matrix4x4.CreateTranslation(bonePosition.ToMapVector()); + Matrix4x4.CreateTranslation(bonePosition); } } diff --git a/FModel/Views/Snooper/Models/Animations/Skeleton.cs b/FModel/Views/Snooper/Models/Animations/Skeleton.cs index c8ab2601..2737c7e2 100644 --- a/FModel/Views/Snooper/Models/Animations/Skeleton.cs +++ b/FModel/Views/Snooper/Models/Animations/Skeleton.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; -using System.Numerics; using CUE4Parse.UE4.Assets.Exports.Animation; using CUE4Parse.UE4.Assets.Exports.SkeletalMesh; -using CUE4Parse.UE4.Objects.Core.Math; using CUE4Parse.UE4.Objects.UObject; using FModel.Views.Snooper.Shading; @@ -26,48 +24,35 @@ public class Skeleton : IDisposable Sockets = new Socket[RefSkel.Sockets.Length]; for (int i = 0; i < Sockets.Length; i++) { - if (RefSkel.Sockets[i].Load() is not { } socket || - !RefSkel.ReferenceSkeleton.FinalNameToIndexMap.TryGetValue(socket.BoneName.Text, out var boneIndex)) - continue; + if (RefSkel.Sockets[i].Load() is not { } socket) continue; - var transform = Transform.Identity; - var matrix = Matrix4x4.Identity; - while (boneIndex > -1) + if (!RefSkel.ReferenceSkeleton.FinalNameToIndexMap.TryGetValue(socket.BoneName.Text, out var boneIndex)) { - var bone = RefSkel.ReferenceSkeleton.FinalRefBonePose[boneIndex]; - boneIndex = RefSkel.ReferenceSkeleton.FinalRefBoneInfo[boneIndex].ParentIndex; - var parentBone = RefSkel.ReferenceSkeleton.FinalRefBonePose[boneIndex < 0 ? 0 : boneIndex]; - - var orig_loc = bone.Translation; - parentBone.Rotation.Conjugate(); - orig_loc = parentBone.Rotation.RotateVector(orig_loc); - - var orig_quat = bone.Rotation; - orig_quat *= parentBone.Rotation; - orig_quat.Conjugate(); - - var p_rotated = orig_quat * orig_loc; - orig_quat.Conjugate(); - p_rotated *= orig_quat; - - matrix *= - Matrix4x4.CreateFromQuaternion(orig_quat) * - Matrix4x4.CreateTranslation(p_rotated); - - // Console.WriteLine(matrix.Translation); + Sockets[i] = new Socket(socket); } - // for (int j = 0; j <= boneIndex; j++) - // { - // var t = RefSkel.ReferenceSkeleton.FinalRefBonePose[j]; - // var r = RefSkel.ReferenceSkeleton.FinalRefBonePose[j - (j == 0 ? 0 : 1)].Rotation; - // r.Conjugate(); - // matrix *= Matrix4x4.CreateFromQuaternion(r) * Matrix4x4.CreateTranslation(t.Translation); - // - // Console.WriteLine($@"{t.Translation}"); - // transform.Relation *= matrix; - // } + else + { + var transforms = new List(); + while (boneIndex > -1) + { + var bone = RefSkel.ReferenceSkeleton.FinalRefBonePose[boneIndex]; + boneIndex = RefSkel.ReferenceSkeleton.FinalRefBoneInfo[boneIndex].ParentIndex; - Sockets[i] = new Socket(socket, matrix.Translation); + transforms.Add(new Transform + { + Rotation = bone.Rotation, + Position = bone.Translation * Constants.SCALE_DOWN_RATIO, + Scale = bone.Scale3D + }); + } + + for (int j = transforms.Count - 2; j > -1; j--) + { + transforms[j].Relation *= transforms[j + 1].Matrix; + } + + Sockets[i] = new Socket(socket, transforms[0]); + } } } diff --git a/FModel/Views/Snooper/Models/Model.cs b/FModel/Views/Snooper/Models/Model.cs index 777a75cf..6d725cf2 100644 --- a/FModel/Views/Snooper/Models/Model.cs +++ b/FModel/Views/Snooper/Models/Model.cs @@ -79,11 +79,11 @@ public class Model : IDisposable public Model(UStaticMesh export, CStaticMesh staticMesh, Transform transform) : this(export, export.Materials, null, staticMesh.LODs.Count, staticMesh.LODs[0], staticMesh.LODs[0].Verts, transform) { - Box = staticMesh.BoundingBox *= Constants.SCALE_DOWN_RATIO; + Box = staticMesh.BoundingBox * Constants.SCALE_DOWN_RATIO; } private Model(USkeletalMesh export, CSkeletalMesh skeletalMesh, Transform transform) : this(export, export.Materials, export.Skeleton, skeletalMesh.LODs.Count, skeletalMesh.LODs[0], skeletalMesh.LODs[0].Verts, transform) { - Box = skeletalMesh.BoundingBox *= Constants.SCALE_DOWN_RATIO; + Box = skeletalMesh.BoundingBox * Constants.SCALE_DOWN_RATIO; } public Model(USkeletalMesh export, CSkeletalMesh skeletalMesh) : this(export, skeletalMesh, Transform.Identity) { diff --git a/FModel/Views/Snooper/Models/Socket.cs b/FModel/Views/Snooper/Models/Socket.cs index 7842fa31..f65b5134 100644 --- a/FModel/Views/Snooper/Models/Socket.cs +++ b/FModel/Views/Snooper/Models/Socket.cs @@ -1,7 +1,5 @@ using System; -using System.Numerics; using CUE4Parse.UE4.Assets.Exports.SkeletalMesh; -using CUE4Parse.UE4.Objects.Core.Math; namespace FModel.Views.Snooper.Models; @@ -11,23 +9,25 @@ public class Socket : IDisposable public readonly string Bone; public readonly Transform Transform; + public Socket(USkeletalMeshSocket socket) + { + Name = socket.SocketName.Text; + Bone = socket.BoneName.Text; + Transform = Transform.Identity; + Transform.Rotation = socket.RelativeRotation.Quaternion(); + Transform.Position = socket.RelativeLocation * Constants.SCALE_DOWN_RATIO; + Transform.Scale = socket.RelativeScale; + } + public Socket(USkeletalMeshSocket socket, Transform transform) { Name = socket.SocketName.Text; Bone = socket.BoneName.Text; Transform = transform; - // Transform.Relation = transform.Matrix; - // Transform.Position = socket.RelativeRotation.RotateVector(socket.RelativeLocation.ToMapVector()) * Constants.SCALE_DOWN_RATIO; - // Transform.Scale = socket.RelativeScale.ToMapVector(); - } - - public Socket(USkeletalMeshSocket socket, Vector3 position) - { - Name = socket.SocketName.Text; - Bone = socket.BoneName.Text; - Transform = Transform.Identity; - var pos = position /*+ socket.RelativeRotation.RotateVector(socket.RelativeLocation)*/; - Transform.Position = new FVector(pos.X, pos.Z, pos.Y) * Constants.SCALE_DOWN_RATIO; + Transform.Relation = transform.Matrix; + Transform.Rotation = socket.RelativeRotation.Quaternion(); + Transform.Position = socket.RelativeLocation * Constants.SCALE_DOWN_RATIO; + Transform.Scale = socket.RelativeScale; } public void Dispose() diff --git a/FModel/Views/Snooper/Renderer.cs b/FModel/Views/Snooper/Renderer.cs index 86b8d51c..016054c2 100644 --- a/FModel/Views/Snooper/Renderer.cs +++ b/FModel/Views/Snooper/Renderer.cs @@ -212,11 +212,9 @@ public class Renderer : IDisposable if (persistentLevel.TryGetValue(out FSoftObjectPath runtimeCell, "WorldPartitionRuntimeCell") && Utils.TryLoadObject(runtimeCell.AssetPathName.Text.SubstringBeforeWithLast(".") + runtimeCell.SubPathString.SubstringAfterLast("."), out UObject worldPartition)) { - var ratio = MathF.Pow(Constants.SCALE_DOWN_RATIO, 2); - var position = worldPartition.GetOrDefault("Position", FVector.ZeroVector).ToMapVector() * Constants.SCALE_DOWN_RATIO; + var position = worldPartition.GetOrDefault("Position", FVector.ZeroVector) * Constants.SCALE_DOWN_RATIO; var box = worldPartition.GetOrDefault("ContentBounds", new FBox(FVector.ZeroVector, FVector.OneVector)); - box.Min *= ratio;box.Max *= ratio; - + box *= MathF.Pow(Constants.SCALE_DOWN_RATIO, 2); CameraOp.Teleport(position, box, true); } @@ -243,8 +241,8 @@ public class Renderer : IDisposable if (actor.ExportType != "LevelBounds" || !actor.TryGetValue(out FPackageIndex boxComponent, "BoxComponent") || boxComponent.Load() is not { } boxObject) return; - var direction = boxObject.GetOrDefault("RelativeLocation", FVector.ZeroVector).ToMapVector() * Constants.SCALE_DOWN_RATIO; - var position = boxObject.GetOrDefault("RelativeScale3D", FVector.OneVector).ToMapVector() / 2f * Constants.SCALE_DOWN_RATIO; + var direction = boxObject.GetOrDefault("RelativeLocation", FVector.ZeroVector) * Constants.SCALE_DOWN_RATIO; + var position = boxObject.GetOrDefault("RelativeScale3D", FVector.OneVector) / 2f * Constants.SCALE_DOWN_RATIO; CameraOp.Setup(new FBox(direction, position)); } @@ -282,9 +280,9 @@ public class Renderer : IDisposable var t = new Transform { Relation = transform.Matrix, - Position = staticMeshComp.GetOrDefault("RelativeLocation", FVector.ZeroVector).ToMapVector() * Constants.SCALE_DOWN_RATIO, - Rotation = staticMeshComp.GetOrDefault("RelativeRotation", FRotator.ZeroRotator), - Scale = staticMeshComp.GetOrDefault("RelativeScale3D", FVector.OneVector).ToMapVector() + Position = staticMeshComp.GetOrDefault("RelativeLocation", FVector.ZeroVector) * Constants.SCALE_DOWN_RATIO, + Rotation = staticMeshComp.GetOrDefault("RelativeRotation", FRotator.ZeroRotator).Quaternion(), + Scale = staticMeshComp.GetOrDefault("RelativeScale3D", FVector.OneVector) }; if (Options.TryGetModel(guid, out var model)) @@ -351,12 +349,12 @@ public class Renderer : IDisposable if (actor.TryGetValue(out FPackageIndex treasureLight, "PointLight", "TreasureLight") && treasureLight.TryLoad(out var pl1) && pl1.Template.TryLoad(out var pl2)) { - Options.Lights.Add(new PointLight(guid, Options.Icons["pointlight"], pl1, pl2, t.Position)); + Options.Lights.Add(new PointLight(guid, Options.Icons["pointlight"], pl1, pl2, t)); } if (actor.TryGetValue(out FPackageIndex spotLight, "SpotLight") && spotLight.TryLoad(out var sl1) && sl1.Template.TryLoad(out var sl2)) { - Options.Lights.Add(new SpotLight(guid, Options.Icons["spotlight"], sl1, sl2, t.Position)); + Options.Lights.Add(new SpotLight(guid, Options.Icons["spotlight"], sl1, sl2, t)); } } @@ -376,9 +374,8 @@ public class Renderer : IDisposable var transform = new Transform { Relation = relation, - Position = staticMeshComp.GetOrDefault("RelativeLocation", FVector.ZeroVector).ToMapVector() * Constants.SCALE_DOWN_RATIO, - Rotation = staticMeshComp.GetOrDefault("RelativeRotation", FRotator.ZeroRotator), - Scale = FVector.OneVector.ToMapVector() + Position = staticMeshComp.GetOrDefault("RelativeLocation", FVector.ZeroVector) * Constants.SCALE_DOWN_RATIO, + Rotation = staticMeshComp.GetOrDefault("RelativeRotation", FRotator.ZeroRotator).Quaternion() }; for (int j = 0; j < additionalWorlds.Length; j++) diff --git a/FModel/Views/Snooper/Transform.cs b/FModel/Views/Snooper/Transform.cs index 69658869..0d570e3b 100644 --- a/FModel/Views/Snooper/Transform.cs +++ b/FModel/Views/Snooper/Transform.cs @@ -12,17 +12,15 @@ public class Transform } public Matrix4x4 Relation = Matrix4x4.Identity; - public FVector Position = FVector.ZeroVector.ToMapVector(); - public FRotator Rotation = new (0f); - public FVector Scale = FVector.OneVector.ToMapVector(); + public FVector Position = FVector.ZeroVector; + public FQuat Rotation = new (0f); + public FVector Scale = FVector.OneVector; public Matrix4x4 Matrix => - Matrix4x4.CreateScale(Scale) * - Matrix4x4.CreateRotationX(Helper.DegreesToRadians(Rotation.Roll)) * - Matrix4x4.CreateRotationY(Helper.DegreesToRadians(-Rotation.Yaw)) * - Matrix4x4.CreateRotationZ(Helper.DegreesToRadians(Rotation.Pitch)) * - Matrix4x4.CreateTranslation(Position) * - Relation; + Matrix4x4.CreateScale(Scale.X, Scale.Z, Scale.Y) * + Matrix4x4.CreateFromQuaternion(new Quaternion(Rotation.X, Rotation.Z, Rotation.Y, -Rotation.W)) * + Matrix4x4.CreateTranslation(Position.X, Position.Z, Position.Y) + * Relation; public void ImGuiTransform(float speed) { @@ -50,13 +48,16 @@ public class Transform { ImGui.PushID(2); ImGui.SetNextItemWidth(width); - ImGui.DragFloat("X", ref Rotation.Roll, .5f, 0f, 0f, "%.1f°"); + ImGui.DragFloat("X", ref Rotation.X, .5f, 0f, 0f, "%.1f°"); ImGui.SetNextItemWidth(width); - ImGui.DragFloat("Y", ref Rotation.Pitch, .5f, 0f, 0f, "%.1f°"); + ImGui.DragFloat("Y", ref Rotation.Z, .5f, 0f, 0f, "%.1f°"); ImGui.SetNextItemWidth(width); - ImGui.DragFloat("Z", ref Rotation.Yaw, .5f, 0f, 0f, "%.1f°"); + ImGui.DragFloat("Z", ref Rotation.Y, .5f, 0f, 0f, "%.1f°"); + + ImGui.SetNextItemWidth(width); + ImGui.DragFloat("W", ref Rotation.W, .5f, 0f, 0f, "%.1f°"); ImGui.PopID(); ImGui.TreePop();