24

我正在使用 html5 和 THREE.js 创建游戏,并且我有一个以“YXZ”的欧拉顺序旋转的相机。

这样相机就可以像头部一样上下左右旋转。就像第一人称视角一样。

使用此欧拉顺序,不使用 camera.rotation 中的 z 属性(始终为 0)。x 用于以弧度指定间距或纬度,y 用于描述经度。

我有许多目标以球形方式围绕用户移动,相机始终位于该球体的中心。假设球体的半径为 1000。

我的目标是计算相机正在看的位置和目标位置之间的角度。

我写了这段代码来计算两个向量之间的角度:

var A = new THREE.Vector3(1,0,0);
var B = new THREE.Vector3(0,1,0);

var theta = Math.acos( A.dot(B) / A.length() / B.length() );

// theta = PI/2;

我有目标的向量(targets[0].position)。

问题是我无法找到一种方法来获取相机正在寻找的矢量。

我查看了 Vector3.applyProjection 和 applyEuler 方法,并玩过但仍然无法获得任何好的结果。

我相信在进行任何预测之前,必须首先将欧拉顺序改回“XYZ”?我已经尝试过了,但我不知道该怎么做,文档很难理解。

假设如果相机直接向右看,那么我需要得到一个向量,该向量在当前旋转方向上距中心的 RADIUS 距离。

所以我最终会得到 2 个向量,我可以对它们进行计算!

4

4 回答 4

46

相机正在向下看它的内部负 z 轴。因此,创建一个指向负 z 轴的向量:

var vector = new THREE.Vector3( 0, 0, - 1 );

现在,对应用于相机的向量应用相同的旋转:

vector.applyQuaternion( camera.quaternion );

您可以像这样获得与目标的弧度角:

angle = vector.angleTo( target.position );

编辑:您现在可以得到相机看起来像这样的方向:

var vector = new THREE.Vector3(); // create once and reuse it!
...
camera.getWorldDirection( vector );

注意:通过传入vector存储结果的方法,该方法不必在THREE.Vector3每次调用该方法时都实例化一个新方法。

更新为three.js r.107

于 2013-02-11T16:33:01.020 回答
16

我花了很长时间试图弄清楚船长明显的问题。

这就是它最终对我有用的方式:

    vector = camera.getWorldDirection();
    theta = Math.atan2(vector.x,vector.z);

theta 以弧度为单位。这就是我如何让我的游戏角色以与摄像机相同的方式面对。getWorldDirection() 是相机上一个相当新的选项。

于 2015-12-17T08:29:29.913 回答
0

fluffybunny 搞定了。对他的绝妙想法稍作改动,您就可以获得以度数为单位的旋转:

var vector = camera.getWorldDirection();
angle = THREE.Math.radToDeg( Math.atan2(vector.x,vector.z) );  
于 2018-03-20T21:44:12.193 回答
0

我无法发表评论,但 fluffybunny 的回答非常有效。getWorldDirection()然后将该向量更改为弧度是要走的路。

于 2016-08-01T22:16:50.500 回答