Need a bit of help with Quaternions

Ok, I have the following code in my InputHandler:



public void update(float tpf) {
   DisplaySystem display = DisplaySystem.getDisplaySystem();
   float yRotation = ((am.getHotSpotPosition().getX()) / (display.getWidth() - 1)) * 2 - 1;
   Quaternion quat = new Quaternion().fromAngleAxis(yRotation * FastMath.PI, Vector3f.UNIT_Y);
   player.getOrientation().set(quat);
   Vector3f directionVector = new Vector3f();
   player.getOrientation().toAngleAxis(directionVector);
   camera.setLocation(player.getCoordinates().add(new Vector3f(0, -5, 2)));
   camera.lookAt(player.getCoordinates().add(directionVector), Vector3f.UNIT_Z);
}



And what this does is it works out a float between -1.0 and 1.0 (inclusive) depending on where the mouse is on the screen, where -1.0 is far left and 1.0 is far right.  It uses this value to set the local rotation (getOrientation()) on a node.  The rotation scalar (yRotation) is multiplied by Pi to produce a rotation between -180 to 180 degrees along the y-axis.  The rest of the code just sets the camera into position.

It took me a while to get my head around Quaternions and as I thought I was beginning to understand them, it did something completely unexpected.  As the mouse crosses the centre of the screen (when yRotation becomes goes from positive to negative or vice-versa) the camera's direction suddenly shifts.  When the mouse is on the left side of the screen (when yRotation is negative), the camera is pointing further downwards than it should be.  When the mouse is on the right (yRotation > 0) the camera is higher (pointing in the correct direction... think).

Can anyone see what I'm doing wrong, I've been struggling with this one for a while now?
(and to think once I get this solved I need to do it for another axis...)

It's onl indirectly related to the mouse movement but at first look what looks odd to me is what you're doing with directionVector. I might just be misunderstanding what it does, but see if this works any better:



public void update(float tpf) {
   DisplaySystem display = DisplaySystem.getDisplaySystem();
   float yRotation = ((am.getHotSpotPosition().getX()) / (display.getWidth() - 1)) * 2 - 1;
   Quaternion quat = new Quaternion().fromAngleAxis(yRotation * FastMath.PI, Vector3f.UNIT_Y);
   player.getOrientation().set(quat);
   Vector3f directionVector = player.getOrientation().getRotationColumn(2);
   camera.setLocation(player.getCoordinates().add(new Vector3f(0, -5, 2)));
   camera.lookAt(player.getCoordinates().add(directionVector), Vector3f.UNIT_Z);
}

That's smooths things out a bit, thanks!



I've seen rotation columns being used in a lot of places on these forums but not entirely sure what they represent.  So, what exactly are the rotation columns of a Quaternion then?  And what do each of the 3 indices represent (noting that you retrieve the last of the 3)?

It gives you the x, y, z axes as they would be after that rotation. 0 is x, 1 is y, 2 is z.

So if the rotation was zero the getRotationColumn(2) should give you the z axis - (0,0,1).



Z axis is the heading usually, which I guess is the intention. toAngleAxis gives you both an axis and an angle to represent the rotation - so the axis alone isn't enough information for a heading.