问题 Three.js围绕物体旋转相机(可能会移动)


我有一个相机在场景中以几种不同的方式移动。相机应围绕目标位置旋转。就我而言,这是用户定位的网格上的一个点。因为相机通常不需要相对于这一点移动,所以我无法在这里使用枢轴点: https://github.com/mrdoob/three.js/issues/1830。我当前的解决方案使用以下代码:

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,因为重新定位。我们希望能够删除该行。

如果我们在没有lookAt的情况下使用上面的代码,我们会围绕这一点进行旋转,但是我们不会看到这一点。我的理解是我的方法应该像摄像机本身旋转一样旋转摄像机的视图,而是相机只旋转少量。谁能帮我理解什么是错的?

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

我的想法是我可以转换到原点(我的目标位置),旋转我想要的数量,然后转换回起始位置。由于轮换,我希望看到原点的新位置。

事实上,我现在正在测试它而没有使用转换矩阵,所以矩阵乘法线是:

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

它似乎表现得一样。感谢您的帮助到目前为止!

还有一件事!问题的一部分是当摄像机表现得非常接近北极或南极时。我正在寻找一种“自由漫游”的感觉。


10695
2018-02-22 17:38


起源

(1) camera.lookAt( vector ) 不接受 matrix 作为一个论点。 (2)你究竟想做什么? - WestLangley
对不起,我试图清理我的代码时搞砸了!我编辑了帖子以反映正确的信息 - maaachine
我正在寻找完全相同的东西..在2017年。我可能错过了一些东西,但我真的希望我不必拿出我的Calc教科书并重新访问向量和3D trig。我只是希望能够“自由”地围绕一个物体旋转。确实有点棘手。 - dylnmc


答案:


将以下内容放在渲染循环中:

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.OrbitControls 要么 THREE.TrackballControls。请参阅three.js示例。


10
2018-02-22 18:32



嗯,这样的事可能有用。不过,我需要这个在三个方向自由移动。其中一个关键问题是它处理极点附近的旋转方式。我已经更新了原帖,以澄清这一点! (希望) - maaachine


你所指的万向节锁(重定向)是因为在相机外观的默认实现中使用了欧拉角。如果你设置

camera.useQuaternion = true;

在你打电话之前,不会使用欧拉角。这会解决你的问题吗?


0
2018-02-22 18:30



这似乎没有解决它,但谢谢! - maaachine