Math.h 21 KB

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