所以,我正盯着自己对这个问题视而不见,解决方案可能很容易。我只是看不到它。
tl; dr:我需要知道我的Object3D实例移动到哪个轴上,完全忽略了方向。
// Init code.
let last_position = new THREE.Vector3(0, 0, 0);
// Update code (called every frame)
if (object.position.distanceTo(last_position) > 0) {
// The object has moved.
let delta = object.position.clone().sub(last_position);
// ... what do I do now?
// - The object can rotate around its Y-axis. (looking around)
// - I'm trying to "remove" the rotation from the delta vector.
// Desired result:
if (delta.z > 0) // Object moved forward!
if (delta.z < 0) // Object moved backward!
if (delta.x > 0) // Object moved right
if (delta.x < 0) // Object moved left
}
last_position = object.position.clone();
基本上,我所要做的就是从delta矢量中有效地“移除”旋转。它基本上是Object3D.translateX / Y / Z函数的工作原理,但我没有更新对象,而是试图读取这些值。
提前致谢!
答案 0 :(得分:1)
您需要将delta矢量的基础从世界空间更改为对象空间(局部空间)。
每次更新场景图时计算的THREE.Object3D.matrixWorld
表示从对象空间到世界空间的转换。
要获得从世界空间到对象空间的转换,您需要invert the matrix。
在你的情况下,我们只对旋转/缩放感兴趣,它是matrixWorld
的左上角3x3矩阵。
所以我会一步一步地做这样的事情:
// compute delta ...
// transform delta in local space
var localToWorld = obj.matrixWorld;
var localToWorldRot = new THREE.Matrix3().setFromMatrix4(localToWorld);
var invLocalToWorldRot = new THREE.Matrix3().getInverse(localToWorldRot);
delta.applyMatrix3(invLocalToWorldRot);
检查this fiddle。 (使用WASDQE键)
如果您的想法是用它来检查玩家如何在网络游戏中移动以便您可以播放相应的动画,那么我会说这是错误的做法,原因如下:
相反,您应该考虑发送操作码进行扫描/旋转,并使用某种运动预测,以便客户端可以看到单位平稳移动。
您可能需要read this。
答案 1 :(得分:0)
我打赌你要找的是THREE.Object3D.getWorldPosition
。
此函数将为您提供对象的世界位置,无论其旋转方式如何,以及其父对象的旋转。
我可以想到几种方法,其中之一就是:
scene.autoUpdate = false
scene.updateMatrixWorld()
以下是computeDelta
的代码:
function computeDelta(obj) {
if (!obj.userData.lastPosition) {
obj.userData.lastPosition = new THREE.Vector3();
obj.getWorldPosition(obj.userData.lastPosition);
}
if (!obj.userData.delta) {
obj.userData.delta = new THREE.Vector3();
}
obj.userData.delta.copy(obj.userData.lastPosition);
obj.getWorldPosition(obj.userData.lastPosition);
return obj.userData.delta.sub(obj.userData.lastPosition).negate();
}
请注意,每个对象的计算都保存在userData
中。每帧调用THREE.Vector3.clone()
是一件坏事,因为它会创建一个新的向量。
检查this fiddle。
当您必须计算多个对象的增量时,此功能并不是很方便。在这种情况下,计算obj.onBeforeRender
中的增量更合适。