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