Mat4.h 16 KB

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