You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1084 lines
40 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2014 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://www.wtfpl.net/ for more details.
  9. //
  10. //
  11. // The vector classes
  12. // ------------------
  13. //
  14. #if !defined __LOL_MATH_VECTOR_H__
  15. #define __LOL_MATH_VECTOR_H__
  16. #include <ostream>
  17. #include <lol/math/half.h>
  18. #include <lol/math/real.h>
  19. #include <lol/math/ops.h>
  20. namespace lol
  21. {
  22. #if !LOL_FEATURE_CXX11_CONSTEXPR
  23. # define constexpr /* */
  24. #endif
  25. #if !LOL_FEATURE_CXX11_RELAXED_UNIONS
  26. # define _____ const
  27. #else
  28. # define _____ /* */
  29. #endif
  30. /*
  31. * Magic vector swizzling (part 1/2)
  32. * These vectors are empty, but thanks to static_cast we can take their
  33. * address and access the vector of T's that they are union'ed with. We
  34. * use static_cast instead of reinterpret_cast because there is a stronger
  35. * guarantee (by the standard) that the address will stay the same across
  36. * casts.
  37. * We need to implement an assignment operator _and_ override the default
  38. * assignment operator. We try to pass arguments by value so that we don't
  39. * have to care about overwriting ourselves (e.g. c.rgb = c.bgr).
  40. * However, Visual Studio 2012 doesn't support unrestricted unions, so
  41. * fuck it.
  42. */
  43. template<typename T, int N, int SWIZZLE>
  44. struct vec_t
  45. /* MUST be a different base than e.g. vec_t<T,2> otherwise the unions
  46. * in vec_t<T,2> with the same base will cause empty base optimisation
  47. * failures. */
  48. : public swizzle_ops::base<T, SWIZZLE>
  49. {
  50. static int const count = N;
  51. typedef T element;
  52. typedef vec_t<T,N> type;
  53. inline vec_t<T, N, SWIZZLE>& operator =(vec_t<T, N> that);
  54. #if LOL_FEATURE_CXX11_RELAXED_UNIONS
  55. inline vec_t<T, N, SWIZZLE>& operator =(vec_t<T, N, SWIZZLE> const &that)
  56. {
  57. /* Pass by value in case this == &that */
  58. return *this = (vec_t<T,N>)that;
  59. }
  60. #endif
  61. inline T& operator[](size_t n)
  62. {
  63. int i = (SWIZZLE >> (4 * (N - 1 - n))) & 3;
  64. return static_cast<T*>(static_cast<void*>(this))[i];
  65. }
  66. inline T const& operator[](size_t n) const
  67. {
  68. int i = (SWIZZLE >> (4 * (N - 1 - n))) & 3;
  69. return static_cast<T const*>(static_cast<void const *>(this))[i];
  70. }
  71. };
  72. /* The generic “vec_t” type, which is a fixed-size vector with no
  73. * swizzling. There's an override for N=2, N=3, N=4 that has swizzling. */
  74. template<typename T, int N>
  75. struct vec_t<T, N, FULL_SWIZZLE>
  76. : public linear_ops::base<T>,
  77. public componentwise_ops::base<T>
  78. {
  79. static int const count = N;
  80. typedef T element;
  81. typedef vec_t<T,N> type;
  82. inline T& operator[](size_t n) { return m_data[n]; }
  83. inline T const& operator[](size_t n) const { return m_data[n]; }
  84. private:
  85. T m_data[N];
  86. };
  87. /*
  88. * Helper macros for vector type member functions
  89. */
  90. #define LOL_COMMON_MEMBER_OPS(first) \
  91. inline T& operator[](size_t n) { return (&this->first)[n]; } \
  92. inline T const& operator[](size_t n) const { return (&this->first)[n]; } \
  93. \
  94. /* Visual Studio insists on having an assignment operator. */ \
  95. inline type & operator =(type const &that) \
  96. { \
  97. for (int i = 0; i < type::count; ++i) \
  98. (*this)[i] = that[i]; \
  99. return *this; \
  100. } \
  101. \
  102. void printf() const; \
  103. String tostring() const;
  104. /*
  105. * 2-element vectors
  106. */
  107. template <typename T>
  108. struct vec_t<T,2>
  109. : public swizzle_ops::base<T>,
  110. public linear_ops::base<T>,
  111. public componentwise_ops::base<T>
  112. {
  113. static int const count = 2;
  114. typedef T element;
  115. typedef vec_t<T,2> type;
  116. /* Default constructor, copy constructor, and destructor */
  117. inline constexpr vec_t() : x(), y() {}
  118. inline constexpr vec_t(vec_t<T,2> const &v) : x(v.x), y(v.y) {}
  119. inline ~vec_t() { x.~T(); y.~T(); }
  120. /* Implicit constructor for swizzling */
  121. template<int SWIZZLE>
  122. inline constexpr vec_t(vec_t<T, 2, SWIZZLE> const &v)
  123. : x(v[0]), y(v[1]) {}
  124. /* Explicit constructor for type conversion */
  125. template<typename U, int SWIZZLE>
  126. explicit inline constexpr vec_t(vec_t<U, 2, SWIZZLE> const &v)
  127. : x(v[0]), y(v[1]) {}
  128. /* Various explicit constructors */
  129. explicit inline constexpr vec_t(T X, T Y)
  130. : x(X), y(Y) {}
  131. explicit inline constexpr vec_t(T X)
  132. : x(X), y(X) {}
  133. LOL_COMMON_MEMBER_OPS(x)
  134. static const vec_t<T,2> zero;
  135. static const vec_t<T,2> axis_x;
  136. static const vec_t<T,2> axis_y;
  137. template<typename U>
  138. friend std::ostream &operator<<(std::ostream &stream, vec_t<U,2> const &v);
  139. union
  140. {
  141. struct { T x, y; };
  142. struct { T r, g; };
  143. struct { T s, t; };
  144. #if !_DOXYGEN_SKIP_ME
  145. vec_t<T,2,0x00> const xx, rr, ss;
  146. vec_t<T,2,0x01> _____ xy, rg, st;
  147. vec_t<T,2,0x10> _____ yx, gr, ts;
  148. vec_t<T,2,0x11> const yy, gg, tt;
  149. vec_t<T,3,0x000> const xxx, rrr, sss;
  150. vec_t<T,3,0x001> const xxy, rrg, sst;
  151. vec_t<T,3,0x010> const xyx, rgr, sts;
  152. vec_t<T,3,0x011> const xyy, rgg, stt;
  153. vec_t<T,3,0x100> const yxx, grr, tss;
  154. vec_t<T,3,0x101> const yxy, grg, tst;
  155. vec_t<T,3,0x110> const yyx, ggr, tts;
  156. vec_t<T,3,0x111> const yyy, ggg, ttt;
  157. vec_t<T,4,0x0000> const xxxx, rrrr, ssss;
  158. vec_t<T,4,0x0001> const xxxy, rrrg, ssst;
  159. vec_t<T,4,0x0010> const xxyx, rrgr, ssts;
  160. vec_t<T,4,0x0011> const xxyy, rrgg, sstt;
  161. vec_t<T,4,0x0100> const xyxx, rgrr, stss;
  162. vec_t<T,4,0x0101> const xyxy, rgrg, stst;
  163. vec_t<T,4,0x0110> const xyyx, rggr, stts;
  164. vec_t<T,4,0x0111> const xyyy, rggg, sttt;
  165. vec_t<T,4,0x1000> const yxxx, grrr, tsss;
  166. vec_t<T,4,0x1001> const yxxy, grrg, tsst;
  167. vec_t<T,4,0x1010> const yxyx, grgr, tsts;
  168. vec_t<T,4,0x1011> const yxyy, grgg, tstt;
  169. vec_t<T,4,0x1100> const yyxx, ggrr, ttss;
  170. vec_t<T,4,0x1101> const yyxy, ggrg, ttst;
  171. vec_t<T,4,0x1110> const yyyx, gggr, ttts;
  172. vec_t<T,4,0x1111> const yyyy, gggg, tttt;
  173. #endif
  174. };
  175. };
  176. static_assert(sizeof(i8vec2) == 2, "sizeof(i8vec2) == 2");
  177. static_assert(sizeof(i16vec2) == 4, "sizeof(i16vec2) == 4");
  178. static_assert(sizeof(ivec2) == 8, "sizeof(ivec2) == 8");
  179. static_assert(sizeof(i64vec2) == 16, "sizeof(i64vec2) == 16");
  180. static_assert(sizeof(f16vec2) == 4, "sizeof(f16vec2) == 4");
  181. static_assert(sizeof(vec2) == 8, "sizeof(vec2) == 8");
  182. static_assert(sizeof(dvec2) == 16, "sizeof(dvec2) == 16");
  183. /*
  184. * 3-element vectors
  185. */
  186. template <typename T>
  187. struct vec_t<T,3>
  188. : public swizzle_ops::base<T>,
  189. public linear_ops::base<T>,
  190. public componentwise_ops::base<T>
  191. {
  192. static int const count = 3;
  193. typedef T element;
  194. typedef vec_t<T,3> type;
  195. /* Default constructor, copy constructor, and destructor */
  196. inline constexpr vec_t() : x(), y(), z() {}
  197. inline constexpr vec_t(vec_t<T,3> const &v) : x(v.x), y(v.y), z(v.z) {}
  198. inline ~vec_t() { x.~T(); y.~T(); z.~T(); }
  199. /* Implicit constructor for swizzling */
  200. template<int SWIZZLE>
  201. inline constexpr vec_t(vec_t<T, 3, SWIZZLE> const &v)
  202. : x(v[0]), y(v[1]), z(v[2]) {}
  203. /* Explicit constructor for type conversion */
  204. template<typename U, int SWIZZLE>
  205. explicit inline constexpr vec_t(vec_t<U, 3, SWIZZLE> const &v)
  206. : x(v[0]), y(v[1]), z(v[2]) {}
  207. /* Various explicit constructors */
  208. explicit inline constexpr vec_t(T X)
  209. : x(X), y(X), z(X) {}
  210. explicit inline constexpr vec_t(T X, T Y, T Z)
  211. : x(X), y(Y), z(Z) {}
  212. explicit inline constexpr vec_t(vec_t<T,2> XY, T Z)
  213. : x(XY.x), y(XY.y), z(Z) {}
  214. explicit inline constexpr vec_t(T X, vec_t<T,2> YZ)
  215. : x(X), y(YZ.x), z(YZ.y) {}
  216. LOL_COMMON_MEMBER_OPS(x)
  217. static vec_t<T,3> toeuler_xyx(quat_t<T> const &q);
  218. static vec_t<T,3> toeuler_xzx(quat_t<T> const &q);
  219. static vec_t<T,3> toeuler_yxy(quat_t<T> const &q);
  220. static vec_t<T,3> toeuler_yzy(quat_t<T> const &q);
  221. static vec_t<T,3> toeuler_zxz(quat_t<T> const &q);
  222. static vec_t<T,3> toeuler_zyz(quat_t<T> const &q);
  223. static vec_t<T,3> toeuler_xyz(quat_t<T> const &q);
  224. static vec_t<T,3> toeuler_xzy(quat_t<T> const &q);
  225. static vec_t<T,3> toeuler_yxz(quat_t<T> const &q);
  226. static vec_t<T,3> toeuler_yzx(quat_t<T> const &q);
  227. static vec_t<T,3> toeuler_zxy(quat_t<T> const &q);
  228. static vec_t<T,3> toeuler_zyx(quat_t<T> const &q);
  229. /* Return the cross product (vector product) of “a” and “b” */ \
  230. friend inline type cross(type const &a, type const &b)
  231. {
  232. return type(a.y * b.z - a.z * b.y,
  233. a.z * b.x - a.x * b.z,
  234. a.x * b.y - a.y * b.x);
  235. }
  236. /* Return a vector that is orthogonal to “a” */
  237. friend inline type orthogonal(type const &a)
  238. {
  239. return lol::abs(a.x) > lol::abs(a.z)
  240. ? type(-a.y, a.x, (T)0)
  241. : type((T)0, -a.z, a.y);
  242. }
  243. /* Return a vector that is orthonormal to “a” */
  244. friend inline type orthonormal(type const &a)
  245. {
  246. return normalize(orthogonal(a));
  247. }
  248. static const vec_t<T,3> zero;
  249. static const vec_t<T,3> axis_x;
  250. static const vec_t<T,3> axis_y;
  251. static const vec_t<T,3> axis_z;
  252. template<typename U>
  253. friend std::ostream &operator<<(std::ostream &stream, vec_t<U,3> const &v);
  254. union
  255. {
  256. struct { T x, y, z; };
  257. struct { T r, g, b; };
  258. struct { T s, t, p; };
  259. #if !_DOXYGEN_SKIP_ME
  260. vec_t<T,2,0x00> const xx, rr, ss;
  261. vec_t<T,2,0x01> _____ xy, rg, st;
  262. vec_t<T,2,0x02> _____ xz, rb, sp;
  263. vec_t<T,2,0x10> _____ yx, gr, ts;
  264. vec_t<T,2,0x11> const yy, gg, tt;
  265. vec_t<T,2,0x12> _____ yz, gb, tp;
  266. vec_t<T,2,0x20> _____ zx, br, ps;
  267. vec_t<T,2,0x21> _____ zy, bg, pt;
  268. vec_t<T,2,0x22> const zz, bb, pp;
  269. vec_t<T,3,0x000> const xxx, rrr, sss;
  270. vec_t<T,3,0x001> const xxy, rrg, sst;
  271. vec_t<T,3,0x002> const xxz, rrb, ssp;
  272. vec_t<T,3,0x010> const xyx, rgr, sts;
  273. vec_t<T,3,0x011> const xyy, rgg, stt;
  274. vec_t<T,3,0x012> _____ xyz, rgb, stp;
  275. vec_t<T,3,0x020> const xzx, rbr, sps;
  276. vec_t<T,3,0x021> _____ xzy, rbg, spt;
  277. vec_t<T,3,0x022> const xzz, rbb, spp;
  278. vec_t<T,3,0x100> const yxx, grr, tss;
  279. vec_t<T,3,0x101> const yxy, grg, tst;
  280. vec_t<T,3,0x102> _____ yxz, grb, tsp;
  281. vec_t<T,3,0x110> const yyx, ggr, tts;
  282. vec_t<T,3,0x111> const yyy, ggg, ttt;
  283. vec_t<T,3,0x112> const yyz, ggb, ttp;
  284. vec_t<T,3,0x120> _____ yzx, gbr, tps;
  285. vec_t<T,3,0x121> const yzy, gbg, tpt;
  286. vec_t<T,3,0x122> const yzz, gbb, tpp;
  287. vec_t<T,3,0x200> const zxx, brr, pss;
  288. vec_t<T,3,0x201> _____ zxy, brg, pst;
  289. vec_t<T,3,0x202> const zxz, brb, psp;
  290. vec_t<T,3,0x210> _____ zyx, bgr, pts;
  291. vec_t<T,3,0x211> const zyy, bgg, ptt;
  292. vec_t<T,3,0x212> const zyz, bgb, ptp;
  293. vec_t<T,3,0x220> const zzx, bbr, pps;
  294. vec_t<T,3,0x221> const zzy, bbg, ppt;
  295. vec_t<T,3,0x222> const zzz, bbb, ppp;
  296. vec_t<T,4,0x0000> const xxxx, rrrr, ssss;
  297. vec_t<T,4,0x0001> const xxxy, rrrg, ssst;
  298. vec_t<T,4,0x0002> const xxxz, rrrb, sssp;
  299. vec_t<T,4,0x0010> const xxyx, rrgr, ssts;
  300. vec_t<T,4,0x0011> const xxyy, rrgg, sstt;
  301. vec_t<T,4,0x0012> const xxyz, rrgb, sstp;
  302. vec_t<T,4,0x0020> const xxzx, rrbr, ssps;
  303. vec_t<T,4,0x0021> const xxzy, rrbg, sspt;
  304. vec_t<T,4,0x0022> const xxzz, rrbb, sspp;
  305. vec_t<T,4,0x0100> const xyxx, rgrr, stss;
  306. vec_t<T,4,0x0101> const xyxy, rgrg, stst;
  307. vec_t<T,4,0x0102> const xyxz, rgrb, stsp;
  308. vec_t<T,4,0x0110> const xyyx, rggr, stts;
  309. vec_t<T,4,0x0111> const xyyy, rggg, sttt;
  310. vec_t<T,4,0x0112> const xyyz, rggb, sttp;
  311. vec_t<T,4,0x0120> const xyzx, rgbr, stps;
  312. vec_t<T,4,0x0121> const xyzy, rgbg, stpt;
  313. vec_t<T,4,0x0122> const xyzz, rgbb, stpp;
  314. vec_t<T,4,0x0200> const xzxx, rbrr, spss;
  315. vec_t<T,4,0x0201> const xzxy, rbrg, spst;
  316. vec_t<T,4,0x0202> const xzxz, rbrb, spsp;
  317. vec_t<T,4,0x0210> const xzyx, rbgr, spts;
  318. vec_t<T,4,0x0211> const xzyy, rbgg, sptt;
  319. vec_t<T,4,0x0212> const xzyz, rbgb, sptp;
  320. vec_t<T,4,0x0220> const xzzx, rbbr, spps;
  321. vec_t<T,4,0x0221> const xzzy, rbbg, sppt;
  322. vec_t<T,4,0x0222> const xzzz, rbbb, sppp;
  323. vec_t<T,4,0x1000> const yxxx, grrr, tsss;
  324. vec_t<T,4,0x1001> const yxxy, grrg, tsst;
  325. vec_t<T,4,0x1002> const yxxz, grrb, tssp;
  326. vec_t<T,4,0x1010> const yxyx, grgr, tsts;
  327. vec_t<T,4,0x1011> const yxyy, grgg, tstt;
  328. vec_t<T,4,0x1012> const yxyz, grgb, tstp;
  329. vec_t<T,4,0x1020> const yxzx, grbr, tsps;
  330. vec_t<T,4,0x1021> const yxzy, grbg, tspt;
  331. vec_t<T,4,0x1022> const yxzz, grbb, tspp;
  332. vec_t<T,4,0x1100> const yyxx, ggrr, ttss;
  333. vec_t<T,4,0x1101> const yyxy, ggrg, ttst;
  334. vec_t<T,4,0x1102> const yyxz, ggrb, ttsp;
  335. vec_t<T,4,0x1110> const yyyx, gggr, ttts;
  336. vec_t<T,4,0x1111> const yyyy, gggg, tttt;
  337. vec_t<T,4,0x1112> const yyyz, gggb, tttp;
  338. vec_t<T,4,0x1120> const yyzx, ggbr, ttps;
  339. vec_t<T,4,0x1121> const yyzy, ggbg, ttpt;
  340. vec_t<T,4,0x1122> const yyzz, ggbb, ttpp;
  341. vec_t<T,4,0x1200> const yzxx, gbrr, tpss;
  342. vec_t<T,4,0x1201> const yzxy, gbrg, tpst;
  343. vec_t<T,4,0x1202> const yzxz, gbrb, tpsp;
  344. vec_t<T,4,0x1210> const yzyx, gbgr, tpts;
  345. vec_t<T,4,0x1211> const yzyy, gbgg, tptt;
  346. vec_t<T,4,0x1212> const yzyz, gbgb, tptp;
  347. vec_t<T,4,0x1220> const yzzx, gbbr, tpps;
  348. vec_t<T,4,0x1221> const yzzy, gbbg, tppt;
  349. vec_t<T,4,0x1222> const yzzz, gbbb, tppp;
  350. vec_t<T,4,0x2000> const zxxx, brrr, psss;
  351. vec_t<T,4,0x2001> const zxxy, brrg, psst;
  352. vec_t<T,4,0x2002> const zxxz, brrb, pssp;
  353. vec_t<T,4,0x2010> const zxyx, brgr, psts;
  354. vec_t<T,4,0x2011> const zxyy, brgg, pstt;
  355. vec_t<T,4,0x2012> const zxyz, brgb, pstp;
  356. vec_t<T,4,0x2020> const zxzx, brbr, psps;
  357. vec_t<T,4,0x2021> const zxzy, brbg, pspt;
  358. vec_t<T,4,0x2022> const zxzz, brbb, pspp;
  359. vec_t<T,4,0x2100> const zyxx, bgrr, ptss;
  360. vec_t<T,4,0x2101> const zyxy, bgrg, ptst;
  361. vec_t<T,4,0x2102> const zyxz, bgrb, ptsp;
  362. vec_t<T,4,0x2110> const zyyx, bggr, ptts;
  363. vec_t<T,4,0x2111> const zyyy, bggg, pttt;
  364. vec_t<T,4,0x2112> const zyyz, bggb, pttp;
  365. vec_t<T,4,0x2120> const zyzx, bgbr, ptps;
  366. vec_t<T,4,0x2121> const zyzy, bgbg, ptpt;
  367. vec_t<T,4,0x2122> const zyzz, bgbb, ptpp;
  368. vec_t<T,4,0x2200> const zzxx, bbrr, ppss;
  369. vec_t<T,4,0x2201> const zzxy, bbrg, ppst;
  370. vec_t<T,4,0x2202> const zzxz, bbrb, ppsp;
  371. vec_t<T,4,0x2210> const zzyx, bbgr, ppts;
  372. vec_t<T,4,0x2211> const zzyy, bbgg, pptt;
  373. vec_t<T,4,0x2212> const zzyz, bbgb, pptp;
  374. vec_t<T,4,0x2220> const zzzx, bbbr, ppps;
  375. vec_t<T,4,0x2221> const zzzy, bbbg, pppt;
  376. vec_t<T,4,0x2222> const zzzz, bbbb, pppp;
  377. #endif
  378. };
  379. };
  380. static_assert(sizeof(i8vec3) == 3, "sizeof(i8vec3) == 3");
  381. static_assert(sizeof(i16vec3) == 6, "sizeof(i16vec3) == 6");
  382. static_assert(sizeof(ivec3) == 12, "sizeof(ivec3) == 12");
  383. static_assert(sizeof(i64vec3) == 24, "sizeof(i64vec3) == 24");
  384. static_assert(sizeof(f16vec3) == 6, "sizeof(f16vec3) == 6");
  385. static_assert(sizeof(vec3) == 12, "sizeof(vec3) == 12");
  386. static_assert(sizeof(dvec3) == 24, "sizeof(dvec3) == 24");
  387. /*
  388. * 4-element vectors
  389. */
  390. template <typename T>
  391. struct vec_t<T,4>
  392. : public swizzle_ops::base<T>,
  393. public linear_ops::base<T>,
  394. public componentwise_ops::base<T>
  395. {
  396. static int const count = 4;
  397. typedef T element;
  398. typedef vec_t<T,4> type;
  399. /* Default constructor, copy constructor, and destructor */
  400. inline constexpr vec_t() : x(), y(), z(), w() {}
  401. inline constexpr vec_t(vec_t<T,4> const &v)
  402. : x(v.x), y(v.y), z(v.z), w(v.w) {}
  403. inline ~vec_t() { x.~T(); y.~T(); z.~T(); w.~T(); }
  404. /* Implicit constructor for swizzling */
  405. template<int SWIZZLE>
  406. inline constexpr vec_t(vec_t<T, 4, SWIZZLE> const &v)
  407. : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
  408. /* Explicit constructor for type conversion */
  409. template<typename U, int SWIZZLE>
  410. explicit inline constexpr vec_t(vec_t<U, 4, SWIZZLE> const &v)
  411. : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
  412. /* Various explicit constructors */
  413. explicit inline constexpr vec_t(T X)
  414. : x(X), y(X), z(X), w(X) {}
  415. explicit inline constexpr vec_t(T X, T Y, T Z, T W)
  416. : x(X), y(Y), z(Z), w(W) {}
  417. explicit inline constexpr vec_t(vec_t<T,2> XY, T Z, T W)
  418. : x(XY.x), y(XY.y), z(Z), w(W) {}
  419. explicit inline constexpr vec_t(T X, vec_t<T,2> YZ, T W)
  420. : x(X), y(YZ.x), z(YZ.y), w(W) {}
  421. explicit inline constexpr vec_t(T X, T Y, vec_t<T,2> ZW)
  422. : x(X), y(Y), z(ZW.x), w(ZW.y) {}
  423. explicit inline constexpr vec_t(vec_t<T,2> XY, vec_t<T,2> ZW)
  424. : x(XY.x), y(XY.y), z(ZW.x), w(ZW.y) {}
  425. explicit inline constexpr vec_t(vec_t<T,3> XYZ, T W)
  426. : x(XYZ.x), y(XYZ.y), z(XYZ.z), w(W) {}
  427. explicit inline constexpr vec_t(T X, vec_t<T,3> YZW)
  428. : x(X), y(YZW.x), z(YZW.y), w(YZW.z) {}
  429. LOL_COMMON_MEMBER_OPS(x)
  430. static const vec_t<T,4> zero;
  431. static const vec_t<T,4> axis_x;
  432. static const vec_t<T,4> axis_y;
  433. static const vec_t<T,4> axis_z;
  434. static const vec_t<T,4> axis_w;
  435. template<typename U>
  436. friend std::ostream &operator<<(std::ostream &stream, vec_t<U,4> const &v);
  437. union
  438. {
  439. struct { T x, y, z, w; };
  440. struct { T r, g, b, a; };
  441. struct { T s, t, p, q; };
  442. #if !_DOXYGEN_SKIP_ME
  443. vec_t<T,2,0x00> const xx, rr, ss;
  444. vec_t<T,2,0x01> _____ xy, rg, st;
  445. vec_t<T,2,0x02> _____ xz, rb, sp;
  446. vec_t<T,2,0x03> _____ xw, ra, sq;
  447. vec_t<T,2,0x10> _____ yx, gr, ts;
  448. vec_t<T,2,0x11> const yy, gg, tt;
  449. vec_t<T,2,0x12> _____ yz, gb, tp;
  450. vec_t<T,2,0x13> _____ yw, ga, tq;
  451. vec_t<T,2,0x20> _____ zx, br, ps;
  452. vec_t<T,2,0x21> _____ zy, bg, pt;
  453. vec_t<T,2,0x22> const zz, bb, pp;
  454. vec_t<T,2,0x23> _____ zw, ba, pq;
  455. vec_t<T,2,0x30> _____ wx, ar, qs;
  456. vec_t<T,2,0x31> _____ wy, ag, qt;
  457. vec_t<T,2,0x32> _____ wz, ab, qp;
  458. vec_t<T,2,0x33> const ww, aa, qq;
  459. vec_t<T,3,0x000> const xxx, rrr, sss;
  460. vec_t<T,3,0x001> const xxy, rrg, sst;
  461. vec_t<T,3,0x002> const xxz, rrb, ssp;
  462. vec_t<T,3,0x003> const xxw, rra, ssq;
  463. vec_t<T,3,0x010> const xyx, rgr, sts;
  464. vec_t<T,3,0x011> const xyy, rgg, stt;
  465. vec_t<T,3,0x012> _____ xyz, rgb, stp;
  466. vec_t<T,3,0x013> _____ xyw, rga, stq;
  467. vec_t<T,3,0x020> const xzx, rbr, sps;
  468. vec_t<T,3,0x021> _____ xzy, rbg, spt;
  469. vec_t<T,3,0x022> const xzz, rbb, spp;
  470. vec_t<T,3,0x023> _____ xzw, rba, spq;
  471. vec_t<T,3,0x030> const xwx, rar, sqs;
  472. vec_t<T,3,0x031> _____ xwy, rag, sqt;
  473. vec_t<T,3,0x032> _____ xwz, rab, sqp;
  474. vec_t<T,3,0x033> const xww, raa, sqq;
  475. vec_t<T,3,0x100> const yxx, grr, tss;
  476. vec_t<T,3,0x101> const yxy, grg, tst;
  477. vec_t<T,3,0x102> _____ yxz, grb, tsp;
  478. vec_t<T,3,0x103> _____ yxw, gra, tsq;
  479. vec_t<T,3,0x110> const yyx, ggr, tts;
  480. vec_t<T,3,0x111> const yyy, ggg, ttt;
  481. vec_t<T,3,0x112> const yyz, ggb, ttp;
  482. vec_t<T,3,0x113> const yyw, gga, ttq;
  483. vec_t<T,3,0x120> _____ yzx, gbr, tps;
  484. vec_t<T,3,0x121> const yzy, gbg, tpt;
  485. vec_t<T,3,0x122> const yzz, gbb, tpp;
  486. vec_t<T,3,0x123> _____ yzw, gba, tpq;
  487. vec_t<T,3,0x130> _____ ywx, gar, tqs;
  488. vec_t<T,3,0x131> const ywy, gag, tqt;
  489. vec_t<T,3,0x132> _____ ywz, gab, tqp;
  490. vec_t<T,3,0x133> const yww, gaa, tqq;
  491. vec_t<T,3,0x200> const zxx, brr, pss;
  492. vec_t<T,3,0x201> _____ zxy, brg, pst;
  493. vec_t<T,3,0x202> const zxz, brb, psp;
  494. vec_t<T,3,0x203> _____ zxw, bra, psq;
  495. vec_t<T,3,0x210> _____ zyx, bgr, pts;
  496. vec_t<T,3,0x211> const zyy, bgg, ptt;
  497. vec_t<T,3,0x212> const zyz, bgb, ptp;
  498. vec_t<T,3,0x213> _____ zyw, bga, ptq;
  499. vec_t<T,3,0x220> const zzx, bbr, pps;
  500. vec_t<T,3,0x221> const zzy, bbg, ppt;
  501. vec_t<T,3,0x222> const zzz, bbb, ppp;
  502. vec_t<T,3,0x223> const zzw, bba, ppq;
  503. vec_t<T,3,0x230> _____ zwx, bar, pqs;
  504. vec_t<T,3,0x231> _____ zwy, bag, pqt;
  505. vec_t<T,3,0x232> const zwz, bab, pqp;
  506. vec_t<T,3,0x233> const zww, baa, pqq;
  507. vec_t<T,3,0x300> const wxx, arr, qss;
  508. vec_t<T,3,0x301> _____ wxy, arg, qst;
  509. vec_t<T,3,0x302> _____ wxz, arb, qsp;
  510. vec_t<T,3,0x303> const wxw, ara, qsq;
  511. vec_t<T,3,0x310> _____ wyx, agr, qts;
  512. vec_t<T,3,0x311> const wyy, agg, qtt;
  513. vec_t<T,3,0x312> _____ wyz, agb, qtp;
  514. vec_t<T,3,0x313> const wyw, aga, qtq;
  515. vec_t<T,3,0x320> _____ wzx, abr, qps;
  516. vec_t<T,3,0x321> _____ wzy, abg, qpt;
  517. vec_t<T,3,0x322> const wzz, abb, qpp;
  518. vec_t<T,3,0x323> const wzw, aba, qpq;
  519. vec_t<T,3,0x330> const wwx, aar, qqs;
  520. vec_t<T,3,0x331> const wwy, aag, qqt;
  521. vec_t<T,3,0x332> const wwz, aab, qqp;
  522. vec_t<T,3,0x333> const www, aaa, qqq;
  523. vec_t<T,4,0x0000> const xxxx, rrrr, ssss;
  524. vec_t<T,4,0x0001> const xxxy, rrrg, ssst;
  525. vec_t<T,4,0x0002> const xxxz, rrrb, sssp;
  526. vec_t<T,4,0x0003> const xxxw, rrra, sssq;
  527. vec_t<T,4,0x0010> const xxyx, rrgr, ssts;
  528. vec_t<T,4,0x0011> const xxyy, rrgg, sstt;
  529. vec_t<T,4,0x0012> const xxyz, rrgb, sstp;
  530. vec_t<T,4,0x0013> const xxyw, rrga, sstq;
  531. vec_t<T,4,0x0020> const xxzx, rrbr, ssps;
  532. vec_t<T,4,0x0021> const xxzy, rrbg, sspt;
  533. vec_t<T,4,0x0022> const xxzz, rrbb, sspp;
  534. vec_t<T,4,0x0023> const xxzw, rrba, sspq;
  535. vec_t<T,4,0x0030> const xxwx, rrar, ssqs;
  536. vec_t<T,4,0x0031> const xxwy, rrag, ssqt;
  537. vec_t<T,4,0x0032> const xxwz, rrab, ssqp;
  538. vec_t<T,4,0x0033> const xxww, rraa, ssqq;
  539. vec_t<T,4,0x0100> const xyxx, rgrr, stss;
  540. vec_t<T,4,0x0101> const xyxy, rgrg, stst;
  541. vec_t<T,4,0x0102> const xyxz, rgrb, stsp;
  542. vec_t<T,4,0x0103> const xyxw, rgra, stsq;
  543. vec_t<T,4,0x0110> const xyyx, rggr, stts;
  544. vec_t<T,4,0x0111> const xyyy, rggg, sttt;
  545. vec_t<T,4,0x0112> const xyyz, rggb, sttp;
  546. vec_t<T,4,0x0113> const xyyw, rgga, sttq;
  547. vec_t<T,4,0x0120> const xyzx, rgbr, stps;
  548. vec_t<T,4,0x0121> const xyzy, rgbg, stpt;
  549. vec_t<T,4,0x0122> const xyzz, rgbb, stpp;
  550. vec_t<T,4,0x0123> _____ xyzw, rgba, stpq;
  551. vec_t<T,4,0x0130> const xywx, rgar, stqs;
  552. vec_t<T,4,0x0131> const xywy, rgag, stqt;
  553. vec_t<T,4,0x0132> _____ xywz, rgab, stqp;
  554. vec_t<T,4,0x0133> const xyww, rgaa, stqq;
  555. vec_t<T,4,0x0200> const xzxx, rbrr, spss;
  556. vec_t<T,4,0x0201> const xzxy, rbrg, spst;
  557. vec_t<T,4,0x0202> const xzxz, rbrb, spsp;
  558. vec_t<T,4,0x0203> const xzxw, rbra, spsq;
  559. vec_t<T,4,0x0210> const xzyx, rbgr, spts;
  560. vec_t<T,4,0x0211> const xzyy, rbgg, sptt;
  561. vec_t<T,4,0x0212> const xzyz, rbgb, sptp;
  562. vec_t<T,4,0x0213> _____ xzyw, rbga, sptq;
  563. vec_t<T,4,0x0220> const xzzx, rbbr, spps;
  564. vec_t<T,4,0x0221> const xzzy, rbbg, sppt;
  565. vec_t<T,4,0x0222> const xzzz, rbbb, sppp;
  566. vec_t<T,4,0x0223> const xzzw, rbba, sppq;
  567. vec_t<T,4,0x0230> const xzwx, rbar, spqs;
  568. vec_t<T,4,0x0231> _____ xzwy, rbag, spqt;
  569. vec_t<T,4,0x0232> const xzwz, rbab, spqp;
  570. vec_t<T,4,0x0233> const xzww, rbaa, spqq;
  571. vec_t<T,4,0x0300> const xwxx, rarr, sqss;
  572. vec_t<T,4,0x0301> const xwxy, rarg, sqst;
  573. vec_t<T,4,0x0302> const xwxz, rarb, sqsp;
  574. vec_t<T,4,0x0303> const xwxw, rara, sqsq;
  575. vec_t<T,4,0x0310> const xwyx, ragr, sqts;
  576. vec_t<T,4,0x0311> const xwyy, ragg, sqtt;
  577. vec_t<T,4,0x0312> _____ xwyz, ragb, sqtp;
  578. vec_t<T,4,0x0313> const xwyw, raga, sqtq;
  579. vec_t<T,4,0x0320> const xwzx, rabr, sqps;
  580. vec_t<T,4,0x0321> _____ xwzy, rabg, sqpt;
  581. vec_t<T,4,0x0322> const xwzz, rabb, sqpp;
  582. vec_t<T,4,0x0323> const xwzw, raba, sqpq;
  583. vec_t<T,4,0x0330> const xwwx, raar, sqqs;
  584. vec_t<T,4,0x0331> const xwwy, raag, sqqt;
  585. vec_t<T,4,0x0332> const xwwz, raab, sqqp;
  586. vec_t<T,4,0x0333> const xwww, raaa, sqqq;
  587. vec_t<T,4,0x1000> const yxxx, grrr, tsss;
  588. vec_t<T,4,0x1001> const yxxy, grrg, tsst;
  589. vec_t<T,4,0x1002> const yxxz, grrb, tssp;
  590. vec_t<T,4,0x1003> const yxxw, grra, tssq;
  591. vec_t<T,4,0x1010> const yxyx, grgr, tsts;
  592. vec_t<T,4,0x1011> const yxyy, grgg, tstt;
  593. vec_t<T,4,0x1012> const yxyz, grgb, tstp;
  594. vec_t<T,4,0x1013> const yxyw, grga, tstq;
  595. vec_t<T,4,0x1020> const yxzx, grbr, tsps;
  596. vec_t<T,4,0x1021> const yxzy, grbg, tspt;
  597. vec_t<T,4,0x1022> const yxzz, grbb, tspp;
  598. vec_t<T,4,0x1023> _____ yxzw, grba, tspq;
  599. vec_t<T,4,0x1030> const yxwx, grar, tsqs;
  600. vec_t<T,4,0x1031> const yxwy, grag, tsqt;
  601. vec_t<T,4,0x1032> _____ yxwz, grab, tsqp;
  602. vec_t<T,4,0x1033> const yxww, graa, tsqq;
  603. vec_t<T,4,0x1100> const yyxx, ggrr, ttss;
  604. vec_t<T,4,0x1101> const yyxy, ggrg, ttst;
  605. vec_t<T,4,0x1102> const yyxz, ggrb, ttsp;
  606. vec_t<T,4,0x1103> const yyxw, ggra, ttsq;
  607. vec_t<T,4,0x1110> const yyyx, gggr, ttts;
  608. vec_t<T,4,0x1111> const yyyy, gggg, tttt;
  609. vec_t<T,4,0x1112> const yyyz, gggb, tttp;
  610. vec_t<T,4,0x1113> const yyyw, ggga, tttq;
  611. vec_t<T,4,0x1120> const yyzx, ggbr, ttps;
  612. vec_t<T,4,0x1121> const yyzy, ggbg, ttpt;
  613. vec_t<T,4,0x1122> const yyzz, ggbb, ttpp;
  614. vec_t<T,4,0x1123> const yyzw, ggba, ttpq;
  615. vec_t<T,4,0x1130> const yywx, ggar, ttqs;
  616. vec_t<T,4,0x1131> const yywy, ggag, ttqt;
  617. vec_t<T,4,0x1132> const yywz, ggab, ttqp;
  618. vec_t<T,4,0x1133> const yyww, ggaa, ttqq;
  619. vec_t<T,4,0x1200> const yzxx, gbrr, tpss;
  620. vec_t<T,4,0x1201> const yzxy, gbrg, tpst;
  621. vec_t<T,4,0x1202> const yzxz, gbrb, tpsp;
  622. vec_t<T,4,0x1203> _____ yzxw, gbra, tpsq;
  623. vec_t<T,4,0x1210> const yzyx, gbgr, tpts;
  624. vec_t<T,4,0x1211> const yzyy, gbgg, tptt;
  625. vec_t<T,4,0x1212> const yzyz, gbgb, tptp;
  626. vec_t<T,4,0x1213> const yzyw, gbga, tptq;
  627. vec_t<T,4,0x1220> const yzzx, gbbr, tpps;
  628. vec_t<T,4,0x1221> const yzzy, gbbg, tppt;
  629. vec_t<T,4,0x1222> const yzzz, gbbb, tppp;
  630. vec_t<T,4,0x1223> const yzzw, gbba, tppq;
  631. vec_t<T,4,0x1230> _____ yzwx, gbar, tpqs;
  632. vec_t<T,4,0x1231> const yzwy, gbag, tpqt;
  633. vec_t<T,4,0x1232> const yzwz, gbab, tpqp;
  634. vec_t<T,4,0x1233> const yzww, gbaa, tpqq;
  635. vec_t<T,4,0x1300> const ywxx, garr, tqss;
  636. vec_t<T,4,0x1301> const ywxy, garg, tqst;
  637. vec_t<T,4,0x1302> _____ ywxz, garb, tqsp;
  638. vec_t<T,4,0x1303> const ywxw, gara, tqsq;
  639. vec_t<T,4,0x1310> const ywyx, gagr, tqts;
  640. vec_t<T,4,0x1311> const ywyy, gagg, tqtt;
  641. vec_t<T,4,0x1312> const ywyz, gagb, tqtp;
  642. vec_t<T,4,0x1313> const ywyw, gaga, tqtq;
  643. vec_t<T,4,0x1320> _____ ywzx, gabr, tqps;
  644. vec_t<T,4,0x1321> const ywzy, gabg, tqpt;
  645. vec_t<T,4,0x1322> const ywzz, gabb, tqpp;
  646. vec_t<T,4,0x1323> const ywzw, gaba, tqpq;
  647. vec_t<T,4,0x1330> const ywwx, gaar, tqqs;
  648. vec_t<T,4,0x1331> const ywwy, gaag, tqqt;
  649. vec_t<T,4,0x1332> const ywwz, gaab, tqqp;
  650. vec_t<T,4,0x1333> const ywww, gaaa, tqqq;
  651. vec_t<T,4,0x2000> const zxxx, brrr, psss;
  652. vec_t<T,4,0x2001> const zxxy, brrg, psst;
  653. vec_t<T,4,0x2002> const zxxz, brrb, pssp;
  654. vec_t<T,4,0x2003> const zxxw, brra, pssq;
  655. vec_t<T,4,0x2010> const zxyx, brgr, psts;
  656. vec_t<T,4,0x2011> const zxyy, brgg, pstt;
  657. vec_t<T,4,0x2012> const zxyz, brgb, pstp;
  658. vec_t<T,4,0x2013> _____ zxyw, brga, pstq;
  659. vec_t<T,4,0x2020> const zxzx, brbr, psps;
  660. vec_t<T,4,0x2021> const zxzy, brbg, pspt;
  661. vec_t<T,4,0x2022> const zxzz, brbb, pspp;
  662. vec_t<T,4,0x2023> const zxzw, brba, pspq;
  663. vec_t<T,4,0x2030> const zxwx, brar, psqs;
  664. vec_t<T,4,0x2031> _____ zxwy, brag, psqt;
  665. vec_t<T,4,0x2032> const zxwz, brab, psqp;
  666. vec_t<T,4,0x2033> const zxww, braa, psqq;
  667. vec_t<T,4,0x2100> const zyxx, bgrr, ptss;
  668. vec_t<T,4,0x2101> const zyxy, bgrg, ptst;
  669. vec_t<T,4,0x2102> const zyxz, bgrb, ptsp;
  670. vec_t<T,4,0x2103> _____ zyxw, bgra, ptsq;
  671. vec_t<T,4,0x2110> const zyyx, bggr, ptts;
  672. vec_t<T,4,0x2111> const zyyy, bggg, pttt;
  673. vec_t<T,4,0x2112> const zyyz, bggb, pttp;
  674. vec_t<T,4,0x2113> const zyyw, bgga, pttq;
  675. vec_t<T,4,0x2120> const zyzx, bgbr, ptps;
  676. vec_t<T,4,0x2121> const zyzy, bgbg, ptpt;
  677. vec_t<T,4,0x2122> const zyzz, bgbb, ptpp;
  678. vec_t<T,4,0x2123> const zyzw, bgba, ptpq;
  679. vec_t<T,4,0x2130> _____ zywx, bgar, ptqs;
  680. vec_t<T,4,0x2131> const zywy, bgag, ptqt;
  681. vec_t<T,4,0x2132> const zywz, bgab, ptqp;
  682. vec_t<T,4,0x2133> const zyww, bgaa, ptqq;
  683. vec_t<T,4,0x2200> const zzxx, bbrr, ppss;
  684. vec_t<T,4,0x2201> const zzxy, bbrg, ppst;
  685. vec_t<T,4,0x2202> const zzxz, bbrb, ppsp;
  686. vec_t<T,4,0x2203> const zzxw, bbra, ppsq;
  687. vec_t<T,4,0x2210> const zzyx, bbgr, ppts;
  688. vec_t<T,4,0x2211> const zzyy, bbgg, pptt;
  689. vec_t<T,4,0x2212> const zzyz, bbgb, pptp;
  690. vec_t<T,4,0x2213> const zzyw, bbga, pptq;
  691. vec_t<T,4,0x2220> const zzzx, bbbr, ppps;
  692. vec_t<T,4,0x2221> const zzzy, bbbg, pppt;
  693. vec_t<T,4,0x2222> const zzzz, bbbb, pppp;
  694. vec_t<T,4,0x2223> const zzzw, bbba, pppq;
  695. vec_t<T,4,0x2230> const zzwx, bbar, ppqs;
  696. vec_t<T,4,0x2231> const zzwy, bbag, ppqt;
  697. vec_t<T,4,0x2232> const zzwz, bbab, ppqp;
  698. vec_t<T,4,0x2233> const zzww, bbaa, ppqq;
  699. vec_t<T,4,0x2300> const zwxx, barr, pqss;
  700. vec_t<T,4,0x2301> _____ zwxy, barg, pqst;
  701. vec_t<T,4,0x2302> const zwxz, barb, pqsp;
  702. vec_t<T,4,0x2303> const zwxw, bara, pqsq;
  703. vec_t<T,4,0x2310> _____ zwyx, bagr, pqts;
  704. vec_t<T,4,0x2311> const zwyy, bagg, pqtt;
  705. vec_t<T,4,0x2312> const zwyz, bagb, pqtp;
  706. vec_t<T,4,0x2313> const zwyw, baga, pqtq;
  707. vec_t<T,4,0x2320> const zwzx, babr, pqps;
  708. vec_t<T,4,0x2321> const zwzy, babg, pqpt;
  709. vec_t<T,4,0x2322> const zwzz, babb, pqpp;
  710. vec_t<T,4,0x2323> const zwzw, baba, pqpq;
  711. vec_t<T,4,0x2330> const zwwx, baar, pqqs;
  712. vec_t<T,4,0x2331> const zwwy, baag, pqqt;
  713. vec_t<T,4,0x2332> const zwwz, baab, pqqp;
  714. vec_t<T,4,0x2333> const zwww, baaa, pqqq;
  715. vec_t<T,4,0x3000> const wxxx, arrr, qsss;
  716. vec_t<T,4,0x3001> const wxxy, arrg, qsst;
  717. vec_t<T,4,0x3002> const wxxz, arrb, qssp;
  718. vec_t<T,4,0x3003> const wxxw, arra, qssq;
  719. vec_t<T,4,0x3010> const wxyx, argr, qsts;
  720. vec_t<T,4,0x3011> const wxyy, argg, qstt;
  721. vec_t<T,4,0x3012> _____ wxyz, argb, qstp;
  722. vec_t<T,4,0x3013> const wxyw, arga, qstq;
  723. vec_t<T,4,0x3020> const wxzx, arbr, qsps;
  724. vec_t<T,4,0x3021> _____ wxzy, arbg, qspt;
  725. vec_t<T,4,0x3022> const wxzz, arbb, qspp;
  726. vec_t<T,4,0x3023> const wxzw, arba, qspq;
  727. vec_t<T,4,0x3030> const wxwx, arar, qsqs;
  728. vec_t<T,4,0x3031> const wxwy, arag, qsqt;
  729. vec_t<T,4,0x3032> const wxwz, arab, qsqp;
  730. vec_t<T,4,0x3033> const wxww, araa, qsqq;
  731. vec_t<T,4,0x3100> const wyxx, agrr, qtss;
  732. vec_t<T,4,0x3101> const wyxy, agrg, qtst;
  733. vec_t<T,4,0x3102> _____ wyxz, agrb, qtsp;
  734. vec_t<T,4,0x3103> const wyxw, agra, qtsq;
  735. vec_t<T,4,0x3110> const wyyx, aggr, qtts;
  736. vec_t<T,4,0x3111> const wyyy, aggg, qttt;
  737. vec_t<T,4,0x3112> const wyyz, aggb, qttp;
  738. vec_t<T,4,0x3113> const wyyw, agga, qttq;
  739. vec_t<T,4,0x3120> _____ wyzx, agbr, qtps;
  740. vec_t<T,4,0x3121> const wyzy, agbg, qtpt;
  741. vec_t<T,4,0x3122> const wyzz, agbb, qtpp;
  742. vec_t<T,4,0x3123> const wyzw, agba, qtpq;
  743. vec_t<T,4,0x3130> const wywx, agar, qtqs;
  744. vec_t<T,4,0x3131> const wywy, agag, qtqt;
  745. vec_t<T,4,0x3132> const wywz, agab, qtqp;
  746. vec_t<T,4,0x3133> const wyww, agaa, qtqq;
  747. vec_t<T,4,0x3200> const wzxx, abrr, qpss;
  748. vec_t<T,4,0x3201> _____ wzxy, abrg, qpst;
  749. vec_t<T,4,0x3202> const wzxz, abrb, qpsp;
  750. vec_t<T,4,0x3203> const wzxw, abra, qpsq;
  751. vec_t<T,4,0x3210> _____ wzyx, abgr, qpts;
  752. vec_t<T,4,0x3211> const wzyy, abgg, qptt;
  753. vec_t<T,4,0x3212> const wzyz, abgb, qptp;
  754. vec_t<T,4,0x3213> const wzyw, abga, qptq;
  755. vec_t<T,4,0x3220> const wzzx, abbr, qpps;
  756. vec_t<T,4,0x3221> const wzzy, abbg, qppt;
  757. vec_t<T,4,0x3222> const wzzz, abbb, qppp;
  758. vec_t<T,4,0x3223> const wzzw, abba, qppq;
  759. vec_t<T,4,0x3230> const wzwx, abar, qpqs;
  760. vec_t<T,4,0x3231> const wzwy, abag, qpqt;
  761. vec_t<T,4,0x3232> const wzwz, abab, qpqp;
  762. vec_t<T,4,0x3233> const wzww, abaa, qpqq;
  763. vec_t<T,4,0x3300> const wwxx, aarr, qqss;
  764. vec_t<T,4,0x3301> const wwxy, aarg, qqst;
  765. vec_t<T,4,0x3302> const wwxz, aarb, qqsp;
  766. vec_t<T,4,0x3303> const wwxw, aara, qqsq;
  767. vec_t<T,4,0x3310> const wwyx, aagr, qqts;
  768. vec_t<T,4,0x3311> const wwyy, aagg, qqtt;
  769. vec_t<T,4,0x3312> const wwyz, aagb, qqtp;
  770. vec_t<T,4,0x3313> const wwyw, aaga, qqtq;
  771. vec_t<T,4,0x3320> const wwzx, aabr, qqps;
  772. vec_t<T,4,0x3321> const wwzy, aabg, qqpt;
  773. vec_t<T,4,0x3322> const wwzz, aabb, qqpp;
  774. vec_t<T,4,0x3323> const wwzw, aaba, qqpq;
  775. vec_t<T,4,0x3330> const wwwx, aaar, qqqs;
  776. vec_t<T,4,0x3331> const wwwy, aaag, qqqt;
  777. vec_t<T,4,0x3332> const wwwz, aaab, qqqp;
  778. vec_t<T,4,0x3333> const wwww, aaaa, qqqq;
  779. #endif
  780. };
  781. };
  782. static_assert(sizeof(i8vec4) == 4, "sizeof(i8vec4) == 4");
  783. static_assert(sizeof(i16vec4) == 8, "sizeof(i16vec4) == 8");
  784. static_assert(sizeof(ivec4) == 16, "sizeof(ivec4) == 16");
  785. static_assert(sizeof(i64vec4) == 32, "sizeof(i64vec4) == 32");
  786. static_assert(sizeof(f16vec4) == 8, "sizeof(f16vec4) == 8");
  787. static_assert(sizeof(vec4) == 16, "sizeof(vec4) == 16");
  788. static_assert(sizeof(dvec4) == 32, "sizeof(dvec4) == 32");
  789. /*
  790. * vec_t *(scalar, vec_t)
  791. */
  792. template<typename T, int N, int SWIZZLE>
  793. static inline vec_t<T,N> operator *(T const &val, vec_t<T,N,SWIZZLE> const &a)
  794. {
  795. vec_t<T,N> ret;
  796. for (int i = 0; i < N; ++i)
  797. ret[i] = val * a[i];
  798. return ret;
  799. }
  800. /*
  801. * vec_t min|max|fmod(vec_t, vec_t|scalar)
  802. * vec_t min|max|fmod(scalar, vec_t)
  803. */
  804. #define LOL_SWIZZLE_V_VV_FUN(fun) \
  805. template<typename T, int N, int SWIZZLE1, int SWIZZLE2> \
  806. inline vec_t<T,N> fun(vec_t<T,N,SWIZZLE1> const &a, \
  807. vec_t<T,N,SWIZZLE2> const &b) \
  808. { \
  809. using lol::fun; \
  810. vec_t<T,N> ret; \
  811. for (int i = 0; i < N; ++i) \
  812. ret[i] = fun(a[i], b[i]); \
  813. return ret; \
  814. } \
  815. \
  816. template<typename T, int N, int SWIZZLE> \
  817. inline vec_t<T,N> fun(vec_t<T,N,SWIZZLE> const &a, T const &b) \
  818. { \
  819. using lol::fun; \
  820. vec_t<T,N> ret; \
  821. for (int i = 0; i < N; ++i) \
  822. ret[i] = fun(a[i], b); \
  823. return ret; \
  824. } \
  825. \
  826. template<typename T, int N, int SWIZZLE> \
  827. inline vec_t<T,N> fun(T const &a, vec_t<T,N,SWIZZLE> const &b) \
  828. { \
  829. using lol::fun; \
  830. vec_t<T,N> ret; \
  831. for (int i = 0; i < N; ++i) \
  832. ret[i] = fun(a, b[i]); \
  833. return ret; \
  834. }
  835. LOL_SWIZZLE_V_VV_FUN(min)
  836. LOL_SWIZZLE_V_VV_FUN(max)
  837. LOL_SWIZZLE_V_VV_FUN(fmod)
  838. #undef LOL_SWIZZLE_V_VV_FUN
  839. /*
  840. * vec_t clamp(vec_t, vec_t, vec_t)
  841. * vec_t clamp(vec_t, scalar, vec_t)
  842. * vec_t clamp(vec_t, vec_t, scalar)
  843. * vec_t clamp(vec_t, scalar, scalar)
  844. */
  845. template<typename T, int N, int SWIZZLE1, int SWIZZLE2, int SWIZZLE3>
  846. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  847. vec_t<T,N,SWIZZLE2> const &a,
  848. vec_t<T,N,SWIZZLE3> const &b)
  849. {
  850. return max(min(x, b), a);
  851. }
  852. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  853. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  854. T const &a,
  855. vec_t<T,N,SWIZZLE2> const &b)
  856. {
  857. return max(min(x, b), a);
  858. }
  859. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  860. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  861. vec_t<T,N,SWIZZLE2> const &a,
  862. T const &b)
  863. {
  864. return max(min(x, b), a);
  865. }
  866. template<typename T, int N, int SWIZZLE1>
  867. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  868. T const &a,
  869. T const &b)
  870. {
  871. return max(min(x, b), a);
  872. }
  873. /*
  874. * vec_t mix(vec_t, vec_t, vec_t)
  875. * vec_t mix(vec_t, vec_t, scalar)
  876. */
  877. template<typename T, int N, int SWIZZLE1, int SWIZZLE2, int SWIZZLE3>
  878. static inline vec_t<T,N> mix(vec_t<T,N,SWIZZLE1> const &x,
  879. vec_t<T,N,SWIZZLE2> const &y,
  880. vec_t<T,N,SWIZZLE3> const &a)
  881. {
  882. return x + a * (y - x);
  883. }
  884. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  885. static inline vec_t<T,N> mix(vec_t<T,N,SWIZZLE1> const &x,
  886. vec_t<T,N,SWIZZLE2> const &y,
  887. T const &a)
  888. {
  889. return x + a * (y - x);
  890. }
  891. /*
  892. * Some GLSL-like functions.
  893. */
  894. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  895. static inline T dot(vec_t<T,N,SWIZZLE1> const &a,
  896. vec_t<T,N,SWIZZLE2> const &b)
  897. {
  898. T ret(0);
  899. for (int i = 0; i < N; ++i)
  900. ret += a[i] * b[i];
  901. return ret;
  902. }
  903. template<typename T, int N, int SWIZZLE>
  904. static inline T sqlength(vec_t<T,N,SWIZZLE> const &a)
  905. {
  906. return dot(a, a);
  907. }
  908. template<typename T, int N, int SWIZZLE>
  909. static inline T length(vec_t<T,N,SWIZZLE> const &a)
  910. {
  911. /* FIXME: this is not very nice */
  912. return (T)sqrt((double)sqlength(a));
  913. }
  914. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  915. static inline vec_t<T,N> lerp(vec_t<T,N,SWIZZLE1> const &a,
  916. vec_t<T,N,SWIZZLE2> const &b,
  917. T const &s)
  918. {
  919. vec_t<T,N> ret;
  920. for (int i = 0; i < N; ++i)
  921. ret[i] = a[i] + s * (b[i] - a[i]);
  922. return ret;
  923. }
  924. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  925. static inline T distance(vec_t<T,N,SWIZZLE1> const &a,
  926. vec_t<T,N,SWIZZLE2> const &b)
  927. {
  928. return length(a - b);
  929. }
  930. template<typename T, int N, int SWIZZLE>
  931. static inline vec_t<T,N> fract(vec_t<T,N,SWIZZLE> const &a)
  932. {
  933. vec_t<T,N> ret;
  934. for (int i = 0; i < N; ++i)
  935. ret[i] = fract(a[i]);
  936. return ret;
  937. }
  938. template<typename T, int N, int SWIZZLE>
  939. static inline vec_t<T,N> normalize(vec_t<T,N,SWIZZLE> const &a)
  940. {
  941. T norm = (T)length(a);
  942. return norm ? a / norm : vec_t<T,N>(T(0));
  943. }
  944. template<typename T, int N, int SWIZZLE>
  945. static inline vec_t<T,N> abs(vec_t<T,N,SWIZZLE> const &a)
  946. {
  947. vec_t<T,N> ret;
  948. for (int i = 0; i < N; ++i)
  949. ret[i] = lol::abs(a[i]);
  950. return ret;
  951. }
  952. template<typename T, int N, int SWIZZLE>
  953. static inline vec_t<T,N> degrees(vec_t<T,N,SWIZZLE> const &a)
  954. {
  955. vec_t<T,N> ret;
  956. for (int i = 0; i < N; ++i)
  957. ret[i] = lol::degrees(a[i]);
  958. return ret;
  959. }
  960. template<typename T, int N, int SWIZZLE>
  961. static inline vec_t<T,N> radians(vec_t<T,N,SWIZZLE> const &a)
  962. {
  963. vec_t<T,N> ret;
  964. for (int i = 0; i < N; ++i)
  965. ret[i] = lol::radians(a[i]);
  966. return ret;
  967. }
  968. /*
  969. * Magic vector swizzling (part 2/2)
  970. */
  971. #if LOL_FEATURE_CXX11_RELAXED_UNIONS
  972. template<int N, typename T, int SWIZZLE>
  973. inline vec_t<T, N, SWIZZLE>& vec_t<T, N, SWIZZLE>::operator =(vec_t<T,N> that)
  974. {
  975. for (int i = 0; i < N; ++i)
  976. (*this)[i] = that[i];
  977. return *this;
  978. }
  979. #endif
  980. #if !LOL_FEATURE_CXX11_CONSTEXPR
  981. #undef constexpr
  982. #endif
  983. } /* namespace lol */
  984. #endif // __LOL_MATH_VECTOR_H__