From c5d3954bc8102867d3ffda3f145f2333f1f292a3 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 4 Nov 2023 20:32:52 +0100 Subject: [PATCH] Add `CalculateBoneOffsetMatrices` option to fix some animated model skeletons rendering #1862 --- Source/Engine/Tools/ModelTool/ModelTool.cpp | 20 +++++++++++--------- Source/Engine/Tools/ModelTool/ModelTool.h | 3 +++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Source/Engine/Tools/ModelTool/ModelTool.cpp b/Source/Engine/Tools/ModelTool/ModelTool.cpp index 116f63407..9954db2c3 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.cpp @@ -367,6 +367,7 @@ void ModelTool::Options::Serialize(SerializeStream& stream, const void* otherObj SERIALIZE(ImportLODs); SERIALIZE(ImportVertexColors); SERIALIZE(ImportBlendShapes); + SERIALIZE(CalculateBoneOffsetMatrices); SERIALIZE(LightmapUVsSource); SERIALIZE(CollisionMeshesPrefix); SERIALIZE(Scale); @@ -413,6 +414,7 @@ void ModelTool::Options::Deserialize(DeserializeStream& stream, ISerializeModifi DESERIALIZE(ImportLODs); DESERIALIZE(ImportVertexColors); DESERIALIZE(ImportBlendShapes); + DESERIALIZE(CalculateBoneOffsetMatrices); DESERIALIZE(LightmapUVsSource); DESERIALIZE(CollisionMeshesPrefix); DESERIALIZE(Scale); @@ -1418,6 +1420,15 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op SkeletonUpdater hierarchyUpdater(data.Nodes); hierarchyUpdater.UpdateMatrices(); + if (options.CalculateBoneOffsetMatrices) + { + // Calculate offset matrix (inverse bind pose transform) for every bone manually + for (SkeletonBone& bone : data.Skeleton.Bones) + { + CalculateBoneOffsetMatrix(data.Skeleton.Nodes, bone.OffsetMatrix, bone.NodeIndex); + } + } + // Move meshes in the new nodes for (int32 lodIndex = 0; lodIndex < data.LODs.Count(); lodIndex++) { @@ -1439,15 +1450,6 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op } } - // TODO: allow to link skeleton asset to model to retarget model bones skeleton for an animation - // use SkeletonMapping to map bones? - - // Calculate offset matrix (inverse bind pose transform) for every bone manually - /*for (SkeletonBone& bone : data.Skeleton.Bones) - { - CalculateBoneOffsetMatrix(data.Skeleton.Nodes, bone.OffsetMatrix, bone.NodeIndex); - }*/ - #if USE_SKELETON_NODES_SORTING // Sort skeleton nodes and bones hierarchy (parents first) // Then it can be used with a simple linear loop update diff --git a/Source/Engine/Tools/ModelTool/ModelTool.h b/Source/Engine/Tools/ModelTool/ModelTool.h index bad10b86e..f5d0b07a7 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.h +++ b/Source/Engine/Tools/ModelTool/ModelTool.h @@ -258,6 +258,9 @@ public: // Enable/disable importing blend shapes (morph targets). API_FIELD(Attributes="EditorOrder(85), EditorDisplay(\"Geometry\"), VisibleIf(nameof(ShowSkinnedModel))") bool ImportBlendShapes = false; + // Enable skeleton bones offset matrices recalculating. + API_FIELD(Attributes="EditorOrder(86), EditorDisplay(\"Geometry\"), VisibleIf(nameof(ShowSkinnedModel))") + bool CalculateBoneOffsetMatrices = false; // The lightmap UVs source. API_FIELD(Attributes="EditorOrder(90), EditorDisplay(\"Geometry\", \"Lightmap UVs Source\"), VisibleIf(nameof(ShowModel))") ModelLightmapUVsSource LightmapUVsSource = ModelLightmapUVsSource::Disable;