PDA

View Full Version : Convert camera with target to 4x4 matrix

project6
05-26-2008, 12:07 PM
Hi

I have an API which takes a 4x4 OGL Matrix as input. I have to my disposal a Camera in a 3D space. The camera itself has xyz coordinates, attached to it is a target which also has xyz coords. Both of these can be moved around indepently.

What I want to do is use the information from these two entities to construct a 4x4 OGL Matrix, which has the same position in 3D space as the camera.

As I understand it, the diagonal of the Matrix represents the position of the eye(camera).

1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 0.0

This would "place" my camera at (1.0, 1.0, 1.0) If I'm correct?

Apart from this I need to calculate the angle/direction of the camera to properly match it. Any hints or suggestions are greatly appreciated.

/p6

Edit: Sigh, after this advanced post I just found gluLookAt, which probably does the exact thing I'm after... I'm such as bad googler. You may still reply to this thread though if I'm going in the complete wrong direction.

-NiCo-
05-26-2008, 12:33 PM
You're on the right track with gluLookat. I do believe your understanding of the 4x4 transformation matrix is incorrect though.
The upper left 3x3 matrix of the 4x4 modelview matrix usually represents a rotation matrix. If this matrix equals the identity matrix that means that there is no rotation. The rightmost column of the 4x4 matrix represents the translation.

PS. the bottom right value usually equals 1 and not 0

project6
05-26-2008, 03:50 PM
NiCo, thanks for the explanation. Haven't used OGL in a long time so my skills are heavily rusted.

Just a quick follow-up:
My OGL API creates a couple of new matrices, which should later be converted back to camera positions. Since OGL translates the environemt as opposed to a camera, then I would need to inverse these matrices to mimic the movement with my camera?

I found good documentation here on opengl.org of the gluLookAt, is it a difficult task to "backtrack" those steps in order to split up a 4x4 matrix to an eye and a target?

-NiCo-
05-26-2008, 04:01 PM
Indeed. The modelview matrix operates on vertex data in object space. If you multiply the modelview matrix with the origin in object space (0,0,0,1), you will end up with the last column of the modelview matrix. This column represents the translational component, it defines where the object space origin lies in terms of eye-space (camera) coordinates. So if you take the translational component of the inverse modelview matrix, you will get the camera's origin in terms of object space coordinates.

project6
05-26-2008, 04:22 PM
NiCo,

I'm glad I understand the concept a little bit better now, thanks for explaining.
You seem to know a lot about matrix operations, is it a difficult task to reverse this workflow to retrieve eye(x,y,z) and center(x,y,z) out of a given matrix M?

( centerX - eyeX )
F = | |
| centerY - eyeY |
( centerZ - eyeZ )

Let UP be the vector (upX,upY,upZ).

Then normalize as follows: f = _____
||F||

UP' = ______
||UP||

Finally, let s = f x UP', and u = s x f.

M is then constructed as follows:
( s[0] s[1] s[2] 0 )
| u[0] u[1] u[2] 0 |
M = | |
|-f[0] -f[1] -f[2] 0 |
| 0 0 0 1 |
( )

Is it even possible? Considering the normalization and all.

/p6

-NiCo-
05-26-2008, 04:59 PM
It's possible to retrieve the eye coordinates, but not the center. The center, along with the eye coordinates, only specifies a viewing direction. If you would have specified any other point P = eye + t*(center-eye) where t is some positive value, you would get exactly the same transformation matrix.

Because the modelview matrix transforms from object space to eye space, the inverse modelview matrix transforms from eye space to object space. So like I said in my previous post, the last column of the inverse modelview matrix corresponds to the eye coordinates in object space. You can retrieve one possible value of the center coordinates by multiplying the inverse modelview matrix with the point (-1,0,0,1), this will transform a point at unit distance away from the camera along the optical axis to coordinates in object space.

project6
05-27-2008, 09:40 AM
Thanks NiCo.

Then normalize as follows: f = _____
||F||
UP' = ______
||UP||

I created these functions myself cause I couldn't find any method to normalize the matrices I have.

Do the normalization in this case mean;

f = limiting all values between 0-1 and making them all absolute
UP' = exactly like f? Or should I also invert this?

/p6

-NiCo-
05-27-2008, 10:25 AM
f and UP are vectors, not matrices (well, strictly speaking a vector is also a matrix but you know what I mean). Normalizing a vector means that you create a new vector that has the same direction as the original vector, but with a length equal to 1. If you want to normalize a vector with components x,y and z you have to multiply each component with 1/sqrt(x*x+y*y+z*z).

project6
05-28-2008, 07:01 AM
NiCo,

I realized since I have OpenGL at my disposal I might as well let gluLookAt() do the work for me, on an identity matrix, and afterwards retrieve the modified one?

This is what I was thinking:

// Reset the OGL coordinate system before modifying
glMatrixMode(GL_PROJECTION);

gluLookAt( pInvCamEye->X,
pInvCamEye->Y,
pInvCamEye->Z,
pInvCamTgt->X,
pInvCamTgt->Y,
pInvCamTgt->Z,
pUpVec->X,
pUpVec->Y,
pUpVec->Z );

glMatrixMode(GL_MODELVIEW);

GLdouble modelview[16];

glGetDoublev(GL_MODELVIEW_MATRIX, modelview);

Now, If I'm correct, my modelview variable should hold the values for the current view in matrix form, converted from cam.eye and cam.target?

Now I can insert this matrix into my OpenGL API, and out pops a new one.

I understand how I can get the translation components for the Eye, is it possible somehow to calculate the angle the camera would have by using the other values in this matrix?

What I'm trying to do now, in this last step, is to interpretate how my new camera would be placed according to my new matrix.