Skip to content

Commit

Permalink
Fix how materials are handled to support AssimpNet 4.1.0
Browse files Browse the repository at this point in the history
This also makes material names look normal in Blender finally, no more "m17ear_2_" nonsense.
However, the old sanitized format like "m17ear_2_" is still supported as legacy when converting dae -> bmd/bdl.
  • Loading branch information
LagoLunatic committed Jul 9, 2020
1 parent 0989d2a commit ddaf992
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 21 deletions.
70 changes: 54 additions & 16 deletions SuperBMDLib/source/BMD/MAT3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Text.RegularExpressions;

namespace SuperBMDLib.BMD
{
Expand Down Expand Up @@ -474,6 +475,38 @@ public MAT3(Assimp.Scene scene, TEX1 textures, SHP1 shapes, Arguments args)
FillMaterialDataBlocks();
}

public int GetMaterialIndexFromMaterialName(string matName)
{
for (int i = 0; i < m_Materials.Count; i++)
{
if (matName == m_MaterialNames[i])
{
return i;
}
}

return -1;
}

public int GetMaterialIndexFromSanitizedMaterialName(string sanitizedMatName)
{
List<string> allSanitizedMatNames = new List<string>();
foreach (string materialName in m_MaterialNames)
{
allSanitizedMatNames.Add(materialName.Replace("(", "_").Replace(")", "_"));
}

for (int i = 0; i < m_Materials.Count; i++)
{
if (sanitizedMatName == allSanitizedMatNames[i])
{
return i;
}
}

return -1;
}

private void LoadFromJson(Assimp.Scene scene, TEX1 textures, SHP1 shapes, string json_path)
{
JsonSerializer serial = new JsonSerializer();
Expand Down Expand Up @@ -513,32 +546,37 @@ private void LoadFromJson(Assimp.Scene scene, TEX1 textures, SHP1 shapes, string
for (int i = 0; i < scene.MeshCount; i++)
{
Assimp.Material meshMat = scene.Materials[scene.Meshes[i].MaterialIndex];
string matName = meshMat.Name.Replace("-material", "");

List<string> materialNamesWithoutParentheses = new List<string>();
foreach (string materialName in m_MaterialNames)
{
materialNamesWithoutParentheses.Add(materialName.Replace("(", "_").Replace(")", "_"));
}
int matIndex = GetMaterialIndexFromMaterialName(meshMat.Name);

while (!materialNamesWithoutParentheses.Contains(matName))
if (matIndex == -1)
{
if (matName.Length <= 1)
// None of material names in materials.json are an exact match.
// Try checking if this is a legacy model from an older version of SuperBMD where the material names were sanitized.
Regex reg = new Regex("^m(\\d+)([^\"]+)");
Match match = reg.Match(meshMat.Name);
if (match.Success)
{
throw new Exception($"Mesh \"{scene.Meshes[i].Name}\" has a material named \"{meshMat.Name.Replace("-material", "")}\" which was not found in materials.json.");
int tmpMatIndex = Int32.Parse(match.Groups[1].Value);
string tmpSanitizedMatName = match.Groups[2].Value;
if (tmpMatIndex >= 0 && tmpMatIndex < m_Materials.Count)
{
string possibleMatName = m_Materials[tmpMatIndex].Name;
if (tmpSanitizedMatName == possibleMatName.Replace("(", "_").Replace(")", "_"))
{
matIndex = tmpMatIndex;
}
}
}
matName = matName.Substring(1);
}

for (int j = 0; j < m_Materials.Count; j++)
if (matIndex == -1)
{
if (matName == materialNamesWithoutParentheses[j])
{
scene.Meshes[i].MaterialIndex = j;
break;
}
throw new Exception($"Mesh \"{scene.Meshes[i].Name}\" has a material named \"{meshMat.Name}\" which was not found in materials.json.");
}

scene.Meshes[i].MaterialIndex = matIndex;

//m_RemapIndices[i] = scene.Meshes[i].MaterialIndex;
}
}
Expand Down
10 changes: 5 additions & 5 deletions SuperBMDLib/source/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,14 @@ public void ExportAssImp(string fileName, string modelType, ExportSettings setti
}
else if (line.Contains("<material id=\""))
{
Regex reg = new Regex("^ <material id=\"(m(\\d+)[^\"]+)\" name=\"[^\"]+\">$");
Regex reg = new Regex("^ <material id=\"([^\"]+)\" name=\"[^\"]+\">$");
Match match = reg.Match(line);
if (match.Success)
{
string mat_id = match.Groups[1].Value;
int mat_index = Int32.Parse(match.Groups[2].Value);
string mat_name_sanitized = match.Groups[1].Value;
int mat_index = Materials.GetMaterialIndexFromSanitizedMaterialName(mat_name_sanitized);
string mat_name = Materials.m_Materials[mat_index].Name;
string matLine = $" <material id=\"{mat_id}\" name=\"{mat_name}\">";
string matLine = $" <material id=\"{mat_name_sanitized}\" name=\"{mat_name}\">";
test.WriteLine(matLine);
}
else
Expand All @@ -264,7 +264,7 @@ public void ExportAssImp(string fileName, string modelType, ExportSettings setti
test.WriteLine(" <skeleton>#skeleton_root</skeleton>");
test.WriteLine(" <bind_material>");
test.WriteLine(" <technique_common>");
test.WriteLine($" <instance_material symbol=\"m{mesh.MaterialIndex}{ Materials.m_Materials[mesh.MaterialIndex].Name }\" target=\"#m{mesh.MaterialIndex}{ Materials.m_Materials[mesh.MaterialIndex].Name.Replace("(","_").Replace(")","_") }\" />");
test.WriteLine($" <instance_material symbol=\"{ Materials.m_Materials[mesh.MaterialIndex].Name }\" target=\"#{ Materials.m_Materials[mesh.MaterialIndex].Name.Replace("(", "_").Replace(")", "_") }\" />");
test.WriteLine(" </technique_common>");
test.WriteLine(" </bind_material>");
test.WriteLine(" </instance_controller>");
Expand Down

0 comments on commit ddaf992

Please sign in to comment.