将相机移动以使所有物体完全适合视锥体内 - three.js

3

编辑:我已经重新表述我的问题,以帮助有同样问题的用户。

我有一个three.js场景,在其中添加了一些球体。

我想将相机朝着特定方向移动,直到所有随机放置在场景中的物体“完全适合”用户的屏幕。

1个回答

0

我已经找到了解决问题的答案!

1. 我在循环内移动相机(缩放到所需方向),并在每次重复时使用相机矩阵创建一个新的视锥体。

2. 我检查我的任何一个球是否与视锥体的平面相交。如果是,那就意味着我的某个对象的一部分在视锥体外面,因此我会中断循环并将相机移动到其最后位置。

以上方法也适用于任何对象(不仅仅是球),因为每个对象都有一个可以计算出来的边界球(虽然结果可能不是非常精确)。

缩小时,它也可以工作,您只需要将相机从对象移开,直到没有一个对象对所有平面都有负距离(负距离表示对象在视锥体平面之外)。

代码(仅适用于缩小 - 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; 
    } 

  } 
}  

那似乎是一种非常低效的解决方案。我正在寻找一种更直接的解决方案,使用相机的截锥面。 - Tara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接