0
votes

Initial PoseAfter rotationUnwanted affectThe wanted affectI'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();
1
insert standard disclaimer about deprecated fixed function pipeline, the current way to do this is using shaders and managing your own transformation matricesratchet freak
Unclear what you want to do and what your values means. Few illustrations or screenshots with comments would be nice. From what I'm able to understand, you need all translates first, then rotation.keltar
@keltar What I want to do basically is to move (translate) the model with the direction of rotation. For example, if I rotate the model 90 degree to the left (around z-axis), then moving the object along the -x axis, the model should move down (according to the model (local) coordinate, and not left according to the world coordinate.jouzef19
@jouzef19 your last comment contradicts with "the rotation is no longer around the model center". Anyway, I've already said what I wanted to - it is you who's looking for answer, so it's up to you to describe the problem in a way others could understand. From my point it is not the case here, sorry. Since there are only two combinations possible, and both of them don't satisfy you - I really fail to understand what you want it to be.keltar
@jouzef19 From your comment, it would seem that you want to translate first, then rotate. How does the result of translate then rotate (remembering that operations are applied in reverse order from the code) differ from the desired results? Pictures of what you're getting and what you expect would really help.beaker

1 Answers

0
votes

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):

[3  2  3  4]
[5  2  3  2]
[0  0  0  0]
[1  1  1  1]

So the first point is at x=3, y=5, z=0. Drawing this model we get:

Original model

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:

Model rotated then translated Y

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:

Model rotated then translated at angle

This, I believe, is what you DO want. Here's the code I used.

glTranslatef(3.0, 3.0, 0.0);
glTranslatef(-2.728, 2.924, 0.0);
glRotatef(43.0, 0.0, 0.0, 1.0);
glTranslatef(-3.0, -3.0, 0.0);  

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:

glTranslatef(3.0, 3.0, 0.0);
glRotatef(43.0, 0.0, 0.0, 1.0);
glTranslatef(0.0, 4.0, 0.0);
glTranslatef(-3.0, -3.0, 0.0);  

Here's the result of the second set of code for comparison:

Model translated then rotated

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 _yTranslate variable, for each press of the "rotate" button, add or subtract some value from _zangle, and so on.