
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();
}