Add T5 model dumping material texture semantic detection to other game's dumpers

This commit is contained in:
Jan 2021-08-14 14:08:13 +02:00
parent ee22face41
commit 963e6537ca
6 changed files with 264 additions and 115 deletions

View File

@ -17,6 +17,84 @@ bool AssetDumperXModel::ShouldDump(XAssetInfo<XModel>* asset)
return !asset->m_name.empty() && asset->m_name[0] != ','; return !asset->m_name.empty() && asset->m_name[0] != ',';
} }
GfxImage* AssetDumperXModel::GetMaterialColorMap(const Material* material)
{
std::vector<MaterialTextureDef*> 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<MaterialTextureDef*> 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<MaterialTextureDef*> 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<Material*>& materialMapper, const XModel* model) void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapper<Material*>& materialMapper, const XModel* model)
{ {
if (!model->materialHandles) if (!model->materialHandles)
@ -31,34 +109,9 @@ void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapper<Materi
MtlMaterial mtl; MtlMaterial mtl;
mtl.materialName = std::string(material->info.name); mtl.materialName = std::string(material->info.name);
GfxImage* colorMap = nullptr; GfxImage* colorMap = GetMaterialColorMap(material);
GfxImage* normalMap = nullptr; GfxImage* normalMap = GetMaterialNormalMap(material);
GfxImage* specularMap = nullptr; GfxImage* specularMap = GetMaterialSpecularMap(material);
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;
}
}
if (colorMap != nullptr) if (colorMap != nullptr)
mtl.colorMapName = colorMap->name; mtl.colorMapName = colorMap->name;
@ -257,16 +310,9 @@ void AssetDumperXModel::AddXModelMaterials(AbstractXModelWriter& writer, Distinc
xMaterial.ApplyDefaults(); xMaterial.ApplyDefaults();
xMaterial.name = material->info.name; xMaterial.name = material->info.name;
const auto* colorMap = GetMaterialColorMap(material);
for (auto textureIndex = 0; textureIndex < material->textureCount; textureIndex++) if (colorMap)
{ xMaterial.colorMapName = std::string(colorMap->name);
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;
}
}
writer.AddMaterial(std::move(xMaterial)); writer.AddMaterial(std::move(xMaterial));
} }

View File

@ -10,6 +10,10 @@ namespace IW3
{ {
class AssetDumperXModel final : public AbstractAssetDumper<XModel> class AssetDumperXModel final : public AbstractAssetDumper<XModel>
{ {
static GfxImage* GetMaterialColorMap(const Material* material);
static GfxImage* GetMaterialNormalMap(const Material* material);
static GfxImage* GetMaterialSpecularMap(const Material* material);
static void AddObjMaterials(ObjWriter& writer, DistinctMapper<Material*>& materialMapper, const XModel* model); static void AddObjMaterials(ObjWriter& writer, DistinctMapper<Material*>& materialMapper, const XModel* model);
static void AddObjObjects(ObjWriter& writer, const DistinctMapper<Material*>& materialMapper, const XModel* model, unsigned lod); static void AddObjObjects(ObjWriter& writer, const DistinctMapper<Material*>& materialMapper, const XModel* model, unsigned lod);
static void AddObjVertices(ObjWriter& writer, const XModel* model, unsigned lod); static void AddObjVertices(ObjWriter& writer, const XModel* model, unsigned lod);

View File

@ -16,6 +16,84 @@ bool AssetDumperXModel::ShouldDump(XAssetInfo<XModel>* asset)
return !asset->m_name.empty() && asset->m_name[0] != ','; return !asset->m_name.empty() && asset->m_name[0] != ',';
} }
GfxImage* AssetDumperXModel::GetMaterialColorMap(const Material* material)
{
std::vector<MaterialTextureDef*> 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<MaterialTextureDef*> 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<MaterialTextureDef*> 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<Material*>& materialMapper, const XModel* model) void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapper<Material*>& materialMapper, const XModel* model)
{ {
if (!model->materialHandles) if (!model->materialHandles)
@ -30,34 +108,9 @@ void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapper<Materi
MtlMaterial mtl; MtlMaterial mtl;
mtl.materialName = std::string(material->info.name); mtl.materialName = std::string(material->info.name);
GfxImage* colorMap = nullptr; GfxImage* colorMap = GetMaterialColorMap(material);
GfxImage* normalMap = nullptr; GfxImage* normalMap = GetMaterialNormalMap(material);
GfxImage* specularMap = nullptr; GfxImage* specularMap = GetMaterialSpecularMap(material);
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;
}
}
if (colorMap != nullptr) if (colorMap != nullptr)
mtl.colorMapName = colorMap->name; mtl.colorMapName = colorMap->name;
@ -249,16 +302,9 @@ void AssetDumperXModel::AddXModelMaterials(AbstractXModelWriter& writer, Distinc
xMaterial.ApplyDefaults(); xMaterial.ApplyDefaults();
xMaterial.name = material->info.name; xMaterial.name = material->info.name;
const auto* colorMap = GetMaterialColorMap(material);
for (auto textureIndex = 0; textureIndex < material->textureCount; textureIndex++) if (colorMap)
{ xMaterial.colorMapName = std::string(colorMap->name);
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;
}
}
writer.AddMaterial(std::move(xMaterial)); writer.AddMaterial(std::move(xMaterial));
} }

