6 @maintainer Morgan McGuire, matrix@graphics3d.com
7 @cite highestBit by Jukka Liimatta
12 Copyright 2000-2006, Morgan McGuire.
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)
27 #include "G3D/platform.h"
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
47 #include "G3D/debug.h"
57 Win32 implementation of the C99 fast rounding routines.
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
) {
80 __inline
long int lrintf(float flt
) {
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
104 static const double i
= 1.0/sin(0.0);
106 // double is a standard type and should have infinity
107 static const double i
= std::numeric_limits
<double>::infinity();
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
120 static const double n
= 0.0/sin(0.0);
122 // double is a standard type and should have quiet NaN
123 static const double n
= std::numeric_limits
<double>::quiet_NaN();
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;
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;
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;
147 @deprecated Use G3D::pi() instead. */
148 #define G3D_PI (3.1415926535898)
150 @deprecated Use G3D::halfPi() instead. */
151 #define G3D_HALF_PI (1.5707963267949)
153 @deprecated Use G3D::twoPi() instead. */
154 #define G3D_TWO_PI (6.283185)
156 typedef signed char int8
;
157 typedef unsigned char uint8
;
159 typedef unsigned short uint16
;
161 typedef unsigned int uint32
;
163 #ifdef _MSC_EXTENSIONS
164 typedef __int64 int64
;
165 typedef unsigned __int64 uint64
;
167 typedef long long int64
;
168 typedef unsigned long long uint64
;
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
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
);
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
);
223 Fast round to integer using the lrint routine.
224 Typically 6x faster than casting to integer.
226 inline int iRound(float f
) {
231 Returns a random number uniformly at random between low and hi
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
);
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
);
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
);
323 inline T
min(const T
& x
, const T
& y
) {
324 return std::min
<T
>(x
, y
);
328 inline T
max(const T
& x
, const T
& y
) {
329 return std::max
<T
>(x
, y
);
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
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)
397 return 1.0f
/ sqrt(x
);
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
406 int ceilPow2(unsigned int in
);
409 * True if num is a power of two.
411 bool isPow2(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
) {
427 Returns true if x is not exactly equal to 0.0f.
429 inline bool all(float x
) {
434 v / v (for DirectX/Cg support)
436 inline float normalize(float v
) {
441 a * b (for DirectX/Cg support)
443 inline float dot(float a
, float b
) {
449 a * b (for DirectX/Cg support)
451 inline float mul(float a
, float b
) {
458 inline double exp2(double x
) {
462 inline double rsqrt(double x
) {
463 return 1.0 / sqrt(x
);
470 inline double sinc(double x
) {
471 double r
= sin(x
) / x
;
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
)) {
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
);
504 # pragma warning (pop)
507 #include "g3dmath.inl"