PDA

View Full Version : Flying - Rotating/Translating?



mikeynovemberoscar
01-10-2010, 12:27 PM
Hello I am relatively new to the forums (but not OpenGL) and have made a few 2D games.

I was working on a 3D 'flight' simulator, but I had a problem. The goal is to have the user be able to fly (heading,pitch,roll) through a world, like any spaceship simulator. There will be no 'gravity' or drag.

I had code for heading (y rotation) and pitch (x rotation) but which order do I roll (z rotation)? Do I rotate, then translate, or rotate?

Here is my code:


xp += cos(DEG_TO_RAD * (heading - 90.0f ) ) * sin(DEG_TO_RAD * roll + 90.0f) * airspeed * dt;
zp += sin(DEG_TO_RAD * (heading - 90.0f) ) * airspeed * dt;





yp += sin(DEG_TO_RAD * -pitch ) * cos(DEG_TO_RAD * -roll) * airspeed * dt;


glRotatef(pitch, 1.0f, 0.0f, 0.0f);

glRotatef(roll, 0.0f,0.0f,1.0f);


glRotatef(heading, 0.0f, 1.0f, 0.0f);



glTranslatef(-xp,0.0f,0.0f);

glTranslatef(0.0f,-yp,0.0f);

glTranslatef(0.0f,0.0f,-zp);



I kept the three translates seperate so I can move them easily.

Please help

mikeynovemberoscar

mikeynovemberoscar
01-11-2010, 10:06 AM
OK, I have been researching more. I think my problem is gimbal lock. How do I fix this? I have read about quaternions but I don't really understand.

Yomboprime
01-12-2010, 03:56 PM
Here's a good article on quaternions. There you can basically find functions to convert from a quaternion to matrix and viceversa, and to convert euler angles to a quaternion. And of course quaternion multiplication, that works as transformation combination.

http://www.gamasutra.com/view/feature/3278/rotating_objects_using_quaternions.php

A quaternion is a set of 4 numbers that define a rotation.

You can use quaternions this way:

- You have a quaternion describing the current rotation of the airplane. When you have to draw it in opengl, obtain the matrix from the quaternion and use it in opengl.

- When you have to rotate the airplane, you normally have to do it in X axis, then in Y, then in Z (or any other order). So let's say you have an axis A and an angle a, and want to combine that rotation with the current airplane quaternion. Note that the axis must be in world coordinates, so you probably have to obtain the matrix from the current quaternion and obtaining your axis from the matrix.
Well, there is another operation (described in the article) that converts from an axis and angle to a quaternion. Simply use it to obtain another quaternion (let's say q1) from the axis A and angle a. This quaternion describes the little rotation of the airplane for the current frame.
Now, obtain a third quaternion that is the multiplication of the current quaternion by q1. You have obtained the new airplane quaternion. (If you have to rotate over three axis, obtain q1 and apply the quaternion multiplication twice more)

Regards

mikeynovemberoscar
01-14-2010, 10:51 AM
Yeah thanks but I don't really understand. Can I just check:

Here are my two functions:


eulerToQuat(float qroll, float qpitch, float qyaw, QUAT * quat)
{
float cr, cp, cy, sr, sp, sy, cpcy, spsy;
// calculate trig identities
cr = cos(qroll/2);
cp = cos(qpitch/2);
cy = cos(qyaw/2);
sr = sin(qroll/2);
sp = sin(qpitch/2);
sy = sin(qyaw/2);
cpcy = cp * cy;
spsy = sp * sy;
quat->w = cr * cpcy + sr * spsy;
quat->x = sr * cpcy - cr * spsy;
quat->y = cr * sp * cy + sr * cp * sy;
quat->z = cr * cp * sy - sr * sp * cy;
}


quatToMatrix(QUAT * quat)
{


float x2 = quat->x * quat->x;
float y2 = quat->y * quat->y;
float z2 = quat->z * quat->z;
float xy = quat->x * quat->y;
float xz = quat->x * quat->z;
float yz = quat->y * quat->z;
float wx = quat->w * quat->x;
float wy = quat->w * quat->y;
float wz = quat->w * quat->z;

// This calculation would be a lot more complicated for non-unit length quaternions
// Note: The constructor of Matrix4 expects the Matrix in column-major format like expected by
// OpenGL
return Matrix4( 1.0f - 2.0f * (y2 + z2), 2.0f * (xy - wz), 2.0f * (xz + wy), 0.0f,
2.0f * (xy + wz), 1.0f - 2.0f * (x2 + z2), 2.0f * (yz - wx), 0.0f,
2.0f * (xz - wy), 2.0f * (yz + wx), 1.0f - 2.0f * (x2 + y2), 0.0f,
0.0f, 0.0f, 0.0f, 1.0f)




}


And what I should do:

1. Make quaternion from PITCH, ROLL, and YAW
2. Multiply quaternion to the current one
3. glMultMatrixf(newquaternion);

???

Should I translate before I rotate? Or after?

Yomboprime
01-15-2010, 04:44 PM
Er..sorry, I've answered you in the other post, in "Math and Algorithms" because i read it before this one. Anyway, that forum is better for this thread, i think.

Heres the link to that post
http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=270189#Post2701 89