From d88ceb5211313cdab383221b22479242c9196483 Mon Sep 17 00:00:00 2001 From: MediaMoots <81146974+MediaMoots@users.noreply.github.com> Date: Tue, 1 Aug 2023 06:52:49 +0800 Subject: [PATCH] Fix Replacing meshes with over 4 skin count (#649) --- .../BFRES/Bfres Structs/SubFiles/FMDL/FSHP.cs | 111 ++++++++++++------ .../FileFormats/BFRES/BfresWiiU.cs | 45 ++++--- 2 files changed, 99 insertions(+), 57 deletions(-) diff --git a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL/FSHP.cs b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL/FSHP.cs index f8f882f3..9c2c6867 100644 --- a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL/FSHP.cs +++ b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL/FSHP.cs @@ -1569,28 +1569,6 @@ namespace Bfres.Structs vert.Format = att.Format; atrib.Add(vert); } - if (att.Name == "_w0") - { - VertexBufferHelperAttrib vert = new VertexBufferHelperAttrib(); - vert.Name = att.Name; - vert.Data = weights.ToArray(); - vert.Format = att.Format; - atrib.Add(vert); - - for (int i = 0; i < weights.Count; i++) - { - Console.WriteLine($"w {i} {weights[i]}"); - } - - } - if (att.Name == "_i0") - { - VertexBufferHelperAttrib vert = new VertexBufferHelperAttrib(); - vert.Name = att.Name; - vert.Data = boneInd.ToArray(); - vert.Format = att.Format; - atrib.Add(vert); - } if (att.Name == "_b0") { VertexBufferHelperAttrib vert = new VertexBufferHelperAttrib(); @@ -1615,6 +1593,33 @@ namespace Bfres.Structs vert.Format = att.Format; atrib.Add(vert); } + + // Set _w and _i + for (int i = 0; i < weights.Count; i++) + { + if (att.Name == "_w" + i.ToString()) + { + VertexBufferHelperAttrib vert = new VertexBufferHelperAttrib(); + vert.Name = att.Name; + vert.Data = weights[i].ToArray(); + vert.Format = att.Format; + atrib.Add(vert); + + for (int j = 0; j < weights.Count; j++) + { + Console.WriteLine($"w {j} {weights[j]}"); + } + + } + if (att.Name == "_i" + i.ToString()) + { + VertexBufferHelperAttrib vert = new VertexBufferHelperAttrib(); + vert.Name = att.Name; + vert.Data = boneInd[i].ToArray(); + vert.Format = att.Format; + atrib.Add(vert); + } + } } if (atrib.Count == 0) { @@ -1635,8 +1640,8 @@ namespace Bfres.Structs internal List uv2 = new List(); internal List tans = new List(); internal List bitans = new List(); - internal List weights = new List(); - internal List boneInd = new List(); + internal List> weights = new List>(); + internal List> boneInd = new List>(); internal List colors = new List(); public string GetBoneNameFromIndex(FMDL mdl, int index) @@ -1793,6 +1798,14 @@ namespace Bfres.Structs weights.Clear(); boneInd.Clear(); + // Create arrays to be able to fit the needed skin count + int listCount = (int)Math.Ceiling(VertexSkinCount / 4.0); + for (int i = 0; i < listCount; i++) + { + weights.Add(new List()); + boneInd.Add(new List()); + } + foreach (Vertex vtx in vertices) { if (VertexSkinCount == 0 || VertexSkinCount == 1) @@ -1814,25 +1827,25 @@ namespace Bfres.Structs bitans.Add(new Syroot.Maths.Vector4F(vtx.bitan.X, vtx.bitan.Y, vtx.bitan.Z, vtx.bitan.W)); colors.Add(new Syroot.Maths.Vector4F(vtx.col.X, vtx.col.Y, vtx.col.Z, vtx.col.W)); - float[] weightsA = new float[4]; - int[] indicesA = new int[4]; + // Init arrays based on skincount + float[] weightsA = new float[Math.Max(4, (int)VertexSkinCount)]; + int[] indicesA = new int[Math.Max(4, (int)VertexSkinCount)]; - - if (vtx.boneWeights.Count >= 1) - weightsA[0] = vtx.boneWeights[0]; - if (vtx.boneWeights.Count >= 2) - weightsA[1] = vtx.boneWeights[1]; - if (vtx.boneWeights.Count >= 3) - weightsA[2] = vtx.boneWeights[2]; - if (vtx.boneWeights.Count >= 4) - weightsA[3] = vtx.boneWeights[3]; + // Cache bone weights + for (int i = 0; i < VertexSkinCount; i++) + { + if (vtx.boneWeights.Count > i) + { + weightsA[i] = vtx.boneWeights[i]; + } + } var WeightAttribute = GetWeightAttribute(0); //Produce identical results for the weight output as BFRES_Vertex.py //This should prevent encoding back and exploding int MaxWeight = 255; - for (int i = 0; i < 4; i++) + for (int i = 0; i < Math.Max(4, (int)VertexSkinCount); i++) { if (VertexSkinCount < i + 1 || vtx.boneWeights.Count < i + 1) { @@ -1857,13 +1870,33 @@ namespace Bfres.Structs } } - for (int i = 0; i < VertexSkinCount; i++) { + for (int i = 0; i < VertexSkinCount; i++) + { if (vtx.boneIds.Count > i) indicesA[i] = vtx.boneIds[i]; } - weights.Add(new Syroot.Maths.Vector4F(weightsA[0], weightsA[1], weightsA[2], weightsA[3])); - boneInd.Add(new Syroot.Maths.Vector4F(indicesA[0], indicesA[1], indicesA[2], indicesA[3])); + int v4ListIndex = 0; + int v4Index = 0; + + Syroot.Maths.Vector4F vWeight4 = new Syroot.Maths.Vector4F(); + Syroot.Maths.Vector4F vBoneInd4 = new Syroot.Maths.Vector4F(); + for (int i = 0; i < Math.Max(4, (int)VertexSkinCount); i++) + { + vWeight4[v4Index] = weightsA[i]; + vBoneInd4[v4Index] = indicesA[i]; + + // Save a v4 set each time v4Index hits 3 (.w) + if (v4Index == 3) + { + weights[v4ListIndex].Add(vWeight4); + boneInd[v4ListIndex].Add(vBoneInd4); + v4ListIndex++; + v4Index = 0; + continue; + } + v4Index++; + } } } diff --git a/File_Format_Library/FileFormats/BFRES/BfresWiiU.cs b/File_Format_Library/FileFormats/BFRES/BfresWiiU.cs index 47af37d3..7b812f59 100644 --- a/File_Format_Library/FileFormats/BFRES/BfresWiiU.cs +++ b/File_Format_Library/FileFormats/BFRES/BfresWiiU.cs @@ -1050,24 +1050,6 @@ namespace FirstPlugin vert.BufferIndex = att.BufferIndex; atrib.Add(vert); } - if (att.Name == "_w0") - { - VertexBufferHelperAttrib vert = new VertexBufferHelperAttrib(); - vert.Name = att.Name; - vert.Data = fshp.weights.ToArray(); - vert.Format = att.SetTypeWiiU(att.Format); - vert.BufferIndex = att.BufferIndex; - atrib.Add(vert); - } - if (att.Name == "_i0") - { - VertexBufferHelperAttrib vert = new VertexBufferHelperAttrib(); - vert.Name = att.Name; - vert.Data = fshp.boneInd.ToArray(); - vert.Format = att.SetTypeWiiU(att.Format); - vert.BufferIndex = att.BufferIndex; - atrib.Add(vert); - } if (att.Name == "_b0") { VertexBufferHelperAttrib vert = new VertexBufferHelperAttrib(); @@ -1095,6 +1077,33 @@ namespace FirstPlugin vert.BufferIndex = att.BufferIndex; atrib.Add(vert); } + + // Set _w and _i + for (int i = 0; i < fshp.weights.Count; i++) + { + if (att.Name == "_w" + i.ToString()) + { + VertexBufferHelperAttrib vert = new VertexBufferHelperAttrib(); + vert.Name = att.Name; + vert.Data = fshp.weights[i].ToArray(); + vert.Format = att.SetTypeWiiU(att.Format); + atrib.Add(vert); + + for (int j = 0; j < fshp.weights.Count; j++) + { + Console.WriteLine($"w {j} {fshp.weights[j]}"); + } + + } + if (att.Name == "_i" + i.ToString()) + { + VertexBufferHelperAttrib vert = new VertexBufferHelperAttrib(); + vert.Name = att.Name; + vert.Data = fshp.boneInd[i].ToArray(); + vert.Format = att.SetTypeWiiU(att.Format); + atrib.Add(vert); + } + } } if (atrib.Count == 0) {