core | glapi | vbo | math | shader | swrast | swrast_setup | tnl | tnl_dd

m_matrix.c File Reference


Detailed Description

Matrix operations.

Note:
  1. 4x4 transformation matrices are stored in memory in column major order.
  2. Points/vertices are to be thought of as column vectors.
  3. Transformation of a point p by a matrix M is: p' = M * p

#include "main/glheader.h"
#include "main/imports.h"
#include "main/macros.h"
#include "m_matrix.h"

Matrix multiplication

#define A(row, col)   a[(col<<2)+row]
#define B(row, col)   b[(col<<2)+row]
#define P(row, col)   product[(col<<2)+row]
static void matmul4 (GLfloat *product, const GLfloat *a, const GLfloat *b)
 Perform a full 4x4 matrix multiplication.
static void matmul34 (GLfloat *product, const GLfloat *a, const GLfloat *b)
 Multiply two matrices known to occupy only the top three rows, such as typical model matrices, and orthogonal matrices.
static void matrix_multf (GLmatrix *mat, const GLfloat *m, GLuint flags)
 Multiply a matrix by an array of floats with known properties.
void _math_matrix_mul_matrix (GLmatrix *dest, const GLmatrix *a, const GLmatrix *b)
 Matrix multiplication.
void _math_matrix_mul_floats (GLmatrix *dest, const GLfloat *m)
 Matrix multiplication.

Matrix inversion

#define SWAP_ROWS(a, b)   { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; }
 Swaps the values of two floating pointer variables.
static inv_mat_func inv_mat_tab [7]
 Table of the matrix inversion functions according to the matrix type.
typedef GLboolean(* inv_mat_func )(GLmatrix *mat)
 Matrix inversion function pointer type.
static GLboolean invert_matrix_general (GLmatrix *mat)
 Compute inverse of 4x4 transformation matrix.
static GLboolean invert_matrix_3d_general (GLmatrix *mat)
 Compute inverse of a general 3d transformation matrix.
static GLboolean invert_matrix_3d (GLmatrix *mat)
 Compute inverse of a 3d transformation matrix.
static GLboolean invert_matrix_identity (GLmatrix *mat)
 Compute inverse of an identity transformation matrix.
static GLboolean invert_matrix_3d_no_rot (GLmatrix *mat)
 Compute inverse of a no-rotation 3d transformation matrix.
static GLboolean invert_matrix_2d_no_rot (GLmatrix *mat)
 Compute inverse of a no-rotation 2d transformation matrix.
static GLboolean matrix_invert (GLmatrix *mat)
 Compute inverse of a transformation matrix.

Matrix analysis

#define ZERO(x)   (1<<x)
#define ONE(x)   (1<<(x+16))
#define MASK_NO_TRX   (ZERO(12) | ZERO(13) | ZERO(14))
#define MASK_NO_2D_SCALE   ( ONE(0) | ONE(5))
#define MASK_IDENTITY
#define MASK_2D_NO_ROT
#define MASK_2D
#define MASK_3D_NO_ROT
#define MASK_3D
#define MASK_PERSPECTIVE
#define SQ(x)   ((x)*(x))
static void analyse_from_scratch (GLmatrix *mat)
 Determine type and flags from scratch.
static void analyse_from_flags (GLmatrix *mat)
 Analyze a matrix given that its flags are accurate.
void _math_matrix_analyse (GLmatrix *mat)
 Analyze and update a matrix.

Defines

#define MAT_FLAG_IDENTITY   0
 is an identity matrix flag.
#define MAT_FLAG_GENERAL   0x1
 is a general matrix flag
#define MAT_FLAG_ROTATION   0x2
 is a rotation matrix flag
#define MAT_FLAG_TRANSLATION   0x4
 is a translation matrix flag
#define MAT_FLAG_UNIFORM_SCALE   0x8
 is an uniform scaling matrix flag
#define MAT_FLAG_GENERAL_SCALE   0x10
 is a general scaling matrix flag
