获得骨骼的全球位置

时间:2013-05-22 12:14:06

标签: three.js

我正在尝试构建一个可以显示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相同的全局位置

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

2 个答案:

答案 0 :(得分: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);
    }
});

上面的代码似乎可以解决问题。我可以看到为什么选择了这个设计,但它确实提供了一个 gotcha ,可能会覆盖THREE上的localToWorldworldToLocal方法.Bone将是一个半解决方案?< / p>

答案 1 :(得分:0)

所选答案可能已过时,因为在当前版本中现在支持多个动画。不要编辑原始答案,因为人们使用不同版本的three.js

这一行(来自Anton的代码):

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

现在看起来应该是这样的:

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

或只是

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