diff --git a/src/ObjLoading/XModel/LoaderXModel.cpp.template b/src/ObjLoading/XModel/LoaderXModel.cpp.template index b3332821..4522ca18 100644 --- a/src/ObjLoading/XModel/LoaderXModel.cpp.template +++ b/src/ObjLoading/XModel/LoaderXModel.cpp.template @@ -9,12 +9,16 @@ #if GAME == "IW3" #define FEATURE_IW3 +#define EVEN_TRI_COUNT #elif GAME == "IW4" #define FEATURE_IW4 +#define EVEN_TRI_COUNT #elif GAME == "IW5" #define FEATURE_IW5 +#define EVEN_TRI_COUNT #elif GAME == "T5" #define FEATURE_T5 +#define EVEN_TRI_COUNT #elif GAME == "T6" #define FEATURE_T6 #endif @@ -26,6 +30,7 @@ #include JSON_HEADER #include "Asset/AssetRegistration.h" +#include "Utils/Alignment.h" #include "Utils/Logging/Log.h" #include "Utils/QuatInt16.h" #include "Utils/StringUtils.h" @@ -723,7 +728,14 @@ namespace } surface.triCount = static_cast(commonObject.m_faces.size()); + +#ifdef EVEN_TRI_COUNT + // Some games round up to an even tri count + const auto allocatedTriCount = utils::Align(surface.triCount, 2); + surface.triIndices = m_memory.Alloc(allocatedTriCount); +#else surface.triIndices = m_memory.Alloc(surface.triCount); +#endif xmodelToCommonVertexIndexLookup.reserve(static_cast(surface.triCount) * std::extent_v); for (auto faceIndex = 0u; faceIndex < surface.triCount; faceIndex++) @@ -815,6 +827,18 @@ namespace return false; } } + +#ifdef EVEN_TRI_COUNT + // The game makes sure to allows have an even triCount + // If the triCount is uneven, an additional tri is added that uses the last vertex three times + if (allocatedTriCount > surface.triCount) + { + assert(allocatedTriCount == surface.triCount + 1); + surface.triIndices[allocatedTriCount - 1].i[0] = surface.triIndices[surface.triCount - 1].i[2]; + surface.triIndices[allocatedTriCount - 1].i[1] = surface.triIndices[surface.triCount - 1].i[2]; + surface.triIndices[allocatedTriCount - 1].i[2] = surface.triIndices[surface.triCount - 1].i[2]; + } +#endif return true; }