How can I place Camera to show all objects?

I have a scene with multiple models (GLTF models) and would like to place camera in order to see all of the models placed randomly on screen.How can I achieve that?
Thanks in advance

you find some code and pointers here: Camera Zoom To Fit Object - #35 by pinki generally, search for “zoom to fit”.

it’s still a complex issue and i’ve not been able to find code that suits all usecases, camera types (orthographic/oerspective), animated. i’ve searched through all forums i knew, stackoverflow, etc.

scraped every bit of info i could find together to form a magic bullet component for react + three: <Bounds/>, and here’s a demo: Bounds and makeDefault - CodeSandbox but it’s open source, if the discourse link above isn’t enough you can cross check the components source.

@drcmda Yes I went through this post but couldn’t make functions I’ve found over the net work even for one object. I’ve managed to create a pseudo bounding box object for the entire scene and didn’t know what to do with it. Thank you for your component, I’ll try find the code but I’m using Angular at this point. Many thanks in advance.

i feel your pain, i’ve had such a hard time - mostly because i struggle a lot with math, but thought something simple like that surely cannot be so hard. maybe ask him: https://twitter.com/Nartc1410/status/1496352326428282884 he’s translated most of these drei components to angular already.

@drcmda Thanks for your answer. I’m looking at the getSize() function and don’t understand how I could get size of Scene or Group in the manner you wrote it. At this point you retrieve Vector of default Box object. Any ideas? Thanks in advance.

In fact I’ve found the solution by copying part of your code for perspectiveCamera.Only problem I have now is that the camera don’t face the objects, instead I get to see the objects from below ( still, I’m able to see all objects ). any Idea how I could avoid this behaviour? Thnaks in advance.
Here’s my code:

export const fitCameraToObjects = ( group:THREE.Group, camera:THREE.PerspectiveCamera ) => {

    const box = new THREE.Box3().setFromObject( group );
    const size = box.getSize( new THREE.Vector3() );
    const center = box.getCenter( new THREE.Vector3() );
    const maxSize = Math.max( size.x, size.y );
    const margin = 1.2;
    const fitHeightDistance = maxSize / ( 2 * Math.atan( ( Math.PI * camera.fov) / 360 ) );
    const fitWidthDistance = fitHeightDistance / camera.aspect;
    const distance = margin * Math.max( fitHeightDistance, fitWidthDistance );

    const currentCameraPos = new THREE.Vector3().copy( camera.position )
    const direction = center.clone().sub( camera.position ).normalize().multiplyScalar( distance )

    const goalCameraPos = new THREE.Vector3().copy( center ).sub( direction )
    const goalFocusVec = new THREE.Vector3().copy( center );
    camera.position.copy( goalCameraPos )
    camera.lookAt( goalFocusVec )

}

It’s actually not that hard. And it gets easier when you make a little sketch first:

Let’s assume you have computed the bounding sphere “BS” of your collective geometry, having a radius of “r”. Here’s how to do that.

Two cases to consider:

  1. find the minimum Radius “R” for a given “fov”
  2. find the minimum “fov” for a given radius “R”

which are guaranteed to show all that’s inside of the bounding sphere silhouette.

The respective “minimum” is given by the requirement, that the frustum emanating from the camera just barely touches (tangent condition!) the bounding sphere “BS”. The tangent condition implies a right angle between the red BS-sphere radius “r” and the ray “L” touching the sphere.

It’s required, that the bounding sphere “BS” radius “r” is always known.

We can infer, that L * L + r * r = R * R
We can also infer, that R * sin ( fov / 2 ) = r

That’s two equations having two unknows, so it’s not hopeless. :wink:

Solving for case 1:

R ≥ r / sin( fov / 2 )

Solving for case 2:

fov ≥ 2 * asin( r / R )

That’s about it.

@vielzutun.ch Hey thanks for your answer do you have same but for bounding boxes. Thanks in advance.

Bounding spheres have the advantage, that their silhouette is a constant size circular shape for a given “R”-“fov” combination, regardless of the angle from which the camera is looking at the bounding sphere.

A bounding box will appear as differently sized, depending on the angle from which you are looking at it. So, for that case I’m unable to provide formulas as above which would work from any direction of view.

1 Like

@vielzutun.ch ok thanks anyway.