I can't get it to work for the life of me. Its rotating the camera in the global coordinate system, or some other random coordinate system, not the camera local coordinate system. WASDEC work perfectly, right until I start rotating. Here's the annotated code:
//eye.r is the quat camera rotation
//eye.p is the vec3 camera position
// Get the local axes we're going to do transformations with
var axes = {
x: quat4.multiplyVec3(eye.r, [1, 0, 0]),
y: quat4.multiplyVec3(eye.r, [0, 1, 0]),
z: quat4.multiplyVec3(eye.r, [0, 0, 1])
};
// If a movement key is down, add the appropriately scaled local axis
// to our position
if(keystate[W]) vec3.add(eye.p, vec3.scale(axes.z, 10, []));
if(keystate[S]) vec3.add(eye.p, vec3.scale(axes.z, -10, []));
if(keystate[A]) vec3.add(eye.p, vec3.scale(axes.x, 10, []));
if(keystate[D]) vec3.add(eye.p, vec3.scale(axes.x, -10, []));
if(keystate[E]) vec3.add(eye.p, vec3.scale(axes.y, -10, []));
if(keystate[C]) vec3.add(eye.p, vec3.scale(axes.y, 10, []));
// If a rotation key is down, create a scaled rotation about the appropriate
// local axis, and multiply it into the current rotation
if(keystate[UP]) quat4.multiply(quat4.rotation(-0.05, axes.x), eye.r, eye.r);
if(keystate[DOWN]) quat4.multiply(quat4.rotation( 0.05, axes.x), eye.r, eye.r);
if(keystate[LEFT]) quat4.multiply(quat4.rotation(-0.05, axes.y), eye.r, eye.r);
if(keystate[RIGHT]) quat4.multiply(quat4.rotation( 0.05, axes.y), eye.r, eye.r);
Thanks for your help!
Edit: Since it might not be clear what the functions do. This is javascript and the glmatrix linear algebra/quat library.
quat4.multiplyVec3(quat, vec) // vec = quat * vec
vec3.add(vec, vec2) // vec = vec + vec2
vec3.scale(vec, scalar, dest) // dest = vec * scalar
quat4.rotation(angle, axis) // creates a quaternion rotation about the given axis, by the given angle
quat4.multiply(quat, quat2, dest) // dest = quat * quat2