Math.h 21 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. // ----------------------------------------------------------------
  2. // From Game Programming in C++ by Sanjay Madhav
  3. // Copyright (C) 2017 Sanjay Madhav. All rights reserved.
  4. //
  5. // Released under the BSD License
  6. // See LICENSE in root directory for full details.
  7. // ----------------------------------------------------------------
  8. #pragma once
  9. #include <cmath>
  10. #include <memory.h>
  11. #include <limits>
  12. namespace Math
  13. {
  14. const float Pi = 3.1415926535f;
  15. const float TwoPi = Pi * 2.0f;
  16. const float PiOver2 = Pi / 2.0f;
  17. const float Infinity = std::numeric_limits<float>::infinity();
  18. const float NegInfinity = -std::numeric_limits<float>::infinity();
  19. inline float ToRadians(float degrees)
  20. {
  21. return degrees * Pi / 180.0f;
  22. }
  23. inline float ToDegrees(float radians)
  24. {
  25. return radians * 180.0f / Pi;
  26. }
  27. inline bool NearZero(float val, float epsilon = 0.001f)
  28. {
  29. if (fabs(val) <= epsilon)
  30. {
  31. return true;
  32. }
  33. else
  34. {
  35. return false;
  36. }
  37. }
  38. template <typename T>
  39. T Max(const T& a, const T& b)
  40. {
  41. return (a < b ? b : a);
  42. }
  43. template <typename T>
  44. T Min(const T& a, const T& b)
  45. {
  46. return (a < b ? a : b);
  47. }
  48. template <typename T>
  49. T Clamp(const T& value, const T& lower, const T& upper)
  50. {
  51. return Min(upper, Max(lower, value));
  52. }
  53. inline float Abs(float value)
  54. {
  55. return fabs(value);
  56. }
  57. inline float Cos(float angle)
  58. {
  59. return cosf(angle);
  60. }
  61. inline float Sin(float angle)
  62. {
  63. return sinf(angle);
  64. }
  65. inline float Tan(float angle)
  66. {
  67. return tanf(angle);
  68. }
  69. inline float Acos(float value)
  70. {
  71. return acosf(value);
  72. }
  73. inline float Atan2(float y, float x)
  74. {
  75. return atan2f(y, x);
  76. }
  77. inline float Cot(float angle)
  78. {
  79. return 1.0f / Tan(angle);
  80. }
  81. inline float Lerp(float a, float b, float f)
  82. {
  83. return a + f * (b - a);
  84. }
  85. inline float Sqrt(float value)
  86. {
  87. return sqrtf(value);
  88. }
  89. inline float Fmod(float numer, float denom)
  90. {
  91. return fmod(numer, denom);
  92. }
  93. }
  94. // 2D Vector
  95. class Vector2
  96. {
  97. public:
  98. float x;
  99. float y;
  100. Vector2()
  101. :x(0.0f)
  102. ,y(0.0f)
  103. {}
  104. explicit Vector2(float inX, float inY)
  105. :x(inX)
  106. ,y(inY)
  107. {}
  108. // Set both components in one line
  109. void Set(float inX, float inY)
  110. {
  111. x = inX;
  112. y = inY;
  113. }
  114. // Vector addition (a + b)
  115. friend Vector2 operator+(const Vector2& a, const Vector2& b)
  116. {
  117. return Vector2(a.x + b.x, a.y + b.y);
  118. }
  119. // Vector subtraction (a - b)
  120. friend Vector2 operator-(const Vector2& a, const Vector2& b)
  121. {
  122. return Vector2(a.x - b.x, a.y - b.y);
  123. }
  124. // Component-wise multiplication
  125. // (a.x * b.x, ...)
  126. friend Vector2 operator*(const Vector2& a, const Vector2& b)
  127. {
  128. return Vector2(a.x * b.x, a.y * b.y);
  129. }
  130. // Scalar multiplication
  131. friend Vector2 operator*(const Vector2& vec, float scalar)
  132. {
  133. return Vector2(vec.x * scalar, vec.y * scalar);
  134. }
  135. // Scalar multiplication
  136. friend Vector2 operator*(float scalar, const Vector2& vec)
  137. {
  138. return Vector2(vec.x * scalar, vec.y * scalar);
  139. }
  140. // Scalar *=
  141. Vector2& operator*=(float scalar)
  142. {
  143. x *= scalar;
  144. y *= scalar;
  145. return *this;
  146. }
  147. // Vector +=
  148. Vector2& operator+=(const Vector2& right)
  149. {
  150. x += right.x;
  151. y += right.y;
  152. return *this;
  153. }
  154. // Vector -=
  155. Vector2& operator-=(const Vector2& right)
  156. {
  157. x -= right.x;
  158. y -= right.y;
  159. return *this;
  160. }
  161. // Length squared of vector
  162. float LengthSq() const
  163. {
  164. return (x*x + y*y);
  165. }
  166. // Length of vector
  167. float Length() const
  168. {
  169. return (Math::Sqrt(LengthSq()));
  170. }
  171. // Normalize this vector
  172. void Normalize()
  173. {
  174. float length = Length();
  175. x /= length;
  176. y /= length;
  177. }
  178. // Normalize the provided vector
  179. static Vector2 Normalize(const Vector2& vec)
  180. {
  181. Vector2 temp = vec;
  182. temp.Normalize();
  183. return temp;
  184. }
  185. // Dot product between two vectors (a dot b)
  186. static float Dot(const Vector2& a, const Vector2& b)
  187. {
  188. return (a.x * b.x + a.y * b.y);
  189. }
  190. // Lerp from A to B by f
  191. static Vector2 Lerp(const Vector2& a, const Vector2& b, float f)
  192. {
  193. return Vector2(a + f * (b - a));
  194. }
  195. // Reflect V about (normalized) N
  196. static Vector2 Reflect(const Vector2& v, const Vector2& n)
  197. {
  198. return v - 2.0f * Vector2::Dot(v, n) * n;
  199. }
  200. // Transform vector by matrix
  201. static Vector2 Transform(const Vector2& vec, const class Matrix3& mat, float w = 1.0f);
  202. static const Vector2 Zero;
  203. static const Vector2 UnitX;
  204. static const Vector2 UnitY;
  205. static const Vector2 NegUnitX;
  206. static const Vector2 NegUnitY;
  207. };
  208. // 3D Vector
  209. class Vector3
  210. {
  211. public:
  212. float x;
  213. float y;
  214. float z;
  215. Vector3()
  216. :x(0.0f)
  217. ,y(0.0f)
  218. ,z(0.0f)
  219. {}
  220. explicit Vector3(float inX, float inY, float inZ)
  221. :x(inX)
  222. ,y(inY)
  223. ,z(inZ)
  224. {}
  225. // Cast to a const float pointer
  226. const float* GetAsFloatPtr() const
  227. {
  228. return reinterpret_cast<const float*>(&x);
  229. }
  230. // Set all three components in one line
  231. void Set(float inX, float inY, float inZ)
  232. {
  233. x = inX;
  234. y = inY;
  235. z = inZ;
  236. }
  237. // Vector addition (a + b)
  238. friend Vector3 operator+(const Vector3& a, const Vector3& b)
  239. {
  240. return Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
  241. }
  242. // Vector subtraction (a - b)
  243. friend Vector3 operator-(const Vector3& a, const Vector3& b)
  244. {
  245. return Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
  246. }
  247. // Component-wise multiplication
  248. friend Vector3 operator*(const Vector3& left, const Vector3& right)
  249. {
  250. return Vector3(left.x * right.x, left.y * right.y, left.z * right.z);
  251. }
  252. // Scalar multiplication
  253. friend Vector3 operator*(const Vector3& vec, float scalar)
  254. {
  255. return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
  256. }
  257. // Scalar multiplication
  258. friend Vector3 operator*(float scalar, const Vector3& vec)
  259. {
  260. return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
  261. }
  262. // Scalar *=
  263. Vector3& operator*=(float scalar)
  264. {
  265. x *= scalar;
  266. y *= scalar;
  267. z *= scalar;
  268. return *this;
  269. }
  270. // Vector +=
  271. Vector3& operator+=(const Vector3& right)
  272. {
  273. x += right.x;
  274. y += right.y;
  275. z += right.z;
  276. return *this;
  277. }
  278. // Vector -=
  279. Vector3& operator-=(const Vector3& right)
  280. {
  281. x -= right.x;
  282. y -= right.y;
  283. z -= right.z;
  284. return *this;
  285. }
  286. // Length squared of vector
  287. float LengthSq() const
  288. {
  289. return (x*x + y*y + z*z);
  290. }
  291. // Length of vector
  292. float Length() const
  293. {
  294. return (Math::Sqrt(LengthSq()));
  295. }
  296. // Normalize this vector
  297. void Normalize()
  298. {
  299. float length = Length();
  300. x /= length;
  301. y /= length;
  302. z /= length;
  303. }
  304. // Normalize the provided vector
  305. static Vector3 Normalize(const Vector3& vec)
  306. {
  307. Vector3 temp = vec;
  308. temp.Normalize();
  309. return temp;
  310. }
  311. // Dot product between two vectors (a dot b)
  312. static float Dot(const Vector3& a, const Vector3& b)
  313. {
  314. return (a.x * b.x + a.y * b.y + a.z * b.z);
  315. }
  316. // Cross product between two vectors (a cross b)
  317. static Vector3 Cross(const Vector3& a, const Vector3& b)
  318. {
  319. Vector3 temp;
  320. temp.x = a.y * b.z - a.z * b.y;
  321. temp.y = a.z * b.x - a.x * b.z;
  322. temp.z = a.x * b.y - a.y * b.x;
  323. return temp;
  324. }
  325. // Lerp from A to B by f
  326. static Vector3 Lerp(const Vector3& a, const Vector3& b, float f)
  327. {
  328. return Vector3(a + f * (b - a));
  329. }
  330. // Reflect V about (normalized) N
  331. static Vector3 Reflect(const Vector3& v, const Vector3& n)
  332. {
  333. return v - 2.0f * Vector3::Dot(v, n) * n;
  334. }
  335. static Vector3 Transform(const Vector3& vec, const class Matrix4& mat, float w = 1.0f);
  336. // This will transform the vector and renormalize the w component
  337. static Vector3 TransformWithPerspDiv(const Vector3& vec, const class Matrix4& mat, float w = 1.0f);
  338. // Transform a Vector3 by a quaternion
  339. static Vector3 Transform(const Vector3& v, const class Quaternion& q);
  340. static const Vector3 Zero;
  341. static const Vector3 UnitX;
  342. static const Vector3 UnitY;
  343. static const Vector3 UnitZ;
  344. static const Vector3 NegUnitX;
  345. static const Vector3 NegUnitY;
  346. static const Vector3 NegUnitZ;
  347. static const Vector3 Infinity;
  348. static const Vector3 NegInfinity;
  349. };
  350. // 3x3 Matrix
  351. class Matrix3
  352. {
  353. public:
  354. float mat[3][3];
  355. Matrix3()
  356. {
  357. *this = Matrix3::Identity;
  358. }
  359. explicit Matrix3(float inMat[3][3])
  360. {
  361. memcpy(mat, inMat, 9 * sizeof(float));
  362. }
  363. // Cast to a const float pointer
  364. const float* GetAsFloatPtr() const
  365. {
  366. return reinterpret_cast<const float*>(&mat[0][0]);
  367. }
  368. // Matrix multiplication
  369. friend Matrix3 operator*(const Matrix3& left, const Matrix3& right)
  370. {
  371. Matrix3 retVal;
  372. // row 0
  373. retVal.mat[0][0] =
  374. left.mat[0][0] * right.mat[0][0] +
  375. left.mat[0][1] * right.mat[1][0] +
  376. left.mat[0][2] * right.mat[2][0];
  377. retVal.mat[0][1] =
  378. left.mat[0][0] * right.mat[0][1] +
  379. left.mat[0][1] * right.mat[1][1] +
  380. left.mat[0][2] * right.mat[2][1];
  381. retVal.mat[0][2] =
  382. left.mat[0][0] * right.mat[0][2] +
  383. left.mat[0][1] * right.mat[1][2] +
  384. left.mat[0][2] * right.mat[2][2];
  385. // row 1
  386. retVal.mat[1][0] =
  387. left.mat[1][0] * right.mat[0][0] +
  388. left.mat[1][1] * right.mat[1][0] +
  389. left.mat[1][2] * right.mat[2][0];
  390. retVal.mat[1][1] =
  391. left.mat[1][0] * right.mat[0][1] +
  392. left.mat[1][1] * right.mat[1][1] +
  393. left.mat[1][2] * right.mat[2][1];
  394. retVal.mat[1][2] =
  395. left.mat[1][0] * right.mat[0][2] +
  396. left.mat[1][1] * right.mat[1][2] +
  397. left.mat[1][2] * right.mat[2][2];
  398. // row 2
  399. retVal.mat[2][0] =
  400. left.mat[2][0] * right.mat[0][0] +
  401. left.mat[2][1] * right.mat[1][0] +
  402. left.mat[2][2] * right.mat[2][0];
  403. retVal.mat[2][1] =
  404. left.mat[2][0] * right.mat[0][1] +
  405. left.mat[2][1] * right.mat[1][1] +
  406. left.mat[2][2] * right.mat[2][1];
  407. retVal.mat[2][2] =
  408. left.mat[2][0] * right.mat[0][2] +
  409. left.mat[2][1] * right.mat[1][2] +
  410. left.mat[2][2] * right.mat[2][2];
  411. return retVal;
  412. }
  413. Matrix3& operator*=(const Matrix3& right)
  414. {
  415. *this = *this * right;
  416. return *this;
  417. }
  418. // Create a scale matrix with x and y scales
  419. static Matrix3 CreateScale(float xScale, float yScale)
  420. {
  421. float temp[3][3] =
  422. {
  423. { xScale, 0.0f, 0.0f },
  424. { 0.0f, yScale, 0.0f },
  425. { 0.0f, 0.0f, 1.0f },
  426. };
  427. return Matrix3(temp);
  428. }
  429. static Matrix3 CreateScale(const Vector2& scaleVector)
  430. {
  431. return CreateScale(scaleVector.x, scaleVector.y);
  432. }
  433. // Create a scale matrix with a uniform factor
  434. static Matrix3 CreateScale(float scale)
  435. {
  436. return CreateScale(scale, scale);
  437. }
  438. // Create a rotation matrix about the Z axis
  439. // theta is in radians
  440. static Matrix3 CreateRotation(float theta)
  441. {
  442. float temp[3][3] =
  443. {
  444. { Math::Cos(theta), Math::Sin(theta), 0.0f },
  445. { -Math::Sin(theta), Math::Cos(theta), 0.0f },
  446. { 0.0f, 0.0f, 1.0f },
  447. };
  448. return Matrix3(temp);
  449. }
  450. // Create a translation matrix (on the xy-plane)
  451. static Matrix3 CreateTranslation(const Vector2& trans)
  452. {
  453. float temp[3][3] =
  454. {
  455. { 1.0f, 0.0f, 0.0f },
  456. { 0.0f, 1.0f, 0.0f },
  457. { trans.x, trans.y, 1.0f },
  458. };
  459. return Matrix3(temp);
  460. }
  461. static const Matrix3 Identity;
  462. };
  463. // 4x4 Matrix
  464. class Matrix4
  465. {
  466. public:
  467. float mat[4][4];
  468. Matrix4()
  469. {
  470. *this = Matrix4::Identity;
  471. }
  472. explicit Matrix4(float inMat[4][4])
  473. {
  474. memcpy(mat, inMat, 16 * sizeof(float));
  475. }
  476. // Cast to a const float pointer
  477. const float* GetAsFloatPtr() const
  478. {
  479. return reinterpret_cast<const float*>(&mat[0][0]);
  480. }
  481. // Matrix multiplication (a * b)
  482. friend Matrix4 operator*(const Matrix4& a, const Matrix4& b)
  483. {
  484. Matrix4 retVal;
  485. // row 0
  486. retVal.mat[0][0] =
  487. a.mat[0][0] * b.mat[0][0] +
  488. a.mat[0][1] * b.mat[1][0] +
  489. a.mat[0][2] * b.mat[2][0] +
  490. a.mat[0][3] * b.mat[3][0];
  491. retVal.mat[0][1] =
  492. a.mat[0][0] * b.mat[0][1] +
  493. a.mat[0][1] * b.mat[1][1] +
  494. a.mat[0][2] * b.mat[2][1] +
  495. a.mat[0][3] * b.mat[3][1];
  496. retVal.mat[0][2] =
  497. a.mat[0][0] * b.mat[0][2] +
  498. a.mat[0][1] * b.mat[1][2] +
  499. a.mat[0][2] * b.mat[2][2] +
  500. a.mat[0][3] * b.mat[3][2];
  501. retVal.mat[0][3] =
  502. a.mat[0][0] * b.mat[0][3] +
  503. a.mat[0][1] * b.mat[1][3] +
  504. a.mat[0][2] * b.mat[2][3] +
  505. a.mat[0][3] * b.mat[3][3];
  506. // row 1
  507. retVal.mat[1][0] =
  508. a.mat[1][0] * b.mat[0][0] +
  509. a.mat[1][1] * b.mat[1][0] +
  510. a.mat[1][2] * b.mat[2][0] +
  511. a.mat[1][3] * b.mat[3][0];
  512. retVal.mat[1][1] =
  513. a.mat[1][0] * b.mat[0][1] +
  514. a.mat[1][1] * b.mat[1][1] +
  515. a.mat[1][2] * b.mat[2][1] +
  516. a.mat[1][3] * b.mat[3][1];
  517. retVal.mat[1][2] =
  518. a.mat[1][0] * b.mat[0][2] +
  519. a.mat[1][1] * b.mat[1][2] +
  520. a.mat[1][2] * b.mat[2][2] +
  521. a.mat[1][3] * b.mat[3][2];
  522. retVal.mat[1][3] =
  523. a.mat[1][0] * b.mat[0][3] +
  524. a.mat[1][1] * b.mat[1][3] +
  525. a.mat[1][2] * b.mat[2][3] +
  526. a.mat[1][3] * b.mat[3][3];
  527. // row 2
  528. retVal.mat[2][0] =
  529. a.mat[2][0] * b.mat[0][0] +
  530. a.mat[2][1] * b.mat[1][0] +
  531. a.mat[2][2] * b.mat[2][0] +
  532. a.mat[2][3] * b.mat[3][0];
  533. retVal.mat[2][1] =
  534. a.mat[2][0] * b.mat[0][1] +
  535. a.mat[2][1] * b.mat[1][1] +
  536. a.mat[2][2] * b.mat[2][1] +
  537. a.mat[2][3] * b.mat[3][1];
  538. retVal.mat[2][2] =
  539. a.mat[2][0] * b.mat[0][2] +
  540. a.mat[2][1] * b.mat[1][2] +
  541. a.mat[2][2] * b.mat[2][2] +
  542. a.mat[2][3] * b.mat[3][2];
  543. retVal.mat[2][3] =
  544. a.mat[2][0] * b.mat[0][3] +
  545. a.mat[2][1] * b.mat[1][3] +
  546. a.mat[2][2] * b.mat[2][3] +
  547. a.mat[2][3] * b.mat[3][3];
  548. // row 3
  549. retVal.mat[3][0] =
  550. a.mat[3][0] * b.mat[0][0] +
  551. a.mat[3][1] * b.mat[1][0] +
  552. a.mat[3][2] * b.mat[2][0] +
  553. a.mat[3][3] * b.mat[3][0];
  554. retVal.mat[3][1] =
  555. a.mat[3][0] * b.mat[0][1] +
  556. a.mat[3][1] * b.mat[1][1] +
  557. a.mat[3][2] * b.mat[2][1] +
  558. a.mat[3][3] * b.mat[3][1];
  559. retVal.mat[3][2] =
  560. a.mat[3][0] * b.mat[0][2] +
  561. a.mat[3][1] * b.mat[1][2] +
  562. a.mat[3][2] * b.mat[2][2] +
  563. a.mat[3][3] * b.mat[3][2];
  564. retVal.mat[3][3] =
  565. a.mat[3][0] * b.mat[0][3] +
  566. a.mat[3][1] * b.mat[1][3] +
  567. a.mat[3][2] * b.mat[2][3] +
  568. a.mat[3][3] * b.mat[3][3];
  569. return retVal;
  570. }
  571. Matrix4& operator*=(const Matrix4& right)
  572. {
  573. *this = *this * right;
  574. return *this;
  575. }
  576. // Invert the matrix - super slow
  577. void Invert();
  578. // Get the translation component of the matrix
  579. Vector3 GetTranslation() const
  580. {
  581. return Vector3(mat[3][0], mat[3][1], mat[3][2]);
  582. }
  583. // Get the X axis of the matrix (forward)
  584. Vector3 GetXAxis() const
  585. {
  586. return Vector3::Normalize(Vector3(mat[0][0], mat[0][1], mat[0][2]));
  587. }
  588. // Get the Y axis of the matrix (left)
  589. Vector3 GetYAxis() const
  590. {
  591. return Vector3::Normalize(Vector3(mat[1][0], mat[1][1], mat[1][2]));
  592. }
  593. // Get the Z axis of the matrix (up)
  594. Vector3 GetZAxis() const
  595. {
  596. return Vector3::Normalize(Vector3(mat[2][0], mat[2][1], mat[2][2]));
  597. }
  598. // Extract the scale component from the matrix
  599. Vector3 GetScale() const
  600. {
  601. Vector3 retVal;
  602. retVal.x = Vector3(mat[0][0], mat[0][1], mat[0][2]).Length();
  603. retVal.y = Vector3(mat[1][0], mat[1][1], mat[1][2]).Length();
  604. retVal.z = Vector3(mat[2][0], mat[2][1], mat[2][2]).Length();
  605. return retVal;
  606. }
  607. // Create a scale matrix with x, y, and z scales
  608. static Matrix4 CreateScale(float xScale, float yScale, float zScale)
  609. {
  610. float temp[4][4] =
  611. {
  612. { xScale, 0.0f, 0.0f, 0.0f },
  613. { 0.0f, yScale, 0.0f, 0.0f },
  614. { 0.0f, 0.0f, zScale, 0.0f },
  615. { 0.0f, 0.0f, 0.0f, 1.0f }
  616. };
  617. return Matrix4(temp);
  618. }
  619. static Matrix4 CreateScale(const Vector3& scaleVector)
  620. {
  621. return CreateScale(scaleVector.x, scaleVector.y, scaleVector.z);
  622. }
  623. // Create a scale matrix with a uniform factor
  624. static Matrix4 CreateScale(float scale)
  625. {
  626. return CreateScale(scale, scale, scale);
  627. }
  628. // Rotation about x-axis
  629. static Matrix4 CreateRotationX(float theta)
  630. {
  631. float temp[4][4] =
  632. {
  633. { 1.0f, 0.0f, 0.0f , 0.0f },
  634. { 0.0f, Math::Cos(theta), Math::Sin(theta), 0.0f },
  635. { 0.0f, -Math::Sin(theta), Math::Cos(theta), 0.0f },
  636. { 0.0f, 0.0f, 0.0f, 1.0f },
  637. };
  638. return Matrix4(temp);
  639. }
  640. // Rotation about y-axis
  641. static Matrix4 CreateRotationY(float theta)
  642. {
  643. float temp[4][4] =
  644. {
  645. { Math::Cos(theta), 0.0f, -Math::Sin(theta), 0.0f },
  646. { 0.0f, 1.0f, 0.0f, 0.0f },
  647. { Math::Sin(theta), 0.0f, Math::Cos(theta), 0.0f },
  648. { 0.0f, 0.0f, 0.0f, 1.0f },
  649. };
  650. return Matrix4(temp);
  651. }
  652. // Rotation about z-axis
  653. static Matrix4 CreateRotationZ(float theta)
  654. {
  655. float temp[4][4] =
  656. {
  657. { Math::Cos(theta), Math::Sin(theta), 0.0f, 0.0f },
  658. { -Math::Sin(theta), Math::Cos(theta), 0.0f, 0.0f },
  659. { 0.0f, 0.0f, 1.0f, 0.0f },
  660. { 0.0f, 0.0f, 0.0f, 1.0f },
  661. };
  662. return Matrix4(temp);
  663. }
  664. // Create a rotation matrix from a quaternion
  665. static Matrix4 CreateFromQuaternion(const class Quaternion& q);
  666. static Matrix4 CreateTranslation(const Vector3& trans)
  667. {
  668. float temp[4][4] =
  669. {
  670. { 1.0f, 0.0f, 0.0f, 0.0f },
  671. { 0.0f, 1.0f, 0.0f, 0.0f },
  672. { 0.0f, 0.0f, 1.0f, 0.0f },
  673. { trans.x, trans.y, trans.z, 1.0f }
  674. };
  675. return Matrix4(temp);
  676. }
  677. static Matrix4 CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
  678. {
  679. Vector3 zaxis = Vector3::Normalize(target - eye);
  680. Vector3 xaxis = Vector3::Normalize(Vector3::Cross(up, zaxis));
  681. Vector3 yaxis = Vector3::Normalize(Vector3::Cross(zaxis, xaxis));
  682. Vector3 trans;
  683. trans.x = -Vector3::Dot(xaxis, eye);
  684. trans.y = -Vector3::Dot(yaxis, eye);
  685. trans.z = -Vector3::Dot(zaxis, eye);
  686. float temp[4][4] =
  687. {
  688. { xaxis.x, yaxis.x, zaxis.x, 0.0f },
  689. { xaxis.y, yaxis.y, zaxis.y, 0.0f },
  690. { xaxis.z, yaxis.z, zaxis.z, 0.0f },
  691. { trans.x, trans.y, trans.z, 1.0f }
  692. };
  693. return Matrix4(temp);
  694. }
  695. static Matrix4 CreateOrtho(float width, float height, float near, float far)
  696. {
  697. float temp[4][4] =
  698. {
  699. { 2.0f / width, 0.0f, 0.0f, 0.0f },
  700. { 0.0f, 2.0f / height, 0.0f, 0.0f },
  701. { 0.0f, 0.0f, 1.0f / (far - near), 0.0f },
  702. { 0.0f, 0.0f, near / (near - far), 1.0f }
  703. };
  704. return Matrix4(temp);
  705. }
  706. static Matrix4 CreatePerspectiveFOV(float fovY, float width, float height, float near, float far)
  707. {
  708. float yScale = Math::Cot(fovY / 2.0f);
  709. float xScale = yScale * height / width;
  710. float temp[4][4] =
  711. {
  712. { xScale, 0.0f, 0.0f, 0.0f },
  713. { 0.0f, yScale, 0.0f, 0.0f },
  714. { 0.0f, 0.0f, far / (far - near), 1.0f },
  715. { 0.0f, 0.0f, -near * far / (far - near), 0.0f }
  716. };
  717. return Matrix4(temp);
  718. }
  719. // Create "Simple" View-Projection Matrix from Chapter 6
  720. static Matrix4 CreateSimpleViewProj(float width, float height)
  721. {
  722. float temp[4][4] =
  723. {
  724. { 2.0f/width, 0.0f, 0.0f, 0.0f },
  725. { 0.0f, 2.0f/height, 0.0f, 0.0f },
  726. { 0.0f, 0.0f, 1.0f, 0.0f },
  727. { 0.0f, 0.0f, 1.0f, 1.0f }
  728. };
  729. return Matrix4(temp);
  730. }
  731. static const Matrix4 Identity;
  732. };
  733. // (Unit) Quaternion
  734. class Quaternion
  735. {
  736. public:
  737. float x;
  738. float y;
  739. float z;
  740. float w;
  741. Quaternion()
  742. {
  743. *this = Quaternion::Identity;
  744. }
  745. // This directly sets the quaternion components --
  746. // don't use for axis/angle
  747. explicit Quaternion(float inX, float inY, float inZ, float inW)
  748. {
  749. Set(inX, inY, inZ, inW);
  750. }
  751. // Construct the quaternion from an axis and angle
  752. // It is assumed that axis is already normalized,
  753. // and the angle is in radians
  754. explicit Quaternion(const Vector3& axis, float angle)
  755. {
  756. float scalar = Math::Sin(angle / 2.0f);
  757. x = axis.x * scalar;
  758. y = axis.y * scalar;
  759. z = axis.z * scalar;
  760. w = Math::Cos(angle / 2.0f);
  761. }
  762. // Directly set the internal components
  763. void Set(float inX, float inY, float inZ, float inW)
  764. {
  765. x = inX;
  766. y = inY;
  767. z = inZ;
  768. w = inW;
  769. }
  770. void Conjugate()
  771. {
  772. x *= -1.0f;
  773. y *= -1.0f;
  774. z *= -1.0f;
  775. }
  776. float LengthSq() const
  777. {
  778. return (x*x + y*y + z*z + w*w);
  779. }
  780. float Length() const
  781. {
  782. return Math::Sqrt(LengthSq());
  783. }
  784. void Normalize()
  785. {
  786. float length = Length();
  787. x /= length;
  788. y /= length;
  789. z /= length;
  790. w /= length;
  791. }
  792. // Normalize the provided quaternion
  793. static Quaternion Normalize(const Quaternion& q)
  794. {
  795. Quaternion retVal = q;
  796. retVal.Normalize();
  797. return retVal;
  798. }
  799. // Linear interpolation
  800. static Quaternion Lerp(const Quaternion& a, const Quaternion& b, float f)
  801. {
  802. Quaternion retVal;
  803. retVal.x = Math::Lerp(a.x, b.x, f);
  804. retVal.y = Math::Lerp(a.y, b.y, f);
  805. retVal.z = Math::Lerp(a.z, b.z, f);
  806. retVal.w = Math::Lerp(a.w, b.w, f);
  807. retVal.Normalize();
  808. return retVal;
  809. }
  810. static float Dot(const Quaternion& a, const Quaternion& b)
  811. {
  812. return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
  813. }
  814. // Spherical Linear Interpolation
  815. static Quaternion Slerp(const Quaternion& a, const Quaternion& b, float f)
  816. {
  817. float rawCosm = Quaternion::Dot(a, b);
  818. float cosom = -rawCosm;
  819. if (rawCosm >= 0.0f)
  820. {
  821. cosom = rawCosm;
  822. }
  823. float scale0, scale1;
  824. if (cosom < 0.9999f)
  825. {
  826. const float omega = Math::Acos(cosom);
  827. const float invSin = 1.f / Math::Sin(omega);
  828. scale0 = Math::Sin((1.f - f) * omega) * invSin;
  829. scale1 = Math::Sin(f * omega) * invSin;
  830. }
  831. else
  832. {
  833. // Use linear interpolation if the quaternions
  834. // are collinear
  835. scale0 = 1.0f - f;
  836. scale1 = f;
  837. }
  838. if (rawCosm < 0.0f)
  839. {
  840. scale1 = -scale1;
  841. }
  842. Quaternion retVal;
  843. retVal.x = scale0 * a.x + scale1 * b.x;
  844. retVal.y = scale0 * a.y + scale1 * b.y;
  845. retVal.z = scale0 * a.z + scale1 * b.z;
  846. retVal.w = scale0 * a.w + scale1 * b.w;
  847. retVal.Normalize();
  848. return retVal;
  849. }
  850. // Concatenate
  851. // Rotate by q FOLLOWED BY p
  852. static Quaternion Concatenate(const Quaternion& q, const Quaternion& p)
  853. {
  854. Quaternion retVal;
  855. // Vector component is:
  856. // ps * qv + qs * pv + pv x qv
  857. Vector3 qv(q.x, q.y, q.z);
  858. Vector3 pv(p.x, p.y, p.z);
  859. Vector3 newVec = p.w * qv + q.w * pv + Vector3::Cross(pv, qv);
  860. retVal.x = newVec.x;
  861. retVal.y = newVec.y;
  862. retVal.z = newVec.z;
  863. // Scalar component is:
  864. // ps * qs - pv . qv
  865. retVal.w = p.w * q.w - Vector3::Dot(pv, qv);
  866. return retVal;
  867. }
  868. static const Quaternion Identity;
  869. };
  870. namespace Color
  871. {
  872. static const Vector3 Black(0.0f, 0.0f, 0.0f);
  873. static const Vector3 White(1.0f, 1.0f, 1.0f);
  874. static const Vector3 Red(1.0f, 0.0f, 0.0f);
  875. static const Vector3 Green(0.0f, 1.0f, 0.0f);
  876. static const Vector3 Blue(0.0f, 0.0f, 1.0f);
  877. static const Vector3 Yellow(1.0f, 1.0f, 0.0f);
  878. static const Vector3 LightYellow(1.0f, 1.0f, 0.88f);
  879. static const Vector3 LightBlue(0.68f, 0.85f, 0.9f);
  880. static const Vector3 LightPink(1.0f, 0.71f, 0.76f);
  881. static const Vector3 LightGreen(0.56f, 0.93f, 0.56f);
  882. }