From 79b0706fc1fb86afcfa88cb809cfba7968c23a4f Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 25 Jun 2025 18:30:07 +0100 Subject: [PATCH] refactor: use templating for JsonMaterials --- src/ObjCommon.lua | 7 +- .../Game/IW5/Material/JsonMaterial.h | 391 ------------- src/ObjCommon/Game/T6/Material/JsonMaterial.h | 397 ------------- .../Material/JsonMaterial.h.template | 529 ++++++++++++++++++ src/ObjWriting.lua | 1 + .../Material/JsonMaterialWriter.cpp.template | 2 +- 6 files changed, 536 insertions(+), 791 deletions(-) delete mode 100644 src/ObjCommon/Game/IW5/Material/JsonMaterial.h delete mode 100644 src/ObjCommon/Game/T6/Material/JsonMaterial.h create mode 100644 src/ObjCommon/Material/JsonMaterial.h.template diff --git a/src/ObjCommon.lua b/src/ObjCommon.lua index bcbed0e1..d1e28826 100644 --- a/src/ObjCommon.lua +++ b/src/ObjCommon.lua @@ -7,7 +7,8 @@ function ObjCommon:include(includes) minizip:include(includes) Parser:include(includes) includedirs { - path.join(ProjectFolder(), "ObjCommon") + path.join(ProjectFolder(), "ObjCommon"), + "%{wks.location}/src/ObjCommon" } end end @@ -21,7 +22,7 @@ function ObjCommon:link(links) end function ObjCommon:use() - + dependson(self:name()) end function ObjCommon:name() @@ -48,6 +49,8 @@ function ObjCommon:project() path.join(folder, "ObjCommon") } } + + useSourceTemplating("ObjCommon") self:include(includes) Utils:include(includes) diff --git a/src/ObjCommon/Game/IW5/Material/JsonMaterial.h b/src/ObjCommon/Game/IW5/Material/JsonMaterial.h deleted file mode 100644 index b6dd0d25..00000000 --- a/src/ObjCommon/Game/IW5/Material/JsonMaterial.h +++ /dev/null @@ -1,391 +0,0 @@ -#pragma once - -#include "Game/IW5/IW5.h" - -#include "Json/JsonExtension.h" -#include -#include -#include -#include -#include - -namespace IW5 -{ - NLOHMANN_JSON_SERIALIZE_ENUM(GfxStencilOp, - { - {GFXS_STENCILOP_KEEP, "keep" }, - {GFXS_STENCILOP_ZERO, "zero" }, - {GFXS_STENCILOP_REPLACE, "replace"}, - {GFXS_STENCILOP_INCRSAT, "incrsat"}, - {GFXS_STENCILOP_DECRSAT, "decrsat"}, - {GFXS_STENCILOP_INVERT, "invert" }, - {GFXS_STENCILOP_INCR, "incr" }, - {GFXS_STENCILOP_DECR, "decr" }, - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(GfxStencilFunc, - { - {GFXS_STENCILFUNC_NEVER, "never" }, - {GFXS_STENCILFUNC_LESS, "less" }, - {GFXS_STENCILFUNC_EQUAL, "equal" }, - {GFXS_STENCILFUNC_LESSEQUAL, "lessequal" }, - {GFXS_STENCILFUNC_GREATER, "greater" }, - {GFXS_STENCILFUNC_NOTEQUAL, "notequal" }, - {GFXS_STENCILFUNC_GREATEREQUAL, "greaterequal"}, - {GFXS_STENCILFUNC_ALWAYS, "always" }, - }); - - class JsonStencil - { - public: - GfxStencilOp pass; - GfxStencilOp fail; - GfxStencilOp zfail; - GfxStencilFunc func; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStencil, pass, fail, zfail, func); - - enum class JsonAlphaTest - { - INVALID, - DISABLED, - GT0, - LT128, - GE128 - }; - - NLOHMANN_JSON_SERIALIZE_ENUM(JsonAlphaTest, - { - {JsonAlphaTest::INVALID, nullptr }, - {JsonAlphaTest::DISABLED, "disabled"}, - {JsonAlphaTest::GT0, "gt0" }, - {JsonAlphaTest::LT128, "lt128" }, - {JsonAlphaTest::GE128, "ge128" } - }); - - enum class JsonCullFace - { - INVALID, - NONE, - BACK, - FRONT - }; - - NLOHMANN_JSON_SERIALIZE_ENUM( - JsonCullFace, - { - {JsonCullFace::INVALID, nullptr}, - {JsonCullFace::NONE, "none" }, - {JsonCullFace::BACK, "back" }, - {JsonCullFace::FRONT, "front"} - }); - - enum class JsonDepthTest - { - INVALID, - DISABLED, - ALWAYS, - LESS, - EQUAL, - LESS_EQUAL - }; - - NLOHMANN_JSON_SERIALIZE_ENUM(JsonDepthTest, - { - {JsonDepthTest::INVALID, nullptr }, - {JsonDepthTest::DISABLED, "disabled" }, - {JsonDepthTest::ALWAYS, "always" }, - {JsonDepthTest::LESS, "less" }, - {JsonDepthTest::EQUAL, "equal" }, - {JsonDepthTest::LESS_EQUAL, "less_equal"} - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(GfxBlend, - { - {GFXS_BLEND_DISABLED, "disabled" }, - {GFXS_BLEND_ZERO, "zero" }, - {GFXS_BLEND_ONE, "one" }, - {GFXS_BLEND_SRCCOLOR, "srccolor" }, - {GFXS_BLEND_INVSRCCOLOR, "invsrccolor" }, - {GFXS_BLEND_SRCALPHA, "srcalpha" }, - {GFXS_BLEND_INVSRCALPHA, "invsrcalpha" }, - {GFXS_BLEND_DESTALPHA, "destalpha" }, - {GFXS_BLEND_INVDESTALPHA, "invdestalpha"}, - {GFXS_BLEND_DESTCOLOR, "destcolor" }, - {GFXS_BLEND_INVDESTCOLOR, "invdestcolor"}, - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(GfxBlendOp, - { - {GFXS_BLENDOP_DISABLED, "disabled" }, - {GFXS_BLENDOP_ADD, "add" }, - {GFXS_BLENDOP_SUBTRACT, "subtract" }, - {GFXS_BLENDOP_REVSUBTRACT, "revsubtract"}, - {GFXS_BLENDOP_MIN, "min" }, - {GFXS_BLENDOP_MAX, "max" }, - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(GfxPolygonOffset_e, - { - {GFXS_POLYGON_OFFSET_0, "offset0" }, - {GFXS_POLYGON_OFFSET_1, "offset1" }, - {GFXS_POLYGON_OFFSET_2, "offset2" }, - {GFXS_POLYGON_OFFSET_SHADOWMAP, "offsetShadowmap"}, - }); - - class JsonStateBitsTableEntry - { - public: - GfxBlend srcBlendRgb; - GfxBlend dstBlendRgb; - GfxBlendOp blendOpRgb; - JsonAlphaTest alphaTest; - JsonCullFace cullFace; - GfxBlend srcBlendAlpha; - GfxBlend dstBlendAlpha; - GfxBlendOp blendOpAlpha; - bool colorWriteRgb; - bool colorWriteAlpha; - bool gammaWrite; - bool polymodeLine; - bool depthWrite; - JsonDepthTest depthTest; - GfxPolygonOffset_e polygonOffset; - std::optional stencilFront; - std::optional stencilBack; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStateBitsTableEntry, - srcBlendRgb, - dstBlendRgb, - blendOpRgb, - alphaTest, - cullFace, - srcBlendAlpha, - dstBlendAlpha, - blendOpAlpha, - colorWriteRgb, - colorWriteAlpha, - polymodeLine, - depthWrite, - depthWrite, - depthTest, - polygonOffset, - stencilFront, - stencilBack); - - class JsonConstant - { - public: - std::optional name; - std::optional nameFragment; - std::optional nameHash; - std::vector literal; - }; - - inline void to_json(nlohmann::json& out, const JsonConstant& in) - { - if (in.name.has_value()) - { - optional_to_json(out, "name", in.name); - } - else - { - optional_to_json(out, "nameFragment", in.nameFragment); - optional_to_json(out, "nameHash", in.nameHash); - } - - out["literal"] = in.literal; - } - - inline void from_json(const nlohmann::json& in, JsonConstant& out) - { - optional_from_json(in, "name", out.name); - optional_from_json(in, "nameFragment", out.nameFragment); - optional_from_json(in, "nameHash", out.nameHash); - in.at("literal").get_to(out.literal); - }; - - NLOHMANN_JSON_SERIALIZE_ENUM(TextureFilter, - { - {TEXTURE_FILTER_DISABLED, "disabled"}, - {TEXTURE_FILTER_NEAREST, "nearest" }, - {TEXTURE_FILTER_LINEAR, "linear" }, - {TEXTURE_FILTER_ANISO2X, "aniso2x" }, - {TEXTURE_FILTER_ANISO4X, "aniso4x" }, - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(SamplerStateBitsMipMap_e, - { - {SAMPLER_MIPMAP_ENUM_DISABLED, "disabled"}, - {SAMPLER_MIPMAP_ENUM_NEAREST, "nearest" }, - {SAMPLER_MIPMAP_ENUM_LINEAR, "linear" }, - }); - - class JsonSamplerState - { - public: - TextureFilter filter; - SamplerStateBitsMipMap_e mipMap; - bool clampU; - bool clampV; - bool clampW; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonSamplerState, filter, mipMap, clampU, clampV, clampW); - - class JsonComplex - { - public: - float real; - float imag; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonComplex, real, imag); - - class JsonWater - { - public: - float floatTime; - int m; - int n; - std::string h0; - std::string wTerm; - float lx; - float lz; - float gravity; - float windvel; - std::array winddir; - float amplitude; - std::array codeConstant; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWater, floatTime, m, n, h0, wTerm, lx, lz, gravity, windvel, winddir, amplitude, codeConstant); - - NLOHMANN_JSON_SERIALIZE_ENUM(TextureSemantic, - { - {TS_2D, "2D" }, - {TS_FUNCTION, "function" }, - {TS_COLOR_MAP, "colorMap" }, - {TS_DETAIL_MAP, "detailMap" }, - {TS_UNUSED_2, "unused2" }, - {TS_NORMAL_MAP, "normalMap" }, - {TS_UNUSED_3, "unused3" }, - {TS_UNUSED_4, "unused4" }, - {TS_SPECULAR_MAP, "specularMap" }, - {TS_UNUSED_5, "unused5" }, - {TS_UNUSED_6, "unused6" }, - {TS_WATER_MAP, "waterMap" }, - {TS_DISPLACEMENT_MAP, "displacementMap"}, - }); - - class JsonTexture - { - public: - std::optional name; - std::optional nameHash; - std::optional nameStart; - std::optional nameEnd; - TextureSemantic semantic; - JsonSamplerState samplerState; - std::string image; - std::optional water; - }; - - inline void to_json(nlohmann::json& out, const JsonTexture& in) - { - if (in.name.has_value()) - { - optional_to_json(out, "name", in.name); - } - else - { - optional_to_json(out, "nameHash", in.nameHash); - optional_to_json(out, "nameStart", in.nameStart); - optional_to_json(out, "nameEnd", in.nameEnd); - } - - out["semantic"] = in.semantic; - out["samplerState"] = in.samplerState; - out["image"] = in.image; - optional_to_json(out, "water", in.water); - } - - inline void from_json(const nlohmann::json& in, JsonTexture& out) - { - optional_from_json(in, "name", out.name); - optional_from_json(in, "nameHash", out.nameHash); - optional_from_json(in, "nameStart", out.nameStart); - optional_from_json(in, "nameEnd", out.nameEnd); - in.at("semantic").get_to(out.semantic); - in.at("samplerState").get_to(out.samplerState); - in.at("image").get_to(out.image); - optional_from_json(in, "water", out.water); - }; - - class JsonTextureAtlas - { - public: - uint8_t rows; - uint8_t columns; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonTextureAtlas, rows, columns); - - NLOHMANN_JSON_SERIALIZE_ENUM(MaterialGameFlags, - { - {MTL_GAMEFLAG_1, "1" }, - {MTL_GAMEFLAG_2, "2" }, - {MTL_GAMEFLAG_4, "4" }, - {MTL_GAMEFLAG_8, "8" }, - {MTL_GAMEFLAG_10, "10" }, - {MTL_GAMEFLAG_20, "20" }, - {MTL_GAMEFLAG_40, "40" }, - {MTL_GAMEFLAG_80, "80" }, - {MTL_GAMEFLAG_100, "100" }, - {MTL_GAMEFLAG_200, "200" }, - {MTL_GAMEFLAG_400, "400" }, - {MTL_GAMEFLAG_800, "800" }, - {MTL_GAMEFLAG_1000, "1000"}, - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(GfxCameraRegionType, - { - {CAMERA_REGION_LIT_OPAQUE, "litOpaque" }, - {CAMERA_REGION_LIT_TRANS, "litTrans" }, - {CAMERA_REGION_EMISSIVE, "emissive" }, - {CAMERA_REGION_DEPTH_HACK, "depthHack" }, - {CAMERA_REGION_LIGHT_MAP_OPAQUE, "lightMapOpaque"}, - {CAMERA_REGION_NONE, "none" }, - }); - - class JsonMaterial - { - public: - std::vector gameFlags; - unsigned sortKey; - std::optional textureAtlas; - unsigned surfaceTypeBits; - std::vector stateBitsEntry; - unsigned stateFlags; - GfxCameraRegionType cameraRegion; - std::string techniqueSet; - std::vector textures; - std::vector constants; - std::vector stateBits; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonMaterial, - gameFlags, - sortKey, - textureAtlas, - surfaceTypeBits, - stateBitsEntry, - stateFlags, - cameraRegion, - techniqueSet, - textures, - constants, - stateBits); -} // namespace IW5 diff --git a/src/ObjCommon/Game/T6/Material/JsonMaterial.h b/src/ObjCommon/Game/T6/Material/JsonMaterial.h deleted file mode 100644 index e210676d..00000000 --- a/src/ObjCommon/Game/T6/Material/JsonMaterial.h +++ /dev/null @@ -1,397 +0,0 @@ -#pragma once - -#include "Game/T6/T6.h" - -#include "Json/JsonExtension.h" -#include -#include -#include -#include -#include - -namespace T6 -{ - NLOHMANN_JSON_SERIALIZE_ENUM(GfxStencilOp, - { - {GFXS_STENCILOP_KEEP, "keep" }, - {GFXS_STENCILOP_ZERO, "zero" }, - {GFXS_STENCILOP_REPLACE, "replace"}, - {GFXS_STENCILOP_INCRSAT, "incrsat"}, - {GFXS_STENCILOP_DECRSAT, "decrsat"}, - {GFXS_STENCILOP_INVERT, "invert" }, - {GFXS_STENCILOP_INCR, "incr" }, - {GFXS_STENCILOP_DECR, "decr" }, - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(GfxStencilFunc, - { - {GFXS_STENCILFUNC_NEVER, "never" }, - {GFXS_STENCILFUNC_LESS, "less" }, - {GFXS_STENCILFUNC_EQUAL, "equal" }, - {GFXS_STENCILFUNC_LESSEQUAL, "lessequal" }, - {GFXS_STENCILFUNC_GREATER, "greater" }, - {GFXS_STENCILFUNC_NOTEQUAL, "notequal" }, - {GFXS_STENCILFUNC_GREATEREQUAL, "greaterequal"}, - {GFXS_STENCILFUNC_ALWAYS, "always" }, - }); - - class JsonStencil - { - public: - GfxStencilOp pass; - GfxStencilOp fail; - GfxStencilOp zfail; - GfxStencilFunc func; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStencil, pass, fail, zfail, func); - - enum class JsonAlphaTest - { - INVALID, - DISABLED, - GT0, - GE128 - }; - - NLOHMANN_JSON_SERIALIZE_ENUM( - JsonAlphaTest, - { - {JsonAlphaTest::INVALID, nullptr }, - {JsonAlphaTest::DISABLED, "disabled"}, - {JsonAlphaTest::GT0, "gt0" }, - {JsonAlphaTest::GE128, "ge128" } - }); - - enum class JsonCullFace - { - INVALID, - NONE, - BACK, - FRONT - }; - - NLOHMANN_JSON_SERIALIZE_ENUM( - JsonCullFace, - { - {JsonCullFace::INVALID, nullptr}, - {JsonCullFace::NONE, "none" }, - {JsonCullFace::BACK, "back" }, - {JsonCullFace::FRONT, "front"} - }); - - enum class JsonDepthTest - { - INVALID, - DISABLED, - ALWAYS, - LESS, - EQUAL, - LESS_EQUAL - }; - - NLOHMANN_JSON_SERIALIZE_ENUM(JsonDepthTest, - { - {JsonDepthTest::INVALID, nullptr }, - {JsonDepthTest::DISABLED, "disabled" }, - {JsonDepthTest::ALWAYS, "always" }, - {JsonDepthTest::LESS, "less" }, - {JsonDepthTest::EQUAL, "equal" }, - {JsonDepthTest::LESS_EQUAL, "less_equal"} - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(GfxBlend, - { - {GFXS_BLEND_DISABLED, "disabled" }, - {GFXS_BLEND_ZERO, "zero" }, - {GFXS_BLEND_ONE, "one" }, - {GFXS_BLEND_SRCCOLOR, "srccolor" }, - {GFXS_BLEND_INVSRCCOLOR, "invsrccolor" }, - {GFXS_BLEND_SRCALPHA, "srcalpha" }, - {GFXS_BLEND_INVSRCALPHA, "invsrcalpha" }, - {GFXS_BLEND_DESTALPHA, "destalpha" }, - {GFXS_BLEND_INVDESTALPHA, "invdestalpha"}, - {GFXS_BLEND_DESTCOLOR, "destcolor" }, - {GFXS_BLEND_INVDESTCOLOR, "invdestcolor"}, - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(GfxBlendOp, - { - {GFXS_BLENDOP_DISABLED, "disabled" }, - {GFXS_BLENDOP_ADD, "add" }, - {GFXS_BLENDOP_SUBTRACT, "subtract" }, - {GFXS_BLENDOP_REVSUBTRACT, "revsubtract"}, - {GFXS_BLENDOP_MIN, "min" }, - {GFXS_BLENDOP_MAX, "max" }, - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(GfxPolygonOffset_e, - { - {GFXS_POLYGON_OFFSET_0, "offset0" }, - {GFXS_POLYGON_OFFSET_1, "offset1" }, - {GFXS_POLYGON_OFFSET_2, "offset2" }, - {GFXS_POLYGON_OFFSET_SHADOWMAP, "offsetShadowmap"}, - }); - - class JsonStateBitsTableEntry - { - public: - GfxBlend srcBlendRgb; - GfxBlend dstBlendRgb; - GfxBlendOp blendOpRgb; - JsonAlphaTest alphaTest; - JsonCullFace cullFace; - GfxBlend srcBlendAlpha; - GfxBlend dstBlendAlpha; - GfxBlendOp blendOpAlpha; - bool colorWriteRgb; - bool colorWriteAlpha; - bool polymodeLine; - bool depthWrite; - JsonDepthTest depthTest; - GfxPolygonOffset_e polygonOffset; - std::optional stencilFront; - std::optional stencilBack; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStateBitsTableEntry, - srcBlendRgb, - dstBlendRgb, - blendOpRgb, - alphaTest, - cullFace, - srcBlendAlpha, - dstBlendAlpha, - blendOpAlpha, - colorWriteRgb, - colorWriteAlpha, - polymodeLine, - depthWrite, - depthWrite, - depthTest, - polygonOffset, - stencilFront, - stencilBack); - - class JsonConstant - { - public: - std::optional name; - std::optional nameFragment; - std::optional nameHash; - std::vector literal; - }; - - inline void to_json(nlohmann::json& out, const JsonConstant& in) - { - if (in.name.has_value()) - { - optional_to_json(out, "name", in.name); - } - else - { - optional_to_json(out, "nameFragment", in.nameFragment); - optional_to_json(out, "nameHash", in.nameHash); - } - - out["literal"] = in.literal; - } - - inline void from_json(const nlohmann::json& in, JsonConstant& out) - { - optional_from_json(in, "name", out.name); - optional_from_json(in, "nameFragment", out.nameFragment); - optional_from_json(in, "nameHash", out.nameHash); - in.at("literal").get_to(out.literal); - }; - - NLOHMANN_JSON_SERIALIZE_ENUM(TextureFilter, - { - {TEXTURE_FILTER_DISABLED, "disabled"}, - {TEXTURE_FILTER_NEAREST, "nearest" }, - {TEXTURE_FILTER_LINEAR, "linear" }, - {TEXTURE_FILTER_ANISO2X, "aniso2x" }, - {TEXTURE_FILTER_ANISO4X, "aniso4x" }, - {TEXTURE_FILTER_COMPARE, "compare" }, - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(SamplerStateBitsMipMap_e, - { - {SAMPLER_MIPMAP_ENUM_DISABLED, "disabled"}, - {SAMPLER_MIPMAP_ENUM_NEAREST, "nearest" }, - {SAMPLER_MIPMAP_ENUM_LINEAR, "linear" }, - }); - - class JsonSamplerState - { - public: - TextureFilter filter; - SamplerStateBitsMipMap_e mipMap; - bool clampU; - bool clampV; - bool clampW; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonSamplerState, filter, mipMap, clampU, clampV, clampW); - - NLOHMANN_JSON_SERIALIZE_ENUM(TextureSemantic, - { - {TS_2D, "2D" }, - {TS_FUNCTION, "function" }, - {TS_COLOR_MAP, "colorMap" }, - {TS_UNUSED_1, "unused1" }, - {TS_UNUSED_2, "unused2" }, - {TS_NORMAL_MAP, "normalMap" }, - {TS_UNUSED_3, "unused3" }, - {TS_UNUSED_4, "unused4" }, - {TS_SPECULAR_MAP, "specularMap" }, - {TS_UNUSED_5, "unused5" }, - {TS_OCCLUSION_MAP, "occlusionMap"}, - {TS_UNUSED_6, "unused6" }, - {TS_COLOR0_MAP, "color0Map" }, - {TS_COLOR1_MAP, "color1Map" }, - {TS_COLOR2_MAP, "color2Map" }, - {TS_COLOR3_MAP, "color3Map" }, - {TS_COLOR4_MAP, "color4Map" }, - {TS_COLOR5_MAP, "color5Map" }, - {TS_COLOR6_MAP, "color6Map" }, - {TS_COLOR7_MAP, "color7Map" }, - {TS_COLOR8_MAP, "color8Map" }, - {TS_COLOR9_MAP, "color9Map" }, - {TS_COLOR10_MAP, "color10Map" }, - {TS_COLOR11_MAP, "color11Map" }, - {TS_COLOR12_MAP, "color12Map" }, - {TS_COLOR13_MAP, "color13Map" }, - {TS_COLOR14_MAP, "color14Map" }, - {TS_COLOR15_MAP, "color15Map" }, - {TS_THROW_MAP, "throwMap" }, - }); - - class JsonTexture - { - public: - std::optional name; - std::optional nameHash; - std::optional nameStart; - std::optional nameEnd; - TextureSemantic semantic; - bool isMatureContent; - JsonSamplerState samplerState; - std::string image; - }; - - inline void to_json(nlohmann::json& out, const JsonTexture& in) - { - if (in.name.has_value()) - { - optional_to_json(out, "name", in.name); - } - else - { - optional_to_json(out, "nameHash", in.nameHash); - optional_to_json(out, "nameStart", in.nameStart); - optional_to_json(out, "nameEnd", in.nameEnd); - } - - out["semantic"] = in.semantic; - out["isMatureContent"] = in.isMatureContent; - out["samplerState"] = in.samplerState; - out["image"] = in.image; - } - - inline void from_json(const nlohmann::json& in, JsonTexture& out) - { - optional_from_json(in, "name", out.name); - optional_from_json(in, "nameHash", out.nameHash); - optional_from_json(in, "nameStart", out.nameStart); - optional_from_json(in, "nameEnd", out.nameEnd); - in.at("semantic").get_to(out.semantic); - in.at("isMatureContent").get_to(out.isMatureContent); - in.at("samplerState").get_to(out.samplerState); - in.at("image").get_to(out.image); - }; - - class JsonTextureAtlas - { - public: - uint8_t rows; - uint8_t columns; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonTextureAtlas, rows, columns); - - NLOHMANN_JSON_SERIALIZE_ENUM(MaterialGameFlags, - { - {MTL_GAMEFLAG_1, "1" }, - {MTL_GAMEFLAG_2, "2" }, - {MTL_GAMEFLAG_NO_MARKS, "NO_MARKS" }, - {MTL_GAMEFLAG_NO_MARKS, "4" }, - {MTL_GAMEFLAG_8, "8" }, - {MTL_GAMEFLAG_10, "10" }, - {MTL_GAMEFLAG_20, "20" }, - {MTL_GAMEFLAG_CASTS_SHADOW, "CASTS_SHADOW"}, - {MTL_GAMEFLAG_CASTS_SHADOW, "40" }, - {MTL_GAMEFLAG_80, "80" }, - {MTL_GAMEFLAG_100, "100" }, - {MTL_GAMEFLAG_200, "200" }, - {MTL_GAMEFLAG_400, "400" }, - {MTL_GAMEFLAG_800, "800" }, - {MTL_GAMEFLAG_1000, "1000" }, - }); - - NLOHMANN_JSON_SERIALIZE_ENUM(GfxCameraRegionType, - { - {CAMERA_REGION_LIT_OPAQUE, "litOpaque" }, - {CAMERA_REGION_LIT_TRANS, "litTrans" }, - {CAMERA_REGION_LIT_QUASI_OPAQUE, "litQuasiOpaque"}, - {CAMERA_REGION_EMISSIVE_OPAQUE, "emissiveOpaque"}, - {CAMERA_REGION_EMISSIVE_TRANS, "emissiveTrans" }, - {CAMERA_REGION_EMISSIVE_FX, "emissiveFx" }, - {CAMERA_REGION_LIGHT_MAP_OPAQUE, "lightMapOpaque"}, - {CAMERA_REGION_DEPTH_HACK, "depthHack" }, - {CAMERA_REGION_UNUSED, "unused" }, - {CAMERA_REGION_SONAR, "sonar" }, - {CAMERA_REGION_NONE, "none" }, - }); - - class JsonMaterial - { - public: - std::vector gameFlags; - unsigned sortKey; - std::optional textureAtlas; - unsigned surfaceTypeBits; - unsigned layeredSurfaceTypes; - unsigned hashIndex; - unsigned surfaceFlags; - unsigned contents; - std::vector stateBitsEntry; - unsigned stateFlags; - GfxCameraRegionType cameraRegion; - uint8_t probeMipBits; - std::string techniqueSet; - std::vector textures; - std::vector constants; - std::vector stateBits; - std::optional thermalMaterial; - }; - - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonMaterial, - gameFlags, - sortKey, - textureAtlas, - surfaceTypeBits, - layeredSurfaceTypes, - hashIndex, - surfaceFlags, - contents, - stateBitsEntry, - stateFlags, - cameraRegion, - probeMipBits, - techniqueSet, - textures, - constants, - stateBits, - thermalMaterial); -} // namespace T6 diff --git a/src/ObjCommon/Material/JsonMaterial.h.template b/src/ObjCommon/Material/JsonMaterial.h.template new file mode 100644 index 00000000..168b29fd --- /dev/null +++ b/src/ObjCommon/Material/JsonMaterial.h.template @@ -0,0 +1,529 @@ +#options GAME (IW5, T6) + +#filename "Game/" + GAME + "/Material/JsonMaterial" + GAME + ".h" + +#if GAME == "IW5" +#define FEATURE_IW5 +#define HAS_WATER +#elif GAME == "T6" +#define FEATURE_T6 +#endif + +// This file was templated. +// See JsonMaterialWriter.h.template. +// Do not modify, changes will be lost. + +#pragma once + +#set GAME_HEADER "\"Game/" + GAME + "/" + GAME + ".h\"" +#include GAME_HEADER + +#include "Json/JsonExtension.h" +#include +#include +#include +#include +#include + +namespace GAME +{ + NLOHMANN_JSON_SERIALIZE_ENUM(GfxStencilOp, { + {GFXS_STENCILOP_KEEP, "keep" }, + {GFXS_STENCILOP_ZERO, "zero" }, + {GFXS_STENCILOP_REPLACE, "replace"}, + {GFXS_STENCILOP_INCRSAT, "incrsat"}, + {GFXS_STENCILOP_DECRSAT, "decrsat"}, + {GFXS_STENCILOP_INVERT, "invert" }, + {GFXS_STENCILOP_INCR, "incr" }, + {GFXS_STENCILOP_DECR, "decr" }, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(GfxStencilFunc, { + {GFXS_STENCILFUNC_NEVER, "never" }, + {GFXS_STENCILFUNC_LESS, "less" }, + {GFXS_STENCILFUNC_EQUAL, "equal" }, + {GFXS_STENCILFUNC_LESSEQUAL, "lessequal" }, + {GFXS_STENCILFUNC_GREATER, "greater" }, + {GFXS_STENCILFUNC_NOTEQUAL, "notequal" }, + {GFXS_STENCILFUNC_GREATEREQUAL, "greaterequal"}, + {GFXS_STENCILFUNC_ALWAYS, "always" }, + }); + + class JsonStencil + { + public: + GfxStencilOp pass; + GfxStencilOp fail; + GfxStencilOp zfail; + GfxStencilFunc func; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION( + JsonStencil, + pass, + fail, + zfail, + func + ); + + enum class JsonAlphaTest + { + INVALID, + DISABLED, + GT0, +#ifdef FEATURE_IW5 + LT128, +#endif + GE128 + }; + + NLOHMANN_JSON_SERIALIZE_ENUM(JsonAlphaTest, { + {JsonAlphaTest::INVALID, nullptr }, + {JsonAlphaTest::DISABLED, "disabled"}, + {JsonAlphaTest::GT0, "gt0" }, +#ifdef FEATURE_IW5 + {JsonAlphaTest::LT128, "lt128" }, +#endif + {JsonAlphaTest::GE128, "ge128" } + }); + + enum class JsonCullFace + { + INVALID, + NONE, + BACK, + FRONT + }; + + NLOHMANN_JSON_SERIALIZE_ENUM(JsonCullFace, { + {JsonCullFace::INVALID, nullptr}, + {JsonCullFace::NONE, "none" }, + {JsonCullFace::BACK, "back" }, + {JsonCullFace::FRONT, "front"} + }); + + enum class JsonDepthTest + { + INVALID, + DISABLED, + ALWAYS, + LESS, + EQUAL, + LESS_EQUAL + }; + + NLOHMANN_JSON_SERIALIZE_ENUM(JsonDepthTest, { + {JsonDepthTest::INVALID, nullptr }, + {JsonDepthTest::DISABLED, "disabled" }, + {JsonDepthTest::ALWAYS, "always" }, + {JsonDepthTest::LESS, "less" }, + {JsonDepthTest::EQUAL, "equal" }, + {JsonDepthTest::LESS_EQUAL, "less_equal"} + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(GfxBlend, { + {GFXS_BLEND_DISABLED, "disabled" }, + {GFXS_BLEND_ZERO, "zero" }, + {GFXS_BLEND_ONE, "one" }, + {GFXS_BLEND_SRCCOLOR, "srccolor" }, + {GFXS_BLEND_INVSRCCOLOR, "invsrccolor" }, + {GFXS_BLEND_SRCALPHA, "srcalpha" }, + {GFXS_BLEND_INVSRCALPHA, "invsrcalpha" }, + {GFXS_BLEND_DESTALPHA, "destalpha" }, + {GFXS_BLEND_INVDESTALPHA, "invdestalpha"}, + {GFXS_BLEND_DESTCOLOR, "destcolor" }, + {GFXS_BLEND_INVDESTCOLOR, "invdestcolor"}, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(GfxBlendOp, { + {GFXS_BLENDOP_DISABLED, "disabled" }, + {GFXS_BLENDOP_ADD, "add" }, + {GFXS_BLENDOP_SUBTRACT, "subtract" }, + {GFXS_BLENDOP_REVSUBTRACT, "revsubtract"}, + {GFXS_BLENDOP_MIN, "min" }, + {GFXS_BLENDOP_MAX, "max" }, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(GfxPolygonOffset_e, { + {GFXS_POLYGON_OFFSET_0, "offset0" }, + {GFXS_POLYGON_OFFSET_1, "offset1" }, + {GFXS_POLYGON_OFFSET_2, "offset2" }, + {GFXS_POLYGON_OFFSET_SHADOWMAP, "offsetShadowmap"}, + }); + + class JsonStateBitsTableEntry + { + public: + GfxBlend srcBlendRgb; + GfxBlend dstBlendRgb; + GfxBlendOp blendOpRgb; + JsonAlphaTest alphaTest; + JsonCullFace cullFace; + GfxBlend srcBlendAlpha; + GfxBlend dstBlendAlpha; + GfxBlendOp blendOpAlpha; + bool colorWriteRgb; + bool colorWriteAlpha; +#ifdef FEATURE_IW5 + bool gammaWrite; +#endif + bool polymodeLine; + bool depthWrite; + JsonDepthTest depthTest; + GfxPolygonOffset_e polygonOffset; + std::optional stencilFront; + std::optional stencilBack; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStateBitsTableEntry, + srcBlendRgb, + dstBlendRgb, + blendOpRgb, + alphaTest, + cullFace, + srcBlendAlpha, + dstBlendAlpha, + blendOpAlpha, + colorWriteRgb, + colorWriteAlpha, + polymodeLine, + depthWrite, + depthWrite, + depthTest, + polygonOffset, + stencilFront, + stencilBack + ); + + class JsonConstant + { + public: + std::optional name; + std::optional nameFragment; + std::optional nameHash; + std::vector literal; + }; + + inline void to_json(nlohmann::json& out, const JsonConstant& in) + { + if (in.name.has_value()) + { + optional_to_json(out, "name", in.name); + } + else + { + optional_to_json(out, "nameFragment", in.nameFragment); + optional_to_json(out, "nameHash", in.nameHash); + } + + out["literal"] = in.literal; + } + + inline void from_json(const nlohmann::json& in, JsonConstant& out) + { + optional_from_json(in, "name", out.name); + optional_from_json(in, "nameFragment", out.nameFragment); + optional_from_json(in, "nameHash", out.nameHash); + in.at("literal").get_to(out.literal); + }; + + NLOHMANN_JSON_SERIALIZE_ENUM(TextureFilter, { + {TEXTURE_FILTER_DISABLED, "disabled"}, + {TEXTURE_FILTER_NEAREST, "nearest" }, + {TEXTURE_FILTER_LINEAR, "linear" }, + {TEXTURE_FILTER_ANISO2X, "aniso2x" }, + {TEXTURE_FILTER_ANISO4X, "aniso4x" }, +#ifdef FEATURE_T6 + {TEXTURE_FILTER_COMPARE, "compare" }, +#endif + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(SamplerStateBitsMipMap_e, { + {SAMPLER_MIPMAP_ENUM_DISABLED, "disabled"}, + {SAMPLER_MIPMAP_ENUM_NEAREST, "nearest" }, + {SAMPLER_MIPMAP_ENUM_LINEAR, "linear" }, + }); + + class JsonSamplerState + { + public: + TextureFilter filter; + SamplerStateBitsMipMap_e mipMap; + bool clampU; + bool clampV; + bool clampW; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION( + JsonSamplerState, + filter, + mipMap, + clampU, + clampV, + clampW + ); + +#ifdef HAS_WATER + class JsonComplex + { + public: + float real; + float imag; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonComplex, real, imag); + + class JsonWater + { + public: + float floatTime; + int m; + int n; + std::string h0; + std::string wTerm; + float lx; + float lz; + float gravity; + float windvel; + std::array winddir; + float amplitude; + std::array codeConstant; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION( + JsonWater, + floatTime, + m, + n, + h0, + wTerm, + lx, + lz, + gravity, + windvel, + winddir, + amplitude, + codeConstant + ); +#endif + + NLOHMANN_JSON_SERIALIZE_ENUM(TextureSemantic, { +#ifdef FEATURE_IW5 + {TS_2D, "2D" }, + {TS_FUNCTION, "function" }, + {TS_COLOR_MAP, "colorMap" }, + {TS_DETAIL_MAP, "detailMap" }, + {TS_UNUSED_2, "unused2" }, + {TS_NORMAL_MAP, "normalMap" }, + {TS_UNUSED_3, "unused3" }, + {TS_UNUSED_4, "unused4" }, + {TS_SPECULAR_MAP, "specularMap" }, + {TS_UNUSED_5, "unused5" }, + {TS_UNUSED_6, "unused6" }, + {TS_WATER_MAP, "waterMap" }, + {TS_DISPLACEMENT_MAP, "displacementMap"}, +#elif defined(FEATURE_T6) + {TS_2D, "2D" }, + {TS_FUNCTION, "function" }, + {TS_COLOR_MAP, "colorMap" }, + {TS_UNUSED_1, "unused1" }, + {TS_UNUSED_2, "unused2" }, + {TS_NORMAL_MAP, "normalMap" }, + {TS_UNUSED_3, "unused3" }, + {TS_UNUSED_4, "unused4" }, + {TS_SPECULAR_MAP, "specularMap" }, + {TS_UNUSED_5, "unused5" }, + {TS_OCCLUSION_MAP, "occlusionMap"}, + {TS_UNUSED_6, "unused6" }, + {TS_COLOR0_MAP, "color0Map" }, + {TS_COLOR1_MAP, "color1Map" }, + {TS_COLOR2_MAP, "color2Map" }, + {TS_COLOR3_MAP, "color3Map" }, + {TS_COLOR4_MAP, "color4Map" }, + {TS_COLOR5_MAP, "color5Map" }, + {TS_COLOR6_MAP, "color6Map" }, + {TS_COLOR7_MAP, "color7Map" }, + {TS_COLOR8_MAP, "color8Map" }, + {TS_COLOR9_MAP, "color9Map" }, + {TS_COLOR10_MAP, "color10Map" }, + {TS_COLOR11_MAP, "color11Map" }, + {TS_COLOR12_MAP, "color12Map" }, + {TS_COLOR13_MAP, "color13Map" }, + {TS_COLOR14_MAP, "color14Map" }, + {TS_COLOR15_MAP, "color15Map" }, + {TS_THROW_MAP, "throwMap" }, +#endif + }); + + class JsonTexture + { + public: + std::optional name; + std::optional nameHash; + std::optional nameStart; + std::optional nameEnd; + TextureSemantic semantic; +#ifdef FEATURE_T6 + bool isMatureContent; +#endif + JsonSamplerState samplerState; + std::string image; +#ifdef HAS_WATER + std::optional water; +#endif + }; + + inline void to_json(nlohmann::json& out, const JsonTexture& in) + { + if (in.name.has_value()) + { + optional_to_json(out, "name", in.name); + } + else + { + optional_to_json(out, "nameHash", in.nameHash); + optional_to_json(out, "nameStart", in.nameStart); + optional_to_json(out, "nameEnd", in.nameEnd); + } + + out["semantic"] = in.semantic; +#ifdef FEATURE_T6 + out["isMatureContent"] = in.isMatureContent; +#endif + out["samplerState"] = in.samplerState; + out["image"] = in.image; +#ifdef HAS_WATER + optional_to_json(out, "water", in.water); +#endif + } + + inline void from_json(const nlohmann::json& in, JsonTexture& out) + { + optional_from_json(in, "name", out.name); + optional_from_json(in, "nameHash", out.nameHash); + optional_from_json(in, "nameStart", out.nameStart); + optional_from_json(in, "nameEnd", out.nameEnd); + in.at("semantic").get_to(out.semantic); +#ifdef FEATURE_T6 + in.at("isMatureContent").get_to(out.isMatureContent); +#endif + in.at("samplerState").get_to(out.samplerState); + in.at("image").get_to(out.image); +#ifdef HAS_WATER + optional_from_json(in, "water", out.water); +#endif + }; + + class JsonTextureAtlas + { + public: + uint8_t rows; + uint8_t columns; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonTextureAtlas, rows, columns); + + NLOHMANN_JSON_SERIALIZE_ENUM(MaterialGameFlags, { +#ifdef FEATURE_IW5 + {MTL_GAMEFLAG_1, "1" }, + {MTL_GAMEFLAG_2, "2" }, + {MTL_GAMEFLAG_4, "4" }, + {MTL_GAMEFLAG_8, "8" }, + {MTL_GAMEFLAG_10, "10" }, + {MTL_GAMEFLAG_20, "20" }, + {MTL_GAMEFLAG_40, "40" }, + {MTL_GAMEFLAG_80, "80" }, + {MTL_GAMEFLAG_100, "100" }, + {MTL_GAMEFLAG_200, "200" }, + {MTL_GAMEFLAG_400, "400" }, + {MTL_GAMEFLAG_800, "800" }, + {MTL_GAMEFLAG_1000, "1000"}, +#elif defined(FEATURE_T6) + {MTL_GAMEFLAG_1, "1" }, + {MTL_GAMEFLAG_2, "2" }, + {MTL_GAMEFLAG_NO_MARKS, "NO_MARKS" }, + {MTL_GAMEFLAG_NO_MARKS, "4" }, + {MTL_GAMEFLAG_8, "8" }, + {MTL_GAMEFLAG_10, "10" }, + {MTL_GAMEFLAG_20, "20" }, + {MTL_GAMEFLAG_CASTS_SHADOW, "CASTS_SHADOW"}, + {MTL_GAMEFLAG_CASTS_SHADOW, "40" }, + {MTL_GAMEFLAG_80, "80" }, + {MTL_GAMEFLAG_100, "100" }, + {MTL_GAMEFLAG_200, "200" }, + {MTL_GAMEFLAG_400, "400" }, + {MTL_GAMEFLAG_800, "800" }, + {MTL_GAMEFLAG_1000, "1000" }, +#endif + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(GfxCameraRegionType, { +#ifdef FEATURE_IW5 + {CAMERA_REGION_LIT_OPAQUE, "litOpaque" }, + {CAMERA_REGION_LIT_TRANS, "litTrans" }, + {CAMERA_REGION_EMISSIVE, "emissive" }, + {CAMERA_REGION_DEPTH_HACK, "depthHack" }, + {CAMERA_REGION_LIGHT_MAP_OPAQUE, "lightMapOpaque"}, + {CAMERA_REGION_NONE, "none" }, +#elif defined(FEATURE_T6) + {CAMERA_REGION_LIT_OPAQUE, "litOpaque" }, + {CAMERA_REGION_LIT_TRANS, "litTrans" }, + {CAMERA_REGION_LIT_QUASI_OPAQUE, "litQuasiOpaque"}, + {CAMERA_REGION_EMISSIVE_OPAQUE, "emissiveOpaque"}, + {CAMERA_REGION_EMISSIVE_TRANS, "emissiveTrans" }, + {CAMERA_REGION_EMISSIVE_FX, "emissiveFx" }, + {CAMERA_REGION_LIGHT_MAP_OPAQUE, "lightMapOpaque"}, + {CAMERA_REGION_DEPTH_HACK, "depthHack" }, + {CAMERA_REGION_UNUSED, "unused" }, + {CAMERA_REGION_SONAR, "sonar" }, + {CAMERA_REGION_NONE, "none" }, +#endif + }); + + class JsonMaterial + { + public: +#ifdef FEATURE_T6 + unsigned layeredSurfaceTypes; + unsigned hashIndex; + unsigned surfaceFlags; + unsigned contents; + uint8_t probeMipBits; + std::optional thermalMaterial; +#endif + std::vector gameFlags; + unsigned sortKey; + std::optional textureAtlas; + unsigned surfaceTypeBits; + std::vector stateBitsEntry; + unsigned stateFlags; + GfxCameraRegionType cameraRegion; + std::string techniqueSet; + std::vector textures; + std::vector constants; + std::vector stateBits; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION( + JsonMaterial, +#ifdef FEATURE_T6 + layeredSurfaceTypes, + hashIndex, + surfaceFlags, + contents, + probeMipBits, + thermalMaterial, +#endif + gameFlags, + sortKey, + textureAtlas, + surfaceTypeBits, + stateBitsEntry, + stateFlags, + cameraRegion, + techniqueSet, + textures, + constants, + stateBits + ); +} // namespace GAME diff --git a/src/ObjWriting.lua b/src/ObjWriting.lua index 1f715ade..6fd8361a 100644 --- a/src/ObjWriting.lua +++ b/src/ObjWriting.lua @@ -53,6 +53,7 @@ function ObjWriting:project() } } + ObjCommon:use() useSourceTemplating("ObjWriting") self:include(includes) diff --git a/src/ObjWriting/Material/JsonMaterialWriter.cpp.template b/src/ObjWriting/Material/JsonMaterialWriter.cpp.template index 9c14304f..8724b403 100644 --- a/src/ObjWriting/Material/JsonMaterialWriter.cpp.template +++ b/src/ObjWriting/Material/JsonMaterialWriter.cpp.template @@ -24,7 +24,7 @@ #set COMMON_HEADER "\"Game/" + GAME + "/Common" + GAME + ".h\"" #include COMMON_HEADER -#set JSON_HEADER "\"Game/" + GAME + "/Material/JsonMaterial.h\"" +#set JSON_HEADER "\"Game/" + GAME + "/Material/JsonMaterial" + GAME + ".h\"" #include JSON_HEADER #set CONSTANTS_HEADER "\"Game/" + GAME + "/Material/MaterialConstantZoneState.h\"" #include CONSTANTS_HEADER