How can I center an arbitrary object in 3D (perspective view) such that it’s centered in the viewport. For example, its screen space bounding box is centered within the viewport?

I tried to translate the object such that its center is on the Z axis but that did not work for a very obvious reason.

Use a default camera positioned at the origin looking into the screen (i.e. in the -z direction). Set up a scene with a 3D, wireframe cube with vertex coordinates of 1, and -1. Thus each edge of the cube is 2 units long. Translate it in Z by something like -5 units. Set the clipping planes at 2 and 8. Set the field of view of the camera just large enough to see the entire cube.

Now all you have to do is translate and scale the object to fit inside the cube. Loop through all the vertices in the object to find xmin, xmax, ymin, ymax, zmin, zmax. The viewing center of your object will have coordinates (u,v,w), where u = (xmin+xmax)/2, v = (ymin+ymax)/2, and w = (zmin+zmax)/2]. You also have to compute a scale factor (call it Q). Set d equal to the maximum of (xmax-xmin), (ymax-ymin), and (zmax-zmin). Then Q = 0.5/d. Do these calculations in a subroutine before you enter the draw routine.

The pseudo-code for the draw routine would look something like this -

gluPerspective (fov, 1.0, 2.0, 8.0);
glTranslatef (0,0,-5); // Move box and object away from camera.
glRotatef (...); // Rotate objects around center of cube.
glRotatef (...); // Rotate objects around center of cube.
Display_Cube (); // Use wireframe cube as a guide.
glScalef (Q, Q, Q); // Scale centered object to fit inside cube.
glTranslatef (-u, -v, -w); // Place viewing origin of object at center of cube.
Display_Ojbect ();

Make subroutines to draw the wireframe cube and the object.

What I would do is to use a function similar to gluUnproject to get from screen space coord to world space, and then move the object to the transformed point.

For example, suppose that screen center is (400,300)

gluUnProject(400, 300, 0.5, // Windows coordinates 0.5 for mid z in screen space
modelMat, projMat, viewPort, // Matrices that describe the viewing transformations.
&wx, &wy, &wz // Ouput vars to hold center point in world space
);
// Update object position to (wx,wy,wz)
glTranslate(...);
// Draw object
DrawObject();

But does not the first method is similar to centering the 3D bounding box of the object in world coordinates? Then if the object is irregular shape it will not fit the viewport with equal margins on edges.

My technique will let you rotate the object to any orientation and always keep in it in the camera fov. There will be some orientations where it doesn’t completely fill the FOV from left to right, or top to bottom. Is that what you want?