#46643 - connor9 - Tue Jun 28, 2005 4:08 pm
I'm trying to build a simple camera class. It's a simple camera that you can tell to move forward along it's viewing direction, roll, pitch and yaw along it's respective axes. The problem I'm running into is that as you use the camera the view volume becomes skewed, as if the directions that specify viewing direction, up and right are becoming non orthogonal. Printing out the dot product of each of these vectors confirms that the camera is slowly ruining it's vectors.
I assume it's a problem of data precision and that I'm probably using fixed point numbers completely incorrectly.
Here's the code to the simple camera class:
Set view is called to initialize the camera. Sort of an initial gluLookAt. Each frame various camera.roll(angle), camera.moveForward(distance) actions are called and the the matrix is loaded by calling camera.setModelViewMatrix(); Oh, it's not shown in the camera class but before setModelViewMatrix() is called the matrix stack is set to model view.
The following is only the roll implementation. As you roll the camera the dot product of u and v becomes non-zero.
LUT_MASK is defined in camera.h
CAM0 and CAM1 are defined as the 1.0 and 0.0 in a fixed point f32 number.
My question is how can I make this class work without warping the viewing parameters. Or what is a better method of implementing a camera class on the DS that still gives me easy access to my camera's current position and view vector?
Thanks!
I assume it's a problem of data precision and that I'm probably using fixed point numbers completely incorrectly.
Here's the code to the simple camera class:
Code: |
void Camera::setModelViewMatrix() { m4x4 viewMatrix; viewMatrix.m[0] = u[0]; viewMatrix.m[1] = v[0]; viewMatrix.m[2] = n[0]; viewMatrix.m[3] = CAM0; viewMatrix.m[4] = u[1]; viewMatrix.m[5] = v[1]; viewMatrix.m[6] = n[1]; viewMatrix.m[7] = CAM0; viewMatrix.m[8] = u[2]; viewMatrix.m[9] = v[2]; viewMatrix.m[10] = n[2]; viewMatrix.m[11] = CAM0; viewMatrix.m[12] = -dotf32(eye,u); viewMatrix.m[13] = -dotf32(eye,v); viewMatrix.m[14] = -dotf32(eye,n); viewMatrix.m[15] = CAM1; glLoadMatrix4x4(&viewMatrix); } void Camera::setView(f32 eye_in[3], f32 look_in[3], f32 up_in[3]) { eye[0] = eye_in[0]; eye[1] = eye_in[1]; eye[2] = eye_in[2]; n[0] = eye[0] - look_in[0]; n[1] = eye[1] - look_in[1]; n[2] = eye[2] - look_in[2]; crossf32(up_in,n,u); normalizef32(n); normalizef32(u); crossf32(n,u,v); setModelViewMatrix(); } |
Set view is called to initialize the camera. Sort of an initial gluLookAt. Each frame various camera.roll(angle), camera.moveForward(distance) actions are called and the the matrix is loaded by calling camera.setModelViewMatrix(); Oh, it's not shown in the camera class but before setModelViewMatrix() is called the matrix stack is set to model view.
The following is only the roll implementation. As you roll the camera the dot product of u and v becomes non-zero.
Code: |
void Camera::roll(int angle) { f32 sine = SIN[angle & LUT_MASK]; //f32 cosine = sqrtf32((CAM1 - sine2)); f32 cosine = COS[angle & LUT_MASK]; f32 t[3]; t[0] = u[0]; t[1] = u[1]; t[2] = u[2]; u[0] = mulf32(cosine,t[0]) - mulf32(sine,v[0]); u[1] = mulf32(cosine,t[1]) - mulf32(sine,v[1]); u[2] = mulf32(cosine,t[2]) - mulf32(sine,v[2]); v[0] = mulf32(sine,t[0]) + mulf32(cosine,v[0]); v[1] = mulf32(sine,t[1]) + mulf32(cosine,v[1]); v[2] = mulf32(sine,t[2]) + mulf32(cosine,v[2]); } void Camera::moveForward(f32 distance) { eye[0] += mulf32(distance,n[0]); eye[1] += mulf32(distance,n[1]); eye[2] += mulf32(distance,n[2]); } |
LUT_MASK is defined in camera.h
Code: |
#define LUT_MASK (0x1FF) |
CAM0 and CAM1 are defined as the 1.0 and 0.0 in a fixed point f32 number.
My question is how can I make this class work without warping the viewing parameters. Or what is a better method of implementing a camera class on the DS that still gives me easy access to my camera's current position and view vector?
Thanks!