mrdoob/three.js — Issue #1424: FitAll function implementation
Author: libe
Created: 2012-02-29 12:43:06+00:00
State: open

Hi, I have a new ```THREE.PerspectiveCamera``` and a ```THREE.TrackballControls``` in my scene and I am trying to implement a function that fit all the models in the scene maintaing the camera direction.

What I'm doing is:

* Compute scene bounding box
* Compute the "radius" of that bounding box getting half of its diagonal
* Compute an offset that move back the camera from the scene bounding box center that much needed to center a sphere with the "radius" of scene bounding box given the camera vertical field of view
* Update the camera position

With this code:

```javascript
function fitAll()
{
// Compute world AABB
var aabbMin = new THREE.Vector3();
var aabbMax = new THREE.Vector3();
for (var m = 0; m < meshes.length; m++)
{
var geo = meshes[m];

aabbMin.x = Math.min(aabbMin.x, geo.boundingBox.min.x);
aabbMin.y = Math.min(aabbMin.y, geo.boundingBox.min.y);
aabbMin.z = Math.min(aabbMin.z, geo.boundingBox.min.z);
aabbMax.x = Math.max(aabbMax.x, geo.boundingBox.max.x);
aabbMax.y = Math.max(aabbMax.y, geo.boundingBox.max.y);
aabbMax.z = Math.max(aabbMax.z, geo.boundingBox.max.z);
}

// Compute world AABB center
var aabbCenter = new THREE.Vector3();
aabbCenter.x = (aabbMax.x + aabbMin.x) * 0.5;
aabbCenter.y = (aabbMax.y + aabbMin.y) * 0.5;
aabbCenter.z = (aabbMax.z + aabbMin.z) * 0.5;

// Compute world AABB "radius"
var diag = new THREE.Vector3();
diag = diag.sub(aabbMax, aabbMin);
var radius = diag.length() * 0.5;

// Compute offset needed to move the camera back that much needed to center AABB
// camera.fov is the vertical field of view
var offset = radius / Math.tan(Math.PI / 180.0 * camera.fov * 0.5);

// Compute new camera position
var dir = camera.matrix.getColumnZ();
dir.multiplyScalar(offset);
var newPos = new THREE.Vector3();
newPos.add(aabbCenter, dir);

// Update camera
camera.position.set( newPos.x, newPos.y, newPos.z );
camera.lookAt(aabbCenter);
}

```

In another raw OpenGL viewer I wrote this trick worked very well, guess I am missing some three.js stuff. Any tips?

Thanks