Platform SDK: DirectX

Setting Up a World Matrix

Like any other transformation, you create the world transformation by concatenating a series of transformation matrices into a single matrix that contains the sum total of their effects. In the simplest case, when a model is at the world origin and its local coordinate axes are oriented the same as world space, the world matrix is the identity matrix. More commonly, the world matrix is a combination of a translation into world space, and possibly one or more rotations to "turn" the model as needed.

[C++]

The following example, from a fictitious 3-D model class written in C++, uses the helper functions in the D3dutil.cpp and D3dmath.cpp files (included with the DirectX SDK) to create a world matrix that includes three rotations to orient a model and a translation to relocate it relative to its position in world space.

/*
 * For the purposes of this example, the following variables
 * assumed to be valid and initialized.
 *
 * The m_vPos variable is a D3DVECTOR that contains the model's
 * location in world coordinates.
 *
 * The m_fPitch, m_fYaw, and m_fRoll variables are D3DVALUEs that 
 * contain the model's orientation in terms of pitch, yaw, and roll
 * angles (in radians).
 */
 
D3DMATRIX C3DModel::MakeWorldMatrix(void)
{
    D3DMATRIX matWorld, // World matrix being constructed.
      matTemp,  // Temp matrix for rotations.
      matRot;   // Final rotation matrix (applied to matWorld).
 
    // Using the left-to-right order of matrix concatenation,
    // apply the translation to the object's world position
    // before applying the rotations.
    D3DUtil_SetTranslateMatrix(matWorld, m_vPos);
    D3DUtil_SetIdentityMatrix(matRot);
 
    //
    // Now, apply the orientation variables into the 
    // world matrix
    //
    if(m_fPitch || m_fYaw || m_fRoll)
    {
// Produce and combine the rotation matrices.
D3DUtil_SetRotateXMatrix(matTemp, m_fPitch);    // pitch
D3DMath_MatrixMultiply(matRot,matRot,matTemp);
D3DUtil_SetRotateYMatrix(matTemp, m_fYaw);      // yaw
D3DMath_MatrixMultiply(matRot,matRot,matTemp);
D3DUtil_SetRotateZMatrix(matTemp, m_fRoll);     // roll
D3DMath_MatrixMultiply(matRot,matRot,matTemp);
 
// Apply the rotation matrices to complete the world matrix.
D3DMath_MatrixMultiply(matWorld, matRot, matWorld);
    }
    return (matWorld);
} 

After you prepare the world transformation matrix, call the IDirect3DDevice7::SetTransform method to set it, specifying the D3DTRANSFORMSTATE_WORLD flag in the first parameter. For more information, see Setting Transformations.

[Visual Basic]

The following example, from a fictitious 3-D model class, uses the functions offered by the DirectX7 class to create a world matrix that includes three rotations to orient a model and a translation to relocate it relative to its position in world space.

'
' For the purposes of this example, the following variables
' assumed to be valid and initialized.
'
'   The g_dx variable contains a valid reference to a DirectX7 object.
'
'   The m_vPos variable is a D3DVECTOR that contains the model's
'   location in world coordinates.
'
'   The m_sPitch, m_sYaw, and m_sRoll variables are Singles that
'   contain the model's orientation in terms of pitch, yaw, and roll
'   angles (in radians).
'
Public Function MakeWorldMatrix() As D3DMATRIX
    Dim matWorld As D3DMATRIX   ' World matrix to be returned.
    Dim matTemp As D3DMATRIX    ' Temp matrix to hold rotations.
    Dim matRot As D3DMATRIX     ' Temp rotation matrix.
 
    ' Modify matWorld to create a translation matrix.
    Call g_dx.IdentityMatrix(matWorld)
    matWorld.rc41 = m_vPos.x
    matWorld.rc42 = m_vPos.y
    matWorld.rc43 = m_vPos.z
    
    Call g_dx.IdentityMatrix(matRot) ' Sets up the rotation matrix
    
    '
    ' Using the left-to-right order of matrix concatenation,
    ' apply the translation to the object's world position
    ' before applying the rotations.
    '
    
    ' Produce and combine the rotation matrices.
    If (m_sPitch <> 0) Or (m_sYaw <> 0) Or (m_sRoll <> 0) Then
' First, pitch.
Call g_dx.RotateXMatrix(matTemp, m_sPitch)
Call g_dx.MatrixMultiply(matRot, matRot, matTemp)

' Then, yaw.
Call g_dx.RotateYMatrix(matTemp, m_sYaw)
Call g_dx.MatrixMultiply(matRot, matRot, matTemp)

' Finally, roll.
Call g_dx.RotateZMatrix(matTemp, m_sRoll)
Call g_dx.MatrixMultiply(matRot, matRot, matTemp)
 
' Apply the rotation matrices to the translation already in
' matWorld to complete the world matrix.
Call g_dx.MatrixMultiply(matWorld, matRot, matWorld)
    End If
    
    MakeWorldMatrix = matWorld
End Function

After you prepare the world transformation matrix, call the Direct3DDevice7.SetTransform method to set it, specifying the D3DTRANSFORMSTATE_WORLD flag in the first parameter. For more information, see Setting Transformations.

Performance Optimization  Direct3D uses the world and view matrices that you set to configure several of its internal data structures. Each time you set a new world or view matrix, the system recalculates the associated internal structures. Setting these matrices frequently—for example, thousands of times per frame—is computationally expensive. You can minimize the number of required calculations by concatenating your world and view matrices into a proverbial "world-view" matrix that you set as the world matrix, then set the view matrix to the identity. Keep cached copies of individual world and view matrices that you can modify, concatenate, and reset the world matrix as needed. (For clarity, Direct3D samples rarely employ this optimization.)