State tracked NxM dimensional Matrix (ordered in memory by Column). More...
#include <Matrix.h>
Classes | |
class | ConstRowAccessor |
Helper class for Matrix op[] const. More... | |
class | RowAccessor |
Helper class for Matrix op[]. More... | |
Public Types | |
enum | Params { Rows = ROWS, Cols = COLS } |
enum | XformState { IDENTITY = 1, TRANS = 2, ORTHOGONAL = 4, AFFINE = 16, NON_UNISCALE = 32, FULL = 64, XFORM_ERROR = 128 } |
describes the xforms that this matrix has been through. More... | |
typedef DATA_TYPE | DataType |
use this to declare single value types of the same type as this matrix. | |
Public Member Functions | |
Matrix () | |
Default Constructor (Identity constructor). | |
Matrix (const Matrix< DATA_TYPE, ROWS, COLS > &matrix) | |
copy constructor | |
void | set (DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v10, DATA_TYPE v11) |
element wise setter for 2x2. | |
void | set (DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02, DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12) |
element wise setter for 2x3. | |
void | set (DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02, DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12, DATA_TYPE v20, DATA_TYPE v21, DATA_TYPE v22) |
element wise setter for 3x3. | |
void | set (DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02, DATA_TYPE v03, DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12, DATA_TYPE v13, DATA_TYPE v20, DATA_TYPE v21, DATA_TYPE v22, DATA_TYPE v23) |
element wise setter for 3x4. | |
void | set (DATA_TYPE v00, DATA_TYPE v01, DATA_TYPE v02, DATA_TYPE v03, DATA_TYPE v10, DATA_TYPE v11, DATA_TYPE v12, DATA_TYPE v13, DATA_TYPE v20, DATA_TYPE v21, DATA_TYPE v22, DATA_TYPE v23, DATA_TYPE v30, DATA_TYPE v31, DATA_TYPE v32, DATA_TYPE v33) |
element wise setter for 4x4. | |
void | set (const DATA_TYPE *data) |
comma operator | |
void | setTranspose (const DATA_TYPE *data) |
set the matrix to the transpose of the given data. | |
DATA_TYPE & | operator() (const unsigned row, const unsigned column) |
access [row, col] in the matrix WARNING: If you set data in the matrix (using this interface), you are required to set mState appropriately, failure to do so will result in incorrect calculations by other functions in GMTL. | |
const DATA_TYPE & | operator() (const unsigned row, const unsigned column) const |
access [row, col] in the matrix (const version) | |
RowAccessor | operator[] (const unsigned row) |
bracket operator WARNING: If you set data in the matrix (using this interface), you are required to set mState appropriately, failure to do so will result in incorrect calculations by other functions in GMTL. | |
ConstRowAccessor | operator[] (const unsigned row) const |
bracket operator (const version) | |
const DATA_TYPE * | getData () const |
Gets a DATA_TYPE pointer to the matrix data. | |
bool | isError () |
void | setError () |
void | setState (int state) |
Public Attributes | |
DATA_TYPE | mData [COLS *ROWS] |
Column major. | |
int | mState |
describes what xforms are in this matrix |
State tracked NxM dimensional Matrix (ordered in memory by Column).
Memory mapping:
gmtl::Matrix stores its elements in column major order. That is, it stores each column end-to-end in memory.
Typically, for 3D transform matrices, the 3x3 rotation is in the first three columns, while the translation is in the last column.
This memory alignment is chosen for compatibility with the OpenGL graphics API and others, which take matrices in this specific column major ordering described above.
See the interfaces for operator[r][c] and operator(r,c) for how to iterate over columns and rows for a GMTL Matrix.
NOTES on Matrix memory layout and [][] accessors:
gmtl Matrix memory is "column major" ordered, where columns are end to end in memory, while a C/C++ Matrix accessed the same way (using operator[][]) as a gmtl Matrix is "row major" ordered.
In practice, the differences between GMTL and C/C++ defined matrices all depends how you iterate over your matrix.
If gmtl is accessed mat[row][col] and C/C++ is accessed mat[col][row], then memory-wise, these two will yield the same memory mapping (column major as described above), thus, are equivelent and can both be used interchangably in many popular graphics APIs such as OpenGL, DirectX, and others.
In C/C++ access of a matrix via mat[row][col] yields this memory mapping after using ((float*)mat) to return it:
(0,0) (0,1) (0,2) (0,3) <=== Contiguous memory arranged by row (1,0) (1,1) (1,2) (1,3) <=== Contiguous (2,0) (2,1) (2,2) (2,3) <=== Contiguous (3,0) (3,1) (3,2) (3,3) <=== Contiguous
or linearly if you prefer: (0,0) (0,1) (0,2) (0,3) (1,0) (1,1) (1,2) (1,3) (2,0) (2,1) (2,2) (2,3) (3,0) (3,1) (3,2) (3,3)
In gmtl, access of a matrix via mat[row][col] yields this memory mapping after using getData() to return it:
(0,0) (0,1) (0,2) (0,3) (1,0) (1,1) (1,2) (1,3) (2,0) (2,1) (2,2) (2,3) (3,0) (3,1) (3,2) (3,3) ^ ^ ^ ^ --1-----2-----3-----4---- Contiguous memory arranged by column
or linearly if you prefer: (0,0) (1,0) (2,0) (3,0) (0,1) (1,1) (2,1) (3,1) (0,2) (1,2) (2,2) (3,2) (0,3) (1,3) (2,3) (3,3)
State Tracking:
The idea of a state-tracked matrix is that if we track the information as it is stored into the matrix, then other operations could make more optimal descisions based on the known state. A good example is in matrix invertion, a reletively costly operation for matrices. However, if we know the matrix state is (i.e.) ORTHOGONAL, then inversion becomes a simple transpose operation. There are also optimizations with multiplication, as well as other.
One side effect of this state tracking is that EVERY MATRIC FUNCTION NEEDS TO TRACK STATE. This means that anyone writing custom methods, or extentions to gmtl, will need to pay close attention to matrix state.
To facilitate state tracking in extensions, we've provided the function gmtl::combineMatrixStates() to help in determining state based on two combined matrices.
Definition at line 107 of file Matrix.h.
typedef DATA_TYPE gmtl::Matrix< DATA_TYPE, ROWS, COLS >::DataType |
enum gmtl::Matrix::Params |
enum gmtl::Matrix::XformState |
describes the xforms that this matrix has been through.
Definition at line 181 of file Matrix.h.
{ // identity matrix. IDENTITY = 1, // only translation, can simply negate that column TRANS = 2, // able to tranpose to get the inverse. only rotation component is set ORTHOGONAL = 4, // orthogonal, and normalized axes. //ORTHONORMAL = 8, // leaves the homogeneous coordinate unchanged - that is, in which the last column is (0,0,0,s). // can include rotation, uniform scale, and translation, but no shearing or nonuniform scaling // This can optionally be combined with the NON_UNISCALE state to indicate there is also non-uniform scale AFFINE = 16, // AFFINE matrix with non-uniform scale, a matrix cannot // have this state without also having AFFINE (must be or'd together). NON_UNISCALE = 32, // fully set matrix containing more information than the above, or state is unknown, // or unclassifiable in terms of the above. FULL = 64, // error bit XFORM_ERROR = 128 };
gmtl::Matrix< DATA_TYPE, ROWS, COLS >::Matrix | ( | ) | [inline] |
Default Constructor (Identity constructor).
Definition at line 213 of file Matrix.h.
{ for (unsigned int r = 0; r < ROWS; ++r) { for (unsigned int c = 0; c < COLS; ++c) { this->operator()( r, c ) = (DATA_TYPE)0.0; } } for (unsigned int x = 0; x < Math::Min( COLS, ROWS ); ++x) { this->operator()( x, x ) = (DATA_TYPE)1.0; } mState = IDENTITY; }
gmtl::Matrix< DATA_TYPE, ROWS, COLS >::Matrix | ( | const Matrix< DATA_TYPE, ROWS, COLS > & | matrix | ) | [inline] |
const DATA_TYPE* gmtl::Matrix< DATA_TYPE, ROWS, COLS >::getData | ( | ) | const [inline] |
bool gmtl::Matrix< DATA_TYPE, ROWS, COLS >::isError | ( | ) | [inline] |
const DATA_TYPE& gmtl::Matrix< DATA_TYPE, ROWS, COLS >::operator() | ( | const unsigned | row, | |
const unsigned | column | |||
) | const [inline] |
access [row, col] in the matrix (const version)
Definition at line 424 of file Matrix.h.
{ gmtlASSERT( (row < ROWS) && (column < COLS) ); return mData[column*ROWS + row]; }
DATA_TYPE& gmtl::Matrix< DATA_TYPE, ROWS, COLS >::operator() | ( | const unsigned | row, | |
const unsigned | column | |||
) | [inline] |
access [row, col] in the matrix WARNING: If you set data in the matrix (using this interface), you are required to set mState appropriately, failure to do so will result in incorrect calculations by other functions in GMTL.
If you are unsure about how to set mState, set it to FULL and you will be sure to get the correct result at the cost of some performance.
Definition at line 417 of file Matrix.h.
{ gmtlASSERT( (row < ROWS) && (column < COLS) ); return mData[column*ROWS + row]; }
RowAccessor gmtl::Matrix< DATA_TYPE, ROWS, COLS >::operator[] | ( | const unsigned | row | ) | [inline] |
bracket operator WARNING: If you set data in the matrix (using this interface), you are required to set mState appropriately, failure to do so will result in incorrect calculations by other functions in GMTL.
If you are unsure about how to set mState, set it to FULL and you will be sure to get the correct result at the cost of some performance.
Definition at line 438 of file Matrix.h.
{ return RowAccessor(this, row); }
ConstRowAccessor gmtl::Matrix< DATA_TYPE, ROWS, COLS >::operator[] | ( | const unsigned | row | ) | const [inline] |
void gmtl::Matrix< DATA_TYPE, ROWS, COLS >::set | ( | DATA_TYPE | v00, | |
DATA_TYPE | v01, | |||
DATA_TYPE | v10, | |||
DATA_TYPE | v11 | |||
) | [inline] |
element wise setter for 2x2.
void gmtl::Matrix< DATA_TYPE, ROWS, COLS >::set | ( | DATA_TYPE | v00, | |
DATA_TYPE | v01, | |||
DATA_TYPE | v02, | |||
DATA_TYPE | v03, | |||
DATA_TYPE | v10, | |||
DATA_TYPE | v11, | |||
DATA_TYPE | v12, | |||
DATA_TYPE | v13, | |||
DATA_TYPE | v20, | |||
DATA_TYPE | v21, | |||
DATA_TYPE | v22, | |||
DATA_TYPE | v23 | |||
) | [inline] |
element wise setter for 3x4.
Definition at line 293 of file Matrix.h.
{ GMTL_STATIC_ASSERT( (ROWS == 3 && COLS == 4), Set_called_when_Matrix_not_of_size_3_4 ); mData[0] = v00; mData[1] = v10; mData[2] = v20; mData[3] = v01; mData[4] = v11; mData[5] = v21; mData[6] = v02; mData[7] = v12; mData[8] = v22; // right row mData[9] = v03; mData[10] = v13; mData[11] = v23; mState = FULL; }
void gmtl::Matrix< DATA_TYPE, ROWS, COLS >::set | ( | DATA_TYPE | v00, | |
DATA_TYPE | v01, | |||
DATA_TYPE | v02, | |||
DATA_TYPE | v10, | |||
DATA_TYPE | v11, | |||
DATA_TYPE | v12 | |||
) | [inline] |
void gmtl::Matrix< DATA_TYPE, ROWS, COLS >::set | ( | DATA_TYPE | v00, | |
DATA_TYPE | v01, | |||
DATA_TYPE | v02, | |||
DATA_TYPE | v03, | |||
DATA_TYPE | v10, | |||
DATA_TYPE | v11, | |||
DATA_TYPE | v12, | |||
DATA_TYPE | v13, | |||
DATA_TYPE | v20, | |||
DATA_TYPE | v21, | |||
DATA_TYPE | v22, | |||
DATA_TYPE | v23, | |||
DATA_TYPE | v30, | |||
DATA_TYPE | v31, | |||
DATA_TYPE | v32, | |||
DATA_TYPE | v33 | |||
) | [inline] |
element wise setter for 4x4.
Definition at line 318 of file Matrix.h.
{ GMTL_STATIC_ASSERT( (ROWS == 4 && COLS == 4), Set_called_when_Matrix_not_of_size_4_4 ); mData[0] = v00; mData[1] = v10; mData[2] = v20; mData[4] = v01; mData[5] = v11; mData[6] = v21; mData[8] = v02; mData[9] = v12; mData[10] = v22; // right row mData[12] = v03; mData[13] = v13; mData[14] = v23; // bottom row mData[3] = v30; mData[7] = v31; mData[11] = v32; mData[15] = v33; mState = FULL; }
void gmtl::Matrix< DATA_TYPE, ROWS, COLS >::set | ( | const DATA_TYPE * | data | ) | [inline] |
comma operator
set the matrix to the given data. This function is useful to copy matrix data from another math library.
pfMatrix other_matrix; other_matrix.setRot( 90, 1, 0, 0 ); gmtl::Matrix44f mat; mat.set( other_matrix.getFloatPtr() );
WARNING: this isn't really safe, size and datatype are not enforced by the compiler.
void gmtl::Matrix< DATA_TYPE, ROWS, COLS >::set | ( | DATA_TYPE | v00, | |
DATA_TYPE | v01, | |||
DATA_TYPE | v02, | |||
DATA_TYPE | v10, | |||
DATA_TYPE | v11, | |||
DATA_TYPE | v12, | |||
DATA_TYPE | v20, | |||
DATA_TYPE | v21, | |||
DATA_TYPE | v22 | |||
) | [inline] |
element wise setter for 3x3.
void gmtl::Matrix< DATA_TYPE, ROWS, COLS >::setError | ( | ) | [inline] |
void gmtl::Matrix< DATA_TYPE, ROWS, COLS >::setState | ( | int | state | ) | [inline] |
void gmtl::Matrix< DATA_TYPE, ROWS, COLS >::setTranspose | ( | const DATA_TYPE * | data | ) | [inline] |
set the matrix to the transpose of the given data.
normally set() takes raw matrix data in column by column order, this function allows you to pass in row by row data.
Normally you'll use this function if you want to use a float array to init the matrix (see code example).
float data[] = { 1, 0, 0, 15, 0, 1, 0, -4, 0, 0, 1, 20, 0, 0, 0, 1 }; gmtl::Matrix44f mat; mat.setTranspose( data );
WARNING: this isn't really safe, size and datatype are not enforced by the compiler.
Definition at line 400 of file Matrix.h.
{ for (unsigned int r = 0; r < ROWS; ++r) for (unsigned int c = 0; c < COLS; ++c) this->operator()( r, c ) = data[(r * COLS) + c]; mState = FULL; }
DATA_TYPE gmtl::Matrix< DATA_TYPE, ROWS, COLS >::mData[COLS *ROWS] |
Column major.
In other words {Column1, Column2, Column3, Column4} in memory access element mData[column][row] WARNING: If you set data in the matrix (using this interface), you are required to set mState appropriately, failure to do so will result in incorrect calculations by other functions in GMTL. If you are unsure about how to set mState, set it to FULL and you will be sure to get the correct result at the cost of some performance.
int gmtl::Matrix< DATA_TYPE, ROWS, COLS >::mState |