4

我正在尝试构建一个组件,它可以显示 SkinMesh 骨骼的位置和方向,但遇到了一些障碍。不知何故,我无法确定骨骼的全局位置。

我努力了:

this.updateMatrixWorld(true);
this.traverse(function (bone) {
    var twinGlobalPos = new THREE.Vector3().getPositionFromMatrix(bone.matrixWorld);
    console.log(typeof (bone), "GlobalPos", twinGlobalPos.x, twinGlobalPos.y, twinGlobalPos.z);
});

和明显的变化,不幸的是,这似乎不起作用,所有骨骼,除了根报告的位置为 0,0,0。根骨骼报告与 SkinMesh 相同的全局位置

我究竟做错了什么?有其他方法吗?

4

2 回答 2

5

好的,我自己找到了答案。

SkinMesh 重载了 updateMatrixWorld 的实现,它不对 THREE.Bone 的任何实例执行更新。相反,它委托给骨骼的更新方法,该方法维护一个矩阵“skinmatrix”。

Skinmatrix 的工作方式类似于 worldMatrix,但使用 SkinnedMesh 作为全局参考而不是场景。结合 SkinnedMesh 的 worldMatrix 和骨骼的 SkinMatrix 似乎可以解决问题。

this.updateMatrixWorld(true);
// assuming this is a SkinnedMesh
var meshGlobal = new THREE.Vector3().setFromMatrixPosition(this.matrixWorld);
this.traverse(function (bone) {
    if(bone instanceof THREE.Bone) {
        var twinGlobalPos = new THREE.Vector3().setFromMatrixPosition(bone.skinMatrix).add(meshGlobal);
        console.log(typeof (bone), "GlobalPos", twinGlobalPos.x, twinGlobalPos.y, twinGlobalPos.z);
    }
});

上面的代码似乎可以解决问题。我可以明白为什么选择了这种设计,但它确实提出了一个问题,也许覆盖 THREE.Bone 上的andlocalToWorld方法worldToLocal将是一个半解决方案?

于 2013-05-22T12:56:42.393 回答
0

The chosen answer might be outdated because in current version multiple animations are now supported. Don't edit the original answer because people use different versions of three.js

this line (from Anton's code):

var twinGlobalPos = new THREE.Vector3().setFromMatrixPosition(bone.skinMatrix).add(meshGlobal);

should be now looking like that:

 var twinGlobalPos = new THREE.Vector3().setFromMatrixPosition(bone.animationCache.animations[animation.data.name].originalMatrix).add(meshGlobal);

or just

var twinGlobalPos = new THREE.Vector3().setFromMatrixPosition(bone.position).add(meshGlobal);
于 2015-01-23T22:57:23.687 回答