您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

1432 行
48 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 <algorithm> // std::min, std::max
  21. #include <cmath> // std::fabs, std::cos…
  22. // FIXME: get rid of this, too
  23. #include <../legacy/lol/base/types.h>
  24. #include "ops.h"
  25. namespace lol
  26. {
  27. template<typename T> struct quat_t;
  28. /*
  29. * Magic vector swizzling
  30. *
  31. * These vectors are empty, but thanks to static_cast we can take their
  32. * address and access the vector of T's that they are union'ed with. We
  33. * use static_cast instead of reinterpret_cast because there is a stronger
  34. * guarantee (by the standard) that the address will stay the same across
  35. * casts.
  36. *
  37. * Using swizzled vectors as lvalues:
  38. * We need to implement an assignment operator _and_ override the default
  39. * assignment operator. We try to pass arguments by value so that we don't
  40. * have to care about overwriting ourselves (e.g. c.rgb = c.bgr).
  41. * However, Visual Studio 2013 doesn't support unrestricted unions, so
  42. * fuck it for now.
  43. */
  44. template<typename T, int N, int SWIZZLE>
  45. struct [[nodiscard]] vec_t
  46. /* MUST have a different base than e.g. vec_t<T,2> otherwise the unions
  47. * in vec_t<T,2> with the same base will cause empty base optimisation
  48. * failures. */
  49. : public swizzle_ops::base<T, SWIZZLE>
  50. {
  51. static int const count = N;
  52. typedef T scalar_element;
  53. typedef T element;
  54. typedef vec_t<T,N> type;
  55. /* Allow the assignment operator if unrestricted unions are supported. */
  56. inline vec_t<T, N, SWIZZLE>& operator =(vec_t<T, N> that)
  57. {
  58. for (int i = 0; i < N; ++i)
  59. (*this)[i] = that[i];
  60. return *this;
  61. }
  62. inline vec_t<T, N, SWIZZLE>& operator =(vec_t<T, N, SWIZZLE> const &that)
  63. {
  64. /* Pass by value in case this == &that */
  65. return *this = (vec_t<T,N>)that;
  66. }
  67. inline T& operator[](size_t n)
  68. {
  69. int const i = (SWIZZLE >> (3 * (N - 1 - n))) & 3;
  70. return static_cast<T*>(static_cast<void*>(this))[i];
  71. }
  72. inline T const& operator[](size_t n) const
  73. {
  74. int const i = (SWIZZLE >> (3 * (N - 1 - n))) & 3;
  75. return static_cast<T const*>(static_cast<void const *>(this))[i];
  76. }
  77. private:
  78. // Hide all default constructors and destructors; this object
  79. // is only intended to exist as part of a union.
  80. template<typename T2, int N2, int SWIZZLE2> friend struct vec_t;
  81. vec_t() = default;
  82. vec_t(vec_t<T, N, SWIZZLE> const &) = default;
  83. ~vec_t() = default;
  84. };
  85. /*
  86. * Helper macros for vector type member functions
  87. */
  88. #define LOL_COMMON_MEMBER_OPS(first) \
  89. inline T& operator[](size_t n) { return (&this->first)[n]; } \
  90. inline T const& operator[](size_t n) const { return (&this->first)[n]; } \
  91. \
  92. /* An explicit assignment operator is now mandatory */ \
  93. inline type & operator =(type const &that) \
  94. { \
  95. for (int i = 0; i < type::count; ++i) \
  96. (*this)[i] = that[i]; \
  97. return *this; \
  98. } \
  99. \
  100. std::string tostring() const;
  101. /* The generic “vec_t” type, which is a fixed-size vector with no
  102. * swizzling. There's an override for N=2, N=3, N=4 that has swizzling. */
  103. template<typename T, int N>
  104. struct [[nodiscard]] vec_t<T, N, FULL_SWIZZLE>
  105. : public componentwise_ops::base<T>
  106. {
  107. static int const count = N;
  108. typedef T scalar_element;
  109. typedef T element;
  110. typedef vec_t<T,N> type;
  111. // Default constructor, copy constructor, and destructor
  112. inline constexpr vec_t() = default;
  113. inline constexpr vec_t(type const &v) = default;
  114. inline ~vec_t() = default;
  115. LOL_COMMON_MEMBER_OPS(m_data[0])
  116. /* Explicit constructor that takes exactly N arguments thanks to SFINAE. */
  117. template<typename... ARGS>
  118. explicit inline vec_t(T const &X,
  119. typename std::enable_if<sizeof...(ARGS) + 2 == N, T>::type const &Y,
  120. ARGS... args)
  121. {
  122. static_assert(sizeof...(ARGS) + 2 == N,
  123. "wrong argument count in vec_t constructor");
  124. internal_init(m_data, X, Y, args...);
  125. }
  126. /* Various explicit constructors */
  127. explicit inline vec_t(T const &X)
  128. {
  129. for (auto &value : m_data)
  130. value = X;
  131. }
  132. /* Explicit constructor for type conversion */
  133. template<typename U>
  134. explicit inline vec_t(vec_t<U, N> const &v)
  135. {
  136. for (int i = 0; i < N; ++i)
  137. m_data[i] = T(v[i]);
  138. }
  139. /* Factory for base axis vectors, e.g. [1,0,0,…,0] */
  140. static inline vec_t<T, N> axis(int i)
  141. {
  142. assert(i >= 0);
  143. assert(i < N);
  144. vec_t<T, N> ret(T(0));
  145. ret[i] = T(1);
  146. return ret;
  147. }
  148. /* Constructor for initializer_list. We need these ugly
  149. * loops until C++ lets us initialize m_data directly. */
  150. inline vec_t(std::initializer_list<element> const &list)
  151. {
  152. auto l = list.begin();
  153. for (int i = 0; i < count && l != list.end(); ++i, ++l)
  154. m_data[i] = *l;
  155. for (int i = (int)list.size(); i < count; ++i)
  156. m_data[i] = T(0);
  157. }
  158. static const vec_t<T,N> zero;
  159. private:
  160. template<typename... ARGS>
  161. static inline void internal_init(T *data, T const &x, ARGS... args)
  162. {
  163. *data++ = x;
  164. internal_init(data, args...);
  165. }
  166. static inline void internal_init(T *data)
  167. {
  168. (void)data;
  169. }
  170. T m_data[count];
  171. };
  172. /*
  173. * 2-element vectors
  174. */
  175. template <typename T>
  176. struct [[nodiscard]] vec_t<T,2>
  177. : public swizzle_ops::base<T>
  178. {
  179. static int const count = 2;
  180. typedef T scalar_element;
  181. typedef T element;
  182. typedef vec_t<T,2> type;
  183. // Default constructor, copy constructor, and destructor
  184. inline constexpr vec_t() = default;
  185. inline constexpr vec_t(type const &v) = default;
  186. inline ~vec_t() = default;
  187. /* Implicit constructor for swizzling */
  188. template<int SWIZZLE>
  189. inline constexpr vec_t(vec_t<T, 2, SWIZZLE> const &v)
  190. : x(v[0]), y(v[1]) {}
  191. /* Explicit constructor for type conversion */
  192. template<typename U, int SWIZZLE>
  193. explicit inline constexpr vec_t(vec_t<U, 2, SWIZZLE> const &v)
  194. : x(T(v[0])), y(T(v[1])) {}
  195. /* Constructor for initializer_list. We need these ugly
  196. * loops until C++ lets us initialize m_data directly. */
  197. inline vec_t(std::initializer_list<element> const &list)
  198. {
  199. auto l = list.begin();
  200. for (int i = 0; i < count && l != list.end(); ++i, ++l)
  201. m_data[i] = *l;
  202. for (int i = (int)list.size(); i < count; ++i)
  203. m_data[i] = T(0);
  204. }
  205. /* Various explicit constructors */
  206. explicit inline constexpr vec_t(T X, T Y)
  207. : x(X), y(Y) {}
  208. explicit inline constexpr vec_t(T X)
  209. : x(X), y(X) {}
  210. /* Factory for base axis vectors, e.g. [1,0,0,…,0] */
  211. static inline vec_t<T,2> axis(int i)
  212. {
  213. assert(i >= 0);
  214. assert(i < 2);
  215. return vec_t<T,2>(T(i == 0), T(i == 1));
  216. }
  217. LOL_COMMON_MEMBER_OPS(x)
  218. static const vec_t<T,2> zero;
  219. static const vec_t<T,2> axis_x;
  220. static const vec_t<T,2> axis_y;
  221. union
  222. {
  223. struct { T x, y; }; /* axis */
  224. struct { T r, g; }; /* red, green */
  225. struct { T s, t; };
  226. #if !_DOXYGEN_SKIP_ME
  227. vec_t<T,2,000> const xx, rr, ss;
  228. vec_t<T,2,001> const xy, rg, st;
  229. vec_t<T,2,010> const yx, gr, ts;
  230. vec_t<T,2,011> const yy, gg, tt;
  231. vec_t<T,3,0000> const xxx, rrr, sss;
  232. vec_t<T,3,0001> const xxy, rrg, sst;
  233. vec_t<T,3,0010> const xyx, rgr, sts;
  234. vec_t<T,3,0011> const xyy, rgg, stt;
  235. vec_t<T,3,0100> const yxx, grr, tss;
  236. vec_t<T,3,0101> const yxy, grg, tst;
  237. vec_t<T,3,0110> const yyx, ggr, tts;
  238. vec_t<T,3,0111> const yyy, ggg, ttt;
  239. vec_t<T,4,00000> const xxxx, rrrr, ssss;
  240. vec_t<T,4,00001> const xxxy, rrrg, ssst;
  241. vec_t<T,4,00010> const xxyx, rrgr, ssts;
  242. vec_t<T,4,00011> const xxyy, rrgg, sstt;
  243. vec_t<T,4,00100> const xyxx, rgrr, stss;
  244. vec_t<T,4,00101> const xyxy, rgrg, stst;
  245. vec_t<T,4,00110> const xyyx, rggr, stts;
  246. vec_t<T,4,00111> const xyyy, rggg, sttt;
  247. vec_t<T,4,01000> const yxxx, grrr, tsss;
  248. vec_t<T,4,01001> const yxxy, grrg, tsst;
  249. vec_t<T,4,01010> const yxyx, grgr, tsts;
  250. vec_t<T,4,01011> const yxyy, grgg, tstt;
  251. vec_t<T,4,01100> const yyxx, ggrr, ttss;
  252. vec_t<T,4,01101> const yyxy, ggrg, ttst;
  253. vec_t<T,4,01110> const yyyx, gggr, ttts;
  254. vec_t<T,4,01111> const yyyy, gggg, tttt;
  255. #endif
  256. T m_data[count];
  257. };
  258. };
  259. /*
  260. * 3-element vectors
  261. */
  262. template <typename T>
  263. struct [[nodiscard]] vec_t<T,3>
  264. : public swizzle_ops::base<T>
  265. {
  266. static int const count = 3;
  267. typedef T scalar_element;
  268. typedef T element;
  269. typedef vec_t<T,3> type;
  270. // Default constructor, copy constructor, and destructor
  271. inline constexpr vec_t() = default;
  272. inline constexpr vec_t(type const &v) = default;
  273. inline ~vec_t() = default;
  274. /* Implicit constructor for swizzling */
  275. template<int SWIZZLE>
  276. inline constexpr vec_t(vec_t<T, 3, SWIZZLE> const &v)
  277. : x(v[0]), y(v[1]), z(v[2]) {}
  278. /* Explicit constructor for type conversion */
  279. template<typename U, int SWIZZLE>
  280. explicit inline constexpr vec_t(vec_t<U, 3, SWIZZLE> const &v)
  281. : x(T(v[0])), y(T(v[1])), z(T(v[2])) {}
  282. /* Constructor for initializer_list. We need these ugly
  283. * loops until C++ lets us initialize m_data directly. */
  284. inline vec_t(std::initializer_list<element> const &list)
  285. {
  286. auto l = list.begin();
  287. for (int i = 0; i < count && l != list.end(); ++i, ++l)
  288. m_data[i] = *l;
  289. for (int i = (int)list.size(); i < count; ++i)
  290. m_data[i] = T(0);
  291. }
  292. /* Various explicit constructors */
  293. explicit inline constexpr vec_t(T X)
  294. : x(X), y(X), z(X) {}
  295. explicit inline constexpr vec_t(T X, T Y, T Z)
  296. : x(X), y(Y), z(Z) {}
  297. explicit inline constexpr vec_t(vec_t<T,2> XY, T Z)
  298. : x(XY.x), y(XY.y), z(Z) {}
  299. explicit inline constexpr vec_t(T X, vec_t<T,2> YZ)
  300. : x(X), y(YZ.x), z(YZ.y) {}
  301. /* Factory for base axis vectors, e.g. [1,0,0,…,0] */
  302. static inline vec_t<T,3> axis(int i)
  303. {
  304. assert(i >= 0);
  305. assert(i < 3);
  306. return vec_t<T,3>(T(i == 0), T(i == 1), T(i == 2));
  307. }
  308. LOL_COMMON_MEMBER_OPS(x)
  309. static vec_t<T,3> toeuler_xyx(quat_t<T> const &q);
  310. static vec_t<T,3> toeuler_xzx(quat_t<T> const &q);
  311. static vec_t<T,3> toeuler_yxy(quat_t<T> const &q);
  312. static vec_t<T,3> toeuler_yzy(quat_t<T> const &q);
  313. static vec_t<T,3> toeuler_zxz(quat_t<T> const &q);
  314. static vec_t<T,3> toeuler_zyz(quat_t<T> const &q);
  315. static vec_t<T,3> toeuler_xyz(quat_t<T> const &q);
  316. static vec_t<T,3> toeuler_xzy(quat_t<T> const &q);
  317. static vec_t<T,3> toeuler_yxz(quat_t<T> const &q);
  318. static vec_t<T,3> toeuler_yzx(quat_t<T> const &q);
  319. static vec_t<T,3> toeuler_zxy(quat_t<T> const &q);
  320. static vec_t<T,3> toeuler_zyx(quat_t<T> const &q);
  321. /* Return the cross product (vector product) of “a” and “b” */ \
  322. friend inline type cross(type const &a, type const &b)
  323. {
  324. return type(a.y * b.z - a.z * b.y,
  325. a.z * b.x - a.x * b.z,
  326. a.x * b.y - a.y * b.x);
  327. }
  328. /* Return a vector that is orthogonal to “a” */
  329. friend inline type orthogonal(type const &a)
  330. {
  331. using std::fabs;
  332. return fabs(a.x) > fabs(a.z)
  333. ? type(-a.y, a.x, T(0))
  334. : type(T(0), -a.z, a.y);
  335. }
  336. /* Return a vector that is orthonormal to “a” */
  337. friend inline type orthonormal(type const &a)
  338. {
  339. return normalize(orthogonal(a));
  340. }
  341. static const vec_t<T,3> zero;
  342. static const vec_t<T,3> axis_x;
  343. static const vec_t<T,3> axis_y;
  344. static const vec_t<T,3> axis_z;
  345. union
  346. {
  347. struct { T x, y, z; }; /* axis */
  348. struct { T r, g, b; }; /* red, green, blue */
  349. struct { T s, t, p; };
  350. #if !_DOXYGEN_SKIP_ME
  351. vec_t<T,2,000> const xx, rr, ss;
  352. vec_t<T,2,001> const xy, rg, st;
  353. vec_t<T,2,002> const xz, rb, sp;
  354. vec_t<T,2,010> const yx, gr, ts;
  355. vec_t<T,2,011> const yy, gg, tt;
  356. vec_t<T,2,012> const yz, gb, tp;
  357. vec_t<T,2,020> const zx, br, ps;
  358. vec_t<T,2,021> const zy, bg, pt;
  359. vec_t<T,2,022> const zz, bb, pp;
  360. vec_t<T,3,0000> const xxx, rrr, sss;
  361. vec_t<T,3,0001> const xxy, rrg, sst;
  362. vec_t<T,3,0002> const xxz, rrb, ssp;
  363. vec_t<T,3,0010> const xyx, rgr, sts;
  364. vec_t<T,3,0011> const xyy, rgg, stt;
  365. vec_t<T,3,0012> const xyz, rgb, stp;
  366. vec_t<T,3,0020> const xzx, rbr, sps;
  367. vec_t<T,3,0021> const xzy, rbg, spt;
  368. vec_t<T,3,0022> const xzz, rbb, spp;
  369. vec_t<T,3,0100> const yxx, grr, tss;
  370. vec_t<T,3,0101> const yxy, grg, tst;
  371. vec_t<T,3,0102> const yxz, grb, tsp;
  372. vec_t<T,3,0110> const yyx, ggr, tts;
  373. vec_t<T,3,0111> const yyy, ggg, ttt;
  374. vec_t<T,3,0112> const yyz, ggb, ttp;
  375. vec_t<T,3,0120> const yzx, gbr, tps;
  376. vec_t<T,3,0121> const yzy, gbg, tpt;
  377. vec_t<T,3,0122> const yzz, gbb, tpp;
  378. vec_t<T,3,0200> const zxx, brr, pss;
  379. vec_t<T,3,0201> const zxy, brg, pst;
  380. vec_t<T,3,0202> const zxz, brb, psp;
  381. vec_t<T,3,0210> const zyx, bgr, pts;
  382. vec_t<T,3,0211> const zyy, bgg, ptt;
  383. vec_t<T,3,0212> const zyz, bgb, ptp;
  384. vec_t<T,3,0220> const zzx, bbr, pps;
  385. vec_t<T,3,0221> const zzy, bbg, ppt;
  386. vec_t<T,3,0222> const zzz, bbb, ppp;
  387. vec_t<T,4,00000> const xxxx, rrrr, ssss;
  388. vec_t<T,4,00001> const xxxy, rrrg, ssst;
  389. vec_t<T,4,00002> const xxxz, rrrb, sssp;
  390. vec_t<T,4,00010> const xxyx, rrgr, ssts;
  391. vec_t<T,4,00011> const xxyy, rrgg, sstt;
  392. vec_t<T,4,00012> const xxyz, rrgb, sstp;
  393. vec_t<T,4,00020> const xxzx, rrbr, ssps;
  394. vec_t<T,4,00021> const xxzy, rrbg, sspt;
  395. vec_t<T,4,00022> const xxzz, rrbb, sspp;
  396. vec_t<T,4,00100> const xyxx, rgrr, stss;
  397. vec_t<T,4,00101> const xyxy, rgrg, stst;
  398. vec_t<T,4,00102> const xyxz, rgrb, stsp;
  399. vec_t<T,4,00110> const xyyx, rggr, stts;
  400. vec_t<T,4,00111> const xyyy, rggg, sttt;
  401. vec_t<T,4,00112> const xyyz, rggb, sttp;
  402. vec_t<T,4,00120> const xyzx, rgbr, stps;
  403. vec_t<T,4,00121> const xyzy, rgbg, stpt;
  404. vec_t<T,4,00122> const xyzz, rgbb, stpp;
  405. vec_t<T,4,00200> const xzxx, rbrr, spss;
  406. vec_t<T,4,00201> const xzxy, rbrg, spst;
  407. vec_t<T,4,00202> const xzxz, rbrb, spsp;
  408. vec_t<T,4,00210> const xzyx, rbgr, spts;
  409. vec_t<T,4,00211> const xzyy, rbgg, sptt;
  410. vec_t<T,4,00212> const xzyz, rbgb, sptp;
  411. vec_t<T,4,00220> const xzzx, rbbr, spps;
  412. vec_t<T,4,00221> const xzzy, rbbg, sppt;
  413. vec_t<T,4,00222> const xzzz, rbbb, sppp;
  414. vec_t<T,4,01000> const yxxx, grrr, tsss;
  415. vec_t<T,4,01001> const yxxy, grrg, tsst;
  416. vec_t<T,4,01002> const yxxz, grrb, tssp;
  417. vec_t<T,4,01010> const yxyx, grgr, tsts;
  418. vec_t<T,4,01011> const yxyy, grgg, tstt;
  419. vec_t<T,4,01012> const yxyz, grgb, tstp;
  420. vec_t<T,4,01020> const yxzx, grbr, tsps;
  421. vec_t<T,4,01021> const yxzy, grbg, tspt;
  422. vec_t<T,4,01022> const yxzz, grbb, tspp;
  423. vec_t<T,4,01100> const yyxx, ggrr, ttss;
  424. vec_t<T,4,01101> const yyxy, ggrg, ttst;
  425. vec_t<T,4,01102> const yyxz, ggrb, ttsp;
  426. vec_t<T,4,01110> const yyyx, gggr, ttts;
  427. vec_t<T,4,01111> const yyyy, gggg, tttt;
  428. vec_t<T,4,01112> const yyyz, gggb, tttp;
  429. vec_t<T,4,01120> const yyzx, ggbr, ttps;
  430. vec_t<T,4,01121> const yyzy, ggbg, ttpt;
  431. vec_t<T,4,01122> const yyzz, ggbb, ttpp;
  432. vec_t<T,4,01200> const yzxx, gbrr, tpss;
  433. vec_t<T,4,01201> const yzxy, gbrg, tpst;
  434. vec_t<T,4,01202> const yzxz, gbrb, tpsp;
  435. vec_t<T,4,01210> const yzyx, gbgr, tpts;
  436. vec_t<T,4,01211> const yzyy, gbgg, tptt;
  437. vec_t<T,4,01212> const yzyz, gbgb, tptp;
  438. vec_t<T,4,01220> const yzzx, gbbr, tpps;
  439. vec_t<T,4,01221> const yzzy, gbbg, tppt;
  440. vec_t<T,4,01222> const yzzz, gbbb, tppp;
  441. vec_t<T,4,02000> const zxxx, brrr, psss;
  442. vec_t<T,4,02001> const zxxy, brrg, psst;
  443. vec_t<T,4,02002> const zxxz, brrb, pssp;
  444. vec_t<T,4,02010> const zxyx, brgr, psts;
  445. vec_t<T,4,02011> const zxyy, brgg, pstt;
  446. vec_t<T,4,02012> const zxyz, brgb, pstp;
  447. vec_t<T,4,02020> const zxzx, brbr, psps;
  448. vec_t<T,4,02021> const zxzy, brbg, pspt;
  449. vec_t<T,4,02022> const zxzz, brbb, pspp;
  450. vec_t<T,4,02100> const zyxx, bgrr, ptss;
  451. vec_t<T,4,02101> const zyxy, bgrg, ptst;
  452. vec_t<T,4,02102> const zyxz, bgrb, ptsp;
  453. vec_t<T,4,02110> const zyyx, bggr, ptts;
  454. vec_t<T,4,02111> const zyyy, bggg, pttt;
  455. vec_t<T,4,02112> const zyyz, bggb, pttp;
  456. vec_t<T,4,02120> const zyzx, bgbr, ptps;
  457. vec_t<T,4,02121> const zyzy, bgbg, ptpt;
  458. vec_t<T,4,02122> const zyzz, bgbb, ptpp;
  459. vec_t<T,4,02200> const zzxx, bbrr, ppss;
  460. vec_t<T,4,02201> const zzxy, bbrg, ppst;
  461. vec_t<T,4,02202> const zzxz, bbrb, ppsp;
  462. vec_t<T,4,02210> const zzyx, bbgr, ppts;
  463. vec_t<T,4,02211> const zzyy, bbgg, pptt;
  464. vec_t<T,4,02212> const zzyz, bbgb, pptp;
  465. vec_t<T,4,02220> const zzzx, bbbr, ppps;
  466. vec_t<T,4,02221> const zzzy, bbbg, pppt;
  467. vec_t<T,4,02222> const zzzz, bbbb, pppp;
  468. #endif
  469. T m_data[count];
  470. };
  471. };
  472. /*
  473. * 4-element vectors
  474. */
  475. template <typename T>
  476. struct [[nodiscard]] vec_t<T,4>
  477. : public swizzle_ops::base<T>
  478. {
  479. static int const count = 4;
  480. typedef T scalar_element;
  481. typedef T element;
  482. typedef vec_t<T,4> type;
  483. // Default constructor, copy constructor, and destructor
  484. inline constexpr vec_t() = default;
  485. inline constexpr vec_t(type const &v) = default;
  486. inline ~vec_t() = default;
  487. /* Implicit constructor for swizzling */
  488. template<int SWIZZLE>
  489. inline constexpr vec_t(vec_t<T, 4, SWIZZLE> const &v)
  490. : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
  491. /* Explicit constructor for type conversion */
  492. template<typename U, int SWIZZLE>
  493. explicit inline constexpr vec_t(vec_t<U, 4, SWIZZLE> const &v)
  494. : x(T(v[0])), y(T(v[1])), z(T(v[2])), w(T(v[3])) {}
  495. /* Constructor for initializer_list. We need these ugly
  496. * loops until C++ lets us initialize m_data directly. */
  497. inline vec_t(std::initializer_list<element> const &list)
  498. {
  499. auto l = list.begin();
  500. for (int i = 0; i < count && l != list.end(); ++i, ++l)
  501. m_data[i] = *l;
  502. for (int i = (int)list.size(); i < count; ++i)
  503. m_data[i] = T(0);
  504. }
  505. /* Various explicit constructors */
  506. explicit inline constexpr vec_t(T X)
  507. : x(X), y(X), z(X), w(X) {}
  508. explicit inline constexpr vec_t(T X, T Y, T Z, T W)
  509. : x(X), y(Y), z(Z), w(W) {}
  510. explicit inline constexpr vec_t(vec_t<T,2> XY, T Z, T W)
  511. : x(XY.x), y(XY.y), z(Z), w(W) {}
  512. explicit inline constexpr vec_t(T X, vec_t<T,2> YZ, T W)
  513. : x(X), y(YZ.x), z(YZ.y), w(W) {}
  514. explicit inline constexpr vec_t(T X, T Y, vec_t<T,2> ZW)
  515. : x(X), y(Y), z(ZW.x), w(ZW.y) {}
  516. explicit inline constexpr vec_t(vec_t<T,2> XY, vec_t<T,2> ZW)
  517. : x(XY.x), y(XY.y), z(ZW.x), w(ZW.y) {}
  518. explicit inline constexpr vec_t(vec_t<T,3> XYZ, T W)
  519. : x(XYZ.x), y(XYZ.y), z(XYZ.z), w(W) {}
  520. explicit inline constexpr vec_t(T X, vec_t<T,3> YZW)
  521. : x(X), y(YZW.x), z(YZW.y), w(YZW.z) {}
  522. /* Factory for base axis vectors, e.g. [1,0,0,…,0] */
  523. static inline vec_t<T,4> axis(int i)
  524. {
  525. assert(i >= 0);
  526. assert(i < 4);
  527. return vec_t<T,4>(T(i == 0), T(i == 1), T(i == 2), T(i == 3));
  528. }
  529. LOL_COMMON_MEMBER_OPS(x)
  530. static const vec_t<T,4> zero;
  531. static const vec_t<T,4> axis_x;
  532. static const vec_t<T,4> axis_y;
  533. static const vec_t<T,4> axis_z;
  534. static const vec_t<T,4> axis_w;
  535. union
  536. {
  537. struct { T x, y, z, w; }; /* axis */
  538. struct { T r, g, b, a; }; /* red, green, blue, alpha */
  539. struct { T s, t, p, q; };
  540. #if !_DOXYGEN_SKIP_ME
  541. vec_t<T,2,000> const xx, rr, ss;
  542. vec_t<T,2,001> const xy, rg, st;
  543. vec_t<T,2,002> const xz, rb, sp;
  544. vec_t<T,2,003> const xw, ra, sq;
  545. vec_t<T,2,010> const yx, gr, ts;
  546. vec_t<T,2,011> const yy, gg, tt;
  547. vec_t<T,2,012> const yz, gb, tp;
  548. vec_t<T,2,013> const yw, ga, tq;
  549. vec_t<T,2,020> const zx, br, ps;
  550. vec_t<T,2,021> const zy, bg, pt;
  551. vec_t<T,2,022> const zz, bb, pp;
  552. vec_t<T,2,023> const zw, ba, pq;
  553. vec_t<T,2,030> const wx, ar, qs;
  554. vec_t<T,2,031> const wy, ag, qt;
  555. vec_t<T,2,032> const wz, ab, qp;
  556. vec_t<T,2,033> const ww, aa, qq;
  557. vec_t<T,3,0000> const xxx, rrr, sss;
  558. vec_t<T,3,0001> const xxy, rrg, sst;
  559. vec_t<T,3,0002> const xxz, rrb, ssp;
  560. vec_t<T,3,0003> const xxw, rra, ssq;
  561. vec_t<T,3,0010> const xyx, rgr, sts;
  562. vec_t<T,3,0011> const xyy, rgg, stt;
  563. vec_t<T,3,0012> const xyz, rgb, stp;
  564. vec_t<T,3,0013> const xyw, rga, stq;
  565. vec_t<T,3,0020> const xzx, rbr, sps;
  566. vec_t<T,3,0021> const xzy, rbg, spt;
  567. vec_t<T,3,0022> const xzz, rbb, spp;
  568. vec_t<T,3,0023> const xzw, rba, spq;
  569. vec_t<T,3,0030> const xwx, rar, sqs;
  570. vec_t<T,3,0031> const xwy, rag, sqt;
  571. vec_t<T,3,0032> const xwz, rab, sqp;
  572. vec_t<T,3,0033> const xww, raa, sqq;
  573. vec_t<T,3,0100> const yxx, grr, tss;
  574. vec_t<T,3,0101> const yxy, grg, tst;
  575. vec_t<T,3,0102> const yxz, grb, tsp;
  576. vec_t<T,3,0103> const yxw, gra, tsq;
  577. vec_t<T,3,0110> const yyx, ggr, tts;
  578. vec_t<T,3,0111> const yyy, ggg, ttt;
  579. vec_t<T,3,0112> const yyz, ggb, ttp;
  580. vec_t<T,3,0113> const yyw, gga, ttq;
  581. vec_t<T,3,0120> const yzx, gbr, tps;
  582. vec_t<T,3,0121> const yzy, gbg, tpt;
  583. vec_t<T,3,0122> const yzz, gbb, tpp;
  584. vec_t<T,3,0123> const yzw, gba, tpq;
  585. vec_t<T,3,0130> const ywx, gar, tqs;
  586. vec_t<T,3,0131> const ywy, gag, tqt;
  587. vec_t<T,3,0132> const ywz, gab, tqp;
  588. vec_t<T,3,0133> const yww, gaa, tqq;
  589. vec_t<T,3,0200> const zxx, brr, pss;
  590. vec_t<T,3,0201> const zxy, brg, pst;
  591. vec_t<T,3,0202> const zxz, brb, psp;
  592. vec_t<T,3,0203> const zxw, bra, psq;
  593. vec_t<T,3,0210> const zyx, bgr, pts;
  594. vec_t<T,3,0211> const zyy, bgg, ptt;
  595. vec_t<T,3,0212> const zyz, bgb, ptp;
  596. vec_t<T,3,0213> const zyw, bga, ptq;
  597. vec_t<T,3,0220> const zzx, bbr, pps;
  598. vec_t<T,3,0221> const zzy, bbg, ppt;
  599. vec_t<T,3,0222> const zzz, bbb, ppp;
  600. vec_t<T,3,0223> const zzw, bba, ppq;
  601. vec_t<T,3,0230> const zwx, bar, pqs;
  602. vec_t<T,3,0231> const zwy, bag, pqt;
  603. vec_t<T,3,0232> const zwz, bab, pqp;
  604. vec_t<T,3,0233> const zww, baa, pqq;
  605. vec_t<T,3,0300> const wxx, arr, qss;
  606. vec_t<T,3,0301> const wxy, arg, qst;
  607. vec_t<T,3,0302> const wxz, arb, qsp;
  608. vec_t<T,3,0303> const wxw, ara, qsq;
  609. vec_t<T,3,0310> const wyx, agr, qts;
  610. vec_t<T,3,0311> const wyy, agg, qtt;
  611. vec_t<T,3,0312> const wyz, agb, qtp;
  612. vec_t<T,3,0313> const wyw, aga, qtq;
  613. vec_t<T,3,0320> const wzx, abr, qps;
  614. vec_t<T,3,0321> const wzy, abg, qpt;
  615. vec_t<T,3,0322> const wzz, abb, qpp;
  616. vec_t<T,3,0323> const wzw, aba, qpq;
  617. vec_t<T,3,0330> const wwx, aar, qqs;
  618. vec_t<T,3,0331> const wwy, aag, qqt;
  619. vec_t<T,3,0332> const wwz, aab, qqp;
  620. vec_t<T,3,0333> const www, aaa, qqq;
  621. vec_t<T,4,00000> const xxxx, rrrr, ssss;
  622. vec_t<T,4,00001> const xxxy, rrrg, ssst;
  623. vec_t<T,4,00002> const xxxz, rrrb, sssp;
  624. vec_t<T,4,00003> const xxxw, rrra, sssq;
  625. vec_t<T,4,00010> const xxyx, rrgr, ssts;
  626. vec_t<T,4,00011> const xxyy, rrgg, sstt;
  627. vec_t<T,4,00012> const xxyz, rrgb, sstp;
  628. vec_t<T,4,00013> const xxyw, rrga, sstq;
  629. vec_t<T,4,00020> const xxzx, rrbr, ssps;
  630. vec_t<T,4,00021> const xxzy, rrbg, sspt;
  631. vec_t<T,4,00022> const xxzz, rrbb, sspp;
  632. vec_t<T,4,00023> const xxzw, rrba, sspq;
  633. vec_t<T,4,00030> const xxwx, rrar, ssqs;
  634. vec_t<T,4,00031> const xxwy, rrag, ssqt;
  635. vec_t<T,4,00032> const xxwz, rrab, ssqp;
  636. vec_t<T,4,00033> const xxww, rraa, ssqq;
  637. vec_t<T,4,00100> const xyxx, rgrr, stss;
  638. vec_t<T,4,00101> const xyxy, rgrg, stst;
  639. vec_t<T,4,00102> const xyxz, rgrb, stsp;
  640. vec_t<T,4,00103> const xyxw, rgra, stsq;
  641. vec_t<T,4,00110> const xyyx, rggr, stts;
  642. vec_t<T,4,00111> const xyyy, rggg, sttt;
  643. vec_t<T,4,00112> const xyyz, rggb, sttp;
  644. vec_t<T,4,00113> const xyyw, rgga, sttq;
  645. vec_t<T,4,00120> const xyzx, rgbr, stps;
  646. vec_t<T,4,00121> const xyzy, rgbg, stpt;
  647. vec_t<T,4,00122> const xyzz, rgbb, stpp;
  648. vec_t<T,4,00123> const xyzw, rgba, stpq;
  649. vec_t<T,4,00130> const xywx, rgar, stqs;
  650. vec_t<T,4,00131> const xywy, rgag, stqt;
  651. vec_t<T,4,00132> const xywz, rgab, stqp;
  652. vec_t<T,4,00133> const xyww, rgaa, stqq;
  653. vec_t<T,4,00200> const xzxx, rbrr, spss;
  654. vec_t<T,4,00201> const xzxy, rbrg, spst;
  655. vec_t<T,4,00202> const xzxz, rbrb, spsp;
  656. vec_t<T,4,00203> const xzxw, rbra, spsq;
  657. vec_t<T,4,00210> const xzyx, rbgr, spts;
  658. vec_t<T,4,00211> const xzyy, rbgg, sptt;
  659. vec_t<T,4,00212> const xzyz, rbgb, sptp;
  660. vec_t<T,4,00213> const xzyw, rbga, sptq;
  661. vec_t<T,4,00220> const xzzx, rbbr, spps;
  662. vec_t<T,4,00221> const xzzy, rbbg, sppt;
  663. vec_t<T,4,00222> const xzzz, rbbb, sppp;
  664. vec_t<T,4,00223> const xzzw, rbba, sppq;
  665. vec_t<T,4,00230> const xzwx, rbar, spqs;
  666. vec_t<T,4,00231> const xzwy, rbag, spqt;
  667. vec_t<T,4,00232> const xzwz, rbab, spqp;
  668. vec_t<T,4,00233> const xzww, rbaa, spqq;
  669. vec_t<T,4,00300> const xwxx, rarr, sqss;
  670. vec_t<T,4,00301> const xwxy, rarg, sqst;
  671. vec_t<T,4,00302> const xwxz, rarb, sqsp;
  672. vec_t<T,4,00303> const xwxw, rara, sqsq;
  673. vec_t<T,4,00310> const xwyx, ragr, sqts;
  674. vec_t<T,4,00311> const xwyy, ragg, sqtt;
  675. vec_t<T,4,00312> const xwyz, ragb, sqtp;
  676. vec_t<T,4,00313> const xwyw, raga, sqtq;
  677. vec_t<T,4,00320> const xwzx, rabr, sqps;
  678. vec_t<T,4,00321> const xwzy, rabg, sqpt;
  679. vec_t<T,4,00322> const xwzz, rabb, sqpp;
  680. vec_t<T,4,00323> const xwzw, raba, sqpq;
  681. vec_t<T,4,00330> const xwwx, raar, sqqs;
  682. vec_t<T,4,00331> const xwwy, raag, sqqt;
  683. vec_t<T,4,00332> const xwwz, raab, sqqp;
  684. vec_t<T,4,00333> const xwww, raaa, sqqq;
  685. vec_t<T,4,01000> const yxxx, grrr, tsss;
  686. vec_t<T,4,01001> const yxxy, grrg, tsst;
  687. vec_t<T,4,01002> const yxxz, grrb, tssp;
  688. vec_t<T,4,01003> const yxxw, grra, tssq;
  689. vec_t<T,4,01010> const yxyx, grgr, tsts;
  690. vec_t<T,4,01011> const yxyy, grgg, tstt;
  691. vec_t<T,4,01012> const yxyz, grgb, tstp;
  692. vec_t<T,4,01013> const yxyw, grga, tstq;
  693. vec_t<T,4,01020> const yxzx, grbr, tsps;
  694. vec_t<T,4,01021> const yxzy, grbg, tspt;
  695. vec_t<T,4,01022> const yxzz, grbb, tspp;
  696. vec_t<T,4,01023> const yxzw, grba, tspq;
  697. vec_t<T,4,01030> const yxwx, grar, tsqs;
  698. vec_t<T,4,01031> const yxwy, grag, tsqt;
  699. vec_t<T,4,01032> const yxwz, grab, tsqp;
  700. vec_t<T,4,01033> const yxww, graa, tsqq;
  701. vec_t<T,4,01100> const yyxx, ggrr, ttss;
  702. vec_t<T,4,01101> const yyxy, ggrg, ttst;
  703. vec_t<T,4,01102> const yyxz, ggrb, ttsp;
  704. vec_t<T,4,01103> const yyxw, ggra, ttsq;
  705. vec_t<T,4,01110> const yyyx, gggr, ttts;
  706. vec_t<T,4,01111> const yyyy, gggg, tttt;
  707. vec_t<T,4,01112> const yyyz, gggb, tttp;
  708. vec_t<T,4,01113> const yyyw, ggga, tttq;
  709. vec_t<T,4,01120> const yyzx, ggbr, ttps;
  710. vec_t<T,4,01121> const yyzy, ggbg, ttpt;
  711. vec_t<T,4,01122> const yyzz, ggbb, ttpp;
  712. vec_t<T,4,01123> const yyzw, ggba, ttpq;
  713. vec_t<T,4,01130> const yywx, ggar, ttqs;
  714. vec_t<T,4,01131> const yywy, ggag, ttqt;
  715. vec_t<T,4,01132> const yywz, ggab, ttqp;
  716. vec_t<T,4,01133> const yyww, ggaa, ttqq;
  717. vec_t<T,4,01200> const yzxx, gbrr, tpss;
  718. vec_t<T,4,01201> const yzxy, gbrg, tpst;
  719. vec_t<T,4,01202> const yzxz, gbrb, tpsp;
  720. vec_t<T,4,01203> const yzxw, gbra, tpsq;
  721. vec_t<T,4,01210> const yzyx, gbgr, tpts;
  722. vec_t<T,4,01211> const yzyy, gbgg, tptt;
  723. vec_t<T,4,01212> const yzyz, gbgb, tptp;
  724. vec_t<T,4,01213> const yzyw, gbga, tptq;
  725. vec_t<T,4,01220> const yzzx, gbbr, tpps;
  726. vec_t<T,4,01221> const yzzy, gbbg, tppt;
  727. vec_t<T,4,01222> const yzzz, gbbb, tppp;
  728. vec_t<T,4,01223> const yzzw, gbba, tppq;
  729. vec_t<T,4,01230> const yzwx, gbar, tpqs;
  730. vec_t<T,4,01231> const yzwy, gbag, tpqt;
  731. vec_t<T,4,01232> const yzwz, gbab, tpqp;
  732. vec_t<T,4,01233> const yzww, gbaa, tpqq;
  733. vec_t<T,4,01300> const ywxx, garr, tqss;
  734. vec_t<T,4,01301> const ywxy, garg, tqst;
  735. vec_t<T,4,01302> const ywxz, garb, tqsp;
  736. vec_t<T,4,01303> const ywxw, gara, tqsq;
  737. vec_t<T,4,01310> const ywyx, gagr, tqts;
  738. vec_t<T,4,01311> const ywyy, gagg, tqtt;
  739. vec_t<T,4,01312> const ywyz, gagb, tqtp;
  740. vec_t<T,4,01313> const ywyw, gaga, tqtq;
  741. vec_t<T,4,01320> const ywzx, gabr, tqps;
  742. vec_t<T,4,01321> const ywzy, gabg, tqpt;
  743. vec_t<T,4,01322> const ywzz, gabb, tqpp;
  744. vec_t<T,4,01323> const ywzw, gaba, tqpq;
  745. vec_t<T,4,01330> const ywwx, gaar, tqqs;
  746. vec_t<T,4,01331> const ywwy, gaag, tqqt;
  747. vec_t<T,4,01332> const ywwz, gaab, tqqp;
  748. vec_t<T,4,01333> const ywww, gaaa, tqqq;
  749. vec_t<T,4,02000> const zxxx, brrr, psss;
  750. vec_t<T,4,02001> const zxxy, brrg, psst;
  751. vec_t<T,4,02002> const zxxz, brrb, pssp;
  752. vec_t<T,4,02003> const zxxw, brra, pssq;
  753. vec_t<T,4,02010> const zxyx, brgr, psts;
  754. vec_t<T,4,02011> const zxyy, brgg, pstt;
  755. vec_t<T,4,02012> const zxyz, brgb, pstp;
  756. vec_t<T,4,02013> const zxyw, brga, pstq;
  757. vec_t<T,4,02020> const zxzx, brbr, psps;
  758. vec_t<T,4,02021> const zxzy, brbg, pspt;
  759. vec_t<T,4,02022> const zxzz, brbb, pspp;
  760. vec_t<T,4,02023> const zxzw, brba, pspq;
  761. vec_t<T,4,02030> const zxwx, brar, psqs;
  762. vec_t<T,4,02031> const zxwy, brag, psqt;
  763. vec_t<T,4,02032> const zxwz, brab, psqp;
  764. vec_t<T,4,02033> const zxww, braa, psqq;
  765. vec_t<T,4,02100> const zyxx, bgrr, ptss;
  766. vec_t<T,4,02101> const zyxy, bgrg, ptst;
  767. vec_t<T,4,02102> const zyxz, bgrb, ptsp;
  768. vec_t<T,4,02103> const zyxw, bgra, ptsq;
  769. vec_t<T,4,02110> const zyyx, bggr, ptts;
  770. vec_t<T,4,02111> const zyyy, bggg, pttt;
  771. vec_t<T,4,02112> const zyyz, bggb, pttp;
  772. vec_t<T,4,02113> const zyyw, bgga, pttq;
  773. vec_t<T,4,02120> const zyzx, bgbr, ptps;
  774. vec_t<T,4,02121> const zyzy, bgbg, ptpt;
  775. vec_t<T,4,02122> const zyzz, bgbb, ptpp;
  776. vec_t<T,4,02123> const zyzw, bgba, ptpq;
  777. vec_t<T,4,02130> const zywx, bgar, ptqs;
  778. vec_t<T,4,02131> const zywy, bgag, ptqt;
  779. vec_t<T,4,02132> const zywz, bgab, ptqp;
  780. vec_t<T,4,02133> const zyww, bgaa, ptqq;
  781. vec_t<T,4,02200> const zzxx, bbrr, ppss;
  782. vec_t<T,4,02201> const zzxy, bbrg, ppst;
  783. vec_t<T,4,02202> const zzxz, bbrb, ppsp;
  784. vec_t<T,4,02203> const zzxw, bbra, ppsq;
  785. vec_t<T,4,02210> const zzyx, bbgr, ppts;
  786. vec_t<T,4,02211> const zzyy, bbgg, pptt;
  787. vec_t<T,4,02212> const zzyz, bbgb, pptp;
  788. vec_t<T,4,02213> const zzyw, bbga, pptq;
  789. vec_t<T,4,02220> const zzzx, bbbr, ppps;
  790. vec_t<T,4,02221> const zzzy, bbbg, pppt;
  791. vec_t<T,4,02222> const zzzz, bbbb, pppp;
  792. vec_t<T,4,02223> const zzzw, bbba, pppq;
  793. vec_t<T,4,02230> const zzwx, bbar, ppqs;
  794. vec_t<T,4,02231> const zzwy, bbag, ppqt;
  795. vec_t<T,4,02232> const zzwz, bbab, ppqp;
  796. vec_t<T,4,02233> const zzww, bbaa, ppqq;
  797. vec_t<T,4,02300> const zwxx, barr, pqss;
  798. vec_t<T,4,02301> const zwxy, barg, pqst;
  799. vec_t<T,4,02302> const zwxz, barb, pqsp;
  800. vec_t<T,4,02303> const zwxw, bara, pqsq;
  801. vec_t<T,4,02310> const zwyx, bagr, pqts;
  802. vec_t<T,4,02311> const zwyy, bagg, pqtt;
  803. vec_t<T,4,02312> const zwyz, bagb, pqtp;
  804. vec_t<T,4,02313> const zwyw, baga, pqtq;
  805. vec_t<T,4,02320> const zwzx, babr, pqps;
  806. vec_t<T,4,02321> const zwzy, babg, pqpt;
  807. vec_t<T,4,02322> const zwzz, babb, pqpp;
  808. vec_t<T,4,02323> const zwzw, baba, pqpq;
  809. vec_t<T,4,02330> const zwwx, baar, pqqs;
  810. vec_t<T,4,02331> const zwwy, baag, pqqt;
  811. vec_t<T,4,02332> const zwwz, baab, pqqp;
  812. vec_t<T,4,02333> const zwww, baaa, pqqq;
  813. vec_t<T,4,03000> const wxxx, arrr, qsss;
  814. vec_t<T,4,03001> const wxxy, arrg, qsst;
  815. vec_t<T,4,03002> const wxxz, arrb, qssp;
  816. vec_t<T,4,03003> const wxxw, arra, qssq;
  817. vec_t<T,4,03010> const wxyx, argr, qsts;
  818. vec_t<T,4,03011> const wxyy, argg, qstt;
  819. vec_t<T,4,03012> const wxyz, argb, qstp;
  820. vec_t<T,4,03013> const wxyw, arga, qstq;
  821. vec_t<T,4,03020> const wxzx, arbr, qsps;
  822. vec_t<T,4,03021> const wxzy, arbg, qspt;
  823. vec_t<T,4,03022> const wxzz, arbb, qspp;
  824. vec_t<T,4,03023> const wxzw, arba, qspq;
  825. vec_t<T,4,03030> const wxwx, arar, qsqs;
  826. vec_t<T,4,03031> const wxwy, arag, qsqt;
  827. vec_t<T,4,03032> const wxwz, arab, qsqp;
  828. vec_t<T,4,03033> const wxww, araa, qsqq;
  829. vec_t<T,4,03100> const wyxx, agrr, qtss;
  830. vec_t<T,4,03101> const wyxy, agrg, qtst;
  831. vec_t<T,4,03102> const wyxz, agrb, qtsp;
  832. vec_t<T,4,03103> const wyxw, agra, qtsq;
  833. vec_t<T,4,03110> const wyyx, aggr, qtts;
  834. vec_t<T,4,03111> const wyyy, aggg, qttt;
  835. vec_t<T,4,03112> const wyyz, aggb, qttp;
  836. vec_t<T,4,03113> const wyyw, agga, qttq;
  837. vec_t<T,4,03120> const wyzx, agbr, qtps;
  838. vec_t<T,4,03121> const wyzy, agbg, qtpt;
  839. vec_t<T,4,03122> const wyzz, agbb, qtpp;
  840. vec_t<T,4,03123> const wyzw, agba, qtpq;
  841. vec_t<T,4,03130> const wywx, agar, qtqs;
  842. vec_t<T,4,03131> const wywy, agag, qtqt;
  843. vec_t<T,4,03132> const wywz, agab, qtqp;
  844. vec_t<T,4,03133> const wyww, agaa, qtqq;
  845. vec_t<T,4,03200> const wzxx, abrr, qpss;
  846. vec_t<T,4,03201> const wzxy, abrg, qpst;
  847. vec_t<T,4,03202> const wzxz, abrb, qpsp;
  848. vec_t<T,4,03203> const wzxw, abra, qpsq;
  849. vec_t<T,4,03210> const wzyx, abgr, qpts;
  850. vec_t<T,4,03211> const wzyy, abgg, qptt;
  851. vec_t<T,4,03212> const wzyz, abgb, qptp;
  852. vec_t<T,4,03213> const wzyw, abga, qptq;
  853. vec_t<T,4,03220> const wzzx, abbr, qpps;
  854. vec_t<T,4,03221> const wzzy, abbg, qppt;
  855. vec_t<T,4,03222> const wzzz, abbb, qppp;
  856. vec_t<T,4,03223> const wzzw, abba, qppq;
  857. vec_t<T,4,03230> const wzwx, abar, qpqs;
  858. vec_t<T,4,03231> const wzwy, abag, qpqt;
  859. vec_t<T,4,03232> const wzwz, abab, qpqp;
  860. vec_t<T,4,03233> const wzww, abaa, qpqq;
  861. vec_t<T,4,03300> const wwxx, aarr, qqss;
  862. vec_t<T,4,03301> const wwxy, aarg, qqst;
  863. vec_t<T,4,03302> const wwxz, aarb, qqsp;
  864. vec_t<T,4,03303> const wwxw, aara, qqsq;
  865. vec_t<T,4,03310> const wwyx, aagr, qqts;
  866. vec_t<T,4,03311> const wwyy, aagg, qqtt;
  867. vec_t<T,4,03312> const wwyz, aagb, qqtp;
  868. vec_t<T,4,03313> const wwyw, aaga, qqtq;
  869. vec_t<T,4,03320> const wwzx, aabr, qqps;
  870. vec_t<T,4,03321> const wwzy, aabg, qqpt;
  871. vec_t<T,4,03322> const wwzz, aabb, qqpp;
  872. vec_t<T,4,03323> const wwzw, aaba, qqpq;
  873. vec_t<T,4,03330> const wwwx, aaar, qqqs;
  874. vec_t<T,4,03331> const wwwy, aaag, qqqt;
  875. vec_t<T,4,03332> const wwwz, aaab, qqqp;
  876. vec_t<T,4,03333> const wwww, aaaa, qqqq;
  877. #endif
  878. T m_data[count];
  879. };
  880. };
  881. /*
  882. * stdstream method implementation
  883. */
  884. template<typename U, int N, int SWIZZLE = FULL_SWIZZLE>
  885. std::ostream &operator<<(std::ostream &stream, vec_t<U,N> const &v)
  886. {
  887. stream << '(';
  888. for (int i = 0; i < N; ++i)
  889. stream << v[i] << (i == N - 1 ? ")" : ", ");
  890. return stream;
  891. }
  892. /*
  893. * vec_t *(scalar, vec_t)
  894. */
  895. template<typename T, int N, int SWIZZLE>
  896. static inline typename std::enable_if<SWIZZLE != FULL_SWIZZLE, vec_t<T,N>>::type
  897. operator *(T const &val, vec_t<T,N,SWIZZLE> const &a)
  898. {
  899. vec_t<T,N> ret;
  900. for (int i = 0; i < N; ++i)
  901. ret[i] = val * a[i];
  902. return ret;
  903. }
  904. /*
  905. * vec_t min|max|fmod(vec_t, vec_t|scalar)
  906. * vec_t min|max|fmod(scalar, vec_t)
  907. */
  908. #define LOL_SWIZZLE_V_VV_FUN(fun) \
  909. template<typename T, int N, int SWIZZLE1, int SWIZZLE2> \
  910. inline vec_t<T,N> fun(vec_t<T,N,SWIZZLE1> const &a, \
  911. vec_t<T,N,SWIZZLE2> const &b) \
  912. { \
  913. using std::fun; \
  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. using std::fun; \
  924. vec_t<T,N> ret; \
  925. for (int i = 0; i < N; ++i) \
  926. ret[i] = fun(a[i], b); \
  927. return ret; \
  928. } \
  929. \
  930. template<typename T, int N, int SWIZZLE> \
  931. inline vec_t<T,N> fun(T const &a, vec_t<T,N,SWIZZLE> const &b) \
  932. { \
  933. using std::fun; \
  934. vec_t<T,N> ret; \
  935. for (int i = 0; i < N; ++i) \
  936. ret[i] = fun(a, b[i]); \
  937. return ret; \
  938. }
  939. LOL_SWIZZLE_V_VV_FUN(min)
  940. LOL_SWIZZLE_V_VV_FUN(max)
  941. LOL_SWIZZLE_V_VV_FUN(fmod)
  942. #undef LOL_SWIZZLE_V_VV_FUN
  943. /*
  944. * vec_t clamp(vec_t, vec_t, vec_t)
  945. * vec_t clamp(vec_t, scalar, vec_t)
  946. * vec_t clamp(vec_t, vec_t, scalar)
  947. * vec_t clamp(vec_t, scalar, scalar)
  948. */
  949. template<typename T, int N, int SWIZZLE1, int SWIZZLE2, int SWIZZLE3>
  950. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  951. vec_t<T,N,SWIZZLE2> const &a,
  952. vec_t<T,N,SWIZZLE3> const &b)
  953. {
  954. return max(min(x, b), a);
  955. }
  956. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  957. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  958. T const &a,
  959. vec_t<T,N,SWIZZLE2> const &b)
  960. {
  961. return max(min(x, b), a);
  962. }
  963. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  964. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  965. vec_t<T,N,SWIZZLE2> const &a,
  966. T const &b)
  967. {
  968. return max(min(x, b), a);
  969. }
  970. template<typename T, int N, int SWIZZLE1>
  971. static inline vec_t<T,N> clamp(vec_t<T,N,SWIZZLE1> const &x,
  972. T const &a,
  973. T const &b)
  974. {
  975. return max(min(x, b), a);
  976. }
  977. /*
  978. * vec_t mix(vec_t, vec_t, vec_t)
  979. * vec_t mix(vec_t, vec_t, scalar)
  980. */
  981. template<typename T, int N, int SWIZZLE1, int SWIZZLE2, int SWIZZLE3>
  982. static inline vec_t<T,N> mix(vec_t<T,N,SWIZZLE1> const &x,
  983. vec_t<T,N,SWIZZLE2> const &y,
  984. vec_t<T,N,SWIZZLE3> const &a)
  985. {
  986. return x + a * (y - x);
  987. }
  988. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  989. static inline vec_t<T,N> mix(vec_t<T,N,SWIZZLE1> const &x,
  990. vec_t<T,N,SWIZZLE2> const &y,
  991. T const &a)
  992. {
  993. return x + a * (y - x);
  994. }
  995. /*
  996. * Some GLSL-like functions.
  997. */
  998. template<typename T, int N, int SWIZZLE1, int SWIZZLE2> [[nodiscard]]
  999. static inline T dot(vec_t<T,N,SWIZZLE1> const &a,
  1000. vec_t<T,N,SWIZZLE2> const &b)
  1001. {
  1002. T ret(0);
  1003. for (int i = 0; i < N; ++i)
  1004. ret += a[i] * b[i];
  1005. return ret;
  1006. }
  1007. template<typename T, int N, int SWIZZLE> [[nodiscard]]
  1008. static inline T sqlength(vec_t<T,N,SWIZZLE> const &a)
  1009. {
  1010. return dot(a, a);
  1011. }
  1012. template<typename T, int N, int SWIZZLE> [[nodiscard]]
  1013. static inline T length(vec_t<T,N,SWIZZLE> const &a)
  1014. {
  1015. using std::sqrt;
  1016. /* FIXME: this is not very nice */
  1017. return T(sqrt(sqlength(a)));
  1018. }
  1019. template<typename T, int N, int SWIZZLE1, int SWIZZLE2>
  1020. static inline vec_t<T,N> lerp(vec_t<T,N,SWIZZLE1> const &a,
  1021. vec_t<T,N,SWIZZLE2> const &b,
  1022. T const &s)
  1023. {
  1024. vec_t<T,N> ret;
  1025. for (int i = 0; i < N; ++i)
  1026. ret[i] = a[i] + s * (b[i] - a[i]);
  1027. return ret;
  1028. }
  1029. template<typename T, int N, int SWIZZLE1, int SWIZZLE2> [[nodiscard]]
  1030. static inline T distance(vec_t<T,N,SWIZZLE1> const &a,
  1031. vec_t<T,N,SWIZZLE2> const &b)
  1032. {
  1033. return length(a - b);
  1034. }
  1035. template<typename T, int N, int SWIZZLE>
  1036. static inline vec_t<T,N> fract(vec_t<T,N,SWIZZLE> const &a)
  1037. {
  1038. vec_t<T,N> ret;
  1039. for (int i = 0; i < N; ++i)
  1040. ret[i] = fract(a[i]);
  1041. return ret;
  1042. }
  1043. template<typename T, int N, int SWIZZLE>
  1044. static inline vec_t<T,N> saturate(vec_t<T,N,SWIZZLE> const &a)
  1045. {
  1046. vec_t<T,N> ret;
  1047. for (int i = 0; i < N; ++i)
  1048. ret[i] = saturate(a[i]);
  1049. return ret;
  1050. }
  1051. template<typename T, int N, int SWIZZLE>
  1052. static inline vec_t<T,N> normalize(vec_t<T,N,SWIZZLE> const &a)
  1053. {
  1054. T norm = T(length(a));
  1055. return norm ? a / norm : vec_t<T,N>(T(0));
  1056. }
  1057. // We define fabs() because that’s the C++ std library uses for
  1058. // floating-point numbers, and abs() because GLSL does.
  1059. template<typename T, int N, int SWIZZLE>
  1060. static inline vec_t<T,N> fabs(vec_t<T,N,SWIZZLE> const &a)
  1061. {
  1062. using std::fabs;
  1063. vec_t<T,N> ret;
  1064. for (int i = 0; i < N; ++i)
  1065. ret[i] = fabs(a[i]);
  1066. return ret;
  1067. }
  1068. template<typename T, int N, int SWIZZLE>
  1069. static inline vec_t<T,N> abs(vec_t<T,N,SWIZZLE> const &a)
  1070. {
  1071. return fabs(a);
  1072. }
  1073. template<typename T, int N, int SWIZZLE>
  1074. static inline vec_t<T,N> degrees(vec_t<T,N,SWIZZLE> const &a)
  1075. {
  1076. vec_t<T,N> ret;
  1077. for (int i = 0; i < N; ++i)
  1078. ret[i] = degrees(a[i]);
  1079. return ret;
  1080. }
  1081. template<typename T, int N, int SWIZZLE>
  1082. static inline vec_t<T, N> radians(vec_t<T, N, SWIZZLE> const &a)
  1083. {
  1084. vec_t<T, N> ret;
  1085. for (int i = 0; i < N; ++i)
  1086. ret[i] = radians(a[i]);
  1087. return ret;
  1088. }
  1089. // Cartesian operation consider that you're in spherical coordinate
  1090. template<typename T, int SWIZZLE>
  1091. static inline vec_t<T, 2> cartesian(vec_t<T, 2, SWIZZLE> const &a)
  1092. {
  1093. using std::sin, std::cos;
  1094. vec_t<T, 2> ret;
  1095. ret.x = a[0] * cos(a[1]);
  1096. ret.y = a[0] * sin(a[1]);
  1097. return ret;
  1098. }
  1099. template<typename T, int SWIZZLE>
  1100. static inline vec_t<T, 3> cartesian(vec_t<T, 3, SWIZZLE> const &a)
  1101. {
  1102. using std::sin, std::cos;
  1103. vec_t<T, 3> ret;
  1104. ret.x = a[0] * sin(a[2]) * cos(a[1]);
  1105. ret.y = a[0] * cos(a[2]);
  1106. ret.z = a[0] * sin(a[2]) * sin(a[1]);
  1107. return ret;
  1108. }
  1109. // Spherical operation consider that you're in cartesian coordinate
  1110. template<typename T, int SWIZZLE>
  1111. static inline vec_t<T, 2> spherical(vec_t<T, 2, SWIZZLE> const &a)
  1112. {
  1113. vec_t<T, 2> ret;
  1114. ret[0] = sqlength(a);
  1115. ret[1] = atan2(a.y, a.x);
  1116. return ret;
  1117. }
  1118. template<typename T, int SWIZZLE>
  1119. static inline vec_t<T, 3> spherical(vec_t<T, 3, SWIZZLE> const &a)
  1120. {
  1121. using std::atan, std::acos;
  1122. vec_t<T, 3> ret;
  1123. ret[0] = sqlength(a);
  1124. ret[1] = atan(a.y / a.x);
  1125. ret[2] = acos(a.z / ret[0]);
  1126. return ret;
  1127. }
  1128. /*
  1129. * C++11 iterators
  1130. */
  1131. template<typename T, int N, int SWIZZLE>
  1132. class vec_const_iter
  1133. {
  1134. public:
  1135. inline vec_const_iter(vec_t<T,N,SWIZZLE> const &vec, int pos)
  1136. : m_vec(vec),
  1137. m_pos(pos)
  1138. { }
  1139. inline bool operator !=(vec_const_iter<T,N,SWIZZLE> const & that) const
  1140. {
  1141. return m_pos != that.m_pos;
  1142. }
  1143. template<int S = SWIZZLE>
  1144. inline typename std::enable_if<S != FULL_SWIZZLE, T const &>::type
  1145. operator *() const
  1146. {
  1147. return m_vec[m_pos];
  1148. }
  1149. template<int S = SWIZZLE>
  1150. inline typename std::enable_if<S == FULL_SWIZZLE, T const &>::type
  1151. operator *() const
  1152. {
  1153. return m_vec[m_pos];
  1154. }
  1155. inline vec_const_iter<T,N,SWIZZLE> & operator ++()
  1156. {
  1157. ++m_pos;
  1158. return *this;
  1159. }
  1160. private:
  1161. vec_t<T,N,SWIZZLE> const &m_vec;
  1162. int m_pos;
  1163. };
  1164. /* FIXME: do we need a non-const iterator? Looks almost useless to me,
  1165. * and a lot of hassle with swizzling. */
  1166. template<typename T, int N, int SWIZZLE>
  1167. inline vec_const_iter<T,N,SWIZZLE> begin(vec_t<T,N,SWIZZLE> const &a)
  1168. {
  1169. return vec_const_iter<T,N,SWIZZLE>(a, 0);
  1170. }
  1171. template<typename T, int N, int SWIZZLE>
  1172. inline vec_const_iter<T,N,SWIZZLE> end(vec_t<T,N,SWIZZLE> const &a)
  1173. {
  1174. return vec_const_iter<T,N,SWIZZLE>(a, N);
  1175. }
  1176. /*
  1177. * Constants
  1178. */
  1179. template<typename T, int N>
  1180. vec_t<T,N> const vec_t<T,N>::zero = vec_t<T,N>(T(0));
  1181. template<typename T>
  1182. vec_t<T,2> const vec_t<T,2>::zero = vec_t<T,2>(T(0));
  1183. template<typename T>
  1184. vec_t<T,3> const vec_t<T,3>::zero = vec_t<T,3>(T(0));
  1185. template<typename T>
  1186. vec_t<T,4> const vec_t<T,4>::zero = vec_t<T,4>(T(0));
  1187. template<typename T>
  1188. vec_t<T,2> const vec_t<T,2>::axis_x = vec_t<T,2>(T(1), T(0));
  1189. template<typename T>
  1190. vec_t<T,2> const vec_t<T,2>::axis_y = vec_t<T,2>(T(0), T(1));
  1191. template<typename T>
  1192. vec_t<T,3> const vec_t<T,3>::axis_x = vec_t<T,3>(T(1), T(0), T(0));
  1193. template<typename T>
  1194. vec_t<T,3> const vec_t<T,3>::axis_y = vec_t<T,3>(T(0), T(1), T(0));
  1195. template<typename T>
  1196. vec_t<T,3> const vec_t<T,3>::axis_z = vec_t<T,3>(T(0), T(0), T(1));
  1197. template<typename T>
  1198. vec_t<T,4> const vec_t<T,4>::axis_x = vec_t<T,4>(T(1), T(0), T(0), T(0));
  1199. template<typename T>
  1200. vec_t<T,4> const vec_t<T,4>::axis_y = vec_t<T,4>(T(0), T(1), T(0), T(0));
  1201. template<typename T>
  1202. vec_t<T,4> const vec_t<T,4>::axis_z = vec_t<T,4>(T(0), T(0), T(1), T(0));
  1203. template<typename T>
  1204. vec_t<T,4> const vec_t<T,4>::axis_w = vec_t<T,4>(T(0), T(0), T(0), T(1));
  1205. //
  1206. // Generic GLSL-like type names
  1207. //
  1208. #define T_(tleft, tright, suffix) \
  1209. typedef tleft half tright f16##suffix; \
  1210. typedef tleft float tright suffix; \
  1211. typedef tleft double tright d##suffix; \
  1212. typedef tleft ldouble tright f128##suffix; \
  1213. typedef tleft int8_t tright i8##suffix; \
  1214. typedef tleft uint8_t tright u8##suffix; \
  1215. typedef tleft int16_t tright i16##suffix; \
  1216. typedef tleft uint16_t tright u16##suffix; \
  1217. typedef tleft int32_t tright i##suffix; \
  1218. typedef tleft uint32_t tright u##suffix; \
  1219. typedef tleft int64_t tright i64##suffix; \
  1220. typedef tleft uint64_t tright u64##suffix; \
  1221. typedef tleft real tright r##suffix;
  1222. // Idiotic hack to put "," inside a macro argument
  1223. #define C_ ,
  1224. T_(vec_t<, C_ 2>, vec2)
  1225. T_(vec_t<, C_ 3>, vec3)
  1226. T_(vec_t<, C_ 4>, vec4)
  1227. T_(vec_t<, C_ 5>, vec5)
  1228. T_(vec_t<, C_ 6>, vec6)
  1229. T_(vec_t<, C_ 7>, vec7)
  1230. T_(vec_t<, C_ 8>, vec8)
  1231. T_(vec_t<, C_ 9>, vec9)
  1232. T_(vec_t<, C_ 10>, vec10)
  1233. T_(vec_t<, C_ 11>, vec11)
  1234. T_(vec_t<, C_ 12>, vec12)
  1235. #undef C_
  1236. #undef T_
  1237. static_assert(sizeof(i8vec2) == 2, "sizeof(i8vec2) == 2");
  1238. static_assert(sizeof(i16vec2) == 4, "sizeof(i16vec2) == 4");
  1239. static_assert(sizeof(ivec2) == 8, "sizeof(ivec2) == 8");
  1240. static_assert(sizeof(i64vec2) == 16, "sizeof(i64vec2) == 16");
  1241. static_assert(sizeof(vec2) == 8, "sizeof(vec2) == 8");
  1242. static_assert(sizeof(dvec2) == 16, "sizeof(dvec2) == 16");
  1243. static_assert(sizeof(i8vec3) == 3, "sizeof(i8vec3) == 3");
  1244. static_assert(sizeof(i16vec3) == 6, "sizeof(i16vec3) == 6");
  1245. static_assert(sizeof(ivec3) == 12, "sizeof(ivec3) == 12");
  1246. static_assert(sizeof(i64vec3) == 24, "sizeof(i64vec3) == 24");
  1247. static_assert(sizeof(vec3) == 12, "sizeof(vec3) == 12");
  1248. static_assert(sizeof(dvec3) == 24, "sizeof(dvec3) == 24");
  1249. static_assert(sizeof(i8vec4) == 4, "sizeof(i8vec4) == 4");
  1250. static_assert(sizeof(i16vec4) == 8, "sizeof(i16vec4) == 8");
  1251. static_assert(sizeof(ivec4) == 16, "sizeof(ivec4) == 16");
  1252. static_assert(sizeof(i64vec4) == 32, "sizeof(i64vec4) == 32");
  1253. static_assert(sizeof(vec4) == 16, "sizeof(vec4) == 16");
  1254. static_assert(sizeof(dvec4) == 32, "sizeof(dvec4) == 32");
  1255. //
  1256. // HLSL/Cg-compliant type names
  1257. //
  1258. typedef vec2 float2;
  1259. typedef vec3 float3;
  1260. typedef vec4 float4;
  1261. typedef vec5 float5;
  1262. typedef vec6 float6;
  1263. typedef vec7 float7;
  1264. typedef vec8 float8;
  1265. typedef vec9 float9;
  1266. typedef vec10 float10;
  1267. typedef vec11 float11;
  1268. typedef vec12 float12;
  1269. typedef f16vec2 half2;
  1270. typedef f16vec3 half3;
  1271. typedef f16vec4 half4;
  1272. typedef ivec2 int2;
  1273. typedef ivec3 int3;
  1274. typedef ivec4 int4;
  1275. typedef ivec5 int5;
  1276. typedef ivec6 int6;
  1277. typedef ivec7 int7;
  1278. typedef ivec8 int8;
  1279. typedef ivec9 int9;
  1280. typedef ivec10 int10;
  1281. typedef ivec11 int11;
  1282. typedef ivec12 int12;
  1283. } // namespace lol
  1284. #include "vector.ipp"