305 行
7.2 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 __LOL_MATRIX_H__
  15. #define __LOL_MATRIX_H__
  16. #include <cmath>
  17. namespace lol
  18. {
  19. #define VECTOR_OP(elems, op) \
  20. template<typename U> \
  21. inline Vec##elems<T> operator op(Vec##elems<U> const &val) const \
  22. { \
  23. Vec##elems<T> ret; \
  24. for (int n = 0; n < elems; n++) \
  25. ret[n] = (*this)[n] op val[n]; \
  26. return ret; \
  27. } \
  28. \
  29. template<typename U> \
  30. inline Vec##elems<T> operator op##=(Vec##elems<U> const &val) \
  31. { \
  32. return *this = (*this) op val; \
  33. }
  34. #define BOOL_OP(elems, op, op2, ret) \
  35. inline bool operator op(Vec##elems<T> const &val) const \
  36. { \
  37. for (int n = 0; n < elems; n++) \
  38. if (!((*this)[n] op2 val[n])) \
  39. return !ret; \
  40. return ret; \
  41. }
  42. #define SCALAR_OP(elems, op) \
  43. inline Vec##elems<T> operator op(T const &val) const \
  44. { \
  45. Vec##elems<T> ret; \
  46. for (int n = 0; n < elems; n++) \
  47. ret[n] = (*this)[n] op val; \
  48. return ret; \
  49. } \
  50. \
  51. inline Vec##elems<T> operator op##=(T const &val) \
  52. { \
  53. return *this = (*this) op val; \
  54. }
  55. #define CAST_OP(elems, dest) \
  56. inline operator Vec##dest<T>() const \
  57. { \
  58. Vec##dest<T> ret; \
  59. for (int n = 0; n < elems && n < dest; n++) \
  60. ret[n] = (*this)[n]; \
  61. for (int n = elems; n < dest; n++) \
  62. ret[n] = 0; \
  63. return ret; \
  64. }
  65. #define OPERATORS(elems) \
  66. inline T& operator[](int n) { return *(&x + n); } \
  67. inline T const& operator[](int n) const { return *(&x + n); } \
  68. \
  69. VECTOR_OP(elems, -) \
  70. VECTOR_OP(elems, +) \
  71. VECTOR_OP(elems, *) \
  72. VECTOR_OP(elems, /) \
  73. \
  74. BOOL_OP(elems, ==, ==, true) \
  75. BOOL_OP(elems, !=, ==, false) \
  76. BOOL_OP(elems, <=, <=, true) \
  77. BOOL_OP(elems, >=, >=, true) \
  78. BOOL_OP(elems, <, <, true) \
  79. BOOL_OP(elems, >, >, true) \
  80. \
  81. SCALAR_OP(elems, -) \
  82. SCALAR_OP(elems, +) \
  83. SCALAR_OP(elems, *) \
  84. SCALAR_OP(elems, /) \
  85. \
  86. CAST_OP(elems, 2) \
  87. CAST_OP(elems, 3) \
  88. CAST_OP(elems, 4) \
  89. \
  90. template<typename U> \
  91. inline operator Vec##elems<U>() const \
  92. { \
  93. Vec##elems<U> ret; \
  94. for (int n = 0; n < elems; n++) \
  95. ret[n] = static_cast<U>((*this)[n]); \
  96. return ret; \
  97. } \
  98. \
  99. inline Vec##elems<T> operator -() const \
  100. { \
  101. Vec##elems<T> ret; \
  102. for (int n = 0; n < elems; n++) \
  103. ret[n] = -(*this)[n]; \
  104. return ret; \
  105. } \
  106. \
  107. inline T sqlen() const \
  108. { \
  109. T acc = 0; \
  110. for (int n = 0; n < elems; n++) \
  111. acc += (*this)[n] * (*this)[n]; \
  112. return acc; \
  113. } \
  114. \
  115. inline float len() const \
  116. { \
  117. using namespace std; \
  118. return sqrtf((float)sqlen()); \
  119. }
  120. template <typename T> struct Vec2;
  121. template <typename T> struct Vec3;
  122. template <typename T> struct Vec4;
  123. template <typename T> struct Vec2
  124. {
  125. inline Vec2() { }
  126. inline Vec2(T val) { x = y = val; }
  127. inline Vec2(T _x, T _y) { x = _x; y = _y; }
  128. OPERATORS(2)
  129. union { T x; T a; T i; };
  130. union { T y; T b; T j; };
  131. };
  132. typedef Vec2<float> vec2;
  133. typedef Vec2<int> ivec2;
  134. template <typename T> struct Vec3
  135. {
  136. inline Vec3() { }
  137. inline Vec3(T val) { x = y = z = val; }
  138. inline Vec3(T _x, T _y, T _z) { x = _x; y = _y; z = _z; }
  139. OPERATORS(3)
  140. union { T x; T a; T i; };
  141. union { T y; T b; T j; };
  142. union { T z; T c; T k; };
  143. };
  144. typedef Vec3<float> vec3;
  145. typedef Vec3<int> vec3i;
  146. template <typename T> struct Vec4
  147. {
  148. inline Vec4() { }
  149. inline Vec4(T val) { x = y = z = w = val; }
  150. inline Vec4(T _x, T _y, T _z, T _w) { x = _x; y = _y; z = _z; w = _w; }
  151. OPERATORS(4)
  152. union { T x; T a; T i; };
  153. union { T y; T b; T j; };
  154. union { T z; T c; T k; };
  155. union { T w; T d; T l; };
  156. };
  157. typedef Vec4<float> vec4;
  158. typedef Vec4<int> vec4i;
  159. #define SCALAR_GLOBAL(elems, op, U) \
  160. template<typename T> \
  161. static inline Vec##elems<U> operator op(U const &val, \
  162. Vec##elems<T> const &that) \
  163. { \
  164. Vec##elems<U> ret; \
  165. for (int n = 0; n < elems; n++) \
  166. ret[n] = val op that[n]; \
  167. return ret; \
  168. }
  169. #define SCALAR_GLOBAL2(elems, op) \
  170. SCALAR_GLOBAL(elems, op, int) \
  171. SCALAR_GLOBAL(elems, op, float)
  172. #define GLOBALS(elems) \
  173. SCALAR_GLOBAL2(elems, -) \
  174. SCALAR_GLOBAL2(elems, +) \
  175. SCALAR_GLOBAL2(elems, *) \
  176. SCALAR_GLOBAL2(elems, /)
  177. GLOBALS(2)
  178. GLOBALS(3)
  179. GLOBALS(4)
  180. template <typename T> struct Mat4
  181. {
  182. inline Mat4() { }
  183. inline Mat4(T val)
  184. {
  185. for (int j = 0; j < 4; j++)
  186. for (int i = 0; i < 4; i++)
  187. v[i][j] = (i == j) ? val : 0;
  188. }
  189. inline Mat4(Vec4<T> v0, Vec4<T> v1, Vec4<T> v2, Vec4<T> v3)
  190. {
  191. v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3;
  192. }
  193. inline Vec4<T>& operator[](int n) { return v[n]; }
  194. inline Vec4<T> const& operator[](int n) const { return v[n]; }
  195. T det() const;
  196. Mat4<T> invert() const;
  197. static Mat4<T> ortho(T left, T right, T bottom, T top, T near, T far);
  198. static Mat4<T> frustum(T left, T right, T bottom, T top, T near, T far);
  199. static Mat4<T> perspective(T theta, T width, T height, T near, T far);
  200. static Mat4<T> translate(T x, T y, T z);
  201. static Mat4<T> rotate(T theta, T x, T y, T z);
  202. void printf() const;
  203. inline Mat4<T> operator +(Mat4<T> const val) const
  204. {
  205. Mat4<T> ret;
  206. for (int j = 0; j < 4; j++)
  207. for (int i = 0; i < 4; i++)
  208. ret[i][j] = v[i][j] + val[i][j];
  209. return ret;
  210. }
  211. inline Mat4<T> operator +=(Mat4<T> const val)
  212. {
  213. return *this = *this + val;
  214. }
  215. inline Mat4<T> operator -(Mat4<T> const val) const
  216. {
  217. Mat4<T> ret;
  218. for (int j = 0; j < 4; j++)
  219. for (int i = 0; i < 4; i++)
  220. ret[i][j] = v[i][j] - val[i][j];
  221. return ret;
  222. }
  223. inline Mat4<T> operator -=(Mat4<T> const val)
  224. {
  225. return *this = *this - val;
  226. }
  227. inline Mat4<T> operator *(Mat4<T> const val) const
  228. {
  229. Mat4<T> ret;
  230. for (int j = 0; j < 4; j++)
  231. for (int i = 0; i < 4; i++)
  232. {
  233. T tmp = 0;
  234. for (int k = 0; k < 4; k++)
  235. tmp += v[k][j] * val[i][k];
  236. ret[i][j] = tmp;
  237. }
  238. return ret;
  239. }
  240. inline Mat4<T> operator *=(Mat4<T> const val)
  241. {
  242. return *this = *this * val;
  243. }
  244. inline Vec4<T> operator *(Vec4<T> const val) const
  245. {
  246. Vec4<T> ret;
  247. for (int j = 0; j < 4; j++)
  248. {
  249. T tmp = 0;
  250. for (int i = 0; i < 4; i++)
  251. tmp += v[i][j] * val[i];
  252. ret[j] = tmp;
  253. }
  254. return ret;
  255. }
  256. Vec4<T> v[4];
  257. };
  258. typedef Mat4<float> mat4;
  259. typedef Mat4<int> mat4i;
  260. } /* namespace lol */
  261. #endif // __LOL_MATRIX_H__