11.3 Matrix State

The "geometry engine" in the RSP implements a fixed-point matrix engine with the following matrix state:

A 10-element modeling matrix stack
New matrices can be loaded onto the stack, multiplied with the top of the stack, popped off of the stack, etc. This matrix stack is primarily used for manipulating objects within the world coordinate system (often combinations of rotations, translations, and sometimes scales).
A 1-element projection and viewing matrix "stack"
New matrices can be loaded onto the stack, multiplied with the top of the stack, but cannot be pushed or popped. This matrix "stack" is primarily used for the projection matrix and the viewing matrix. The projection matrix (often created with the guPerspective or the guOrtho functions) is loaded onto the stack, and then the viewing matrix (often created with the guLookAt function) is multiplied on top of it.
A "perspective normalization" factor
This is used to improve precision of the fixed-point perspective computation.

When a group of vertices is loaded, they are first transformed by the matrix MP (the current top of the modeling stack multiplied by the projection matrix). All vertex transformations are done only when they are loaded; sending a new matrix down later will not change any points already in the points buffer.

The modeling matrix stack resides in DRAM. It is the application's responsibility to allocate enough memory for this stack and provide a pointer to this stack area in the task list.

The format of a matrix is a bit unusual. It is optimized for the RSP's vector unit (used during the process of multiplication through transformation.) This format groups all of the integer parts of the elements, followed by all of the fractional parts of the elements. This unusual format is not exposed to the user, unless he/she chooses not to use the matrix utilities in the libraries.


11.3.1 Insert a Matrix

Inserts a new matrix into the display list.

Table 11-4 gsSPMatrix(Mtx *m,unsigned int p)
mpointer to the new matrix


11.3.2 Pop a Matrix

This command pops the matrix stack.

Table 11-5 gsSPPopMatrix(unsigned int n)


11.3.3 Perspective Normalization

This scale value is used to scale the transformed w coordinate down, prior to dividing out w to compute the screen coordinates (which are similarly scaled). The effect of this is to maximize the precision of this division.

The library function guPerspective() returns one approximation for this scale value, which is a good estimate for most cases:

Figure 11-2 Perspective Normalization Calculation
[Figure 11-2]

This approximation normalizes w=1.0 halfway between the near and far planes.

Table 11-6 gsSPPerspNormalize(unsigned short int s)
s16-bit unsigned fractional perspective normalization scale


11.3.4 Note on Coordinate Systems and Big Numbers

The RSP is a fixed point machine, so keeping coordinate systems within a certain range is important. If numbers in the final coordinate system (or intermediate coordinate systems) are too big, then the geometry of objects can be distorted, textures can shift erratically, and clipping can fail to work correctly. In order to avoid these problems keep the following notes in mind:

  1. No coordinate component (x, y, z, or w) should ever be greater than 32767.0 or less than -32767.0
  2. The difference between any 2 vertices of a triangle should not have any components greater than 32767.0
  3. The sum of the difference of w's of any 2 vertices plus the sum of the differences of any of the x, y, or z components should be less than 32767.0. In other words for any 2 vertices in a triangle, v1=(x1,y1,z1,w1), and v2=(x2,y2,z2,w2), these should all be true:
    abs (x1 - x2) + abs (w1 - w2) < 32767.0
    abs (y1 - y2) + abs (w1 - w2) < 32767.0
    abs (z1 - z2) + abs (w1 - w2) < 32767.0

One way to check this is to take the largest vertices that you have and run them through the largest matrices you are likely to have, then check to make sure that these conditions are met.

A recommended way of avoiding trouble is to never allow any component to get larger than 16383.0 or smaller than -16383.0. If you want to keep all components of coordinate value within the range of value above, ensure that M*S+T<16383.0. M, S and T are as follows:

the largest component (x, y, or z) of the largest model in your database.
The largest scale (i.e., number in the upper 3 rows of the matrix) in the matrix made up of the concatenation of the largest modeling matrix, the largest LookAt matrix, and the largest Perspective matrix you will use.
the largest translation (i.e., number in the 4th row of the matrix) in the matrix made up of the concatenation of the largest modeling matrix, the largest LookAt matrix, and the largest Perspective matrix you will use.

If you experience textures wobbling or shifting over a surface, clipping not working correctly, or geometry behaving erratically, this is a good place to check.


11.3.5 A Few Words About Matrix Precision

The RSP uses fixed-point 32-bit multiplies during matrix operations. Since the product of two 32-bit numbers is a 64-bit number, only the middle 32 bits of the answer is retained. Overflow of intermediate terms is possible, especially in large coordinate systems or unusual projection matrices.

In order to avoid fixed-point precision problems, in some cases it may be desirable to compute the matrix in floating point on the N64 CPU and just load it.

Matrix multiplies are very fast on the RSP, but they are not free. If possible, reduce matrix operations by pre-multiplying the matrices at modeling time or compile time.

Please see Section 11.3.4 "Note on Coordinate Systems and Big Numbers" for information about keeping coordinates from becoming too large.