Skip to content

Commit

Permalink
fuck you bones position
Browse files Browse the repository at this point in the history
that's a problem for future me
  • Loading branch information
4sval committed Nov 13, 2022
1 parent 25de508 commit ad6c4b9
Show file tree
Hide file tree
Showing 13 changed files with 581 additions and 396 deletions.
1 change: 1 addition & 0 deletions FModel/Framework/ImGuiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ public void Render()
ImGui.Render();
RenderImDrawData(ImGui.GetDrawData());
}
CheckGLError("End of frame");
}

/// <summary>
Expand Down
12 changes: 9 additions & 3 deletions FModel/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,15 @@ private async void OnLoaded(object sender, RoutedEventArgs e)
_discordHandler.Initialize(_applicationView.CUE4Parse.Game);

#if DEBUG
await _threadWorkerView.Begin(cancellationToken =>
_applicationView.CUE4Parse.Extract(cancellationToken,
"FortniteGame/Content/Athena/Artemis/Maps/Buildings/5x5/Artemis_5x5_Shop_AB.umap"));
// await _threadWorkerView.Begin(cancellationToken =>
// _applicationView.CUE4Parse.Extract(cancellationToken,
// "FortniteGame/Content/Characters/Player/Female/Medium/Bodies/F_MED_RoseDust/Meshes/F_MED_RoseDust.uasset"));
// await _threadWorkerView.Begin(cancellationToken =>
// _applicationView.CUE4Parse.Extract(cancellationToken,
// "fortnitegame/Content/Accessories/FORT_Backpacks/Backpack_M_MED_Despair/Meshes/M_MED_Despair_Pack.uasset"));
// await _threadWorkerView.Begin(cancellationToken =>
// _applicationView.CUE4Parse.Extract(cancellationToken,
// "FortniteGame/Content/Animation/Game/MainPlayer/Emotes/Acrobatic_Superhero/Emote_AcrobaticSuperhero_CMM.uasset"));
#endif
}

Expand Down
20 changes: 18 additions & 2 deletions FModel/Resources/default.vert
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ layout (location = 3) in vec3 vTangent;
layout (location = 4) in vec2 vTexCoords;
layout (location = 5) in float vTexLayer;
layout (location = 6) in vec4 vColor;
layout (location = 7) in ivec4 vBoneIds;
layout (location = 8) in vec4 vWeights;
layout (location = 7) in vec4 vBoneIds;
layout (location = 8) in vec4 vBoneWeights;
layout (location = 9) in mat4 vInstanceMatrix;
layout (location = 13) in vec3 vMorphTarget;

//const int MAX_BONES = 0;
//const int MAX_BONE_INFLUENCE = 0;

uniform mat4 uView;
uniform mat4 uProjection;
uniform float uMorphTime;
//uniform mat4 uFinalBonesMatrix[MAX_BONES];

out vec3 fPos;
out vec3 fNormal;
Expand All @@ -25,6 +29,18 @@ out vec4 fColor;
void main()
{
vec4 pos = vec4(mix(vPos, vMorphTarget, uMorphTime), 1.0);
// for(int i = 0 ; i < MAX_BONE_INFLUENCE; i++)
// {
// if(vBoneIds[i] == -1) continue;
// if(vBoneIds[i] >= MAX_BONES)
// {
// break;
// }
//
// vec4 localPos = uFinalBonesMatrix[int(vBoneIds[i])] * pos;
// pos += localPos * vBoneWeights[i];
// }

gl_Position = uProjection * uView * vInstanceMatrix * pos;

fPos = vec3(vInstanceMatrix * pos);
Expand Down
13 changes: 13 additions & 0 deletions FModel/ViewModels/CUE4ParseViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ public bool ModelIsOverwritingMaterial
set => SetProperty(ref _modelIsOverwritingMaterial, value);
}

private bool _modelIsWaitingAnimation;
public bool ModelIsWaitingAnimation
{
get => _modelIsWaitingAnimation;
set => SetProperty(ref _modelIsWaitingAnimation, value);
}

