From 353ad52ebae616ab0adb248e68434decf21afe98 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 23 Apr 2022 16:41:30 +0200 Subject: [PATCH] Add material dumping debug switches --- .../IW3/AssetDumpers/AssetDumperMaterial.cpp | 16 ++- .../IW4/AssetDumpers/AssetDumperMaterial.cpp | 115 ++++++++++++------ 2 files changed, 94 insertions(+), 37 deletions(-) diff --git a/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperMaterial.cpp b/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperMaterial.cpp index edc6e01d..f5444b1e 100644 --- a/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperMaterial.cpp +++ b/src/ObjWriting/Game/IW3/AssetDumpers/AssetDumperMaterial.cpp @@ -7,6 +7,8 @@ #include "Game/IW3/MaterialConstantsIW3.h" #include "Game/IW3/TechsetConstantsIW3.h" +#define FLAGS_DEBUG 1 + using namespace IW3; using json = nlohmann::json; @@ -354,7 +356,7 @@ namespace IW3 return json(ss.str()); } - json BuildGameFlagsJson(const unsigned char gameFlags) + json BuildCharFlagsJson(const std::string& prefix, const unsigned char gameFlags) { std::vector values; @@ -363,7 +365,7 @@ namespace IW3 if (gameFlags & (1 << i)) { std::ostringstream ss; - ss << "0x" << std::hex << (1 << i); + ss << prefix << " 0x" << std::hex << (1 << i); values.emplace_back(ss.str()); } } @@ -444,7 +446,11 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfoinfo.gameFlags)}, // TODO: Find out what gameflags mean +#if defined(FLAGS_DEBUG) && FLAGS_DEBUG == 1 + {"gameFlags", BuildCharFlagsJson("gameFlag", material->info.gameFlags)}, // TODO: Find out what gameflags mean +#else + {"gameFlags", material->info.gameFlags}, // TODO: Find out what gameflags mean +#endif {"sortKey", foundSortKeyName != sortKeyNames.end() ? foundSortKeyName->second : std::to_string(material->info.sortKey)}, {"textureAtlasRowCount", material->info.textureAtlasRowCount}, {"textureAtlasColumnCount", material->info.textureAtlasColumnCount}, @@ -465,7 +471,11 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfostateBitsEntry), std::end(material->stateBitsEntry))}, +#if defined(FLAGS_DEBUG) && FLAGS_DEBUG == 1 + {"stateFlags", BuildCharFlagsJson("stateFlag", material->stateFlags)}, +#else {"stateFlags", material->stateFlags}, +#endif {"cameraRegion", ArrayEntry(cameraRegionNames, material->cameraRegion)}, {"techniqueSet", material->techniqueSet && material->techniqueSet->name ? AssetName(material->techniqueSet->name) : nullptr}, {"textureTable", BuildTextureTableJson(material->textureTable, material->textureCount)}, diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp index 1debf830..b9810c3d 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMaterial.cpp @@ -5,16 +5,18 @@ #include #include +#include "Utils/ClassUtils.h" #include "Game/IW4/MaterialConstantsIW4.h" #include "Game/IW4/TechsetConstantsIW4.h" +#define DUMP_AS_GDT 1 +#define FLAGS_DEBUG 1 + using namespace IW4; using json = nlohmann::json; namespace IW4 { - static constexpr auto DUMP_AS_GDT = true; - const char* AssetName(const char* name) { if (name && name[0] == ',') @@ -159,7 +161,7 @@ namespace IW4 return jArray; } - json BuildConstantTableJson(MaterialConstantDef* constantTable, const size_t count) + json BuildConstantTableJson(const MaterialConstantDef* constantTable, const size_t count) { auto jArray = json::array(); @@ -210,7 +212,7 @@ namespace IW4 return jArray; } - json BuildStateBitsTableJson(GfxStateBits* stateBitsTable, const size_t count) + json BuildStateBitsTableJson(const GfxStateBits* stateBitsTable, const size_t count) { static const char* blendNames[] { @@ -350,7 +352,7 @@ namespace IW4 std::string CreateSurfaceTypeString(const unsigned surfaceTypeBits) { if (!surfaceTypeBits) - return surfaceTypeNames[SURF_TYPE_DEFAULT]; + return ""; static constexpr auto NON_SURFACE_TYPE_BITS = ~(std::numeric_limits::max() >> ((sizeof(unsigned) * 8) - (static_cast(SURF_TYPE_NUM) - 1))); assert((surfaceTypeBits & NON_SURFACE_TYPE_BITS) == 0); @@ -370,7 +372,7 @@ namespace IW4 } if (firstSurfaceType) - return surfaceTypeNames[SURF_TYPE_DEFAULT]; + return ""; return ss.str(); } @@ -389,7 +391,11 @@ namespace IW4 const json j = { { "info", { +#if defined(FLAGS_DEBUG) && FLAGS_DEBUG == 1 {"gameFlags", BuildCharFlagsJson("gameFlag", material->info.gameFlags)}, // TODO: Find out what gameflags mean +#else + {"gameFlags", material->info.gameFlags}, // TODO: Find out what gameflags mean +#endif {"sortKey", material->info.sortKey}, {"textureAtlasRowCount", material->info.textureAtlasRowCount}, {"textureAtlasColumnCount", material->info.textureAtlasColumnCount}, @@ -412,7 +418,11 @@ namespace IW4 } }, {"stateBitsEntry", std::vector(std::begin(material->stateBitsEntry), std::end(material->stateBitsEntry))}, +#if defined(FLAGS_DEBUG) && FLAGS_DEBUG == 1 {"stateFlags", BuildCharFlagsJson("stateFlag", material->stateFlags)}, +#else + {"stateFlags", material->stateFlags}, +#endif {"cameraRegion", ArrayEntry(cameraRegionNames, material->cameraRegion)}, {"techniqueSet", material->techniqueSet && material->techniqueSet->name ? AssetName(material->techniqueSet->name) : nullptr}, {"textureTable", BuildTextureTableJson(material->textureTable, material->textureCount)}, @@ -426,6 +436,7 @@ namespace IW4 class MaterialGdtDumper { std::ostream& m_stream; + const Material* m_material; GdtEntry m_entry; void SetValue(const std::string& key, std::string value) @@ -433,6 +444,13 @@ namespace IW4 m_entry.m_properties.emplace(std::make_pair(key, std::move(value))); } + void SetValue(const std::string& key, const float (&value)[4]) + { + std::ostringstream ss; + ss << value[0] << " " << value[1] << " " << value[2] << " " << value[3]; + m_entry.m_properties.emplace(std::make_pair(key, ss.str())); + } + template , T>> void SetValue(const std::string& key, T value) @@ -440,29 +458,55 @@ namespace IW4 m_entry.m_properties.emplace(std::make_pair(key, std::to_string(value))); } - void SetCommonValues(const Material* material) + _NODISCARD int FindConstant(const std::string& constantName) const { - SetValue("textureAtlasRowCount", material->info.textureAtlasRowCount); - SetValue("textureAtlasColumnCount", material->info.textureAtlasColumnCount); - SetValue("surfaceType", CreateSurfaceTypeString(material->info.surfaceTypeBits)); + const auto constantHash = Common::R_HashString(constantName.c_str(), 0u); + + if (m_material->constantTable) + { + for (auto i = 0; i < m_material->constantCount; i++) + { + if (m_material->constantTable[i].nameHash == constantHash) + return i; + } + } + + return -1; + } + + void SetConstantValues(const Material* material) + { + const auto colorTintIndex = FindConstant("colorTint"); + if (colorTintIndex >= 0) + SetValue("colorTint", material->constantTable[colorTintIndex].literal); + } + + void SetCommonValues() + { + SetValue("textureAtlasRowCount", m_material->info.textureAtlasRowCount); + SetValue("textureAtlasColumnCount", m_material->info.textureAtlasColumnCount); + SetValue("surfaceType", CreateSurfaceTypeString(m_material->info.surfaceTypeBits)); } public: - explicit MaterialGdtDumper(std::ostream& stream) - : m_stream(stream) + explicit MaterialGdtDumper(std::ostream& stream, const Material* material) + : m_stream(stream), + m_material(material) { m_entry.m_gdf_name = "material.gdf"; + m_entry.m_name = m_material->info.name; } - void Dump(const Material* material) + void CreateGdtEntry() { - m_entry.m_name = material->info.name; - SetCommonValues(material); + SetCommonValues(); + } + void Dump() + { Gdt gdt(GdtVersion("IW4", 1)); gdt.m_entries.emplace_back(std::make_unique(std::move(m_entry))); - GdtOutputStream::WriteGdt(gdt, m_stream); } }; @@ -477,24 +521,27 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfoAsset(); - std::ostringstream ss; - if (DUMP_AS_GDT) - ss << "materials/" << asset->m_name << ".gdt"; - else - ss << "materials/" << asset->m_name << ".json"; - - const auto assetFile = context.OpenAssetFile(ss.str()); - - if (!assetFile) - return; - - auto& stream = *assetFile; - - if (DUMP_AS_GDT) { - MaterialGdtDumper dumper(stream); - dumper.Dump(material); - } - else + std::ostringstream ss; + ss << "materials/" << asset->m_name << ".json"; + const auto assetFile = context.OpenAssetFile(ss.str()); + if (!assetFile) + return; + auto& stream = *assetFile; DumpMaterialAsJson(material, stream); + } + +#if defined(DUMP_AS_GDT) && DUMP_AS_GDT == 1 + { + std::ostringstream ss; + ss << "materials/" << asset->m_name << ".gdt"; + const auto assetFile = context.OpenAssetFile(ss.str()); + if (!assetFile) + return; + auto& stream = *assetFile; + MaterialGdtDumper dumper(stream, material); + dumper.CreateGdtEntry(); + dumper.Dump(); + } +#endif }