Center the object

Started by
11 comments, last by Erik Rufelt 14 years, 6 months ago
Hey all! I have a problem. (i'm working in perspective projection (opengl)) I have a simple model viewer and when i load the 3d model i'd like to center it in the middle of the screen. And then after every rotation and translation (made by me with the mouse). I'd press a button which would re-center the object. How would i calculate the position (x,y,z) for the object so it will be completely centered when drawn in 2D screen! X-s on the images will be of same pixel lenght, same goes for Y-s. Eg1: Eg2: after some rotation...
Advertisement
Unfortunately your pictures are not loading so I can't see the example you are trying to show (if you fix that I can learn more about what specific issue you are having).

You should know that there is not one set of x/y/z coordinates that will place your object in the center of the screen. Every time you perform an operation on the MODELVIEW matrix what is in the center of the screen will be different.

A standard initialization will put the "eye" at location 0,0,0 facing in the -z direction, so if you place an object at 0,0,-1 (or any -z value) that should place the object in your view (provided it is inside your clipping planes).

However I'm not really sure what kind of issue you are having, from your statement you sound like you can put it in the center of the screen to start, but then you have trouble getting it to go back to the center?

I'm not sure yet what you don't understand, so maybe you can get working pictures or try to explain more.
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
You can approximate by using the gluLookAt function, telling the camera to look at the center of the object from its current position. Doing what you are suggesting exactly would be very complicated.
Images are not showing? weird... well here are the links

EG1:
http://www.shrani.si/f/u/po/1CG7l2w6/demo1.jpg

EG2:
http://www.shrani.si/f/2/uM/2BpcFAZ2/demo2.jpg


You can approximate by using the gluLookAt function, telling the camera to look at the center of the object from its current position. Doing what you are suggesting exactly would be very complicated.

I od not want an approximate, and i don't care if it's complicated. This is something i really want to do and if you can shed some light on this or throw in some ideas, please do!

Rightnow i'm using an iterative solution which works well but it's not 100% exact and a bit slow (400ms for "any" object).
One solution I know to be used is where you generate a bounding sphere for the object, and then focus the camera on the center and move the camera back to radius times some constant (depending on how big the object should be one the screen). This will place the center of the object in the center of the screen, like Erik Rufelt suggested.

If you, on the other hand, don't want the object centered, but rather make sure that there is the same amount of space on corresponding sides, you need to work in screenspace. Try the following:

1. First, make a good guess using the method mentioned above.
2. Project all vertices to screenspace and isolate the topmost, bottommost, leftmost and rightmost vertex.

To position the object correctly over the x-axis:
3. From the leftmost and rightmost vertices, find out how long they must be moved to be placed correctly.
4. Take the leftmost vertex (could also be the rightmost) and translate that (still in screenspace) with the calculated distance.
5. Now, unproject it to find its world position.
6. Compare this world position with the old one to find out how much the camera should be moved.

Do step 3-6 for the y-axis too.

I haven't tried this so I cannot promise it will work as expected, but I believe so.

Hope this helps,

Per Rasmussen.
I can not use bounding sphere since the boundign shpere is of constant size. Because when i rotate the object i might be possible to zoom-in more since
the rotation changed objects 2D screen shape (representation).

As for this:


1. First, make a good guess using the method mentioned above.
2. Project all vertices to screenspace and isolate the topmost, bottommost, leftmost and rightmost vertex.

To position the object correctly over the x-axis:
3. From the leftmost and rightmost vertices, find out how long they must be moved to be placed correctly.
4. Take the leftmost vertex (could also be the rightmost) and translate that (still in screenspace) with the calculated distance.
5. Now, unproject it to find its world position.
6. Compare this world position with the old one to find out how much the camera should be moved.


I have a problem with nr. 5. How do i know which Z to choose then unprojecting?
One solution would be to calculate the Axis-Aligned Bounding-Box of the object, then calculate the center:

((min + max) / 2.0f)


And then translate negatively by that.

glTranslate(-Center.x, -Center.y, -Center.z);


That will center your object.

To be able to see it properly, you should calculate the size of the AABB:

max-min


And then use gluLookAt like so:

gluLookAt(0, 0, MaxDistance, 0, 0, 0, 0, 1, 0);


Where you calculate MaxDistance as the maximum size (be it width, height, or depth) of the AABB.

Hope i was able to help a bit.
AABBOX sounds interesting. I'll try it out. Thanks for the idea!
I have a slow solution, but it's ok if you only want to center if a keypress event occurs, and with low vertex counts.

Calculate all your verticles window coordinates (for example with gluProject)
then find the minx, maxx, miny, maxy, minz, maxz values than you can use these to calculate the center in window coordinates, which you can gluUnproject to get the world coordinates, than gluLookAt at this center.
It's the same as the bounding box thing, but simpler to understand/implement.

I hope the minx.... part makes sense. Calculating with the minz, maxz values may be tricky, because the z-buffer isn't linear, but I think you can easily find it's equation on the net. But maybe it's not so important, since you have to calculate a zoom value to fit the object well. I think it can be calculated somehow using minx, maxx, miny, maxy and the window sizes.
"I have a problem with nr. 5. How do i know which Z to choose then unprojecting?"

The vertex also has a Z value in screenspace (Actually, I meant projectionspace). Just keep this value as you are not interested in moving the object back or forth (correct?).

" I can not use bounding sphere since the boundign shpere is of constant size. Because when i rotate the object i might be possible to zoom-in more since
the rotation changed objects 2D screen shape (representation)."

As I said earlier, this will place the object in the center of the screen. It will not necessary make the same amount of space on all sides on the screen. That's why I suggested the second approach.

This topic is closed to new replies.

Advertisement