Math Lib: add transpose_m3_m3, m3_m4, m4_m4
[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_m4_v4(float M[4][4], float r[4]);
110 void mul_v4_m4v4(float r[4], float M[4][4], const float v[4]);
111 void mul_project_m4_v3(float M[4][4], float vec[3]);
112 void mul_v3_project_m4_v3(float r[3], float mat[4][4], const float vec[3]);
113 void mul_v2_project_m4_v3(float r[2], float M[4][4], const float vec[3]);
114
115 void mul_m3_v2(float m[3][3], float r[2]);
116 void mul_v2_m3v2(float r[2], float m[3][3], float v[2]);
117 void mul_m3_v3(float M[3][3], float r[3]);
118 void mul_v3_m3v3(float r[3], float M[3][3], const float a[3]);
119 void mul_v2_m3v3(float r[2], float M[3][3], const float a[3]);
120 void mul_transposed_m3_v3(float M[3][3], float r[3]);
121 void mul_transposed_mat3_m4_v3(float M[4][4], float r[3]);
122 void mul_m3_v3_double(float M[3][3], double r[3]);
123
124 void mul_m3_fl(float R[3][3], float f);
125 void mul_m4_fl(float R[4][4], float f);
126 void mul_mat3_m4_fl(float R[4][4], float f);
127
128 void negate_m3(float R[3][3]);
129 void negate_m4(float R[4][4]);
130
131 bool invert_m3_ex(float m[3][3], const float epsilon);
132 bool invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon);
133
134 bool invert_m3(float R[3][3]);
135 bool invert_m3_m3(float R[3][3], float A[3][3]);
136 bool invert_m4(float R[4][4]);
137 bool invert_m4_m4(float R[4][4], float A[4][4]);
138
139 /* double ariphmetics */
140 void mul_m4_v4d(float M[4][4], double r[4]);
141 void mul_v4d_m4v4d(double r[4], float M[4][4], double v[4]);
142
143
144 /****************************** Linear Algebra *******************************/
145
146 void transpose_m3(float R[3][3]);
147 void transpose_m3_m3(float R[3][3], float A[3][3]);
148 void transpose_m3_m4(float R[3][3], float A[4][4]);
149 void transpose_m4(float R[4][4]);
150 void transpose_m4_m4(float R[4][4], float A[4][4]);
151
152 int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit);
153
154 void normalize_m3(float R[3][3]);
155 void normalize_m3_m3(float R[3][3], float A[3][3]);
156 void normalize_m4(float R[4][4]);
157 void normalize_m4_m4(float R[4][4], float A[4][4]);
158
159 void orthogonalize_m3(float R[3][3], int axis);
160 void orthogonalize_m4(float R[4][4], int axis);
161
162 bool is_orthogonal_m3(float mat[3][3]);
163 bool is_orthogonal_m4(float mat[4][4]);
164 bool is_orthonormal_m3(float mat[3][3]);
165 bool is_orthonormal_m4(float mat[4][4]);
166
167 bool is_uniform_scaled_m3(float mat[3][3]);
168 bool is_uniform_scaled_m4(float m[4][4]);
169
170 void adjoint_m2_m2(float R[2][2], float A[2][2]);
171 void adjoint_m3_m3(float R[3][3], float A[3][3]);
172 void adjoint_m4_m4(float R[4][4], float A[4][4]);
173
174 float determinant_m2(float a, float b,
175                      float c, float d);
176 float determinant_m3(float a, float b, float c,
177                      float d, float e, float f,
178                      float g, float h, float i);
179 float determinant_m3_array(float m[3][3]);
180 float determinant_m4(float A[4][4]);
181
182 #define PSEUDOINVERSE_EPSILON 1e-8f
183
184 void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]);
185 void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon);
186 void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon);
187
188 bool has_zero_axis_m4(float matrix[4][4]);
189
190 void invert_m4_m4_safe(float Ainv[4][4], float A[4][4]);
191
192 /****************************** Transformations ******************************/
193
194 void scale_m3_fl(float R[3][3], float scale);
195 void scale_m4_fl(float R[4][4], float scale);
196
197 float mat3_to_scale(float M[3][3]);
198 float mat4_to_scale(float M[4][4]);
199
200 void size_to_mat3(float R[3][3], const float size[3]);
201 void size_to_mat4(float R[4][4], const float size[3]);
202
203 void mat3_to_size(float r[3], float M[3][3]);
204 void mat4_to_size(float r[3], float M[4][4]);
205
206 void translate_m4(float mat[4][4], float tx, float ty, float tz);
207 void rotate_m4(float mat[4][4], const char axis, const float angle);
208 void rotate_m2(float mat[2][2], const float angle);
209 void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
210
211 void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);
212 void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]);
213 void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4]);
214 void mat4_decompose(float loc[3], float quat[4], float size[3], float wmat[4][4]);
215
216 void loc_eul_size_to_mat4(float R[4][4],
217                           const float loc[3], const float eul[3], const float size[3]);
218 void loc_eulO_size_to_mat4(float R[4][4],
219                            const float loc[3], const float eul[3], const float size[3], const short order);
220 void loc_quat_size_to_mat4(float R[4][4],
221                            const float loc[3], const float quat[4], const float size[3]);
222 void loc_axisangle_size_to_mat4(float R[4][4],
223                                 const float loc[3], const float axis[4], const float angle, const float size[3]);
224
225 void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t);
226 void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t);
227
228 bool is_negative_m3(float mat[3][3]);
229 bool is_negative_m4(float mat[4][4]);
230
231 bool is_zero_m3(float mat[3][3]);
232 bool is_zero_m4(float mat[4][4]);
233
234 /* SpaceTransform helper */
235 typedef struct SpaceTransform {
236         float local2target[4][4];
237         float target2local[4][4];
238
239 } SpaceTransform;
240
241 void BLI_space_transform_from_matrices(struct SpaceTransform *data, float local[4][4], float target[4][4]);
242 void BLI_space_transform_apply(const struct SpaceTransform *data, float co[3]);
243 void BLI_space_transform_invert(const struct SpaceTransform *data, float co[3]);
244 void BLI_space_transform_apply_normal(const struct SpaceTransform *data, float no[3]);
245 void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float no[3]);
246
247 #define BLI_SPACE_TRANSFORM_SETUP(data, local, target) \
248         BLI_space_transform_from_matrices((data), (local)->obmat, (target)->obmat)
249
250 /*********************************** Other ***********************************/
251
252 void print_m3(const char *str, float M[3][3]);
253 void print_m4(const char *str, float M[3][4]);
254
255 #define print_m3_id(M) print_m3(STRINGIFY(M), M)
256 #define print_m4_id(M) print_m4(STRINGIFY(M), M)
257
258 #ifdef __cplusplus
259 }
260 #endif
261
262 #endif /* __BLI_MATH_MATRIX_H__ */
263