MathFuncs.inl.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "MathDfltHeader.h"
  2. namespace M {
  3. // mathSanityChecks
  4. inline void mathSanityChecks()
  5. {
  6. const int fs = sizeof(float); // float size
  7. if( sizeof(Vec2)!=fs*2 || sizeof(Vec3)!=fs*3 || sizeof(Vec4)!=fs*4 || sizeof(Quat)!=fs*4 ||
  8. sizeof(Euler)!=fs*3 || sizeof(Mat3)!=fs*9 || sizeof(Mat4)!=fs*16 )
  9. {
  10. FATAL( "Your compiler does class alignment" );
  11. }
  12. }
  13. // 1/sqrt(f)
  14. inline float invSqrt( float f )
  15. {
  16. #if defined( PLATFORM_WIN )
  17. float fhalf = 0.5*f;
  18. int i = *(int*)&f;
  19. i = 0x5F3759DF - (i>>1);
  20. f = *(float*)&i;
  21. f *= 1.5 - fhalf*f*f;
  22. return f;
  23. #elif defined( PLATFORM_LINUX )
  24. float fhalf = 0.5*f;
  25. asm
  26. (
  27. "mov %1, %%eax;"
  28. "sar %%eax;"
  29. "mov $0x5F3759DF, %%ebx;"
  30. "sub %%eax, %%ebx;"
  31. "mov %%ebx, %0"
  32. :"=g"(f)
  33. :"g"(f)
  34. :"%eax", "%ebx"
  35. );
  36. f *= 1.5 - fhalf*f*f;
  37. return f;
  38. #else
  39. #error "See file"
  40. #endif
  41. }
  42. // polynomialSinQuadrant
  43. /**
  44. * Used in sinCos
  45. */
  46. inline static float polynomialSinQuadrant( float a )
  47. {
  48. return a * ( 1.0 + a * a * (-0.16666 + a * a * (0.0083143 - a * a * 0.00018542)));
  49. }
  50. // Sine and Cosine
  51. inline void sinCos( float a, float& sina, float& cosa )
  52. {
  53. bool negative = false;
  54. if (a < 0.0)
  55. {
  56. a = -a;
  57. negative = true;
  58. }
  59. const float kTwoOverPi = 1.0 / (PI/2.0);
  60. float floatA = kTwoOverPi * a;
  61. int intA = (int)floatA;
  62. const float k_rational_half_pi = 201 / 128.0;
  63. const float kRemainderHalfPi = 4.8382679e-4;
  64. floatA = (a - k_rational_half_pi * intA) - kRemainderHalfPi * intA;
  65. float floatAMinusHalfPi = (floatA - k_rational_half_pi) - kRemainderHalfPi;
  66. switch( intA & 3 )
  67. {
  68. case 0: // 0 - Pi/2
  69. sina = polynomialSinQuadrant(floatA);
  70. cosa = polynomialSinQuadrant(-floatAMinusHalfPi);
  71. break;
  72. case 1: // Pi/2 - Pi
  73. sina = polynomialSinQuadrant(-floatAMinusHalfPi);
  74. cosa = polynomialSinQuadrant(-floatA);
  75. break;
  76. case 2: // Pi - 3Pi/2
  77. sina = polynomialSinQuadrant(-floatA);
  78. cosa = polynomialSinQuadrant(floatAMinusHalfPi);
  79. break;
  80. case 3: // 3Pi/2 - 2Pi
  81. sina = polynomialSinQuadrant(floatAMinusHalfPi);
  82. cosa = polynomialSinQuadrant(floatA);
  83. break;
  84. };
  85. if( negative )
  86. sina = -sina;
  87. // a unit test
  88. #if defined( DEBUG_ENABLED )
  89. float sina_ = M::sin(a);
  90. float cosa_ = M::cos(a);
  91. DEBUG_ERR( isZero( sina_ - sina ) || isZero( cosa_ - cosa ) );
  92. #endif
  93. }
  94. //======================================================================================================================
  95. // Small funcs =
  96. //======================================================================================================================
  97. inline float sqrt( float f ) { return 1/invSqrt(f); }
  98. inline float toRad( float degrees ) { return degrees*(PI/180.0); }
  99. inline float toDegrees( float rad ) { return rad*(180.0/PI); }
  100. inline float sin( float rad ) { return ::sin(rad); }
  101. inline float cos( float rad ) { return ::cos(rad); }
  102. inline bool isZero( float f ) { return ( fabs(f) < EPSILON ); }
  103. // combineTransformations
  104. // mat4(t0,r0,s0)*mat4(t1,r1,s1) == mat4(tf,rf,sf)
  105. inline void combineTransformations( const Vec3& t0, const Mat3& r0, float s0,
  106. const Vec3& t1, const Mat3& r1, float s1,
  107. Vec3& tf, Mat3& rf, float& sf )
  108. {
  109. tf = t1.getTransformed( t0, r0, s0 );
  110. rf = r0 * r1;
  111. sf = s0 * s1;
  112. }
  113. // combineTransformations as the above but without scale
  114. inline void combineTransformations( const Vec3& t0, const Mat3& r0, const Vec3& t1, const Mat3& r1, Vec3& tf, Mat3& rf)
  115. {
  116. tf = t1.getTransformed( t0, r0 );
  117. rf = r0 * r1;
  118. }
  119. } // end namespace