#include <revolution/mtx/GeoTypes.h>
typedef f32 Mtx[3][4];
typedef f32 (*MtxPtr)[4];
#define MTX_PTR_OFFSET 3
Mtx is a 3-row, 4-column two-dimensional array of 12 floating-point values. It's used by the matrix library as a 3x4 transformation matrix. In this context, it has an implied fourth row of (0,0,0,1). 3x4 matrices are used by all MTX-prefixed functions except those involving projection. These functions (MTXFrustum, MTXPerspective and MTXOrtho) all require a true 4x4 matrix (see Mtx44, Mtx44Ptr).
Matrices are stored and dereferenced C-style in row-major format. The table below summarizes the three ways of looking at a matrix: in memory, from a mathematical viewpoint, and as a C-style array.
| address | Mathematical | C arrays |
| 0x80200080 | m00 | m[0][0] |
| 0x80200084 | m01 | m[0][1] |
| 0x80200088 | m02 | m[0][2] |
| 0x8020008c | m03 | m[0][3] |
| 0x80200090 | m10 | m[1][0] |
| 0x80200094 | m11 | m[1][1] |
| 0x80200098 | m12 | m[1][2] |
| 0x8020009c | m13 | m[1][3] |
| 0x802000a0 | m20 | m[2][0] |
| 0x802000a4 | m21 | m[2][1] |
| 0x802000a8 | m22 | m[2][2] |
| 0x802000ac | m23 | m[2][3] |
Note: Storage format is transparent to the programmer if matrices are set and manipulated exclusively by MTX functions, but it is relevant if matrix elements are set individually. To insulate code from future changes to the storage format, do not set matrix values by hand, and do not initialize matrices when they are first declared. Instead, use the macro MTXRowCol(m,row,col) defined in mtx.h.
An Mtx is row-major for computational purposes, e.g., to apply a rotation (mR) followed by a translation (mT) to a point (pOld): pNew = mT x mR x pOld. If programmed, this appears as shown below.
MTXConcat( mT, mR, mFinal );
MTXMultVec( mFinal, &pOld, &pNew );
An MtxPtr is a pointer to an array of four floats. MtxPtr is also a pointer to Mtx and can replace Mtx as a function argument. It's even possible to use subscripts just as with Mtx. However, it's really a pointer to an array of four floats. This has two implications. First, an MtxPtr is assigned to an Mtx without the use of the & operator. For example:
void foo( Mtx m1, Mtx m2 )
{
MtxPtr mPtr;
if( condition )
mPtr = m1; // note that the & operator is not required.
else
mPtr = m2;MTXIdentity( mPtr );
}
Second, you cannot just increment and decrement an MtxPtr, because its size is 16, not 48. Therefore, we have defined a constant in mtx.h which provides the correct multiplier to offset a MtxPtr by the size of one matrix:
#define MTX_PTR_OFFSET 3
Use MTX_PTR_OFFSET whenever you need to increment an MtxPtr to the next matrix of an array. This will insulate your code from future changes to the Mtx storage format. For example:
Mtx mArray[2];
MtxPtr mPtr;
mPtr = (MtxPtr)mArray; // mPtr points to mArray[0]
MTXIdentity( mPtr ); // set mArray[0] to an identity matrix
mPtr += MTX_PTR_OFFSET // mPtr now points to mArray[1]
MTXTrans( mPtr, 3.0, 4.0, 5.0 ); // set mArray[1] to a translation matrix
A function cannot return a pointer to a two-dimensional array, but it can return an MtxPtr. This makes MtxPtr especially useful for functions that need to return a matrix, For example, the following type of matrix stack function.
MtxPtr mPtr;
MtxStack stack;
Point3d pt = { 3.0, 4.0, 5.0 };
// + some code to initialize stack
mPtr = GetStackPtr( &stack );
MTXMultVec( mPtr, &pt, &pt );
Mtx44, Mtx44Ptr, MTXAllocStack, MTXConcat, MTXCopy, MTXFreeStack, MTXGetStackPtr, MTXIdentity, MTXInitStack, MTXInverse, MTXLookAt, MTXMultVec, MTXMultVecArray, MTXPop, MTXPush, MTXPushFwd, MTXPushInv, MTXPushInvXpose, MTXQuat, MTXRotAxis, MTXRotDeg, MTXRotTrig, MTXRowCol, MTXScale, MTXTrans, MTXTranspose
03/01/2006 Initial version.