移动相机使所有对象完全适合平截头体 - three.js

时间:2016-02-02 14:49:45

标签: javascript three.js intersect plane frustum

编辑:我已经改述了我的问题,以帮助用户解决同样的问题。

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

我想将相机移向特定方向,直到所有物体(随机定位在场景内)完全“恰好适合”用户的屏幕。

1 个答案:

答案 0 :(得分: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; 
    } 

  } 
}