| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is: some of this file. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 20:37:56 +00:00
										 |  |  | /** \file blender/blenlib/intern/math_matrix.c
 | 
					
						
							|  |  |  |  *  \ingroup bli | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-16 01:19:37 +00:00
										 |  |  | #include <assert.h>
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************* Init **************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | void zero_m3(float m[3][3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	memset(m, 0, 3 * 3 * sizeof(float)); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | void zero_m4(float m[4][4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	memset(m, 0, 4 * 4 * sizeof(float)); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void unit_m3(float m[][3]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m[0][0] = m[1][1] = m[2][2] = 1.0; | 
					
						
							|  |  |  | 	m[0][1] = m[0][2] = 0.0; | 
					
						
							|  |  |  | 	m[1][0] = m[1][2] = 0.0; | 
					
						
							|  |  |  | 	m[2][0] = m[2][1] = 0.0; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void unit_m4(float m[][4]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0; | 
					
						
							|  |  |  | 	m[0][1] = m[0][2] = m[0][3] = 0.0; | 
					
						
							|  |  |  | 	m[1][0] = m[1][2] = m[1][3] = 0.0; | 
					
						
							|  |  |  | 	m[2][0] = m[2][1] = m[2][3] = 0.0; | 
					
						
							|  |  |  | 	m[3][0] = m[3][1] = m[3][2] = 0.0; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | void copy_m3_m3(float m1[][3], float m2[][3]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* destination comes first: */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	memcpy(&m1[0], &m2[0], 9 * sizeof(float)); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | void copy_m4_m4(float m1[][4], float m2[][4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	memcpy(m1, m2, 4 * 4 * sizeof(float)); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void copy_m3_m4(float m1[][3], float m2[][4]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[0][0] = m2[0][0]; | 
					
						
							|  |  |  | 	m1[0][1] = m2[0][1]; | 
					
						
							|  |  |  | 	m1[0][2] = m2[0][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[1][0] = m2[1][0]; | 
					
						
							|  |  |  | 	m1[1][1] = m2[1][1]; | 
					
						
							|  |  |  | 	m1[1][2] = m2[1][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[2][0] = m2[2][0]; | 
					
						
							|  |  |  | 	m1[2][1] = m2[2][1]; | 
					
						
							|  |  |  | 	m1[2][2] = m2[2][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | void copy_m4_m3(float m1[][4], float m2[][3]) /* no clear */ | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[0][0] = m2[0][0]; | 
					
						
							|  |  |  | 	m1[0][1] = m2[0][1]; | 
					
						
							|  |  |  | 	m1[0][2] = m2[0][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[1][0] = m2[1][0]; | 
					
						
							|  |  |  | 	m1[1][1] = m2[1][1]; | 
					
						
							|  |  |  | 	m1[1][2] = m2[1][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[2][0] = m2[2][0]; | 
					
						
							|  |  |  | 	m1[2][1] = m2[2][1]; | 
					
						
							|  |  |  | 	m1[2][2] = m2[2][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/*	Reevan's Bugfix */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[0][3] = 0.0F; | 
					
						
							|  |  |  | 	m1[1][3] = 0.0F; | 
					
						
							|  |  |  | 	m1[2][3] = 0.0F; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[3][0] = 0.0F; | 
					
						
							|  |  |  | 	m1[3][1] = 0.0F; | 
					
						
							|  |  |  | 	m1[3][2] = 0.0F; | 
					
						
							|  |  |  | 	m1[3][3] = 1.0F; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-31 20:02:51 +00:00
										 |  |  | void swap_m3m3(float m1[][3], float m2[][3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float t; | 
					
						
							|  |  |  | 	int i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	for (i = 0; i < 3; i++) { | 
					
						
							| 
									
										
										
										
											2011-01-31 20:02:51 +00:00
										 |  |  | 		for (j = 0; j < 3; j++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			t = m1[i][j]; | 
					
						
							| 
									
										
										
										
											2011-01-31 20:02:51 +00:00
										 |  |  | 			m1[i][j] = m2[i][j]; | 
					
						
							|  |  |  | 			m2[i][j] = t; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | void swap_m4m4(float m1[][4], float m2[][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float t; | 
					
						
							|  |  |  | 	int i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 		for (j = 0; j < 4; j++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			t = m1[i][j]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 			m1[i][j] = m2[i][j]; | 
					
						
							|  |  |  | 			m2[i][j] = t; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /******************************** Arithmetic *********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Math lib: matrix multiplication order fix for two functions that were
inconsistent with similar functions & math notation:
mul_m4_m4m4(R, B, A) => mult_m4_m4m4(R, A, B)
mul_m3_m3m4(R, B, A) => mult_m3_m3m4(R, A, B)
For branch maintainers, it should be relatively simple to fix things manually,
it's also possible run this script after merging to do automatic replacement:
http://www.pasteall.org/27459/python
											
										 
											2011-12-16 19:53:12 +00:00
										 |  |  | void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | 	float m2[4][4], m3[4][4]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | 	/* copy so it works when m1 is the same pointer as m2 or m3 */ | 
					
						
							|  |  |  | 	copy_m4_m4(m2, m2_); | 
					
						
							|  |  |  | 	copy_m4_m4(m3, m3_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* matrix product: m1[j][k] = m2[j][i].m3[i][k] */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							|  |  |  | 	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]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | 	float m2[3][3], m3[3][3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* copy so it works when m1 is the same pointer as m2 or m3 */ | 
					
						
							|  |  |  | 	copy_m3_m3(m2, m2_); | 
					
						
							|  |  |  | 	copy_m3_m3(m3, m3_); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	/* m1[i][j] = m2[i][k] * m3[k][j], args are flipped!  */ | 
					
						
							|  |  |  | 	m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2]; | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2]; | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-16 15:25:28 +00:00
										 |  |  | void mul_m4_m4m3(float m1[][4], float m3_[][4], float m2_[][3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-15 16:09:57 +00:00
										 |  |  | 	float m2[3][3], m3[4][4]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* copy so it works when m1 is the same pointer as m2 or m3 */ | 
					
						
							|  |  |  | 	copy_m3_m3(m2, m2_); | 
					
						
							|  |  |  | 	copy_m4_m4(m3, m3_); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2]; | 
					
						
							|  |  |  | 	m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2]; | 
					
						
							|  |  |  | 	m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | /* m1 = m2 * m3, ignore the elements on the 4th row/column of m3 */ | 
					
						
							| 
									
										
										
										
											2012-09-16 15:25:28 +00:00
										 |  |  | void mult_m3_m3m4(float m1[][3], float m3_[][4], float m2_[][3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-16 15:25:28 +00:00
										 |  |  | 	float m2[3][3], m3[4][4]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* copy so it works when m1 is the same pointer as m2 or m3 */ | 
					
						
							|  |  |  | 	copy_m3_m3(m2, m2_); | 
					
						
							|  |  |  | 	copy_m4_m4(m3, m3_); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 	/* m1[i][j] = m2[i][k] * m3[k][j] */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-16 15:25:28 +00:00
										 |  |  | void mul_m4_m3m4(float m1[][4], float m3_[][3], float m2_[][4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-16 15:25:28 +00:00
										 |  |  | 	float m2[4][4], m3[3][3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* copy so it works when m1 is the same pointer as m2 or m3 */ | 
					
						
							|  |  |  | 	copy_m4_m4(m2, m2_); | 
					
						
							|  |  |  | 	copy_m3_m3(m3, m3_); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2]; | 
					
						
							|  |  |  | 	m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2]; | 
					
						
							|  |  |  | 	m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0]; | 
					
						
							|  |  |  | 	m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1]; | 
					
						
							|  |  |  | 	m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void mul_serie_m3(float answ[][3], | 
					
						
							| 
									
										
										
										
											2012-03-25 15:56:17 +00:00
										 |  |  |                   float m1[][3], float m2[][3], float m3[][3], | 
					
						
							|  |  |  |                   float m4[][3], float m5[][3], float m6[][3], | 
					
						
							|  |  |  |                   float m7[][3], float m8[][3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float temp[3][3]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (m1 == NULL || m2 == NULL) return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mul_m3_m3m3(answ, m2, m1); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	if (m3) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 		mul_m3_m3m3(temp, m3, answ); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		if (m4) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 			mul_m3_m3m3(answ, m4, temp); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			if (m5) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				mul_m3_m3m3(temp, m5, answ); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 				if (m6) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 					mul_m3_m3m3(answ, m6, temp); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 					if (m7) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 						mul_m3_m3m3(temp, m7, answ); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 						if (m8) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 							mul_m3_m3m3(answ, m8, temp); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						else copy_m3_m3(answ, temp); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else copy_m3_m3(answ, temp); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else copy_m3_m3(answ, temp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void mul_serie_m4(float answ[][4], float m1[][4], | 
					
						
							| 
									
										
										
										
											2012-03-25 15:56:17 +00:00
										 |  |  |                   float m2[][4], float m3[][4], float m4[][4], | 
					
						
							|  |  |  |                   float m5[][4], float m6[][4], float m7[][4], | 
					
						
							|  |  |  |                   float m8[][4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float temp[4][4]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (m1 == NULL || m2 == NULL) return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Math lib: matrix multiplication order fix for two functions that were
inconsistent with similar functions & math notation:
mul_m4_m4m4(R, B, A) => mult_m4_m4m4(R, A, B)
mul_m3_m3m4(R, B, A) => mult_m3_m3m4(R, A, B)
For branch maintainers, it should be relatively simple to fix things manually,
it's also possible run this script after merging to do automatic replacement:
http://www.pasteall.org/27459/python
											
										 
											2011-12-16 19:53:12 +00:00
										 |  |  | 	mult_m4_m4m4(answ, m1, m2); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	if (m3) { | 
					
						
							| 
									
										
										
											
												Math lib: matrix multiplication order fix for two functions that were
inconsistent with similar functions & math notation:
mul_m4_m4m4(R, B, A) => mult_m4_m4m4(R, A, B)
mul_m3_m3m4(R, B, A) => mult_m3_m3m4(R, A, B)
For branch maintainers, it should be relatively simple to fix things manually,
it's also possible run this script after merging to do automatic replacement:
http://www.pasteall.org/27459/python
											
										 
											2011-12-16 19:53:12 +00:00
										 |  |  | 		mult_m4_m4m4(temp, answ, m3); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		if (m4) { | 
					
						
							| 
									
										
										
											
												Math lib: matrix multiplication order fix for two functions that were
inconsistent with similar functions & math notation:
mul_m4_m4m4(R, B, A) => mult_m4_m4m4(R, A, B)
mul_m3_m3m4(R, B, A) => mult_m3_m3m4(R, A, B)
For branch maintainers, it should be relatively simple to fix things manually,
it's also possible run this script after merging to do automatic replacement:
http://www.pasteall.org/27459/python
											
										 
											2011-12-16 19:53:12 +00:00
										 |  |  | 			mult_m4_m4m4(answ, temp, m4); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			if (m5) { | 
					
						
							| 
									
										
										
											
												Math lib: matrix multiplication order fix for two functions that were
inconsistent with similar functions & math notation:
mul_m4_m4m4(R, B, A) => mult_m4_m4m4(R, A, B)
mul_m3_m3m4(R, B, A) => mult_m3_m3m4(R, A, B)
For branch maintainers, it should be relatively simple to fix things manually,
it's also possible run this script after merging to do automatic replacement:
http://www.pasteall.org/27459/python
											
										 
											2011-12-16 19:53:12 +00:00
										 |  |  | 				mult_m4_m4m4(temp, answ, m5); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 				if (m6) { | 
					
						
							| 
									
										
										
											
												Math lib: matrix multiplication order fix for two functions that were
inconsistent with similar functions & math notation:
mul_m4_m4m4(R, B, A) => mult_m4_m4m4(R, A, B)
mul_m3_m3m4(R, B, A) => mult_m3_m3m4(R, A, B)
For branch maintainers, it should be relatively simple to fix things manually,
it's also possible run this script after merging to do automatic replacement:
http://www.pasteall.org/27459/python
											
										 
											2011-12-16 19:53:12 +00:00
										 |  |  | 					mult_m4_m4m4(answ, temp, m6); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 					if (m7) { | 
					
						
							| 
									
										
										
											
												Math lib: matrix multiplication order fix for two functions that were
inconsistent with similar functions & math notation:
mul_m4_m4m4(R, B, A) => mult_m4_m4m4(R, A, B)
mul_m3_m3m4(R, B, A) => mult_m3_m3m4(R, A, B)
For branch maintainers, it should be relatively simple to fix things manually,
it's also possible run this script after merging to do automatic replacement:
http://www.pasteall.org/27459/python
											
										 
											2011-12-16 19:53:12 +00:00
										 |  |  | 						mult_m4_m4m4(temp, answ, m7); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 						if (m8) { | 
					
						
							| 
									
										
										
											
												Math lib: matrix multiplication order fix for two functions that were
inconsistent with similar functions & math notation:
mul_m4_m4m4(R, B, A) => mult_m4_m4m4(R, A, B)
mul_m3_m3m4(R, B, A) => mult_m3_m3m4(R, A, B)
For branch maintainers, it should be relatively simple to fix things manually,
it's also possible run this script after merging to do automatic replacement:
http://www.pasteall.org/27459/python
											
										 
											2011-12-16 19:53:12 +00:00
										 |  |  | 							mult_m4_m4m4(answ, temp, m8); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						else copy_m4_m4(answ, temp); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else copy_m4_m4(answ, temp); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else copy_m4_m4(answ, temp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-12 13:00:24 +00:00
										 |  |  | void mul_m4_v3(float mat[][4], float vec[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float x, y; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	x = vec[0]; | 
					
						
							|  |  |  | 	y = vec[1]; | 
					
						
							|  |  |  | 	vec[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0]; | 
					
						
							|  |  |  | 	vec[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1]; | 
					
						
							|  |  |  | 	vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-12 13:00:24 +00:00
										 |  |  | void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float x, y; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	x = vec[0]; | 
					
						
							|  |  |  | 	y = vec[1]; | 
					
						
							|  |  |  | 	in[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0]; | 
					
						
							|  |  |  | 	in[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1]; | 
					
						
							|  |  |  | 	in[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-26 18:20:20 +00:00
										 |  |  | /* same as mul_m4_v3() but doesnt apply translation component */ | 
					
						
							| 
									
										
										
										
											2011-09-12 13:00:24 +00:00
										 |  |  | void mul_mat3_m4_v3(float mat[][4], float vec[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float x, y; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	x = vec[0]; | 
					
						
							|  |  |  | 	y = vec[1]; | 
					
						
							|  |  |  | 	vec[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2]; | 
					
						
							|  |  |  | 	vec[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2]; | 
					
						
							|  |  |  | 	vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-20 10:09:03 +00:00
										 |  |  | void mul_project_m4_v3(float mat[][4], float vec[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mul_m4_v3(mat, vec); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vec[0] /= w; | 
					
						
							|  |  |  | 	vec[1] /= w; | 
					
						
							|  |  |  | 	vec[2] /= w; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | void mul_v4_m4v4(float r[4], float mat[4][4], float v[4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | 	float x, y, z; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	x = v[0]; | 
					
						
							|  |  |  | 	y = v[1]; | 
					
						
							|  |  |  | 	z = v[2]; | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	r[0] = x * mat[0][0] + y * mat[1][0] + z * mat[2][0] + mat[3][0] * v[3]; | 
					
						
							|  |  |  | 	r[1] = x * mat[0][1] + y * mat[1][1] + z * mat[2][1] + mat[3][1] * v[3]; | 
					
						
							|  |  |  | 	r[2] = x * mat[0][2] + y * mat[1][2] + z * mat[2][2] + mat[3][2] * v[3]; | 
					
						
							|  |  |  | 	r[3] = x * mat[0][3] + y * mat[1][3] + z * mat[2][3] + mat[3][3] * v[3]; | 
					
						
							| 
									
										
										
										
											2010-04-15 10:28:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void mul_m4_v4(float mat[4][4], float r[4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	mul_v4_m4v4(r, mat, r); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-08 11:57:51 +00:00
										 |  |  | void mul_v4d_m4v4d(double r[4], float mat[4][4], double v[4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	double x, y, z; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	x = v[0]; | 
					
						
							|  |  |  | 	y = v[1]; | 
					
						
							|  |  |  | 	z = v[2]; | 
					
						
							| 
									
										
										
										
											2012-03-08 11:57:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	r[0] = x * (double)mat[0][0] + y * (double)mat[1][0] + z * (double)mat[2][0] + (double)mat[3][0] * v[3]; | 
					
						
							|  |  |  | 	r[1] = x * (double)mat[0][1] + y * (double)mat[1][1] + z * (double)mat[2][1] + (double)mat[3][1] * v[3]; | 
					
						
							|  |  |  | 	r[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + z * (double)mat[2][2] + (double)mat[3][2] * v[3]; | 
					
						
							|  |  |  | 	r[3] = x * (double)mat[0][3] + y * (double)mat[1][3] + z * (double)mat[2][3] + (double)mat[3][3] * v[3]; | 
					
						
							| 
									
										
										
										
											2012-03-08 11:57:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void mul_m4_v4d(float mat[4][4], double r[4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	mul_v4d_m4v4d(r, mat, r); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 13:11:41 +00:00
										 |  |  | void mul_v3_m3v3(float r[3], float M[3][3], float a[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	r[0] = M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2]; | 
					
						
							|  |  |  | 	r[1] = M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2]; | 
					
						
							|  |  |  | 	r[2] = M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2]; | 
					
						
							| 
									
										
										
										
											2009-11-28 13:11:41 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 13:11:41 +00:00
										 |  |  | void mul_m3_v3(float M[3][3], float r[3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float tmp[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mul_v3_m3v3(tmp, M, r); | 
					
						
							|  |  |  | 	copy_v3_v3(r, tmp); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-12 13:00:24 +00:00
										 |  |  | void mul_transposed_m3_v3(float mat[][3], float vec[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float x, y; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	x = vec[0]; | 
					
						
							|  |  |  | 	y = vec[1]; | 
					
						
							|  |  |  | 	vec[0] = x * mat[0][0] + y * mat[0][1] + mat[0][2] * vec[2]; | 
					
						
							|  |  |  | 	vec[1] = x * mat[1][0] + y * mat[1][1] + mat[1][2] * vec[2]; | 
					
						
							|  |  |  | 	vec[2] = x * mat[2][0] + y * mat[2][1] + mat[2][2] * vec[2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | void mul_m3_fl(float m[3][3], float f) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 	int i, j; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (i = 0; i < 3; i++) | 
					
						
							|  |  |  | 		for (j = 0; j < 3; j++) | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 			m[i][j] *= f; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | void mul_m4_fl(float m[4][4], float f) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 	int i, j; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) | 
					
						
							|  |  |  | 		for (j = 0; j < 4; j++) | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 			m[i][j] *= f; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | void mul_mat3_m4_fl(float m[4][4], float f) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 	int i, j; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (i = 0; i < 3; i++) | 
					
						
							|  |  |  | 		for (j = 0; j < 3; j++) | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 			m[i][j] *= f; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-12 13:00:24 +00:00
										 |  |  | void mul_m3_v3_double(float mat[][3], double vec[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	double x, y; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	x = vec[0]; | 
					
						
							|  |  |  | 	y = vec[1]; | 
					
						
							|  |  |  | 	vec[0] = x * (double)mat[0][0] + y * (double)mat[1][0] + (double)mat[2][0] * vec[2]; | 
					
						
							|  |  |  | 	vec[1] = x * (double)mat[0][1] + y * (double)mat[1][1] + (double)mat[2][1] * vec[2]; | 
					
						
							|  |  |  | 	vec[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + (double)mat[2][2] * vec[2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void add_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (i = 0; i < 3; i++) | 
					
						
							|  |  |  | 		for (j = 0; j < 3; j++) | 
					
						
							|  |  |  | 			m1[i][j] = m2[i][j] + m3[i][j]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) | 
					
						
							|  |  |  | 		for (j = 0; j < 4; j++) | 
					
						
							|  |  |  | 			m1[i][j] = m2[i][j] + m3[i][j]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (i = 0; i < 3; i++) | 
					
						
							|  |  |  | 		for (j = 0; j < 3; j++) | 
					
						
							|  |  |  | 			m1[i][j] = m2[i][j] - m3[i][j]; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) | 
					
						
							|  |  |  | 		for (j = 0; j < 4; j++) | 
					
						
							|  |  |  | 			m1[i][j] = m2[i][j] - m3[i][j]; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | int invert_m3(float m[3][3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float tmp[3][3]; | 
					
						
							|  |  |  | 	int success; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	success = invert_m3_m3(tmp, m); | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 	copy_m3_m3(m, tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return success; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int invert_m3_m3(float m1[3][3], float m2[3][3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float det; | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 	int a, b, success; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* calc adjoint */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	adjoint_m3_m3(m1, m2); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* then determinant old matrix! */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	det = (m2[0][0] * (m2[1][1] * m2[2][2] - m2[1][2] * m2[2][1]) - | 
					
						
							|  |  |  | 	       m2[1][0] * (m2[0][1] * m2[2][2] - m2[0][2] * m2[2][1]) + | 
					
						
							|  |  |  | 	       m2[2][0] * (m2[0][1] * m2[1][2] - m2[0][2] * m2[1][1])); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	success = (det != 0); | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	if (det == 0) det = 1; | 
					
						
							|  |  |  | 	det = 1 / det; | 
					
						
							|  |  |  | 	for (a = 0; a < 3; a++) { | 
					
						
							|  |  |  | 		for (b = 0; b < 3; b++) { | 
					
						
							|  |  |  | 			m1[a][b] *= det; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return success; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int invert_m4(float m[4][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float tmp[4][4]; | 
					
						
							|  |  |  | 	int success; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	success = invert_m4_m4(tmp, m); | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | 	copy_m4_m4(m, tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return success; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  |  * invertmat - | 
					
						
							| 
									
										
										
										
											2012-03-25 15:56:17 +00:00
										 |  |  |  *      computes the inverse of mat and puts it in inverse.  Returns | 
					
						
							|  |  |  |  *  TRUE on success (i.e. can always find a pivot) and FALSE on failure. | 
					
						
							|  |  |  |  *  Uses Gaussian Elimination with partial (maximal column) pivoting. | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *					Mark Segal - 1992 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 19:13:05 +00:00
										 |  |  | int invert_m4_m4(float inverse[4][4], float mat[4][4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int i, j, k; | 
					
						
							|  |  |  | 	double temp; | 
					
						
							|  |  |  | 	float tempmat[4][4]; | 
					
						
							|  |  |  | 	float max; | 
					
						
							|  |  |  | 	int maxj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Set inverse to identity */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) | 
					
						
							|  |  |  | 		for (j = 0; j < 4; j++) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 			inverse[i][j] = 0; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 		inverse[i][i] = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Copy original matrix so we don't mess it up */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		for (j = 0; j < 4; j++) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 			tempmat[i][j] = mat[i][j]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 		/* Look for row with max pivot */ | 
					
						
							|  |  |  | 		max = fabs(tempmat[i][i]); | 
					
						
							|  |  |  | 		maxj = i; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		for (j = i + 1; j < 4; j++) { | 
					
						
							|  |  |  | 			if (fabsf(tempmat[j][i]) > max) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				max = fabs(tempmat[j][i]); | 
					
						
							|  |  |  | 				maxj = j; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/* Swap rows if necessary */ | 
					
						
							|  |  |  | 		if (maxj != i) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			for (k = 0; k < 4; k++) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				SWAP(float, tempmat[i][k], tempmat[maxj][k]); | 
					
						
							|  |  |  | 				SWAP(float, inverse[i][k], inverse[maxj][k]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		temp = tempmat[i][i]; | 
					
						
							|  |  |  | 		if (temp == 0) | 
					
						
							| 
									
										
										
										
											2012-03-25 15:56:17 +00:00
										 |  |  | 			return 0;  /* No non-zero pivot */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		for (k = 0; k < 4; k++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			tempmat[i][k] = (float)(tempmat[i][k] / temp); | 
					
						
							|  |  |  | 			inverse[i][k] = (float)(inverse[i][k] / temp); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		for (j = 0; j < 4; j++) { | 
					
						
							|  |  |  | 			if (j != i) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				temp = tempmat[j][i]; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 				for (k = 0; k < 4; k++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					tempmat[j][k] -= (float)(tempmat[i][k] * temp); | 
					
						
							|  |  |  | 					inverse[j][k] -= (float)(inverse[i][k] * temp); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /****************************** Linear Algebra *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void transpose_m3(float mat[][3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	t = mat[0][1]; | 
					
						
							|  |  |  | 	mat[0][1] = mat[1][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mat[1][0] = t; | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	t = mat[0][2]; | 
					
						
							|  |  |  | 	mat[0][2] = mat[2][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mat[2][0] = t; | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	t = mat[1][2]; | 
					
						
							|  |  |  | 	mat[1][2] = mat[2][1]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mat[2][1] = t; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void transpose_m4(float mat[][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	t = mat[0][1]; | 
					
						
							|  |  |  | 	mat[0][1] = mat[1][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mat[1][0] = t; | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	t = mat[0][2]; | 
					
						
							|  |  |  | 	mat[0][2] = mat[2][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mat[2][0] = t; | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	t = mat[0][3]; | 
					
						
							|  |  |  | 	mat[0][3] = mat[3][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mat[3][0] = t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	t = mat[1][2]; | 
					
						
							|  |  |  | 	mat[1][2] = mat[2][1]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mat[2][1] = t; | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	t = mat[1][3]; | 
					
						
							|  |  |  | 	mat[1][3] = mat[3][1]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mat[3][1] = t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	t = mat[2][3]; | 
					
						
							|  |  |  | 	mat[2][3] = mat[3][2]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mat[3][2] = t; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void orthogonalize_m3(float mat[][3], int axis) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float size[3]; | 
					
						
							| 
									
										
										
										
											2010-08-15 15:14:08 +00:00
										 |  |  | 	mat3_to_size(size, mat); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	normalize_v3(mat[axis]); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	switch (axis) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 		case 0: | 
					
						
							|  |  |  | 			if (dot_v3v3(mat[0], mat[1]) < 1) { | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], mat[1]); | 
					
						
							|  |  |  | 				normalize_v3(mat[2]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (dot_v3v3(mat[0], mat[2]) < 1) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							|  |  |  | 				normalize_v3(mat[1]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], mat[1]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2010-11-02 13:12:30 +00:00
										 |  |  | 				float vec[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				vec[0] = mat[0][1]; | 
					
						
							|  |  |  | 				vec[1] = mat[0][2]; | 
					
						
							|  |  |  | 				vec[2] = mat[0][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], vec); | 
					
						
							|  |  |  | 				normalize_v3(mat[2]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		case 1: | 
					
						
							|  |  |  | 			if (dot_v3v3(mat[1], mat[0]) < 1) { | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], mat[1]); | 
					
						
							|  |  |  | 				normalize_v3(mat[2]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[0], mat[1], mat[2]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (dot_v3v3(mat[0], mat[2]) < 1) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				cross_v3_v3v3(mat[0], mat[1], mat[2]); | 
					
						
							|  |  |  | 				normalize_v3(mat[0]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], mat[1]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2010-11-02 13:12:30 +00:00
										 |  |  | 				float vec[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				vec[0] = mat[1][1]; | 
					
						
							|  |  |  | 				vec[1] = mat[1][2]; | 
					
						
							|  |  |  | 				vec[2] = mat[1][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[0], mat[1], vec); | 
					
						
							|  |  |  | 				normalize_v3(mat[0]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], mat[1]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		case 2: | 
					
						
							|  |  |  | 			if (dot_v3v3(mat[2], mat[0]) < 1) { | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							|  |  |  | 				normalize_v3(mat[1]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[0], mat[1], mat[2]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (dot_v3v3(mat[2], mat[1]) < 1) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				cross_v3_v3v3(mat[0], mat[1], mat[2]); | 
					
						
							|  |  |  | 				normalize_v3(mat[0]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2010-11-02 13:12:30 +00:00
										 |  |  | 				float vec[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				vec[0] = mat[2][1]; | 
					
						
							|  |  |  | 				vec[1] = mat[2][2]; | 
					
						
							|  |  |  | 				vec[2] = mat[2][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[0], vec, mat[2]); | 
					
						
							|  |  |  | 				normalize_v3(mat[0]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mul_v3_fl(mat[0], size[0]); | 
					
						
							|  |  |  | 	mul_v3_fl(mat[1], size[1]); | 
					
						
							|  |  |  | 	mul_v3_fl(mat[2], size[2]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void orthogonalize_m4(float mat[][4], int axis) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float size[3]; | 
					
						
							| 
									
										
										
										
											2010-08-15 15:14:08 +00:00
										 |  |  | 	mat4_to_size(size, mat); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	normalize_v3(mat[axis]); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	switch (axis) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 		case 0: | 
					
						
							|  |  |  | 			if (dot_v3v3(mat[0], mat[1]) < 1) { | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], mat[1]); | 
					
						
							|  |  |  | 				normalize_v3(mat[2]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (dot_v3v3(mat[0], mat[2]) < 1) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							|  |  |  | 				normalize_v3(mat[1]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], mat[1]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2010-11-02 13:12:30 +00:00
										 |  |  | 				float vec[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				vec[0] = mat[0][1]; | 
					
						
							|  |  |  | 				vec[1] = mat[0][2]; | 
					
						
							|  |  |  | 				vec[2] = mat[0][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], vec); | 
					
						
							|  |  |  | 				normalize_v3(mat[2]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		case 1: | 
					
						
							|  |  |  | 			normalize_v3(mat[0]); | 
					
						
							|  |  |  | 			if (dot_v3v3(mat[1], mat[0]) < 1) { | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], mat[1]); | 
					
						
							|  |  |  | 				normalize_v3(mat[2]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[0], mat[1], mat[2]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (dot_v3v3(mat[0], mat[2]) < 1) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				cross_v3_v3v3(mat[0], mat[1], mat[2]); | 
					
						
							|  |  |  | 				normalize_v3(mat[0]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], mat[1]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2010-11-02 13:12:30 +00:00
										 |  |  | 				float vec[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				vec[0] = mat[1][1]; | 
					
						
							|  |  |  | 				vec[1] = mat[1][2]; | 
					
						
							|  |  |  | 				vec[2] = mat[1][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[0], mat[1], vec); | 
					
						
							|  |  |  | 				normalize_v3(mat[0]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[2], mat[0], mat[1]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		case 2: | 
					
						
							|  |  |  | 			if (dot_v3v3(mat[2], mat[0]) < 1) { | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							|  |  |  | 				normalize_v3(mat[1]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[0], mat[1], mat[2]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (dot_v3v3(mat[2], mat[1]) < 1) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 				cross_v3_v3v3(mat[0], mat[1], mat[2]); | 
					
						
							|  |  |  | 				normalize_v3(mat[0]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2010-11-02 13:12:30 +00:00
										 |  |  | 				float vec[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				vec[0] = mat[2][1]; | 
					
						
							|  |  |  | 				vec[1] = mat[2][2]; | 
					
						
							|  |  |  | 				vec[2] = mat[2][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[0], vec, mat[2]); | 
					
						
							|  |  |  | 				normalize_v3(mat[0]); | 
					
						
							|  |  |  | 				cross_v3_v3v3(mat[1], mat[2], mat[0]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mul_v3_fl(mat[0], size[0]); | 
					
						
							|  |  |  | 	mul_v3_fl(mat[1], size[1]); | 
					
						
							|  |  |  | 	mul_v3_fl(mat[2], size[2]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-26 17:11:43 +00:00
										 |  |  | int is_orthogonal_m3(float m[][3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 07:36:32 +00:00
										 |  |  | 	int i, j; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:36:32 +00:00
										 |  |  | 	for (i = 0; i < 3; i++) { | 
					
						
							|  |  |  | 		for (j = 0; j < i; j++) { | 
					
						
							|  |  |  | 			if (fabsf(dot_v3v3(m[i], m[j])) > 1.5f * FLT_EPSILON) | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-01-26 17:11:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:36:32 +00:00
										 |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-26 17:11:43 +00:00
										 |  |  | int is_orthogonal_m4(float m[][4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 07:36:32 +00:00
										 |  |  | 	int i, j; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:36:32 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) { | 
					
						
							|  |  |  | 		for (j = 0; j < i; j++) { | 
					
						
							|  |  |  | 			if (fabsf(dot_vn_vn(m[i], m[j], 4)) > 1.5f * FLT_EPSILON) | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:36:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-01-26 17:11:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:36:32 +00:00
										 |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-01 00:14:41 +00:00
										 |  |  | int is_orthonormal_m3(float m[][3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (is_orthogonal_m3(m)) { | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (i = 0; i < 3; i++) | 
					
						
							|  |  |  | 			if (fabsf(dot_v3v3(m[i], m[i]) - 1) > 1.5f * FLT_EPSILON) | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int is_orthonormal_m4(float m[][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (is_orthogonal_m4(m)) { | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (i = 0; i < 4; i++) | 
					
						
							|  |  |  | 			if (fabsf(dot_vn_vn(m[i], m[i], 4) - 1) > 1.5f * FLT_EPSILON) | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-01 11:01:24 +00:00
										 |  |  | int is_uniform_scaled_m3(float m[][3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const float eps = 1e-7; | 
					
						
							|  |  |  | 	float t[3][3]; | 
					
						
							|  |  |  | 	float l1, l2, l3, l4, l5, l6; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	copy_m3_m3(t, m); | 
					
						
							|  |  |  | 	transpose_m3(t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	l1 = len_squared_v3(m[0]); | 
					
						
							|  |  |  | 	l2 = len_squared_v3(m[1]); | 
					
						
							|  |  |  | 	l3 = len_squared_v3(m[2]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	l4 = len_squared_v3(t[0]); | 
					
						
							|  |  |  | 	l5 = len_squared_v3(t[1]); | 
					
						
							|  |  |  | 	l6 = len_squared_v3(t[2]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (fabsf(l2 - l1) <= eps && | 
					
						
							|  |  |  | 	    fabsf(l3 - l1) <= eps && | 
					
						
							|  |  |  | 	    fabsf(l4 - l1) <= eps && | 
					
						
							|  |  |  | 	    fabsf(l5 - l1) <= eps && | 
					
						
							|  |  |  | 	    fabsf(l6 - l1) <= eps) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | void normalize_m3(float mat[][3]) | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	normalize_v3(mat[0]); | 
					
						
							|  |  |  | 	normalize_v3(mat[1]); | 
					
						
							|  |  |  | 	normalize_v3(mat[2]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-26 20:41:16 +00:00
										 |  |  | void normalize_m3_m3(float rmat[][3], float mat[][3]) | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-18 02:36:43 +00:00
										 |  |  | 	normalize_v3_v3(rmat[0], mat[0]); | 
					
						
							|  |  |  | 	normalize_v3_v3(rmat[1], mat[1]); | 
					
						
							|  |  |  | 	normalize_v3_v3(rmat[2], mat[2]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | void normalize_m4(float mat[][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float len; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	len = normalize_v3(mat[0]); | 
					
						
							|  |  |  | 	if (len != 0.0f) mat[0][3] /= len; | 
					
						
							|  |  |  | 	len = normalize_v3(mat[1]); | 
					
						
							|  |  |  | 	if (len != 0.0f) mat[1][3] /= len; | 
					
						
							|  |  |  | 	len = normalize_v3(mat[2]); | 
					
						
							|  |  |  | 	if (len != 0.0f) mat[2][3] /= len; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-26 20:41:16 +00:00
										 |  |  | void normalize_m4_m4(float rmat[][4], float mat[][4]) | 
					
						
							| 
									
										
										
										
											2010-10-18 02:36:43 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float len; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	len = normalize_v3_v3(rmat[0], mat[0]); | 
					
						
							|  |  |  | 	if (len != 0.0f) rmat[0][3] = mat[0][3] / len; | 
					
						
							|  |  |  | 	len = normalize_v3_v3(rmat[1], mat[1]); | 
					
						
							|  |  |  | 	if (len != 0.0f) rmat[1][3] = mat[1][3] / len; | 
					
						
							|  |  |  | 	len = normalize_v3_v3(rmat[2], mat[2]); | 
					
						
							|  |  |  | 	if (len != 0.0f) rmat[2][3] = mat[2][3] / len; | 
					
						
							| 
									
										
										
										
											2010-10-18 02:36:43 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-29 03:36:55 +00:00
										 |  |  | void adjoint_m2_m2(float m1[][2], float m[][2]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BLI_assert(m1 != m); | 
					
						
							|  |  |  | 	m1[0][0] =  m[1][1]; | 
					
						
							|  |  |  | 	m1[0][1] = -m[1][0]; | 
					
						
							|  |  |  | 	m1[1][0] = -m[0][1]; | 
					
						
							|  |  |  | 	m1[1][1] =  m[0][0]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | void adjoint_m3_m3(float m1[][3], float m[][3]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-29 03:36:55 +00:00
										 |  |  | 	BLI_assert(m1 != m); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1]; | 
					
						
							|  |  |  | 	m1[0][1] = -m[0][1] * m[2][2] + m[0][2] * m[2][1]; | 
					
						
							|  |  |  | 	m1[0][2] = m[0][1] * m[1][2] - m[0][2] * m[1][1]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[1][0] = -m[1][0] * m[2][2] + m[1][2] * m[2][0]; | 
					
						
							|  |  |  | 	m1[1][1] = m[0][0] * m[2][2] - m[0][2] * m[2][0]; | 
					
						
							|  |  |  | 	m1[1][2] = -m[0][0] * m[1][2] + m[0][2] * m[1][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m1[2][0] = m[1][0] * m[2][1] - m[1][1] * m[2][0]; | 
					
						
							|  |  |  | 	m1[2][1] = -m[0][0] * m[2][1] + m[0][1] * m[2][0]; | 
					
						
							|  |  |  | 	m1[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | void adjoint_m4_m4(float out[][4], float in[][4]) /* out = ADJ(in) */ | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float a1, a2, a3, a4, b1, b2, b3, b4; | 
					
						
							|  |  |  | 	float c1, c2, c3, c4, d1, d2, d3, d4; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	a1 = in[0][0]; | 
					
						
							|  |  |  | 	b1 = in[0][1]; | 
					
						
							|  |  |  | 	c1 = in[0][2]; | 
					
						
							|  |  |  | 	d1 = in[0][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	a2 = in[1][0]; | 
					
						
							|  |  |  | 	b2 = in[1][1]; | 
					
						
							|  |  |  | 	c2 = in[1][2]; | 
					
						
							|  |  |  | 	d2 = in[1][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	a3 = in[2][0]; | 
					
						
							|  |  |  | 	b3 = in[2][1]; | 
					
						
							|  |  |  | 	c3 = in[2][2]; | 
					
						
							|  |  |  | 	d3 = in[2][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	a4 = in[3][0]; | 
					
						
							|  |  |  | 	b4 = in[3][1]; | 
					
						
							|  |  |  | 	c4 = in[3][2]; | 
					
						
							|  |  |  | 	d4 = in[3][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	out[0][0] = determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4); | 
					
						
							|  |  |  | 	out[1][0] = -determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4); | 
					
						
							|  |  |  | 	out[2][0] = determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4); | 
					
						
							|  |  |  | 	out[3][0] = -determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	out[0][1] = -determinant_m3(b1, b3, b4, c1, c3, c4, d1, d3, d4); | 
					
						
							|  |  |  | 	out[1][1] = determinant_m3(a1, a3, a4, c1, c3, c4, d1, d3, d4); | 
					
						
							|  |  |  | 	out[2][1] = -determinant_m3(a1, a3, a4, b1, b3, b4, d1, d3, d4); | 
					
						
							|  |  |  | 	out[3][1] = determinant_m3(a1, a3, a4, b1, b3, b4, c1, c3, c4); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	out[0][2] = determinant_m3(b1, b2, b4, c1, c2, c4, d1, d2, d4); | 
					
						
							|  |  |  | 	out[1][2] = -determinant_m3(a1, a2, a4, c1, c2, c4, d1, d2, d4); | 
					
						
							|  |  |  | 	out[2][2] = determinant_m3(a1, a2, a4, b1, b2, b4, d1, d2, d4); | 
					
						
							|  |  |  | 	out[3][2] = -determinant_m3(a1, a2, a4, b1, b2, b4, c1, c2, c4); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	out[0][3] = -determinant_m3(b1, b2, b3, c1, c2, c3, d1, d2, d3); | 
					
						
							|  |  |  | 	out[1][3] = determinant_m3(a1, a2, a3, c1, c2, c3, d1, d2, d3); | 
					
						
							|  |  |  | 	out[2][3] = -determinant_m3(a1, a2, a3, b1, b2, b3, d1, d2, d3); | 
					
						
							|  |  |  | 	out[3][3] = determinant_m3(a1, a2, a3, b1, b2, b3, c1, c2, c3); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | float determinant_m2(float a, float b, float c, float d) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	return a * d - b * c; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float determinant_m3(float a1, float a2, float a3, | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  |                      float b1, float b2, float b3, | 
					
						
							|  |  |  |                      float c1, float c2, float c3) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float ans; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	ans = (a1 * determinant_m2(b2, b3, c2, c3) - | 
					
						
							|  |  |  | 	       b1 * determinant_m2(a2, a3, c2, c3) + | 
					
						
							|  |  |  | 	       c1 * determinant_m2(a2, a3, b2, b3)); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ans; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float determinant_m4(float m[][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float ans; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	a1 = m[0][0]; | 
					
						
							|  |  |  | 	b1 = m[0][1]; | 
					
						
							|  |  |  | 	c1 = m[0][2]; | 
					
						
							|  |  |  | 	d1 = m[0][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	a2 = m[1][0]; | 
					
						
							|  |  |  | 	b2 = m[1][1]; | 
					
						
							|  |  |  | 	c2 = m[1][2]; | 
					
						
							|  |  |  | 	d2 = m[1][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	a3 = m[2][0]; | 
					
						
							|  |  |  | 	b3 = m[2][1]; | 
					
						
							|  |  |  | 	c3 = m[2][2]; | 
					
						
							|  |  |  | 	d3 = m[2][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	a4 = m[3][0]; | 
					
						
							|  |  |  | 	b4 = m[3][1]; | 
					
						
							|  |  |  | 	c4 = m[3][2]; | 
					
						
							|  |  |  | 	d4 = m[3][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	ans = (a1 * determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4) - | 
					
						
							|  |  |  | 	       b1 * determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4) + | 
					
						
							|  |  |  | 	       c1 * determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4) - | 
					
						
							|  |  |  | 	       d1 * determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4)); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ans; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /****************************** Transformations ******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 03:56:50 +00:00
										 |  |  | void size_to_mat3(float mat[][3], const float size[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	mat[0][0] = size[0]; | 
					
						
							|  |  |  | 	mat[0][1] = 0.0f; | 
					
						
							|  |  |  | 	mat[0][2] = 0.0f; | 
					
						
							|  |  |  | 	mat[1][1] = size[1]; | 
					
						
							|  |  |  | 	mat[1][0] = 0.0f; | 
					
						
							|  |  |  | 	mat[1][2] = 0.0f; | 
					
						
							|  |  |  | 	mat[2][2] = size[2]; | 
					
						
							|  |  |  | 	mat[2][1] = 0.0f; | 
					
						
							|  |  |  | 	mat[2][0] = 0.0f; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 03:56:50 +00:00
										 |  |  | void size_to_mat4(float mat[][4], const float size[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float tmat[3][3]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	size_to_mat3(tmat, size); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	unit_m4(mat); | 
					
						
							|  |  |  | 	copy_m4_m3(mat, tmat); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-12 13:00:24 +00:00
										 |  |  | void mat3_to_size(float size[3], float mat[][3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	size[0] = len_v3(mat[0]); | 
					
						
							|  |  |  | 	size[1] = len_v3(mat[1]); | 
					
						
							|  |  |  | 	size[2] = len_v3(mat[2]); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-12 13:00:24 +00:00
										 |  |  | void mat4_to_size(float size[3], float mat[][4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	size[0] = len_v3(mat[0]); | 
					
						
							|  |  |  | 	size[1] = len_v3(mat[1]); | 
					
						
							|  |  |  | 	size[2] = len_v3(mat[2]); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* this gets the average scale of a matrix, only use when your scaling
 | 
					
						
							|  |  |  |  * data that has no idea of scale axis, examples are bone-envelope-radius | 
					
						
							|  |  |  |  * and curve radius */ | 
					
						
							|  |  |  | float mat3_to_scale(float mat[][3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* unit length vector */ | 
					
						
							|  |  |  | 	float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f}; | 
					
						
							|  |  |  | 	mul_m3_v3(mat, unit_vec); | 
					
						
							|  |  |  | 	return len_v3(unit_vec); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float mat4_to_scale(float mat[][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float tmat[3][3]; | 
					
						
							|  |  |  | 	copy_m3_m4(tmat, mat); | 
					
						
							|  |  |  | 	return mat3_to_scale(tmat); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]) | 
					
						
							| 
									
										
										
										
											2010-10-26 12:48:07 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float mat3_n[3][3]; /* mat3 -> normalized, 3x3 */ | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | 	float imat3_n[3][3]; /* mat3 -> normalized & inverted, 3x3 */ | 
					
						
							| 
									
										
										
										
											2010-10-26 12:48:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* rotation & scale are linked, we need to create the mat's
 | 
					
						
							|  |  |  | 	 * for these together since they are related. */ | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-18 11:01:23 +00:00
										 |  |  | 	/* so scale doesn't interfere with rotation [#24291] */ | 
					
						
							| 
									
										
										
										
											2010-10-26 12:48:07 +00:00
										 |  |  | 	/* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */ | 
					
						
							| 
									
										
										
										
											2010-10-26 20:41:16 +00:00
										 |  |  | 	normalize_m3_m3(mat3_n, mat3); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 	if (is_negative_m3(mat3)) { | 
					
						
							| 
									
										
										
										
											2010-10-26 12:48:07 +00:00
										 |  |  | 		negate_v3(mat3_n[0]); | 
					
						
							|  |  |  | 		negate_v3(mat3_n[1]); | 
					
						
							|  |  |  | 		negate_v3(mat3_n[2]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* rotation */ | 
					
						
							|  |  |  | 	/* keep rot as a 3x3 matrix, the caller can convert into a quat or euler */ | 
					
						
							|  |  |  | 	copy_m3_m3(rot, mat3_n); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* scale */ | 
					
						
							|  |  |  | 	/* note: mat4_to_size(ob->size, mat) fails for negative scale */ | 
					
						
							|  |  |  | 	invert_m3_m3(imat3_n, mat3_n); | 
					
						
							|  |  |  | 	mul_m3_m3m3(mat3, imat3_n, mat3); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	size[0] = mat3[0][0]; | 
					
						
							|  |  |  | 	size[1] = mat3[1][1]; | 
					
						
							|  |  |  | 	size[2] = mat3[2][2]; | 
					
						
							| 
									
										
										
										
											2010-10-26 12:48:07 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float mat3[3][3]; /* wmat -> 3x3 */ | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	copy_m3_m4(mat3, wmat); | 
					
						
							|  |  |  | 	mat3_to_rot_size(rot, size, mat3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* location */ | 
					
						
							|  |  |  | 	copy_v3_v3(loc, wmat[3]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | void scale_m3_fl(float m[][3], float scale) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m[0][0] = m[1][1] = m[2][2] = scale; | 
					
						
							|  |  |  | 	m[0][1] = m[0][2] = 0.0; | 
					
						
							|  |  |  | 	m[1][0] = m[1][2] = 0.0; | 
					
						
							|  |  |  | 	m[2][0] = m[2][1] = 0.0; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void scale_m4_fl(float m[][4], float scale) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	m[0][0] = m[1][1] = m[2][2] = scale; | 
					
						
							|  |  |  | 	m[3][3] = 1.0; | 
					
						
							|  |  |  | 	m[0][1] = m[0][2] = m[0][3] = 0.0; | 
					
						
							|  |  |  | 	m[1][0] = m[1][2] = m[1][3] = 0.0; | 
					
						
							|  |  |  | 	m[2][0] = m[2][1] = m[2][3] = 0.0; | 
					
						
							|  |  |  | 	m[3][0] = m[3][1] = m[3][2] = 0.0; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | void translate_m4(float mat[][4], float Tx, float Ty, float Tz) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]); | 
					
						
							|  |  |  | 	mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]); | 
					
						
							|  |  |  | 	mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-22 00:14:56 +00:00
										 |  |  | void rotate_m4(float mat[][4], const char axis, const float angle) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int col; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	float temp[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 	float cosine, sine; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-16 01:19:37 +00:00
										 |  |  | 	assert(axis >= 'X' && axis <= 'Z'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 	cosine = (float)cos(angle); | 
					
						
							|  |  |  | 	sine = (float)sin(angle); | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	switch (axis) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		case 'X': | 
					
						
							|  |  |  | 			for (col = 0; col < 4; col++) | 
					
						
							|  |  |  | 				temp[col] = cosine * mat[1][col] + sine * mat[2][col]; | 
					
						
							|  |  |  | 			for (col = 0; col < 4; col++) { | 
					
						
							|  |  |  | 				mat[2][col] = -sine * mat[1][col] + cosine * mat[2][col]; | 
					
						
							|  |  |  | 				mat[1][col] = temp[col]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'Y': | 
					
						
							|  |  |  | 			for (col = 0; col < 4; col++) | 
					
						
							|  |  |  | 				temp[col] = cosine * mat[0][col] - sine * mat[2][col]; | 
					
						
							|  |  |  | 			for (col = 0; col < 4; col++) { | 
					
						
							|  |  |  | 				mat[2][col] = sine * mat[0][col] + cosine * mat[2][col]; | 
					
						
							|  |  |  | 				mat[0][col] = temp[col]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 'Z': | 
					
						
							|  |  |  | 			for (col = 0; col < 4; col++) | 
					
						
							|  |  |  | 				temp[col] = cosine * mat[0][col] + sine * mat[1][col]; | 
					
						
							|  |  |  | 			for (col = 0; col < 4; col++) { | 
					
						
							|  |  |  | 				mat[1][col] = -sine * mat[0][col] + cosine * mat[1][col]; | 
					
						
							|  |  |  | 				mat[0][col] = temp[col]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-03-22 09:30:00 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float srcweight) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | 	float srot[3][3], drot[3][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	float squat[4], dquat[4], fquat[4]; | 
					
						
							| 
									
										
										
										
											2011-12-04 03:35:54 +00:00
										 |  |  | 	float sscale[3], dscale[3], fsize[3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	float rmat[3][3], smat[3][3]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-04 03:35:54 +00:00
										 |  |  | 	mat3_to_rot_size(drot, dscale, dst); | 
					
						
							|  |  |  | 	mat3_to_rot_size(srot, sscale, src); | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mat3_to_quat(dquat, drot); | 
					
						
							|  |  |  | 	mat3_to_quat(squat, srot); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* do blending */ | 
					
						
							|  |  |  | 	interp_qt_qtqt(fquat, dquat, squat, srcweight); | 
					
						
							| 
									
										
										
										
											2011-12-04 03:35:54 +00:00
										 |  |  | 	interp_v3_v3v3(fsize, dscale, sscale, srcweight); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* compose new matrix */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	quat_to_mat3(rmat, fquat); | 
					
						
							|  |  |  | 	size_to_mat3(smat, fsize); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mul_m3_m3m3(out, rmat, smat); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float srcweight) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | 	float sloc[3], dloc[3], floc[3]; | 
					
						
							|  |  |  | 	float srot[3][3], drot[3][3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	float squat[4], dquat[4], fquat[4]; | 
					
						
							| 
									
										
										
										
											2011-12-04 03:35:54 +00:00
										 |  |  | 	float sscale[3], dscale[3], fsize[3]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-04 03:35:54 +00:00
										 |  |  | 	mat4_to_loc_rot_size(dloc, drot, dscale, dst); | 
					
						
							|  |  |  | 	mat4_to_loc_rot_size(sloc, srot, sscale, src); | 
					
						
							| 
									
										
										
										
											2010-11-22 10:39:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mat3_to_quat(dquat, drot); | 
					
						
							|  |  |  | 	mat3_to_quat(squat, srot); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* do blending */ | 
					
						
							|  |  |  | 	interp_v3_v3v3(floc, dloc, sloc, srcweight); | 
					
						
							|  |  |  | 	interp_qt_qtqt(fquat, dquat, squat, srcweight); | 
					
						
							| 
									
										
										
										
											2011-12-04 03:35:54 +00:00
										 |  |  | 	interp_v3_v3v3(fsize, dscale, sscale, srcweight); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* compose new matrix */ | 
					
						
							|  |  |  | 	loc_quat_size_to_mat4(out, floc, fquat, fsize); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-30 13:15:39 +00:00
										 |  |  | int is_negative_m3(float mat[][3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float vec[3]; | 
					
						
							|  |  |  | 	cross_v3_v3v3(vec, mat[0], mat[1]); | 
					
						
							|  |  |  | 	return (dot_v3v3(vec, mat[2]) < 0.0f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int is_negative_m4(float mat[][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float vec[3]; | 
					
						
							|  |  |  | 	cross_v3_v3v3(vec, mat[0], mat[1]); | 
					
						
							|  |  |  | 	return (dot_v3v3(vec, mat[2]) < 0.0f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /* make a 4x4 matrix out of 3 transform components */ | 
					
						
							|  |  |  | /* matrices are made in the order: scale * rot * loc */ | 
					
						
							| 
									
										
										
										
											2012-07-06 23:56:59 +00:00
										 |  |  | /* TODO: need to have a version that allows for rotation order... */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 03:56:50 +00:00
										 |  |  | void loc_eul_size_to_mat4(float mat[4][4], const float loc[3], const float eul[3], const float size[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float rmat[3][3], smat[3][3], tmat[3][3]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-02 16:05:54 +00:00
										 |  |  | 	/* initialize new matrix */ | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	unit_m4(mat); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* make rotation + scaling part */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	eul_to_mat3(rmat, eul); | 
					
						
							|  |  |  | 	size_to_mat3(smat, size); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mul_m3_m3m3(tmat, rmat, smat); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* copy rot/scale part to output matrix*/ | 
					
						
							|  |  |  | 	copy_m4_m3(mat, tmat); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* copy location to matrix */ | 
					
						
							|  |  |  | 	mat[3][0] = loc[0]; | 
					
						
							|  |  |  | 	mat[3][1] = loc[1]; | 
					
						
							|  |  |  | 	mat[3][2] = loc[2]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* make a 4x4 matrix out of 3 transform components */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /* matrices are made in the order: scale * rot * loc */ | 
					
						
							| 
									
										
										
										
											2010-10-22 03:56:50 +00:00
										 |  |  | 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) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float rmat[3][3], smat[3][3], tmat[3][3]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-02 16:05:54 +00:00
										 |  |  | 	/* initialize new matrix */ | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	unit_m4(mat); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* make rotation + scaling part */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	eulO_to_mat3(rmat, eul, rotOrder); | 
					
						
							|  |  |  | 	size_to_mat3(smat, size); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mul_m3_m3m3(tmat, rmat, smat); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* copy rot/scale part to output matrix*/ | 
					
						
							|  |  |  | 	copy_m4_m3(mat, tmat); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* copy location to matrix */ | 
					
						
							|  |  |  | 	mat[3][0] = loc[0]; | 
					
						
							|  |  |  | 	mat[3][1] = loc[1]; | 
					
						
							|  |  |  | 	mat[3][2] = loc[2]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* make a 4x4 matrix out of 3 transform components */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /* matrices are made in the order: scale * rot * loc */ | 
					
						
							| 
									
										
										
										
											2010-10-22 03:56:50 +00:00
										 |  |  | void loc_quat_size_to_mat4(float mat[4][4], const float loc[3], const float quat[4], const float size[3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float rmat[3][3], smat[3][3], tmat[3][3]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-02 16:05:54 +00:00
										 |  |  | 	/* initialize new matrix */ | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	unit_m4(mat); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* make rotation + scaling part */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	quat_to_mat3(rmat, quat); | 
					
						
							|  |  |  | 	size_to_mat3(smat, size); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	mul_m3_m3m3(tmat, rmat, smat); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* copy rot/scale part to output matrix*/ | 
					
						
							|  |  |  | 	copy_m4_m3(mat, tmat); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	/* copy location to matrix */ | 
					
						
							|  |  |  | 	mat[3][0] = loc[0]; | 
					
						
							|  |  |  | 	mat[3][1] = loc[1]; | 
					
						
							|  |  |  | 	mat[3][2] = loc[2]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 03:56:50 +00:00
										 |  |  | 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]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float q[4]; | 
					
						
							|  |  |  | 	axis_angle_to_quat(q, axis, angle); | 
					
						
							|  |  |  | 	loc_quat_size_to_mat4(mat, loc, q, size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | /*********************************** Other ***********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-06 13:49:09 +00:00
										 |  |  | void print_m3(const char *str, float m[][3]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	printf("%s\n", str); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	printf("%f %f %f\n", m[0][0], m[1][0], m[2][0]); | 
					
						
							|  |  |  | 	printf("%f %f %f\n", m[0][1], m[1][1], m[2][1]); | 
					
						
							|  |  |  | 	printf("%f %f %f\n", m[0][2], m[1][2], m[2][2]); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	printf("\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-06 13:49:09 +00:00
										 |  |  | void print_m4(const char *str, float m[][4]) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	printf("%s\n", str); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	printf("%f %f %f %f\n", m[0][0], m[1][0], m[2][0], m[3][0]); | 
					
						
							|  |  |  | 	printf("%f %f %f %f\n", m[0][1], m[1][1], m[2][1], m[3][1]); | 
					
						
							|  |  |  | 	printf("%f %f %f %f\n", m[0][2], m[1][2], m[2][2], m[3][2]); | 
					
						
							|  |  |  | 	printf("%f %f %f %f\n", m[0][3], m[1][3], m[2][3], m[3][3]); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:42:41 +00:00
										 |  |  | 	printf("\n"); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*********************************** SVD ************************************
 | 
					
						
							|  |  |  |  * from TNT matrix library | 
					
						
							| 
									
										
										
										
											2012-03-03 20:19:11 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  |  * Compute the Single Value Decomposition of an arbitrary matrix A | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  |  * That is compute the 3 matrices U,W,V with U column orthogonal (m,n) | 
					
						
							|  |  |  |  * ,W a diagonal matrix and V an orthogonal square matrix s.t. | 
					
						
							|  |  |  |  * A = U.W.Vt. From this decomposition it is trivial to compute the | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  |  * (pseudo-inverse) of A as Ainv = V.Winv.tranpose(U). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float A[4][4]; | 
					
						
							|  |  |  | 	float work1[4], work2[4]; | 
					
						
							|  |  |  | 	int m = 4; | 
					
						
							|  |  |  | 	int n = 4; | 
					
						
							|  |  |  | 	int maxiter = 200; | 
					
						
							| 
									
										
										
										
											2012-10-23 13:28:22 +00:00
										 |  |  | 	int nu = min_ff(m, n); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	float *work = work1; | 
					
						
							|  |  |  | 	float *e = work2; | 
					
						
							|  |  |  | 	float eps; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	int i = 0, j = 0, k = 0, p, pp, iter; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 	/* Reduce A to bidiagonal form, storing the diagonal elements
 | 
					
						
							|  |  |  | 	 * in s and the super-diagonal elements in e. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 13:28:22 +00:00
										 |  |  | 	int nct = min_ff(m - 1, n); | 
					
						
							|  |  |  | 	int nrt = max_ff(0, min_ff(n - 2, m)); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	copy_m4_m4(A, A_); | 
					
						
							|  |  |  | 	zero_m4(U); | 
					
						
							|  |  |  | 	zero_v4(s); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 13:28:22 +00:00
										 |  |  | 	for (k = 0; k < max_ff(nct, nrt); k++) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 		if (k < nct) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 			/* Compute the transformation for the k-th column and
 | 
					
						
							|  |  |  | 			 * place the k-th diagonal in s[k]. | 
					
						
							|  |  |  | 			 * Compute 2-norm of k-th column without under/overflow. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			s[k] = 0; | 
					
						
							|  |  |  | 			for (i = k; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				s[k] = hypotf(s[k], A[i][k]); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if (s[k] != 0.0f) { | 
					
						
							|  |  |  | 				float invsk; | 
					
						
							|  |  |  | 				if (A[k][k] < 0.0f) { | 
					
						
							|  |  |  | 					s[k] = -s[k]; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				invsk = 1.0f / s[k]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				for (i = k; i < m; i++) { | 
					
						
							|  |  |  | 					A[i][k] *= invsk; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				A[k][k] += 1.0f; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			s[k] = -s[k]; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		for (j = k + 1; j < n; j++) { | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 			if ((k < nct) && (s[k] != 0.0f)) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 				/* Apply the transformation. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				float t = 0; | 
					
						
							|  |  |  | 				for (i = k; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					t += A[i][k] * A[i][j]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				t = -t / A[k][k]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				for (i = k; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					A[i][j] += t * A[i][k]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 			/* Place the k-th row of A into e for the */ | 
					
						
							|  |  |  | 			/* subsequent calculation of the row transformation. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			e[j] = A[k][j]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (k < nct) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 			/* Place the transformation in U for subsequent back
 | 
					
						
							|  |  |  | 			 * multiplication. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			for (i = k; i < m; i++) | 
					
						
							|  |  |  | 				U[i][k] = A[i][k]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (k < nrt) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 			/* Compute the k-th row transformation and place the
 | 
					
						
							|  |  |  | 			 * k-th super-diagonal in e[k]. | 
					
						
							|  |  |  | 			 * Compute 2-norm without under/overflow. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			e[k] = 0; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			for (i = k + 1; i < n; i++) { | 
					
						
							|  |  |  | 				e[k] = hypotf(e[k], e[i]); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if (e[k] != 0.0f) { | 
					
						
							|  |  |  | 				float invek; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				if (e[k + 1] < 0.0f) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					e[k] = -e[k]; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				invek = 1.0f / e[k]; | 
					
						
							|  |  |  | 				for (i = k + 1; i < n; i++) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					e[i] *= invek; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				e[k + 1] += 1.0f; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			e[k] = -e[k]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			if ((k + 1 < m) & (e[k] != 0.0f)) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				float invek1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 				/* Apply the transformation. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				for (i = k + 1; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					work[i] = 0.0f; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				for (j = k + 1; j < n; j++) { | 
					
						
							|  |  |  | 					for (i = k + 1; i < m; i++) { | 
					
						
							|  |  |  | 						work[i] += e[j] * A[i][j]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				invek1 = 1.0f / e[k + 1]; | 
					
						
							|  |  |  | 				for (j = k + 1; j < n; j++) { | 
					
						
							|  |  |  | 					float t = -e[j] * invek1; | 
					
						
							|  |  |  | 					for (i = k + 1; i < m; i++) { | 
					
						
							|  |  |  | 						A[i][j] += t * work[i]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 			/* Place the transformation in V for subsequent
 | 
					
						
							|  |  |  | 			 * back multiplication. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			for (i = k + 1; i < n; i++) | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				V[i][k] = e[i]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 	/* Set up the final bidiagonal matrix or order p. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 13:28:22 +00:00
										 |  |  | 	p = min_ff(n, m + 1); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 	if (nct < n) { | 
					
						
							|  |  |  | 		s[nct] = A[nct][nct]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (m < p) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		s[p - 1] = 0.0f; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	if (nrt + 1 < p) { | 
					
						
							|  |  |  | 		e[nrt] = A[nrt][p - 1]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	e[p - 1] = 0.0f; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 	/* If required, generate U. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (j = nct; j < nu; j++) { | 
					
						
							|  |  |  | 		for (i = 0; i < m; i++) { | 
					
						
							|  |  |  | 			U[i][j] = 0.0f; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		U[j][j] = 1.0f; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (k = nct - 1; k >= 0; k--) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 		if (s[k] != 0.0f) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			for (j = k + 1; j < nu; j++) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				float t = 0; | 
					
						
							|  |  |  | 				for (i = k; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					t += U[i][k] * U[i][j]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				t = -t / U[k][k]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				for (i = k; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					U[i][j] += t * U[i][k]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			for (i = k; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				U[i][k] = -U[i][k]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			U[k][k] = 1.0f + U[k][k]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			for (i = 0; i < k - 1; i++) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				U[i][k] = 0.0f; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			for (i = 0; i < m; i++) { | 
					
						
							|  |  |  | 				U[i][k] = 0.0f; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			U[k][k] = 1.0f; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 	/* If required, generate V. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (k = n - 1; k >= 0; k--) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 		if ((k < nrt) & (e[k] != 0.0f)) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			for (j = k + 1; j < nu; j++) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				float t = 0; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				for (i = k + 1; i < n; i++) { | 
					
						
							|  |  |  | 					t += V[i][k] * V[i][j]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				t = -t / V[k + 1][k]; | 
					
						
							|  |  |  | 				for (i = k + 1; i < n; i++) { | 
					
						
							|  |  |  | 					V[i][j] += t * V[i][k]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for (i = 0; i < n; i++) { | 
					
						
							|  |  |  | 			V[i][k] = 0.0f; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		V[k][k] = 1.0f; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 	/* Main iteration loop for the singular values. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	pp = p - 1; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 	iter = 0; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	eps = powf(2.0f, -52.0f); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 	while (p > 0) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		int kase = 0; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 		/* Test for maximum iterations to avoid infinite loop */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		if (maxiter == 0) | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		maxiter--; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 		/* This section of the program inspects for
 | 
					
						
							|  |  |  | 		 * negligible elements in the s and e arrays.  On | 
					
						
							|  |  |  | 		 * completion the variables kase and k are set as follows. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * kase = 1	  if s(p) and e[k - 1] are negligible and k<p | 
					
						
							|  |  |  | 		 * kase = 2	  if s(k) is negligible and k<p | 
					
						
							|  |  |  | 		 * kase = 3	  if e[k - 1] is negligible, k<p, and | 
					
						
							|  |  |  | 		 *               s(k), ..., s(p) are not negligible (qr step). | 
					
						
							|  |  |  | 		 * kase = 4	  if e(p - 1) is negligible (convergence). */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		for (k = p - 2; k >= -1; k--) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			if (k == -1) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			if (fabsf(e[k]) <= eps * (fabsf(s[k]) + fabsf(s[k + 1]))) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				e[k] = 0.0f; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 		if (k == p - 2) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			kase = 4; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			int ks; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			for (ks = p - 1; ks >= k; ks--) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				float t; | 
					
						
							|  |  |  | 				if (ks == k) { | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				t = (ks != p ? fabsf(e[ks]) : 0.f) + | 
					
						
							| 
									
										
										
										
											2012-03-25 15:56:17 +00:00
										 |  |  | 				    (ks != k + 1 ? fabsf(e[ks - 1]) : 0.0f); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				if (fabsf(s[ks]) <= eps * t) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					s[ks] = 0.0f; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (ks == k) { | 
					
						
							|  |  |  | 				kase = 3; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			else if (ks == p - 1) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				kase = 1; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:18:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				kase = 2; | 
					
						
							|  |  |  | 				k = ks; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		k++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 		/* Perform the task indicated by kase. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		switch (kase) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 			/* Deflate negligible s(p). */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			case 1: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				float f = e[p - 2]; | 
					
						
							|  |  |  | 				e[p - 2] = 0.0f; | 
					
						
							|  |  |  | 				for (j = p - 2; j >= k; j--) { | 
					
						
							|  |  |  | 					float t = hypotf(s[j], f); | 
					
						
							|  |  |  | 					float invt = 1.0f / t; | 
					
						
							|  |  |  | 					float cs = s[j] * invt; | 
					
						
							|  |  |  | 					float sn = f * invt; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					s[j] = t; | 
					
						
							|  |  |  | 					if (j != k) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 						f = -sn * e[j - 1]; | 
					
						
							|  |  |  | 						e[j - 1] = cs * e[j - 1]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					for (i = 0; i < n; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 						t = cs * V[i][j] + sn * V[i][p - 1]; | 
					
						
							|  |  |  | 						V[i][p - 1] = -sn * V[i][j] + cs * V[i][p - 1]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 						V[i][j] = t; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 			/* Split at negligible s(k). */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			case 2: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				float f = e[k - 1]; | 
					
						
							|  |  |  | 				e[k - 1] = 0.0f; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				for (j = k; j < p; j++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					float t = hypotf(s[j], f); | 
					
						
							|  |  |  | 					float invt = 1.0f / t; | 
					
						
							|  |  |  | 					float cs = s[j] * invt; | 
					
						
							|  |  |  | 					float sn = f * invt; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					s[j] = t; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					f = -sn * e[j]; | 
					
						
							|  |  |  | 					e[j] = cs * e[j]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					for (i = 0; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 						t = cs * U[i][j] + sn * U[i][k - 1]; | 
					
						
							|  |  |  | 						U[i][k - 1] = -sn * U[i][j] + cs * U[i][k - 1]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 						U[i][j] = t; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 			/* Perform one qr step. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			case 3: | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 				/* Calculate the shift. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 13:28:22 +00:00
										 |  |  | 				float scale = max_ff(max_ff(max_ff(max_ff( | 
					
						
							| 
									
										
										
										
											2012-04-29 15:47:02 +00:00
										 |  |  | 				                   fabsf(s[p - 1]), fabsf(s[p - 2])), fabsf(e[p - 2])), | 
					
						
							|  |  |  | 				                   fabsf(s[k])), fabsf(e[k])); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				float invscale = 1.0f / scale; | 
					
						
							|  |  |  | 				float sp = s[p - 1] * invscale; | 
					
						
							|  |  |  | 				float spm1 = s[p - 2] * invscale; | 
					
						
							|  |  |  | 				float epm1 = e[p - 2] * invscale; | 
					
						
							|  |  |  | 				float sk = s[k] * invscale; | 
					
						
							|  |  |  | 				float ek = e[k] * invscale; | 
					
						
							|  |  |  | 				float b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) * 0.5f; | 
					
						
							|  |  |  | 				float c = (sp * epm1) * (sp * epm1); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				float shift = 0.0f; | 
					
						
							|  |  |  | 				float f, g; | 
					
						
							|  |  |  | 				if ((b != 0.0f) || (c != 0.0f)) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					shift = sqrtf(b * b + c); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					if (b < 0.0f) { | 
					
						
							|  |  |  | 						shift = -shift; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					shift = c / (b + shift); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				f = (sk + sp) * (sk - sp) + shift; | 
					
						
							|  |  |  | 				g = sk * ek; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 				/* Chase zeros. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				for (j = k; j < p - 1; j++) { | 
					
						
							|  |  |  | 					float t = hypotf(f, g); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					/* division by zero checks added to avoid NaN (brecht) */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					float cs = (t == 0.0f) ? 0.0f : f / t; | 
					
						
							|  |  |  | 					float sn = (t == 0.0f) ? 0.0f : g / t; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					if (j != k) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 						e[j - 1] = t; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					f = cs * s[j] + sn * e[j]; | 
					
						
							|  |  |  | 					e[j] = cs * e[j] - sn * s[j]; | 
					
						
							|  |  |  | 					g = sn * s[j + 1]; | 
					
						
							|  |  |  | 					s[j + 1] = cs * s[j + 1]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					for (i = 0; i < n; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 						t = cs * V[i][j] + sn * V[i][j + 1]; | 
					
						
							|  |  |  | 						V[i][j + 1] = -sn * V[i][j] + cs * V[i][j + 1]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 						V[i][j] = t; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					t = hypotf(f, g); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					/* division by zero checks added to avoid NaN (brecht) */ | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					cs = (t == 0.0f) ? 0.0f : f / t; | 
					
						
							|  |  |  | 					sn = (t == 0.0f) ? 0.0f : g / t; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 					s[j] = t; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					f = cs * e[j] + sn * s[j + 1]; | 
					
						
							|  |  |  | 					s[j + 1] = -sn * e[j] + cs * s[j + 1]; | 
					
						
							|  |  |  | 					g = sn * e[j + 1]; | 
					
						
							|  |  |  | 					e[j + 1] = cs * e[j + 1]; | 
					
						
							|  |  |  | 					if (j < m - 1) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 						for (i = 0; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 							t = cs * U[i][j] + sn * U[i][j + 1]; | 
					
						
							|  |  |  | 							U[i][j + 1] = -sn * U[i][j] + cs * U[i][j + 1]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 							U[i][j] = t; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				e[p - 2] = f; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 				iter = iter + 1; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 			/* Convergence. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 			case 4: | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 				/* Make the singular values positive. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (s[k] <= 0.0f) { | 
					
						
							|  |  |  | 					s[k] = (s[k] < 0.0f ? -s[k] : 0.0f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					for (i = 0; i <= pp; i++) | 
					
						
							|  |  |  | 						V[i][k] = -V[i][k]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-20 20:20:02 +00:00
										 |  |  | 				/* Order the singular values. */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				while (k < pp) { | 
					
						
							|  |  |  | 					float t; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					if (s[k] >= s[k + 1]) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					t = s[k]; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					s[k] = s[k + 1]; | 
					
						
							|  |  |  | 					s[k + 1] = t; | 
					
						
							|  |  |  | 					if (k < n - 1) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 						for (i = 0; i < n; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 							t = V[i][k + 1]; | 
					
						
							|  |  |  | 							V[i][k + 1] = V[i][k]; | 
					
						
							|  |  |  | 							V[i][k] = t; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 					if (k < m - 1) { | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 						for (i = 0; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 							t = U[i][k + 1]; | 
					
						
							|  |  |  | 							U[i][k + 1] = U[i][k]; | 
					
						
							|  |  |  | 							U[i][k] = t; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					k++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				iter = 0; | 
					
						
							|  |  |  | 				p--; | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* compute moon-penrose pseudo inverse of matrix, singular values
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:19:11 +00:00
										 |  |  | 	 * below epsilon are ignored for stability (truncated SVD) */ | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 	float V[4][4], W[4], Wm[4][4], U[4][4]; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	transpose_m4(A); | 
					
						
							|  |  |  | 	svd_m4(V, W, U, A); | 
					
						
							|  |  |  | 	transpose_m4(U); | 
					
						
							|  |  |  | 	transpose_m4(V); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	zero_m4(Wm); | 
					
						
							| 
									
										
										
										
											2012-03-25 12:41:58 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) | 
					
						
							|  |  |  | 		Wm[i][i] = (W[i] < epsilon) ? 0.0f : 1.0f / W[i]; | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	transpose_m4(V); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	mul_serie_m4(Ainv, U, Wm, V, NULL, NULL, NULL, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2010-06-22 15:20:06 +00:00
										 |  |  | } |