I switched everything to quats.. and all is well except one thing.. ill try to explain the best i can
I build a rotation matrix from a quaternion and use it as such for all my game objects
screenSpace = projMat * camMat * translateMat * rotateMat * scaleMat * positionVec
and for my camera
camMat = rotateMat * translateMat * camOrigin
where rotateMat is given by the following
NSMatrix4Df NSQuaternion::getRotationMatrix() const
{
NSMatrix4Df retMat;
retMat.setRow(NSVec4Df(getRightVec(), 0.0f), 0);
retMat.setRow(NSVec4Df(getUpVec(), 0.0f), 1);
retMat.setRow(NSVec4Df(getTargetVec(), 0.0f), 2);
return retMat;
}
NSVec3Df NSQuaternion::getRightVec() const
{
return NSVec3Df(1.0f - 2.0f*y*y - 2.0f*z*z, 2.0f*x*y - 2.0f*w*z, 2.0f*x*z + 2.0f*w*y);
}
NSVec3Df NSQuaternion::getUpVec() const
{
return NSVec3Df(2.0f*x*y + 2.0f*w*z, 1.0f - 2.0f*x*x - 2.0f*z*z, 2.0f*y*z - 2.0f*w*x);
}
NSVec3Df NSQuaternion::getTargetVec() const
{
return NSVec3Df(2.0f*x*z - 2.0f*w*y, 2.0f*y*z + 2.0f*w*x, 1.0f - 2.0f*x*x - 2.0f*y*y);
}
I then have a rotate function that when I call rotates the object about a given axis - shown below
void NSQuaternion::rotate(const NSVec3Df & pAxis, float pAngle)
{
NSQuaternion localRotation, temp(pAxis, pAngle);
float halfAngle = sinf(DegreesToRadians((pAngle/2.0f)));
localRotation.x = pAxis.x * halfAngle;
localRotation.y = pAxis.y * halfAngle;
localRotation.z = pAxis.z * halfAngle;
localRotation.w = cosf(DegreesToRadians(pAngle / 2.0f));
(*this) = (*this) * localRotation;
normalize();
}
This works - but I'm confused because when I use this rotation function it rotates the object about its Local axis... so if I give it the vector (0,0,1) and the angle 45 it will rotate the object about its local z axis by 45 degrees no matter which way the object is oriented... if I change the last line (before normalize) to
(*this) = localRotation * (*this);
it then rotates objects correctly about the worlds z axis if i give it (0,0,1) rather than its local axis. The problem is that with this version the targetVector that is returned by the function getTargetVec is not actually the direction the object is facing... hence...
when I use the second version the camera is all messed up..
Anyone know how to use a quaternion to store rotation information so that the same rotate function can be used by a camera as by an object? I would like both the camera and the objects to be able to rotate around world space vectors rather than their local space
If I want a rotation around a local space axis I can get the local space axis with getTargetVec or getUpVec etc..