Jump to content
  • Advertisement
Sign in to follow this  


This topic is 4040 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Well, if you have an object with it's own local coordinate system, you can put it into another coordinate system by translating it. For instance, to get an object into the world's coordinate system, you translate the object's local coordinate system by the object's position in the world. If I misunderstood the question, please clarify.

Share this post

Link to post
Share on other sites
I've checked the OpenGL FAQ. If we premultiply the current matrix by a transformation matrix it will transform the object w.r.t the world axis not local space. But gl transformation calls only postmultiply. How can I make a premultiplication ?

Share this post

Link to post
Share on other sites
You apply your transformations in reverse order. The last transformation you make actually has the effect of being the first transformation applied. So, like this:

glTranslatef(100.0F, 100.0F, 0.0F); //Move object to (100, 100, 0) in world
glRotatef(45.0F, 0.0F, 1.0F, 0.0F); //Rotate the object 45 degress around Y axis
glScalef(10.0F, 10.0F, 10.0F); //Scale the object

What happens to the object is this:

1. It gets scaled by 10 in x, y, and z
2. It gets rotated around the Y axis, at its center, by 45 degrees
3. It gets moved to world position (100, 100, 0)

The reason this is the case is that OpenGL uses column vectors. When transforming a column vector by a matrix, the matrix has to be on the left and the vector on the right. This has the effect that when you post-multiply the transformation matrix, you are actually adding a transformation to be applied earlier than the existing transformations. Hope this makes sense.

Share this post

Link to post
Share on other sites
A chain of n transformations is mathematically written down as
M := M1 * M2 * ... * Mn

Matrix multiplication isn't commutative (so you can't exchange 2 matrices and expect to get the same result), but the order of performing the multiplications itself plays no role:
( M1 * M2 ) * M3 == M1 * ( M2 * M3 )
Please bear in mind that vectors are just 1 column or 1 row matrices.

If using column vectors (as OpenGL does), such a transformation is applied to a vector like so:
v' := M * v = M1 * M2 * ... * Mn * v

Due to OpenGL uses post-multiplication, you simply provide OpenGL with the data from left to right. I.e. you first provide M1, then with M2, ..., and last but not least v. Due to the feature shown above, it is totally okay to provide all transformations before providing the vertices. As an example, the sequence
glRotate(...); // M1
glTranslate(...); // M2
glScale(...); // M3
glVertex(...); // the 1st v
glVertex(...); // the 2nd v
glVertex(...); // the 3nd v
works like
M := I * M1 * M2 * M3
v1' := M * v1
v2' := M * v2
v3' := M * v3

The effect becomes clear when remembering (from the said above) that
M1 * M2 * M3 * v
can be written as
M1 * ( M2 * ( M3 * v ) )

Interpreting this one can say that M3 is applied to v, M2 is applied to the result of the former transformation, and M1 is applied to the respective result. This fact is what strtok means with "applied in reverse order" (although I'm not happy with using this term here, since the math shows that OpenGL doesn't revert anything in a closer sense; but that is a matter of taste).

A local co-ordinate frame L can be understood as a transformation that maps geometry given in the (local) frame to the parent frame (i.e. the co-ordinate frame where the local frame is given in). Without loss of generality we assume that L is given in the "world". So geometry in the local frame is transformed into the world by
vw := L * vl

A transformation M that should be applied to the geometry is given in a co-ordinate frame. You get the desired effect if and only if you apply the transformation to the geometry in the same co-ordinate frame. This can be reached by transforming the geometry into the frame where M is given in (and normally transforming the result back to the local frame).

Assume e.g. that M is given already in the geometry's local frame: Ml. Then you can apply it directly, yielding in a transformed geometry still given in its local frame:
vl' = Ml * vl

The transform M may alternatively be given in "world" frame: Mw. So you have to compute the Ml from Mw first, yielding in
Ml := L-1 * Mw * L

Why this? Setting in you get
vl' = L-1 * Mw * L * vl = L-1 * ( Mw * ( L * vl ) )
Here you can see exactly the steps descibed above: The geometry is transformed into the wanted frame (here from its local frame to "world"), the wanted transformation is applied, and the result is transformed back to the local frame. You can drop the back transformation, of course, if you want the result be given in the world frame.

So, for OpenGL in that case, you would have to provide the inverse of the local frame's transformation, followed by the desired transformation, followed by the local frame's transformation.

Share this post

Link to post
Share on other sites
Thats ok, suppose I have a sphere sitting on the world coordinate origin, and one box rotating about the world's y-axis and also x-axis. When I write the above code, after some translation in the z-axis, the box rotation behave stranglely i.e it rotates around z-axis instead of y-axis. I think thats because of the postmultiplication

// Draw a sphere at the world origin

// Draw a box
glRotatef(pitch, 1.0f, 0.0f, 0.0f);
glRotatef(yaw, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0f, 0.0f, transZ);

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!