need to position viewpoint (z-position) nicely in front of *.OBJ-object...

I loaded in a wavefront *.OBJ-file and made a routine that returns the bounding box / limits of the obj-file using min/max on all the vertices… My bounding box function returns 6 numbers:

  • min/max of all X-vertices => I calculate dx as the width/span in X-direction…
  • min/max of all Y-vertices => I calculate dy as the width/span in Y-direction…
  • min/max of all Z-vertices => I calculate dz as the width/span in Z-direction…

I then initialize my rotation center ( rotCenter ) to 0,0,0 and translation: tx = ty = tz = 0 and rotation around two axes: rx = ry = 0.

Incomplete code (python) - to give you an idea:


    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    
    gluPerspective(90.0, width/float(height), zNear, zFar) # width = 800, height = 600 pixels (as an example)
    glMatrixMode(GL_MODELVIEW)

    while running:
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()

        # Move to center of object (consider special add/subtract in Z-dir!):
        glTranslate(-rotCenter[0], -rotCenter[1], -rotCenter[2]) # not sure if plus/minus, however not an issue now

        # add user-defined viewpoint:
        glTranslate( tx, ty, tz ) # tx and ty is ok (halfways). tz should NOT be halfways into the bounding box/object...
        glRotate(ry, 1, 0, 0)
        glRotate(rx, 0, 1, 0)

        # Below here I display my wavefront *.OBJ file etc...
        #  ........ not too relevant code follows below ....

This code means that I start in the middle of my *.OBJ file and I have to zoom out before I can see my whole object / *.OBJ-file (have to start somewhere).

Now, I have x-axis right, y-axis up and z-axis from my screen and pointing out of the monitor. I want to initialize tz to a value to be a “good value” so when I start the program, I’ll immediately see the object in front of me - maybe taking up 75% of the vertical screen space (in the y-direction) - instead of now, where the initial position is in the middle of the bounding box of the object… How should I change my gluPerspective(90.0, width/float(height), zNear, zFar)-function ? It could also be that I wanted my object to take up 60% of the horizontal screen width, maybe ?

So I have dx = the width of my object and dy = the height of my object…

Basically I’m asking you: Which value should I initialize tz to ?
Take an example: The bounding box has dx=2000, dy=1000, dz=200 (something very wide, half as tall and 1/10 of the width in the depth-direction)… Which formula could I use to get a good initial tz-value and how to implement it in my program code ? Must be some frustrum/viewport/viewpoint equation…?

Sorry, but I cannot seem to figure out, what is the best/nicest way of solving this problem… I’m a bit of a noob, although I now can solve the most basic things/problems myself. Here I need a good idea/suggestion to continue my program. I hope you understand… I highly appreciate ANY ideas/suggestions/references.

Thank you (and please ask, if something is unclear, I hope you get the idea of what I’m trying to solve here)!

You’re trying to recreate the concept of a VIEWING transform. Consider just using gluLookAt(). You tell it 1) where you are looking from, 2) where you are looking “to”, and 3) a vector in the “up” direction, and it builds a transform to load on the MODELVIEW stack to put your eyepoint where you want.

Either way, you can figure out what you want (what to set tz to, or where to place the eyepoint with gluLookAt()) with a little trig. Compute the bounding sphere around your object (center, radius). center incidentally is “where you are looking to” with gluLookAt(). Now based on your field of view (e.g. 90 deg horizontal), figure out how far out your eyepoint needs to be to fit that entire bsphere within the frustum. Just draw your bounding sphere within the frustum (a triangle, in 2D) so that it barely fits. A little basic trig will tell you the distance your object needs to be.

In the case that your VFOV is smaller, you’d use that instead. That way your object fits within the horizontal and vertical dimensions.

Or you could do some other type of fit.

[QUOTE=Dark Photon;1243468]You’re trying to recreate the concept of a VIEWING transform. Consider just using gluLookAt(). You tell it 1) where you are looking from, 2) where you are looking “to”, and 3) a vector in the “up” direction, and it builds a transform to load on the MODELVIEW stack to put your eyepoint where you want.[/QUOTE]THANK YOU (for the hint about “viewing transform” so I could google that)… Regarding gluLookAt(), the only input argument I have a bit of trouble getting is the “eyeZ” ; similar to my “tz”, I guess. So I guess my problem is the same - I need to find eyeZ/tz… I didn’t use gluLookAt() below - not sure what I would gain of it / how I would benefit from that…

Either way, you can figure out what you want (what to set tz to, or where to place the eyepoint with gluLookAt()) with a little trig. Compute the bounding sphere around your object (center, radius). center incidentally is “where you are looking to” with gluLookAt(). Now based on your field of view (e.g. 90 deg horizontal), figure out how far out your eyepoint needs to be to fit that entire bsphere within the frustum. Just draw your bounding sphere within the frustum (a triangle, in 2D) so that it barely fits. A little basic trig will tell you the distance your object needs to be.
Ok, here’s what I did (just before entering the “while running”-loop):


    viewAngle = 65.0/180*pi
    tz = -0.5*(dy/(2*atan(viewAngle/2)) +\
               dx/(2*atan(viewAngle/2)))

So “tz” is negative, I guess because I’m moving the modelview matrix. Then I want an average of something, so it doesn’t look too weird in any of the x/y-directions. What do you think of this solution ? Is this a good way of solving the problem or is there a better method ?

I also know about linear algebra, if someone wants to post a better/more advanced solution… I think I’ve solved my problem now - wasn’t too big. However, I would be VERY interested, if someone would post something that is better than my solution which I think is maybe so simple that I imagine there must be a better method… ?

In any case: Thank you very much, Dark Photon, for leading me in the rigth direction - yesterday I was lost but today I googled what you wrote “viewing transform” and came up with this solution shown above… Appreciate your final comments (or from others), if you have any additional good hints for a good solution…