#define MAT_FLAG_GENERAL_3D   0x20
 general 3D matrix flag
#define MAT_FLAG_PERSPECTIVE   0x40
 is a perspective proj matrix flag
#define MAT_FLAG_SINGULAR   0x80
 is a singular matrix flag
#define MAT_DIRTY_TYPE   0x100
 matrix type is dirty
#define MAT_DIRTY_FLAGS   0x200
 matrix flags are dirty
#define MAT_DIRTY_INVERSE   0x400
 matrix inverse is dirty
#define MAT_FLAGS_ANGLE_PRESERVING
 angle preserving matrix flags mask
#define MAT_FLAGS_GEOMETRY
 geometry related matrix flags mask
#define MAT_FLAGS_LENGTH_PRESERVING
 length preserving matrix flags mask
#define MAT_FLAGS_3D
 3D (non-perspective) matrix flags mask
#define MAT_DIRTY
 dirty matrix flags mask
#define TEST_MAT_FLAGS(mat, a)   ((MAT_FLAGS_GEOMETRY & (~(a)) & ((mat)->flags) ) == 0)
 Test geometry related matrix flags.
#define MAT(m, r, c)   (m)[(c)*4+(r)]
 References an element of 4x4 matrix.
#define M(row, col)   m[col*4+row]
#define M(row, col)   m[col*4+row]
#define M(row, col)   m[col*4+row]
#define M(row, col)   m[row + col*4]

Functions

GLboolean _math_matrix_is_length_preserving (const GLmatrix *m)
 Test if the given matrix preserves vector lengths.
GLboolean _math_matrix_has_rotation (const GLmatrix *m)
 Test if the given matrix does any rotation.
GLboolean _math_matrix_is_general_scale (const GLmatrix *m)
GLboolean _math_matrix_is_dirty (const GLmatrix *m)
void _mesa_transform_vector (GLfloat u[4], const GLfloat v[4], const GLfloat m[16])
 Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix.
Matrix output
static void print_matrix_floats (const GLfloat m[16])
 Print a matrix array.
void _math_matrix_print (const GLmatrix *m)
 Dumps the contents of a GLmatrix structure.
Matrix generation
void _math_matrix_rotate (GLmatrix *mat, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
 Generate a 4x4 transformation matrix from glRotate parameters, and post-multiply the input matrix by it.
void _math_matrix_frustum (GLmatrix *mat, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearval, GLfloat farval)
 Apply a perspective projection matrix.
void _math_matrix_ortho (GLmatrix *mat, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearval, GLfloat farval)
 Apply an orthographic projection matrix.
void _math_matrix_scale (GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z)
 Multiply a matrix with a general scaling matrix.
void _math_matrix_translate (GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z)
 Multiply a matrix with a translation matrix.
void _math_matrix_viewport (GLmatrix *m, GLint x, GLint y, GLint width, GLint height, GLfloat zNear, GLfloat zFar, GLfloat depthMax)
 Set matrix to do viewport and depthrange mapping.
void _math_matrix_set_identity (GLmatrix *mat)
 Set a matrix to the identity matrix.
Matrix setup
void _math_matrix_copy (GLmatrix *to, const GLmatrix *from)
 Copy a matrix.
void _math_matrix_loadf (GLmatrix *mat, const GLfloat *m)
 Loads a matrix array into GLmatrix.
void _math_matrix_ctr (GLmatrix *m)
 Matrix constructor.
void _math_matrix_dtr (GLmatrix *m)
 Matrix destructor.
void _math_matrix_alloc_inv (GLmatrix *m)
 Allocate a matrix inverse.
Matrix transpose
void _math_transposef (GLfloat to[16], const GLfloat from[16])
 Transpose a GLfloat matrix.
void _math_transposed (GLdouble to[16], const GLdouble from[16])
 Transpose a GLdouble matrix.
void _math_transposefd (GLfloat to[16], const GLdouble from[16])
 Transpose a GLdouble matrix and convert to GLfloat.

Variables

static const char * types []
 Names of the corresponding GLmatrixtype values.
static GLfloat Identity [16]
 Identity matrix.


Define Documentation

#define A ( row,
col   )     a[(col<<2)+row]

