Blender V4.5
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_uniform_scaled_m3(const float m[3][3])
1676{
1677 const float eps = 1e-7f;
1678 float t[3][3];
1679 float l1, l2, l3, l4, l5, l6;
1680
1681 transpose_m3_m3(t, m);
1682
1683 l1 = len_squared_v3(m[0]);
1684 l2 = len_squared_v3(m[1]);
1685 l3 = len_squared_v3(m[2]);
1686
1687 l4 = len_squared_v3(t[0]);
1688 l5 = len_squared_v3(t[1]);
1689 l6 = len_squared_v3(t[2]);
1690
1691 if (fabsf(l2 - l1) <= eps && fabsf(l3 - l1) <= eps && fabsf(l4 - l1) <= eps &&
1692 fabsf(l5 - l1) <= eps && fabsf(l6 - l1) <= eps)
1693 {
1694 return true;
1695 }
1696
1697 return false;
1698}
1699
1700bool is_uniform_scaled_m4(const float m[4][4])
1701{
1702 float t[3][3];
1703 copy_m3_m4(t, m);
1704 return is_uniform_scaled_m3(t);
1705}
1706
1707void normalize_m2_m2(float R[2][2], const float M[2][2])
1708{
1709 int i;
1710 for (i = 0; i < 2; i++) {
1711 normalize_v2_v2(R[i], M[i]);
1712 }
1713}
1714
1715void normalize_m3(float R[3][3])
1716{
1717 int i;
1718 for (i = 0; i < 3; i++) {
1719 normalize_v3(R[i]);
1720 }
1721}
1722
1723void normalize_m3_m3(float R[3][3], const float M[3][3])
1724{
1725 int i;
1726 for (i = 0; i < 3; i++) {
1727 normalize_v3_v3(R[i], M[i]);
1728 }
1729}
1730
1731void normalize_m4_ex(float R[4][4], float r_scale[3])
1732{
1733 int i;
1734 for (i = 0; i < 3; i++) {
1735 r_scale[i] = normalize_v3(R[i]);
1736 if (r_scale[i] != 0.0f) {
1737 R[i][3] /= r_scale[i];
1738 }
1739 }
1740}
1741void normalize_m4(float R[4][4])
1742{
1743 int i;
1744 for (i = 0; i < 3; i++) {
1745 float len = normalize_v3(R[i]);
1746 if (len != 0.0f) {
1747 R[i][3] /= len;
1748 }
1749 }
1750}
1751
1752void normalize_m4_m4(float rmat[4][4], const float mat[4][4])
1753{
1754 int i;
1755 for (i = 0; i < 3; i++) {
1756 float len = normalize_v3_v3(rmat[i], mat[i]);
1757 rmat[i][3] = (len != 0.0f) ? (mat[i][3] / len) : mat[i][3];
1758 }
1759 copy_v4_v4(rmat[3], mat[3]);
1760}
1761
1762void adjoint_m2_m2(float R[2][2], const float M[2][2])
1763{
1764 const float r00 = M[1][1];
1765 const float r01 = -M[0][1];
1766 const float r10 = -M[1][0];
1767 const float r11 = M[0][0];
1768
1769 R[0][0] = r00;
1770 R[0][1] = r01;
1771 R[1][0] = r10;
1772 R[1][1] = r11;
1773}
1774
1775void adjoint_m3_m3(float R[3][3], const float M[3][3])
1776{
1777 BLI_assert(R != M);
1778 R[0][0] = M[1][1] * M[2][2] - M[1][2] * M[2][1];
1779 R[0][1] = -M[0][1] * M[2][2] + M[0][2] * M[2][1];
1780 R[0][2] = M[0][1] * M[1][2] - M[0][2] * M[1][1];
1781
1782 R[1][0] = -M[1][0] * M[2][2] + M[1][2] * M[2][0];
1783 R[1][1] = M[0][0] * M[2][2] - M[0][2] * M[2][0];
1784 R[1][2] = -M[0][0] * M[1][2] + M[0][2] * M[1][0];
1785
1786 R[2][0] = M[1][0] * M[2][1] - M[1][1] * M[2][0];
1787 R[2][1] = -M[0][0] * M[2][1] + M[0][1] * M[2][0];
1788 R[2][2] = M[0][0] * M[1][1] - M[0][1] * M[1][0];
1789}
1790
1791void adjoint_m4_m4(float R[4][4], const float M[4][4]) /* out = ADJ(in) */
1792{
1793 float a1, a2, a3, a4, b1, b2, b3, b4;
1794 float c1, c2, c3, c4, d1, d2, d3, d4;
1795
1796 a1 = M[0][0];
1797 b1 = M[0][1];
1798 c1 = M[0][2];
1799 d1 = M[0][3];
1800
1801 a2 = M[1][0];
1802 b2 = M[1][1];
1803 c2 = M[1][2];
1804 d2 = M[1][3];
1805
1806 a3 = M[2][0];
1807 b3 = M[2][1];
1808 c3 = M[2][2];
1809 d3 = M[2][3];
1810
1811 a4 = M[3][0];
1812 b4 = M[3][1];
1813 c4 = M[3][2];
1814 d4 = M[3][3];
1815
1816 R[0][0] = determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
1817 R[1][0] = -determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
1818 R[2][0] = determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
1819 R[3][0] = -determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
1820
1821 R[0][1] = -determinant_m3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
1822 R[1][1] = determinant_m3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
1823 R[2][1] = -determinant_m3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
1824 R[3][1] = determinant_m3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
1825
1826 R[0][2] = determinant_m3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
1827 R[1][2] = -determinant_m3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
1828 R[2][2] = determinant_m3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
1829 R[3][2] = -determinant_m3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
1830
1831 R[0][3] = -determinant_m3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
1832 R[1][3] = determinant_m3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
1833 R[2][3] = -determinant_m3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
1834 R[3][3] = determinant_m3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
1835}
1836
1837float determinant_m2(const float a, const float b, const float c, const float d)
1838{
1839 return a * d - b * c;
1840}
1841
1843 float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3)
1844{
1845 float ans;
1846
1847 ans = (a1 * determinant_m2(b2, b3, c2, c3) - b1 * determinant_m2(a2, a3, c2, c3) +
1848 c1 * determinant_m2(a2, a3, b2, b3));
1849
1850 return ans;
1851}
1852
1853float determinant_m4(const float m[4][4])
1854{
1855 float ans;
1856 float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
1857
1858 a1 = m[0][0];
1859 b1 = m[0][1];
1860 c1 = m[0][2];
1861 d1 = m[0][3];
1862
1863 a2 = m[1][0];
1864 b2 = m[1][1];
1865 c2 = m[1][2];
1866 d2 = m[1][3];
1867
1868 a3 = m[2][0];
1869 b3 = m[2][1];
1870 c3 = m[2][2];
1871 d3 = m[2][3];
1872
1873 a4 = m[3][0];
1874 b4 = m[3][1];
1875 c4 = m[3][2];
1876 d4 = m[3][3];
1877
1878 ans = (a1 * determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4) -
1879 b1 * determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4) +
1880 c1 * determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4) -
1881 d1 * determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4));
1882
1883 return ans;
1884}
1885
1886/****************************** Transformations ******************************/
1887
1888void size_to_mat3(float R[3][3], const float size[3])
1889{
1890 R[0][0] = size[0];
1891 R[0][1] = 0.0f;
1892 R[0][2] = 0.0f;
1893 R[1][1] = size[1];
1894 R[1][0] = 0.0f;
1895 R[1][2] = 0.0f;
1896 R[2][2] = size[2];
1897 R[2][1] = 0.0f;
1898 R[2][0] = 0.0f;
1899}
1900
1901void size_to_mat4(float R[4][4], 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[0][3] = 0.0f;
1907 R[1][0] = 0.0f;
1908 R[1][1] = size[1];
1909 R[1][2] = 0.0f;
1910 R[1][3] = 0.0f;
1911 R[2][0] = 0.0f;
1912 R[2][1] = 0.0f;
1913 R[2][2] = size[2];
1914 R[2][3] = 0.0f;
1915 R[3][0] = 0.0f;
1916 R[3][1] = 0.0f;
1917 R[3][2] = 0.0f;
1918 R[3][3] = 1.0f;
1919}
1920
1921void mat3_to_size(float size[3], const float M[3][3])
1922{
1923 size[0] = len_v3(M[0]);
1924 size[1] = len_v3(M[1]);
1925 size[2] = len_v3(M[2]);
1926}
1927
1928void mat4_to_size(float size[3], const float M[4][4])
1929{
1930 size[0] = len_v3(M[0]);
1931 size[1] = len_v3(M[1]);
1932 size[2] = len_v3(M[2]);
1933}
1934
1935float mat4_to_size_max_axis(const float M[4][4])
1936{
1938}
1939
1940void mat4_to_size_fix_shear(float size[3], const float M[4][4])
1941{
1943
1944 float volume = size[0] * size[1] * size[2];
1945
1946 if (volume != 0.0f) {
1947 mul_v3_fl(size, cbrtf(fabsf(mat4_to_volume_scale(M) / volume)));
1948 }
1949}
1950
1951float mat4_to_volume_scale(const float mat[4][4])
1952{
1953 return determinant_m4_mat3_array(mat);
1954}
1955
1956float mat3_to_scale(const float mat[3][3])
1957{
1958 /* unit length vector */
1959 float unit_vec[3];
1960 copy_v3_fl(unit_vec, float(M_SQRT1_3));
1961 mul_m3_v3(mat, unit_vec);
1962 return len_v3(unit_vec);
1963}
1964
1965float mat4_to_scale(const float mat[4][4])
1966{
1967 /* unit length vector */
1968 float unit_vec[3];
1969 copy_v3_fl(unit_vec, float(M_SQRT1_3));
1970 mul_mat3_m4_v3(mat, unit_vec);
1971 return len_v3(unit_vec);
1972}
1973
1974void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3])
1975{
1976 /* keep rot as a 3x3 matrix, the caller can convert into a quat or euler */
1977 size[0] = normalize_v3_v3(rot[0], mat3[0]);
1978 size[1] = normalize_v3_v3(rot[1], mat3[1]);
1979 size[2] = normalize_v3_v3(rot[2], mat3[2]);
1980 if (UNLIKELY(is_negative_m3(rot))) {
1981 negate_m3(rot);
1982 negate_v3(size);
1983 }
1984}
1985
1986void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4])
1987{
1988 float mat3[3][3]; /* wmat -> 3x3 */
1989
1990 copy_m3_m4(mat3, wmat);
1991 mat3_to_rot_size(rot, size, mat3);
1992
1993 /* location */
1994 copy_v3_v3(loc, wmat[3]);
1995}
1996
1997void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4])
1998{
1999 float mat3[3][3];
2000 float mat3_n[3][3]; /* normalized mat3 */
2001
2002 copy_m3_m4(mat3, wmat);
2003 normalize_m3_m3(mat3_n, mat3);
2004
2005 mat3_normalized_to_quat(quat, mat3_n);
2006 copy_v3_v3(loc, wmat[3]);
2007}
2008
2009void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4])
2010{
2011 float rot[3][3];
2012 mat4_to_loc_rot_size(loc, rot, size, wmat);
2014}
2015
2025#ifndef MATH_STANDALONE
2026void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3])
2027{
2028 /* From svd decomposition (M = WSV*), we have:
2029 * U = WV*
2030 * P = VSV*
2031 */
2032 float W[3][3], S[3][3], V[3][3], Vt[3][3];
2033 float sval[3];
2034
2035 BLI_svd_m3(mat3, W, sval, V);
2036
2037 size_to_mat3(S, sval);
2038
2039 transpose_m3_m3(Vt, V);
2040 mul_m3_m3m3(r_U, W, Vt);
2041 mul_m3_series(r_P, V, S, Vt);
2042}
2043#endif
2044
2045void scale_m3_fl(float R[3][3], float scale)
2046{
2047 R[0][0] = R[1][1] = R[2][2] = scale;
2048 R[0][1] = R[0][2] = 0.0;
2049 R[1][0] = R[1][2] = 0.0;
2050 R[2][0] = R[2][1] = 0.0;
2051}
2052
2053void scale_m4_fl(float R[4][4], float scale)
2054{
2055 R[0][0] = R[1][1] = R[2][2] = scale;
2056 R[3][3] = 1.0;
2057 R[0][1] = R[0][2] = R[0][3] = 0.0;
2058 R[1][0] = R[1][2] = R[1][3] = 0.0;
2059 R[2][0] = R[2][1] = R[2][3] = 0.0;
2060 R[3][0] = R[3][1] = R[3][2] = 0.0;
2061}
2062
2063void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
2064{
2065 mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]);
2066 mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]);
2067 mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
2068}
2069
2070void rotate_m4(float mat[4][4], const char axis, const float angle)
2071{
2072 const float angle_cos = cosf(angle);
2073 const float angle_sin = sinf(angle);
2074
2075 BLI_assert(axis >= 'X' && axis <= 'Z');
2076
2077 switch (axis) {
2078 case 'X':
2079 for (int col = 0; col < 4; col++) {
2080 float temp = angle_cos * mat[1][col] + angle_sin * mat[2][col];
2081 mat[2][col] = -angle_sin * mat[1][col] + angle_cos * mat[2][col];
2082 mat[1][col] = temp;
2083 }
2084 break;
2085
2086 case 'Y':
2087 for (int col = 0; col < 4; col++) {
2088 float temp = angle_cos * mat[0][col] - angle_sin * mat[2][col];
2089 mat[2][col] = angle_sin * mat[0][col] + angle_cos * mat[2][col];
2090 mat[0][col] = temp;
2091 }
2092 break;
2093
2094 case 'Z':
2095 for (int col = 0; col < 4; col++) {
2096 float temp = angle_cos * mat[0][col] + angle_sin * mat[1][col];
2097 mat[1][col] = -angle_sin * mat[0][col] + angle_cos * mat[1][col];
2098 mat[0][col] = temp;
2099 }
2100 break;
2101 default:
2103 break;
2104 }
2105}
2106
2107void rescale_m4(float mat[4][4], const float scale[3])
2108{
2109 mul_v3_fl(mat[0], scale[0]);
2110 mul_v3_fl(mat[1], scale[1]);
2111 mul_v3_fl(mat[2], scale[2]);
2112}
2113
2114void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
2115{
2116 float tmat[4][4];
2117
2118 unit_m4(tmat);
2119
2120 copy_v3_v3(tmat[3], pivot);
2121 mul_m4_m4m4(mat, tmat, mat);
2122
2123 /* invert the matrix */
2124 negate_v3(tmat[3]);
2125 mul_m4_m4m4(mat, mat, tmat);
2126}
2127
2128void blend_m3_m3m3(float out[3][3],
2129 const float dst[3][3],
2130 const float src[3][3],
2131 const float srcweight)
2132{
2133 float srot[3][3], drot[3][3];
2134 float squat[4], dquat[4], fquat[4];
2135 float sscale[3], dscale[3], fsize[3];
2136 float rmat[3][3], smat[3][3];
2137
2138 mat3_to_rot_size(drot, dscale, dst);
2139 mat3_to_rot_size(srot, sscale, src);
2140
2141 mat3_normalized_to_quat_fast(dquat, drot);
2142 mat3_normalized_to_quat_fast(squat, srot);
2143
2144 /* do blending */
2145 interp_qt_qtqt(fquat, dquat, squat, srcweight);
2146 interp_v3_v3v3(fsize, dscale, sscale, srcweight);
2147
2148 /* compose new matrix */
2149 quat_to_mat3(rmat, fquat);
2150 size_to_mat3(smat, fsize);
2151 mul_m3_m3m3(out, rmat, smat);
2152}
2153
2154void blend_m4_m4m4(float out[4][4],
2155 const float dst[4][4],
2156 const float src[4][4],
2157 const float srcweight)
2158{
2159 float sloc[3], dloc[3], floc[3];
2160 float srot[3][3], drot[3][3];
2161 float squat[4], dquat[4], fquat[4];
2162 float sscale[3], dscale[3], fsize[3];
2163
2164 mat4_to_loc_rot_size(dloc, drot, dscale, dst);
2165 mat4_to_loc_rot_size(sloc, srot, sscale, src);
2166
2167 mat3_normalized_to_quat_fast(dquat, drot);
2168 mat3_normalized_to_quat_fast(squat, srot);
2169
2170 /* do blending */
2171 interp_v3_v3v3(floc, dloc, sloc, srcweight);
2172 interp_qt_qtqt(fquat, dquat, squat, srcweight);
2173 interp_v3_v3v3(fsize, dscale, sscale, srcweight);
2174
2175 /* compose new matrix */
2176 loc_quat_size_to_mat4(out, floc, fquat, fsize);
2177}
2178
2179/* for builds without Eigen */
2180#ifndef MATH_STANDALONE
2181void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t)
2182{
2183 /* 'Rotation' component ('U' part of polar decomposition,
2184 * the closest orthogonal matrix to M3 rot/scale
2185 * transformation matrix), spherically interpolated. */
2186 float U_A[3][3], U_B[3][3], U[3][3];
2187 float quat_A[4], quat_B[4], quat[4];
2188 /* 'Scaling' component ('P' part of polar decomposition, i.e. scaling in U-defined space),
2189 * linearly interpolated. */
2190 float P_A[3][3], P_B[3][3], P[3][3];
2191
2192 int i;
2193
2194 mat3_polar_decompose(A, U_A, P_A);
2195 mat3_polar_decompose(B, U_B, P_B);
2196
2197 /* Quaternions cannot represent an axis flip. If such a singularity is detected, choose a
2198 * different decomposition of the matrix that still satisfies A = U_A * P_A but which has a
2199 * positive determinant and thus no axis flips. This resolves #77154.
2200 *
2201 * Note that a flip of two axes is just a rotation of 180 degrees around the third axis, and
2202 * three flipped axes are just an 180 degree rotation + a single axis flip. It is thus sufficient
2203 * to solve this problem for single axis flips. */
2204 if (is_negative_m3(U_A)) {
2205 mul_m3_fl(U_A, -1.0f);
2206 mul_m3_fl(P_A, -1.0f);
2207 }
2208 if (is_negative_m3(U_B)) {
2209 mul_m3_fl(U_B, -1.0f);
2210 mul_m3_fl(P_B, -1.0f);
2211 }
2212
2213 mat3_to_quat(quat_A, U_A);
2214 mat3_to_quat(quat_B, U_B);
2215 interp_qt_qtqt(quat, quat_A, quat_B, t);
2216 quat_to_mat3(U, quat);
2217
2218 for (i = 0; i < 3; i++) {
2219 interp_v3_v3v3(P[i], P_A[i], P_B[i], t);
2220 }
2221
2222 /* And we reconstruct rot/scale matrix from interpolated polar components */
2223 mul_m3_m3m3(R, U, P);
2224}
2225
2226void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t)
2227{
2228 float A3[3][3], B3[3][3], R3[3][3];
2229
2230 /* Location component, linearly interpolated. */
2231 float loc_A[3], loc_B[3], loc[3];
2232
2233 copy_v3_v3(loc_A, A[3]);
2234 copy_v3_v3(loc_B, B[3]);
2235 interp_v3_v3v3(loc, loc_A, loc_B, t);
2236
2237 copy_m3_m4(A3, A);
2238 copy_m3_m4(B3, B);
2239
2240 interp_m3_m3m3(R3, A3, B3, t);
2241
2242 copy_m4_m3(R, R3);
2243 copy_v3_v3(R[3], loc);
2244}
2245#endif /* MATH_STANDALONE */
2246
2247bool is_negative_m3(const float mat[3][3])
2248{
2249 return determinant_m3_array(mat) < 0.0f;
2250}
2251
2252bool is_negative_m4(const float mat[4][4])
2253{
2254 /* Don't use #determinant_m4 as only the 3x3 components are needed
2255 * when the matrix is used as a transformation to represent location/scale/rotation. */
2256 return determinant_m4_mat3_array(mat) < 0.0f;
2257}
2258
2259bool is_zero_m4(const float mat[4][4])
2260{
2261 return (is_zero_v4(mat[0]) && is_zero_v4(mat[1]) && is_zero_v4(mat[2]) && is_zero_v4(mat[3]));
2262}
2263
2264bool equals_m3m3(const float mat1[3][3], const float mat2[3][3])
2265{
2266 return (equals_v3v3(mat1[0], mat2[0]) && equals_v3v3(mat1[1], mat2[1]) &&
2267 equals_v3v3(mat1[2], mat2[2]));
2268}
2269
2270bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
2271{
2272 return (equals_v4v4(mat1[0], mat2[0]) && equals_v4v4(mat1[1], mat2[1]) &&
2273 equals_v4v4(mat1[2], mat2[2]) && equals_v4v4(mat1[3], mat2[3]));
2274}
2275
2276void loc_rot_size_to_mat4(float R[4][4],
2277 const float loc[3],
2278 const float rot[3][3],
2279 const float size[3])
2280{
2281 copy_m4_m3(R, rot);
2282 rescale_m4(R, size);
2283 copy_v3_v3(R[3], loc);
2284}
2285
2286void loc_eul_size_to_mat4(float R[4][4],
2287 const float loc[3],
2288 const float eul[3],
2289 const float size[3])
2290{
2291 float rmat[3][3], smat[3][3], tmat[3][3];
2292
2293 /* initialize new matrix */
2294 unit_m4(R);
2295
2296 /* make rotation + scaling part */
2297 eul_to_mat3(rmat, eul);
2298 size_to_mat3(smat, size);
2299 mul_m3_m3m3(tmat, rmat, smat);
2300
2301 /* Copy rot/scale part to output matrix. */
2302 copy_m4_m3(R, tmat);
2303
2304 /* copy location to matrix */
2305 R[3][0] = loc[0];
2306 R[3][1] = loc[1];
2307 R[3][2] = loc[2];
2308}
2309
2311 float R[4][4], const float loc[3], const float eul[3], const float size[3], const short order)
2312{
2313 float rmat[3][3], smat[3][3], tmat[3][3];
2314
2315 /* Initialize new matrix. */
2316 unit_m4(R);
2317
2318 /* Make rotation + scaling part. */
2319 eulO_to_mat3(rmat, eul, order);
2320 size_to_mat3(smat, size);
2321 mul_m3_m3m3(tmat, rmat, smat);
2322
2323 /* Copy rot/scale part to output matrix. */
2324 copy_m4_m3(R, tmat);
2325
2326 /* Copy location to matrix. */
2327 R[3][0] = loc[0];
2328 R[3][1] = loc[1];
2329 R[3][2] = loc[2];
2330}
2331
2332void loc_quat_size_to_mat4(float R[4][4],
2333 const float loc[3],
2334 const float quat[4],
2335 const float size[3])
2336{
2337 float rmat[3][3], smat[3][3], tmat[3][3];
2338
2339 /* initialize new matrix */
2340 unit_m4(R);
2341
2342 /* make rotation + scaling part */
2343 quat_to_mat3(rmat, quat);
2344 size_to_mat3(smat, size);
2345 mul_m3_m3m3(tmat, rmat, smat);
2346
2347 /* Copy rot/scale part to output matrix. */
2348 copy_m4_m3(R, tmat);
2349
2350 /* copy location to matrix */
2351 R[3][0] = loc[0];
2352 R[3][1] = loc[1];
2353 R[3][2] = loc[2];
2354}
2355
2356/*********************************** Other ***********************************/
2357
2358void print_m3(const char *str, const float m[3][3])
2359{
2360 printf("%s\n", str);
2361 printf("%f %f %f\n", m[0][0], m[1][0], m[2][0]);
2362 printf("%f %f %f\n", m[0][1], m[1][1], m[2][1]);
2363 printf("%f %f %f\n", m[0][2], m[1][2], m[2][2]);
2364 printf("\n");
2365}
2366
2367void print_m4(const char *str, const float m[4][4])
2368{
2369 printf("%s\n", str);
2370 printf("%f %f %f %f\n", m[0][0], m[1][0], m[2][0], m[3][0]);
2371 printf("%f %f %f %f\n", m[0][1], m[1][1], m[2][1], m[3][1]);
2372 printf("%f %f %f %f\n", m[0][2], m[1][2], m[2][2], m[3][2]);
2373 printf("%f %f %f %f\n", m[0][3], m[1][3], m[2][3], m[3][3]);
2374 printf("\n");
2375}
2376
2377void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4])
2378{
2379 /* NOTE: originally from TNT (template numeric toolkit) matrix library.
2380 * https://math.nist.gov/tnt */
2381
2382 float A[4][4];
2383 float work1[4], work2[4];
2384 int m = 4;
2385 int n = 4;
2386 int maxiter = 200;
2387 int nu = min_ii(m, n);
2388
2389 float *work = work1;
2390 float *e = work2;
2391 float eps;
2392
2393 int i = 0, j = 0, k = 0, p, pp, iter;
2394
2395 /* Reduce A to bidiagonal form, storing the diagonal elements
2396 * in s and the super-diagonal elements in e. */
2397
2398 int nct = min_ii(m - 1, n);
2399 int nrt = max_ii(0, min_ii(n - 2, m));
2400
2401 copy_m4_m4(A, A_);
2402 zero_m4(U);
2403 zero_v4(s);
2404
2405 for (k = 0; k < max_ii(nct, nrt); k++) {
2406 if (k < nct) {
2407
2408 /* Compute the transformation for the k-th column and
2409 * place the k-th diagonal in s[k].
2410 * Compute 2-norm of k-th column without under/overflow. */
2411 s[k] = 0;
2412 for (i = k; i < m; i++) {
2413 s[k] = hypotf(s[k], A[i][k]);
2414 }
2415 if (s[k] != 0.0f) {
2416 float invsk;
2417 if (A[k][k] < 0.0f) {
2418 s[k] = -s[k];
2419 }
2420 invsk = 1.0f / s[k];
2421 for (i = k; i < m; i++) {
2422 A[i][k] *= invsk;
2423 }
2424 A[k][k] += 1.0f;
2425 }
2426 s[k] = -s[k];
2427 }
2428 for (j = k + 1; j < n; j++) {
2429 if ((k < nct) && (s[k] != 0.0f)) {
2430
2431 /* Apply the transformation. */
2432
2433 float t = 0;
2434 for (i = k; i < m; i++) {
2435 t += A[i][k] * A[i][j];
2436 }
2437 t = -t / A[k][k];
2438 for (i = k; i < m; i++) {
2439 A[i][j] += t * A[i][k];
2440 }
2441 }
2442
2443 /* Place the k-th row of A into e for the */
2444 /* subsequent calculation of the row transformation. */
2445
2446 e[j] = A[k][j];
2447 }
2448 if (k < nct) {
2449
2450 /* Place the transformation in U for subsequent back
2451 * multiplication. */
2452
2453 for (i = k; i < m; i++) {
2454 U[i][k] = A[i][k];
2455 }
2456 }
2457 if (k < nrt) {
2458
2459 /* Compute the k-th row transformation and place the
2460 * k-th super-diagonal in e[k].
2461 * Compute 2-norm without under/overflow. */
2462 e[k] = 0;
2463 for (i = k + 1; i < n; i++) {
2464 e[k] = hypotf(e[k], e[i]);
2465 }
2466 if (e[k] != 0.0f) {
2467 float invek;
2468 if (e[k + 1] < 0.0f) {
2469 e[k] = -e[k];
2470 }
2471 invek = 1.0f / e[k];
2472 for (i = k + 1; i < n; i++) {
2473 e[i] *= invek;
2474 }
2475 e[k + 1] += 1.0f;
2476 }
2477 e[k] = -e[k];
2478 if ((k + 1 < m) && (e[k] != 0.0f)) {
2479 float invek1;
2480
2481 /* Apply the transformation. */
2482
2483 for (i = k + 1; i < m; i++) {
2484 work[i] = 0.0f;
2485 }
2486 for (j = k + 1; j < n; j++) {
2487 for (i = k + 1; i < m; i++) {
2488 work[i] += e[j] * A[i][j];
2489 }
2490 }
2491 invek1 = 1.0f / e[k + 1];
2492 for (j = k + 1; j < n; j++) {
2493 float t = -e[j] * invek1;
2494 for (i = k + 1; i < m; i++) {
2495 A[i][j] += t * work[i];
2496 }
2497 }
2498 }
2499
2500 /* Place the transformation in V for subsequent
2501 * back multiplication. */
2502
2503 for (i = k + 1; i < n; i++) {
2504 V[i][k] = e[i];
2505 }
2506 }
2507 }
2508
2509 /* Set up the final bidiagonal matrix or order p. */
2510
2511 p = min_ii(n, m + 1);
2512 if (nct < n) {
2513 s[nct] = A[nct][nct];
2514 }
2515 if (m < p) {
2516 s[p - 1] = 0.0f;
2517 }
2518 if (nrt + 1 < p) {
2519 e[nrt] = A[nrt][p - 1];
2520 }
2521 e[p - 1] = 0.0f;
2522
2523 /* If required, generate U. */
2524
2525 for (j = nct; j < nu; j++) {
2526 for (i = 0; i < m; i++) {
2527 U[i][j] = 0.0f;
2528 }
2529 U[j][j] = 1.0f;
2530 }
2531 for (k = nct - 1; k >= 0; k--) {
2532 if (s[k] != 0.0f) {
2533 for (j = k + 1; j < nu; j++) {
2534 float t = 0;
2535 for (i = k; i < m; i++) {
2536 t += U[i][k] * U[i][j];
2537 }
2538 t = -t / U[k][k];
2539 for (i = k; i < m; i++) {
2540 U[i][j] += t * U[i][k];
2541 }
2542 }
2543 for (i = k; i < m; i++) {
2544 U[i][k] = -U[i][k];
2545 }
2546 U[k][k] = 1.0f + U[k][k];
2547 for (i = 0; i < k - 1; i++) {
2548 U[i][k] = 0.0f;
2549 }
2550 }
2551 else {
2552 for (i = 0; i < m; i++) {
2553 U[i][k] = 0.0f;
2554 }
2555 U[k][k] = 1.0f;
2556 }
2557 }
2558
2559 /* If required, generate V. */
2560
2561 for (k = n - 1; k >= 0; k--) {
2562 if ((k < nrt) && (e[k] != 0.0f)) {
2563 for (j = k + 1; j < nu; j++) {
2564 float t = 0;
2565 for (i = k + 1; i < n; i++) {
2566 t += V[i][k] * V[i][j];
2567 }
2568 t = -t / V[k + 1][k];
2569 for (i = k + 1; i < n; i++) {
2570 V[i][j] += t * V[i][k];
2571 }
2572 }
2573 }
2574 for (i = 0; i < n; i++) {
2575 V[i][k] = 0.0f;
2576 }
2577 V[k][k] = 1.0f;
2578 }
2579
2580 /* Main iteration loop for the singular values. */
2581
2582 pp = p - 1;
2583 iter = 0;
2584 eps = powf(2.0f, -52.0f);
2585 while (p > 0) {
2586 int kase = 0;
2587
2588 /* Test for maximum iterations to avoid infinite loop */
2589 if (maxiter == 0) {
2590 break;
2591 }
2592 maxiter--;
2593
2594 /* This section of the program inspects for
2595 * negligible elements in the s and e arrays. On
2596 * completion the variables kase and k are set as follows.
2597 *
2598 * kase = 1: if s(p) and e[k - 1] are negligible and k<p
2599 * kase = 2: if s(k) is negligible and k<p
2600 * kase = 3: if e[k - 1] is negligible, k<p, and
2601 * s(k), ..., s(p) are not negligible (qr step).
2602 * kase = 4: if e(p - 1) is negligible (convergence). */
2603
2604 for (k = p - 2; k >= -1; k--) {
2605 if (k == -1) {
2606 break;
2607 }
2608 if (fabsf(e[k]) <= eps * (fabsf(s[k]) + fabsf(s[k + 1]))) {
2609 e[k] = 0.0f;
2610 break;
2611 }
2612 }
2613 if (k == p - 2) {
2614 kase = 4;
2615 }
2616 else {
2617 int ks;
2618 for (ks = p - 1; ks >= k; ks--) {
2619 float t;
2620 if (ks == k) {
2621 break;
2622 }
2623 t = (ks != p ? fabsf(e[ks]) : 0.0f) + (ks != k + 1 ? fabsf(e[ks - 1]) : 0.0f);
2624 if (fabsf(s[ks]) <= eps * t) {
2625 s[ks] = 0.0f;
2626 break;
2627 }
2628 }
2629 if (ks == k) {
2630 kase = 3;
2631 }
2632 else if (ks == p - 1) {
2633 kase = 1;
2634 }
2635 else {
2636 kase = 2;
2637 k = ks;
2638 }
2639 }
2640 k++;
2641
2642 /* Perform the task indicated by kase. */
2643
2644 switch (kase) {
2645
2646 /* Deflate negligible s(p). */
2647
2648 case 1: {
2649 float f = e[p - 2];
2650 e[p - 2] = 0.0f;
2651 for (j = p - 2; j >= k; j--) {
2652 float t = hypotf(s[j], f);
2653 float invt = 1.0f / t;
2654 float cs = s[j] * invt;
2655 float sn = f * invt;
2656 s[j] = t;
2657 if (j != k) {
2658 f = -sn * e[j - 1];
2659 e[j - 1] = cs * e[j - 1];
2660 }
2661
2662 for (i = 0; i < n; i++) {
2663 t = cs * V[i][j] + sn * V[i][p - 1];
2664 V[i][p - 1] = -sn * V[i][j] + cs * V[i][p - 1];
2665 V[i][j] = t;
2666 }
2667 }
2668 break;
2669 }
2670
2671 /* Split at negligible s(k). */
2672
2673 case 2: {
2674 float f = e[k - 1];
2675 e[k - 1] = 0.0f;
2676 for (j = k; j < p; j++) {
2677 float t = hypotf(s[j], f);
2678 float invt = 1.0f / t;
2679 float cs = s[j] * invt;
2680 float sn = f * invt;
2681 s[j] = t;
2682 f = -sn * e[j];
2683 e[j] = cs * e[j];
2684
2685 for (i = 0; i < m; i++) {
2686 t = cs * U[i][j] + sn * U[i][k - 1];
2687 U[i][k - 1] = -sn * U[i][j] + cs * U[i][k - 1];
2688 U[i][j] = t;
2689 }
2690 }
2691 break;
2692 }
2693
2694 /* Perform one qr step. */
2695
2696 case 3: {
2697
2698 /* Calculate the shift. */
2699
2700 float scale = max_ff(
2701 max_ff(max_ff(max_ff(fabsf(s[p - 1]), fabsf(s[p - 2])), fabsf(e[p - 2])), fabsf(s[k])),
2702 fabsf(e[k]));
2703 float invscale = 1.0f / scale;
2704 float sp = s[p - 1] * invscale;
2705 float spm1 = s[p - 2] * invscale;
2706 float epm1 = e[p - 2] * invscale;
2707 float sk = s[k] * invscale;
2708 float ek = e[k] * invscale;
2709 float b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) * 0.5f;
2710 float c = (sp * epm1) * (sp * epm1);
2711 float shift = 0.0f;
2712 float f, g;
2713 if ((b != 0.0f) || (c != 0.0f)) {
2714 shift = sqrtf(b * b + c);
2715 if (b < 0.0f) {
2716 shift = -shift;
2717 }
2718 shift = c / (b + shift);
2719 }
2720 f = (sk + sp) * (sk - sp) + shift;
2721 g = sk * ek;
2722
2723 /* Chase zeros. */
2724
2725 for (j = k; j < p - 1; j++) {
2726 float t = hypotf(f, g);
2727 /* NOTE(@brecht): division by zero checks added to avoid NaN. */
2728 float cs = (t == 0.0f) ? 0.0f : f / t;
2729 float sn = (t == 0.0f) ? 0.0f : g / t;
2730 if (j != k) {
2731 e[j - 1] = t;
2732 }
2733 f = cs * s[j] + sn * e[j];
2734 e[j] = cs * e[j] - sn * s[j];
2735 g = sn * s[j + 1];
2736 s[j + 1] = cs * s[j + 1];
2737
2738 for (i = 0; i < n; i++) {
2739 t = cs * V[i][j] + sn * V[i][j + 1];
2740 V[i][j + 1] = -sn * V[i][j] + cs * V[i][j + 1];
2741 V[i][j] = t;
2742 }
2743
2744 t = hypotf(f, g);
2745 /* NOTE(@brecht): division by zero checks added to avoid NaN. */
2746 cs = (t == 0.0f) ? 0.0f : f / t;
2747 sn = (t == 0.0f) ? 0.0f : g / t;
2748 s[j] = t;
2749 f = cs * e[j] + sn * s[j + 1];
2750 s[j + 1] = -sn * e[j] + cs * s[j + 1];
2751 g = sn * e[j + 1];
2752 e[j + 1] = cs * e[j + 1];
2753 if (j < m - 1) {
2754 for (i = 0; i < m; i++) {
2755 t = cs * U[i][j] + sn * U[i][j + 1];
2756 U[i][j + 1] = -sn * U[i][j] + cs * U[i][j + 1];
2757 U[i][j] = t;
2758 }
2759 }
2760 }
2761 e[p - 2] = f;
2762 iter = iter + 1;
2763 break;
2764 }
2765 /* Convergence. */
2766
2767 case 4: {
2768
2769 /* Make the singular values positive. */
2770
2771 if (s[k] <= 0.0f) {
2772 s[k] = (s[k] < 0.0f ? -s[k] : 0.0f);
2773
2774 for (i = 0; i <= pp; i++) {
2775 V[i][k] = -V[i][k];
2776 }
2777 }
2778
2779 /* Order the singular values. */
2780
2781 while (k < pp) {
2782 float t;
2783 if (s[k] >= s[k + 1]) {
2784 break;
2785 }
2786 t = s[k];
2787 s[k] = s[k + 1];
2788 s[k + 1] = t;
2789 if (k < n - 1) {
2790 for (i = 0; i < n; i++) {
2791 t = V[i][k + 1];
2792 V[i][k + 1] = V[i][k];
2793 V[i][k] = t;
2794 }
2795 }
2796 if (k < m - 1) {
2797 for (i = 0; i < m; i++) {
2798 t = U[i][k + 1];
2799 U[i][k + 1] = U[i][k];
2800 U[i][k] = t;
2801 }
2802 }
2803 k++;
2804 }
2805 iter = 0;
2806 p--;
2807 break;
2808 }
2809 }
2810 }
2811}
2812
2813void pseudoinverse_m4_m4(float inverse[4][4], const float mat[4][4], float epsilon)
2814{
2815 /* compute Moore-Penrose pseudo inverse of matrix, singular values
2816 * below epsilon are ignored for stability (truncated SVD) */
2817 float A[4][4], V[4][4], W[4], Wm[4][4], U[4][4];
2818 int i;
2819
2820 transpose_m4_m4(A, mat);
2821 svd_m4(V, W, U, A);
2822 transpose_m4(U);
2823 transpose_m4(V);
2824
2825 zero_m4(Wm);
2826 for (i = 0; i < 4; i++) {
2827 Wm[i][i] = (W[i] < epsilon) ? 0.0f : 1.0f / W[i];
2828 }
2829
2830 transpose_m4(V);
2831
2832 mul_m4_series(inverse, U, Wm, V);
2833}
2834
2835void pseudoinverse_m3_m3(float inverse[3][3], const float mat[3][3], float epsilon)
2836{
2837 /* try regular inverse when possible, otherwise fall back to slow svd */
2838 if (!invert_m3_m3(inverse, mat)) {
2839 float mat_tmp[4][4], tmpinv[4][4];
2840
2841 copy_m4_m3(mat_tmp, mat);
2842 pseudoinverse_m4_m4(tmpinv, mat_tmp, epsilon);
2843 copy_m3_m4(inverse, tmpinv);
2844 }
2845}
2846
2847bool has_zero_axis_m4(const float matrix[4][4])
2848{
2849 return len_squared_v3(matrix[0]) < FLT_EPSILON || len_squared_v3(matrix[1]) < FLT_EPSILON ||
2850 len_squared_v3(matrix[2]) < FLT_EPSILON;
2851}
2852
2853void invert_m4_m4_safe(float inverse[4][4], const float mat[4][4])
2854{
2855 if (!invert_m4_m4(inverse, mat)) {
2856 float mat_tmp[4][4];
2857
2858 copy_m4_m4(mat_tmp, mat);
2859
2860 /* Matrix is degenerate (e.g. 0 scale on some axis), ideally we should
2861 * never be in this situation, but try to invert it anyway with tweak.
2862 */
2863 mat_tmp[0][0] += 1e-8f;
2864 mat_tmp[1][1] += 1e-8f;
2865 mat_tmp[2][2] += 1e-8f;
2866
2867 if (!invert_m4_m4(inverse, mat_tmp)) {
2869 }
2870 }
2871}
2872
2873/* -------------------------------------------------------------------- */
2887
2888void invert_m4_m4_safe_ortho(float inverse[4][4], const float mat[4][4])
2889{
2890 if (UNLIKELY(!invert_m4_m4(inverse, mat))) {
2891 float mat_tmp[4][4];
2892 copy_m4_m4(mat_tmp, mat);
2893 if (UNLIKELY(!(orthogonalize_m4_zero_axes(mat_tmp, 1.0f) && invert_m4_m4(inverse, mat_tmp)))) {
2895 }
2896 }
2897}
2898
2899void invert_m3_m3_safe_ortho(float inverse[3][3], const float mat[3][3])
2900{
2901 if (UNLIKELY(!invert_m3_m3(inverse, mat))) {
2902 float mat_tmp[3][3];
2903 copy_m3_m3(mat_tmp, mat);
2904 if (UNLIKELY(!(orthogonalize_m3_zero_axes(mat_tmp, 1.0f) && invert_m3_m3(inverse, mat_tmp)))) {
2906 }
2907 }
2908}
2909
2911
2913 const float local[4][4],
2914 const float target[4][4])
2915{
2916 float itarget[4][4];
2917 invert_m4_m4(itarget, target);
2918 mul_m4_m4m4(data->local2target, itarget, local);
2919 invert_m4_m4(data->target2local, data->local2target);
2920}
2921
2923 const float local[4][4],
2924 const float target[4][4])
2925{
2926 float ilocal[4][4];
2927 invert_m4_m4(ilocal, local);
2928 mul_m4_m4m4(data->local2target, target, ilocal);
2929 invert_m4_m4(data->target2local, data->local2target);
2930}
2931
2933{
2934 mul_v3_m4v3(co, ((SpaceTransform *)data)->local2target, co);
2935}
2936
2938{
2939 mul_v3_m4v3(co, ((SpaceTransform *)data)->target2local, co);
2940}
2941
2943{
2944 mul_mat3_m4_v3(((SpaceTransform *)data)->local2target, no);
2945 normalize_v3(no);
2946}
2947
2949{
2950 mul_mat3_m4_v3(((SpaceTransform *)data)->target2local, no);
2951 normalize_v3(no);
2952}
#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)
#define sinf(x)
#define cosf(x)
#define powf(x, y)
#define hypotf(x, y)
#define acosf(x)
#define fabsf(x)
#define sqrtf(x)
#define rot(x, k)
#define str(s)
uint col
MatBase< C, R > inverse(MatBase< C, R >) RET
VecBase< float, D > normalize(VecOp< float, D >) RET
#define out
#define printf(...)
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])
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
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:139