quaternions for object orientation

I’ve done a lot of Googling, code reading and experimentation and I just can’t seem to get object orientation working using quaternions.

Can anyone point me to some code showing how to orient an object with quaternions and render the object in OpenGL (preferably - but not neccessarily - using java)

TIA

Peter.

:slight_smile:
I think I can help you. I was having the same problem with a molecule viewer I am working on. Drove me damn near insane for 10 days. Couldn’t eat, kicked the dog, didn’t service the wife…anyhow I hit upon this as a solution that finally worked. Note I am using some Java3D classes for Quaternion, AxisAngle4d and Matrix4d. There are java examples on the web where you can implement these yourself. I am storing my mouse rotations in the Quaterion, but converting each mouse drag from Euler to Quaternion. The key is to maintain the rotation in the quaterion by updating. A really important key is to make sure that you initialize the rotation quaternion (viewQuat for me) to the 0, 0, 0 euler angles…let me know how it works for you…

//*******Converts euler angles to quaterion
public Quat4d toQuaternion(double pitch, double yaw, double roll)
{
Quat4d qt = new Quat4d();

    double radx = Math.toRadians(pitch);
    double rady = Math.toRadians(yaw);
    double radz = Math.toRadians(roll);

    AxisAngle4d aax = new AxisAngle4d(1, 0, 0, radx);
    AxisAngle4d aay = new AxisAngle4d(0, 1, 0, rady);
    AxisAngle4d aaz = new AxisAngle4d(0, 0, 1, radz);
    Quat4d qtx = new Quat4d();
    Quat4d qty = new Quat4d();
    Quat4d qtz = new Quat4d();
    qtx.set(aax);
    qty.set(aay);
    qtz.set(aaz);
    qt.mul(qtz, qty);
    qt.mul(qtx);
    qt.normalize();

    return qt;
}

public void display(GLDrawable drawable)
{
    GL gl = drawable.getGL();
    GLU glu = drawable.getGLU();
    //**********Rotation Stuff***************
    Quat4d mouse_quat, temp_quat;
    // Converts the current mouse movement from Eulers to Quaternion
    mouse_quat = toQuaternion(tempx, tempy, tempz);
    // Holds the old rotation
    temp_quat = viewQuat;
    // Set the value of the viewQuat (stores the rotation) to the value
    // of the (current rotation) X (the old rotation)....order matters!
    viewQuat.mul(mouse_quat, temp_quat);
    // Now that the current rotation is updated need to make it
    // OGL friendly...
    Matrix4d rotmat = new Matrix4d();
    // Converts the quat to a roation matrix
    rotmat.set(viewQuat);
    // Have to flip it so it works for openGL
    rotmat.transpose();
    // now we have to make it linear
    double[] rotate = new double[]
        {
        rotmat.m00, rotmat.m01, rotmat.m02, 0,
        rotmat.m10, rotmat.m11, rotmat.m12, 0,
        rotmat.m20, rotmat.m21, rotmat.m22, 0,
        0, 0, 0, 1
    };

    tempx = 0;
    tempy = 0;
    tempz = 0;

    gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
    gl.glLoadIdentity();
    gl.glPushMatrix();
    gl.glTranslated(transX / 10, -transY / 10, -zoom);
    //  Now we can multipy the current matrix by our linearized 
    // rotation matrix
    gl.glMultMatrixd(rotate);
    drawMoleculeHash(drawable);
    gl.glPopMatrix();
    gl.glFlush();
}

Cheers! Thanks very much for that, your post help me get past the worst of the problem :slight_smile:

I still have a little work to do as I want to rotate around the object’s own axis’ (ie.: pitch roll and yaw relative to the objects frame of reference, not the world space x,y,z) but that should be trivial (I hope) - but I thought I’d jst say thanks for the help before I forge on :slight_smile:

BTW: I think the transpose is redundant isn’t it? Instead of transposing the data then loading it into a GL-friendly 2d array in order, why not load it into the array taking into acount it’s initial order? (the transpose just rearranges the order of the data in the matrix, IIRC?)

Also: I’m sure some performance would be gained by caching the matrix and GLdouble array and resetting the data rather than creating them new each time?

Anyway - thanks again for the help, I’ve been struggling with &!%#&^!! Quaternions for so long and finally getting on top of them is brilliant!

Thanks,

Peter.

Yep, I noticed some of those optimization errors too and have fixed them. You know how it is when you pull the shot gun out to try and solve a problem. Shoot first and clean up the mess later! I believe what you want to accomplish can be done by merely changing the order of operations. So instead of translate, rotate, draw you would rotate, translate, draw or something. Also if you switch the order of multiplication of the Quats you can get them to rotate differently too. Good luck and I am glad to be of some help.

[quote]Yep, I noticed some of those optimization errors too and have fixed them. You know how it is when you pull the shot gun out to try and solve a problem. Shoot first and clean up the mess later! .
[/quote]
LOL! Yeah - make it work first then make it fast :slight_smile:

I got the rotations working relative the object quite easily. I maintain an up, forward and right vector for each object and when I create the rotation matrix, use that matrix to transform the vectors. These can then be used for the pitch, roll and yaw axis/angle rotations. It works fine.

The only thing that is wierd and I don’t undertand is that the rotation works fine if I watch an object which I rotate using pitch/roll/yaw relative to its own frame of reference, yet if I attach a camera to that object so I can render from it’s frame of reference, the rotations are all screwed up and whip around in strange ways.

I’m not sure where the problem lies, but that’s my current area of investigation :slight_smile:

Anyway, thanks for the input - it really has helped :o)

It’s been my experience that when I get “whippy rotations” that somewhere I’ve forgotten to convert my degrees to radians, other than that who knows?