#define B ( row,
col   )     b[(col<<2)+row]

#define M ( row,
col   )     m[row + col*4]

#define M ( row,
col   )     m[col*4+row]

#define M ( row,
col   )     m[col*4+row]

#define M ( row,
col   )     m[col*4+row]

#define MASK_2D

Value:

(                      ZERO(8)  |           \
                                                ZERO(9)  |           \
                          ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
                          ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )

#define MASK_2D_NO_ROT

Value:

(           ZERO(4)  | ZERO(8)  |           \
                          ZERO(1)  |            ZERO(9)  |           \
                          ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
                          ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )

#define MASK_3D

Value:

(                                           \
                                                                     \
                                                                     \
                          ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )

#define MASK_3D_NO_ROT

Value:

(           ZERO(4)  | ZERO(8)  |           \
                          ZERO(1)  |            ZERO(9)  |           \
                          ZERO(2)  | ZERO(6)  |                      \
                          ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )

#define MASK_IDENTITY

Value:

( ONE(0)  | ZERO(4)  | ZERO(8)  | ZERO(12) |\
                          ZERO(1)  |  ONE(5)  | ZERO(9)  | ZERO(13) |\
                          ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
                          ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )

#define MASK_NO_2D_SCALE   ( ONE(0) | ONE(5))

#define MASK_NO_TRX   (ZERO(12) | ZERO(13) | ZERO(14))

#define MASK_PERSPECTIVE

Value:

(           ZERO(4)  |            ZERO(12) |\
                          ZERO(1)  |                       ZERO(13) |\
                          ZERO(2)  | ZERO(6)  |                      \
                          ZERO(3)  | ZERO(7)  |            ZERO(15) )

#define MAT ( m,
r,
 )     (m)[(c)*4+(r)]

References an element of 4x4 matrix.

Parameters:
m matrix array.
c column of the desired element.
r row of the desired element.
Returns:
value of the desired element.
Calculate the linear storage index of the element and references it.

#define ONE (  )     (1<<(x+16))

#define P ( row,
col   )     product[(col<<2)+row]

#define SQ (  )     ((x)*(x))

#define SWAP_ROWS ( a,
 )     { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; }

Swaps the values of two floating pointer variables.

Used by invert_matrix_general() to swap the row pointers.

#define TEST_MAT_FLAGS ( mat,
 )     ((MAT_FLAGS_GEOMETRY & (~(a)) & ((mat)->flags) ) == 0)

Test geometry related matrix flags.

Parameters:
mat a pointer to a GLmatrix structure.
a flags mask.
Returns:
non-zero if all geometry related matrix flags are contained within the mask, or zero otherwise.

#define ZERO (  )     (1<<x)


Typedef Documentation

typedef GLboolean(* inv_mat_func)(GLmatrix *mat)

Matrix inversion function pointer type.


Function Documentation

void _math_matrix_alloc_inv ( GLmatrix m  ) 

Allocate a matrix inverse.

Parameters:
m matrix.
Allocates the matrix inverse, GLmatrix::inv, and sets it to Identity.

void _math_matrix_analyse ( GLmatrix mat  ) 

Analyze and update a matrix.

Parameters:
mat matrix.
If the matrix type is dirty then calls either analyse_from_scratch() or analyse_from_flags() to determine its type, according to whether the flags are dirty or not, respectively. If the matrix has an inverse and it's dirty then calls matrix_invert(). Finally clears the dirty flags.

void _math_matrix_copy ( GLmatrix to,
const GLmatrix from 
)

Copy a matrix.

Parameters:
to destination matrix.
from source matrix.
Copies all fields in GLmatrix, creating an inverse array if necessary.

void _math_matrix_ctr ( GLmatrix m  ) 

Matrix constructor.

Parameters:
m matrix.
Initialize the GLmatrix fields.

