doxygen: add newline after \file
[blender.git] / source / blender / blenlib / BLI_math_geom.h
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  *
19  * The Original Code is: some of this file.
20  *
21  * */
22
23 #ifndef __BLI_MATH_GEOM_H__
24 #define __BLI_MATH_GEOM_H__
25
26 /** \file
27  * \ingroup bli
28  */
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 #include "BLI_compiler_attrs.h"
35 #include "BLI_math_inline.h"
36
37 #ifdef BLI_MATH_GCC_WARN_PRAGMA
38 #  pragma GCC diagnostic push
39 #  pragma GCC diagnostic ignored "-Wredundant-decls"
40 #endif
41
42 /********************************** Polygons *********************************/
43
44 float normal_tri_v3(float r[3], const float a[3], const float b[3], const float c[3]);
45 float normal_quad_v3(float r[3], const float a[3], const float b[3], const float c[3], const float d[3]);
46 float normal_poly_v3(float r[3], const float verts[][3], unsigned int nr);
47
48 MINLINE float area_tri_v2(const float a[2], const float b[2], const float c[2]);
49 MINLINE float area_squared_tri_v2(const float a[2], const float b[2], const float c[2]);
50 MINLINE float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]);
51 float area_tri_v3(const float a[3], const float b[3], const float c[3]);
52 float area_squared_tri_v3(const float a[3], const float b[3], const float c[3]);
53 float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3]);
54 float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
55 float area_squared_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
56 float area_poly_v3(const float verts[][3], unsigned int nr);
57 float area_poly_v2(const float verts[][2], unsigned int nr);
58 float area_squared_poly_v3(const float verts[][3], unsigned int nr);
59 float area_squared_poly_v2(const float verts[][2], unsigned int nr);
60 float area_poly_signed_v2(const float verts[][2], unsigned int nr);
61 float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3]);
62
63 void          cross_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3]);
64 MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2]);
65 void cross_poly_v3(float n[3], const float verts[][3], unsigned int nr);
66 float cross_poly_v2(const float verts[][2], unsigned int nr);
67
68 /********************************* Planes **********************************/
69
70 void  plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3]);
71 void  plane_to_point_vector_v3(const float plane[4], float r_plane_co[3], float r_plane_no[3]);
72 void  plane_to_point_vector_v3_normalized(const float plane[4], float r_plane_co[3], float r_plane_no[3]);
73
74 MINLINE float plane_point_side_v3(const float plane[4], const float co[3]);
75
76 /********************************* Volume **********************************/
77
78 float volume_tetrahedron_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
79 float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
80
81 bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
82 bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
83 bool is_poly_convex_v2(const float verts[][2], unsigned int nr);
84 int  is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
85 bool is_quad_flip_v3_first_third_fast(const float v0[3], const float v1[3], const float v2[3], const float v3[3]);
86
87 /********************************* Distance **********************************/
88
89 float dist_squared_to_line_v2(const float p[2], const float l1[2], const float l2[2]);
90 float         dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]);
91 float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]);
92 float         dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]);
93
94 float dist_signed_squared_to_plane_v3(const float p[3], const float plane[4]);
95 float        dist_squared_to_plane_v3(const float p[3], const float plane[4]);
96 float dist_signed_to_plane_v3(const float p[3], const float plane[4]);
97 float        dist_to_plane_v3(const float p[3], const float plane[4]);
98
99 /* plane3 versions */
100 float dist_signed_squared_to_plane3_v3(const float p[3], const float plane[4]);
101 float        dist_squared_to_plane3_v3(const float p[3], const float plane[4]);
102 float dist_signed_to_plane3_v3(const float p[3], const float plane[4]);
103 float        dist_to_plane3_v3(const float p[3], const float plane[4]);
104
105 float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
106 float         dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
107 float dist_squared_to_line_v3(const float p[3], const float l1[3], const float l2[3]);
108 float         dist_to_line_v3(const float p[3], const float l1[3], const float l2[3]);
109 float dist_signed_squared_to_corner_v3v3v3(
110         const float p[3],
111         const float v1[3], const float v2[3], const float v3[3],
112         const float axis_ref[3]);
113 float dist_squared_to_ray_v3_normalized(
114         const float ray_origin[3], const float ray_direction[3],
115         const float co[3]);
116 float dist_squared_ray_to_seg_v3(
117         const float ray_origin[3], const float ray_direction[3],
118         const float v0[3], const float v1[3],
119         float r_point[3], float *r_depth);
120
121 void aabb_get_near_far_from_plane(
122         const float plane_no[3], const float bbmin[3], const float bbmax[3],
123         float bb_near[3], float bb_afar[3]);
124
125 struct DistRayAABB_Precalc {
126         float ray_origin[3];
127         float ray_direction[3];
128         float ray_inv_dir[3];
129 };
130 void dist_squared_ray_to_aabb_v3_precalc(
131         struct DistRayAABB_Precalc *neasrest_precalc,
132         const float ray_origin[3], const float ray_direction[3]);
133 float dist_squared_ray_to_aabb_v3(
134         const struct DistRayAABB_Precalc *data,
135         const float bb_min[3], const float bb_max[3],
136         float r_point[3], float *r_depth);
137 /* when there is no advantage to precalc. */
138 float dist_squared_ray_to_aabb_v3_simple(
139         const float ray_origin[3], const float ray_direction[3],
140         const float bb_min[3], const float bb_max[3],
141         float r_point[3], float *r_depth);
142
143 struct DistProjectedAABBPrecalc {
144         float ray_origin[3];
145         float ray_direction[3];
146         float ray_inv_dir[3];
147         float pmat[4][4];
148         float mval[2];
149 };
150 void dist_squared_to_projected_aabb_precalc(
151         struct DistProjectedAABBPrecalc *precalc,
152         const float projmat[4][4], const float winsize[2], const float mval[2]);
153 float dist_squared_to_projected_aabb(
154         struct DistProjectedAABBPrecalc *data,
155         const float bbmin[3], const float bbmax[3],
156         bool r_axis_closest[3]);
157 float dist_squared_to_projected_aabb_simple(
158         const float projmat[4][4], const float winsize[2], const float mval[2],
159         const float bbmin[3], const float bbmax[3]);
160
161 float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2]);
162 float closest_to_line_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3]);
163 void closest_to_line_segment_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2]);
164 void closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3]);
165 void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3]);
166 void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3]);
167 void closest_to_plane3_normalized_v3(float r_close[3], const float plane[3], const float pt[3]);
168 void closest_to_plane3_v3(float r_close[3], const float plane[3], const float pt[3]);
169
170 /* Set 'r' to the point in triangle (t1, t2, t3) closest to point 'p' */
171 void closest_on_tri_to_point_v3(float r[3], const float p[3], const float t1[3], const float t2[3], const float t3[3]);
172
173 float ray_point_factor_v3_ex(
174         const float p[3], const float ray_origin[3], const float ray_direction[3],
175         const float epsilon, const float fallback);
176 float ray_point_factor_v3(
177         const float p[3], const float ray_origin[3], const float ray_direction[3]);
178
179 float line_point_factor_v3_ex(
180         const float p[3], const float l1[3], const float l2[3],
181         const float epsilon, const float fallback);
182 float line_point_factor_v3(
183         const float p[3], const float l1[3], const float l2[3]);
184
185 float line_point_factor_v2_ex(
186         const float p[2], const float l1[2], const float l2[2],
187         const float epsilon, const float fallback);
188 float line_point_factor_v2(
189         const float p[2], const float l1[2], const float l2[2]);
190
191 float line_plane_factor_v3(const float plane_co[3], const float plane_no[3],
192                            const float l1[3], const float l2[3]);
193
194 void limit_dist_v3(float v1[3], float v2[3], const float dist);
195
196 /******************************* Intersection ********************************/
197
198 /* TODO int return value consistency */
199
200 /* line-line */
201 #define ISECT_LINE_LINE_COLINEAR    -1
202 #define ISECT_LINE_LINE_NONE         0
203 #define ISECT_LINE_LINE_EXACT        1
204 #define ISECT_LINE_LINE_CROSS        2
205
206 int  isect_seg_seg_v2(const float a1[2], const float a2[2], const float b1[2], const float b2[2]);
207 void isect_seg_seg_v3(
208         const float a0[3], const float a1[3],
209         const float b0[3], const float b1[3],
210         float r_a[3], float r_b[3]);
211
212 int  isect_seg_seg_v2_int(const int a1[2], const int a2[2], const int b1[2], const int b2[2]);
213 int  isect_seg_seg_v2_point_ex(
214         const float v0[2], const float v1[2], const float v2[2], const float v3[2], const float endpoint_bias,
215         float vi[2]);
216 int  isect_seg_seg_v2_point(
217         const float v0[2], const float v1[2], const float v2[2], const float v3[2],
218         float vi[2]);
219 bool isect_seg_seg_v2_simple(
220         const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
221
222 int isect_line_sphere_v3(const float l1[3], const float l2[3], const float sp[3], const float r, float r_p1[3], float r_p2[3]);
223 int isect_line_sphere_v2(const float l1[2], const float l2[2], const float sp[2], const float r, float r_p1[2], float r_p2[2]);
224
225 int isect_line_line_v2_point(
226         const float v0[2], const float v1[2],
227         const float v2[2], const float v3[2],
228         float r_vi[2]);
229 int isect_line_line_epsilon_v3(
230         const float v1[3], const float v2[3],
231         const float v3[3], const float v4[3],
232         float i1[3], float i2[3],
233         const float epsilon);
234 int isect_line_line_v3(
235         const float v1[3], const float v2[3],
236         const float v3[3], const float v4[3],
237         float r_i1[3], float r_i2[3]);
238 bool isect_line_line_strict_v3(
239         const float v1[3], const float v2[3],
240         const float v3[3], const float v4[3],
241         float vi[3], float *r_lambda);
242
243 bool isect_ray_plane_v3(
244         const float ray_origin[3], const float ray_direction[3],
245         const float plane[4],
246         float *r_lambda, const bool clip);
247
248 bool isect_point_planes_v3(float (*planes)[4], int totplane, const float p[3]);
249 bool isect_point_planes_v3_negated(
250         const float (*planes)[4], const int totplane, const float p[3]);
251
252 bool isect_line_plane_v3(
253         float r_isect_co[3], const float l1[3], const float l2[3],
254         const float plane_co[3], const float plane_no[3]) ATTR_WARN_UNUSED_RESULT;
255
256 bool isect_plane_plane_plane_v3(
257         const float plane_a[4], const float plane_b[4], const float plane_c[4],
258         float r_isect_co[3]) ATTR_WARN_UNUSED_RESULT;
259 bool isect_plane_plane_v3(
260         const float plane_a[4], const float plane_b[4],
261         float r_isect_co[3], float r_isect_no[3]) ATTR_WARN_UNUSED_RESULT;
262
263 /* line/ray triangle */
264 bool isect_line_segment_tri_v3(
265         const float p1[3], const float p2[3],
266         const float v0[3], const float v1[3], const float v2[3],
267         float *r_lambda, float r_uv[2]);
268 bool isect_line_segment_tri_epsilon_v3(
269         const float p1[3], const float p2[3],
270         const float v0[3], const float v1[3], const float v2[3],
271         float *r_lambda, float r_uv[2], const float epsilon);
272 bool isect_axial_line_segment_tri_v3(
273         const int axis, const float p1[3], const float p2[3],
274         const float v0[3], const float v1[3], const float v2[3], float *r_lambda);
275
276 bool isect_ray_tri_v3(
277         const float ray_origin[3], const float ray_direction[3],
278         const float v0[3], const float v1[3], const float v2[3],
279         float *r_lambda, float r_uv[2]);
280 bool isect_ray_tri_threshold_v3(
281         const float ray_origin[3], const float ray_direction[3],
282         const float v0[3], const float v1[3], const float v2[3],
283         float *r_lambda, float r_uv[2], const float threshold);
284 bool isect_ray_tri_epsilon_v3(
285         const float ray_origin[3], const float ray_direction[3],
286         const float v0[3], const float v1[3], const float v2[3],
287         float *r_lambda, float r_uv[2], const float epsilon);
288 bool isect_tri_tri_epsilon_v3(
289         const float t_a0[3], const float t_a1[3], const float t_a2[3],
290         const float t_b0[3], const float t_b1[3], const float t_b2[3],
291         float r_i1[3], float r_i2[3],
292         const float epsilon);
293
294 /* water-tight raycast (requires pre-calculation) */
295 struct IsectRayPrecalc {
296         /* Maximal dimension kz, and orthogonal dimensions. */
297         int kx, ky, kz;
298
299         /* Shear constants. */
300         float sx, sy, sz;
301 };
302
303 void isect_ray_tri_watertight_v3_precalc(
304         struct IsectRayPrecalc *isect_precalc, const float ray_direction[3]);
305 bool isect_ray_tri_watertight_v3(
306         const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc,
307         const float v0[3], const float v1[3], const float v2[3],
308         float *r_dist, float r_uv[2]);
309 /* slower version which calculates IsectRayPrecalc each time */
310 bool isect_ray_tri_watertight_v3_simple(
311         const float ray_origin[3], const float ray_direction[3],
312         const float v0[3], const float v1[3], const float v2[3],
313         float *r_lambda, float r_uv[2]);
314
315 bool isect_ray_seg_v2(
316         const float ray_origin[2], const float ray_direction[2],
317         const float v0[2], const float v1[2],
318         float *r_lambda, float *r_u);
319
320 bool isect_ray_seg_v3(
321         const float ray_origin[3], const float ray_direction[3],
322         const float v0[3], const float v1[3],
323         float *r_lambda);
324
325 /* point in polygon */
326 bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr, const bool use_holes);
327 bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr, const bool use_holes);
328
329 int isect_point_quad_v2(const float p[2], const float a[2], const float b[2], const float c[2], const float d[2]);
330
331 int  isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
332 bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
333 int  isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b);
334 bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]);
335 bool isect_point_tri_v3(
336         const float p[3], const float v1[3], const float v2[3], const float v3[3],
337         float r_isect_co[3]);
338
339 /* axis-aligned bounding box */
340 bool isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], const float max2[3]);
341
342 struct IsectRayAABB_Precalc {
343         float ray_origin[3];
344         float ray_inv_dir[3];
345         int sign[3];
346 };
347
348 void isect_ray_aabb_v3_precalc(
349         struct IsectRayAABB_Precalc *data,
350         const float ray_origin[3], const float ray_direction[3]);
351 bool isect_ray_aabb_v3(
352         const struct IsectRayAABB_Precalc *data,
353         const float bb_min[3], const float bb_max[3], float *tmin);
354 bool isect_ray_aabb_v3_simple(
355         const float orig[3], const float dir[3],
356         const float bb_min[3], const float bb_max[3],
357         float *tmin, float *tmax);
358
359 /* other */
360 #define ISECT_AABB_PLANE_BEHIND_ANY   0
361 #define ISECT_AABB_PLANE_CROSS_ANY    1
362 #define ISECT_AABB_PLANE_IN_FRONT_ALL 2
363
364 int isect_aabb_planes_v3(
365         const float (*planes)[4], const int totplane,
366         const float bbmin[3], const float bbmax[3]);
367
368 bool isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const float radius,
369                                   const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float ipoint[3]);
370
371 bool clip_segment_v3_plane(
372         const float p1[3], const float p2[3], const float plane[4],
373         float r_p1[3], float r_p2[3]);
374 bool clip_segment_v3_plane_n(
375         const float p1[3], const float p2[3], const float plane_array[][4], const int plane_tot,
376         float r_p1[3], float r_p2[3]);
377
378 bool point_in_slice_seg(float p[3], float l1[3], float l2[3]);
379
380 /****************************** Interpolation ********************************/
381 void interp_weights_tri_v3(float w[3], const float a[3], const float b[3], const float c[3], const float p[3]);
382 void interp_weights_quad_v3(float w[4], const float a[3], const float b[3], const float c[3], const float d[3], const float p[3]);
383 void interp_weights_poly_v3(float w[], float v[][3], const int n, const float co[3]);
384 void interp_weights_poly_v2(float w[], float v[][2], const int n, const float co[2]);
385
386 void interp_cubic_v3(float x[3], float v[3],
387                      const float x1[3], const float v1[3], const float x2[3], const float v2[3], const float t);
388
389 int interp_sparse_array(float *array, const int list_size, const float invalid);
390
391 void transform_point_by_tri_v3(
392         float pt_tar[3], float const pt_src[3],
393         const float tri_tar_p1[3], const float tri_tar_p2[3], const float tri_tar_p3[3],
394         const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3]);
395 void transform_point_by_seg_v3(
396         float p_dst[3], const float p_src[3],
397         const float l_dst_p1[3], const float l_dst_p2[3],
398         const float l_src_p1[3], const float l_src_p2[3]);
399
400 void barycentric_weights_v2(
401         const float v1[2], const float v2[2], const float v3[2],
402         const float co[2], float w[3]);
403 void barycentric_weights_v2_clamped(
404         const float v1[2], const float v2[2], const float v3[2],
405         const float co[2], float w[3]);
406 void barycentric_weights_v2_persp(
407         const float v1[4], const float v2[4], const float v3[4],
408         const float co[2], float w[3]);
409 void barycentric_weights_v2_quad(
410         const float v1[2], const float v2[2], const float v3[2], const float v4[2],
411         const float co[2], float w[4]);
412
413 bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]);
414 int barycentric_inside_triangle_v2(const float w[3]);
415
416 void resolve_tri_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]);
417 void resolve_tri_uv_v3(float r_uv[2], const float st[3], const float st0[3], const float st1[3], const float st2[3]);
418 void resolve_quad_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
419 void resolve_quad_uv_v2_deriv(float r_uv[2], float r_deriv[2][2],
420                               const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
421 float resolve_quad_u_v2(const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
422
423 /* use to find the point of a UV on a face */
424 void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3]);
425 void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3]);
426
427 /***************************** View & Projection *****************************/
428
429 void lookat_m4(float mat[4][4], float vx, float vy,
430                float vz, float px, float py, float pz, float twist);
431 void polarview_m4(float mat[4][4], float dist, float azimuth,
432                   float incidence, float twist);
433
434 void perspective_m4(float mat[4][4], const float left, const float right,
435                     const float bottom, const float top, const float nearClip, const float farClip);
436 void orthographic_m4(float mat[4][4], const float left, const float right,
437                      const float bottom, const float top, const float nearClip, const float farClip);
438 void window_translate_m4(float winmat[4][4], float perspmat[4][4],
439                          const float x, const float y);
440
441 void planes_from_projmat(float mat[4][4], float left[4], float right[4], float top[4], float bottom[4],
442                          float front[4], float back[4]);
443
444 int box_clip_bounds_m4(float boundbox[2][3],
445                        const float bounds[4], float winmat[4][4]);
446 void box_minmax_bounds_m4(float min[3], float max[3],
447                           float boundbox[2][3], float mat[4][4]);
448
449 /********************************** Mapping **********************************/
450
451 void map_to_tube(float *r_u, float *r_v, const float x, const float y, const float z);
452 void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z);
453 void map_to_plane_v2_v3v3(float r_co[2], const float co[3], const float no[3]);
454 void map_to_plane_axis_angle_v2_v3v3fl(float r_co[2], const float co[3], const float axis[3], const float angle);
455
456 /********************************** Normals **********************************/
457
458 void accumulate_vertex_normals_tri_v3(
459         float n1[3], float n2[3], float n3[3],
460         const float f_no[3],
461         const float co1[3], const float co2[3], const float co3[3]);
462
463 void accumulate_vertex_normals_v3(
464         float n1[3], float n2[3], float n3[3], float n4[3],
465         const float f_no[3],
466         const float co1[3], const float co2[3], const float co3[3], const float co4[3]);
467
468 void accumulate_vertex_normals_poly_v3(
469         float **vertnos, const float polyno[3],
470         const float **vertcos, float vdiffs[][3], const int nverts);
471
472 /********************************* Tangents **********************************/
473
474 void tangent_from_uv_v3(
475         const float uv1[2], const float uv2[2], const float uv3[2],
476         const float co1[3], const float co2[3], const float co3[3],
477         const float n[3],
478         float r_tang[3]);
479
480 /******************************** Vector Clouds ******************************/
481
482 void vcloud_estimate_transform_v3(
483         const int list_size, const float (*pos)[3], const float *weight, const float (*rpos)[3], const float *rweight,
484         float lloc[3], float rloc[3], float lrot[3][3], float lscale[3][3]);
485
486 /****************************** Spherical Harmonics *************************/
487
488 /* Uses 2nd order SH => 9 coefficients, stored in this order:
489  * 0 = (0, 0),
490  * 1 = (1, -1), 2 = (1, 0), 3 = (1, 1),
491  * 4 = (2, -2), 5 = (2, -1), 6 = (2, 0), 7 = (2, 1), 8 = (2, 2) */
492
493 MINLINE void zero_sh(float r[9]);
494 MINLINE void copy_sh_sh(float r[9], const float a[9]);
495 MINLINE void mul_sh_fl(float r[9], const float f);
496 MINLINE void add_sh_shsh(float r[9], const float a[9], const float b[9]);
497 MINLINE float dot_shsh(const float a[9], const float b[9]);
498
499 MINLINE float eval_shv3(float r[9], const float v[3]);
500 MINLINE float diffuse_shv3(float r[9], const float v[3]);
501 MINLINE void vec_fac_to_sh(float r[9], const float v[3], const float f);
502 MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f);
503
504 /********************************* Form Factor *******************************/
505
506 float form_factor_quad(const float p[3], const float n[3],
507                        const float q0[3], const float q1[3], const float q2[3], const float q3[3]);
508 bool form_factor_visible_quad(const float p[3], const float n[3],
509                               const float v0[3], const float v1[3], const float v2[3],
510                               float q0[3], float q1[3], float q2[3], float q3[3]);
511 float form_factor_hemi_poly(float p[3], float n[3],
512                             float v1[3], float v2[3], float v3[3], float v4[3]);
513
514 void axis_dominant_v3_to_m3_negate(float r_mat[3][3], const float normal[3]);
515 void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3]);
516
517 MINLINE void  axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]);
518 MINLINE float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3]) ATTR_WARN_UNUSED_RESULT;
519 MINLINE int   axis_dominant_v3_single(const float vec[3]);
520 MINLINE int   axis_dominant_v3_ortho_single(const float vec[3]);
521
522 MINLINE int max_axis_v3(const float vec[3]);
523 MINLINE int min_axis_v3(const float vec[3]);
524
525 MINLINE int poly_to_tri_count(const int poly_count, const int corner_count);
526
527 MINLINE float shell_angle_to_dist(const float angle);
528 MINLINE float shell_v3v3_normalized_to_dist(const float a[3], const float b[3]);
529 MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2]);
530 MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[3]);
531 MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[2]);
532
533 /********************************* Cubic (Bezier) *******************************/
534
535 float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3]);
536
537 /**************************** Inline Definitions ******************************/
538
539 #if BLI_MATH_DO_INLINE
540 #include "intern/math_geom_inline.c"
541 #endif
542
543 #ifdef BLI_MATH_GCC_WARN_PRAGMA
544 #  pragma GCC diagnostic pop
545 #endif
546
547 #ifdef __cplusplus
548 }
549 #endif
550
551 #endif /* __BLI_MATH_GEOM_H__ */