[4054] added: Line of sight (vmaps) [part 1]
[mangos-git.git] / dep / include / g3dlite / G3D / g3dmath.h
bloba4183ed255ee6daefe98e8658450ac1c3dc191a7
1 /**
2 @file g3dmath.h
4 Math util class.
6 @maintainer Morgan McGuire, matrix@graphics3d.com
7 @cite highestBit by Jukka Liimatta
9 @created 2001-06-02
10 @edited 2006-01-16
12 Copyright 2000-2006, Morgan McGuire.
13 All rights reserved.
16 #ifndef G3DMATH_H
17 #define G3DMATH_H
19 #ifdef _MSC_VER
20 // Disable conditional expression is constant, which occurs incorrectly on inlined functions
21 # pragma warning (push)
22 # pragma warning (disable : 4127)
23 // disable: "C++ exception handler used"
24 # pragma warning (disable : 4530)
25 #endif
27 #include "G3D/platform.h"
28 #include <ctype.h>
29 #include <string>
30 #include <float.h>
31 #include <limits>
33 /*These defines enable functionality introduced with the 1999 ISO C
34 **standard. They must be defined before the inclusion of math.h to
35 **engage them. If optimisation is enabled, these functions will be
36 **inlined. With optimisation switched off, you have to link in the
37 **maths library using -lm.
40 #define _ISOC9X_SOURCE1
41 #define _ISOC99_SOURCE1
42 #define __USE_ISOC9X1
43 #define __USE_ISOC991
45 #include <math.h>
47 #include "G3D/debug.h"
49 #undef min
50 #undef max
52 namespace G3D {
54 #ifdef _MSC_VER
56 /**
57 Win32 implementation of the C99 fast rounding routines.
59 @cite routines are
60 Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
62 Permission to use, copy, modify, distribute, and sell this file for any
63 purpose is hereby granted without fee, provided that the above copyright
64 and this permission notice appear in all copies. No representations are
65 made about the suitability of this software for any purpose. It is
66 provided "as is" without express or implied warranty.
69 __inline long int lrint (double flt) {
70 int intgr;
72 _asm {
73 fld flt
74 fistp intgr
77 return intgr;
80 __inline long int lrintf(float flt) {
81 int intgr;
83 _asm {
84 fld flt
85 fistp intgr
88 return intgr;
90 #endif
94 const double fuzzyEpsilon = 0.00001;
96 /** Returns a reference to a static double.
97 This value should not be tested against directly, instead
98 G3D::isNan() and G3D::isFinite() will return reliable results. */
99 inline const double& inf() {
101 // We already have <limits> included but
102 // not using it in older gcc for safe compilations
103 #if (__GNUC__ == 2)
104 static const double i = 1.0/sin(0.0);
105 #else
106 // double is a standard type and should have infinity
107 static const double i = std::numeric_limits<double>::infinity();
108 #endif
109 return i;
112 /** Returns a reference to a static double.
113 This value should not be tested against directly, instead
114 G3D::isNan() and G3D::isFinite() will return reliable results. */
115 inline const double& nan() {
117 // We already have <limits> included but
118 // not using it in older gcc for safe compilations
119 #if (__GNUC__ == 2)
120 static const double n = 0.0/sin(0.0);
121 #else
122 // double is a standard type and should have quiet NaN
123 static const double n = std::numeric_limits<double>::quiet_NaN();
124 #endif
125 return n;
128 /** Returns a reference to a static double. Use instead of G3D_PI. */
129 inline const double& pi() {
130 static const double p = 3.1415926535898;
131 return p;
134 /** Returns a reference to a static double. Use instead of G3D_HALF_PI. */
135 inline const double& halfPi() {
136 static const double p = 1.5707963267949;
137 return p;
140 /** Returns a reference to a static double. Use instead of G3D_TWO_PI. */
141 inline const double& twoPi() {
142 static const double p = 6.283185;
143 return p;
146 /** @def G3D_PI
147 @deprecated Use G3D::pi() instead. */
148 #define G3D_PI (3.1415926535898)
149 /** @def G3D_HALF_PI
150 @deprecated Use G3D::halfPi() instead. */
151 #define G3D_HALF_PI (1.5707963267949)
152 /** @def G3D_TWO_PI
153 @deprecated Use G3D::twoPi() instead. */
154 #define G3D_TWO_PI (6.283185)
156 typedef signed char int8;
157 typedef unsigned char uint8;
158 typedef short int16;
159 typedef unsigned short uint16;
160 typedef int int32;
161 typedef unsigned int uint32;
163 #ifdef _MSC_EXTENSIONS
164 typedef __int64 int64;
165 typedef unsigned __int64 uint64;
166 #else
167 typedef long long int64;
168 typedef unsigned long long uint64;
169 #endif
170 typedef unsigned int uint;
172 typedef float float32;
173 typedef double float64;
175 int iAbs(int iValue);
176 int iCeil(double fValue);
179 Clamps the value to the range [low, hi] (inclusive)
181 int iClamp(int val, int low, int hi);
182 double clamp(double val, double low, double hi);
183 float clamp(float val, float low, float hi);
186 Returns a + (b - a) * f;
188 inline double lerp(double a, double b, double f) {
189 return a + (b - a) * f;
192 inline float lerp(float a, float b, float f) {
193 return a + (b - a) * f;
197 Wraps the value to the range [0, hi) (exclusive
198 on the high end). This is like the clock arithmetic
199 produced by % (modulo) except the result is guaranteed
200 to be positive.
202 int iWrap(int val, int hi);
204 int iFloor(double fValue);
206 int iSign(int iValue);
207 int iSign(double fValue);
209 inline int iSign(float f) {
210 return iSign((double)f);
214 /**
215 Fast round to integer using the lrint routine.
216 Typically 6x faster than casting to integer.
218 inline int iRound(double fValue) {
219 return lrint(fValue);
222 /**
223 Fast round to integer using the lrint routine.
224 Typically 6x faster than casting to integer.
226 inline int iRound(float f) {
227 return lrintf(f);
231 Returns a random number uniformly at random between low and hi
232 (inclusive).
234 int iRandom(int low, int hi);
236 double abs (double fValue);
237 double aCos (double fValue);
238 double aSin (double fValue);
239 double aTan (double fValue);
240 double aTan2 (double fY, double fX);
241 double sign (double fValue);
242 double square (double fValue);
245 Returns true if the argument is a finite real number.
247 bool isFinite(double x);
250 Returns true if the argument is NaN (not a number).
251 You can't use x == nan to test this because all
252 comparisons against nan return false.
254 bool isNaN(double x);
257 Computes x % 3.
259 int iMod3(int x);
261 /**
262 [0, 1]
263 @deprecated use uniformRandom()
265 double unitRandom ();
268 Uniform random number between low and hi, inclusive.
269 @deprecated use uniformRandom()
271 double random(double low, double hi);
274 [-1, 1]
275 @deprecated use uniformRandom()
277 double symmetricRandom ();
280 Uniform random number between low and hi, inclusive. [low, hi]
282 float uniformRandom(float low = 0.0f, float hi = 1.0f);
285 Normally distributed random number.
287 float gaussRandom(float mean = 0.0f, float stdev = 1.0f);
289 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
291 /** VC6 lacks std::min and std::max */
292 inline double min(double x, double y) {
293 return std::_cpp_min(x, y);
296 /** VC6 lacks std::min and std::max */
297 inline float min(float x, float y) {
298 return std::_cpp_min(x, y);
301 /** VC6 lacks std::min and std::max */
302 inline int min(int x, int y) {
303 return std::_cpp_min(x, y);
306 /** VC6 lacks std::min and std::max */
307 inline double max(double x, double y) {
308 return std::_cpp_max(x, y);
311 /** VC6 lacks std::min and std::max */
312 inline float max(float x, float y) {
313 return std::_cpp_max(x, y);
316 /** VC6 lacks std::min and std::max */
317 inline int max(int x, int y) {
318 return std::_cpp_max(x, y);
321 #else
322 template <class T>
323 inline T min(const T& x, const T& y) {
324 return std::min<T>(x, y);
327 template <class T>
328 inline T max(const T& x, const T& y) {
329 return std::max<T>(x, y);
332 #endif
334 int iMin(int x, int y);
335 int iMax(int x, int y);
337 double square(double x);
338 double sumSquares(double x, double y);
339 double sumSquares(double x, double y, double z);
340 double distance(double x, double y);
341 double distance(double x, double y, double z);
344 Returnes the 0-based index of the highest 1 bit from
345 the left. -1 means the number was 0.
347 @cite Based on code by jukka@liimatta.org
349 int highestBit(uint32 x);
352 Note that fuzzyEq(a, b) && fuzzyEq(b, c) does not imply
353 fuzzyEq(a, c), although that will be the case on some
354 occasions.
356 bool fuzzyEq(double a, double b);
358 /** True if a is definitely not equal to b.
359 Guaranteed false if a == b.
360 Possibly false when a != b.*/
361 bool fuzzyNe(double a, double b);
363 /** Is a strictly greater than b? (Guaranteed false if a <= b).
364 (Possibly false if a > b) */
365 bool fuzzyGt(double a, double b);
367 /** Is a near or greater than b? */
368 bool fuzzyGe(double a, double b);
370 /** Is a strictly less than b? (Guaranteed false if a >= b)*/
371 bool fuzzyLt(double a, double b);
373 /** Is a near or less than b? */
374 bool fuzzyLe(double a, double b);
377 Computes 1 / sqrt(x).
379 inline float rsq(float x) {
380 return 1.0f / sqrtf(x);
384 Uses SSE to implement rsq.
385 @cite Nick nicolas@capens.net
387 inline float SSErsq(float x) {
389 #if defined(SSE) && defined(G3D_WIN32)
390 __asm {
391 movss xmm0, x
392 rsqrtss xmm0, xmm0
393 movss x, xmm0
395 return x;
396 #else
397 return 1.0f / sqrt(x);
398 #endif
402 Return the next power of 2 higher than the input
403 If the input is already a power of 2, the output will be the same
404 as the input.
406 int ceilPow2(unsigned int in);
409 * True if num is a power of two.
411 bool isPow2(int num);
413 bool isOdd(int num);
414 bool isEven(int num);
416 double toRadians(double deg);
417 double toDegrees(double rad);
420 Returns true if x is not exactly equal to 0.0f.
422 inline bool any(float x) {
423 return x != 0;
427 Returns true if x is not exactly equal to 0.0f.
429 inline bool all(float x) {
430 return x != 0;
434 v / v (for DirectX/Cg support)
436 inline float normalize(float v) {
437 return v / v;
441 a * b (for DirectX/Cg support)
443 inline float dot(float a, float b) {
444 return a * b;
449 a * b (for DirectX/Cg support)
451 inline float mul(float a, float b) {
452 return a * b;
458 inline double exp2(double x) {
459 return pow(2.0, x);
462 inline double rsqrt(double x) {
463 return 1.0 / sqrt(x);
468 sin(x)/x
470 inline double sinc(double x) {
471 double r = sin(x) / x;
473 if (isNaN(r)) {
474 return 1.0;
475 } else {
476 return r;
481 Computes a floating point modulo; the result is t wrapped to the range [lo, hi).
483 inline double wrap(double t, double lo, double hi) {
484 if ((t >= lo) && (t < hi)) {
485 return t;
488 debugAssert(hi > lo);
490 double interval = hi - lo;
492 return t - interval * iFloor((t - lo) / interval);
496 inline double wrap(double t, double hi) {
497 return wrap(t, 0, hi);
501 } // namespace
503 #ifdef _MSC_VER
504 # pragma warning (pop)
505 #endif
507 #include "g3dmath.inl"
509 #endif