2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-04-21 10:58:44 +00:00

fix: properly load all root bones from gltf

This commit is contained in:
Jan Laupetin
2026-04-20 22:36:31 +01:00
parent 279ac9ee5c
commit 9aa91011a4

View File

@@ -405,13 +405,12 @@ namespace
return true;
}
static std::optional<unsigned> GetRootNodeForSkin(const JsonRoot& jRoot, const JsonSkin& skin)
static std::vector<unsigned> GetRootNodesForSkin(const JsonRoot& jRoot, const JsonSkin& skin)
{
if (!jRoot.nodes || skin.joints.empty())
return std::nullopt;
return {};
const auto jointCount = skin.joints.size();
auto rootCount = jointCount;
std::vector<bool> isRoot(jointCount, true);
for (const auto joint : skin.joints)
@@ -431,23 +430,20 @@ namespace
if (isRoot[foundChildJointIndex])
{
isRoot[foundChildJointIndex] = false;
rootCount--;
}
}
}
}
}
if (rootCount != 1)
throw GltfLoadException("Skins must have exactly one common root node");
std::vector<unsigned> result;
for (auto index = 0u; index < jointCount; index++)
{
if (isRoot[index])
return skin.joints[index];
result.emplace_back(skin.joints[index]);
}
return std::nullopt;
return std::move(result);
}
void ApplyNodeMatrixTRS(const JsonNode& node, float (&localOffsetRhc)[3], float (&localRotationRhc)[4], float (&scaleRhc)[3]) const
@@ -611,9 +607,11 @@ namespace
{
if (!ConvertJoint(
jRoot, skin, common, skinBoneOffset, childIndex, commonBoneOffset, globalTranslationEigenRhc, globalRotationEigenRhc, bone.scale))
{
return false;
}
}
}
return true;
}
@@ -625,7 +623,10 @@ namespace
if (!jRoot.nodes)
return false;
const auto rootNode = GetRootNodeForSkin(jRoot, skin).value_or(skin.joints[0]);
auto rootNodes = GetRootNodesForSkin(jRoot, skin);
if (rootNodes.empty())
rootNodes.emplace_back(skin.joints[0]);
const auto skinBoneOffset = static_cast<unsigned>(common.m_bones.size());
common.m_bones.resize(skinBoneOffset + skin.joints.size());
@@ -633,10 +634,16 @@ namespace
const Eigen::Quaternionf defaultRotation(1.0f, 0.0f, 0.0f, 0.0f);
constexpr float defaultScale[3]{1.0f, 1.0f, 1.0f};
for (const auto rootNode : rootNodes)
{
if (!ConvertJoint(jRoot, skin, common, skinBoneOffset, rootNode, std::nullopt, defaultTranslation, defaultRotation, defaultScale))
return false;
}
common.CalculateBoneLocalsFromGlobals();
// TODO: Reorder bones if necessary and prepare lookup
return true;
}