2013-02-22 467 views
10

我有一个在场景中以几种不同方式移动的相机。相机应该围绕目标位置旋转。就我而言,这是用户定位的网格上的一个点。由于相机通常不需要相对于此点移动,因此我无法在此处使用数据透视图:https://github.com/mrdoob/three.js/issues/1830。我目前的解决方案使用下面的代码:Three.js围绕物体旋转相机(可能会移动)

var rotationY = new THREE.Matrix4(); 
var rotationX = new THREE.Matrix4(); 
var translation = new THREE.Matrix4(); 
var translationInverse = new THREE.Matrix4(); 
var matrix = new THREE.Matrix4(); 
function rotateCameraAroundObject(dx, dy, target) { 
    // collect up and right vectors from camera perspective 
    camComponents.up = rotateVectorForObject(new THREE.Vector3(0,1,0), camera.matrixWorld); 
    camComponents.right = rotateVectorForObject(new THREE.Vector3(1,0,0), camera.matrixWorld); 

    matrix.identity(); 

    rotationX.makeRotationAxis(camComponents.right, -dx); 
    rotationY.makeRotationAxis(camComponents.up, -dy); 
    translation.makeTranslation(
     target.position.x - camera.position.x, 
     target.position.y - camera.position.y, 
     target.position.z - camera.position.z); 
    translationInverse.getInverse(translation); 

    matrix.multiply(translation).multiply(rotationY).multiply(rotationX).multiply(translationInverse); 
    camera.applyMatrix(matrix); 
    camera.lookAt(target.position); 
} 

的问题是,我们不希望使用的lookAt,因为重新定位。我们希望能够删除该行。

如果我们使用上面的代码而没有看,我们围绕这个点旋转,但我们没有看到这一点。我的理解是,我的方法应该旋转相机的视图,就像相机本身旋转一样,但相机只能旋转一小部分。任何人都可以帮助我了解什么是错的?

编辑:清理原来的帖子和代码,希望澄清我的问题。

我的想法是,我可以翻译成原点(我的目标位置),旋转我想要的数量,然后转回到开始位置。由于轮换,我期望在一个新的位置看起源。

其实,我现在测试它没有被使用的转换矩阵,因此矩阵乘法线:

matrix.multiply(rotationY).multiply(rotationX); 

,它似乎要表现相同。感谢所有帮助!

还有一件事!问题的一个部分是,当相机的行为严重接近北极或南极时。我正在寻找一种“自由漫游”的感觉。

+0

(1)'camera.lookAt(vector)'不会将'matrix'作为参数。 (2)你究竟想要做什么? – WestLangley 2013-02-22 18:29:50

+0

我试图清理我的代码时搞砸了,对不起!我已编辑帖子以反映正确的信息 – maaachine 2013-02-22 18:58:34

+0

我在2017年寻找完全相同的东西..我可能错过了一些东西,但我真的希望我不必拔出我的Calc教科书并重新访问媒介和3D触发。我只是想能够围绕物体“自由”旋转。确实,这有点棘手。 – dylnmc 2017-05-26 20:40:08

回答

0

您提到的Gimbal锁(重新定向)是因为在相机预览的默认实现中使用了欧拉角。如果你在你打电话之前设置

camera.useQuaternion = true; 

然后euler角度将不会被使用。这会解决你的问题吗?

+0

这似乎没有解决它,但谢谢你! – maaachine 2013-02-22 19:26:41

9

把你的渲染循环如下:

camera.position.x = target.position.x + radius * Math.cos(constant * elapsedTime);   
camera.position.z = target.position.z + radius * Math.sin(constant * elapsedTime); 
camera.lookAt(target.position); 

renderer.render(scene, camera); 

或者,你可以使用THREE.OrbitControlsTHREE.TrackballControls。请参阅three.js示例。

+0

嗯,像这样的东西可能会起作用。不过,我需要在三个方向上自由移动。其中一个关键问题是它在极点附近处理旋转的方式。我已经更新了原文,以澄清这一点! (希望) – maaachine 2013-02-22 19:32:04