Alembic: quiet compilation warnings on Windows.
[blender.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_m2(float R[2][2]);
42 void zero_m3(float R[3][3]);
43 void zero_m4(float R[4][4]);
44
45 void unit_m2(float R[2][2]);
46 void unit_m3(float R[3][3]);
47 void unit_m4(float R[4][4]);
48
49 void copy_m2_m2(float R[2][2], float A[2][2]);
50 void copy_m3_m3(float R[3][3], float A[3][3]);
51 void copy_m4_m4(float R[4][4], float A[4][4]);
52 void copy_m3_m4(float R[3][3], float A[4][4]);
53 void copy_m4_m3(float R[4][4], float A[3][3]);
54
55 /* double->float */
56 void copy_m3_m3d(float R[3][3], double A[3][3]);
57
58 void swap_m3m3(float A[3][3], float B[3][3]);
59 void swap_m4m4(float A[4][4], float B[4][4]);
60
61 /******************************** Arithmetic *********************************/
62
63 void add_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
64 void add_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
65
66 void sub_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
67 void sub_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
68
69 void mul_m3_m3m3(float R[3][3], float A[3][3], float B[3][3]);
70 void mul_m4_m3m4(float R[4][4], float A[3][3], float B[4][4]);
71 void mul_m4_m4m3(float R[4][4], float A[4][4], float B[3][3]);
72 void mul_m4_m4m4(float R[4][4], float A[4][4], float B[4][4]);
73 void mul_m3_m3m4(float R[3][3], float A[4][4], float B[3][3]);
74
75 /* mul_m3_series */
76 void _va_mul_m3_series_3(float R[3][3], float M1[3][3], float M2[3][3]) ATTR_NONNULL();
77 void _va_mul_m3_series_4(float R[3][3], float M1[3][3], float M2[3][3], float M3[3][3]) ATTR_NONNULL();
78 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();
79 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],
80                          float M5[3][3]) ATTR_NONNULL();
81 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],
82                          float M5[3][3], float M6[3][3]) ATTR_NONNULL();
83 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],
84                          float M5[3][3], float M6[3][3], float M7[3][3]) ATTR_NONNULL();
85 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],
86                          float M5[3][3], float M6[3][3], float M7[3][3], float M8[3][3]) ATTR_NONNULL();
87 /* mul_m4_series */
88 void _va_mul_m4_series_3(float R[4][4], float M1[4][4], float M2[4][4]) ATTR_NONNULL();
89 void _va_mul_m4_series_4(float R[4][4], float M1[4][4], float M2[4][4], float M3[4][4]) ATTR_NONNULL();
90 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();
91 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],
92                         float M5[4][4]) ATTR_NONNULL();
93 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],
94                          float M5[4][4], float M6[4][4]) ATTR_NONNULL();
95 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],
96                          float M5[4][4], float M6[4][4], float M7[4][4]) ATTR_NONNULL();
97 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],
98                          float M5[4][4], float M6[4][4], float M7[4][4], float M8[4][4]) ATTR_NONNULL();
99
100 #define mul_m3_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m3_series_, __VA_ARGS__)
101 #define mul_m4_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m4_series_, __VA_ARGS__)
102
103 void mul_m4_v3(float M[4][4], float r[3]);
104 void mul_v3_m4v3(float r[3], float M[4][4], const float v[3]);
105 void mul_v2_m4v3(float r[2], float M[4][4], const float v[3]);
106 void mul_v2_m2v2(float r[2], float M[2][2], const float v[2]);
107 void mul_m2v2(float M[2][2], float v[2]);
108 void mul_mat3_m4_v3(float M[4][4], float r[3]);
109 void mul_v3_mat3_m4v3(float r[3], float M[4][4], const float v[3]);
110 void mul_m4_v4(float M[4][4], float r[4]);
111 void mul_v4_m4v4(float r[4], float M[4][4], const float v[4]);
112 void mul_project_m4_v3(float M[4][4], float vec[3]);
113 void mul_v3_project_m4_v3(float r[3], float mat[4][4], const float vec[3]);
114 void mul_v2_project_m4_v3(float r[2], float M[4][4], const float vec[3]);
115
116 void mul_m3_v2(float m[3][3], float r[2]);
117 void mul_v2_m3v2(float r[2], float m[3][3], float v[2]);
118 void mul_m3_v3(float M[3][3], float r[3]);
119 void mul_v3_m3v3(float r[3], float M[3][3], const float a[3]);
120 void mul_v2_m3v3(float r[2], float M[3][3], const float a[3]);
121 void mul_transposed_m3_v3(float M[3][3], float r[3]);
122 void mul_transposed_mat3_m4_v3(float M[4][4], float r[3]);
123 void mul_m3_v3_double(float M[3][3], double r[3]);
124
125 void mul_m3_fl(float R[3][3], float f);
126 void mul_m4_fl(float R[4][4], float f);
127 void mul_mat3_m4_fl(float R[4][4], float f);
128
129 void negate_m3(float R[3][3]);
130 void negate_mat3_m4(float R[4][4]);
131 void negate_m4(float R[4][4]);
132
133 bool invert_m3_ex(float m[3][3], const float epsilon);
134 bool invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon);
135
136 bool invert_m3(float R[3][3]);
137 bool invert_m3_m3(float R[3][3], float A[3][3]);
138 bool invert_m4(float R[4][4]);
139 bool invert_m4_m4(float R[4][4], float A[4][4]);
140
141 /* double arithmetic (mixed float/double) */
142 void mul_m4_v4d(float M[4][4], double r[4]);
143 void mul_v4d_m4v4d(double r[4], float M[4][4], double v[4]);
144
145 /* double matrix functions (no mixing types) */
146 void mul_v3_m3v3_db(double r[3], double M[3][3], const double a[3]);
147 void mul_m3_v3_db(double M[3][3], double r[3]);
148
149
150 /****************************** Linear Algebra *******************************/
151
152 void transpose_m3(float R[3][3]);
153 void transpose_m3_m3(float R[3][3], float A[3][3]);
154 void transpose_m3_m4(float R[3][3], float A[4][4]);
155 void transpose_m4(float R[4][4]);
156 void transpose_m4_m4(float R[4][4], float A[4][4]);
157
158 int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit);
159
160 void normalize_m3_ex(float R[3][3], float r_scale[3]) ATTR_NONNULL();
161 void normalize_m3(float R[3][3]) ATTR_NONNULL();
162 void normalize_m3_m3_ex(float R[3][3], float A[3][3], float r_scale[3]) ATTR_NONNULL();
163 void normalize_m3_m3(float R[3][3], float A[3][3]) ATTR_NONNULL();
164 void normalize_m4_ex(float R[4][4], float r_scale[3]) ATTR_NONNULL();
165 void normalize_m4(float R[4][4]) ATTR_NONNULL();
166 void normalize_m4_m4_ex(float R[4][4], float A[4][4], float r_scale[3]) ATTR_NONNULL();
167 void normalize_m4_m4(float R[4][4], float A[4][4]) ATTR_NONNULL();
168
169 void orthogonalize_m3(float R[3][3], int axis);
170 void orthogonalize_m4(float R[4][4], int axis);
171
172 bool is_orthogonal_m3(float mat[3][3]);
173 bool is_orthogonal_m4(float mat[4][4]);
174 bool is_orthonormal_m3(float mat[3][3]);
175 bool is_orthonormal_m4(float mat[4][4]);
176
177 bool is_uniform_scaled_m3(float mat[3][3]);
178 bool is_uniform_scaled_m4(float m[4][4]);
179
180 /* Note: 'adjoint' here means the adjugate (adjunct, "classical adjoint") matrix!
181  * Nowadays 'adjoint' usually refers to the conjugate transpose,
182  * which for real-valued matrices is simply the transpose.
183  */
184 void adjoint_m2_m2(float R[2][2], float A[2][2]);
185 void adjoint_m3_m3(float R[3][3], float A[3][3]);
186 void adjoint_m4_m4(float R[4][4], float A[4][4]);
187
188 float determinant_m2(float a, float b,
189                      float c, float d);
190 float determinant_m3(float a, float b, float c,
191                      float d, float e, float f,
192                      float g, float h, float i);
193 float determinant_m3_array(float m[3][3]);
194 float determinant_m4(float A[4][4]);
195
196 #define PSEUDOINVERSE_EPSILON 1e-8f
197
198 void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]);
199 void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon);
200 void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon);
201
202 bool has_zero_axis_m4(float matrix[4][4]);
203
204 void invert_m4_m4_safe(float Ainv[4][4], float A[4][4]);
205
206 /****************************** Transformations ******************************/
207
208 void scale_m3_fl(float R[3][3], float scale);
209 void scale_m4_fl(float R[4][4], float scale);
210
211 float mat3_to_scale(float M[3][3]);
212 float mat4_to_scale(float M[4][4]);
213
214 void size_to_mat3(float R[3][3], const float size[3]);
215 void size_to_mat4(float R[4][4], const float size[3]);
216
217 void mat3_to_size(float r[3], float M[3][3]);
218 void mat4_to_size(float r[3], float M[4][4]);
219
220 void translate_m4(float mat[4][4], float tx, float ty, float tz);
221 void rotate_m4(float mat[4][4], const char axis, const float angle);
222 void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
223
224 void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);
225 void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]);
226 void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4]);
227 void mat4_decompose(float loc[3], float quat[4], float size[3], float wmat[4][4]);
228
229 void mat3_polar_decompose(float mat3[3][3], float r_U[3][3], float r_P[3][3]);
230
231 void loc_eul_size_to_mat4(float R[4][4],
232                           const float loc[3], const float eul[3], const float size[3]);
233 void loc_eulO_size_to_mat4(float R[4][4],
234                            const float loc[3], const float eul[3], const float size[3], const short order);
235 void loc_quat_size_to_mat4(float R[4][4],
236                            const float loc[3], const float quat[4], const float size[3]);
237 void loc_axisangle_size_to_mat4(float R[4][4],
238                                 const float loc[3], const float axis[4], const float angle, const float size[3]);
239
240 void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t);
241 void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t);
242
243 void interp_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t);
244 void interp_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t);
245
246 bool is_negative_m3(float mat[3][3]);
247 bool is_negative_m4(float mat[4][4]);
248
249 bool is_zero_m3(float mat[3][3]);
250 bool is_zero_m4(float mat[4][4]);
251
252 bool equals_m3m3(float mat1[3][3], float mat2[3][3]);
253 bool equals_m4m4(float mat1[4][4], float mat2[4][4]);
254
255 /* SpaceTransform helper */
256 typedef struct SpaceTransform {
257         float local2target[4][4];
258         float target2local[4][4];
259
260 } SpaceTransform;
261
262 void BLI_space_transform_from_matrices(struct SpaceTransform *data, float local[4][4], float target[4][4]);
263 void BLI_space_transform_global_from_matrices(struct SpaceTransform *data, float local[4][4], float target[4][4]);
264 void BLI_space_transform_apply(const struct SpaceTransform *data, float co[3]);
265 void BLI_space_transform_invert(const struct SpaceTransform *data, float co[3]);
266 void BLI_space_transform_apply_normal(const struct SpaceTransform *data, float no[3]);
267 void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float no[3]);
268
269 #define BLI_SPACE_TRANSFORM_SETUP(data, local, target) \
270         BLI_space_transform_from_matrices((data), (local)->obmat, (target)->obmat)
271
272 /*********************************** Other ***********************************/
273
274 void print_m3(const char *str, float M[3][3]);
275 void print_m4(const char *str, float M[4][4]);
276
277 #define print_m3_id(M) print_m3(STRINGIFY(M), M)
278 #define print_m4_id(M) print_m4(STRINGIFY(M), M)
279
280 #ifdef __cplusplus
281 }
282 #endif
283
284 #endif /* __BLI_MATH_MATRIX_H__ */
285