【问题标题】:What is the correct way to bind a Skeleton to a SkinnedMesh in three.js?在 three.js 中将骨架绑定到 SkinnedMesh 的正确方法是什么?
【发布时间】:2018-03-01 06:30:36
【问题描述】:

所以我有一组反向骨骼矩阵,一组我想绑定到蒙皮网格的骨骼,以及整个网格的世界变换矩阵。我可以正确应用骨骼,但不能为整个网格应用网格变换(同样,如果我应用网格变换,则蒙皮变换不正确)

此代码将具有正确的蒙皮(我可以调试渲染骨骼,旋转任意骨骼并且变换正确):

skeleton = new THREE.Skeleton( bones , boneInvMtx);
skeleton.pose();
mesh.bind( skeleton);

但是网格变换不起作用,当我将矩阵应用于 SkinnedMesh 对象时,它不起作用。强制更新世界矩阵没有任何效果(如果我在材质中禁用蒙皮,则可以很好地应用变换)。

mesh.applyMatrix(meshXform)

如果我将 meshXform 传递给绑定函数,则会应用变换,但现在所有骨骼变换都不正确(应用旋转会导致围绕世界轴旋转,而不是关节轴,并且不会从场景父)

mesh.bind( skeleton, meshXform );

对设置这样的网格的正确方法有什么想法吗?

我设置了骨骼(按层次结构排列)和一组这样的骨骼矩阵(我可以验证层次结构和矩阵是否正确):

const bones = [];
const boneInvMtx = [];

for(i=0;i<numBones;i++)
    bones.push(new Bone());
    boneInvMtx.push(boneData[i].invMtx);
};
for(i=0;i<numBones;i++)
    bones[boneData[i].parent].add(bone[i]);

我像这样创建几何体、材质和网格(将骨骼添加到几何体没有效果):

var geom = new THREE.BufferGeometry();
geom.setIndex(new THREE.BufferAttribute( indBuffer, 1 ));
geom.addAttribute( 'position', new THREE.BufferAttribute( posBuffer, 3 ) );
geom.addAttribute( 'normal', new THREE.BufferAttribute(normBuffer, 3) );
geom.addAttribute( 'uv', new THREE.BufferAttribute( uvBuffer, 2 ) );
geom.addAttribute( 'skinWeight', new THREE.BufferAttribute( weightsBuffer, 4 ) );
geom.addAttribute( 'skinIndex', new THREE.BufferAttribute( boneIndBuffer, 4 ) );

const nodeMaterial = new THREE.MeshNormalMaterial( { skinning:true} );
const mesh = new THREE.SkinnedMesh( geom, nodeMaterial );

【问题讨论】:

    标签: three.js


    【解决方案1】:

    啊,解决了。您需要将根骨骼添加到网格中:

    mesh.add(bones[0])
    

    【讨论】:

    • 我知道这是一个老问题.. 但请您详细说明它为什么有效?在我的测试中,按照您的建议使用网格和骨架助手更新助手而不是网格。乍一看,添加骨头听起来很奇怪,因为整个骨架已经被绑定了。感谢您的 cmets。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 2014-12-10
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多