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