4x4 matrix class. More...
#include <Inventor/SbMatrix.h>
Public Member Functions | |
SbMatrix () | |
SbMatrix (float a11, float a12, float a13, float a14, float a21, float a22, float a23, float a24, float a31, float a32, float a33, float a34, float a41, float a42, float a43, float a44) | |
SbMatrix (const SbMat &m) | |
void | setValue (const SbMat &m) |
void | setValue (const float *pMat) |
void | setValue (const SbMatrixd &md) |
void | makeIdentity () |
void | setRotate (const SbRotation &q) |
void | setScale (float s) |
void | setScale (const SbVec3f &s) |
void | setTranslate (const SbVec3f &t) |
void | setTransform (const SbVec3f &translation, const SbRotation &rotation, const SbVec3f &scaleFactor, const SbRotation &scaleOrientation, const SbVec3f ¢er) |
void | setTransform (const SbVec3f &t, const SbRotation &r, const SbVec3f &s) |
void | setTransform (const SbVec3f &t, const SbRotation &r, const SbVec3f &s, const SbRotation &so) |
void | getTransform (SbVec3f &translation, SbRotation &rotation, SbVec3f &scaleFactor, SbRotation &scaleOrientation, const SbVec3f ¢er) const |
void | getTransform (SbVec3f &t, SbRotation &r, SbVec3f &s, SbRotation &so) const |
void | getValue (SbMat &m) const |
const SbMat & | getValue () const |
float | det3 (int r1, int r2, int r3, int c1, int c2, int c3) const |
float | det3 () const |
float | det4 () const |
SbBool | factor (SbMatrix &r, SbVec3f &s, SbMatrix &u, SbVec3f &t, SbMatrix &proj) const |
SbMatrix | inverse () const |
void | translate (const SbVec3f &translation) |
void | scale (const SbVec3f &scaleFactor) |
SbBool | LUDecomposition (int index[4], float &d) |
void | LUBackSubstitution (int index[4], float b[4]) const |
SbMatrix | transpose () const |
SbMatrix & | multRight (const SbMatrix &m) |
SbMatrix & | multLeft (const SbMatrix &m) |
void | multMatrixVec (const SbVec3f &src, SbVec3f &dst) const |
void | multVecMatrix (const SbVec3f &src, SbVec3f &dst) const |
void | multMatrixVec (const SbVec3f &src, SbVec4f &dst) const |
void | multVecMatrix (const SbVec3f &src, SbVec4f &dst) const |
void | multDirMatrix (const SbVec3f &src, SbVec3f &dst) const |
void | multLineMatrix (const SbLine &src, SbLine &dst) const |
void | print (FILE *fp) const |
operator float * () | |
operator SbMat & () | |
float * | operator[] (int i) |
const float * | operator[] (int i) const |
SbMatrix & | operator= (const SbMat &m) |
SbMatrix & | operator= (const SbMatrix &m) |
SbMatrix & | operator= (const SbRotation &q) |
SbMatrix & | operator*= (const SbMatrix &m) |
SbVec4f | operator* (const SbVec4f &v) |
SbBool | equals (const SbMatrix &m, float tolerance) const |
bool | isInvertible () const |
Static Public Member Functions | |
static SbMatrix | identity () |
Friends | |
SbVec4f | operator* (const SbVec4f &v, const SbMatrix &m) |
SbMatrix | operator* (const SbMatrix &m1, const SbMatrix &m2) |
int | operator== (const SbMatrix &m1, const SbMatrix &m2) |
int | operator!= (const SbMatrix &m1, const SbMatrix &m2) |
4x4 matrix class.
4x4 matrix class/datatype used by many Open Inventor node and action classes.
Matrices
The Open Inventor API uses the convention that positions and directions in 3D space are represented by row vectors. Therefore, to apply a transform matrix, the vector is post-multiplied by the matrix as shown in the following figure. Many mathematics and computer graphics books use column vector notation, however there is no functional difference between these two approaches.
Note that the commonly used terms "row major" and "column major" refer to the storage order of the matrix components in memory. This has nothing to do with how you use matrices and vectors with the Open Inventor API. Internally Open Inventor uses the same storage order as OpenGL to allow matrices to be passed efficiently to/from the GPU. When using the Open Inventor API just remember that positions are row vectors, as shown here.
[X' Y' Z' 1] = [X Y Z 1] * | m11 m12 m13 m14 | | m21 m22 m23 m24 | | m31 m32 m33 m34 | | m41 m42 m43 m44 |
Some common 4x4 transform matrices look like this:
Identity | 1 0 0 0 | Translate | 1 0 0 0 | Scale | Sx 0 0 0 | RotateX | 1 0 0 0 | | 0 1 0 0 | | 0 1 0 0 | | 0 Sy 0 0 | | 0 cosT -sinT 0 | | 0 0 1 0 | | 0 0 1 0 | | 0 0 Sz 0 | | 0 sinT cosT 0 | | 0 0 0 1 | | Tx Ty Tz 1 | | 0 0 0 1 | | 0 0 0 1 |
Therefore, to create a translation matrix you could initialize the SbMatrix object like this (or you could simply use the setTranslate() convenience method):
SbMatrix( 1,0,0,0, 0,1,0,0, 0,0,1,0, Tx,Ty,Tz,1 )
For convenience SbMatrix allows its values to be accessed using 2D array syntax, like this:
value = matrix[row][column];
For example, the translation X, Y, Z values in the above example can be retrieved using:
Tx = matrix[3][0] // Row 3, Column 0 Ty = matrix[3][1] // Row 3, Column 1 Tz = matrix[3][2] // Row 3, Column 2
Multiplying points
Points (positions in 3D space) are transformed by post-multiplying the row vector with the transform matrix like this:
P' = P * M
If you need to transform a point by a matrix use the multVecMatrix() method as shown here:
SbMatrix M; SbVec3f src, dst; M.multVecMatrix( src, dst );
Note that it is safe to use the same SbVec3f object as both src and dst.
In SbViewVolume, for example, the projectToScreen() method first calls the getMatrix() method to get the combined model/view/projection matrix, then calls that object's multVecMatrix() method to transform the 3D point into normalized clipping space (-1 to 1). (It then does one more step to convert that position to 0..1 normalized screen space but that's not important here.)
Multiplying directions
Vectors that represent a direction in 3D space rather than a position, for example surface normal vectors for geometry, can also be transformed. But in this case the translation portion of the matrix (if any) must not be used. For example, if a matrix contains the translation [10, 20, 30], then transforming the normal vector [0, 0, 1] using multVecMatrix() would produce the result [10, 20, 31]. However the correct result is still [0, 0, 1] because translation has no meaning for a direction vector. The method multDirMatrix() is provided to transform direction vectors ignoring the translation portion of the matrix.
Generally normals should be transformed by the inverse transpose of the matrix. See standard computer graphic references for the explanation.
SbMatrix M; SbVec3f src, dst; M.transpose().inverse().multDirMatrix( src, dst );
However note that if the matrix is orthonormal, i.e. purely rotational with no scaling or shearing, then the inverse transpose is the same as the original matrix and it is not necessary to compute the inverse transpose.
Multiplying matrices
A series of transforms, for example scale, rotate and translate can be combined into a single transform matrix by multiplying the matrices together. The result of such a multiplication is order dependent. Using the row vector convention, we can say that transforms are applied from "left to right". We normally want scaling applied first, then rotation, then translation, as shown here:
P' = P * S * R * T
So we would build the combined transform matrix M from scale, rotate and translate matrices S, R and T like this:
M = S * R * T
Note that convenience nodes like SoTransform do this (combine the scale, rotate and translate) for you automatically. So you don't necessarily need to remember all the details.
If you need to combine matrices yourself, you can use the multLeft() or multRight() method to multiple each matrix with the combined matrix. The name multLeft means to pre-multiply the SbMatrix object with the specified SbMatrix parameter, so we would combine the matrices like this:
Note that multLeft() overwrites the matrix currently in the SbMatrix object. So usually (as shown) you will start by making a copy of the first matrix as the starting point for accumulation.
The name multRight means to post-multiply the SbMatrix object with the specified SbMatrix parameter. So we would combine the matrices like this:
Note that multRight() also overwrites the matrix currently in the SbMatrix object. So usually (as shown) you will start by making a copy of the first matrix as the starting point for accumulation.
In C++, you can also use the "*=" operator to do a multRight operation that replaces the target matrix and you can also use the "*" operator to multiply two matrices without modifying either matrix. For example, to concatenate scale, rotate and translate matrices as above you can simply write:
SbMatrix M, S, R, T; M = S * R * T;
SbMatrix3, SbMatrixd, SbRotation, SbRotationd, SbVec2d, SbVec2f, SbVec2i32, SbVec2s, SbVec3d, SbVec3f, SbVec3i32, SbVec3s, SbVec4b, SbVec4d, SbVec4f, SbVec4i32, SbVec4s, SbVec4ub, SbVec4ui32, SbVec4us
SbMatrix::SbMatrix | ( | ) | [inline] |
Default constructor.
The matrix is initialized with zeros.
SbMatrix::SbMatrix | ( | float | a11, | |
float | a12, | |||
float | a13, | |||
float | a14, | |||
float | a21, | |||
float | a22, | |||
float | a23, | |||
float | a24, | |||
float | a31, | |||
float | a32, | |||
float | a33, | |||
float | a34, | |||
float | a41, | |||
float | a42, | |||
float | a43, | |||
float | a44 | |||
) |
Constructor.
SbMatrix::SbMatrix | ( | const SbMat & | m | ) |
Constructor.
float SbMatrix::det3 | ( | ) | const [inline] |
Returns determinant of upper-left 3x3 submatrix.
float SbMatrix::det3 | ( | int | r1, | |
int | r2, | |||
int | r3, | |||
int | c1, | |||
int | c2, | |||
int | c3 | |||
) | const |
Returns determinant of 3x3 submatrix composed of given row and column indices (0-3 for each).
float SbMatrix::det4 | ( | ) | const |
Returns determinant of entire matrix.
Equality comparison within given tolerance, for each component.
SbBool SbMatrix::factor | ( | SbMatrix & | r, | |
SbVec3f & | s, | |||
SbMatrix & | u, | |||
SbVec3f & | t, | |||
SbMatrix & | proj | |||
) | const |
Factors a matrix m into 5 pieces: m = r s r^ u t, where r^ means transpose of r, and r and u are rotations, s is a scale, and t is a translation.
Any projection information is returned in proj.
void SbMatrix::getTransform | ( | SbVec3f & | t, | |
SbRotation & | r, | |||
SbVec3f & | s, | |||
SbRotation & | so | |||
) | const |
Returns the translation, rotation, scale, and scale orientation components of the matrix.
void SbMatrix::getTransform | ( | SbVec3f & | translation, | |
SbRotation & | rotation, | |||
SbVec3f & | scaleFactor, | |||
SbRotation & | scaleOrientation, | |||
const SbVec3f & | center | |||
) | const |
Decomposes the matrix into a translation, rotation, scale, and scale orientation.
Any projection information is discarded. The decomposition depends upon choice of center point for rotation and scaling, which is optional as the last parameter. Note that if the center is 0, decompose() is the same as factor() where t is translation, u is rotation, s is scaleFactor, and r is scaleOrientation.
const SbMat& SbMatrix::getValue | ( | ) | const [inline] |
Returns matrix as a 4x4 array of elements.
void SbMatrix::getValue | ( | SbMat & | m | ) | const |
Returns matrix as a 4x4 array of elements.
static SbMatrix SbMatrix::identity | ( | ) | [static] |
Returns an identity matrix.
SbMatrix SbMatrix::inverse | ( | ) | const |
Returns inverse of matrix.
Results are undefined for singular matrices. Uses LU decomposition.
Matrix is not modified.
bool SbMatrix::isInvertible | ( | ) | const |
Returns true if the matrix is invertible.
void SbMatrix::LUBackSubstitution | ( | int | index[4], | |
float | b[4] | |||
) | const |
Perform back-substitution on LU-decomposed matrix.
Index is permutation of rows from original matrix.
SbBool SbMatrix::LUDecomposition | ( | int | index[4], | |
float & | d | |||
) |
Perform in-place LU decomposition of matrix.
index is index of rows in matrix. d is the parity of row swaps. Returns FALSE if singular.
void SbMatrix::makeIdentity | ( | ) |
Sets matrix to be identity.
Pre-multiplies the matrix by the given row vector, giving vector result.
src is assumed to be a direction vector, so translation part of matrix is ignored.
Note: If you need to transform surface points and normal vectors by a matrix, call multVecMatrix() for the points and call multDirMatrix() for the normals. Generally normals should be transformed by the inverse transpose of the matrix. However note that the inverse transpose is equal to the original matrix if the matrix is orthonormal, i.e. purely rotational with no scaling or shearing.
It is safe to let src and dst be the same instance of SbVec3f.
Pre-multiplies matrix by the given matrix.
Matrix is replaced by the result.
Multiplies the given line's origin by the matrix, and the line's direction by the rotation portion of the matrix.
It is safe to let src and dst be the same instance of SbLine.
Posts-multiplies matrix by the given column vector, giving vector result in homogeneous coordinates.
It is safe to let src and dst be the same instance of SbVec3f.
Post-multiplies matrix by the given column vector, giving a 3D vector result.
The intermediate homogeneous (vec4) value is converted to 3D by dividing the X, Y and Z components by W.
It is safe to let src and dst be the same instance of SbVec3f.
Post-multiplies the matrix by the given matrix.
Matrix is replaced by the result.
Pre-multiplies matrix by the given row vector, giving vector result in homogeneous coordinates.
Use this method to transform a point (position vector).
Use multDirMatrix() to transform a normal (direction vector).
Pre-multiplies matrix by the given row vector, giving a 3D vector result.
The intermediate homogeneous (vec4) value is converted to 3D by dividing the X, Y and Z components by W.
Use this method to transform a point (position vector).
Use multDirMatrix() to transform a normal (direction vector).
It is safe to let src and dst be the same instance of SbVec3f.
SbMatrix::operator float * | ( | ) | [inline] |
Cast: Returns pointer to storage of first element.
SbMatrix::operator SbMat & | ( | ) | [inline] |
Cast: returns reference to a 4x4 array.
Post-multiplies the matrix by the given matrix (equivalent to multRight() method).
Matrix is replaced by the resulting matrix.
SbMatrix& SbMatrix::operator= | ( | const SbRotation & | q | ) | [inline] |
Set the matrix from an SbRotation.
const float* SbMatrix::operator[] | ( | int | i | ) | const [inline] |
Make it look like a usual matrix (so you can do m[3][2]).
float* SbMatrix::operator[] | ( | int | i | ) | [inline] |
Make it look like a usual matrix (so you can do m[3][2]).
void SbMatrix::print | ( | FILE * | fp | ) | const |
Prints a formatted version of the matrix to the given file pointer.
void SbMatrix::scale | ( | const SbVec3f & | scaleFactor | ) |
Scales this matrice by the given vector.
void SbMatrix::setRotate | ( | const SbRotation & | q | ) |
Sets matrix to rotate by given rotation.
void SbMatrix::setScale | ( | const SbVec3f & | s | ) |
Sets matrix to scale by given vector.
void SbMatrix::setScale | ( | float | s | ) |
Sets matrix to scale by given uniform factor.
void SbMatrix::setTransform | ( | const SbVec3f & | t, | |
const SbRotation & | r, | |||
const SbVec3f & | s, | |||
const SbRotation & | so | |||
) |
Composes the matrix based on a translation, rotation, scale, and orientation for scale.
The scaleOrientation chooses the primary axes for the scale. The center point for scaling and rotation is (0,0,0).
void SbMatrix::setTransform | ( | const SbVec3f & | t, | |
const SbRotation & | r, | |||
const SbVec3f & | s | |||
) |
Composes the matrix based on a translation, rotation, and scale.
A scale orientation value of (0,0,0,1) is used. The center point for scaling and rotation is (0,0,0).
void SbMatrix::setTransform | ( | const SbVec3f & | translation, | |
const SbRotation & | rotation, | |||
const SbVec3f & | scaleFactor, | |||
const SbRotation & | scaleOrientation, | |||
const SbVec3f & | center | |||
) |
Composes the matrix based on a translation, rotation, scale, orientation for scale, and center.
The scaleOrientation chooses the primary axes for the scale. The center is the center point for scaling and rotation.
void SbMatrix::setTranslate | ( | const SbVec3f & | t | ) |
Sets matrix to translate by given vector.
void SbMatrix::setValue | ( | const SbMatrixd & | md | ) |
Sets value from a double precision matrix.
void SbMatrix::setValue | ( | const float * | pMat | ) | [inline] |
Sets matrix from a 16 value float array.
void SbMatrix::setValue | ( | const SbMat & | m | ) |
Sets matrix from a 4x4 array of elements.
void SbMatrix::translate | ( | const SbVec3f & | translation | ) |
Translates this matrice by the given vector.
SbMatrix SbMatrix::transpose | ( | ) | const |
Returns transpose of matrix.
Matrix is not modified.
Inequality comparison operator.
Multiplies two matrices, returning a matrix result.
Multiplies matrices by vector, returning a vector result.
Return v*m.