我正在尝试构建一个可以显示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相同的全局位置
我做错了什么?还有其他方法吗?
答案 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上的localToWorld
和worldToLocal
方法.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);