C# 骨架蒙皮算法将模型上的所有内容聚集在一起';脚

C# 骨架蒙皮算法将模型上的所有内容聚集在一起';脚,c#,opengl,assimp,skeletal-animation,C#,Opengl,Assimp,Skeletal Animation,我正在尝试使用Collada文件中存储的骨骼动画实现蒙皮,虽然我成功地加载了骨骼动画并在没有正确蒙皮的情况下渲染了模型,但我不明白为什么在应用我的蒙皮算法时,所有部分都聚集在模型的脚部,或者极度变形。整个项目存储在上以供参考(蒙皮分支) 我相信顶点着色器是正确的,因为如果我将标识变换传递给骨骼,我将获得默认姿势模型,它将根据.dae文件中不知何故损坏的骨骼动画计算骨骼变换。这就是我的问题所在,而不是模型在默认姿势下的外观: 我相信我的问题是在应用递归骨骼变换时: public

我正在尝试使用Collada文件中存储的骨骼动画实现蒙皮,虽然我成功地加载了骨骼动画并在没有正确蒙皮的情况下渲染了模型,但我不明白为什么在应用我的蒙皮算法时,所有部分都聚集在模型的脚部,或者极度变形。整个项目存储在上以供参考(蒙皮分支)

我相信顶点着色器是正确的,因为如果我将标识变换传递给骨骼,我将获得默认姿势模型,它将根据
.dae
文件中不知何故损坏的骨骼动画计算骨骼变换。这就是我的问题所在,而不是模型在默认姿势下的外观:

我相信我的问题是在应用递归骨骼变换时:

        public void Update(double deltaSec)
        {
            if (CurrentAnimationName is null) return;

            var anim = animations[CurrentAnimationName];
            currentAnimationSec = (currentAnimationSec + deltaSec) % anim.Duration.TotalSeconds;

            void calculateBoneTransforms(BoneNode boneNode, Matrix4x4 parentTransform)
            {
                var bone = anim.Bones.FirstOrDefault(b => b.Id == boneNode.Id);
                var nodeTransform = bone?[TimeSpan.FromSeconds(currentAnimationSec)] ?? boneNode.Transform;
                var globalTransform = parentTransform * nodeTransform;

                if (boneNode.Id >= 0)
                    for (int meshIdx = 0; meshIdx < perMeshData.Length; ++meshIdx)
                        perMeshData[meshIdx].FinalBoneMatrices[boneNode.Id] = globalTransform * perMeshData[meshIdx].boneOffsetMatrices[boneNode.Id];

                foreach (var child in boneNode.Children)
                    calculateBoneTransforms(child, globalTransform);
            }
            calculateBoneTransforms(rootBoneNode, Matrix4x4.Identity);
        }
            BoneNode visitTransforms(Node node, Matrix4x4 mat)
            {
                var boneNode = new BoneNode
                {
                    Children = new BoneNode[node.ChildCount],
                    Id = boneIds.TryGetValue(node.Name, out var id) ? id : -1,
                    Transform = Matrix4x4.Transpose(node.Transform.ToNumerics()),
                };

                mat = node.Transform.ToNumerics() * mat;
                foreach (var meshIndex in node.MeshIndices)
                    transformsDictionary[scene.Meshes[meshIndex]] = mat;
                int childIdx = 0;
                foreach (var child in node.Children)
                    boneNode.Children[childIdx++] = visitTransforms(child, mat);

                return boneNode;
            }
            rootBoneNode = visitTransforms(scene.RootNode, Matrix4x4.Identity);

我相信骨骼到顶点的权重已正确收集并上载到着色器,并且最终的骨骼阵列均匀性已正确上载(但可能计算不正确)。我也不确定矩阵乘法的顺序,也不确定上传到着色器时是否要转置任何内容,尽管我每次都尝试过两种方法。

如果有人遇到类似问题,我的问题是,与其他变换链的计算方式相比,我的关键帧骨骼变换被转置,所以当我将它们相乘时,一切都变得疯狂。所以,请跟踪哪些矩阵是左手矩阵,哪些是右手矩阵

我还不太了解骨骼/递归变换,但也许可以先尝试使其非递归?只需变换附加到“根”骨骼的骨骼,而不首先变换其他骨骼?由于blender导出场景的方式,根已经有3个变换深度。