Adjusting the camera for the visible form Three.js

I have a CubeGeometry that the camera is looking at, and I want the camera to increase so that the cube is fully visible, but no more.

My initial attempt was to convert the vertices of a cube to a camera coordinate system,

function toScreenXY(position, camera) { var pos = position.clone(); var projScreenMat = new THREE.Matrix4(); projScreenMat.multiply(camera.projectionMatrix, camera.matrixWorldInverse); projScreenMat.multiplyVector3( pos ); return pos; } function ScaleInView() { camera.fov = 0.0; for (var i=0; i<8; i++) { proj2d = toScreenXY(cube.geometry.vertices[i],camera); angle = 57.296 * Math.max(Math.atan(proj2d.x/proj2d.z), Math.atan(proj2d.y/proj2d.z)); camera.fov = Math.max(camera.fov,angle); } camera.updateProjectionMatrix(); } 

I thought this would work, but sometimes it is too small, and sometimes too large (depending on the position of the camera).

I also need to do this for a spelling camera.

Edit: I know how to do this when the cube is facing the camera, I am looking for a way to do this when the camera moves to some arbitrary position (r, theta, phi) (spherical polar coordinates; r is actually constant for my purposes).

+5
javascript
source share
2 answers

Multiplication using camera.matrixWorldInverse gives the vector in the coordinates of the camera, but, in essence, does not apply.

 function toCameraCoords(position) { return camera.matrixWorldInverse.multiplyVector3(position.clone()); } 

Then we can find the smallest angle that will correspond to all the corners of the box in the scene. arctan (Dx / Dz) gives the angle BCD, where B is what the camera is looking at, C is the camera position, D is the position of the object that you want to see in camera coordinates.

In my case, the following ensures that the cube framebox is fully visible.

 function ScaleInView() { var tmp_fov = 0.0; for (var i=0; i<8; i++) { proj2d = toCameraCoords(boundbox.geometry.vertices[i]); angle = 114.59 * Math.max( // 2 * (Pi / 180) Math.abs(Math.atan(proj2d.x/proj2d.z) / camera.aspect), Math.abs(Math.atan(proj2d.y/proj2d.z)) ); tmp_fov = Math.max(tmp_fov, angle); } camera.fov = tmp_fov + 5; // An extra 5 degrees keeps all lines visible camera.updateProjectionMatrix(); } 
+2
source share

Perspective camera . If the camera is in the center and is viewing a cube, define

dist = distance from the camera to the front surface (important!) of the cube

and

height = cube height.

If you set the camera field of view as follows

 fov = 2 * Math.atan( height / ( 2 * dist ) ) * ( 180 / Math.PI ); 

then the height of the cube will correspond to the visible height.

Spelling camera . If the camera is in the center and is viewing a cube, define

aspect = aspect ratio of your window (i.e. width / height)

and

height = cube height.

Then create a camera as follows:

 camera = new THREE.OrthographicCamera( -aspect * height/2, aspect * height/2, height/2, -height/2, near, far ); 

The height of the cube will correspond to the visible height.

In any case, if the camera is not centered or otherwise views the cube at an angle, the problem becomes more complex.

In addition, if the window is narrower than tall, then the width is a deterrent, and the problem is more complicated.

+3
source share

All Articles