PDA

View Full Version : transformations



eckiller
04-03-2000, 03:05 PM
Hey,

I translate an object out say 10 units and then i want to rotate it.
The problem is, is that it doesn't rotate around itself, but it rotates
around the original origin.

If i rotate first and then translate, it rotates around itself but then
the translation only translates around the original axis.

This is for a simple virtual world i'm making. Say the user presses the
up arrow key to walk forward. I translate the world so it looks like
he's walking forward. Then he stops and wants to turn left, i rotate
the world to the right but its making a rotation around the original
origin.

Basically i think i'm saying i need to translate the world, make that
the new origin and then rotate around that new origin. Or ratate first and then translate in the direction i rotated.

Ugh i hope i explained myself

My render function code will probably explain some more....

void Draw_Scene(void)
{
// clear the screen and the depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

// enable face culling
glEnable(GL_CULL_FACE);
// cull back facing triangles
glCullFace(GL_BACK);

glBindTexture(GL_TEXTURE_2D, tex);

// rotate
glRotatef(x_rot, 1.0f, 0.0f, 0.0f);
glRotatef(y_rot, 0.0f, 1.0f, 0.0f);
glRotatef(z_rot, 0.0f, 0.0f, 1.0f);

// set object position in scene
glTranslatef(move_left_right, move_up_down, move_in_out);

Draw_Land_Scape();

//glPopMatrix();
// disable state
glDisable(GL_CULL_FACE);

// Swap buffers
glutSwapBuffers();
}

I'm sure this is a fundamental thing but i just can't see it.

holy_moly
04-04-2000, 12:13 AM
where's the corresponding glPushMatrix() call
to glPopMatrix() ?

Eric
04-04-2000, 12:22 AM
Hmmm...

Holy, I think the glPopMatrix() is in comments (notice the // at the beginning of the line !).

Just a question : do you want to do a walkthrough (i.e. like in a first-person shooter) or do you want to be able to have an object translated/rotated (like in a modeller) ?

Eric

MikeC
04-04-2000, 01:46 AM
This question comes up a lot.

You should be translating first, then rotating. Your problem lies in trying to use object-relative directions (left/right) for what has to be a world-relative translation.

Here's what you need to do:

Each object you want to transform should have a position (x, y, z, in WORLD coordinates) and a rotation. Quaternions are the best way to represent arbitrary rotations; matrices are also OK and a lot easier to understand. If you're only ever rotating around one axis (Y in a basic Doom-type thing) then just store rotation as an angle and save yourself a lot of work).

Now, each frame:

1) Build a vector M representing the object-relative movement for this frame. E.g. if you're moving forward, M might be (0.0f,0.0f,-1.0f).

2) Rotate the M vector by the object's rotation.

3) Add the rotated M vector to the object's current position vector.

4) Translate by the new current position.

5) Update the object's current rotation.

6) Rotate by the new current rotation.

Hope this helps.

FATBUDDHA
04-04-2000, 06:46 AM
I think I see what you mean.

Here is the order that you should be doing things:

Set the matrix mode to projection (so that you are altering the position of the camera):
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

Now apply all of the matrix transformations for the positioning of the camera. These transformations must be applied in this reverse order:
glRotated(rotx, 1, 0, 0);
glRotated(roty, 0, 1, 0);
glTranslated(posx, posy, posz);

Now switch modes to modelview mode (so that you are altering the current 'drawing' position.):
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Now draw everything in your scene.

If the user presses left or right, then increment or decrement the roty value appropriately. If the user presses lookup or lookdown, then increment or decrement to rotx value.

If the user presses the moveforward or movebackward key, then you need to use a little bit of trigonometry to alter the posx and posz values appropriately based on the angle i.e. for move forward you would need:

posx += 10*cos(roty);
posy += 10*cos(roty);

Well something like this anyhow.

Hope this is what you were after.

Bob
04-04-2000, 07:19 AM
Why involve the projection matrix here? The projectionmatrix is to project polygons on the screen, and the modelview matrix is for translating objects from world coordinates to eye coordinates.
Don't you have to recalculate both the modelview matrix and the projection matrix everytime you move the camera? Won't this destroy the projection if you load it with the identity matrix first?

Bob

eckiller
04-04-2000, 10:34 AM
Its to be a first person shooter. I still need to digest some of your ideas. But late last night i figured out what the problem is. After i translate my world (to simulate the player moving) and i set up a rotate, the world rotates around its newly translated place. I need it to go back to the camera origin rotate and then go back to where it was translated. Did that make any sense.

FATBUDDHA
04-04-2000, 01:27 PM
Your quite right Bob about my use of the projection matrix. You need to call glPersepective() (or whatever) while your in the projection matrix mode, for my pseudo code to make sense (I guess I forgot to mention it...)

I like to use the projection matrix in this way, because I find it more intuitive to work with as you are positioning the camera relative to the global origin, rather than vice versa.

Whatever you prefer I guess. http://www.opengl.org/discussion_boards/ubb/smile.gif

Bob
04-05-2000, 01:50 AM
Read through my post, and noticed I might have been sounding rude (I apologize if I did http://www.opengl.org/discussion_boards/ubb/tongue.gif ). Just wanted to say that it can be abit confusing to use the projection matrix for another purpose then projecting polygons. However, I agree with what you are saying.

I prefer to use gluLookAt, so I dont have to bother about placing origin or camera http://www.opengl.org/discussion_boards/ubb/biggrin.gif .

Bob

FATBUDDHA
04-05-2000, 07:40 AM
http://www.opengl.org/discussion_boards/ubb/cool.gif