Mat4.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #pragma once
  2. #include "Vec3.h"
  3. #include <iostream>
  4. namespace Framework
  5. {
  6. template< typename T >
  7. // Eine 4x4 Matrix
  8. class Mat4
  9. {
  10. public:
  11. T elements[ 4 ][ 4 ]; // Die Elemente der Matrix
  12. // Kopiert alle Werte einer anderen Matrix
  13. // r: Die andere Matrix
  14. Mat4 &operator=( const Mat4 &r )
  15. {
  16. memcpy( elements, r.elements, sizeof( elements ) );
  17. return *this;
  18. }
  19. // Skalliert die Matrix
  20. // r: der Faktor
  21. Mat4 &operator*=( const T r )
  22. {
  23. for( T &e : elements )
  24. e *= r;
  25. return *this;
  26. }
  27. // Multipliziert die MAtrix mit einer anderen
  28. // r: Die andere Matrix
  29. Mat4 &operator*=( const Mat4 &r )
  30. {
  31. return *this = *this * r;
  32. }
  33. // Skalliert die Matrix ohne sie zu verändern
  34. // r: der Faktor
  35. Mat4 operator*( const T r ) const
  36. {
  37. Mat4 result = *this;
  38. return result *= r;
  39. }
  40. // Multipliziert zwei Matrizen
  41. // r: Die andere Matrix
  42. Mat4 operator*( const Mat4 &r ) const
  43. {
  44. Mat4 result;
  45. for( int j = 0; j < 4; j++ )
  46. {
  47. for( int k = 0; k < 4; k++ )
  48. {
  49. T sum = 0;
  50. for( int i = 0; i < 4; i++ )
  51. sum += elements[ j ][ i ] * r.elements[ i ][ k ];
  52. result.elements[ j ][ k ] = sum;
  53. }
  54. }
  55. return result;
  56. }
  57. // Multiplziert die Matrix mit einem Vektor
  58. // r: Der Vektor
  59. Vec3< T > operator*( const Vec3< T > &r ) const
  60. {
  61. Vec3< T > result;
  62. result.x = elements[ 0 ][ 0 ] * r.x + elements[ 0 ][ 1 ] * r.y + elements[ 0 ][ 2 ] * r.z + elements[ 0 ][ 3 ];
  63. result.y = elements[ 1 ][ 0 ] * r.x + elements[ 1 ][ 1 ] * r.y + elements[ 1 ][ 2 ] * r.z + elements[ 1 ][ 3 ];
  64. result.z = elements[ 2 ][ 0 ] * r.x + elements[ 2 ][ 1 ] * r.y + elements[ 2 ][ 2 ] * r.z + elements[ 2 ][ 3 ];
  65. return result;
  66. }
  67. // Berechnet die inverse Matrix
  68. Mat4 getInverse()
  69. {
  70. Mat4 ret;
  71. ret.elements[ 0 ][ 0 ] =
  72. elements[ 1 ][ 1 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 3 ] -
  73. elements[ 1 ][ 1 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 2 ] -
  74. elements[ 2 ][ 1 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 3 ] +
  75. elements[ 2 ][ 1 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 2 ] +
  76. elements[ 3 ][ 1 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 3 ] -
  77. elements[ 3 ][ 1 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 2 ];
  78. ret.elements[ 1 ][ 0 ] =
  79. -elements[ 1 ][ 0 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 3 ] +
  80. elements[ 1 ][ 0 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 2 ] +
  81. elements[ 2 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 3 ] -
  82. elements[ 2 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 2 ] -
  83. elements[ 3 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 3 ] +
  84. elements[ 3 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 2 ];
  85. ret.elements[ 2 ][ 0 ] =
  86. elements[ 1 ][ 0 ] * elements[ 2 ][ 1 ] * elements[ 3 ][ 3 ] -
  87. elements[ 1 ][ 0 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 1 ] -
  88. elements[ 2 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 3 ][ 3 ] +
  89. elements[ 2 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 1 ] +
  90. elements[ 3 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 2 ][ 3 ] -
  91. elements[ 3 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 1 ];
  92. ret.elements[ 3 ][ 0 ] =
  93. -elements[ 1 ][ 0 ] * elements[ 2 ][ 1 ] * elements[ 3 ][ 2 ] +
  94. elements[ 1 ][ 0 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 1 ] +
  95. elements[ 2 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 3 ][ 2 ] -
  96. elements[ 2 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 1 ] -
  97. elements[ 3 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 2 ][ 2 ] +
  98. elements[ 3 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 1 ];
  99. ret.elements[ 0 ][ 1 ] =
  100. -elements[ 0 ][ 1 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 3 ] +
  101. elements[ 0 ][ 1 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 2 ] +
  102. elements[ 2 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 3 ] -
  103. elements[ 2 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 2 ] -
  104. elements[ 3 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 3 ] +
  105. elements[ 3 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 2 ];
  106. ret.elements[ 1 ][ 1 ] =
  107. elements[ 0 ][ 0 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 3 ] -
  108. elements[ 0 ][ 0 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 2 ] -
  109. elements[ 2 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 3 ] +
  110. elements[ 2 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 2 ] +
  111. elements[ 3 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 3 ] -
  112. elements[ 3 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 2 ];
  113. ret.elements[ 2 ][ 1 ] =
  114. -elements[ 0 ][ 0 ] * elements[ 2 ][ 1 ] * elements[ 3 ][ 3 ] +
  115. elements[ 0 ][ 0 ] * elements[ 2 ][ 3 ] * elements[ 3 ][ 1 ] +
  116. elements[ 2 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 3 ][ 3 ] -
  117. elements[ 2 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 1 ] -
  118. elements[ 3 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 2 ][ 3 ] +
  119. elements[ 3 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 1 ];
  120. ret.elements[ 3 ][ 1 ] =
  121. elements[ 0 ][ 0 ] * elements[ 2 ][ 1 ] * elements[ 3 ][ 2 ] -
  122. elements[ 0 ][ 0 ] * elements[ 2 ][ 2 ] * elements[ 3 ][ 1 ] -
  123. elements[ 2 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 3 ][ 2 ] +
  124. elements[ 2 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 1 ] +
  125. elements[ 3 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 2 ][ 2 ] -
  126. elements[ 3 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 1 ];
  127. ret.elements[ 0 ][ 2 ] =
  128. elements[ 0 ][ 1 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 3 ] -
  129. elements[ 0 ][ 1 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 2 ] -
  130. elements[ 1 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 3 ] +
  131. elements[ 1 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 2 ] +
  132. elements[ 3 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 3 ] -
  133. elements[ 3 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 2 ];
  134. ret.elements[ 1 ][ 2 ] =
  135. -elements[ 0 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 3 ] +
  136. elements[ 0 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 2 ] +
  137. elements[ 1 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 3 ] -
  138. elements[ 1 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 2 ] -
  139. elements[ 3 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 3 ] +
  140. elements[ 3 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 2 ];
  141. ret.elements[ 2 ][ 2 ] =
  142. elements[ 0 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 3 ][ 3 ] -
  143. elements[ 0 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 3 ][ 1 ] -
  144. elements[ 1 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 3 ][ 3 ] +
  145. elements[ 1 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 3 ][ 1 ] +
  146. elements[ 3 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 1 ][ 3 ] -
  147. elements[ 3 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 1 ];
  148. ret.elements[ 3 ][ 2 ] =
  149. -elements[ 0 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 3 ][ 2 ] +
  150. elements[ 0 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 3 ][ 1 ] +
  151. elements[ 1 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 3 ][ 2 ] -
  152. elements[ 1 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 3 ][ 1 ] -
  153. elements[ 3 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 1 ][ 2 ] +
  154. elements[ 3 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 1 ];
  155. ret.elements[ 0 ][ 3 ] =
  156. -elements[ 0 ][ 1 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 3 ] +
  157. elements[ 0 ][ 1 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 2 ] +
  158. elements[ 1 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 3 ] -
  159. elements[ 1 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 2 ] -
  160. elements[ 2 ][ 1 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 3 ] +
  161. elements[ 2 ][ 1 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 2 ];
  162. ret.elements[ 1 ][ 3 ] =
  163. elements[ 0 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 3 ] -
  164. elements[ 0 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 2 ] -
  165. elements[ 1 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 3 ] +
  166. elements[ 1 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 2 ] +
  167. elements[ 2 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 3 ] -
  168. elements[ 2 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 2 ];
  169. ret.elements[ 2 ][ 3 ] =
  170. -elements[ 0 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 2 ][ 3 ] +
  171. elements[ 0 ][ 0 ] * elements[ 1 ][ 3 ] * elements[ 2 ][ 1 ] +
  172. elements[ 1 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 2 ][ 3 ] -
  173. elements[ 1 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 2 ][ 1 ] -
  174. elements[ 2 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 1 ][ 3 ] +
  175. elements[ 2 ][ 0 ] * elements[ 0 ][ 3 ] * elements[ 1 ][ 1 ];
  176. ret.elements[ 3 ][ 3 ] =
  177. elements[ 0 ][ 0 ] * elements[ 1 ][ 1 ] * elements[ 2 ][ 2 ] -
  178. elements[ 0 ][ 0 ] * elements[ 1 ][ 2 ] * elements[ 2 ][ 1 ] -
  179. elements[ 1 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 2 ][ 2 ] +
  180. elements[ 1 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 2 ][ 1 ] +
  181. elements[ 2 ][ 0 ] * elements[ 0 ][ 1 ] * elements[ 1 ][ 2 ] -
  182. elements[ 2 ][ 0 ] * elements[ 0 ][ 2 ] * elements[ 1 ][ 1 ];
  183. T det = elements[ 0 ][ 0 ] * ret.elements[ 0 ][ 0 ] + elements[ 0 ][ 1 ] * ret.elements[ 1 ][ 0 ] + elements[ 0 ][ 2 ] * ret.elements[ 2 ][ 0 ] + elements[ 0 ][ 3 ] * ret.elements[ 3 ][ 0 ];
  184. if( det == 0 )
  185. {
  186. std::cout << "Fehler beim erstellen der Inversen Matrix";
  187. return ret;
  188. }
  189. det = 1.0f / det;
  190. for( int i = 0; i < 16; i++ )
  191. ret.elements[ i / 4 ][ i % 4 ] = ret.elements[ i / 4 ][ i % 4 ] * det;
  192. return ret;
  193. }
  194. // Erzeugt eine Matrix, die einen Vektor um die Z Achse dreht, wenn sie mit ihm multipliziert wird
  195. // radian: Der Winkel in Bogenmas
  196. static Mat4 rotationZ( T radian )
  197. {
  198. const T cosTheta = (T)cos( radian );
  199. const T sinTheta = (T)sin( radian );
  200. Mat4 r = { cosTheta, -sinTheta, 0, 0, sinTheta, cosTheta, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
  201. return r;
  202. }
  203. // Erzeugt eine Matrix, die einen Vektor um die X Achse dreht, wenn sie mit ihm multipliziert wird
  204. // radian: Der Winkel in Bogenmas
  205. static Mat4 rotationX( T radian )
  206. {
  207. const T cosTheta = (T)cos( radian );
  208. const T sinTheta = (T)sin( radian );
  209. Mat4 r = { 1, 0, 0, 0, 0, cosTheta, -sinTheta, 0, 0, sinTheta, cosTheta, 0, 0, 0, 0, 1 };
  210. return r;
  211. }
  212. // Erzeugt eine Matrix, die einen Vektor um die Y Achse dreht, wenn sie mit ihm multipliziert wird
  213. // radian: Der Winkel in Bogenmas
  214. static Mat4 rotationY( T radian )
  215. {
  216. const T cosTheta = (T)cos( radian );
  217. const T sinTheta = (T)sin( radian );
  218. Mat4 r = { cosTheta, 0, sinTheta, 0, 0, 1, 0, 0, -sinTheta, 0, cosTheta, 0, 0, 0, 0, 1 };
  219. return r;
  220. }
  221. // Erzeugt eine Matrix, die einen Vektor Skalliert, wenn sie mit ihm multipliziert wird
  222. // faktor: Der Faktor
  223. static Mat4 scaling( T faktor )
  224. {
  225. Mat4 s = { faktor, 0, 0, 0, 0, faktor, 0, 0, 0, 0, faktor, 0, 0, 0, 1 };
  226. return s;
  227. }
  228. // Erzeugt eine Matrix, die einen Vektor Skalliert, wenn sie mit ihm multipliziert wird
  229. // faktorX: Der Faktor für die X Komponente des Vektors
  230. // faktorY: Der Faktor für die Y Komponente des Vektors
  231. // faktorZ: Der Faktor für die Z Komponente des Vektors
  232. static Mat4 scaling( T faktorX, T faktorY, T faktorZ )
  233. {
  234. Mat4 s = { faktorX, 0, 0, 0, 0, faktorY, 0, 0, 0, 0, faktorZ, 0, 0, 0, 1 };
  235. return s;
  236. }
  237. // Erzeugt eine Matrix, die einen Vektor verchiebt, wenn sie mit ihm multipliziert wird
  238. // offset: Die Koordinaten, um die der Vektor verschoben werden soll
  239. static Mat4 translation( const Vec3< T > offset )
  240. {
  241. Mat4 t = { 1, 0, 0, offset.x, 0, 1, 0, offset.y, 0, 0, 1, offset.z, 0, 0, 0, 1 };
  242. return t;
  243. }
  244. // Erzeugt eine Matrix, die einen Vektor auf den Bildschirm Projeziert
  245. // openingAngle: Der Öffnungswinkel der Kamera im Bogenmas
  246. // bildschirmXY: Das Seitenverhältnis des Rechtecks auf dem Bildschirm, in dem gezeichnet werden soll. (Breite / Höhe)
  247. // minz: Der Mindestabstand zur Kamera, ab dem gezeichnet wird
  248. // maxZ: Der Maximalabstand zur Kamera, ab dem nicht mehr gezeichnet wird
  249. static Mat4 projektion( float openingAngle, float bildschirmXY, float minZ, float maxZ )
  250. {
  251. Mat4 p = { (float)( 1 / tan( openingAngle / 2 ) ) / bildschirmXY, 0, 0, 0,
  252. 0, (float)( 1 / tan( openingAngle / 2 ) ), 0, 0,
  253. 0, 0, maxZ / ( maxZ - minZ ), -( minZ * maxZ ) / ( maxZ - minZ ),
  254. 0, 0, 1, 0 };
  255. return p;
  256. }
  257. // Erzeugt eine Matrix, die mit allem Multipliziert werden kann ohne es zu ändern
  258. static Mat4 identity()
  259. {
  260. Mat4 i = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
  261. return i;
  262. }
  263. };
  264. }