Hi, all. I am developing a 6DOF camera class for use with OpenGL. It "mostly" works, but sometimes a "roll" occurs after a sufficient (> 90 degree) yaw or pitch. Here's the camera structure:

And here's the code for yaw:Code:`typedef struct Camera3D`

{

Vector3D u; // the "right" direction

Vector3D v; // the "up" direction

Vector3D n; // the "forward" direction

Vector3D p; // eye position

Matrix3D Mv; // view transformation matrix

Matrix3D Mp; // perspective transformation matrix

float rx; // current rotation about x axis

float ry; // current rotation about y axis

float rz; // current rotation about z axis

}

Camera3D;

The basic approach in yaw is to make the N vector coincide with the Z axis, then rotate it about Y, and keep U orthogonal to N.Code:`void`

cam3D_yaw(Camera3D* eye, float angle)

{

Matrix3D r;

mat3D_set_to_identity(r);

mat3D_rotx(r, eye->rx);

mat3D_roty(r, eye->ry);

mat3D_rotz(r, eye->rz);

mat3D_roty(r, angle);

mat3D_rotz(r, -eye->rz);

mat3D_roty(r, -eye->ry);

mat3D_rotx(r, -eye->rx);

mat3D_xfrm(r, eye->n);

vec3D_norm(eye->n);

vec3D_dup(eye->u, eye->n);

vec3D_cross(eye->u, eye->v);

eye->ry += angle;

update(eye);

}

I have tried many approaches, this one seems to work the best. I think I am confused about transforming between "view" space and "world" space. The camera vectors N, U, and V are in "view" space, correct? Also, to "yaw" is logically equivalent to rotating the N "look" axis about the V "up" axis? I think the problem is that I am rotating N about Y, not about V, and I know of no way to rotate N about an arbitrary axis, other than the matrix transform I already have:

So I guess the final question is how to rotate N about V, and in what space this should be done. Note that I do not have time to implement a quaternion class and would like to use what I already have.Code:`static void`

update(Camera3D* eye)

{

/* Normalize u, v, n */

vec3D_norm(eye->u);

vec3D_norm(eye->v);

vec3D_norm(eye->n);

/* Set up transform */

eye->Mv[0] = eye->u[0];

eye->Mv[1] = eye->v[0];

eye->Mv[2] = eye->n[0];

eye->Mv[3] = 0.0;

eye->Mv[4] = eye->u[1];

eye->Mv[5] = eye->v[1];

eye->Mv[6] = eye->n[1];

eye->Mv[7] = 0.0;

eye->Mv[8] = eye->u[2];

eye->Mv[9] = eye->v[2];

eye->Mv[10] = eye->n[2];

eye->Mv[11] = 0.0;

eye->Mv[12] = -vec3D_dot(eye->u, eye->p);

eye->Mv[13] = -vec3D_dot(eye->v, eye->p);

eye->Mv[14] = -vec3D_dot(eye->n, eye->p);

eye->Mv[15] = 1.0;

#ifdef DEBUG

printf("eye location: (%f, %f, %f)\n", eye->p[0], eye->p[1], eye->p[2]);

printf("right vector: (%f, %f, %f)\n", eye->u[0], eye->u[1], eye->u[2]);

printf("up vector: (%f, %f, %f)\n", eye->v[0], eye->v[1], eye->v[2]);

printf("look vector: (%f, %f, %f)\n", eye->n[0], eye->n[1], eye->n[2]);

#endif

}