private Snooper _snooper;
public Snooper SnooperViewer
{
Expand Down Expand Up @@ -790,6 +797,12 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
SnooperViewer.Run();
return true;
}
case UAnimSequence a when ModelIsWaitingAnimation:
{
SnooperViewer.Renderer.Animate(a);
SnooperViewer.Run();
return true;
}
case UStaticMesh when UserSettings.Default.SaveStaticMeshes:
case USkeletalMesh when UserSettings.Default.SaveSkeletalMeshes:
case UMaterialInstance when UserSettings.Default.SaveMaterials:
Expand Down
64 changes: 64 additions & 0 deletions FModel/Views/Snooper/Animation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Numerics;
using CUE4Parse_Conversion.Animations;
using CUE4Parse.UE4.Objects.Core.Math;

namespace FModel.Views.Snooper;

public class Animation : IDisposable
{
public float CurrentTime;
public float DeltaTime;
public CAnimSet CurrentAnimation;
public Matrix4x4[] FinalBonesMatrix;

public Animation(CAnimSet anim)
{
CurrentTime = 0f;
CurrentAnimation = anim;

FinalBonesMatrix = new Matrix4x4[anim.TrackBoneNames.Length];
for (int i = 0; i < FinalBonesMatrix.Length; i++)
{
FinalBonesMatrix[i] = Matrix4x4.Identity;
}
}

public void UpdateAnimation(float deltaTime)
{
DeltaTime = deltaTime;
if (CurrentAnimation != null)
{
CurrentTime = deltaTime;
CalculateBoneTransform();
}
}

public void CalculateBoneTransform()
{
var sequence = CurrentAnimation.Sequences[0];
for (int boneIndex = 0; boneIndex < FinalBonesMatrix.Length; boneIndex++)
{
var boneOrientation = FQuat.Identity;
var bonePosition = FVector.ZeroVector;
sequence.Tracks[boneIndex].GetBonePosition(CurrentTime, sequence.NumFrames, false, ref bonePosition, ref boneOrientation);

boneOrientation *= CurrentAnimation.BonePositions[boneIndex].Orientation;
bonePosition = boneOrientation.RotateVector(bonePosition);
bonePosition *= Constants.SCALE_DOWN_RATIO;
if (CurrentAnimation.TrackBoneNames[boneIndex].Text == "pelvis")
{

}

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

public void Dispose()
{
throw new NotImplementedException();
}
}
27 changes: 13 additions & 14 deletions FModel/Views/Snooper/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ public class Model : IDisposable
public readonly string Name;
public readonly string Type;
public readonly bool HasVertexColors;
public readonly bool HasBones;
public readonly bool HasMorphTargets;
public readonly int NumTexCoords;
public uint[] Indices;
public float[] Vertices;
public Section[] Sections;
public Material[] Materials;
public readonly List<CSkelMeshBone> Skeleton;

public bool HasSkeleton => Skeleton is { IsLoaded: true };
public readonly Skeleton Skeleton;

public int TransformsCount;
public readonly List<Transform> Transforms;
Expand All @@ -50,7 +51,6 @@ public class Model : IDisposable
public bool bVertexNormals;
public bool bVertexTangent;
public bool bVertexTexCoords;
public bool DisplayBones;
public int SelectedInstance;
public float MorphTime;

Expand All @@ -63,10 +63,10 @@ protected Model(string name, string type)
}

public Model(string name, string type, ResolvedObject[] materials, CStaticMesh staticMesh) : this(name, type, materials, staticMesh, Transform.Identity) {}
public Model(string name, string type, ResolvedObject[] materials, CStaticMesh staticMesh, Transform transform) : this(name, type, materials, staticMesh.LODs[0], staticMesh.LODs[0].Verts, transform) {}
public Model(string name, string type, ResolvedObject[] materials, CSkeletalMesh skeletalMesh) : this(name, type, materials, skeletalMesh, Transform.Identity) {}
public Model(string name, string type, ResolvedObject[] materials, CSkeletalMesh skeletalMesh, Transform transform) : this(name, type, materials, skeletalMesh.LODs[0], skeletalMesh.LODs[0].Verts, transform, skeletalMesh.RefSkeleton) {}
public Model(string name, string type, ResolvedObject[] materials, FPackageIndex[] morphTargets, CSkeletalMesh skeletalMesh) : this(name, type, materials, skeletalMesh)
public Model(string name, string type, ResolvedObject[] materials, CStaticMesh staticMesh, Transform transform) : this(name, type, materials, null, staticMesh.LODs[0], staticMesh.LODs[0].Verts, transform) {}
public Model(string name, string type, ResolvedObject[] materials, FPackageIndex skeleton, CSkeletalMesh skeletalMesh) : this(name, type, materials, skeleton, skeletalMesh, Transform.Identity) {}
public Model(string name, string type, ResolvedObject[] materials, FPackageIndex skeleton, CSkeletalMesh skeletalMesh, Transform transform) : this(name, type, materials, skeleton, skeletalMesh.LODs[0], skeletalMesh.LODs[0].Verts, transform) {}
public Model(string name, string type, ResolvedObject[] materials, FPackageIndex skeleton, FPackageIndex[] morphTargets, CSkeletalMesh skeletalMesh) : this(name, type, materials, skeleton, skeletalMesh)
{
if (morphTargets is not { Length: > 0 })
return;
Expand All @@ -79,7 +79,7 @@ public Model(string name, string type, ResolvedObject[] materials, FPackageIndex
}
}

private Model(string name, string type, ResolvedObject[] materials, CBaseMeshLod lod, CMeshVertex[] vertices, Transform transform, List<CSkelMeshBone> skeleton = null) : this(name, type)
private Model(string name, string type, ResolvedObject[] materials, FPackageIndex skeleton, CBaseMeshLod lod, CMeshVertex[] vertices, Transform transform = null) : this(name, type)
{
NumTexCoords = lod.NumTexCoords;

Expand All @@ -96,10 +96,9 @@ private Model(string name, string type, ResolvedObject[] materials, CBaseMeshLod
_vertexSize += 4; // + Color
}

if (skeleton is { Count: > 0 })
if (skeleton != null)
{
HasBones = true;
Skeleton = skeleton;
Skeleton = new Skeleton(skeleton);
_vertexSize += 8; // + BoneIds + BoneWeights
}

Expand Down Expand Up @@ -146,7 +145,7 @@ private Model(string name, string type, ResolvedObject[] materials, CBaseMeshLod
Vertices[baseIndex + count++] = color.A;
}

if (HasBones)
if (HasSkeleton)
{
var skelVert = (CSkelMeshVertex) vert;
var weightsHash = skelVert.UnpackWeights();
Expand All @@ -165,7 +164,7 @@ private Model(string name, string type, ResolvedObject[] materials, CBaseMeshLod
}
}

AddInstance(transform);
AddInstance(transform ?? Transform.Identity);
}

public void AddInstance(Transform transform)
Expand Down Expand Up @@ -212,7 +211,7 @@ public void Setup(Cache cache)
_vao.VertexAttributePointer(4, 2, VertexAttribPointerType.Float, _vertexSize, 10); // uv
_vao.VertexAttributePointer(5, 1, VertexAttribPointerType.Float, _vertexSize, 12); // texture index
_vao.VertexAttributePointer(6, 4, VertexAttribPointerType.Float, _vertexSize, 13); // color
_vao.VertexAttributePointer(7, 4, VertexAttribPointerType.Int, _vertexSize, 17); // boneids
_vao.VertexAttributePointer(7, 4, VertexAttribPointerType.Float, _vertexSize, 17); // boneids
_vao.VertexAttributePointer(8, 4, VertexAttribPointerType.Float, _vertexSize, 21); // boneweights

SetupInstances(); // instanced models transform
Expand Down
5 changes: 5 additions & 0 deletions FModel/Views/Snooper/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,9 @@ public void SwapMaterial(bool value)
{
Services.ApplicationService.ApplicationView.CUE4Parse.ModelIsOverwritingMaterial = value;
}

public void AnimateMesh(bool value)
{
Services.ApplicationService.ApplicationView.CUE4Parse.ModelIsWaitingAnimation = value;
}
}
14 changes: 13 additions & 1 deletion FModel/Views/Snooper/Renderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
using System.Numerics;
using System.Threading;
using System.Windows;
using CUE4Parse_Conversion.Animations;
using CUE4Parse_Conversion.Meshes;
using CUE4Parse.UE4.Assets.Exports;
using CUE4Parse.UE4.Assets.Exports.Animation;
using CUE4Parse.UE4.Assets.Exports.Material;
using CUE4Parse.UE4.Assets.Exports.SkeletalMesh;
using CUE4Parse.UE4.Assets.Exports.StaticMesh;
Expand Down Expand Up @@ -55,6 +57,16 @@ public void Swap(UMaterialInstance unrealMaterial)
Settings.SwapMaterial(false);
}