void _math_matrix_dtr ( GLmatrix m  ) 

Matrix destructor.

Parameters:
m matrix.
Frees the data in a GLmatrix.

void _math_matrix_frustum ( GLmatrix mat,
GLfloat  left,
GLfloat  right,
GLfloat  bottom,
GLfloat  top,
GLfloat  nearval,
GLfloat  farval 
)

Apply a perspective projection matrix.

Parameters:
mat matrix to apply the projection.
left left clipping plane coordinate.
right right clipping plane coordinate.
bottom bottom clipping plane coordinate.
top top clipping plane coordinate.
nearval distance to the near clipping plane.
farval distance to the far clipping plane.
Creates the projection matrix and multiplies it with mat, marking the MAT_FLAG_PERSPECTIVE flag.

GLboolean _math_matrix_has_rotation ( const GLmatrix m  ) 

Test if the given matrix does any rotation.

(or perhaps if the upper-left 3x3 is non-identity)

GLboolean _math_matrix_is_dirty ( const GLmatrix m  ) 

GLboolean _math_matrix_is_general_scale ( const GLmatrix m  ) 

GLboolean _math_matrix_is_length_preserving ( const GLmatrix m  ) 

Test if the given matrix preserves vector lengths.

void _math_matrix_loadf ( GLmatrix mat,
const GLfloat *  m 
)

Loads a matrix array into GLmatrix.

Parameters:
m matrix array.
mat matrix.
Copies m into GLmatrix::m and marks the MAT_FLAG_GENERAL and MAT_DIRTY flags.

void _math_matrix_mul_floats ( GLmatrix dest,
const GLfloat *  m 
)

Matrix multiplication.

Parameters:
dest left and destination matrix.
m right matrix array.
Marks the matrix flags with general flag, and type and inverse dirty flags. Calls matmul4() for the multiplication.

void _math_matrix_mul_matrix ( GLmatrix dest,
const GLmatrix a,
const GLmatrix b 
)

Matrix multiplication.

Parameters:
dest destination matrix.
a left matrix.
b right matrix.
Joins both flags and marks the type and inverse as dirty. Calls matmul34() if both matrices are 3D, or matmul4() otherwise.

void _math_matrix_ortho ( GLmatrix mat,
GLfloat  left,
GLfloat  right,
GLfloat  bottom,
GLfloat  top,
GLfloat  nearval,
GLfloat  farval 
)

Apply an orthographic projection matrix.

Parameters:
mat matrix to apply the projection.
left left clipping plane coordinate.
right right clipping plane coordinate.
bottom bottom clipping plane coordinate.
top top clipping plane coordinate.
nearval distance to the near clipping plane.
farval distance to the far clipping plane.
Creates the projection matrix and multiplies it with mat, marking the MAT_FLAG_GENERAL_SCALE and MAT_FLAG_TRANSLATION flags.

void _math_matrix_print ( const GLmatrix m  ) 

Dumps the contents of a GLmatrix structure.

Parameters:
m pointer to the GLmatrix structure.

void _math_matrix_rotate ( GLmatrix mat,
GLfloat  angle,
GLfloat  x,
GLfloat  y,
GLfloat  z 
)

Generate a 4x4 transformation matrix from glRotate parameters, and post-multiply the input matrix by it.

Author:
This function was contributed by Erich Boleyn (erich@uruk.org). Optimizations contributed by Rudolf Opalla (rudi@khm.de).

void _math_matrix_scale ( GLmatrix mat,
GLfloat  x,
GLfloat  y,
GLfloat  z 
)

Multiply a matrix with a general scaling matrix.

Parameters:
mat matrix.
x x axis scale factor.
y y axis scale factor.
z z axis scale factor.
Multiplies in-place the elements of mat by the scale factors. Checks if the scales factors are roughly the same, marking the MAT_FLAG_UNIFORM_SCALE flag, or MAT_FLAG_GENERAL_SCALE. Marks the MAT_DIRTY_TYPE and MAT_DIRTY_INVERSE dirty flags.

