BsMath.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsPrerequisitesUtil.h"
  5. #include "BsDegree.h"
  6. #include "BsRadian.h"
  7. #include "BsVector3.h"
  8. namespace bs
  9. {
  10. /** @addtogroup Math
  11. * @{
  12. */
  13. /** Utility class providing common scalar math operations. */
  14. class BS_UTILITY_EXPORT Math
  15. {
  16. public:
  17. static Radian acos(float val);
  18. static Radian asin(float val);
  19. static Radian atan(float val) { return Radian(std::atan(val)); }
  20. static Radian atan2(float y, float x) { return Radian(std::atan2(y,x)); }
  21. static float cos(const Radian& val) { return (float)std::cos(val.valueRadians()); }
  22. static float cos(float val) { return (float)std::cos(val); }
  23. static float sin(const Radian& val) { return (float)std::sin(val.valueRadians()); }
  24. static float sin(float val) { return (float)std::sin(val); }
  25. static float tan(const Radian& val) { return (float)std::tan(val.valueRadians()); }
  26. static float tan(float val) { return (float)std::tan(val); }
  27. static float sqrt(float val) { return (float)std::sqrt(val); }
  28. static Radian sqrt(const Radian& val) { return Radian(std::sqrt(val.valueRadians())); }
  29. static Degree sqrt(const Degree& val) { return Degree(std::sqrt(val.valueDegrees())); }
  30. static float invSqrt(float val);
  31. static float sqr(float val) { return val*val; }
  32. static float pow(float base, float exponent) { return (float)std::pow(base, exponent); }
  33. static float exp(float val) { return (float)std::exp(val); }
  34. static float log(float val) { return (float)std::log(val); }
  35. static float log2(float val) { return (float)(std::log(val)/LOG2); }
  36. static float logN(float base, float val) { return (float)(std::log(val)/std::log(base)); }
  37. static float sign(float val);
  38. static Radian sign(const Radian& val) { return Radian(sign(val.valueRadians())); }
  39. static Degree sign(const Degree& val) { return Degree(sign(val.valueDegrees())); }
  40. static float abs(float val) { return float(std::fabs(val)); }
  41. static Degree abs(const Degree& val) { return Degree(std::fabs(val.valueDegrees())); }
  42. static Radian abs(const Radian& val) { return Radian(std::fabs(val.valueRadians())); }
  43. static float ceil(float val) { return (float)std::ceil(val); }
  44. static int ceilToInt(float val) { return (int)std::ceil(val); }
  45. static float round(float val) { return (float)std::floor(val + 0.5f); }
  46. static int roundToInt(float val) { return (int)std::floor(val + 0.5f); }
  47. static float floor(float val) { return (float)std::floor(val); }
  48. static int floorToInt(float val) { return (int)std::floor(val); }
  49. /** Clamp a value within an inclusive range. */
  50. template <typename T>
  51. static T clamp(T val, T minval, T maxval)
  52. {
  53. assert (minval <= maxval && "Invalid clamp range");
  54. return std::max(std::min(val, maxval), minval);
  55. }
  56. /** Clamp a value within an inclusive range [0..1]. */
  57. template <typename T>
  58. static T clamp01(T val)
  59. {
  60. return std::max(std::min(val, (T)1), (T)0);
  61. }
  62. static bool isNaN(float f)
  63. {
  64. return f != f;
  65. }
  66. /** Compare two floats, using tolerance for inaccuracies. */
  67. static bool approxEquals(float a, float b,
  68. float tolerance = std::numeric_limits<float>::epsilon())
  69. {
  70. return fabs(b - a) <= tolerance;
  71. }
  72. /** Compare two doubles, using tolerance for inaccuracies. */
  73. static bool approxEquals(double a, double b,
  74. double tolerance = std::numeric_limits<double>::epsilon())
  75. {
  76. return fabs(b - a) <= tolerance;
  77. }
  78. /** Compare two 2D vectors, using tolerance for inaccuracies. */
  79. static bool approxEquals(const Vector2& a, const Vector2& b,
  80. float tolerance = std::numeric_limits<float>::epsilon());
  81. /** Compare two 3D vectors, using tolerance for inaccuracies. */
  82. static bool approxEquals(const Vector3& a, const Vector3& b,
  83. float tolerance = std::numeric_limits<float>::epsilon());
  84. /** Compare two 4D vectors, using tolerance for inaccuracies. */
  85. static bool approxEquals(const Vector4& a, const Vector4& b,
  86. float tolerance = std::numeric_limits<float>::epsilon());
  87. /** Compare two quaternions, using tolerance for inaccuracies. */
  88. static bool approxEquals(const Quaternion& a, const Quaternion& b,
  89. float tolerance = std::numeric_limits<float>::epsilon());
  90. /** Calculates the tangent space vector for a given set of positions / texture coords. */
  91. static Vector3 calculateTriTangent(const Vector3& position1, const Vector3& position2,
  92. const Vector3& position3, float u1, float v1, float u2, float v2, float u3, float v3);
  93. /************************************************************************/
  94. /* TRIG APPROXIMATIONS */
  95. /************************************************************************/
  96. /**
  97. * Sine function approximation.
  98. *
  99. * @param[in] val Angle in range [0, pi/2].
  100. *
  101. * @note Evaluates trigonometric functions using polynomial approximations.
  102. */
  103. static float fastSin0(const Radian& val) { return (float)fastASin0(val.valueRadians()); }
  104. /**
  105. * Sine function approximation.
  106. *
  107. * @param[in] val Angle in range [0, pi/2].
  108. *
  109. * @note Evaluates trigonometric functions using polynomial approximations.
  110. */
  111. static float fastSin0(float val);
  112. /**
  113. * Sine function approximation.
  114. *
  115. * @param[in] val Angle in range [0, pi/2].
  116. *
  117. * @note
  118. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastSin0.
  119. */
  120. static float fastSin1(const Radian& val) { return (float)fastASin1(val.valueRadians()); }
  121. /**
  122. * Sine function approximation.
  123. *
  124. * @param[in] val Angle in range [0, pi/2].
  125. *
  126. * @note
  127. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastSin0.
  128. */
  129. static float fastSin1(float val);
  130. /**
  131. * Cosine function approximation.
  132. *
  133. * @param[in] val Angle in range [0, pi/2].
  134. *
  135. * @note Evaluates trigonometric functions using polynomial approximations.
  136. */
  137. static float fastCos0(const Radian& val) { return (float)fastACos0(val.valueRadians()); }
  138. /**
  139. * Cosine function approximation.
  140. *
  141. * @param[in] val Angle in range [0, pi/2].
  142. *
  143. * @note Evaluates trigonometric functions using polynomial approximations.
  144. */
  145. static float fastCos0(float val);
  146. /**
  147. * Cosine function approximation.
  148. *
  149. * @param[in] val Angle in range [0, pi/2].
  150. *
  151. * @note
  152. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastCos0.
  153. */
  154. static float fastCos1(const Radian& val) { return (float)fastACos1(val.valueRadians()); }
  155. /**
  156. * Cosine function approximation.
  157. *
  158. * @param[in] val Angle in range [0, pi/2].
  159. *
  160. * @note
  161. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastCos0.
  162. */
  163. static float fastCos1(float val);
  164. /**
  165. * Tangent function approximation.
  166. *
  167. * @param[in] val Angle in range [0, pi/4].
  168. *
  169. * @note Evaluates trigonometric functions using polynomial approximations.
  170. */
  171. static float fastTan0(const Radian& val) { return (float)fastATan0(val.valueRadians()); }
  172. /**
  173. * Tangent function approximation.
  174. *
  175. * @param[in] val Angle in range [0, pi/4].
  176. *
  177. * @note Evaluates trigonometric functions using polynomial approximations.
  178. */
  179. static float fastTan0(float val);
  180. /**
  181. * Tangent function approximation.
  182. *
  183. * @param[in] val Angle in range [0, pi/4].
  184. *
  185. * @note
  186. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastTan0.
  187. */
  188. static float fastTan1(const Radian& val) { return (float)fastATan1(val.valueRadians()); }
  189. /**
  190. * Tangent function approximation.
  191. *
  192. * @param[in] val Angle in range [0, pi/4].
  193. *
  194. * @note
  195. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastTan0.
  196. */
  197. static float fastTan1(float val);
  198. /**
  199. * Inverse sine function approximation.
  200. *
  201. * @param[in] val Angle in range [0, 1].
  202. *
  203. * @note Evaluates trigonometric functions using polynomial approximations.
  204. */
  205. static float fastASin0(const Radian& val) { return (float)fastASin0(val.valueRadians()); }
  206. /**
  207. * Inverse sine function approximation.
  208. *
  209. * @param[in] val Angle in range [0, 1].
  210. *
  211. * @note Evaluates trigonometric functions using polynomial approximations.
  212. */
  213. static float fastASin0(float val);
  214. /**
  215. * Inverse sine function approximation.
  216. *
  217. * @param[in] val Angle in range [0, 1].
  218. *
  219. * @note
  220. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastASin0.
  221. */
  222. static float fastASin1(const Radian& val) { return (float)fastASin1(val.valueRadians()); }
  223. /**
  224. * Inverse sine function approximation.
  225. *
  226. * @param[in] val Angle in range [0, 1].
  227. *
  228. * @note
  229. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastASin0.
  230. */
  231. static float fastASin1(float val);
  232. /**
  233. * Inverse cosine function approximation.
  234. *
  235. * @param[in] val Angle in range [0, 1].
  236. *
  237. * @note Evaluates trigonometric functions using polynomial approximations.
  238. */
  239. static float fastACos0(const Radian& val) { return (float)fastACos0(val.valueRadians()); }
  240. /**
  241. * Inverse cosine function approximation.
  242. *
  243. * @param[in] val Angle in range [0, 1].
  244. *
  245. * @note Evaluates trigonometric functions using polynomial approximations.
  246. */
  247. static float fastACos0(float val);
  248. /**
  249. * Inverse cosine function approximation.
  250. *
  251. * @param[in] val Angle in range [0, 1].
  252. *
  253. * @note
  254. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastACos0.
  255. */
  256. static float fastACos1(const Radian& val) { return (float)fastACos1(val.valueRadians()); }
  257. /**
  258. * Inverse cosine function approximation.
  259. *
  260. * @param[in] val Angle in range [0, 1].
  261. *
  262. * @note
  263. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastACos0.
  264. */
  265. static float fastACos1(float val);
  266. /**
  267. * Inverse tangent function approximation.
  268. *
  269. * @param[in] val Angle in range [-1, 1].
  270. *
  271. * @note Evaluates trigonometric functions using polynomial approximations.
  272. */
  273. static float fastATan0(const Radian& val) { return (float)fastATan0(val.valueRadians()); }
  274. /**
  275. * Inverse tangent function approximation.
  276. *
  277. * @param[in] val Angle in range [-1, 1].
  278. *
  279. * @note Evaluates trigonometric functions using polynomial approximations.
  280. */
  281. static float fastATan0(float val);
  282. /**
  283. * Inverse tangent function approximation.
  284. *
  285. * @param[in] val Angle in range [-1, 1].
  286. *
  287. * @note
  288. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastATan0.
  289. */
  290. static float fastATan1(const Radian& val) { return (float)fastATan1(val.valueRadians()); }
  291. /**
  292. * Inverse tangent function approximation.
  293. *
  294. * @param[in] val Angle in range [-1, 1].
  295. *
  296. * @note
  297. * Evaluates trigonometric functions using polynomial approximations. Slightly better (and slower) than fastATan0.
  298. */
  299. static float fastATan1(float val);
  300. /**
  301. * Interpolates between min and max. Returned value is in [0, 1] range where min = 0, max = 1 and 0.5 is
  302. * the average of min and max.
  303. */
  304. template <typename T>
  305. static float lerp01(T val, T min, T max)
  306. {
  307. return clamp01((val - min) / std::max(max - min, 0.0001F));
  308. }
  309. /**
  310. * Solves the linear equation with the parameters A, B. Returns number of roots found and the roots themselves will
  311. * be output in the @p roots array.
  312. *
  313. * @param[in] A First variable.
  314. * @param[in] B Second variable.
  315. * @param[out] roots Must be at least size of 1.
  316. *
  317. * @note Only returns real roots.
  318. */
  319. template <typename T>
  320. static UINT32 solveLinear(T A, T B, T* roots)
  321. {
  322. if (!approxEquals(A, (T)0))
  323. {
  324. roots[0] = -B / A;
  325. return 1;
  326. }
  327. roots[0] = 0.0f;
  328. return 1;
  329. }
  330. /**
  331. * Solves the quadratic equation with the parameters A, B, C. Returns number of roots found and the roots themselves
  332. * will be output in the @p roots array.
  333. *
  334. * @param[in] A First variable.
  335. * @param[in] B Second variable.
  336. * @param[in] C Third variable.
  337. * @param[out] roots Must be at least size of 2.
  338. *
  339. * @note Only returns real roots.
  340. */
  341. template <typename T>
  342. static UINT32 solveQuadratic(T A, T B, T C, T* roots)
  343. {
  344. if (!approxEquals(A, (T)0))
  345. {
  346. T p = B / (2 * A);
  347. T q = C / A;
  348. T D = p * p - q;
  349. if (!approxEquals(D, (T)0))
  350. {
  351. if (D < (T)0)
  352. return 0;
  353. T sqrtD = sqrt(D);
  354. roots[0] = sqrtD - p;
  355. roots[1] = -sqrtD - p;
  356. return 2;
  357. }
  358. else
  359. {
  360. roots[0] = -p;
  361. roots[1] = -p;
  362. return 1;
  363. }
  364. }
  365. else
  366. {
  367. return solveLinear(B, C, roots);
  368. }
  369. }
  370. /**
  371. * Solves the cubic equation with the parameters A, B, C, D. Returns number of roots found and the roots themselves
  372. * will be output in the @p roots array.
  373. *
  374. * @param[in] A First variable.
  375. * @param[in] B Second variable.
  376. * @param[in] C Third variable.
  377. * @param[in] D Fourth variable.
  378. * @param[out] roots Must be at least size of 3.
  379. *
  380. * @note Only returns real roots.
  381. */
  382. template <typename T>
  383. static UINT32 solveCubic(T A, T B, T C, T D, T* roots)
  384. {
  385. static const T THIRD = (1 / (T)3);
  386. T invA = 1 / A;
  387. A = B * invA;
  388. B = C * invA;
  389. C = D * invA;
  390. T sqA = A * A;
  391. T p = THIRD * (-THIRD * sqA + B);
  392. T q = ((T)0.5) * ((2 / (T)27) * A * sqA - THIRD * A * B + C);
  393. T cbp = p * p * p;
  394. D = q * q + cbp;
  395. UINT32 numRoots = 0;
  396. if (!approxEquals(D, (T)0))
  397. {
  398. if (D < 0.0)
  399. {
  400. T phi = THIRD * ::acos(-q / sqrt(-cbp));
  401. T t = 2 * sqrt(-p);
  402. roots[0] = t * cos(phi);
  403. roots[1] = -t * cos(phi + PI * THIRD);
  404. roots[2] = -t * cos(phi - PI * THIRD);
  405. numRoots = 3;
  406. }
  407. else
  408. {
  409. T sqrtD = sqrt(D);
  410. T u = cbrt(sqrtD + fabs(q));
  411. if (q > (T)0)
  412. roots[0] = -u + p / u;
  413. else
  414. roots[0] = u - p / u;
  415. numRoots = 1;
  416. }
  417. }
  418. else
  419. {
  420. if (!approxEquals(q, (T)0))
  421. {
  422. T u = cbrt(-q);
  423. roots[0] = 2 * u;
  424. roots[1] = -u;
  425. numRoots = 2;
  426. }
  427. else
  428. {
  429. roots[0] = 0.0f;
  430. numRoots = 1;
  431. }
  432. }
  433. T sub = THIRD * A;
  434. for (UINT32 i = 0; i < numRoots; i++)
  435. roots[i] -= sub;
  436. return numRoots;
  437. }
  438. /**
  439. * Solves the quartic equation with the parameters A, B, C, D, E. Returns number of roots found and the roots
  440. * themselves will be output in the @p roots array.
  441. *
  442. * @param[in] A First variable.
  443. * @param[in] B Second variable.
  444. * @param[in] C Third variable.
  445. * @param[in] D Fourth variable.
  446. * @param[in] E Fifth variable.
  447. * @param[out] roots Must be at least size of 4.
  448. *
  449. * @note Only returns real roots.
  450. */
  451. template <typename T>
  452. static UINT32 solveQuartic(T A, T B, T C, T D, T E, T* roots)
  453. {
  454. T invA = 1 / A;
  455. A = B * invA;
  456. B = C * invA;
  457. C = D * invA;
  458. D = E * invA;
  459. T sqA = A*A;
  460. T p = -(3 / (T)8) * sqA + B;
  461. T q = (1 / (T)8) * sqA * A - (T)0.5 * A * B + C;
  462. T r = -(3 / (T)256) * sqA * sqA + (1 / (T)16) * sqA * B - (1 / (T)4) * A * C + D;
  463. UINT32 numRoots = 0;
  464. if (!approxEquals(r, (T)0))
  465. {
  466. T cubicA = 1;
  467. T cubicB = -(T)0.5 * p ;
  468. T cubicC = -r;
  469. T cubicD = (T)0.5 * r * p - (1 / (T)8) * q * q;
  470. solveCubic(cubicA, cubicB, cubicC, cubicD, roots);
  471. T z = roots[0];
  472. T u = z * z - r;
  473. T v = 2 * z - p;
  474. if (approxEquals(u, T(0)))
  475. u = 0;
  476. else if (u > 0)
  477. u = sqrt(u);
  478. else
  479. return 0;
  480. if (approxEquals(v, T(0)))
  481. v = 0;
  482. else if (v > 0)
  483. v = sqrt(v);
  484. else
  485. return 0;
  486. T quadraticA = 1;
  487. T quadraticB = q < 0 ? -v : v;
  488. T quadraticC = z - u;
  489. numRoots = solveQuadratic(quadraticA, quadraticB, quadraticC, roots);
  490. quadraticA = 1;
  491. quadraticB = q < 0 ? v : -v;
  492. quadraticC = z + u;
  493. numRoots += solveQuadratic(quadraticA, quadraticB, quadraticC, roots + numRoots);
  494. }
  495. else
  496. {
  497. numRoots = solveCubic(q, p, (T)0, (T)1, roots);
  498. roots[numRoots++] = 0;
  499. }
  500. T sub = (1/(T)4) * A;
  501. for (UINT32 i = 0; i < numRoots; i++)
  502. roots[i] -= sub;
  503. return numRoots;
  504. }
  505. /**
  506. * Evaluates a cubic Hermite curve at a specific point.
  507. *
  508. * @param[in] t Parameter that at which to evaluate the curve, in range [0, 1].
  509. * @param[in] pointA Starting point (at t=0).
  510. * @param[in] pointB Ending point (at t=1).
  511. * @param[in] tangentA Starting tangent (at t=0).
  512. * @param[in] tangentB Ending tangent (at t = 1).
  513. * @return Evaluated value at @p t.
  514. */
  515. template<class T>
  516. static T cubicHermite(float t, const T& pointA, const T& pointB, const T& tangentA, const T& tangentB)
  517. {
  518. float t2 = t * t;
  519. float t3 = t2 * t;
  520. float a = 2 * t3 - 3 * t2 + 1;
  521. float b = t3 - 2 * t2 + t;
  522. float c = -2 * t3 + 3 * t2;
  523. float d = t3 - t2;
  524. return a * pointA + b * tangentA + c * pointB + d * tangentB;
  525. }
  526. /**
  527. * Evaluates the first derivative of a cubic Hermite curve at a specific point.
  528. *
  529. * @param[in] t Parameter that at which to evaluate the curve, in range [0, 1].
  530. * @param[in] pointA Starting point (at t=0).
  531. * @param[in] pointB Ending point (at t=1).
  532. * @param[in] tangentA Starting tangent (at t=0).
  533. * @param[in] tangentB Ending tangent (at t = 1).
  534. * @return Evaluated value at @p t.
  535. */
  536. template<class T>
  537. static T cubicHermiteD1(float t, const T& pointA, const T& pointB, const T& tangentA, const T& tangentB)
  538. {
  539. float t2 = t * t;
  540. float a = 6 * t2 - 6 * t;
  541. float b = 3 * t2 - 4 * t + 1;
  542. float c = -6 * t2 + 6 * t;
  543. float d = 3 * t2 - 2 * t;
  544. return a * pointA + b * tangentA + c * pointB + d * tangentB;
  545. }
  546. /**
  547. * Calculates coefficients needed for evaluating a cubic curve in Hermite form. Assumes @p t has been normalized is
  548. * in range [0, 1]. Tangents must be scaled by the length of the curve (length is the maximum value of @p t before
  549. * it was normalized).
  550. *
  551. * @param[in] pointA Starting point (at t=0).
  552. * @param[in] pointB Ending point (at t=1).
  553. * @param[in] tangentA Starting tangent (at t=0).
  554. * @param[in] tangentB Ending tangent (at t = 1).
  555. * @param[out] coefficients Four coefficients for the cubic curve, in order [t^3, t^2, t, 1].
  556. */
  557. template<class T>
  558. static void cubicHermiteCoefficients(const T& pointA, const T& pointB, const T& tangentA, const T& tangentB,
  559. T (&coefficients)[4])
  560. {
  561. T diff = pointA - pointB;
  562. coefficients[0] = 2 * diff + tangentA + tangentB;
  563. coefficients[1] = -3 * diff - 2 * tangentA - tangentB;
  564. coefficients[2] = tangentA;
  565. coefficients[3] = pointA;
  566. }
  567. /**
  568. * Calculates coefficients needed for evaluating a cubic curve in Hermite form. Assumes @p t is in range
  569. * [0, @p length]. Tangents must not be scaled by @p length.
  570. *
  571. * @param[in] pointA Starting point (at t=0).
  572. * @param[in] pointB Ending point (at t=length).
  573. * @param[in] tangentA Starting tangent (at t=0).
  574. * @param[in] tangentB Ending tangent (at t=length).
  575. * @param[in] length Maximum value the curve will be evaluated at.
  576. * @param[out] coefficients Four coefficients for the cubic curve, in order [t^3, t^2, t, 1].
  577. */
  578. template<class T>
  579. static void cubicHermiteCoefficients(const T& pointA, const T& pointB, const T& tangentA, const T& tangentB,
  580. float length, T (&coefficients)[4])
  581. {
  582. float length2 = length * length;
  583. float invLength2 = 1.0f / length2;
  584. float invLength3 = 1.0f / (length2 * length);
  585. T scaledTangentA = tangentA * length;
  586. T scaledTangentB = tangentB * length;
  587. T diff = pointA - pointB;
  588. coefficients[0] = (2 * diff + scaledTangentA + scaledTangentB) * invLength3;
  589. coefficients[1] = (-3 * diff - 2 * scaledTangentA - scaledTangentB) * invLength2;
  590. coefficients[2] = tangentA;
  591. coefficients[3] = pointA;
  592. }
  593. static const float POS_INFINITY;
  594. static const float NEG_INFINITY;
  595. static const float PI;
  596. static const float TWO_PI;
  597. static const float HALF_PI;
  598. static const float DEG2RAD;
  599. static const float RAD2DEG;
  600. static const float LOG2;
  601. };
  602. /** @} */
  603. }