From 0736b8043b7b6a3377cecddfbe609926a388a7dd Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 24 Jun 2025 22:26:39 +0100 Subject: [PATCH] refactor: use templates for JsonMaterialDumper of IW5 and T6 --- src/Common/Game/T6/T6_Assets.h | 6 +- .../Game/T6/{Json => Material}/JsonMaterial.h | 0 .../IW5/AssetDumpers/AssetDumperMaterial.cpp | 4 +- .../Game/IW5/Material/JsonMaterialWriter.h | 11 - .../T6/AssetDumpers/AssetDumperMaterial.cpp | 4 +- .../Game/T6/Material/JsonMaterialWriter.cpp | 250 ------------------ .../Game/T6/Material/JsonMaterialWriter.h | 11 - .../JsonMaterialWriter.cpp.template} | 82 +++++- .../Material/JsonMaterialWriter.h.template | 20 ++ 9 files changed, 96 insertions(+), 292 deletions(-) rename src/ObjCommon/Game/T6/{Json => Material}/JsonMaterial.h (100%) delete mode 100644 src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.h delete mode 100644 src/ObjWriting/Game/T6/Material/JsonMaterialWriter.cpp delete mode 100644 src/ObjWriting/Game/T6/Material/JsonMaterialWriter.h rename src/ObjWriting/{Game/IW5/Material/JsonMaterialWriter.cpp => Material/JsonMaterialWriter.cpp.template} (84%) create mode 100644 src/ObjWriting/Material/JsonMaterialWriter.h.template diff --git a/src/Common/Game/T6/T6_Assets.h b/src/Common/Game/T6/T6_Assets.h index 4eec23ae..62f3f300 100644 --- a/src/Common/Game/T6/T6_Assets.h +++ b/src/Common/Game/T6/T6_Assets.h @@ -2929,9 +2929,9 @@ namespace T6 enum GfxCullFace_e { - GFXS0_CULL_NONE = 1, - GFXS0_CULL_BACK = 2, - GFXS0_CULL_FRONT = 3, + GFXS_CULL_NONE = 1, + GFXS_CULL_BACK = 2, + GFXS_CULL_FRONT = 3, }; enum GfxDepthTest_e diff --git a/src/ObjCommon/Game/T6/Json/JsonMaterial.h b/src/ObjCommon/Game/T6/Material/JsonMaterial.h similarity index 100% rename from src/ObjCommon/Game/T6/Json/JsonMaterial.h rename to src/ObjCommon/Game/T6/Material/JsonMaterial.h diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperMaterial.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperMaterial.cpp index c4efb8f9..d564ba93 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperMaterial.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperMaterial.cpp @@ -1,6 +1,6 @@ #include "AssetDumperMaterial.h" -#include "Game/IW5/Material/JsonMaterialWriter.h" +#include "Game/IW5/Material/JsonMaterialWriterIW5.h" #include "Game/IW5/Material/MaterialConstantZoneState.h" #include @@ -36,7 +36,7 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfoAsset(), context); + DumpMaterialAsJson(*assetFile, *asset->Asset(), context); } void AssetDumperMaterial::DumpPool(AssetDumpingContext& context, AssetPool* pool) diff --git a/src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.h b/src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.h deleted file mode 100644 index c7869286..00000000 --- a/src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "Dumping/AssetDumpingContext.h" -#include "Game/IW5/IW5.h" - -#include - -namespace IW5 -{ - void DumpMaterialAsJson(std::ostream& stream, const Material* material, AssetDumpingContext& context); -} // namespace IW5 diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperMaterial.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperMaterial.cpp index b967a41e..169458c8 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperMaterial.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperMaterial.cpp @@ -1,6 +1,6 @@ #include "AssetDumperMaterial.h" -#include "Game/T6/Material/JsonMaterialWriter.h" +#include "Game/T6/Material/JsonMaterialWriterT6.h" #include "Game/T6/Material/MaterialConstantZoneState.h" #include @@ -36,7 +36,7 @@ void AssetDumperMaterial::DumpAsset(AssetDumpingContext& context, XAssetInfoAsset(), context); + DumpMaterialAsJson(*assetFile, *asset->Asset(), context); } void AssetDumperMaterial::DumpPool(AssetDumpingContext& context, AssetPool* pool) diff --git a/src/ObjWriting/Game/T6/Material/JsonMaterialWriter.cpp b/src/ObjWriting/Game/T6/Material/JsonMaterialWriter.cpp deleted file mode 100644 index 194626ba..00000000 --- a/src/ObjWriting/Game/T6/Material/JsonMaterialWriter.cpp +++ /dev/null @@ -1,250 +0,0 @@ -#include "JsonMaterialWriter.h" - -#include "Game/T6/CommonT6.h" -#include "Game/T6/Json/JsonMaterial.h" -#include "MaterialConstantZoneState.h" - -#include -#include - -using namespace nlohmann; -using namespace T6; - -namespace -{ - class JsonDumper - { - public: - JsonDumper(AssetDumpingContext& context, std::ostream& stream) - : m_stream(stream), - m_material_constants(*context.GetZoneAssetDumperState()) - { - } - - void Dump(const Material* material) const - { - JsonMaterial jsonMaterial; - CreateJsonMaterial(jsonMaterial, *material); - json jRoot = jsonMaterial; - - jRoot["_type"] = "material"; - jRoot["_version"] = 1; - jRoot["_game"] = "t6"; - - m_stream << std::setw(4) << jRoot << "\n"; - } - - private: - static const char* AssetName(const char* input) - { - if (input && input[0] == ',') - return &input[1]; - - return input; - } - - static void CreateJsonGameFlags(JsonMaterial& jMaterial, const unsigned gameFlags) - { - jMaterial.gameFlags.clear(); - for (auto i = 0u; i < sizeof(gameFlags) * 8u; i++) - { - const auto flag = static_cast(1 << i); - - if (gameFlags & flag) - jMaterial.gameFlags.emplace_back(flag); - } - } - - static void CreateJsonSamplerState(JsonSamplerState& jSamplerState, const MaterialTextureDefSamplerState& samplerState) - { - jSamplerState.filter = static_cast(samplerState.filter); - jSamplerState.mipMap = static_cast(samplerState.mipMap); - jSamplerState.clampU = samplerState.clampU; - jSamplerState.clampV = samplerState.clampV; - jSamplerState.clampW = samplerState.clampW; - } - - void CreateJsonTexture(JsonTexture& jTextureDef, const MaterialTextureDef& textureDef) const - { - std::string textureDefName; - if (m_material_constants.GetTextureDefName(textureDef.nameHash, textureDefName)) - { - jTextureDef.name = textureDefName; - } - else - { - jTextureDef.nameHash = textureDef.nameHash; - jTextureDef.nameStart = std::string(1u, textureDef.nameStart); - jTextureDef.nameEnd = std::string(1u, textureDef.nameEnd); - } - - jTextureDef.semantic = static_cast(textureDef.semantic); - jTextureDef.isMatureContent = textureDef.isMatureContent; - - CreateJsonSamplerState(jTextureDef.samplerState, textureDef.samplerState); - - if (textureDef.image && textureDef.image->name) - jTextureDef.image = AssetName(textureDef.image->name); - } - - void CreateJsonConstant(JsonConstant& jConstantDef, const MaterialConstantDef& constantDef) const - { - const auto fragmentLength = strnlen(constantDef.name, std::extent_v); - const std::string nameFragment(constantDef.name, fragmentLength); - std::string knownConstantName; - - if (fragmentLength < std::extent_v || Common::R_HashString(nameFragment.c_str(), 0) == constantDef.nameHash) - { - jConstantDef.name = nameFragment; - } - else if (m_material_constants.GetConstantName(constantDef.nameHash, knownConstantName)) - { - jConstantDef.name = knownConstantName; - } - else - { - jConstantDef.nameHash = constantDef.nameHash; - jConstantDef.nameFragment = nameFragment; - } - - jConstantDef.literal = std::vector({ - constantDef.literal.x, - constantDef.literal.y, - constantDef.literal.z, - constantDef.literal.w, - }); - } - - static void CreateJsonStencil(JsonStencil& jStencil, const unsigned pass, const unsigned fail, const unsigned zFail, const unsigned func) - { - jStencil.pass = static_cast(pass); - jStencil.fail = static_cast(fail); - jStencil.zfail = static_cast(zFail); - jStencil.func = static_cast(func); - } - - static void CreateJsonStateBitsTableEntry(JsonStateBitsTableEntry& jStateBitsTableEntry, const GfxStateBitsTable& stateBitsTableEntry) - { - const auto& structured = stateBitsTableEntry.loadBits.structured; - - jStateBitsTableEntry.srcBlendRgb = static_cast(structured.srcBlendRgb); - jStateBitsTableEntry.dstBlendRgb = static_cast(structured.dstBlendRgb); - jStateBitsTableEntry.blendOpRgb = static_cast(structured.blendOpRgb); - - assert(structured.alphaTestDisabled || structured.alphaTest == GFXS_ALPHA_TEST_GT_0 || structured.alphaTest == GFXS_ALPHA_TEST_GE_128); - if (structured.alphaTestDisabled) - jStateBitsTableEntry.alphaTest = JsonAlphaTest::DISABLED; - else if (structured.alphaTest == GFXS_ALPHA_TEST_GT_0) - jStateBitsTableEntry.alphaTest = JsonAlphaTest::GT0; - else if (structured.alphaTest == GFXS_ALPHA_TEST_GE_128) - jStateBitsTableEntry.alphaTest = JsonAlphaTest::GE128; - else - jStateBitsTableEntry.alphaTest = JsonAlphaTest::INVALID; - - assert(structured.cullFace == GFXS0_CULL_NONE || structured.cullFace == GFXS0_CULL_BACK || structured.cullFace == GFXS0_CULL_FRONT); - if (structured.cullFace == GFXS0_CULL_NONE) - jStateBitsTableEntry.cullFace = JsonCullFace::NONE; - else if (structured.cullFace == GFXS0_CULL_BACK) - jStateBitsTableEntry.cullFace = JsonCullFace::BACK; - else if (structured.cullFace == GFXS0_CULL_FRONT) - jStateBitsTableEntry.cullFace = JsonCullFace::FRONT; - else - jStateBitsTableEntry.cullFace = JsonCullFace::INVALID; - - jStateBitsTableEntry.srcBlendAlpha = static_cast(structured.srcBlendAlpha); - jStateBitsTableEntry.dstBlendAlpha = static_cast(structured.dstBlendAlpha); - jStateBitsTableEntry.blendOpAlpha = static_cast(structured.blendOpAlpha); - jStateBitsTableEntry.colorWriteRgb = structured.colorWriteRgb; - jStateBitsTableEntry.colorWriteAlpha = structured.colorWriteAlpha; - jStateBitsTableEntry.polymodeLine = structured.polymodeLine; - jStateBitsTableEntry.depthWrite = structured.depthWrite; - - assert(structured.depthTestDisabled || structured.depthTest == GFXS_DEPTHTEST_ALWAYS || structured.depthTest == GFXS_DEPTHTEST_LESS - || structured.depthTest == GFXS_DEPTHTEST_EQUAL || structured.depthTest == GFXS_DEPTHTEST_LESSEQUAL); - if (structured.depthTestDisabled) - jStateBitsTableEntry.depthTest = JsonDepthTest::DISABLED; - else if (structured.depthTest == GFXS_DEPTHTEST_ALWAYS) - jStateBitsTableEntry.depthTest = JsonDepthTest::ALWAYS; - else if (structured.depthTest == GFXS_DEPTHTEST_LESS) - jStateBitsTableEntry.depthTest = JsonDepthTest::LESS; - else if (structured.depthTest == GFXS_DEPTHTEST_EQUAL) - jStateBitsTableEntry.depthTest = JsonDepthTest::EQUAL; - else if (structured.depthTest == GFXS_DEPTHTEST_LESSEQUAL) - jStateBitsTableEntry.depthTest = JsonDepthTest::LESS_EQUAL; - else - jStateBitsTableEntry.depthTest = JsonDepthTest::INVALID; - - jStateBitsTableEntry.polygonOffset = static_cast(structured.polygonOffset); - - if (structured.stencilFrontEnabled) - { - JsonStencil jStencilFront; - CreateJsonStencil( - jStencilFront, structured.stencilFrontPass, structured.stencilFrontFail, structured.stencilFrontZFail, structured.stencilFrontFunc); - jStateBitsTableEntry.stencilFront = jStencilFront; - } - - if (structured.stencilBackEnabled) - { - JsonStencil jStencilBack; - CreateJsonStencil( - jStencilBack, structured.stencilBackPass, structured.stencilBackFail, structured.stencilBackZFail, structured.stencilBackFunc); - jStateBitsTableEntry.stencilBack = jStencilBack; - } - } - - void CreateJsonMaterial(JsonMaterial& jMaterial, const Material& material) const - { - CreateJsonGameFlags(jMaterial, material.info.gameFlags); - jMaterial.sortKey = material.info.sortKey; - - jMaterial.textureAtlas = JsonTextureAtlas(); - jMaterial.textureAtlas->rows = material.info.textureAtlasRowCount; - jMaterial.textureAtlas->columns = material.info.textureAtlasColumnCount; - - jMaterial.surfaceTypeBits = material.info.surfaceTypeBits; - jMaterial.layeredSurfaceTypes = material.info.layeredSurfaceTypes; - jMaterial.hashIndex = material.info.hashIndex; - jMaterial.surfaceFlags = material.info.surfaceFlags; - jMaterial.contents = material.info.contents; - - jMaterial.stateBitsEntry.resize(std::extent_v); - for (auto i = 0u; i < std::extent_v; i++) - jMaterial.stateBitsEntry[i] = material.stateBitsEntry[i]; - - jMaterial.stateFlags = material.stateFlags; - jMaterial.cameraRegion = static_cast(material.cameraRegion); - jMaterial.probeMipBits = material.probeMipBits; - - if (material.techniqueSet && material.techniqueSet->name) - jMaterial.techniqueSet = AssetName(material.techniqueSet->name); - - jMaterial.textures.resize(material.textureCount); - for (auto i = 0u; i < material.textureCount; i++) - CreateJsonTexture(jMaterial.textures[i], material.textureTable[i]); - - jMaterial.constants.resize(material.constantCount); - for (auto i = 0u; i < material.constantCount; i++) - CreateJsonConstant(jMaterial.constants[i], material.constantTable[i]); - - jMaterial.stateBits.resize(material.stateBitsCount); - for (auto i = 0u; i < material.stateBitsCount; i++) - CreateJsonStateBitsTableEntry(jMaterial.stateBits[i], material.stateBitsTable[i]); - - if (material.thermalMaterial && material.thermalMaterial->info.name) - jMaterial.thermalMaterial = AssetName(material.thermalMaterial->info.name); - } - - std::ostream& m_stream; - const MaterialConstantZoneState& m_material_constants; - }; -} // namespace - -namespace T6 -{ - void DumpMaterialAsJson(std::ostream& stream, const Material* material, AssetDumpingContext& context) - { - const JsonDumper dumper(context, stream); - dumper.Dump(material); - } -} // namespace T6 diff --git a/src/ObjWriting/Game/T6/Material/JsonMaterialWriter.h b/src/ObjWriting/Game/T6/Material/JsonMaterialWriter.h deleted file mode 100644 index ac012e4f..00000000 --- a/src/ObjWriting/Game/T6/Material/JsonMaterialWriter.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "Dumping/AssetDumpingContext.h" -#include "Game/T6/T6.h" - -#include - -namespace T6 -{ - void DumpMaterialAsJson(std::ostream& stream, const Material* material, AssetDumpingContext& context); -} // namespace T6 diff --git a/src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.cpp b/src/ObjWriting/Material/JsonMaterialWriter.cpp.template similarity index 84% rename from src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.cpp rename to src/ObjWriting/Material/JsonMaterialWriter.cpp.template index f5cf4884..9c14304f 100644 --- a/src/ObjWriting/Game/IW5/Material/JsonMaterialWriter.cpp +++ b/src/ObjWriting/Material/JsonMaterialWriter.cpp.template @@ -1,15 +1,39 @@ -#include "JsonMaterialWriter.h" +#options GAME (IW5, T6) +#filename "Game/" + GAME + "/Material/JsonMaterialWriter" + GAME + ".cpp" + +#if GAME == "IW5" +#define FEATURE_IW5 +#define HAS_WATER +#define GAME_LOWER "iw5" +#elif GAME == "T6" +#define FEATURE_T6 +#define GAME_LOWER "t6" +#endif + +// This file was templated. +// See JsonMaterialWriter.h.template. +// Do not modify, changes will be lost. + +#set WRITER_HEADER "\"JsonMaterialWriter" + GAME + ".h\"" +#include WRITER_HEADER + +#ifdef HAS_WATER #include "Base64.h" -#include "Game/IW5/CommonIW5.h" -#include "Game/IW5/Material/JsonMaterial.h" -#include "MaterialConstantZoneState.h" +#endif + +#set COMMON_HEADER "\"Game/" + GAME + "/Common" + GAME + ".h\"" +#include COMMON_HEADER +#set JSON_HEADER "\"Game/" + GAME + "/Material/JsonMaterial.h\"" +#include JSON_HEADER +#set CONSTANTS_HEADER "\"Game/" + GAME + "/Material/MaterialConstantZoneState.h\"" +#include CONSTANTS_HEADER #include #include using namespace nlohmann; -using namespace IW5; +using namespace GAME; namespace { @@ -22,15 +46,15 @@ namespace { } - void Dump(const Material* material) const + void Dump(const Material& material) const { JsonMaterial jsonMaterial; - CreateJsonMaterial(jsonMaterial, *material); + CreateJsonMaterial(jsonMaterial, material); json jRoot = jsonMaterial; jRoot["_type"] = "material"; jRoot["_version"] = 1; - jRoot["_game"] = "iw5"; + jRoot["_game"] = GAME_LOWER; m_stream << std::setw(4) << jRoot << "\n"; } @@ -65,6 +89,7 @@ namespace jSamplerState.clampW = samplerState.clampW; } +#ifdef HAS_WATER static void CreateJsonWater(JsonWater& jWater, const water_t& water) { jWater.floatTime = water.writable.floatTime; @@ -94,6 +119,7 @@ namespace jWater.wTerm = base64::EncodeBase64(water.wTerm, sizeof(float) * count); } } +#endif void CreateJsonTexture(JsonTexture& jTextureDef, const MaterialTextureDef& textureDef) const { @@ -110,9 +136,13 @@ namespace } jTextureDef.semantic = static_cast(textureDef.semantic); +#if defined(FEATURE_T6) + jTextureDef.isMatureContent = textureDef.isMatureContent; +#endif CreateJsonSamplerState(jTextureDef.samplerState, textureDef.samplerState); +#ifdef HAS_WATER if (textureDef.semantic == TS_WATER_MAP) { if (textureDef.u.water) @@ -132,6 +162,10 @@ namespace if (textureDef.u.image && textureDef.u.image->name) jTextureDef.image = AssetName(textureDef.u.image->name); } +#else + if (textureDef.image && textureDef.image->name) + jTextureDef.image = AssetName(textureDef.image->name); +#endif } void CreateJsonConstant(JsonConstant& jConstantDef, const MaterialConstantDef& constantDef) const @@ -178,14 +212,20 @@ namespace jStateBitsTableEntry.dstBlendRgb = static_cast(structured.dstBlendRgb); jStateBitsTableEntry.blendOpRgb = static_cast(structured.blendOpRgb); - assert(structured.alphaTestDisabled || structured.alphaTest == GFXS_ALPHA_TEST_GT_0 || structured.alphaTest == GFXS_ALPHA_TEST_LT_128 - || structured.alphaTest == GFXS_ALPHA_TEST_GE_128); + assert(structured.alphaTestDisabled + || structured.alphaTest == GFXS_ALPHA_TEST_GT_0 +#ifdef FEATURE_IW5 + || structured.alphaTest == GFXS_ALPHA_TEST_LT_128 +#endif + || structured.alphaTest == GFXS_ALPHA_TEST_GE_128); if (structured.alphaTestDisabled) jStateBitsTableEntry.alphaTest = JsonAlphaTest::DISABLED; else if (structured.alphaTest == GFXS_ALPHA_TEST_GT_0) jStateBitsTableEntry.alphaTest = JsonAlphaTest::GT0; +#ifdef FEATURE_IW5 else if (structured.alphaTest == GFXS_ALPHA_TEST_LT_128) jStateBitsTableEntry.alphaTest = JsonAlphaTest::LT128; +#endif else if (structured.alphaTest == GFXS_ALPHA_TEST_GE_128) jStateBitsTableEntry.alphaTest = JsonAlphaTest::GE128; else @@ -206,7 +246,9 @@ namespace jStateBitsTableEntry.blendOpAlpha = static_cast(structured.blendOpAlpha); jStateBitsTableEntry.colorWriteRgb = structured.colorWriteRgb; jStateBitsTableEntry.colorWriteAlpha = structured.colorWriteAlpha; +#ifdef FEATURE_IW5 jStateBitsTableEntry.gammaWrite = structured.gammaWrite; +#endif jStateBitsTableEntry.polymodeLine = structured.polymodeLine; jStateBitsTableEntry.depthWrite = structured.depthWrite; @@ -254,6 +296,12 @@ namespace jMaterial.textureAtlas->columns = material.info.textureAtlasColumnCount; jMaterial.surfaceTypeBits = material.info.surfaceTypeBits; +#ifdef FEATURE_T6 + jMaterial.layeredSurfaceTypes = material.info.layeredSurfaceTypes; + jMaterial.hashIndex = material.info.hashIndex; + jMaterial.surfaceFlags = material.info.surfaceFlags; + jMaterial.contents = material.info.contents; +#endif jMaterial.stateBitsEntry.resize(std::extent_v); for (auto i = 0u; i < std::extent_v; i++) @@ -261,6 +309,9 @@ namespace jMaterial.stateFlags = material.stateFlags; jMaterial.cameraRegion = static_cast(material.cameraRegion); +#ifdef FEATURE_T6 + jMaterial.probeMipBits = material.probeMipBits; +#endif if (material.techniqueSet && material.techniqueSet->name) jMaterial.techniqueSet = AssetName(material.techniqueSet->name); @@ -276,6 +327,11 @@ namespace jMaterial.stateBits.resize(material.stateBitsCount); for (auto i = 0u; i < material.stateBitsCount; i++) CreateJsonStateBitsTableEntry(jMaterial.stateBits[i], material.stateBitsTable[i]); + +#ifdef FEATURE_T6 + if (material.thermalMaterial && material.thermalMaterial->info.name) + jMaterial.thermalMaterial = AssetName(material.thermalMaterial->info.name); +#endif } std::ostream& m_stream; @@ -283,11 +339,11 @@ namespace }; } // namespace -namespace IW5 +namespace GAME { - void DumpMaterialAsJson(std::ostream& stream, const Material* material, AssetDumpingContext& context) + void DumpMaterialAsJson(std::ostream& stream, const Material& material, AssetDumpingContext& context) { const JsonDumper dumper(context, stream); dumper.Dump(material); } -} // namespace IW5 +} // namespace GAME diff --git a/src/ObjWriting/Material/JsonMaterialWriter.h.template b/src/ObjWriting/Material/JsonMaterialWriter.h.template new file mode 100644 index 00000000..cbc6d0a4 --- /dev/null +++ b/src/ObjWriting/Material/JsonMaterialWriter.h.template @@ -0,0 +1,20 @@ +#options GAME (IW5, T6) + +#filename "Game/" + GAME + "/Material/JsonMaterialWriter" + GAME + ".h" + +// This file was templated. +// See JsonMaterialWriter.h.template. +// Do not modify, changes will be lost. + +#pragma once + +#include "Dumping/AssetDumpingContext.h" +#set GAME_HEADER "\"Game/" + GAME + "/" + GAME + ".h\"" +#include GAME_HEADER + +#include + +namespace GAME +{ + void DumpMaterialAsJson(std::ostream& stream, const Material& material, AssetDumpingContext& context); +} // namespace GAME