Camera rotations and movement

Started by
4 comments, last by fortenbt 18 years, 9 months ago
Okay, I'm creating a camera class that is based on an object class that I already have done. This camera should act like a first person space shooter camera, allowing all rotations and movement in any direction relative to itself at any time. The problem I'm having is that things eventually get "out of whack," best explained by saying that the rotations are being performed about the wrong axes (trying to rotate left will rotate the view diagonally downwards, etc.). This is being done in OpenGL using the glLookAt function, giving it the camera's position, the camera's lookAt vector, and the camera's up vector. Some background information: The "Camera" is an "Object." And Object has: position, rotation, velocity, acceleration, rot_vel (rotational velocity), rot_accel (rotational acceleration), up, right, forward vectors, and a boolean has_friction variable. If has_friction is true, a friction will be applied to the object's velocity and rot_vel during its update to slow it down. The Object's update function does the following: -Updates the velocity with the acceleration with respect to how many milliseconds have passed in the last frame -Applies that velocity to the position -Updates the rot_vel with rot_accel -Applies rot_vel to rotation -Updates the up, right, and forward vectors. Here's where the problem may lie. I got my equations through this site. I've used those and I've also made some adjustments to them because I think there's a sign error. Everything I've tried still gives me crazy rotation problems.

bool Object::Update(int ms)
{
   velocity += acceleration * ms / 1000;
   position += velocity * ms / 1000;
   rot_vel += rot_accel * ms / 50;
   rotation += rot_vel * ms / 50;

   right = right*cos(rotation.getZ()) + up*sin(rotation.getZ());
   up = right* -sin(rotation.getZ()) + up*cos(rotation.getZ());
   forward = forward*cos(rotation.getY()) + right * -sin(rotation.getY());
   right = forward * -sin(rotation.getY()) + right*cos(rotation.getY());
   forward = forward*cos(rotation.getX()) + up*sin(rotation.getX());
   up = forward * -sin(rotation.getX()) + up*cos(rotation.getX());
   right.normalize();
   up.normalize();
   forward.normalize();

   if(has_friction)
   {
      acceleration = velocity * fric;
      rot_accel = rot_vel * fric / 30;
   }

   else
   {
      rot_accel = 0;
      acceleration = 0;
   }
	
   return true
}


So the problem either lies with my math right there, or something I'm doing wrong with the movement. My Camera is a child of Object with one extra variable: a lookAt vector, which is given to gluLookAt every frame to update orientation. The only thing my camera's update does is call Object's update, then sets the lookAt vector to position + forward. As far as I know, this works correctly, because moving around works fine. The orientation only gets screwed up when I look around (rotate). Finally, here's my code for rotating the camera:

void Camera::moveForward(double ms)
{
   acceleration += forward * 100;
}
void Camera::rollRight(double ms)
{
   rot_accel += forward * 0.03f;
}

void Camera::rotateLeft(double ms)
{
   rot_accel += up * 0.03f;
}
I think you can figure out the rest of the functions...they work in the same manner. Wow, this was a long post. If I've confused you, let me know what you'd like me to elaborate on. I have the project to send if you want to check it out. I'm using SDL, so in order to run it, SDL has to be set up from libsdl.org. Thanks for any suggestions, Ben
Advertisement
I would suggest you to start simple. Try to make a camera that moves/rotates on two axes. When you have a working camera you can add more features to it.
You might find useful this page .

My project`s facebook page is “DreamLand Page”

The way he sets up that camera though is not how I set mine up. That one just translates and rotates everything that's drawn, rather than using gluLookAt to position a viewpoint.

And basic movement does work on mine. I can move all over the place no problem; things start to screw up when I rotate. I need to make sure I'm updating all the vectors correctly.

--Ben
Your problems with rotation are probably due to "gimbal lock". This is caused by using Euler angles (angle per axis) to keep track of rotation. This is usually not a problem in games that prevent you from looking straight up or turning over on your side, but in a space sim you have to use a different way to represent rotation -- axis/angle, quaternion, or matrix.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Hey,
It could be numerical drift which can cause the camera to be unstable and/or shakey
I'm almost positive the problem is gimbal lock. I thought that using small rotations each frame, and then resetting the rotation to 0,0,0 after updating the vectors would override that problem. I guess not.

I was hoping not to rebuild the entire class. Is there possibly an easy way to incorporate matrices into this implementation? I'll research it more tonight and see what I can do.

Thanks for the advice guys,
Ben

This topic is closed to new replies.

Advertisement