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