2013-02-22 219 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