From 3692dff9bd784a7fade3366b72b3250d89fcda44 Mon Sep 17 00:00:00 2001 From: MeltyPlayer Date: Thu, 26 Oct 2023 03:10:13 -0500 Subject: [PATCH] Finally got the melee meshes loading correctly! --- .../Formats/Dat/src/api/DatModelImporter.cs | 24 +++++++++++---- FinModelUtility/Formats/Dat/src/schema/Dat.cs | 30 ++++++++++++------- .../Formats/Dat/src/schema/JObj.cs | 2 +- .../Formats/Dat/src/schema/PObj.cs | 3 +- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/FinModelUtility/Formats/Dat/src/api/DatModelImporter.cs b/FinModelUtility/Formats/Dat/src/api/DatModelImporter.cs index 175c65241..799e7cbc5 100644 --- a/FinModelUtility/Formats/Dat/src/api/DatModelImporter.cs +++ b/FinModelUtility/Formats/Dat/src/api/DatModelImporter.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Runtime.InteropServices.ComTypes; +using Assimp; using Assimp.Unmanaged; using dat.schema; @@ -22,9 +23,11 @@ public IModel ImportModel(DatModelFileBundle modelFileBundle) { modelFileBundle.PrimaryDatFile.ReadNew(Endianness.BigEndian); var finModel = new ModelImpl(); + var finSkin = finModel.Skin; // Adds skeleton var finBoneByJObj = new Dictionary(); + var boneWeightsByJObj = new Dictionary(); var boneQueue = new Queue<(IBone finParentBone, JObj datBone)>(); foreach (var datRootBone in dat.RootJObjs) { boneQueue.Enqueue((finModel.Skeleton.Root, datRootBone)); @@ -50,6 +53,8 @@ public IModel ImportModel(DatModelFileBundle modelFileBundle) { finBone.Name = jObj.Name; finBoneByJObj[jObj] = finBone; + boneWeightsByJObj[jObj] = + finSkin.GetOrCreateBoneWeights(VertexSpace.BONE, finBone); foreach (var datChildBone in jObj.Children) { boneQueue.Enqueue((finBone, datChildBone)); @@ -61,9 +66,10 @@ public IModel ImportModel(DatModelFileBundle modelFileBundle) { var finMaterialsByMObjOffset = new Dictionary(); var finTexturesByTObjOffset = new Dictionary(); - var finSkin = finModel.Skin; var finMesh = finSkin.AddMesh(); foreach (var jObj in dat.JObjs) { + var defaultBoneWeights = boneWeightsByJObj[jObj]; + foreach (var dObj in jObj.DObjs) { // Gets material IMaterial? finMaterial = null; @@ -92,7 +98,8 @@ public IModel ImportModel(DatModelFileBundle modelFileBundle) { } } - finMaterial = finMaterialManager.AddTextureMaterial(firstTexture!); + finMaterial = + finMaterialManager.AddTextureMaterial(firstTexture!); } finMaterial.Name = mObj.Name ?? mObjOffset.ToHex(); @@ -111,7 +118,7 @@ public IModel ImportModel(DatModelFileBundle modelFileBundle) { .Select( pObjWeight => new BoneWeight( finBoneByJObj[pObjWeight.JObj], - null, + pObjWeight.JObj.InverseBindMatrix, pObjWeight.Weight )) .ToArray())) @@ -137,9 +144,14 @@ public IModel ImportModel(DatModelFileBundle modelFileBundle) { finVertex.SetUv(1, uv1.X, uv1.Y); } - if (datVertex.WeightId != null && finWeights != null) { - finVertex.SetBoneWeights( - finWeights[datVertex.WeightId.Value]); + // TODO: Is this right??? + if (datVertex.WeightId != null) { + if (finWeights != null) { + finVertex.SetBoneWeights( + finWeights[datVertex.WeightId.Value]); + } + } else { + finVertex.SetBoneWeights(defaultBoneWeights); } return finVertex; diff --git a/FinModelUtility/Formats/Dat/src/schema/Dat.cs b/FinModelUtility/Formats/Dat/src/schema/Dat.cs index 7b443234d..68f996a40 100644 --- a/FinModelUtility/Formats/Dat/src/schema/Dat.cs +++ b/FinModelUtility/Formats/Dat/src/schema/Dat.cs @@ -1,17 +1,11 @@ using System.Numerics; -using CommunityToolkit.HighPerformance; - -using fin.color; -using fin.data.queues; using fin.math.matrix.four; -using fin.schema.matrix; +using fin.model.impl; using fin.util.asserts; using fin.util.enumerables; using fin.util.hex; -using gx; - using schema.binary; using schema.binary.attributes; @@ -157,10 +151,24 @@ uint jObjDataOffset br.Position = jObjDataOffset; jObjData.Read(br); - br.Position = jObjData.InverseBindMatrixOffset; - var inverseBindMatrixValues = new float[4 * 4]; - br.ReadSingles(inverseBindMatrixValues.AsSpan(0, 4 * 3)); - jObj.InverseBindMatrix = new FinMatrix4x4(inverseBindMatrixValues).TransposeInPlace(); + if (jObjData.InverseBindMatrixOffset != 0) { + br.Position = jObjData.InverseBindMatrixOffset; + + var inverseBindMatrixValues = new float[4 * 4]; + br.ReadSingles(inverseBindMatrixValues.AsSpan(0, 4 * 3)); + inverseBindMatrixValues[15] = 1; + jObj.InverseBindMatrix = + new FinMatrix4x4(inverseBindMatrixValues).TransposeInPlace(); + + var parentInverseBindMatrix = + parentJObj?.InverseBindMatrix ?? FinMatrix4x4.IDENTITY; + var thisInverseBindMatrix = + parentInverseBindMatrix.CloneAndInvert() + .MultiplyInPlace(jObj.InverseBindMatrix!); + + var thisMatrix = thisInverseBindMatrix.CloneAndInvert(); + ; + } var firstChildOffset = jObj.Data.FirstChildBoneOffset; if (this.AssertNullOrValidPointer_(firstChildOffset)) { diff --git a/FinModelUtility/Formats/Dat/src/schema/JObj.cs b/FinModelUtility/Formats/Dat/src/schema/JObj.cs index 9149525a8..6219abe45 100644 --- a/FinModelUtility/Formats/Dat/src/schema/JObj.cs +++ b/FinModelUtility/Formats/Dat/src/schema/JObj.cs @@ -88,7 +88,7 @@ public IEnumerable DObjs { public List Children { get; } = new(); - public IFinMatrix4x4 InverseBindMatrix { get; set; } + public IFinMatrix4x4? InverseBindMatrix { get; set; } public override string ToString() => this.Name; } diff --git a/FinModelUtility/Formats/Dat/src/schema/PObj.cs b/FinModelUtility/Formats/Dat/src/schema/PObj.cs index 9b33b4240..60c6ad87a 100644 --- a/FinModelUtility/Formats/Dat/src/schema/PObj.cs +++ b/FinModelUtility/Formats/Dat/src/schema/PObj.cs @@ -19,7 +19,6 @@ namespace dat.schema { [Flags] public enum PObjFlags : ushort { OBJTYPE_SKIN = 0 << 12, - USE_BONES_DIRECTLY = 1 << 2, OBJTYPE_SHAPEANIM = 1 << 12, OBJTYPE_ENVELOPE = 1 << 13, OBJTYPE_MASK = 0x3000, @@ -114,7 +113,7 @@ private void ReadDisplayList_(IBinaryReader br) { var pObjWeights = this.Weights = new List>(); // Weight list is children of a given bone - if (this.Header.Flags.CheckFlag(PObjFlags.USE_BONES_DIRECTLY)) { + if (!this.Header.Flags.CheckFlag(PObjFlags.OBJTYPE_ENVELOPE)) { var currentJObjOffset = weightListOffset; while (currentJObjOffset != 0) { var jObj = this.dat_.JObjByOffset[currentJObjOffset];