25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1422 lines
49 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2020 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #pragma once
  13. //
  14. // The vector classes
  15. // ——————————————————
  16. //
  17. #include <cassert>
  18. #include <ostream> // std::ostream
  19. #include <type_traits>
  20. #include <cmath> // std::fabs, std::cos…
  21. // FIXME: get rid of this, too
  22. #include <../legacy/lol/base/types.h>
  23. #include "private/ops.h"
  24. namespace lol
  25. {
  26. template<typename T> struct quat_t;
  27. /*
  28. * Magic vector swizzling
  29. *
  30. * These vectors are empty, but thanks to static_cast we can take their
  31. * address and access the vector of T's that they are union'ed with. We
  32. * use static_cast instead of reinterpret_cast because there is a stronger
  33. * guarantee (by the standard) that the address will stay the same across
  34. * casts.
  35. *
  36. * Using swizzled vectors as lvalues:
  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 2013 doesn't support unrestricted unions, so
  41. * fuck it for now.
  42. */
  43. template<typename T, int N, int SWIZZLE>
  44. struct [[nodiscard]] vec_t
  45. /* MUST have 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 scalar_element;
  52. typedef T element;
  53. typedef vec_t<T,N> type;
  54. /* Allow the assignment operator if unrestricted unions are supported. */
  55. inline vec_t<T, N, SWIZZLE>& operator =(vec_t<T, N> that)
  56. {
  57. for (int i = 0; i < N; ++i)
  58. (*this)[i] = that[i];
  59. return *this;
  60. }
  61. inline vec_t<T, N, SWIZZLE>& operator =(vec_t<T, N, SWIZZLE> const &that)
  62. {
  63. /* Pass by value in case this == &that */
  64. return *this = (vec_t<T,N>)that;
  65. }
  66. inline T& operator[](size_t n)
  67. {
  68. int const lut[] = { 1000, 100, 10, 1 };
  69. int const i = SWIZZLE / lut[n + 4 - N] % 10;
  70. return static_cast<T*>(static_cast<void*>(this))[i];
  71. }
  72. inline T const& operator[](size_t n) const
  73. {
  74. int const lut[] = { 1000, 100, 10, 1 };
  75. int const i = SWIZZLE / lut[n + 4 - N] % 10;
  76. return static_cast<T const*>(static_cast<void const *>(this))[i];
  77. }
  78. private:
  79. // Hide all default constructors and destructors; this object
  80. // is only intended to exist as part of a union.
  81. template<typename T2, int N2, int SWIZZLE2> friend struct vec_t;
  82. vec_t() = default;
  83. vec_t(vec_t<T, N, SWIZZLE> const &) = default;
  84. ~vec_t() = default;
  85. };
  86. /*
  87. * Helper macros for vector type member functions
  88. */
  89. #define LOL_COMMON_MEMBER_OPS(first) \
  90. inline T& operator[](size_t n) { return (&this->first)[n]; } \
  91. inline T const& operator[](size_t n) const { return (&this->first)[n]; } \
  92. \
  93. /* An explicit assignment operator is now mandatory */ \
  94. inline type & operator =(type const &that) \
  95. { \
  96. for (int i = 0; i < type::count; ++i) \
  97. (*this)[i] = that[i]; \
  98. return *this; \
  99. } \
  100. \
  101. std::string tostring() const;
  102. /* The generic “vec_t” type, which is a fixed-size vector with no
  103. * swizzling. There's an override for N=2, N=3, N=4 that has swizzling. */
  104. template<typename T, int N>
  105. struct [[nodiscard]] vec_t<T, N, FULL_SWIZZLE>
  106. : public componentwise_ops::base<T>
  107. {
  108. static int const count = N;
  109. typedef T scalar_element;
  110. typedef T element;
  111. typedef vec_t<T,N> type;
  112. // Default constructor, copy constructor, and destructor
  113. inline constexpr vec_t() = default;
  114. inline constexpr vec_t(type const &v) = default;
  115. inline ~vec_t() = default;
  116. LOL_COMMON_MEMBER_OPS(m_data[0])
  117. /* Explicit constructor that takes exactly N arguments thanks to SFINAE. */
  118. template<typename... ARGS>
  119. explicit inline vec_t(T const &X,
  120. typename std::enable_if<sizeof...(ARGS) + 2 == N, T>::type const &Y,
  121. ARGS... args)
  122. {
  123. static_assert(sizeof...(ARGS) + 2 == N,
  124. "wrong argument count in vec_t constructor");
  125. internal_init(m_data, X, Y, args...);
  126. }
  127. /* Various explicit constructors */
  128. explicit inline vec_t(T const &X)
  129. {
  130. for (auto &value : m_data)
  131. value = X;
  132. }
  133. /* Explicit constructor for type conversion */
  134. template<typename U>
  135. explicit inline vec_t(vec_t<U, N> const &v)
  136. {
  137. for (int i = 0; i < N; ++i)
  138. m_data[i] = T(v[i]);
  139. }
  140. /* Factory for base axis vectors, e.g. [1,0,0,…,0] */
  141. static inline vec_t<T, N> axis(int i)
  142. {
  143. assert(i >= 0);
  144. assert(i < N);
  145. vec_t<T, N> ret(T(0));
  146. ret[i] = T(1);
  147. return ret;
  148. }
  149. /* Constructor for initializer_list. We need these ugly
  150. * loops until C++ lets us initialize m_data directly. */
  151. inline vec_t(std::initializer_list<element> const &list)
  152. {
  153. auto l = list.begin();
  154. for (int i = 0; i < count && l != list.end(); ++i, ++l)
  155. m_data[i] = *l;
  156. for (int i = (int)list.size(); i < count; ++i)
  157. m_data[i] = T(0);
  158. }
  159. static const vec_t<T,N> zero;
  160. private:
  161. template<typename... ARGS>
  162. static inline void internal_init(T *data, T const &x, ARGS... args)
  163. {
  164. *data++ = x;
  165. internal_init(data, args...);
  166. }
  167. static inline void internal_init(T *data)
  168. {
  169. (void)data;
  170. }
  171. T m_data[count];
  172. };
  173. /*
  174. * 2-element vectors
  175. */
  176. template <typename T>
  177. struct [[nodiscard]] vec_t<T,2>
  178. : public swizzle_ops::base<T>
  179. {
  180. static int const count = 2;
  181. typedef T scalar_element;
  182. typedef T element;
  183. typedef vec_t<T,2> type;
  184. // Default constructor, copy constructor, and destructor
  185. inline constexpr vec_t() = default;
  186. inline constexpr vec_t(type const &v) = default;
  187. inline ~vec_t() = default;
  188. /* Implicit constructor for swizzling */
  189. template<int SWIZZLE>
  190. inline constexpr vec_t(vec_t<T, 2, SWIZZLE> const &v)
  191. : x(v[0]), y(v[1]) {}
  192. /* Explicit constructor for type conversion */
  193. template<typename U, int SWIZZLE>
  194. explicit inline constexpr vec_t(vec_t<U, 2, SWIZZLE> const &v)
  195. : x(T(v[0])), y(T(v[1])) {}
  196. /* Constructor for initializer_list. We need these ugly
  197. * loops until C++ lets us initialize m_data directly. */
  198. inline vec_t(std::initializer_list<element> const &list)
  199. {
  200. auto l = list.begin();
  201. for (int i = 0; i < count && l != list.end(); ++i, ++l)
  202. m_data[i] = *l;
  203. for (int i = (int)list.size(); i < count; ++i)
  204. m_data[i] = T(0);
  205. }
  206. /* Various explicit constructors */
  207. explicit inline constexpr vec_t(T X, T Y)
  208. : x(X), y(Y) {}
  209. explicit inline constexpr vec_t(T X)
  210. : x(X), y(X) {}
  211. /* Factory for base axis vectors, e.g. [1,0,0,…,0] */
  212. static inline vec_t<T,2> axis(int i)
  213. {
  214. assert(i >= 0);
  215. assert(i < 2);
  216. return vec_t<T,2>(T(i == 0), T(i == 1));
  217. }
  218. LOL_COMMON_MEMBER_OPS(x)
  219. static const vec_t<T,2> zero;
  220. static const vec_t<T,2> axis_x;
  221. static const vec_t<T,2> axis_y;
  222. union
  223. {
  224. struct { T x, y; }; /* axis */
  225. struct { T r, g; }; /* red, green */
  226. struct { T s, t; };
  227. #if !_DOXYGEN_SKIP_ME
  228. vec_t<T, 2, 9000> const xx, rr, ss/**/, ww;
  229. vec_t<T, 2, 9001> const xy, rg, st, rt, wh;
  230. vec_t<T, 2, 9010> const yx, gr, ts, tr, hw;
  231. vec_t<T, 2, 9011> const yy, gg, tt/**/, hh;
  232. vec_t<T, 3, 90000> const xxx, rrr, sss /**/, www;
  233. vec_t<T, 3, 90001> const xxy, rrg, sst, rrt, wwh;
  234. vec_t<T, 3, 90010> const xyx, rgr, sts, rtr, whw;
  235. vec_t<T, 3, 90011> const xyy, rgg, stt, rtt, whh;
  236. vec_t<T, 3, 90100> const yxx, grr, tss, trr, hww;
  237. vec_t<T, 3, 90101> const yxy, grg, tst, trt, hwh;
  238. vec_t<T, 3, 90110> const yyx, ggr, tts, ttr, hhw;
  239. vec_t<T, 3, 90111> const yyy, ggg, ttt /**/, hhh;
  240. vec_t<T, 4, 900000> const xxxx, rrrr, ssss /**/, wwww;
  241. vec_t<T, 4, 900001> const xxxy, rrrg, ssst, rrrt, wwwh;
  242. vec_t<T, 4, 900010> const xxyx, rrgr, ssts, rrtr, wwhw;
  243. vec_t<T, 4, 900011> const xxyy, rrgg, sstt, rrtt, wwhh;
  244. vec_t<T, 4, 900100> const xyxx, rgrr, stss, rtrr, whww;
  245. vec_t<T, 4, 900101> const xyxy, rgrg, stst, rtrt, whwh;
  246. vec_t<T, 4, 900110> const xyyx, rggr, stts, rttr, whhw;
  247. vec_t<T, 4, 900111> const xyyy, rggg, sttt, rttt, whhh;
  248. vec_t<T, 4, 901000> const yxxx, grrr, tsss, trrr, hwww;
  249. vec_t<T, 4, 901001> const yxxy, grrg, tsst, trrt, hwwh;
  250. vec_t<T, 4, 901010> const yxyx, grgr, tsts, trtr, hwhw;
  251. vec_t<T, 4, 901011> const yxyy, grgg, tstt, trtt, hwhh;
  252. vec_t<T, 4, 901100> const yyxx, ggrr, ttss, ttrr, hhww;
  253. vec_t<T, 4, 901101> const yyxy, ggrg, ttst, ttrt, hhwh;
  254. vec_t<T, 4, 901110> const yyyx, gggr, ttts, tttr, hhhw;
  255. vec_t<T, 4, 901111> const yyyy, gggg, tttt /**/, hhhh;
  256. #endif
  257. T m_data[count];
  258. };
  259. };
  260. /*
  261. * 3-element vectors
  262. */
  263. template <typename T>
  264. struct [[nodiscard]] vec_t<T,3>
  265. : public swizzle_ops::base<T>
  266. {
  267. static int const count = 3;
  268. typedef T scalar_element;
  269. typedef T element;
  270. typedef vec_t<T,3> type;
  271. // Default constructor, copy constructor, and destructor
  272. inline constexpr vec_t() = default;
  273. inline constexpr vec_t(type const &v) = default;
  274. inline ~vec_t() = default;
  275. /* Implicit constructor for swizzling */
  276. template<int SWIZZLE>
  277. inline constexpr vec_t(vec_t<T, 3, SWIZZLE> const &v)
  278. : x(v[0]), y(v[1]), z(v[2]) {}
  279. /* Explicit constructor for type conversion */
  280. template<typename U, int SWIZZLE>
  281. explicit inline constexpr vec_t(vec_t<U, 3, SWIZZLE> const &v)
  282. : x(T(v[0])), y(T(v[1])), z(T(v[2])) {}
  283. /* Constructor for initializer_list. We need these ugly
  284. * loops until C++ lets us initialize m_data directly. */
  285. inline vec_t(std::initializer_list<element> const &list)
  286. {
  287. auto l = list.begin();
  288. for (int i = 0; i < count && l != list.end(); ++i, ++l)
  289. m_data[i] = *l;
  290. for (int i = (int)list.size(); i < count; ++i)
  291. m_data[i] = T(0);
  292. }
  293. /* Various explicit constructors */
  294. explicit inline constexpr vec_t(T X)
  295. : x(X), y(X), z(X) {}
  296. explicit inline constexpr vec_t(T X, T Y, T Z)
  297. : x(X), y(Y), z(Z) {}
  298. explicit inline constexpr vec_t(vec_t<T,2> XY, T Z)
  299. : x(XY.x), y(XY.y), z(Z) {}
  300. explicit inline constexpr vec_t(T X, vec_t<T,2> YZ)
  301. : x(X), y(YZ.x), z(YZ.y) {}
  302. /* Factory for base axis vectors, e.g. [1,0,0,…,0] */
  303. static inline vec_t<T,3> axis(int i)
  304. {
  305. assert(i >= 0);
  306. assert(i < 3);
  307. return vec_t<T,3>(T(i == 0), T(i == 1), T(i == 2));
  308. }
  309. LOL_COMMON_MEMBER_OPS(x)
  310. static vec_t<T,3> toeuler_xyx(quat_t<T> const &q);
  311. static vec_t<T,3> toeuler_xzx(quat_t<T> const &q);
  312. static vec_t<T,3> toeuler_yxy(quat_t<T> const &q);
  313. static vec_t<T,3> toeuler_yzy(quat_t<T> const &q);
  314. static vec_t<T,3> toeuler_zxz(quat_t<T> const &q);
  315. static vec_t<T,3> toeuler_zyz(quat_t<T> const &q);
  316. static vec_t<T,3> toeuler_xyz(quat_t<T> const &q);
  317. static vec_t<T,3> toeuler_xzy(quat_t<T> const &q);
  318. static vec_t<T,3> toeuler_yxz(quat_t<T> const &q);
  319. static vec_t<T,3> toeuler_yzx(quat_t<T> const &q);
  320. static vec_t<T,3> toeuler_zxy(quat_t<T> const &q);
  321. static vec_t<T,3> toeuler_zyx(quat_t<T> const &q);
  322. /* Return the cross product (vector product) of “a” and “b” */ \
  323. friend inline type cross(type const &a, type const &b)
  324. {
  325. return type(a.y * b.z - a.z * b.y,
  326. a.z * b.x - a.x * b.z,
  327. a.x * b.y - a.y * b.x);
  328. }
  329. /* Return a vector that is orthogonal to “a” */
  330. friend inline type orthogonal(type const &a)
  331. {
  332. using std::fabs;
  333. return fabs(a.x) > fabs(a.z)
  334. ? type(-a.y, a.x, T(0))
  335. : type(T(0), -a.z, a.y);
  336. }
  337. /* Return a vector that is orthonormal to “a” */
  338. friend inline type orthonormal(type const &a)
  339. {
  340. return normalize(orthogonal(a));
  341. }
  342. static const vec_t<T,3> zero;
  343. static const vec_t<T,3> axis_x;
  344. static const vec_t<T,3> axis_y;
  345. static const vec_t<T,3> axis_z;
  346. union
  347. {
  348. struct { T x, y, z; }; /* axis */
  349. struct { T r, g, b; }; /* red, green, blue */
  350. struct { T s, t, p; };
  351. #if !_DOXYGEN_SKIP_ME
  352. vec_t<T, 2, 9000> const xx, rr, ss/**/, ww;
  353. vec_t<T, 2, 9001> const xy, rg, st, rt, wh;
  354. vec_t<T, 2, 9002> const xz, rb, sp, rp, wd;
  355. vec_t<T, 2, 9010> const yx, gr, ts, tr, hw;
  356. vec_t<T, 2, 9011> const yy, gg, tt/**/, hh;
  357. vec_t<T, 2, 9012> const yz, gb, tp/**/, hd;
  358. vec_t<T, 2, 9020> const zx, br, ps, pr, dw;
  359. vec_t<T, 2, 9021> const zy, bg, pt/**/, dh;
  360. vec_t<T, 2, 9022> const zz, bb, pp/**/, dd;
  361. vec_t<T, 3, 90000> const xxx, rrr, sss /**/, www;
  362. vec_t<T, 3, 90001> const xxy, rrg, sst, rrt, wwh;
  363. vec_t<T, 3, 90002> const xxz, rrb, ssp, rrp, wwd;
  364. vec_t<T, 3, 90010> const xyx, rgr, sts, rtr, whw;
  365. vec_t<T, 3, 90011> const xyy, rgg, stt, rtt, whh;
  366. vec_t<T, 3, 90012> const xyz, rgb, stp, rtp, whd;
  367. vec_t<T, 3, 90020> const xzx, rbr, sps, rpr, wdw;
  368. vec_t<T, 3, 90021> const xzy, rbg, spt, rpt, wdh;
  369. vec_t<T, 3, 90022> const xzz, rbb, spp, rpp, wdd;
  370. vec_t<T, 3, 90100> const yxx, grr, tss, trr, hww;
  371. vec_t<T, 3, 90101> const yxy, grg, tst, trt, hwh;
  372. vec_t<T, 3, 90102> const yxz, grb, tsp, trp, hwd;
  373. vec_t<T, 3, 90110> const yyx, ggr, tts, ttr, hhw;
  374. vec_t<T, 3, 90111> const yyy, ggg, ttt /**/, hhh;
  375. vec_t<T, 3, 90112> const yyz, ggb, ttp /**/, hhd;
  376. vec_t<T, 3, 90120> const yzx, gbr, tps, tpr, hdw;
  377. vec_t<T, 3, 90121> const yzy, gbg, tpt /**/, hdh;
  378. vec_t<T, 3, 90122> const yzz, gbb, tpp /**/, hdd;
  379. vec_t<T, 3, 90200> const zxx, brr, pss, prr, dww;
  380. vec_t<T, 3, 90201> const zxy, brg, pst, prt, dwh;
  381. vec_t<T, 3, 90202> const zxz, brb, psp, prp, dwd;
  382. vec_t<T, 3, 90210> const zyx, bgr, pts, ptr, dhw;
  383. vec_t<T, 3, 90211> const zyy, bgg, ptt /**/, dhh;
  384. vec_t<T, 3, 90212> const zyz, bgb, ptp /**/, dhd;
  385. vec_t<T, 3, 90220> const zzx, bbr, pps, ppr, ddw;
  386. vec_t<T, 3, 90221> const zzy, bbg, ppt /**/, ddh;
  387. vec_t<T, 3, 90222> const zzz, bbb, ppp /**/, ddd;
  388. vec_t<T,4,900000> const xxxx, rrrr, ssss;
  389. vec_t<T,4,900001> const xxxy, rrrg, ssst;
  390. vec_t<T,4,900002> const xxxz, rrrb, sssp;
  391. vec_t<T,4,900010> const xxyx, rrgr, ssts;
  392. vec_t<T,4,900011> const xxyy, rrgg, sstt;
  393. vec_t<T,4,900012> const xxyz, rrgb, sstp;
  394. vec_t<T,4,900020> const xxzx, rrbr, ssps;
  395. vec_t<T,4,900021> const xxzy, rrbg, sspt;
  396. vec_t<T,4,900022> const xxzz, rrbb, sspp;
  397. vec_t<T,4,900100> const xyxx, rgrr, stss;
  398. vec_t<T,4,900101> const xyxy, rgrg, stst;
  399. vec_t<T,4,900102> const xyxz, rgrb, stsp;
  400. vec_t<T,4,900110> const xyyx, rggr, stts;
  401. vec_t<T,4,900111> const xyyy, rggg, sttt;
  402. vec_t<T,4,900112> const xyyz, rggb, sttp;
  403. vec_t<T,4,900120> const xyzx, rgbr, stps;
  404. vec_t<T,4,900121> const xyzy, rgbg, stpt;
  405. vec_t<T,4,900122> const xyzz, rgbb, stpp;
  406. vec_t<T,4,900200> const xzxx, rbrr, spss;
  407. vec_t<T,4,900201> const xzxy, rbrg, spst;
  408. vec_t<T,4,900202> const xzxz, rbrb, spsp;
  409. vec_t<T,4,900210> const xzyx, rbgr, spts;
  410. vec_t<T,4,900211> const xzyy, rbgg, sptt;
  411. vec_t<T,4,900212> const xzyz, rbgb, sptp;
  412. vec_t<T,4,900220> const xzzx, rbbr, spps;
  413. vec_t<T,4,900221> const xzzy, rbbg, sppt;
  414. vec_t<T,4,900222> const xzzz, rbbb, sppp;
  415. vec_t<T,4,901000> const yxxx, grrr, tsss;
  416. vec_t<T,4,901001> const yxxy, grrg, tsst;
  417. vec_t<T,4,901002> const yxxz, grrb, tssp;
  418. vec_t<T,4,901010> const yxyx, grgr, tsts;
  419. vec_t<T,4,901011> const yxyy, grgg, tstt;
  420. vec_t<T,4,901012> const yxyz, grgb, tstp;
  421. vec_t<T,4,901020> const yxzx, grbr, tsps;
  422. vec_t<T,4,901021> const yxzy, grbg, tspt;
  423. vec_t<T,4,901022> const yxzz, grbb, tspp;
  424. vec_t<T,4,901100> const yyxx, ggrr, ttss;
  425. vec_t<T,4,901101> const yyxy, ggrg, ttst;
  426. vec_t<T,4,901102> const yyxz, ggrb, ttsp;
  427. vec_t<T,4,901110> const yyyx, gggr, ttts;
  428. vec_t<T,4,901111> const yyyy, gggg, tttt;
  429. vec_t<T,4,901112> const yyyz, gggb, tttp;
  430. vec_t<T,4,901120> const yyzx, ggbr, ttps;
  431. vec_t<T,4,901121> const yyzy, ggbg, ttpt;
  432. vec_t<T,4,901122> const yyzz, ggbb, ttpp;
  433. vec_t<T,4,901200> const yzxx, gbrr, tpss;
  434. vec_t<T,4,901201> const yzxy, gbrg, tpst;
  435. vec_t<T,4,901202> const yzxz, gbrb, tpsp;
  436. vec_t<T,4,901210> const yzyx, gbgr, tpts;
  437. vec_t<T,4,901211> const yzyy, gbgg, tptt;
  438. vec_t<T,4,901212> const yzyz, gbgb, tptp;
  439. vec_t<T,4,901220> const yzzx, gbbr, tpps;
  440. vec_t<T,4,901221> const yzzy, gbbg, tppt;
  441. vec_t<T,4,901222> const yzzz, gbbb, tppp;
  442. vec_t<T,4,902000> const zxxx, brrr, psss;
  443. vec_t<T,4,902001> const zxxy, brrg, psst;
  444. vec_t<T,4,902002> const zxxz, brrb, pssp;
  445. vec_t<T,4,902010> const zxyx, brgr, psts;
  446. vec_t<T,4,902011> const zxyy, brgg, pstt;
  447. vec_t<T,4,902012> const zxyz, brgb, pstp;
  448. vec_t<T,4,902020> const zxzx, brbr, psps;
  449. vec_t<T,4,902021> const zxzy, brbg, pspt;
  450. vec_t<T,4,902022> const zxzz, brbb, pspp;
  451. vec_t<T,4,902100> const zyxx, bgrr, ptss;
  452. vec_t<T,4,902101> const zyxy, bgrg, ptst;
  453. vec_t<T,4,902102> const zyxz, bgrb, ptsp;
  454. vec_t<T,4,902110> const zyyx, bggr, ptts;
  455. vec_t<T,4,902111> const zyyy, bggg, pttt;
  456. vec_t<T,4,902112> const zyyz, bggb, pttp;
  457. vec_t<T,4,902120> const zyzx, bgbr, ptps;
  458. vec_t<T,4,902121> const zyzy, bgbg, ptpt;
  459. vec_t<T,4,902122> const zyzz, bgbb, ptpp;
  460. vec_t<T,4,902200> const zzxx, bbrr, ppss;
  461. vec_t<T,4,902201> const zzxy, bbrg, ppst;
  462. vec_t<T,4,902202> const zzxz, bbrb, ppsp;
  463. vec_t<T,4,902210> const zzyx, bbgr, ppts;
  464. vec_t<T,4,902211> const zzyy, bbgg, pptt;
  465. vec_t<T,4,902212> const zzyz, bbgb, pptp;
  466. vec_t<T,4,902220> const zzzx, bbbr, ppps;
  467. vec_t<T,4,902221> const zzzy, bbbg, pppt;
  468. vec_t<T,4,902222> const zzzz, bbbb, pppp;
  469. #endif
  470. T m_data[count];
  471. };
  472. };
  473. /*
  474. * 4-element vectors
  475. */
  476. template <typename T>
  477. struct [[nodiscard]] vec_t<T,4>
  478. : public swizzle_ops::base<T>
  479. {
  480. static int const count = 4;
  481. typedef T scalar_element;
  482. typedef T element;
  483. typedef vec_t<T,4> type;
  484. // Default constructor, copy constructor, and destructor
  485. inline constexpr vec_t() = default;
  486. inline constexpr vec_t(type const &v) = default;
  487. inline ~vec_t() = default;
  488. /* Implicit constructor for swizzling */
  489. template<int SWIZZLE>
  490. inline constexpr vec_t(vec_t<T, 4, SWIZZLE> const &v)
  491. : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
  492. /* Explicit constructor for type conversion */
  493. template<typename U, int SWIZZLE>
  494. explicit inline constexpr vec_t(vec_t<U, 4, SWIZZLE> const &v)
  495. : x(T(v[0])), y(T(v[1])), z(T(v[2])), w(T(v[3])) {}
  496. /* Constructor for initializer_list. We need these ugly
  497. * loops until C++ lets us initialize m_data directly. */
  498. inline vec_t(std::initializer_list<element> const &list)
  499. {
  500. auto l = list.begin();
  501. for (int i = 0; i < count && l != list.end(); ++i, ++l)
  502. m_data[i] = *l;
  503. for (int i = (int)list.size(); i < count; ++i)
  504. m_data[i] = T(0);
  505. }
  506. /* Various explicit constructors */
  507. explicit inline constexpr vec_t(T X)
  508. : x(X), y(X), z(X), w(X) {}
  509. explicit inline constexpr vec_t(T X, T Y, T Z, T W)
  510. : x(X), y(Y), z(Z), w(W) {}
  511. explicit inline constexpr vec_t(vec_t<T,2> XY, T Z, T W)
  512. : x(XY.x), y(XY.y), z(Z), w(W) {}
  513. explicit inline constexpr vec_t(T X, vec_t<T,2> YZ, T W)
  514. : x(X), y(YZ.x), z(YZ.y), w(W) {}
  515. explicit inline constexpr vec_t(T X, T Y, vec_t<T,2> ZW)
  516. : x(X), y(Y), z(ZW.x), w(ZW.y) {}
  517. explicit inline constexpr vec_t(vec_t<T,2> XY, vec_t<T,2> ZW)
  518. : x(XY.x), y(XY.y), z(ZW.x), w(ZW.y) {}
  519. explicit inline constexpr vec_t(vec_t<T,3> XYZ, T W)
  520. : x(XYZ.x), y(XYZ.y), z(XYZ.z), w(W) {}
  521. explicit inline constexpr vec_t(T X, vec_t<T,3> YZW)
  522. : x(X), y(YZW.x), z(YZW.y), w(YZW.z) {}
  523. /* Factory for base axis vectors, e.g. [1,0,0,…,0] */
  524. static inline vec_t<T,4> axis(int i)
  525. {
  526. assert(i >= 0);
  527. assert(i < 4);
  528. return vec_t<T,4>(T(i == 0), T(i == 1), T(i == 2), T(i == 3));
  529. }
  530. LOL_COMMON_MEMBER_OPS(x)
  531. static const vec_t<T,4> zero;
  532. static const vec_t<T,4> axis_x;
  533. static const vec_t<T,4> axis_y;
  534. static const vec_t<T,4> axis_z;
  535. static const vec_t<T,4> axis_w;
  536. union
  537. {
  538. struct { T x, y, z, w; }; /* axis */
  539. struct { T r, g, b, a; }; /* red, green, blue, alpha */
  540. struct { T s, t, p, q; };
  541. #if !_DOXYGEN_SKIP_ME
  542. vec_t<T,2,9000> const xx, rr, ss;
  543. vec_t<T,2,9001> const xy, rg, st;
  544. vec_t<T,2,9002> const xz, rb, sp;
  545. vec_t<T,2,9003> const xw, ra, sq;
  546. vec_t<T,2,9010> const yx, gr, ts;
  547. vec_t<T,2,9011> const yy, gg, tt;
  548. vec_t<T,2,9012> const yz, gb, tp;
  549. vec_t<T,2,9013> const yw, ga, tq;
  550. vec_t<T,2,9020> const zx, br, ps;
  551. vec_t<T,2,9021> const zy, bg, pt;
  552. vec_t<T,2,9022> const zz, bb, pp;
  553. vec_t<T,2,9023> const zw, ba, pq;
  554. vec_t<T,2,9030> const wx, ar, qs;
  555. vec_t<T,2,9031> const wy, ag, qt;
  556. vec_t<T,2,9032> const wz, ab, qp;
  557. vec_t<T,2,9033> const ww, aa, qq;
  558. vec_t<T,3,90000> const xxx, rrr, sss;
  559. vec_t<T,3,90001> const xxy, rrg, sst;
  560. vec_t<T,3,90002> const xxz, rrb, ssp;
  561. vec_t<T,3,90003> const xxw, rra, ssq;
  562. vec_t<T,3,90010> const xyx, rgr, sts;
  563. vec_t<T,3,90011> const xyy, rgg, stt;
  564. vec_t<T,3,90012> const xyz, rgb, stp;
  565. vec_t<T,3,90013> const xyw, rga, stq;
  566. vec_t<T,3,90020> const xzx, rbr, sps;
  567. vec_t<T,3,90021> const xzy, rbg, spt;
  568. vec_t<T,3,90022> const xzz, rbb, spp;
  569. vec_t<T,3,90023> const xzw, rba, spq;
  570. vec_t<T,3,90030> const xwx, rar, sqs;
  571. vec_t<T,3,90031> const xwy, rag, sqt;
  572. vec_t<T,3,90032> const xwz, rab, sqp;
  573. vec_t<T,3,90033> const xww, raa, sqq;
  574. vec_t<T,3,90100> const yxx, grr, tss;
  575. vec_t<T,3,90101> const yxy, grg, tst;
  576. vec_t<T,3,90102> const yxz, grb, tsp;
  577. vec_t<T,3,90103> const yxw, gra, tsq;
  578. vec_t<T,3,90110> const yyx, ggr, tts;
  579. vec_t<T,3,90111> const yyy, ggg, ttt;
  580. vec_t<T,3,90112> const yyz, ggb, ttp;
  581. vec_t<T,3,90113> const yyw, gga, ttq;
  582. vec_t<T,3,90120> const yzx, gbr, tps;
  583. vec_t<T,3,90121> const yzy, gbg, tpt;
  584. vec_t<T,3,90122> const yzz, gbb, tpp;
  585. vec_t<T,3,90123> const yzw, gba, tpq;
  586. vec_t<T,3,90130> const ywx, gar, tqs;
  587. vec_t<T,3,90131> const ywy, gag, tqt;
  588. vec_t<T,3,90132> const ywz, gab, tqp;
  589. vec_t<T,3,90133> const yww, gaa, tqq;
  590. vec_t<T,3,90200> const zxx, brr, pss;
  591. vec_t<T,3,90201> const zxy, brg, pst;
  592. vec_t<T,3,90202> const zxz, brb, psp;
  593. vec_t<T,3,90203> const zxw, bra, psq;
  594. vec_t<T,3,90210> const zyx, bgr, pts;
  595. vec_t<T,3,90211> const zyy, bgg, ptt;
  596. vec_t<T,3,90212> const zyz, bgb, ptp;
  597. vec_t<T,3,90213> const zyw, bga, ptq;
  598. vec_t<T,3,90220> const zzx, bbr, pps;
  599. vec_t<T,3,90221> const zzy, bbg, ppt;
  600. vec_t<T,3,90222> const zzz, bbb, ppp;
  601. vec_t<T,3,90223> const zzw, bba, ppq;
  602. vec_t<T,3,90230> const zwx, bar, pqs;
  603. vec_t<T,3,90231> const zwy, bag, pqt;
  604. vec_t<T,3,90232> const zwz, bab, pqp;
  605. vec_t<T,3,90233> const zww, baa, pqq;
  606. vec_t<T,3,90300> const wxx, arr, qss;
  607. vec_t<T,3,90301> const wxy, arg, qst;
  608. vec_t<T,3,90302> const wxz, arb, qsp;
  609. vec_t<T,3,90303> const wxw, ara, qsq;
  610. vec_t<T,3,90310> const wyx, agr, qts;
  611. vec_t<T,3,90311> const wyy, agg, qtt;
  612. vec_t<T,3,90312> const wyz, agb, qtp;
  613. vec_t<T,3,90313> const wyw, aga, qtq;
  614. vec_t<T,3,90320> const wzx, abr, qps;
  615. vec_t<T,3,90321> const wzy, abg, qpt;
  616. vec_t<T,3,90322> const wzz, abb, qpp;
  617. vec_t<T,3,90323> const wzw, aba, qpq;
  618. vec_t<T,3,90330> const wwx, aar, qqs;
  619. vec_t<T,3,90331> const wwy, aag, qqt;
  620. vec_t<T,3,90332> const wwz, aab, qqp;
  621. vec_t<T,3,90333> const www, aaa, qqq;
  622. vec_t<T,4,900000> const xxxx, rrrr, ssss;
  623. vec_t<T,4,900001> const xxxy, rrrg, ssst;
  624. vec_t<T,4,900002> const xxxz, rrrb, sssp;
  625. vec_t<T,4,900003> const xxxw, rrra, sssq;
  626. vec_t<T,4,900010> const xxyx, rrgr, ssts;
  627. vec_t<T,4,900011> const xxyy, rrgg, sstt;
  628. vec_t<T,4,900012> const xxyz, rrgb, sstp;
  629. vec_t<T,4,900013> const xxyw, rrga, sstq;
  630. vec_t<T,4,900020> const xxzx, rrbr, ssps;
  631. vec_t<T,4,900021> const xxzy, rrbg, sspt;
  632. vec_t<T,4,900022> const xxzz, rrbb, sspp;
  633. vec_t<T,4,900023> const xxzw, rrba, sspq;
  634. vec_t<T,4,900030> const xxwx, rrar, ssqs;
  635. vec_t<T,4,900031> const xxwy, rrag, ssqt;
  636. vec_t<T,4,900032> const xxwz, rrab, ssqp;
  637. vec_t<T,4,900033> const xxww, rraa, ssqq;
  638. vec_t<T,4,900100> const xyxx, rgrr, stss;
  639. vec_t<T,4,900101> const xyxy, rgrg, stst;
  640. vec_t<T,4,900102> const xyxz, rgrb, stsp;
  641. vec_t<T,4,900103> const xyxw, rgra, stsq;
  642. vec_t<T,4,900110> const xyyx, rggr, stts;
  643. vec_t<T,4,900111> const xyyy, rggg, sttt;
  644. vec_t<T,4,900112> const xyyz, rggb, sttp;
  645. vec_t<T,4,900113> const xyyw, rgga, sttq;
  646. vec_t<T,4,900120> const xyzx, rgbr, stps;
  647. vec_t<T,4,900121> const xyzy, rgbg, stpt;
  648. vec_t<T,4,900122> const xyzz, rgbb, stpp;
  649. vec_t<T,4,900123> const xyzw, rgba, stpq;
  650. vec_t<T,4,900130> const xywx, rgar, stqs;
  651. vec_t<T,4,900131> const xywy, rgag, stqt;
  652. vec_t<T,4,900132> const xywz, rgab, stqp;
  653. vec_t<T,4,900133> const xyww, rgaa, stqq;
  654. vec_t<T,4,900200> const xzxx, rbrr, spss;
  655. vec_t<T,4,900201> const xzxy, rbrg, spst;
  656. vec_t<T,4,900202> const xzxz, rbrb, spsp;
  657. vec_t<T,4,900203> const xzxw, rbra, spsq;
  658. vec_t<T,4,900210> const xzyx, rbgr, spts;
  659. vec_t<T,4,900211> const xzyy, rbgg, sptt;
  660. vec_t<T,4,900212> const xzyz, rbgb, sptp;
  661. vec_t<T,4,900213> const xzyw, rbga, sptq;
  662. vec_t<T,4,900220> const xzzx, rbbr, spps;
  663. vec_t<T,4,900221> const xzzy, rbbg, sppt;
  664. vec_t<T,4,900222> const xzzz, rbbb, sppp;
  665. vec_t<T,4,900223> const xzzw, rbba, sppq;
  666. vec_t<T,4,900230> const xzwx, rbar, spqs;
  667. vec_t<T,4,900231> const xzwy, rbag, spqt;
  668. vec_t<T,4,900232> const xzwz, rbab, spqp;
  669. vec_t<T,4,900233> const xzww, rbaa, spqq;
  670. vec_t<T,4,900300> const xwxx, rarr, sqss;
  671. vec_t<T,4,900301> const xwxy, rarg, sqst;
  672. vec_t<T,4,900302> const xwxz, rarb, sqsp;
  673. vec_t<T,4,900303> const xwxw, rara, sqsq;
  674. vec_t<T,4,900310> const xwyx, ragr, sqts;
  675. vec_t<T,4,900311> const xwyy, ragg, sqtt;
  676. vec_t<T,4,900312> const xwyz, ragb, sqtp;
  677. vec_t<T,4,900313> const xwyw, raga, sqtq;
  678. vec_t<T,4,900320> const xwzx, rabr, sqps;
  679. vec_t<T,4,900321> const xwzy, rabg, sqpt;
  680. vec_t<T,4,900322> const xwzz, rabb, sqpp;
  681. vec_t<T,4,900323> const xwzw, raba, sqpq;
  682. vec_t<T,4,900330> const xwwx, raar, sqqs;
  683. vec_t<T,4,900331> const xwwy, raag, sqqt;
  684. vec_t<T,4,900332> const xwwz, raab, sqqp;
  685. vec_t<T,4,900333> const xwww, raaa, sqqq;
  686. vec_t<T,4,901000> const yxxx, grrr, tsss;
  687. vec_t<T,4,901001> const yxxy, grrg, tsst;
  688. vec_t<T,4,901002> const yxxz, grrb, tssp;
  689. vec_t<T,4,901003> const yxxw, grra, tssq;
  690. vec_t<T,4,901010> const yxyx, grgr, tsts;
  691. vec_t<T,4,901011> const yxyy, grgg, tstt;
  692. vec_t<T,4,901012> const yxyz, grgb, tstp;
  693. vec_t<T,4,901013> const yxyw, grga, tstq;
  694. vec_t<T,4,901020> const yxzx, grbr, tsps;
  695. vec_t<T,4,901021> const yxzy, grbg, tspt;
  696. vec_t<T,4,901022> const yxzz, grbb, tspp;
  697. vec_t<T,4,901023> const yxzw, grba, tspq;
  698. vec_t<T,4,901030> const yxwx, grar, tsqs;
  699. vec_t<T,4,901031> const yxwy, grag, tsqt;
  700. vec_t<T,4,901032> const yxwz, grab, tsqp;
  701. vec_t<T,4,901033> const yxww, graa, tsqq;
  702. vec_t<T,4,901100> const yyxx, ggrr, ttss;
  703. vec_t<T,4,901101> const yyxy, ggrg, ttst;
  704. vec_t<T,4,901102> const yyxz, ggrb, ttsp;
  705. vec_t<T,4,901103> const yyxw, ggra, ttsq;
  706. vec_t<T,4,901110> const yyyx, gggr, ttts;
  707. vec_t<T,4,901111> const yyyy, gggg, tttt;
  708. vec_t<T,4,901112> const yyyz, gggb, tttp;
  709. vec_t<T,4,901113> const yyyw, ggga, tttq;
  710. vec_t<T,4,901120> const yyzx, ggbr, ttps;
  711. vec_t<T,4,901121> const yyzy, ggbg, ttpt;
  712. vec_t<T,4,901122> const yyzz, ggbb, ttpp;
  713. vec_t<T,4,901123> const yyzw, ggba, ttpq;
  714. vec_t<T,4,901130> const yywx, ggar, ttqs;
  715. vec_t<T,4,901131> const yywy, ggag, ttqt;
  716. vec_t<T,4,901132> const yywz, ggab, ttqp;
  717. vec_t<T,4,901133> const yyww, ggaa, ttqq;
  718. vec_t<T,4,901200> const yzxx, gbrr, tpss;
  719. vec_t<T,4,901201> const yzxy, gbrg, tpst;
  720. vec_t<T,4,901202> const yzxz, gbrb, tpsp;
  721. vec_t<T,4,901203> const yzxw, gbra, tpsq;
  722. vec_t<T,4,901210> const yzyx, gbgr, tpts;
  723. vec_t<T,4,901211> const yzyy, gbgg, tptt;
  724. vec_t<T,4,901212> const yzyz, gbgb, tptp;
  725. vec_t<T,4,901213> const yzyw, gbga, tptq;
  726. vec_t<T,4,901220> const yzzx, gbbr, tpps;
  727. vec_t<T,4,901221> const yzzy, gbbg, tppt;
  728. vec_t<T,4,901222> const yzzz, gbbb, tppp;
  729. vec_t<T,4,901223> const yzzw, gbba, tppq;
  730. vec_t<T,4,901230> const yzwx, gbar, tpqs;
  731. vec_t<T,4,901231> const yzwy, gbag, tpqt;
  732. vec_t<T,4,901232> const yzwz, gbab, tpqp;
  733. vec_t<T,4,901233> const yzww, gbaa, tpqq;
  734. vec_t<T,4,901300> const ywxx, garr, tqss;
  735. vec_t<T,4,901301> const ywxy, garg, tqst;
  736. vec_t<T,4,901302> const ywxz, garb, tqsp;
  737. vec_t<T,4,901303> const ywxw, gara, tqsq;
  738. vec_t<T,4,901310> const ywyx, gagr, tqts;
  739. vec_t<T,4,901311> const ywyy, gagg, tqtt;
  740. vec_t<T,4,901312> const ywyz, gagb, tqtp;
  741. vec_t<T,4,901313> const ywyw, gaga, tqtq;
  742. vec_t<T,4,901320> const ywzx, gabr, tqps;
  743. vec_t<T,4,901321> const ywzy, gabg, tqpt;
  744. vec_t<T,4,901322> const ywzz, gabb, tqpp;
  745. vec_t<T,4,901323> const ywzw, gaba, tqpq;
  746. vec_t<T,4,901330> const ywwx, gaar, tqqs;
  747. vec_t<T,4,901331> const ywwy, gaag, tqqt;
  748. vec_t<T,4,901332> const ywwz, gaab, tqqp;
  749. vec_t<T,4,901333> const ywww, gaaa, tqqq;
  750. vec_t<T,4,902000> const zxxx, brrr, psss;
  751. vec_t<T,4,902001> const zxxy, brrg, psst;
  752. vec_t<T,4,902002> const zxxz, brrb, pssp;
  753. vec_t<T,4,902003> const zxxw, brra, pssq;
  754. vec_t<T,4,902010> const zxyx, brgr, psts;
  755. vec_t<T,4,902011> const zxyy, brgg, pstt;
  756. vec_t<T,4,902012> const zxyz, brgb, pstp;
  757. vec_t<T,4,902013> const zxyw, brga, pstq;
  758. vec_t<T,4,902020> const zxzx, brbr, psps;
  759. vec_t<T,4,902021> const zxzy, brbg, pspt;
  760. vec_t<T,4,902022> const zxzz, brbb, pspp;
  761. vec_t<T,4,902023> const zxzw, brba, pspq;
  762. vec_t<T,4,902030> const zxwx, brar, psqs;
  763. vec_t<T,4,902031> const zxwy, brag, psqt;
  764. vec_t<T,4,902032> const zxwz, brab, psqp;
  765. vec_t<T,4,902033> const zxww, braa, psqq;
  766. vec_t<T,4,902100> const zyxx, bgrr, ptss;
  767. vec_t<T,4,902101> const zyxy, bgrg, ptst;
  768. vec_t<T,4,902102> const zyxz, bgrb, ptsp;
  769. vec_t<T,4,902103> const zyxw, bgra, ptsq;
  770. vec_t<T,4,902110> const zyyx, bggr, ptts;
  771. vec_t<T,4,902111> const zyyy, bggg, pttt;
  772. vec_t<T,4,902112> const zyyz, bggb, pttp;
  773. vec_t<T,4,902113> const zyyw, bgga, pttq;
  774. vec_t<T,4,902120> const zyzx, bgbr, ptps;
  775. vec_t<T,4,902121> const zyzy, bgbg, ptpt;
  776. vec_t<T,4,902122> const zyzz, bgbb, ptpp;
  777. vec_t<T,4,902123> const zyzw, bgba, ptpq;
  778. vec_t<T,4,902130> const zywx, bgar, ptqs;
  779. vec_t<T,4,902131> const zywy, bgag, ptqt;
  780. vec_t<T,4,902132> const zywz, bgab, ptqp;
  781. vec_t<T,4,902133> const zyww, bgaa, ptqq;
  782. vec_t<T,4,902200> const zzxx, bbrr, ppss;
  783. vec_t<T,4,902201> const zzxy, bbrg, ppst;
  784. vec_t<T,4,902202> const zzxz, bbrb, ppsp;
  785. vec_t<T,4,902203> const zzxw, bbra, ppsq;
  786. vec_t<T,4,902210> const zzyx, bbgr, ppts;
  787. vec_t<T,4,902211> const zzyy, bbgg, pptt;
  788. vec_t<T,4,902212> const zzyz, bbgb, pptp;
  789. vec_t<T,4,902213> const zzyw, bbga, pptq;
  790. vec_t<T,4,902220> const zzzx, bbbr, ppps;
  791. vec_t<T,4,902221> const zzzy, bbbg, pppt;
  792. vec_t<T,4,902222> const zzzz, bbbb, pppp;
  793. vec_t<T,4,902223> const zzzw, bbba, pppq;
  794. vec_t<T,4,902230> const zzwx, bbar, ppqs;
  795. vec_t<T,4,902231> const zzwy, bbag, ppqt;
  796. vec_t<T,4,902232> const zzwz, bbab, ppqp;
  797. vec_t<T,4,902233> const zzww, bbaa, ppqq;
  798. vec_t<T,4,902300> const zwxx, barr, pqss;
  799. vec_t<T,4,902301> const zwxy, barg, pqst;
  800. vec_t<T,4,902302> const zwxz, barb, pqsp;
  801. vec_t<T,4,902303> const zwxw, bara, pqsq;
  802. vec_t<T,4,902310> const zwyx, bagr, pqts;
  803. vec_t<T,4,902311> const zwyy, bagg, pqtt;
  804. vec_t<T,4,902312> const zwyz, bagb, pqtp;
  805. vec_t<T,4,902313> const zwyw, baga, pqtq;
  806. vec_t<T,4,902320> const zwzx, babr, pqps;
  807. vec_t<T,4,902321> const zwzy, babg, pqpt;
  808. vec_t<T,4,902322> const zwzz, babb, pqpp;
  809. vec_t<T,4,902323> const zwzw, baba, pqpq;
  810. vec_t<T,4,902330> const zwwx, baar, pqqs;
  811. vec_t<T,4,902331> const zwwy, baag, pqqt;
  812. vec_t<T,4,902332> const zwwz, baab, pqqp;
  813. vec_t<T,4,902333> const zwww, baaa, pqqq;
  814. vec_t<T,4,903000> const wxxx, arrr, qsss;
  815. vec_t<T,4,903001> const wxxy, arrg, qsst;
  816. vec_t<T,4,903002> const wxxz, arrb, qssp;
  817. vec_t<T,4,903003> const wxxw, arra, qssq;
  818. vec_t<T,4,903010> const wxyx, argr, qsts;
  819. vec_t<T,4,903011> const wxyy, argg, qstt;
  820. vec_t<T,4,903012> const wxyz, argb, qstp;
  821. vec_t<T,4,903013> const wxyw, arga, qstq;
  822. vec_t<T,4,903020> const wxzx, arbr, qsps;
  823. vec_t<T,4,903021> const wxzy, arbg, qspt;
  824. vec_t<T,4,903022> const wxzz, arbb, qspp;
  825. vec_t<T,4,903023> const wxzw, arba, qspq;
  826. vec_t<T,4,903030> const wxwx, arar, qsqs;
  827. vec_t<T,4,903031> const wxwy, arag, qsqt;
  828. vec_t<T,4,903032> const wxwz, arab, qsqp;
  829. vec_t<T,4,903033> const wxww, araa, qsqq;
  830. vec_t<T,4,903100> const wyxx, agrr, qtss;
  831. vec_t<T,4,903101> const wyxy, agrg, qtst;
  832. vec_t<T,4,903102> const wyxz, agrb, qtsp;
  833. vec_t<T,4,903103> const wyxw, agra, qtsq;
  834. vec_t<T,4,903110> const wyyx, aggr, qtts;
  835. vec_t<T,4,903111> const wyyy, aggg, qttt;
  836. vec_t<T,4,903112> const wyyz, aggb, qttp;
  837. vec_t<T,4,903113> const wyyw, agga, qttq;
  838. vec_t<T,4,903120> const wyzx, agbr, qtps;
  839. vec_t<T,4,903121> const wyzy, agbg, qtpt;
  840. vec_t<T,4,903122> const wyzz, agbb, qtpp;
  841. vec_t<T,4,903123> const wyzw, agba, qtpq;
  842. vec_t<T,4,903130> const wywx, agar, qtqs;
  843. vec_t<T,4,903131> const wywy, agag, qtqt;
  844. vec_t<T,4,903132> const wywz, agab, qtqp;
  845. vec_t<T,4,903133> const wyww, agaa, qtqq;
  846. vec_t<T,4,903200> const wzxx, abrr, qpss;
  847. vec_t<T,4,903201> const wzxy, abrg, qpst;
  848. vec_t<T,4,903202> const wzxz, abrb, qpsp;
  849. vec_t<T,4,903203> const wzxw, abra, qpsq;
  850. vec_t<T,4,903210> const wzyx, abgr, qpts;
  851. vec_t<T,4,903211> const wzyy, abgg, qptt;
  852. vec_t<T,4,903212> const wzyz, abgb, qptp;
  853. vec_t<T,4,903213> const wzyw, abga, qptq;
  854. vec_t<T,4,903220> const wzzx, abbr, qpps;
  855. vec_t<T,4,903221> const wzzy, abbg, qppt;
  856. vec_t<T,4,903222> const wzzz, abbb, qppp;
  857. vec_t<T,4,903223> const wzzw, abba, qppq;
  858. vec_t<T,4,903230> const wzwx, abar, qpqs;
  859. vec_t<T,4,903231> const wzwy, abag, qpqt;
  860. vec_t<T,4,903232> const wzwz, abab, qpqp;
  861. vec_t<T,4,903233> const wzww, abaa, qpqq;
  862. vec_t<T,4,903300> const wwxx, aarr, qqss;
  863. vec_t<T,4,903301> const wwxy, aarg, qqst;
  864. vec_t<T,4,903302> const wwxz, aarb, qqsp;
  865. vec_t<T,4,903303> const wwxw, aara, qqsq;
  866. vec_t<T,4,903310> const wwyx, aagr, qqts;
  867. vec_t<T,4,903311> const wwyy, aagg, qqtt;
  868. vec_t<T,4,903312> const wwyz, aagb, qqtp;
  869. vec_t<T,4,903313> const wwyw, aaga, qqtq;
  870. vec_t<T,4,903320> const wwzx, aabr, qqps;
  871. vec_t<T,4,903321> const wwzy, aabg, qqpt;
  872. vec_t<T,4,903322> const wwzz, aabb, qqpp;
  873. vec_t<T,4,903323> const wwzw, aaba, qqpq;
  874. vec_t<T,4,903330> const wwwx, aaar, qqqs;
  875. vec_t<T,4,903331> const wwwy, aaag, qqqt;
  876. vec_t<T,4,903332> const wwwz, aaab, qqqp;
  877. vec_t<T,4,903333> const wwww, aaaa, qqqq;
  878. #endif
  879. T m_data[count];
  880. };
  881. };
  882. /*
  883. * stdstream method implementation
  884. */
  885. template<typename U, int N, int SWIZZLE = FULL_SWIZZLE>
  886. std::ostream &operator<<(std::ostream &stream, vec_t<U,N> const &v)
  887. {
  888. stream << '(';
  889. for (int i = 0; i < N; ++i)
  890. stream << v[i] << (i == N - 1 ? ")" : ", ");
  891. return stream;
  892. }
  893. /*
  894. * vec_t *(scalar, vec_t)
  895. */
  896. template<typename T, int N, int SWIZZLE>
  897. static inline typename std::enable_if<SWIZZLE != FULL_SWIZZLE, vec_t<T,N>>::type
  898. operator *(T const &val, vec_t<T,N,SWIZZLE> const &a)
  899. {
  900. vec_t<T,N> ret;
  901. for (int i = 0; i < N; ++i)
  902. ret[i] = val * a[i];
  903. return ret;
  904. }
  905. /*
  906. * vec_t min|max|fmod(vec_t, vec_t|scalar)
  907. * vec_t min|max|fmod(scalar, vec_t)
  908. */
  909. #define LOL_SWIZZLE_V_VV_FUN(fun) \
  910. template<typename T, int N, int SWIZZLE1, int SWIZZLE2> \
  911. inline vec_t<T,N> fun(vec_t<T,N,SWIZZLE1> const &a, \
  912. vec_t<T,N,SWIZZLE2> const &b) \
  913. { \
  914. vec_t<T,N> ret; \
  915. for (int i = 0; i < N; ++i) \
  916. ret[i] = fun(a[i], b[i]); \
  917. return ret; \
  918. } \
  919. \
  920. template<typename T, int N, int SWIZZLE> \
  921. inline vec_t<T,N> fun(vec_t<T,N,SWIZZLE> const &a, T const &b) \
  922. { \
  923. vec_t<T,N> ret; \
  924. for (int i = 0; i < N; ++i) \
  925. ret[i] = fun(a[i], b); \
  926. return ret; \
  927. } \
  928. \
  929. template<typename T, int N, int SWIZZLE> \
  930. inline vec_t<T,N> fun(T const &a, vec_t<T,N,SWIZZLE> const &b) \
  931. { \
  932. vec_t<T,N> ret; \
  933. for (int i = 0; i < N; ++i) \
  934. ret[i] = fun(a, b[i]); \
  935. return ret; \
  936. }
  937. LOL_SWIZZLE_V_VV_FUN(min)
  938. LOL_SWIZZLE_V_VV_FUN(max)
  939. LOL_SWIZZLE_V_VV_FUN(fmod)
  940. #undef LOL_SWIZZLE_V_VV_FUN
  941. /*
  942. * vec_t clamp(vec_t, vec_t, vec_t)
  943. * vec_t clamp(vec_t, scalar, vec_t)
  944. * vec_t clamp(vec_t, vec_t, scalar)
  945. * vec_t clamp(vec_t, scalar, scalar)
  946. */
  947. template<typename T, int N, int SWIZZLE1, int SWIZZLE2, int SWIZZLE3>
  948. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  949. vec_t<T,N,SWIZZLE2> const &a,
  950. vec_t<T,N,SWIZZLE3> const &b)
  951. {
  952. return max(min(x, b), a);
  953. }
  954. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  955. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  956. T const &a,
  957. vec_t<T,N,SWIZZLE2> const &b)
  958. {
  959. return max(min(x, b), a);
  960. }
  961. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  962. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  963. vec_t<T,N,SWIZZLE2> const &a,
  964. T const &b)
  965. {
  966. return max(min(x, b), a);
  967. }
  968. template<typename T, int N, int SWIZZLE1>
  969. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  970. T const &a,
  971. T const &b)
  972. {
  973. return max(min(x, b), a);
  974. }
  975. /*
  976. * vec_t mix(vec_t, vec_t, vec_t)
  977. * vec_t mix(vec_t, vec_t, scalar)
  978. */
  979. template<typename T, int N, int SWIZZLE1, int SWIZZLE2, int SWIZZLE3>
  980. static inline vec_t<T,N> mix(vec_t<T,N,SWIZZLE1> const &x,
  981. vec_t<T,N,SWIZZLE2> const &y,
  982. vec_t<T,N,SWIZZLE3> const &a)
  983. {
  984. return x + a * (y - x);
  985. }
  986. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  987. static inline vec_t<T,N> mix(vec_t<T,N,SWIZZLE1> const &x,
  988. vec_t<T,N,SWIZZLE2> const &y,
  989. T const &a)
  990. {
  991. return x + a * (y - x);
  992. }
  993. /*
  994. * Some GLSL-like functions.
  995. */
  996. template<typename T, int N, int SWIZZLE1, int SWIZZLE2> [[nodiscard]]
  997. static inline T dot(vec_t<T,N,SWIZZLE1> const &a,
  998. vec_t<T,N,SWIZZLE2> const &b)
  999. {
  1000. T ret(0);
  1001. for (int i = 0; i < N; ++i)
  1002. ret += a[i] * b[i];
  1003. return ret;
  1004. }
  1005. template<typename T, int N, int SWIZZLE> [[nodiscard]]
  1006. static inline T sqlength(vec_t<T,N,SWIZZLE> const &a)
  1007. {
  1008. return dot(a, a);
  1009. }
  1010. template<typename T, int N, int SWIZZLE> [[nodiscard]]
  1011. static inline T length(vec_t<T,N,SWIZZLE> const &a)
  1012. {
  1013. using std::sqrt;
  1014. /* FIXME: this is not very nice */
  1015. return T(sqrt(sqlength(a)));
  1016. }
  1017. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  1018. static inline vec_t<T,N> lerp(vec_t<T,N,SWIZZLE1> const &a,
  1019. vec_t<T,N,SWIZZLE2> const &b,
  1020. T const &s)
  1021. {
  1022. vec_t<T,N> ret;
  1023. for (int i = 0; i < N; ++i)
  1024. ret[i] = a[i] + s * (b[i] - a[i]);
  1025. return ret;
  1026. }
  1027. template<typename T, int N, int SWIZZLE1, int SWIZZLE2> [[nodiscard]]
  1028. static inline T distance(vec_t<T,N,SWIZZLE1> const &a,
  1029. vec_t<T,N,SWIZZLE2> const &b)
  1030. {
  1031. return length(a - b);
  1032. }
  1033. template<typename T, int N, int SWIZZLE>
  1034. static inline vec_t<T,N> fract(vec_t<T,N,SWIZZLE> const &a)
  1035. {
  1036. vec_t<T,N> ret;
  1037. for (int i = 0; i < N; ++i)
  1038. ret[i] = fract(a[i]);
  1039. return ret;
  1040. }
  1041. template<typename T, int N, int SWIZZLE>
  1042. static inline vec_t<T,N> saturate(vec_t<T,N,SWIZZLE> const &a)
  1043. {
  1044. vec_t<T,N> ret;
  1045. for (int i = 0; i < N; ++i)
  1046. ret[i] = saturate(a[i]);
  1047. return ret;
  1048. }
  1049. template<typename T, int N, int SWIZZLE>
  1050. static inline vec_t<T,N> normalize(vec_t<T,N,SWIZZLE> const &a)
  1051. {
  1052. T norm = T(length(a));
  1053. return norm ? a / norm : vec_t<T,N>(T(0));
  1054. }
  1055. template<typename T, int N, int SWIZZLE>
  1056. static inline vec_t<T,N> abs(vec_t<T,N,SWIZZLE> const &a)
  1057. {
  1058. vec_t<T,N> ret;
  1059. for (int i = 0; i < N; ++i)
  1060. ret[i] = abs(a[i]);
  1061. return ret;
  1062. }
  1063. template<typename T, int N, int SWIZZLE>
  1064. static inline vec_t<T,N> degrees(vec_t<T,N,SWIZZLE> const &a)
  1065. {
  1066. vec_t<T,N> ret;
  1067. for (int i = 0; i < N; ++i)
  1068. ret[i] = degrees(a[i]);
  1069. return ret;
  1070. }
  1071. template<typename T, int N, int SWIZZLE>
  1072. static inline vec_t<T, N> radians(vec_t<T, N, SWIZZLE> const &a)
  1073. {
  1074. vec_t<T, N> ret;
  1075. for (int i = 0; i < N; ++i)
  1076. ret[i] = radians(a[i]);
  1077. return ret;
  1078. }
  1079. // Cartesian operation consider that you're in spherical coordinate
  1080. template<typename T, int SWIZZLE>
  1081. static inline vec_t<T, 2> cartesian(vec_t<T, 2, SWIZZLE> const &a)
  1082. {
  1083. using std::sin, std::cos;
  1084. vec_t<T, 2> ret;
  1085. ret.x = a[0] * cos(a[1]);
  1086. ret.y = a[0] * sin(a[1]);
  1087. return ret;
  1088. }
  1089. template<typename T, int SWIZZLE>
  1090. static inline vec_t<T, 3> cartesian(vec_t<T, 3, SWIZZLE> const &a)
  1091. {
  1092. using std::sin, std::cos;
  1093. vec_t<T, 3> ret;
  1094. ret.x = a[0] * sin(a[2]) * cos(a[1]);
  1095. ret.y = a[0] * cos(a[2]);
  1096. ret.z = a[0] * sin(a[2]) * sin(a[1]);
  1097. return ret;
  1098. }
  1099. // Spherical operation consider that you're in cartesian coordinate
  1100. template<typename T, int SWIZZLE>
  1101. static inline vec_t<T, 2> spherical(vec_t<T, 2, SWIZZLE> const &a)
  1102. {
  1103. vec_t<T, 2> ret;
  1104. ret[0] = sqlength(a);
  1105. ret[1] = atan2(a.y, a.x);
  1106. return ret;
  1107. }
  1108. template<typename T, int SWIZZLE>
  1109. static inline vec_t<T, 3> spherical(vec_t<T, 3, SWIZZLE> const &a)
  1110. {
  1111. using std::atan, std::acos;
  1112. vec_t<T, 3> ret;
  1113. ret[0] = sqlength(a);
  1114. ret[1] = atan(a.y / a.x);
  1115. ret[2] = acos(a.z / ret[0]);
  1116. return ret;
  1117. }
  1118. /*
  1119. * C++11 iterators
  1120. */
  1121. template<typename T, int N, int SWIZZLE>
  1122. class vec_const_iter
  1123. {
  1124. public:
  1125. inline vec_const_iter(vec_t<T,N,SWIZZLE> const &vec, int pos)
  1126. : m_vec(vec),
  1127. m_pos(pos)
  1128. { }
  1129. inline bool operator !=(vec_const_iter<T,N,SWIZZLE> const & that) const
  1130. {
  1131. return m_pos != that.m_pos;
  1132. }
  1133. template<int S = SWIZZLE>
  1134. inline typename std::enable_if<S != FULL_SWIZZLE, T const &>::type
  1135. operator *() const
  1136. {
  1137. return m_vec[m_pos];
  1138. }
  1139. template<int S = SWIZZLE>
  1140. inline typename std::enable_if<S == FULL_SWIZZLE, T const &>::type
  1141. operator *() const
  1142. {
  1143. return m_vec[m_pos];
  1144. }
  1145. inline vec_const_iter<T,N,SWIZZLE> & operator ++()
  1146. {
  1147. ++m_pos;
  1148. return *this;
  1149. }
  1150. private:
  1151. vec_t<T,N,SWIZZLE> const &m_vec;
  1152. int m_pos;
  1153. };
  1154. /* FIXME: do we need a non-const iterator? Looks almost useless to me,
  1155. * and a lot of hassle with swizzling. */
  1156. template<typename T, int N, int SWIZZLE>
  1157. inline vec_const_iter<T,N,SWIZZLE> begin(vec_t<T,N,SWIZZLE> const &a)
  1158. {
  1159. return vec_const_iter<T,N,SWIZZLE>(a, 0);
  1160. }
  1161. template<typename T, int N, int SWIZZLE>
  1162. inline vec_const_iter<T,N,SWIZZLE> end(vec_t<T,N,SWIZZLE> const &a)
  1163. {
  1164. return vec_const_iter<T,N,SWIZZLE>(a, N);
  1165. }
  1166. /*
  1167. * Constants
  1168. */
  1169. template<typename T, int N>
  1170. vec_t<T,N> const vec_t<T,N>::zero = vec_t<T,N>(T(0));
  1171. template<typename T>
  1172. vec_t<T,2> const vec_t<T,2>::zero = vec_t<T,2>(T(0));
  1173. template<typename T>
  1174. vec_t<T,3> const vec_t<T,3>::zero = vec_t<T,3>(T(0));
  1175. template<typename T>
  1176. vec_t<T,4> const vec_t<T,4>::zero = vec_t<T,4>(T(0));
  1177. template<typename T>
  1178. vec_t<T,2> const vec_t<T,2>::axis_x = vec_t<T,2>(T(1), T(0));
  1179. template<typename T>
  1180. vec_t<T,2> const vec_t<T,2>::axis_y = vec_t<T,2>(T(0), T(1));
  1181. template<typename T>
  1182. vec_t<T,3> const vec_t<T,3>::axis_x = vec_t<T,3>(T(1), T(0), T(0));
  1183. template<typename T>
  1184. vec_t<T,3> const vec_t<T,3>::axis_y = vec_t<T,3>(T(0), T(1), T(0));
  1185. template<typename T>
  1186. vec_t<T,3> const vec_t<T,3>::axis_z = vec_t<T,3>(T(0), T(0), T(1));
  1187. template<typename T>
  1188. vec_t<T,4> const vec_t<T,4>::axis_x = vec_t<T,4>(T(1), T(0), T(0), T(0));
  1189. template<typename T>
  1190. vec_t<T,4> const vec_t<T,4>::axis_y = vec_t<T,4>(T(0), T(1), T(0), T(0));
  1191. template<typename T>
  1192. vec_t<T,4> const vec_t<T,4>::axis_z = vec_t<T,4>(T(0), T(0), T(1), T(0));
  1193. template<typename T>
  1194. vec_t<T,4> const vec_t<T,4>::axis_w = vec_t<T,4>(T(0), T(0), T(0), T(1));
  1195. //
  1196. // Generic GLSL-like type names
  1197. //
  1198. #define T_(tleft, tright, suffix) \
  1199. typedef tleft half tright f16##suffix; \
  1200. typedef tleft float tright suffix; \
  1201. typedef tleft double tright d##suffix; \
  1202. typedef tleft ldouble tright f128##suffix; \
  1203. typedef tleft int8_t tright i8##suffix; \
  1204. typedef tleft uint8_t tright u8##suffix; \
  1205. typedef tleft int16_t tright i16##suffix; \
  1206. typedef tleft uint16_t tright u16##suffix; \
  1207. typedef tleft int32_t tright i##suffix; \
  1208. typedef tleft uint32_t tright u##suffix; \
  1209. typedef tleft int64_t tright i64##suffix; \
  1210. typedef tleft uint64_t tright u64##suffix; \
  1211. typedef tleft real tright r##suffix;
  1212. // Idiotic hack to put "," inside a macro argument
  1213. #define C_ ,
  1214. T_(vec_t<, C_ 2>, vec2)
  1215. T_(vec_t<, C_ 3>, vec3)
  1216. T_(vec_t<, C_ 4>, vec4)
  1217. T_(vec_t<, C_ 5>, vec5)
  1218. T_(vec_t<, C_ 6>, vec6)
  1219. T_(vec_t<, C_ 7>, vec7)
  1220. T_(vec_t<, C_ 8>, vec8)
  1221. T_(vec_t<, C_ 9>, vec9)
  1222. T_(vec_t<, C_ 10>, vec10)
  1223. T_(vec_t<, C_ 11>, vec11)
  1224. T_(vec_t<, C_ 12>, vec12)
  1225. #undef C_
  1226. #undef T_
  1227. static_assert(sizeof(i8vec2) == 2, "sizeof(i8vec2) == 2");
  1228. static_assert(sizeof(i16vec2) == 4, "sizeof(i16vec2) == 4");
  1229. static_assert(sizeof(ivec2) == 8, "sizeof(ivec2) == 8");
  1230. static_assert(sizeof(i64vec2) == 16, "sizeof(i64vec2) == 16");
  1231. static_assert(sizeof(vec2) == 8, "sizeof(vec2) == 8");
  1232. static_assert(sizeof(dvec2) == 16, "sizeof(dvec2) == 16");
  1233. static_assert(sizeof(i8vec3) == 3, "sizeof(i8vec3) == 3");
  1234. static_assert(sizeof(i16vec3) == 6, "sizeof(i16vec3) == 6");
  1235. static_assert(sizeof(ivec3) == 12, "sizeof(ivec3) == 12");
  1236. static_assert(sizeof(i64vec3) == 24, "sizeof(i64vec3) == 24");
  1237. static_assert(sizeof(vec3) == 12, "sizeof(vec3) == 12");
  1238. static_assert(sizeof(dvec3) == 24, "sizeof(dvec3) == 24");
  1239. static_assert(sizeof(i8vec4) == 4, "sizeof(i8vec4) == 4");
  1240. static_assert(sizeof(i16vec4) == 8, "sizeof(i16vec4) == 8");
  1241. static_assert(sizeof(ivec4) == 16, "sizeof(ivec4) == 16");
  1242. static_assert(sizeof(i64vec4) == 32, "sizeof(i64vec4) == 32");
  1243. static_assert(sizeof(vec4) == 16, "sizeof(vec4) == 16");
  1244. static_assert(sizeof(dvec4) == 32, "sizeof(dvec4) == 32");
  1245. //
  1246. // HLSL/Cg-compliant type names
  1247. //
  1248. typedef vec2 float2;
  1249. typedef vec3 float3;
  1250. typedef vec4 float4;
  1251. typedef vec5 float5;
  1252. typedef vec6 float6;
  1253. typedef vec7 float7;
  1254. typedef vec8 float8;
  1255. typedef vec9 float9;
  1256. typedef vec10 float10;
  1257. typedef vec11 float11;
  1258. typedef vec12 float12;
  1259. typedef f16vec2 half2;
  1260. typedef f16vec3 half3;
  1261. typedef f16vec4 half4;
  1262. typedef ivec2 int2;
  1263. typedef ivec3 int3;
  1264. typedef ivec4 int4;
  1265. typedef ivec5 int5;
  1266. typedef ivec6 int6;
  1267. typedef ivec7 int7;
  1268. typedef ivec8 int8;
  1269. typedef ivec9 int9;
  1270. typedef ivec10 int10;
  1271. typedef ivec11 int11;
  1272. typedef ivec12 int12;
  1273. } // namespace lol
  1274. #include "private/vector.ipp"