void _math_matrix_set_identity ( GLmatrix mat  ) 

Set a matrix to the identity matrix.

Parameters:
mat matrix.
Copies Identity into GLmatrix::m, and into GLmatrix::inv if not NULL. Sets the matrix type to identity, and clear the dirty flags.

void _math_matrix_translate ( GLmatrix mat,
GLfloat  x,
GLfloat  y,
GLfloat  z 
)

Multiply a matrix with a translation matrix.

Parameters:
mat matrix.
x translation vector x coordinate.
y translation vector y coordinate.
z translation vector z coordinate.
Adds the translation coordinates to the elements of mat in-place. Marks the MAT_FLAG_TRANSLATION flag, and the MAT_DIRTY_TYPE and MAT_DIRTY_INVERSE dirty flags.

void _math_matrix_viewport ( GLmatrix m,
GLint  x,
GLint  y,
GLint  width,
GLint  height,
GLfloat  zNear,
GLfloat  zFar,
GLfloat  depthMax 
)

Set matrix to do viewport and depthrange mapping.

Transforms Normalized Device Coords to window/Z values.

void _math_transposed ( GLdouble  to[16],
const GLdouble  from[16] 
)

Transpose a GLdouble matrix.

Parameters:
to destination array.
from source array.

void _math_transposef ( GLfloat  to[16],
const GLfloat  from[16] 
)

Transpose a GLfloat matrix.

Parameters:
to destination array.
from source array.

void _math_transposefd ( GLfloat  to[16],
const GLdouble  from[16] 
)

Transpose a GLdouble matrix and convert to GLfloat.

Parameters:
to destination array.
from source array.

void _mesa_transform_vector ( GLfloat  u[4],
const GLfloat  v[4],
const GLfloat  m[16] 
)

Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix.

This function is used for transforming clipping plane equations and spotlight directions. Mathematically, u = v * m. Input: v - input vector m - transformation matrix Output: u - transformed vector

static void analyse_from_flags ( GLmatrix mat  )  [static]

Analyze a matrix given that its flags are accurate.

This is the more common operation, hopefully.

static void analyse_from_scratch ( GLmatrix mat  )  [static]

Determine type and flags from scratch.

Parameters:
mat matrix.
This is expensive enough to only want to do it once.

static GLboolean invert_matrix_2d_no_rot ( GLmatrix mat  )  [static]

Compute inverse of a no-rotation 2d transformation matrix.

Parameters:
mat pointer to a GLmatrix structure. The matrix inverse will be stored in the GLmatrix::inv attribute.
Returns:
GL_TRUE for success, GL_FALSE for failure (singular matrix).
Calculates the inverse matrix by applying the inverse scaling and translation to the identity matrix.

static GLboolean invert_matrix_3d ( GLmatrix mat  )  [static]

Compute inverse of a 3d transformation matrix.

Parameters:
mat pointer to a GLmatrix structure. The matrix inverse will be stored in the GLmatrix::inv attribute.
Returns:
GL_TRUE for success, GL_FALSE for failure (singular matrix).
If the matrix is not an angle preserving matrix then calls invert_matrix_3d_general for the actual calculation. Otherwise calculates the inverse matrix analyzing and inverting each of the scaling, rotation and translation parts.

static GLboolean invert_matrix_3d_general ( GLmatrix mat  )  [static]

Compute inverse of a general 3d transformation matrix.

Parameters:
mat pointer to a GLmatrix structure. The matrix inverse will be stored in the GLmatrix::inv attribute.
Returns:
GL_TRUE for success, GL_FALSE for failure (singular matrix).
Author:
Adapted from graphics gems II.
Calculates the inverse of the upper left by first calculating its determinant and multiplying it to the symmetric adjust matrix of each element. Finally deals with the translation part by transforming the original translation vector using by the calculated submatrix inverse.

static GLboolean invert_matrix_3d_no_rot ( GLmatrix mat  )  [static]

