Quaternions and gimble lock

Hi I originally posted in the Newless Clubies forum, but it was suggested I repost here.

http://www.java-gaming.org/forums/index.php?topic=12796.0

Im trying to create a camera class using JOGL, one fairly similar to an FPS except when moving forward if the camera is angled up or down the height will change. Im trying to use vectors for movement (forward, backward and strafing) and quaternions for for actual view rotation which is placed into a matrix. The whole thing seemed to be working when i was using gluLookat with my vectors ecept for what i think is gimble lock. After I tried quaternions for the view rotation I got allmost exactly the same result as before, what i think is gimble lock.

This is the code for the camera update method


public void updateCamera()
{
	Quat4f rotation = new Quat4f();
		
	AxisAngle4f axisAngleX = new AxisAngle4f(cameraX.x, cameraX.y, cameraX.z, (float)Math.toRadians(angleX));
	AxisAngle4f axisAngleY = new AxisAngle4f(cameraY.x, cameraY.y, cameraY.z, (float)Math.toRadians(angleY));
		
	Quat4f quatXRotation = new Quat4f();
	Quat4f quatYRotation = new Quat4f();
		
	quatXRotation.set(axisAngleX);
	quatYRotation.set(axisAngleY);
		
	rotation.mul(quatYRotation, quatXRotation);
	rotation.normalize();
		
	Matrix4f newViewMatrix = new Matrix4f();
	newViewMatrix.set(rotation);
	newViewMatrix.transpose();
		
	float[] rotationMatrixArray = new float[]
	{
		newViewMatrix.m00, newViewMatrix.m01, newViewMatrix.m02, 0,
		newViewMatrix.m10, newViewMatrix.m11, newViewMatrix.m12, 0,
		newViewMatrix.m20, newViewMatrix.m21, newViewMatrix.m22, 0,
		0, 0, 0, 1
	};

	gl.glLoadIdentity();
	glu.gluPerspective(60.0, 800/600, 2.0, 500.0f);
		
	gl.glMultMatrixf(rotationMatrixArray);
	gl.glTranslatef(cameraPosition.x, cameraPosition.y, cameraPosition.z);
}

The camera has its position, vectors, and angles stored globally and updated in seperate methods.

And to answer zero’s questions from the last thread

[quote]what are the values for the vectors cameraX and cameraY? Simply, the axes <1,0,0>, <0,1,0>?
[/quote]
cameraX and cameraY are the cameras up and strafe vectors, they start off as 1,0,0 and 0,1,0 bu they are updated as the camera moves. I had originally fixed the axes to 1,0,0 and 0,10 and didnt change them. I appeard to get exactly the same result using both methods.

[quote]and do you change angleX/angleY on key strokes?
[/quote]
Im using JInput and polling the mouse “ball”, then adding that to the angles. I was using keys and acheived the same effect, but this way is nicer.

Sorry im finding this hard to explain, I’ll have another go.

If I do nothing except look up or down, the view rotates in a perfect circle around the x axis. The same occurs if i only look left or right, i get a perfect circle around the y axis. If i look left/right then up/or down (or the other way around) I seem to also tilt on the z axis and it feels like im being forced away from the direction I want to rotate. Sometimes it becomes impossible to turn in certain directions.

And thanks for the link Mike Jacobs, Ive been there several times, but I cant seem to make sense of most of the guides and tutorials i find. I thnk there might be something im just missing or cant seem to get my head around.

I think im doing something completely wrong somewhere, though i cant seem to work out where.

Thanks for any help or interest

It almost sounds to me to be less Gimble Lock, and more you may not be rotating along the CORRECT axes. If what you want is to ALWAYS have the camera’s up vector to be straight up, then make sure that you are checking the order of rotation of the camera. If you rotate around the X-axis first, then the Y, your view will likely be tilted. but if instead you rotate around the Y first then the X, you will (likely) achieve the result you want.

However, if you DON’T want the view to always have a defined up vector (not always viewing perpendicular to gravity), then you should check to make sure you’re rotating perhaps around the camera’s up/right/frint vectors instead of the world’s X/Y/Z vectors.

Hopefully this made sense jsut now. If now, let me know and I’ll try to explain better.

–Scott

Thanks Lareon, I reversed the rotation multiplication, and fixed the axisangle rotate for the y angle to 0,1,0 and everything is working much better. It still tilts slightly though, but the whole thing is much more usable now.

Im going to look at it some more and see if I can find whats causing the slight tilt.

My best suggestion for tracking that down is to envision the rotation by hand, and to realize that when you rotate something in OpenGL, you also rotate the object’s axes with it. so if I rotate along the -Z axis by 90 degrees, I’ll find that any further rotations along the +Y axis will be along what USED to be the -X axis.

Hopefully that makes sense and will be useful to you.

Good luck!
–Scott