os/graphics/m3g/m3gcore11/inc/m3g_math.h
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/m3g/m3gcore11/inc/m3g_math.h	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,286 @@
     1.4 +/*
     1.5 +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
     1.6 +* All rights reserved.
     1.7 +* This component and the accompanying materials are made available
     1.8 +* under the terms of the License "Eclipse Public License v1.0"
     1.9 +* which accompanies this distribution, and is available
    1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.11 +*
    1.12 +* Initial Contributors:
    1.13 +* Nokia Corporation - initial contribution.
    1.14 +*
    1.15 +* Contributors:
    1.16 +*
    1.17 +* Description: Vector and matrix math functions and data types
    1.18 +*
    1.19 +*/
    1.20 +
    1.21 +#ifndef __M3G_MATH_H__
    1.22 +#define __M3G_MATH_H__
    1.23 +
    1.24 +/*!
    1.25 + * \file
    1.26 + * \brief Vector and matrix math functions and data types
    1.27 + */
    1.28 +
    1.29 +/*----------------------------------------------------------------------
    1.30 + * Internal data types
    1.31 + *--------------------------------------------------------------------*/
    1.32 +
    1.33 +/*!
    1.34 + * \internal
    1.35 + * \brief Axis-aligned bounding box
    1.36 + */
    1.37 +typedef struct
    1.38 +{
    1.39 +    M3Gfloat min[3], max[3];
    1.40 +    /*
    1.41 +    M3Gbyte min[3], minExp;
    1.42 +    M3Gbyte max[3], maxExp;
    1.43 +    */
    1.44 +} AABB;
    1.45 +
    1.46 +/*----------------------------------------------------------------------
    1.47 + * Global constants
    1.48 + *--------------------------------------------------------------------*/
    1.49 +
    1.50 +/*!
    1.51 + * \internal
    1.52 + * \brief Maximum positive float value
    1.53 + */
    1.54 +#define M3G_MAX_POSITIVE_FLOAT  (3.402e+38f)
    1.55 +
    1.56 +/*!
    1.57 + * \internal
    1.58 + * \brief Minimum negative float value
    1.59 + */
    1.60 +#define M3G_MIN_NEGATIVE_FLOAT  (-3.402e+38f)
    1.61 +
    1.62 +/*! 
    1.63 + * \internal
    1.64 + * \brief Degrees to radians multiplier
    1.65 + */
    1.66 +#define M3G_DEG2RAD             (0.017453292519943295769236907684886f)
    1.67 +
    1.68 +#define EPSILON         (1.0e-5f)
    1.69 +#define EPSILON_EXP     (-17)
    1.70 +#define RAD2DEG         (57.295779513082320876798154814105f)
    1.71 +#define PI              (3.14159265359f)
    1.72 +#define HALF_PI         (PI / 2.0f)
    1.73 +#define ONE_AND_HALF_PI (PI + HALF_PI)
    1.74 +#define TWO_PI          (2.f * PI)
    1.75 +
    1.76 +/*! \internal \brief Extracts the bit pattern of a floating point number */
    1.77 +#define FLOAT_AS_UINT(x) (*(M3Guint*)&(x))
    1.78 +
    1.79 +/*! \internal \brief Returns an integer bit pattern as float */
    1.80 +#define INT_AS_FLOAT(x) (*(M3Gfloat*)&(x))
    1.81 +
    1.82 +/* IEEE floating point format */
    1.83 +#define MANTISSA_MASK   0x007FFFFFu
    1.84 +#define EXP_MASK        0x7F800000u
    1.85 +#define SIGN_MASK       0x80000000u
    1.86 +
    1.87 +#define M3G_FLOAT_ONE   0x3F800000
    1.88 +
    1.89 +/*! \internal \brief Extracts the exponent of a floating point number */
    1.90 +#define EXPONENT(x) (((M3Gint)(FLOAT_AS_UINT(x) & EXP_MASK) >> 23) - 127)
    1.91 +
    1.92 +/*! \internal \brief Extracts the mantissa of a floating point number */
    1.93 +#define MANTISSA(x) (FLOAT_AS_UINT(x) & MANTISSA_MASK)
    1.94 +
    1.95 +/*! \internal \brief Extracts the sign of a floating point number */
    1.96 +#define SIGN(x) (1 - ((FLOAT_AS_UINT(x) & SIGN_MASK) >> 30))
    1.97 +
    1.98 +/*! \internal \brief Extracts just the sign bit of a floating point number */
    1.99 +#define SIGN_BIT(x) (FLOAT_AS_UINT(x) >> 31)
   1.100 +
   1.101 +/* Useful constants */
   1.102 +#define LEADING_ONE (1 << 23)
   1.103 +
   1.104 +/*! \internal \brief Checks the sign of a floating point number */
   1.105 +#define IS_NEGATIVE(x) ((FLOAT_AS_UINT(x) & SIGN_MASK) != 0)
   1.106 +
   1.107 +/* Floating-point constant identification macros */
   1.108 +#   define IS_ZERO(x)      ((FLOAT_AS_UINT(x) & ~SIGN_MASK) <= 0x01000000)
   1.109 +#   define IS_ONE(x)       (((x) > 1.0f - EPSILON) && ((x) < 1.0f + EPSILON))
   1.110 +#   define IS_MINUS_ONE(x) (((x) > -1.0f - EPSILON) && ((x) < -1.0f + EPSILON))
   1.111 +
   1.112 +/* Elementary vectors */
   1.113 +static const Vec4 Vec4_X_AXIS = {1, 0, 0, 0};
   1.114 +static const Vec4 Vec4_Y_AXIS = {0, 1, 0, 0};
   1.115 +static const Vec4 Vec4_Z_AXIS = {0, 0, 1, 0};
   1.116 +static const Vec4 Vec4_ORIGIN = {0, 0, 0, 1};
   1.117 +
   1.118 +/*----------------------------------------------------------------------
   1.119 + * Elementary floating-point math
   1.120 + *--------------------------------------------------------------------*/
   1.121 +
   1.122 +#if defined(M3G_SOFT_FLOAT)
   1.123 +static M3Gfloat m3gAdd(const M3Gfloat a, const M3Gfloat b);
   1.124 +static M3Gfloat m3gMul(const M3Gfloat a, const M3Gfloat b);
   1.125 +static M3Gfloat m3gRcpSqrt(const M3Gfloat x);
   1.126 +static M3Gfloat m3gSqrt(const M3Gfloat x);
   1.127 +static M3G_INLINE M3Gfloat m3gAbs(const M3Gfloat a)
   1.128 +{
   1.129 +    M3Guint temp = FLOAT_AS_UINT(a) & ~SIGN_MASK;
   1.130 +    return INT_AS_FLOAT(temp);
   1.131 +}
   1.132 +static M3G_INLINE M3Gfloat m3gDiv(const M3Gfloat a, const M3Gfloat b)
   1.133 +{
   1.134 +    return (a / b);
   1.135 +}
   1.136 +static M3G_INLINE M3Gfloat m3gDivif(const M3Gint a, const M3Gint b)
   1.137 +{
   1.138 +    return m3gDiv((M3Gfloat) a, (M3Gfloat) b);
   1.139 +}
   1.140 +static M3G_INLINE M3Gfloat m3gMadd(const M3Gfloat a, const M3Gfloat b, const M3Gfloat c)
   1.141 +{
   1.142 +    return m3gAdd(m3gMul(a, b), c);
   1.143 +}
   1.144 +static M3G_INLINE M3Gfloat m3gRcp(const M3Gfloat x)
   1.145 +{
   1.146 +    return (1.0f / x);
   1.147 +}
   1.148 +static M3G_INLINE M3Gfloat m3gSub(const M3Gfloat a, const M3Gfloat b)
   1.149 +{
   1.150 +    M3Guint bNeg = FLOAT_AS_UINT(b) ^ SIGN_MASK;
   1.151 +    return m3gAdd(a, INT_AS_FLOAT(bNeg));
   1.152 +}
   1.153 +#else
   1.154 +#   include <math.h>
   1.155 +#   define m3gAbs(a)            ((float)fabs(a))
   1.156 +#   define m3gAdd(a, b)         ((float)(a) + (float)(b))
   1.157 +#   define m3gMadd(a, b, c)     ((float)(a) * (float)(b) + (float)(c))
   1.158 +#   define m3gMul(a, b)         ((float)(a) * (float)(b))
   1.159 +#   define m3gDiv(a, b)         ((float)(a) / (float)(b))
   1.160 +#   define m3gDivif(a, b)       ((float)(a) / (float)(b))
   1.161 +#   define m3gRcp(x)            (1.0f / (float)(x))
   1.162 +#   define m3gRcpSqrt(x)        (1.0f / (float)sqrt(x))
   1.163 +#   define m3gSqrt(x)           ((float)sqrt(x))
   1.164 +#   define m3gSub(a, b)         ((float)(a) - (float)(b))
   1.165 +#endif /* M3G_SOFT_FLOAT */
   1.166 +
   1.167 +/*----------------------------------------------------------------------
   1.168 + * Trigonometric and exp functions
   1.169 + *--------------------------------------------------------------------*/
   1.170 +
   1.171 +#if defined(M3G_SOFT_FLOAT)
   1.172 +static M3Gfloat m3gArcCos(const M3Gfloat x);
   1.173 +static M3Gfloat m3gArcTan(const M3Gfloat y, const M3Gfloat x);
   1.174 +static M3Gfloat m3gCos(const M3Gfloat x);
   1.175 +static M3Gfloat m3gSin(const M3Gfloat x);
   1.176 +static M3Gfloat m3gTan(const M3Gfloat x);
   1.177 +static M3Gfloat m3gExp(const M3Gfloat a);
   1.178 +#else
   1.179 +#   define m3gArcCos(x)         ((float)acos(x))
   1.180 +#   define m3gArcTan(y, x)      ((float)atan2((y), (x)))
   1.181 +#   define m3gCos(x)            ((float)cos(x))
   1.182 +#   define m3gSin(x)            ((float)sin(x))
   1.183 +#   define m3gTan(x)            ((float)tan(x))
   1.184 +#   define m3gExp(x)            ((float)exp(x))
   1.185 +#endif
   1.186 +
   1.187 +/*----------------------------------------------------------------------
   1.188 + * Matrix and quaternion stuff
   1.189 + *--------------------------------------------------------------------*/
   1.190 +
   1.191 +static M3Gbool m3gIsWUnity        (const Matrix *mtx);
   1.192 +
   1.193 +static void    m3gExpQuat         (Quat *quat, const Vec3 *qExp);
   1.194 +static void    m3gLogQuat         (Vec3 *qLog, const Quat *quat);
   1.195 +static void    m3gLogDiffQuat     (Vec3 *logDiff,
   1.196 +                                   const Quat *from, const Quat *to);
   1.197 +static M3Gint  m3gGetFixedPoint3x3Basis(const Matrix *mtx, M3Gshort *elem);
   1.198 +static M3Gint  m3gGetFixedPointTranslation(const Matrix *mtx, M3Gshort *elem);
   1.199 +
   1.200 +/*----------------------------------------------------------------------
   1.201 + * Bounding boxes
   1.202 + *--------------------------------------------------------------------*/
   1.203 +
   1.204 +static void m3gFitAABB(AABB *box, const AABB *a, const AABB *b);
   1.205 +static void m3gTransformAABB(AABB *box, const Matrix *mtx);
   1.206 +#if defined(M3G_DEBUG)
   1.207 +static void m3gValidateAABB(const AABB *aabb);
   1.208 +#else
   1.209 +#   define m3gValidateAABB(a)
   1.210 +#endif
   1.211 +                             
   1.212 +/*----------------------------------------------------------------------
   1.213 + * Rounding and conversion
   1.214 + *--------------------------------------------------------------------*/
   1.215 +
   1.216 +static M3Gint  m3gRoundToInt(const M3Gfloat a);
   1.217 +
   1.218 +static M3Guint m3gAlpha1f(M3Gfloat a);
   1.219 +/*static M3Guint m3gColor1f(M3Gfloat i);*/
   1.220 +static M3Guint m3gColor3f(M3Gfloat r, M3Gfloat g, M3Gfloat b);
   1.221 +static M3Guint m3gColor4f(M3Gfloat r, M3Gfloat g, M3Gfloat b, M3Gfloat a);
   1.222 +static void    m3gFloatColor(M3Gint argb, M3Gfloat intensity, M3Gfloat *rgba);
   1.223 +
   1.224 +static M3Gbool m3gIntersectTriangle(const Vec3 *orig, const Vec3 *dir,
   1.225 +                                    const Vec3 *vert0, const Vec3 *vert1, const Vec3 *vert2,
   1.226 +                                    Vec3 *tuv, M3Gint cullMode);
   1.227 +static M3Gbool m3gIntersectBox(const Vec3 *orig, const Vec3 *dir, const AABB *box);
   1.228 +static M3Gbool m3gIntersectRectangle(M3GRectangle *dst, M3GRectangle *r1, M3GRectangle *r2);
   1.229 +
   1.230 +/*----------------------------------------------------------------------
   1.231 + * Inline functions
   1.232 + *--------------------------------------------------------------------*/
   1.233 +
   1.234 +/*!
   1.235 + * \internal
   1.236 + * \brief Multiplies a floating point number by 0.5.
   1.237 + *
   1.238 + * \param x the number to multiply
   1.239 + * \return 0.5 * \c x
   1.240 + */
   1.241 +static M3G_INLINE M3Gfloat m3gHalf(M3Gfloat x)
   1.242 +{
   1.243 +    M3Guint bits = FLOAT_AS_UINT(x);
   1.244 +    M3Guint mask = 0xff;
   1.245 +    M3Gint exponent = bits & (mask << 23);
   1.246 +    bits ^= exponent;
   1.247 +    exponent = exponent - (1 << 23);
   1.248 +    if (exponent > 0) bits |= exponent;
   1.249 +    return INT_AS_FLOAT(bits);
   1.250 +}
   1.251 +
   1.252 +/*!
   1.253 + * \internal
   1.254 + * \brief Multiplies a floating point number by two
   1.255 + *
   1.256 + * This does NOT handle overflows.
   1.257 + * 
   1.258 + * \param x the number to multiply
   1.259 + * \return 2 * \c x
   1.260 + */
   1.261 +static M3G_INLINE M3Gfloat m3gDouble(M3Gfloat x)
   1.262 +{
   1.263 +    M3Guint bits = FLOAT_AS_UINT(x) + (1 << 23);
   1.264 +    return INT_AS_FLOAT(bits);
   1.265 +}
   1.266 +
   1.267 +/*!
   1.268 + * \internal
   1.269 + * \brief Computes the square of a floating point number
   1.270 + *
   1.271 + * \param x the input number
   1.272 + * \return x * x
   1.273 + */
   1.274 +static M3G_INLINE M3Gfloat m3gSquare(M3Gfloat x)
   1.275 +{
   1.276 +    return m3gMul(x, x);
   1.277 +}
   1.278 +
   1.279 +/*!
   1.280 + * \internal
   1.281 + * \brief Negates a floating-point value
   1.282 + */
   1.283 +static M3G_INLINE M3Gfloat m3gNegate(M3Gfloat x)
   1.284 +{
   1.285 +    M3Guint ix = FLOAT_AS_UINT(x) ^ SIGN_MASK;
   1.286 +    return INT_AS_FLOAT(ix);
   1.287 +}
   1.288 +
   1.289 +#endif /*__M3G_MATH_H__*/