編集:同じ問題を抱えているユーザーを支援するために、質問を言い換えました。
いくつかの球体を追加した three.js シーンがあります。
すべてのオブジェクト (シーン内にランダムに配置されている) がユーザーの画面に「正確に収まる」まで、カメラを特定の方向に動かしたいと考えています。
編集:同じ問題を抱えているユーザーを支援するために、質問を言い換えました。
いくつかの球体を追加した three.js シーンがあります。
すべてのオブジェクト (シーン内にランダムに配置されている) がユーザーの画面に「正確に収まる」まで、カメラを特定の方向に動かしたいと考えています。
私は私の問題に対する答えを見つけました!
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;
}
}
}