Mat4.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. #pragma once
  2. #include <iostream>
  3. #include "Mat3.h"
  4. #include "Vec3.h"
  5. namespace Framework
  6. {
  7. template<typename T>
  8. //! Eine 4x4 Matrix
  9. class Mat4
  10. {
  11. public:
  12. T elements[4][4]; //! Die Elemente der Matrix
  13. //! Kopiert alle Werte einer anderen Matrix
  14. //! \param r Die andere Matrix
  15. Mat4& operator=(const Mat4& r)
  16. {
  17. memcpy(elements, r.elements, sizeof(elements));
  18. return *this;
  19. }
  20. //! Skalliert die Matrix
  21. //! \param r der Faktor
  22. Mat4& operator*=(const T r)
  23. {
  24. for (T& e : elements)
  25. e *= r;
  26. return *this;
  27. }
  28. //! Multipliziert die MAtrix mit einer anderen
  29. //! \param r Die andere Matrix
  30. Mat4& operator*=(const Mat4& r)
  31. {
  32. return *this = *this * r;
  33. }
  34. //! Skalliert die Matrix ohne sie zu verändern
  35. //! \param r der Faktor
  36. Mat4 operator*(const T r) const
  37. {
  38. Mat4 result = *this;
  39. return result *= r;
  40. }
  41. //! Multipliziert zwei Matrizen
  42. //! \param r Die andere Matrix
  43. Mat4 operator*(const Mat4& r) const
  44. {
  45. Mat4 result;
  46. for (int j = 0; j < 4; j++)
  47. {
  48. for (int k = 0; k < 4; k++)
  49. {
  50. T sum = 0;
  51. for (int i = 0; i < 4; i++)
  52. sum += elements[j][i] * r.elements[i][k];
  53. result.elements[j][k] = sum;
  54. }
  55. }
  56. return result;
  57. }
  58. //! Multiplziert die Matrix mit einem Vektor
  59. //! \param r Der Vektor
  60. Vec3<T> operator*(const Vec3<T>& r) const
  61. {
  62. Vec3<T> result;
  63. result.x = elements[0][0] * r.x + elements[0][1] * r.y
  64. + elements[0][2] * r.z + elements[0][3];
  65. result.y = elements[1][0] * r.x + elements[1][1] * r.y
  66. + elements[1][2] * r.z + elements[1][3];
  67. result.z = elements[2][0] * r.x + elements[2][1] * r.y
  68. + elements[2][2] * r.z + elements[2][3];
  69. return result;
  70. }
  71. Vec3<T> mult0(const Vec3<T>& r) const
  72. {
  73. Vec3<T> result;
  74. result.x = elements[0][0] * r.x + elements[0][1] * r.y
  75. + elements[0][2] * r.z;
  76. result.y = elements[1][0] * r.x + elements[1][1] * r.y
  77. + elements[1][2] * r.z;
  78. result.z = elements[2][0] * r.x + elements[2][1] * r.y
  79. + elements[2][2] * r.z;
  80. return result;
  81. }
  82. //! Berechnet die inverse Matrix
  83. Mat4 getInverse() const
  84. {
  85. Mat4 ret;
  86. ret.elements[0][0]
  87. = elements[1][1] * elements[2][2] * elements[3][3]
  88. - elements[1][1] * elements[2][3] * elements[3][2]
  89. - elements[2][1] * elements[1][2] * elements[3][3]
  90. + elements[2][1] * elements[1][3] * elements[3][2]
  91. + elements[3][1] * elements[1][2] * elements[2][3]
  92. - elements[3][1] * elements[1][3] * elements[2][2];
  93. ret.elements[1][0]
  94. = -elements[1][0] * elements[2][2] * elements[3][3]
  95. + elements[1][0] * elements[2][3] * elements[3][2]
  96. + elements[2][0] * elements[1][2] * elements[3][3]
  97. - elements[2][0] * elements[1][3] * elements[3][2]
  98. - elements[3][0] * elements[1][2] * elements[2][3]
  99. + elements[3][0] * elements[1][3] * elements[2][2];
  100. ret.elements[2][0]
  101. = elements[1][0] * elements[2][1] * elements[3][3]
  102. - elements[1][0] * elements[2][3] * elements[3][1]
  103. - elements[2][0] * elements[1][1] * elements[3][3]
  104. + elements[2][0] * elements[1][3] * elements[3][1]
  105. + elements[3][0] * elements[1][1] * elements[2][3]
  106. - elements[3][0] * elements[1][3] * elements[2][1];
  107. ret.elements[3][0]
  108. = -elements[1][0] * elements[2][1] * elements[3][2]
  109. + elements[1][0] * elements[2][2] * elements[3][1]
  110. + elements[2][0] * elements[1][1] * elements[3][2]
  111. - elements[2][0] * elements[1][2] * elements[3][1]
  112. - elements[3][0] * elements[1][1] * elements[2][2]
  113. + elements[3][0] * elements[1][2] * elements[2][1];
  114. ret.elements[0][1]
  115. = -elements[0][1] * elements[2][2] * elements[3][3]
  116. + elements[0][1] * elements[2][3] * elements[3][2]
  117. + elements[2][1] * elements[0][2] * elements[3][3]
  118. - elements[2][1] * elements[0][3] * elements[3][2]
  119. - elements[3][1] * elements[0][2] * elements[2][3]
  120. + elements[3][1] * elements[0][3] * elements[2][2];
  121. ret.elements[1][1]
  122. = elements[0][0] * elements[2][2] * elements[3][3]
  123. - elements[0][0] * elements[2][3] * elements[3][2]
  124. - elements[2][0] * elements[0][2] * elements[3][3]
  125. + elements[2][0] * elements[0][3] * elements[3][2]
  126. + elements[3][0] * elements[0][2] * elements[2][3]
  127. - elements[3][0] * elements[0][3] * elements[2][2];
  128. ret.elements[2][1]
  129. = -elements[0][0] * elements[2][1] * elements[3][3]
  130. + elements[0][0] * elements[2][3] * elements[3][1]
  131. + elements[2][0] * elements[0][1] * elements[3][3]
  132. - elements[2][0] * elements[0][3] * elements[3][1]
  133. - elements[3][0] * elements[0][1] * elements[2][3]
  134. + elements[3][0] * elements[0][3] * elements[2][1];
  135. ret.elements[3][1]
  136. = elements[0][0] * elements[2][1] * elements[3][2]
  137. - elements[0][0] * elements[2][2] * elements[3][1]
  138. - elements[2][0] * elements[0][1] * elements[3][2]
  139. + elements[2][0] * elements[0][2] * elements[3][1]
  140. + elements[3][0] * elements[0][1] * elements[2][2]
  141. - elements[3][0] * elements[0][2] * elements[2][1];
  142. ret.elements[0][2]
  143. = elements[0][1] * elements[1][2] * elements[3][3]
  144. - elements[0][1] * elements[1][3] * elements[3][2]
  145. - elements[1][1] * elements[0][2] * elements[3][3]
  146. + elements[1][1] * elements[0][3] * elements[3][2]
  147. + elements[3][1] * elements[0][2] * elements[1][3]
  148. - elements[3][1] * elements[0][3] * elements[1][2];
  149. ret.elements[1][2]
  150. = -elements[0][0] * elements[1][2] * elements[3][3]
  151. + elements[0][0] * elements[1][3] * elements[3][2]
  152. + elements[1][0] * elements[0][2] * elements[3][3]
  153. - elements[1][0] * elements[0][3] * elements[3][2]
  154. - elements[3][0] * elements[0][2] * elements[1][3]
  155. + elements[3][0] * elements[0][3] * elements[1][2];
  156. ret.elements[2][2]
  157. = elements[0][0] * elements[1][1] * elements[3][3]
  158. - elements[0][0] * elements[1][3] * elements[3][1]
  159. - elements[1][0] * elements[0][1] * elements[3][3]
  160. + elements[1][0] * elements[0][3] * elements[3][1]
  161. + elements[3][0] * elements[0][1] * elements[1][3]
  162. - elements[3][0] * elements[0][3] * elements[1][1];
  163. ret.elements[3][2]
  164. = -elements[0][0] * elements[1][1] * elements[3][2]
  165. + elements[0][0] * elements[1][2] * elements[3][1]
  166. + elements[1][0] * elements[0][1] * elements[3][2]
  167. - elements[1][0] * elements[0][2] * elements[3][1]
  168. - elements[3][0] * elements[0][1] * elements[1][2]
  169. + elements[3][0] * elements[0][2] * elements[1][1];
  170. ret.elements[0][3]
  171. = -elements[0][1] * elements[1][2] * elements[2][3]
  172. + elements[0][1] * elements[1][3] * elements[2][2]
  173. + elements[1][1] * elements[0][2] * elements[2][3]
  174. - elements[1][1] * elements[0][3] * elements[2][2]
  175. - elements[2][1] * elements[0][2] * elements[1][3]
  176. + elements[2][1] * elements[0][3] * elements[1][2];
  177. ret.elements[1][3]
  178. = elements[0][0] * elements[1][2] * elements[2][3]
  179. - elements[0][0] * elements[1][3] * elements[2][2]
  180. - elements[1][0] * elements[0][2] * elements[2][3]
  181. + elements[1][0] * elements[0][3] * elements[2][2]
  182. + elements[2][0] * elements[0][2] * elements[1][3]
  183. - elements[2][0] * elements[0][3] * elements[1][2];
  184. ret.elements[2][3]
  185. = -elements[0][0] * elements[1][1] * elements[2][3]
  186. + elements[0][0] * elements[1][3] * elements[2][1]
  187. + elements[1][0] * elements[0][1] * elements[2][3]
  188. - elements[1][0] * elements[0][3] * elements[2][1]
  189. - elements[2][0] * elements[0][1] * elements[1][3]
  190. + elements[2][0] * elements[0][3] * elements[1][1];
  191. ret.elements[3][3]
  192. = elements[0][0] * elements[1][1] * elements[2][2]
  193. - elements[0][0] * elements[1][2] * elements[2][1]
  194. - elements[1][0] * elements[0][1] * elements[2][2]
  195. + elements[1][0] * elements[0][2] * elements[2][1]
  196. + elements[2][0] * elements[0][1] * elements[1][2]
  197. - elements[2][0] * elements[0][2] * elements[1][1];
  198. T det = elements[0][0] * ret.elements[0][0]
  199. + elements[0][1] * ret.elements[1][0]
  200. + elements[0][2] * ret.elements[2][0]
  201. + elements[0][3] * ret.elements[3][0];
  202. if (det == 0)
  203. {
  204. std::cout << "Fehler beim erstellen der Inversen Matrix";
  205. return ret;
  206. }
  207. det = 1.0f / det;
  208. for (int i = 0; i < 16; i++)
  209. ret.elements[i / 4][i % 4] = ret.elements[i / 4][i % 4] * det;
  210. return ret;
  211. }
  212. //! Erzeugt eine Matrix, die einen Vektor um die Z Achse dreht, wenn sie
  213. //! mit ihm multipliziert wird \param radian Der Winkel in Bogenmas
  214. static Mat4 rotationZ(T radian)
  215. {
  216. const T cosTheta = (T)lowPrecisionCos(radian);
  217. const T sinTheta = (T)lowPrecisionSin(radian);
  218. Mat4 r = {cosTheta,
  219. -sinTheta,
  220. 0,
  221. 0,
  222. sinTheta,
  223. cosTheta,
  224. 0,
  225. 0,
  226. 0,
  227. 0,
  228. 1,
  229. 0,
  230. 0,
  231. 0,
  232. 0,
  233. 1};
  234. return r;
  235. }
  236. //! Erzeugt eine Matrix, die einen Vektor um die X Achse dreht, wenn sie
  237. //! mit ihm multipliziert wird \param radian Der Winkel in Bogenmas
  238. static Mat4 rotationX(T radian)
  239. {
  240. const T cosTheta = (T)lowPrecisionCos(radian);
  241. const T sinTheta = (T)lowPrecisionSin(radian);
  242. Mat4 r = {1,
  243. 0,
  244. 0,
  245. 0,
  246. 0,
  247. cosTheta,
  248. -sinTheta,
  249. 0,
  250. 0,
  251. sinTheta,
  252. cosTheta,
  253. 0,
  254. 0,
  255. 0,
  256. 0,
  257. 1};
  258. return r;
  259. }
  260. //! Erzeugt eine Matrix, die einen Vektor um die Y Achse dreht, wenn sie
  261. //! mit ihm multipliziert wird \param radian Der Winkel in Bogenmas
  262. static Mat4 rotationY(T radian)
  263. {
  264. const T cosTheta = (T)lowPrecisionCos(radian);
  265. const T sinTheta = (T)lowPrecisionSin(radian);
  266. Mat4 r = {cosTheta,
  267. 0,
  268. sinTheta,
  269. 0,
  270. 0,
  271. 1,
  272. 0,
  273. 0,
  274. -sinTheta,
  275. 0,
  276. cosTheta,
  277. 0,
  278. 0,
  279. 0,
  280. 0,
  281. 1};
  282. return r;
  283. }
  284. //! Erzeugt eine Matrix, die einen Vektor Skalliert, wenn sie mit ihm
  285. //! multipliziert wird \param faktor Der Faktor
  286. static Mat4 scaling(T faktor)
  287. {
  288. Mat4 s = {
  289. faktor, 0, 0, 0, 0, faktor, 0, 0, 0, 0, faktor, 0, 0, 0, 0, 1};
  290. return s;
  291. }
  292. //! Erzeugt eine Matrix, die einen Vektor Skalliert, wenn sie mit ihm
  293. //! multipliziert wird \param faktorX Der Faktor für die X Komponente
  294. //! des Vektors \param faktorY Der Faktor für die Y Komponente des
  295. //! Vektors \param faktorZ Der Faktor für die Z Komponente des Vektors
  296. static Mat4 scaling(T faktorX, T faktorY, T faktorZ)
  297. {
  298. Mat4 s = {faktorX,
  299. 0,
  300. 0,
  301. 0,
  302. 0,
  303. faktorY,
  304. 0,
  305. 0,
  306. 0,
  307. 0,
  308. faktorZ,
  309. 0,
  310. 0,
  311. 0,
  312. 0,
  313. 1};
  314. return s;
  315. }
  316. //! Erzeugt eine Matrix, die einen Vektor verchiebt, wenn sie mit ihm
  317. //! multipliziert wird \param offset Die Koordinaten, um die der Vektor
  318. //! verschoben werden soll
  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. //! Erzeugt eine Matrix, die einen Vektor auf den Bildschirm Projeziert
  340. //! \param openingAngle Der Öffnungswinkel der Kamera im Bogenmas
  341. //! \param bildschirmXY Das Seitenverhältnis des Rechtecks auf dem
  342. //! Bildschirm, in dem gezeichnet werden soll. (Breite / Höhe) \param
  343. //! minz Der Mindestabstand zur Kamera, ab dem gezeichnet wird \param
  344. //! maxZ Der Maximalabstand zur Kamera, ab dem nicht mehr gezeichnet
  345. //! wird
  346. static Mat4 projektion(
  347. float openingAngle, float bildschirmXY, float minZ, float maxZ)
  348. {
  349. Mat4 p = {(float)(1 / tan(openingAngle / 2)) / bildschirmXY,
  350. 0,
  351. 0,
  352. 0,
  353. 0,
  354. (float)(1 / tan(openingAngle / 2)),
  355. 0,
  356. 0,
  357. 0,
  358. 0,
  359. maxZ / (maxZ - minZ),
  360. -(minZ * maxZ) / (maxZ - minZ),
  361. 0,
  362. 0,
  363. 1,
  364. 0};
  365. return p;
  366. }
  367. //! Erzeugt eine Matrix, die mit allem Multipliziert werden kann ohne es
  368. //! zu ändern
  369. static Mat4 identity()
  370. {
  371. Mat4 i = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
  372. return i;
  373. }
  374. //! Gibt eine Rotationsmatrix zurück, so dass vector a wenn man ihn
  375. //! damit dreht in richtung des vectors b zeigt \param a der vector der
  376. //! gedreht werden soll \param b der vector zu dem gedreht werden soll
  377. static Mat4 rotationTo(Vec3<T>& a, Vec3<T>& b)
  378. {
  379. Vec3<T> aNorm = Vec3<T>(a).normalize();
  380. Vec3<T> bNorm = Vec3<T>(b).normalize();
  381. Vec3<T> v = aNorm.crossProduct(bNorm);
  382. T s = v.getLengthSq();
  383. T c = aNorm * bNorm;
  384. T m = (1 - c) / s;
  385. Mat3<T> cpm({0, -v.z, v.y, v.z, 0, -v.x, -v.y, v.x, 0});
  386. Mat3<T> cpm2 = cpm * cpm;
  387. Mat3<T> res = Mat3<T>::identity() + cpm + cpm2 * m;
  388. return Mat4({res.elements[0][0],
  389. res.elements[0][1],
  390. res.elements[0][2],
  391. 0,
  392. res.elements[1][0],
  393. res.elements[1][1],
  394. res.elements[1][2],
  395. 0,
  396. res.elements[2][0],
  397. res.elements[2][1],
  398. res.elements[2][2],
  399. 0,
  400. 0,
  401. 0,
  402. 0,
  403. 1});
  404. }
  405. };
  406. } // namespace Framework