Compute inverse of a no-rotation 3d transformation matrix.

Parameters:
mat pointer to a GLmatrix structure. The matrix inverse will be stored in the GLmatrix::inv attribute.
Returns:
GL_TRUE for success, GL_FALSE for failure (singular matrix).
Calculates the

static GLboolean invert_matrix_general ( GLmatrix mat  )  [static]

Compute inverse of 4x4 transformation matrix.

Parameters:
mat pointer to a GLmatrix structure. The matrix inverse will be stored in the GLmatrix::inv attribute.
Returns:
GL_TRUE for success, GL_FALSE for failure (singular matrix).
Author:
Code contributed by Jacques Leroy jle@star.be
Calculates the inverse matrix by performing the gaussian matrix reduction with partial pivoting followed by back/substitution with the loops manually unrolled.

static GLboolean invert_matrix_identity ( GLmatrix mat  )  [static]

Compute inverse of an identity transformation matrix.

Parameters:
mat pointer to a GLmatrix structure. The matrix inverse will be stored in the GLmatrix::inv attribute.
Returns:
always GL_TRUE.
Simply copies Identity into GLmatrix::inv.

static void matmul34 ( GLfloat *  product,
const GLfloat *  a,
const GLfloat *  b 
) [static]

Multiply two matrices known to occupy only the top three rows, such as typical model matrices, and orthogonal matrices.

Parameters:
a matrix.
b matrix.
product will receive the product of a and b.

static void matmul4 ( GLfloat *  product,
const GLfloat *  a,
const GLfloat *  b 
) [static]

Perform a full 4x4 matrix multiplication.

Parameters:
a matrix.
b matrix.
product will receive the product of a and b.
Warning:
Is assumed that product != b. product == a is allowed.
Note:
KW: 4*16 = 64 multiplications
Author:
This matmul was contributed by Thomas Malik

static GLboolean matrix_invert ( GLmatrix mat  )  [static]

Compute inverse of a transformation matrix.

Parameters:
mat pointer to a GLmatrix structure. The matrix inverse will be stored in the GLmatrix::inv attribute.
Returns:
GL_TRUE for success, GL_FALSE for failure (singular matrix).
Calls the matrix inversion function in inv_mat_tab corresponding to the given matrix type. In case of failure, updates the MAT_FLAG_SINGULAR flag, and copies the identity matrix into GLmatrix::inv.

static void matrix_multf ( GLmatrix mat,
const GLfloat *  m,
GLuint  flags 
) [static]

Multiply a matrix by an array of floats with known properties.

Parameters:
mat pointer to a GLmatrix structure containing the left multiplication matrix, and that will receive the product result.
m right multiplication matrix array.
flags flags of the matrix m.
Joins both flags and marks the type and inverse as dirty. Calls matmul34() if both matrices are 3D, or matmul4() otherwise.

static void print_matrix_floats ( const GLfloat  m[16]  )  [static]

Print a matrix array.

Parameters:
m matrix array.
Called by _math_matrix_print() to print a matrix or its inverse.


Variable Documentation

GLfloat Identity[16] [static]

Initial value:

 {
   1.0, 0.0, 0.0, 0.0,
   0.0, 1.0, 0.0, 0.0,
   0.0, 0.0, 1.0, 0.0,
   0.0, 0.0, 0.0, 1.0
}
Identity matrix.

inv_mat_func inv_mat_tab[7] [static]

Initial value:

Table of the matrix inversion functions according to the matrix type.

const char* types[] [static]

Initial value:

 {
   "MATRIX_GENERAL",
   "MATRIX_IDENTITY",
   "MATRIX_3D_NO_ROT",
   "MATRIX_PERSPECTIVE",
   "MATRIX_2D",
   "MATRIX_2D_NO_ROT",
   "MATRIX_3D"
}
Names of the corresponding GLmatrixtype values.


Generated on Sun Sep 27 06:47:50 2009 for Mesa math module by  doxygen 1.5.4