Math Lib: rename mul_serie_m3 to mul_m3_series & reorder args
[blender-staging.git] / source / blender / blenlib / BLI_math_matrix.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  
21  * The Original Code is: some of this file.
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  * */
25
26 #ifndef __BLI_MATH_MATRIX_H__
27 #define __BLI_MATH_MATRIX_H__
28
29 /** \file BLI_math_matrix.h
30  *  \ingroup bli
31  */
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 #include "BLI_compiler_attrs.h"
38
39 /********************************* Init **************************************/
40
41 void zero_m3(float R[3][3]);
42 void zero_m4(float R[4][4]);
43
44 void unit_m3(float R[3][3]);
45 void unit_m4(float R[4][4]);
46
47 void copy_m3_m3(float R[3][3], float A[3][3]);
48 void copy_m4_m4(float R[4][4], float A[4][4]);
49 void copy_m3_m4(float R[3][3], float A[4][4]);
50 void copy_m4_m3(float R[4][4], float A[3][3]);
51
52 /* double->float */
53 void copy_m3_m3d(float R[3][3], double A[3][3]);
54
55 void swap_m3m3(float A[3][3], float B[3][3]);
56 void swap_m4m4(float A[4][4], float B[4][4]);
57
58 /******************************** Arithmetic *********************************/
59
60 void add_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
61 void add_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
62
63 void sub_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
64 void sub_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
65
66 void mul_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
67 void mul_m4_m3m4(float R[4][4], float A[3][3], float B[4][4]);
68 void mul_m4_m4m3(float R[4][4], float A[4][4], float B[3][3]);
69 void mul_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
70 void mul_m3_m3m4(float R[3][3], float A[4][4], float B[3][3]);
71
72 /* mul_m3_series */
73 void _va_mul_m3_series_3(float R[3][3], float M1[3][3], float M2[3][3]) ATTR_NONNULL();
74 void _va_mul_m3_series_4(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3]) ATTR_NONNULL();
75 void _va_mul_m3_series_5(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3]) ATTR_NONNULL();
76 void _va_mul_m3_series_6(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3],
77                          float M5[3][3]) ATTR_NONNULL();
78 void _va_mul_m3_series_7(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3],
79                          float M5[3][3], float M6[3][3]) ATTR_NONNULL();
80 void _va_mul_m3_series_8(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3],
81                          float M5[3][3], float M6[3][3], float M7[3][3]) ATTR_NONNULL();
82 void _va_mul_m3_series_9(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3], float M4[3][3],
83                          float M5[3][3], float M6[3][3], float M7[3][3], float M8[3][3]) ATTR_NONNULL();
84 /* mul_m4_series */
85 void _va_mul_m4_series_3(float R[4][4], float M1[4][4], float M2[4][4]) ATTR_NONNULL();
86 void _va_mul_m4_series_4(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4]) ATTR_NONNULL();
87 void _va_mul_m4_series_5(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4]) ATTR_NONNULL();
88 void _va_mul_m4_series_6(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4],
89                         float M5[4][4]) ATTR_NONNULL();
90 void _va_mul_m4_series_7(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4],
91                          float M5[4][4], float M6[4][4]) ATTR_NONNULL();
92 void _va_mul_m4_series_8(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4],
93                          float M5[4][4], float M6[4][4], float M7[4][4]) ATTR_NONNULL();
94 void _va_mul_m4_series_9(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4], float M4[4][4],
95                          float M5[4][4], float M6[4][4], float M7[4][4], float M8[4][4]) ATTR_NONNULL();
96
97 #define mul_m3_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m3_series_, __VA_ARGS__)
98 #define mul_m4_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m4_series_, __VA_ARGS__)
99
100 void mul_m4_v3(float M[4][4], float r[3]);
101 void mul_v3_m4v3(float r[3], float M[4][4], const float v[3]);
102 void mul_v2_m4v3(float r[2], float M[4][4], const float v[3]);
103 void mul_v2_m2v2(float r[2], float M[2][2], const float v[2]);
104 void mul_m2v2(float M[2][2], float v[2]);
105 void mul_mat3_m4_v3(float M[4][4], float r[3]);
106 void mul_m4_v4(float M[4][4], float r[4]);
107 void mul_v4_m4v4(float r[4], float M[4][4], const float v[4]);
108 void mul_project_m4_v3(float M[4][4], float vec[3]);
109 void mul_v2_project_m4_v3(float r[2], float M[4][4], const float vec[3]);
110
111 void mul_m3_v2(float m[3][3], float r[2]);
112 void mul_v2_m3v2(float r[2], float m[3][3], float v[2]);
113 void mul_m3_v3(float M[3][3], float r[3]);
114 void mul_v3_m3v3(float r[3], float M[3][3], const float a[3]);
115 void mul_v2_m3v3(float r[2], float M[3][3], const float a[3]);
116 void mul_transposed_m3_v3(float M[3][3], float r[3]);
117 void mul_transposed_mat3_m4_v3(float M[4][4], float r[3]);
118 void mul_m3_v3_double(float M[3][3], double r[3]);
119
120 void mul_m3_fl(float R[3][3], float f);
121 void mul_m4_fl(float R[4][4], float f);
122 void mul_mat3_m4_fl(float R[4][4], float f);
123
124 void negate_m3(float R[4][4]);
125 void negate_m4(float R[4][4]);
126
127 bool invert_m3_ex(float m[3][3], const float epsilon);
128 bool invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon);
129
130 bool invert_m3(float R[3][3]);
131 bool invert_m3_m3(float R[3][3], float A[3][3]);
132 bool invert_m4(float R[4][4]);
133 bool invert_m4_m4(float R[4][4], float A[4][4]);
134
135 /* double ariphmetics */
136 void mul_m4_v4d(float M[4][4], double r[4]);
137 void mul_v4d_m4v4d(double r[4], float M[4][4], double v[4]);
138
139
140 /****************************** Linear Algebra *******************************/
141
142 void transpose_m3(float R[3][3]);
143 void transpose_m4(float R[4][4]);
144
145 int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit);
146
147 void normalize_m3(float R[3][3]);
148 void normalize_m3_m3(float R[3][3], float A[3][3]);
149 void normalize_m4(float R[4][4]);
150 void normalize_m4_m4(float R[4][4], float A[4][4]);
151
152 void orthogonalize_m3(float R[3][3], int axis);
153 void orthogonalize_m4(float R[4][4], int axis);
154
155 bool is_orthogonal_m3(float mat[3][3]);
156 bool is_orthogonal_m4(float mat[4][4]);
157 bool is_orthonormal_m3(float mat[3][3]);
158 bool is_orthonormal_m4(float mat[4][4]);
159
160 bool is_uniform_scaled_m3(float mat[3][3]);
161 bool is_uniform_scaled_m4(float m[4][4]);
162
163 void adjoint_m2_m2(float R[2][2], float A[2][2]);
164 void adjoint_m3_m3(float R[3][3], float A[3][3]);
165 void adjoint_m4_m4(float R[4][4], float A[4][4]);
166
167 float determinant_m2(float a, float b,
168                      float c, float d);
169 float determinant_m3(float a, float b, float c,
170                      float d, float e, float f,
171                      float g, float h, float i);
172 float determinant_m3_array(float m[3][3]);
173 float determinant_m4(float A[4][4]);
174
175 #define PSEUDOINVERSE_EPSILON 1e-8f
176
177 void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]);
178 void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon);
179 void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon);
180
181 bool has_zero_axis_m4(float matrix[4][4]);
182
183 void invert_m4_m4_safe(float Ainv[4][4], float A[4][4]);
184
185 /****************************** Transformations ******************************/
186
187 void scale_m3_fl(float R[3][3], float scale);
188 void scale_m4_fl(float R[4][4], float scale);
189
190 float mat3_to_scale(float M[3][3]);
191 float mat4_to_scale(float M[4][4]);
192
193 void size_to_mat3(float R[3][3], const float size[3]);
194 void size_to_mat4(float R[4][4], const float size[3]);
195
196 void mat3_to_size(float r[3], float M[3][3]);
197 void mat4_to_size(float r[3], float M[4][4]);
198
199 void translate_m4(float mat[4][4], float tx, float ty, float tz);
200 void rotate_m4(float mat[4][4], const char axis, const float angle);
201 void rotate_m2(float mat[2][2], const float angle);
202 void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
203
204 void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);
205 void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]);
206 void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4]);
207 void mat4_decompose(float loc[3], float quat[4], float size[3], float wmat[4][4]);
208
209 void loc_eul_size_to_mat4(float R[4][4],
210                           const float loc[3], const float eul[3], const float size[3]);
211 void loc_eulO_size_to_mat4(float R[4][4],
212                            const float loc[3], const float eul[3], const float size[3], const short order);
213 void loc_quat_size_to_mat4(float R[4][4],
214                            const float loc[3], const float quat[4], const float size[3]);
215 void loc_axisangle_size_to_mat4(float R[4][4],
216                                 const float loc[3], const float axis[4], const float angle, const float size[3]);
217
218 void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t);
219 void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t);
220
221 bool is_negative_m3(float mat[3][3]);
222 bool is_negative_m4(float mat[4][4]);
223
224 bool is_zero_m3(float mat[3][3]);
225 bool is_zero_m4(float mat[4][4]);
226
227 /*********************************** Other ***********************************/
228
229 void print_m3(const char *str, float M[3][3]);
230 void print_m4(const char *str, float M[3][4]);
231
232 #define print_m3_id(M) print_m3(STRINGIFY(M), M)
233 #define print_m4_id(M) print_m4(STRINGIFY(M), M)
234
235 #ifdef __cplusplus
236 }
237 #endif
238
239 #endif /* __BLI_MATH_MATRIX_H__ */
240