3 * Some matrix operations.
6 * - vector with x components : float x[3], int x[3], etc
10 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version. The Blender
16 * Foundation also sells licenses for use in proprietary software under
17 * the Blender License. See http://www.blender.org/BL/ for information
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software Foundation,
27 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
30 * All rights reserved.
32 * The Original Code is: all of this file.
34 * Contributor(s): none yet.
36 * ***** END GPL/BL DUAL LICENSE BLOCK *****
39 /* ------------------------------------------------------------------------- */
41 #include "MTC_matrixops.h"
42 #include "MTC_vectorops.h"
43 /* ------------------------------------------------------------------------- */
50 #include "BLI_winstuff.h"
53 #if defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__)
57 #define ABS(x) ((x) < 0 ? -(x) : (x))
58 #define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
60 void MTC_Mat4CpyMat4(float m1[][4], float m2[][4])
62 memcpy(m1, m2, 4*4*sizeof(float));
65 /* ------------------------------------------------------------------------- */
67 void MTC_Mat4MulSerie(float answ[][4],
68 float m1[][4], float m2[][4], float m3[][4],
69 float m4[][4], float m5[][4], float m6[][4],
70 float m7[][4], float m8[][4])
74 if(m1==0 || m2==0) return;
76 MTC_Mat4MulMat4(answ, m2, m1);
78 MTC_Mat4MulMat4(temp, m3, answ);
80 MTC_Mat4MulMat4(answ, m4, temp);
82 MTC_Mat4MulMat4(temp, m5, answ);
84 MTC_Mat4MulMat4(answ, m6, temp);
86 MTC_Mat4MulMat4(temp, m7, answ);
88 MTC_Mat4MulMat4(answ, m8, temp);
90 else MTC_Mat4CpyMat4(answ, temp);
93 else MTC_Mat4CpyMat4(answ, temp);
96 else MTC_Mat4CpyMat4(answ, temp);
100 /* ------------------------------------------------------------------------- */
101 void MTC_Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4])
103 /* matrix product: c[j][k] = a[j][i].b[i][k] */
105 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];
106 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];
107 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];
108 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];
110 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];
111 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];
112 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];
113 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];
115 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];
116 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];
117 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];
118 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];
120 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];
121 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];
122 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];
123 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];
126 /* ------------------------------------------------------------------------- */
128 void MTC_Mat4MulVecfl(float mat[][4], float *vec)
134 vec[0]=x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2] + mat[3][0];
135 vec[1]=x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2] + mat[3][1];
136 vec[2]=x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2];
139 /* ------------------------------------------------------------------------- */
140 void MTC_Mat3MulVecfl(float mat[][3], float *vec)
146 vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2];
147 vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2];
148 vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2];
151 /* ------------------------------------------------------------------------- */
153 int MTC_Mat4Invert(float inverse[][4], float mat[][4])
161 /* Set inverse to identity */
168 /* Copy original matrix so we don't mess it up */
169 for(i = 0; i < 4; i++)
170 for(j = 0; j <4; j++)
171 tempmat[i][j] = mat[i][j];
173 for(i = 0; i < 4; i++) {
174 /* Look for row with max pivot */
175 max = ABS(tempmat[i][i]);
177 for(j = i + 1; j < 4; j++) {
178 if(ABS(tempmat[j][i]) > max) {
179 max = ABS(tempmat[j][i]);
183 /* Swap rows if necessary */
185 for( k = 0; k < 4; k++) {
186 SWAP(float, tempmat[i][k], tempmat[maxj][k]);
187 SWAP(float, inverse[i][k], inverse[maxj][k]);
191 temp = tempmat[i][i];
193 return 0; /* No non-zero pivot */
194 for(k = 0; k < 4; k++) {
195 tempmat[i][k] /= temp;
196 inverse[i][k] /= temp;
198 for(j = 0; j < 4; j++) {
200 temp = tempmat[j][i];
201 for(k = 0; k < 4; k++) {
202 tempmat[j][k] -= tempmat[i][k]*temp;
203 inverse[j][k] -= inverse[i][k]*temp;
211 /* ------------------------------------------------------------------------- */
212 void MTC_Mat3CpyMat4(float m1[][3], float m2[][4])
228 /* ------------------------------------------------------------------------- */
230 void MTC_Mat3CpyMat3(float m1[][3], float m2[][3])
232 memcpy(m1, m2, 3*3*sizeof(float));
235 /* ------------------------------------------------------------------------- */
236 /* void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) */
237 void MTC_Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3])
239 /* be careful about this rewrite... */
240 /* m1[i][j] = m2[i][k]*m3[k][j], args are flipped! */
241 m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0];
242 m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1];
243 m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2];
245 m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0];
246 m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1];
247 m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2];
249 m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0];
250 m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1];
251 m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2];
253 /* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */
254 /* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */
255 /* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */
258 /* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */
259 /* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */
260 /* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */
263 /* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */
264 /* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */
265 /* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */
266 } /* end of void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) */
268 /* ------------------------------------------------------------------------- */
270 void MTC_Mat4Ortho(float mat[][4])
274 len= MTC_normalise3DF(mat[0]);
275 if(len!=0.0) mat[0][3]/= len;
276 len= MTC_normalise3DF(mat[1]);
277 if(len!=0.0) mat[1][3]/= len;
278 len= MTC_normalise3DF(mat[2]);
279 if(len!=0.0) mat[2][3]/= len;
282 /* ------------------------------------------------------------------------- */
284 void MTC_Mat4Mul3Vecfl(float mat[][4], float *vec)
287 /* vec = mat^T dot vec !!! or vec a row, then vec = vec dot mat*/
291 vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2];
292 vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2];
293 vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2];
296 /* ------------------------------------------------------------------------- */
298 void MTC_Mat4One(float m[][4])
301 m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0;
302 m[0][1]= m[0][2]= m[0][3]= 0.0;
303 m[1][0]= m[1][2]= m[1][3]= 0.0;
304 m[2][0]= m[2][1]= m[2][3]= 0.0;
305 m[3][0]= m[3][1]= m[3][2]= 0.0;
309 /* ------------------------------------------------------------------------- */
310 /* Result is a 3-vector!*/
311 void MTC_Mat3MulVecd(float mat[][3], double *vec)
315 /* vec = mat^T dot vec !!! or vec a row, then vec = vec dot mat*/
318 vec[0]= x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2];
319 vec[1]= x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2];
320 vec[2]= x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
323 /* ------------------------------------------------------------------------- */
325 void MTC_Mat3Inv(float m1[][3], float m2[][3])
333 /* then determinant old mat! */
334 det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1])
335 -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1])
336 +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]);
347 /* ------------------------------------------------------------------------- */
349 void MTC_Mat3Adj(float m1[][3], float m[][3])
351 m1[0][0]=m[1][1]*m[2][2]-m[1][2]*m[2][1];
352 m1[0][1]= -m[0][1]*m[2][2]+m[0][2]*m[2][1];
353 m1[0][2]=m[0][1]*m[1][2]-m[0][2]*m[1][1];
355 m1[1][0]= -m[1][0]*m[2][2]+m[1][2]*m[2][0];
356 m1[1][1]=m[0][0]*m[2][2]-m[0][2]*m[2][0];
357 m1[1][2]= -m[0][0]*m[1][2]+m[0][2]*m[1][0];
359 m1[2][0]=m[1][0]*m[2][1]-m[1][1]*m[2][0];
360 m1[2][1]= -m[0][0]*m[2][1]+m[0][1]*m[2][0];
361 m1[2][2]=m[0][0]*m[1][1]-m[0][1]*m[1][0];
364 /* ------------------------------------------------------------------------- */
366 void MTC_Mat3One(float m[][3])
369 m[0][0]= m[1][1]= m[2][2]= 1.0;
370 m[0][1]= m[0][2]= 0.0;
371 m[1][0]= m[1][2]= 0.0;
372 m[2][0]= m[2][1]= 0.0;
375 /* ------------------------------------------------------------------------- */
377 void MTC_Mat4SwapMat4(float m1[][4], float m2[][4])
382 for(i = 0; i < 4; i++) {
383 for (j = 0; j < 4; j++) {
391 /* ------------------------------------------------------------------------- */
393 void MTC_Mat4MulVec4fl(float mat[][4], float *vec)
400 vec[0] = x*mat[0][0] + y*mat[1][0] + z*mat[2][0] + mat[3][0]*vec[3];
401 vec[1] = x*mat[0][1] + y*mat[1][1] + z*mat[2][1] + mat[3][1]*vec[3];
402 vec[2] = x*mat[0][2] + y*mat[1][2] + z*mat[2][2] + mat[3][2]*vec[3];
403 vec[3] = x*mat[0][3] + y*mat[1][3] + z*mat[2][3] + mat[3][3]*vec[3];
406 /* ------------------------------------------------------------------------- */
408 void MTC_Mat4CpyMat3nc(float m1[][4], float m2[][3]) /* no clear */
423 /* ------------------------------------------------------------------------- */
425 void MTC_Mat4MulMat33(float m1[][3], float m2[][4], float m3[][3])
427 /* m1_i_j = m2_i_k * m3_k_j ? */
429 m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0];
430 m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1];
431 m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2];
433 m1[1][0] = m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0];
434 m1[1][1] = m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1];
435 m1[1][2] = m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2];
437 m1[2][0] = m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0];
438 m1[2][1] = m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1];
439 m1[2][2] = m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2];
443 /* ------------------------------------------------------------------------- */