/*
* 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_*/