mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
Add material dumping debug switches
This commit is contained in:
parent
cd34f8db39
commit
353ad52eba
@ -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)},
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user