Blender  V2.93
math_matrix.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  *
19  * The Original Code is: some of this file.
20  */
21 
26 #include "BLI_math.h"
27 
28 #include "BLI_strict_flags.h"
29 
30 #ifndef MATH_STANDALONE
31 # include "eigen_capi.h"
32 #endif
33 
34 /********************************* Init **************************************/
35 
36 void zero_m2(float m[2][2])
37 {
38  memset(m, 0, sizeof(float[2][2]));
39 }
40 
41 void zero_m3(float m[3][3])
42 {
43  memset(m, 0, sizeof(float[3][3]));
44 }
45 
46 void zero_m4(float m[4][4])
47 {
48  memset(m, 0, sizeof(float[4][4]));
49 }
50 
51 void unit_m2(float m[2][2])
52 {
53  m[0][0] = m[1][1] = 1.0f;
54  m[0][1] = 0.0f;
55  m[1][0] = 0.0f;
56 }
57 
58 void unit_m3(float m[3][3])
59 {
60  m[0][0] = m[1][1] = m[2][2] = 1.0f;
61  m[0][1] = m[0][2] = 0.0f;
62  m[1][0] = m[1][2] = 0.0f;
63  m[2][0] = m[2][1] = 0.0f;
64 }
65 
66 void unit_m4(float m[4][4])
67 {
68  m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
69  m[0][1] = m[0][2] = m[0][3] = 0.0f;
70  m[1][0] = m[1][2] = m[1][3] = 0.0f;
71  m[2][0] = m[2][1] = m[2][3] = 0.0f;
72  m[3][0] = m[3][1] = m[3][2] = 0.0f;
73 }
74 
75 void unit_m4_db(double m[4][4])
76 {
77  m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
78  m[0][1] = m[0][2] = m[0][3] = 0.0f;
79  m[1][0] = m[1][2] = m[1][3] = 0.0f;
80  m[2][0] = m[2][1] = m[2][3] = 0.0f;
81  m[3][0] = m[3][1] = m[3][2] = 0.0f;
82 }
83 
84 void copy_m2_m2(float m1[2][2], const float m2[2][2])
85 {
86  memcpy(m1, m2, sizeof(float[2][2]));
87 }
88 
89 void copy_m3_m3(float m1[3][3], const float m2[3][3])
90 {
91  /* destination comes first: */
92  memcpy(m1, m2, sizeof(float[3][3]));
93 }
94 
95 void copy_m4_m4(float m1[4][4], const float m2[4][4])
96 {
97  memcpy(m1, m2, sizeof(float[4][4]));
98 }
99 
100 void copy_m4_m4_db(double m1[4][4], const double m2[4][4])
101 {
102  memcpy(m1, m2, sizeof(double[4][4]));
103 }
104 
105 void copy_m3_m4(float m1[3][3], const float m2[4][4])
106 {
107  m1[0][0] = m2[0][0];
108  m1[0][1] = m2[0][1];
109  m1[0][2] = m2[0][2];
110 
111  m1[1][0] = m2[1][0];
112  m1[1][1] = m2[1][1];
113  m1[1][2] = m2[1][2];
114 
115  m1[2][0] = m2[2][0];
116  m1[2][1] = m2[2][1];
117  m1[2][2] = m2[2][2];
118 }
119 
120 void copy_m4_m3(float m1[4][4], const float m2[3][3]) /* no clear */
121 {
122  m1[0][0] = m2[0][0];
123  m1[0][1] = m2[0][1];
124  m1[0][2] = m2[0][2];
125 
126  m1[1][0] = m2[1][0];
127  m1[1][1] = m2[1][1];
128  m1[1][2] = m2[1][2];
129 
130  m1[2][0] = m2[2][0];
131  m1[2][1] = m2[2][1];
132  m1[2][2] = m2[2][2];
133 
134  /* Reevan's Bugfix */
135  m1[0][3] = 0.0f;
136  m1[1][3] = 0.0f;
137  m1[2][3] = 0.0f;
138 
139  m1[3][0] = 0.0f;
140  m1[3][1] = 0.0f;
141  m1[3][2] = 0.0f;
142  m1[3][3] = 1.0f;
143 }
144 
145 void copy_m3_m2(float m1[3][3], const float m2[2][2])
146 {
147  m1[0][0] = m2[0][0];
148  m1[0][1] = m2[0][1];
149  m1[0][2] = 0.0f;
150 
151  m1[1][0] = m2[1][0];
152  m1[1][1] = m2[1][1];
153  m1[1][2] = 0.0f;
154 
155  m1[2][0] = 0.0f;
156  m1[2][1] = 0.0f;
157  m1[2][2] = 1.0f;
158 }
159 
160 void copy_m4_m2(float m1[4][4], const float m2[2][2])
161 {
162  m1[0][0] = m2[0][0];
163  m1[0][1] = m2[0][1];
164  m1[0][2] = 0.0f;
165  m1[0][3] = 0.0f;
166 
167  m1[1][0] = m2[1][0];
168  m1[1][1] = m2[1][1];
169  m1[1][2] = 0.0f;
170  m1[1][3] = 0.0f;
171 
172  m1[2][0] = 0.0f;
173  m1[2][1] = 0.0f;
174  m1[2][2] = 1.0f;
175  m1[2][3] = 0.0f;
176 
177  m1[3][0] = 0.0f;
178  m1[3][1] = 0.0f;
179  m1[3][2] = 0.0f;
180  m1[3][3] = 1.0f;
181 }
182 
183 void copy_m4d_m4(double m1[4][4], const float m2[4][4])
184 {
185  m1[0][0] = m2[0][0];
186  m1[0][1] = m2[0][1];
187  m1[0][2] = m2[0][2];
188  m1[0][3] = m2[0][3];
189 
190  m1[1][0] = m2[1][0];
191  m1[1][1] = m2[1][1];
192  m1[1][2] = m2[1][2];
193  m1[1][3] = m2[1][3];
194 
195  m1[2][0] = m2[2][0];
196  m1[2][1] = m2[2][1];
197  m1[2][2] = m2[2][2];
198  m1[2][3] = m2[2][3];
199 
200  m1[3][0] = m2[3][0];
201  m1[3][1] = m2[3][1];
202  m1[3][2] = m2[3][2];
203  m1[3][3] = m2[3][3];
204 }
205 
206 void copy_m3_m3d(float m1[3][3], const double m2[3][3])
207 {
208  /* Keep it stupid simple for better data flow in CPU. */
209  m1[0][0] = (float)m2[0][0];
210  m1[0][1] = (float)m2[0][1];
211  m1[0][2] = (float)m2[0][2];
212 
213  m1[1][0] = (float)m2[1][0];
214  m1[1][1] = (float)m2[1][1];
215  m1[1][2] = (float)m2[1][2];
216 
217  m1[2][0] = (float)m2[2][0];
218  m1[2][1] = (float)m2[2][1];
219  m1[2][2] = (float)m2[2][2];
220 }
221 
222 void swap_m3m3(float m1[3][3], float m2[3][3])
223 {
224  float t;
225  int i, j;
226 
227  for (i = 0; i < 3; i++) {
228  for (j = 0; j < 3; j++) {
229  t = m1[i][j];
230  m1[i][j] = m2[i][j];
231  m2[i][j] = t;
232  }
233  }
234 }
235 
236 void swap_m4m4(float m1[4][4], float m2[4][4])
237 {
238  float t;
239  int i, j;
240 
241  for (i = 0; i < 4; i++) {
242  for (j = 0; j < 4; j++) {
243  t = m1[i][j];
244  m1[i][j] = m2[i][j];
245  m2[i][j] = t;
246  }
247  }
248 }
249 
250 void shuffle_m4(float R[4][4], const int index[4])
251 {
252  zero_m4(R);
253  for (int k = 0; k < 4; k++) {
254  if (index[k] >= 0) {
255  R[index[k]][k] = 1.0f;
256  }
257  }
258 }
259 
260 /******************************** Arithmetic *********************************/
261 
262 void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
263 {
264  if (A == R) {
265  mul_m4_m4_post(R, B);
266  }
267  else if (B == R) {
268  mul_m4_m4_pre(R, A);
269  }
270  else {
271  mul_m4_m4m4_uniq(R, A, B);
272  }
273 }
274 
275 void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4])
276 {
277  BLI_assert(!ELEM(R, A, B));
278 
279  /* matrix product: R[j][k] = A[j][i] . B[i][k] */
280 #ifdef BLI_HAVE_SSE2
281  __m128 A0 = _mm_loadu_ps(A[0]);
282  __m128 A1 = _mm_loadu_ps(A[1]);
283  __m128 A2 = _mm_loadu_ps(A[2]);
284  __m128 A3 = _mm_loadu_ps(A[3]);
285 
286  for (int i = 0; i < 4; i++) {
287  __m128 B0 = _mm_set1_ps(B[i][0]);
288  __m128 B1 = _mm_set1_ps(B[i][1]);
289  __m128 B2 = _mm_set1_ps(B[i][2]);
290  __m128 B3 = _mm_set1_ps(B[i][3]);
291 
292  __m128 sum = _mm_add_ps(_mm_add_ps(_mm_mul_ps(B0, A0), _mm_mul_ps(B1, A1)),
293  _mm_add_ps(_mm_mul_ps(B2, A2), _mm_mul_ps(B3, A3)));
294 
295  _mm_storeu_ps(R[i], sum);
296  }
297 #else
298  R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0] + B[0][3] * A[3][0];
299  R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1] + B[0][3] * A[3][1];
300  R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2] + B[0][3] * A[3][2];
301  R[0][3] = B[0][0] * A[0][3] + B[0][1] * A[1][3] + B[0][2] * A[2][3] + B[0][3] * A[3][3];
302 
303  R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0] + B[1][3] * A[3][0];
304  R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1] + B[1][3] * A[3][1];
305  R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2] + B[1][3] * A[3][2];
306  R[1][3] = B[1][0] * A[0][3] + B[1][1] * A[1][3] + B[1][2] * A[2][3] + B[1][3] * A[3][3];
307 
308  R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0] + B[2][3] * A[3][0];
309  R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1] + B[2][3] * A[3][1];
310  R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2] + B[2][3] * A[3][2];
311  R[2][3] = B[2][0] * A[0][3] + B[2][1] * A[1][3] + B[2][2] * A[2][3] + B[2][3] * A[3][3];
312 
313  R[3][0] = B[3][0] * A[0][0] + B[3][1] * A[1][0] + B[3][2] * A[2][0] + B[3][3] * A[3][0];
314  R[3][1] = B[3][0] * A[0][1] + B[3][1] * A[1][1] + B[3][2] * A[2][1] + B[3][3] * A[3][1];
315  R[3][2] = B[3][0] * A[0][2] + B[3][1] * A[1][2] + B[3][2] * A[2][2] + B[3][3] * A[3][2];
316  R[3][3] = B[3][0] * A[0][3] + B[3][1] * A[1][3] + B[3][2] * A[2][3] + B[3][3] * A[3][3];
317 #endif
318 }
319 
320 void mul_m4_m4m4_db_uniq(double R[4][4], const double A[4][4], const double B[4][4])
321 {
322  BLI_assert(!ELEM(R, A, B));
323 
324  /* matrix product: R[j][k] = A[j][i] . B[i][k] */
325 
326  R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0] + B[0][3] * A[3][0];
327  R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1] + B[0][3] * A[3][1];
328  R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2] + B[0][3] * A[3][2];
329  R[0][3] = B[0][0] * A[0][3] + B[0][1] * A[1][3] + B[0][2] * A[2][3] + B[0][3] * A[3][3];
330 
331  R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0] + B[1][3] * A[3][0];
332  R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1] + B[1][3] * A[3][1];
333  R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2] + B[1][3] * A[3][2];
334  R[1][3] = B[1][0] * A[0][3] + B[1][1] * A[1][3] + B[1][2] * A[2][3] + B[1][3] * A[3][3];
335 
336  R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0] + B[2][3] * A[3][0];
337  R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1] + B[2][3] * A[3][1];
338  R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2] + B[2][3] * A[3][2];
339  R[2][3] = B[2][0] * A[0][3] + B[2][1] * A[1][3] + B[2][2] * A[2][3] + B[2][3] * A[3][3];
340 
341  R[3][0] = B[3][0] * A[0][0] + B[3][1] * A[1][0] + B[3][2] * A[2][0] + B[3][3] * A[3][0];
342  R[3][1] = B[3][0] * A[0][1] + B[3][1] * A[1][1] + B[3][2] * A[2][1] + B[3][3] * A[3][1];
343  R[3][2] = B[3][0] * A[0][2] + B[3][1] * A[1][2] + B[3][2] * A[2][2] + B[3][3] * A[3][2];
344  R[3][3] = B[3][0] * A[0][3] + B[3][1] * A[1][3] + B[3][2] * A[2][3] + B[3][3] * A[3][3];
345 }
346 
347 void mul_m4db_m4db_m4fl_uniq(double R[4][4], const double A[4][4], const float B[4][4])
348 {
349  /* Remove second check since types don't match. */
350  BLI_assert(!ELEM(R, A /*, B */));
351 
352  /* matrix product: R[j][k] = A[j][i] . B[i][k] */
353 
354  R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0] + B[0][3] * A[3][0];
355  R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1] + B[0][3] * A[3][1];
356  R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2] + B[0][3] * A[3][2];
357  R[0][3] = B[0][0] * A[0][3] + B[0][1] * A[1][3] + B[0][2] * A[2][3] + B[0][3] * A[3][3];
358 
359  R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0] + B[1][3] * A[3][0];
360  R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1] + B[1][3] * A[3][1];
361  R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2] + B[1][3] * A[3][2];
362  R[1][3] = B[1][0] * A[0][3] + B[1][1] * A[1][3] + B[1][2] * A[2][3] + B[1][3] * A[3][3];
363 
364  R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0] + B[2][3] * A[3][0];
365  R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1] + B[2][3] * A[3][1];
366  R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2] + B[2][3] * A[3][2];
367  R[2][3] = B[2][0] * A[0][3] + B[2][1] * A[1][3] + B[2][2] * A[2][3] + B[2][3] * A[3][3];
368 
369  R[3][0] = B[3][0] * A[0][0] + B[3][1] * A[1][0] + B[3][2] * A[2][0] + B[3][3] * A[3][0];
370  R[3][1] = B[3][0] * A[0][1] + B[3][1] * A[1][1] + B[3][2] * A[2][1] + B[3][3] * A[3][1];
371  R[3][2] = B[3][0] * A[0][2] + B[3][1] * A[1][2] + B[3][2] * A[2][2] + B[3][3] * A[3][2];
372  R[3][3] = B[3][0] * A[0][3] + B[3][1] * A[1][3] + B[3][2] * A[2][3] + B[3][3] * A[3][3];
373 }
374 
375 void mul_m4_m4_pre(float R[4][4], const float A[4][4])
376 {
377  BLI_assert(A != R);
378  float B[4][4];
379  copy_m4_m4(B, R);
380  mul_m4_m4m4_uniq(R, A, B);
381 }
382 
383 void mul_m4_m4_post(float R[4][4], const float B[4][4])
384 {
385  BLI_assert(B != R);
386  float A[4][4];
387  copy_m4_m4(A, R);
388  mul_m4_m4m4_uniq(R, A, B);
389 }
390 
391 void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
392 {
393  if (A == R) {
394  mul_m3_m3_post(R, B);
395  }
396  else if (B == R) {
397  mul_m3_m3_pre(R, A);
398  }
399  else {
400  mul_m3_m3m3_uniq(R, A, B);
401  }
402 }
403 
404 void mul_m3_m3_pre(float R[3][3], const float A[3][3])
405 {
406  BLI_assert(A != R);
407  float B[3][3];
408  copy_m3_m3(B, R);
409  mul_m3_m3m3_uniq(R, A, B);
410 }
411 
412 void mul_m3_m3_post(float R[3][3], const float B[3][3])
413 {
414  BLI_assert(B != R);
415  float A[3][3];
416  copy_m3_m3(A, R);
417  mul_m3_m3m3_uniq(R, A, B);
418 }
419 
420 void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3])
421 {
422  BLI_assert(!ELEM(R, A, B));
423 
424  R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0];
425  R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1];
426  R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2];
427 
428  R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0];
429  R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1];
430  R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2];
431 
432  R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0];
433  R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1];
434  R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2];
435 }
436 
437 void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3])
438 {
439  float B_[3][3], A_[4][4];
440 
441  /* copy so it works when R is the same pointer as A or B */
442  /* TODO: avoid copying when matrices are different */
443  copy_m4_m4(A_, A);
444  copy_m3_m3(B_, B);
445 
446  R[0][0] = B_[0][0] * A_[0][0] + B_[0][1] * A_[1][0] + B_[0][2] * A_[2][0];
447  R[0][1] = B_[0][0] * A_[0][1] + B_[0][1] * A_[1][1] + B_[0][2] * A_[2][1];
448  R[0][2] = B_[0][0] * A_[0][2] + B_[0][1] * A_[1][2] + B_[0][2] * A_[2][2];
449  R[1][0] = B_[1][0] * A_[0][0] + B_[1][1] * A_[1][0] + B_[1][2] * A_[2][0];
450  R[1][1] = B_[1][0] * A_[0][1] + B_[1][1] * A_[1][1] + B_[1][2] * A_[2][1];
451  R[1][2] = B_[1][0] * A_[0][2] + B_[1][1] * A_[1][2] + B_[1][2] * A_[2][2];
452  R[2][0] = B_[2][0] * A_[0][0] + B_[2][1] * A_[1][0] + B_[2][2] * A_[2][0];
453  R[2][1] = B_[2][0] * A_[0][1] + B_[2][1] * A_[1][1] + B_[2][2] * A_[2][1];
454  R[2][2] = B_[2][0] * A_[0][2] + B_[2][1] * A_[1][2] + B_[2][2] * A_[2][2];
455 }
456 
457 /* R = A * B, ignore the elements on the 4th row/column of A */
458 void mul_m3_m3m4(float R[3][3], const float A[3][3], const float B[4][4])
459 {
460  float B_[4][4], A_[3][3];
461 
462  /* copy so it works when R is the same pointer as A or B */
463  /* TODO: avoid copying when matrices are different */
464  copy_m3_m3(A_, A);
465  copy_m4_m4(B_, B);
466 
467  /* R[i][j] = B_[i][k] * A_[k][j] */
468  R[0][0] = B_[0][0] * A_[0][0] + B_[0][1] * A_[1][0] + B_[0][2] * A_[2][0];
469  R[0][1] = B_[0][0] * A_[0][1] + B_[0][1] * A_[1][1] + B_[0][2] * A_[2][1];
470  R[0][2] = B_[0][0] * A_[0][2] + B_[0][1] * A_[1][2] + B_[0][2] * A_[2][2];
471 
472  R[1][0] = B_[1][0] * A_[0][0] + B_[1][1] * A_[1][0] + B_[1][2] * A_[2][0];
473  R[1][1] = B_[1][0] * A_[0][1] + B_[1][1] * A_[1][1] + B_[1][2] * A_[2][1];
474  R[1][2] = B_[1][0] * A_[0][2] + B_[1][1] * A_[1][2] + B_[1][2] * A_[2][2];
475 
476  R[2][0] = B_[2][0] * A_[0][0] + B_[2][1] * A_[1][0] + B_[2][2] * A_[2][0];
477  R[2][1] = B_[2][0] * A_[0][1] + B_[2][1] * A_[1][1] + B_[2][2] * A_[2][1];
478  R[2][2] = B_[2][0] * A_[0][2] + B_[2][1] * A_[1][2] + B_[2][2] * A_[2][2];
479 }
480 
481 /* R = A * B, ignore the elements on the 4th row/column of B */
482 void mul_m3_m4m3(float R[3][3], const float A[4][4], const float B[3][3])
483 {
484  float B_[3][3], A_[4][4];
485 
486  /* copy so it works when R is the same pointer as A or B */
487  /* TODO: avoid copying when matrices are different */
488  copy_m4_m4(A_, A);
489  copy_m3_m3(B_, B);
490 
491  /* R[i][j] = B[i][k] * A[k][j] */
492  R[0][0] = B_[0][0] * A_[0][0] + B_[0][1] * A_[1][0] + B_[0][2] * A_[2][0];
493  R[0][1] = B_[0][0] * A_[0][1] + B_[0][1] * A_[1][1] + B_[0][2] * A_[2][1];
494  R[0][2] = B_[0][0] * A_[0][2] + B_[0][1] * A_[1][2] + B_[0][2] * A_[2][2];
495 
496  R[1][0] = B_[1][0] * A_[0][0] + B_[1][1] * A_[1][0] + B_[1][2] * A_[2][0];
497  R[1][1] = B_[1][0] * A_[0][1] + B_[1][1] * A_[1][1] + B_[1][2] * A_[2][1];
498  R[1][2] = B_[1][0] * A_[0][2] + B_[1][1] * A_[1][2] + B_[1][2] * A_[2][2];
499 
500  R[2][0] = B_[2][0] * A_[0][0] + B_[2][1] * A_[1][0] + B_[2][2] * A_[2][0];
501  R[2][1] = B_[2][0] * A_[0][1] + B_[2][1] * A_[1][1] + B_[2][2] * A_[2][1];
502  R[2][2] = B_[2][0] * A_[0][2] + B_[2][1] * A_[1][2] + B_[2][2] * A_[2][2];
503 }
504 
505 void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4])
506 {
507  float B_[4][4], A_[3][3];
508 
509  /* copy so it works when R is the same pointer as A or B */
510  /* TODO: avoid copying when matrices are different */
511  copy_m3_m3(A_, A);
512  copy_m4_m4(B_, B);
513 
514  R[0][0] = B_[0][0] * A_[0][0] + B_[0][1] * A_[1][0] + B_[0][2] * A_[2][0];
515  R[0][1] = B_[0][0] * A_[0][1] + B_[0][1] * A_[1][1] + B_[0][2] * A_[2][1];
516  R[0][2] = B_[0][0] * A_[0][2] + B_[0][1] * A_[1][2] + B_[0][2] * A_[2][2];
517  R[1][0] = B_[1][0] * A_[0][0] + B_[1][1] * A_[1][0] + B_[1][2] * A_[2][0];
518  R[1][1] = B_[1][0] * A_[0][1] + B_[1][1] * A_[1][1] + B_[1][2] * A_[2][1];
519  R[1][2] = B_[1][0] * A_[0][2] + B_[1][1] * A_[1][2] + B_[1][2] * A_[2][2];
520  R[2][0] = B_[2][0] * A_[0][0] + B_[2][1] * A_[1][0] + B_[2][2] * A_[2][0];
521  R[2][1] = B_[2][0] * A_[0][1] + B_[2][1] * A_[1][1] + B_[2][2] * A_[2][1];
522  R[2][2] = B_[2][0] * A_[0][2] + B_[2][1] * A_[1][2] + B_[2][2] * A_[2][2];
523 }
524 
525 void mul_m3_m4m4(float R[3][3], const float A[4][4], const float B[4][4])
526 {
527  R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0];
528  R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1];
529  R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2];
530  R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0];
531  R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1];
532  R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2];
533  R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0];
534  R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1];
535  R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2];
536 }
537 
538 /* -------------------------------------------------------------------- */
542 void _va_mul_m3_series_3(float r[3][3], const float m1[3][3], const float m2[3][3])
543 {
544  mul_m3_m3m3(r, m1, m2);
545 }
546 void _va_mul_m3_series_4(float r[3][3],
547  const float m1[3][3],
548  const float m2[3][3],
549  const float m3[3][3])
550 {
551  mul_m3_m3m3(r, m1, m2);
552  mul_m3_m3m3(r, r, m3);
553 }
554 void _va_mul_m3_series_5(float r[3][3],
555  const float m1[3][3],
556  const float m2[3][3],
557  const float m3[3][3],
558  const float m4[3][3])
559 {
560  mul_m3_m3m3(r, m1, m2);
561  mul_m3_m3m3(r, r, m3);
562  mul_m3_m3m3(r, r, m4);
563 }
564 void _va_mul_m3_series_6(float r[3][3],
565  const float m1[3][3],
566  const float m2[3][3],
567  const float m3[3][3],
568  const float m4[3][3],
569  const float m5[3][3])
570 {
571  mul_m3_m3m3(r, m1, m2);
572  mul_m3_m3m3(r, r, m3);
573  mul_m3_m3m3(r, r, m4);
574  mul_m3_m3m3(r, r, m5);
575 }
576 void _va_mul_m3_series_7(float r[3][3],
577  const float m1[3][3],
578  const float m2[3][3],
579  const float m3[3][3],
580  const float m4[3][3],
581  const float m5[3][3],
582  const float m6[3][3])
583 {
584  mul_m3_m3m3(r, m1, m2);
585  mul_m3_m3m3(r, r, m3);
586  mul_m3_m3m3(r, r, m4);
587  mul_m3_m3m3(r, r, m5);
588  mul_m3_m3m3(r, r, m6);
589 }
590 void _va_mul_m3_series_8(float r[3][3],
591  const float m1[3][3],
592  const float m2[3][3],
593  const float m3[3][3],
594  const float m4[3][3],
595  const float m5[3][3],
596  const float m6[3][3],
597  const float m7[3][3])
598 {
599  mul_m3_m3m3(r, m1, m2);
600  mul_m3_m3m3(r, r, m3);
601  mul_m3_m3m3(r, r, m4);
602  mul_m3_m3m3(r, r, m5);
603  mul_m3_m3m3(r, r, m6);
604  mul_m3_m3m3(r, r, m7);
605 }
606 void _va_mul_m3_series_9(float r[3][3],
607  const float m1[3][3],
608  const float m2[3][3],
609  const float m3[3][3],
610  const float m4[3][3],
611  const float m5[3][3],
612  const float m6[3][3],
613  const float m7[3][3],
614  const float m8[3][3])
615 {
616  mul_m3_m3m3(r, m1, m2);
617  mul_m3_m3m3(r, r, m3);
618  mul_m3_m3m3(r, r, m4);
619  mul_m3_m3m3(r, r, m5);
620  mul_m3_m3m3(r, r, m6);
621  mul_m3_m3m3(r, r, m7);
622  mul_m3_m3m3(r, r, m8);
623 }
626 /* -------------------------------------------------------------------- */
630 void _va_mul_m4_series_3(float r[4][4], const float m1[4][4], const float m2[4][4])
631 {
632  mul_m4_m4m4(r, m1, m2);
633 }
634 void _va_mul_m4_series_4(float r[4][4],
635  const float m1[4][4],
636  const float m2[4][4],
637  const float m3[4][4])
638 {
639  mul_m4_m4m4(r, m1, m2);
640  mul_m4_m4m4(r, r, m3);
641 }
642 void _va_mul_m4_series_5(float r[4][4],
643  const float m1[4][4],
644  const float m2[4][4],
645  const float m3[4][4],
646  const float m4[4][4])
647 {
648  mul_m4_m4m4(r, m1, m2);
649  mul_m4_m4m4(r, r, m3);
650  mul_m4_m4m4(r, r, m4);
651 }
652 void _va_mul_m4_series_6(float r[4][4],
653  const float m1[4][4],
654  const float m2[4][4],
655  const float m3[4][4],
656  const float m4[4][4],
657  const float m5[4][4])
658 {
659  mul_m4_m4m4(r, m1, m2);
660  mul_m4_m4m4(r, r, m3);
661  mul_m4_m4m4(r, r, m4);
662  mul_m4_m4m4(r, r, m5);
663 }
664 void _va_mul_m4_series_7(float r[4][4],
665  const float m1[4][4],
666  const float m2[4][4],
667  const float m3[4][4],
668  const float m4[4][4],
669  const float m5[4][4],
670  const float m6[4][4])
671 {
672  mul_m4_m4m4(r, m1, m2);
673  mul_m4_m4m4(r, r, m3);
674  mul_m4_m4m4(r, r, m4);
675  mul_m4_m4m4(r, r, m5);
676  mul_m4_m4m4(r, r, m6);
677 }
678 void _va_mul_m4_series_8(float r[4][4],
679  const float m1[4][4],
680  const float m2[4][4],
681  const float m3[4][4],
682  const float m4[4][4],
683  const float m5[4][4],
684  const float m6[4][4],
685  const float m7[4][4])
686 {
687  mul_m4_m4m4(r, m1, m2);
688  mul_m4_m4m4(r, r, m3);
689  mul_m4_m4m4(r, r, m4);
690  mul_m4_m4m4(r, r, m5);
691  mul_m4_m4m4(r, r, m6);
692  mul_m4_m4m4(r, r, m7);
693 }
694 void _va_mul_m4_series_9(float r[4][4],
695  const float m1[4][4],
696  const float m2[4][4],
697  const float m3[4][4],
698  const float m4[4][4],
699  const float m5[4][4],
700  const float m6[4][4],
701  const float m7[4][4],
702  const float m8[4][4])
703 {
704  mul_m4_m4m4(r, m1, m2);
705  mul_m4_m4m4(r, r, m3);
706  mul_m4_m4m4(r, r, m4);
707  mul_m4_m4m4(r, r, m5);
708  mul_m4_m4m4(r, r, m6);
709  mul_m4_m4m4(r, r, m7);
710  mul_m4_m4m4(r, r, m8);
711 }
714 void mul_v2_m3v2(float r[2], const float m[3][3], const float v[2])
715 {
716  float temp[3], warped[3];
717 
718  copy_v2_v2(temp, v);
719  temp[2] = 1.0f;
720 
721  mul_v3_m3v3(warped, m, temp);
722 
723  r[0] = warped[0] / warped[2];
724  r[1] = warped[1] / warped[2];
725 }
726 
727 void mul_m3_v2(const float m[3][3], float r[2])
728 {
729  mul_v2_m3v2(r, m, r);
730 }
731 
732 void mul_m4_v3(const float M[4][4], float r[3])
733 {
734  const float x = r[0];
735  const float y = r[1];
736 
737  r[0] = x * M[0][0] + y * M[1][0] + M[2][0] * r[2] + M[3][0];
738  r[1] = x * M[0][1] + y * M[1][1] + M[2][1] * r[2] + M[3][1];
739  r[2] = x * M[0][2] + y * M[1][2] + M[2][2] * r[2] + M[3][2];
740 }
741 
742 void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
743 {
744  const float x = vec[0];
745  const float y = vec[1];
746 
747  r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
748  r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
749  r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
750 }
751 
752 void mul_v3_m4v3_db(double r[3], const double mat[4][4], const double vec[3])
753 {
754  const double x = vec[0];
755  const double y = vec[1];
756 
757  r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
758  r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
759  r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
760 }
761 void mul_v4_m4v3_db(double r[4], const double mat[4][4], const double vec[3])
762 {
763  const double x = vec[0];
764  const double y = vec[1];
765 
766  r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
767  r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
768  r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
769  r[3] = x * mat[0][3] + y * mat[1][3] + mat[2][3] * vec[2] + mat[3][3];
770 }
771 
772 void mul_v2_m4v3(float r[2], const float mat[4][4], const float vec[3])
773 {
774  const float x = vec[0];
775 
776  r[0] = x * mat[0][0] + vec[1] * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
777  r[1] = x * mat[0][1] + vec[1] * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
778 }
779 
780 void mul_v2_m2v2(float r[2], const float mat[2][2], const float vec[2])
781 {
782  const float x = vec[0];
783 
784  r[0] = mat[0][0] * x + mat[1][0] * vec[1];
785  r[1] = mat[0][1] * x + mat[1][1] * vec[1];
786 }
787 
788 void mul_m2_v2(const float mat[2][2], float vec[2])
789 {
790  mul_v2_m2v2(vec, mat, vec);
791 }
792 
794 void mul_mat3_m4_v3(const float M[4][4], float r[3])
795 {
796  const float x = r[0];
797  const float y = r[1];
798 
799  r[0] = x * M[0][0] + y * M[1][0] + M[2][0] * r[2];
800  r[1] = x * M[0][1] + y * M[1][1] + M[2][1] * r[2];
801  r[2] = x * M[0][2] + y * M[1][2] + M[2][2] * r[2];
802 }
803 
804 void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
805 {
806  const float x = vec[0];
807  const float y = vec[1];
808 
809  r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2];
810  r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2];
811  r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
812 }
813 
814 void mul_v3_mat3_m4v3_db(double r[3], const double mat[4][4], const double vec[3])
815 {
816  const double x = vec[0];
817  const double y = vec[1];
818 
819  r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2];
820  r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2];
821  r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
822 }
823 
824 void mul_project_m4_v3(const float mat[4][4], float vec[3])
825 {
826  /* absolute value to not flip the frustum upside down behind the camera */
827  const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
828  mul_m4_v3(mat, vec);
829 
830  vec[0] /= w;
831  vec[1] /= w;
832  vec[2] /= w;
833 }
834 
835 void mul_v3_project_m4_v3(float r[3], const float mat[4][4], const float vec[3])
836 {
837  const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
838  mul_v3_m4v3(r, mat, vec);
839 
840  r[0] /= w;
841  r[1] /= w;
842  r[2] /= w;
843 }
844 
845 void mul_v2_project_m4_v3(float r[2], const float mat[4][4], const float vec[3])
846 {
847  const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
848  mul_v2_m4v3(r, mat, vec);
849 
850  r[0] /= w;
851  r[1] /= w;
852 }
853 
854 void mul_v4_m4v4(float r[4], const float mat[4][4], const float v[4])
855 {
856  const float x = v[0];
857  const float y = v[1];
858  const float z = v[2];
859 
860  r[0] = x * mat[0][0] + y * mat[1][0] + z * mat[2][0] + mat[3][0] * v[3];
861  r[1] = x * mat[0][1] + y * mat[1][1] + z * mat[2][1] + mat[3][1] * v[3];
862  r[2] = x * mat[0][2] + y * mat[1][2] + z * mat[2][2] + mat[3][2] * v[3];
863  r[3] = x * mat[0][3] + y * mat[1][3] + z * mat[2][3] + mat[3][3] * v[3];
864 }
865 
866 void mul_m4_v4(const float mat[4][4], float r[4])
867 {
868  mul_v4_m4v4(r, mat, r);
869 }
870 
871 void mul_v4d_m4v4d(double r[4], const float mat[4][4], const double v[4])
872 {
873  const double x = v[0];
874  const double y = v[1];
875  const double z = v[2];
876 
877  r[0] = x * (double)mat[0][0] + y * (double)mat[1][0] + z * (double)mat[2][0] +
878  (double)mat[3][0] * v[3];
879  r[1] = x * (double)mat[0][1] + y * (double)mat[1][1] + z * (double)mat[2][1] +
880  (double)mat[3][1] * v[3];
881  r[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + z * (double)mat[2][2] +
882  (double)mat[3][2] * v[3];
883  r[3] = x * (double)mat[0][3] + y * (double)mat[1][3] + z * (double)mat[2][3] +
884  (double)mat[3][3] * v[3];
885 }
886 
887 void mul_m4_v4d(const float mat[4][4], double r[4])
888 {
889  mul_v4d_m4v4d(r, mat, r);
890 }
891 
892 void mul_v4_m4v3(float r[4], const float M[4][4], const float v[3])
893 {
894  /* v has implicit w = 1.0f */
895  r[0] = v[0] * M[0][0] + v[1] * M[1][0] + M[2][0] * v[2] + M[3][0];
896  r[1] = v[0] * M[0][1] + v[1] * M[1][1] + M[2][1] * v[2] + M[3][1];
897  r[2] = v[0] * M[0][2] + v[1] * M[1][2] + M[2][2] * v[2] + M[3][2];
898  r[3] = v[0] * M[0][3] + v[1] * M[1][3] + M[2][3] * v[2] + M[3][3];
899 }
900 
901 void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
902 {
903  float t[3];
904  copy_v3_v3(t, a);
905 
906  r[0] = M[0][0] * t[0] + M[1][0] * t[1] + M[2][0] * t[2];
907  r[1] = M[0][1] * t[0] + M[1][1] * t[1] + M[2][1] * t[2];
908  r[2] = M[0][2] * t[0] + M[1][2] * t[1] + M[2][2] * t[2];
909 }
910 
911 void mul_v3_m3v3_db(double r[3], const double M[3][3], const double a[3])
912 {
913  double t[3];
914  copy_v3_v3_db(t, a);
915 
916  r[0] = M[0][0] * t[0] + M[1][0] * t[1] + M[2][0] * t[2];
917  r[1] = M[0][1] * t[0] + M[1][1] * t[1] + M[2][1] * t[2];
918  r[2] = M[0][2] * t[0] + M[1][2] * t[1] + M[2][2] * t[2];
919 }
920 
921 void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
922 {
923  float t[3];
924  copy_v3_v3(t, a);
925 
926  r[0] = M[0][0] * t[0] + M[1][0] * t[1] + M[2][0] * t[2];
927  r[1] = M[0][1] * t[0] + M[1][1] * t[1] + M[2][1] * t[2];
928 }
929 
930 void mul_m3_v3(const float M[3][3], float r[3])
931 {
932  mul_v3_m3v3(r, M, (const float[3]){UNPACK3(r)});
933 }
934 
935 void mul_m3_v3_db(const double M[3][3], double r[3])
936 {
937  mul_v3_m3v3_db(r, M, (const double[3]){UNPACK3(r)});
938 }
939 
940 void mul_transposed_m3_v3(const float M[3][3], float r[3])
941 {
942  const float x = r[0];
943  const float y = r[1];
944 
945  r[0] = x * M[0][0] + y * M[0][1] + M[0][2] * r[2];
946  r[1] = x * M[1][0] + y * M[1][1] + M[1][2] * r[2];
947  r[2] = x * M[2][0] + y * M[2][1] + M[2][2] * r[2];
948 }
949 
950 void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3])
951 {
952  const float x = r[0];
953  const float y = r[1];
954 
955  r[0] = x * M[0][0] + y * M[0][1] + M[0][2] * r[2];
956  r[1] = x * M[1][0] + y * M[1][1] + M[1][2] * r[2];
957  r[2] = x * M[2][0] + y * M[2][1] + M[2][2] * r[2];
958 }
959 
960 void mul_m3_fl(float R[3][3], float f)
961 {
962  int i, j;
963 
964  for (i = 0; i < 3; i++) {
965  for (j = 0; j < 3; j++) {
966  R[i][j] *= f;
967  }
968  }
969 }
970 
971 void mul_m4_fl(float R[4][4], float f)
972 {
973  int i, j;
974 
975  for (i = 0; i < 4; i++) {
976  for (j = 0; j < 4; j++) {
977  R[i][j] *= f;
978  }
979  }
980 }
981 
982 void mul_mat3_m4_fl(float R[4][4], float f)
983 {
984  int i, j;
985 
986  for (i = 0; i < 3; i++) {
987  for (j = 0; j < 3; j++) {
988  R[i][j] *= f;
989  }
990  }
991 }
992 
993 void negate_m3(float R[3][3])
994 {
995  int i, j;
996 
997  for (i = 0; i < 3; i++) {
998  for (j = 0; j < 3; j++) {
999  R[i][j] *= -1.0f;
1000  }
1001  }
1002 }
1003 
1004 void negate_mat3_m4(float R[4][4])
1005 {
1006  int i, j;
1007 
1008  for (i = 0; i < 3; i++) {
1009  for (j = 0; j < 3; j++) {
1010  R[i][j] *= -1.0f;
1011  }
1012  }
1013 }
1014 
1015 void negate_m4(float R[4][4])
1016 {
1017  int i, j;
1018 
1019  for (i = 0; i < 4; i++) {
1020  for (j = 0; j < 4; j++) {
1021  R[i][j] *= -1.0f;
1022  }
1023  }
1024 }
1025 
1026 void mul_m3_v3_double(const float M[3][3], double r[3])
1027 {
1028  const double x = r[0];
1029  const double y = r[1];
1030 
1031  r[0] = x * (double)M[0][0] + y * (double)M[1][0] + (double)M[2][0] * r[2];
1032  r[1] = x * (double)M[0][1] + y * (double)M[1][1] + (double)M[2][1] * r[2];
1033  r[2] = x * (double)M[0][2] + y * (double)M[1][2] + (double)M[2][2] * r[2];
1034 }
1035 
1036 void add_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
1037 {
1038  int i, j;
1039 
1040  for (i = 0; i < 3; i++) {
1041  for (j = 0; j < 3; j++) {
1042  R[i][j] = A[i][j] + B[i][j];
1043  }
1044  }
1045 }
1046 
1047 void add_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
1048 {
1049  int i, j;
1050 
1051  for (i = 0; i < 4; i++) {
1052  for (j = 0; j < 4; j++) {
1053  R[i][j] = A[i][j] + B[i][j];
1054  }
1055  }
1056 }
1057 
1058 void madd_m3_m3m3fl(float R[3][3], const float A[3][3], const float B[3][3], const float f)
1059 {
1060  int i, j;
1061 
1062  for (i = 0; i < 3; i++) {
1063  for (j = 0; j < 3; j++) {
1064  R[i][j] = A[i][j] + B[i][j] * f;
1065  }
1066  }
1067 }
1068 
1069 void madd_m4_m4m4fl(float R[4][4], const float A[4][4], const float B[4][4], const float f)
1070 {
1071  int i, j;
1072 
1073  for (i = 0; i < 4; i++) {
1074  for (j = 0; j < 4; j++) {
1075  R[i][j] = A[i][j] + B[i][j] * f;
1076  }
1077  }
1078 }
1079 
1080 void sub_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
1081 {
1082  int i, j;
1083 
1084  for (i = 0; i < 3; i++) {
1085  for (j = 0; j < 3; j++) {
1086  R[i][j] = A[i][j] - B[i][j];
1087  }
1088  }
1089 }
1090 
1091 void sub_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
1092 {
1093  int i, j;
1094 
1095  for (i = 0; i < 4; i++) {
1096  for (j = 0; j < 4; j++) {
1097  R[i][j] = A[i][j] - B[i][j];
1098  }
1099  }
1100 }
1101 
1102 float determinant_m3_array(const float m[3][3])
1103 {
1104  return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
1105  m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) +
1106  m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
1107 }
1108 
1109 float determinant_m4_mat3_array(const float m[4][4])
1110 {
1111  return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
1112  m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) +
1113  m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
1114 }
1115 
1116 bool invert_m3_ex(float m[3][3], const float epsilon)
1117 {
1118  float tmp[3][3];
1119  const bool success = invert_m3_m3_ex(tmp, m, epsilon);
1120 
1121  copy_m3_m3(m, tmp);
1122  return success;
1123 }
1124 
1125 bool invert_m3_m3_ex(float m1[3][3], const float m2[3][3], const float epsilon)
1126 {
1127  float det;
1128  int a, b;
1129  bool success;
1130 
1131  BLI_assert(epsilon >= 0.0f);
1132 
1133  /* calc adjoint */
1134  adjoint_m3_m3(m1, m2);
1135 
1136  /* then determinant old matrix! */
1137  det = determinant_m3_array(m2);
1138 
1139  success = (fabsf(det) > epsilon);
1140 
1141  if (LIKELY(det != 0.0f)) {
1142  det = 1.0f / det;
1143  for (a = 0; a < 3; a++) {
1144  for (b = 0; b < 3; b++) {
1145  m1[a][b] *= det;
1146  }
1147  }
1148  }
1149  return success;
1150 }
1151 
1152 bool invert_m3(float m[3][3])
1153 {
1154  float tmp[3][3];
1155  const bool success = invert_m3_m3(tmp, m);
1156 
1157  copy_m3_m3(m, tmp);
1158  return success;
1159 }
1160 
1161 bool invert_m3_m3(float m1[3][3], const float m2[3][3])
1162 {
1163  float det;
1164  int a, b;
1165  bool success;
1166 
1167  /* calc adjoint */
1168  adjoint_m3_m3(m1, m2);
1169 
1170  /* then determinant old matrix! */
1171  det = determinant_m3_array(m2);
1172 
1173  success = (det != 0.0f);
1174 
1175  if (LIKELY(det != 0.0f)) {
1176  det = 1.0f / det;
1177  for (a = 0; a < 3; a++) {
1178  for (b = 0; b < 3; b++) {
1179  m1[a][b] *= det;
1180  }
1181  }
1182  }
1183 
1184  return success;
1185 }
1186 
1187 bool invert_m4(float m[4][4])
1188 {
1189  float tmp[4][4];
1190  const bool success = invert_m4_m4(tmp, m);
1191 
1192  copy_m4_m4(m, tmp);
1193  return success;
1194 }
1195 
1206 bool invert_m4_m4_fallback(float inverse[4][4], const float mat[4][4])
1207 {
1208 #ifndef MATH_STANDALONE
1209  if (EIG_invert_m4_m4(inverse, mat)) {
1210  return true;
1211  }
1212 #endif
1213 
1214  int i, j, k;
1215  double temp;
1216  float tempmat[4][4];
1217  float max;
1218  int maxj;
1219 
1220  BLI_assert(inverse != mat);
1221 
1222  /* Set inverse to identity */
1223  for (i = 0; i < 4; i++) {
1224  for (j = 0; j < 4; j++) {
1225  inverse[i][j] = 0;
1226  }
1227  }
1228  for (i = 0; i < 4; i++) {
1229  inverse[i][i] = 1;
1230  }
1231 
1232  /* Copy original matrix so we don't mess it up */
1233  for (i = 0; i < 4; i++) {
1234  for (j = 0; j < 4; j++) {
1235  tempmat[i][j] = mat[i][j];
1236  }
1237  }
1238 
1239  for (i = 0; i < 4; i++) {
1240  /* Look for row with max pivot */
1241  max = fabsf(tempmat[i][i]);
1242  maxj = i;
1243  for (j = i + 1; j < 4; j++) {
1244  if (fabsf(tempmat[j][i]) > max) {
1245  max = fabsf(tempmat[j][i]);
1246  maxj = j;
1247  }
1248  }
1249  /* Swap rows if necessary */
1250  if (maxj != i) {
1251  for (k = 0; k < 4; k++) {
1252  SWAP(float, tempmat[i][k], tempmat[maxj][k]);
1253  SWAP(float, inverse[i][k], inverse[maxj][k]);
1254  }
1255  }
1256 
1257  if (UNLIKELY(tempmat[i][i] == 0.0f)) {
1258  return false; /* No non-zero pivot */
1259  }
1260  temp = (double)tempmat[i][i];
1261  for (k = 0; k < 4; k++) {
1262  tempmat[i][k] = (float)((double)tempmat[i][k] / temp);
1263  inverse[i][k] = (float)((double)inverse[i][k] / temp);
1264  }
1265  for (j = 0; j < 4; j++) {
1266  if (j != i) {
1267  temp = tempmat[j][i];
1268  for (k = 0; k < 4; k++) {
1269  tempmat[j][k] -= (float)((double)tempmat[i][k] * temp);
1270  inverse[j][k] -= (float)((double)inverse[i][k] * temp);
1271  }
1272  }
1273  }
1274  }
1275  return true;
1276 }
1277 
1278 bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
1279 {
1280 #ifndef MATH_STANDALONE
1281  /* Use optimized matrix inverse from Eigen, since performance
1282  * impact of this function is significant in complex rigs. */
1283  return EIG_invert_m4_m4(inverse, mat);
1284 #else
1285  return invert_m4_m4_fallback(inverse, mat);
1286 #endif
1287 }
1288 
1294 void mul_m4_m4m4_aligned_scale(float R[4][4], const float A[4][4], const float B[4][4])
1295 {
1296  float loc_a[3], rot_a[3][3], size_a[3];
1297  float loc_b[3], rot_b[3][3], size_b[3];
1298  float loc_r[3], rot_r[3][3], size_r[3];
1299 
1300  mat4_to_loc_rot_size(loc_a, rot_a, size_a, A);
1301  mat4_to_loc_rot_size(loc_b, rot_b, size_b, B);
1302 
1303  mul_v3_m4v3(loc_r, A, loc_b);
1304  mul_m3_m3m3_uniq(rot_r, rot_a, rot_b);
1305  mul_v3_v3v3(size_r, size_a, size_b);
1306 
1307  loc_rot_size_to_mat4(R, loc_r, rot_r, size_r);
1308 }
1309 
1310 /****************************** Linear Algebra *******************************/
1311 
1312 void transpose_m3(float R[3][3])
1313 {
1314  float t;
1315 
1316  t = R[0][1];
1317  R[0][1] = R[1][0];
1318  R[1][0] = t;
1319  t = R[0][2];
1320  R[0][2] = R[2][0];
1321  R[2][0] = t;
1322  t = R[1][2];
1323  R[1][2] = R[2][1];
1324  R[2][1] = t;
1325 }
1326 
1327 void transpose_m3_m3(float R[3][3], const float M[3][3])
1328 {
1329  BLI_assert(R != M);
1330 
1331  R[0][0] = M[0][0];
1332  R[0][1] = M[1][0];
1333  R[0][2] = M[2][0];
1334  R[1][0] = M[0][1];
1335  R[1][1] = M[1][1];
1336  R[1][2] = M[2][1];
1337  R[2][0] = M[0][2];
1338  R[2][1] = M[1][2];
1339  R[2][2] = M[2][2];
1340 }
1341 
1342 /* seems obscure but in-fact a common operation */
1343 void transpose_m3_m4(float R[3][3], const float M[4][4])
1344 {
1345  BLI_assert(&R[0][0] != &M[0][0]);
1346 
1347  R[0][0] = M[0][0];
1348  R[0][1] = M[1][0];
1349  R[0][2] = M[2][0];
1350  R[1][0] = M[0][1];
1351  R[1][1] = M[1][1];
1352  R[1][2] = M[2][1];
1353  R[2][0] = M[0][2];
1354  R[2][1] = M[1][2];
1355  R[2][2] = M[2][2];
1356 }
1357 
1358 void transpose_m4(float R[4][4])
1359 {
1360  float t;
1361 
1362  t = R[0][1];
1363  R[0][1] = R[1][0];
1364  R[1][0] = t;
1365  t = R[0][2];
1366  R[0][2] = R[2][0];
1367  R[2][0] = t;
1368  t = R[0][3];
1369  R[0][3] = R[3][0];
1370  R[3][0] = t;
1371 
1372  t = R[1][2];
1373  R[1][2] = R[2][1];
1374  R[2][1] = t;
1375  t = R[1][3];
1376  R[1][3] = R[3][1];
1377  R[3][1] = t;
1378 
1379  t = R[2][3];
1380  R[2][3] = R[3][2];
1381  R[3][2] = t;
1382 }
1383 
1384 void transpose_m4_m4(float R[4][4], const float M[4][4])
1385 {
1386  BLI_assert(R != M);
1387 
1388  R[0][0] = M[0][0];
1389  R[0][1] = M[1][0];
1390  R[0][2] = M[2][0];
1391  R[0][3] = M[3][0];
1392  R[1][0] = M[0][1];
1393  R[1][1] = M[1][1];
1394  R[1][2] = M[2][1];
1395  R[1][3] = M[3][1];
1396  R[2][0] = M[0][2];
1397  R[2][1] = M[1][2];
1398  R[2][2] = M[2][2];
1399  R[2][3] = M[3][2];
1400  R[3][0] = M[0][3];
1401  R[3][1] = M[1][3];
1402  R[3][2] = M[2][3];
1403  R[3][3] = M[3][3];
1404 }
1405 
1406 bool compare_m4m4(const float mat1[4][4], const float mat2[4][4], float limit)
1407 {
1408  if (compare_v4v4(mat1[0], mat2[0], limit)) {
1409  if (compare_v4v4(mat1[1], mat2[1], limit)) {
1410  if (compare_v4v4(mat1[2], mat2[2], limit)) {
1411  if (compare_v4v4(mat1[3], mat2[3], limit)) {
1412  return true;
1413  }
1414  }
1415  }
1416  }
1417  return false;
1418 }
1419 
1425 void orthogonalize_m3(float R[3][3], int axis)
1426 {
1427  float size[3];
1428  mat3_to_size(size, R);
1429  normalize_v3(R[axis]);
1430  switch (axis) {
1431  case 0:
1432  if (dot_v3v3(R[0], R[1]) < 1) {
1433  cross_v3_v3v3(R[2], R[0], R[1]);
1434  normalize_v3(R[2]);
1435  cross_v3_v3v3(R[1], R[2], R[0]);
1436  }
1437  else if (dot_v3v3(R[0], R[2]) < 1) {
1438  cross_v3_v3v3(R[1], R[2], R[0]);
1439  normalize_v3(R[1]);
1440  cross_v3_v3v3(R[2], R[0], R[1]);
1441  }
1442  else {
1443  float vec[3];
1444 
1445  vec[0] = R[0][1];
1446  vec[1] = R[0][2];
1447  vec[2] = R[0][0];
1448 
1449  cross_v3_v3v3(R[2], R[0], vec);
1450  normalize_v3(R[2]);
1451  cross_v3_v3v3(R[1], R[2], R[0]);
1452  }
1453  break;
1454  case 1:
1455  if (dot_v3v3(R[1], R[0]) < 1) {
1456  cross_v3_v3v3(R[2], R[0], R[1]);
1457  normalize_v3(R[2]);
1458  cross_v3_v3v3(R[0], R[1], R[2]);
1459  }
1460  else if (dot_v3v3(R[0], R[2]) < 1) {
1461  cross_v3_v3v3(R[0], R[1], R[2]);
1462  normalize_v3(R[0]);
1463  cross_v3_v3v3(R[2], R[0], R[1]);
1464  }
1465  else {
1466  float vec[3];
1467 
1468  vec[0] = R[1][1];
1469  vec[1] = R[1][2];
1470  vec[2] = R[1][0];
1471 
1472  cross_v3_v3v3(R[0], R[1], vec);
1473  normalize_v3(R[0]);
1474  cross_v3_v3v3(R[2], R[0], R[1]);
1475  }
1476  break;
1477  case 2:
1478  if (dot_v3v3(R[2], R[0]) < 1) {
1479  cross_v3_v3v3(R[1], R[2], R[0]);
1480  normalize_v3(R[1]);
1481  cross_v3_v3v3(R[0], R[1], R[2]);
1482  }
1483  else if (dot_v3v3(R[2], R[1]) < 1) {
1484  cross_v3_v3v3(R[0], R[1], R[2]);
1485  normalize_v3(R[0]);
1486  cross_v3_v3v3(R[1], R[2], R[0]);
1487  }
1488  else {
1489  float vec[3];
1490 
1491  vec[0] = R[2][1];
1492  vec[1] = R[2][2];
1493  vec[2] = R[2][0];
1494 
1495  cross_v3_v3v3(R[0], vec, R[2]);
1496  normalize_v3(R[0]);
1497  cross_v3_v3v3(R[1], R[2], R[0]);
1498  }
1499  break;
1500  default:
1501  BLI_assert(0);
1502  break;
1503  }
1504  mul_v3_fl(R[0], size[0]);
1505  mul_v3_fl(R[1], size[1]);
1506  mul_v3_fl(R[2], size[2]);
1507 }
1508 
1514 void orthogonalize_m4(float R[4][4], int axis)
1515 {
1516  float size[3];
1517  mat4_to_size(size, R);
1518  normalize_v3(R[axis]);
1519  switch (axis) {
1520  case 0:
1521  if (dot_v3v3(R[0], R[1]) < 1) {
1522  cross_v3_v3v3(R[2], R[0], R[1]);
1523  normalize_v3(R[2]);
1524  cross_v3_v3v3(R[1], R[2], R[0]);
1525  }
1526  else if (dot_v3v3(R[0], R[2]) < 1) {
1527  cross_v3_v3v3(R[1], R[2], R[0]);
1528  normalize_v3(R[1]);
1529  cross_v3_v3v3(R[2], R[0], R[1]);
1530  }
1531  else {
1532  float vec[3];
1533 
1534  vec[0] = R[0][1];
1535  vec[1] = R[0][2];
1536  vec[2] = R[0][0];
1537 
1538  cross_v3_v3v3(R[2], R[0], vec);
1539  normalize_v3(R[2]);
1540  cross_v3_v3v3(R[1], R[2], R[0]);
1541  }
1542  break;
1543  case 1:
1544  if (dot_v3v3(R[1], R[0]) < 1) {
1545  cross_v3_v3v3(R[2], R[0], R[1]);
1546  normalize_v3(R[2]);
1547  cross_v3_v3v3(R[0], R[1], R[2]);
1548  }
1549  else if (dot_v3v3(R[0], R[2]) < 1) {
1550  cross_v3_v3v3(R[0], R[1], R[2]);
1551  normalize_v3(R[0]);
1552  cross_v3_v3v3(R[2], R[0], R[1]);
1553  }
1554  else {
1555  float vec[3];
1556 
1557  vec[0] = R[1][1];
1558  vec[1] = R[1][2];
1559  vec[2] = R[1][0];
1560 
1561  cross_v3_v3v3(R[0], R[1], vec);
1562  normalize_v3(R[0]);
1563  cross_v3_v3v3(R[2], R[0], R[1]);
1564  }
1565  break;
1566  case 2:
1567  if (dot_v3v3(R[2], R[0]) < 1) {
1568  cross_v3_v3v3(R[1], R[2], R[0]);
1569  normalize_v3(R[1]);
1570  cross_v3_v3v3(R[0], R[1], R[2]);
1571  }
1572  else if (dot_v3v3(R[2], R[1]) < 1) {
1573  cross_v3_v3v3(R[0], R[1], R[2]);
1574  normalize_v3(R[0]);
1575  cross_v3_v3v3(R[1], R[2], R[0]);
1576  }
1577  else {
1578  float vec[3];
1579 
1580  vec[0] = R[2][1];
1581  vec[1] = R[2][2];
1582  vec[2] = R[2][0];
1583 
1584  cross_v3_v3v3(R[0], vec, R[2]);
1585  normalize_v3(R[0]);
1586  cross_v3_v3v3(R[1], R[2], R[0]);
1587  }
1588  break;
1589  default:
1590  BLI_assert(0);
1591  break;
1592  }
1593  mul_v3_fl(R[0], size[0]);
1594  mul_v3_fl(R[1], size[1]);
1595  mul_v3_fl(R[2], size[2]);
1596 }
1597 
1599 static void orthogonalize_stable(float v1[3], float v2[3], float v3[3], bool normalize)
1600 {
1601  /* Make secondary axis vectors orthogonal to the primary via
1602  * plane projection, which preserves the determinant. */
1603  float len_sq_v1 = len_squared_v3(v1);
1604 
1605  if (len_sq_v1 > 0.0f) {
1606  madd_v3_v3fl(v2, v1, -dot_v3v3(v2, v1) / len_sq_v1);
1607  madd_v3_v3fl(v3, v1, -dot_v3v3(v3, v1) / len_sq_v1);
1608 
1609  if (normalize) {
1610  mul_v3_fl(v1, 1.0f / sqrtf(len_sq_v1));
1611  }
1612  }
1613 
1614  /* Make secondary axis vectors orthogonal relative to each other. */
1615  float norm_v2[3], norm_v3[3], tmp[3];
1616  float length_v2 = normalize_v3_v3(norm_v2, v2);
1617  float length_v3 = normalize_v3_v3(norm_v3, v3);
1618  float cos_angle = dot_v3v3(norm_v2, norm_v3);
1619  float abs_cos_angle = fabsf(cos_angle);
1620 
1621  /* Apply correction if the shear angle is significant, and not degenerate. */
1622  if (abs_cos_angle > 1e-4f && abs_cos_angle < 1.0f - FLT_EPSILON) {
1623  /* Adjust v2 by half of the necessary angle correction.
1624  * Thus the angle change is the same for both axis directions. */
1625  float angle = acosf(cos_angle);
1626  float target_angle = angle + ((float)M_PI_2 - angle) / 2;
1627 
1628  madd_v3_v3fl(norm_v2, norm_v3, -cos_angle);
1629  mul_v3_fl(norm_v2, sinf(target_angle) / len_v3(norm_v2));
1630  madd_v3_v3fl(norm_v2, norm_v3, cosf(target_angle));
1631 
1632  /* Make v3 orthogonal. */
1633  cross_v3_v3v3(tmp, norm_v2, norm_v3);
1634  cross_v3_v3v3(norm_v3, tmp, norm_v2);
1635  normalize_v3(norm_v3);
1636 
1637  /* Re-apply scale, preserving area and proportion. */
1638  if (!normalize) {
1639  float scale_fac = sqrtf(sinf(angle));
1640  mul_v3_v3fl(v2, norm_v2, length_v2 * scale_fac);
1641  mul_v3_v3fl(v3, norm_v3, length_v3 * scale_fac);
1642  }
1643  }
1644 
1645  if (normalize) {
1646  copy_v3_v3(v2, norm_v2);
1647  copy_v3_v3(v3, norm_v3);
1648  }
1649 }
1650 
1659 void orthogonalize_m3_stable(float R[3][3], int axis, bool normalize)
1660 {
1661  switch (axis) {
1662  case 0:
1663  orthogonalize_stable(R[0], R[1], R[2], normalize);
1664  break;
1665  case 1:
1666  orthogonalize_stable(R[1], R[0], R[2], normalize);
1667  break;
1668  case 2:
1669  orthogonalize_stable(R[2], R[0], R[1], normalize);
1670  break;
1671  default:
1672  BLI_assert(0);
1673  break;
1674  }
1675 }
1676 
1685 void orthogonalize_m4_stable(float R[4][4], int axis, bool normalize)
1686 {
1687  switch (axis) {
1688  case 0:
1689  orthogonalize_stable(R[0], R[1], R[2], normalize);
1690  break;
1691  case 1:
1692  orthogonalize_stable(R[1], R[0], R[2], normalize);
1693  break;
1694  case 2:
1695  orthogonalize_stable(R[2], R[0], R[1], normalize);
1696  break;
1697  default:
1698  BLI_assert(0);
1699  break;
1700  }
1701 }
1702 
1703 /* -------------------------------------------------------------------- */
1718 static bool orthogonalize_m3_zero_axes_impl(float *mat[3], const float unit_length)
1719 {
1720  enum { X = 1 << 0, Y = 1 << 1, Z = 1 << 2 };
1721  int flag = 0;
1722  for (int i = 0; i < 3; i++) {
1723  flag |= (len_squared_v3(mat[i]) == 0.0f) ? (1 << i) : 0;
1724  }
1725 
1726  /* Either all or none are zero, either way we can't properly resolve this
1727  * since we need to fill invalid axes from valid ones. */
1728  if (ELEM(flag, 0, X | Y | Z)) {
1729  return false;
1730  }
1731 
1732  switch (flag) {
1733  case X | Y: {
1734  ortho_v3_v3(mat[1], mat[2]);
1736  }
1737  case X: {
1738  cross_v3_v3v3(mat[0], mat[1], mat[2]);
1739  break;
1740  }
1741 
1742  case Y | Z: {
1743  ortho_v3_v3(mat[2], mat[0]);
1745  }
1746  case Y: {
1747  cross_v3_v3v3(mat[1], mat[0], mat[2]);
1748  break;
1749  }
1750 
1751  case Z | X: {
1752  ortho_v3_v3(mat[0], mat[1]);
1754  }
1755  case Z: {
1756  cross_v3_v3v3(mat[2], mat[0], mat[1]);
1757  break;
1758  }
1759  default: {
1760  BLI_assert(0); /* Unreachable! */
1761  }
1762  }
1763 
1764  for (int i = 0; i < 3; i++) {
1765  if (flag & (1 << i)) {
1766  if (UNLIKELY(normalize_v3_length(mat[i], unit_length) == 0.0f)) {
1767  mat[i][i] = unit_length;
1768  }
1769  }
1770  }
1771 
1772  return true;
1773 }
1774 
1775 bool orthogonalize_m3_zero_axes(float m[3][3], const float unit_length)
1776 {
1777  return orthogonalize_m3_zero_axes_impl((float *[3]){UNPACK3(m)}, unit_length);
1778 }
1779 bool orthogonalize_m4_zero_axes(float m[4][4], const float unit_length)
1780 {
1781  return orthogonalize_m3_zero_axes_impl((float *[3]){UNPACK3(m)}, unit_length);
1782 }
1783 
1786 bool is_orthogonal_m3(const float m[3][3])
1787 {
1788  int i, j;
1789 
1790  for (i = 0; i < 3; i++) {
1791  for (j = 0; j < i; j++) {
1792  if (fabsf(dot_v3v3(m[i], m[j])) > 1e-5f) {
1793  return false;
1794  }
1795  }
1796  }
1797 
1798  return true;
1799 }
1800 
1801 bool is_orthogonal_m4(const float m[4][4])
1802 {
1803  int i, j;
1804 
1805  for (i = 0; i < 4; i++) {
1806  for (j = 0; j < i; j++) {
1807  if (fabsf(dot_v4v4(m[i], m[j])) > 1e-5f) {
1808  return false;
1809  }
1810  }
1811  }
1812 
1813  return true;
1814 }
1815 
1816 bool is_orthonormal_m3(const float m[3][3])
1817 {
1818  if (is_orthogonal_m3(m)) {
1819  int i;
1820 
1821  for (i = 0; i < 3; i++) {
1822  if (fabsf(dot_v3v3(m[i], m[i]) - 1) > 1e-5f) {
1823  return false;
1824  }
1825  }
1826 
1827  return true;
1828  }
1829 
1830  return false;
1831 }
1832 
1833 bool is_orthonormal_m4(const float m[4][4])
1834 {
1835  if (is_orthogonal_m4(m)) {
1836  int i;
1837 
1838  for (i = 0; i < 4; i++) {
1839  if (fabsf(dot_v4v4(m[i], m[i]) - 1) > 1e-5f) {
1840  return false;
1841  }
1842  }
1843 
1844  return true;
1845  }
1846 
1847  return false;
1848 }
1849 
1850 bool is_uniform_scaled_m3(const float m[3][3])
1851 {
1852  const float eps = 1e-7f;
1853  float t[3][3];
1854  float l1, l2, l3, l4, l5, l6;
1855 
1856  transpose_m3_m3(t, m);
1857 
1858  l1 = len_squared_v3(m[0]);
1859  l2 = len_squared_v3(m[1]);
1860  l3 = len_squared_v3(m[2]);
1861 
1862  l4 = len_squared_v3(t[0]);
1863  l5 = len_squared_v3(t[1]);
1864  l6 = len_squared_v3(t[2]);
1865 
1866  if (fabsf(l2 - l1) <= eps && fabsf(l3 - l1) <= eps && fabsf(l4 - l1) <= eps &&
1867  fabsf(l5 - l1) <= eps && fabsf(l6 - l1) <= eps) {
1868  return true;
1869  }
1870 
1871  return false;
1872 }
1873 
1874 bool is_uniform_scaled_m4(const float m[4][4])
1875 {
1876  float t[3][3];
1877  copy_m3_m4(t, m);
1878  return is_uniform_scaled_m3(t);
1879 }
1880 
1881 void normalize_m2_ex(float R[2][2], float r_scale[2])
1882 {
1883  int i;
1884  for (i = 0; i < 2; i++) {
1885  r_scale[i] = normalize_v2(R[i]);
1886  }
1887 }
1888 
1889 void normalize_m2(float R[2][2])
1890 {
1891  int i;
1892  for (i = 0; i < 2; i++) {
1893  normalize_v2(R[i]);
1894  }
1895 }
1896 
1897 void normalize_m2_m2_ex(float R[2][2], const float M[2][2], float r_scale[2])
1898 {
1899  int i;
1900  for (i = 0; i < 2; i++) {
1901  r_scale[i] = normalize_v2_v2(R[i], M[i]);
1902  }
1903 }
1904 void normalize_m2_m2(float R[2][2], const float M[2][2])
1905 {
1906  int i;
1907  for (i = 0; i < 2; i++) {
1908  normalize_v2_v2(R[i], M[i]);
1909  }
1910 }
1911 
1912 void normalize_m3_ex(float R[3][3], float r_scale[3])
1913 {
1914  int i;
1915  for (i = 0; i < 3; i++) {
1916  r_scale[i] = normalize_v3(R[i]);
1917  }
1918 }
1919 void normalize_m3(float R[3][3])
1920 {
1921  int i;
1922  for (i = 0; i < 3; i++) {
1923  normalize_v3(R[i]);
1924  }
1925 }
1926 
1927 void normalize_m3_m3_ex(float R[3][3], const float M[3][3], float r_scale[3])
1928 {
1929  int i;
1930  for (i = 0; i < 3; i++) {
1931  r_scale[i] = normalize_v3_v3(R[i], M[i]);
1932  }
1933 }
1934 void normalize_m3_m3(float R[3][3], const float M[3][3])
1935 {
1936  int i;
1937  for (i = 0; i < 3; i++) {
1938  normalize_v3_v3(R[i], M[i]);
1939  }
1940 }
1941 
1942 void normalize_m4_ex(float R[4][4], float r_scale[3])
1943 {
1944  int i;
1945  for (i = 0; i < 3; i++) {
1946  r_scale[i] = normalize_v3(R[i]);
1947  if (r_scale[i] != 0.0f) {
1948  R[i][3] /= r_scale[i];
1949  }
1950  }
1951 }
1952 void normalize_m4(float R[4][4])
1953 {
1954  int i;
1955  for (i = 0; i < 3; i++) {
1956  float len = normalize_v3(R[i]);
1957  if (len != 0.0f) {
1958  R[i][3] /= len;
1959  }
1960  }
1961 }
1962 
1963 void normalize_m4_m4_ex(float rmat[4][4], const float mat[4][4], float r_scale[3])
1964 {
1965  int i;
1966  for (i = 0; i < 3; i++) {
1967  r_scale[i] = normalize_v3_v3(rmat[i], mat[i]);
1968  rmat[i][3] = (r_scale[i] != 0.0f) ? (mat[i][3] / r_scale[i]) : mat[i][3];
1969  }
1970  copy_v4_v4(rmat[3], mat[3]);
1971 }
1972 void normalize_m4_m4(float rmat[4][4], const float mat[4][4])
1973 {
1974  int i;
1975  for (i = 0; i < 3; i++) {
1976  float len = normalize_v3_v3(rmat[i], mat[i]);
1977  rmat[i][3] = (len != 0.0f) ? (mat[i][3] / len) : mat[i][3];
1978  }
1979  copy_v4_v4(rmat[3], mat[3]);
1980 }
1981 
1982 void adjoint_m2_m2(float R[2][2], const float M[2][2])
1983 {
1984  BLI_assert(R != M);
1985  R[0][0] = M[1][1];
1986  R[0][1] = -M[0][1];
1987  R[1][0] = -M[1][0];
1988  R[1][1] = M[0][0];
1989 }
1990 
1991 void adjoint_m3_m3(float R[3][3], const float M[3][3])
1992 {
1993  BLI_assert(R != M);
1994  R[0][0] = M[1][1] * M[2][2] - M[1][2] * M[2][1];
1995  R[0][1] = -M[0][1] * M[2][2] + M[0][2] * M[2][1];
1996  R[0][2] = M[0][1] * M[1][2] - M[0][2] * M[1][1];
1997 
1998  R[1][0] = -M[1][0] * M[2][2] + M[1][2] * M[2][0];
1999  R[1][1] = M[0][0] * M[2][2] - M[0][2] * M[2][0];
2000  R[1][2] = -M[0][0] * M[1][2] + M[0][2] * M[1][0];
2001 
2002  R[2][0] = M[1][0] * M[2][1] - M[1][1] * M[2][0];
2003  R[2][1] = -M[0][0] * M[2][1] + M[0][1] * M[2][0];
2004  R[2][2] = M[0][0] * M[1][1] - M[0][1] * M[1][0];
2005 }
2006 
2007 void adjoint_m4_m4(float R[4][4], const float M[4][4]) /* out = ADJ(in) */
2008 {
2009  float a1, a2, a3, a4, b1, b2, b3, b4;
2010  float c1, c2, c3, c4, d1, d2, d3, d4;
2011 
2012  a1 = M[0][0];
2013  b1 = M[0][1];
2014  c1 = M[0][2];
2015  d1 = M[0][3];
2016 
2017  a2 = M[1][0];
2018  b2 = M[1][1];
2019  c2 = M[1][2];
2020  d2 = M[1][3];
2021 
2022  a3 = M[2][0];
2023  b3 = M[2][1];
2024  c3 = M[2][2];
2025  d3 = M[2][3];
2026 
2027  a4 = M[3][0];
2028  b4 = M[3][1];
2029  c4 = M[3][2];
2030  d4 = M[3][3];
2031 
2032  R[0][0] = determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
2033  R[1][0] = -determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
2034  R[2][0] = determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
2035  R[3][0] = -determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
2036 
2037  R[0][1] = -determinant_m3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
2038  R[1][1] = determinant_m3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
2039  R[2][1] = -determinant_m3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
2040  R[3][1] = determinant_m3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
2041 
2042  R[0][2] = determinant_m3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
2043  R[1][2] = -determinant_m3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
2044  R[2][2] = determinant_m3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
2045  R[3][2] = -determinant_m3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
2046 
2047  R[0][3] = -determinant_m3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
2048  R[1][3] = determinant_m3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
2049  R[2][3] = -determinant_m3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
2050  R[3][3] = determinant_m3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
2051 }
2052 
2053 float determinant_m2(float a, float b, float c, float d)
2054 {
2055 
2056  return a * d - b * c;
2057 }
2058 
2060  float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3)
2061 {
2062  float ans;
2063 
2064  ans = (a1 * determinant_m2(b2, b3, c2, c3) - b1 * determinant_m2(a2, a3, c2, c3) +
2065  c1 * determinant_m2(a2, a3, b2, b3));
2066 
2067  return ans;
2068 }
2069 
2070 float determinant_m4(const float m[4][4])
2071 {
2072  float ans;
2073  float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
2074 
2075  a1 = m[0][0];
2076  b1 = m[0][1];
2077  c1 = m[0][2];
2078  d1 = m[0][3];
2079 
2080  a2 = m[1][0];
2081  b2 = m[1][1];
2082  c2 = m[1][2];
2083  d2 = m[1][3];
2084 
2085  a3 = m[2][0];
2086  b3 = m[2][1];
2087  c3 = m[2][2];
2088  d3 = m[2][3];
2089 
2090  a4 = m[3][0];
2091  b4 = m[3][1];
2092  c4 = m[3][2];
2093  d4 = m[3][3];
2094 
2095  ans = (a1 * determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4) -
2096  b1 * determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4) +
2097  c1 * determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4) -
2098  d1 * determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4));
2099 
2100  return ans;
2101 }
2102 
2103 /****************************** Transformations ******************************/
2104 
2105 void size_to_mat3(float R[3][3], const float size[3])
2106 {
2107  R[0][0] = size[0];
2108  R[0][1] = 0.0f;
2109  R[0][2] = 0.0f;
2110  R[1][1] = size[1];
2111  R[1][0] = 0.0f;
2112  R[1][2] = 0.0f;
2113  R[2][2] = size[2];
2114  R[2][1] = 0.0f;
2115  R[2][0] = 0.0f;
2116 }
2117 
2118 void size_to_mat4(float R[4][4], const float size[3])
2119 {
2120  R[0][0] = size[0];
2121  R[0][1] = 0.0f;
2122  R[0][2] = 0.0f;
2123  R[0][3] = 0.0f;
2124  R[1][0] = 0.0f;
2125  R[1][1] = size[1];
2126  R[1][2] = 0.0f;
2127  R[1][3] = 0.0f;
2128  R[2][0] = 0.0f;
2129  R[2][1] = 0.0f;
2130  R[2][2] = size[2];
2131  R[2][3] = 0.0f;
2132  R[3][0] = 0.0f;
2133  R[3][1] = 0.0f;
2134  R[3][2] = 0.0f;
2135  R[3][3] = 1.0f;
2136 }
2137 
2138 void mat3_to_size(float size[3], const float M[3][3])
2139 {
2140  size[0] = len_v3(M[0]);
2141  size[1] = len_v3(M[1]);
2142  size[2] = len_v3(M[2]);
2143 }
2144 
2145 void mat4_to_size(float size[3], const float M[4][4])
2146 {
2147  size[0] = len_v3(M[0]);
2148  size[1] = len_v3(M[1]);
2149  size[2] = len_v3(M[2]);
2150 }
2151 
2156 void mat4_to_size_fix_shear(float size[3], const float M[4][4])
2157 {
2158  mat4_to_size(size, M);
2159 
2160  float volume = size[0] * size[1] * size[2];
2161 
2162  if (volume != 0.0f) {
2163  mul_v3_fl(size, cbrtf(fabsf(mat4_to_volume_scale(M) / volume)));
2164  }
2165 }
2166 
2172 float mat3_to_volume_scale(const float mat[3][3])
2173 {
2174  return determinant_m3_array(mat);
2175 }
2176 
2177 float mat4_to_volume_scale(const float mat[4][4])
2178 {
2179  return determinant_m4_mat3_array(mat);
2180 }
2181 
2187 float mat3_to_scale(const float mat[3][3])
2188 {
2189  /* unit length vector */
2190  float unit_vec[3];
2191  copy_v3_fl(unit_vec, (float)M_SQRT1_3);
2192  mul_m3_v3(mat, unit_vec);
2193  return len_v3(unit_vec);
2194 }
2195 
2196 float mat4_to_scale(const float mat[4][4])
2197 {
2198  /* unit length vector */
2199  float unit_vec[3];
2200  copy_v3_fl(unit_vec, (float)M_SQRT1_3);
2201  mul_mat3_m4_v3(mat, unit_vec);
2202  return len_v3(unit_vec);
2203 }
2204 
2206 float mat4_to_xy_scale(const float M[4][4])
2207 {
2208  /* unit length vector in xy plane */
2209  float unit_vec[3] = {(float)M_SQRT1_2, (float)M_SQRT1_2, 0.0f};
2210  mul_mat3_m4_v3(M, unit_vec);
2211  return len_v3(unit_vec);
2212 }
2213 
2214 void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3])
2215 {
2216  /* keep rot as a 3x3 matrix, the caller can convert into a quat or euler */
2217  size[0] = normalize_v3_v3(rot[0], mat3[0]);
2218  size[1] = normalize_v3_v3(rot[1], mat3[1]);
2219  size[2] = normalize_v3_v3(rot[2], mat3[2]);
2220  if (UNLIKELY(is_negative_m3(rot))) {
2221  negate_m3(rot);
2222  negate_v3(size);
2223  }
2224 }
2225 
2226 void mat4_to_rot(float rot[3][3], const float wmat[4][4])
2227 {
2228  normalize_v3_v3(rot[0], wmat[0]);
2229  normalize_v3_v3(rot[1], wmat[1]);
2230  normalize_v3_v3(rot[2], wmat[2]);
2231  if (UNLIKELY(is_negative_m3(rot))) {
2232  negate_m3(rot);
2233  }
2234 }
2235 
2236 void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4])
2237 {
2238  float mat3[3][3]; /* wmat -> 3x3 */
2239 
2240  copy_m3_m4(mat3, wmat);
2241  mat3_to_rot_size(rot, size, mat3);
2242 
2243  /* location */
2244  copy_v3_v3(loc, wmat[3]);
2245 }
2246 
2247 void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4])
2248 {
2249  float mat3[3][3];
2250  float mat3_n[3][3]; /* normalized mat3 */
2251 
2252  copy_m3_m4(mat3, wmat);
2253  normalize_m3_m3(mat3_n, mat3);
2254 
2255  /* so scale doesn't interfere with rotation T24291. */
2256  /* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */
2257  if (is_negative_m3(mat3)) {
2258  negate_m3(mat3_n);
2259  }
2260 
2261  mat3_normalized_to_quat(quat, mat3_n);
2262  copy_v3_v3(loc, wmat[3]);
2263 }
2264 
2265 void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4])
2266 {
2267  float rot[3][3];
2268  mat4_to_loc_rot_size(loc, rot, size, wmat);
2270 }
2271 
2281 #ifndef MATH_STANDALONE
2282 void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3])
2283 {
2284  /* From svd decomposition (M = WSV*), we have:
2285  * U = WV*
2286  * P = VSV*
2287  */
2288  float W[3][3], S[3][3], V[3][3], Vt[3][3];
2289  float sval[3];
2290 
2291  BLI_svd_m3(mat3, W, sval, V);
2292 
2293  size_to_mat3(S, sval);
2294 
2295  transpose_m3_m3(Vt, V);
2296  mul_m3_m3m3(r_U, W, Vt);
2297  mul_m3_series(r_P, V, S, Vt);
2298 }
2299 #endif
2300 
2301 void scale_m3_fl(float R[3][3], float scale)
2302 {
2303  R[0][0] = R[1][1] = R[2][2] = scale;
2304  R[0][1] = R[0][2] = 0.0;
2305  R[1][0] = R[1][2] = 0.0;
2306  R[2][0] = R[2][1] = 0.0;
2307 }
2308 
2309 void scale_m4_fl(float R[4][4], float scale)
2310 {
2311  R[0][0] = R[1][1] = R[2][2] = scale;
2312  R[3][3] = 1.0;
2313  R[0][1] = R[0][2] = R[0][3] = 0.0;
2314  R[1][0] = R[1][2] = R[1][3] = 0.0;
2315  R[2][0] = R[2][1] = R[2][3] = 0.0;
2316  R[3][0] = R[3][1] = R[3][2] = 0.0;
2317 }
2318 
2319 void translate_m3(float mat[3][3], float tx, float ty)
2320 {
2321  mat[2][0] += (tx * mat[0][0] + ty * mat[1][0]);
2322  mat[2][1] += (tx * mat[0][1] + ty * mat[1][1]);
2323 }
2324 
2325 void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
2326 {
2327  mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]);
2328  mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]);
2329  mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
2330 }
2331 
2332 void rotate_m3(float mat[3][3], const float angle)
2333 {
2334  const float angle_cos = cosf(angle);
2335  const float angle_sin = sinf(angle);
2336 
2337  for (int col = 0; col < 3; col++) {
2338  float temp = angle_cos * mat[0][col] + angle_sin * mat[1][col];
2339  mat[1][col] = -angle_sin * mat[0][col] + angle_cos * mat[1][col];
2340  mat[0][col] = temp;
2341  }
2342 }
2343 
2344 /* TODO: enum for axis? */
2352 void rotate_m4(float mat[4][4], const char axis, const float angle)
2353 {
2354  const float angle_cos = cosf(angle);
2355  const float angle_sin = sinf(angle);
2356 
2357  BLI_assert(axis >= 'X' && axis <= 'Z');
2358 
2359  switch (axis) {
2360  case 'X':
2361  for (int col = 0; col < 4; col++) {
2362  float temp = angle_cos * mat[1][col] + angle_sin * mat[2][col];
2363  mat[2][col] = -angle_sin * mat[1][col] + angle_cos * mat[2][col];
2364  mat[1][col] = temp;
2365  }
2366  break;
2367 
2368  case 'Y':
2369  for (int col = 0; col < 4; col++) {
2370  float temp = angle_cos * mat[0][col] - angle_sin * mat[2][col];
2371  mat[2][col] = angle_sin * mat[0][col] + angle_cos * mat[2][col];
2372  mat[0][col] = temp;
2373  }
2374  break;
2375 
2376  case 'Z':
2377  for (int col = 0; col < 4; col++) {
2378  float temp = angle_cos * mat[0][col] + angle_sin * mat[1][col];
2379  mat[1][col] = -angle_sin * mat[0][col] + angle_cos * mat[1][col];
2380  mat[0][col] = temp;
2381  }
2382  break;
2383  default:
2384  BLI_assert(0);
2385  break;
2386  }
2387 }
2388 
2389 void rescale_m3(float mat[3][3], const float scale[2])
2390 {
2391  mul_v3_fl(mat[0], scale[0]);
2392  mul_v3_fl(mat[1], scale[1]);
2393 }
2394 
2396 void rescale_m4(float mat[4][4], const float scale[3])
2397 {
2398  mul_v3_fl(mat[0], scale[0]);
2399  mul_v3_fl(mat[1], scale[1]);
2400  mul_v3_fl(mat[2], scale[2]);
2401 }
2402 
2411 void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
2412 {
2413  float tmat[4][4];
2414 
2415  unit_m4(tmat);
2416 
2417  copy_v3_v3(tmat[3], pivot);
2418  mul_m4_m4m4(mat, tmat, mat);
2419 
2420  /* invert the matrix */
2421  negate_v3(tmat[3]);
2422  mul_m4_m4m4(mat, mat, tmat);
2423 }
2424 
2425 void transform_pivot_set_m3(float mat[3][3], const float pivot[2])
2426 {
2427  float tmat[3][3];
2428 
2429  unit_m3(tmat);
2430 
2431  copy_v2_v2(tmat[2], pivot);
2432  mul_m3_m3m3(mat, tmat, mat);
2433 
2434  /* invert the matrix */
2435  negate_v2(tmat[2]);
2436  mul_m3_m3m3(mat, mat, tmat);
2437 }
2438 
2439 void blend_m3_m3m3(float out[3][3],
2440  const float dst[3][3],
2441  const float src[3][3],
2442  const float srcweight)
2443 {
2444  float srot[3][3], drot[3][3];
2445  float squat[4], dquat[4], fquat[4];
2446  float sscale[3], dscale[3], fsize[3];
2447  float rmat[3][3], smat[3][3];
2448 
2449  mat3_to_rot_size(drot, dscale, dst);
2450  mat3_to_rot_size(srot, sscale, src);
2451 
2452  mat3_normalized_to_quat(dquat, drot);
2453  mat3_normalized_to_quat(squat, srot);
2454 
2455  /* do blending */
2456  interp_qt_qtqt(fquat, dquat, squat, srcweight);
2457  interp_v3_v3v3(fsize, dscale, sscale, srcweight);
2458 
2459  /* compose new matrix */
2460  quat_to_mat3(rmat, fquat);
2461  size_to_mat3(smat, fsize);
2462  mul_m3_m3m3(out, rmat, smat);
2463 }
2464 
2465 void blend_m4_m4m4(float out[4][4],
2466  const float dst[4][4],
2467  const float src[4][4],
2468  const float srcweight)
2469 {
2470  float sloc[3], dloc[3], floc[3];
2471  float srot[3][3], drot[3][3];
2472  float squat[4], dquat[4], fquat[4];
2473  float sscale[3], dscale[3], fsize[3];
2474 
2475  mat4_to_loc_rot_size(dloc, drot, dscale, dst);
2476  mat4_to_loc_rot_size(sloc, srot, sscale, src);
2477 
2478  mat3_normalized_to_quat(dquat, drot);
2479  mat3_normalized_to_quat(squat, srot);
2480 
2481  /* do blending */
2482  interp_v3_v3v3(floc, dloc, sloc, srcweight);
2483  interp_qt_qtqt(fquat, dquat, squat, srcweight);
2484  interp_v3_v3v3(fsize, dscale, sscale, srcweight);
2485 
2486  /* compose new matrix */
2487  loc_quat_size_to_mat4(out, floc, fquat, fsize);
2488 }
2489 
2490 /* for builds without Eigen */
2491 #ifndef MATH_STANDALONE
2508 void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t)
2509 {
2510  /* 'Rotation' component ('U' part of polar decomposition,
2511  * the closest orthogonal matrix to M3 rot/scale
2512  * transformation matrix), spherically interpolated. */
2513  float U_A[3][3], U_B[3][3], U[3][3];
2514  float quat_A[4], quat_B[4], quat[4];
2515  /* 'Scaling' component ('P' part of polar decomposition, i.e. scaling in U-defined space),
2516  * linearly interpolated. */
2517  float P_A[3][3], P_B[3][3], P[3][3];
2518 
2519  int i;
2520 
2521  mat3_polar_decompose(A, U_A, P_A);
2522  mat3_polar_decompose(B, U_B, P_B);
2523 
2524  /* Quaternions cannot represent an axis flip. If such a singularity is detected, choose a
2525  * different decomposition of the matrix that still satisfies A = U_A * P_A but which has a
2526  * positive determinant and thus no axis flips. This resolves T77154.
2527  *
2528  * Note that a flip of two axes is just a rotation of 180 degrees around the third axis, and
2529  * three flipped axes are just an 180 degree rotation + a single axis flip. It is thus sufficient
2530  * to solve this problem for single axis flips. */
2531  if (determinant_m3_array(U_A) < 0) {
2532  mul_m3_fl(U_A, -1.0f);
2533  mul_m3_fl(P_A, -1.0f);
2534  }
2535  if (determinant_m3_array(U_B) < 0) {
2536  mul_m3_fl(U_B, -1.0f);
2537  mul_m3_fl(P_B, -1.0f);
2538  }
2539 
2540  mat3_to_quat(quat_A, U_A);
2541  mat3_to_quat(quat_B, U_B);
2542  interp_qt_qtqt(quat, quat_A, quat_B, t);
2543  quat_to_mat3(U, quat);
2544 
2545  for (i = 0; i < 3; i++) {
2546  interp_v3_v3v3(P[i], P_A[i], P_B[i], t);
2547  }
2548 
2549  /* And we reconstruct rot/scale matrix from interpolated polar components */
2550  mul_m3_m3m3(R, U, P);
2551 }
2552 
2562 void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t)
2563 {
2564  float A3[3][3], B3[3][3], R3[3][3];
2565 
2566  /* Location component, linearly interpolated. */
2567  float loc_A[3], loc_B[3], loc[3];
2568 
2569  copy_v3_v3(loc_A, A[3]);
2570  copy_v3_v3(loc_B, B[3]);
2571  interp_v3_v3v3(loc, loc_A, loc_B, t);
2572 
2573  copy_m3_m4(A3, A);
2574  copy_m3_m4(B3, B);
2575 
2576  interp_m3_m3m3(R3, A3, B3, t);
2577 
2578  copy_m4_m3(R, R3);
2579  copy_v3_v3(R[3], loc);
2580 }
2581 #endif /* MATH_STANDALONE */
2582 
2583 bool is_negative_m3(const float mat[3][3])
2584 {
2585  float vec[3];
2586  cross_v3_v3v3(vec, mat[0], mat[1]);
2587  return (dot_v3v3(vec, mat[2]) < 0.0f);
2588 }
2589 
2590 bool is_negative_m4(const float mat[4][4])
2591 {
2592  float vec[3];
2593  cross_v3_v3v3(vec, mat[0], mat[1]);
2594  return (dot_v3v3(vec, mat[2]) < 0.0f);
2595 }
2596 
2597 bool is_zero_m3(const float mat[3][3])
2598 {
2599  return (is_zero_v3(mat[0]) && is_zero_v3(mat[1]) && is_zero_v3(mat[2]));
2600 }
2601 bool is_zero_m4(const float mat[4][4])
2602 {
2603  return (is_zero_v4(mat[0]) && is_zero_v4(mat[1]) && is_zero_v4(mat[2]) && is_zero_v4(mat[3]));
2604 }
2605 
2606 bool equals_m3m3(const float mat1[3][3], const float mat2[3][3])
2607 {
2608  return (equals_v3v3(mat1[0], mat2[0]) && equals_v3v3(mat1[1], mat2[1]) &&
2609  equals_v3v3(mat1[2], mat2[2]));
2610 }
2611 
2612 bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
2613 {
2614  return (equals_v4v4(mat1[0], mat2[0]) && equals_v4v4(mat1[1], mat2[1]) &&
2615  equals_v4v4(mat1[2], mat2[2]) && equals_v4v4(mat1[3], mat2[3]));
2616 }
2617 
2622 void loc_rot_size_to_mat3(float R[3][3],
2623  const float loc[2],
2624  const float angle,
2625  const float size[2])
2626 {
2627  unit_m3(R);
2628  translate_m3(R, loc[0], loc[1]);
2629  rotate_m3(R, angle);
2630  rescale_m3(R, size);
2631 }
2632 
2637 void loc_rot_size_to_mat4(float R[4][4],
2638  const float loc[3],
2639  const float rot[3][3],
2640  const float size[3])
2641 {
2642  copy_m4_m3(R, rot);
2643  rescale_m4(R, size);
2644  copy_v3_v3(R[3], loc);
2645 }
2646 
2653 void loc_eul_size_to_mat4(float R[4][4],
2654  const float loc[3],
2655  const float eul[3],
2656  const float size[3])
2657 {
2658  float rmat[3][3], smat[3][3], tmat[3][3];
2659 
2660  /* initialize new matrix */
2661  unit_m4(R);
2662 
2663  /* make rotation + scaling part */
2664  eul_to_mat3(rmat, eul);
2665  size_to_mat3(smat, size);
2666  mul_m3_m3m3(tmat, rmat, smat);
2667 
2668  /* copy rot/scale part to output matrix*/
2669  copy_m4_m3(R, tmat);
2670 
2671  /* copy location to matrix */
2672  R[3][0] = loc[0];
2673  R[3][1] = loc[1];
2674  R[3][2] = loc[2];
2675 }
2676 
2681 void loc_eulO_size_to_mat4(float R[4][4],
2682  const float loc[3],
2683  const float eul[3],
2684  const float size[3],
2685  const short rotOrder)
2686 {
2687  float rmat[3][3], smat[3][3], tmat[3][3];
2688 
2689  /* initialize new matrix */
2690  unit_m4(R);
2691 
2692  /* make rotation + scaling part */
2693  eulO_to_mat3(rmat, eul, rotOrder);
2694  size_to_mat3(smat, size);
2695  mul_m3_m3m3(tmat, rmat, smat);
2696 
2697  /* copy rot/scale part to output matrix*/
2698  copy_m4_m3(R, tmat);
2699 
2700  /* copy location to matrix */
2701  R[3][0] = loc[0];
2702  R[3][1] = loc[1];
2703  R[3][2] = loc[2];
2704 }
2705 
2710 void loc_quat_size_to_mat4(float R[4][4],
2711  const float loc[3],
2712  const float quat[4],
2713  const float size[3])
2714 {
2715  float rmat[3][3], smat[3][3], tmat[3][3];
2716 
2717  /* initialize new matrix */
2718  unit_m4(R);
2719 
2720  /* make rotation + scaling part */
2721  quat_to_mat3(rmat, quat);
2722  size_to_mat3(smat, size);
2723  mul_m3_m3m3(tmat, rmat, smat);
2724 
2725  /* copy rot/scale part to output matrix*/
2726  copy_m4_m3(R, tmat);
2727 
2728  /* copy location to matrix */
2729  R[3][0] = loc[0];
2730  R[3][1] = loc[1];
2731  R[3][2] = loc[2];
2732 }
2733 
2735  float R[4][4], const float loc[3], const float axis[3], const float angle, const float size[3])
2736 {
2737  float q[4];
2738  axis_angle_to_quat(q, axis, angle);
2739  loc_quat_size_to_mat4(R, loc, q, size);
2740 }
2741 
2742 /*********************************** Other ***********************************/
2743 
2744 void print_m3(const char *str, const float m[3][3])
2745 {
2746  printf("%s\n", str);
2747  printf("%f %f %f\n", m[0][0], m[1][0], m[2][0]);
2748  printf("%f %f %f\n", m[0][1], m[1][1], m[2][1]);
2749  printf("%f %f %f\n", m[0][2], m[1][2], m[2][2]);
2750  printf("\n");
2751 }
2752 
2753 void print_m4(const char *str, const float m[4][4])
2754 {
2755  printf("%s\n", str);
2756  printf("%f %f %f %f\n", m[0][0], m[1][0], m[2][0], m[3][0]);
2757  printf("%f %f %f %f\n", m[0][1], m[1][1], m[2][1], m[3][1]);
2758  printf("%f %f %f %f\n", m[0][2], m[1][2], m[2][2], m[3][2]);
2759  printf("%f %f %f %f\n", m[0][3], m[1][3], m[2][3], m[3][3]);
2760  printf("\n");
2761 }
2762 
2763 /*********************************** SVD ************************************
2764  * from TNT matrix library
2765  *
2766  * Compute the Single Value Decomposition of an arbitrary matrix A
2767  * That is compute the 3 matrices U,W,V with U column orthogonal (m,n)
2768  * ,W a diagonal matrix and V an orthogonal square matrix `s.t.A = U.W.Vt`.
2769  * From this decomposition it is trivial to compute the (pseudo-inverse)
2770  * of `A` as `Ainv = V.Winv.transpose(U)`.
2771  */
2772 
2773 void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4])
2774 {
2775  float A[4][4];
2776  float work1[4], work2[4];
2777  int m = 4;
2778  int n = 4;
2779  int maxiter = 200;
2780  int nu = min_ii(m, n);
2781 
2782  float *work = work1;
2783  float *e = work2;
2784  float eps;
2785 
2786  int i = 0, j = 0, k = 0, p, pp, iter;
2787 
2788  /* Reduce A to bidiagonal form, storing the diagonal elements
2789  * in s and the super-diagonal elements in e. */
2790 
2791  int nct = min_ii(m - 1, n);
2792  int nrt = max_ii(0, min_ii(n - 2, m));
2793 
2794  copy_m4_m4(A, A_);
2795  zero_m4(U);
2796  zero_v4(s);
2797 
2798  for (k = 0; k < max_ii(nct, nrt); k++) {
2799  if (k < nct) {
2800 
2801  /* Compute the transformation for the k-th column and
2802  * place the k-th diagonal in s[k].
2803  * Compute 2-norm of k-th column without under/overflow. */
2804  s[k] = 0;
2805  for (i = k; i < m; i++) {
2806  s[k] = hypotf(s[k], A[i][k]);
2807  }
2808  if (s[k] != 0.0f) {
2809  float invsk;
2810  if (A[k][k] < 0.0f) {
2811  s[k] = -s[k];
2812  }
2813  invsk = 1.0f / s[k];
2814  for (i = k; i < m; i++) {
2815  A[i][k] *= invsk;
2816  }
2817  A[k][k] += 1.0f;
2818  }
2819  s[k] = -s[k];
2820  }
2821  for (j = k + 1; j < n; j++) {
2822  if ((k < nct) && (s[k] != 0.0f)) {
2823 
2824  /* Apply the transformation. */
2825 
2826  float t = 0;
2827  for (i = k; i < m; i++) {
2828  t += A[i][k] * A[i][j];
2829  }
2830  t = -t / A[k][k];
2831  for (i = k; i < m; i++) {
2832  A[i][j] += t * A[i][k];
2833  }
2834  }
2835 
2836  /* Place the k-th row of A into e for the */
2837  /* subsequent calculation of the row transformation. */
2838 
2839  e[j] = A[k][j];
2840  }
2841  if (k < nct) {
2842 
2843  /* Place the transformation in U for subsequent back
2844  * multiplication. */
2845 
2846  for (i = k; i < m; i++) {
2847  U[i][k] = A[i][k];
2848  }
2849  }
2850  if (k < nrt) {
2851 
2852  /* Compute the k-th row transformation and place the
2853  * k-th super-diagonal in e[k].
2854  * Compute 2-norm without under/overflow. */
2855  e[k] = 0;
2856  for (i = k + 1; i < n; i++) {
2857  e[k] = hypotf(e[k], e[i]);
2858  }
2859  if (e[k] != 0.0f) {
2860  float invek;
2861  if (e[k + 1] < 0.0f) {
2862  e[k] = -e[k];
2863  }
2864  invek = 1.0f / e[k];
2865  for (i = k + 1; i < n; i++) {
2866  e[i] *= invek;
2867  }
2868  e[k + 1] += 1.0f;
2869  }
2870  e[k] = -e[k];
2871  if ((k + 1 < m) & (e[k] != 0.0f)) {
2872  float invek1;
2873 
2874  /* Apply the transformation. */
2875 
2876  for (i = k + 1; i < m; i++) {
2877  work[i] = 0.0f;
2878  }
2879  for (j = k + 1; j < n; j++) {
2880  for (i = k + 1; i < m; i++) {
2881  work[i] += e[j] * A[i][j];
2882  }
2883  }
2884  invek1 = 1.0f / e[k + 1];
2885  for (j = k + 1; j < n; j++) {
2886  float t = -e[j] * invek1;
2887  for (i = k + 1; i < m; i++) {
2888  A[i][j] += t * work[i];
2889  }
2890  }
2891  }
2892 
2893  /* Place the transformation in V for subsequent
2894  * back multiplication. */
2895 
2896  for (i = k + 1; i < n; i++) {
2897  V[i][k] = e[i];
2898  }
2899  }
2900  }
2901 
2902  /* Set up the final bidiagonal matrix or order p. */
2903 
2904  p = min_ii(n, m + 1);
2905  if (nct < n) {
2906  s[nct] = A[nct][nct];
2907  }
2908  if (m < p) {
2909  s[p - 1] = 0.0f;
2910  }
2911  if (nrt + 1 < p) {
2912  e[nrt] = A[nrt][p - 1];
2913  }
2914  e[p - 1] = 0.0f;
2915 
2916  /* If required, generate U. */
2917 
2918  for (j = nct; j < nu; j++) {
2919  for (i = 0; i < m; i++) {
2920  U[i][j] = 0.0f;
2921  }
2922  U[j][j] = 1.0f;
2923  }
2924  for (k = nct - 1; k >= 0; k--) {
2925  if (s[k] != 0.0f) {
2926  for (j = k + 1; j < nu; j++) {
2927  float t = 0;
2928  for (i = k; i < m; i++) {
2929  t += U[i][k] * U[i][j];
2930  }
2931  t = -t / U[k][k];
2932  for (i = k; i < m; i++) {
2933  U[i][j] += t * U[i][k];
2934  }
2935  }
2936  for (i = k; i < m; i++) {
2937  U[i][k] = -U[i][k];
2938  }
2939  U[k][k] = 1.0f + U[k][k];
2940  for (i = 0; i < k - 1; i++) {
2941  U[i][k] = 0.0f;
2942  }
2943  }
2944  else {
2945  for (i = 0; i < m; i++) {
2946  U[i][k] = 0.0f;
2947  }
2948  U[k][k] = 1.0f;
2949  }
2950  }
2951 
2952  /* If required, generate V. */
2953 
2954  for (k = n - 1; k >= 0; k--) {
2955  if ((k < nrt) & (e[k] != 0.0f)) {
2956  for (j = k + 1; j < nu; j++) {
2957  float t = 0;
2958  for (i = k + 1; i < n; i++) {
2959  t += V[i][k] * V[i][j];
2960  }
2961  t = -t / V[k + 1][k];
2962  for (i = k + 1; i < n; i++) {
2963  V[i][j] += t * V[i][k];
2964  }
2965  }
2966  }
2967  for (i = 0; i < n; i++) {
2968  V[i][k] = 0.0f;
2969  }
2970  V[k][k] = 1.0f;
2971  }
2972 
2973  /* Main iteration loop for the singular values. */
2974 
2975  pp = p - 1;
2976  iter = 0;
2977  eps = powf(2.0f, -52.0f);
2978  while (p > 0) {
2979  int kase = 0;
2980 
2981  /* Test for maximum iterations to avoid infinite loop */
2982  if (maxiter == 0) {
2983  break;
2984  }
2985  maxiter--;
2986 
2987  /* This section of the program inspects for
2988  * negligible elements in the s and e arrays. On
2989  * completion the variables kase and k are set as follows.
2990  *
2991  * kase = 1: if s(p) and e[k - 1] are negligible and k<p
2992  * kase = 2: if s(k) is negligible and k<p
2993  * kase = 3: if e[k - 1] is negligible, k<p, and
2994  * s(k), ..., s(p) are not negligible (qr step).
2995  * kase = 4: if e(p - 1) is negligible (convergence). */
2996 
2997  for (k = p - 2; k >= -1; k--) {
2998  if (k == -1) {
2999  break;
3000  }
3001  if (fabsf(e[k]) <= eps * (fabsf(s[k]) + fabsf(s[k + 1]))) {
3002  e[k] = 0.0f;
3003  break;
3004  }
3005  }
3006  if (k == p - 2) {
3007  kase = 4;
3008  }
3009  else {
3010  int ks;
3011  for (ks = p - 1; ks >= k; ks--) {
3012  float t;
3013  if (ks == k) {
3014  break;
3015  }
3016  t = (ks != p ? fabsf(e[ks]) : 0.0f) + (ks != k + 1 ? fabsf(e[ks - 1]) : 0.0f);
3017  if (fabsf(s[ks]) <= eps * t) {
3018  s[ks] = 0.0f;
3019  break;
3020  }
3021  }
3022  if (ks == k) {
3023  kase = 3;
3024  }
3025  else if (ks == p - 1) {
3026  kase = 1;
3027  }
3028  else {
3029  kase = 2;
3030  k = ks;
3031  }
3032  }
3033  k++;
3034 
3035  /* Perform the task indicated by kase. */
3036 
3037  switch (kase) {
3038 
3039  /* Deflate negligible s(p). */
3040 
3041  case 1: {
3042  float f = e[p - 2];
3043  e[p - 2] = 0.0f;
3044  for (j = p - 2; j >= k; j--) {
3045  float t = hypotf(s[j], f);
3046  float invt = 1.0f / t;
3047  float cs = s[j] * invt;
3048  float sn = f * invt;
3049  s[j] = t;
3050  if (j != k) {
3051  f = -sn * e[j - 1];
3052  e[j - 1] = cs * e[j - 1];
3053  }
3054 
3055  for (i = 0; i < n; i++) {
3056  t = cs * V[i][j] + sn * V[i][p - 1];
3057  V[i][p - 1] = -sn * V[i][j] + cs * V[i][p - 1];
3058  V[i][j] = t;
3059  }
3060  }
3061  break;
3062  }
3063 
3064  /* Split at negligible s(k). */
3065 
3066  case 2: {
3067  float f = e[k - 1];
3068  e[k - 1] = 0.0f;
3069  for (j = k; j < p; j++) {
3070  float t = hypotf(s[j], f);
3071  float invt = 1.0f / t;
3072  float cs = s[j] * invt;
3073  float sn = f * invt;
3074  s[j] = t;
3075  f = -sn * e[j];
3076  e[j] = cs * e[j];
3077 
3078  for (i = 0; i < m; i++) {
3079  t = cs * U[i][j] + sn * U[i][k - 1];
3080  U[i][k - 1] = -sn * U[i][j] + cs * U[i][k - 1];
3081  U[i][j] = t;
3082  }
3083  }
3084  break;
3085  }
3086 
3087  /* Perform one qr step. */
3088 
3089  case 3: {
3090 
3091  /* Calculate the shift. */
3092 
3093  float scale = max_ff(
3094  max_ff(max_ff(max_ff(fabsf(s[p - 1]), fabsf(s[p - 2])), fabsf(e[p - 2])), fabsf(s[k])),
3095  fabsf(e[k]));
3096  float invscale = 1.0f / scale;
3097  float sp = s[p - 1] * invscale;
3098  float spm1 = s[p - 2] * invscale;
3099  float epm1 = e[p - 2] * invscale;
3100  float sk = s[k] * invscale;
3101  float ek = e[k] * invscale;
3102  float b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) * 0.5f;
3103  float c = (sp * epm1) * (sp * epm1);
3104  float shift = 0.0f;
3105  float f, g;
3106  if ((b != 0.0f) || (c != 0.0f)) {
3107  shift = sqrtf(b * b + c);
3108  if (b < 0.0f) {
3109  shift = -shift;
3110  }
3111  shift = c / (b + shift);
3112  }
3113  f = (sk + sp) * (sk - sp) + shift;
3114  g = sk * ek;
3115 
3116  /* Chase zeros. */
3117 
3118  for (j = k; j < p - 1; j++) {
3119  float t = hypotf(f, g);
3120  /* division by zero checks added to avoid NaN (brecht) */
3121  float cs = (t == 0.0f) ? 0.0f : f / t;
3122  float sn = (t == 0.0f) ? 0.0f : g / t;
3123  if (j != k) {
3124  e[j - 1] = t;
3125  }
3126  f = cs * s[j] + sn * e[j];
3127  e[j] = cs * e[j] - sn * s[j];
3128  g = sn * s[j + 1];
3129  s[j + 1] = cs * s[j + 1];
3130 
3131  for (i = 0; i < n; i++) {
3132  t = cs * V[i][j] + sn * V[i][j + 1];
3133  V[i][j + 1] = -sn * V[i][j] + cs * V[i][j + 1];
3134  V[i][j] = t;
3135  }
3136 
3137  t = hypotf(f, g);
3138  /* division by zero checks added to avoid NaN (brecht) */
3139  cs = (t == 0.0f) ? 0.0f : f / t;
3140  sn = (t == 0.0f) ? 0.0f : g / t;
3141  s[j] = t;
3142  f = cs * e[j] + sn * s[j + 1];
3143  s[j + 1] = -sn * e[j] + cs * s[j + 1];
3144  g = sn * e[j + 1];
3145  e[j + 1] = cs * e[j + 1];
3146  if (j < m - 1) {
3147  for (i = 0; i < m; i++) {
3148  t = cs * U[i][j] + sn * U[i][j + 1];
3149  U[i][j + 1] = -sn * U[i][j] + cs * U[i][j + 1];
3150  U[i][j] = t;
3151  }
3152  }
3153  }
3154  e[p - 2] = f;
3155  iter = iter + 1;
3156  break;
3157  }
3158  /* Convergence. */
3159 
3160  case 4: {
3161 
3162  /* Make the singular values positive. */
3163 
3164  if (s[k] <= 0.0f) {
3165  s[k] = (s[k] < 0.0f ? -s[k] : 0.0f);
3166 
3167  for (i = 0; i <= pp; i++) {
3168  V[i][k] = -V[i][k];
3169  }
3170  }
3171 
3172  /* Order the singular values. */
3173 
3174  while (k < pp) {
3175  float t;
3176  if (s[k] >= s[k + 1]) {
3177  break;
3178  }
3179  t = s[k];
3180  s[k] = s[k + 1];
3181  s[k + 1] = t;
3182  if (k < n - 1) {
3183  for (i = 0; i < n; i++) {
3184  t = V[i][k + 1];
3185  V[i][k + 1] = V[i][k];
3186  V[i][k] = t;
3187  }
3188  }
3189  if (k < m - 1) {
3190  for (i = 0; i < m; i++) {
3191  t = U[i][k + 1];
3192  U[i][k + 1] = U[i][k];
3193  U[i][k] = t;
3194  }
3195  }
3196  k++;
3197  }
3198  iter = 0;
3199  p--;
3200  break;
3201  }
3202  }
3203  }
3204 }
3205 
3206 void pseudoinverse_m4_m4(float Ainv[4][4], const float A_[4][4], float epsilon)
3207 {
3208  /* compute Moore-Penrose pseudo inverse of matrix, singular values
3209  * below epsilon are ignored for stability (truncated SVD) */
3210  float A[4][4], V[4][4], W[4], Wm[4][4], U[4][4];
3211  int i;
3212 
3213  transpose_m4_m4(A, A_);
3214  svd_m4(V, W, U, A);
3215  transpose_m4(U);
3216  transpose_m4(V);
3217 
3218  zero_m4(Wm);
3219  for (i = 0; i < 4; i++) {
3220  Wm[i][i] = (W[i] < epsilon) ? 0.0f : 1.0f / W[i];
3221  }
3222 
3223  transpose_m4(V);
3224 
3225  mul_m4_series(Ainv, U, Wm, V);
3226 }
3227 
3228 void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon)
3229 {
3230  /* try regular inverse when possible, otherwise fall back to slow svd */
3231  if (!invert_m3_m3(Ainv, A)) {
3232  float tmp[4][4], tmpinv[4][4];
3233 
3234  copy_m4_m3(tmp, A);
3235  pseudoinverse_m4_m4(tmpinv, tmp, epsilon);
3236  copy_m3_m4(Ainv, tmpinv);
3237  }
3238 }
3239 
3240 bool has_zero_axis_m4(const float matrix[4][4])
3241 {
3242  return len_squared_v3(matrix[0]) < FLT_EPSILON || len_squared_v3(matrix[1]) < FLT_EPSILON ||
3243  len_squared_v3(matrix[2]) < FLT_EPSILON;
3244 }
3245 
3246 void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4])
3247 {
3248  if (!invert_m4_m4(Ainv, A)) {
3249  float Atemp[4][4];
3250 
3251  copy_m4_m4(Atemp, A);
3252 
3253  /* Matrix is degenerate (e.g. 0 scale on some axis), ideally we should
3254  * never be in this situation, but try to invert it anyway with tweak.
3255  */
3256  Atemp[0][0] += 1e-8f;
3257  Atemp[1][1] += 1e-8f;
3258  Atemp[2][2] += 1e-8f;
3259 
3260  if (!invert_m4_m4(Ainv, Atemp)) {
3261  unit_m4(Ainv);
3262  }
3263  }
3264 }
3265 
3266 /* -------------------------------------------------------------------- */
3287 void invert_m4_m4_safe_ortho(float Ainv[4][4], const float A[4][4])
3288 {
3289  if (UNLIKELY(!invert_m4_m4(Ainv, A))) {
3290  float Atemp[4][4];
3291  copy_m4_m4(Atemp, A);
3292  if (UNLIKELY(!(orthogonalize_m4_zero_axes(Atemp, 1.0f) && invert_m4_m4(Ainv, Atemp)))) {
3293  unit_m4(Ainv);
3294  }
3295  }
3296 }
3297 
3298 void invert_m3_m3_safe_ortho(float Ainv[3][3], const float A[3][3])
3299 {
3300  if (UNLIKELY(!invert_m3_m3(Ainv, A))) {
3301  float Atemp[3][3];
3302  copy_m3_m3(Atemp, A);
3303  if (UNLIKELY(!(orthogonalize_m3_zero_axes(Atemp, 1.0f) && invert_m3_m3(Ainv, Atemp)))) {
3304  unit_m3(Ainv);
3305  }
3306  }
3307 }
3308 
3343  const float local[4][4],
3344  const float target[4][4])
3345 {
3346  float itarget[4][4];
3347  invert_m4_m4(itarget, target);
3348  mul_m4_m4m4(data->local2target, itarget, local);
3349  invert_m4_m4(data->target2local, data->local2target);
3350 }
3351 
3365  const float local[4][4],
3366  const float target[4][4])
3367 {
3368  float ilocal[4][4];
3369  invert_m4_m4(ilocal, local);
3370  mul_m4_m4m4(data->local2target, target, ilocal);
3371  invert_m4_m4(data->target2local, data->local2target);
3372 }
3373 
3375 {
3376  mul_v3_m4v3(co, ((SpaceTransform *)data)->local2target, co);
3377 }
3378 
3380 {
3381  mul_v3_m4v3(co, ((SpaceTransform *)data)->target2local, co);
3382 }
3383 
3385 {
3386  mul_mat3_m4_v3(((SpaceTransform *)data)->local2target, no);
3387  normalize_v3(no);
3388 }
3389 
3391 {
3392  mul_mat3_m4_v3(((SpaceTransform *)data)->target2local, no);
3393  normalize_v3(no);
3394 }
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define ATTR_FALLTHROUGH
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
#define M_SQRT1_3
Definition: BLI_math_base.h:56
MINLINE int max_ii(int a, int b)
#define M_PI_2
Definition: BLI_math_base.h:41
#define M_SQRT1_2
Definition: BLI_math_base.h:50
#define mul_m4_series(...)
#define mul_m3_series(...)
void eul_to_mat3(float mat[3][3], const float eul[3])
void mat3_to_quat(float q[4], const float mat[3][3])
void axis_angle_to_quat(float r[4], const float axis[3], const float angle)
void eulO_to_mat3(float mat[3][3], const float eul[3], const short order)
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], const float t)
void quat_to_mat3(float mat[3][3], const float q[4])
void mat3_normalized_to_quat(float q[4], const float mat[3][3])
void BLI_svd_m3(const float m3[3][3], float r_U[3][3], float r_S[], float r_V[3][3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE bool equals_v4v4(const float a[4], const float b[4]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3(float r[3])
MINLINE bool is_zero_v4(const float a[4]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void negate_v2(float r[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v4v4(const float a[4], const float b[4]) ATTR_WARN_UNUSED_RESULT
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
void ortho_v3_v3(float out[3], const float v[3])
Definition: math_vector.c:875
MINLINE void negate_v3(float r[3])
MINLINE void zero_v4(float r[4])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE bool compare_v4v4(const float a[4], const float b[4], const float limit) ATTR_WARN_UNUSED_RESULT
MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT
MINLINE bool equals_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3_length(float r[3], const float unit_scale)
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3_db(double r[3], const double a[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v2(float r[2])
MINLINE float normalize_v2_v2(float r[2], const float a[2])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
#define SWAP(type, a, b)
#define UNPACK3(a)
#define UNLIKELY(x)
#define ELEM(...)
#define LIKELY(x)
typedef double(DMatrix)[4][4]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
#define X
Definition: GeomUtils.cpp:213
#define Z
Definition: GeomUtils.cpp:215
#define Y
Definition: GeomUtils.cpp:214
#define A0
Definition: RandGen.cpp:36
#define A2
Definition: RandGen.cpp:38
#define A1
Definition: RandGen.cpp:37
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define A
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
btMatrix3x3 inverse() const
Return the inverse of the matrix.
Definition: btTransform.h:182
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
static T sum(const btAlignedObjectArray< T > &items)
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
#define rot(x, k)
#define str(s)
uint col
#define sinf(x)
#define cosf(x)
#define powf(x, y)
#define hypotf(x, y)
#define acosf(x)
#define fabsf(x)
#define sqrtf(x)
static float P(float k)
Definition: math_interp.c:41
void mul_v4_m4v3(float r[4], const float M[4][4], const float v[3])
Definition: math_matrix.c:892
void _va_mul_m4_series_4(float r[4][4], const float m1[4][4], const float m2[4][4], const float m3[4][4])
Definition: math_matrix.c:634
void mul_v2_m4v3(float r[2], const float mat[4][4], const float vec[3])
Definition: math_matrix.c:772
void orthogonalize_m3_stable(float R[3][3], int axis, bool normalize)
Definition: math_matrix.c:1659
float mat3_to_scale(const float mat[3][3])
Definition: math_matrix.c:2187
float mat4_to_volume_scale(const float mat[4][4])
Definition: math_matrix.c:2177
bool is_negative_m3(const float mat[3][3])
Definition: math_matrix.c:2583
void mul_v2_project_m4_v3(float r[2], const float mat[4][4], const float vec[3])
Definition: math_matrix.c:845
bool is_orthogonal_m3(const float m[3][3])
Definition: math_matrix.c:1786
void sub_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:1080
void unit_m2(float m[2][2])
Definition: math_matrix.c:51
void BLI_space_transform_apply_normal(const SpaceTransform *data, float no[3])
Definition: math_matrix.c:3384
void mul_v4_m4v3_db(double r[4], const double mat[4][4], const double vec[3])
Definition: math_matrix.c:761
void normalize_m4_m4(float rmat[4][4], const float mat[4][4])
Definition: math_matrix.c:1972
void negate_m3(float R[3][3])
Definition: math_matrix.c:993
void _va_mul_m3_series_6(float r[3][3], const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3], const float m5[3][3])
Definition: math_matrix.c:564
void _va_mul_m3_series_5(float r[3][3], const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3])
Definition: math_matrix.c:554
float mat4_to_scale(const float mat[4][4])
Definition: math_matrix.c:2196
bool is_zero_m3(const float mat[3][3])
Definition: math_matrix.c:2597
void orthogonalize_m4(float R[4][4], int axis)
Definition: math_matrix.c:1514
void swap_m3m3(float m1[3][3], float m2[3][3])
Definition: math_matrix.c:222
void mul_v3_project_m4_v3(float r[3], const float mat[4][4], const float vec[3])
Definition: math_matrix.c:835
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
void zero_m4(float m[4][4])
Definition: math_matrix.c:46
void _va_mul_m4_series_9(float r[4][4], const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4], const float m5[4][4], const float m6[4][4], const float m7[4][4], const float m8[4][4])
Definition: math_matrix.c:694
void mul_m4_fl(float R[4][4], float f)
Definition: math_matrix.c:971
void _va_mul_m3_series_8(float r[3][3], const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3], const float m5[3][3], const float m6[3][3], const float m7[3][3])
Definition: math_matrix.c:590
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
bool invert_m3(float m[3][3])
Definition: math_matrix.c:1152
void mul_mat3_m4_fl(float R[4][4], float f)
Definition: math_matrix.c:982
void _va_mul_m4_series_7(float r[4][4], const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4], const float m5[4][4], const float m6[4][4])
Definition: math_matrix.c:664
void mul_v4_m4v4(float r[4], const float mat[4][4], const float v[4])
Definition: math_matrix.c:854
void mul_m3_m3_pre(float R[3][3], const float A[3][3])
Definition: math_matrix.c:404
void normalize_m2_m2_ex(float R[2][2], const float M[2][2], float r_scale[2])
Definition: math_matrix.c:1897
void size_to_mat3(float R[3][3], const float size[3])
Definition: math_matrix.c:2105
void normalize_m2(float R[2][2])
Definition: math_matrix.c:1889
void sub_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:1091
void mul_v3_m3v3_db(double r[3], const double M[3][3], const double a[3])
Definition: math_matrix.c:911
void BLI_space_transform_invert_normal(const SpaceTransform *data, float no[3])
Definition: math_matrix.c:3390
void loc_rot_size_to_mat3(float R[3][3], const float loc[2], const float angle, const float size[2])
Definition: math_matrix.c:2622
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:89
void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4])
Definition: math_matrix.c:2265
void madd_m4_m4m4fl(float R[4][4], const float A[4][4], const float B[4][4], const float f)
Definition: math_matrix.c:1069
bool is_orthogonal_m4(const float m[4][4])
Definition: math_matrix.c:1801
void adjoint_m3_m3(float R[3][3], const float M[3][3])
Definition: math_matrix.c:1991
void unit_m3(float m[3][3])
Definition: math_matrix.c:58
void mul_m3_v2(const float m[3][3], float r[2])
Definition: math_matrix.c:727
void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3])
Definition: math_matrix.c:2214
void add_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:1047
void scale_m3_fl(float R[3][3], float scale)
Definition: math_matrix.c:2301
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
float determinant_m4_mat3_array(const float m[4][4])
Definition: math_matrix.c:1109
void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3])
Definition: math_matrix.c:437
void mul_v3_m4v3_db(double r[3], const double mat[4][4], const double vec[3])
Definition: math_matrix.c:752
void transpose_m4_m4(float R[4][4], const float M[4][4])
Definition: math_matrix.c:1384
void mul_m4_m4_pre(float R[4][4], const float A[4][4])
Definition: math_matrix.c:375
void mul_m4_m4m4_db_uniq(double R[4][4], const double A[4][4], const double B[4][4])
Definition: math_matrix.c:320
bool invert_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:1161
float mat4_to_xy_scale(const float M[4][4])
Definition: math_matrix.c:2206
void mul_m3_fl(float R[3][3], float f)
Definition: math_matrix.c:960
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
Definition: math_matrix.c:921
void zero_m2(float m[2][2])
Definition: math_matrix.c:36
void _va_mul_m3_series_7(float r[3][3], const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3], const float m5[3][3], const float m6[3][3])
Definition: math_matrix.c:576
void invert_m4_m4_safe_ortho(float Ainv[4][4], const float A[4][4])
Definition: math_matrix.c:3287
void orthogonalize_m3(float R[3][3], int axis)
Definition: math_matrix.c:1425
void copy_m3_m3d(float m1[3][3], const double m2[3][3])
Definition: math_matrix.c:206
void mul_m3_m3_post(float R[3][3], const float B[3][3])
Definition: math_matrix.c:412
void add_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:1036
void copy_m4_m3(float m1[4][4], const float m2[3][3])
Definition: math_matrix.c:120
void translate_m3(float mat[3][3], float tx, float ty)
Definition: math_matrix.c:2319
bool is_uniform_scaled_m3(const float m[3][3])
Definition: math_matrix.c:1850
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:794
void mul_m4_v4d(const float mat[4][4], double r[4])
Definition: math_matrix.c:887
void loc_rot_size_to_mat4(float R[4][4], const float loc[3], const float rot[3][3], const float size[3])
Definition: math_matrix.c:2637
void mat4_to_rot(float rot[3][3], const float wmat[4][4])
Definition: math_matrix.c:2226
void mat4_to_size_fix_shear(float size[3], const float M[4][4])
Definition: math_matrix.c:2156
bool is_uniform_scaled_m4(const float m[4][4])
Definition: math_matrix.c:1874
void invert_m3_m3_safe_ortho(float Ainv[3][3], const float A[3][3])
Definition: math_matrix.c:3298
void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4])
Definition: math_matrix.c:2236
void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4])
Definition: math_matrix.c:2773
bool is_orthonormal_m3(const float m[3][3])
Definition: math_matrix.c:1816
void zero_m3(float m[3][3])
Definition: math_matrix.c:41
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
Definition: math_matrix.c:2325
void loc_axisangle_size_to_mat4(float R[4][4], const float loc[3], const float axis[3], const float angle, const float size[3])
Definition: math_matrix.c:2734
bool has_zero_axis_m4(const float matrix[4][4])
Definition: math_matrix.c:3240
void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
Definition: math_matrix.c:2411
void mul_m3_v3_double(const float M[3][3], double r[3])
Definition: math_matrix.c:1026
float determinant_m2(float a, float b, float c, float d)
Definition: math_matrix.c:2053
void transform_pivot_set_m3(float mat[3][3], const float pivot[2])
Definition: math_matrix.c:2425
bool equals_m3m3(const float mat1[3][3], const float mat2[3][3])
Definition: math_matrix.c:2606
void rescale_m4(float mat[4][4], const float scale[3])
Definition: math_matrix.c:2396
void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:275
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2118
void mul_project_m4_v3(const float mat[4][4], float vec[3])
Definition: math_matrix.c:824
void unit_m4_db(double m[4][4])
Definition: math_matrix.c:75
void copy_m4d_m4(double m1[4][4], const float m2[4][4])
Definition: math_matrix.c:183
void mul_v4d_m4v4d(double r[4], const float mat[4][4], const double v[4])
Definition: math_matrix.c:871
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void orthogonalize_m4_stable(float R[4][4], int axis, bool normalize)
Definition: math_matrix.c:1685
void scale_m4_fl(float R[4][4], float scale)
Definition: math_matrix.c:2309
void normalize_m4(float R[4][4])
Definition: math_matrix.c:1952
void adjoint_m4_m4(float R[4][4], const float M[4][4])
Definition: math_matrix.c:2007
bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
Definition: math_matrix.c:2612
float determinant_m4(const float m[4][4])
Definition: math_matrix.c:2070
void swap_m4m4(float m1[4][4], float m2[4][4])
Definition: math_matrix.c:236
void _va_mul_m3_series_4(float r[3][3], const float m1[3][3], const float m2[3][3], const float m3[3][3])
Definition: math_matrix.c:546
void transpose_m3_m4(float R[3][3], const float M[4][4])
Definition: math_matrix.c:1343
static bool orthogonalize_m3_zero_axes_impl(float *mat[3], const float unit_length)
Definition: math_matrix.c:1718
void copy_m2_m2(float m1[2][2], const float m2[2][2])
Definition: math_matrix.c:84
void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3])
Definition: math_matrix.c:2282
void mul_v2_m2v2(float r[2], const float mat[2][2], const float vec[2])
Definition: math_matrix.c:780
void normalize_m3(float R[3][3])
Definition: math_matrix.c:1919
void _va_mul_m3_series_9(float r[3][3], const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3], const float m5[3][3], const float m6[3][3], const float m7[3][3], const float m8[3][3])
Definition: math_matrix.c:606
void normalize_m4_ex(float R[4][4], float r_scale[3])
Definition: math_matrix.c:1942
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void normalize_m4_m4_ex(float rmat[4][4], const float mat[4][4], float r_scale[3])
Definition: math_matrix.c:1963
void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t)
Definition: math_matrix.c:2562
void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4])
Definition: math_matrix.c:2247
void normalize_m3_ex(float R[3][3], float r_scale[3])
Definition: math_matrix.c:1912
void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:950
void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4])
Definition: math_matrix.c:3246
void mul_m3_m3m4(float R[3][3], const float A[3][3], const float B[4][4])
Definition: math_matrix.c:458
bool orthogonalize_m4_zero_axes(float m[4][4], const float unit_length)
Definition: math_matrix.c:1779
void mul_m4db_m4db_m4fl_uniq(double R[4][4], const double A[4][4], const float B[4][4])
Definition: math_matrix.c:347
void normalize_m3_m3_ex(float R[3][3], const float M[3][3], float r_scale[3])
Definition: math_matrix.c:1927
bool is_orthonormal_m4(const float m[4][4])
Definition: math_matrix.c:1833
void mul_m3_v3_db(const double M[3][3], double r[3])
Definition: math_matrix.c:935
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
Definition: math_matrix.c:742
float determinant_m3_array(const float m[3][3])
Definition: math_matrix.c:1102
void copy_m4_m2(float m1[4][4], const float m2[2][2])
Definition: math_matrix.c:160
void shuffle_m4(float R[4][4], const int index[4])
Definition: math_matrix.c:250
bool is_negative_m4(const float mat[4][4])
Definition: math_matrix.c:2590
void blend_m3_m3m3(float out[3][3], const float dst[3][3], const float src[3][3], const float srcweight)
Definition: math_matrix.c:2439
void negate_mat3_m4(float R[4][4])
Definition: math_matrix.c:1004
void normalize_m2_m2(float R[2][2], const float M[2][2])
Definition: math_matrix.c:1904
void copy_m3_m2(float m1[3][3], const float m2[2][2])
Definition: math_matrix.c:145
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
Definition: math_matrix.c:1278
void mul_v2_m3v2(float r[2], const float m[3][3], const float v[2])
Definition: math_matrix.c:714
void normalize_m2_ex(float R[2][2], float r_scale[2])
Definition: math_matrix.c:1881
static void orthogonalize_stable(float v1[3], float v2[3], float v3[3], bool normalize)
Definition: math_matrix.c:1599
void normalize_m3_m3(float R[3][3], const float M[3][3])
Definition: math_matrix.c:1934
void mul_m4_m4m4_aligned_scale(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:1294
void print_m3(const char *str, const float m[3][3])
Definition: math_matrix.c:2744
void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:420
void mul_m4_v4(const float mat[4][4], float r[4])
Definition: math_matrix.c:866
void loc_quat_size_to_mat4(float R[4][4], const float loc[3], const float quat[4], const float size[3])
Definition: math_matrix.c:2710
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
Definition: math_matrix.c:901
void loc_eul_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], const float size[3])
Definition: math_matrix.c:2653
void rescale_m3(float mat[3][3], const float scale[2])
Definition: math_matrix.c:2389
void mat4_to_size(float size[3], const float M[4][4])
Definition: math_matrix.c:2145
bool invert_m3_m3_ex(float m1[3][3], const float m2[3][3], const float epsilon)
Definition: math_matrix.c:1125
void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t)
Definition: math_matrix.c:2508
void transpose_m3(float R[3][3])
Definition: math_matrix.c:1312
float determinant_m3(float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3)
Definition: math_matrix.c:2059
bool invert_m4(float m[4][4])
Definition: math_matrix.c:1187
void mul_m2_v2(const float mat[2][2], float vec[2])
Definition: math_matrix.c:788
void blend_m4_m4m4(float out[4][4], const float dst[4][4], const float src[4][4], const float srcweight)
Definition: math_matrix.c:2465
void transpose_m3_m3(float R[3][3], const float M[3][3])
Definition: math_matrix.c:1327
void _va_mul_m4_series_8(float r[4][4], const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4], const float m5[4][4], const float m6[4][4], const float m7[4][4])
Definition: math_matrix.c:678
void _va_mul_m4_series_6(float r[4][4], const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4], const float m5[4][4])
Definition: math_matrix.c:652
void pseudoinverse_m4_m4(float Ainv[4][4], const float A_[4][4], float epsilon)
Definition: math_matrix.c:3206
void BLI_space_transform_global_from_matrices(SpaceTransform *data, const float local[4][4], const float target[4][4])
Definition: math_matrix.c:3364
void negate_m4(float R[4][4])
Definition: math_matrix.c:1015
void mul_transposed_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:940
bool compare_m4m4(const float mat1[4][4], const float mat2[4][4], float limit)
Definition: math_matrix.c:1406
void BLI_space_transform_apply(const SpaceTransform *data, float co[3])
Definition: math_matrix.c:3374
void mul_v3_mat3_m4v3_db(double r[3], const double mat[4][4], const double vec[3])
Definition: math_matrix.c:814
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:391
void print_m4(const char *str, const float m[4][4])
Definition: math_matrix.c:2753
bool is_zero_m4(const float mat[4][4])
Definition: math_matrix.c:2601
void mat3_to_size(float size[3], const float M[3][3])
Definition: math_matrix.c:2138
void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4])
Definition: math_matrix.c:505
void _va_mul_m4_series_3(float r[4][4], const float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:630
void transpose_m4(float R[4][4])
Definition: math_matrix.c:1358
void rotate_m3(float mat[3][3], const float angle)
Definition: math_matrix.c:2332
void mul_m4_m4_post(float R[4][4], const float B[4][4])
Definition: math_matrix.c:383
void _va_mul_m3_series_3(float r[3][3], const float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:542
void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
Definition: math_matrix.c:804
void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon)
Definition: math_matrix.c:3228
bool invert_m3_ex(float m[3][3], const float epsilon)
Definition: math_matrix.c:1116
void _va_mul_m4_series_5(float r[4][4], const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4])
Definition: math_matrix.c:642
void loc_eulO_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], const float size[3], const short rotOrder)
Definition: math_matrix.c:2681
void madd_m3_m3m3fl(float R[3][3], const float A[3][3], const float B[3][3], const float f)
Definition: math_matrix.c:1058
void mul_m3_m4m4(float R[3][3], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:525
void copy_m4_m4_db(double m1[4][4], const double m2[4][4])
Definition: math_matrix.c:100
void BLI_space_transform_from_matrices(SpaceTransform *data, const float local[4][4], const float target[4][4])
Definition: math_matrix.c:3342
bool invert_m4_m4_fallback(float inverse[4][4], const float mat[4][4])
Definition: math_matrix.c:1206
bool orthogonalize_m3_zero_axes(float m[3][3], const float unit_length)
Definition: math_matrix.c:1775
void BLI_space_transform_invert(const SpaceTransform *data, float co[3])
Definition: math_matrix.c:3379
void mul_m3_m4m3(float R[3][3], const float A[4][4], const float B[3][3])
Definition: math_matrix.c:482
float mat3_to_volume_scale(const float mat[3][3])
Definition: math_matrix.c:2172
void rotate_m4(float mat[4][4], const char axis, const float angle)
Definition: math_matrix.c:2352
void adjoint_m2_m2(float R[2][2], const float M[2][2])
Definition: math_matrix.c:1982
void unit_m4(float m[4][4])
Definition: math_matrix.c:66
#define M
bool EIG_invert_m4_m4(float inverse[4][4], const float matrix[4][4])
Definition: matrix.cc:39
#define B
#define R
static unsigned c
Definition: RandGen.cpp:97
static double B1(double u)
Definition: FitCurve.cpp:318
static double B0(double u)
Definition: FitCurve.cpp:312
static double B3(double u)
Definition: FitCurve.cpp:330
static double B2(double u)
Definition: FitCurve.cpp:324
static unsigned a[3]
Definition: RandGen.cpp:92
static double epsilon
const btScalar eps
Definition: poly34.cpp:11
float max
ccl_device_inline float2 normalize(const float2 &a)
CCL_NAMESPACE_BEGIN struct View V
uint len