View File

@ -10,6 +10,10 @@ namespace IW4
{ {
class AssetDumperXModel final : public AbstractAssetDumper<XModel> class AssetDumperXModel final : public AbstractAssetDumper<XModel>
{ {
static GfxImage* GetMaterialColorMap(const Material* material);
static GfxImage* GetMaterialNormalMap(const Material* material);
static GfxImage* GetMaterialSpecularMap(const Material* material);
static void AddObjMaterials(ObjWriter& writer, DistinctMapper<Material*>& materialMapper, const XModel* model); static void AddObjMaterials(ObjWriter& writer, DistinctMapper<Material*>& materialMapper, const XModel* model);
static void AddObjObjects(ObjWriter& writer, const DistinctMapper<Material*>& materialMapper, const XModelSurfs* modelSurfs, int baseSurfaceIndex); static void AddObjObjects(ObjWriter& writer, const DistinctMapper<Material*>& materialMapper, const XModelSurfs* modelSurfs, int baseSurfaceIndex);
static void AddObjVertices(ObjWriter& writer, const XModelSurfs* modelSurfs); static void AddObjVertices(ObjWriter& writer, const XModelSurfs* modelSurfs);

View File

@ -16,6 +16,84 @@ bool AssetDumperXModel::ShouldDump(XAssetInfo<XModel>* asset)
return !asset->m_name.empty() && asset->m_name[0] != ','; return !asset->m_name.empty() && asset->m_name[0] != ',';
} }
GfxImage* AssetDumperXModel::GetMaterialColorMap(const Material* material)
{
std::vector<MaterialTextureDef*> 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<MaterialTextureDef*> 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<MaterialTextureDef*> 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<Material*>& materialMapper, const XModel* model) void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapper<Material*>& materialMapper, const XModel* model)
{ {
if (!model->materialHandles) if (!model->materialHandles)
@ -29,35 +107,9 @@ void AssetDumperXModel::AddObjMaterials(ObjWriter& writer, DistinctMapper<Materi
MtlMaterial mtl; MtlMaterial mtl;
mtl.materialName = std::string(material->info.name); mtl.materialName = std::string(material->info.name);
GfxImage* colorMap = GetMaterialColorMap(material);
GfxImage* colorMap = nullptr; GfxImage* normalMap = GetMaterialNormalMap(material);
GfxImage* normalMap = nullptr; GfxImage* specularMap = GetMaterialSpecularMap(material);
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;
}
}
if (colorMap != nullptr) if (colorMap != nullptr)
mtl.colorMapName = colorMap->name; mtl.colorMapName = colorMap->name;
@ -249,16 +301,9 @@ void AssetDumperXModel::AddXModelMaterials(AbstractXModelWriter& writer, Distinc
xMaterial.ApplyDefaults(); xMaterial.ApplyDefaults();
xMaterial.name = material->info.name; xMaterial.name = material->info.name;
const auto* colorMap = GetMaterialColorMap(material);
for (auto textureIndex = 0; textureIndex < material->textureCount; textureIndex++) if (colorMap)
{ xMaterial.colorMapName = std::string(colorMap->name);
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;
}
}
writer.AddMaterial(std::move(xMaterial)); writer.AddMaterial(std::move(xMaterial));
} }

View File

@ -10,6 +10,10 @@ namespace IW5
{ {
class AssetDumperXModel final : public AbstractAssetDumper<XModel> class AssetDumperXModel final : public AbstractAssetDumper<XModel>
{ {
static GfxImage* GetMaterialColorMap(const Material* material);
static GfxImage* GetMaterialNormalMap(const Material* material);
static GfxImage* GetMaterialSpecularMap(const Material* material);
static void AddObjMaterials(ObjWriter& writer, DistinctMapper<Material*>& materialMapper, const XModel* model); static void AddObjMaterials(ObjWriter& writer, DistinctMapper<Material*>& materialMapper, const XModel* model);
static void AddObjObjects(ObjWriter& writer, const DistinctMapper<Material*>& materialMapper, const XModelSurfs* modelSurfs, int baseSurfaceIndex); static void AddObjObjects(ObjWriter& writer, const DistinctMapper<Material*>& materialMapper, const XModelSurfs* modelSurfs, int baseSurfaceIndex);
static void AddObjVertices(ObjWriter& writer, const XModelSurfs* modelSurfs); static void AddObjVertices(ObjWriter& writer, const XModelSurfs* modelSurfs);