PDA

View Full Version : need help with camera transformations

0100010
03-26-2010, 04:27 AM
I have an assignment part of which I need to construct a camera class. The camera class has 4 vectors initialized as:

position.x = position.y = position.z = 0; position.w = 1;
u.w = u.x = 1; u.y = u.z = 0; //"Right"
v.x = v.z = 0; v.y = v.w = 1; //"Up"
n.x = n.y = 0; n.z = n.w = 1; //"(-)Forward" camera looks in -Z direction

I need to be able to translate and rotate the camera on its own axes, by updating the camera values above, and using them with the gluLookAt function. (I can only use the gluLookAt function to point the camera, cannot use the glRotate, glTranlate, etc.) I have to use Axis angle rotation to rotate the camera about an arbitrary axis.

I current have the following function defined but implementing them does not seem to look right. Can anyway spot/ or tell me what's wrong?

(and before anyone asks, my Matrix::MultiplyVector function works correctly)

void Camera::Translate(Axis axis, float delta)
{
Vector unit_axis;
switch (axis)
{
case AXIS_U: unit_axis = u; break;
case AXIS_V: unit_axis = v; break;
case AXIS_N: unit_axis = n; break;
}
position.x += delta * unit_axis.x;
position.y += delta * unit_axis.y;
position.z += delta * unit_axis.z;
}

void Camera::Rotate(Axis axis, float theta)
{
Vector ua; //unit axis vector.
switch (axis)
{
case AXIS_U: ua = u; break;
case AXIS_V: ua = v; break;
case AXIS_N: ua = n; break;
}
//Axis -angle rotation from:
//R = ua * transpose(ua) + cos(theta) * (I - ua * transpose(ua)) + sin(theta) * v'
//v' = skew symetric dual matix of v.
vector<float> rm;
float s = sinf(theta);
float c = cosf(theta);
float t = (1 - c);
rm.push_back(t*ua.x*ua.x + c);
rm.push_back(t*ua.x*ua.y + s*ua.z);
rm.push_back(t*ua.x*ua.z - s*ua.y);
rm.push_back(0);
rm.push_back(t*ua.x*ua.y - s*ua.z);
rm.push_back(t*ua.y*ua.y + c);
rm.push_back(t*ua.y*ua.z + s*ua.x);
rm.push_back(0);
rm.push_back(t*ua.x*ua.y + s*ua.y);
rm.push_back(t*ua.y*ua.z + s*ua.x);
rm.push_back(t*ua.z*ua.z + c);
rm.push_back(0);
rm.push_back(0);
rm.push_back(0);
rm.push_back(0);
rm.push_back(1);

vector<float> mv;
if (axis != AXIS_V)
{
mv = Matrix::MultiplyVector(rm, v.GetVector());
v.x = mv[0]; v.y = mv[1]; v.z = mv[2]; v.w = mv[3];
}
if (axis != AXIS_U)
{
mv = Matrix::MultiplyVector(rm, u.GetVector());
u.x = mv[0]; u.y = mv[1]; u.z = mv[2]; u.w = mv[3];
}
if (axis != AXIS_N)
{
mv = Matrix::MultiplyVector(rm, n.GetVector());
n.x = mv[0]; n.y = mv[1]; n.z = mv[2]; n.w = mv[3];
}
}

void Camera::LookAt()
{
float lookAtX = position.x + n.x;
float lookAtY = position.y + n.y;
float lookAtZ = position.z + n.z;
gluLookAt(position.x, position.y, position.x, -lookAtX, -lookAtY, -lookAtZ, v.x, v.y, v.z);
}