multiple rotations in Opengl
TinoR

Hi
I need help with rotations in Opengl
I couldn't find a function that would
operate the same kind of way that this one
does for allegro.

void get_rotation_matrix_f(MATRIX_f *m, float x, float y, float z);

What I am trying to do is I have a model of a person. I want to be able to rotate by the yaxis
so the person can turn and walk in different directions.

When the person is walking up and down hills I need to rotate by the x and z axis so that I can make the person look like it is leaning over.

I have trouble with the Rotatef function for opengl because once I rotate around the y axis
It changes the position of the x and z axis.
Im pretty sure that is the function I need to use
but how can I use it to say rotate the y axis by 75 degrees to turn the person around and then rotate the x axis by 10 to make it look like the person is walking up.
Any help is appreciated.
Thanks
Tino

StevenVI

Well, I'm a bit confused on what you're saying, and I know nothing about the Allegro function. This is the prototype for glRotatef:

glRotatef(float rotateFactor, float x, float y, float z);

The x, y, z values (I always believed to be) the percent of the rotateFactor to rotate about the specified axis. So if you just want to rotate around the 'y' axis, you'd call glRotatef(playerAngle, 0.0f, 1.0f, 0.0f);

-Steve

spellcaster

Just make sure you get the rotations in the right order ;)
Lean them forward first, the rotate around y.

Thomas Harte
Quote:

I have trouble with the Rotatef function for opengl because once I rotate around the y axis
It changes the position of the x and z axis.

Quote:

Just make sure you get the rotations in the right order

Notice also that the Allegro function has an order in which it does the rotations since it is the only way that rotations specified like you wish make any sense at all.

Look at it this way - suppose you rotated by 45 degrees around the x axis, then 22 degrees around the y axis. That is exactly the same thing as rotating 22 degrees around the y axis, then 45 degrees around a modified x axis which itself was rotated 22 degrees around y.

Therefore you can always construct the direct equivalent of get_rotation_matrix_f from three glRotatefs. You'll just have to guess the right order of x,y,z rotations, since the Allegro docs won't tell you! But there are only six possible arrangements, so...

X-G

The whole rotating axes thing also has the unfortunate side effect of gimbal lock ...

Thomas Harte

But Tino Restivo seems to want to use only two axes, not all three, so surely he won't have a problem?

X-G

He should be fine. But it's good to show the whole picture, in case he ever decides he needs that extra axis.

Edit:

Quote:

The x, y, z values (I always believed to be) the percent of the rotateFactor to rotate about the specified axis.

The x, y, z values specify an arbitrary axis to rotate around.

kazzmir

Does gimble lock only occur if you explicitly rotate around X then rotate around Y then rotate around Z? Would it go away if you just combined those three rotation matricies then rotated by that?

spellcaster

Just use a quaternion, does the same job, and is plain simple to use. U'm using the quaternion functions which were in that gamedev (or gamasutra) article... but i guess those in gameprogramming gems will work, too.

Thomas Harte
Quote:

Does gimble lock only occur if you explicitly rotate around X then rotate around Y then rotate around Z? Would it go away if you just combined those three rotation matricies then rotated by that?

No, gimbal lock is unavoidable in any system that measures orientation in Euler angles.

Quote:

Just use a quaternion, does the same job, and is plain simple to use.

There are actually three significant options without any sort of singularities ala gimbal lock, each with different pros and cons.

Quaternions are one. The main attraction is that you can interpolate between Quaternions and get pretty much the same effect as if you were to do the job by hand in real life. Quaternions are therefore very good for applications such as skeletal animation. They are also relatively compact - four numbers but usually with the constraint that the sum of the squares is equal to one, so you can get away with three. The downsides are that the Quaternions maths is difficult to understand and therefore hard to be inventive with, and Quaternions must be converted to matrices in order to use with any modern graphics card, so additional costs are incurred there.

