Rotation around the center of the screen...How???

Hi,

I am developing an OpenGL graphics framework. It is such that I can add components to it which are in world coordinates. Now the problem is… When I rotate the entire model, the model rotates around the origin of the World coordinate i.e. around the first object added to the framework.
But I want the model to rotate around the center of the screen. I am a little confused about the orer of my translations and rotations. Can someone help me out here???

here is a snapshot of the code where I set my camera.

void UpdatecameraLocation()
{
// set the zooming factor
Graphics.Scale(zoom,zoom,1);

// move the eye to the new origin
Graphics.Translate(scaledOrigin.x*aspect_ratio, scaledOrigin.y, scaledOrigin.z);

// rotate the eye
Graphics.Rotate(rotation.x, rotation.y, 0);
}

I also want to pan the model left/right, up/down, so I need to take that into account as well. If I simply switch the translate and rotate call above, the model does rotate about the center of the screen but then it wont pan in the correct direction. e.g. when I have rotated the model by 90 degrees, it pans in and out of the screen instead of left and right.

Waiting for your replies…

Fastian

[This message has been edited by Fastian (edited 09-11-2001).]

Hi,

What about:

glLoadIdentity();
PlaceCamera();
// Add an object to the scene
glPushMatrix();
// rotate around the center of the screen:
glRotatef(x-angle, 1.0, 0.0, 0.0);
glRotatef(y-angle, 0.0, 1.0, 0.0);
glRotatef(z-angle, 0.0, 0.0, 1.0);
// Move to the desired position:
glTranslate(x, y, z);
DrawObject();
// Return to the origin
glPopMatrix();
// Add a second object to the scene:
glPushMatrix();
// Rotate around center of the screen:
glRotatef(…)

Hope that helps,

Ritchie

[This message has been edited by Ritchie (edited 09-12-2001).]

code:

glLoadIdentity();PlaceCamera();// Add an object to the sceneglPushMatrix();// rotate around the center of the screen:glRotatef(x-angle, 1.0, 0.0, 0.0);glRotatef(y-angle, 0.0, 1.0, 0.0);glRotatef(x-angle, 0.0, 0.0, 1.0);// Move to the desired position:glTranslate(x, y, z);DrawObject();// Return to the originglPopMatrix();// Add a second object to the scene:glPushMatrix();// Rotate around center of the screen:glRotatef(…)…


