/* * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre * Copyright (c) Telecom ParisTech 2000-2012 * All rights reserved * * This file is part of GPAC / common tools sub-project * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _GF_MATH_H_ #define _GF_MATH_H_ #ifdef __cplusplus extern "C" { #endif /*! * \file <gpac/maths.h> * \brief Mathematics and Trigonometric. */ #include <gpac/setup.h> #include <math.h> /*! *\addtogroup math_grp Math *\ingroup utils_grp *\brief Mathematics and Trigonometric * *This section documents the math and trigo functions used in the GPAC framework. GPAC can be compiled with *fixed-point support, representing float values on a 16.16 signed integer, which implies a developer *must take care of float computations when using GPAC.\n *A developper should not need to know in which mode the framework has been compiled as long as he uses *the math functions of GPAC which work in both float and fixed-point mode.\n *Using fixed-point version is decided at compilation time and cannot be changed. The feature is signaled *through the following macros: *- GPAC_FIXED_POINT: when defined, GPAC has been compiled in fixed-point mode *- GPAC_NO_FIXED_POINT: when defined, GPAC has been compiled in regular (float) mode * @{ */ /***************************************************************************************** FIXED-POINT SUPPORT - HARDCODED FOR 16.16 representation the software rasterizer also use a 16.16 representation even in non-fixed version ******************************************************************************************/ #ifdef GPAC_FIXED_POINT /*! *Fixed 16.16 number *\hideinitializer \note This documentation has been generated for a fixed-point version of the GPAC framework. */ typedef s32 Fixed; #define FIX_ONE 0x10000L #define INT2FIX(v) ((Fixed)( ((s32) (v) ) << 16)) #define FLT2FIX(v) ((Fixed) ((v) * FIX_ONE)) #define FIX2INT(v) ((s32)(((v)+((FIX_ONE>>1)))>>16)) #define FIX2FLT(v) ((Float)( ((Float)(v)) / ((Float) FIX_ONE))) #define FIX_EPSILON 2 #define FIX_MAX 0x7FFFFFFF #define FIX_MIN -FIX_MAX #define GF_PI2 102944 #define GF_PI 205887 #define GF_2PI 411774 /*!\return 1/a, expressed as fixed number*/ Fixed gf_invfix(Fixed a); /*!\return a*b, expressed as fixed number*/ Fixed gf_mulfix(Fixed a, Fixed b); /*!\return a*b/c, expressed as fixed number*/ Fixed gf_muldiv(Fixed a, Fixed b, Fixed c); /*!\return a/b, expressed as fixed number*/ Fixed gf_divfix(Fixed a, Fixed b); /*!\return sqrt(a), expressed as fixed number*/ Fixed gf_sqrt(Fixed x); /*!\return ceil(a), expressed as fixed number*/ Fixed gf_ceil(Fixed a); /*!\return floor(a), expressed as fixed number*/ Fixed gf_floor(Fixed a); /*!\return cos(a), expressed as fixed number*/ Fixed gf_cos(Fixed angle); /*!\return sin(a), expressed as fixed number*/ Fixed gf_sin(Fixed angle); /*!\return tan(a), expressed as fixed number*/ Fixed gf_tan(Fixed angle); /*!\return acos(a), expressed as fixed number*/ Fixed gf_acos(Fixed angle); /*!\return asin(a), expressed as fixed number*/ Fixed gf_asin(Fixed angle); /*!\return atan(y, x), expressed as fixed number*/ Fixed gf_atan2(Fixed y, Fixed x); #else /*!Fixed is 32bit float number \note This documentation has been generated for a float version of the GPAC framework. */ typedef Float Fixed; #define FIX_ONE 1.0f #define INT2FIX(v) ((Float) (v)) #define FLT2FIX(v) ((Float) (v)) #define FIX2INT(v) ((s32)(v)) #define FIX2FLT(v) ((Float) (v)) #define FIX_EPSILON GF_EPSILON_FLOAT #define FIX_MAX GF_MAX_FLOAT #define FIX_MIN -GF_MAX_FLOAT #define GF_PI2 1.5707963267949f #define GF_PI 3.1415926535898f #define GF_2PI 6.2831853071796f /*!\hideinitializer 1/_a, expressed as fixed number*/ #define gf_invfix(_a) (FIX_ONE/(_a)) /*!\hideinitializer _a*_b, expressed as fixed number*/ #define gf_mulfix(_a, _b) ((_a)*(_b)) /*!\hideinitializer _a*_b/_c, expressed as fixed number*/ #define gf_muldiv(_a, _b, _c) (((_c != 0)) ? (_a)*(_b)/(_c) : GF_MAX_FLOAT) /*!\hideinitializer _a/_b, expressed as fixed number*/ #define gf_divfix(_a, _b) (((_b != 0)) ? (_a)/(_b) : GF_MAX_FLOAT) /*!\hideinitializer sqrt(_a), expressed as fixed number*/ #define gf_sqrt(_a) ((Float) sqrt(_a)) /*!\hideinitializer ceil(_a), expressed as fixed number*/ #define gf_ceil(_a) ((Float) ceil(_a)) /*!\hideinitializer floor(_a), expressed as fixed number*/ #define gf_floor(_a) ((Float) floor(_a)) /*!\hideinitializer cos(_a), expressed as fixed number*/ #define gf_cos(_a) ((Float) cos(_a)) /*!\hideinitializer sin(_a), expressed as fixed number*/ #define gf_sin(_a) ((Float) sin(_a)) /*!\hideinitializer tan(_a), expressed as fixed number*/ #define gf_tan(_a) ((Float) tan(_a)) /*!\hideinitializer atan2(_y,_x), expressed as fixed number*/ #define gf_atan2(_y, _x) ((Float) atan2(_y, _x)) /*!\hideinitializer acos(_a), expressed as fixed number*/ #define gf_acos(_a) ((Float) acos(_a)) /*!\hideinitializer asin(_a), expressed as fixed number*/ #define gf_asin(_a) ((Float) asin(_a)) #endif /*!\def FIX_ONE \hideinitializer Fixed unit value */ /*!\def INT2FIX(v) \hideinitializer Conversion from integer to fixed */ /*!\def FLT2FIX(v) \hideinitializer Conversion from float to fixed */ /*!\def FIX2INT(v) \hideinitializer Conversion from fixed to integer */ /*!\def FIX2FLT(v) \hideinitializer Conversion from fixed to float */ /*!\def FIX_EPSILON \hideinitializer Epsilon Fixed (positive value closest to 0) */ /*!\def FIX_MAX \hideinitializer Maximum Fixed (maximum representable fixed value) */ /*!\def FIX_MIN \hideinitializer Minimum Fixed (minimum representable fixed value) */ /*!\def GF_PI2 \hideinitializer PI/2 expressed as Fixed */ /*!\def GF_PI \hideinitializer PI expressed as Fixed */ /*!\def GF_2PI \hideinitializer 2*PI expressed as Fixed */ Fixed gf_angle_diff(Fixed a, Fixed b); /*! * \brief Field bit-size * * Gets the number of bits needed to represent the value. * \param MaxVal Maximum value to be represented. * \return number of bits required to represent the value. */ u32 gf_get_bit_size(u32 MaxVal); /*! * \brief Get power of 2 * * Gets the closest power of 2 greater or equal to the value. * \param val value to be used. * \return requested power of 2. */ u32 gf_get_next_pow2(u32 val); /*! *\addtogroup math2d_grp Math 2d *\ingroup math_grp *\brief 2D Mathematics * *This section documents mathematic tools for 2D geometry and color matrices operations * @{ */ /*!\brief 2D point * *The 2D point object is used in all the GPAC framework for both point and vector representation. */ typedef struct __vec2f { Fixed x; Fixed y; } GF_Point2D; /*! *\brief get 2D vector length * *Gets the length of a 2D vector *\return length of the vector */ Fixed gf_v2d_len(GF_Point2D *vec); /*! *\brief get distance between 2 points * *Gets the distance between the 2 points *\return distance */ Fixed gf_v2d_distance(GF_Point2D *a, GF_Point2D *b); /*! *\brief 2D vector from polar coordinates * *Constructs a 2D vector from its polar coordinates *\param length the length of the vector *\param angle the angle of the vector in radians *\return the 2D vector */ GF_Point2D gf_v2d_from_polar(Fixed length, Fixed angle); /*!\brief rectangle 2D * *The 2D rectangle used in the GPAC project. */ typedef struct { /*!the left coordinate of the rectangle*/ Fixed x; /*!the top coordinate of the rectangle, regardless of the canvas orientation. In other words, y is always the greatest coordinate value, even if the rectangle is presented bottom-up. This insures proper rectangles testing*/ Fixed y; /*!the width of the rectangle. Width must be greater than or equal to 0*/ Fixed width; /*!the height of the rectangle. Height must be greater than or equal to 0*/ Fixed height; } GF_Rect; /*! \brief rectangle union * *Gets the union of two rectangles. *\param rc1 first rectangle of the union. Upon return, this rectangle will contain the result of the union *\param rc2 second rectangle of the union */ void gf_rect_union(GF_Rect *rc1, GF_Rect *rc2); /*! \brief centers a rectangle * *Builds a rectangle centered on the origin *\param w width of the rectangle *\param h height of the rectangle *\return centered rectangle object */ GF_Rect gf_rect_center(Fixed w, Fixed h); /*! \brief rectangle overlap test * *Tests if two rectangles overlap. *\param rc1 first rectangle to test *\param rc2 second rectangle to test *\return 1 if rectangles overlap, 0 otherwise */ Bool gf_rect_overlaps(GF_Rect rc1, GF_Rect rc2); /*! \brief rectangle identity test * *Tests if two rectangles are identical. *\param rc1 first rectangle to test *\param rc2 second rectangle to test *\return 1 if rectangles are identical, 0 otherwise */ Bool gf_rect_equal(GF_Rect rc1, GF_Rect rc2); /*! *\brief pixel-aligned rectangle * *Pixel-aligned rectangle used in the GPAC framework. This is usually needed for 2D drawing algorithms. */ typedef struct { /*!the left coordinate of the rectangle*/ s32 x; /*!the top coordinate of the rectangle, regardless of the canvas orientation. In other words, y is always the greatest coordinate value, even if the rectangle is presented bottom-up. This insures proper rectangles operations*/ s32 y; /*!the width of the rectangle. Width must be greater than or equal to 0*/ s32 width; /*!the height of the rectangle. Height must be greater than or equal to 0*/ s32 height; } GF_IRect; /*! *\brief gets the pixelized version of a rectangle * *Returns the smallest pixel-aligned rectangle completely containing a rectangle *\param r the rectangle to transform *\return the pixel-aligned transformed rectangle */ GF_IRect gf_rect_pixelize(GF_Rect *r); /*! *\brief 2D matrix * *The 2D affine matrix object usied in GPAC. The transformation of P(x,y) in P'(X, Y) is: \code X = m[0]*x + m[1]*y + m[2]; Y = m[3]*x + m[4]*y + m[5]; \endcode */ typedef struct { Fixed m[6]; } GF_Matrix2D; /*!\brief matrix initialization *\hideinitializer * *Inits the matrix to the identity matrix */ #define gf_mx2d_init(_obj) { memset((_obj).m, 0, sizeof(Fixed)*6); (_obj).m[0] = (_obj).m[4] = FIX_ONE; } /*!\brief matrix copy *\hideinitializer * *Copies the matrix _from to the matrix _obj */ #define gf_mx2d_copy(_obj, from) memcpy((_obj).m, (from).m, sizeof(Fixed)*6) /*!\brief matrix identity testing *\hideinitializer * *This macro evaluates to 1 if the matrix _obj is the identity matrix, 0 otherwise */ #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) /*!\brief 2D matrix multiplication * *Multiplies two 2D matrices from*_this *\param _this matrix being transformed. Once the function is called, _this contains the result matrix *\param from transformation matrix to add */ void gf_mx2d_add_matrix(GF_Matrix2D *_this, GF_Matrix2D *from); /*!\brief 2D matrix pre-multiplication * *Multiplies two 2D matrices _this*from *\param _this matrix being transformed. Once the function is called, _this contains the result matrix *\param from transformation matrix to add */ void gf_mx2d_pre_multiply(GF_Matrix2D *_this, GF_Matrix2D *from); /*!\brief matrix translating * *Translates a 2D matrix *\param _this matrix being transformed. Once the function is called, _this contains the result matrix *\param cx horizontal translation *\param cy vertical translation */ void gf_mx2d_add_translation(GF_Matrix2D *_this, Fixed cx, Fixed cy); /*!\brief matrix rotating * *Rotates a 2D matrix *\param _this matrix being transformed. Once the function is called, _this contains the result matrix *\param cx horizontal rotation center coordinate *\param cy vertical rotation center coordinate *\param angle rotation angle in radians */ void gf_mx2d_add_rotation(GF_Matrix2D *_this, Fixed cx, Fixed cy, Fixed angle); /*!\brief matrix scaling * *Scales a 2D matrix *\param _this matrix being transformed. Once the function is called, _this contains the result matrix *\param scale_x horizontal scaling factor *\param scale_y vertical scaling factor */ void gf_mx2d_add_scale(GF_Matrix2D *_this, Fixed scale_x, Fixed scale_y); /*!\brief matrix uncentered scaling * *Scales a 2D matrix with a non-centered scale *\param _this matrix being transformed. Once the function is called, _this contains the result matrix *\param scale_x horizontal scaling factor *\param scale_y vertical scaling factor *\param cx horizontal scaling center coordinate *\param cy vertical scaling center coordinate *\param angle scale orienttion angle in radians */ void gf_mx2d_add_scale_at(GF_Matrix2D *_this, Fixed scale_x, Fixed scale_y, Fixed cx, Fixed cy, Fixed angle); /*!\brief matrix skewing * *Skews a 2D matrix *\param _this matrix being transformed. Once the function is called, _this contains the result matrix *\param skew_x horizontal skew factor *\param skew_y vertical skew factor */ void gf_mx2d_add_skew(GF_Matrix2D *_this, Fixed skew_x, Fixed skew_y); /*!\brief matrix horizontal skewing * *Skews a 2D matrix horizontally by a given angle *\param _this matrix being transformed. Once the function is called, _this contains the result matrix *\param angle horizontal skew angle in radians */ void gf_mx2d_add_skew_x(GF_Matrix2D *_this, Fixed angle); /*!\brief matrix vertical skewing * *Skews a 2D matrix vertically by a given angle *\param _this matrix being transformed. Once the function is called, _this contains the result matrix *\param angle vertical skew angle in radians */ void gf_mx2d_add_skew_y(GF_Matrix2D *_this, Fixed angle); /*!\brief matrix inversing * *Inverses a 2D matrix *\param _this matrix being transformed. Once the function is called, _this contains the result matrix */ void gf_mx2d_inverse(GF_Matrix2D *_this); /*!\brief matrix coordinate transformation * *Applies a 2D matrix transformation to coordinates *\param _this transformation matrix *\param x pointer to horizontal coordinate. Once the function is called, x contains the transformed horizontal coordinate *\param y pointer to vertical coordinate. Once the function is called, y contains the transformed vertical coordinate */ void gf_mx2d_apply_coords(GF_Matrix2D *_this, Fixed *x, Fixed *y); /*!\brief matrix point transformation * *Applies a 2D matrix transformation to a 2D point *\param _this transformation matrix *\param pt pointer to 2D point. Once the function is called, pt contains the transformed point */ void gf_mx2d_apply_point(GF_Matrix2D *_this, GF_Point2D *pt); /*!\brief matrix rectangle transformation * *Applies a 2D matrix transformation to a rectangle, giving the enclosing rectangle of the transformed one *\param _this transformation matrix *\param rc pointer to rectangle. Once the function is called, rc contains the transformed rectangle */ void gf_mx2d_apply_rect(GF_Matrix2D *_this, GF_Rect *rc); /*!\brief matrix decomposition * *Decomposes a 2D matrix M as M=Scale x Rotation x Translation if possible *\param _this transformation matrix *\param scale resulting scale part *\param rotate resulting rotation part *\param translate resulting translation part *\return 0 if matrix cannot be decomposed, 1 otherwise */ Bool gf_mx2d_decompose(GF_Matrix2D *_this, GF_Point2D *scale, Fixed *rotate, GF_Point2D *translate); /*! @} */ /*! *\addtogroup math3d_grp Math 3d *\ingroup math_grp *\brief 3D Mathematics * *This section documents mathematic tools for 3D geometry operations * @{ */ /*!\brief 3D point or vector * *The 3D point object is used in all the GPAC framework for both point and vector representation. */ typedef struct __vec3f { Fixed x; Fixed y; Fixed z; } GF_Vec; /*base vector operations are MACROs for faster access*/ /*!\hideinitializer macro evaluating to 1 if vectors are equal, 0 otherwise*/ #define gf_vec_equal(v1, v2) (((v1).x == (v2).x) && ((v1).y == (v2).y) && ((v1).z == (v2).z)) /*!\hideinitializer macro reversing a vector v = v*/ #define gf_vec_rev(v) { (v).x = -(v).x; (v).y = -(v).y; (v).z = -(v).z; } /*!\hideinitializer macro performing the minus operation res = v1 - v2*/ #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; } /*!\hideinitializer macro performing the add operation res = v1 + v2*/ #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; } /*! *\brief get 3D vector length * *Gets the length of a 3D vector *\return length of the vector */ Fixed gf_vec_len(GF_Vec v); /*! *\brief get 3D vector square length * *Gets the square length of a 3D vector *\return square length of the vector */ Fixed gf_vec_lensq(GF_Vec v); /*! *\brief get 3D vector dot product * *Gets the dot product of two vectors *\return dot product of the vectors */ Fixed gf_vec_dot(GF_Vec v1, GF_Vec v2); /*! *\brief vector normalization * *Norms the vector, eg make its length equal to \ref FIX_ONE *\param v vector to normalize */ void gf_vec_norm(GF_Vec *v); /*! *\brief vector scaling * *Scales a vector by a given amount *\param v vector to scale *\param f scale factor *\return scaled vector */ GF_Vec gf_vec_scale(GF_Vec v, Fixed f); /*! *\brief vector cross product * *Gets the cross product of two vectors *\param v1 first vector *\param v2 second vector *\return cross-product vector */ GF_Vec gf_vec_cross(GF_Vec v1, GF_Vec v2); /*!\brief 4D vector * *The 4D vector object is used in all the GPAC framework for 4 dimension vectors, VRML Rotations and quaternions representation. */ typedef struct __vec4f { Fixed x; Fixed y; Fixed z; Fixed q; } GF_Vec4; /*!\brief 3D matrix * *The 3D matrix object used in GPAC. The matrix is oriented like OpenGL matrices (column-major ordering), with the translation part at the end of the coefficients list. \note Unless specified otherwise, the matrix object is always expected to represent an affine transformation. */ typedef struct __matrix { Fixed m[16]; } GF_Matrix; /*!\hideinitializer gets the len of a quaternion*/ #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)) /*!\hideinitializer normalizes a quaternion*/ #define gf_quat_norm(v) { \ Fixed __mag = gf_quat_len(v); \ (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); \ } \ /*!\brief quaternion to rotation * *Transforms a quaternion to a Rotation, expressed as a 4 dimension vector with x,y,z for axis and q for rotation angle *\param quat the quaternion to transform *\return the rotation value */ GF_Vec4 gf_quat_to_rotation(GF_Vec4 *quat); /*!\brief quaternion from rotation * *Transforms a Rotation to a quaternion *\param rot the rotation to transform *\return the quaternion value */ GF_Vec4 gf_quat_from_rotation(GF_Vec4 rot); /*!inverses a quaternion*/ GF_Vec4 gf_quat_get_inv(GF_Vec4 *quat); /*!\brief quaternion multiplication * *Multiplies two quaternions *\param q1 the first quaternion *\param q2 the second quaternion *\return the resulting quaternion */ GF_Vec4 gf_quat_multiply(GF_Vec4 *q1, GF_Vec4 *q2); /*!\brief quaternion vector rotating * *Rotates a vector with a quaternion *\param quat the quaternion modelizing the rotation *\param vec the vector to rotate *\return the resulting vector */ GF_Vec gf_quat_rotate(GF_Vec4 *quat, GF_Vec *vec); /*!\brief quaternion from axis and cos * *Constructs a quaternion from an axis and a cosinus value (shortcut to \ref gf_quat_from_rotation) *\param axis the rotation axis *\param cos_a the rotation cosinus value *\return the resulting quaternion */ GF_Vec4 gf_quat_from_axis_cos(GF_Vec axis, Fixed cos_a); /*!\brief quaternion interpolation * *Interpolates two quaternions using spherical linear interpolation *\param q1 the first quaternion *\param q2 the second quaternion *\param frac the fraction of the interpolation, between 0 and \ref FIX_ONE *\return the interpolated quaternion */ GF_Vec4 gf_quat_slerp(GF_Vec4 q1, GF_Vec4 q2, Fixed frac); /*!\brief 3D Bounding Box * *The 3D Bounding Box is a 3D Axis-Aligned Bounding Box used to in various tools of the GPAC framework for bounds estimation of a 3D object. It features an axis-aligned box and a sphere bounding volume for fast intersection tests. */ typedef struct { /*!minimum x, y, and z of the object*/ GF_Vec min_edge; /*!maximum x, y, and z of the object*/ GF_Vec max_edge; /*!center of the bounding box.\note this is computed from min_edge and max_edge*/ GF_Vec center; /*!radius of the bounding sphere for this box.\note this is computed from min_edge and max_edge*/ Fixed radius; /*!the bbox center and radius are valid*/ Bool is_set; } GF_BBox; /*!updates information of the bounding box based on the edge information*/ void gf_bbox_refresh(GF_BBox *b); /*!builds a bounding box from a 2D rectangle*/ void gf_bbox_from_rect(GF_BBox *box, GF_Rect *rc); /*!builds a rectangle from a 3D bounding box.\note The z dimension is lost and no projection is performed*/ void gf_rect_from_bbox(GF_Rect *rc, GF_BBox *box); /*!\brief bounding box expansion * *Checks if a point is inside a bounding box and updates the bounding box to include it if not the case *\param box the bounding box object *\param pt the 3D point to check */ void gf_bbox_grow_point(GF_BBox *box, GF_Vec pt); /*!performs the union of two bounding boxes*/ void gf_bbox_union(GF_BBox *b1, GF_BBox *b2); /*!checks if two bounding boxes are equal or not*/ Bool gf_bbox_equal(GF_BBox *b1, GF_BBox *b2); /*!checks if a point is inside a bounding box or not*/ Bool gf_bbox_point_inside(GF_BBox *box, GF_Vec *p); /*!\brief get box vertices * *Returns the 8 bounding box vertices given the minimum and maximum edge. Vertices are ordered to respect "p-vertex indexes", (vertex from a box closest to plane) and so that n-vertex (vertex from a box farthest from plane) is 7-p_vx_idx *\param bmin minimum edge of the box *\param bmax maximum edge of the box *\param vecs list of 8 3D points used to store the vertices. */ void gf_bbox_get_vertices(GF_Vec bmin, GF_Vec bmax, GF_Vec *vecs); /*!\brief matrix initialization *\hideinitializer * *Inits the matrix to the identity matrix */ #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; } #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) /*!\brief matrix copy *\hideinitializer * *Copies the matrix _from to the matrix _obj */ #define gf_mx_copy(_obj, from) memcpy(&(_obj), &(from), sizeof(GF_Matrix)); /*!\brief matrix constructor from 2D * *Initializes a 3D matrix from a 2D matrix.\note all z-related coefficients will be set to default. */ void gf_mx_from_mx2d(GF_Matrix *mx, GF_Matrix2D *mat2D); /*!\brief matrix identity testing * *Tests if two matrices are equal or not. \return 1 if matrices are same, 0 otherwise */ Bool gf_mx_equal(GF_Matrix *mx1, GF_Matrix *mx2); /*!\brief matrix translation * *Translates a matrix *\param mx the matrix being transformed. Once the function is called, contains the result matrix *\param tx horizontal translation *\param ty vertical translation *\param tz depth translation */ void gf_mx_add_translation(GF_Matrix *mx, Fixed tx, Fixed ty, Fixed tz); /*!\brief matrix scaling * *Scales a matrix *\param mx the matrix being transformed. Once the function is called, contains the result matrix *\param sx horizontal translation scaling *\param sy vertical translation scaling *\param sz depth translation scaling */ void gf_mx_add_scale(GF_Matrix *mx, Fixed sx, Fixed sy, Fixed sz); /*!\brief matrix rotating * *Rotates a matrix *\param mx the matrix being transformed. Once the function is called, contains the result matrix *\param angle rotation angle in radians *\param x horizontal coordinate of rotation axis *\param y vertical coordinate of rotation axis *\param z depth coordinate of rotation axis */ void gf_mx_add_rotation(GF_Matrix *mx, Fixed angle, Fixed x, Fixed y, Fixed z); /*!\brief matrices multiplication * *Multiplies a matrix with another one mx = mx*mul *\param mx the matrix being transformed. Once the function is called, contains the result matrix *\param mul the matrix to add */ void gf_mx_add_matrix(GF_Matrix *mx, GF_Matrix *mul); /*!\brief 2D matrix multiplication * *Adds a 2D affine matrix to a matrix *\param mx the matrix *\param mat2D the matrix to premultiply */ void gf_mx_add_matrix_2d(GF_Matrix *mx, GF_Matrix2D *mat2D); /*!\brief affine matrix inversion * *Inverses an affine matrix.\warning Results are undefined if the matrix is not an affine one *\param mx the matrix to inverse */ void gf_mx_inverse(GF_Matrix *mx); /*!\brief transpose 4x4 matrix * *Transposes a 4x4 matrix *\param mx the matrix to transpose */ void gf_mx_transpose(GF_Matrix *mx); /*!\brief matrix point transformation * *Applies a 3D matrix transformation to a 3D point *\param mx transformation matrix *\param pt pointer to 3D point. Once the function is called, pt contains the transformed point */ void gf_mx_apply_vec(GF_Matrix *mx, GF_Vec *pt); /*!\brief matrix rectangle transformation * *Applies a 3D matrix transformation to a rectangle, giving the enclosing rectangle of the transformed one.\note all depth information are discarded. *\param _this transformation matrix *\param rc pointer to rectangle. Once the function is called, rc contains the transformed rectangle */ void gf_mx_apply_rect(GF_Matrix *_this, GF_Rect *rc); /*!\brief ortho matrix construction * *Creates an orthogonal projection matrix *\param mx matrix to initialize *\param left min horizontal coordinate of viewport *\param right max horizontal coordinate of viewport *\param bottom min vertical coordinate of viewport *\param top max vertical coordinate of viewport *\param z_near min depth coordinate of viewport *\param z_far max depth coordinate of viewport */ void gf_mx_ortho(GF_Matrix *mx, Fixed left, Fixed right, Fixed bottom, Fixed top, Fixed z_near, Fixed z_far); /*!\brief perspective matrix construction * *Creates a perspective projection matrix *\param mx matrix to initialize *\param fov camera field of view angle in radian *\param aspect_ratio viewport aspect ratio *\param z_near min depth coordinate of viewport *\param z_far max depth coordinate of viewport */ void gf_mx_perspective(GF_Matrix *mx, Fixed fov, Fixed aspect_ratio, Fixed z_near, Fixed z_far); /*!\brief creates look matrix * *Creates a transformation matrix looking at a given direction from a given point (camera matrix). *\param mx matrix to initialize *\param position position *\param target look direction *\param up_vector vector describing the up direction */ void gf_mx_lookat(GF_Matrix *mx, GF_Vec position, GF_Vec target, GF_Vec up_vector); /*!\brief matrix box transformation * *Applies a 3D matrix transformation to a bounding box, giving the enclosing box of the transformed one *\param mx transformation matrix *\param b pointer to bounding box. Once the function is called, contains the transformed bounding box */ void gf_mx_apply_bbox(GF_Matrix *mx, GF_BBox *b); /*!\brief matrix box sphere transformation * *Applies a 3D matrix transformation to a bounding box, computing only the enclosing sphere of the transformed one. *\param mx transformation matrix *\param box pointer to bounding box. Once the function is called, contains the transformed bounding sphere */ void gf_mx_apply_bbox_sphere(GF_Matrix *mx, GF_BBox *box); /*!\brief non-affine matrix multiplication * *Multiplies two non-affine matrices mx = mx*mul */ void gf_mx_add_matrix_4x4(GF_Matrix *mat, GF_Matrix *mul); /*!\brief non-affine matrix inversion * *Inverses a non-affine matrices *\return 1 if inversion was done, 0 if inversion not possible. */ Bool gf_mx_inverse_4x4(GF_Matrix *mx); /*!\brief matrix 4D vector transformation * *Applies a 3D non-affine matrix transformation to a 4 dimension vector *\param mx transformation matrix *\param vec pointer to the vector. Once the function is called, contains the transformed vector */ void gf_mx_apply_vec_4x4(GF_Matrix *mx, GF_Vec4 *vec); /*!\brief matrix decomposition * *Decomposes a matrix into translation, scale, shear and rotate *\param mx the matrix to decompose *\param translate the decomposed translation part *\param scale the decomposed scaling part *\param rotate the decomposed rotation part, expressed as a Rotataion (axis + angle) *\param shear the decomposed shear part */ void gf_mx_decompose(GF_Matrix *mx, GF_Vec *translate, GF_Vec *scale, GF_Vec4 *rotate, GF_Vec *shear); /*!\brief matrix vector rotation * *Rotates a vector with a given matrix, ignoring any translation. *\param mx transformation matrix *\param pt pointer to 3D vector. Once the function is called, pt contains the transformed vector */ void gf_mx_rotate_vector(GF_Matrix *mx, GF_Vec *pt); /*!\brief matrix initialization from vectors * *Inits a matrix to rotate the local axis in the given vectors \param mx matrix to initialize \param x_axis target normalized X axis \param y_axis target normalized Y axis \param z_axis target normalized Z axis */ void gf_mx_rotation_matrix_from_vectors(GF_Matrix *mx, GF_Vec x_axis, GF_Vec y_axis, GF_Vec z_axis); /*!\brief matrix to 2D matrix * *Inits a 2D matrix by removing all depth info from a 3D matrix *\param mx2d 2D matrix to initialize *\param mx 3D matrix to use */ void gf_mx2d_from_mx(GF_Matrix2D *mx2d, GF_Matrix *mx); /*!\brief Plane object*/ typedef struct { /*!normal vector to the plane*/ GF_Vec normal; /*!distance from origin of the plane*/ Fixed d; } GF_Plane; /*!\brief matrix plane transformation * *Transorms a plane by a given matrix *\param mx the matrix to use *\param plane pointer to 3D plane. Once the function is called, plane contains the transformed plane */ void gf_mx_apply_plane(GF_Matrix *mx, GF_Plane *plane); /*!\brief point to plane distance * *Gets the distance between a point and a plne *\param plane the plane to use *\param p pointer to ^point to check *\return the distance between the place and the point */ Fixed gf_plane_get_distance(GF_Plane *plane, GF_Vec *p); /*!\brief closest point on a line * *Gets the closest point on a line from a given point in space *\param line_pt a point of the line to test *\param line_vec the normalized direction vector of the line *\param pt the point to check *\return the closest point on the line to the desired point */ GF_Vec gf_closest_point_to_line(GF_Vec line_pt, GF_Vec line_vec, GF_Vec pt); /*!\brief box p-vertex index * *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 *ordered in GPAC? cf \ref gf_bbox_get_vertices *\param p the plane to check *\return the p-vertex index value, ranging from 0 to 7 */ u32 gf_plane_get_p_vertex_idx(GF_Plane *p); /*!\brief plane line intersection * *Checks for the intersection of a plane and a line *\param plane plane to test *\param linepoint a point on the line to test *\param linevec normalized direction vector of the line to test *\param outPoint optional pointer to retrieve the intersection point, NULL otherwise *\return 1 if line and plane intersect, 0 otherwise */ Bool gf_plane_intersect_line(GF_Plane *plane, GF_Vec *linepoint, GF_Vec *linevec, GF_Vec *outPoint); /*!Classification types for box/plane position used in \ref gf_bbox_plane_relation*/ enum { /*!box is in front of the plane*/ GF_BBOX_FRONT, /*!box intersects the plane*/ GF_BBOX_INTER, /*!box is back of the plane*/ GF_BBOX_BACK }; /*!\brief box-plane relation * *Gets the spatial relation between a box and a plane *\param box the box to check *\param p the plane to check *\return the relation type */ u32 gf_bbox_plane_relation(GF_BBox *box, GF_Plane *p); /*!\brief 3D Ray * *The 3D ray object is used in GPAC for all collision and mouse interaction tests */ typedef struct { /*!origin point of the ray*/ GF_Vec orig; /*!normalized direction vector of the ray*/ GF_Vec dir; } GF_Ray; /*!\brief ray constructor * *Constructs a ray object *\param start starting point of the ray *\param end end point of the ray, or any point on the ray *\return the ray object */ GF_Ray gf_ray(GF_Vec start, GF_Vec end); /*!\brief matrix ray transformation * *Transforms a ray by a given transformation matrix *\param mx the matrix to use *\param r pointer to the ray. Once the function is called, contains the transformed ray */ void gf_mx_apply_ray(GF_Matrix *mx, GF_Ray *r); /*!\brief ray box intersection test * *Checks if a ray intersects a box or not *\param ray the ray to check *\param min_edge the minimum edge of the box to check *\param max_edge the maximum edge of the box to check *\param out_point optional location of a 3D point to store the intersection, NULL otherwise. *\return retuns 1 if the ray intersects the box, 0 otherwise */ Bool gf_ray_hit_box(GF_Ray *ray, GF_Vec min_edge, GF_Vec max_edge, GF_Vec *out_point); /*!\brief ray sphere intersection test * *Checks if a ray intersects a box or not *\param ray the ray to check *\param center the center of the sphere to check. If NULL, the origin (0,0,0)is used *\param radius the radius of the sphere to check *\param out_point optional location of a 3D point to store the intersection, NULL otherwise *\return retuns 1 if the ray intersects the sphere, 0 otherwise */ Bool gf_ray_hit_sphere(GF_Ray *ray, GF_Vec *center, Fixed radius, GF_Vec *out_point); /*!\brief ray triangle intersection test * *Checks if a ray intersects a triangle or not *\param ray the ray to check *\param v0 first vertex of the triangle *\param v1 second vertex of the triangle *\param v2 third vertex of the triangle *\param dist optional location of a fixed number to store the intersection distance from ray origin if any, NULL otherwise *\return retuns 1 if the ray intersects the triangle, 0 otherwise */ Bool gf_ray_hit_triangle(GF_Ray *ray, GF_Vec *v0, GF_Vec *v1, GF_Vec *v2, Fixed *dist); /*same as above and performs backface cull (solid meshes)*/ /*!\brief ray triangle intersection test * *Checks if a ray intersects a triangle or not, performing backface culling. For parameters details, look at \ref gf_ray_hit_triangle_backcull */ Bool gf_ray_hit_triangle_backcull(GF_Ray *ray, GF_Vec *v0, GF_Vec *v1, GF_Vec *v2, Fixed *dist); /*! @} */ /*! @} */ #ifdef __cplusplus } #endif #endif /*_GF_MATH_H_*/