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