Skip to content

Commit

Permalink
I should have persevered with quaternions
Browse files Browse the repository at this point in the history
  • Loading branch information
4sval committed Jan 6, 2023
1 parent eebaa19 commit 0221405
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 94 deletions.
2 changes: 1 addition & 1 deletion CUE4Parse
11 changes: 9 additions & 2 deletions FModel/Resources/light.vert
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
5 changes: 2 additions & 3 deletions FModel/Views/Snooper/Camera.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,11 @@ public 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);
Expand Down
17 changes: 9 additions & 8 deletions FModel/Views/Snooper/Lights/Light.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -91,7 +92,7 @@ public void Render(Shader shader)
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);
}

Expand Down
2 changes: 1 addition & 1 deletion FModel/Views/Snooper/Lights/PointLight.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion FModel/Views/Snooper/Lights/SpotLight.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion FModel/Views/Snooper/Models/Animations/Animation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void CalculateBoneTransform()

FinalBonesMatrix[boneIndex] =
Matrix4x4.CreateFromQuaternion(boneOrientation) *
Matrix4x4.CreateTranslation(bonePosition.ToMapVector());
Matrix4x4.CreateTranslation(bonePosition);
}
}

Expand Down
61 changes: 23 additions & 38 deletions FModel/Views/Snooper/Models/Animations/Skeleton.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -26,48 +24,35 @@ public Skeleton(FPackageIndex package)
Sockets = new Socket[RefSkel.Sockets.Length];
for (int i = 0; i < Sockets.Length; i++)
{
if (RefSkel.Sockets[i].Load<USkeletalMeshSocket>() is not { } socket ||
!RefSkel.ReferenceSkeleton.FinalNameToIndexMap.TryGetValue(socket.BoneName.Text, out var boneIndex))
continue;
if (RefSkel.Sockets[i].Load<USkeletalMeshSocket>() 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();
Sockets[i] = new Socket(socket);
}
else
{
var transforms = new List<Transform>();
while (boneIndex > -1)
{
var bone = RefSkel.ReferenceSkeleton.FinalRefBonePose[boneIndex];
boneIndex = RefSkel.ReferenceSkeleton.FinalRefBoneInfo[boneIndex].ParentIndex;

var p_rotated = orig_quat * orig_loc;
orig_quat.Conjugate();
p_rotated *= orig_quat;
transforms.Add(new Transform
{
Rotation = bone.Rotation,
Position = bone.Translation * Constants.SCALE_DOWN_RATIO,
Scale = bone.Scale3D
});
}

matrix *=
Matrix4x4.CreateFromQuaternion(orig_quat) *
Matrix4x4.CreateTranslation(p_rotated);
for (int j = transforms.Count - 2; j > -1; j--)
{
transforms[j].Relation *= transforms[j + 1].Matrix;
}

// Console.WriteLine(matrix.Translation);
Sockets[i] = new Socket(socket, transforms[0]);
}
// 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;
// }

Sockets[i] = new Socket(socket, matrix.Translation);
}
}

Expand Down
4 changes: 2 additions & 2 deletions FModel/Views/Snooper/Models/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ public Model(UStaticMesh export, CStaticMesh staticMesh) : this(export, staticMe

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)
{
Expand Down
22 changes: 11 additions & 11 deletions FModel/Views/Snooper/Models/Socket.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -11,23 +9,25 @@ public class Socket : IDisposable
public readonly string Bone;
public readonly Transform Transform;

public Socket(USkeletalMeshSocket socket, Transform transform)
public Socket(USkeletalMeshSocket socket)
{
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();
Transform = Transform.Identity;
Transform.Rotation = socket.RelativeRotation.Quaternion();
Transform.Position = socket.RelativeLocation * Constants.SCALE_DOWN_RATIO;
Transform.Scale = socket.RelativeScale;
}

public Socket(USkeletalMeshSocket socket, Vector3 position)
public Socket(USkeletalMeshSocket socket, Transform transform)
{
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 = transform;
Transform.Relation = transform.Matrix;
Transform.Rotation = socket.RelativeRotation.Quaternion();
Transform.Position = socket.RelativeLocation * Constants.SCALE_DOWN_RATIO;
Transform.Scale = socket.RelativeScale;
}

public void Dispose()
Expand Down
25 changes: 11 additions & 14 deletions FModel/Views/Snooper/Renderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,9 @@ private void LoadWorld(CancellationToken cancellationToken, UWorld original, Tra
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);
}

Expand All @@ -243,8 +241,8 @@ private void WorldCamera(UObject actor)
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));
}

Expand Down Expand Up @@ -282,9 +280,9 @@ private void WorldMesh(UObject actor, Transform transform)
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))
Expand Down Expand Up @@ -351,12 +349,12 @@ private void WorldMesh(UObject actor, Transform transform)
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));
}
}

Expand All @@ -376,9 +374,8 @@ private void AdditionalWorlds(UObject actor, Matrix4x4 relation, CancellationTok
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++)
Expand Down
25 changes: 13 additions & 12 deletions FModel/Views/Snooper/Transform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@ public static Transform Identity
}

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)
{
Expand Down Expand Up @@ -50,13 +48,16 @@ public void ImGuiTransform(float speed)
{
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();
Expand Down

0 comments on commit 0221405

Please sign in to comment.