ReactOS  0.4.12-dev-18-gf469aca
m_matrix.c
Go to the documentation of this file.
1 /*
2  * Mesa 3-D graphics library
3  * Version: 6.3
4  *
5  * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 
36 #include <precomp.h>
37 
45 #define MAT_FLAG_IDENTITY 0
50 #define MAT_FLAG_GENERAL 0x1
51 #define MAT_FLAG_ROTATION 0x2
52 #define MAT_FLAG_TRANSLATION 0x4
53 #define MAT_FLAG_UNIFORM_SCALE 0x8
54 #define MAT_FLAG_GENERAL_SCALE 0x10
55 #define MAT_FLAG_GENERAL_3D 0x20
56 #define MAT_FLAG_PERSPECTIVE 0x40
57 #define MAT_FLAG_SINGULAR 0x80
58 #define MAT_DIRTY_TYPE 0x100
59 #define MAT_DIRTY_FLAGS 0x200
60 #define MAT_DIRTY_INVERSE 0x400
63 #define MAT_FLAGS_ANGLE_PRESERVING (MAT_FLAG_ROTATION | \
64  MAT_FLAG_TRANSLATION | \
65  MAT_FLAG_UNIFORM_SCALE)
66 
68 #define MAT_FLAGS_GEOMETRY (MAT_FLAG_GENERAL | \
69  MAT_FLAG_ROTATION | \
70  MAT_FLAG_TRANSLATION | \
71  MAT_FLAG_UNIFORM_SCALE | \
72  MAT_FLAG_GENERAL_SCALE | \
73  MAT_FLAG_GENERAL_3D | \
74  MAT_FLAG_PERSPECTIVE | \
75  MAT_FLAG_SINGULAR)
76 
78 #define MAT_FLAGS_LENGTH_PRESERVING (MAT_FLAG_ROTATION | \
79  MAT_FLAG_TRANSLATION)
80 
81 
83 #define MAT_FLAGS_3D (MAT_FLAG_ROTATION | \
84  MAT_FLAG_TRANSLATION | \
85  MAT_FLAG_UNIFORM_SCALE | \
86  MAT_FLAG_GENERAL_SCALE | \
87  MAT_FLAG_GENERAL_3D)
88 
90 #define MAT_DIRTY (MAT_DIRTY_TYPE | \
91  MAT_DIRTY_FLAGS | \
92  MAT_DIRTY_INVERSE)
93 
106 #define TEST_MAT_FLAGS(mat, a) \
107  ((MAT_FLAGS_GEOMETRY & (~(a)) & ((mat)->flags) ) == 0)
108 
109 
114 static const char *types[] = {
115  "MATRIX_GENERAL",
116  "MATRIX_IDENTITY",
117  "MATRIX_3D_NO_ROT",
118  "MATRIX_PERSPECTIVE",
119  "MATRIX_2D",
120  "MATRIX_2D_NO_ROT",
121  "MATRIX_3D"
122 };
123 
124 
128 static GLfloat Identity[16] = {
129  1.0, 0.0, 0.0, 0.0,
130  0.0, 1.0, 0.0, 0.0,
131  0.0, 0.0, 1.0, 0.0,
132  0.0, 0.0, 0.0, 1.0
133 };
134 
135 
136 
137 /**********************************************************************/
140 
141 #define A(row,col) a[(col<<2)+row]
142 #define B(row,col) b[(col<<2)+row]
143 #define P(row,col) product[(col<<2)+row]
144 
158 static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b )
159 {
160  GLint i;
161  for (i = 0; i < 4; i++) {
162  const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
163  P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
164  P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
165  P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
166  P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
167  }
168 }
169 
178 static void matmul34( GLfloat *product, const GLfloat *a, const GLfloat *b )
179 {
180  GLint i;
181  for (i = 0; i < 3; i++) {
182  const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
183  P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0);
184  P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1);
185  P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2);
186  P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3;
187  }
188  P(3,0) = 0;
189  P(3,1) = 0;
190  P(3,2) = 0;
191  P(3,3) = 1;
192 }
193 
194 #undef A
195 #undef B
196 #undef P
197 
209 static void matrix_multf( GLmatrix *mat, const GLfloat *m, GLuint flags )
210 {
211  mat->flags |= (flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE);
212 
214  matmul34( mat->m, mat->m, m );
215  else
216  matmul4( mat->m, mat->m, m );
217 }
218 
229 void
230 _math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b )
231 {
232  dest->flags = (a->flags |
233  b->flags |
236 
237  if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D))
238  matmul34( dest->m, a->m, b->m );
239  else
240  matmul4( dest->m, a->m, b->m );
241 }
242 
252 void
253 _math_matrix_mul_floats( GLmatrix *dest, const GLfloat *m )
254 {
255  dest->flags |= (MAT_FLAG_GENERAL |
259 
260  matmul4( dest->m, dest->m, m );
261 }
262 
266 /**********************************************************************/
269 
277 static void print_matrix_floats( const GLfloat m[16] )
278 {
279  int i;
280  for (i=0;i<4;i++) {
281  _mesa_debug(NULL,"\t%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] );
282  }
283 }
284 
290 void
291 _math_matrix_print( const GLmatrix *m )
292 {
293  _mesa_debug(NULL, "Matrix type: %s, flags: %x\n", types[m->type], m->flags);
295  _mesa_debug(NULL, "Inverse: \n");
296  if (m->inv) {
297  GLfloat prod[16];
299  matmul4(prod, m->m, m->inv);
300  _mesa_debug(NULL, "Mat * Inverse:\n");
301  print_matrix_floats(prod);
302  }
303  else {
304  _mesa_debug(NULL, " - not available\n");
305  }
306 }
307 
322 #define MAT(m,r,c) (m)[(c)*4+(r)]
323 
324 
325 /**********************************************************************/
328 
334 #define SWAP_ROWS(a, b) { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; }
335 
352 {
353  const GLfloat *m = mat->m;
354  GLfloat *out = mat->inv;
355  GLfloat wtmp[4][8];
356  GLfloat m0, m1, m2, m3, s;
357  GLfloat *r0, *r1, *r2, *r3;
358 
359  r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
360 
361  r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1),
362  r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3),
363  r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
364 
365  r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1),
366  r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3),
367  r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
368 
369  r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1),
370  r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3),
371  r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
372 
373  r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1),
374  r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3),
375  r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
376 
377  /* choose pivot - or die */
378  if (FABSF(r3[0])>FABSF(r2[0])) SWAP_ROWS(r3, r2);
379  if (FABSF(r2[0])>FABSF(r1[0])) SWAP_ROWS(r2, r1);
380  if (FABSF(r1[0])>FABSF(r0[0])) SWAP_ROWS(r1, r0);
381  if (0.0 == r0[0]) return GL_FALSE;
382 
383  /* eliminate first variable */
384  m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0];
385  s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
386  s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
387  s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
388  s = r0[4];
389  if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
390  s = r0[5];
391  if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
392  s = r0[6];
393  if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
394  s = r0[7];
395  if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }
396 
397  /* choose pivot - or die */
398  if (FABSF(r3[1])>FABSF(r2[1])) SWAP_ROWS(r3, r2);
399  if (FABSF(r2[1])>FABSF(r1[1])) SWAP_ROWS(r2, r1);
400  if (0.0 == r1[1]) return GL_FALSE;
401 
402  /* eliminate second variable */
403  m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1];
404  r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
405  r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
406  s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; }
407  s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; }
408  s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; }
409  s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; }
410 
411  /* choose pivot - or die */
412  if (FABSF(r3[2])>FABSF(r2[2])) SWAP_ROWS(r3, r2);
413  if (0.0 == r2[2]) return GL_FALSE;
414 
415  /* eliminate third variable */
416  m3 = r3[2]/r2[2];
417  r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
418  r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6],
419  r3[7] -= m3 * r2[7];
420 
421  /* last check */
422  if (0.0 == r3[3]) return GL_FALSE;
423 
424  s = 1.0F/r3[3]; /* now back substitute row 3 */
425  r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;
426 
427  m2 = r2[3]; /* now back substitute row 2 */
428  s = 1.0F/r2[2];
429  r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
430  r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
431  m1 = r1[3];
432  r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
433  r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
434  m0 = r0[3];
435  r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
436  r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
437 
438  m1 = r1[2]; /* now back substitute row 1 */
439  s = 1.0F/r1[1];
440  r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
441  r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
442  m0 = r0[2];
443  r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
444  r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
445 
446  m0 = r0[1]; /* now back substitute row 0 */
447  s = 1.0F/r0[0];
448  r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
449  r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
450 
451  MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5],
452  MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7],
453  MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5],
454  MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7],
455  MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5],
456  MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7],
457  MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5],
458  MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7];
459 
460  return GL_TRUE;
461 }
462 #undef SWAP_ROWS
463 
480 {
481  const GLfloat *in = mat->m;
482  GLfloat *out = mat->inv;
483  GLfloat pos, neg, t;
484  GLfloat det;
485 
486  /* Calculate the determinant of upper left 3x3 submatrix and
487  * determine if the matrix is singular.
488  */
489  pos = neg = 0.0;
490  t = MAT(in,0,0) * MAT(in,1,1) * MAT(in,2,2);
491  if (t >= 0.0) pos += t; else neg += t;
492 
493  t = MAT(in,1,0) * MAT(in,2,1) * MAT(in,0,2);
494  if (t >= 0.0) pos += t; else neg += t;
495 
496  t = MAT(in,2,0) * MAT(in,0,1) * MAT(in,1,2);
497  if (t >= 0.0) pos += t; else neg += t;
498 
499  t = -MAT(in,2,0) * MAT(in,1,1) * MAT(in,0,2);
500  if (t >= 0.0) pos += t; else neg += t;
501 
502  t = -MAT(in,1,0) * MAT(in,0,1) * MAT(in,2,2);
503  if (t >= 0.0) pos += t; else neg += t;
504 
505  t = -MAT(in,0,0) * MAT(in,2,1) * MAT(in,1,2);
506  if (t >= 0.0) pos += t; else neg += t;
507 
508  det = pos + neg;
509 
510  if (det*det < 1e-25)
511  return GL_FALSE;
512 
513  det = 1.0F / det;
514  MAT(out,0,0) = ( (MAT(in,1,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,1,2) )*det);
515  MAT(out,0,1) = (- (MAT(in,0,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,0,2) )*det);
516  MAT(out,0,2) = ( (MAT(in,0,1)*MAT(in,1,2) - MAT(in,1,1)*MAT(in,0,2) )*det);
517  MAT(out,1,0) = (- (MAT(in,1,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,1,2) )*det);
518  MAT(out,1,1) = ( (MAT(in,0,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,0,2) )*det);
519  MAT(out,1,2) = (- (MAT(in,0,0)*MAT(in,1,2) - MAT(in,1,0)*MAT(in,0,2) )*det);
520  MAT(out,2,0) = ( (MAT(in,1,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,1,1) )*det);
521  MAT(out,2,1) = (- (MAT(in,0,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,0,1) )*det);
522  MAT(out,2,2) = ( (MAT(in,0,0)*MAT(in,1,1) - MAT(in,1,0)*MAT(in,0,1) )*det);
523 
524  /* Do the translation part */
525  MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) +
526  MAT(in,1,3) * MAT(out,0,1) +
527  MAT(in,2,3) * MAT(out,0,2) );
528  MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) +
529  MAT(in,1,3) * MAT(out,1,1) +
530  MAT(in,2,3) * MAT(out,1,2) );
531  MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) +
532  MAT(in,1,3) * MAT(out,2,1) +
533  MAT(in,2,3) * MAT(out,2,2) );
534 
535  return GL_TRUE;
536 }
537 
551 static GLboolean invert_matrix_3d( GLmatrix *mat )
552 {
553  const GLfloat *in = mat->m;
554  GLfloat *out = mat->inv;
557  return invert_matrix_3d_general( mat );
558  }
559 
560  if (mat->flags & MAT_FLAG_UNIFORM_SCALE) {
561  GLfloat scale = (MAT(in,0,0) * MAT(in,0,0) +
562  MAT(in,0,1) * MAT(in,0,1) +
563  MAT(in,0,2) * MAT(in,0,2));
564 
565  if (scale == 0.0)
566  return GL_FALSE;
567 
568  scale = 1.0F / scale;
569 
570  /* Transpose and scale the 3 by 3 upper-left submatrix. */
571  MAT(out,0,0) = scale * MAT(in,0,0);
572  MAT(out,1,0) = scale * MAT(in,0,1);
573  MAT(out,2,0) = scale * MAT(in,0,2);
574  MAT(out,0,1) = scale * MAT(in,1,0);
575  MAT(out,1,1) = scale * MAT(in,1,1);
576  MAT(out,2,1) = scale * MAT(in,1,2);
577  MAT(out,0,2) = scale * MAT(in,2,0);
578  MAT(out,1,2) = scale * MAT(in,2,1);
579  MAT(out,2,2) = scale * MAT(in,2,2);
580  }
581  else if (mat->flags & MAT_FLAG_ROTATION) {
582  /* Transpose the 3 by 3 upper-left submatrix. */
583  MAT(out,0,0) = MAT(in,0,0);
584  MAT(out,1,0) = MAT(in,0,1);
585  MAT(out,2,0) = MAT(in,0,2);
586  MAT(out,0,1) = MAT(in,1,0);
587  MAT(out,1,1) = MAT(in,1,1);
588  MAT(out,2,1) = MAT(in,1,2);
589  MAT(out,0,2) = MAT(in,2,0);
590  MAT(out,1,2) = MAT(in,2,1);
591  MAT(out,2,2) = MAT(in,2,2);
592  }
593  else {
594  /* pure translation */
595  memcpy( out, Identity, sizeof(Identity) );
596  MAT(out,0,3) = - MAT(in,0,3);
597  MAT(out,1,3) = - MAT(in,1,3);
598  MAT(out,2,3) = - MAT(in,2,3);
599  return GL_TRUE;
600  }
601 
602  if (mat->flags & MAT_FLAG_TRANSLATION) {
603  /* Do the translation part */
604  MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) +
605  MAT(in,1,3) * MAT(out,0,1) +
606  MAT(in,2,3) * MAT(out,0,2) );
607  MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) +
608  MAT(in,1,3) * MAT(out,1,1) +
609  MAT(in,2,3) * MAT(out,1,2) );
610  MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) +
611  MAT(in,1,3) * MAT(out,2,1) +
612  MAT(in,2,3) * MAT(out,2,2) );
613  }
614  else {
615  MAT(out,0,3) = MAT(out,1,3) = MAT(out,2,3) = 0.0;
616  }
617 
618  return GL_TRUE;
619 }
620 
632 {
633  memcpy( mat->inv, Identity, sizeof(Identity) );
634  return GL_TRUE;
635 }
636 
648 {
649  const GLfloat *in = mat->m;
650  GLfloat *out = mat->inv;
652  if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0 || MAT(in,2,2) == 0 )
653  return GL_FALSE;
654 
655  memcpy( out, Identity, 16 * sizeof(GLfloat) );
656  MAT(out,0,0) = 1.0F / MAT(in,0,0);
657  MAT(out,1,1) = 1.0F / MAT(in,1,1);
658  MAT(out,2,2) = 1.0F / MAT(in,2,2);
659 
660  if (mat->flags & MAT_FLAG_TRANSLATION) {
661  MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0));
662  MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1));
663  MAT(out,2,3) = - (MAT(in,2,3) * MAT(out,2,2));
664  }
665 
666  return GL_TRUE;
667 }
668 
681 {
682  const GLfloat *in = mat->m;
683  GLfloat *out = mat->inv;
685  if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0)
686  return GL_FALSE;
687 
688  memcpy( out, Identity, 16 * sizeof(GLfloat) );
689  MAT(out,0,0) = 1.0F / MAT(in,0,0);
690  MAT(out,1,1) = 1.0F / MAT(in,1,1);
691 
692  if (mat->flags & MAT_FLAG_TRANSLATION) {
693  MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0));
694  MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1));
695  }
696 
697  return GL_TRUE;
698 }
699 
700 #if 0
701 /* broken */
702 static GLboolean invert_matrix_perspective( GLmatrix *mat )
703 {
704  const GLfloat *in = mat->m;
705  GLfloat *out = mat->inv;
706 
707  if (MAT(in,2,3) == 0)
708  return GL_FALSE;
709 
710  memcpy( out, Identity, 16 * sizeof(GLfloat) );
711 
712  MAT(out,0,0) = 1.0F / MAT(in,0,0);
713  MAT(out,1,1) = 1.0F / MAT(in,1,1);
714 
715  MAT(out,0,3) = MAT(in,0,2);
716  MAT(out,1,3) = MAT(in,1,2);
717 
718  MAT(out,2,2) = 0;
719  MAT(out,2,3) = -1;
720 
721  MAT(out,3,2) = 1.0F / MAT(in,2,3);
722  MAT(out,3,3) = MAT(in,2,2) * MAT(out,3,2);
723 
724  return GL_TRUE;
725 }
726 #endif
727 
731 typedef GLboolean (*inv_mat_func)( GLmatrix *mat );
732 
736 static inv_mat_func inv_mat_tab[7] = {
740 #if 0
741  /* Don't use this function for now - it fails when the projection matrix
742  * is premultiplied by a translation (ala Chromium's tilesort SPU).
743  */
744  invert_matrix_perspective,
745 #else
747 #endif
748  invert_matrix_3d, /* lazy! */
750  invert_matrix_3d
751 };
752 
765 static GLboolean matrix_invert( GLmatrix *mat )
766 {
767  if (inv_mat_tab[mat->type](mat)) {
768  mat->flags &= ~MAT_FLAG_SINGULAR;
769  return GL_TRUE;
770  } else {
771  mat->flags |= MAT_FLAG_SINGULAR;
772  memcpy( mat->inv, Identity, sizeof(Identity) );
773  return GL_FALSE;
774  }
775 }
776 
780 /**********************************************************************/
783 
792 void
795 {
796  GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c;
797  GLfloat m[16];
798  GLboolean optimized;
799 
800  s = (GLfloat) sin( angle * DEG2RAD );
801  c = (GLfloat) cos( angle * DEG2RAD );
802 
803  memcpy(m, Identity, sizeof(GLfloat)*16);
804  optimized = GL_FALSE;
805 
806 #define M(row,col) m[col*4+row]
807 
808  if (x == 0.0F) {
809  if (y == 0.0F) {
810  if (z != 0.0F) {
811  optimized = GL_TRUE;
812  /* rotate only around z-axis */
813  M(0,0) = c;
814  M(1,1) = c;
815  if (z < 0.0F) {
816  M(0,1) = s;
817  M(1,0) = -s;
818  }
819  else {
820  M(0,1) = -s;
821  M(1,0) = s;
822  }
823  }
824  }
825  else if (z == 0.0F) {
826  optimized = GL_TRUE;
827  /* rotate only around y-axis */
828  M(0,0) = c;
829  M(2,2) = c;
830  if (y < 0.0F) {
831  M(0,2) = -s;
832  M(2,0) = s;
833  }
834  else {
835  M(0,2) = s;
836  M(2,0) = -s;
837  }
838  }
839  }
840  else if (y == 0.0F) {
841  if (z == 0.0F) {
842  optimized = GL_TRUE;
843  /* rotate only around x-axis */
844  M(1,1) = c;
845  M(2,2) = c;
846  if (x < 0.0F) {
847  M(1,2) = s;
848  M(2,1) = -s;
849  }
850  else {
851  M(1,2) = -s;
852  M(2,1) = s;
853  }
854  }
855  }
856 
857  if (!optimized) {
858  const GLfloat mag = SQRTF(x * x + y * y + z * z);
859 
860  if (mag <= 1.0e-4) {
861  /* no rotation, leave mat as-is */
862  return;
863  }
864 
865  x /= mag;
866  y /= mag;
867  z /= mag;
868 
869 
870  /*
871  * Arbitrary axis rotation matrix.
872  *
873  * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
874  * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation
875  * (which is about the X-axis), and the two composite transforms
876  * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
877  * from the arbitrary axis to the X-axis then back. They are
878  * all elementary rotations.
879  *
880  * Rz' is a rotation about the Z-axis, to bring the axis vector
881  * into the x-z plane. Then Ry' is applied, rotating about the
882  * Y-axis to bring the axis vector parallel with the X-axis. The
883  * rotation about the X-axis is then performed. Ry and Rz are
884  * simply the respective inverse transforms to bring the arbitrary
885  * axis back to its original orientation. The first transforms
886  * Rz' and Ry' are considered inverses, since the data from the
887  * arbitrary axis gives you info on how to get to it, not how
888  * to get away from it, and an inverse must be applied.
889  *
890  * The basic calculation used is to recognize that the arbitrary
891  * axis vector (x, y, z), since it is of unit length, actually
892  * represents the sines and cosines of the angles to rotate the
893  * X-axis to the same orientation, with theta being the angle about
894  * Z and phi the angle about Y (in the order described above)
895  * as follows:
896  *
897  * cos ( theta ) = x / sqrt ( 1 - z^2 )
898  * sin ( theta ) = y / sqrt ( 1 - z^2 )
899  *
900  * cos ( phi ) = sqrt ( 1 - z^2 )
901  * sin ( phi ) = z
902  *
903  * Note that cos ( phi ) can further be inserted to the above
904  * formulas:
905  *
906  * cos ( theta ) = x / cos ( phi )
907  * sin ( theta ) = y / sin ( phi )
908  *
909  * ...etc. Because of those relations and the standard trigonometric
910  * relations, it is pssible to reduce the transforms down to what
911  * is used below. It may be that any primary axis chosen will give the
912  * same results (modulo a sign convention) using thie method.
913  *
914  * Particularly nice is to notice that all divisions that might
915  * have caused trouble when parallel to certain planes or
916  * axis go away with care paid to reducing the expressions.
917  * After checking, it does perform correctly under all cases, since
918  * in all the cases of division where the denominator would have
919  * been zero, the numerator would have been zero as well, giving
920  * the expected result.
921  */
922 
923  xx = x * x;
924  yy = y * y;
925  zz = z * z;
926  xy = x * y;
927  yz = y * z;
928  zx = z * x;
929  xs = x * s;
930  ys = y * s;
931  zs = z * s;
932  one_c = 1.0F - c;
933 
934  /* We already hold the identity-matrix so we can skip some statements */
935  M(0,0) = (one_c * xx) + c;
936  M(0,1) = (one_c * xy) - zs;
937  M(0,2) = (one_c * zx) + ys;
938 /* M(0,3) = 0.0F; */
939 
940  M(1,0) = (one_c * xy) + zs;
941  M(1,1) = (one_c * yy) + c;
942  M(1,2) = (one_c * yz) - xs;
943 /* M(1,3) = 0.0F; */
944 
945  M(2,0) = (one_c * zx) - ys;
946  M(2,1) = (one_c * yz) + xs;
947  M(2,2) = (one_c * zz) + c;
948 /* M(2,3) = 0.0F; */
949 
950 /*
951  M(3,0) = 0.0F;
952  M(3,1) = 0.0F;
953  M(3,2) = 0.0F;
954  M(3,3) = 1.0F;
955 */
956  }
957 #undef M
958 
959  matrix_multf( mat, m, MAT_FLAG_ROTATION );
960 }
961 
976 void
980  GLfloat nearval, GLfloat farval )
981 {
982  GLfloat x, y, a, b, c, d;
983  GLfloat m[16];
984 
985  x = (2.0F*nearval) / (right-left);
986  y = (2.0F*nearval) / (top-bottom);
987  a = (right+left) / (right-left);
988  b = (top+bottom) / (top-bottom);
989  c = -(farval+nearval) / ( farval-nearval);
990  d = -(2.0F*farval*nearval) / (farval-nearval); /* error? */
991 
992 #define M(row,col) m[col*4+row]
993  M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
994  M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
995  M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
996  M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
997 #undef M
998 
1000 }
1001 
1016 void
1020  GLfloat nearval, GLfloat farval )
1022  GLfloat m[16];
1023 
1024 #define M(row,col) m[col*4+row]
1025  M(0,0) = 2.0F / (right-left);
1026  M(0,1) = 0.0F;
1027  M(0,2) = 0.0F;
1028  M(0,3) = -(right+left) / (right-left);
1029 
1030  M(1,0) = 0.0F;
1031  M(1,1) = 2.0F / (top-bottom);
1032  M(1,2) = 0.0F;
1033  M(1,3) = -(top+bottom) / (top-bottom);
1034 
1035  M(2,0) = 0.0F;
1036  M(2,1) = 0.0F;
1037  M(2,2) = -2.0F / (farval-nearval);
1038  M(2,3) = -(farval+nearval) / (farval-nearval);
1039 
1040  M(3,0) = 0.0F;
1041  M(3,1) = 0.0F;
1042  M(3,2) = 0.0F;
1043  M(3,3) = 1.0F;
1044 #undef M
1045 
1047 }
1048 
1062 void
1064 {
1065  GLfloat *m = mat->m;
1066  m[0] *= x; m[4] *= y; m[8] *= z;
1067  m[1] *= x; m[5] *= y; m[9] *= z;
1068  m[2] *= x; m[6] *= y; m[10] *= z;
1069  m[3] *= x; m[7] *= y; m[11] *= z;
1070 
1071  if (FABSF(x - y) < 1e-8 && FABSF(x - z) < 1e-8)
1072  mat->flags |= MAT_FLAG_UNIFORM_SCALE;
1073  else
1074  mat->flags |= MAT_FLAG_GENERAL_SCALE;
1075 
1076  mat->flags |= (MAT_DIRTY_TYPE |
1078 }
1079 
1092 void
1094 {
1095  GLfloat *m = mat->m;
1096  m[12] = m[0] * x + m[4] * y + m[8] * z + m[12];
1097  m[13] = m[1] * x + m[5] * y + m[9] * z + m[13];
1098  m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
1099  m[15] = m[3] * x + m[7] * y + m[11] * z + m[15];
1100 
1101  mat->flags |= (MAT_FLAG_TRANSLATION |
1102  MAT_DIRTY_TYPE |
1104 }
1105 
1106 
1111 void
1113  GLfloat zNear, GLfloat zFar, GLfloat depthMax)
1114 {
1115  m->m[MAT_SX] = (GLfloat) width / 2.0F;
1116  m->m[MAT_TX] = m->m[MAT_SX] + x;
1117  m->m[MAT_SY] = (GLfloat) height / 2.0F;
1118  m->m[MAT_TY] = m->m[MAT_SY] + y;
1119  m->m[MAT_SZ] = depthMax * ((zFar - zNear) / 2.0F);
1120  m->m[MAT_TZ] = depthMax * ((zFar - zNear) / 2.0F + zNear);
1122  m->type = MATRIX_3D_NO_ROT;
1123 }
1124 
1125 
1134 void
1136 {
1137  memcpy( mat->m, Identity, 16*sizeof(GLfloat) );
1138 
1139  if (mat->inv)
1140  memcpy( mat->inv, Identity, 16*sizeof(GLfloat) );
1141 
1142  mat->type = MATRIX_IDENTITY;
1143  mat->flags &= ~(MAT_DIRTY_FLAGS|
1146 }
1147 
1151 /**********************************************************************/
1154 
1155 #define ZERO(x) (1<<x)
1156 #define ONE(x) (1<<(x+16))
1157 
1158 #define MASK_NO_TRX (ZERO(12) | ZERO(13) | ZERO(14))
1159 #define MASK_NO_2D_SCALE ( ONE(0) | ONE(5))
1161 #define MASK_IDENTITY ( ONE(0) | ZERO(4) | ZERO(8) | ZERO(12) |\
1162  ZERO(1) | ONE(5) | ZERO(9) | ZERO(13) |\
1163  ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\
1164  ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) )
1166 #define MASK_2D_NO_ROT ( ZERO(4) | ZERO(8) | \
1167  ZERO(1) | ZERO(9) | \
1168  ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\
1169  ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) )
1171 #define MASK_2D ( ZERO(8) | \
1172  ZERO(9) | \
1173  ZERO(2) | ZERO(6) | ONE(10) | ZERO(14) |\
1174  ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) )
1176 
1177 #define MASK_3D_NO_ROT ( ZERO(4) | ZERO(8) | \
1178  ZERO(1) | ZERO(9) | \
1179  ZERO(2) | ZERO(6) | \
1180  ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) )
1182 #define MASK_3D ( \
1183  \
1184  \
1185  ZERO(3) | ZERO(7) | ZERO(11) | ONE(15) )
1187 
1188 #define MASK_PERSPECTIVE ( ZERO(4) | ZERO(12) |\
1189  ZERO(1) | ZERO(13) |\
1190  ZERO(2) | ZERO(6) | \
1191  ZERO(3) | ZERO(7) | ZERO(15) )
1193 #define SQ(x) ((x)*(x))
1194 
1202 static void analyse_from_scratch( GLmatrix *mat )
1203 {
1204  const GLfloat *m = mat->m;
1205  GLuint mask = 0;
1207 
1208  for (i = 0 ; i < 16 ; i++) {
1209  if (m[i] == 0.0) mask |= (1<<i);
1210  }
1211 
1212  if (m[0] == 1.0F) mask |= (1<<16);
1213  if (m[5] == 1.0F) mask |= (1<<21);
1214  if (m[10] == 1.0F) mask |= (1<<26);
1215  if (m[15] == 1.0F) mask |= (1<<31);
1216 
1217  mat->flags &= ~MAT_FLAGS_GEOMETRY;
1218 
1219  /* Check for translation - no-one really cares
1220  */
1221  if ((mask & MASK_NO_TRX) != MASK_NO_TRX)
1222  mat->flags |= MAT_FLAG_TRANSLATION;
1223 
1224  /* Do the real work
1225  */
1226  if (mask == (GLuint) MASK_IDENTITY) {
1227  mat->type = MATRIX_IDENTITY;
1228  }
1229  else if ((mask & MASK_2D_NO_ROT) == (GLuint) MASK_2D_NO_ROT) {
1230  mat->type = MATRIX_2D_NO_ROT;
1231 
1232  if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE)
1233  mat->flags |= MAT_FLAG_GENERAL_SCALE;
1234  }
1235  else if ((mask & MASK_2D) == (GLuint) MASK_2D) {
1236  GLfloat mm = DOT2(m, m);
1237  GLfloat m4m4 = DOT2(m+4,m+4);
1238  GLfloat mm4 = DOT2(m,m+4);
1239 
1240  mat->type = MATRIX_2D;
1241 
1242  /* Check for scale */
1243  if (SQ(mm-1) > SQ(1e-6) ||
1244  SQ(m4m4-1) > SQ(1e-6))
1245  mat->flags |= MAT_FLAG_GENERAL_SCALE;
1246 
1247  /* Check for rotation */
1248  if (SQ(mm4) > SQ(1e-6))
1249  mat->flags |= MAT_FLAG_GENERAL_3D;
1250  else
1251  mat->flags |= MAT_FLAG_ROTATION;
1252 
1253  }
1254  else if ((mask & MASK_3D_NO_ROT) == (GLuint) MASK_3D_NO_ROT) {
1255  mat->type = MATRIX_3D_NO_ROT;
1256 
1257  /* Check for scale */
1258  if (SQ(m[0]-m[5]) < SQ(1e-6) &&
1259  SQ(m[0]-m[10]) < SQ(1e-6)) {
1260  if (SQ(m[0]-1.0) > SQ(1e-6)) {
1261  mat->flags |= MAT_FLAG_UNIFORM_SCALE;
1262  }
1263  }
1264  else {
1265  mat->flags |= MAT_FLAG_GENERAL_SCALE;
1266  }
1267  }
1268  else if ((mask & MASK_3D) == (GLuint) MASK_3D) {
1269  GLfloat c1 = DOT3(m,m);
1270  GLfloat c2 = DOT3(m+4,m+4);
1271  GLfloat c3 = DOT3(m+8,m+8);
1272  GLfloat d1 = DOT3(m, m+4);
1273  GLfloat cp[3];
1274 
1275  mat->type = MATRIX_3D;
1276 
1277  /* Check for scale */
1278  if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) {
1279  if (SQ(c1-1.0) > SQ(1e-6))
1280  mat->flags |= MAT_FLAG_UNIFORM_SCALE;
1281  /* else no scale at all */
1282  }
1283  else {
1284  mat->flags |= MAT_FLAG_GENERAL_SCALE;
1285  }
1286 
1287  /* Check for rotation */
1288  if (SQ(d1) < SQ(1e-6)) {
1289  CROSS3( cp, m, m+4 );
1290  SUB_3V( cp, cp, (m+8) );
1291  if (LEN_SQUARED_3FV(cp) < SQ(1e-6))
1292  mat->flags |= MAT_FLAG_ROTATION;
1293  else
1294  mat->flags |= MAT_FLAG_GENERAL_3D;
1295  }
1296  else {
1297  mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */
1298  }
1299  }
1300  else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) {
1301  mat->type = MATRIX_PERSPECTIVE;
1302  mat->flags |= MAT_FLAG_GENERAL;
1303  }
1304  else {
1305  mat->type = MATRIX_GENERAL;
1306  mat->flags |= MAT_FLAG_GENERAL;
1307  }
1308 }
1309 
1315 static void analyse_from_flags( GLmatrix *mat )
1316 {
1317  const GLfloat *m = mat->m;
1318 
1319  if (TEST_MAT_FLAGS(mat, 0)) {
1320  mat->type = MATRIX_IDENTITY;
1321  }
1322  else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION |
1325  if ( m[10]==1.0F && m[14]==0.0F ) {
1326  mat->type = MATRIX_2D_NO_ROT;
1327  }
1328  else {
1329  mat->type = MATRIX_3D_NO_ROT;
1330  }
1331  }
1332  else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) {
1333  if ( m[ 8]==0.0F
1334  && m[ 9]==0.0F
1335  && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F) {
1336  mat->type = MATRIX_2D;
1337  }
1338  else {
1339  mat->type = MATRIX_3D;
1340  }
1341  }
1342  else if ( m[4]==0.0F && m[12]==0.0F
1343  && m[1]==0.0F && m[13]==0.0F
1344  && m[2]==0.0F && m[6]==0.0F
1345  && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) {
1346  mat->type = MATRIX_PERSPECTIVE;
1347  }
1348  else {
1349  mat->type = MATRIX_GENERAL;
1350  }
1351 }
1352 
1363 void
1365 {
1366  if (mat->flags & MAT_DIRTY_TYPE) {
1367  if (mat->flags & MAT_DIRTY_FLAGS)
1369  else
1370  analyse_from_flags( mat );
1371  }
1372 
1373  if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) {
1374  matrix_invert( mat );
1375  mat->flags &= ~MAT_DIRTY_INVERSE;
1376  }
1377 
1378  mat->flags &= ~(MAT_DIRTY_FLAGS | MAT_DIRTY_TYPE);
1379 }
1380 
1387 GLboolean
1389 {
1391 }
1393 
1398 GLboolean
1400 {
1401  if (m->flags & (MAT_FLAG_GENERAL |
1405  return GL_TRUE;
1406  else
1407  return GL_FALSE;
1408 }
1409 
1410 
1411 GLboolean
1413 {
1414  return (m->flags & MAT_FLAG_GENERAL_SCALE) ? GL_TRUE : GL_FALSE;
1415 }
1417 
1418 GLboolean
1419 _math_matrix_is_dirty( const GLmatrix *m )
1420 {
1421  return (m->flags & MAT_DIRTY) ? GL_TRUE : GL_FALSE;
1422 }
1424 
1425 /**********************************************************************/
1428 
1437 void
1438 _math_matrix_copy( GLmatrix *to, const GLmatrix *from )
1439 {
1440  memcpy( to->m, from->m, sizeof(Identity) );
1441  to->flags = from->flags;
1442  to->type = from->type;
1443 
1444  if (to->inv != 0) {
1445  if (from->inv == 0) {
1446  matrix_invert( to );
1447  }
1448  else {
1449  memcpy(to->inv, from->inv, sizeof(GLfloat)*16);
1450  }
1451  }
1452 }
1453 
1463 void
1464 _math_matrix_loadf( GLmatrix *mat, const GLfloat *m )
1465 {
1466  memcpy( mat->m, m, 16*sizeof(GLfloat) );
1467  mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY);
1469 
1477 void
1479 {
1480  m->m = (GLfloat *) _mesa_align_malloc( 16 * sizeof(GLfloat), 16 );
1481  if (m->m)
1482  memcpy( m->m, Identity, sizeof(Identity) );
1483  m->inv = NULL;
1484  m->type = MATRIX_IDENTITY;
1485  m->flags = 0;
1486 }
1487 
1495 void
1497 {
1498  if (m->m) {
1499  _mesa_align_free( m->m );
1500  m->m = NULL;
1501  }
1502  if (m->inv) {
1503  _mesa_align_free( m->inv );
1504  m->inv = NULL;
1505  }
1506 }
1507 
1515 void
1517 {
1518  if (!m->inv) {
1519  m->inv = (GLfloat *) _mesa_align_malloc( 16 * sizeof(GLfloat), 16 );
1520  if (m->inv)
1521  memcpy( m->inv, Identity, 16 * sizeof(GLfloat) );
1522  }
1523 }
1524 
1528 /**********************************************************************/
1531 
1538 void
1539 _math_transposef( GLfloat to[16], const GLfloat from[16] )
1540 {
1541  to[0] = from[0];
1542  to[1] = from[4];
1543  to[2] = from[8];
1544  to[3] = from[12];
1545  to[4] = from[1];
1546  to[5] = from[5];
1547  to[6] = from[9];
1548  to[7] = from[13];
1549  to[8] = from[2];
1550  to[9] = from[6];
1551  to[10] = from[10];
1552  to[11] = from[14];
1553  to[12] = from[3];
1554  to[13] = from[7];
1555  to[14] = from[11];
1556  to[15] = from[15];
1557 }
1558 
1565 void
1566 _math_transposed( GLdouble to[16], const GLdouble from[16] )
1567 {
1568  to[0] = from[0];
1569  to[1] = from[4];
1570  to[2] = from[8];
1571  to[3] = from[12];
1572  to[4] = from[1];
1573  to[5] = from[5];
1574  to[6] = from[9];
1575  to[7] = from[13];
1576  to[8] = from[2];
1577  to[9] = from[6];
1578  to[10] = from[10];
1579  to[11] = from[14];
1580  to[12] = from[3];
1581  to[13] = from[7];
1582  to[14] = from[11];
1583  to[15] = from[15];
1584 }
1585 
1592 void
1593 _math_transposefd( GLfloat to[16], const GLdouble from[16] )
1594 {
1595  to[0] = (GLfloat) from[0];
1596  to[1] = (GLfloat) from[4];
1597  to[2] = (GLfloat) from[8];
1598  to[3] = (GLfloat) from[12];
1599  to[4] = (GLfloat) from[1];
1600  to[5] = (GLfloat) from[5];
1601  to[6] = (GLfloat) from[9];
1602  to[7] = (GLfloat) from[13];
1603  to[8] = (GLfloat) from[2];
1604  to[9] = (GLfloat) from[6];
1605  to[10] = (GLfloat) from[10];
1606  to[11] = (GLfloat) from[14];
1607  to[12] = (GLfloat) from[3];
1608  to[13] = (GLfloat) from[7];
1609  to[14] = (GLfloat) from[11];
1610  to[15] = (GLfloat) from[15];
1611 }
1612 
1625 void
1626 _mesa_transform_vector( GLfloat u[4], const GLfloat v[4], const GLfloat m[16] )
1627 {
1628  const GLfloat v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
1629 #define M(row,col) m[row + col*4]
1630  u[0] = v0 * M(0,0) + v1 * M(1,0) + v2 * M(2,0) + v3 * M(3,0);
1631  u[1] = v0 * M(0,1) + v1 * M(1,1) + v2 * M(2,1) + v3 * M(3,1);
1632  u[2] = v0 * M(0,2) + v1 * M(1,2) + v2 * M(2,2) + v3 * M(3,2);
1633  u[3] = v0 * M(0,3) + v1 * M(1,3) + v2 * M(2,3) + v3 * M(3,3);
1634 #undef M
1635 }
GLint GLint GLsizei width
Definition: gl.h:1546
void _math_matrix_print(const GLmatrix *m)
Definition: m_matrix.c:295
void _math_matrix_mul_floats(GLmatrix *dest, const GLfloat *m)
Definition: m_matrix.c:257
#define MAT_FLAGS_LENGTH_PRESERVING
Definition: m_matrix.c:82
static DNS_RECORDW r3
Definition: record.c:39
double GLdouble
Definition: gl.h:163
GLboolean _math_matrix_has_rotation(const GLmatrix *m)
Definition: m_matrix.c:1403
#define MASK_PERSPECTIVE
Definition: m_matrix.c:1192
#define MAT_FLAG_GENERAL_SCALE
Definition: m_matrix.c:58
void _math_matrix_alloc_inv(GLmatrix *m)
Definition: m_matrix.c:1520
#define MAT_DIRTY
Definition: m_matrix.c:94
void _math_matrix_frustum(GLmatrix *mat, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearval, GLfloat farval)
Definition: m_matrix.c:981
void _math_transposed(GLdouble to[16], const GLdouble from[16])
Definition: m_matrix.c:1570
GLboolean _math_matrix_is_general_scale(const GLmatrix *m)
Definition: m_matrix.c:1416
static inv_mat_func inv_mat_tab[7]
Definition: m_matrix.c:740
#define GL_FALSE
Definition: gl.h:173
void _math_matrix_set_identity(GLmatrix *mat)
Definition: m_matrix.c:1139
#define B(row, col)
Definition: m_matrix.c:146
void _math_matrix_loadf(GLmatrix *mat, const GLfloat *m)
Definition: m_matrix.c:1468
GLfloat v0
Definition: glext.h:6061
#define FABSF(x)
Definition: imports.h:280
#define MAT_FLAG_TRANSLATION
Definition: m_matrix.c:56
static DNS_RECORDW r1
Definition: record.c:37
void _math_transposefd(GLfloat to[16], const GLdouble from[16])
Definition: m_matrix.c:1597
GLdouble GLdouble t
Definition: gl.h:2047
static void print_matrix_floats(const GLfloat m[16])
Definition: m_matrix.c:281
#define MAT_FLAGS_ANGLE_PRESERVING
Definition: m_matrix.c:67
void _mesa_debug(const struct gl_context *ctx, const char *fmtString,...)
Definition: imports.c:889
static const MAT2 mat
Definition: font.c:66
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble * u
Definition: glfuncs.h:88
GLfloat angle
Definition: glext.h:10853
#define MAT_SX
Definition: m_matrix.h:49
#define MASK_3D
Definition: m_matrix.c:1186
static GLboolean invert_matrix_3d_general(GLmatrix *mat)
Definition: m_matrix.c:483
#define MAT_TZ
Definition: m_matrix.h:54
enum GLmatrixtype type
Definition: m_matrix.h:81
#define MASK_NO_2D_SCALE
Definition: m_matrix.c:1163
static void matrix_multf(GLmatrix *mat, const GLfloat *m, GLuint flags)
Definition: m_matrix.c:213
#define MAT_TX
Definition: m_matrix.h:52
#define SQ(x)
Definition: m_matrix.c:1197
static GLboolean matrix_invert(GLmatrix *mat)
Definition: m_matrix.c:769
INT INT y
Definition: msvc.h:62
GLfloat * m
Definition: m_matrix.h:76
GLfloat scale
Definition: m_xform.h:122
#define MASK_NO_TRX
Definition: m_matrix.c:1162
static GLboolean invert_matrix_3d_no_rot(GLmatrix *mat)
Definition: m_matrix.c:651
static void analyse_from_scratch(GLmatrix *mat)
Definition: m_matrix.c:1206
static GLboolean invert_matrix_2d_no_rot(GLmatrix *mat)
Definition: m_matrix.c:684
GLenum GLclampf GLint i
Definition: glfuncs.h:14
GLenum GLint GLuint mask
Definition: glext.h:6028
#define MAT_SZ
Definition: m_matrix.h:51
#define MAT_FLAGS_3D
Definition: m_matrix.c:87
GLfloat * inv
Definition: m_matrix.h:77
#define a
Definition: ke_i.h:78
#define e
Definition: ke_i.h:82
unsigned char GLboolean
Definition: gl.h:151
static GLboolean invert_matrix_3d(GLmatrix *mat)
Definition: m_matrix.c:555
GLdouble GLdouble z
Definition: glext.h:5874
void _math_matrix_rotate(GLmatrix *mat, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
Definition: m_matrix.c:797
GLdouble zFar
Definition: glext.h:10465
_STLP_DECLSPEC complex< float > _STLP_CALL cos(const complex< float > &)
#define MAT_FLAG_GENERAL_3D
Definition: m_matrix.c:59
#define M(row, col)
smooth NULL
Definition: ftsmooth.c:416
#define MAT_SY
Definition: m_matrix.h:50
void _math_matrix_dtr(GLmatrix *m)
Definition: m_matrix.c:1500
GLint GLint bottom
Definition: glext.h:7726
#define TEST_MAT_FLAGS(mat, a)
Definition: m_matrix.c:110
void _mesa_transform_vector(GLfloat u[4], const GLfloat v[4], const GLfloat m[16])
Definition: m_matrix.c:1630
#define MAT_FLAG_SINGULAR
Definition: m_matrix.c:61
#define MASK_2D_NO_ROT
Definition: m_matrix.c:1170
static GLboolean invert_matrix_general(GLmatrix *mat)
Definition: m_matrix.c:355
#define b
Definition: ke_i.h:79
float GLfloat
Definition: gl.h:161
#define MAT_TY
Definition: m_matrix.h:53
static void matmul34(GLfloat *product, const GLfloat *a, const GLfloat *b)
Definition: m_matrix.c:182
GLboolean(* inv_mat_func)(GLmatrix *mat)
Definition: m_matrix.c:735
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm4
Definition: synth_sse3d.h:133
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define CROSS3(n, u, v)
Definition: macros.h:645
#define MASK_3D_NO_ROT
Definition: m_matrix.c:1181
#define d
Definition: ke_i.h:81
#define MASK_2D
Definition: m_matrix.c:1175
if(!(yy_init))
Definition: macro.lex.yy.c:717
Definition: cmds.c:130
void _math_matrix_mul_matrix(GLmatrix *dest, const GLmatrix *a, const GLmatrix *b)
Definition: m_matrix.c:234
static void matmul4(GLfloat *product, const GLfloat *a, const GLfloat *b)
Definition: m_matrix.c:162
static DNS_RECORDW r2
Definition: record.c:38
GLfloat CONST GLvector4f CONST GLfloat GLvector4f * dest
Definition: m_xform.h:122
static FILE * out
Definition: regtests2xml.c:44
int xx
Definition: npserver.c:29
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
#define A(row, col)
Definition: m_matrix.c:145
GLbitfield flags
Definition: glext.h:7161
static GLfloat Identity[16]
Definition: m_matrix.c:132
static GLboolean invert_matrix_identity(GLmatrix *mat)
Definition: m_matrix.c:635
#define MAT_FLAG_PERSPECTIVE
Definition: m_matrix.c:60
void * _mesa_align_malloc(size_t bytes, unsigned long alignment)
Definition: imports.c:82
#define MAT_FLAG_ROTATION
Definition: m_matrix.c:55
#define MAT(m, r, c)
Definition: m_matrix.c:326
GLboolean _math_matrix_is_length_preserving(const GLmatrix *m)
Definition: m_matrix.c:1392
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define DOT3(a, b)
Definition: macros.h:637
GLdouble s
Definition: gl.h:2039
GLfloat GLfloat GLfloat GLfloat v3
Definition: glext.h:6064
GLdouble GLdouble GLdouble GLdouble GLdouble zNear
Definition: glext.h:10859
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLfloat CONST GLvector4f * in
Definition: m_xform.h:122
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
#define MAT_FLAG_GENERAL
Definition: m_matrix.c:54
const GLfloat * m
Definition: glext.h:10848
GLuint flags
Definition: m_matrix.h:78
void _math_matrix_ortho(GLmatrix *mat, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat nearval, GLfloat farval)
Definition: m_matrix.c:1021
#define MASK_IDENTITY
Definition: m_matrix.c:1165
const GLdouble * v
Definition: gl.h:2040
unsigned int GLuint
Definition: gl.h:159
INT x
Definition: msvc.h:62
void _math_matrix_translate(GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z)
Definition: m_matrix.c:1097
#define GL_TRUE
Definition: gl.h:174
#define DOT2(a, b)
Definition: macros.h:634
void _math_matrix_viewport(GLmatrix *m, GLint x, GLint y, GLint width, GLint height, GLfloat zNear, GLfloat zFar, GLfloat depthMax)
Definition: m_matrix.c:1116
GLboolean _math_matrix_is_dirty(const GLmatrix *m)
Definition: m_matrix.c:1423
#define LEN_SQUARED_3FV(V)
Definition: macros.h:668
#define DEG2RAD
Definition: imports.h:96
#define MAT_FLAG_UNIFORM_SCALE
Definition: m_matrix.c:57
void _math_matrix_scale(GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z)
Definition: m_matrix.c:1067
#define SUB_3V(DST, SRCA, SRCB)
Definition: macros.h:395
POINT cp
Definition: magnifier.c:60
#define c
Definition: ke_i.h:80
#define MAT_FLAGS_GEOMETRY
Definition: m_matrix.c:72
#define MAT_DIRTY_INVERSE
Definition: m_matrix.c:64
void _math_transposef(GLfloat to[16], const GLfloat from[16])
Definition: m_matrix.c:1543
#define SWAP_ROWS(a, b)
Definition: m_matrix.c:338
void _mesa_align_free(void *ptr)
Definition: imports.c:173
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
#define SQRTF(X)
Definition: imports.h:105
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
CardRegion * from
Definition: spigame.cpp:19
void _math_matrix_copy(GLmatrix *to, const GLmatrix *from)
Definition: m_matrix.c:1442
GLfloat GLfloat v1
Definition: glext.h:6062
#define MAT_DIRTY_FLAGS
Definition: m_matrix.c:63
static void analyse_from_flags(GLmatrix *mat)
Definition: m_matrix.c:1319
void _math_matrix_ctr(GLmatrix *m)
Definition: m_matrix.c:1482
#define F(x, y, z)
Definition: md5.c:51
const GLint const GLsizei GLint
Definition: dispatch.h:5271
#define P(row, col)
Definition: m_matrix.c:147
#define MAT_DIRTY_TYPE
Definition: m_matrix.c:62
void _math_matrix_analyse(GLmatrix *mat)
Definition: m_matrix.c:1368