isn’t this just like doing
glRotate(…
glRotate(…
glRotate(…
Translate(…

once and then pushing/popping matrix between each object drawn???

No, it isn’t… You say you want to use the center of the screen as a reference point (is this the case, or did I get that wrong?)

The pushing and popping will make sure you use the center of the screen as a reference point.

As to your panning question, I would play with gluLookAt. If you want the camera to rotate around the center too:

gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, 1, 0);
glRotatef (camAngle, 0, 1, 0); // Rotate around y-axis

Other method, using the same gluLookAt function:

if you want to pan to the right, increase eyex and centerx equally,
and to pan left, decrease both of them.

Hope this helps
Ritchie

Yes, I want to rotate around the center of the screen always. Even when I pan.

Doing what you told at the last, the scene pans, but the scene still rotates around the first object.

Fastian

Post your code, or e mail it to me and I’ll have a look at it. Are you sure it is rotating around the first object? It does sound like you are pushing your matrix one too many time. Is the first object you draw situated at the center of rotation? Probably not, but just to make sure

Ritchie

My first object is originally at the origin. But once i pan it, its no longer at the origin. yet when I rotate the model, it rotates around the origin of the first object.

i’ll give it one more try and see if i’m doing something wrong…

O.k here is the process it goes through.

I am makinng the framewok for a piping application. All the components (pipes, bend etc) have global coordinates. When I am loading a model, it loads each and every component(pipe, bend, valve etc.) into a inked list. In the main draw loop

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFER_BIT)

gluLookAt(0+origin.x, 0.origin.y,20, origin.x, origin.y,0,0,1,0);
// rotate the eye
glRotatef(rotation.x,1,0,0);
glRotatef(rotation.y,0,1,0);

// here we traverse the linked list and get the pointer to each object and call its draw function

object->Draw();

// Draw is a derived virtual function which calls corresponding draw of cylinder, bend etc.

//heres the code for clinder…
void DrawCylinder(const RGFW3f *startPoint, float angleXY, float angleXZ, float length, float baseRadius, float topRadius)
{
glPushMatrix();
// move to the starting position of the pipe
glTranslatef(startPoint->x, startPoint->y, startPoint->z);
// draw the pipe
gluCylinder(cylinder, baseRadius, topRadius, length, 18, 1);
glPopMatrix();

}

//so what effectively am I doing is…
Draw()
{
glLoaddentity()//once

gluLookAt(…// for panning
glRotate(…// for rotation

glPushMatrix();
DrawObject1();// which calls the corresponding draw of cylinder or bend…
glPopMatrix();// actually these push and pos are in the drawobject function but i’m showing here for understanding
glPushMatrix()
DrawObject2();
glPopMatrix()
.
.
.
and so on until the end of the list.

swapBuffers()
}

sorry if i’m hgetting you confused.

from the above its obvious that since my model will be panned first through gluLookAt, thus shifting the local coordinate system, the whole system will start to rotate around the new position of the local coordinate system.

If on the other hand I switch the gluLookat and rotate calls in the the beginnig, then it rotates around the center of the screen but then once I rotate the model by 90 degrees along y axis and pan the model, now the x axis is facing outside the screen so instead of panning left right, its panning in and out of the screen…

i’m again sorry if i’m confusing you. This is probably my longest post ever on these forums and my worst problem ever with opengl.
or should I say my logic…

thanx for your time.

Fastian

I think I finally get what you want to do…
Whenever you pan, you also want to move the center of rotation.

I think what you should do is:

  1. Move the center of rotation to the point where the camera is aimed at;
  2. Position your camera (including your rotations);
  3. Return to the actual center of your scene;
  4. Draw the scene;

I cannot test it right now but try this:
(I’ll assume you are panning in x direction only, for this example)

glLoadIdentity();
glTranslatef(centerx, 0, 0);
gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, 1, 0);
glRotatef(camAngle, 0, 1, 0);
glTranslatef(-centerx, 0, 0);
glPushMatrix();

and then start rendering your scene.
If this is not what you need, or it doesn’t work let me know, and I’ll look at it tonight.

Regards,
Ritchie

[This message has been edited by Ritchie (edited 09-12-2001).]

Thanx a lot for you time, I really appreciate what you’r doing.

Yes this is exactly what I want to do. When I pan, I want to move the center of rotation so that my scene moves somewhere but my axis of rotation always remains at the center of the screen. just like hoops, where the model always rotate about the center of the screen even if we pan to whatever location.

I did what you said, but the problem remains the same. once I rotate th model about 90 degrees along y axis, and then pan the model, it pans in and out of the screen instead of panning left and right.

Fastian

Hi Fastian,

I have been browsing through my files at home and found the code I think you are looking for (although i never used it for panning, just rotation):

glLoadIdentity();

gluLookAt(cobj.x, cobj.y, (cobj.z + 5.0), cobj.x, cobj.y, cobj.z, 0.0, 1.0, 0.0);
// glPushMatrix();
// Translate to the point of rotation
glTranslatef(cobj.x, cobj.y, cobj.z);

// Rotate accordingly
glRotatef(camrot.x, 1.0, 0.0, 0.0);
glRotatef(camrot.y, 0.0, 1.0, 0.0);
glRotatef(camrot.z, 0.0, 0.0, 1.0);
// Move back to the origin
glTranslatef(-cobj.x, -cobj.y, -cobj.z);

There is only slight change with the code above, but I know this works
You said that things go wrong with rotation of 90 degrees… using this code, is that still what happens?

Sincerely,
Ritchie