For testing/learning purposes I am trying to use quaternions in place of euler angles when doing the rotation/translation for the view camera. I managed to get everything to work with the exception that the camera is now rotating around the center-point axis rather than on it's own axis. What do I need to do to achieve rotation on the camera's own axis rather than rotating around the center axis?

Below is my code used for this test:

Any questions regarding to the code please let me know. I hope I've been descriptive enough for anyone to understand my situation.

Code :void Draw(void) { vec4_t vec1; vec4_t vec2; vec4_t vec3; double m[16]; .... glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glPushMatrix(); M_SetQuaternion(&vec1, R_ViewAngleToEuler(cam_yaw), 0, 1, 0); M_SetQuaternion(&vec2, R_ViewAngleToEuler(cam_pitch), 1, 0, 0); M_MultiplyQuaternions(&vec3, &vec1, &vec2); M_CalcRotationMatrix(&vec3, m); M_CalcTranslationMatrix(m, cam_x, cam_y, cam_z); // the stuff above is suppose to behave like this below: // glRotatef(R_ViewAngleToEuler(cam_pitch), 1.0f, 0.0f, 0.0f); // glRotatef(R_ViewAngleToEuler(cam_yaw), 0.0f, 1.0f, 0.0f); // glTranslatef(cam_x, cam_y, cam_z); glMultMatrixd(m); .... glPopMatrix(); .... } // here's the utilities used in case anyone wants to look typedef struct { double x; double y; double z; double w; } vec4_t; #define M_PI 3.1415926535897932384626433832795 #define M_RAD (M_PI / 180.0) #define M_DEG (180.0 / M_PI) float R_ViewAngleToEuler(float angle) { return angle * 0.0439453125f; // should probably not worry about this. This converts the game's angle value into euler degrees. Game's angle value ranges from -4096 to 4096 } void M_CalcRotationMatrix(vec4_t* vec, double *m) { double xx = vec->x * vec->x; double yx = vec->y * vec->x; double zx = vec->z * vec->x; double wx = vec->w * vec->x; double yy = vec->y * vec->y; double zy = vec->z * vec->y; double wy = vec->w * vec->y; double zz = vec->z * vec->z; double wz = vec->w * vec->z; double ww = vec->w * vec->w; m[ 0] = ((ww + xx) - yy) - zz; m[ 1] = (wz + wz) + (yx + yx); m[ 2] = (zx + zx) - (wy + wy); m[ 3] = 0.0; m[ 4] = (yx + yx) - (wz + wz); m[ 5] = (yy + (ww - xx)) - zz; m[ 6] = (wx + wx) + (zy + zy); m[ 7] = 0.0; m[ 8] = (wy + wy + zx + zx); m[ 9] = (zy + zy) - (wx + wx); m[10] = ((ww - xx) - yy) + zz; m[11] = 0.0; m[12] = 0.0; m[13] = 0.0; m[14] = 0.0; m[15] = 1.0; } void M_CalcTranslationMatrix(double *m, double x, double y, double z) { m[12] = x + m[12]; m[13] = y + m[13]; m[14] = z + m[14]; } void M_MultiplyQuaternions(vec4_t *out, vec4_t *q1, vec4_t *q2) { out->x = q1->x * q2->w - q1->y * q2->z + q2->x * q1->w + q2->y * q1->z; out->y = q1->x * q2->z + q1->y * q2->w - q2->x * q1->z + q1->w * q2->y; out->z = q2->x * q1->y + q1->w * q2->z + q1->z * q2->w - q1->x * q2->y; out->w = q1->w * q2->w - (q2->y * q1->y + q1->z * q2->z + q2->x * q1->x); } void M_Normalize4(vec4_t *out) { long double d; d = sqrt(out->y * out->y + out->z * out->z + out->w * out->w + out->x * out->x); if(d != 0.0) { out->x = out->x * 1.0 / d; out->y = out->y * 1.0 / d; out->z = out->z * 1.0 / d; out->w = out->w * 1.0 / d; } } void M_SetQuaternion(vec4_t* vec, double angle, double x, double y, double z) { double sin_a = sin((angle * M_RAD) * 0.5); double cos_a = cos((angle * M_RAD) * 0.5); vec->x = x * sin_a; vec->y = y * sin_a; vec->z = z * sin_a; vec->w = cos_a; M_Normalize4(vec); }