tags:

views:

2067

answers:

4

I have an input 3D vector, along with the pitch and yaw of the camera. Can anyone describe or provide a link to a resource that will help me understand and implement the required transformation and matrix mapping?

+2  A: 

The world-to-camera transformation matrix is the inverse of the camera-to-world matrix. The camera-to-world matrix is the combination of a translation to the camera's position and a rotation to the camera's orientation. Thus, if M is the 3x3 rotation matrix corresponding to the camera's orientation and t is the camera's position, then the 4x4 camera-to-world matrix is:

M00 M01 M02 tx
M10 M11 M12 ty
M20 M21 M22 tz
0   0  0   1

Note that I've assumed that vectors are column vectors which are multiplied on the right to perform transformations. If you use the opposite convention, make sure to transpose the matrix.

To find M, you can use one of the formulas listed on Wikipedia, depending on your particular convention for roll, pitch, and yaw. Keep in mind that those formulas use the convention that vectors are row vectors which are multiplied on the left.

Instead of computing the camera-to-world matrix and inverting it, a more efficient (and numerically stable) alternative is to calculate the world-to-camera matrix directly. To do so, just invert the camera's position (by negating all 3 coordinates) and its orientation (by negating the roll, pitch, and yaw angles, and adjusting them to be in their proper ranges), and then compute the matrix using the same algorithm.

Adam Rosenfield
A: 

What you are describing is called 'Perspective Projection' and there are reams of resources on the web that explain the matrix math and give the code necessary to do this. You could start with the wikipedia page

Scott Evernden
+2  A: 

If we have a structure like this to describe a 4x4 matrix:

class Matrix4x4
{
public:
    union
    {
     struct
     {
      Type Xx, Xy, Xz, Xw;
      Type Yx, Yy, Yz, Yw;
      Type Zx, Zy, Zz, Zw;
      Type Wx, Wy, Wz, Ww;
     };

     struct
     {
      Vector3<Type> Right;
      Type XW;
      Vector3<Type> Up;
      Type YW;
      Vector3<Type> Look;
      Type ZW;
      Vector3<Type> Pos;
      Type WW;
     };

     Type asDoubleArray[4][4];
     Type asArray[16];
    };
};

If all you have is Euler angles, that is an angles representing the yaw, pitch, and roll and a point in 3d space for the position, you can calculate the Right, Up, and Look vectors. Note that Right, Up, and Look are just the X,Y,Z Vectors, but since this is a camera, I find it easier to name it so. The simplest way to apply your roations to the camera matrix is to build a series of rotation matrices and multiply our camera matrix by each rotation matrix.

A good reference for that is here: http://www.euclideanspace.com

Once you have applied all the needed rotations, you can set the vector Pos to the camera's position in the world space.

Lastly, before you apply the camera's transformation, you need to take the camera's inverse of its matrix. This is what you are going to multiply your modelview matrix by before you start drawing polygons. For the matrix class above, the inverse is calculated like this:

template <typename Type>
Matrix4x4<Type> Matrix4x4<Type>::OrthoNormalInverse(void)
{
    Matrix4x4<Type> OrthInv;
    OrthInv = Transpose();
    OrthInv.Xw = 0;
    OrthInv.Yw = 0;
    OrthInv.Zw = 0;
    OrthInv.Wx = -(Right*Pos);
    OrthInv.Wy = -(Up*Pos);
    OrthInv.Wz = -(Look*Pos);
    return OrthInv;
}

So finally, with all our matrix constuction out of the way, you would be doing something like this:

Matrix4x4<float> cameraMatrix, rollRotation, pitchRotation, yawRotation;
Vector4<float> cameraPosition;

cameraMatrix = cameraMatrix * rollRotation * pitchRotation * yawRotation;

Matrix4x4<float> invCameraMat;

invCameraMat = cameraMatrix.OrthoNormalInverse();

glMultMatrixf(invCameraMat.asArray);

Hope this helps.

Brandorf
A: 

Have a look at the online documention for:

These provided all of the information I needed to perform a World -> Camera coordinate transformation when I was developing my ray tracer.

Alnitak