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 #pragma once
24 
25 /** \file
26  * \ingroup bli
27  */
28 
29 #include "BLI_compiler_attrs.h"
30 #include "BLI_math_inline.h"
31 
32 #ifdef BLI_MATH_GCC_WARN_PRAGMA
33 #  pragma GCC diagnostic push
34 #  pragma GCC diagnostic ignored "-Wredundant-decls"
35 #endif
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /********************************** Polygons *********************************/
42 
43 float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3]);
44 float normal_quad_v3(
45     float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
46 float normal_poly_v3(float n[3], const float verts[][3], unsigned int nr);
47 
48 MINLINE float area_tri_v2(const float v1[2], const float v2[2], const float v3[2]);
49 MINLINE float area_squared_tri_v2(const float v1[2], const float v2[2], const float v3[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 v1[3], const float v2[3], const float v3[3]);
52 float area_squared_tri_v3(const float v1[3], const float v2[3], const float v3[3]);
53 float area_tri_signed_v3(const float v1[3],
54                          const float v2[3],
55                          const float v3[3],
56                          const float normal[3]);
57 float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
58 float area_squared_quad_v3(const float v1[3],
59                            const float v2[3],
60                            const float v3[3],
61                            const float v4[3]);
62 float area_poly_v3(const float verts[][3], unsigned int nr);
63 float area_poly_v2(const float verts[][2], unsigned int nr);
64 float area_squared_poly_v3(const float verts[][3], unsigned int nr);
65 float area_squared_poly_v2(const float verts[][2], unsigned int nr);
66 float area_poly_signed_v2(const float verts[][2], unsigned int nr);
67 float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3]);
68 
69 void cross_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3]);
70 MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2]);
71 void cross_poly_v3(float n[3], const float verts[][3], unsigned int nr);
72 float cross_poly_v2(const float verts[][2], unsigned int nr);
73 
74 /********************************* Planes **********************************/
75 
76 void plane_from_point_normal_v3(float r_plane[4],
77                                 const float plane_co[3],
78                                 const float plane_no[3]);
79 void plane_to_point_vector_v3(const float plane[4], float r_plane_co[3], float r_plane_no[3]);
80 void plane_to_point_vector_v3_normalized(const float plane[4],
81                                          float r_plane_co[3],
82                                          float r_plane_no[3]);
83 
84 MINLINE float plane_point_side_v3(const float plane[4], const float co[3]);
85 
86 /********************************* Volume **********************************/
87 
88 float volume_tetrahedron_v3(const float v1[3],
89                             const float v2[3],
90                             const float v3[3],
91                             const float v4[3]);
92 float volume_tetrahedron_signed_v3(const float v1[3],
93                                    const float v2[3],
94                                    const float v3[3],
95                                    const float v4[3]);
96 
97 float volume_tri_tetrahedron_signed_v3_6x(const float v1[3], const float v2[3], const float v3[3]);
98 float volume_tri_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3]);
99 
100 bool is_edge_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
101 bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
102 bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
103 bool is_poly_convex_v2(const float verts[][2], unsigned int nr);
104 int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
105 bool is_quad_flip_v3_first_third_fast(const float v1[3],
106                                       const float v2[3],
107                                       const float v3[3],
108                                       const float v4[3]);
109 
110 /********************************* Distance **********************************/
111 
112 float dist_squared_to_line_v2(const float p[2], const float l1[2], const float l2[2]);
113 float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]);
114 float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]);
115 float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]);
116 
117 float dist_signed_squared_to_plane_v3(const float p[3], const float plane[4]);
118 float dist_squared_to_plane_v3(const float p[3], const float plane[4]);
119 float dist_signed_to_plane_v3(const float p[3], const float plane[4]);
120 float dist_to_plane_v3(const float p[3], const float plane[4]);
121 
122 /* plane3 versions */
123 float dist_signed_squared_to_plane3_v3(const float p[3], const float plane[4]);
124 float dist_squared_to_plane3_v3(const float p[3], const float plane[4]);
125 float dist_signed_to_plane3_v3(const float p[3], const float plane[4]);
126 float dist_to_plane3_v3(const float p[3], const float plane[4]);
127 
128 float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
129 float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
130 float dist_squared_to_line_v3(const float p[3], const float l1[3], const float l2[3]);
131 float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3]);
132 float dist_signed_squared_to_corner_v3v3v3(const float p[3],
133                                            const float v1[3],
134                                            const float v2[3],
135                                            const float v3[3],
136                                            const float axis_ref[3]);
137 float dist_squared_to_ray_v3_normalized(const float ray_origin[3],
138                                         const float ray_direction[3],
139                                         const float co[3]);
140 float dist_squared_ray_to_seg_v3(const float ray_origin[3],
141                                  const float ray_direction[3],
142                                  const float v0[3],
143                                  const float v1[3],
144                                  float r_point[3],
145                                  float *r_depth);
146 
147 void aabb_get_near_far_from_plane(const float plane_no[3],
148                                   const float bbmin[3],
149                                   const float bbmax[3],
150                                   float bb_near[3],
151                                   float bb_afar[3]);
152 
153 struct DistRayAABB_Precalc {
154   float ray_origin[3];
155   float ray_direction[3];
156   float ray_inv_dir[3];
157 };
158 void dist_squared_ray_to_aabb_v3_precalc(struct DistRayAABB_Precalc *neasrest_precalc,
159                                          const float ray_origin[3],
160                                          const float ray_direction[3]);
161 float dist_squared_ray_to_aabb_v3(const struct DistRayAABB_Precalc *data,
162                                   const float bb_min[3],
163                                   const float bb_max[3],
164                                   float r_point[3],
165                                   float *r_depth);
166 /* when there is no advantage to precalc. */
167 float dist_squared_ray_to_aabb_v3_simple(const float ray_origin[3],
168                                          const float ray_direction[3],
169                                          const float bb_min[3],
170                                          const float bb_max[3],
171                                          float r_point[3],
172                                          float *r_depth);
173 
174 struct DistProjectedAABBPrecalc {
175   float ray_origin[3];
176   float ray_direction[3];
177   float ray_inv_dir[3];
178   float pmat[4][4];
179   float mval[2];
180 };
181 void dist_squared_to_projected_aabb_precalc(struct DistProjectedAABBPrecalc *precalc,
182                                             const float projmat[4][4],
183                                             const float winsize[2],
184                                             const float mval[2]);
185 float dist_squared_to_projected_aabb(struct DistProjectedAABBPrecalc *data,
186                                      const float bbmin[3],
187                                      const float bbmax[3],
188                                      bool r_axis_closest[3]);
189 float dist_squared_to_projected_aabb_simple(const float projmat[4][4],
190                                             const float winsize[2],
191                                             const float mval[2],
192                                             const float bbmin[3],
193                                             const float bbmax[3]);
194 
195 float closest_to_ray_v3(float r_close[3],
196                         const float p[3],
197                         const float ray_orig[3],
198                         const float ray_dir[3]);
199 float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2]);
200 double closest_to_line_v2_db(double r_close[2],
201                              const double p[2],
202                              const double l1[2],
203                              const double l2[2]);
204 float closest_to_line_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3]);
205 void closest_to_line_segment_v2(float r_close[2],
206                                 const float p[2],
207                                 const float l1[2],
208                                 const float l2[2]);
209 void closest_to_line_segment_v3(float r_close[3],
210                                 const float p[3],
211                                 const float l1[3],
212                                 const float l2[3]);
213 void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3]);
214 void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3]);
215 void closest_to_plane3_normalized_v3(float r_close[3], const float plane[3], const float pt[3]);
216 void closest_to_plane3_v3(float r_close[3], const float plane[3], const float pt[3]);
217 
218 /* Set 'r' to the point in triangle (v1, v2, v3) closest to point 'p' */
219 void closest_on_tri_to_point_v3(
220     float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3]);
221 
222 float ray_point_factor_v3_ex(const float p[3],
223                              const float ray_origin[3],
224                              const float ray_direction[3],
225                              const float epsilon,
226                              const float fallback);
227 float ray_point_factor_v3(const float p[3],
228                           const float ray_origin[3],
229                           const float ray_direction[3]);
230 
231 float line_point_factor_v3_ex(const float p[3],
232                               const float l1[3],
233                               const float l2[3],
234                               const float epsilon,
235                               const float fallback);
236 float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3]);
237 
238 float line_point_factor_v2_ex(const float p[2],
239                               const float l1[2],
240                               const float l2[2],
241                               const float epsilon,
242                               const float fallback);
243 float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2]);
244 
245 float line_plane_factor_v3(const float plane_co[3],
246                            const float plane_no[3],
247                            const float l1[3],
248                            const float l2[3]);
249 
250 void limit_dist_v3(float v1[3], float v2[3], const float dist);
251 
252 /******************************* Intersection ********************************/
253 
254 /* TODO int return value consistency */
255 
256 /* line-line */
257 #define ISECT_LINE_LINE_COLINEAR -1
258 #define ISECT_LINE_LINE_NONE 0
259 #define ISECT_LINE_LINE_EXACT 1
260 #define ISECT_LINE_LINE_CROSS 2
261 
262 int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
263 void isect_seg_seg_v3(const float a0[3],
264                       const float a1[3],
265                       const float b0[3],
266                       const float b1[3],
267                       float r_a[3],
268                       float r_b[3]);
269 
270 int isect_seg_seg_v2_int(const int v1[2], const int v2[2], const int v3[2], const int v4[2]);
271 int isect_seg_seg_v2_point_ex(const float v0[2],
272                               const float v1[2],
273                               const float v2[2],
274                               const float v3[2],
275                               const float endpoint_bias,
276                               float vi[2]);
277 int isect_seg_seg_v2_point(
278     const float v0[2], const float v1[2], const float v2[2], const float v3[2], float vi[2]);
279 bool isect_seg_seg_v2_simple(const float v1[2],
280                              const float v2[2],
281                              const float v3[2],
282                              const float v4[2]);
283 int isect_seg_seg_v2_lambda_mu_db(const double v1[2],
284                                   const double v2[2],
285                                   const double v3[2],
286                                   const double v4[2],
287                                   double *r_lambda,
288                                   double *r_mu);
289 int isect_line_sphere_v3(const float l1[3],
290                          const float l2[3],
291                          const float sp[3],
292                          const float r,
293                          float r_p1[3],
294                          float r_p2[3]);
295 int isect_line_sphere_v2(const float l1[2],
296                          const float l2[2],
297                          const float sp[2],
298                          const float r,
299                          float r_p1[2],
300                          float r_p2[2]);
301 
302 int isect_line_line_v2_point(
303     const float v0[2], const float v1[2], const float v2[2], const float v3[2], float r_vi[2]);
304 int isect_line_line_epsilon_v3(const float v1[3],
305                                const float v2[3],
306                                const float v3[3],
307                                const float v4[3],
308                                float i1[3],
309                                float i2[3],
310                                const float epsilon);
311 int isect_line_line_v3(const float v1[3],
312                        const float v2[3],
313                        const float v3[3],
314                        const float v4[3],
315                        float r_i1[3],
316                        float r_i2[3]);
317 bool isect_line_line_strict_v3(const float v1[3],
318                                const float v2[3],
319                                const float v3[3],
320                                const float v4[3],
321                                float vi[3],
322                                float *r_lambda);
323 bool isect_ray_ray_epsilon_v3(const float ray_origin_a[3],
324                               const float ray_direction_a[3],
325                               const float ray_origin_b[3],
326                               const float ray_direction_b[3],
327                               const float epsilon,
328                               float *r_lambda_a,
329                               float *r_lambda_b);
330 bool isect_ray_ray_v3(const float ray_origin_a[3],
331                       const float ray_direction_a[3],
332                       const float ray_origin_b[3],
333                       const float ray_direction_b[3],
334                       float *r_lambda_a,
335                       float *r_lambda_b);
336 
337 bool isect_ray_plane_v3(const float ray_origin[3],
338                         const float ray_direction[3],
339                         const float plane[4],
340                         float *r_lambda,
341                         const bool clip);
342 
343 bool isect_point_planes_v3(float (*planes)[4], int totplane, const float p[3]);
344 bool isect_point_planes_v3_negated(const float (*planes)[4], const int totplane, const float p[3]);
345 
346 bool isect_line_plane_v3(float r_isect_co[3],
347                          const float l1[3],
348                          const float l2[3],
349                          const float plane_co[3],
350                          const float plane_no[3]) ATTR_WARN_UNUSED_RESULT;
351 
352 bool isect_plane_plane_plane_v3(const float plane_a[4],
353                                 const float plane_b[4],
354                                 const float plane_c[4],
355                                 float r_isect_co[3]) ATTR_WARN_UNUSED_RESULT;
356 bool isect_plane_plane_v3(const float plane_a[4],
357                           const float plane_b[4],
358                           float r_isect_co[3],
359                           float r_isect_no[3]) ATTR_WARN_UNUSED_RESULT;
360 
361 /* line/ray triangle */
362 bool isect_line_segment_tri_v3(const float p1[3],
363                                const float p2[3],
364                                const float v0[3],
365                                const float v1[3],
366                                const float v2[3],
367                                float *r_lambda,
368                                float r_uv[2]);
369 bool isect_line_segment_tri_epsilon_v3(const float p1[3],
370                                        const float p2[3],
371                                        const float v0[3],
372                                        const float v1[3],
373                                        const float v2[3],
374                                        float *r_lambda,
375                                        float r_uv[2],
376                                        const float epsilon);
377 bool isect_axial_line_segment_tri_v3(const int axis,
378                                      const float p1[3],
379                                      const float p2[3],
380                                      const float v0[3],
381                                      const float v1[3],
382                                      const float v2[3],
383                                      float *r_lambda);
384 
385 bool isect_ray_tri_v3(const float ray_origin[3],
386                       const float ray_direction[3],
387                       const float v0[3],
388                       const float v1[3],
389                       const float v2[3],
390                       float *r_lambda,
391                       float r_uv[2]);
392 bool isect_ray_tri_threshold_v3(const float ray_origin[3],
393                                 const float ray_direction[3],
394                                 const float v0[3],
395                                 const float v1[3],
396                                 const float v2[3],
397                                 float *r_lambda,
398                                 float r_uv[2],
399                                 const float threshold);
400 bool isect_ray_tri_epsilon_v3(const float ray_origin[3],
401                               const float ray_direction[3],
402                               const float v0[3],
403                               const float v1[3],
404                               const float v2[3],
405                               float *r_lambda,
406                               float r_uv[2],
407                               const float epsilon);
408 bool isect_tri_tri_v3_ex(const float tri_a[3][3],
409                          const float tri_b[3][3],
410                          float r_i1[3],
411                          float r_i2[3],
412                          int *r_tri_a_edge_isect_count);
413 bool isect_tri_tri_v3(const float t_a0[3],
414                       const float t_a1[3],
415                       const float t_a2[3],
416                       const float t_b0[3],
417                       const float t_b1[3],
418                       const float t_b2[3],
419                       float r_i1[3],
420                       float r_i2[3]);
421 
422 bool isect_tri_tri_v2(const float p1[2],
423                       const float q1[2],
424                       const float r1[2],
425                       const float p2[2],
426                       const float q2[2],
427                       const float r2[2]);
428 
429 /* water-tight raycast (requires pre-calculation) */
430 struct IsectRayPrecalc {
431   /* Maximal dimension kz, and orthogonal dimensions. */
432   int kx, ky, kz;
433 
434   /* Shear constants. */
435   float sx, sy, sz;
436 };
437 
438 void isect_ray_tri_watertight_v3_precalc(struct IsectRayPrecalc *isect_precalc,
439                                          const float ray_direction[3]);
440 bool isect_ray_tri_watertight_v3(const float ray_origin[3],
441                                  const struct IsectRayPrecalc *isect_precalc,
442                                  const float v0[3],
443                                  const float v1[3],
444                                  const float v2[3],
445                                  float *r_dist,
446                                  float r_uv[2]);
447 /* slower version which calculates IsectRayPrecalc each time */
448 bool isect_ray_tri_watertight_v3_simple(const float ray_origin[3],
449                                         const float ray_direction[3],
450                                         const float v0[3],
451                                         const float v1[3],
452                                         const float v2[3],
453                                         float *r_lambda,
454                                         float r_uv[2]);
455 
456 bool isect_ray_seg_v2(const float ray_origin[2],
457                       const float ray_direction[2],
458                       const float v0[2],
459                       const float v1[2],
460                       float *r_lambda,
461                       float *r_u);
462 
463 bool isect_ray_line_v3(const float ray_origin[3],
464                        const float ray_direction[3],
465                        const float v0[3],
466                        const float v1[3],
467                        float *r_lambda);
468 
469 /* point in polygon */
470 bool isect_point_poly_v2(const float pt[2],
471                          const float verts[][2],
472                          const unsigned int nr,
473                          const bool use_holes);
474 bool isect_point_poly_v2_int(const int pt[2],
475                              const int verts[][2],
476                              const unsigned int nr,
477                              const bool use_holes);
478 
479 int isect_point_quad_v2(
480     const float p[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
481 
482 int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
483 bool isect_point_tri_v2_cw(const float pt[2],
484                            const float v1[2],
485                            const float v2[2],
486                            const float v3[2]);
487 int isect_point_tri_v2_int(
488     const int x1, const int y1, const int x2, const int y2, const int a, const int b);
489 bool isect_point_tri_prism_v3(const float p[3],
490                               const float v1[3],
491                               const float v2[3],
492                               const float v3[3]);
493 bool isect_point_tri_v3(const float p[3],
494                         const float v1[3],
495                         const float v2[3],
496                         const float v3[3],
497                         float r_isect_co[3]);
498 
499 /* axis-aligned bounding box */
500 bool isect_aabb_aabb_v3(const float min1[3],
501                         const float max1[3],
502                         const float min2[3],
503                         const float max2[3]);
504 
505 struct IsectRayAABB_Precalc {
506   float ray_origin[3];
507   float ray_inv_dir[3];
508   int sign[3];
509 };
510 
511 void isect_ray_aabb_v3_precalc(struct IsectRayAABB_Precalc *data,
512                                const float ray_origin[3],
513                                const float ray_direction[3]);
514 bool isect_ray_aabb_v3(const struct IsectRayAABB_Precalc *data,
515                        const float bb_min[3],
516                        const float bb_max[3],
517                        float *tmin);
518 bool isect_ray_aabb_v3_simple(const float orig[3],
519                               const float dir[3],
520                               const float bb_min[3],
521                               const float bb_max[3],
522                               float *tmin,
523                               float *tmax);
524 
525 /* other */
526 #define ISECT_AABB_PLANE_BEHIND_ANY 0
527 #define ISECT_AABB_PLANE_CROSS_ANY 1
528 #define ISECT_AABB_PLANE_IN_FRONT_ALL 2
529 
530 int isect_aabb_planes_v3(const float (*planes)[4],
531                          const int totplane,
532                          const float bbmin[3],
533                          const float bbmax[3]);
534 
535 bool isect_sweeping_sphere_tri_v3(const float p1[3],
536                                   const float p2[3],
537                                   const float radius,
538                                   const float v0[3],
539                                   const float v1[3],
540                                   const float v2[3],
541                                   float *r_lambda,
542                                   float ipoint[3]);
543 
544 bool clip_segment_v3_plane(
545     const float p1[3], const float p2[3], const float plane[4], float r_p1[3], float r_p2[3]);
546 bool clip_segment_v3_plane_n(const float p1[3],
547                              const float p2[3],
548                              const float plane_array[][4],
549                              const int plane_tot,
550                              float r_p1[3],
551                              float r_p2[3]);
552 
553 bool point_in_slice_seg(float p[3], float l1[3], float l2[3]);
554 
555 /****************************** Interpolation ********************************/
556 void interp_weights_tri_v3(
557     float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3]);
558 void interp_weights_quad_v3(float w[4],
559                             const float v1[3],
560                             const float v2[3],
561                             const float v3[3],
562                             const float v4[3],
563                             const float co[3]);
564 void interp_weights_poly_v3(float w[], float v[][3], const int n, const float co[3]);
565 void interp_weights_poly_v2(float w[], float v[][2], const int n, const float co[2]);
566 
567 void interp_cubic_v3(float x[3],
568                      float v[3],
569                      const float x1[3],
570                      const float v1[3],
571                      const float x2[3],
572                      const float v2[3],
573                      const float t);
574 
575 int interp_sparse_array(float *array, const int list_size, const float skipval);
576 
577 void transform_point_by_tri_v3(float pt_tar[3],
578                                float const pt_src[3],
579                                const float tri_tar_p1[3],
580                                const float tri_tar_p2[3],
581                                const float tri_tar_p3[3],
582                                const float tri_src_p1[3],
583                                const float tri_src_p2[3],
584                                const float tri_src_p3[3]);
585 void transform_point_by_seg_v3(float p_dst[3],
586                                const float p_src[3],
587                                const float l_dst_p1[3],
588                                const float l_dst_p2[3],
589                                const float l_src_p1[3],
590                                const float l_src_p2[3]);
591 
592 void barycentric_weights_v2(
593     const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]);
594 void barycentric_weights_v2_clamped(
595     const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]);
596 void barycentric_weights_v2_persp(
597     const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3]);
598 void barycentric_weights_v2_quad(const float v1[2],
599                                  const float v2[2],
600                                  const float v3[2],
601                                  const float v4[2],
602                                  const float co[2],
603                                  float w[4]);
604 
605 bool barycentric_coords_v2(
606     const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]);
607 int barycentric_inside_triangle_v2(const float w[3]);
608 
609 void resolve_tri_uv_v2(
610     float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]);
611 void resolve_tri_uv_v3(
612     float r_uv[2], const float st[3], const float st0[3], const float st1[3], const float st2[3]);
613 void resolve_quad_uv_v2(float r_uv[2],
614                         const float st[2],
615                         const float st0[2],
616                         const float st1[2],
617                         const float st2[2],
618                         const float st3[2]);
619 void resolve_quad_uv_v2_deriv(float r_uv[2],
620                               float r_deriv[2][2],
621                               const float st[2],
622                               const float st0[2],
623                               const float st1[2],
624                               const float st2[2],
625                               const float st3[2]);
626 float resolve_quad_u_v2(const float st[2],
627                         const float st0[2],
628                         const float st1[2],
629                         const float st2[2],
630                         const float st3[2]);
631 
632 /* use to find the point of a UV on a face */
633 void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3]);
634 void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3]);
635 
636 /***************************** View & Projection *****************************/
637 
638 void lookat_m4(
639     float mat[4][4], float vx, float vy, float vz, float px, float py, float pz, float twist);
640 void polarview_m4(float mat[4][4], float dist, float azimuth, float incidence, float twist);
641 
642 void perspective_m4(float mat[4][4],
643                     const float left,
644                     const float right,
645                     const float bottom,
646                     const float top,
647                     const float nearClip,
648                     const float farClip);
649 void perspective_m4_fov(float mat[4][4],
650                         const float angle_left,
651                         const float angle_right,
652                         const float angle_up,
653                         const float angle_down,
654                         const float nearClip,
655                         const float farClip);
656 void orthographic_m4(float mat[4][4],
657                      const float left,
658                      const float right,
659                      const float bottom,
660                      const float top,
661                      const float nearClip,
662                      const float farClip);
663 void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x, const float y);
664 
665 void planes_from_projmat(const float mat[4][4],
666                          float left[4],
667                          float right[4],
668                          float top[4],
669                          float bottom[4],
670                          float near[4],
671                          float far[4]);
672 
673 void projmat_dimensions(const float projmat[4][4],
674                         float *r_left,
675                         float *r_right,
676                         float *r_bottom,
677                         float *r_top,
678                         float *r_near,
679                         float *r_far);
680 void projmat_dimensions_db(const float projmat[4][4],
681                            double *r_left,
682                            double *r_right,
683                            double *r_bottom,
684                            double *r_top,
685                            double *r_near,
686                            double *r_far);
687 
688 void projmat_from_subregion(const float projmat[4][4],
689                             const int win_size[2],
690                             const int x_min,
691                             const int x_max,
692                             const int y_min,
693                             const int y_max,
694                             float r_projmat[4][4]);
695 
696 int box_clip_bounds_m4(float boundbox[2][3], const float bounds[4], float winmat[4][4]);
697 void box_minmax_bounds_m4(float min[3], float max[3], float boundbox[2][3], float mat[4][4]);
698 
699 /********************************** Mapping **********************************/
700 
701 void map_to_tube(float *r_u, float *r_v, const float x, const float y, const float z);
702 void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z);
703 void map_to_plane_v2_v3v3(float r_co[2], const float co[3], const float no[3]);
704 void map_to_plane_axis_angle_v2_v3v3fl(float r_co[2],
705                                        const float co[3],
706                                        const float axis[3],
707                                        const float angle);
708 
709 /********************************** Normals **********************************/
710 
711 void accumulate_vertex_normals_tri_v3(float n1[3],
712                                       float n2[3],
713                                       float n3[3],
714                                       const float f_no[3],
715                                       const float co1[3],
716                                       const float co2[3],
717                                       const float co3[3]);
718 
719 void accumulate_vertex_normals_v3(float n1[3],
720                                   float n2[3],
721                                   float n3[3],
722                                   float n4[3],
723                                   const float f_no[3],
724                                   const float co1[3],
725                                   const float co2[3],
726                                   const float co3[3],
727                                   const float co4[3]);
728 
729 void accumulate_vertex_normals_poly_v3(float **vertnos,
730                                        const float polyno[3],
731                                        const float **vertcos,
732                                        float vdiffs[][3],
733                                        const int nverts);
734 
735 /********************************* Tangents **********************************/
736 
737 void tangent_from_uv_v3(const float uv1[2],
738                         const float uv2[2],
739                         const float uv3[2],
740                         const float co1[3],
741                         const float co2[3],
742                         const float co3[3],
743                         const float n[3],
744                         float r_tang[3]);
745 
746 /******************************** Vector Clouds ******************************/
747 
748 void vcloud_estimate_transform_v3(const int list_size,
749                                   const float (*pos)[3],
750                                   const float *weight,
751                                   const float (*rpos)[3],
752                                   const float *rweight,
753                                   float lloc[3],
754                                   float rloc[3],
755                                   float lrot[3][3],
756                                   float lscale[3][3]);
757 
758 /****************************** Spherical Harmonics *************************/
759 
760 /* Uses 2nd order SH => 9 coefficients, stored in this order:
761  * 0 = (0, 0),
762  * 1 = (1, -1), 2 = (1, 0), 3 = (1, 1),
763  * 4 = (2, -2), 5 = (2, -1), 6 = (2, 0), 7 = (2, 1), 8 = (2, 2) */
764 
765 MINLINE void zero_sh(float r[9]);
766 MINLINE void copy_sh_sh(float r[9], const float a[9]);
767 MINLINE void mul_sh_fl(float r[9], const float f);
768 MINLINE void add_sh_shsh(float r[9], const float a[9], const float b[9]);
769 MINLINE float dot_shsh(const float a[9], const float b[9]);
770 
771 MINLINE float eval_shv3(float r[9], const float v[3]);
772 MINLINE float diffuse_shv3(float r[9], const float v[3]);
773 MINLINE void vec_fac_to_sh(float r[9], const float v[3], const float f);
774 MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f);
775 
776 /********************************* Form Factor *******************************/
777 
778 float form_factor_quad(const float p[3],
779                        const float n[3],
780                        const float q0[3],
781                        const float q1[3],
782                        const float q2[3],
783                        const float q3[3]);
784 bool form_factor_visible_quad(const float p[3],
785                               const float n[3],
786                               const float v0[3],
787                               const float v1[3],
788                               const float v2[3],
789                               float q0[3],
790                               float q1[3],
791                               float q2[3],
792                               float q3[3]);
793 float form_factor_hemi_poly(
794     float p[3], float n[3], float v1[3], float v2[3], float v3[3], float v4[3]);
795 
796 void axis_dominant_v3_to_m3_negate(float r_mat[3][3], const float normal[3]);
797 void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3]);
798 
799 MINLINE void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]);
800 MINLINE float axis_dominant_v3_max(int *r_axis_a,
801                                    int *r_axis_b,
802                                    const float axis[3]) ATTR_WARN_UNUSED_RESULT;
803 MINLINE int axis_dominant_v3_single(const float vec[3]);
804 MINLINE int axis_dominant_v3_ortho_single(const float vec[3]);
805 
806 MINLINE int max_axis_v3(const float vec[3]);
807 MINLINE int min_axis_v3(const float vec[3]);
808 
809 MINLINE int poly_to_tri_count(const int poly_count, const int corner_count);
810 
811 MINLINE float shell_angle_to_dist(const float angle);
812 MINLINE float shell_v3v3_normalized_to_dist(const float a[3], const float b[3]);
813 MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2]);
814 MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[3]);
815 MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[2]);
816 
817 /********************************* Cubic (Bezier) *******************************/
818 
819 float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3]);
820 
821 /**************************** Inline Definitions ******************************/
822 
823 #if BLI_MATH_DO_INLINE
824 #  include "intern/math_geom_inline.c"
825 #endif
826 
827 #ifdef BLI_MATH_GCC_WARN_PRAGMA
828 #  pragma GCC diagnostic pop
829 #endif
830 
831 #ifdef __cplusplus
832 }
833 #endif
834