3

編集:同じ問題を抱えているユーザーを支援するために、質問を言い換えました。

いくつかの球体を追加した three.js シーンがあります。

すべてのオブジェクト (シーン内にランダムに配置されている) がユーザーの画面に「正確に収まる」まで、カメラを特定の方向に動かしたいと考えています。

4

1 に答える 1

0

私は私の問題に対する答えを見つけました!

1.ループ内でカメラを移動し (目的の方向にズーム)、繰り返しのたびに、カメラのマトリックスを使用して新しい錐台を作成します。

2.球体のいずれかが錐台の平面と交差するかどうかを確認します。そうであれば、オブジェクトの一部が錐台の外側にあることを意味するため、ループを中断してカメラを最後の位置に移動します。

すべてのオブジェクトには計算可能なboundingSphereがあるため、上記は(球だけでなく)任意のオブジェクトでも機能する可能性があります(ただし、結果はあまり正確ではない場合があります)。

ズームアウトするときも機能します。すべての平面から負の距離がなくなるまで、オブジェクトからカメラを移動する必要があります (負の距離は、オブジェクトが錐台の平面の「外側」であることを意味します)。

コード (縮小のみ - r72) :

var finished = false;
var camLookingAt = /* calc. */ ;

while( finished === false ){

var toDirection= camera.position.clone().sub(camLookingAt.clone());
toDirection.setLength(vec.length() - 1); // reduce length for zooming out
camera.position.set(toDirection.x, toDirection.y, toDirection.z);

camera.updateMatrix(); // make sure camera's local matrix is updated
camera.updateMatrixWorld(); // make sure camera's world matrix is updated

var frustum = new THREE.Frustum();
frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ) );

for (var j = frustum.planes.length - 1; j >= 0; j--) {  
  var p = frustum.planes[j];  
  for (var i = myMeshSpheres.length - 1; i >= 0; i--) { 
    var sphere = new THREE.Sphere(myMeshSpheres[0].position.clone(), myMeshSpheres[0].radius); 

    if( p.distanceToSphere(sphere) < 1 ){ // if is negative means part of sphere is outside plane/frustum
      finished = true; 
    } 

  } 
}  
于 2016-02-02T23:53:24.270 に答える