13

シーン内でいくつかの異なる方法で動くカメラがあります。カメラはターゲット位置を中心に回転する必要があります。私の場合、これはユーザーがターゲットにしたメッシュ上のポイントです。カメラは通常、このポイントに対して相対的に移動する必要がないため、ここでピボットのアイデアを使用できませんでした: 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);

そしてそれは同じように振る舞っているようです。これまでのすべての助けに感謝します!

もう一つ!問題の一部は、カメラが北極または南極の近くでひどく動作する場合です。「フリーローミング」のような感覚を探しています。

4

2 に答える 2

12

レンダー ループに次のコードを追加します。

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 の例を参照してください。

于 2013-02-22T18:32:34.907 に答える
0

あなたが参照しているジンバル ロック (向きの変更) は、カメラ ルックアットの既定の実装でオイラー角が使用されているためです。設定した場合

camera.useQuaternion = true;

lookat を呼び出す前に、オイラー角は使用されません。これで問題は解決しますか?

于 2013-02-22T18:30:16.110 に答える