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