From 4cdf568f5b390d21777d3d9cfe4443faf07f5799 Mon Sep 17 00:00:00 2001 From: Jan Laupetin Date: Thu, 17 Jul 2025 18:09:19 +0100 Subject: [PATCH] chore: set proper flags and data for animated models --- src/Common/Game/T5/T5_Assets.h | 9 +++++ src/Common/Game/T6/T6_Assets.h | 8 ++++ .../XModel/LoaderXModel.cpp.template | 39 +++++++++++++++++++ .../XModel/XModelDumper.cpp.template | 2 +- 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/Common/Game/T5/T5_Assets.h b/src/Common/Game/T5/T5_Assets.h index 81fdfd7b..d06015db 100644 --- a/src/Common/Game/T5/T5_Assets.h +++ b/src/Common/Game/T5/T5_Assets.h @@ -540,6 +540,15 @@ namespace T5 XSurfaceCollisionTree* collisionTree; }; + enum XSurfaceFlag + { + XSURFACE_FLAG_QUANTIZED = 0x1, + XSURFACE_FLAG_SKINNED = 0x2, + XSURFACE_FLAG_CONSTANT_COLOR = 0x4, + XSURFACE_FLAG_DEFORMED = 0x80, + XSURFACE_FLAG_STREAMED = 0x8000, + }; + struct XSurfaceTri { uint16_t i[3]; diff --git a/src/Common/Game/T6/T6_Assets.h b/src/Common/Game/T6/T6_Assets.h index 28de10dc..1a7b9b0e 100644 --- a/src/Common/Game/T6/T6_Assets.h +++ b/src/Common/Game/T6/T6_Assets.h @@ -2743,6 +2743,14 @@ namespace T6 float transWeight; }; + enum XSurfaceFlag + { + XSURFACE_FLAG_QUANTIZED = 0x1, + XSURFACE_FLAG_SKINNED = 0x2, + XSURFACE_FLAG_CONSTANT_COLOR = 0x4, + XSURFACE_FLAG_DEFORMED = 0x80, + }; + struct XSurfaceVertexInfo { int16_t vertCount[4]; diff --git a/src/ObjLoading/XModel/LoaderXModel.cpp.template b/src/ObjLoading/XModel/LoaderXModel.cpp.template index 27930189..2e30b730 100644 --- a/src/ObjLoading/XModel/LoaderXModel.cpp.template +++ b/src/ObjLoading/XModel/LoaderXModel.cpp.template @@ -72,6 +72,9 @@ namespace auto* xmodel = m_memory.Alloc(); xmodel->name = m_memory.Dup(assetName.c_str()); + m_materials.clear(); + m_surfaces.clear(); + AssetRegistration registration(assetName, xmodel); if (!LoadFromFile(*file.m_stream, *xmodel, context, registration)) { @@ -340,6 +343,12 @@ namespace } } + // TODO: Dirty hack, this is not necessarly always related to the name + if (strstr(xmodel.name, "viewhands")) + { + memset(xmodel.trans, 0, sizeof(float) * 4 * (xmodel.numBones - xmodel.numRootBones)); + } + return true; } @@ -730,10 +739,18 @@ namespace // Since bone weights are sorted by weight count, the last must have the highest weight count const auto maxWeightCount = common.m_vertex_bone_weights[xmodelToCommonVertexIndexLookup[xmodelToCommonVertexIndexLookup.size() - 1]].weightCount; + if (maxWeightCount == 0) // XModel is rigid + { CreateVertListData(surface, xmodelToCommonVertexIndexLookup, common); + } else if (maxWeightCount < std::extent_v + 1) + { CreateVertsBlendData(surface, xmodelToCommonVertexIndexLookup, common); +#if defined(FEATURE_T5) || defined(FEATURE_T6) + surface.flags |= XSURFACE_FLAG_SKINNED | XSURFACE_FLAG_DEFORMED; +#endif + } else { std::cerr << std::format("Models must not have vertices that are influenced by more than {} bones\n", @@ -916,6 +933,24 @@ namespace #endif } +#if defined(FEATURE_T5) || defined(FEATURE_T6) + static bool HasAnySkinnedSurfs(const XModel& xmodel) + { + for (auto lodIndex = 0u; lodIndex < xmodel.numLods; lodIndex++) + { + const auto& lod = xmodel.lodInfo[lodIndex]; + for (auto surfIndex = lod.surfIndex; surfIndex < lod.numsurfs; surfIndex++) + { + const auto& surf = xmodel.surfs[lod.surfIndex + surfIndex]; + if (surf.flags & XSURFACE_FLAG_DEFORMED) + return true; + } + } + + return false; + } +#endif + bool CreateXModelFromJson(const JsonXModel& jXModel, XModel& xmodel, AssetCreationContext& context, AssetRegistration& registration) { constexpr auto maxLods = std::extent_v; @@ -964,6 +999,10 @@ namespace else xmodel.collLod = -1; +#if defined(FEATURE_T5) || defined(FEATURE_T6) + xmodel.lodRampType = HasAnySkinnedSurfs(xmodel) ? XMODEL_LOD_RAMP_SKINNED : XMODEL_LOD_RAMP_RIGID; +#endif + if (jXModel.physPreset) { auto* physPreset = context.LoadDependency(jXModel.physPreset.value()); diff --git a/src/ObjWriting/XModel/XModelDumper.cpp.template b/src/ObjWriting/XModel/XModelDumper.cpp.template index 5426b73a..0cbc0a30 100644 --- a/src/ObjWriting/XModel/XModelDumper.cpp.template +++ b/src/ObjWriting/XModel/XModelDumper.cpp.template @@ -282,7 +282,7 @@ namespace void AddXModelMaterials(XModelCommon& out, DistinctMapper& materialMapper, const XModel* model) { - for (auto surfaceMaterialNum = 0; surfaceMaterialNum < model->numsurfs; surfaceMaterialNum++) + for (auto surfaceMaterialNum = 0u; surfaceMaterialNum < model->numsurfs; surfaceMaterialNum++) { Material* material = model->materialHandles[surfaceMaterialNum]; if (materialMapper.Add(material))