Mat4.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. #pragma once
  2. #include <iostream>
  3. #include "Logging.h"
  4. #include "Mat3.h"
  5. #include "Vec3.h"
  6. namespace Framework
  7. {
  8. template<typename T>
  9. //! A 4x4 Matrix
  10. class Mat4
  11. {
  12. public:
  13. union
  14. {
  15. T elements[4][4]; //! The elements of the matrix
  16. T allElements[16]; //! The elements of the matrix as a single array
  17. };
  18. //! Copies all values from another matrix
  19. //! \param r The other matrix
  20. Mat4& operator=(const Mat4& r)
  21. {
  22. memcpy(allElements, r.allElements, sizeof(allElements));
  23. return *this;
  24. }
  25. //! Scales the matrix
  26. //! \param r The factor
  27. Mat4& operator*=(const T r)
  28. {
  29. for (T& e : allElements)
  30. e *= r;
  31. return *this;
  32. }
  33. //! Multiplies the matrix with another
  34. //! \param r The other matrix
  35. Mat4& operator*=(const Mat4& r)
  36. {
  37. return *this = *this * r;
  38. }
  39. //! Scales the matrix without modifying it
  40. //! \param r The factor
  41. Mat4 operator*(const T r) const
  42. {
  43. Mat4 result = *this;
  44. return result *= r;
  45. }
  46. //! Multiplies two matrices
  47. //! \param r The other matrix
  48. Mat4 operator*(const Mat4& r) const
  49. {
  50. Mat4 result;
  51. for (int j = 0; j < 4; j++)
  52. {
  53. for (int k = 0; k < 4; k++)
  54. {
  55. T sum = 0;
  56. for (int i = 0; i < 4; i++)
  57. sum += elements[j][i] * r.elements[i][k];
  58. result.elements[j][k] = sum;
  59. }
  60. }
  61. return result;
  62. }
  63. //! Multiplies the matrix with a vector
  64. //! \param r The vector
  65. Vec3<T> operator*(const Vec3<T>& r) const
  66. {
  67. Vec3<T> result;
  68. result.x = elements[0][0] * r.x + elements[0][1] * r.y
  69. + elements[0][2] * r.z + elements[0][3];
  70. result.y = elements[1][0] * r.x + elements[1][1] * r.y
  71. + elements[1][2] * r.z + elements[1][3];
  72. result.z = elements[2][0] * r.x + elements[2][1] * r.y
  73. + elements[2][2] * r.z + elements[2][3];
  74. return result;
  75. }
  76. Vec3<T> mult0(const Vec3<T>& r) const
  77. {
  78. Vec3<T> result;
  79. result.x = elements[0][0] * r.x + elements[0][1] * r.y
  80. + elements[0][2] * r.z;
  81. result.y = elements[1][0] * r.x + elements[1][1] * r.y
  82. + elements[1][2] * r.z;
  83. result.z = elements[2][0] * r.x + elements[2][1] * r.y
  84. + elements[2][2] * r.z;
  85. return result;
  86. }
  87. //! Calculates the inverse matrix
  88. Mat4 getInverse() const
  89. {
  90. Mat4 ret;
  91. ret.elements[0][0]
  92. = elements[1][1] * elements[2][2] * elements[3][3]
  93. - elements[1][1] * elements[2][3] * elements[3][2]
  94. - elements[2][1] * elements[1][2] * elements[3][3]
  95. + elements[2][1] * elements[1][3] * elements[3][2]
  96. + elements[3][1] * elements[1][2] * elements[2][3]
  97. - elements[3][1] * elements[1][3] * elements[2][2];
  98. ret.elements[1][0]
  99. = -elements[1][0] * elements[2][2] * elements[3][3]
  100. + elements[1][0] * elements[2][3] * elements[3][2]
  101. + elements[2][0] * elements[1][2] * elements[3][3]
  102. - elements[2][0] * elements[1][3] * elements[3][2]
  103. - elements[3][0] * elements[1][2] * elements[2][3]
  104. + elements[3][0] * elements[1][3] * elements[2][2];
  105. ret.elements[2][0]
  106. = elements[1][0] * elements[2][1] * elements[3][3]
  107. - elements[1][0] * elements[2][3] * elements[3][1]
  108. - elements[2][0] * elements[1][1] * elements[3][3]
  109. + elements[2][0] * elements[1][3] * elements[3][1]
  110. + elements[3][0] * elements[1][1] * elements[2][3]
  111. - elements[3][0] * elements[1][3] * elements[2][1];
  112. ret.elements[3][0]
  113. = -elements[1][0] * elements[2][1] * elements[3][2]
  114. + elements[1][0] * elements[2][2] * elements[3][1]
  115. + elements[2][0] * elements[1][1] * elements[3][2]
  116. - elements[2][0] * elements[1][2] * elements[3][1]
  117. - elements[3][0] * elements[1][1] * elements[2][2]
  118. + elements[3][0] * elements[1][2] * elements[2][1];
  119. ret.elements[0][1]
  120. = -elements[0][1] * elements[2][2] * elements[3][3]
  121. + elements[0][1] * elements[2][3] * elements[3][2]
  122. + elements[2][1] * elements[0][2] * elements[3][3]
  123. - elements[2][1] * elements[0][3] * elements[3][2]
  124. - elements[3][1] * elements[0][2] * elements[2][3]
  125. + elements[3][1] * elements[0][3] * elements[2][2];
  126. ret.elements[1][1]
  127. = elements[0][0] * elements[2][2] * elements[3][3]
  128. - elements[0][0] * elements[2][3] * elements[3][2]
  129. - elements[2][0] * elements[0][2] * elements[3][3]
  130. + elements[2][0] * elements[0][3] * elements[3][2]
  131. + elements[3][0] * elements[0][2] * elements[2][3]
  132. - elements[3][0] * elements[0][3] * elements[2][2];
  133. ret.elements[2][1]
  134. = -elements[0][0] * elements[2][1] * elements[3][3]
  135. + elements[0][0] * elements[2][3] * elements[3][1]
  136. + elements[2][0] * elements[0][1] * elements[3][3]
  137. - elements[2][0] * elements[0][3] * elements[3][1]
  138. - elements[3][0] * elements[0][1] * elements[2][3]
  139. + elements[3][0] * elements[0][3] * elements[2][1];
  140. ret.elements[3][1]
  141. = elements[0][0] * elements[2][1] * elements[3][2]
  142. - elements[0][0] * elements[2][2] * elements[3][1]
  143. - elements[2][0] * elements[0][1] * elements[3][2]
  144. + elements[2][0] * elements[0][2] * elements[3][1]
  145. + elements[3][0] * elements[0][1] * elements[2][2]
  146. - elements[3][0] * elements[0][2] * elements[2][1];
  147. ret.elements[0][2]
  148. = elements[0][1] * elements[1][2] * elements[3][3]
  149. - elements[0][1] * elements[1][3] * elements[3][2]
  150. - elements[1][1] * elements[0][2] * elements[3][3]
  151. + elements[1][1] * elements[0][3] * elements[3][2]
  152. + elements[3][1] * elements[0][2] * elements[1][3]
  153. - elements[3][1] * elements[0][3] * elements[1][2];
  154. ret.elements[1][2]
  155. = -elements[0][0] * elements[1][2] * elements[3][3]
  156. + elements[0][0] * elements[1][3] * elements[3][2]
  157. + elements[1][0] * elements[0][2] * elements[3][3]
  158. - elements[1][0] * elements[0][3] * elements[3][2]
  159. - elements[3][0] * elements[0][2] * elements[1][3]
  160. + elements[3][0] * elements[0][3] * elements[1][2];
  161. ret.elements[2][2]
  162. = elements[0][0] * elements[1][1] * elements[3][3]
  163. - elements[0][0] * elements[1][3] * elements[3][1]
  164. - elements[1][0] * elements[0][1] * elements[3][3]
  165. + elements[1][0] * elements[0][3] * elements[3][1]
  166. + elements[3][0] * elements[0][1] * elements[1][3]
  167. - elements[3][0] * elements[0][3] * elements[1][1];
  168. ret.elements[3][2]
  169. = -elements[0][0] * elements[1][1] * elements[3][2]
  170. + elements[0][0] * elements[1][2] * elements[3][1]
  171. + elements[1][0] * elements[0][1] * elements[3][2]
  172. - elements[1][0] * elements[0][2] * elements[3][1]
  173. - elements[3][0] * elements[0][1] * elements[1][2]
  174. + elements[3][0] * elements[0][2] * elements[1][1];
  175. ret.elements[0][3]
  176. = -elements[0][1] * elements[1][2] * elements[2][3]
  177. + elements[0][1] * elements[1][3] * elements[2][2]
  178. + elements[1][1] * elements[0][2] * elements[2][3]
  179. - elements[1][1] * elements[0][3] * elements[2][2]
  180. - elements[2][1] * elements[0][2] * elements[1][3]
  181. + elements[2][1] * elements[0][3] * elements[1][2];
  182. ret.elements[1][3]
  183. = elements[0][0] * elements[1][2] * elements[2][3]
  184. - elements[0][0] * elements[1][3] * elements[2][2]
  185. - elements[1][0] * elements[0][2] * elements[2][3]
  186. + elements[1][0] * elements[0][3] * elements[2][2]
  187. + elements[2][0] * elements[0][2] * elements[1][3]
  188. - elements[2][0] * elements[0][3] * elements[1][2];
  189. ret.elements[2][3]
  190. = -elements[0][0] * elements[1][1] * elements[2][3]
  191. + elements[0][0] * elements[1][3] * elements[2][1]
  192. + elements[1][0] * elements[0][1] * elements[2][3]
  193. - elements[1][0] * elements[0][3] * elements[2][1]
  194. - elements[2][0] * elements[0][1] * elements[1][3]
  195. + elements[2][0] * elements[0][3] * elements[1][1];
  196. ret.elements[3][3]
  197. = elements[0][0] * elements[1][1] * elements[2][2]
  198. - elements[0][0] * elements[1][2] * elements[2][1]
  199. - elements[1][0] * elements[0][1] * elements[2][2]
  200. + elements[1][0] * elements[0][2] * elements[2][1]
  201. + elements[2][0] * elements[0][1] * elements[1][2]
  202. - elements[2][0] * elements[0][2] * elements[1][1];
  203. T det = elements[0][0] * ret.elements[0][0]
  204. + elements[0][1] * ret.elements[1][0]
  205. + elements[0][2] * ret.elements[2][0]
  206. + elements[0][3] * ret.elements[3][0];
  207. if (det == 0)
  208. {
  209. Logging::error() << "Error creating the inverse matrix";
  210. return ret;
  211. }
  212. det = 1.0f / det;
  213. for (int i = 0; i < 16; i++)
  214. ret.elements[i / 4][i % 4] = ret.elements[i / 4][i % 4] * det;
  215. return ret;
  216. }
  217. //! Creates a matrix that rotates a vector around the Z axis when
  218. //! multiplied with it \param radian The angle in radians
  219. static Mat4 rotationZ(T radian)
  220. {
  221. const T cosTheta = (T)lowPrecisionCos(radian);
  222. const T sinTheta = (T)lowPrecisionSin(radian);
  223. Mat4 r = {cosTheta,
  224. -sinTheta,
  225. 0,
  226. 0,
  227. sinTheta,
  228. cosTheta,
  229. 0,
  230. 0,
  231. 0,
  232. 0,
  233. 1,
  234. 0,
  235. 0,
  236. 0,
  237. 0,
  238. 1};
  239. return r;
  240. }
  241. //! Creates a matrix that rotates a vector around the X axis when
  242. //! multiplied with it \param radian The angle in radians
  243. static Mat4 rotationX(T radian)
  244. {
  245. const T cosTheta = (T)lowPrecisionCos(radian);
  246. const T sinTheta = (T)lowPrecisionSin(radian);
  247. Mat4 r = {1,
  248. 0,
  249. 0,
  250. 0,
  251. 0,
  252. cosTheta,
  253. -sinTheta,
  254. 0,
  255. 0,
  256. sinTheta,
  257. cosTheta,
  258. 0,
  259. 0,
  260. 0,
  261. 0,
  262. 1};
  263. return r;
  264. }
  265. //! Creates a matrix that rotates a vector around the Y axis when
  266. //! multiplied with it \param radian The angle in radians
  267. static Mat4 rotationY(T radian)
  268. {
  269. const T cosTheta = (T)lowPrecisionCos(radian);
  270. const T sinTheta = (T)lowPrecisionSin(radian);
  271. Mat4 r = {cosTheta,
  272. 0,
  273. sinTheta,
  274. 0,
  275. 0,
  276. 1,
  277. 0,
  278. 0,
  279. -sinTheta,
  280. 0,
  281. cosTheta,
  282. 0,
  283. 0,
  284. 0,
  285. 0,
  286. 1};
  287. return r;
  288. }
  289. //! Creates a matrix that scales a vector when multiplied with it
  290. //! \param faktor The factor
  291. static Mat4 scaling(T faktor)
  292. {
  293. Mat4 s = {
  294. faktor, 0, 0, 0, 0, faktor, 0, 0, 0, 0, faktor, 0, 0, 0, 0, 1};
  295. return s;
  296. }
  297. //! Creates a matrix that scales a vector when multiplied with it
  298. //! \param faktorX The factor for the X component of the vector
  299. //! \param faktorY The factor for the Y component of the vector
  300. //! \param faktorZ The factor for the Z component of the vector
  301. static Mat4 scaling(T faktorX, T faktorY, T faktorZ)
  302. {
  303. Mat4 s = {faktorX,
  304. 0,
  305. 0,
  306. 0,
  307. 0,
  308. faktorY,
  309. 0,
  310. 0,
  311. 0,
  312. 0,
  313. faktorZ,
  314. 0,
  315. 0,
  316. 0,
  317. 0,
  318. 1};
  319. return s;
  320. }
  321. //! Creates a matrix that translates a vector when multiplied with it
  322. //! \param offset The coordinates by which the vector should be shifted
  323. static Mat4 translation(const Vec3<T> offset)
  324. {
  325. Mat4 t = {1,
  326. 0,
  327. 0,
  328. offset.x,
  329. 0,
  330. 1,
  331. 0,
  332. offset.y,
  333. 0,
  334. 0,
  335. 1,
  336. offset.z,
  337. 0,
  338. 0,
  339. 0,
  340. 1};
  341. return t;
  342. }
  343. //! Creates a matrix that projects a vector onto the screen
  344. //! \param openingAngle The opening angle of the camera in radians
  345. //! \param bildschirmXY The aspect ratio of the rectangle on the
  346. //! screen to draw in. (Width / Height) \param
  347. //! minz The minimum distance to the camera from which drawing begins
  348. //! \param maxZ The maximum distance to the camera beyond which drawing
  349. //! stops
  350. static Mat4 projektion(
  351. float openingAngle, float bildschirmXY, float minZ, float maxZ)
  352. {
  353. Mat4 p = {(float)(1 / tan(openingAngle / 2)) / bildschirmXY,
  354. 0,
  355. 0,
  356. 0,
  357. 0,
  358. (float)(1 / tan(openingAngle / 2)),
  359. 0,
  360. 0,
  361. 0,
  362. 0,
  363. maxZ / (maxZ - minZ),
  364. -(minZ * maxZ) / (maxZ - minZ),
  365. 0,
  366. 0,
  367. 1,
  368. 0};
  369. return p;
  370. }
  371. //! Creates an identity matrix that can be multiplied with anything
  372. //! without changing it
  373. static Mat4 identity()
  374. {
  375. Mat4 i = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
  376. return i;
  377. }
  378. //! Returns a rotation matrix such that vector a, when rotated by it,
  379. //! points in the direction of vector b \param a The vector to rotate
  380. //! \param b The vector to rotate towards
  381. static Mat4 rotationTo(Vec3<T>& a, Vec3<T>& b)
  382. {
  383. Vec3<T> aNorm = Vec3<T>(a).normalize();
  384. Vec3<T> bNorm = Vec3<T>(b).normalize();
  385. Vec3<T> v = aNorm.crossProduct(bNorm);
  386. T s = v.getLengthSq();
  387. T c = aNorm * bNorm;
  388. T m = (1 - c) / s;
  389. Mat3<T> cpm({0, -v.z, v.y, v.z, 0, -v.x, -v.y, v.x, 0});
  390. Mat3<T> cpm2 = cpm * cpm;
  391. Mat3<T> res = Mat3<T>::identity() + cpm + cpm2 * m;
  392. return Mat4({res.elements[0][0],
  393. res.elements[0][1],
  394. res.elements[0][2],
  395. 0,
  396. res.elements[1][0],
  397. res.elements[1][1],
  398. res.elements[1][2],
  399. 0,
  400. res.elements[2][0],
  401. res.elements[2][1],
  402. res.elements[2][2],
  403. 0,
  404. 0,
  405. 0,
  406. 0,
  407. 1});
  408. }
  409. };
  410. } // namespace Framework