The following for- mula is used for each of the four columns of vector C, where A represents the matrix on the left and B represents the matrix on the right: The product of A * B, theref
Trang 1In video game development, matrices are used to store data such as vertices and mation about how to transform an object Matrices are simply grids of rows and col-umns, but they are essential for scaling, rotating, and translating objects in 3D space.You will have noticed by now that matrix calculations are used throughout yourXNA and shader code for performing transformations, controlling your camera, andeven drawing 3D models Understanding how these matrix methods work will pro-vide you with a better understanding of 3D game engines Most of the time, you canget away with just using XNA matrix methods to automatically create matrices and
infor-to implement your transformations However, for complex vecinfor-tor transformations,you may need to be able to build your own matrices for the calculations
In Chapter 8, a matrix is manually created to compute the flight path of an plane In Chapter 19, a matrix is manually built to implement a vector transforma-tion that determines the starting position and direction of a rocket In cases like these,understanding the matrix math can definitely help to simplify your transformations
This section introduces matrix multiplication and prepares you for performing ual transformations later in the chapter The product of two matrices is obtained bymultiplying the rows of matrix A by the columns of matrix B (where matrix A is onthe left side of the operator) For the multiplication to be possible, the total number ofcolumns in matrix A must equal the total number of rows in matrix B
man-Matrix Types
XNA’s Matrix type enables storage of 3×3 matrices (3 rows by 3 columns) and 4×4matrices (4 rows by 4 columns) Each cell in the matrix grid can be accessed by refer-encing the matrix and suffixing it with the cell’s row and column, where the top-leftcell begins at row 1, column 1 Each cell stores a float:
float cellvalue = Matrix matrix.MRC
For example, matrix.M11 represents the value in row 1, column 1 trix.M13represents the value in row 1, column 3
Ma-Matrix Multiplication Example:
1×4 Matrix * 4×4 Matrix
This example shows how to multiply a 1×4 matrix by a 4×4 matrix We’ll first showthe multiplication done by hand so that you can see each step of the calculation
Trang 2Later, the same operation will be shown in code For this example, a vector with X=2,
Y=1, Z=0, and W=0 will be multiplied by a 4×4 matrix
Manual Calculation To set up the equation, the vector is placed on the left side of the
multiplication operator, and the 4×4 matrix is placed on the right, as shown here:
| 2 1 0 0 | X | 2 1 3 1 |
| 1 2 4 1 |
| 0 3 5 1 |
| 2 1 2 1 |The row on the left is multiplied by each column on the right The following for-
mula is used for each of the four columns of vector C, where A represents the matrix
on the left and B represents the matrix on the right:
The product of A * B, therefore, is a new vector with X=5, Y=4, Z=10, and W=3
Calculation in Code The previous computation will now be performed in code This
allows you to print the calculation results in the game window To begin, start with
the solution for the “Font Example: Displaying Text in the Game Window” section
of Chapter 13 This solution can be found in the Solutions folder on this book’s
website
Since we will be displaying rows and columns of numeric data, we need to have a
suitable font type to align the text in each cell To keep things simple, this example
uses the Courier New font, which is a monospace, or nonproportional, font, which
means that all characters are the same width A monospace font ensures that each
character is the same pixel width This is useful because having alphabetical and
nu-meric characters of the same width simplifies the data formatting calculations
Once you have the project open, to improve readability, add theCell()method
so you can create an evenly spaced string for each cell This method will right-align
the columns when they are displayed in a matrix grid.Cell() first formats the data
in each cell so it appears as a floating-point number with two decimal places Then
Cell()compares the length of the data string with the number of spaces allotted for
Trang 3each cell.Cell()does this by adding extra spaces until the total character count forthe string matches the number of spaces allotted for each cell When the string hasbeen created, it is returned to the calling function:
public string Cell(float cell){
string cellDisplay = cell.ToString("N2"); // 2 decimals
const int CELL_WIDTH = 8; // 8 chars wide int numDigits = cellDisplay.Length;
// right align text and add padding on left
for (int i = 0; i < CELL_WIDTH - numDigits; i++)
public void DrawMatrix(Matrix C){
String[] row = new String[4]; // output strings
row[0] = Cell(C.M11) + Cell(C.M12) + Cell(C.M13) + Cell(C.M14);
row[1] = Cell(C.M21) + Cell(C.M22) + Cell(C.M23) + Cell(C.M24);
row[2] = Cell(C.M31) + Cell(C.M32) + Cell(C.M33) + Cell(C.M34);
row[3] = Cell(C.M41) + Cell(C.M42) + Cell(C.M43) + Cell(C.M44);
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, // enable transparency
SpriteSortMode.Immediate, // use manual order SaveStateMode.SaveState); // preserve 3D settings
for (int i = 0; i < 4; i++){ // draw 4 matrix rows Rectangle safeArea = TitleSafeRegion(row[i], spriteFont);
float height = spriteFont.MeasureString(row[i]).Y;
spriteBatch.DrawString(
spriteFont, // font row[i], // row string new Vector2(safeArea.Left, // top left pixel
safeArea.Top+(float)i*height), Color.Yellow); // color
Trang 4spriteBatch.End();
}
When you open the solution, you must add theMultiplyMatrix()method to
the game class so it can initialize two matrices and calculate their product For this
example, the code declares matrix A and initializes it to store the vector in the first
row Initially, when the constructor for the Matrix type is referenced, all cells in
ma-trix A are initialized to 0 The vector’s X, Y, Z, and W components are assigned to the
four cells of the first row of matrix A The cell data for the matrix on the right side of
the operator is assigned to matrix B; then A and B are multiplied together to generate
the product matrix
public Matrix MultiplyMatrix(){
Matrix A = new Matrix();
Matrix B = new Matrix();
// store vector in first row - all other cells equal 0
A.M11 = 2.0f; A.M12 = 1.0f; A.M13 = 0.0f; A.M14 = 0.0f;
To trigger the methods that calculate the matrix product and display the output,
replace the line
Trang 50.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
This result verifies that the code, C = A * B (where A, B, and C areMatrixjects), generates the same product as shown in the lengthy manual calculation.Matrix Multiplication Example:
ob-4×4 Matrix * ob-4×4 MatrixThis next example demonstrates how to multiply a 4×4 matrix by a 4×4 matrix.Knowing how to do this by hand is very useful because all of the transformations youhave been implementing in your XNA code involve multiplying 4×4 matrices by 4×4matrices You will first see how the multiplication can be performed manually, andthen how you can do it in code
Manual Calculation For this case, the following two matrices, A and B, are to bemultiplied:
Trang 6| 5 4 10 3 |
|-4 -5 -11 -3 |
| 7 5 13 4 |
|-4 7 9 1 |
Calculation in Code After performing the long-winded manual calculation, you can
appreciate the simplicity of being able to compute the same result with the
instruc-tion C = A * B
Using the code solution from the previous example, inMultiplyMatrix(),
re-place the instructions that set the individual cell values for matrix A with the
follow-ing version (matrix B remains the same as the previous example, so no changes are
required to it):
A.M11 = 2.0f; A.M12 = 1.0f; A.M13 = 0.0f; A.M14 = 0.0f;
A.M21 =-1.0f; A.M22 =-2.0f; A.M23 = 0.0f; A.M24 = 0.0f;
A.M31 = 3.0f; A.M32 = 1.0f; A.M33 = 0.0f; A.M34 = 0.0f;
A.M41 =-3.0f; A.M42 = 2.0f; A.M43 = 2.0f; A.M44 = 0.0f;
When you run the code, you will see the result does indeed match the manual
At this point, we can say when multiplying a 4×4 matrix by a 4×4 matrix that the
manual calculation can be executed in one line with the following instruction:
Matrix C = A * B
As mentioned earlier in this chapter, when drawing primitive shapes and 3D models,
you use matrices to transform sets of vertices Through the study of linear algebra,
specific matrices have been defined to scale, rotate, and translate sets of vertices In
Chapter 7, the I.S.R.O.T (Identity, Scale, Revolve, Orbit [translation and rotation],
Translate) sequence of matrices is used to ensure balanced transformations The
same logic applies when you are using transformation matrices that have been
cre-ated manually If the matrices are multiplied in an incorrect order, the
transforma-tions will also be incorrect
Trang 7When matrix calculations are performed in XNA, they are applied using the RightHand Rule perspective, which was explained in Chapter 7 This chapter applies thetransformation matrices from a Right Hand Rule perspective to suit the XNA frame-work.
When you perform transformations on an object, the data matrix containing the
X, Y, Z, and W coordinates is located on the left of the multiplication operator Thetransformation matrix is located on the right
When you are presented with a 4×4 matrix with 1s along the diagonal, values for
X, Y, Z at the bottom, and 0s elsewhere, you can conclude the matrix will perform atranslation of X units along the X plane, Y units along the Y plane, and Z units alongthe Z plane
Handling the W ComponentWhen a vector representing the X, Y, and Z coordinates of an object is transformedusing a translation matrix, the W component in the fourth column of the data matrixmust be set to 1
Failing to set all values in the fourth column of the data matrix to 1 will lead
to inaccurate translations
Translation Matrix ExampleImagine that the vertex (X=2, Y=1, Z=0) is transformed by the matrix on the right.The vector data matrix is located on the left Note that the fourth column represent-ing the W component is set to 1 The translation matrix for the format described heremust be located on the right side of the operator for the calculation to work properly
| 2 1 0 1 | X | 1 0 0 0 |
| 0 1 0 0 |
| 0 0 1 0 |
| 3 5 0 1 |
Trang 8Viewing this vertex and translation matrix gives you enough information to
deter-mine that the vertex with the coordinates X=2, Y=1, and Z=0 will be transformed by
three units in the positive X direction, and five units in the positive Y direction If this is
correct, the product of the vertex and translation matrix should move the vertex to
X=5, Y=6, and Z=0 Figure 16-1 shows the coordinate in its original position before
the predicted translation (on the left) and after the predicted translation (on the right)
To verify the prediction, you can try this calculation in code To set up the data
matrix, replace the code that initializes the cells in matrix A with this revision to
ini-tialize the vector data The remaining rows will take on the default of 0 in each cell
// store vector in first row - all other cells equal 0 by default
A.M11 = 2.0f; A.M12 = 1.0f; A.M13 = 0.0f; A.M14 = 1.0f;
Next, to set up the translation matrix, replace the code that assigns matrix B with
If you run this code, the output that appears in the window matches the prediction
that the new coordinates are X=5, Y=6, and Z=0:
Trang 9The translation moved the original vertex three units in the positive X direction,and five units in the positive Y direction.
Translation Matrix Example Using the CreateTranslation() Method
Since Chapter 7, we have used the method CreateTranslation(float x,float y, float z) to automatically generate the translation matrix Thismethod actually generates a translation matrix that is identical to the translation ma-trix we just created manually If you replace the code insideMultiplyMatrix()that assigns cell values to matrix B with the following instruction, you will generate
Scaling matrices are used any time an object needs to be resized You will often need
to scale your 3D models because modeling tools usually generate them in a size that isdifferent from the size needed for your game project The following matrix represents
a standard matrix for performing scaling operations At a glance, this scaling matrixcontains information to expand or shrink an object in the X, Y, and Z planes The X,
Y, and Z scaling factors are set on the diagonal down from the top left to the bottomright The digit, one, is needed in the bottom-right corner, and zeros are placed else-where to make this matrix a scaling matrix
X 0 0 0
0 Y 0 0
0 0 Z 0
0 0 0 1
Scaling Matrix Example
In this example, you will use a scaling matrix to double the size of a triangle A gle is represented with the matrix containing the triangle vertices on the left The ver-tex coordinates used to build the triangle are ( (0, 0, 0), (1, 4, 0), (4, 2, 0) ) The scalingmatrix that doubles the size of the triangle is on the right In the first three rows of thedata matrix on the left, the X, Y, and Z coordinates for the three triangle vertices are
Trang 10trian-stored One triangle vertex is stored in each of the first three rows When multiplying
the triangle vertices by the scaling matrix (to double the size), you can use the
follow-ing matrix equation:
| 0 0 0 0 | X | 2 0 0 0 |
| 1 4 0 0 | | 0 2 0 0 |
| 4 2 0 0 | | 0 0 2 0 |
| 0 0 0 0 | | 0 0 0 1 |
By looking at the scaling matrix—and without performing any calculations—it is
apparent that the size of the existing triangle is going to be doubled In Figure 16-2,
you can see that the size of the triangle has doubled when a vector set was
trans-formed with the scaling matrix
InsideMultiplyMatrix(), replace the code that assigns values to the cells of
matrix A with the following revision to initialize the data matrix for the triangle:
A.M11 = 0.0f; A.M12 = 0.0f; A.M13 = 0.0f; A.M14 = 0.0f;
A.M21 = 1.0f; A.M22 = 4.0f; A.M23 = 0.0f; A.M24 = 0.0f;
A.M31 = 4.0f; A.M32 = 2.0f; A.M33 = 0.0f; A.M34 = 0.0f;
A.M41 = 0.0f; A.M42 = 0.0f; A.M43 = 0.0f; A.M44 = 0.0f;
Before scaling and after scaling
Trang 11Next, replace the code that initializes matrix B with this version to initialize a ing matrix:
B = Matrix.CreateScale(2.0f, 2.0f, 2.0f);
When you run the code, the output will be the same as before
Rotation Matrix X Axis
The X rotation matrix is used to transform sets of vertices by an angle of θradiansabout the X axis:
| 1 0 0 0 |
| 0 cos θ sin θ 0 |
| 0 -sin θ cos θ 0 |
| 0 0 0 1 |
Trang 12Rotation Matrix X Axis Example
This example applies the X rotation matrix to rotate a triangle by 45 degrees (π/4)
The original set of coordinates (before the rotation) is in the left matrix, and the X
ro-tation matrix is located on the right:
Now we will show this implementation of the rotation matrix in code by using the
solution from the previous example To create a rotation matrix of π/4 radians about
Rotation of a triangle using the X rotation matrix
Trang 13the X axis, replace the instructions that initialize matrix B with the following versioninsideMultiplyMatrix():
float sin = (float)Math.Sin(Math.PI / 4.0);
float cos = (float)Math.Cos(Math.PI / 4.0);
X rotation matrix with a matrix that is generated using theCreateRotationX()method:
Trang 14Rotation Matrix Y Axis Example
This example demonstrates the use of the Y rotation matrix to rotate a set of triangle
coordinates by π/4 radians about the Y axis The data matrix is on the left, and the Y
rotation matrix is on the right:
Figure 16-4 shows the triangle coordinates before and after the multiplication that
performs the rotation
To implement the Y rotation in code, replace the code that initializes matrix B
with a rotation matrix to rotate the vertices by π/4 radians:
float sin = (float)Math.Sin(Math.PI / 4.0);
float cos = (float)Math.Cos(Math.PI / 4.0);
Trang 15When you run this program, the product matrix stores the triangle’s new nates after they are rotated by π/4 units around the Y axis (see Figure 16-4).
coordi-Y Axis Rotation Example Using the CreateRotationY() Method
In Chapter 7, theCreateRotationY(float radians)method was used to erate an identical Y rotation matrix as the one presented in this chapter You can re-place the code that initializes matrix B with the following instruction and it willproduce the same result:
gen-B = Matrix.CreateRotationY(MathHelper.Pi/4.0f);
When you run this code, the product matrix will be the same as before, but thisversion requires less code
Rotation Matrix Z Axis
The following matrix is the classic matrix for rotations of θ radians on the Z axis:
| cos θ sin θ 0 0 |
| -sin θ cos θ 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
Rotation Matrix Z Axis Example
In this example, the triangle coordinates on the left are transformed with the Z tion matrix by π/4 radians (45 degrees) about the Z axis: