world rotation v. body rotation

how do you guys implement them?
any useful links?

thanks

Variables work nice…

world.x
world.y
world.z
world.rotation_x
world.rotation_y
world.rotation_z

object.x
object.y
object.z
object.rotation_x
object.rotation_y
object.rotation_z

Always keep in mind that you aren’t rotating objects, you are rotating coordinate systems.

glLoadIdentity();
ApplyWorldMatrix();
DrawWorld();

glPushMatrix();
ApplyObject1Matrix(); //remember object matrix is still active here if you don’t need it just load identity matrix
DrawObject1();
glPopMatrix();

glPushMatrix();
ApplyObject2Matrix();
DrawObject2();
glPopMatrix();

this is how it works…

thanks guys
that was useful

correct me if i am wrong but as i understand it it goes like this:

in order to make an object rotate around its axis i have to use glPopMatrix() till i get the object’s coords to coincide the world coords, then perform the rotation, and then to multiply by all the transformations that were done prior to rotation.
in other words: premultiply!!!

is this right?

WHOA hold on there! You have it REALLY close…but do not go applying glPopMatrix() without already having a glPushMatrix(). They work in pairs. glPushMatrix() and then a glPopMatrix(). If you called a glPopMatrix() first…say goodbye to any and all transforms you had applied to your world. OpenGL may have some form of error checking for that, but you need to call them in pairs.

A glPushMatrix() call pushes the current transformation matrix down one level and puts an identity matrix on top. Because of that, all other transforms before do not affect the object. Therefore, it will spin about it’s own center because the transform to get it out to where it is lies in the matrix one below that.

  • Halcyon

thanks blaze,
[b]WHOA hold on there! You have it REALLY close…but do not go applying glPopMatrix() without already having a glPushMatrix().
They work in pairs. glPushMatrix() and then a glPopMatrix().

yeah i meant that(to use them in pairs) sorry i wasnt clear.

A glPushMatrix() call pushes the current transformation matrix down one level and puts an identity matrix on top. Because of that, all other transforms before do not affect the object. Therefore, it will spin about it’s own center because the transform to get it out to where it is lies in the matrix one below that.

i am confused here…
i have always thought that glRotate will rotate the object (regardless of its position) around the world coords…right???
thats why to make in spin around its own coords i have to remember all the transformations, then make the world and object coords coincide, and then perform the remembered transformations.

am i being clear?? or correct for that matter?
thanks

jenny

Well, you have the idea, but you have it a bit confused. I know it is a bit difficult to get.

You will probably see the concepts if we talk about spaces (coordinate system)… For example, you have texture space, you have object space, you have world space…
Well, glPushMatrix, and its partner in crime, glPopMatrix allow you to apply transformations to different spaces without affecting other objects spaces… What I mean is that transformation are cumulative. So if you rotate an Object A 45 degrees, and then you rotate Object B 45 degrees, without glPushMatrix() glLoadIdentity() glPopMatrix(), your Object B will end up rotating 90 degrees. So if you want to rotate Object A 45 degrees and Object B 45 degrees, you would do:

glPushMatrix()
glLoadIdentity()
glRotate( … )
DrawObject( A )
glPopMatrix()

glPushMatrix()
glLoadIdentity()
glRotate( … )
DrawObject( B )
glPopMatrix()

If you dont use the glPush glLoadIdentity and glPop, you will end up rotating Object B 90 degress instead because the current matrix still has those 45 degrees from the previous rotation…

The different spaces have different purposes of course. You normally draw objects in object space, which is the MODELVIEW matrix. The PROJECTION matrix would be the world matrix. So vertices are multiplied by the MODELVIEW matrix to get eye coordinates, which are then multiplied with the PROJECTION matrix to get clipping coordinates, which go under perspective division and viewport to get screen coordinates… Sigh.

An object rotates arounds its own space, but it is then multiplied with the PROJECTION matrix. This is why you need to bring the object to the origin of the world space (make the object and world space coincide) and apply rotation. Otherwise your rotation will be off.

I hope this clarified your doubts…

Miguel Castillo

Something you also need to know is that there is no real difference if you translate or rotate the object or the world because they will produce the same effect. The only difference is that they are inverse transformation of each other. You rotate your object to the left, you get the same effect by rotating your world to the right.

A glPushMatrix() call pushes the current transformation matrix down one level and puts an identity matrix on top.

Just wanted to clarify so cosmicGirl isn’t mislead: the current matrix is copied onto the stack, not the identity matrix.

http://www.3dlabs.com/support/developer/GLmanpages/glpushmatrix.htm

glPushMatrix pushes the current matrix stack down by one, duplicating the current matrix. That is, after a glPushMatrix call, the matrix on top of the stack is identical to the one below it. glPopMatrix pops the current matrix stack, replacing the current matrix with the one below it on the stack. Initially, each of the stacks contains one matrix, an identity matrix.

