I have an OpenGL application which implements navigation functions such as Orbit, Walk, Pan, Rotate, etc. for navigating a 3D environment. All this works flawlessly and is fairly straighforward to set up using gluPerspective and gluLookAt.
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective m_ViewAngle, m_AspectRatio, m_ClipDistance_Near, m_ClipDistance_Far
glMatrixMode GL_MODELVIEW
glLoadIdentity
gluLookAt m_Eye.X, m_Eye.Y, m_Eye.Z, m_Focus.X, m_Focus.Y, m_Focus.Z, m_ViewUP.X, m_ViewUP.Y, m_ViewUP.Z
glCallList DisplayListIndex
Similar to a typical ZoomExtents or ZoomToFit command in CAD software, from any arbitrary viewpoint (view direction), I would like to be able to zoom so that
(1) The entire 3D environment is visible, and
(2) The 3D environment model fills the entire viewport (is as large as possible given the current size of the viewport).
I know the bounding box (extents) of the environment (min XYZ, max XYZ). However, I have been unable to derive what the Eye and Focus positions should be for the given ViewAngle and AspectRatio and environment extents.
Perhaps there’s an easier way to accomplish this, than with gluLookAt. Any help is appreciated!
Actually it can be done much ‘easier’.
What you need to do is a projection of your model to a plane. Then, determine the highest and lowest points (top y, bottom y, leftmost x, rightmost x), and finally determine how much scaling you need to fit this rectangle in the rectangle you’d actually need.
The plane you need to project on is the screen plane.
Luckily for you, you are already doing this.
So, transform every point of your model using the matrices you already have set, and determine the maximum points.
Calculate how much scaling you’d need to fit it on the screen. And apply this scaling to the zoom of the object
Thats it