BsMath.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #include "BsMath.h"
  2. #include "BsVector2.h"
  3. #include "BsVector3.h"
  4. #include "BsVector4.h"
  5. #include "BsRay.h"
  6. #include "BsSphere.h"
  7. #include "BsAABox.h"
  8. #include "BsPlane.h"
  9. namespace BansheeEngine
  10. {
  11. const float Math::POS_INFINITY = std::numeric_limits<float>::infinity();
  12. const float Math::NEG_INFINITY = -std::numeric_limits<float>::infinity();
  13. const float Math::PI = (float)4.0f * std::atan(1.0f);
  14. const float Math::TWO_PI = (float)(2.0f * PI);
  15. const float Math::HALF_PI = (float)(0.5f * PI);
  16. const float Math::DEG2RAD = PI / 180.0f;
  17. const float Math::RAD2DEG = 180.0f / PI;
  18. const float Math::LOG2 = std::log(2.0f);
  19. Radian Math::acos(float val)
  20. {
  21. if (-1.0f < val)
  22. {
  23. if (val < 1.0f)
  24. return Radian(std::acos(val));
  25. else
  26. return Radian(0.0f);
  27. }
  28. else
  29. {
  30. return Radian(PI);
  31. }
  32. }
  33. Radian Math::asin(float val)
  34. {
  35. if (-1.0f < val)
  36. {
  37. if (val < 1.0f)
  38. return Radian(std::asin(val));
  39. else
  40. return Radian(HALF_PI);
  41. }
  42. else
  43. {
  44. return Radian(-HALF_PI);
  45. }
  46. }
  47. float Math::sign(float val)
  48. {
  49. if (val > 0.0f)
  50. return 1.0f;
  51. if (val < 0.0f)
  52. return -1.0f;
  53. return 0.0f;
  54. }
  55. float Math::invSqrt(float val)
  56. {
  57. return 1.0f/sqrt(val);
  58. }
  59. float Math::fastSin0(float val)
  60. {
  61. float angleSqr = val*val;
  62. float result = 7.61e-03f;
  63. result *= angleSqr;
  64. result -= 1.6605e-01f;
  65. result *= angleSqr;
  66. result += 1.0f;
  67. result *= val;
  68. return result;
  69. }
  70. float Math::fastSin1(float val)
  71. {
  72. float angleSqr = val*val;
  73. float result = -2.39e-08f;
  74. result *= angleSqr;
  75. result += 2.7526e-06f;
  76. result *= angleSqr;
  77. result -= 1.98409e-04f;
  78. result *= angleSqr;
  79. result += 8.3333315e-03f;
  80. result *= angleSqr;
  81. result -= 1.666666664e-01f;
  82. result *= angleSqr;
  83. result += 1.0f;
  84. result *= val;
  85. return result;
  86. }
  87. float Math::fastCos0(float val)
  88. {
  89. float angleSqr = val*val;
  90. float result = 3.705e-02f;
  91. result *= angleSqr;
  92. result -= 4.967e-01f;
  93. result *= angleSqr;
  94. result += 1.0f;
  95. return result;
  96. }
  97. float Math::fastCos1(float val)
  98. {
  99. float angleSqr = val*val;
  100. float result = -2.605e-07f;
  101. result *= angleSqr;
  102. result += 2.47609e-05f;
  103. result *= angleSqr;
  104. result -= 1.3888397e-03f;
  105. result *= angleSqr;
  106. result += 4.16666418e-02f;
  107. result *= angleSqr;
  108. result -= 4.999999963e-01f;
  109. result *= angleSqr;
  110. result += 1.0f;
  111. return result;
  112. }
  113. float Math::fastTan0(float val)
  114. {
  115. float angleSqr = val*val;
  116. float result = 2.033e-01f;
  117. result *= angleSqr;
  118. result += 3.1755e-01f;
  119. result *= angleSqr;
  120. result += 1.0f;
  121. result *= val;
  122. return result;
  123. }
  124. float Math::fastTan1(float val)
  125. {
  126. float angleSqr = val*val;
  127. float result = 9.5168091e-03f;
  128. result *= angleSqr;
  129. result += 2.900525e-03f;
  130. result *= angleSqr;
  131. result += 2.45650893e-02f;
  132. result *= angleSqr;
  133. result += 5.33740603e-02f;
  134. result *= angleSqr;
  135. result += 1.333923995e-01f;
  136. result *= angleSqr;
  137. result += 3.333314036e-01f;
  138. result *= angleSqr;
  139. result += 1.0f;
  140. result *= val;
  141. return result;
  142. }
  143. float Math::fastASin0(float val)
  144. {
  145. float root = sqrt(abs(1.0f - val));
  146. float result = -0.0187293f;
  147. result *= val;
  148. result += 0.0742610f;
  149. result *= val;
  150. result -= 0.2121144f;
  151. result *= val;
  152. result += 1.5707288f;
  153. result = HALF_PI - root*result;
  154. return result;
  155. }
  156. float Math::fastASin1(float val)
  157. {
  158. float root = sqrt(abs(1.0f - val));
  159. float result = -0.0012624911f;
  160. result *= val;
  161. result += 0.0066700901f;
  162. result *= val;
  163. result -= 0.0170881256f;
  164. result *= val;
  165. result += 0.0308918810f;
  166. result *= val;
  167. result -= 0.0501743046f;
  168. result *= val;
  169. result += 0.0889789874f;
  170. result *= val;
  171. result -= 0.2145988016f;
  172. result *= val;
  173. result += 1.5707963050f;
  174. result = HALF_PI - root*result;
  175. return result;
  176. }
  177. float Math::fastACos0(float val)
  178. {
  179. float root = sqrt(abs(1.0f - val));
  180. float result = -0.0187293f;
  181. result *= val;
  182. result += 0.0742610f;
  183. result *= val;
  184. result -= 0.2121144f;
  185. result *= val;
  186. result += 1.5707288f;
  187. result *= root;
  188. return result;
  189. }
  190. float Math::fastACos1(float val)
  191. {
  192. float root = sqrt(abs(1.0f - val));
  193. float result = -0.0012624911f;
  194. result *= val;
  195. result += 0.0066700901f;
  196. result *= val;
  197. result -= 0.0170881256f;
  198. result *= val;
  199. result += 0.0308918810f;
  200. result *= val;
  201. result -= 0.0501743046f;
  202. result *= val;
  203. result += 0.0889789874f;
  204. result *= val;
  205. result -= 0.2145988016f;
  206. result *= val;
  207. result += 1.5707963050f;
  208. result *= root;
  209. return result;
  210. }
  211. float Math::fastATan0(float val)
  212. {
  213. float valueSqr = val*val;
  214. float result = 0.0208351f;
  215. result *= valueSqr;
  216. result -= 0.085133f;
  217. result *= valueSqr;
  218. result += 0.180141f;
  219. result *= valueSqr;
  220. result -= 0.3302995f;
  221. result *= valueSqr;
  222. result += 0.999866f;
  223. result *= val;
  224. return result;
  225. }
  226. float Math::fastATan1(float val)
  227. {
  228. float valueSqr = val*val;
  229. float result = 0.0028662257f;
  230. result *= valueSqr;
  231. result -= 0.0161657367f;
  232. result *= valueSqr;
  233. result += 0.0429096138f;
  234. result *= valueSqr;
  235. result -= 0.0752896400f;
  236. result *= valueSqr;
  237. result += 0.1065626393f;
  238. result *= valueSqr;
  239. result -= 0.1420889944f;
  240. result *= valueSqr;
  241. result += 0.1999355085f;
  242. result *= valueSqr;
  243. result -= 0.3333314528f;
  244. result *= valueSqr;
  245. result += 1.0f;
  246. result *= val;
  247. return result;
  248. }
  249. bool Math::approxEquals(float a, float b, float tolerance)
  250. {
  251. if (fabs(b-a) <= tolerance)
  252. return true;
  253. else
  254. return false;
  255. }
  256. Vector3 Math::calculateTriTangent(const Vector3& position1, const Vector3& position2,
  257. const Vector3& position3, float u1, float v1, float u2, float v2, float u3, float v3)
  258. {
  259. Vector3 side0 = position1 - position2;
  260. Vector3 side1 = position3 - position1;
  261. // Calculate face normal
  262. Vector3 normal = side1.cross(side0);
  263. normal.normalize();
  264. // Now we use a formula to calculate the tangent.
  265. float deltaV0 = v1 - v2;
  266. float deltaV1 = v3 - v1;
  267. Vector3 tangent = deltaV1 * side0 - deltaV0 * side1;
  268. tangent.normalize();
  269. // Calculate binormal
  270. float deltaU0 = u1 - u2;
  271. float deltaU1 = u3 - u1;
  272. Vector3 binormal = deltaU1 * side0 - deltaU0 * side1;
  273. binormal.normalize();
  274. // Now, we take the cross product of the tangents to get a vector which
  275. // should point in the same direction as our normal calculated above.
  276. // If it points in the opposite direction (the dot product between the normals is less than zero),
  277. // then we need to reverse the s and t tangents.
  278. // This is because the triangle has been mirrored when going from tangent space to object space.
  279. // reverse tangents if necessary.
  280. Vector3 tangentCross = tangent.cross(binormal);
  281. if (tangentCross.dot(normal) < 0.0f)
  282. {
  283. tangent = -tangent;
  284. binormal = -binormal;
  285. }
  286. return tangent;
  287. }
  288. }