GLTF 动画导致网格扭曲
我已经下载了 GLTF 示例 Fox https://github。 com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Fox 并试图通过 SharpGLTF 使动画正常工作。
到目前为止,当传入联合 worldTransform * inverseBindMatrix 时看起来很好
这是计算骨骼变换的代码。我希望有人知道可能出了什么问题,我已经尝试让它工作 3 天了,但不知道该去哪里了。
private void UpdateBone (Node node, Matrix4x4 parentTransformation) {
Skin skin = skeleton.skin;
(Node joint, System.Numerics.Matrix4x4 inverseBindMatrix) = skin.GetJoint(0);
for (var i = 0; i < skin.JointsCount; i++) {
(joint, inverseBindMatrix) = skin.GetJoint(i);
if (joint.Name == node.Name) break;
}
Matrix4x4 scale = Matrix4x4.Identity;
Matrix4x4 rotation = Matrix4x4.Identity;
Matrix4x4 translation = Matrix4x4.Identity;
IEnumerable<AnimationChannel> jointChannels = currentAnimation.logicalAnimation.FindChannels(joint);
foreach (var jointChannel in jointChannels) {
if (jointChannel.GetTranslationSampler() is { } translationSampler) {
translation = Matrix4x4.Translation(Vector3.FromSystemVector(translationSampler.GetLinearKeys().First().Value));
}
if (jointChannel.GetRotationSampler() is { } rotationSampler) {
rotation = Matrix4x4.RotationQuaternion((Quaternion) rotationSampler.GetLinearKeys().First().Value);
}
if (jointChannel.GetScaleSampler() is { } scaleSampler) {
scale = Matrix4x4.Scaling(Vector3.FromSystemVector(scaleSampler.GetLinearKeys().First().Value));
}
}
Matrix4x4 localTransformation = translation * rotation * scale;
Matrix4x4 globalTransformation = parentTransformation * localTransformation;
skeletonState.BoneTransformations[node.LogicalIndex] = Matrix4x4.Identity;
foreach (var child in node.VisualChildren) {
if (child is null || !child.IsSkinJoint) continue;
UpdateBone(child, globalTransformation);
}
}
I've downloaded the GLTF sample Fox https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Fox
and been trying to get the animations working through SharpGLTF.
So far it looks fine when pass in the joint worldTransform * inverseBindMatrix
But when trying the first frame of the animation looks all distorted
Here is the code that calculates the bone transformations. I hope anyone knows what might be wrong, I've been trying to get it to work for 3 days and don't know where to look anymore.
private void UpdateBone (Node node, Matrix4x4 parentTransformation) {
Skin skin = skeleton.skin;
(Node joint, System.Numerics.Matrix4x4 inverseBindMatrix) = skin.GetJoint(0);
for (var i = 0; i < skin.JointsCount; i++) {
(joint, inverseBindMatrix) = skin.GetJoint(i);
if (joint.Name == node.Name) break;
}
Matrix4x4 scale = Matrix4x4.Identity;
Matrix4x4 rotation = Matrix4x4.Identity;
Matrix4x4 translation = Matrix4x4.Identity;
IEnumerable<AnimationChannel> jointChannels = currentAnimation.logicalAnimation.FindChannels(joint);
foreach (var jointChannel in jointChannels) {
if (jointChannel.GetTranslationSampler() is { } translationSampler) {
translation = Matrix4x4.Translation(Vector3.FromSystemVector(translationSampler.GetLinearKeys().First().Value));
}
if (jointChannel.GetRotationSampler() is { } rotationSampler) {
rotation = Matrix4x4.RotationQuaternion((Quaternion) rotationSampler.GetLinearKeys().First().Value);
}
if (jointChannel.GetScaleSampler() is { } scaleSampler) {
scale = Matrix4x4.Scaling(Vector3.FromSystemVector(scaleSampler.GetLinearKeys().First().Value));
}
}
Matrix4x4 localTransformation = translation * rotation * scale;
Matrix4x4 globalTransformation = parentTransformation * localTransformation;
skeletonState.BoneTransformations[node.LogicalIndex] = Matrix4x4.Identity;
foreach (var child in node.VisualChildren) {
if (child is null || !child.IsSkinJoint) continue;
UpdateBone(child, globalTransformation);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
显然没有必要在 SharpGLTF 中自己编写动画。以下是 VPenades 关于 SharpGLTF Discord 的有用信息
Apparently there is no need to compose the animations myself in SharpGLTF. Here is the helpful message from VPenades on the SharpGLTF Discord
看来正确的矩阵运算是:
m0i * m0 * bindm * m
其中 m0i 是 m0 矩阵的逆矩阵,m0 是从树中收集的矩阵(未应用动画),bindm 是绑定矩阵,m 是从应用了动画的树中收集的 slerped 矩阵。
(但我实际上使用 ri * m0i * m0 * bindm * m * resize,其中 ri 和 resize 可以正确调整模型大小)
It seems that correct matrix operation is:
m0i * m0 * bindm * m
where m0i is inverse of m0 matrix, m0 is the matrix collected from the tree (without animations applied), bindm is the bind matrix, and m is the slerped matrix collected from the tree with animations applied.
(but I'm actually using ri * m0i * m0 * bindm * m * resize, where ri and resize are there to resize the model correctly)