2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * The Original Code is: some of this file.
23 * ***** END GPL LICENSE BLOCK *****
26 #ifndef __BLI_MATH_MATRIX_H__
27 #define __BLI_MATH_MATRIX_H__
29 /** \file BLI_math_matrix.h
37 #include "BLI_compiler_attrs.h"
39 /********************************* Init **************************************/
41 void zero_m2(float R[2][2]);
42 void zero_m3(float R[3][3]);
43 void zero_m4(float R[4][4]);
45 void unit_m2(float R[2][2]);
46 void unit_m3(float R[3][3]);
47 void unit_m4(float R[4][4]);
49 void copy_m2_m2(float R[2][2], const float A[2][2]);
50 void copy_m3_m3(float R[3][3], const float A[3][3]);
51 void copy_m4_m4(float R[4][4], const float A[4][4]);
52 void copy_m3_m4(float R[3][3], const float A[4][4]);
53 void copy_m4_m3(float R[4][4], const float A[3][3]);
56 void copy_m3_m3d(float R[3][3], const double A[3][3]);
58 void swap_m3m3(float A[3][3], float B[3][3]);
59 void swap_m4m4(float A[4][4], float B[4][4]);
61 /******************************** Arithmetic *********************************/
63 void add_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]);
64 void add_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]);
66 void sub_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]);
67 void sub_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]);
69 void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]);
70 void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4]);
71 void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3]);
72 void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]);
73 void mul_m3_m3m4(float R[3][3], const float A[4][4], const float B[3][3]);
75 /* special matrix multiplies
76 * uniq: R <-- AB, R is neither A nor B
80 void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3]);
81 void mul_m3_m3_pre(float R[3][3], const float A[3][3]);
82 void mul_m3_m3_post(float R[3][3], const float B[3][3]);
83 void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4]);
84 void mul_m4_m4_pre(float R[4][4], const float A[4][4]);
85 void mul_m4_m4_post(float R[4][4], const float B[4][4]);
88 void _va_mul_m3_series_3(
89 float R[3][3], const float M1[3][3], const float M2[3][3]) ATTR_NONNULL();
90 void _va_mul_m3_series_4(
91 float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3]) ATTR_NONNULL();
92 void _va_mul_m3_series_5(
93 float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3],
94 const float M4[3][3]) ATTR_NONNULL();
95 void _va_mul_m3_series_6(
96 float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3],
97 const float M4[3][3], const float M5[3][3]) ATTR_NONNULL();
98 void _va_mul_m3_series_7(
99 float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3],
100 const float M4[3][3], const float M5[3][3], const float M6[3][3]) ATTR_NONNULL();
101 void _va_mul_m3_series_8(
102 float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3],
103 const float M4[3][3], const float M5[3][3], const float M6[3][3], const float M7[3][3]) ATTR_NONNULL();
104 void _va_mul_m3_series_9(
105 float R[3][3], const float M1[3][3], const float M2[3][3], const float M3[3][3],
106 const float M4[3][3], const float M5[3][3], const float M6[3][3], const float M7[3][3],
107 const float M8[3][3]) ATTR_NONNULL();
109 void _va_mul_m4_series_3(
110 float R[4][4], const float M1[4][4], const float M2[4][4]) ATTR_NONNULL();
111 void _va_mul_m4_series_4(
112 float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4]) ATTR_NONNULL();
113 void _va_mul_m4_series_5(
114 float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4],
115 const float M4[4][4]) ATTR_NONNULL();
116 void _va_mul_m4_series_6(
117 float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4],
118 const float M4[4][4], const float M5[4][4]) ATTR_NONNULL();
119 void _va_mul_m4_series_7(
120 float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4],
121 const float M4[4][4], const float M5[4][4], const float M6[4][4]) ATTR_NONNULL();
122 void _va_mul_m4_series_8(
123 float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4],
124 const float M4[4][4], const float M5[4][4], const float M6[4][4], const float M7[4][4]) ATTR_NONNULL();
125 void _va_mul_m4_series_9(
126 float R[4][4], const float M1[4][4], const float M2[4][4], const float M3[4][4],
127 const float M4[4][4], const float M5[4][4], const float M6[4][4], const float M7[4][4],
128 const float M8[4][4]) ATTR_NONNULL();
130 #define mul_m3_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m3_series_, __VA_ARGS__)
131 #define mul_m4_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m4_series_, __VA_ARGS__)
133 void mul_m4_v3(const float M[4][4], float r[3]);
134 void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3]);
135 void mul_v2_m4v3(float r[2], const float M[4][4], const float v[3]);
136 void mul_v2_m2v2(float r[2], const float M[2][2], const float v[2]);
137 void mul_m2v2(const float M[2][2], float v[2]);
138 void mul_mat3_m4_v3(const float M[4][4], float r[3]);
139 void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3]);
140 void mul_m4_v4(const float M[4][4], float r[4]);
141 void mul_v4_m4v4(float r[4], const float M[4][4], const float v[4]);
142 void mul_v4_m4v3(float r[4], const float M[4][4], const float v[3]); /* v has implicit w = 1.0f */
143 void mul_project_m4_v3(const float M[4][4], float vec[3]);
144 void mul_v3_project_m4_v3(float r[3], const float mat[4][4], const float vec[3]);
145 void mul_v2_project_m4_v3(float r[2], const float M[4][4], const float vec[3]);
147 void mul_m3_v2(const float m[3][3], float r[2]);
148 void mul_v2_m3v2(float r[2], const float m[3][3], const float v[2]);
149 void mul_m3_v3(const float M[3][3], float r[3]);
150 void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3]);
151 void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3]);
152 void mul_transposed_m3_v3(const float M[3][3], float r[3]);
153 void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3]);
154 void mul_m3_v3_double(const float M[3][3], double r[3]);
156 void mul_m3_fl(float R[3][3], float f);
157 void mul_m4_fl(float R[4][4], float f);
158 void mul_mat3_m4_fl(float R[4][4], float f);
160 void negate_m3(float R[3][3]);
161 void negate_mat3_m4(float R[4][4]);
162 void negate_m4(float R[4][4]);
164 bool invert_m3_ex(float m[3][3], const float epsilon);
165 bool invert_m3_m3_ex(float m1[3][3], const float m2[3][3], const float epsilon);
167 bool invert_m3(float R[3][3]);
168 bool invert_m3_m3(float R[3][3], const float A[3][3]);
169 bool invert_m4(float R[4][4]);
170 bool invert_m4_m4(float R[4][4], const float A[4][4]);
172 /* double arithmetic (mixed float/double) */
173 void mul_m4_v4d(const float M[4][4], double r[4]);
174 void mul_v4d_m4v4d(double r[4], const float M[4][4], const double v[4]);
176 /* double matrix functions (no mixing types) */
177 void mul_v3_m3v3_db(double r[3], const double M[3][3], const double a[3]);
178 void mul_m3_v3_db(const double M[3][3], double r[3]);
181 /****************************** Linear Algebra *******************************/
183 void transpose_m3(float R[3][3]);
184 void transpose_m3_m3(float R[3][3], const float A[3][3]);
185 void transpose_m3_m4(float R[3][3], const float A[4][4]);
186 void transpose_m4(float R[4][4]);
187 void transpose_m4_m4(float R[4][4], const float A[4][4]);
189 int compare_m4m4(const float mat1[4][4], const float mat2[4][4], float limit);
191 void normalize_m3_ex(float R[3][3], float r_scale[3]) ATTR_NONNULL();
192 void normalize_m3(float R[3][3]) ATTR_NONNULL();
193 void normalize_m3_m3_ex(float R[3][3], const float A[3][3], float r_scale[3]) ATTR_NONNULL();
194 void normalize_m3_m3(float R[3][3], const float A[3][3]) ATTR_NONNULL();
195 void normalize_m4_ex(float R[4][4], float r_scale[3]) ATTR_NONNULL();
196 void normalize_m4(float R[4][4]) ATTR_NONNULL();
197 void normalize_m4_m4_ex(float R[4][4], const float A[4][4], float r_scale[3]) ATTR_NONNULL();
198 void normalize_m4_m4(float R[4][4], const float A[4][4]) ATTR_NONNULL();
200 void orthogonalize_m3(float R[3][3], int axis);
201 void orthogonalize_m4(float R[4][4], int axis);
203 bool is_orthogonal_m3(const float mat[3][3]);
204 bool is_orthogonal_m4(const float mat[4][4]);
205 bool is_orthonormal_m3(const float mat[3][3]);
206 bool is_orthonormal_m4(const float mat[4][4]);
208 bool is_uniform_scaled_m3(const float mat[3][3]);
209 bool is_uniform_scaled_m4(const float m[4][4]);
211 /* Note: 'adjoint' here means the adjugate (adjunct, "classical adjoint") matrix!
212 * Nowadays 'adjoint' usually refers to the conjugate transpose,
213 * which for real-valued matrices is simply the transpose.
215 void adjoint_m2_m2(float R[2][2], const float A[2][2]);
216 void adjoint_m3_m3(float R[3][3], const float A[3][3]);
217 void adjoint_m4_m4(float R[4][4], const float A[4][4]);
219 float determinant_m2(float a, float b,
221 float determinant_m3(float a, float b, float c,
222 float d, float e, float f,
223 float g, float h, float i);
224 float determinant_m3_array(const float m[3][3]);
225 float determinant_m4(const float A[4][4]);
227 #define PSEUDOINVERSE_EPSILON 1e-8f
229 void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]);
230 void pseudoinverse_m4_m4(float Ainv[4][4], const float A[4][4], float epsilon);
231 void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon);
233 bool has_zero_axis_m4(const float matrix[4][4]);
235 void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4]);
237 /****************************** Transformations ******************************/
239 void scale_m3_fl(float R[3][3], float scale);
240 void scale_m4_fl(float R[4][4], float scale);
242 float mat3_to_scale(const float M[3][3]);
243 float mat4_to_scale(const float M[4][4]);
244 float mat4_to_xy_scale(const float M[4][4]);
246 void size_to_mat3(float R[3][3], const float size[3]);
247 void size_to_mat4(float R[4][4], const float size[3]);
249 void mat3_to_size(float r[3], const float M[3][3]);
250 void mat4_to_size(float r[3], const float M[4][4]);
252 void translate_m4(float mat[4][4], float tx, float ty, float tz);
253 void rotate_m4(float mat[4][4], const char axis, const float angle);
254 void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
256 void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3]);
257 void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4]);
258 void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4]);
259 void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4]);
261 void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3]);
263 void loc_eul_size_to_mat4(float R[4][4],
264 const float loc[3], const float eul[3], const float size[3]);
265 void loc_eulO_size_to_mat4(float R[4][4],
266 const float loc[3], const float eul[3], const float size[3], const short order);
267 void loc_quat_size_to_mat4(float R[4][4],
268 const float loc[3], const float quat[4], const float size[3]);
269 void loc_axisangle_size_to_mat4(float R[4][4],
270 const float loc[3], const float axis[4], const float angle, const float size[3]);
272 void blend_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t);
273 void blend_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t);
275 void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t);
276 void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t);
278 bool is_negative_m3(const float mat[3][3]);
279 bool is_negative_m4(const float mat[4][4]);
281 bool is_zero_m3(const float mat[3][3]);
282 bool is_zero_m4(const float mat[4][4]);
284 bool equals_m3m3(const float mat1[3][3], const float mat2[3][3]);
285 bool equals_m4m4(const float mat1[4][4], const float mat2[4][4]);
287 /* SpaceTransform helper */
288 typedef struct SpaceTransform {
289 float local2target[4][4];
290 float target2local[4][4];
294 void BLI_space_transform_from_matrices(struct SpaceTransform *data, const float local[4][4], const float target[4][4]);
295 void BLI_space_transform_global_from_matrices(struct SpaceTransform *data, const float local[4][4], const float target[4][4]);
296 void BLI_space_transform_apply(const struct SpaceTransform *data, float co[3]);
297 void BLI_space_transform_invert(const struct SpaceTransform *data, float co[3]);
298 void BLI_space_transform_apply_normal(const struct SpaceTransform *data, float no[3]);
299 void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float no[3]);
301 #define BLI_SPACE_TRANSFORM_SETUP(data, local, target) \
302 BLI_space_transform_from_matrices((data), (local)->obmat, (target)->obmat)
304 /*********************************** Other ***********************************/
306 void print_m3(const char *str, const float M[3][3]);
307 void print_m4(const char *str, const float M[4][4]);
309 #define print_m3_id(M) print_m3(STRINGIFY(M), M)
310 #define print_m4_id(M) print_m4(STRINGIFY(M), M)
316 #endif /* __BLI_MATH_MATRIX_H__ */