Notifications
Clear all

[Closed] zoom extents as tight as possible

does anyone have a good algorithm or idea for one to perform a zoom extents on some objects that fits the objects into the viewport safe frame as tightly as possible? I need to generate some thumbnails for a bunch of objects of various sizes. Regular zoom extents usually leaves too much room around the objects. I am currently generating a camera with a certain fov and initial look-at direction so I figure I just need to move it up/down/left/right/forward/backward in its local space.

Ideas?

12 Replies

You would need to loop through all vertices of the object, calculate the view vector of it, calculate the angle between that and the camera forward vector – then you know how wide your FOV needs to be to capture all vertices.
I assume for thumbnails, keeping a steady fov is not essential.
If you want to keep the fov and change only the position of the camera that would be a bit more complicated.

Pseudocode:


 fMaxAngleX = 0.0
 fMaxAngleY = 0.0
 for i = 1 to $.verts.count do
 (
   p3ViewVector = $.verts[i].pos - nCamera.pos
   p3ViewVectorProjX = p3CameraRightVector * (dot p3ViewVector p3CameraRightVector)
   p3ViewVectorProjY = p3CameraUpVector * (dot p3ViewVector p3CameraUpVector)
   fAngleX = acos (dot (normalize p3ViewVectorProjX) p3CameraForwardVector)
   fAngleY = acos (dot (normalize p3ViewVectorProjY) p3CameraForwardVector)
   fMaxAngleX = aMax #(fMaxAngleX , fAngleX)
   fMaxAngleY = aMax #(fMaxAngleY , fAngleY)
 )
 nCamera.fov.x = fMaxAngleX * 2
 nCamera.fov.y = fMaxAngleY * 2
 

This should give you the tightest fit if you can freely set the fov angles on both axes of the screen.

thanks for the speedy reply. I had something similar to your solution working already however I would prefer to keep the fov constant so unfortunately it is a bit more complicated as you have stated.

I’m not very good with matrices, so I’m not sure if this would work:

  1. Make sure that all vertices lie before the camera.
  2. Apply the camera projection matrix to all the vertices (the one that transforms from world space to screen space).
  3. Calculate the bounding box of those vertices.
  4. Reverse transform the bounding box with the screenspace to worldspace matrix.
  5. Where the four y-aligned edges of the transformed box intersect is your perfect camera pivot.

Does that make sense?

1 Reply
(@gravey)
Joined: 1 year ago

Posts: 0

not quite.
for point #3 I assume the bounding box is calculated in screen space?
and in point #5 i dont understand what you mean by “the four y-aligned edges of the transformed box”

3: correct
5: there are 12 edges in a bounding box – 4 are parallel to the local x-axis, 4 to y, 4 to z
so the four edges that are parallel with the camera’s forward axis should intersect in one point after applying the screenspace to worldspace matrix.
Actually the edge won’t necessarily intersect, but if you treat them as lines (infinite length) they should intersect.

ok now I’m confused… you say that 4 parallel sides of a bounding box can intersect, but as far as i’m aware, parallel lines can never intersect, which leads me to believe the ‘projection matrix’ that you have mentioned is not the same as the camera’s transform matrix. I dont think I’ve ever needed to get or calculate a “projection matrix” before. Do you know how to do it? or am I not understanding something?

Yes the camera’s projection matrix is not its transform matrix.
It’s the matrix that transforms a point in world space into screen space.
You know when things closer to the camera look larger than the same object further away? That’s because the camera lens focuses all incoming rays onto a single point like this:

A camera’s projection matrix does that too, so lines that are parallel in world space will converge into one point in screenspace. (Unless you’re using an orthographic projection like max’s user view)

Unfortunately I have no idea how to get the projection matrix of a camera in maxscript without calculating it yourself.

thanks for the info. I would be happy to calculate the projection matrix myself if i knew what I was doing… I just read this article and it seems to explain what I need but i’m still trying to wrap my head around it a bit… any thoughts or links to ‘simpler’ articles?

I forgot one step.
Also I couldn’t help but make a drawing…

Still no guarantee for correctness.

ok that makes a LOT more sense now. that drawing is the perfect description. now the only problem is getting my head around calculating a projection matrix and i guess the inverse projection matrix as well.
any tips on that?

Page 1 / 2