yes, more coffee.
it depends on when you apply which quat to which vector/matrix :persecutioncomplex: … and if the update values are deltas or not.
it’s not clear from the code yet.
you could do something like this : idea is to create vectors, apply quaternions and then extract matrix. this might be not the most correct way to do it but is convenient and fast.
camera : vec3d pos, up, side (right in your code), dir.
side/right : always calculated with cross(up,dir)
so if i’d rotate the camera along Y axis, to me thats the one pointing up, looking left and right :
void rotate_Y ( float angle ) // angle is delta, not the absolute value
{
quat.setXYZ( up.x * angle , up.y * angle , up.z * angle ); // quat made of up
quat.setW(1.0f);
normalize(quat);
quat.applyTo( up );
quat.applyTo( dir );
side = cross(up, dir);
}
… to rotate along the X axis (nodding up and down) you would use a quat made of side/right, do rotate Z (head bobbing) quad would be made of dir
the apply method could be something like (quat and vector are expected to be normalised) :
public vec3 apply ( vec3 v )
{
float tx = q.y*v.z - v.y*q.z + v.x*q.w;
float ty = q.z*v.x - v.z*q.x + v.y*q.w;
float tz = q.x*v.y - v.x*q.y + v.z*q.w;
v.x += 2.0f*( q.y*tz - ty*q.z );
v.y += 2.0f*( q.z*tx - tz*q.x );
v.z += 2.0f*( q.x*ty - tx*q.y );
return v;
}
// or another version :
public vec3 apply ( vec3 v )
{
float tx = q.y*v.z - v.y*q.z;
float ty = q.z*v.x - v.z*q.x;
float tz = q.x*v.y - v.x*q.y;
tx += v.x*q.w;
ty += v.y*q.w;
tz += v.z*q.w;
float cx = q.y*tz - ty*q.z;
float cy = q.z*tx - tz*q.x;
float cz = q.x*ty - tx*q.y;
v.x += 2.0f*cx;
v.y += 2.0f*cy;
v.z += 2.0f*cz;
return v;
}
// .. or this (works good with glsl)
vec3 apply_quat( in vec4 quat, inout vec3 v )
{
v += 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);
return v;
}
whatever works for you …
now update the projection/modelview with your fav. math lib. like …
projection = setPerspective( fov_y, display_ratio, znear, zfar );
modelview = setLookDir( pos, dir, up );
GLU methods can help here too.