⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m_matrix.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 3 页
字号:
   mat->flags |= (MAT_DIRTY_TYPE |		  MAT_DIRTY_INVERSE);}/** * Multiply a matrix with a translation matrix. * * \param mat matrix. * \param x translation vector x coordinate. * \param y translation vector y coordinate. * \param z translation vector z coordinate. * * Adds the translation coordinates to the elements of \p mat in-place.  Marks * the MAT_FLAG_TRANSLATION flag, and the MAT_DIRTY_TYPE and MAT_DIRTY_INVERSE * dirty flags. */void_math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ){   GLfloat *m = mat->m;   m[12] = m[0] * x + m[4] * y + m[8]  * z + m[12];   m[13] = m[1] * x + m[5] * y + m[9]  * z + m[13];   m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];   m[15] = m[3] * x + m[7] * y + m[11] * z + m[15];   mat->flags |= (MAT_FLAG_TRANSLATION |		  MAT_DIRTY_TYPE |		  MAT_DIRTY_INVERSE);}/** * Set matrix to do viewport and depthrange mapping. * Transforms Normalized Device Coords to window/Z values. */void_math_matrix_viewport(GLmatrix *m, GLint x, GLint y, GLint width, GLint height,                      GLfloat zNear, GLfloat zFar, GLfloat depthMax){   m->m[MAT_SX] = (GLfloat) width / 2.0F;   m->m[MAT_TX] = m->m[MAT_SX] + x;   m->m[MAT_SY] = (GLfloat) height / 2.0F;   m->m[MAT_TY] = m->m[MAT_SY] + y;   m->m[MAT_SZ] = depthMax * ((zFar - zNear) / 2.0F);   m->m[MAT_TZ] = depthMax * ((zFar - zNear) / 2.0F + zNear);   m->flags = MAT_FLAG_GENERAL_SCALE | MAT_FLAG_TRANSLATION;   m->type = MATRIX_3D_NO_ROT;}/** * Set a matrix to the identity matrix. * * \param mat matrix. * * Copies ::Identity into \p GLmatrix::m, and into GLmatrix::inv if not NULL. * Sets the matrix type to identity, and clear the dirty flags. */void_math_matrix_set_identity( GLmatrix *mat ){   MEMCPY( mat->m, Identity, 16*sizeof(GLfloat) );   if (mat->inv)      MEMCPY( mat->inv, Identity, 16*sizeof(GLfloat) );   mat->type = MATRIX_IDENTITY;   mat->flags &= ~(MAT_DIRTY_FLAGS|		   MAT_DIRTY_TYPE|		   MAT_DIRTY_INVERSE);}/*@}*//**********************************************************************//** \name 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    ( 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_2D_NO_ROT   (           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_2D          (                      ZERO(8)  |           \			                        ZERO(9)  |           \			  ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\			  ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )#define MASK_3D_NO_ROT   (           ZERO(4)  | ZERO(8)  |           \			  ZERO(1)  |            ZERO(9)  |           \			  ZERO(2)  | ZERO(6)  |                      \			  ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )#define MASK_3D          (                                           \			                                             \			                                             \			  ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )#define MASK_PERSPECTIVE (           ZERO(4)  |            ZERO(12) |\			  ZERO(1)  |                       ZERO(13) |\			  ZERO(2)  | ZERO(6)  |                      \			  ZERO(3)  | ZERO(7)  |            ZERO(15) )#define SQ(x) ((x)*(x))/** * Determine type and flags from scratch.   * * \param mat matrix. *  * This is expensive enough to only want to do it once. */static void analyse_from_scratch( GLmatrix *mat ){   const GLfloat *m = mat->m;   GLuint mask = 0;   GLuint i;   for (i = 0 ; i < 16 ; i++) {      if (m[i] == 0.0) mask |= (1<<i);   }   if (m[0] == 1.0F) mask |= (1<<16);   if (m[5] == 1.0F) mask |= (1<<21);   if (m[10] == 1.0F) mask |= (1<<26);   if (m[15] == 1.0F) mask |= (1<<31);   mat->flags &= ~MAT_FLAGS_GEOMETRY;   /* Check for translation - no-one really cares    */   if ((mask & MASK_NO_TRX) != MASK_NO_TRX)      mat->flags |= MAT_FLAG_TRANSLATION;   /* Do the real work    */   if (mask == (GLuint) MASK_IDENTITY) {      mat->type = MATRIX_IDENTITY;   }   else if ((mask & MASK_2D_NO_ROT) == (GLuint) MASK_2D_NO_ROT) {      mat->type = MATRIX_2D_NO_ROT;      if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE)	 mat->flags |= MAT_FLAG_GENERAL_SCALE;   }   else if ((mask & MASK_2D) == (GLuint) MASK_2D) {      GLfloat mm = DOT2(m, m);      GLfloat m4m4 = DOT2(m+4,m+4);      GLfloat mm4 = DOT2(m,m+4);      mat->type = MATRIX_2D;      /* Check for scale */      if (SQ(mm-1) > SQ(1e-6) ||	  SQ(m4m4-1) > SQ(1e-6))	 mat->flags |= MAT_FLAG_GENERAL_SCALE;      /* Check for rotation */      if (SQ(mm4) > SQ(1e-6))	 mat->flags |= MAT_FLAG_GENERAL_3D;      else	 mat->flags |= MAT_FLAG_ROTATION;   }   else if ((mask & MASK_3D_NO_ROT) == (GLuint) MASK_3D_NO_ROT) {      mat->type = MATRIX_3D_NO_ROT;      /* Check for scale */      if (SQ(m[0]-m[5]) < SQ(1e-6) &&	  SQ(m[0]-m[10]) < SQ(1e-6)) {	 if (SQ(m[0]-1.0) > SQ(1e-6)) {	    mat->flags |= MAT_FLAG_UNIFORM_SCALE;         }      }      else {	 mat->flags |= MAT_FLAG_GENERAL_SCALE;      }   }   else if ((mask & MASK_3D) == (GLuint) MASK_3D) {      GLfloat c1 = DOT3(m,m);      GLfloat c2 = DOT3(m+4,m+4);      GLfloat c3 = DOT3(m+8,m+8);      GLfloat d1 = DOT3(m, m+4);      GLfloat cp[3];      mat->type = MATRIX_3D;      /* Check for scale */      if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) {	 if (SQ(c1-1.0) > SQ(1e-6))	    mat->flags |= MAT_FLAG_UNIFORM_SCALE;	 /* else no scale at all */      }      else {	 mat->flags |= MAT_FLAG_GENERAL_SCALE;      }      /* Check for rotation */      if (SQ(d1) < SQ(1e-6)) {	 CROSS3( cp, m, m+4 );	 SUB_3V( cp, cp, (m+8) );	 if (LEN_SQUARED_3FV(cp) < SQ(1e-6))	    mat->flags |= MAT_FLAG_ROTATION;	 else	    mat->flags |= MAT_FLAG_GENERAL_3D;      }      else {	 mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */      }   }   else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) {      mat->type = MATRIX_PERSPECTIVE;      mat->flags |= MAT_FLAG_GENERAL;   }   else {      mat->type = MATRIX_GENERAL;      mat->flags |= MAT_FLAG_GENERAL;   }}/** * Analyze a matrix given that its flags are accurate. *  * This is the more common operation, hopefully. */static void analyse_from_flags( GLmatrix *mat ){   const GLfloat *m = mat->m;   if (TEST_MAT_FLAGS(mat, 0)) {      mat->type = MATRIX_IDENTITY;   }   else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION |				 MAT_FLAG_UNIFORM_SCALE |				 MAT_FLAG_GENERAL_SCALE))) {      if ( m[10]==1.0F && m[14]==0.0F ) {	 mat->type = MATRIX_2D_NO_ROT;      }      else {	 mat->type = MATRIX_3D_NO_ROT;      }   }   else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) {      if (                                 m[ 8]==0.0F            &&                             m[ 9]==0.0F            && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F) {	 mat->type = MATRIX_2D;      }      else {	 mat->type = MATRIX_3D;      }   }   else if (                 m[4]==0.0F                 && m[12]==0.0F            && m[1]==0.0F                               && m[13]==0.0F            && m[2]==0.0F && m[6]==0.0F            && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) {      mat->type = MATRIX_PERSPECTIVE;   }   else {      mat->type = MATRIX_GENERAL;   }}/** * Analyze and update a matrix. * * \param 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_analyse( GLmatrix *mat ){   if (mat->flags & MAT_DIRTY_TYPE) {      if (mat->flags & MAT_DIRTY_FLAGS)	 analyse_from_scratch( mat );      else	 analyse_from_flags( mat );   }   if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) {      matrix_invert( mat );   }   mat->flags &= ~(MAT_DIRTY_FLAGS|		   MAT_DIRTY_TYPE|		   MAT_DIRTY_INVERSE);}/*@}*//** * Test if the given matrix preserves vector lengths. */GLboolean_math_matrix_is_length_preserving( const GLmatrix *m ){   return TEST_MAT_FLAGS( m, MAT_FLAGS_LENGTH_PRESERVING);}/** * Test if the given matrix does any rotation. * (or perhaps if the upper-left 3x3 is non-identity) */GLboolean_math_matrix_has_rotation( const GLmatrix *m ){   if (m->flags & (MAT_FLAG_GENERAL |                   MAT_FLAG_ROTATION |                   MAT_FLAG_GENERAL_3D |                   MAT_FLAG_PERSPECTIVE))      return GL_TRUE;   else      return GL_FALSE;}GLboolean_math_matrix_is_general_scale( const GLmatrix *m ){   return (m->flags & MAT_FLAG_GENERAL_SCALE) ? GL_TRUE : GL_FALSE;}GLboolean_math_matrix_is_dirty( const GLmatrix *m ){   return (m->flags & MAT_DIRTY) ? GL_TRUE : GL_FALSE;}/**********************************************************************//** \name Matrix setup *//*@{*//** * Copy a matrix. * * \param to destination matrix. * \param from source matrix. * * Copies all fields in GLmatrix, creating an inverse array if necessary. */void_math_matrix_copy( GLmatrix *to, const GLmatrix *from ){   MEMCPY( to->m, from->m, sizeof(Identity) );   to->flags = from->flags;   to->type = from->type;   if (to->inv != 0) {      if (from->inv == 0) {	 matrix_invert( to );      }      else {	 MEMCPY(to->inv, from->inv, sizeof(GLfloat)*16);      }   }}/** * Loads a matrix array into GLmatrix. *  * \param m matrix array. * \param mat matrix. * * Copies \p m into GLmatrix::m and marks the MAT_FLAG_GENERAL and MAT_DIRTY * flags. */void_math_matrix_loadf( GLmatrix *mat, const GLfloat *m ){   MEMCPY( mat->m, m, 16*sizeof(GLfloat) );   mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY);}/** * Matrix constructor. * * \param m matrix. * * Initialize the GLmatrix fields. */void_math_matrix_ctr( GLmatrix *m ){   m->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );   if (m->m)      MEMCPY( m->m, Identity, sizeof(Identity) );   m->inv = NULL;   m->type = MATRIX_IDENTITY;   m->flags = 0;}/** * Matrix destructor. * * \param m matrix. * * Frees the data in a GLmatrix. */void_math_matrix_dtr( GLmatrix *m ){   if (m->m) {      ALIGN_FREE( m->m );      m->m = NULL;   }   if (m->inv) {      ALIGN_FREE( m->inv );      m->inv = NULL;   }}/** * Allocate a matrix inverse. * * \param m matrix. * * Allocates the matrix inverse, GLmatrix::inv, and sets it to Identity. */void_math_matrix_alloc_inv( GLmatrix *m ){   if (!m->inv) {      m->inv = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );      if (m->inv)         MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) );   }}/*@}*//**********************************************************************//** \name Matrix transpose *//*@{*//** * Transpose a GLfloat matrix. * * \param to destination array. * \param from source array. */void_math_transposef( GLfloat to[16], const GLfloat from[16] ){   to[0] = from[0];   to[1] = from[4];   to[2] = from[8];   to[3] = from[12];   to[4] = from[1];   to[5] = from[5];   to[6] = from[9];   to[7] = from[13];   to[8] = from[2];   to[9] = from[6];   to[10] = from[10];   to[11] = from[14];   to[12] = from[3];   to[13] = from[7];   to[14] = from[11];   to[15] = from[15];}/** * Transpose a GLdouble matrix. * * \param to destination array. * \param from source array. */void_math_transposed( GLdouble to[16], const GLdouble from[16] ){   to[0] = from[0];   to[1] = from[4];   to[2] = from[8];   to[3] = from[12];   to[4] = from[1];   to[5] = from[5];   to[6] = from[9];   to[7] = from[13];   to[8] = from[2];   to[9] = from[6];   to[10] = from[10];   to[11] = from[14];   to[12] = from[3];   to[13] = from[7];   to[14] = from[11];   to[15] = from[15];}/** * Transpose a GLdouble matrix and convert to GLfloat. * * \param to destination array. * \param from source array. */void_math_transposefd( GLfloat to[16], const GLdouble from[16] ){   to[0] = (GLfloat) from[0];   to[1] = (GLfloat) from[4];   to[2] = (GLfloat) from[8];   to[3] = (GLfloat) from[12];   to[4] = (GLfloat) from[1];   to[5] = (GLfloat) from[5];   to[6] = (GLfloat) from[9];   to[7] = (GLfloat) from[13];   to[8] = (GLfloat) from[2];   to[9] = (GLfloat) from[6];   to[10] = (GLfloat) from[10];   to[11] = (GLfloat) from[14];   to[12] = (GLfloat) from[3];   to[13] = (GLfloat) from[7];   to[14] = (GLfloat) from[11];   to[15] = (GLfloat) from[15];}/*@}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -