Add material dumping debug switches

This commit is contained in:
Jan 2022-04-23 16:41:30 +02:00
parent cd34f8db39
commit 353ad52eba
2 changed files with 94 additions and 37 deletions

View File

@ -7,6 +7,8 @@
#include "Game/IW3/MaterialConstantsIW3.h" #include "Game/IW3/MaterialConstantsIW3.h"
#include "Game/IW3/TechsetConstantsIW3.h" #include "Game/IW3/TechsetConstantsIW3.h"
#define FLAGS_DEBUG 1
using namespace IW3; using namespace IW3;
using json = nlohmann::json; using json = nlohmann::json;
@ -354,7 +356,7 @@ namespace IW3
return json(ss.str()); return json(ss.str());
} }
json BuildGameFlagsJson(const unsigned char gameFlags) json BuildCharFlagsJson(const std::string& prefix, const unsigned char gameFlags)
{ {
std::vector<std::string> values; std::vector<std::string> values;
@ -363,7 +365,7 @@ namespace IW3
if (gameFlags & (1 << i)) if (gameFlags & (1 << i))
{ {
std::ostringstream ss; std::ostringstream ss;
ss << "0x" << std::hex << (1 << i); ss << prefix << " 0x" << std::hex << (1 << i);
values.emplace_back(ss.str()); values.emplace_back(ss.str());
} }
} }
@ -444,7 +446,11 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfo<Mat
const json j = { const json j = {
{ {
"info", { "info", {
{"gameFlags", BuildGameFlagsJson(material->info.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)}, {"sortKey", foundSortKeyName != sortKeyNames.end() ? foundSortKeyName->second : std::to_string(material->info.sortKey)},
{"textureAtlasRowCount", material->info.textureAtlasRowCount}, {"textureAtlasRowCount", material->info.textureAtlasRowCount},
{"textureAtlasColumnCount", material->info.textureAtlasColumnCount}, {"textureAtlasColumnCount", material->info.textureAtlasColumnCount},
@ -465,7 +471,11 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfo<Mat
} }
}, },
{"stateBitsEntry", std::vector(std::begin(material->stateBitsEntry), std::end(material->stateBitsEntry))}, {"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}, {"stateFlags", material->stateFlags},
#endif
{"cameraRegion", ArrayEntry(cameraRegionNames, material->cameraRegion)}, {"cameraRegion", ArrayEntry(cameraRegionNames, material->cameraRegion)},
{"techniqueSet", material->techniqueSet && material->techniqueSet->name ? AssetName(material->techniqueSet->name) : nullptr}, {"techniqueSet", material->techniqueSet && material->techniqueSet->name ? AssetName(material->techniqueSet->name) : nullptr},
{"textureTable", BuildTextureTableJson(material->textureTable, material->textureCount)}, {"textureTable", BuildTextureTableJson(material->textureTable, material->textureCount)},

View File

@ -5,16 +5,18 @@
#include <type_traits> #include <type_traits>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include "Utils/ClassUtils.h"
#include "Game/IW4/MaterialConstantsIW4.h" #include "Game/IW4/MaterialConstantsIW4.h"
#include "Game/IW4/TechsetConstantsIW4.h" #include "Game/IW4/TechsetConstantsIW4.h"
#define DUMP_AS_GDT 1
#define FLAGS_DEBUG 1
using namespace IW4; using namespace IW4;
using json = nlohmann::json; using json = nlohmann::json;
namespace IW4 namespace IW4
{ {
static constexpr auto DUMP_AS_GDT = true;
const char* AssetName(const char* name) const char* AssetName(const char* name)
{ {
if (name && name[0] == ',') if (name && name[0] == ',')
@ -159,7 +161,7 @@ namespace IW4
return jArray; return jArray;
} }
json BuildConstantTableJson(MaterialConstantDef* constantTable, const size_t count) json BuildConstantTableJson(const MaterialConstantDef* constantTable, const size_t count)
{ {
auto jArray = json::array(); auto jArray = json::array();
@ -210,7 +212,7 @@ namespace IW4
return jArray; return jArray;
} }
json BuildStateBitsTableJson(GfxStateBits* stateBitsTable, const size_t count) json BuildStateBitsTableJson(const GfxStateBits* stateBitsTable, const size_t count)
{ {
static const char* blendNames[] static const char* blendNames[]
{ {
@ -350,7 +352,7 @@ namespace IW4
std::string CreateSurfaceTypeString(const unsigned surfaceTypeBits) std::string CreateSurfaceTypeString(const unsigned surfaceTypeBits)
{ {
if (!surfaceTypeBits) if (!surfaceTypeBits)
return surfaceTypeNames[SURF_TYPE_DEFAULT]; return "<none>";
static constexpr auto NON_SURFACE_TYPE_BITS = ~(std::numeric_limits<unsigned>::max() >> ((sizeof(unsigned) * 8) - (static_cast<unsigned>(SURF_TYPE_NUM) - 1))); static constexpr auto NON_SURFACE_TYPE_BITS = ~(std::numeric_limits<unsigned>::max() >> ((sizeof(unsigned) * 8) - (static_cast<unsigned>(SURF_TYPE_NUM) - 1)));
assert((surfaceTypeBits & NON_SURFACE_TYPE_BITS) == 0); assert((surfaceTypeBits & NON_SURFACE_TYPE_BITS) == 0);
@ -370,7 +372,7 @@ namespace IW4
} }
if (firstSurfaceType) if (firstSurfaceType)
return surfaceTypeNames[SURF_TYPE_DEFAULT]; return "<none>";
return ss.str(); return ss.str();
} }
@ -389,7 +391,11 @@ namespace IW4
const json j = { const json j = {
{ {
"info", { "info", {
#if defined(FLAGS_DEBUG) && FLAGS_DEBUG == 1
{"gameFlags", BuildCharFlagsJson("gameFlag", material->info.gameFlags)}, // TODO: Find out what gameflags mean {"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}, {"sortKey", material->info.sortKey},
{"textureAtlasRowCount", material->info.textureAtlasRowCount}, {"textureAtlasRowCount", material->info.textureAtlasRowCount},
{"textureAtlasColumnCount", material->info.textureAtlasColumnCount}, {"textureAtlasColumnCount", material->info.textureAtlasColumnCount},
@ -412,7 +418,11 @@ namespace IW4
} }
}, },
{"stateBitsEntry", std::vector(std::begin(material->stateBitsEntry), std::end(material->stateBitsEntry))}, {"stateBitsEntry", std::vector(std::begin(material->stateBitsEntry), std::end(material->stateBitsEntry))},
#if defined(FLAGS_DEBUG) && FLAGS_DEBUG == 1
{"stateFlags", BuildCharFlagsJson("stateFlag", material->stateFlags)}, {"stateFlags", BuildCharFlagsJson("stateFlag", material->stateFlags)},
#else
{"stateFlags", material->stateFlags},
#endif
{"cameraRegion", ArrayEntry(cameraRegionNames, material->cameraRegion)}, {"cameraRegion", ArrayEntry(cameraRegionNames, material->cameraRegion)},
{"techniqueSet", material->techniqueSet && material->techniqueSet->name ? AssetName(material->techniqueSet->name) : nullptr}, {"techniqueSet", material->techniqueSet && material->techniqueSet->name ? AssetName(material->techniqueSet->name) : nullptr},
{"textureTable", BuildTextureTableJson(material->textureTable, material->textureCount)}, {"textureTable", BuildTextureTableJson(material->textureTable, material->textureCount)},
@ -426,6 +436,7 @@ namespace IW4
class MaterialGdtDumper class MaterialGdtDumper
{ {
std::ostream& m_stream; std::ostream& m_stream;
const Material* m_material;
GdtEntry m_entry; GdtEntry m_entry;
void SetValue(const std::string& key, std::string value) 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))); 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 <typename T, template <typename T,
typename = typename std::enable_if_t<std::is_arithmetic_v<T>, T>> typename = typename std::enable_if_t<std::is_arithmetic_v<T>, T>>
void SetValue(const std::string& key, T value) 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))); 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); const auto constantHash = Common::R_HashString(constantName.c_str(), 0u);
SetValue("textureAtlasColumnCount", material->info.textureAtlasColumnCount);
SetValue("surfaceType", CreateSurfaceTypeString(material->info.surfaceTypeBits)); 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: public:
explicit MaterialGdtDumper(std::ostream& stream) explicit MaterialGdtDumper(std::ostream& stream, const Material* material)
: m_stream(stream) : m_stream(stream),
m_material(material)
{ {
m_entry.m_gdf_name = "material.gdf"; 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();
SetCommonValues(material); }
void Dump()
{
Gdt gdt(GdtVersion("IW4", 1)); Gdt gdt(GdtVersion("IW4", 1));
gdt.m_entries.emplace_back(std::make_unique<GdtEntry>(std::move(m_entry))); gdt.m_entries.emplace_back(std::make_unique<GdtEntry>(std::move(m_entry)));
GdtOutputStream::WriteGdt(gdt, m_stream); GdtOutputStream::WriteGdt(gdt, m_stream);
} }
}; };
@ -477,24 +521,27 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfo<Mat
{ {
auto* material = asset->Asset(); auto* material = asset->Asset();
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); std::ostringstream ss;
dumper.Dump(material); ss << "materials/" << asset->m_name << ".json";
} const auto assetFile = context.OpenAssetFile(ss.str());
else if (!assetFile)
return;
auto& stream = *assetFile;
DumpMaterialAsJson(material, stream); 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
} }