Jump to content
  • Advertisement
Sign in to follow this  
fortenbt

Implementing matrices into a camera class (solved)

This topic is 4831 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am creating a camera class that allows 6DOF movement and rotation. I've been struggling with it using Euler angles to keep track of how much it rotates per frame, updating its up, right, and forward vectors based on that rotation, then resetting that rotation back to zero. The camera would then move and rotate along the updated vectors. However, my vectors get all screwed up when I rotate in more than one direction. I've come to a conclusion that the problem is gimbal lock, even though my gut is telling me that really isn't the case, because I'm only rotating about .05 degrees per frame, then resetting the rotation back to zero. However, I cannot be sure, as I don't have an ironclad understanding of exactly what gimbal lock would or can look like. Anyway, my goal is to implement the camera using matrices. I'm thinking from reading a few articles about this that it shouldn't be that hard. Without giving too much confusing details on how my project is set up, I have a camera object which has a world position, and a relative rotation based on its forward, right, and up vectors. Will I need to keep track of a global rotation (how much the camera has rotated altogether around each axis)? And once I have the rotations into a matrix, do I multiply them by the rotation matrix, and then apply them to the modelview matrix (I don't know how to load a matrix into the modelview matrix, or if I even want to do this)? I am using gluLookAt with the camera's position vector, lookAt vector, and up vector to orient the viewport. And finally, will this even get rid of gimbal lock, if that's the problem? Thanks for any help, --Ben [Edited by - fortenbt on July 29, 2005 6:24:07 AM]

Share this post


Link to post
Share on other sites
Advertisement
I've just fixed this in my camera class. Basically, as far as I understand, gimbal lock is going to pop up if your rotation axis are fixed. Try to think more in terms of the cam having it's own independent axis of rotation.

My cam class has UP & LOOK vectors (both normals) and of course a position vector. All rotations are then done with arbitrary axis, e.g. to rotate the cam left or right, just rotate LOOK about the UP vector. To orbit around an object Rotate UP,LOOK by the number of degrees and Position the same number of degrees around the object.

Doing this moves the axis and the vectors that make up the cam, they are the same thing... and I have not had a gimbal lock since.

DaveC

Share this post


Link to post
Share on other sites
the proper solution can also depend on the game too, in situations where there is a prefered up direction it helps to have a real "up" you just place a limit on the pitch. or use quaternion camera, but I think that's overkill personally. also I like daves idea this solution make's gimbel lock impossible

Share this post


Link to post
Share on other sites
So one solution is to store a current 'transform' 4x4 matrix in memory somewhere that represents all the translates and rotates thus far.

Then when it comes time to update the view with rotating and translating, you construct a matrix that represents these translates and rotates, and multiply it by the existing matrix and restore it.

Total_transform = new_translate * Total_transform;
and
Total_transform = new_rotate * Total_transform;

So the new_translates and rotates are always 'small' amounts, like translating a few units or rotating a few degrees. This way you only store one matrix in memory, and continually update and change it with small adjustments. This should solve your problem. And pre-multiplying like above makes sure the adjustments stick with the original axes.

To load this matrix into OpenGL use the glMultMatrixf function. So if your matrix is stored in float m[16], pass in glMultMatrixf(m), and it will apply that matrix to whatever current matrix stack you are in (modelview or projection). ONE HUGE GOTCHA - make sure when passing to OpenGL that you remember they store their matrices COLUMN-MAJOR. Of course, just taking a transpose of a row-major matrix is an easy fix for this.

Hope that helps some

Share this post


Link to post
Share on other sites
Thanks, Gluc0se. I didn't have to implement the matrices, as I finally got the thing to work last night, but I'll probably work with them sometime to become familiar with it.

The problem was that when I was pressing a key to rotate, I would multiply the rotation constant by the vector I was rotating around. Then when I would go to update the vectors, I used the rotations like they were rotations about a world x, y, and z (1,0,0; 0,1,0; and 0,0,1). So I was basically correcting for something that I had already corrected for. I changed the keypress to just add a rotation in a general since, and everything worked correctly.

Thanks a lot for everyone's help.

--Ben

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!