View Transform

The view transform changes coordinates from world space to camera space. In effect, this transform moves the world around so that the right parts of it are in front of the camera, given a camera position and orientation.

The following ViewMatrix sample function creates a view matrix based on the camera location passed to it. It uses the Normalize, CrossProduct, and DotProduct D3D_OVERLOADS helper functions. The RotateZ user-defined function it uses is shown in the World Transform section.

D3DMATRIX
ViewMatrix(const D3DVECTOR from,      // camera location
           const D3DVECTOR at,        // camera look-at target
           const D3DVECTOR world_up,  // world's up, usually 0, 1, 0
           const float roll)          // clockwise roll around
                                      //    viewing direction, 
                                      //    in radians
{
    D3DMATRIX  view = IdentityMatrix();  // shown below
    D3DVECTOR  up, right, view_dir;
    
    view_dir = Normalize(at - from);
    right = CrossProduct(world_up, view_dir);
    up = CrossProduct(view_dir, right);
    
    right = Normalize(right);
    up = Normalize(up);
    
    view(0, 0) = right.x;
    view(1, 0) = right.y;
    view(2, 0) = right.z;
    view(0, 1) = up.x;
    view(1, 1) = up.y;
    view(2, 1) = up.z;
    view(0, 2) = view_dir.x;
    view(1, 2) = view_dir.y;
    view(2, 2) = view_dir.z;
    
    view(3, 0) = -DotProduct(right, from);
    view(3, 1) = -DotProduct(up, from);
    view(3, 2) = -DotProduct(view_dir, from);
    
    if (roll != 0.0f) {
        // MatrixMult function shown below
        view = MatrixMult(RotateZ(-roll), view); 
    }
    
    return view;
    }  // end of ViewMatrix()
 
D3DMATRIX
IdentityMatrix(void)       // initializes identity matrix
{
    D3DMATRIX ret;
    for (int i=0; i<4; i++)
        for (int j=0; j<4; j++)
            ret(i, j) = (i==j) ? 1.0f : 0.0f;
    return ret;
}    // end of IdentityMatrix()
 
// Multiplies two matrices.
D3DMATRIX
MatrixMult(const D3DMATRIX a, const D3DMATRIX b)  
{
    D3DMATRIX ret = ZeroMatrix(); // shown below
 
    for (int i=0; i<4; i++) {
        for (int j=0; j<4; j++) {
            for (int k=0; k<4; k++) {
                ret(i, j) += a(k, j) * b(i, k);
            }
        }
    }
    return ret;
}    // end of MatrixMult()
 
D3DMATRIX 
ZeroMatrix(void)  // initializes matrix to zero
{
    D3DMATRIX ret;
    for (int i=0; i<4; i++)
        for (int j=0; j<4; j++)
            ret(i, j) = 0.0f;
    return ret;
}    // end of ZeroMatrix()