From 963e6537cac1eb011a173cf01d581de4eb8436e7 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 14 Aug 2021 14:08:13 +0200 Subject: [PATCH] Add T5 model dumping material texture semantic detection to other game's dumpers --- .../IW3/AssetDumpers/AssetDumperXModel.cpp | 122 +++++++++++------ .../Game/IW3/AssetDumpers/AssetDumperXModel.h | 4 + .../IW4/AssetDumpers/AssetDumperXModel.cpp | 122 +++++++++++------ .../Game/IW4/AssetDumpers/AssetDumperXModel.h | 4 + .../IW5/AssetDumpers/AssetDumperXModel.cpp | 123 ++++++++++++------ .../Game/IW5/AssetDumpers/AssetDumperXModel.h | 4 + 6 files changed, 264 insertions(+), 115 deletions(-) diff --git a/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.cpp b/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.cpp index c1ccc797..68977d75 100644 --- a/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.cpp +++ b/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.cpp @@ -17,6 +17,84 @@ bool AssetDumperXModel::ShouldDump(XAssetInfo* asset) return !asset->m_name.empty() && asset->m_name[0] != ','; } +GfxImage* AssetDumperXModel::GetMaterialColorMap(const Material* material) +{ + std::vector potentialTextureDefs; + + for (auto textureIndex = 0u; textureIndex < material->textureCount; textureIndex++) + { + MaterialTextureDef* def = &material->textureTable[textureIndex]; + + if (def->semantic == TS_COLOR_MAP) + potentialTextureDefs.push_back(def); + } + + if (potentialTextureDefs.empty()) + return nullptr; + if (potentialTextureDefs.size() == 1) + return potentialTextureDefs[0]->u.image; + + for (const auto* def : potentialTextureDefs) + { + if (def->nameStart == 'c' && def->nameEnd == 'p') + return def->u.image; + } + + return potentialTextureDefs[0]->u.image; +} + +GfxImage* AssetDumperXModel::GetMaterialNormalMap(const Material* material) +{ + std::vector potentialTextureDefs; + + for (auto textureIndex = 0u; textureIndex < material->textureCount; textureIndex++) + { + MaterialTextureDef* def = &material->textureTable[textureIndex]; + + if (def->semantic == TS_NORMAL_MAP) + potentialTextureDefs.push_back(def); + } + + if (potentialTextureDefs.empty()) + return nullptr; + if (potentialTextureDefs.size() == 1) + return potentialTextureDefs[0]->u.image; + + for (const auto* def : potentialTextureDefs) + { + if (def->nameStart == 'n' && def->nameEnd == 'p') + return def->u.image; + } + + return potentialTextureDefs[0]->u.image; +} + +GfxImage* AssetDumperXModel::GetMaterialSpecularMap(const Material* material) +{ + std::vector potentialTextureDefs; + + for (auto textureIndex = 0u; textureIndex < material->textureCount; textureIndex++) + { + MaterialTextureDef* def = &material->textureTable[textureIndex]; + + if (def->semantic == TS_SPECULAR_MAP) + potentialTextureDefs.push_back(def); + } + + if (potentialTextureDefs.empty()) + return nullptr; + if (potentialTextureDefs.size() == 1) + return potentialTextureDefs[0]->u.image; + + for (const auto* def : potentialTextureDefs) + { + if (def->nameStart == 's' && def->nameEnd == 'p') + return def->u.image; + } + + return potentialTextureDefs[0]->u.image; +} + void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapper& materialMapper, const XModel* model) { if (!model->materialHandles) @@ -31,34 +109,9 @@ void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapperinfo.name); - GfxImage* colorMap = nullptr; - GfxImage* normalMap = nullptr; - GfxImage* specularMap = nullptr; - - for (auto i = 0u; i < material->textureCount; i++) - { - const auto& texture = material->textureTable[i]; - - switch (texture.semantic) - { - case TS_COLOR_MAP: - if (texture.nameStart == 'c' && texture.nameEnd == 'p') - colorMap = texture.u.image; - break; - - // Disabled due to looking weird in Blender - // case TS_NORMAL_MAP: - // normalMap = texture.u.image; - // break; - - case TS_SPECULAR_MAP: - specularMap = texture.u.image; - break; - - default: - break; - } - } + GfxImage* colorMap = GetMaterialColorMap(material); + GfxImage* normalMap = GetMaterialNormalMap(material); + GfxImage* specularMap = GetMaterialSpecularMap(material); if (colorMap != nullptr) mtl.colorMapName = colorMap->name; @@ -257,16 +310,9 @@ void AssetDumperXModel::AddXModelMaterials(AbstractXModelWriter& writer, Distinc xMaterial.ApplyDefaults(); xMaterial.name = material->info.name; - - for (auto textureIndex = 0; textureIndex < material->textureCount; textureIndex++) - { - const auto* textureTableEntry = &material->textureTable[textureIndex]; - if (textureTableEntry->semantic == TS_COLOR_MAP && textureTableEntry->nameStart == 'c' && textureTableEntry->nameEnd == 'p' && textureTableEntry->u.image) - { - xMaterial.colorMapName = textureTableEntry->u.image->name; - break; - } - } + const auto* colorMap = GetMaterialColorMap(material); + if (colorMap) + xMaterial.colorMapName = std::string(colorMap->name); writer.AddMaterial(std::move(xMaterial)); } diff --git a/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.h b/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.h index c57920b0..5c57f42a 100644 --- a/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.h +++ b/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperXModel.h @@ -10,6 +10,10 @@ namespace IW3 { class AssetDumperXModel final : public AbstractAssetDumper { + static GfxImage* GetMaterialColorMap(const Material* material); + static GfxImage* GetMaterialNormalMap(const Material* material); + static GfxImage* GetMaterialSpecularMap(const Material* material); + static void AddObjMaterials(ObjWriter& writer, DistinctMapper& materialMapper, const XModel* model); static void AddObjObjects(ObjWriter& writer, const DistinctMapper& materialMapper, const XModel* model, unsigned lod); static void AddObjVertices(ObjWriter& writer, const XModel* model, unsigned lod); diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.cpp index b807a557..765089dd 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.cpp @@ -16,6 +16,84 @@ bool AssetDumperXModel::ShouldDump(XAssetInfo* asset) return !asset->m_name.empty() && asset->m_name[0] != ','; } +GfxImage* AssetDumperXModel::GetMaterialColorMap(const Material* material) +{ + std::vector potentialTextureDefs; + + for (auto textureIndex = 0u; textureIndex < material->textureCount; textureIndex++) + { + MaterialTextureDef* def = &material->textureTable[textureIndex]; + + if (def->semantic == TS_COLOR_MAP) + potentialTextureDefs.push_back(def); + } + + if (potentialTextureDefs.empty()) + return nullptr; + if (potentialTextureDefs.size() == 1) + return potentialTextureDefs[0]->u.image; + + for (const auto* def : potentialTextureDefs) + { + if (def->nameStart == 'c' && def->nameEnd == 'p') + return def->u.image; + } + + return potentialTextureDefs[0]->u.image; +} + +GfxImage* AssetDumperXModel::GetMaterialNormalMap(const Material* material) +{ + std::vector potentialTextureDefs; + + for (auto textureIndex = 0u; textureIndex < material->textureCount; textureIndex++) + { + MaterialTextureDef* def = &material->textureTable[textureIndex]; + + if (def->semantic == TS_NORMAL_MAP) + potentialTextureDefs.push_back(def); + } + + if (potentialTextureDefs.empty()) + return nullptr; + if (potentialTextureDefs.size() == 1) + return potentialTextureDefs[0]->u.image; + + for (const auto* def : potentialTextureDefs) + { + if (def->nameStart == 'n' && def->nameEnd == 'p') + return def->u.image; + } + + return potentialTextureDefs[0]->u.image; +} + +GfxImage* AssetDumperXModel::GetMaterialSpecularMap(const Material* material) +{ + std::vector potentialTextureDefs; + + for (auto textureIndex = 0u; textureIndex < material->textureCount; textureIndex++) + { + MaterialTextureDef* def = &material->textureTable[textureIndex]; + + if (def->semantic == TS_SPECULAR_MAP) + potentialTextureDefs.push_back(def); + } + + if (potentialTextureDefs.empty()) + return nullptr; + if (potentialTextureDefs.size() == 1) + return potentialTextureDefs[0]->u.image; + + for (const auto* def : potentialTextureDefs) + { + if (def->nameStart == 's' && def->nameEnd == 'p') + return def->u.image; + } + + return potentialTextureDefs[0]->u.image; +} + void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapper& materialMapper, const XModel* model) { if (!model->materialHandles) @@ -30,34 +108,9 @@ void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapperinfo.name); - GfxImage* colorMap = nullptr; - GfxImage* normalMap = nullptr; - GfxImage* specularMap = nullptr; - - for (auto i = 0u; i < material->textureCount; i++) - { - const auto& texture = material->textureTable[i]; - - switch (texture.semantic) - { - case TS_COLOR_MAP: - if (texture.nameStart == 'c' && texture.nameEnd == 'p') - colorMap = texture.u.image; - break; - - // Disabled due to looking weird in Blender - // case TS_NORMAL_MAP: - // normalMap = texture.u.image; - // break; - - case TS_SPECULAR_MAP: - specularMap = texture.u.image; - break; - - default: - break; - } - } + GfxImage* colorMap = GetMaterialColorMap(material); + GfxImage* normalMap = GetMaterialNormalMap(material); + GfxImage* specularMap = GetMaterialSpecularMap(material); if (colorMap != nullptr) mtl.colorMapName = colorMap->name; @@ -249,16 +302,9 @@ void AssetDumperXModel::AddXModelMaterials(AbstractXModelWriter& writer, Distinc xMaterial.ApplyDefaults(); xMaterial.name = material->info.name; - - for (auto textureIndex = 0; textureIndex < material->textureCount; textureIndex++) - { - const auto* textureTableEntry = &material->textureTable[textureIndex]; - if (textureTableEntry->semantic == TS_COLOR_MAP && textureTableEntry->nameStart == 'c' && textureTableEntry->nameEnd == 'p' && textureTableEntry->u.image) - { - xMaterial.colorMapName = textureTableEntry->u.image->name; - break; - } - } + const auto* colorMap = GetMaterialColorMap(material); + if (colorMap) + xMaterial.colorMapName = std::string(colorMap->name); writer.AddMaterial(std::move(xMaterial)); } diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.h b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.h index b73cc99e..7ea7d440 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.h +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperXModel.h @@ -10,6 +10,10 @@ namespace IW4 { class AssetDumperXModel final : public AbstractAssetDumper { + static GfxImage* GetMaterialColorMap(const Material* material); + static GfxImage* GetMaterialNormalMap(const Material* material); + static GfxImage* GetMaterialSpecularMap(const Material* material); + static void AddObjMaterials(ObjWriter& writer, DistinctMapper& materialMapper, const XModel* model); static void AddObjObjects(ObjWriter& writer, const DistinctMapper& materialMapper, const XModelSurfs* modelSurfs, int baseSurfaceIndex); static void AddObjVertices(ObjWriter& writer, const XModelSurfs* modelSurfs); diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.cpp index 891f2fd9..2b058174 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.cpp @@ -16,6 +16,84 @@ bool AssetDumperXModel::ShouldDump(XAssetInfo* asset) return !asset->m_name.empty() && asset->m_name[0] != ','; } +GfxImage* AssetDumperXModel::GetMaterialColorMap(const Material* material) +{ + std::vector potentialTextureDefs; + + for (auto textureIndex = 0u; textureIndex < material->textureCount; textureIndex++) + { + MaterialTextureDef* def = &material->textureTable[textureIndex]; + + if (def->semantic == TS_COLOR_MAP) + potentialTextureDefs.push_back(def); + } + + if (potentialTextureDefs.empty()) + return nullptr; + if (potentialTextureDefs.size() == 1) + return potentialTextureDefs[0]->u.image; + + for (const auto* def : potentialTextureDefs) + { + if (def->nameStart == 'c' && def->nameEnd == 'p') + return def->u.image; + } + + return potentialTextureDefs[0]->u.image; +} + +GfxImage* AssetDumperXModel::GetMaterialNormalMap(const Material* material) +{ + std::vector potentialTextureDefs; + + for (auto textureIndex = 0u; textureIndex < material->textureCount; textureIndex++) + { + MaterialTextureDef* def = &material->textureTable[textureIndex]; + + if (def->semantic == TS_NORMAL_MAP) + potentialTextureDefs.push_back(def); + } + + if (potentialTextureDefs.empty()) + return nullptr; + if (potentialTextureDefs.size() == 1) + return potentialTextureDefs[0]->u.image; + + for (const auto* def : potentialTextureDefs) + { + if (def->nameStart == 'n' && def->nameEnd == 'p') + return def->u.image; + } + + return potentialTextureDefs[0]->u.image; +} + +GfxImage* AssetDumperXModel::GetMaterialSpecularMap(const Material* material) +{ + std::vector potentialTextureDefs; + + for (auto textureIndex = 0u; textureIndex < material->textureCount; textureIndex++) + { + MaterialTextureDef* def = &material->textureTable[textureIndex]; + + if (def->semantic == TS_SPECULAR_MAP) + potentialTextureDefs.push_back(def); + } + + if (potentialTextureDefs.empty()) + return nullptr; + if (potentialTextureDefs.size() == 1) + return potentialTextureDefs[0]->u.image; + + for (const auto* def : potentialTextureDefs) + { + if (def->nameStart == 's' && def->nameEnd == 'p') + return def->u.image; + } + + return potentialTextureDefs[0]->u.image; +} + void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapper& materialMapper, const XModel* model) { if (!model->materialHandles) @@ -29,35 +107,9 @@ void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapperinfo.name); - - GfxImage* colorMap = nullptr; - GfxImage* normalMap = nullptr; - GfxImage* specularMap = nullptr; - - for (auto i = 0u; i < material->textureCount; i++) - { - const auto& texture = material->textureTable[i]; - - switch (texture.semantic) - { - case TS_COLOR_MAP: - if(texture.nameStart == 'c' && texture.nameEnd == 'p') - colorMap = texture.u.image; - break; - - // Disabled due to looking weird in Blender - // case TS_NORMAL_MAP: - // normalMap = texture.u.image; - // break; - - case TS_SPECULAR_MAP: - specularMap = texture.u.image; - break; - - default: - break; - } - } + GfxImage* colorMap = GetMaterialColorMap(material); + GfxImage* normalMap = GetMaterialNormalMap(material); + GfxImage* specularMap = GetMaterialSpecularMap(material); if (colorMap != nullptr) mtl.colorMapName = colorMap->name; @@ -249,16 +301,9 @@ void AssetDumperXModel::AddXModelMaterials(AbstractXModelWriter& writer, Distinc xMaterial.ApplyDefaults(); xMaterial.name = material->info.name; - - for (auto textureIndex = 0; textureIndex < material->textureCount; textureIndex++) - { - const auto* textureTableEntry = &material->textureTable[textureIndex]; - if (textureTableEntry->semantic == TS_COLOR_MAP && textureTableEntry->nameStart == 'c' && textureTableEntry->nameEnd == 'p' && textureTableEntry->u.image) - { - xMaterial.colorMapName = textureTableEntry->u.image->name; - break; - } - } + const auto* colorMap = GetMaterialColorMap(material); + if (colorMap) + xMaterial.colorMapName = std::string(colorMap->name); writer.AddMaterial(std::move(xMaterial)); } diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.h index 664b3ab8..8874d8b9 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.h +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperXModel.h @@ -10,6 +10,10 @@ namespace IW5 { class AssetDumperXModel final : public AbstractAssetDumper { + static GfxImage* GetMaterialColorMap(const Material* material); + static GfxImage* GetMaterialNormalMap(const Material* material); + static GfxImage* GetMaterialSpecularMap(const Material* material); + static void AddObjMaterials(ObjWriter& writer, DistinctMapper& materialMapper, const XModel* model); static void AddObjObjects(ObjWriter& writer, const DistinctMapper& materialMapper, const XModelSurfs* modelSurfs, int baseSurfaceIndex); static void AddObjVertices(ObjWriter& writer, const XModelSurfs* modelSurfs);