Blender V2.61 - r43446

math_matrix.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: some of this file.
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  */
00025 
00031 #include <assert.h>
00032 #include "BLI_math.h"
00033 
00034 /********************************* Init **************************************/
00035 
00036 void zero_m3(float m[3][3])
00037 {
00038     memset(m, 0, 3*3*sizeof(float));
00039 }
00040 
00041 void zero_m4(float m[4][4])
00042 {
00043     memset(m, 0, 4*4*sizeof(float));
00044 }
00045 
00046 void unit_m3(float m[][3])
00047 {
00048     m[0][0]= m[1][1]= m[2][2]= 1.0;
00049     m[0][1]= m[0][2]= 0.0;
00050     m[1][0]= m[1][2]= 0.0;
00051     m[2][0]= m[2][1]= 0.0;
00052 }
00053 
00054 void unit_m4(float m[][4])
00055 {
00056     m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0;
00057     m[0][1]= m[0][2]= m[0][3]= 0.0;
00058     m[1][0]= m[1][2]= m[1][3]= 0.0;
00059     m[2][0]= m[2][1]= m[2][3]= 0.0;
00060     m[3][0]= m[3][1]= m[3][2]= 0.0;
00061 }
00062 
00063 void copy_m3_m3(float m1[][3], float m2[][3]) 
00064 {   
00065     /* destination comes first: */
00066     memcpy(&m1[0], &m2[0], 9*sizeof(float));
00067 }
00068 
00069 void copy_m4_m4(float m1[][4], float m2[][4]) 
00070 {
00071     memcpy(m1, m2, 4*4*sizeof(float));
00072 }
00073 
00074 void copy_m3_m4(float m1[][3], float m2[][4])
00075 {
00076     m1[0][0]= m2[0][0];
00077     m1[0][1]= m2[0][1];
00078     m1[0][2]= m2[0][2];
00079 
00080     m1[1][0]= m2[1][0];
00081     m1[1][1]= m2[1][1];
00082     m1[1][2]= m2[1][2];
00083 
00084     m1[2][0]= m2[2][0];
00085     m1[2][1]= m2[2][1];
00086     m1[2][2]= m2[2][2];
00087 }
00088 
00089 void copy_m4_m3(float m1[][4], float m2[][3])   /* no clear */
00090 {
00091     m1[0][0]= m2[0][0];
00092     m1[0][1]= m2[0][1];
00093     m1[0][2]= m2[0][2];
00094 
00095     m1[1][0]= m2[1][0];
00096     m1[1][1]= m2[1][1];
00097     m1[1][2]= m2[1][2];
00098 
00099     m1[2][0]= m2[2][0];
00100     m1[2][1]= m2[2][1];
00101     m1[2][2]= m2[2][2];
00102 
00103     /*  Reevan's Bugfix */
00104     m1[0][3]=0.0F;
00105     m1[1][3]=0.0F;
00106     m1[2][3]=0.0F;
00107 
00108     m1[3][0]=0.0F;  
00109     m1[3][1]=0.0F;  
00110     m1[3][2]=0.0F;  
00111     m1[3][3]=1.0F;
00112 
00113 }
00114 
00115 void swap_m3m3(float m1[][3], float m2[][3])
00116 {
00117     float t;
00118     int i, j;
00119 
00120     for(i = 0; i < 3; i++) {
00121         for (j = 0; j < 3; j++) {
00122             t        = m1[i][j];
00123             m1[i][j] = m2[i][j];
00124             m2[i][j] = t;
00125         }
00126     }
00127 }
00128 
00129 void swap_m4m4(float m1[][4], float m2[][4])
00130 {
00131     float t;
00132     int i, j;
00133 
00134     for(i = 0; i < 4; i++) {
00135         for (j = 0; j < 4; j++) {
00136             t        = m1[i][j];
00137             m1[i][j] = m2[i][j];
00138             m2[i][j] = t;
00139         }
00140     }
00141 }
00142 
00143 /******************************** Arithmetic *********************************/
00144 
00145 void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4])
00146 {
00147     float m2[4][4], m3[4][4];
00148 
00149     /* copy so it works when m1 is the same pointer as m2 or m3 */
00150     copy_m4_m4(m2, m2_);
00151     copy_m4_m4(m3, m3_);
00152 
00153     /* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
00154     m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0] + m2[0][3]*m3[3][0];
00155     m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1] + m2[0][3]*m3[3][1];
00156     m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2] + m2[0][3]*m3[3][2];
00157     m1[0][3] = m2[0][0]*m3[0][3] + m2[0][1]*m3[1][3] + m2[0][2]*m3[2][3] + m2[0][3]*m3[3][3];
00158 
00159     m1[1][0] = m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0] + m2[1][3]*m3[3][0];
00160     m1[1][1] = m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1] + m2[1][3]*m3[3][1];
00161     m1[1][2] = m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2] + m2[1][3]*m3[3][2];
00162     m1[1][3] = m2[1][0]*m3[0][3] + m2[1][1]*m3[1][3] + m2[1][2]*m3[2][3] + m2[1][3]*m3[3][3];
00163 
00164     m1[2][0] = m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0] + m2[2][3]*m3[3][0];
00165     m1[2][1] = m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1] + m2[2][3]*m3[3][1];
00166     m1[2][2] = m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2] + m2[2][3]*m3[3][2];
00167     m1[2][3] = m2[2][0]*m3[0][3] + m2[2][1]*m3[1][3] + m2[2][2]*m3[2][3] + m2[2][3]*m3[3][3];
00168 
00169     m1[3][0] = m2[3][0]*m3[0][0] + m2[3][1]*m3[1][0] + m2[3][2]*m3[2][0] + m2[3][3]*m3[3][0];
00170     m1[3][1] = m2[3][0]*m3[0][1] + m2[3][1]*m3[1][1] + m2[3][2]*m3[2][1] + m2[3][3]*m3[3][1];
00171     m1[3][2] = m2[3][0]*m3[0][2] + m2[3][1]*m3[1][2] + m2[3][2]*m3[2][2] + m2[3][3]*m3[3][2];
00172     m1[3][3] = m2[3][0]*m3[0][3] + m2[3][1]*m3[1][3] + m2[3][2]*m3[2][3] + m2[3][3]*m3[3][3];
00173 
00174 }
00175 
00176 void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3])
00177 {
00178     float m2[3][3], m3[3][3];
00179 
00180     /* copy so it works when m1 is the same pointer as m2 or m3 */
00181     copy_m3_m3(m2, m2_);
00182     copy_m3_m3(m3, m3_);
00183 
00184     /* m1[i][j] = m2[i][k]*m3[k][j], args are flipped!  */
00185     m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; 
00186     m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; 
00187     m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; 
00188 
00189     m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; 
00190     m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; 
00191     m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; 
00192 
00193     m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; 
00194     m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; 
00195     m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; 
00196 }
00197 
00198 void mul_m4_m4m3(float (*m1)[4], float (*m3_)[4], float (*m2_)[3])
00199 {
00200     float m2[3][3], m3[4][4];
00201 
00202     /* copy so it works when m1 is the same pointer as m2 or m3 */
00203     copy_m3_m3(m2, m2_);
00204     copy_m4_m4(m3, m3_);
00205 
00206     m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0];
00207     m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1];
00208     m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2];
00209     m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0];
00210     m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1];
00211     m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2];
00212     m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0];
00213     m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1];
00214     m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2];
00215 }
00216 
00217 /* m1 = m2 * m3, ignore the elements on the 4th row/column of m3*/
00218 void mult_m3_m3m4(float m1[][3], float m3[][4], float m2[][3])
00219 {
00220     /* m1[i][j] = m2[i][k] * m3[k][j] */
00221     m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] +m2[0][2] * m3[2][0];
00222     m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] +m2[0][2] * m3[2][1];
00223     m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] +m2[0][2] * m3[2][2];
00224 
00225     m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] +m2[1][2] * m3[2][0];
00226     m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] +m2[1][2] * m3[2][1];
00227     m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] +m2[1][2] * m3[2][2];
00228 
00229     m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] +m2[2][2] * m3[2][0];
00230     m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] +m2[2][2] * m3[2][1];
00231     m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] +m2[2][2] * m3[2][2];
00232 }
00233 
00234 void mul_m4_m3m4(float (*m1)[4], float (*m3)[3], float (*m2)[4])
00235 {
00236     m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0];
00237     m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1];
00238     m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2];
00239     m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0];
00240     m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1];
00241     m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2];
00242     m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0];
00243     m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1];
00244     m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2];
00245 }
00246 
00247 void mul_serie_m3(float answ[][3],
00248                    float m1[][3], float m2[][3], float m3[][3],
00249                    float m4[][3], float m5[][3], float m6[][3],
00250                    float m7[][3], float m8[][3])
00251 {
00252     float temp[3][3];
00253     
00254     if(m1==NULL || m2==NULL) return;
00255     
00256     mul_m3_m3m3(answ, m2, m1);
00257     if(m3) {
00258         mul_m3_m3m3(temp, m3, answ);
00259         if(m4) {
00260             mul_m3_m3m3(answ, m4, temp);
00261             if(m5) {
00262                 mul_m3_m3m3(temp, m5, answ);
00263                 if(m6) {
00264                     mul_m3_m3m3(answ, m6, temp);
00265                     if(m7) {
00266                         mul_m3_m3m3(temp, m7, answ);
00267                         if(m8) {
00268                             mul_m3_m3m3(answ, m8, temp);
00269                         }
00270                         else copy_m3_m3(answ, temp);
00271                     }
00272                 }
00273                 else copy_m3_m3(answ, temp);
00274             }
00275         }
00276         else copy_m3_m3(answ, temp);
00277     }
00278 }
00279 
00280 void mul_serie_m4(float answ[][4], float m1[][4],
00281                 float m2[][4], float m3[][4], float m4[][4],
00282                 float m5[][4], float m6[][4], float m7[][4],
00283                 float m8[][4])
00284 {
00285     float temp[4][4];
00286     
00287     if(m1==NULL || m2==NULL) return;
00288     
00289     mult_m4_m4m4(answ, m1, m2);
00290     if(m3) {
00291         mult_m4_m4m4(temp, answ, m3);
00292         if(m4) {
00293             mult_m4_m4m4(answ, temp, m4);
00294             if(m5) {
00295                 mult_m4_m4m4(temp, answ, m5);
00296                 if(m6) {
00297                     mult_m4_m4m4(answ, temp, m6);
00298                     if(m7) {
00299                         mult_m4_m4m4(temp, answ, m7);
00300                         if(m8) {
00301                             mult_m4_m4m4(answ, temp, m8);
00302                         }
00303                         else copy_m4_m4(answ, temp);
00304                     }
00305                 }
00306                 else copy_m4_m4(answ, temp);
00307             }
00308         }
00309         else copy_m4_m4(answ, temp);
00310     }
00311 }
00312 
00313 void mul_m4_v3(float mat[][4], float vec[3])
00314 {
00315     float x,y;
00316 
00317     x=vec[0]; 
00318     y=vec[1];
00319     vec[0]=x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2] + mat[3][0];
00320     vec[1]=x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2] + mat[3][1];
00321     vec[2]=x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2];
00322 }
00323 
00324 void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3])
00325 {
00326     float x,y;
00327 
00328     x=vec[0]; 
00329     y=vec[1];
00330     in[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2] + mat[3][0];
00331     in[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2] + mat[3][1];
00332     in[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2];
00333 }
00334 
00335 /* same as mul_m4_v3() but doesnt apply translation component */
00336 void mul_mat3_m4_v3(float mat[][4], float vec[3])
00337 {
00338     float x,y;
00339 
00340     x= vec[0]; 
00341     y= vec[1];
00342     vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2];
00343     vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2];
00344     vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2];
00345 }
00346 
00347 void mul_project_m4_v3(float mat[][4], float vec[3])
00348 {
00349     const float w= vec[0]*mat[0][3] + vec[1]*mat[1][3] + vec[2]*mat[2][3] + mat[3][3];
00350     mul_m4_v3(mat, vec);
00351 
00352     vec[0] /= w;
00353     vec[1] /= w;
00354     vec[2] /= w;
00355 }
00356 
00357 void mul_v4_m4v4(float r[4], float mat[4][4], float v[4])
00358 {
00359     float x, y, z;
00360 
00361     x= v[0]; 
00362     y= v[1]; 
00363     z= v[2];
00364 
00365     r[0]= x*mat[0][0] + y*mat[1][0] + z*mat[2][0] + mat[3][0]*v[3];
00366     r[1]= x*mat[0][1] + y*mat[1][1] + z*mat[2][1] + mat[3][1]*v[3];
00367     r[2]= x*mat[0][2] + y*mat[1][2] + z*mat[2][2] + mat[3][2]*v[3];
00368     r[3]= x*mat[0][3] + y*mat[1][3] + z*mat[2][3] + mat[3][3]*v[3];
00369 }
00370 
00371 void mul_m4_v4(float mat[4][4], float r[4])
00372 {
00373     mul_v4_m4v4(r, mat, r);
00374 }
00375 
00376 void mul_v3_m3v3(float r[3], float M[3][3], float a[3])
00377 {
00378     r[0]= M[0][0]*a[0] + M[1][0]*a[1] + M[2][0]*a[2];
00379     r[1]= M[0][1]*a[0] + M[1][1]*a[1] + M[2][1]*a[2];
00380     r[2]= M[0][2]*a[0] + M[1][2]*a[1] + M[2][2]*a[2];
00381 }
00382 
00383 void mul_m3_v3(float M[3][3], float r[3])
00384 {
00385     float tmp[3];
00386 
00387     mul_v3_m3v3(tmp, M, r);
00388     copy_v3_v3(r, tmp);
00389 }
00390 
00391 void mul_transposed_m3_v3(float mat[][3], float vec[3])
00392 {
00393     float x,y;
00394 
00395     x=vec[0]; 
00396     y=vec[1];
00397     vec[0]= x*mat[0][0] + y*mat[0][1] + mat[0][2]*vec[2];
00398     vec[1]= x*mat[1][0] + y*mat[1][1] + mat[1][2]*vec[2];
00399     vec[2]= x*mat[2][0] + y*mat[2][1] + mat[2][2]*vec[2];
00400 }
00401 
00402 void mul_m3_fl(float m[3][3], float f)
00403 {
00404     int i, j;
00405 
00406     for(i=0;i<3;i++)
00407         for(j=0;j<3;j++)
00408             m[i][j] *= f;
00409 }
00410 
00411 void mul_m4_fl(float m[4][4], float f)
00412 {
00413     int i, j;
00414 
00415     for(i=0;i<4;i++)
00416         for(j=0;j<4;j++)
00417             m[i][j] *= f;
00418 }
00419 
00420 void mul_mat3_m4_fl(float m[4][4], float f)
00421 {
00422     int i, j;
00423 
00424     for(i=0; i<3; i++)
00425         for(j=0; j<3; j++)
00426             m[i][j] *= f;
00427 }
00428 
00429 void mul_m3_v3_double(float mat[][3], double vec[3])
00430 {
00431     double x,y;
00432 
00433     x=vec[0]; 
00434     y=vec[1];
00435     vec[0]= x*(double)mat[0][0] + y*(double)mat[1][0] + (double)mat[2][0]*vec[2];
00436     vec[1]= x*(double)mat[0][1] + y*(double)mat[1][1] + (double)mat[2][1]*vec[2];
00437     vec[2]= x*(double)mat[0][2] + y*(double)mat[1][2] + (double)mat[2][2]*vec[2];
00438 }
00439 
00440 void add_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
00441 {
00442     int i, j;
00443 
00444     for(i=0;i<3;i++)
00445         for(j=0;j<3;j++)
00446             m1[i][j]= m2[i][j] + m3[i][j];
00447 }
00448 
00449 void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
00450 {
00451     int i, j;
00452 
00453     for(i=0;i<4;i++)
00454         for(j=0;j<4;j++)
00455             m1[i][j]= m2[i][j] + m3[i][j];
00456 }
00457 
00458 void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3])
00459 {
00460     int i, j;
00461 
00462     for(i=0;i<3;i++)
00463         for(j=0;j<3;j++)
00464             m1[i][j]= m2[i][j] - m3[i][j];
00465 }
00466 
00467 void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
00468 {
00469     int i, j;
00470 
00471     for(i=0;i<4;i++)
00472         for(j=0;j<4;j++)
00473             m1[i][j]= m2[i][j] - m3[i][j];
00474 }
00475 
00476 int invert_m3(float m[3][3])
00477 {
00478     float tmp[3][3];
00479     int success;
00480 
00481     success= invert_m3_m3(tmp, m);
00482     copy_m3_m3(m, tmp);
00483 
00484     return success;
00485 }
00486 
00487 int invert_m3_m3(float m1[3][3], float m2[3][3])
00488 {
00489     float det;
00490     int a, b, success;
00491 
00492     /* calc adjoint */
00493     adjoint_m3_m3(m1,m2);
00494 
00495     /* then determinant old matrix! */
00496     det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1])
00497         -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1])
00498         +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]);
00499 
00500     success= (det != 0);
00501 
00502     if(det==0) det=1;
00503     det= 1/det;
00504     for(a=0;a<3;a++) {
00505         for(b=0;b<3;b++) {
00506             m1[a][b]*=det;
00507         }
00508     }
00509 
00510     return success;
00511 }
00512 
00513 int invert_m4(float m[4][4])
00514 {
00515     float tmp[4][4];
00516     int success;
00517 
00518     success= invert_m4_m4(tmp, m);
00519     copy_m4_m4(m, tmp);
00520 
00521     return success;
00522 }
00523 
00524 /*
00525  * invertmat - 
00526  *      computes the inverse of mat and puts it in inverse.  Returns 
00527  *  TRUE on success (i.e. can always find a pivot) and FALSE on failure.
00528  *  Uses Gaussian Elimination with partial (maximal column) pivoting.
00529  *
00530  *                  Mark Segal - 1992
00531  */
00532 
00533 int invert_m4_m4(float inverse[4][4], float mat[4][4])
00534 {
00535     int i, j, k;
00536     double temp;
00537     float tempmat[4][4];
00538     float max;
00539     int maxj;
00540 
00541     /* Set inverse to identity */
00542     for (i=0; i<4; i++)
00543         for (j=0; j<4; j++)
00544             inverse[i][j] = 0;
00545     for (i=0; i<4; i++)
00546         inverse[i][i] = 1;
00547 
00548     /* Copy original matrix so we don't mess it up */
00549     for(i = 0; i < 4; i++)
00550         for(j = 0; j <4; j++)
00551             tempmat[i][j] = mat[i][j];
00552 
00553     for(i = 0; i < 4; i++) {
00554         /* Look for row with max pivot */
00555         max = fabs(tempmat[i][i]);
00556         maxj = i;
00557         for(j = i + 1; j < 4; j++) {
00558             if(fabsf(tempmat[j][i]) > max) {
00559                 max = fabs(tempmat[j][i]);
00560                 maxj = j;
00561             }
00562         }
00563         /* Swap rows if necessary */
00564         if (maxj != i) {
00565             for(k = 0; k < 4; k++) {
00566                 SWAP(float, tempmat[i][k], tempmat[maxj][k]);
00567                 SWAP(float, inverse[i][k], inverse[maxj][k]);
00568             }
00569         }
00570 
00571         temp = tempmat[i][i];
00572         if (temp == 0)
00573             return 0;  /* No non-zero pivot */
00574         for(k = 0; k < 4; k++) {
00575             tempmat[i][k] = (float)(tempmat[i][k]/temp);
00576             inverse[i][k] = (float)(inverse[i][k]/temp);
00577         }
00578         for(j = 0; j < 4; j++) {
00579             if(j != i) {
00580                 temp = tempmat[j][i];
00581                 for(k = 0; k < 4; k++) {
00582                     tempmat[j][k] -= (float)(tempmat[i][k]*temp);
00583                     inverse[j][k] -= (float)(inverse[i][k]*temp);
00584                 }
00585             }
00586         }
00587     }
00588     return 1;
00589 }
00590 
00591 /****************************** Linear Algebra *******************************/
00592 
00593 void transpose_m3(float mat[][3])
00594 {
00595     float t;
00596 
00597     t = mat[0][1] ; 
00598     mat[0][1] = mat[1][0] ; 
00599     mat[1][0] = t;
00600     t = mat[0][2] ; 
00601     mat[0][2] = mat[2][0] ; 
00602     mat[2][0] = t;
00603     t = mat[1][2] ; 
00604     mat[1][2] = mat[2][1] ; 
00605     mat[2][1] = t;
00606 }
00607 
00608 void transpose_m4(float mat[][4])
00609 {
00610     float t;
00611 
00612     t = mat[0][1] ; 
00613     mat[0][1] = mat[1][0] ; 
00614     mat[1][0] = t;
00615     t = mat[0][2] ; 
00616     mat[0][2] = mat[2][0] ; 
00617     mat[2][0] = t;
00618     t = mat[0][3] ; 
00619     mat[0][3] = mat[3][0] ; 
00620     mat[3][0] = t;
00621 
00622     t = mat[1][2] ; 
00623     mat[1][2] = mat[2][1] ; 
00624     mat[2][1] = t;
00625     t = mat[1][3] ; 
00626     mat[1][3] = mat[3][1] ; 
00627     mat[3][1] = t;
00628 
00629     t = mat[2][3] ; 
00630     mat[2][3] = mat[3][2] ; 
00631     mat[3][2] = t;
00632 }
00633 
00634 void orthogonalize_m3(float mat[][3], int axis)
00635 {
00636     float size[3];
00637     mat3_to_size(size, mat);
00638     normalize_v3(mat[axis]);
00639     switch(axis)
00640     {
00641         case 0:
00642             if (dot_v3v3(mat[0], mat[1]) < 1) {
00643                 cross_v3_v3v3(mat[2], mat[0], mat[1]);
00644                 normalize_v3(mat[2]);
00645                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00646             } else if (dot_v3v3(mat[0], mat[2]) < 1) {
00647                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00648                 normalize_v3(mat[1]);
00649                 cross_v3_v3v3(mat[2], mat[0], mat[1]);
00650             } else {
00651                 float vec[3];
00652 
00653                 vec[0]= mat[0][1];
00654                 vec[1]= mat[0][2];
00655                 vec[2]= mat[0][0];
00656 
00657                 cross_v3_v3v3(mat[2], mat[0], vec);
00658                 normalize_v3(mat[2]);
00659                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00660             }
00661         case 1:
00662             if (dot_v3v3(mat[1], mat[0]) < 1) {
00663                 cross_v3_v3v3(mat[2], mat[0], mat[1]);
00664                 normalize_v3(mat[2]);
00665                 cross_v3_v3v3(mat[0], mat[1], mat[2]);
00666             } else if (dot_v3v3(mat[0], mat[2]) < 1) {
00667                 cross_v3_v3v3(mat[0], mat[1], mat[2]);
00668                 normalize_v3(mat[0]);
00669                 cross_v3_v3v3(mat[2], mat[0], mat[1]);
00670             } else {
00671                 float vec[3];
00672 
00673                 vec[0]= mat[1][1];
00674                 vec[1]= mat[1][2];
00675                 vec[2]= mat[1][0];
00676 
00677                 cross_v3_v3v3(mat[0], mat[1], vec);
00678                 normalize_v3(mat[0]);
00679                 cross_v3_v3v3(mat[2], mat[0], mat[1]);
00680             }
00681         case 2:
00682             if (dot_v3v3(mat[2], mat[0]) < 1) {
00683                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00684                 normalize_v3(mat[1]);
00685                 cross_v3_v3v3(mat[0], mat[1], mat[2]);
00686             } else if (dot_v3v3(mat[2], mat[1]) < 1) {
00687                 cross_v3_v3v3(mat[0], mat[1], mat[2]);
00688                 normalize_v3(mat[0]);
00689                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00690             } else {
00691                 float vec[3];
00692 
00693                 vec[0]= mat[2][1];
00694                 vec[1]= mat[2][2];
00695                 vec[2]= mat[2][0];
00696 
00697                 cross_v3_v3v3(mat[0], vec, mat[2]);
00698                 normalize_v3(mat[0]);
00699                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00700             }
00701     }
00702     mul_v3_fl(mat[0], size[0]);
00703     mul_v3_fl(mat[1], size[1]);
00704     mul_v3_fl(mat[2], size[2]);
00705 }
00706 
00707 void orthogonalize_m4(float mat[][4], int axis)
00708 {
00709     float size[3];
00710     mat4_to_size(size, mat);
00711     normalize_v3(mat[axis]);
00712     switch(axis)
00713     {
00714         case 0:
00715             if (dot_v3v3(mat[0], mat[1]) < 1) {
00716                 cross_v3_v3v3(mat[2], mat[0], mat[1]);
00717                 normalize_v3(mat[2]);
00718                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00719             } else if (dot_v3v3(mat[0], mat[2]) < 1) {
00720                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00721                 normalize_v3(mat[1]);
00722                 cross_v3_v3v3(mat[2], mat[0], mat[1]);
00723             } else {
00724                 float vec[3];
00725 
00726                 vec[0]= mat[0][1];
00727                 vec[1]= mat[0][2];
00728                 vec[2]= mat[0][0];
00729 
00730                 cross_v3_v3v3(mat[2], mat[0], vec);
00731                 normalize_v3(mat[2]);
00732                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00733             }
00734         case 1:
00735             normalize_v3(mat[0]);
00736             if (dot_v3v3(mat[1], mat[0]) < 1) {
00737                 cross_v3_v3v3(mat[2], mat[0], mat[1]);
00738                 normalize_v3(mat[2]);
00739                 cross_v3_v3v3(mat[0], mat[1], mat[2]);
00740             } else if (dot_v3v3(mat[0], mat[2]) < 1) {
00741                 cross_v3_v3v3(mat[0], mat[1], mat[2]);
00742                 normalize_v3(mat[0]);
00743                 cross_v3_v3v3(mat[2], mat[0], mat[1]);
00744             } else {
00745                 float vec[3];
00746 
00747                 vec[0]= mat[1][1];
00748                 vec[1]= mat[1][2];
00749                 vec[2]= mat[1][0];
00750 
00751                 cross_v3_v3v3(mat[0], mat[1], vec);
00752                 normalize_v3(mat[0]);
00753                 cross_v3_v3v3(mat[2], mat[0], mat[1]);
00754             }
00755         case 2:
00756             if (dot_v3v3(mat[2], mat[0]) < 1) {
00757                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00758                 normalize_v3(mat[1]);
00759                 cross_v3_v3v3(mat[0], mat[1], mat[2]);
00760             } else if (dot_v3v3(mat[2], mat[1]) < 1) {
00761                 cross_v3_v3v3(mat[0], mat[1], mat[2]);
00762                 normalize_v3(mat[0]);
00763                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00764             } else {
00765                 float vec[3];
00766 
00767                 vec[0]= mat[2][1];
00768                 vec[1]= mat[2][2];
00769                 vec[2]= mat[2][0];
00770 
00771                 cross_v3_v3v3(mat[0], vec, mat[2]);
00772                 normalize_v3(mat[0]);
00773                 cross_v3_v3v3(mat[1], mat[2], mat[0]);
00774             }
00775     }
00776     mul_v3_fl(mat[0], size[0]);
00777     mul_v3_fl(mat[1], size[1]);
00778     mul_v3_fl(mat[2], size[2]);
00779 }
00780 
00781 int is_orthogonal_m3(float mat[][3])
00782 {
00783     if (fabsf(dot_v3v3(mat[0], mat[1])) > 1.5f * FLT_EPSILON)
00784         return 0;
00785 
00786     if (fabsf(dot_v3v3(mat[1], mat[2])) > 1.5f * FLT_EPSILON)
00787         return 0;
00788 
00789     if (fabsf(dot_v3v3(mat[0], mat[2])) > 1.5f * FLT_EPSILON)
00790         return 0;
00791     
00792     return 1;
00793 }
00794 
00795 int is_orthogonal_m4(float mat[][4])
00796 {
00797     if (fabsf(dot_v3v3(mat[0], mat[1])) > 1.5f * FLT_EPSILON)
00798         return 0;
00799 
00800     if (fabsf(dot_v3v3(mat[1], mat[2])) > 1.5f * FLT_EPSILON)
00801         return 0;
00802 
00803     if (fabsf(dot_v3v3(mat[0], mat[2])) > 1.5f * FLT_EPSILON)
00804         return 0;
00805     
00806     return 1;
00807 }
00808 
00809 void normalize_m3(float mat[][3])
00810 {   
00811     normalize_v3(mat[0]);
00812     normalize_v3(mat[1]);
00813     normalize_v3(mat[2]);
00814 }
00815 
00816 void normalize_m3_m3(float rmat[][3], float mat[][3])
00817 {   
00818     normalize_v3_v3(rmat[0], mat[0]);
00819     normalize_v3_v3(rmat[1], mat[1]);
00820     normalize_v3_v3(rmat[2], mat[2]);
00821 }
00822 
00823 
00824 void normalize_m4(float mat[][4])
00825 {
00826     float len;
00827     
00828     len= normalize_v3(mat[0]);
00829     if(len!=0.0f) mat[0][3]/= len;
00830     len= normalize_v3(mat[1]);
00831     if(len!=0.0f) mat[1][3]/= len;
00832     len= normalize_v3(mat[2]);
00833     if(len!=0.0f) mat[2][3]/= len;
00834 }
00835 
00836 void normalize_m4_m4(float rmat[][4], float mat[][4])
00837 {
00838     float len;
00839     
00840     len= normalize_v3_v3(rmat[0], mat[0]);
00841     if(len!=0.0f) rmat[0][3]= mat[0][3] / len;
00842     len= normalize_v3_v3(rmat[1], mat[1]);
00843     if(len!=0.0f) rmat[1][3]= mat[1][3] / len;
00844     len= normalize_v3_v3(rmat[2], mat[2]);
00845     if(len!=0.0f) rmat[2][3]= mat[2][3] / len;
00846 }
00847 
00848 void adjoint_m3_m3(float m1[][3], float m[][3])
00849 {
00850     m1[0][0]=m[1][1]*m[2][2]-m[1][2]*m[2][1];
00851     m1[0][1]= -m[0][1]*m[2][2]+m[0][2]*m[2][1];
00852     m1[0][2]=m[0][1]*m[1][2]-m[0][2]*m[1][1];
00853 
00854     m1[1][0]= -m[1][0]*m[2][2]+m[1][2]*m[2][0];
00855     m1[1][1]=m[0][0]*m[2][2]-m[0][2]*m[2][0];
00856     m1[1][2]= -m[0][0]*m[1][2]+m[0][2]*m[1][0];
00857 
00858     m1[2][0]=m[1][0]*m[2][1]-m[1][1]*m[2][0];
00859     m1[2][1]= -m[0][0]*m[2][1]+m[0][1]*m[2][0];
00860     m1[2][2]=m[0][0]*m[1][1]-m[0][1]*m[1][0];
00861 }
00862 
00863 void adjoint_m4_m4(float out[][4], float in[][4])   /* out = ADJ(in) */
00864 {
00865     float a1, a2, a3, a4, b1, b2, b3, b4;
00866     float c1, c2, c3, c4, d1, d2, d3, d4;
00867 
00868     a1= in[0][0]; 
00869     b1= in[0][1];
00870     c1= in[0][2]; 
00871     d1= in[0][3];
00872 
00873     a2= in[1][0]; 
00874     b2= in[1][1];
00875     c2= in[1][2]; 
00876     d2= in[1][3];
00877 
00878     a3= in[2][0]; 
00879     b3= in[2][1];
00880     c3= in[2][2]; 
00881     d3= in[2][3];
00882 
00883     a4= in[3][0]; 
00884     b4= in[3][1];
00885     c4= in[3][2]; 
00886     d4= in[3][3];
00887 
00888 
00889     out[0][0]  =   determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
00890     out[1][0]  = - determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
00891     out[2][0]  =   determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
00892     out[3][0]  = - determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
00893 
00894     out[0][1]  = - determinant_m3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
00895     out[1][1]  =   determinant_m3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
00896     out[2][1]  = - determinant_m3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
00897     out[3][1]  =   determinant_m3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
00898 
00899     out[0][2]  =   determinant_m3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
00900     out[1][2]  = - determinant_m3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
00901     out[2][2]  =   determinant_m3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
00902     out[3][2]  = - determinant_m3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
00903 
00904     out[0][3]  = - determinant_m3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
00905     out[1][3]  =   determinant_m3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
00906     out[2][3]  = - determinant_m3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
00907     out[3][3]  =   determinant_m3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
00908 }
00909 
00910 float determinant_m2(float a,float b,float c,float d)
00911 {
00912 
00913     return a*d - b*c;
00914 }
00915 
00916 float determinant_m3(float a1, float a2, float a3,
00917              float b1, float b2, float b3,
00918              float c1, float c2, float c3)
00919 {
00920     float ans;
00921 
00922     ans = a1 * determinant_m2(b2, b3, c2, c3)
00923         - b1 * determinant_m2(a2, a3, c2, c3)
00924         + c1 * determinant_m2(a2, a3, b2, b3);
00925 
00926     return ans;
00927 }
00928 
00929 float determinant_m4(float m[][4])
00930 {
00931     float ans;
00932     float a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4;
00933 
00934     a1= m[0][0]; 
00935     b1= m[0][1];
00936     c1= m[0][2]; 
00937     d1= m[0][3];
00938 
00939     a2= m[1][0]; 
00940     b2= m[1][1];
00941     c2= m[1][2]; 
00942     d2= m[1][3];
00943 
00944     a3= m[2][0]; 
00945     b3= m[2][1];
00946     c3= m[2][2]; 
00947     d3= m[2][3];
00948 
00949     a4= m[3][0]; 
00950     b4= m[3][1];
00951     c4= m[3][2]; 
00952     d4= m[3][3];
00953 
00954     ans = a1 * determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4)
00955         - b1 * determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4)
00956         + c1 * determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4)
00957         - d1 * determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
00958 
00959     return ans;
00960 }
00961 
00962 /****************************** Transformations ******************************/
00963 
00964 void size_to_mat3(float mat[][3], const float size[3])
00965 {
00966     mat[0][0]= size[0];
00967     mat[0][1]= 0.0f;
00968     mat[0][2]= 0.0f;
00969     mat[1][1]= size[1];
00970     mat[1][0]= 0.0f;
00971     mat[1][2]= 0.0f;
00972     mat[2][2]= size[2];
00973     mat[2][1]= 0.0f;
00974     mat[2][0]= 0.0f;
00975 }
00976 
00977 void size_to_mat4(float mat[][4], const float size[3])
00978 {
00979     float tmat[3][3];
00980     
00981     size_to_mat3(tmat,size);
00982     unit_m4(mat);
00983     copy_m4_m3(mat, tmat);
00984 }
00985 
00986 void mat3_to_size(float size[3], float mat[][3])
00987 {
00988     size[0]= len_v3(mat[0]);
00989     size[1]= len_v3(mat[1]);
00990     size[2]= len_v3(mat[2]);
00991 }
00992 
00993 void mat4_to_size(float size[3], float mat[][4])
00994 {
00995     size[0]= len_v3(mat[0]);
00996     size[1]= len_v3(mat[1]);
00997     size[2]= len_v3(mat[2]);
00998 }
00999 
01000 /* this gets the average scale of a matrix, only use when your scaling
01001  * data that has no idea of scale axis, examples are bone-envelope-radius
01002  * and curve radius */
01003 float mat3_to_scale(float mat[][3])
01004 {
01005     /* unit length vector */
01006     float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f};
01007     mul_m3_v3(mat, unit_vec);
01008     return len_v3(unit_vec);
01009 }
01010 
01011 float mat4_to_scale(float mat[][4])
01012 {
01013     float tmat[3][3];
01014     copy_m3_m4(tmat, mat);
01015     return mat3_to_scale(tmat);
01016 }
01017 
01018 
01019 void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
01020 {
01021     float mat3_n[3][3];  /* mat3 -> normalized, 3x3 */
01022     float imat3_n[3][3]; /* mat3 -> normalized & inverted, 3x3 */
01023 
01024     /* rotation & scale are linked, we need to create the mat's
01025      * for these together since they are related. */
01026 
01027     /* so scale doesnt interfear with rotation [#24291] */
01028     /* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */
01029     normalize_m3_m3(mat3_n, mat3);
01030     if(is_negative_m3(mat3)) {
01031         negate_v3(mat3_n[0]);
01032         negate_v3(mat3_n[1]);
01033         negate_v3(mat3_n[2]);
01034     }
01035 
01036     /* rotation */
01037     /* keep rot as a 3x3 matrix, the caller can convert into a quat or euler */
01038     copy_m3_m3(rot, mat3_n);
01039 
01040     /* scale */
01041     /* note: mat4_to_size(ob->size, mat) fails for negative scale */
01042     invert_m3_m3(imat3_n, mat3_n);
01043     mul_m3_m3m3(mat3, imat3_n, mat3);
01044 
01045     size[0]= mat3[0][0];
01046     size[1]= mat3[1][1];
01047     size[2]= mat3[2][2];
01048 }
01049 
01050 void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4])
01051 {
01052     float mat3[3][3];    /* wmat -> 3x3 */
01053 
01054     copy_m3_m4(mat3, wmat);
01055     mat3_to_rot_size(rot, size, mat3);
01056 
01057     /* location */
01058     copy_v3_v3(loc, wmat[3]);
01059 }
01060 
01061 void scale_m3_fl(float m[][3], float scale)
01062 {
01063     m[0][0]= m[1][1]= m[2][2]= scale;
01064     m[0][1]= m[0][2]= 0.0;
01065     m[1][0]= m[1][2]= 0.0;
01066     m[2][0]= m[2][1]= 0.0;
01067 }
01068 
01069 void scale_m4_fl(float m[][4], float scale)
01070 {
01071     m[0][0]= m[1][1]= m[2][2]= scale;
01072     m[3][3]= 1.0;
01073     m[0][1]= m[0][2]= m[0][3]= 0.0;
01074     m[1][0]= m[1][2]= m[1][3]= 0.0;
01075     m[2][0]= m[2][1]= m[2][3]= 0.0;
01076     m[3][0]= m[3][1]= m[3][2]= 0.0;
01077 }
01078 
01079 void translate_m4(float mat[][4],float Tx, float Ty, float Tz)
01080 {
01081     mat[3][0] += (Tx*mat[0][0] + Ty*mat[1][0] + Tz*mat[2][0]);
01082     mat[3][1] += (Tx*mat[0][1] + Ty*mat[1][1] + Tz*mat[2][1]);
01083     mat[3][2] += (Tx*mat[0][2] + Ty*mat[1][2] + Tz*mat[2][2]);
01084 }
01085 
01086 void rotate_m4(float mat[][4], const char axis, const float angle)
01087 {
01088     int col;
01089     float temp[4]= {0.0f, 0.0f, 0.0f, 0.0f};
01090     float cosine, sine;
01091 
01092     assert(axis >= 'X' && axis <= 'Z');
01093 
01094     cosine = (float)cos(angle);
01095     sine = (float)sin(angle);
01096     switch(axis){
01097     case 'X':    
01098         for(col=0 ; col<4 ; col++)
01099             temp[col] = cosine*mat[1][col] + sine*mat[2][col];
01100         for(col=0 ; col<4 ; col++) {
01101         mat[2][col] = - sine*mat[1][col] + cosine*mat[2][col];
01102             mat[1][col] = temp[col];
01103     }
01104         break;
01105 
01106     case 'Y':
01107         for(col=0 ; col<4 ; col++)
01108             temp[col] = cosine*mat[0][col] - sine*mat[2][col];
01109         for(col=0 ; col<4 ; col++) {
01110             mat[2][col] = sine*mat[0][col] + cosine*mat[2][col];
01111             mat[0][col] = temp[col];
01112         }
01113     break;
01114 
01115     case 'Z':
01116         for(col=0 ; col<4 ; col++)
01117             temp[col] = cosine*mat[0][col] + sine*mat[1][col];
01118         for(col=0 ; col<4 ; col++) {
01119             mat[1][col] = - sine*mat[0][col] + cosine*mat[1][col];
01120             mat[0][col] = temp[col];
01121         }
01122     break;
01123     }
01124 }
01125 
01126 void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float srcweight)
01127 {
01128     float srot[3][3], drot[3][3];
01129     float squat[4], dquat[4], fquat[4];
01130     float sscale[3], dscale[3], fsize[3];
01131     float rmat[3][3], smat[3][3];
01132     
01133     mat3_to_rot_size(drot, dscale, dst);
01134     mat3_to_rot_size(srot, sscale, src);
01135 
01136     mat3_to_quat(dquat, drot);
01137     mat3_to_quat(squat, srot);
01138 
01139     /* do blending */
01140     interp_qt_qtqt(fquat, dquat, squat, srcweight);
01141     interp_v3_v3v3(fsize, dscale, sscale, srcweight);
01142 
01143     /* compose new matrix */
01144     quat_to_mat3(rmat,fquat);
01145     size_to_mat3(smat,fsize);
01146     mul_m3_m3m3(out, rmat, smat);
01147 }
01148 
01149 void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float srcweight)
01150 {
01151     float sloc[3], dloc[3], floc[3];
01152     float srot[3][3], drot[3][3];
01153     float squat[4], dquat[4], fquat[4];
01154     float sscale[3], dscale[3], fsize[3];
01155 
01156     mat4_to_loc_rot_size(dloc, drot, dscale, dst);
01157     mat4_to_loc_rot_size(sloc, srot, sscale, src);
01158 
01159     mat3_to_quat(dquat, drot);
01160     mat3_to_quat(squat, srot);
01161 
01162     /* do blending */
01163     interp_v3_v3v3(floc, dloc, sloc, srcweight);
01164     interp_qt_qtqt(fquat, dquat, squat, srcweight);
01165     interp_v3_v3v3(fsize, dscale, sscale, srcweight);
01166 
01167     /* compose new matrix */
01168     loc_quat_size_to_mat4(out, floc, fquat, fsize);
01169 }
01170 
01171 
01172 int is_negative_m3(float mat[][3])
01173 {
01174     float vec[3];
01175     cross_v3_v3v3(vec, mat[0], mat[1]);
01176     return (dot_v3v3(vec, mat[2]) < 0.0f);
01177 }
01178 
01179 int is_negative_m4(float mat[][4])
01180 {
01181     float vec[3];
01182     cross_v3_v3v3(vec, mat[0], mat[1]);
01183     return (dot_v3v3(vec, mat[2]) < 0.0f);
01184 }
01185 
01186 /* make a 4x4 matrix out of 3 transform components */
01187 /* matrices are made in the order: scale * rot * loc */
01188 // TODO: need to have a version that allows for rotation order...
01189 void loc_eul_size_to_mat4(float mat[4][4], const float loc[3], const float eul[3], const float size[3])
01190 {
01191     float rmat[3][3], smat[3][3], tmat[3][3];
01192     
01193     /* initialise new matrix */
01194     unit_m4(mat);
01195     
01196     /* make rotation + scaling part */
01197     eul_to_mat3(rmat,eul);
01198     size_to_mat3(smat,size);
01199     mul_m3_m3m3(tmat, rmat, smat);
01200     
01201     /* copy rot/scale part to output matrix*/
01202     copy_m4_m3(mat, tmat);
01203     
01204     /* copy location to matrix */
01205     mat[3][0] = loc[0];
01206     mat[3][1] = loc[1];
01207     mat[3][2] = loc[2];
01208 }
01209 
01210 /* make a 4x4 matrix out of 3 transform components */
01211 /* matrices are made in the order: scale * rot * loc */
01212 void loc_eulO_size_to_mat4(float mat[4][4], const float loc[3], const float eul[3], const float size[3], const short rotOrder)
01213 {
01214     float rmat[3][3], smat[3][3], tmat[3][3];
01215     
01216     /* initialise new matrix */
01217     unit_m4(mat);
01218     
01219     /* make rotation + scaling part */
01220     eulO_to_mat3(rmat,eul, rotOrder);
01221     size_to_mat3(smat,size);
01222     mul_m3_m3m3(tmat, rmat, smat);
01223     
01224     /* copy rot/scale part to output matrix*/
01225     copy_m4_m3(mat, tmat);
01226     
01227     /* copy location to matrix */
01228     mat[3][0] = loc[0];
01229     mat[3][1] = loc[1];
01230     mat[3][2] = loc[2];
01231 }
01232 
01233 
01234 /* make a 4x4 matrix out of 3 transform components */
01235 /* matrices are made in the order: scale * rot * loc */
01236 void loc_quat_size_to_mat4(float mat[4][4], const float loc[3], const float quat[4], const float size[3])
01237 {
01238     float rmat[3][3], smat[3][3], tmat[3][3];
01239     
01240     /* initialise new matrix */
01241     unit_m4(mat);
01242     
01243     /* make rotation + scaling part */
01244     quat_to_mat3(rmat,quat);
01245     size_to_mat3(smat,size);
01246     mul_m3_m3m3(tmat, rmat, smat);
01247     
01248     /* copy rot/scale part to output matrix*/
01249     copy_m4_m3(mat, tmat);
01250     
01251     /* copy location to matrix */
01252     mat[3][0] = loc[0];
01253     mat[3][1] = loc[1];
01254     mat[3][2] = loc[2];
01255 }
01256 
01257 void loc_axisangle_size_to_mat4(float mat[4][4], const float loc[3], const float axis[3], const float angle, const float size[3])
01258 {
01259     float q[4];
01260     axis_angle_to_quat(q, axis, angle);
01261     loc_quat_size_to_mat4(mat, loc, q, size);
01262 }
01263 
01264 /*********************************** Other ***********************************/
01265 
01266 void print_m3(const char *str, float m[][3])
01267 {
01268     printf("%s\n", str);
01269     printf("%f %f %f\n",m[0][0],m[1][0],m[2][0]);
01270     printf("%f %f %f\n",m[0][1],m[1][1],m[2][1]);
01271     printf("%f %f %f\n",m[0][2],m[1][2],m[2][2]);
01272     printf("\n");
01273 }
01274 
01275 void print_m4(const char *str, float m[][4])
01276 {
01277     printf("%s\n", str);
01278     printf("%f %f %f %f\n",m[0][0],m[1][0],m[2][0],m[3][0]);
01279     printf("%f %f %f %f\n",m[0][1],m[1][1],m[2][1],m[3][1]);
01280     printf("%f %f %f %f\n",m[0][2],m[1][2],m[2][2],m[3][2]);
01281     printf("%f %f %f %f\n",m[0][3],m[1][3],m[2][3],m[3][3]);
01282     printf("\n");
01283 }
01284 
01285 /*********************************** SVD ************************************
01286  * from TNT matrix library
01287 
01288  * Compute the Single Value Decomposition of an arbitrary matrix A
01289  * That is compute the 3 matrices U,W,V with U column orthogonal (m,n) 
01290  * ,W a diagonal matrix and V an orthogonal square matrix s.t. 
01291  * A = U.W.Vt. From this decomposition it is trivial to compute the 
01292  * (pseudo-inverse) of A as Ainv = V.Winv.tranpose(U).
01293  */
01294 
01295 void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4])
01296 {
01297     float A[4][4];
01298     float work1[4], work2[4];
01299     int m = 4;
01300     int n = 4;
01301     int maxiter = 200;
01302     int nu = minf(m,n);
01303 
01304     float *work = work1;
01305     float *e = work2;
01306     float eps;
01307 
01308     int i=0, j=0, k=0, p, pp, iter;
01309 
01310     // Reduce A to bidiagonal form, storing the diagonal elements
01311     // in s and the super-diagonal elements in e.
01312 
01313     int nct = minf(m-1,n);
01314     int nrt = maxf(0,minf(n-2,m));
01315 
01316     copy_m4_m4(A, A_);
01317     zero_m4(U);
01318     zero_v4(s);
01319 
01320     for (k = 0; k < maxf(nct,nrt); k++) {
01321         if (k < nct) {
01322 
01323             // Compute the transformation for the k-th column and
01324             // place the k-th diagonal in s[k].
01325             // Compute 2-norm of k-th column without under/overflow.
01326             s[k] = 0;
01327             for (i = k; i < m; i++) {
01328                 s[k] = hypotf(s[k],A[i][k]);
01329             }
01330             if (s[k] != 0.0f) {
01331                 float invsk;
01332                 if (A[k][k] < 0.0f) {
01333                     s[k] = -s[k];
01334                 }
01335                 invsk = 1.0f/s[k];
01336                 for (i = k; i < m; i++) {
01337                     A[i][k] *= invsk;
01338                 }
01339                 A[k][k] += 1.0f;
01340             }
01341             s[k] = -s[k];
01342         }
01343         for (j = k+1; j < n; j++) {
01344             if ((k < nct) && (s[k] != 0.0f))  {
01345 
01346             // Apply the transformation.
01347 
01348                 float t = 0;
01349                 for (i = k; i < m; i++) {
01350                     t += A[i][k]*A[i][j];
01351                 }
01352                 t = -t/A[k][k];
01353                 for (i = k; i < m; i++) {
01354                     A[i][j] += t*A[i][k];
01355                 }
01356             }
01357 
01358             // Place the k-th row of A into e for the
01359             // subsequent calculation of the row transformation.
01360 
01361             e[j] = A[k][j];
01362         }
01363         if (k < nct) {
01364 
01365             // Place the transformation in U for subsequent back
01366             // multiplication.
01367 
01368             for (i = k; i < m; i++)
01369                 U[i][k] = A[i][k];
01370         }
01371         if (k < nrt) {
01372 
01373             // Compute the k-th row transformation and place the
01374             // k-th super-diagonal in e[k].
01375             // Compute 2-norm without under/overflow.
01376             e[k] = 0;
01377             for (i = k+1; i < n; i++) {
01378                 e[k] = hypotf(e[k],e[i]);
01379             }
01380             if (e[k] != 0.0f) {
01381                 float invek;
01382                 if (e[k+1] < 0.0f) {
01383                     e[k] = -e[k];
01384                 }
01385                 invek = 1.0f/e[k];
01386                 for (i = k+1; i < n; i++) {
01387                     e[i] *= invek;
01388                 }
01389                 e[k+1] += 1.0f;
01390             }
01391             e[k] = -e[k];
01392             if ((k+1 < m) & (e[k] != 0.0f)) {
01393                 float invek1;
01394 
01395             // Apply the transformation.
01396 
01397                 for (i = k+1; i < m; i++) {
01398                     work[i] = 0.0f;
01399                 }
01400                 for (j = k+1; j < n; j++) {
01401                     for (i = k+1; i < m; i++) {
01402                         work[i] += e[j]*A[i][j];
01403                     }
01404                 }
01405                 invek1 = 1.0f/e[k+1];
01406                 for (j = k+1; j < n; j++) {
01407                     float t = -e[j]*invek1;
01408                     for (i = k+1; i < m; i++) {
01409                         A[i][j] += t*work[i];
01410                     }
01411                 }
01412             }
01413 
01414             // Place the transformation in V for subsequent
01415             // back multiplication.
01416 
01417             for (i = k+1; i < n; i++)
01418                 V[i][k] = e[i];
01419         }
01420     }
01421 
01422     // Set up the final bidiagonal matrix or order p.
01423 
01424     p = minf(n,m+1);
01425     if (nct < n) {
01426         s[nct] = A[nct][nct];
01427     }
01428     if (m < p) {
01429         s[p-1] = 0.0f;
01430     }
01431     if (nrt+1 < p) {
01432         e[nrt] = A[nrt][p-1];
01433     }
01434     e[p-1] = 0.0f;
01435 
01436     // If required, generate U.
01437 
01438     for (j = nct; j < nu; j++) {
01439         for (i = 0; i < m; i++) {
01440             U[i][j] = 0.0f;
01441         }
01442         U[j][j] = 1.0f;
01443     }
01444     for (k = nct-1; k >= 0; k--) {
01445         if (s[k] != 0.0f) {
01446             for (j = k+1; j < nu; j++) {
01447                 float t = 0;
01448                 for (i = k; i < m; i++) {
01449                     t += U[i][k]*U[i][j];
01450                 }
01451                 t = -t/U[k][k];
01452                 for (i = k; i < m; i++) {
01453                     U[i][j] += t*U[i][k];
01454                 }
01455             }
01456             for (i = k; i < m; i++ ) {
01457                 U[i][k] = -U[i][k];
01458             }
01459             U[k][k] = 1.0f + U[k][k];
01460             for (i = 0; i < k-1; i++) {
01461                 U[i][k] = 0.0f;
01462             }
01463         } else {
01464             for (i = 0; i < m; i++) {
01465                 U[i][k] = 0.0f;
01466             }
01467             U[k][k] = 1.0f;
01468         }
01469     }
01470 
01471     // If required, generate V.
01472 
01473     for (k = n-1; k >= 0; k--) {
01474         if ((k < nrt) & (e[k] != 0.0f)) {
01475             for (j = k+1; j < nu; j++) {
01476                 float t = 0;
01477                 for (i = k+1; i < n; i++) {
01478                     t += V[i][k]*V[i][j];
01479                 }
01480                 t = -t/V[k+1][k];
01481                 for (i = k+1; i < n; i++) {
01482                     V[i][j] += t*V[i][k];
01483                 }
01484             }
01485         }
01486         for (i = 0; i < n; i++) {
01487             V[i][k] = 0.0f;
01488         }
01489         V[k][k] = 1.0f;
01490     }
01491 
01492     // Main iteration loop for the singular values.
01493 
01494     pp = p-1;
01495     iter = 0;
01496     eps = powf(2.0f,-52.0f);
01497     while (p > 0) {
01498         int kase=0;
01499 
01500         // Test for maximum iterations to avoid infinite loop
01501         if(maxiter == 0)
01502             break;
01503         maxiter--;
01504 
01505         // This section of the program inspects for
01506         // negligible elements in the s and e arrays.  On
01507         // completion the variables kase and k are set as follows.
01508 
01509         // kase = 1   if s(p) and e[k-1] are negligible and k<p
01510         // kase = 2   if s(k) is negligible and k<p
01511         // kase = 3   if e[k-1] is negligible, k<p, and
01512         //                s(k), ..., s(p) are not negligible (qr step).
01513         // kase = 4   if e(p-1) is negligible (convergence).
01514 
01515         for (k = p-2; k >= -1; k--) {
01516             if (k == -1) {
01517                 break;
01518             }
01519             if (fabsf(e[k]) <= eps*(fabsf(s[k]) + fabsf(s[k+1]))) {
01520                 e[k] = 0.0f;
01521                 break;
01522             }
01523         }
01524         if (k == p-2) {
01525             kase = 4;
01526         } else {
01527             int ks;
01528             for (ks = p-1; ks >= k; ks--) {
01529                 float t;
01530                 if (ks == k) {
01531                     break;
01532                 }
01533                 t = (ks != p ? fabsf(e[ks]) : 0.f) + 
01534                               (ks != k+1 ? fabsf(e[ks-1]) : 0.0f);
01535                 if (fabsf(s[ks]) <= eps*t)  {
01536                     s[ks] = 0.0f;
01537                     break;
01538                 }
01539             }
01540             if (ks == k) {
01541                 kase = 3;
01542             } else if (ks == p-1) {
01543                 kase = 1;
01544             } else {
01545                 kase = 2;
01546                 k = ks;
01547             }
01548         }
01549         k++;
01550 
01551         // Perform the task indicated by kase.
01552 
01553         switch (kase) {
01554 
01555             // Deflate negligible s(p).
01556 
01557             case 1: {
01558                 float f = e[p-2];
01559                 e[p-2] = 0.0f;
01560                 for (j = p-2; j >= k; j--) {
01561                     float t = hypotf(s[j],f);
01562                     float invt = 1.0f/t;
01563                     float cs = s[j]*invt;
01564                     float sn = f*invt;
01565                     s[j] = t;
01566                     if (j != k) {
01567                         f = -sn*e[j-1];
01568                         e[j-1] = cs*e[j-1];
01569                     }
01570 
01571                     for (i = 0; i < n; i++) {
01572                         t = cs*V[i][j] + sn*V[i][p-1];
01573                         V[i][p-1] = -sn*V[i][j] + cs*V[i][p-1];
01574                         V[i][j] = t;
01575                     }
01576                 }
01577             }
01578             break;
01579 
01580             // Split at negligible s(k).
01581 
01582             case 2: {
01583                 float f = e[k-1];
01584                 e[k-1] = 0.0f;
01585                 for (j = k; j < p; j++) {
01586                     float t = hypotf(s[j],f);
01587                     float invt = 1.0f/t;
01588                     float cs = s[j]*invt;
01589                     float sn = f*invt;
01590                     s[j] = t;
01591                     f = -sn*e[j];
01592                     e[j] = cs*e[j];
01593 
01594                     for (i = 0; i < m; i++) {
01595                         t = cs*U[i][j] + sn*U[i][k-1];
01596                         U[i][k-1] = -sn*U[i][j] + cs*U[i][k-1];
01597                         U[i][j] = t;
01598                     }
01599                 }
01600             }
01601             break;
01602 
01603             // Perform one qr step.
01604 
01605             case 3: {
01606 
01607                 // Calculate the shift.
01608 
01609                 float scale = maxf(maxf(maxf(maxf(
01610                           fabsf(s[p-1]),fabsf(s[p-2])),fabsf(e[p-2])), 
01611                           fabsf(s[k])),fabsf(e[k]));
01612                 float invscale = 1.0f/scale;
01613                 float sp = s[p-1]*invscale;
01614                 float spm1 = s[p-2]*invscale;
01615                 float epm1 = e[p-2]*invscale;
01616                 float sk = s[k]*invscale;
01617                 float ek = e[k]*invscale;
01618                 float b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)*0.5f;
01619                 float c = (sp*epm1)*(sp*epm1);
01620                 float shift = 0.0f;
01621                 float f, g;
01622                 if ((b != 0.0f) || (c != 0.0f)) {
01623                     shift = sqrtf(b*b + c);
01624                     if (b < 0.0f) {
01625                         shift = -shift;
01626                     }
01627                     shift = c/(b + shift);
01628                 }
01629                 f = (sk + sp)*(sk - sp) + shift;
01630                 g = sk*ek;
01631 
01632                 // Chase zeros.
01633 
01634                 for (j = k; j < p-1; j++) {
01635                     float t = hypotf(f,g);
01636                     /* division by zero checks added to avoid NaN (brecht) */
01637                     float cs = (t == 0.0f)? 0.0f: f/t;
01638                     float sn = (t == 0.0f)? 0.0f: g/t;
01639                     if (j != k) {
01640                         e[j-1] = t;
01641                     }
01642                     f = cs*s[j] + sn*e[j];
01643                     e[j] = cs*e[j] - sn*s[j];
01644                     g = sn*s[j+1];
01645                     s[j+1] = cs*s[j+1];
01646 
01647                     for (i = 0; i < n; i++) {
01648                         t = cs*V[i][j] + sn*V[i][j+1];
01649                         V[i][j+1] = -sn*V[i][j] + cs*V[i][j+1];
01650                         V[i][j] = t;
01651                     }
01652 
01653                     t = hypotf(f,g);
01654                     /* division by zero checks added to avoid NaN (brecht) */
01655                     cs = (t == 0.0f)? 0.0f: f/t;
01656                     sn = (t == 0.0f)? 0.0f: g/t;
01657                     s[j] = t;
01658                     f = cs*e[j] + sn*s[j+1];
01659                     s[j+1] = -sn*e[j] + cs*s[j+1];
01660                     g = sn*e[j+1];
01661                     e[j+1] = cs*e[j+1];
01662                     if (j < m-1) {
01663                         for (i = 0; i < m; i++) {
01664                             t = cs*U[i][j] + sn*U[i][j+1];
01665                             U[i][j+1] = -sn*U[i][j] + cs*U[i][j+1];
01666                             U[i][j] = t;
01667                         }
01668                     }
01669                 }
01670                 e[p-2] = f;
01671                 iter = iter + 1;
01672             }
01673             break;
01674 
01675             // Convergence.
01676 
01677             case 4: {
01678 
01679                 // Make the singular values positive.
01680 
01681                 if (s[k] <= 0.0f) {
01682                     s[k] = (s[k] < 0.0f ? -s[k] : 0.0f);
01683 
01684                     for (i = 0; i <= pp; i++)
01685                         V[i][k] = -V[i][k];
01686                 }
01687 
01688                 // Order the singular values.
01689 
01690                 while (k < pp) {
01691                     float t;
01692                     if (s[k] >= s[k+1]) {
01693                         break;
01694                     }
01695                     t = s[k];
01696                     s[k] = s[k+1];
01697                     s[k+1] = t;
01698                     if (k < n-1) {
01699                         for (i = 0; i < n; i++) {
01700                             t = V[i][k+1]; V[i][k+1] = V[i][k]; V[i][k] = t;
01701                         }
01702                     }
01703                     if (k < m-1) {
01704                         for (i = 0; i < m; i++) {
01705                             t = U[i][k+1]; U[i][k+1] = U[i][k]; U[i][k] = t;
01706                         }
01707                     }
01708                     k++;
01709                 }
01710                 iter = 0;
01711                 p--;
01712             }
01713             break;
01714         }
01715     }
01716 }
01717 
01718 void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon)
01719 {
01720     /* compute moon-penrose pseudo inverse of matrix, singular values
01721        below epsilon are ignored for stability (truncated SVD) */
01722     float V[4][4], W[4], Wm[4][4], U[4][4];
01723     int i;
01724 
01725     transpose_m4(A);
01726     svd_m4(V, W, U, A);
01727     transpose_m4(U);
01728     transpose_m4(V);
01729 
01730     zero_m4(Wm);
01731     for(i=0; i<4; i++)
01732         Wm[i][i]= (W[i] < epsilon)? 0.0f: 1.0f/W[i];
01733 
01734     transpose_m4(V);
01735 
01736     mul_serie_m4(Ainv, U, Wm, V, NULL, NULL, NULL, NULL, NULL);
01737 }