I should have persevered with quaternions

This commit is contained in:
4sval 2023-01-06 15:14:58 +01:00
parent eebaa19178
commit 0221405758
12 changed files with 89 additions and 99 deletions

@ -1 +1 @@
Subproject commit bfb2b3ce34ceee5c9785d845a5da2b594f534493
Subproject commit 9579eabcde51e8622c79845c26f7f04e29b604e8

View File

@ -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
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -53,7 +53,7 @@ public class Animation : IDisposable
FinalBonesMatrix[boneIndex] =
Matrix4x4.CreateFromQuaternion(boneOrientation) *
Matrix4x4.CreateTranslation(bonePosition.ToMapVector());
Matrix4x4.CreateTranslation(bonePosition);
}
}

View File

@ -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<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();
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<Transform>();
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]);
}
}
}

View File

@ -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)
{

View File

@ -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()

View File

@ -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++)

View File

@ -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();