Wait now i’m confused . If you put an exact copy of the previous matrix on the top of the stack, wouldn’t the transformations in the glPushMatrix()/glPopMatrix() pair be the exact same as if you excluded them? The only difference i see of including them is that the transformations are not saved. I mean if you translate the scene back by 5 units and do a glRotate on a cube, you would have it spin on a circle with a radius of 5. With a glPushMatrix() and glPopMatrix(), you should still be rotating around on a circle with a radius of 5 units right? I mean it’s the same thing. Only thing is that once you’re done, the rest of the code isn’t affected. But i don’t understand how all of the sudden with a glPushMatrix()/glPopmatrix(), you have a cube spinning about the center if it had the same transformation matrix as before?

  • HalcyonBlaze

Thanks for you help on this to those who reply! This stuff is like a brick wall in learning opengl…once you get past this, things just start flowing for a while. Really understanding and getting comfortable with trasforms takes a while.

ok…man am i ever confused now.
is there a place where i can get tutorials that explain this kind of thing? or should i just play around with opengl?

anyhow…what i am trying to do is make the object rotate around its own axis. In the beginning of the application i have object centred at the origin so that the world’s coincide with obejct coords but after i scale/rotate/translate it they dont anymore.
If after i have transformed it say 5 units to the left i simply apply glRotate it will rotate around the (0,0,0) and not around its own axis like i want it to which is why i bring the object back to the origin ( remembering all the transformation done to it) apply rotation around x y or z and then apply all the tranformaions again so that the obejct will be drawn at the correct position in space …

am i confusing ???

Yakuza is correct about the how the push/pop works. If it didn’t work like that you couldn’t have parent/child relationships. Take for example a solar system. You can do something like so.

glTranslate(location of sun);

foreach planet
{
glPushMatrix();
glRotate(planets orbit);
glTranslate(planets distance from sun)
foreach moon in planet.moons
{
glPushMatrix();
glRotate(moon’s orbit around planet)
glTranslate(moon’s distance from planet);
glPopMatrix();
}
glPopMatrix();
}

The reason this works is BECAUSE the matrix stays the same as it was originally after the glPushMatrix. If it didn’t, the moon would get positioned relative to the sun instead of the position of the planet.

The glPopMatrix will then return the matrix to the state it was in at the time of the corresponding glPushMatrix(), thus removing the effects of the transformations of the previous moon and/or planet

I think you just need to understand how the matrix math works to understand your problem cosmicGirl.

There are a couple of ways you can think about the order of matrix operations. I like to think of it in terms of world coordinates. When you think of it this way you need to realize that due to the properties of the matrix math, the last matrix operation done is actually the first thing done.

So… say you want to rotate your model first and then translate it. You need to do the translate FIRST.

glTranslate();
glRotate();
drawModel();

The rotate is actually what will appear to be done first so if your model is centered around 0,0,0 it will be rotated around that and then translated.

If you did it the opposite order

glRotate();
glTranslate();
drawModel();

You now are effectively translating first, and then rotating around the origin of the world.

The Red Book has a fairly decent chapter explaining some of these things. I don’t have any links offhand, but a google search should turn up a lot of places you can find a downloadable copy of that.

^^^ thanks a bunch.
i know that the order is reverse.

in my application, the point is for a user to be able to transform a model with a mouse, so say a use has already translated in 4 units to the right and now he wants it to rotate around its y-axis…which is why i need to remember this translation …
so what i am planning to do is to bring it back to the origin, rotate it around the worlds y-axis, and then translate it.
am i correct? of course the translation will be pushed to be remembered, but my point is that the rotation will be done first…
anyhow i am just gonna get home and plaey aroundwith it, i think its the best way…
thanks guys

actually, i have one more question:

glRotate will rotate the object around the world’s coords right???

Yup, that is correct.

One trick I’ve used to prevent gimbal lock might be useful for you. What I’ve usually done is to keep track of a rotation matrix for the object. Then for each new rotation applied, you PRE-multiply the new rotation to your stored rotation matrix. Then when you do the drawing, you use glMultMatrix in order to apply your rotation matrix.

Originally posted by cosmicGirl:
[b]^^^ thanks a bunch.
i know that the order is reverse.

in my application, the point is for a user to be able to transform a model with a mouse, so say a use has already translated in 4 units to the right and now he wants it to rotate around its y-axis…which is why i need to remember this translation …
so what i am planning to do is to bring it back to the origin, rotate it around the worlds y-axis, and then translate it.
am i correct? of course the translation will be pushed to be remembered, but my point is that the rotation will be done first…
anyhow i am just gonna get home and plaey aroundwith it, i think its the best way…
thanks guys [/b]

instead bringing back the model to 0,0,0 for do correct rotation, you just need to move temporally the world 0,0,0 to the current model position, do this:

glpushmatrix(); //save current world matrix
gltraslatef(x,y,x); //move the world to the model position. x,y,z are object position.
glrotate(xangle,1,0,0); //rotate by x
glrotate(yangle,0,1,0); //rotate by y
glrotate(zangle,0,0,1); //rotate by z

drawobject(); //redraw object with current matrix

glpopmatrix(); //restore world to his original state.


tp.

thanks D, i was talking about just that…maybe i was being unclear.
pre multiplication is the answer…
but in geeneral my understanding is correct???

tp: one question:
your solution seems very elegant…
but in this case how do you keep track of xangle, yangle and zangle? as you will still need to do that to get the model be drawn in the correct place