Update contrib.
2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
14 * Description: Vector and matrix math functions and data types
18 #ifndef __M3G_MATH_H__
19 #define __M3G_MATH_H__
23 * \brief Vector and matrix math functions and data types
26 /*----------------------------------------------------------------------
28 *--------------------------------------------------------------------*/
32 * \brief Axis-aligned bounding box
36 M3Gfloat min[3], max[3];
38 M3Gbyte min[3], minExp;
39 M3Gbyte max[3], maxExp;
43 /*----------------------------------------------------------------------
45 *--------------------------------------------------------------------*/
49 * \brief Maximum positive float value
51 #define M3G_MAX_POSITIVE_FLOAT (3.402e+38f)
55 * \brief Minimum negative float value
57 #define M3G_MIN_NEGATIVE_FLOAT (-3.402e+38f)
61 * \brief Degrees to radians multiplier
63 #define M3G_DEG2RAD (0.017453292519943295769236907684886f)
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)
73 /*! \internal \brief Extracts the bit pattern of a floating point number */
74 #define FLOAT_AS_UINT(x) (*(M3Guint*)&(x))
76 /*! \internal \brief Returns an integer bit pattern as float */
77 #define INT_AS_FLOAT(x) (*(M3Gfloat*)&(x))
79 /* IEEE floating point format */
80 #define MANTISSA_MASK 0x007FFFFFu
81 #define EXP_MASK 0x7F800000u
82 #define SIGN_MASK 0x80000000u
84 #define M3G_FLOAT_ONE 0x3F800000
86 /*! \internal \brief Extracts the exponent of a floating point number */
87 #define EXPONENT(x) (((M3Gint)(FLOAT_AS_UINT(x) & EXP_MASK) >> 23) - 127)
89 /*! \internal \brief Extracts the mantissa of a floating point number */
90 #define MANTISSA(x) (FLOAT_AS_UINT(x) & MANTISSA_MASK)
92 /*! \internal \brief Extracts the sign of a floating point number */
93 #define SIGN(x) (1 - ((FLOAT_AS_UINT(x) & SIGN_MASK) >> 30))
95 /*! \internal \brief Extracts just the sign bit of a floating point number */
96 #define SIGN_BIT(x) (FLOAT_AS_UINT(x) >> 31)
98 /* Useful constants */
99 #define LEADING_ONE (1 << 23)
101 /*! \internal \brief Checks the sign of a floating point number */
102 #define IS_NEGATIVE(x) ((FLOAT_AS_UINT(x) & SIGN_MASK) != 0)
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))
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};
115 /*----------------------------------------------------------------------
116 * Elementary floating-point math
117 *--------------------------------------------------------------------*/
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)
126 M3Guint temp = FLOAT_AS_UINT(a) & ~SIGN_MASK;
127 return INT_AS_FLOAT(temp);
129 static M3G_INLINE M3Gfloat m3gDiv(const M3Gfloat a, const M3Gfloat b)
133 static M3G_INLINE M3Gfloat m3gDivif(const M3Gint a, const M3Gint b)
135 return m3gDiv((M3Gfloat) a, (M3Gfloat) b);
137 static M3G_INLINE M3Gfloat m3gMadd(const M3Gfloat a, const M3Gfloat b, const M3Gfloat c)
139 return m3gAdd(m3gMul(a, b), c);
141 static M3G_INLINE M3Gfloat m3gRcp(const M3Gfloat x)
145 static M3G_INLINE M3Gfloat m3gSub(const M3Gfloat a, const M3Gfloat b)
147 M3Guint bNeg = FLOAT_AS_UINT(b) ^ SIGN_MASK;
148 return m3gAdd(a, INT_AS_FLOAT(bNeg));
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 */
164 /*----------------------------------------------------------------------
165 * Trigonometric and exp functions
166 *--------------------------------------------------------------------*/
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);
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))
184 /*----------------------------------------------------------------------
185 * Matrix and quaternion stuff
186 *--------------------------------------------------------------------*/
188 static M3Gbool m3gIsWUnity (const Matrix *mtx);
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);
197 /*----------------------------------------------------------------------
199 *--------------------------------------------------------------------*/
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);
206 # define m3gValidateAABB(a)
209 /*----------------------------------------------------------------------
210 * Rounding and conversion
211 *--------------------------------------------------------------------*/
213 static M3Gint m3gRoundToInt(const M3Gfloat a);
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);
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);
227 /*----------------------------------------------------------------------
229 *--------------------------------------------------------------------*/
233 * \brief Multiplies a floating point number by 0.5.
235 * \param x the number to multiply
238 static M3G_INLINE M3Gfloat m3gHalf(M3Gfloat x)
240 M3Guint bits = FLOAT_AS_UINT(x);
242 M3Gint exponent = bits & (mask << 23);
244 exponent = exponent - (1 << 23);
245 if (exponent > 0) bits |= exponent;
246 return INT_AS_FLOAT(bits);
251 * \brief Multiplies a floating point number by two
253 * This does NOT handle overflows.
255 * \param x the number to multiply
258 static M3G_INLINE M3Gfloat m3gDouble(M3Gfloat x)
260 M3Guint bits = FLOAT_AS_UINT(x) + (1 << 23);
261 return INT_AS_FLOAT(bits);
266 * \brief Computes the square of a floating point number
268 * \param x the input number
271 static M3G_INLINE M3Gfloat m3gSquare(M3Gfloat x)
278 * \brief Negates a floating-point value
280 static M3G_INLINE M3Gfloat m3gNegate(M3Gfloat x)
282 M3Guint ix = FLOAT_AS_UINT(x) ^ SIGN_MASK;
283 return INT_AS_FLOAT(ix);
286 #endif /*__M3G_MATH_H__*/