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_m3(float R[3][3]);
42 void zero_m4(float R[4][4]);
44 void unit_m3(float R[3][3]);
45 void unit_m4(float R[4][4]);
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]);
53 void copy_m3_m3d(float R[3][3], double A[3][3]);
55 void swap_m3m3(float A[3][3], float B[3][3]);
56 void swap_m4m4(float A[4][4], float B[4][4]);
58 /******************************** Arithmetic *********************************/
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]);
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]);
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]);
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();
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();
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__)
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]);
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]);
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);
124 void negate_m3(float R[4][4]);
125 void negate_m4(float R[4][4]);
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);
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]);
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]);
140 /****************************** Linear Algebra *******************************/
142 void transpose_m3(float R[3][3]);
143 void transpose_m4(float R[4][4]);
145 int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit);
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]);
152 void orthogonalize_m3(float R[3][3], int axis);
153 void orthogonalize_m4(float R[4][4], int axis);
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]);
160 bool is_uniform_scaled_m3(float mat[3][3]);
161 bool is_uniform_scaled_m4(float m[4][4]);
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]);
167 float determinant_m2(float a, float b,
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]);
175 #define PSEUDOINVERSE_EPSILON 1e-8f
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);
181 bool has_zero_axis_m4(float matrix[4][4]);
183 void invert_m4_m4_safe(float Ainv[4][4], float A[4][4]);
185 /****************************** Transformations ******************************/
187 void scale_m3_fl(float R[3][3], float scale);
188 void scale_m4_fl(float R[4][4], float scale);
190 float mat3_to_scale(float M[3][3]);
191 float mat4_to_scale(float M[4][4]);
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]);
196 void mat3_to_size(float r[3], float M[3][3]);
197 void mat4_to_size(float r[3], float M[4][4]);
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]);
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]);
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]);
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);
221 bool is_negative_m3(float mat[3][3]);
222 bool is_negative_m4(float mat[4][4]);
224 bool is_zero_m3(float mat[3][3]);
225 bool is_zero_m4(float mat[4][4]);
227 /*********************************** Other ***********************************/
229 void print_m3(const char *str, float M[3][3]);
230 void print_m4(const char *str, float M[3][4]);
232 #define print_m3_id(M) print_m3(STRINGIFY(M), M)
233 #define print_m4_id(M) print_m4(STRINGIFY(M), M)
239 #endif /* __BLI_MATH_MATRIX_H__ */