Alright, so this is how I am doing it:
float xrot = 0;
float yrot = 0;
float zrot = 0;
Quaternion q = new Quaternion().fromRotationMatrix(player.model.getRotation());
if (q.getW() > 1) {
q.normalizeLocal();
}
float angle = (float) (2 * Math.acos(q.getW()));
double s = Math.sqrt(1-q.getW()*q.getW());
// test to avoid divide by zero, s is always positive due to sqrt
// if s close to zero then direction of axis not important
if (s < 0.001) {
// if it is important that axis is normalised then replace with x=1; y=z=0;
xrot = q.getXf();
yrot = q.getYf();
zrot = q.getZf();
// z = q.getZ();
} else {
xrot = (float) (q.getXf() / s); // normalise axis
yrot = (float) (q.getYf() / s);
zrot = (float) (q.getZf() / s);
}
But it doesn't seem to work when I try to put it into use:
player.model.addTranslation(xrot * player.speed, 0, zrot * player.speed);
AddTranslation takes 3 numbers to move my model by than many spaces (x, y, z), but hen I give it the numbers above it doesn't move the model in the direction it has been rotated (on the XZ plane)
Why isn't this working?
Edit: new code, though it's about 45 degrees off now.
Vector3 move = new Vector3();
move = player.model.getRotation().applyPost(new Vector3(1,0,0), move);
move.multiplyLocal(-player.speed);
player.model.addTranslation(move);
xrot
,yrot
, andzrot
define the axis of the rotation specified by the quaternion. I don't think you want to be using them in youraddTranslation()
call...in general, that won't have anything to do with the direction of motion.What I mean by that is: your 3-D object -- let's say for the sake of argument that it's an airplane -- will have a certain preferred direction of motion in its original coordinate system. So if the original orientation has the center of mass at the origin, and the propeller somewhere along the +X axis, the plane wants to fly in the +X direction.
Now you introduce some coordinate transformation that rotates the airplane into some other orientation. That rotation is described by a rotation matrix, or equivalently, by a quaternion. Which way does the plane want to move after the rotation?
You could find that by taking a unit vector in the +X direction: (1.0, 0.0, 0.0), then applying the rotation matrix or quaternion to that vector to transform it into the new coordinate system. (Then scale it by the speed, as you're doing above.) The X, Y, and Z components of the transformed, scaled vector give the desired incremental motion along each axis. That transformed vector is generally not going to be the rotation axis of the quaternion, and I think that's probably your problem.