Axis/angle rotations are another. In this scheme a single three component vector describes orientation - the direction of the vector is an axis to rotate around and the length of the vector is the angle. This is the system usually used by physics simulations because it is very easy to sum impulses and thus calculate how orientation is affected by collisions. The maths is easy to understand, but as with Quaternions requires a quick matrix-ification for the purposes of graphics cards. However, glRotatef will do this if you can afford a sqrt and is no doubt done in hardware on some modern cards so this isn't necessarily much of a cost. NOTE TO ORIGINAL POSTER: this method is particularly easy for games such as yours.

Special orthogonal matrices are the third. Your object's orientation is defined entirely by the matrix that is used to position its points. For rotations only you are talking about a minimum storage of four numbers, so storage costs are at least 33% higher than for the other two methods. However, the information required to do common manoeuvers (i.e. roll, yaw, pitch) from the point of view of the object is explicitly present and matrices are how the hardware works in the end anyway. However, numerical errors creep in relatively quickly, so especially on low precision targets this may not be a sensible option.

spellcaster

Coul you elaborate more on the axis/angle rotations? Any links? A desire to post a longer explanation? ;)

Thomas Harte
Quote:

Coul you elaborate more on the axis/angle rotations? Any links? A desire to post a longer explanation?

You have a 3d vector, say P=(x, y, z). When you need to create a rotation matrix for your object you do this:

glRotatef(sqrt(x*x + y*y + z*z), x, y, z);

i.e. you really are just using the vector (x,y,z) as your axis and the length of (x,y,z) as your rotation amount.

For physics simulations, you can additionally keep a rotational velocity, V. If you then have an impulse F act upon a body at a position N then you can sum this into the rotational velocity very simply with:

V += (N-P)xF
(x is vector product)

This is the main power of axis/angle systems. Naturally you can describe player required motions as impulses too, and get a body that reacts to user input. You'll have to do some maths inbetween which will more or less amount to a matrix conversion, but...

Bob
Quote:

U'm using the quaternion functions which were in that gamedev (or gamasutra) article... but i guess those in gameprogramming gems will work, too.

There are also the Allegro routines, and those neat AllegroGL functions which turn a QUAT into the components needed for a single glRotate.

Also, you can convert from Axis-Angle to Quaternions and back, and use whichever is easiest for you.

Korval
Quote:

No, gimbal lock is unavoidable in any system that measures orientation in Euler angles.

Let's be clear on this.

Gimbal lock occurs only if you apply 3 successive rotations matrices together that rotate along 3 different axes. I posted a method for converting the 3 Euler angles into 2 angle-axis rotations. This method uses Euler angles to do rotations, but it does not produce Gimal locks.

Quote:

However, glRotatef will do this if you can afford a sqrt and is no doubt done in hardware on some modern cards so this isn't necessarily much of a cost.

I'm almost certain that implementations do not implement these functions in hardware. It wouldn't be worth the silicon; you may as well use the CPU features (SSE/3DNow/etc) to speed up the operations as much as you can.

Quote:

There are also the Allegro routines, and those neat AllegroGL functions which turn a QUAT into the components needed for a single glRotate.

Many angle/axis-to-matrix implementations prefer to convert the angle/axis values into Quaternions and then using Quat-to-matrix on them. Wouldn't it be better/faster to just have a Quat-to-matrix function and let them use glMultMatrix?

Bob
Quote:

Many angle/axis-to-matrix implementations prefer to convert the angle/axis values into Quaternions and then using Quat-to-matrix on them. Wouldn't it be better/faster to just have a Quat-to-matrix function and let them use glMultMatrix?

I have no idea actually. Might be interesting to benchmark glRotate() vs glMultMatrix()...

spellcaster
Quote:

There are also the Allegro routines, and those neat AllegroGL functions which turn a QUAT into the components needed for a single glRotate.

The allegroGL docs should be added to the main download :)

TinoR

Hi
Thanks for the help I tried using
the way Thomas suggested It works good.
glRotatef(sqrt(x*x + y*y + z*z), x, y, z);

Thanks again
It was easy to use in the code I already have.

Thread #260087. Printed from Allegro.cc