MathFuncs.inl.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include "MathCommon.inl.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. THROW_EXCEPTION("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. /*RASSERT_THROW_EXCEPTION(!isZero(M::sin(a) - sina));
  88. RASSERT_THROW_EXCEPTION(!isZero(M::cos(a) - cosa));*/
  89. }
  90. //======================================================================================================================
  91. // Small funcs =
  92. //======================================================================================================================
  93. inline float sqrt(float f)
  94. {
  95. return 1/invSqrt(f);
  96. }
  97. inline float toRad(float degrees)
  98. {
  99. return degrees*(PI/180.0);
  100. }
  101. inline float toDegrees(float rad)
  102. {
  103. return rad*(180.0/PI);
  104. }
  105. inline float sin(float rad)
  106. {
  107. return ::sin(rad);
  108. }
  109. inline float cos(float rad)
  110. {
  111. return ::cos(rad);
  112. }
  113. inline bool isZero(float f)
  114. {
  115. return (fabs(f) < EPSILON);
  116. }
  117. // combineTransformations
  118. // mat4(t0,r0,s0)*mat4(t1,r1,s1) == mat4(tf,rf,sf)
  119. inline void combineTransformations(const Vec3& t0, const Mat3& r0, float s0,
  120. const Vec3& t1, const Mat3& r1, float s1,
  121. Vec3& tf, Mat3& rf, float& sf)
  122. {
  123. tf = t1.getTransformed(t0, r0, s0);
  124. rf = r0 * r1;
  125. sf = s0 * s1;
  126. }
  127. // combineTransformations as the above but without scale
  128. inline void combineTransformations(const Vec3& t0, const Mat3& r0, const Vec3& t1, const Mat3& r1, Vec3& tf, Mat3& rf)
  129. {
  130. tf = t1.getTransformed(t0, r0);
  131. rf = r0 * r1;
  132. }
  133. } // end namespace