public void Animate(UAnimSequence animSequence)
{
if (!Cache.Models.TryGetValue(Settings.SelectedModel, out var model) || !model.Skeleton.IsLoaded ||
model.Skeleton?.RefSkel.ConvertAnims(animSequence) is not { } anim || anim.Sequences.Count == 0)
return;

model.Skeleton.Anim = new Animation(anim);
Settings.AnimateMesh(false);
}

public void Setup()
{
_shader = new Shader();
Expand Down Expand Up @@ -122,7 +134,7 @@ private Camera LoadSkeletalMesh(USkeletalMesh original)
var guid = Guid.NewGuid();
if (Cache.Models.ContainsKey(guid) || !original.TryConvert(out var mesh)) return null;

Cache.Models[guid] = new Model(original.Name, original.ExportType, original.Materials, original.MorphTargets, mesh);
Cache.Models[guid] = new Model(original.Name, original.ExportType, original.Materials, original.Skeleton, original.MorphTargets, mesh);
Settings.SelectModel(guid);
return SetupCamera(mesh.BoundingBox *= Constants.SCALE_DOWN_RATIO);
}
Expand Down
8 changes: 5 additions & 3 deletions FModel/Views/Snooper/Shader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,14 @@ public void SetUniform(string name, int value)
GL.Uniform1(location, value);
}

