#options GAME(IW3, IW4, T5, T6) #filename "Game/" + GAME + "/Techset/TechsetCompiler" + GAME + ".cpp" #set COMPILER_HEADER "\"TechsetCompiler" + GAME + ".h\"" #set GAME_HEADER "\"Game/" + GAME + "/" + GAME + ".h\"" #set TECHSET_CONSTANTS_HEADER "\"Game/" + GAME + "/Techset/TechsetConstants" + GAME + ".h\"" #if GAME == "IW3" #define FEATURE_IW3 #elif GAME == "IW4" #define FEATURE_IW4 #elif GAME == "IW5" #define FEATURE_IW5 #elif GAME == "T5" #define FEATURE_T5 #elif GAME == "T6" #define FEATURE_T6 #endif // This file was templated. // See TechsetCompiler.cpp.template. // Do not modify, changes will be lost. #include COMPILER_HEADER #include GAME_HEADER #include TECHSET_CONSTANTS_HEADER #include "Techset/CommonTechsetLoader.h" #include "Techset/TechsetCommon.h" using namespace GAME; #set COMPILER_CLASS_NAME "TechsetCompiler" + GAME namespace { MaterialWorldVertexFormat GetWorldVertexFormat(const std::string& name) { if (name.contains("lit_")) { size_t texCount = 0u, normalCount = 0u; techset::CountWorldVertFormatParameters(name, texCount, normalCount); // 0 and 1 seem to be treated equally texCount = std::max(texCount, 1uz); normalCount = std::max(normalCount, 1uz); if (texCount == 1 && normalCount == 1) return MTL_WORLDVERT_TEX_1_NRM_1; if (texCount == 2 && normalCount == 1) return MTL_WORLDVERT_TEX_2_NRM_1; if (texCount == 2 && normalCount == 2) return MTL_WORLDVERT_TEX_2_NRM_2; if (texCount == 3 && normalCount == 1) return MTL_WORLDVERT_TEX_3_NRM_1; if (texCount == 3 && normalCount == 2) return MTL_WORLDVERT_TEX_3_NRM_2; if (texCount == 3 && normalCount == 3) return MTL_WORLDVERT_TEX_3_NRM_3; if (texCount == 4 && normalCount == 1) return MTL_WORLDVERT_TEX_4_NRM_1; if (texCount == 4 && normalCount == 2) return MTL_WORLDVERT_TEX_4_NRM_2; if (texCount == 4 && normalCount == 3) return MTL_WORLDVERT_TEX_4_NRM_3; } return static_cast(0); } #if defined(FEATURE_T6) MaterialType GetMaterialType(const std::string& name) { for (unsigned materialTypeIndex = MTL_TYPE_MODEL; materialTypeIndex < MTL_TYPE_COUNT; materialTypeIndex++) { if (name.starts_with(g_materialTypeInfo[materialTypeIndex].techniqueSetPrefix)) return static_cast(materialTypeIndex); } return MTL_TYPE_DEFAULT; } void ApplyMaterialTypeToTechnique(MaterialTechnique& technique, const MaterialType materialType) { for (auto passIndex = 0u; passIndex < technique.passCount; passIndex++) { technique.passArray[passIndex].materialType = materialType; } } #endif MaterialTechniqueSet* ConvertTechniqueSet(const techset::CommonTechset& commonTechset, MemoryManager& memory) { auto* techset = memory.Alloc(); techset->name = memory.Dup(commonTechset.m_name.c_str()); techset->worldVertFormat = GetWorldVertexFormat(commonTechset.m_name); return techset; } class COMPILER_CLASS_NAME final : public AssetCreator { public: COMPILER_CLASS_NAME(ISearchPath& searchPath, MemoryManager& memory) : m_search_path(searchPath), m_memory(memory) { } AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override { bool failure = false; const auto commonTechset = techset::LoadCommonTechset(assetName, commonTechniqueTypeNames, m_search_path, failure); if (!commonTechset) return failure ? AssetCreationResult::Failure() : AssetCreationResult::NoAction(); auto* techset = ConvertTechniqueSet(*commonTechset, m_memory); #if defined(FEATURE_T6) const auto materialType = GetMaterialType(assetName); #endif for (auto techniqueIndex = 0u; techniqueIndex < std::extent_v; techniqueIndex++) { const auto& techniqueName = commonTechset->m_technique_names[techniqueIndex]; if (techniqueName.empty()) continue; auto* technique = context.LoadSubAsset(techniqueName); if (!technique) return AssetCreationResult::Failure(); techset->techniques[techniqueIndex] = technique->Asset(); #if defined(FEATURE_T6) // Another techset may override this for the technique // but the game determines the material type by techset name. // So this may just be a constraint that cannot be changed. ApplyMaterialTypeToTechnique(*techset->techniques[techniqueIndex], materialType); #endif } return AssetCreationResult::Success(context.AddAsset(AssetRegistration(assetName, techset))); } private: ISearchPath& m_search_path; MemoryManager& m_memory; }; } // namespace #set CREATE_COMPILER_METHOD "CreateTechsetCompiler" + GAME namespace techset { std::unique_ptr CREATE_COMPILER_METHOD(MemoryManager& memory, ISearchPath& searchPath) { return std::make_unique(searchPath, memory); } } // namespace techset