Sequential rotations not giving expected results

Hi!

I’m having some problems doing sequential rotations in OpenGL. My goal is to show the orientation of an aircraft using it’s pitch/roll/yaw values. Since it’s shown in a coordinate system I can’t just move the view so I have to rotate the model.

The problem is that the following doesn’t work (for this application) since after the first (i.e last call to glRotatef) the second rotation isn’t around the “new” X axis:


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

After looking around I have found some hints on solutions, but I can’t seem to get the hang of it.

I’m using pyopengl (OpenGL Python bindings) and here are some off the things that I tested:

Using quaternions (which in my case produces the same result as sequential calls to glRotatef):


        p = 0 * (math.pi/180) / 2.0;
        y = aircraft_pitch * (math.pi/180) / 2.0;
        r = aircraft_roll * (math.pi/180) / 2.0;
 
        sinp = math.sin(p);
        siny = math.sin(y);
        sinr = math.sin(r);
        cosp = math.cos(p);
        cosy = math.cos(y);
        cosr = math.cos(r);
 
        x = sinr * cosp * cosy - cosr * sinp * siny;
        y = cosr * sinp * cosy + sinr * cosp * siny;
        z = cosr * cosp * siny - sinr * sinp * cosy;
        w = cosr * cosp * cosy + sinr * sinp * siny;        

        T =  [ 1 - 2*y*y - 2*z*z,    2*x*y - 2*w*z,      2*x*z + 2*w*y, 0,
              2*x*y + 2*w*z,    1 - 2*x*x - 2*z*z,    2*y*z - 2*w*x, 0,
              2*x*z - 2*w*y,      2*y*z + 2*w*x,    1 - 2*x*x - 2*y*y ,0,
              0,0,0,0]
        glMultMatrixf(T)

I’ve also tried to using the current ModelView matrix as input for the axis to do the rotation around (which causes the rotation to be slightly crooked):


        mvm = glGetFloatv(GL_MODELVIEW_MATRIX)
        norm = math.sqrt(mvm[0][0]*mvm[0][0] + mvm[0][1]*mvm[0][1] + mvm[0][2]*mvm[0][2])
        glRotatef(aircraft_roll, mvm[0][0]/norm, mvm[0][1]/norm, mvm[0][2]/norm) #Roll
        mvm = glGetFloatv(GL_MODELVIEW_MATRIX)
        norm = math.sqrt(mvm[2][0]*mvm[2][0] + mvm[2][1]*mvm[2][1] + mvm[2][2]*mvm[2][2]) 
        glRotatef(aircraft_pitch, mvm[2][0]/norm, mvm[2][1]/norm, mvm[2][2]/norm) # Pitch

I’m using the following setup:


        glShadeModel(GL_SMOOTH)
        glClearColor(0.0, 0.0, 0.0, 0.0)
        glClearDepth(1.0)
        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LEQUAL)
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)

        glViewport(0, 0, width, height)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(45, 1.0*width/height, 0.1, 100.0)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

I would really appreciate some help here since I’m pretty stuck at the moment…

Thanks!

So what’s the extra divide by 2 in your deg-to-rad conversions?

Also your aggregate rotation matrix form looks nothing like what I think it should. Where did it come from? Lots more complex than a straight concatenation of elemental rotation matrices.

One other thing: save yourself (and your readers) a lot of headache and explicitly define up-front what heading, pitch and roll “are” in a right-handed coordinate system. Everyone’s got their own favorite convention. E.g. from your pseudocode, presumably pitch is positive rotation around +Y axis.

It was in one of the examples that I found… Since I didn’t think it was related to my problem I never looked into it.

It’s from a tutorial that I found. Do you have an example of what it should look like?

I’ll remember it for the next post.

But are any of the methods along the right track or am I completely off… ?

[quote=“macke_”]

It’s from a tutorial that I found. Do you have an example of what it should look like?[/QUOTE]
Not in code that I can post from. However, just write out the 3 3x3 rotation matrices in symbolic form and multiply them by hand. Pretty easy exercise.