1 /* 2 * GPAC - Multimedia Framework C SDK 3 * 4 * Authors: Jean Le Feuvre 5 * Copyright (c) Telecom ParisTech 2000-2019 6 * All rights reserved 7 * 8 * This file is part of GPAC / common tools sub-project 9 * 10 * GPAC is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License as published by 12 * the Free Software Foundation; either version 2, or (at your option) 13 * any later version. 14 * 15 * GPAC is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; see the file COPYING. If not, write to 22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23 * 24 */ 25 26 #ifndef _GF_MATH_H_ 27 #define _GF_MATH_H_ 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /*! 34 \file <gpac/maths.h> 35 \brief Mathematics and Trigonometric. 36 */ 37 38 #include <gpac/setup.h> 39 40 #include <math.h> 41 42 43 /*! 44 \addtogroup math_grp 45 \brief Mathematics and Trigonometric 46 47 This section documents the math and trigo functions used in the GPAC framework. GPAC can be compiled with 48 fixed-point support, representing float values on a 16.16 signed integer, which implies a developer 49 must take care of float computations when using GPAC.\n 50 A developper should not need to know in which mode the framework has been compiled as long as he uses 51 the math functions of GPAC which work in both float and fixed-point mode.\n 52 Using fixed-point version is decided at compilation time and cannot be changed. The feature is signaled 53 through the GPAC_FIXED_POINT macro: when defined, GPAC has been compiled in fixed-point mode 54 55 @{ 56 */ 57 58 59 /***************************************************************************************** 60 FIXED-POINT SUPPORT - HARDCODED FOR 16.16 representation 61 the software rasterizer also use a 16.16 representation even in non-fixed version 62 ******************************************************************************************/ 63 64 #ifdef GPAC_FIXED_POINT 65 66 /*! 67 Fixed 16.16 number 68 \hideinitializer 69 \note This documentation has been generated for a fixed-point version of the GPAC framework. 70 */ 71 typedef s32 Fixed; 72 #define FIX_ONE 0x10000L 73 #define INT2FIX(v) ((Fixed)( ((s32) (v) ) << 16)) 74 #define FLT2FIX(v) ((Fixed) ((v) * FIX_ONE)) 75 #define FIX2INT(v) ((s32)(((v)+((FIX_ONE>>1)))>>16)) 76 #define FIX2FLT(v) ((Float)( ((Float)(v)) / ((Float) FIX_ONE))) 77 #define FIX_EPSILON 2 78 #define FIX_MAX 0x7FFFFFFF 79 #define FIX_MIN -FIX_MAX 80 #define GF_PI2 102944 81 #define GF_PI 205887 82 #define GF_2PI 411774 83 84 /*!\return 1/a, expressed as fixed number*/ 85 Fixed gf_invfix(Fixed a); 86 /*!\return a*b, expressed as fixed number*/ 87 Fixed gf_mulfix(Fixed a, Fixed b); 88 /*!\return a*b/c, expressed as fixed number*/ 89 Fixed gf_muldiv(Fixed a, Fixed b, Fixed c); 90 /*!\return a/b, expressed as fixed number*/ 91 Fixed gf_divfix(Fixed a, Fixed b); 92 /*!\return sqrt(a), expressed as fixed number*/ 93 Fixed gf_sqrt(Fixed x); 94 /*!\return ceil(a), expressed as fixed number*/ 95 Fixed gf_ceil(Fixed a); 96 /*!\return floor(a), expressed as fixed number*/ 97 Fixed gf_floor(Fixed a); 98 /*!\return cos(a), expressed as fixed number*/ 99 Fixed gf_cos(Fixed angle); 100 /*!\return sin(a), expressed as fixed number*/ 101 Fixed gf_sin(Fixed angle); 102 /*!\return tan(a), expressed as fixed number*/ 103 Fixed gf_tan(Fixed angle); 104 /*!\return acos(a), expressed as fixed number*/ 105 Fixed gf_acos(Fixed angle); 106 /*!\return asin(a), expressed as fixed number*/ 107 Fixed gf_asin(Fixed angle); 108 /*!\return atan(y, x), expressed as fixed number*/ 109 Fixed gf_atan2(Fixed y, Fixed x); 110 111 #else 112 113 114 /*!Fixed is 32bit float number 115 \note This documentation has been generated for a float version of the GPAC framework. 116 */ 117 typedef Float Fixed; 118 #define FIX_ONE 1.0f 119 #define INT2FIX(v) ((Float) (v)) 120 #define FLT2FIX(v) ((Float) (v)) 121 #define FIX2INT(v) ((s32)(v)) 122 #define FIX2FLT(v) ((Float) (v)) 123 #define FIX_EPSILON GF_EPSILON_FLOAT 124 #define FIX_MAX GF_MAX_FLOAT 125 #define FIX_MIN -GF_MAX_FLOAT 126 #define GF_PI2 1.5707963267949f 127 #define GF_PI 3.1415926535898f 128 #define GF_2PI 6.2831853071796f 129 130 /*!\hideinitializer 1/_a, expressed as fixed number*/ 131 #define gf_invfix(_a) (FIX_ONE/(_a)) 132 /*!\hideinitializer _a*_b, expressed as fixed number*/ 133 #define gf_mulfix(_a, _b) ((_a)*(_b)) 134 /*!\hideinitializer _a*_b/_c, expressed as fixed number*/ 135 #define gf_muldiv(_a, _b, _c) (((_c != 0)) ? (_a)*(_b)/(_c) : GF_MAX_FLOAT) 136 /*!\hideinitializer _a/_b, expressed as fixed number*/ 137 #define gf_divfix(_a, _b) (((_b != 0)) ? (_a)/(_b) : GF_MAX_FLOAT) 138 /*!\hideinitializer sqrt(_a), expressed as fixed number*/ 139 #define gf_sqrt(_a) ((Float) sqrt(_a)) 140 /*!\hideinitializer ceil(_a), expressed as fixed number*/ 141 #define gf_ceil(_a) ((Float) ceil(_a)) 142 /*!\hideinitializer floor(_a), expressed as fixed number*/ 143 #define gf_floor(_a) ((Float) floor(_a)) 144 /*!\hideinitializer cos(_a), expressed as fixed number*/ 145 #define gf_cos(_a) ((Float) cos(_a)) 146 /*!\hideinitializer sin(_a), expressed as fixed number*/ 147 #define gf_sin(_a) ((Float) sin(_a)) 148 /*!\hideinitializer tan(_a), expressed as fixed number*/ 149 #define gf_tan(_a) ((Float) tan(_a)) 150 /*!\hideinitializer atan2(_y,_x), expressed as fixed number*/ 151 #define gf_atan2(_y, _x) ((Float) atan2(_y, _x)) 152 /*!\hideinitializer acos(_a), expressed as fixed number*/ 153 #define gf_acos(_a) ((Float) acos(_a)) 154 /*!\hideinitializer asin(_a), expressed as fixed number*/ 155 #define gf_asin(_a) ((Float) asin(_a)) 156 157 #endif 158 159 /*!\def FIX_ONE 160 \hideinitializer 161 Fixed unit value 162 */ 163 /*!\def INT2FIX(v) 164 \hideinitializer 165 Conversion from integer to fixed 166 */ 167 /*!\def FLT2FIX(v) 168 \hideinitializer 169 Conversion from float to fixed 170 */ 171 /*!\def FIX2INT(v) 172 \hideinitializer 173 Conversion from fixed to integer 174 */ 175 /*!\def FIX2FLT(v) 176 \hideinitializer 177 Conversion from fixed to float 178 */ 179 /*!\def FIX_EPSILON 180 \hideinitializer 181 Epsilon Fixed (positive value closest to 0) 182 */ 183 /*!\def FIX_MAX 184 \hideinitializer 185 Maximum Fixed (maximum representable fixed value) 186 */ 187 /*!\def FIX_MIN 188 \hideinitializer 189 Minimum Fixed (minimum representable fixed value) 190 */ 191 /*!\def GF_PI2 192 \hideinitializer 193 PI/2 expressed as Fixed 194 */ 195 /*!\def GF_PI 196 \hideinitializer 197 PI expressed as Fixed 198 */ 199 /*!\def GF_2PI 200 \hideinitializer 201 2*PI expressed as Fixed 202 */ 203 204 /*! compute the difference between two angles, with a result in [-PI, PI] 205 \param a first angle 206 \param b first angle 207 \return angle difference 208 */ 209 Fixed gf_angle_diff(Fixed a, Fixed b); 210 211 /*! 212 \brief Field bit-size 213 214 Gets the number of bits needed to represent the value. 215 \param MaxVal Maximum value to be represented. 216 \return number of bits required to represent the value. 217 */ 218 u32 gf_get_bit_size(u32 MaxVal); 219 220 /*! 221 \brief Get power of 2 222 223 Gets the closest power of 2 greater or equal to the value. 224 \param val value to be used. 225 \return requested power of 2. 226 */ 227 u32 gf_get_next_pow2(u32 val); 228 229 /*! 230 \addtogroup math2d_grp Math 2d 231 \ingroup math_grp 232 \brief 2D Mathematics 233 234 This section documents mathematic tools for 2D geometry and color matrices operations 235 236 @{ 237 */ 238 239 /*!\brief 2D point 240 * 241 *The 2D point object is used in all the GPAC framework for both point and vector representation. 242 */ 243 typedef struct __vec2f 244 { 245 Fixed x; 246 Fixed y; 247 } GF_Point2D; 248 /*! 249 \brief get 2D vector length 250 251 Gets the length of a 2D vector 252 \param vec the target vector 253 \return length of the vector 254 */ 255 Fixed gf_v2d_len(GF_Point2D *vec); 256 /*! 257 \brief get distance between 2 points 258 259 Gets the distance between the 2 points 260 \param a first point 261 \param b second point 262 \return distance 263 */ 264 Fixed gf_v2d_distance(GF_Point2D *a, GF_Point2D *b); 265 /*! 266 \brief 2D vector from polar coordinates 267 268 Constructs a 2D vector from its polar coordinates 269 \param length the length of the vector 270 \param angle the angle of the vector in radians 271 \return the 2D vector 272 */ 273 GF_Point2D gf_v2d_from_polar(Fixed length, Fixed angle); 274 275 /*! 276 \brief rectangle 2D 277 278 The 2D rectangle used in the GPAC project. 279 */ 280 typedef struct 281 { 282 /*!the left coordinate of the rectangle*/ 283 Fixed x; 284 /*!the top coordinate of the rectangle, regardless of the canvas orientation. In other words, y is always the 285 greatest coordinate value, even if the rectangle is presented bottom-up. This insures proper rectangles testing*/ 286 Fixed y; 287 /*!the width of the rectangle. Width must be greater than or equal to 0*/ 288 Fixed width; 289 /*!the height of the rectangle. Height must be greater than or equal to 0*/ 290 Fixed height; 291 } GF_Rect; 292 293 /*! 294 \brief rectangle union 295 296 Gets the union of two rectangles. 297 \param rc1 first rectangle of the union. Upon return, this rectangle will contain the result of the union 298 \param rc2 second rectangle of the union 299 */ 300 void gf_rect_union(GF_Rect *rc1, GF_Rect *rc2); 301 /*! 302 \brief centers a rectangle 303 304 Builds a rectangle centered on the origin 305 \param w width of the rectangle 306 \param h height of the rectangle 307 \return centered rectangle object 308 */ 309 GF_Rect gf_rect_center(Fixed w, Fixed h); 310 /*! 311 \brief rectangle overlap test 312 313 Tests if two rectangles overlap. 314 \param rc1 first rectangle to test 315 \param rc2 second rectangle to test 316 \return 1 if rectangles overlap, 0 otherwise 317 */ 318 Bool gf_rect_overlaps(GF_Rect rc1, GF_Rect rc2); 319 /*! 320 \brief rectangle identity test 321 322 Tests if two rectangles are identical. 323 \param rc1 first rectangle to test 324 \param rc2 second rectangle to test 325 \return 1 if rectangles are identical, 0 otherwise 326 */ 327 Bool gf_rect_equal(GF_Rect *rc1, GF_Rect *rc2); 328 329 /*! 330 \brief pixel-aligned rectangle 331 332 Pixel-aligned rectangle used in the GPAC framework. This is usually needed for 2D drawing algorithms. 333 */ 334 typedef struct 335 { 336 /*!the left coordinate of the rectangle*/ 337 s32 x; 338 /*!the top coordinate of the rectangle, regardless of the canvas orientation. In other words, y is always the 339 greatest coordinate value, even if the rectangle is presented bottom-up. This insures proper rectangles operations*/ 340 s32 y; 341 /*!the width of the rectangle. Width must be greater than or equal to 0*/ 342 s32 width; 343 /*!the height of the rectangle. Height must be greater than or equal to 0*/ 344 s32 height; 345 } GF_IRect; 346 /*! 347 \brief gets the pixelized version of a rectangle 348 349 Gets the smallest pixel-aligned rectangle completely containing a rectangle 350 \param r the rectangle to transform 351 \return the pixel-aligned transformed rectangle 352 */ 353 GF_IRect gf_rect_pixelize(GF_Rect *r); 354 355 356 /*! 357 \brief 2D matrix 358 359 The 2D affine matrix object usied in GPAC. The transformation of P(x,y) in P'(X, Y) is: 360 \code 361 X = m[0]*x + m[1]*y + m[2]; 362 Y = m[3]*x + m[4]*y + m[5]; 363 \endcode 364 */ 365 typedef struct 366 { 367 Fixed m[6]; 368 } GF_Matrix2D; 369 370 /*!\brief matrix initialization 371 \hideinitializer 372 373 Inits the matrix to the identity matrix 374 */ 375 #define gf_mx2d_init(_obj) { memset((_obj).m, 0, sizeof(Fixed)*6); (_obj).m[0] = (_obj).m[4] = FIX_ONE; } 376 /*!\brief matrix copy 377 \hideinitializer 378 379 Copies the matrix _from to the matrix _obj 380 */ 381 #define gf_mx2d_copy(_obj, from) memcpy((_obj).m, (from).m, sizeof(Fixed)*6) 382 /*!\brief matrix identity testing 383 \hideinitializer 384 385 This macro evaluates to 1 if the matrix _obj is the identity matrix, 0 otherwise 386 */ 387 #define gf_mx2d_is_identity(_obj) ((!(_obj).m[1] && !(_obj).m[2] && !(_obj).m[3] && !(_obj).m[5] && ((_obj).m[0]==FIX_ONE) && ((_obj).m[4]==FIX_ONE)) ? 1 : 0) 388 389 /*!\brief 2D matrix multiplication 390 391 Multiplies two 2D matrices from*_this 392 \param _this matrix being transformed. Once the function is called, _this contains the result matrix 393 \param from transformation matrix to add 394 */ 395 void gf_mx2d_add_matrix(GF_Matrix2D *_this, GF_Matrix2D *from); 396 397 /*!\brief 2D matrix pre-multiplication 398 399 Multiplies two 2D matrices _this*from 400 \param _this matrix being transformed. Once the function is called, _this contains the result matrix 401 \param from transformation matrix to add 402 */ 403 void gf_mx2d_pre_multiply(GF_Matrix2D *_this, GF_Matrix2D *from); 404 405 /*!\brief matrix translating 406 407 Translates a 2D matrix 408 \param _this matrix being transformed. Once the function is called, _this contains the result matrix 409 \param cx horizontal translation 410 \param cy vertical translation 411 */ 412 void gf_mx2d_add_translation(GF_Matrix2D *_this, Fixed cx, Fixed cy); 413 /*!\brief matrix rotating 414 415 Rotates a 2D matrix 416 \param _this matrix being transformed. Once the function is called, _this contains the result matrix 417 \param cx horizontal rotation center coordinate 418 \param cy vertical rotation center coordinate 419 \param angle rotation angle in radians 420 */ 421 void gf_mx2d_add_rotation(GF_Matrix2D *_this, Fixed cx, Fixed cy, Fixed angle); 422 /*!\brief matrix scaling 423 424 Scales a 2D matrix 425 \param _this matrix being transformed. Once the function is called, _this contains the result matrix 426 \param scale_x horizontal scaling factor 427 \param scale_y vertical scaling factor 428 */ 429 void gf_mx2d_add_scale(GF_Matrix2D *_this, Fixed scale_x, Fixed scale_y); 430 /*!\brief matrix uncentered scaling 431 432 Scales a 2D matrix with a non-centered scale 433 \param _this matrix being transformed. Once the function is called, _this contains the result matrix 434 \param scale_x horizontal scaling factor 435 \param scale_y vertical scaling factor 436 \param cx horizontal scaling center coordinate 437 \param cy vertical scaling center coordinate 438 \param angle scale orienttion angle in radians 439 */ 440 void gf_mx2d_add_scale_at(GF_Matrix2D *_this, Fixed scale_x, Fixed scale_y, Fixed cx, Fixed cy, Fixed angle); 441 /*!\brief matrix skewing 442 443 Skews a 2D matrix 444 \param _this matrix being transformed. Once the function is called, _this contains the result matrix 445 \param skew_x horizontal skew factor 446 \param skew_y vertical skew factor 447 */ 448 void gf_mx2d_add_skew(GF_Matrix2D *_this, Fixed skew_x, Fixed skew_y); 449 /*!\brief matrix horizontal skewing 450 451 Skews a 2D matrix horizontally by a given angle 452 \param _this matrix being transformed. Once the function is called, _this contains the result matrix 453 \param angle horizontal skew angle in radians 454 */ 455 void gf_mx2d_add_skew_x(GF_Matrix2D *_this, Fixed angle); 456 /*!\brief matrix vertical skewing 457 458 Skews a 2D matrix vertically by a given angle 459 \param _this matrix being transformed. Once the function is called, _this contains the result matrix 460 \param angle vertical skew angle in radians 461 */ 462 void gf_mx2d_add_skew_y(GF_Matrix2D *_this, Fixed angle); 463 /*!\brief matrix inversing 464 465 Inverses a 2D matrix 466 \param _this matrix being transformed. Once the function is called, _this contains the result matrix 467 */ 468 void gf_mx2d_inverse(GF_Matrix2D *_this); 469 /*!\brief matrix coordinate transformation 470 471 Applies a 2D matrix transformation to coordinates 472 \param _this transformation matrix 473 \param x pointer to horizontal coordinate. Once the function is called, x contains the transformed horizontal coordinate 474 \param y pointer to vertical coordinate. Once the function is called, y contains the transformed vertical coordinate 475 */ 476 void gf_mx2d_apply_coords(GF_Matrix2D *_this, Fixed *x, Fixed *y); 477 /*!\brief matrix point transformation 478 479 Applies a 2D matrix transformation to a 2D point 480 \param _this transformation matrix 481 \param pt pointer to 2D point. Once the function is called, pt contains the transformed point 482 */ 483 void gf_mx2d_apply_point(GF_Matrix2D *_this, GF_Point2D *pt); 484 /*!\brief matrix rectangle transformation 485 486 Applies a 2D matrix transformation to a rectangle, giving the enclosing rectangle of the transformed one 487 \param _this transformation matrix 488 \param rc pointer to rectangle. Once the function is called, rc contains the transformed rectangle 489 */ 490 void gf_mx2d_apply_rect(GF_Matrix2D *_this, GF_Rect *rc); 491 492 /*!\brief matrix decomposition 493 494 Decomposes a 2D matrix M as M=Scale x Rotation x Translation if possible 495 \param _this transformation matrix 496 \param scale resulting scale part 497 \param rotate resulting rotation part 498 \param translate resulting translation part 499 \return 0 if matrix cannot be decomposed, 1 otherwise 500 */ 501 Bool gf_mx2d_decompose(GF_Matrix2D *_this, GF_Point2D *scale, Fixed *rotate, GF_Point2D *translate); 502 503 /*! @} */ 504 505 506 /*! 507 \addtogroup math3d_grp Math 3d 508 \ingroup math_grp 509 \brief 3D Mathematics 510 511 This section documents mathematic tools for 3D geometry operations 512 513 @{ 514 */ 515 516 /*!\brief 3D point or vector 517 518 The 3D point object is used in all the GPAC framework for both point and vector representation. 519 */ 520 typedef struct __vec3f 521 { 522 Fixed x; 523 Fixed y; 524 Fixed z; 525 } GF_Vec; 526 527 /*base vector operations are MACROs for faster access*/ 528 /*!\hideinitializer macro evaluating to 1 if vectors are equal, 0 otherwise*/ 529 #define gf_vec_equal(v1, v2) (((v1).x == (v2).x) && ((v1).y == (v2).y) && ((v1).z == (v2).z)) 530 /*!\hideinitializer macro reversing a vector v = v*/ 531 #define gf_vec_rev(v) { (v).x = -(v).x; (v).y = -(v).y; (v).z = -(v).z; } 532 /*!\hideinitializer macro performing the minus operation res = v1 - v2*/ 533 #define gf_vec_diff(res, v1, v2) { (res).x = (v1).x - (v2).x; (res).y = (v1).y - (v2).y; (res).z = (v1).z - (v2).z; } 534 /*!\hideinitializer macro performing the add operation res = v1 + v2*/ 535 #define gf_vec_add(res, v1, v2) { (res).x = (v1).x + (v2).x; (res).y = (v1).y + (v2).y; (res).z = (v1).z + (v2).z; } 536 537 /*! 538 \brief get 3D vector length 539 540 Gets the length of a 3D vector 541 \param v the target vector 542 \return length of the vector 543 */ 544 Fixed gf_vec_len(GF_Vec v); 545 546 /*! 547 \brief get 3D vector length 548 549 Gets the length of a 3D vector 550 \param v the target vector 551 \return length of the vector 552 */ 553 Fixed gf_vec_len_p(GF_Vec *v); 554 555 /*! 556 \brief get 3D vector square length 557 558 Gets the square length of a 3D vector 559 \param v the target vector 560 \return square length of the vector 561 */ 562 Fixed gf_vec_lensq(GF_Vec v); 563 564 /*! 565 \brief get 3D vector square length 566 567 Gets the square length of a 3D vector 568 \param v the target vector 569 \return square length of the vector 570 */ 571 Fixed gf_vec_lensq_p(GF_Vec *v); 572 /*! 573 \brief get 3D vector dot product 574 575 Gets the dot product of two vectors 576 \param v1 first vector 577 \param v2 second vector 578 \return dot product of the vectors 579 */ 580 Fixed gf_vec_dot(GF_Vec v1, GF_Vec v2); 581 /*! 582 \brief get 3D vector dot product 583 584 Gets the dot product of two vectors 585 \param v1 first vector 586 \param v2 second vector 587 \return dot product of the vectors 588 */ 589 Fixed gf_vec_dot_p(GF_Vec *v1, GF_Vec *v2); 590 /*! 591 \brief vector normalization 592 593 Normalize the vector, eg make its length equal to \ref FIX_ONE 594 \param v vector to normalize 595 */ 596 void gf_vec_norm(GF_Vec *v); 597 /*! 598 \brief vector scaling 599 600 Scales a vector by a given amount 601 \param v vector to scale 602 \param f scale factor 603 \return scaled vector 604 */ 605 GF_Vec gf_vec_scale(GF_Vec v, Fixed f); 606 /*! 607 \brief vector scaling 608 609 Scales a vector by a given amount 610 \param v vector to scale 611 \param f scale factor 612 \return scaled vector 613 */ 614 GF_Vec gf_vec_scale_p(GF_Vec *v, Fixed f); 615 /*! 616 \brief vector cross product 617 618 Gets the cross product of two vectors 619 \param v1 first vector 620 \param v2 second vector 621 \return cross-product vector 622 */ 623 GF_Vec gf_vec_cross(GF_Vec v1, GF_Vec v2); 624 /*! 625 \brief vector cross product 626 627 Gets the cross product of two vectors 628 \param v1 first vector 629 \param v2 second vector 630 \return cross-product vector 631 */ 632 GF_Vec gf_vec_cross_p(GF_Vec *v1, GF_Vec *v2); 633 634 /*!\brief 4D vector 635 636 The 4D vector object is used in all the GPAC framework for 4 dimension vectors, VRML Rotations and quaternions representation. 637 */ 638 typedef struct __vec4f 639 { 640 Fixed x; 641 Fixed y; 642 Fixed z; 643 Fixed q; 644 } GF_Vec4; 645 646 647 /*!\brief 3D matrix 648 649 The 3D matrix object used in GPAC. The matrix is oriented like OpenGL matrices (column-major ordering), with 650 the translation part at the end of the coefficients list. 651 \note Unless specified otherwise, the matrix object is always expected to represent an affine transformation. 652 */ 653 typedef struct __matrix 654 { 655 Fixed m[16]; 656 } GF_Matrix; 657 658 659 /*!\hideinitializer gets the len of a quaternion*/ 660 #define gf_quat_len(v) gf_sqrt(gf_mulfix((v).q,(v).q) + gf_mulfix((v).x,(v).x) + gf_mulfix((v).y,(v).y) + gf_mulfix((v).z,(v).z)) 661 /*!\hideinitializer normalizes a quaternion*/ 662 #define gf_quat_norm(v) { \ 663 Fixed __mag = gf_quat_len(v); \ 664 (v).x = gf_divfix((v).x, __mag); (v).y = gf_divfix((v).y, __mag); (v).z = gf_divfix((v).z, __mag); (v).q = gf_divfix((v).q, __mag); \ 665 } \ 666 667 /*!\brief quaternion to rotation 668 669 Transforms a quaternion to a Rotation, expressed as a 4 dimension vector with x,y,z for axis and q for rotation angle 670 \param quat the quaternion to transform 671 \return the rotation value 672 */ 673 GF_Vec4 gf_quat_to_rotation(GF_Vec4 *quat); 674 /*!\brief quaternion from rotation 675 676 Transforms a Rotation to a quaternion 677 \param rot the rotation to transform 678 \return the quaternion value 679 */ 680 GF_Vec4 gf_quat_from_rotation(GF_Vec4 rot); 681 /*! Inverses a quaternion 682 \param quat the quaternion to inverse 683 \return the inverted quaternion 684 */ 685 GF_Vec4 gf_quat_get_inv(GF_Vec4 *quat); 686 /*!\brief quaternion multiplication 687 688 Multiplies two quaternions 689 \param q1 the first quaternion 690 \param q2 the second quaternion 691 \return the resulting quaternion 692 */ 693 GF_Vec4 gf_quat_multiply(GF_Vec4 *q1, GF_Vec4 *q2); 694 /*!\brief quaternion vector rotating 695 696 Rotates a vector with a quaternion 697 \param quat the quaternion modelizing the rotation 698 \param vec the vector to rotate 699 \return the resulting vector 700 */ 701 GF_Vec gf_quat_rotate(GF_Vec4 *quat, GF_Vec *vec); 702 /*!\brief quaternion from axis and cos 703 704 Constructs a quaternion from an axis and a cosinus value (shortcut to \ref gf_quat_from_rotation) 705 \param axis the rotation axis 706 \param cos_a the rotation cosinus value 707 \return the resulting quaternion 708 */ 709 GF_Vec4 gf_quat_from_axis_cos(GF_Vec axis, Fixed cos_a); 710 /*!\brief quaternion interpolation 711 712 Interpolates two quaternions using spherical linear interpolation 713 \param q1 the first quaternion 714 \param q2 the second quaternion 715 \param frac the fraction of the interpolation, between 0 and \ref FIX_ONE 716 \return the interpolated quaternion 717 */ 718 GF_Vec4 gf_quat_slerp(GF_Vec4 q1, GF_Vec4 q2, Fixed frac); 719 720 /*!\brief 3D Bounding Box 721 722 The 3D Bounding Box is a 3D Axis-Aligned Bounding Box used to in various tools of the GPAC framework for bounds 723 estimation of a 3D object. It features an axis-aligned box and a sphere bounding volume for fast intersection tests. 724 */ 725 typedef struct 726 { 727 /*!minimum x, y, and z of the object*/ 728 GF_Vec min_edge; 729 /*!maximum x, y, and z of the object*/ 730 GF_Vec max_edge; 731 732 /*!center of the bounding box.\note this is computed from min_edge and max_edge*/ 733 GF_Vec center; 734 /*!radius of the bounding sphere for this box.\note this is computed from min_edge and max_edge*/ 735 Fixed radius; 736 /*!the bbox center and radius are valid*/ 737 Bool is_set; 738 } GF_BBox; 739 /*! updates information of the bounding box based on the edge information 740 \param b the target bounding box 741 */ 742 void gf_bbox_refresh(GF_BBox *b); 743 /*!builds a bounding box from a 2D rectangle 744 \param box the bounding box to build 745 \param rc the source rectangle 746 */ 747 void gf_bbox_from_rect(GF_BBox *box, GF_Rect *rc); 748 /*!builds a rectangle from a 3D bounding box. 749 \note The z dimension is lost and no projection is performed 750 \param rc the destination rectangle 751 \param box the source bounding box 752 */ 753 void gf_rect_from_bbox(GF_Rect *rc, GF_BBox *box); 754 /*!\brief bounding box expansion 755 756 Checks if a point is inside a bounding box and updates the bounding box to include it if not the case 757 \param box the bounding box object 758 \param pt the 3D point to check 759 */ 760 void gf_bbox_grow_point(GF_BBox *box, GF_Vec pt); 761 /*!performs the union of two bounding boxes 762 \param b1 the first bounding box 763 \param b2 the bounding box to add 764 */ 765 void gf_bbox_union(GF_BBox *b1, GF_BBox *b2); 766 /*!checks if two bounding boxes are equal or not 767 \param b1 the first bounding box 768 \param b2 the second bounding box 769 \return GF_TRUE if equal 770 */ 771 Bool gf_bbox_equal(GF_BBox *b1, GF_BBox *b2); 772 /*!checks if a point is inside a bounding box or not 773 \param box the bounding box 774 \param p the point to check 775 \return GF_TRUE if point is inside 776 */ 777 Bool gf_bbox_point_inside(GF_BBox *box, GF_Vec *p); 778 /*!\brief get box vertices 779 780 Returns the 8 bounding box vertices given the minimum and maximum edge. Vertices are ordered to respect 781 "p-vertex indexes", (vertex from a box closest to plane) and so that n-vertex (vertex from a box farthest from plane) 782 is 7-p_vx_idx 783 \param bmin minimum edge of the box 784 \param bmax maximum edge of the box 785 \param vecs list of 8 3D points used to store the vertices. 786 */ 787 void gf_bbox_get_vertices(GF_Vec bmin, GF_Vec bmax, GF_Vec *vecs); 788 789 790 /*!\brief matrix initialization 791 \hideinitializer 792 793 Inits the matrix to the identity matrix 794 */ 795 #define gf_mx_init(_obj) { memset((_obj).m, 0, sizeof(Fixed)*16); (_obj).m[0] = (_obj).m[5] = (_obj).m[10] = (_obj).m[15] = FIX_ONE; } 796 797 /*! macro to check if a matrix is the identity matrix*/ 798 #define gf_mx_is_identity(_obj) ((!(_obj).m[1] && !(_obj).m[2] && !(_obj).m[3] && !(_obj).m[4] && !(_obj).m[6] && !(_obj).m[7] && !(_obj).m[8] && !(_obj).m[9] && !(_obj).m[11] && !(_obj).m[12] && !(_obj).m[13] && !(_obj).m[14] && ((_obj).m[0]==FIX_ONE) && ((_obj).m[5]==FIX_ONE)&& ((_obj).m[10]==FIX_ONE)&& ((_obj).m[15]==FIX_ONE)) ? 1 : 0) 799 800 /*!\brief matrix copy 801 \hideinitializer 802 803 Copies the matrix _from to the matrix _obj 804 */ 805 #define gf_mx_copy(_obj, from) memcpy(&(_obj), &(from), sizeof(GF_Matrix)); 806 /*!\brief matrix constructor from 2D 807 808 Initializes a 3D matrix from a 2D matrix.\note all z-related coefficients will be set to default. 809 \param mx the target matrix to initialize 810 \param mat2D the source 2D matrix 811 */ 812 void gf_mx_from_mx2d(GF_Matrix *mx, GF_Matrix2D *mat2D); 813 /*!\brief matrix equality testing 814 815 Tests if two matrices are equal or not. 816 \param mx1 the first matrix 817 \param mx2 the first matrix 818 \return GF_TRUE if matrices are same, GF_FALSE otherwise 819 */ 820 Bool gf_mx_equal(GF_Matrix *mx1, GF_Matrix *mx2); 821 /*!\brief matrix translation 822 823 Translates a matrix 824 \param mx the matrix being transformed. Once the function is called, contains the result matrix 825 \param tx horizontal translation 826 \param ty vertical translation 827 \param tz depth translation 828 */ 829 void gf_mx_add_translation(GF_Matrix *mx, Fixed tx, Fixed ty, Fixed tz); 830 /*!\brief matrix scaling 831 832 Scales a matrix 833 \param mx the matrix being transformed. Once the function is called, contains the result matrix 834 \param sx horizontal translation scaling 835 \param sy vertical translation scaling 836 \param sz depth translation scaling 837 */ 838 void gf_mx_add_scale(GF_Matrix *mx, Fixed sx, Fixed sy, Fixed sz); 839 /*!\brief matrix rotating 840 841 Rotates a matrix 842 \param mx the matrix being transformed. Once the function is called, contains the result matrix 843 \param angle rotation angle in radians 844 \param x horizontal coordinate of rotation axis 845 \param y vertical coordinate of rotation axis 846 \param z depth coordinate of rotation axis 847 */ 848 void gf_mx_add_rotation(GF_Matrix *mx, Fixed angle, Fixed x, Fixed y, Fixed z); 849 /*!\brief matrices multiplication 850 851 Multiplies a matrix with another one mx = mx*mul 852 \param mx the matrix being transformed. Once the function is called, contains the result matrix 853 \param mul the matrix to add 854 */ 855 void gf_mx_add_matrix(GF_Matrix *mx, GF_Matrix *mul); 856 /*!\brief 2D matrix multiplication 857 858 Adds a 2D affine matrix to a matrix 859 \param mx the matrix 860 \param mat2D the matrix to premultiply 861 */ 862 void gf_mx_add_matrix_2d(GF_Matrix *mx, GF_Matrix2D *mat2D); 863 864 /*!\brief affine matrix inversion 865 866 Inverses an affine matrix.\warning Results are undefined if the matrix is not an affine one 867 \param mx the matrix to inverse 868 */ 869 void gf_mx_inverse(GF_Matrix *mx); 870 /*!\brief transpose 4x4 matrix 871 872 Transposes a 4x4 matrix 873 \param mx the matrix to transpose 874 */ 875 void gf_mx_transpose(GF_Matrix *mx); 876 /*!\brief matrix point transformation 877 878 Applies a 3D matrix transformation to a 3D point 879 \param mx transformation matrix 880 \param pt pointer to 3D point. Once the function is called, pt contains the transformed point 881 */ 882 void gf_mx_apply_vec(GF_Matrix *mx, GF_Vec *pt); 883 /*!\brief matrix rectangle transformation 884 885 Applies a 3D matrix transformation to a rectangle, giving the enclosing rectangle of the transformed one.\note all depth information are discarded. 886 \param _this transformation matrix 887 \param rc pointer to rectangle. Once the function is called, rc contains the transformed rectangle 888 */ 889 void gf_mx_apply_rect(GF_Matrix *_this, GF_Rect *rc); 890 /*!\brief ortho matrix construction 891 892 Creates an orthogonal projection matrix. This assume the NDC Z lies in [-1,1] 893 \param mx matrix to initialize 894 \param left min horizontal coordinate of viewport 895 \param right max horizontal coordinate of viewport 896 \param bottom min vertical coordinate of viewport 897 \param top max vertical coordinate of viewport 898 \param z_near min depth coordinate of viewport 899 \param z_far max depth coordinate of viewport 900 */ 901 void gf_mx_ortho(GF_Matrix *mx, Fixed left, Fixed right, Fixed bottom, Fixed top, Fixed z_near, Fixed z_far); 902 903 /*!\brief ortho matrix with reverse Z construction 904 905 Creates an orthogonal projection matrix with reverse Z. This assume the NDC Z lies in [0,1], not [-1,1] 906 \param mx matrix to initialize 907 \param left min horizontal coordinate of viewport 908 \param right max horizontal coordinate of viewport 909 \param bottom min vertical coordinate of viewport 910 \param top max vertical coordinate of viewport 911 \param z_near min depth coordinate of viewport 912 \param z_far max depth coordinate of viewport 913 */ 914 void gf_mx_ortho_reverse_z(GF_Matrix *mx, Fixed left, Fixed right, Fixed bottom, Fixed top, Fixed z_near, Fixed z_far); 915 916 /*!\brief perspective matrix construction 917 918 Creates a perspective projection matrix. This assume the NDC Z lies in [-1,1] 919 \param mx matrix to initialize 920 \param fov camera field of view angle in radian 921 \param aspect_ratio viewport aspect ratio 922 \param z_near min depth coordinate of viewport 923 \param z_far max depth coordinate of viewport 924 */ 925 void gf_mx_perspective(GF_Matrix *mx, Fixed fov, Fixed aspect_ratio, Fixed z_near, Fixed z_far); 926 927 /*!\brief perspective matrix with reverse Z construction 928 929 Creates a perspective projection matrix with reverse Z. This assume the NDC Z lies in [0,1] 930 \param mx matrix to initialize 931 \param fov camera field of view angle in radian 932 \param aspect_ratio viewport aspect ratio 933 \param z_near min depth coordinate of viewport 934 \param z_far max depth coordinate of viewport 935 */ 936 void gf_mx_perspective_reverse_z(GF_Matrix *mx, Fixed fov, Fixed aspect_ratio, Fixed z_near, Fixed z_far); 937 938 /*!\brief creates look matrix 939 940 Creates a transformation matrix looking at a given direction from a given point (camera matrix). 941 \param mx matrix to initialize 942 \param position position 943 \param target look direction 944 \param up_vector vector describing the up direction 945 */ 946 void gf_mx_lookat(GF_Matrix *mx, GF_Vec position, GF_Vec target, GF_Vec up_vector); 947 /*!\brief matrix box transformation 948 949 Applies a 3D matrix transformation to a bounding box, giving the enclosing box of the transformed one 950 \param mx transformation matrix 951 \param b pointer to bounding box. Once the function is called, contains the transformed bounding box 952 */ 953 void gf_mx_apply_bbox(GF_Matrix *mx, GF_BBox *b); 954 /*!\brief matrix box sphere transformation 955 956 Applies a 3D matrix transformation to a bounding box, computing only the enclosing sphere of the transformed one. 957 \param mx transformation matrix 958 \param box pointer to bounding box. Once the function is called, contains the transformed bounding sphere 959 */ 960 void gf_mx_apply_bbox_sphere(GF_Matrix *mx, GF_BBox *box); 961 /*!\brief non-affine matrix multiplication 962 963 Multiplies two non-affine matrices mx = mx*mul 964 \param mat the target matrix 965 \param mul the matrix we multiply with 966 */ 967 void gf_mx_add_matrix_4x4(GF_Matrix *mat, GF_Matrix *mul); 968 /*!\brief non-affine matrix inversion 969 970 Inverses a non-affine matrices 971 \param mx the target matrix 972 \return 1 if inversion was done, 0 if inversion not possible. 973 */ 974 Bool gf_mx_inverse_4x4(GF_Matrix *mx); 975 /*!\brief matrix 4D vector transformation 976 977 Applies a 3D non-affine matrix transformation to a 4 dimension vector 978 \param mx transformation matrix 979 \param vec pointer to the vector. Once the function is called, contains the transformed vector 980 */ 981 void gf_mx_apply_vec_4x4(GF_Matrix *mx, GF_Vec4 *vec); 982 983 /*!\brief matrix yaw pitch roll decomposition 984 985 Extracts yaw, pitch and roll info from a matrix 986 \param mx the matrix to decompose 987 \param yaw the extracted yaw angle in radians 988 \param pitch the extracted pitch angle in radians 989 \param roll the extracted roll angle in radians 990 */ 991 void gf_mx_get_yaw_pitch_roll(GF_Matrix *mx, Fixed *yaw, Fixed *pitch, Fixed *roll); 992 993 /*!\brief matrix decomposition 994 995 Decomposes a matrix into translation, scale, shear and rotate 996 \param mx the matrix to decompose 997 \param translate the decomposed translation part 998 \param scale the decomposed scaling part 999 \param rotate the decomposed rotation part, expressed as a Rotataion (axis + angle) 1000 \param shear the decomposed shear part 1001 */ 1002 void gf_mx_decompose(GF_Matrix *mx, GF_Vec *translate, GF_Vec *scale, GF_Vec4 *rotate, GF_Vec *shear); 1003 /*!\brief matrix vector rotation 1004 1005 Rotates a vector with a given matrix, ignoring any translation. 1006 \param mx transformation matrix 1007 \param pt pointer to 3D vector. Once the function is called, pt contains the transformed vector 1008 */ 1009 void gf_mx_rotate_vector(GF_Matrix *mx, GF_Vec *pt); 1010 /*!\brief matrix initialization from vectors 1011 1012 Inits a matrix to rotate the local axis in the given vectors 1013 \param mx matrix to initialize 1014 \param x_axis target normalized X axis 1015 \param y_axis target normalized Y axis 1016 \param z_axis target normalized Z axis 1017 */ 1018 void gf_mx_rotation_matrix_from_vectors(GF_Matrix *mx, GF_Vec x_axis, GF_Vec y_axis, GF_Vec z_axis); 1019 /*!\brief matrix to 2D matrix 1020 1021 Inits a 2D matrix by removing all depth info from a 3D matrix 1022 \param mx2d 2D matrix to initialize 1023 \param mx 3D matrix to use 1024 */ 1025 void gf_mx2d_from_mx(GF_Matrix2D *mx2d, GF_Matrix *mx); 1026 1027 /*!\brief Plane object*/ 1028 typedef struct 1029 { 1030 /*!normal vector to the plane*/ 1031 GF_Vec normal; 1032 /*!distance from origin of the plane*/ 1033 Fixed d; 1034 } GF_Plane; 1035 /*!\brief matrix plane transformation 1036 1037 Transorms a plane by a given matrix 1038 \param mx the matrix to use 1039 \param plane pointer to 3D plane. Once the function is called, plane contains the transformed plane 1040 */ 1041 void gf_mx_apply_plane(GF_Matrix *mx, GF_Plane *plane); 1042 /*!\brief point to plane distance 1043 1044 Gets the distance between a point and a plne 1045 \param plane the plane to use 1046 \param p pointer to ^point to check 1047 \return the distance between the place and the point 1048 */ 1049 Fixed gf_plane_get_distance(GF_Plane *plane, GF_Vec *p); 1050 /*!\brief closest point on a line 1051 1052 Gets the closest point on a line from a given point in space 1053 \param line_pt a point of the line to test 1054 \param line_vec the normalized direction vector of the line 1055 \param pt the point to check 1056 \return the closest point on the line to the desired point 1057 */ 1058 GF_Vec gf_closest_point_to_line(GF_Vec line_pt, GF_Vec line_vec, GF_Vec pt); 1059 /*!\brief box p-vertex index 1060 1061 Gets the p-vertex index for a given plane. The p-vertex index is the index of the closest vertex of a bounding box to the plane. The vertices of a box are always 1062 *ordered in GPAC? cf \ref gf_bbox_get_vertices 1063 \param p the plane to check 1064 \return the p-vertex index value, ranging from 0 to 7 1065 */ 1066 u32 gf_plane_get_p_vertex_idx(GF_Plane *p); 1067 /*!\brief plane line intersection 1068 1069 Checks for the intersection of a plane and a line 1070 \param plane plane to test 1071 \param linepoint a point on the line to test 1072 \param linevec normalized direction vector of the line to test 1073 \param outPoint optional pointer to retrieve the intersection point, NULL otherwise 1074 \return 1 if line and plane intersect, 0 otherwise 1075 */ 1076 Bool gf_plane_intersect_line(GF_Plane *plane, GF_Vec *linepoint, GF_Vec *linevec, GF_Vec *outPoint); 1077 1078 /*!Classification types for box/plane position used in \ref gf_bbox_plane_relation*/ 1079 enum 1080 { 1081 /*!box is in front of the plane*/ 1082 GF_BBOX_FRONT, 1083 /*!box intersects the plane*/ 1084 GF_BBOX_INTER, 1085 /*!box is back of the plane*/ 1086 GF_BBOX_BACK 1087 }; 1088 /*!\brief box-plane relation 1089 1090 Gets the spatial relation between a box and a plane 1091 \param box the box to check 1092 \param p the plane to check 1093 \return the relation type 1094 */ 1095 u32 gf_bbox_plane_relation(GF_BBox *box, GF_Plane *p); 1096 1097 /*!\brief 3D Ray 1098 1099 The 3D ray object is used in GPAC for all collision and mouse interaction tests 1100 */ 1101 typedef struct 1102 { 1103 /*!origin point of the ray*/ 1104 GF_Vec orig; 1105 /*!normalized direction vector of the ray*/ 1106 GF_Vec dir; 1107 } GF_Ray; 1108 1109 /*!\brief ray constructor 1110 1111 Constructs a ray object 1112 \param start starting point of the ray 1113 \param end end point of the ray, or any point on the ray 1114 \return the ray object 1115 */ 1116 GF_Ray gf_ray(GF_Vec start, GF_Vec end); 1117 /*!\brief matrix ray transformation 1118 1119 Transforms a ray by a given transformation matrix 1120 \param mx the matrix to use 1121 \param r pointer to the ray. Once the function is called, contains the transformed ray 1122 */ 1123 void gf_mx_apply_ray(GF_Matrix *mx, GF_Ray *r); 1124 /*!\brief ray box intersection test 1125 1126 Checks if a ray intersects a box or not 1127 \param ray the ray to check 1128 \param min_edge the minimum edge of the box to check 1129 \param max_edge the maximum edge of the box to check 1130 \param out_point optional location of a 3D point to store the intersection, NULL otherwise. 1131 \return retuns 1 if the ray intersects the box, 0 otherwise 1132 */ 1133 Bool gf_ray_hit_box(GF_Ray *ray, GF_Vec min_edge, GF_Vec max_edge, GF_Vec *out_point); 1134 /*!\brief ray sphere intersection test 1135 1136 Checks if a ray intersects a box or not 1137 \param ray the ray to check 1138 \param center the center of the sphere to check. If NULL, the origin (0,0,0)is used 1139 \param radius the radius of the sphere to check 1140 \param out_point optional location of a 3D point to store the intersection, NULL otherwise 1141 \return retuns 1 if the ray intersects the sphere, 0 otherwise 1142 */ 1143 Bool gf_ray_hit_sphere(GF_Ray *ray, GF_Vec *center, Fixed radius, GF_Vec *out_point); 1144 /*!\brief ray triangle intersection test 1145 1146 Checks if a ray intersects a triangle or not 1147 \param ray the ray to check 1148 \param v0 first vertex of the triangle 1149 \param v1 second vertex of the triangle 1150 \param v2 third vertex of the triangle 1151 \param dist optional location of a fixed number to store the intersection distance from ray origin if any, NULL otherwise 1152 \return retuns 1 if the ray intersects the triangle, 0 otherwise 1153 */ 1154 Bool gf_ray_hit_triangle(GF_Ray *ray, GF_Vec *v0, GF_Vec *v1, GF_Vec *v2, Fixed *dist); 1155 1156 /*! @} */ 1157 1158 /*! @} */ 1159 1160 #ifdef __cplusplus 1161 } 1162 #endif 1163 1164 1165 #endif /*_GF_MATH_H_*/ 1166 1167