I'm still having a couple of problems (although there are fewer problems than I had with spherical coordinates). It seems that if the camera eye is near or on the plane defined by (1, 0, -1), (-1, 0, 1), (0, 1, 0) it has trouble rotating for some reason. Also, using the same plane mentioned above, on one side of the plane, moving the mouse up points the camera down, while on the other side, moving the mouse up points the camera up.
Any ideas? I've used the same method jwalsh has mentioned and have used
this as a guide to rotating around and arbitrary axis.
I hope that made sense :p Let me know if I need to clarify anything. Thanks!
The function below rotates the point 'point' around the axis 'axis' specified by 'angle' in degrees:
void rotateMatrixArbitrary(GLfloat angle, GLfloat* axis, GLfloat* point){ GLfloat yzProj[ 3 ] = { 0.0f, axis[ 1 ], axis[ 2 ] }; GLfloat xzProj[ 3 ] = { axis[ 0 ], 0.0f, axis[ 2 ] }; GLfloat d = sqrt(yzProj[ 1 ] * yzProj[ 1 ] + yzProj[ 2 ] * yzProj[ 2 ]); MATRIX4 m1, m2, m3, mi1, mi2, tmp; initMatrix(&m1); initMatrix(&m2); initMatrix(&m3); initMatrix(&mi1); initMatrix(&mi2); initMatrix(&tmp); if(d != 0.0) { m1.matrix[ 1 ][ 1 ] = fabs(yzProj[ 2 ]) / d; m1.matrix[ 1 ][ 2 ] = -1.0f * fabs(yzProj[ 1 ]) / d; m1.matrix[ 2 ][ 1 ] = fabs(yzProj[ 1 ]) / d; m1.matrix[ 2 ][ 2 ] = fabs(yzProj[ 2 ]) / d; mi1.matrix[ 1 ][ 1 ] = fabs(yzProj[ 2 ]) / d; mi1.matrix[ 1 ][ 2 ] = fabs(yzProj[ 1 ]) / d; mi1.matrix[ 2 ][ 1 ] = -1.0f * fabs(yzProj[ 1 ]) / d; mi1.matrix[ 2 ][ 2 ] = fabs(yzProj[ 2 ]) / d; } d = sqrt(xzProj[ 0 ] * xzProj[ 0 ] + xzProj[ 2 ] * xzProj[ 2 ]); if(d != 0.0) { m2.matrix[ 0 ][ 0 ] = fabs(xzProj[ 2 ]) / d; m2.matrix[ 0 ][ 2 ] = fabs(xzProj[ 0 ]) / d; m2.matrix[ 2 ][ 0 ] = -1.0f * fabs(xzProj[ 0 ]) / d; m2.matrix[ 2 ][ 2 ] = fabs(xzProj[ 2 ]) / d; mi2.matrix[ 0 ][ 0 ] = fabs(xzProj[ 2 ]) / d; mi2.matrix[ 0 ][ 2 ] = -1.0f * fabs(xzProj[ 0 ]) / d; mi2.matrix[ 2 ][ 0 ] = fabs(xzProj[ 0 ]) / d; mi2.matrix[ 2 ][ 2 ] = fabs(xzProj[ 2 ]) / d; } rotateMatrixZ(angle, &m3); // Apply rotations matrixMult(m1, point); matrixMult(m2, point); matrixMult(m3, point); matrixMult(mi2, point); matrixMult(mi1, point);}
This is the function which will rotate the camera eye based on mouse movements. It rotates around the point specified by cam.gaze:
void rotateCamera(GLfloat x, GLfloat y){ // Translate eye so that target is at origin cam.eye[ 0 ] -= cam.gaze[ 0 ]; cam.eye[ 1 ] -= cam.gaze[ 1 ]; cam.eye[ 2 ] -= cam.gaze[ 2 ]; MATRIX4 rotateY; rotateMatrixY(y, &rotateY); GLfloat dir[ 3 ] = { cam.eye[ 0 ], cam.eye[ 1 ], cam.eye[ 2 ] }; normalize(dir); GLfloat rightVec[ 3 ]; xprod(dir, cam.up, rightVec); normalize(rightVec); rotateMatrixArbitrary(x, rightVec, cam.eye); matrixMult(rotateY, cam.eye); // Translate eye back cam.eye[ 0 ] += cam.gaze[ 0 ]; cam.eye[ 1 ] += cam.gaze[ 1 ]; cam.eye[ 2 ] += cam.gaze[ 2 ];}