
I'm programming a simple application in OpenGL. I have a model that I want to rotate around its center (local coordinate), then translate it along with its local coordinate, too. I've done two scenarios,
rotate then translate, and vice versa. In the first scenario, I got the rotation correct but the model then translate based on the world coordinate not the model (local) coordinate. When I translate first, I got the translation right but the rotation is no longer around the model center.
here's the code,
glPushMatrix();
// ignore this
/*glRotatef(_zRoll, 0.0, 0.0, 1.0);
glRotatef(_yTilt, 1.0, 0.0, 0.0);
glRotatef(_xPan, 0.0, 1.0, 0.0);*/
glScalef(scale, scale, scale);
glTranslatef(0.0, 0.0, -2.0);
glTranslatef(_xTranslate, _yTranslate, _zTranslate); // The required translation
// The required rotation
glRotatef(_yangle, 0.0, 1.0, 0.0);
glRotatef(_zangle, 0.0, 0.0, 1.0);
glRotatef(_xangle, 1.0, 0.0, 0.0);
glTranslatef(coord.x, coord.y, coord.z); // translate to the model center
glCallList(aHelix);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glPopMatrix();
glutSwapBuffers();
I think I understand now what you're looking for. I will attempt to restate what you want, so please correct me if I am mistaken.
Let's take a simple model with the following vertex coordinates (columns are vertices):
So the first point is at x=3, y=5, z=0. Drawing this model we get:
If we simply rotate the model (in this case by 43°) and then translate it in the Y direction (up), say 4 units, we get this:
The model has now moved 4 units in the Y direction, but in the world coordinate frame. As I understand it, the result above is what you DO NOT want.
If instead we translate the model in the direction it is pointing after rotation, we get this:
This, I believe, is what you DO want. Here's the code I used.
I first rotate the model by 43 degrees and then translate it according to the updated local Y direction. I got the hardcoded translation vector by taking the vector
[0 4 0 0]and rotating it using the same 43° rotation matrix I used for the model. This isn't straightforward to do programmatically (at least in the fixed pipeline) and it gets worse with subsequent rotations.It turns out, though, that you get the exact same results (which you can verify manually) by performing the translation by
[0 4 0 0]first, followed by the rotation:Here's the result of the second set of code for comparison:
The problem is that if you do any subsequent rotations/translations, your coordinate systems still get all messed up. To get around this, you need to make sure you're using an accumulator for your rotations and translations and applying them all at once to the original model rather than making small incremental changes. So, for each press of the up-arrow key, add some incremental value to your
_yTranslatevariable, for each press of the "rotate" button, add or subtract some value from_zangle, and so on.