mirror of
https://github.com/4sval/FModel.git
synced 2026-06-21 07:20:05 -05:00
I should have persevered with quaternions
This commit is contained in:
parent
eebaa19178
commit
0221405758
|
|
@ -1 +1 @@
|
|||
Subproject commit bfb2b3ce34ceee5c9785d845a5da2b594f534493
|
||||
Subproject commit 9579eabcde51e8622c79845c26f7f04e29b604e8
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public class Animation : IDisposable
|
|||
|
||||
FinalBonesMatrix[boneIndex] =
|
||||
Matrix4x4.CreateFromQuaternion(boneOrientation) *
|
||||
Matrix4x4.CreateTranslation(bonePosition.ToMapVector());
|
||||
Matrix4x4.CreateTranslation(bonePosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user