【问题标题】:GLTF animations result in distorted meshGLTF 动画导致网格变形
【发布时间】:2022-06-15 01:33:58
【问题描述】:

我已经下载了 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);
    }
}

【问题讨论】:

    标签: c# gltf


    【解决方案1】:

    显然没有必要自己在 SharpGLTF 中编写动画。这是 VPenades 在 SharpGLTF Discord 上的有用信息

    node.GetLocalTransform(动画,时间);和 node.GetWorldTransform(动画,时间);取决于你是哪一个 需要,是那些给你你需要的动画变换的东西 更新你的骨骼,你不需要所有的代码。

    但是这些调用相当慢,它们在那里是为了方便,但快速的方法是使用 node.GetCurveSamplers 一次,然后重用它来获取矩阵

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    • 这是 Github 上的项目github.com/vpenades/SharpGLTF 不幸的是我找不到任何文档
    【解决方案2】:

    似乎正确的矩阵运算是: m0i * m0 * bindm * m

    其中 m0i 是 m0 矩阵的逆矩阵,m0 是从树中收集的矩阵(未应用动画),bindm 是绑定矩阵,m 是从应用了动画的树中收集的 slerped 矩阵。

    (但我实际上使用的是 ri * m0i * m0 * bindm * m * resize,其中 ri 和 resize 用于正确调整模型大小)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-31
      • 2020-01-31
      • 2018-10-06
      • 2021-12-31
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 2019-05-09
      相关资源
      最近更新 更多