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