293 regels
6.9 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. //
  11. // The Matrix classes
  12. // ------------------
  13. //
  14. #if !defined __DH_MATRIX_H__
  15. #define __DH_MATRIX_H__
  16. #include <cmath>
  17. #define VECTOR_OP(elems, op) \
  18. template<typename U> \
  19. inline Vec##elems<T> operator op(Vec##elems<U> const &val) const \
  20. { \
  21. Vec##elems<T> ret; \
  22. for (int n = 0; n < elems; n++) \
  23. ret[n] = (*this)[n] op val[n]; \
  24. return ret; \
  25. } \
  26. \
  27. template<typename U> \
  28. inline Vec##elems<T> operator op##=(Vec##elems<U> const &val) \
  29. { \
  30. return *this = (*this) op val; \
  31. }
  32. #define BOOL_OP(elems, op, ret) \
  33. inline bool operator op(Vec##elems<T> const &val) const \
  34. { \
  35. for (int n = 0; n < elems; n++) \
  36. if ((*this)[n] != val[n]) \
  37. return ret; \
  38. return !ret; \
  39. }
  40. #define SCALAR_OP(elems, op) \
  41. inline Vec##elems<T> operator op(T const &val) const \
  42. { \
  43. Vec##elems<T> ret; \
  44. for (int n = 0; n < elems; n++) \
  45. ret[n] = (*this)[n] op val; \
  46. return ret; \
  47. } \
  48. \
  49. inline Vec##elems<T> operator op##=(T const &val) \
  50. { \
  51. return *this = (*this) op val; \
  52. }
  53. #define CAST_OP(elems, dest) \
  54. inline operator Vec##dest<T>() const \
  55. { \
  56. Vec##dest<T> ret; \
  57. for (int n = 0; n < elems && n < dest; n++) \
  58. ret[n] = (*this)[n]; \
  59. return ret; \
  60. }
  61. #define OPERATORS(elems) \
  62. inline T& operator[](int n) { return *(&x + n); } \
  63. inline T const& operator[](int n) const { return *(&x + n); } \
  64. \
  65. VECTOR_OP(elems, -) \
  66. VECTOR_OP(elems, +) \
  67. VECTOR_OP(elems, *) \
  68. VECTOR_OP(elems, /) \
  69. \
  70. BOOL_OP(elems, ==, false) \
  71. BOOL_OP(elems, !=, true) \
  72. \
  73. SCALAR_OP(elems, -) \
  74. SCALAR_OP(elems, +) \
  75. SCALAR_OP(elems, *) \
  76. SCALAR_OP(elems, /) \
  77. \
  78. CAST_OP(elems, 2) \
  79. CAST_OP(elems, 3) \
  80. CAST_OP(elems, 4) \
  81. \
  82. template<typename U> \
  83. inline operator Vec##elems<U>() const \
  84. { \
  85. Vec##elems<U> ret; \
  86. for (int n = 0; n < elems; n++) \
  87. ret[n] = static_cast<U>((*this)[n]); \
  88. return ret; \
  89. } \
  90. \
  91. inline T sqlen() const \
  92. { \
  93. T acc = 0; \
  94. for (int n = 0; n < elems; n++) \
  95. acc += (*this)[n] * (*this)[n]; \
  96. return acc; \
  97. } \
  98. \
  99. inline float len() const \
  100. { \
  101. return sqrtf((float)sqlen()); \
  102. }
  103. template <typename T> struct Vec2;
  104. template <typename T> struct Vec3;
  105. template <typename T> struct Vec4;
  106. template <typename T> struct Vec2
  107. {
  108. inline Vec2() { }
  109. inline Vec2(T val) { x = y = val; }
  110. inline Vec2(T _x, T _y) { x = _x; y = _y; }
  111. OPERATORS(2)
  112. union { T x; T a; T i; };
  113. union { T y; T b; T j; };
  114. };
  115. typedef Vec2<float> vec2;
  116. typedef Vec2<int> vec2i;
  117. template <typename T> struct Vec3
  118. {
  119. inline Vec3() { }
  120. inline Vec3(T val) { x = y = z = val; }
  121. inline Vec3(T _x, T _y, T _z) { x = _x; y = _y; z = _z; }
  122. OPERATORS(3)
  123. union { T x; T a; T i; };
  124. union { T y; T b; T j; };
  125. union { T z; T c; T k; };
  126. };
  127. typedef Vec3<float> vec3;
  128. typedef Vec3<int> vec3i;
  129. template <typename T> struct Vec4
  130. {
  131. inline Vec4() { }
  132. inline Vec4(T val) { x = y = z = w = val; }
  133. inline Vec4(T _x, T _y, T _z, T _w) { x = _x; y = _y; z = _z; w = _w; }
  134. OPERATORS(4)
  135. union { T x; T a; T i; };
  136. union { T y; T b; T j; };
  137. union { T z; T c; T k; };
  138. union { T w; T d; T l; };
  139. };
  140. typedef Vec4<float> vec4;
  141. typedef Vec4<int> vec4i;
  142. #define SCALAR_GLOBAL(elems, op, U) \
  143. template<typename T> \
  144. static inline Vec##elems<U> operator op(U const &val, \
  145. Vec##elems<T> const &that) \
  146. { \
  147. Vec##elems<U> ret; \
  148. for (int n = 0; n < elems; n++) \
  149. ret[n] = val op that[n]; \
  150. return ret; \
  151. }
  152. #define SCALAR_GLOBAL2(elems, op) \
  153. SCALAR_GLOBAL(elems, op, int) \
  154. SCALAR_GLOBAL(elems, op, float)
  155. #define GLOBALS(elems) \
  156. SCALAR_GLOBAL2(elems, -) \
  157. SCALAR_GLOBAL2(elems, +) \
  158. SCALAR_GLOBAL2(elems, *) \
  159. SCALAR_GLOBAL2(elems, /)
  160. GLOBALS(2)
  161. GLOBALS(3)
  162. GLOBALS(4)
  163. template <typename T> struct Mat4
  164. {
  165. inline Mat4() { }
  166. inline Mat4(T val)
  167. {
  168. for (int j = 0; j < 4; j++)
  169. for (int i = 0; i < 4; i++)
  170. v[i][j] = (i == j) ? val : 0;
  171. }
  172. inline Mat4(Vec4<T> v0, Vec4<T> v1, Vec4<T> v2, Vec4<T> v3)
  173. {
  174. v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3;
  175. }
  176. inline Vec4<T>& operator[](int n) { return v[n]; }
  177. inline Vec4<T> const& operator[](int n) const { return v[n]; }
  178. T det() const;
  179. Mat4<T> invert() const;
  180. static Mat4<T> ortho(T left, T right, T bottom, T top, T near, T far);
  181. static Mat4<T> frustum(T left, T right, T bottom, T top, T near, T far);
  182. static Mat4<T> perspective(T theta, T width, T height, T near, T far);
  183. static Mat4<T> translate(T x, T y, T z);
  184. static Mat4<T> rotate(T theta, T x, T y, T z);
  185. inline Mat4<T> operator +(Mat4<T> const val) const
  186. {
  187. Mat4<T> ret;
  188. for (int j = 0; j < 4; j++)
  189. for (int i = 0; i < 4; i++)
  190. ret[i][j] = v[i][j] + val[i][j];
  191. return ret;
  192. }
  193. inline Mat4<T> operator +=(Mat4<T> const val)
  194. {
  195. return *this = *this + val;
  196. }
  197. inline Mat4<T> operator -(Mat4<T> const val) const
  198. {
  199. Mat4<T> ret;
  200. for (int j = 0; j < 4; j++)
  201. for (int i = 0; i < 4; i++)
  202. ret[i][j] = v[i][j] - val[i][j];
  203. return ret;
  204. }
  205. inline Mat4<T> operator -=(Mat4<T> const val)
  206. {
  207. return *this = *this - val;
  208. }
  209. inline Mat4<T> operator *(Mat4<T> const val) const
  210. {
  211. Mat4<T> ret;
  212. for (int j = 0; j < 4; j++)
  213. for (int i = 0; i < 4; i++)
  214. {
  215. T tmp = 0;
  216. for (int k = 0; k < 4; k++)
  217. tmp += v[k][j] * val[i][k];
  218. ret[i][j] = tmp;
  219. }
  220. return ret;
  221. }
  222. inline Mat4<T> operator *=(Mat4<T> const val)
  223. {
  224. return *this = *this * val;
  225. }
  226. inline Vec4<T> operator *(Vec4<T> const val) const
  227. {
  228. Vec4<T> ret;
  229. for (int j = 0; j < 4; j++)
  230. {
  231. T tmp = 0;
  232. for (int i = 0; i < 4; i++)
  233. tmp += v[i][j] * val[i];
  234. ret[j] = tmp;
  235. }
  236. return ret;
  237. }
  238. Vec4<T> v[4];
  239. };
  240. typedef Mat4<float> mat4;
  241. typedef Mat4<int> mat4i;
  242. /* Aliases for deprecated stuff */
  243. typedef Vec2<float> float2;
  244. typedef Vec2<int> int2;
  245. typedef Vec3<float> float3;
  246. typedef Vec3<int> int3;
  247. typedef Vec4<float> float4;
  248. typedef Vec4<int> int4;
  249. typedef Mat4<float> float4x4;
  250. typedef Mat4<int> int4x4;
  251. #endif // __DH_MATRIX_H__