os/graphics/m3g/m3gcore11/inc/m3g_math.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200 (2014-06-10)
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: Vector and matrix math functions and data types
    15 *
    16 */
    17 
    18 #ifndef __M3G_MATH_H__
    19 #define __M3G_MATH_H__
    20 
    21 /*!
    22  * \file
    23  * \brief Vector and matrix math functions and data types
    24  */
    25 
    26 /*----------------------------------------------------------------------
    27  * Internal data types
    28  *--------------------------------------------------------------------*/
    29 
    30 /*!
    31  * \internal
    32  * \brief Axis-aligned bounding box
    33  */
    34 typedef struct
    35 {
    36     M3Gfloat min[3], max[3];
    37     /*
    38     M3Gbyte min[3], minExp;
    39     M3Gbyte max[3], maxExp;
    40     */
    41 } AABB;
    42 
    43 /*----------------------------------------------------------------------
    44  * Global constants
    45  *--------------------------------------------------------------------*/
    46 
    47 /*!
    48  * \internal
    49  * \brief Maximum positive float value
    50  */
    51 #define M3G_MAX_POSITIVE_FLOAT  (3.402e+38f)
    52 
    53 /*!
    54  * \internal
    55  * \brief Minimum negative float value
    56  */
    57 #define M3G_MIN_NEGATIVE_FLOAT  (-3.402e+38f)
    58 
    59 /*! 
    60  * \internal
    61  * \brief Degrees to radians multiplier
    62  */
    63 #define M3G_DEG2RAD             (0.017453292519943295769236907684886f)
    64 
    65 #define EPSILON         (1.0e-5f)
    66 #define EPSILON_EXP     (-17)
    67 #define RAD2DEG         (57.295779513082320876798154814105f)
    68 #define PI              (3.14159265359f)
    69 #define HALF_PI         (PI / 2.0f)
    70 #define ONE_AND_HALF_PI (PI + HALF_PI)
    71 #define TWO_PI          (2.f * PI)
    72 
    73 /*! \internal \brief Extracts the bit pattern of a floating point number */
    74 #define FLOAT_AS_UINT(x) (*(M3Guint*)&(x))
    75 
    76 /*! \internal \brief Returns an integer bit pattern as float */
    77 #define INT_AS_FLOAT(x) (*(M3Gfloat*)&(x))
    78 
    79 /* IEEE floating point format */
    80 #define MANTISSA_MASK   0x007FFFFFu
    81 #define EXP_MASK        0x7F800000u
    82 #define SIGN_MASK       0x80000000u
    83 
    84 #define M3G_FLOAT_ONE   0x3F800000
    85 
    86 /*! \internal \brief Extracts the exponent of a floating point number */
    87 #define EXPONENT(x) (((M3Gint)(FLOAT_AS_UINT(x) & EXP_MASK) >> 23) - 127)
    88 
    89 /*! \internal \brief Extracts the mantissa of a floating point number */
    90 #define MANTISSA(x) (FLOAT_AS_UINT(x) & MANTISSA_MASK)
    91 
    92 /*! \internal \brief Extracts the sign of a floating point number */
    93 #define SIGN(x) (1 - ((FLOAT_AS_UINT(x) & SIGN_MASK) >> 30))
    94 
    95 /*! \internal \brief Extracts just the sign bit of a floating point number */
    96 #define SIGN_BIT(x) (FLOAT_AS_UINT(x) >> 31)
    97 
    98 /* Useful constants */
    99 #define LEADING_ONE (1 << 23)
   100 
   101 /*! \internal \brief Checks the sign of a floating point number */
   102 #define IS_NEGATIVE(x) ((FLOAT_AS_UINT(x) & SIGN_MASK) != 0)
   103 
   104 /* Floating-point constant identification macros */
   105 #   define IS_ZERO(x)      ((FLOAT_AS_UINT(x) & ~SIGN_MASK) <= 0x01000000)
   106 #   define IS_ONE(x)       (((x) > 1.0f - EPSILON) && ((x) < 1.0f + EPSILON))
   107 #   define IS_MINUS_ONE(x) (((x) > -1.0f - EPSILON) && ((x) < -1.0f + EPSILON))
   108 
   109 /* Elementary vectors */
   110 static const Vec4 Vec4_X_AXIS = {1, 0, 0, 0};
   111 static const Vec4 Vec4_Y_AXIS = {0, 1, 0, 0};
   112 static const Vec4 Vec4_Z_AXIS = {0, 0, 1, 0};
   113 static const Vec4 Vec4_ORIGIN = {0, 0, 0, 1};
   114 
   115 /*----------------------------------------------------------------------
   116  * Elementary floating-point math
   117  *--------------------------------------------------------------------*/
   118 
   119 #if defined(M3G_SOFT_FLOAT)
   120 static M3Gfloat m3gAdd(const M3Gfloat a, const M3Gfloat b);
   121 static M3Gfloat m3gMul(const M3Gfloat a, const M3Gfloat b);
   122 static M3Gfloat m3gRcpSqrt(const M3Gfloat x);
   123 static M3Gfloat m3gSqrt(const M3Gfloat x);
   124 static M3G_INLINE M3Gfloat m3gAbs(const M3Gfloat a)
   125 {
   126     M3Guint temp = FLOAT_AS_UINT(a) & ~SIGN_MASK;
   127     return INT_AS_FLOAT(temp);
   128 }
   129 static M3G_INLINE M3Gfloat m3gDiv(const M3Gfloat a, const M3Gfloat b)
   130 {
   131     return (a / b);
   132 }
   133 static M3G_INLINE M3Gfloat m3gDivif(const M3Gint a, const M3Gint b)
   134 {
   135     return m3gDiv((M3Gfloat) a, (M3Gfloat) b);
   136 }
   137 static M3G_INLINE M3Gfloat m3gMadd(const M3Gfloat a, const M3Gfloat b, const M3Gfloat c)
   138 {
   139     return m3gAdd(m3gMul(a, b), c);
   140 }
   141 static M3G_INLINE M3Gfloat m3gRcp(const M3Gfloat x)
   142 {
   143     return (1.0f / x);
   144 }
   145 static M3G_INLINE M3Gfloat m3gSub(const M3Gfloat a, const M3Gfloat b)
   146 {
   147     M3Guint bNeg = FLOAT_AS_UINT(b) ^ SIGN_MASK;
   148     return m3gAdd(a, INT_AS_FLOAT(bNeg));
   149 }
   150 #else
   151 #   include <math.h>
   152 #   define m3gAbs(a)            ((float)fabs(a))
   153 #   define m3gAdd(a, b)         ((float)(a) + (float)(b))
   154 #   define m3gMadd(a, b, c)     ((float)(a) * (float)(b) + (float)(c))
   155 #   define m3gMul(a, b)         ((float)(a) * (float)(b))
   156 #   define m3gDiv(a, b)         ((float)(a) / (float)(b))
   157 #   define m3gDivif(a, b)       ((float)(a) / (float)(b))
   158 #   define m3gRcp(x)            (1.0f / (float)(x))
   159 #   define m3gRcpSqrt(x)        (1.0f / (float)sqrt(x))
   160 #   define m3gSqrt(x)           ((float)sqrt(x))
   161 #   define m3gSub(a, b)         ((float)(a) - (float)(b))
   162 #endif /* M3G_SOFT_FLOAT */
   163 
   164 /*----------------------------------------------------------------------
   165  * Trigonometric and exp functions
   166  *--------------------------------------------------------------------*/
   167 
   168 #if defined(M3G_SOFT_FLOAT)
   169 static M3Gfloat m3gArcCos(const M3Gfloat x);
   170 static M3Gfloat m3gArcTan(const M3Gfloat y, const M3Gfloat x);
   171 static M3Gfloat m3gCos(const M3Gfloat x);
   172 static M3Gfloat m3gSin(const M3Gfloat x);
   173 static M3Gfloat m3gTan(const M3Gfloat x);
   174 static M3Gfloat m3gExp(const M3Gfloat a);
   175 #else
   176 #   define m3gArcCos(x)         ((float)acos(x))
   177 #   define m3gArcTan(y, x)      ((float)atan2((y), (x)))
   178 #   define m3gCos(x)            ((float)cos(x))
   179 #   define m3gSin(x)            ((float)sin(x))
   180 #   define m3gTan(x)            ((float)tan(x))
   181 #   define m3gExp(x)            ((float)exp(x))
   182 #endif
   183 
   184 /*----------------------------------------------------------------------
   185  * Matrix and quaternion stuff
   186  *--------------------------------------------------------------------*/
   187 
   188 static M3Gbool m3gIsWUnity        (const Matrix *mtx);
   189 
   190 static void    m3gExpQuat         (Quat *quat, const Vec3 *qExp);
   191 static void    m3gLogQuat         (Vec3 *qLog, const Quat *quat);
   192 static void    m3gLogDiffQuat     (Vec3 *logDiff,
   193                                    const Quat *from, const Quat *to);
   194 static M3Gint  m3gGetFixedPoint3x3Basis(const Matrix *mtx, M3Gshort *elem);
   195 static M3Gint  m3gGetFixedPointTranslation(const Matrix *mtx, M3Gshort *elem);
   196 
   197 /*----------------------------------------------------------------------
   198  * Bounding boxes
   199  *--------------------------------------------------------------------*/
   200 
   201 static void m3gFitAABB(AABB *box, const AABB *a, const AABB *b);
   202 static void m3gTransformAABB(AABB *box, const Matrix *mtx);
   203 #if defined(M3G_DEBUG)
   204 static void m3gValidateAABB(const AABB *aabb);
   205 #else
   206 #   define m3gValidateAABB(a)
   207 #endif
   208                              
   209 /*----------------------------------------------------------------------
   210  * Rounding and conversion
   211  *--------------------------------------------------------------------*/
   212 
   213 static M3Gint  m3gRoundToInt(const M3Gfloat a);
   214 
   215 static M3Guint m3gAlpha1f(M3Gfloat a);
   216 /*static M3Guint m3gColor1f(M3Gfloat i);*/
   217 static M3Guint m3gColor3f(M3Gfloat r, M3Gfloat g, M3Gfloat b);
   218 static M3Guint m3gColor4f(M3Gfloat r, M3Gfloat g, M3Gfloat b, M3Gfloat a);
   219 static void    m3gFloatColor(M3Gint argb, M3Gfloat intensity, M3Gfloat *rgba);
   220 
   221 static M3Gbool m3gIntersectTriangle(const Vec3 *orig, const Vec3 *dir,
   222                                     const Vec3 *vert0, const Vec3 *vert1, const Vec3 *vert2,
   223                                     Vec3 *tuv, M3Gint cullMode);
   224 static M3Gbool m3gIntersectBox(const Vec3 *orig, const Vec3 *dir, const AABB *box);
   225 static M3Gbool m3gIntersectRectangle(M3GRectangle *dst, M3GRectangle *r1, M3GRectangle *r2);
   226 
   227 /*----------------------------------------------------------------------
   228  * Inline functions
   229  *--------------------------------------------------------------------*/
   230 
   231 /*!
   232  * \internal
   233  * \brief Multiplies a floating point number by 0.5.
   234  *
   235  * \param x the number to multiply
   236  * \return 0.5 * \c x
   237  */
   238 static M3G_INLINE M3Gfloat m3gHalf(M3Gfloat x)
   239 {
   240     M3Guint bits = FLOAT_AS_UINT(x);
   241     M3Guint mask = 0xff;
   242     M3Gint exponent = bits & (mask << 23);
   243     bits ^= exponent;
   244     exponent = exponent - (1 << 23);
   245     if (exponent > 0) bits |= exponent;
   246     return INT_AS_FLOAT(bits);
   247 }
   248 
   249 /*!
   250  * \internal
   251  * \brief Multiplies a floating point number by two
   252  *
   253  * This does NOT handle overflows.
   254  * 
   255  * \param x the number to multiply
   256  * \return 2 * \c x
   257  */
   258 static M3G_INLINE M3Gfloat m3gDouble(M3Gfloat x)
   259 {
   260     M3Guint bits = FLOAT_AS_UINT(x) + (1 << 23);
   261     return INT_AS_FLOAT(bits);
   262 }
   263 
   264 /*!
   265  * \internal
   266  * \brief Computes the square of a floating point number
   267  *
   268  * \param x the input number
   269  * \return x * x
   270  */
   271 static M3G_INLINE M3Gfloat m3gSquare(M3Gfloat x)
   272 {
   273     return m3gMul(x, x);
   274 }
   275 
   276 /*!
   277  * \internal
   278  * \brief Negates a floating-point value
   279  */
   280 static M3G_INLINE M3Gfloat m3gNegate(M3Gfloat x)
   281 {
   282     M3Guint ix = FLOAT_AS_UINT(x) ^ SIGN_MASK;
   283     return INT_AS_FLOAT(ix);
   284 }
   285 
   286 #endif /*__M3G_MATH_H__*/