123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686 |
- #ifndef IRR_MATH_H_INCLUDED
- #define IRR_MATH_H_INCLUDED
- #include "IrrCompileConfig.h"
- #include "irrTypes.h"
- #include <math.h>
- #include <float.h>
- #include <stdlib.h>
- #include <limits.h>
- #if defined(_IRR_SOLARIS_PLATFORM_) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) || defined (_WIN32_WCE)
- #define sqrtf(X) (irr::f32)sqrt((irr::f64)(X))
- #define sinf(X) (irr::f32)sin((irr::f64)(X))
- #define cosf(X) (irr::f32)cos((irr::f64)(X))
- #define asinf(X) (irr::f32)asin((irr::f64)(X))
- #define acosf(X) (irr::f32)acos((irr::f64)(X))
- #define atan2f(X,Y) (irr::f32)atan2((irr::f64)(X),(irr::f64)(Y))
- #define ceilf(X) (irr::f32)ceil((irr::f64)(X))
- #define floorf(X) (irr::f32)floor((irr::f64)(X))
- #define powf(X,Y) (irr::f32)pow((irr::f64)(X),(irr::f64)(Y))
- #define fmodf(X,Y) (irr::f32)fmod((irr::f64)(X),(irr::f64)(Y))
- #define fabsf(X) (irr::f32)fabs((irr::f64)(X))
- #define logf(X) (irr::f32)log((irr::f64)(X))
- #endif
- #ifndef FLT_MAX
- #define FLT_MAX 3.402823466E+38F
- #endif
- #ifndef FLT_MIN
- #define FLT_MIN 1.17549435e-38F
- #endif
- namespace irr
- {
- namespace core
- {
-
- const s32 ROUNDING_ERROR_S32 = 0;
- #ifdef __IRR_HAS_S64
- const s64 ROUNDING_ERROR_S64 = 0;
- #endif
- const f32 ROUNDING_ERROR_f32 = 0.000001f;
- const f64 ROUNDING_ERROR_f64 = 0.00000001;
- #ifdef PI
- #undef PI
- #endif
-
- const f32 PI = 3.14159265359f;
-
- const f32 RECIPROCAL_PI = 1.0f/PI;
-
- const f32 HALF_PI = PI/2.0f;
- #ifdef PI64
- #undef PI64
- #endif
-
- const f64 PI64 = 3.1415926535897932384626433832795028841971693993751;
-
- const f64 RECIPROCAL_PI64 = 1.0/PI64;
-
- const f32 DEGTORAD = PI / 180.0f;
-
- const f32 RADTODEG = 180.0f / PI;
-
- const f64 DEGTORAD64 = PI64 / 180.0;
-
- const f64 RADTODEG64 = 180.0 / PI64;
-
-
- inline f32 radToDeg(f32 radians)
- {
- return RADTODEG * radians;
- }
-
-
- inline f64 radToDeg(f64 radians)
- {
- return RADTODEG64 * radians;
- }
-
-
- inline f32 degToRad(f32 degrees)
- {
- return DEGTORAD * degrees;
- }
-
-
- inline f64 degToRad(f64 degrees)
- {
- return DEGTORAD64 * degrees;
- }
-
- template<class T>
- inline const T& min_(const T& a, const T& b)
- {
- return a < b ? a : b;
- }
-
- template<class T>
- inline const T& min_(const T& a, const T& b, const T& c)
- {
- return a < b ? min_(a, c) : min_(b, c);
- }
-
- template<class T>
- inline const T& max_(const T& a, const T& b)
- {
- return a < b ? b : a;
- }
-
- template<class T>
- inline const T& max_(const T& a, const T& b, const T& c)
- {
- return a < b ? max_(b, c) : max_(a, c);
- }
-
- template<class T>
- inline T abs_(const T& a)
- {
- return a < (T)0 ? -a : a;
- }
-
-
- template<class T>
- inline T lerp(const T& a, const T& b, const f32 t)
- {
- return (T)(a*(1.f-t)) + (b*t);
- }
-
- template <class T>
- inline const T clamp (const T& value, const T& low, const T& high)
- {
- return min_ (max_(value,low), high);
- }
-
-
-
-
-
- template <class T1, class T2>
- inline void swap(T1& a, T2& b)
- {
- T1 c(a);
- a = b;
- b = c;
- }
- template <class T>
- inline T roundingError();
- template <>
- inline f32 roundingError()
- {
- return ROUNDING_ERROR_f32;
- }
- template <>
- inline f64 roundingError()
- {
- return ROUNDING_ERROR_f64;
- }
- template <>
- inline s32 roundingError()
- {
- return ROUNDING_ERROR_S32;
- }
- template <>
- inline u32 roundingError()
- {
- return ROUNDING_ERROR_S32;
- }
- #ifdef __IRR_HAS_S64
- template <>
- inline s64 roundingError()
- {
- return ROUNDING_ERROR_S64;
- }
- template <>
- inline u64 roundingError()
- {
- return ROUNDING_ERROR_S64;
- }
- #endif
- template <class T>
- inline T relativeErrorFactor()
- {
- return 1;
- }
- template <>
- inline f32 relativeErrorFactor()
- {
- return 4;
- }
- template <>
- inline f64 relativeErrorFactor()
- {
- return 8;
- }
-
- template <class T>
- inline bool equals(const T a, const T b, const T tolerance = roundingError<T>())
- {
- return (a + tolerance >= b) && (a - tolerance <= b);
- }
-
-
- template <class T>
- inline bool equalsRelative( const T a, const T b, const T factor = relativeErrorFactor<T>())
- {
-
- const T maxi = max_( a, b);
- const T mini = min_( a, b);
- const T maxMagnitude = max_( maxi, -mini);
- return (maxMagnitude*factor + maxi) == (maxMagnitude*factor + mini);
- }
- union FloatIntUnion32
- {
- FloatIntUnion32(float f1 = 0.0f) : f(f1) {}
-
- bool sign() const { return (i >> 31) != 0; }
- irr::s32 i;
- irr::f32 f;
- };
-
-
- inline bool equalsByUlp(f32 a, f32 b, int maxUlpDiff)
- {
-
-
-
-
-
- const FloatIntUnion32 fa(a);
- const FloatIntUnion32 fb(b);
-
- if ( fa.sign() != fb.sign() )
- {
-
- if (fa.i == fb.i)
- return true;
- return false;
- }
-
- const int ulpsDiff = abs_(fa.i- fb.i);
- if (ulpsDiff <= maxUlpDiff)
- return true;
- return false;
- }
-
- inline bool iszero(const f64 a, const f64 tolerance = ROUNDING_ERROR_f64)
- {
- return fabs(a) <= tolerance;
- }
-
- inline bool iszero(const f32 a, const f32 tolerance = ROUNDING_ERROR_f32)
- {
- return fabsf(a) <= tolerance;
- }
-
- inline bool isnotzero(const f32 a, const f32 tolerance = ROUNDING_ERROR_f32)
- {
- return fabsf(a) > tolerance;
- }
-
- inline bool iszero(const s32 a, const s32 tolerance = 0)
- {
- return ( a & 0x7ffffff ) <= tolerance;
- }
-
- inline bool iszero(const u32 a, const u32 tolerance = 0)
- {
- return a <= tolerance;
- }
- #ifdef __IRR_HAS_S64
-
- inline bool iszero(const s64 a, const s64 tolerance = 0)
- {
- return abs_(a) <= tolerance;
- }
- #endif
- inline s32 s32_min(s32 a, s32 b)
- {
- const s32 mask = (a - b) >> 31;
- return (a & mask) | (b & ~mask);
- }
- inline s32 s32_max(s32 a, s32 b)
- {
- const s32 mask = (a - b) >> 31;
- return (b & mask) | (a & ~mask);
- }
- inline s32 s32_clamp (s32 value, s32 low, s32 high)
- {
- return s32_min(s32_max(value,low), high);
- }
-
- typedef union { u32 u; s32 s; f32 f; } inttofloat;
- #define F32_AS_S32(f) (*((s32 *) &(f)))
- #define F32_AS_U32(f) (*((u32 *) &(f)))
- #define F32_AS_U32_POINTER(f) ( ((u32 *) &(f)))
- #define F32_VALUE_0 0x00000000
- #define F32_VALUE_1 0x3f800000
- #define F32_SIGN_BIT 0x80000000U
- #define F32_EXPON_MANTISSA 0x7FFFFFFFU
-
-
- #ifdef IRRLICHT_FAST_MATH
- #define IR(x) ((u32&)(x))
- #else
- inline u32 IR(f32 x) {inttofloat tmp; tmp.f=x; return tmp.u;}
- #endif
-
- #define AIR(x) (IR(x)&0x7fffffff)
-
- #ifdef IRRLICHT_FAST_MATH
- #define FR(x) ((f32&)(x))
- #else
- inline f32 FR(u32 x) {inttofloat tmp; tmp.u=x; return tmp.f;}
- inline f32 FR(s32 x) {inttofloat tmp; tmp.s=x; return tmp.f;}
- #endif
-
- #define IEEE_1_0 0x3f800000
-
- #define IEEE_255_0 0x437f0000
- #ifdef IRRLICHT_FAST_MATH
- #define F32_LOWER_0(f) (F32_AS_U32(f) > F32_SIGN_BIT)
- #define F32_LOWER_EQUAL_0(f) (F32_AS_S32(f) <= F32_VALUE_0)
- #define F32_GREATER_0(f) (F32_AS_S32(f) > F32_VALUE_0)
- #define F32_GREATER_EQUAL_0(f) (F32_AS_U32(f) <= F32_SIGN_BIT)
- #define F32_EQUAL_1(f) (F32_AS_U32(f) == F32_VALUE_1)
- #define F32_EQUAL_0(f) ( (F32_AS_U32(f) & F32_EXPON_MANTISSA ) == F32_VALUE_0)
-
- #define F32_A_GREATER_B(a,b) (F32_AS_S32((a)) > F32_AS_S32((b)))
- #else
- #define F32_LOWER_0(n) ((n) < 0.0f)
- #define F32_LOWER_EQUAL_0(n) ((n) <= 0.0f)
- #define F32_GREATER_0(n) ((n) > 0.0f)
- #define F32_GREATER_EQUAL_0(n) ((n) >= 0.0f)
- #define F32_EQUAL_1(n) ((n) == 1.0f)
- #define F32_EQUAL_0(n) ((n) == 0.0f)
- #define F32_A_GREATER_B(a,b) ((a) > (b))
- #endif
- #ifndef REALINLINE
- #ifdef _MSC_VER
- #define REALINLINE __forceinline
- #else
- #define REALINLINE inline
- #endif
- #endif
- #if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
-
-
- REALINLINE u32 if_c_a_else_b ( const c8 condition, const u32 a, const u32 b )
- {
- return ( ( -condition >> 7 ) & ( a ^ b ) ) ^ b;
- }
-
- REALINLINE u32 if_c_a_else_0 ( const c8 condition, const u32 a )
- {
- return ( -condition >> 31 ) & a;
- }
- #else
-
- REALINLINE u32 if_c_a_else_b ( const s32 condition, const u32 a, const u32 b )
- {
- return ( ( -condition >> 31 ) & ( a ^ b ) ) ^ b;
- }
-
- REALINLINE u16 if_c_a_else_b ( const s16 condition, const u16 a, const u16 b )
- {
- return ( ( -condition >> 15 ) & ( a ^ b ) ) ^ b;
- }
-
- REALINLINE u32 if_c_a_else_0 ( const s32 condition, const u32 a )
- {
- return ( -condition >> 31 ) & a;
- }
- #endif
-
- REALINLINE void setbit_cond ( u32 &state, s32 condition, u32 mask )
- {
-
-
- state ^= ( ( -condition >> 31 ) ^ state ) & mask;
- }
-
-
-
- inline f32 round_( f32 x )
- {
- return floorf( x + 0.5f );
- }
-
- REALINLINE f32 squareroot(const f32 f)
- {
- return sqrtf(f);
- }
-
- REALINLINE f64 squareroot(const f64 f)
- {
- return sqrt(f);
- }
-
- REALINLINE s32 squareroot(const s32 f)
- {
- return static_cast<s32>(squareroot(static_cast<f32>(f)));
- }
- #ifdef __IRR_HAS_S64
-
- REALINLINE s64 squareroot(const s64 f)
- {
- return static_cast<s64>(squareroot(static_cast<f64>(f)));
- }
- #endif
-
- REALINLINE f64 reciprocal_squareroot(const f64 x)
- {
- return 1.0 / sqrt(x);
- }
-
- REALINLINE f32 reciprocal_squareroot(const f32 f)
- {
- #if defined ( IRRLICHT_FAST_MATH )
-
-
- #if defined(_MSC_VER) && !defined(_WIN64)
-
-
- f32 recsqrt;
- __asm rsqrtss xmm0, f
- __asm movss recsqrt, xmm0
- return recsqrt;
- #else
- return 1.f / sqrtf(f);
- #endif
- #else
- return 1.f / sqrtf(f);
- #endif
- }
-
- REALINLINE s32 reciprocal_squareroot(const s32 x)
- {
- return static_cast<s32>(reciprocal_squareroot(static_cast<f32>(x)));
- }
-
- REALINLINE f32 reciprocal( const f32 f )
- {
- #if defined (IRRLICHT_FAST_MATH)
-
-
-
-
-
- #if defined(_MSC_VER) && !defined(_WIN64)
- f32 rec;
- __asm rcpss xmm0, f
- __asm movss xmm1, f
- __asm mulss xmm1, xmm0
- __asm mulss xmm1, xmm0
- __asm addss xmm0, xmm0
- __asm subss xmm0, xmm1
-
- __asm movss rec, xmm0
- return rec;
- #else
- return 1.f / f;
- #endif
-
-
-
-
-
-
- #else
- return 1.f / f;
- #endif
- }
-
- REALINLINE f64 reciprocal ( const f64 f )
- {
- return 1.0 / f;
- }
-
- REALINLINE f32 reciprocal_approxim ( const f32 f )
- {
- #if defined( IRRLICHT_FAST_MATH)
-
-
-
-
- #if defined(_MSC_VER) && !defined(_WIN64)
- f32 rec;
- __asm rcpss xmm0, f
- __asm movss xmm1, f
- __asm mulss xmm1, xmm0
- __asm mulss xmm1, xmm0
- __asm addss xmm0, xmm0
- __asm subss xmm0, xmm1
-
- __asm movss rec, xmm0
- return rec;
- #else
- return 1.f / f;
- #endif
- #else
- return 1.f / f;
- #endif
- }
- REALINLINE s32 floor32(f32 x)
- {
- return (s32) floorf ( x );
- }
- REALINLINE s32 ceil32 ( f32 x )
- {
- return (s32) ceilf ( x );
- }
-
- REALINLINE s32 round32(f32 x)
- {
- return (s32) round_(x);
- }
- inline f32 f32_max3(const f32 a, const f32 b, const f32 c)
- {
- return a > b ? (a > c ? a : c) : (b > c ? b : c);
- }
- inline f32 f32_min3(const f32 a, const f32 b, const f32 c)
- {
- return a < b ? (a < c ? a : c) : (b < c ? b : c);
- }
- inline f32 fract ( f32 x )
- {
- return x - floorf ( x );
- }
- }
- }
- #ifndef IRRLICHT_FAST_MATH
- using irr::core::IR;
- using irr::core::FR;
- #endif
- #endif
|