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