gltf 应该如何计算动画矩阵?
gltf how are the animation matrices supposed to be computed?
我正在尝试让动画适用于复杂的 glTF 模型我正在尝试 RiggedFigure。
特别是我正在尝试按照此处所述计算 globalTransformOfJointNode
:https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_020_Skins.md
为此我有这个功能:
std::vector<Eigen::Matrix4f> GetGlobalJointMatrices(
const std::vector<Eigen::Matrix4f>& local_matrices,
const std::vector<Eigen::Matrix4f>& animation_matrices,
const std::map<int, int>& skeleton,
const int start_joint)
{
std::vector<Eigen::Matrix4f> skeleton_matrices(skeleton.size());
skeleton_matrices[0] = Eigen::Matrix4f::Identity();
for(auto [child, parent]: skeleton)
{
skeleton_matrices[child - start_joint] = skeleton_matrices[parent - start_joint] *
local_matrices[child - start_joint] * animation_matrices[child - start_joint];
}
return skeleton_matrices;
}
这里的local_matrices是指节点数组中描述的骨架中每个节点的局部变换。
animation_matrices
只是针对皮肤节点的动画。
对于两个数组,由于节点是连续的,因此索引i
包含对应于节点i + start_joint
的值。我已验证动画加载正确且顺序正确。
这是执行的结果:
skeleton_matrices[child - start_joint] = skeleton_matrices[parent - start_joint] * local_matrices[child - start_joint];
如果我尝试应用动画矩阵而不是我得到:
将动画矩阵放在其他点会导致类似的行为。
我确定我没有错误地加载矩阵,例如这些是针对节点 6 和 10 的矩阵:
animation targetting node:10
rotation: 0.0245355 -0.319997 0.9446 0.0687827
translation: -0.00234646 -0.0661734 0.0278567
scales: 1 1 1
node 6:
animation targetting node:6
rotation: -0.0341418 -0.319178 0.946171 -0.0414678
translation: -0.00145852 -0.0661988 0.0278567
我去手动验证了这些值是正确的,它们是。
我不明白哪里出了问题。
我觉得规范应该对此更清楚。所以事实证明你不应该应用 thr 节点的变换而只计算动画矩阵,动画矩阵已经包含预乘的节点矩阵。
长话短说:
这样做:
skeleton_matrices[child - start_joint] = skeleton_matrices[parent - start_joint] *
animation_matrices[child - start_joint];
我正在尝试让动画适用于复杂的 glTF 模型我正在尝试 RiggedFigure。
特别是我正在尝试按照此处所述计算 globalTransformOfJointNode
:https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_020_Skins.md
为此我有这个功能:
std::vector<Eigen::Matrix4f> GetGlobalJointMatrices(
const std::vector<Eigen::Matrix4f>& local_matrices,
const std::vector<Eigen::Matrix4f>& animation_matrices,
const std::map<int, int>& skeleton,
const int start_joint)
{
std::vector<Eigen::Matrix4f> skeleton_matrices(skeleton.size());
skeleton_matrices[0] = Eigen::Matrix4f::Identity();
for(auto [child, parent]: skeleton)
{
skeleton_matrices[child - start_joint] = skeleton_matrices[parent - start_joint] *
local_matrices[child - start_joint] * animation_matrices[child - start_joint];
}
return skeleton_matrices;
}
这里的local_matrices是指节点数组中描述的骨架中每个节点的局部变换。
animation_matrices
只是针对皮肤节点的动画。
对于两个数组,由于节点是连续的,因此索引i
包含对应于节点i + start_joint
的值。我已验证动画加载正确且顺序正确。
这是执行的结果:
skeleton_matrices[child - start_joint] = skeleton_matrices[parent - start_joint] * local_matrices[child - start_joint];
如果我尝试应用动画矩阵而不是我得到:
将动画矩阵放在其他点会导致类似的行为。 我确定我没有错误地加载矩阵,例如这些是针对节点 6 和 10 的矩阵:
animation targetting node:10
rotation: 0.0245355 -0.319997 0.9446 0.0687827
translation: -0.00234646 -0.0661734 0.0278567
scales: 1 1 1
node 6:
animation targetting node:6
rotation: -0.0341418 -0.319178 0.946171 -0.0414678
translation: -0.00145852 -0.0661988 0.0278567
我去手动验证了这些值是正确的,它们是。
我不明白哪里出了问题。
我觉得规范应该对此更清楚。所以事实证明你不应该应用 thr 节点的变换而只计算动画矩阵,动画矩阵已经包含预乘的节点矩阵。
长话短说: 这样做:
skeleton_matrices[child - start_joint] = skeleton_matrices[parent - start_joint] *
animation_matrices[child - start_joint];