public unsafe void SetUniform(string name, Matrix4 value)
public unsafe void SetUniform(string name, Matrix4 value) => UniformMatrix4(name, (float*) &value);
public unsafe void SetUniform(string name, System.Numerics.Matrix4x4 value) => UniformMatrix4(name, (float*) &value);
public unsafe void UniformMatrix4(string name, float* value)
{
//A new overload has been created for setting a uniform so we can use the transform in our shader.
int location = GL.GetUniformLocation(_handle, name);
ThrowIfNotFound(location, name);
GL.UniformMatrix4(location, 1, false, (float*) &value);
GL.UniformMatrix4(location, 1, false, value);
}

public void SetUniform(string name, bool value) => SetUniform(name, Convert.ToUInt32(value));
Expand Down Expand Up @@ -124,7 +126,7 @@ private void ThrowIfNotFound(int location, string name)
{
if (location == -1)
{
// throw new Exception($"{name} uniform not found on shader.");
throw new Exception($"{name} uniform not found on shader.");
}
}

Expand Down
52 changes: 52 additions & 0 deletions FModel/Views/Snooper/Skeleton.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using CUE4Parse.UE4.Assets.Exports.Animation;
using CUE4Parse.UE4.Assets.Exports.SkeletalMesh;
using CUE4Parse.UE4.Objects.UObject;

namespace FModel.Views.Snooper;

public class Skeleton : IDisposable
{
public readonly USkeleton RefSkel;
public readonly bool IsLoaded;
public readonly Socket[] Sockets;

public Animation Anim;

public Skeleton(FPackageIndex package)
{
RefSkel = package.Load<USkeleton>();
if (RefSkel == null) return;

IsLoaded = true;
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;

var t = RefSkel.ReferenceSkeleton.FinalRefBonePose[boneIndex];
var transform = Transform.Identity;
transform.Position = t.Translation.ToMapVector() * Constants.SCALE_DOWN_RATIO;
transform.Rotation = t.Rotator();
transform.Scale = t.Scale3D.ToMapVector();

Sockets[i] = new Socket(socket, transform);
}
}

public void SetUniform(Shader shader)
{
if (!IsLoaded) return;
for (var i = 0; i < Anim?.FinalBonesMatrix.Length; i++)
{
shader.SetUniform($"uFinalBonesMatrix[{i}]", Anim.FinalBonesMatrix[i]);
}
}

public void Dispose()
{
throw new NotImplementedException();
}
}
Loading

0 comments on commit ad6c4b9

Please sign in to comment.