Search code examples
openglmathrotationlwjgllinear-algebra

How to roll,pitch,yaw an object like flight simulator in OpenGL?


I'm working on a college Graphics project using LWJGL (OpenGL in Java). I've done most of the scene but I got a problem in figuring out the jet's orientation.

Here's how I tried it at the very beginning: (After translate it to the desired position)

        GL11.glRotatef(xRotation, 1, 0, 0);
        GL11.glRotatef(yRotation, 0, 1, 0);

Then I found the I came across the gimbal lock problem? For example: the jet roll 90 degrees to the right, then it pitch up so that it will make a right turn. But if I pitch up 90 degrees first, then roll at some angle, it look like it's Yawing ! It's still rotate along the original X-axis.
Roll -> Pitch looks fine.
But Pitch -> Roll looks BAD.

Then I tried another way:

        GL11.glRotatef(xRotation, 1, 0, (float)Math.tan(Math.toRadians(-yRotation)));   
        GL11.glRotatef(yRotation, 0, 1, 0);

This time the problem actually inverses! The case I just described is inversed.
Roll -> Pitch looks BAD.
But Pitch -> Roll looks fine.

I can't even imagine what might happen when I add the Yaw Rotation into this.

The jet should be able to orient at any direction and Roll,Yaw,Pitch should not interfere with each other

I've done lot of research, it appears to me that I have to aggregate the Roll-Pitch-Yaw 3 rotations into one which is represented by Quaternions. But I'm really confused about the term. If someone has experience in doing a similar work plz give me some hints(examples are much appreciated!), I'm really really frustrated by this. Thank you !


Solution

  • You can use quaternions but you don't need to. Quaternions are just another way of representing a rotation. If you want, you can keep the matrix representation of glRotatef. However, I would really recommend to abandon these deprecated methods.

    You already know the solution. You need to accumulate the rotations. Thus, don't reset the matrix. If you want to turn left, call

     GL11.glRotatef(turnDegrees, 0, 1, 0);
    

    once, where turnDegrees is the amount of degrees you want to turn left. In terms of matrices, this is:

    ModelMatrix = ModelMatrix * RotationMatrixY(turnDegrees)
    

    This will accumulate the rotations in the ModelMatrix and you don't need to worry about transformation order.