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

1326 line
46 KiB

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