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