Simple transformation problem

You’re probably not accumulating your rotations, and were sending the same rotation each frame after a glLoadIdentity.

what you should do is increment your globals by whatever method you use to calculate the rotation angle, i.e.:

xmouseD += <some function to calculate angle change>

ymouseD += <same thing>

I still suspect your doing this in some funky way, but…
either way…glad to hear it’s finally working.

The reason behind this is, that rotation and translation calls are postmultiplied to to current modelview matrix. Meaning that the call you performed last will be executed first on the object you are drawing.

e.g. if a canonturret-object is defined at the origin with the Y-axis as the axes of revolution, you will want to rotate it first before you put it on top of the tank with a translation.

By calling translatef before rotatef, the rotation is performed before the translation.

If you reverse the operation, it means that you position the turret on top of the tank, and after that you rotate the turret around the axis, passing through the projection center of your camera, which was not what you intended to do.

It’s hard to say why your other code with the operations exchanged didn’t work without the code.

Nico

I didn’t accumulate the angle when I was not loading the identity matrix at the start of each frame (and this is logical AFAIK).
Exchanging the rotation calls didn’t help then.

Now I am loading the identity matrix at the start of each frame and use the accumulated angles.
It’s working only when I exchange the rotation calls.

I don’t understand why exchanging the rotation calls solve the problem.
And I don’t understand why it doesn’t work when I don’t load the identity matrix and transform the old model matrix.

Just to be clear, by exchanging rotation calls, do you mean exchanging tarnslation and rotation calls or exchanging rotate-x and rotate-y?

Nico

Originally posted by -NiCo-:
[b]The reason behind this is, that rotation and translation calls are postmultiplied to to current modelview matrix. Meaning that the call you performed last will be executed first on the object you are drawing.

e.g. if a canonturret-object is defined at the origin with the Y-axis as the axes of revolution, you will want to rotate it first before you put it on top of the tank with a translation.

By calling translatef before rotatef, the rotation is performed before the translation.

If you reverse the operation, it means that you position the turret on top of the tank, and after that you rotate the turret around the axis, passing through the projection center of your camera, which was not what you intended to do.

It’s hard to say why your other code with the operations exchanged didn’t work without the code.
Nico[/b]
But I didn’t exchange the rotation with the translation, but one rotation with the other one and it worked. So how could it solve the problem that it was rotating not correctly?

Ok, I see now. Maybe the object you are drawing is an object of revolution about the x-axis.

In that case, by calling:

glRotatef((float)xmouseD , 0.0f, 1.0f, 0.0f);
glRotatef((float)ymouseD , 1.0f, 0.0f, 0.0f);

the glRotatef((float)ymouseD , 1.0f, 0.0f, 0.0f) call will have no effect at all.

Also, if you accumulate the angles, the total rotation becomes:

Ry_total*Rx_total

if you don’t accumulate, it becomes:

Ry_frame_iRx_frame_iRy_frame_i-1Rx_frame_i-1 . . . Ry_frame_0Rx_frame_0

These are not equivalent.

Nico

Originally posted by -NiCo-:
Ok, I see now. Maybe the object you are drawing is an object of revolution about the x-axis.

In that case, by calling:

glRotatef((float)xmouseD , 0.0f, 1.0f, 0.0f);
glRotatef((float)ymouseD , 1.0f, 0.0f, 0.0f);

the glRotatef((float)ymouseD , 1.0f, 0.0f, 0.0f) call will have no effect at all.
What do you mean with “object of revolution”? Anyway it seems that this is not the case because a transformation occurs for both axis when the problem happens.

Also, if you accumulate the angles, the total rotation becomes:

Ry_total*Rx_total

if you don’t accumulate, it becomes:

Ry_frame_iRx_frame_iRy_frame_i-1Rx_frame_i-1 . . . Ry_frame_0Rx_frame_0

These are not equivalent.

Nico
I just meant the addition of all previous mouse movements with acccumulation.

I was using only the DELTA angle of mousmovement for rotation when I didn’t load the identity model view matrix.
Exchanging the rotation calls didn’t help here.

I was using the total angle of mousmovement for rotation when I did load the identity model view matrix.
Exchanging the rotation did help here.

Is this what you considered with your explenation and I just didn’t understand?

Objects of revolution are objects which are symmetrical about an axis.

This is what I’m trying to say:

When you don’t load identity, the first frame becomes:

glRotatef((float)xmouseDelta1 , 0.0f, 1.0f, 0.0f);
glRotatef((float)ymouseDelta1 , 1.0f, 0.0f, 0.0f);

For the second frame, the modelview matrix is equivalent to calling the next piece of code in the first frame:

glRotatef((float)xmouseDelta1 , 0.0f, 1.0f, 0.0f);
glRotatef((float)ymouseDelta1 , 1.0f, 0.0f, 0.0f);
glRotatef((float)xmouseDelta2 , 0.0f, 1.0f, 0.0f);
glRotatef((float)ymouseDelta2 , 1.0f, 0.0f, 0.0f);

This is not equivalent to loading the identity matrix and calling:

glRotatef((float)(xmouseDelta1+xmouseDelta2) , 0.0f, 1.0f, 0.0f);
glRotatef((float)(ymouseDelta1+ymouseDelta2) , 1.0f, 0.0f, 0.0f);

because the latter is equivalent to:

glRotatef((float)xmouseDelta1 , 0.0f, 1.0f, 0.0f);
glRotatef((float)xmouseDelta2 , 0.0f, 1.0f, 0.0f);
glRotatef((float)ymouseDelta1 , 1.0f, 0.0f, 0.0f);
glRotatef((float)ymouseDelta2 , 1.0f, 0.0f, 0.0f);

and the second and third rotation matrices can not be interchanged.

Nico