MathFuncs.inl.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. #if !defined(DEBUG)
  44. /**
  45. * Used in sinCos
  46. */
  47. inline static float polynomialSinQuadrant( float a )
  48. {
  49. return a * ( 1.0 + a * a * (-0.16666 + a * a * (0.0083143 - a * a * 0.00018542)));
  50. }
  51. #endif
  52. // Sine and Cosine
  53. inline void sinCos( float a, float& sina, float& cosa )
  54. {
  55. #ifdef DEBUG
  56. sina = M::sin(a);
  57. cosa = M::cos(a);
  58. #else
  59. bool negative = false;
  60. if (a < 0.0)
  61. {
  62. a = -a;
  63. negative = true;
  64. }
  65. const float kTwoOverPi = 1.0 / (PI/2.0);
  66. float floatA = kTwoOverPi * a;
  67. int intA = (int)floatA;
  68. const float k_rational_half_pi = 201 / 128.0;
  69. const float kRemainderHalfPi = 4.8382679e-4;
  70. floatA = (a - k_rational_half_pi * intA) - kRemainderHalfPi * intA;
  71. float floatAMinusHalfPi = (floatA - k_rational_half_pi) - kRemainderHalfPi;
  72. switch( intA & 3 )
  73. {
  74. case 0: // 0 - Pi/2
  75. sina = polynomialSinQuadrant(floatA);
  76. cosa = polynomialSinQuadrant(-floatAMinusHalfPi);
  77. break;
  78. case 1: // Pi/2 - Pi
  79. sina = polynomialSinQuadrant(-floatAMinusHalfPi);
  80. cosa = polynomialSinQuadrant(-floatA);
  81. break;
  82. case 2: // Pi - 3Pi/2
  83. sina = polynomialSinQuadrant(-floatA);
  84. cosa = polynomialSinQuadrant(floatAMinusHalfPi);
  85. break;
  86. case 3: // 3Pi/2 - 2Pi
  87. sina = polynomialSinQuadrant(floatAMinusHalfPi);
  88. cosa = polynomialSinQuadrant(floatA);
  89. break;
  90. };
  91. if( negative )
  92. sina = -sina;
  93. #endif
  94. }
  95. //======================================================================================================================
  96. // Small funcs =
  97. //======================================================================================================================
  98. inline float sqrt( float f ) { return 1/invSqrt(f); }
  99. inline float toRad( float degrees ) { return degrees*(PI/180.0); }
  100. inline float toDegrees( float rad ) { return rad*(180.0/PI); }
  101. inline float sin( float rad ) { return ::sin(rad); }
  102. inline float cos( float rad ) { return ::cos(rad); }
  103. inline bool isZero( float f ) { return ( fabs(f) < EPSILON ); }
  104. // combineTransformations
  105. // mat4(t0,r0,s0)*mat4(t1,r1,s1) == mat4(tf,rf,sf)
  106. inline void combineTransformations( const Vec3& t0, const Mat3& r0, float s0,
  107. const Vec3& t1, const Mat3& r1, float s1,
  108. Vec3& tf, Mat3& rf, float& sf )
  109. {
  110. tf = t1.getTransformed( t0, r0, s0 );
  111. rf = r0 * r1;
  112. sf = s0 * s1;
  113. }
  114. // combineTransformations as the above but without scale
  115. inline void combineTransformations( const Vec3& t0, const Mat3& r0, const Vec3& t1, const Mat3& r1, Vec3& tf, Mat3& rf)
  116. {
  117. tf = t1.getTransformed( t0, r0 );
  118. rf = r0 * r1;
  119. }
  120. } // end namespace