OpenGL camera class

Started by
6 comments, last by Taylor001 15 years, 4 months ago
Hi to all, it's my first post here! I need some help with the camera class I'm making. In order to describe the camera, I use a vector to store the camera's position and three vectors for the right, up, and view directions. To calculate each of them I do this: 1. Rotate the view and the right vector by an "alpha" amount about the world's up vector (0, 1, 0) 2. Derive a matrix for rotating about the computed right vector 3. Rotate both the view and up vector multiplying them by this matrix Once I get the three basis vectors, I construct a column-major matrix placing the vectors in this way: [ right.x up.x view.x ] [ right.y up.y view.y ] [ right.z up.z view.z ] Then, I call glLoadMatrixf() to use it. The problem is that the camera doesn't face well in some situations, like when I turn left by 90° and look up or down. Actually, I don't think I'm doing something wrong in the calculation of the basis vectors, instead, I think there's something wrong in placing them into the matrix. Indeed, if I transpose the above matrix, i.e. if I put basis vectors in this way: [ right.x right.y right.z ] [ up.x up.y up.z ] [ view.x view.y view.z ] it seems to work just fine... BUT, shouldn't the basis vectors be positioned like in the first form, i.e. as column vectors as long as I'm using coloumn-major matrices (and OpenGL as well)? Thanks in advance!
Advertisement
Quote:BUT, shouldn't the basis vectors be positioned like in the first form, i.e. as column vectors as long as I'm using coloumn-major matrices (and OpenGL as well)?
Thanks in advance!
That's correct. However, if your intention is for your camera to function as an actual 'camera', you would typically invert the matrix before uploading it to OpenGL (so that it will have the effect of a 'view' matrix). The result of the extra transpose you have in there is similar to the result of this inversion, which is probably why the camera behavior seems 'less incorrect' with the extra transpose there.

In short, try removing the 'extra' transpose and replacing it with a proper matrix inversion.
So, what I should do is simply load the 'inverse' of the matrix I'm currently loading and it's all ok. To derive the inverse of my matrix I simply transpose its rotation section, negate all of the translation part and leave the last row to (0 0 0 1).

Now the camera works as it should but I still have to figure out 'why'. I just cannot imagine what's exactly happening.
Quote:To derive the inverse of my matrix I simply transpose its rotation section, negate all of the translation part and leave the last row to (0 0 0 1).
Actually, that's not quite right. Are you sure it's working correctly in all cases?

In any case, I'd recommend looking online for a general 4x4 matrix inversion function and just using that. (You can in fact treat inversion of rigid-body transform matrices as a special case, but in the case of a 'view' matrix I don't know that it's really worth the effort.)
Quote:Now the camera works as it should but I still have to figure out 'why'. I just cannot imagine what's exactly happening.
Don't have time for a full explanation, but here are a couple of hints:

1. In general, the inverse of a transform matrix represents a transform that does the 'opposite' of what the original transform does.

2. If a given transform transforms geometry from local to world space, the inverse of that transform will transform geometry from world to local space.

3. In the graphics pipeline, prior to projection but after all other transforms have been applied, we want to transform the geometry into the local space of the camera (which is where the 'projection' part of the pipeline expects it to be). This is what the inverse camera matrix does.
Quote:Actually, that's not quite right. Are you sure it's working correctly in all cases?
Yes, I checked it and I'm pretty sure it works in all cases.
Quote:In any case, I'd recommend looking online for a general 4x4 matrix inversion function and just using that. (You can in fact treat inversion of rigid-body transform matrices as a special case, but in the case of a 'view' matrix I don't know that it's really worth the effort.)
I'm reading a book on this and soon will implement a function to substitute that bad matrix I'm deriving by hand. :)

However, I'd like to thank you for your time and for your hints that were at least illuminating. Slowly I'm understanding more and more about this and it's also thanks to people like you!
I made a mistake in explaining how I derive the working matrix! I said I builded a transposed rotation matrix with a negated translation part, but, actually I didn't do this. Instead, what I do is to build a transposed rotation matrix and a _separate_ translation matrix negating its translation part. Then I concatenate them to form the final matrix to upload to OpenGL. It's for this that it works well the same, I think.

[Edited by - Taylor001 on December 18, 2008 4:27:52 PM]
Quote:Original post by Taylor001
I made a mistake in explaining how I derive the working matrix! I said I builded a transposed rotation matrix with a negated translation part, but, actually I didn't do this. Instead, what I do is to build a transposed rotation matrix and a _separate_ translation matrix negating its translation part. Then I concatenate them to form the final matrix to upload to OpenGL. It's for this that it works well the same, I think.
Yes, that sounds right (assuming you're concatenating the transforms in the right order, which it sounds like you are).
Ok, I just implemented the inverse function. Now I load both the rotation part and the translation part in a single matrix, make the inverse and upload to OpenGL. Seems to work perfectly. Thanks a lot!

This topic is closed to new replies.

Advertisement