46#if defined(_MSC_VER) && (_MSC_VER <= 1900)
47#define LINALG_CONSTEXPR14
49#define LINALG_CONSTEXPR14 constexpr
55template <
class T,
int M>
60template <
class T,
int M,
int N>
65template <
class T,
class U>
68template <
class T,
class U>
69using conv_t =
typename std::enable_if<!std::is_same<T, U>::value,
71 std::declval<U>()))>::type;
76template <
class T,
int M>
80template <
class T,
int M,
int N>
92constexpr bool operator==(
const ord<T>& o, std::nullptr_t) {
96constexpr bool operator!=(
const ord<T>& o, std::nullptr_t) {
100constexpr bool operator<(
const ord<T>& o, std::nullptr_t) {
104constexpr bool operator>(
const ord<T>& o, std::nullptr_t) {
108constexpr bool operator<=(
const ord<T>& o, std::nullptr_t) {
112constexpr bool operator>=(
const ord<T>& o, std::nullptr_t) {
117template <
class A,
class B>
130 return !(a.x == b.x) ?
ord<T>{a.x, b.x} :
ord<T>{a.y, b.y};
137 return !(a.x == b.x) ?
ord<T>{a.x, b.x}
138 : !(a.y == b.y) ?
ord<T>{a.y, b.y}
146 return !(a.x == b.x) ?
ord<T>{a.x, b.x}
147 : !(a.y == b.y) ?
ord<T>{a.y, b.y}
148 : !(a.z == b.z) ?
ord<T>{a.z, b.z}
152template <
class T,
int M>
157 return compare(a.x, b.x);
160template <
class T,
int M>
165 return a.x != b.x ? compare(a.x, b.x) : compare(a.y, b.y);
168template <
class T,
int M>
173 return a.x != b.x ? compare(a.x, b.x)
174 : a.y != b.y ? compare(a.y, b.y)
178template <
class T,
int M>
183 return a.x != b.x ? compare(a.x, b.x)
184 : a.y != b.y ? compare(a.y, b.y)
185 : a.z != b.z ? compare(a.z, b.z)
197 constexpr auto operator()(A& a)
const ->
decltype(a.x) {
204 constexpr auto operator()(A& a)
const ->
decltype(a.y) {
211 constexpr auto operator()(A& a)
const ->
decltype(a.z) {
218 constexpr auto operator()(A& a)
const ->
decltype(a.w) {
226template <
int A,
int N>
248template <
int A,
int B>
250template <
class T,
int M,
int... I>
254template <
class T,
int M,
int N,
int... I,
int... J>
255mat<T,
sizeof...(I),
sizeof...(J)>
constexpr swizzle(
const mat<T, M, N>& m,
261template <
class F,
class... T>
262using ret_t =
decltype(std::declval<F>()(std::declval<T>()...));
272template <
class T,
class... U>
273struct scalars<T, U...> : std::conditional<std::is_arithmetic<T>::value,
274 scalars<U...>, empty>::type {};
276using scalars_t =
typename scalars<T...>::type;
280template <
class F,
class Void,
class... T>
282template <
class F,
int M,
class A>
285 enum { size = M, mm = 0 };
291template <
class F,
int M,
class A,
class B>
294 enum { size = M, mm = 0 };
301template <
class F,
int M,
class A,
class B>
304 enum { size = M, mm = 0 };
310template <
class F,
int M,
class A,
class B>
313 enum { size = M, mm = 0 };
319template <
class F,
int M,
class A,
class B,
class C>
322 enum { size = M, mm = 0 };
329template <
class F,
int M,
class A,
class B,
class C>
332 enum { size = M, mm = 0 };
339template <
class F,
int M,
class A,
class B,
class C>
342 enum { size = M, mm = 0 };
349template <
class F,
int M,
class A,
class B,
class C>
352 enum { size = M, mm = 0 };
358template <
class F,
int M,
class A,
class B,
class C>
361 enum { size = M, mm = 0 };
368template <
class F,
int M,
class A,
class B,
class C>
371 enum { size = M, mm = 0 };
377template <
class F,
int M,
class A,
class B,
class C>
380 enum { size = M, mm = 0 };
386template <
class F,
int M,
int N,
class A>
389 enum { size = N, mm = 0 };
396template <
class F,
int M,
int N,
class A,
class B>
399 enum { size = N, mm = 1 };
407template <
class F,
int M,
int N,
class A,
class B>
410 enum { size = N, mm = 0 };
417template <
class F,
int M,
int N,
class A,
class B>
420 enum { size = N, mm = 0 };
427template <
class F,
class... A>
428struct apply<F, scalars_t<A...>, A...> {
429 using type = ret_t<F, A...>;
430 enum { size = 0, mm = 0 };
431 static constexpr type impl(
seq<>, F f, A... a) {
return f(a...); }
436 template <
class A,
class B>
437 constexpr auto operator()(A a, B b)
const ->
438 typename std::remove_reference<
decltype(a < b ? a : b)>::type {
439 return a < b ? a : b;
443 template <
class A,
class B>
444 constexpr auto operator()(A a, B b)
const ->
445 typename std::remove_reference<
decltype(a < b ? b : a)>::type {
446 return a < b ? b : a;
450 template <
class A,
class B,
class C>
451 constexpr auto operator()(A a, B b, C c)
const ->
452 typename std::remove_reference<
decltype(a < b ? b
455 return a < b ? b : a < c ? a : c;
459 template <
class A,
class B,
class C>
460 constexpr auto operator()(A a, B b, C c)
const ->
461 typename std::remove_reference<
decltype(a ? b : c)>::type {
466 template <
class A,
class B,
class C>
467 constexpr auto operator()(A a, B b, C c)
const
468 ->
decltype(a * (1 - c) + b * c) {
469 return a * (1 - c) + b * c;
476 constexpr auto operator()(A a)
const ->
decltype(+a) {
482 constexpr auto operator()(A a)
const ->
decltype(-a) {
488 constexpr auto operator()(A a)
const ->
decltype(!a) {
494 constexpr auto operator()(A a)
const ->
decltype(~(a)) {
499 template <
class A,
class B>
500 constexpr auto operator()(A a, B b)
const ->
decltype(a * b) {
505 template <
class A,
class B>
506 constexpr auto operator()(A a, B b)
const ->
decltype(a / b) {
511 template <
class A,
class B>
512 constexpr auto operator()(A a, B b)
const ->
decltype(a % b) {
517 template <
class A,
class B>
518 constexpr auto operator()(A a, B b)
const ->
decltype(a + b) {
523 template <
class A,
class B>
524 constexpr auto operator()(A a, B b)
const ->
decltype(a - b) {
529 template <
class A,
class B>
530 constexpr auto operator()(A a, B b)
const ->
decltype(a << b) {
535 template <
class A,
class B>
536 constexpr auto operator()(A a, B b)
const ->
decltype(a >> b) {
541 template <
class A,
class B>
542 constexpr auto operator()(A a, B b)
const ->
decltype(a < b) {
547 template <
class A,
class B>
548 constexpr auto operator()(A a, B b)
const ->
decltype(a > b) {
553 template <
class A,
class B>
554 constexpr auto operator()(A a, B b)
const ->
decltype(a <= b) {
559 template <
class A,
class B>
560 constexpr auto operator()(A a, B b)
const ->
decltype(a >= b) {
565 template <
class A,
class B>
566 constexpr auto operator()(A a, B b)
const ->
decltype(a == b) {
571 template <
class A,
class B>
572 constexpr auto operator()(A a, B b)
const ->
decltype(a != b) {
577 template <
class A,
class B>
578 constexpr auto operator()(A a, B b)
const ->
decltype(a & b) {
583 template <
class A,
class B>
584 constexpr auto operator()(A a, B b)
const ->
decltype(a ^ b) {
589 template <
class A,
class B>
590 constexpr auto operator()(A a, B b)
const ->
decltype(a | b) {
595 template <
class A,
class B>
596 constexpr auto operator()(A a, B b)
const ->
decltype(a && b) {
601 template <
class A,
class B>
602 constexpr auto operator()(A a, B b)
const ->
decltype(a || b) {
610 constexpr auto operator()(A a)
const ->
decltype(std::isfinite(a)) {
611 return std::isfinite(a);
616 constexpr auto operator()(A a)
const ->
decltype(std::abs(a)) {
622 constexpr auto operator()(A a)
const ->
decltype(std::floor(a)) {
623 return std::floor(a);
628 constexpr auto operator()(A a)
const ->
decltype(std::ceil(a)) {
634 constexpr auto operator()(A a)
const ->
decltype(std::exp(a)) {
640 constexpr auto operator()(A a)
const ->
decltype(std::log(a)) {
646 constexpr auto operator()(A a)
const ->
decltype(std::log2(a)) {
652 constexpr auto operator()(A a)
const ->
decltype(std::log10(a)) {
653 return std::log10(a);
658 constexpr auto operator()(A a)
const ->
decltype(std::sqrt(a)) {
664 constexpr auto operator()(A a)
const ->
decltype(std::sin(a)) {
670 constexpr auto operator()(A a)
const ->
decltype(std::cos(a)) {
676 constexpr auto operator()(A a)
const ->
decltype(std::tan(a)) {
682 constexpr auto operator()(A a)
const ->
decltype(std::asin(a)) {
688 constexpr auto operator()(A a)
const ->
decltype(std::acos(a)) {
694 constexpr auto operator()(A a)
const ->
decltype(std::atan(a)) {
700 constexpr auto operator()(A a)
const ->
decltype(std::sinh(a)) {
706 constexpr auto operator()(A a)
const ->
decltype(std::cosh(a)) {
712 constexpr auto operator()(A a)
const ->
decltype(std::tanh(a)) {
718 constexpr auto operator()(A a)
const ->
decltype(std::round(a)) {
719 return std::round(a);
723 template <
class A,
class B>
724 constexpr auto operator()(A a, B b)
const ->
decltype(std::fmod(a, b)) {
725 return std::fmod(a, b);
729 template <
class A,
class B>
730 constexpr auto operator()(A a, B b)
const ->
decltype(std::pow(a, b)) {
731 return std::pow(a, b);
735 template <
class A,
class B>
736 constexpr auto operator()(A a, B b)
const ->
decltype(std::atan2(a, b)) {
737 return std::atan2(a, b);
741 template <
class A,
class B>
742 constexpr auto operator()(A a, B b)
const ->
decltype(std::copysign(a, b)) {
743 return std::copysign(a, b);
850 constexpr vec() : x() {}
851 constexpr vec(
const T& x_) : x(x_) {}
855 constexpr explicit vec(
const vec<U, 1>& v) : vec(
static_cast<T
>(v.x)) {}
856 constexpr const T& operator[](
int)
const {
return x; }
857 LINALG_CONSTEXPR14 T& operator[](
int) {
return x; }
859 template <
class U,
class = detail::conv_t<vec, U>>
861 template <
class U,
class = detail::conv_t<U, vec>>
862 constexpr operator U()
const {
869 constexpr vec() : x(), y() {}
870 constexpr vec(
const T& x_,
const T& y_) : x(x_), y(y_) {}
871 constexpr explicit vec(
const T& s) : vec(s, s) {}
872 constexpr explicit vec(
const T* p) : vec(p[0], p[1]) {}
873 template <
class U,
int N>
874 constexpr explicit vec(
const vec<U, N>& v)
875 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y)) {
878 "You must give extra arguments if your input vector is shorter.");
880 constexpr const T& operator[](
int i)
const {
return i == 0 ? x : y; }
881 LINALG_CONSTEXPR14 T& operator[](
int i) {
return i == 0 ? x : y; }
883 template <
class U,
class = detail::conv_t<vec, U>>
885 template <
class U,
class = detail::conv_t<U, vec>>
886 constexpr operator U()
const {
893 constexpr vec() : x(), y(), z() {}
894 constexpr vec(
const T& x_,
const T& y_,
const T& z_) : x(x_), y(y_), z(z_) {}
895 constexpr vec(
const vec<T, 2>& xy,
const T& z_) : vec(xy.x, xy.y, z_) {}
896 constexpr explicit vec(
const T& s) : vec(s, s, s) {}
897 constexpr explicit vec(
const T* p) : vec(p[0], p[1], p[2]) {}
898 template <
class U,
int N>
899 constexpr explicit vec(
const vec<U, N>& v)
900 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z)) {
903 "You must give extra arguments if your input vector is shorter.");
905 constexpr const T& operator[](
int i)
const {
906 return i == 0 ? x : i == 1 ? y : z;
908 LINALG_CONSTEXPR14 T& operator[](
int i) {
909 return i == 0 ? x : i == 1 ? y : z;
911 constexpr const vec<T, 2>& xy()
const {
912 return *
reinterpret_cast<const vec<T, 2>*
>(
this);
914 vec<T, 2>& xy() {
return *
reinterpret_cast<vec<T, 2>*
>(
this); }
916 template <
class U,
class = detail::conv_t<vec, U>>
918 template <
class U,
class = detail::conv_t<U, vec>>
919 constexpr operator U()
const {
926 constexpr vec() : x(), y(), z(), w() {}
927 constexpr vec(
const T& x_,
const T& y_,
const T& z_,
const T& w_)
928 : x(x_), y(y_), z(z_), w(w_) {}
929 constexpr vec(
const vec<T, 2>& xy,
const T& z_,
const T& w_)
930 : vec(xy.x, xy.y, z_, w_) {}
931 constexpr vec(
const vec<T, 3>& xyz,
const T& w_)
932 : vec(xyz.x, xyz.y, xyz.z, w_) {}
933 constexpr explicit vec(
const T& s) : vec(s, s, s, s) {}
934 constexpr explicit vec(
const T* p) : vec(p[0], p[1], p[2], p[3]) {}
935 template <
class U,
int N>
936 constexpr explicit vec(
const vec<U, N>& v)
937 : vec(
static_cast<T
>(v.x),
static_cast<T
>(v.y),
static_cast<T
>(v.z),
938 static_cast<T
>(v.w)) {
941 "You must give extra arguments if your input vector is shorter.");
943 constexpr const T& operator[](
int i)
const {
944 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
946 LINALG_CONSTEXPR14 T& operator[](
int i) {
947 return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
949 constexpr const vec<T, 2>& xy()
const {
950 return *
reinterpret_cast<const vec<T, 2>*
>(
this);
952 constexpr const vec<T, 3>& xyz()
const {
953 return *
reinterpret_cast<const vec<T, 3>*
>(
this);
955 vec<T, 2>& xy() {
return *
reinterpret_cast<vec<T, 2>*
>(
this); }
956 vec<T, 3>& xyz() {
return *
reinterpret_cast<vec<T, 3>*
>(
this); }
958 template <
class U,
class = detail::conv_t<vec, U>>
960 template <
class U,
class = detail::conv_t<U, vec>>
961 constexpr operator U()
const {
1061template <
class T,
int M>
1062struct mat<T, M, 1> {
1065 constexpr mat() : x() {}
1066 constexpr mat(
const V& x_) : x(x_) {}
1067 constexpr explicit mat(
const T& s) : x(s) {}
1068 constexpr explicit mat(
const T* p) : x(p + M * 0) {}
1070 constexpr explicit mat(
const mat<U, M, 1>& m) : mat(V(m.x)) {}
1071 constexpr vec<T, 1> row(
int i)
const {
return {x[i]}; }
1072 constexpr const V& operator[](
int)
const {
return x; }
1073 LINALG_CONSTEXPR14 V& operator[](
int) {
return x; }
1075 template <
class U,
class = detail::conv_t<mat, U>>
1077 template <
class U,
class = detail::conv_t<U, mat>>
1078 constexpr operator U()
const {
1082template <
class T,
int M>
1083struct mat<T, M, 2> {
1086 constexpr mat() : x(), y() {}
1087 constexpr mat(
const V& x_,
const V& y_) : x(x_), y(y_) {}
1088 constexpr explicit mat(
const T& s) : x(s), y(s) {}
1089 constexpr explicit mat(
const T* p) : x(p + M * 0), y(p + M * 1) {}
1090 template <
class U,
int N,
int P>
1091 constexpr explicit mat(
const mat<U, N, P>& m) : mat(V(m.x), V(m.y)) {
1092 static_assert(P >= 2,
"Input matrix dimensions must be at least as big.");
1094 constexpr vec<T, 2> row(
int i)
const {
return {x[i], y[i]}; }
1095 constexpr const V& operator[](
int j)
const {
return j == 0 ? x : y; }
1096 LINALG_CONSTEXPR14 V& operator[](
int j) {
return j == 0 ? x : y; }
1098 template <
class U,
class = detail::conv_t<mat, U>>
1100 template <
class U,
class = detail::conv_t<U, mat>>
1101 constexpr operator U()
const {
1105template <
class T,
int M>
1106struct mat<T, M, 3> {
1109 constexpr mat() : x(), y(), z() {}
1110 constexpr mat(
const V& x_,
const V& y_,
const V& z_) : x(x_), y(y_), z(z_) {}
1111 constexpr mat(
const mat<T, M, 2>& m_,
const V& z_)
1112 : x(m_.x), y(m_.y), z(z_) {}
1113 constexpr explicit mat(
const T& s) : x(s), y(s), z(s) {}
1114 constexpr explicit mat(
const T* p)
1115 : x(p + M * 0), y(p + M * 1), z(p + M * 2) {}
1116 template <
class U,
int N,
int P>
1117 constexpr explicit mat(
const mat<U, N, P>& m) : mat(V(m.x), V(m.y), V(m.z)) {
1118 static_assert(P >= 3,
"Input matrix dimensions must be at least as big.");
1120 constexpr vec<T, 3> row(
int i)
const {
return {x[i], y[i], z[i]}; }
1121 constexpr const V& operator[](
int j)
const {
1122 return j == 0 ? x : j == 1 ? y : z;
1124 LINALG_CONSTEXPR14 V& operator[](
int j) {
1125 return j == 0 ? x : j == 1 ? y : z;
1128 template <
class U,
class = detail::conv_t<mat, U>>
1130 template <
class U,
class = detail::conv_t<U, mat>>
1131 constexpr operator U()
const {
1135template <
class T,
int M>
1136struct mat<T, M, 4> {
1139 constexpr mat() : x(), y(), z(), w() {}
1140 constexpr mat(
const V& x_,
const V& y_,
const V& z_,
const V& w_)
1141 : x(x_), y(y_), z(z_), w(w_) {}
1142 constexpr mat(
const mat<T, M, 3>& m_,
const V& w_)
1143 : x(m_.x), y(m_.y), z(m_.z), w(w_) {}
1144 constexpr explicit mat(
const T& s) : x(s), y(s), z(s), w(s) {}
1145 constexpr explicit mat(
const T* p)
1146 : x(p + M * 0), y(p + M * 1), z(p + M * 2), w(p + M * 3) {}
1147 template <
class U,
int N,
int P>
1148 constexpr explicit mat(
const mat<U, N, P>& m)
1149 : mat(V(m.x), V(m.y), V(m.z), V(m.w)) {
1150 static_assert(P >= 4,
"Input matrix dimensions must be at least as big.");
1153 constexpr vec<T, 4> row(
int i)
const {
return {x[i], y[i], z[i], w[i]}; }
1154 constexpr const V& operator[](
int j)
const {
1155 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1157 LINALG_CONSTEXPR14 V& operator[](
int j) {
1158 return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
1161 template <
class U,
class = detail::conv_t<mat, U>>
1163 template <
class U,
class = detail::conv_t<U, mat>>
1164 constexpr operator U()
const {
1177 constexpr explicit identity_t(
int) {}
1186 return {{1, 0}, {0, 1}};
1192 return {{1, 0}, {0, 1}, {0, 0}};
1198 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
1204 return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}};
1210 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
1223template <
class F,
class A,
class B>
1224constexpr A fold(F f, A a,
const vec<B, 1>& b) {
1227template <
class F,
class A,
class B>
1228constexpr A fold(F f, A a,
const vec<B, 2>& b) {
1229 return f(f(a, b.x), b.y);
1231template <
class F,
class A,
class B>
1232constexpr A fold(F f, A a,
const vec<B, 3>& b) {
1233 return f(f(f(a, b.x), b.y), b.z);
1235template <
class F,
class A,
class B>
1236constexpr A fold(F f, A a,
const vec<B, 4>& b) {
1237 return f(f(f(f(a, b.x), b.y), b.z), b.w);
1239template <
class F,
class A,
class B,
int M>
1241 return fold(f, a, b.x);
1243template <
class F,
class A,
class B,
int M>
1245 return fold(f, fold(f, a, b.x), b.y);
1247template <
class F,
class A,
class B,
int M>
1249 return fold(f, fold(f, fold(f, a, b.x), b.y), b.z);
1251template <
class F,
class A,
class B,
int M>
1253 return fold(f, fold(f, fold(f, fold(f, a, b.x), b.y), b.z), b.w);
1266template <
class F,
class... A>
1268template <
class F,
class... A>
1269using mm_apply_t =
typename std::enable_if<
detail::apply<F, void, A...>::mm,
1270 apply_t<F, A...>>::type;
1271template <
class F,
class... A>
1272using no_mm_apply_t =
typename std::enable_if<!
detail::apply<F, void, A...>::mm,
1273 apply_t<F, A...>>::type;
1281template <
class F,
class... A>
1282constexpr apply_t<F, A...> apply(F func,
const A&... args) {
1288template <
class A,
class F>
1289constexpr apply_t<F, A> map(
const A& a, F func) {
1290 return apply(func, a);
1294template <
class A,
class B,
class F>
1295constexpr apply_t<F, A, B> zip(
const A& a,
const B& b, F func) {
1296 return apply(func, a, b);
1306template <
class A,
class B>
1311template <
class A,
class B>
1312constexpr auto operator==(
const A& a,
const B& b)
1313 ->
decltype(compare(a, b) == 0) {
1314 return compare(a, b) == 0;
1316template <
class A,
class B>
1317constexpr auto operator!=(
const A& a,
const B& b)
1318 ->
decltype(compare(a, b) != 0) {
1319 return compare(a, b) != 0;
1321template <
class A,
class B>
1322constexpr auto operator<(
const A& a,
const B& b)
1323 ->
decltype(compare(a, b) < 0) {
1324 return compare(a, b) < 0;
1326template <
class A,
class B>
1327constexpr auto operator>(
const A& a,
const B& b)
1328 ->
decltype(compare(a, b) > 0) {
1329 return compare(a, b) > 0;
1331template <
class A,
class B>
1332constexpr auto operator<=(
const A& a,
const B& b)
1333 ->
decltype(compare(a, b) <= 0) {
1334 return compare(a, b) <= 0;
1336template <
class A,
class B>
1337constexpr auto operator>=(
const A& a,
const B& b)
1338 ->
decltype(compare(a, b) >= 0) {
1339 return compare(a, b) >= 0;
1349constexpr bool any(
const A& a) {
1353constexpr bool all(
const A& a) {
1357constexpr scalar_t<A> sum(
const A& a) {
1361constexpr scalar_t<A> product(
const A& a) {
1365constexpr scalar_t<A> minelem(
const A& a) {
1369constexpr scalar_t<A> maxelem(
const A& a) {
1372template <
class T,
int M>
1375 for (
int i = 1; i < M; ++i)
1376 if (a[i] < a[j]) j = i;
1379template <
class T,
int M>
1382 for (
int i = 1; i < M; ++i)
1383 if (a[i] > a[j]) j = i;
1394constexpr apply_t<detail::op_pos, A> operator+(
const A& a) {
1398constexpr apply_t<detail::op_neg, A> operator-(
const A& a) {
1402constexpr apply_t<detail::op_cmp, A> operator~(
const A& a) {
1406constexpr apply_t<detail::op_not, A> operator!(
const A& a) {
1419template <
class A,
class B>
1420constexpr apply_t<detail::op_add, A, B> operator+(
const A& a,
const B& b) {
1423template <
class A,
class B>
1424constexpr apply_t<detail::op_sub, A, B> operator-(
const A& a,
const B& b) {
1427template <
class A,
class B>
1428constexpr apply_t<detail::op_mul, A, B> cmul(
const A& a,
const B& b) {
1431template <
class A,
class B>
1432constexpr apply_t<detail::op_div, A, B> operator/(
const A& a,
const B& b) {
1435template <
class A,
class B>
1436constexpr apply_t<detail::op_mod, A, B> operator%(
const A& a,
const B& b) {
1439template <
class A,
class B>
1440constexpr apply_t<detail::op_un, A, B> operator|(
const A& a,
const B& b) {
1443template <
class A,
class B>
1444constexpr apply_t<detail::op_xor, A, B> operator^(
const A& a,
const B& b) {
1447template <
class A,
class B>
1448constexpr apply_t<detail::op_int, A, B> operator&(
const A& a,
const B& b) {
1451template <
class A,
class B>
1452constexpr apply_t<detail::op_lsh, A, B> operator<<(
const A& a,
const B& b) {
1455template <
class A,
class B>
1456constexpr apply_t<detail::op_rsh, A, B> operator>>(
const A& a,
const B& b) {
1462template <
class A,
class B>
1463constexpr auto operator*(
const A& a,
const B& b) {
1469template <
class A,
class B>
1470constexpr auto operator+=(A& a,
const B& b) ->
decltype(a = a + b) {
1473template <
class A,
class B>
1474constexpr auto operator-=(A& a,
const B& b) ->
decltype(a = a - b) {
1477template <
class A,
class B>
1478constexpr auto operator*=(A& a,
const B& b) ->
decltype(a = a * b) {
1481template <
class A,
class B>
1482constexpr auto operator/=(A& a,
const B& b) ->
decltype(a = a / b) {
1485template <
class A,
class B>
1486constexpr auto operator%=(A& a,
const B& b) ->
decltype(a = a % b) {
1489template <
class A,
class B>
1490constexpr auto operator|=(A& a,
const B& b) ->
decltype(a = a | b) {
1493template <
class A,
class B>
1494constexpr auto operator^=(A& a,
const B& b) ->
decltype(a = a ^ b) {
1497template <
class A,
class B>
1498constexpr auto operator&=(A& a,
const B& b) ->
decltype(a = a & b) {
1501template <
class A,
class B>
1502constexpr auto operator<<=(A& a,
const B& b) ->
decltype(a = a << b) {
1505template <
class A,
class B>
1506constexpr auto operator>>=(A& a,
const B& b) ->
decltype(a = a >> b) {
1520template <
int... I,
class T,
int M>
1528template <
int I0,
int I1,
class T,
int M>
1530 return detail::swizzle(a, detail::make_seq<I0, I1>{});
1536template <
int I0,
int J0,
int I1,
int J1,
class T,
int M,
int N>
1538 return detail::swizzle(a, detail::make_seq<I0, I1>{},
1539 detail::make_seq<J0, J1>{});
1549constexpr apply_t<detail::std_isfinite, A> isfinite(
const A& a) {
1550 return apply(detail::std_isfinite{}, a);
1553constexpr apply_t<detail::std_abs, A> abs(
const A& a) {
1557constexpr apply_t<detail::std_floor, A> floor(
const A& a) {
1561constexpr apply_t<detail::std_ceil, A> ceil(
const A& a) {
1565constexpr apply_t<detail::std_exp, A> exp(
const A& a) {
1569constexpr apply_t<detail::std_log, A> log(
const A& a) {
1573constexpr apply_t<detail::std_log2, A> log2(
const A& a) {
1577constexpr apply_t<detail::std_log10, A> log10(
const A& a) {
1581constexpr apply_t<detail::std_sqrt, A> sqrt(
const A& a) {
1585constexpr apply_t<detail::std_sin, A> sin(
const A& a) {
1589constexpr apply_t<detail::std_cos, A> cos(
const A& a) {
1593constexpr apply_t<detail::std_tan, A> tan(
const A& a) {
1597constexpr apply_t<detail::std_asin, A> asin(
const A& a) {
1601constexpr apply_t<detail::std_acos, A> acos(
const A& a) {
1605constexpr apply_t<detail::std_atan, A> atan(
const A& a) {
1609constexpr apply_t<detail::std_sinh, A> sinh(
const A& a) {
1613constexpr apply_t<detail::std_cosh, A> cosh(
const A& a) {
1617constexpr apply_t<detail::std_tanh, A> tanh(
const A& a) {
1621constexpr apply_t<detail::std_round, A> round(
const A& a) {
1632template <
class A,
class B>
1633constexpr apply_t<detail::std_fmod, A, B> fmod(
const A& a,
const B& b) {
1636template <
class A,
class B>
1637constexpr apply_t<detail::std_pow, A, B> pow(
const A& a,
const B& b) {
1640template <
class A,
class B>
1641constexpr apply_t<detail::std_atan2, A, B> atan2(
const A& a,
const B& b) {
1644template <
class A,
class B>
1645constexpr apply_t<detail::std_copysign, A, B> copysign(
const A& a,
const B& b) {
1656template <
class A,
class B>
1657constexpr apply_t<detail::op_eq, A, B> equal(
const A& a,
const B& b) {
1660template <
class A,
class B>
1661constexpr apply_t<detail::op_ne, A, B> nequal(
const A& a,
const B& b) {
1664template <
class A,
class B>
1665constexpr apply_t<detail::op_lt, A, B> less(
const A& a,
const B& b) {
1668template <
class A,
class B>
1669constexpr apply_t<detail::op_gt, A, B> greater(
const A& a,
const B& b) {
1672template <
class A,
class B>
1673constexpr apply_t<detail::op_le, A, B> lequal(
const A& a,
const B& b) {
1676template <
class A,
class B>
1677constexpr apply_t<detail::op_ge, A, B> gequal(
const A& a,
const B& b) {
1688template <
class A,
class B>
1689constexpr apply_t<detail::min, A, B> min(
const A& a,
const B& b) {
1692template <
class A,
class B>
1693constexpr apply_t<detail::max, A, B> max(
const A& a,
const B& b) {
1699template <
class X,
class L,
class H>
1700constexpr apply_t<detail::clamp, X, L, H>
clamp(
const X& x,
const L& l,
1708template <
class P,
class A,
class B>
1709constexpr apply_t<detail::select, P, A, B>
select(
const P& p,
const A& a,
1717template <
class A,
class B,
class T>
1718constexpr apply_t<detail::lerp, A, B, T>
lerp(
const A& a,
const B& b,
1734 return a.x * b.y - a.y * b.x;
1741 return {-a * b.y, a * b.x};
1748 return {a.y * b, -a.x * b};
1756 return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
1762template <
class T,
int M>
1769template <
class T,
int M>
1776template <
class T,
int M>
1785template <
class T,
int M>
1794template <
class T,
int M>
1802template <
class T,
int M>
1809template <
class T,
int M>
1812 return d > 1 ? 0 : std::acos(d < -1 ? -1 : d);
1817template <
class T,
int M>
1827 const T s = std::sin(a), c = std::cos(a);
1828 return {v.x * c - v.y * s, v.x * s + v.y * c};
1836 const T s = std::sin(a), c = std::cos(a);
1837 return {v.x, v.y * c - v.z * s, v.y * s + v.z * c};
1845 const T s = std::sin(a), c = std::cos(a);
1846 return {v.x * c + v.z * s, v.y, -v.x * s + v.z * c};
1854 const T s = std::sin(a), c = std::cos(a);
1855 return {v.x * c - v.y * s, v.x * s + v.y * c, v.z};
1860template <
class T,
int M>
1869template <
class T,
int M>
1873 : a * (std::sin(th * (1 - t)) / std::sin(th)) +
1874 b * (std::sin(th * t) / std::sin(th));
1891 return {-q.x, -q.y, -q.z, q.w};
1909 const auto v = q.xyz();
1910 const auto vv =
length(v);
1911 return std::exp(q.w) *
1912 vec<T, 4>{v * (vv > 0 ? std::sin(vv) / vv : 0), std::cos(vv)};
1921 const auto v = q.xyz();
1923 return {v * (vv > 0 ? std::acos(q.w / qq) / vv : 0), std::log(qq)};
1930 const auto v = q.xyz();
1931 const auto vv =
length(v), qq =
length(q), th = std::acos(q.w / qq);
1932 return std::pow(qq, p) *
1933 vec<T, 4>{v * (vv > 0 ? std::sin(p * th) / vv : 0), std::cos(p * th)};
1942 return {a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y,
1943 a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z,
1944 a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x,
1945 a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z};
1950template <
class T,
class... R>
1966 return {q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z,
1967 (q.x * q.y + q.z * q.w) * 2, (q.z * q.x - q.y * q.w) * 2};
1974 return {(q.x * q.y - q.z * q.w) * 2,
1975 q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z,
1976 (q.y * q.z + q.x * q.w) * 2};
1983 return {(q.z * q.x + q.y * q.w) * 2, (q.y * q.z - q.x * q.w) * 2,
1984 q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z};
2006 return std::atan2(
length(q.xyz()), q.w) * 2;
2022 return nlerp(a,
dot(a, b) < 0 ? -b : b, t);
2029 return slerp(a,
dot(a, b) < 0 ? -b : b, t);
2037 return {axis * std::sin(
angle / 2), std::cos(
angle / 2)};
2058template <
class T,
int M>
2062template <
class T,
int M>
2063constexpr vec<T, M> mul(
const T& b,
const vec<T, M>& a) {
2066template <
class T,
int M,
int N>
2070template <
class T,
int M,
int N>
2074template <
class T,
int M>
2078template <
class T,
int M>
2082template <
class T,
int M>
2084 return a.x * b.x + a.y * b.y;
2086template <
class T,
int M>
2088 return a.x * b.x + a.y * b.y + a.z * b.z;
2090template <
class T,
int M>
2092 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
2094template <
class T,
int M,
int N>
2096 return {mul(a, b.x)};
2098template <
class T,
int M,
int N>
2100 return {mul(a, b.x), mul(a, b.y)};
2102template <
class T,
int M,
int N>
2104 return {mul(a, b.x), mul(a, b.y), mul(a, b.z)};
2106template <
class T,
int M,
int N>
2108 return {mul(a, b.x), mul(a, b.y), mul(a, b.z), mul(a, b.w)};
2110template <
class T,
int M,
int N,
int P>
2113 return mul(mul(a, b), c);
2115template <
class T,
int M,
int N,
int P,
int Q>
2118 return mul(mul(a, b), c);
2120template <
class T,
int M,
int N,
int P,
int Q>
2123 return mul(mul(a, b, c), d);
2125template <
class T,
int M,
int N,
int P,
int Q,
int R>
2128 return mul(mul(a, b, c), d);
2130template <
class T,
int M>
2134template <
class T,
int M>
2136 return {a * b.x, a * b.y};
2138template <
class T,
int M>
2140 return {a * b.x, a * b.y, a * b.z};
2142template <
class T,
int M>
2144 return {a * b.x, a * b.y, a * b.z, a * b.w};
2152 return {a.x.x, a.y.y};
2156 return {a.x.x, a.y.y, a.z.z};
2160 return {a.x.x, a.y.y, a.z.z, a.w.w};
2162template <
class T,
int N>
2164 return sum(diagonal(a));
2166template <
class T,
int M>
2170template <
class T,
int M>
2172 return {m.row(0), m.row(1)};
2174template <
class T,
int M>
2176 return {m.row(0), m.row(1), m.row(2)};
2178template <
class T,
int M>
2180 return {m.row(0), m.row(1), m.row(2), m.row(3)};
2182template <
class T,
int M>
2192 return {{a.y.y, -a.x.y}, {-a.y.x, a.x.x}};
2198template <
class T,
int N>
2200 return transpose(adjugate(a));
2208 return a.x.x * a.y.y - a.x.y * a.y.x;
2212 return a.x.x * (a.y.y * a.z.z - a.z.y * a.y.z) +
2213 a.x.y * (a.y.z * a.z.x - a.z.z * a.y.x) +
2214 a.x.z * (a.y.x * a.z.y - a.z.x * a.y.y);
2218template <
class T,
int N>
2220 return adjugate(a) / determinant(a);
2229template <
class T,
int M>
2233template <
class T,
int M>
2237template <
class T,
int M>
2239 return begin(a) + M;
2241template <
class T,
int M>
2243 return begin(a) + M;
2245template <
class T,
int M,
int N>
2249template <
class T,
int M,
int N>
2253template <
class T,
int M,
int N>
2255 return begin(a) + N;
2257template <
class T,
int M,
int N>
2259 return begin(a) + N;
2279 return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {translation, 1}};
2283 return {{
qxdir(rotation), 0},
2284 {
qydir(rotation), 0},
2285 {
qzdir(rotation), 0},
2290 return {{scaling.x, 0, 0, 0},
2291 {0, scaling.y, 0, 0},
2292 {0, 0, scaling.z, 0},
2301 const vec<T, 3>& view_y_dir, fwd_axis fwd = neg_z);
2303mat<T, 4, 4> frustum_matrix(T x0, T x1, T y0, T y1, T n, T f,
2304 fwd_axis a = neg_z, z_range z = neg_one_to_one);
2306mat<T, 4, 4> perspective_matrix(T fovy, T aspect, T n, T f, fwd_axis a = neg_z,
2307 z_range z = neg_one_to_one) {
2308 T y = n * std::tan(fovy / 2), x = y * aspect;
2309 return frustum_matrix(-x, x, -y, y, n, f, a, z);
2321 vec<T, 1> operator()(
const std::array<T, 1>& a)
const {
return {a[0]}; }
2325 vec<T, 2> operator()(
const std::array<T, 2>& a)
const {
return {a[0], a[1]}; }
2329 vec<T, 3> operator()(
const std::array<T, 3>& a)
const {
2330 return {a[0], a[1], a[2]};
2335 vec<T, 4> operator()(
const std::array<T, 4>& a)
const {
2336 return {a[0], a[1], a[2], a[3]};
2342 std::array<T, 1> operator()(
const vec<T, 1>& a)
const {
return {a[0]}; }
2346 std::array<T, 2> operator()(
const vec<T, 2>& a)
const {
return {a[0], a[1]}; }
2350 std::array<T, 3> operator()(
const vec<T, 3>& a)
const {
2351 return {a[0], a[1], a[2]};
2356 std::array<T, 4> operator()(
const vec<T, 4>& a)
const {
2357 return {a[0], a[1], a[2], a[3]};
2370struct hash<linalg::vec<T, 1>> {
2377struct hash<linalg::vec<T, 2>> {
2380 return h(v.x) ^ (h(v.y) << 1);
2384struct hash<linalg::vec<T, 3>> {
2387 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2);
2391struct hash<linalg::vec<T, 4>> {
2394 return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2) ^ (h(v.w) << 3);
2398template <
class T,
int M>
2399struct hash<linalg::mat<T, M, 1>> {
2401 std::hash<linalg::vec<T, M>> h;
2405template <
class T,
int M>
2406struct hash<linalg::mat<T, M, 2>> {
2408 std::hash<linalg::vec<T, M>> h;
2409 return h(v.x) ^ (h(v.y) << M);
2412template <
class T,
int M>
2413struct hash<linalg::mat<T, M, 3>> {
2415 std::hash<linalg::vec<T, M>> h;
2416 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2));
2419template <
class T,
int M>
2420struct hash<linalg::mat<T, M, 4>> {
2422 std::hash<linalg::vec<T, M>> h;
2423 return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2)) ^ (h(v.w) << (M * 3));
2432 return {{a.y.y * a.z.z - a.z.y * a.y.z, a.z.y * a.x.z - a.x.y * a.z.z,
2433 a.x.y * a.y.z - a.y.y * a.x.z},
2434 {a.y.z * a.z.x - a.z.z * a.y.x, a.z.z * a.x.x - a.x.z * a.z.x,
2435 a.x.z * a.y.x - a.y.z * a.x.x},
2436 {a.y.x * a.z.y - a.z.x * a.y.y, a.z.x * a.x.y - a.x.x * a.z.y,
2437 a.x.x * a.y.y - a.y.x * a.x.y}};
2442 return {{a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2443 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2444 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w,
2445 a.x.y * a.w.z * a.z.w + a.z.y * a.x.z * a.w.w +
2446 a.w.y * a.z.z * a.x.w - a.w.y * a.x.z * a.z.w -
2447 a.z.y * a.w.z * a.x.w - a.x.y * a.z.z * a.w.w,
2448 a.x.y * a.y.z * a.w.w + a.w.y * a.x.z * a.y.w +
2449 a.y.y * a.w.z * a.x.w - a.x.y * a.w.z * a.y.w -
2450 a.y.y * a.x.z * a.w.w - a.w.y * a.y.z * a.x.w,
2451 a.x.y * a.z.z * a.y.w + a.y.y * a.x.z * a.z.w +
2452 a.z.y * a.y.z * a.x.w - a.x.y * a.y.z * a.z.w -
2453 a.z.y * a.x.z * a.y.w - a.y.y * a.z.z * a.x.w},
2454 {a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2455 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2456 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x,
2457 a.x.z * a.z.w * a.w.x + a.w.z * a.x.w * a.z.x +
2458 a.z.z * a.w.w * a.x.x - a.x.z * a.w.w * a.z.x -
2459 a.z.z * a.x.w * a.w.x - a.w.z * a.z.w * a.x.x,
2460 a.x.z * a.w.w * a.y.x + a.y.z * a.x.w * a.w.x +
2461 a.w.z * a.y.w * a.x.x - a.x.z * a.y.w * a.w.x -
2462 a.w.z * a.x.w * a.y.x - a.y.z * a.w.w * a.x.x,
2463 a.x.z * a.y.w * a.z.x + a.z.z * a.x.w * a.y.x +
2464 a.y.z * a.z.w * a.x.x - a.x.z * a.z.w * a.y.x -
2465 a.y.z * a.x.w * a.z.x - a.z.z * a.y.w * a.x.x},
2466 {a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2467 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2468 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y,
2469 a.x.w * a.w.x * a.z.y + a.z.w * a.x.x * a.w.y +
2470 a.w.w * a.z.x * a.x.y - a.x.w * a.z.x * a.w.y -
2471 a.w.w * a.x.x * a.z.y - a.z.w * a.w.x * a.x.y,
2472 a.x.w * a.y.x * a.w.y + a.w.w * a.x.x * a.y.y +
2473 a.y.w * a.w.x * a.x.y - a.x.w * a.w.x * a.y.y -
2474 a.y.w * a.x.x * a.w.y - a.w.w * a.y.x * a.x.y,
2475 a.x.w * a.z.x * a.y.y + a.y.w * a.x.x * a.z.y +
2476 a.z.w * a.y.x * a.x.y - a.x.w * a.y.x * a.z.y -
2477 a.z.w * a.x.x * a.y.y - a.y.w * a.z.x * a.x.y},
2478 {a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2479 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2480 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z,
2481 a.x.x * a.z.y * a.w.z + a.w.x * a.x.y * a.z.z +
2482 a.z.x * a.w.y * a.x.z - a.x.x * a.w.y * a.z.z -
2483 a.z.x * a.x.y * a.w.z - a.w.x * a.z.y * a.x.z,
2484 a.x.x * a.w.y * a.y.z + a.y.x * a.x.y * a.w.z +
2485 a.w.x * a.y.y * a.x.z - a.x.x * a.y.y * a.w.z -
2486 a.w.x * a.x.y * a.y.z - a.y.x * a.w.y * a.x.z,
2487 a.x.x * a.y.y * a.z.z + a.z.x * a.x.y * a.y.z +
2488 a.y.x * a.z.y * a.x.z - a.x.x * a.z.y * a.y.z -
2489 a.y.x * a.x.y * a.z.z - a.z.x * a.y.y * a.x.z}};
2493constexpr T linalg::determinant(
const mat<T, 4, 4>& a) {
2494 return a.x.x * (a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
2495 a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
2496 a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w) +
2497 a.x.y * (a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
2498 a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
2499 a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x) +
2500 a.x.z * (a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
2501 a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
2502 a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y) +
2503 a.x.w * (a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
2504 a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
2505 a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z);
2510 const vec<T, 3>& dest) {
2511 T cosTheta =
dot(orig, dest);
2512 if (cosTheta >= 1 - std::numeric_limits<T>::epsilon()) {
2513 return {0, 0, 0, 1};
2515 if (cosTheta < -1 + std::numeric_limits<T>::epsilon()) {
2516 vec<T, 3> axis =
cross(vec<T, 3>(0, 0, 1), orig);
2517 if (
length2(axis) < std::numeric_limits<T>::epsilon())
2518 axis =
cross(vec<T, 3>(1, 0, 0), orig);
2520 3.14159265358979323846264338327950288);
2522 vec<T, 3> axis =
cross(orig, dest);
2523 T s = std::sqrt((1 + cosTheta) * 2);
2524 return {axis * (1 / s), s * 0.5};
2529 const vec<T, 4> q{m.x.x - m.y.y - m.z.z, m.y.y - m.x.x - m.z.z,
2530 m.z.z - m.x.x - m.y.y, m.x.x + m.y.y + m.z.z},
2531 s[]{{1, m.x.y + m.y.x, m.z.x + m.x.z, m.y.z - m.z.y},
2532 {m.x.y + m.y.x, 1, m.y.z + m.z.y, m.z.x - m.x.z},
2533 {m.x.z + m.z.x, m.y.z + m.z.y, 1, m.x.y - m.y.x},
2534 {m.y.z - m.z.y, m.z.x - m.x.z, m.x.y - m.y.x, 1}};
2535 return copysign(
normalize(sqrt(max(T(0), T(1) + q))), s[argmax(q)]);
2540 const vec<T, 3>& center,
2541 const vec<T, 3>& view_y_dir,
2543 const vec<T, 3> f =
normalize(center - eye), z = a == pos_z ? f : -f,
2545 return inverse(mat<T, 4, 4>{{x, 0}, {y, 0}, {z, 0}, {eye, 1}});
2550 fwd_axis a, z_range z) {
2551 const T s = a == pos_z ? T(1) : T(-1), o = z == neg_one_to_one ? n : 0;
2552 return {{2 * n / (x1 - x0), 0, 0, 0},
2553 {0, 2 * n / (y1 - y0), 0, 0},
2554 {-s * (x0 + x1) / (x1 - x0), -s * (y0 + y1) / (y1 - y0),
2555 s * (f + o) / (f - n), s},
2556 {0, 0, -(n + o) * f / (f - n), 0}};
constexpr mat< T, 3, 3 > qmat(const vec< T, 4 > &q)
Create an equivalent mat3 rotation matrix from the input quaternion.
Definition linalg.h:1990
vec< T, 4 > qslerp(const vec< T, 4 > &a, const vec< T, 4 > &b, T t)
Spherical linear interpolation that takes the shortest path.
Definition linalg.h:2028
T qangle(const vec< T, 4 > &q)
Return the angle in radians of the axis-angle representation of the input normalized quaternion.
Definition linalg.h:2005
constexpr vec< T, 3 > qzdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,0,1})
Definition linalg.h:1982
vec< T, 4 > qnlerp(const vec< T, 4 > &a, const vec< T, 4 > &b, T t)
Linear interpolation that takes the shortest path - this is not geometrically sensible,...
Definition linalg.h:2021
vec< T, 3 > qaxis(const vec< T, 4 > &q)
Return the normalized axis of the axis-angle representation of the input normalized quaternion.
Definition linalg.h:2013
vec< T, 4 > constexpr rotation_quat(const vec< T, 3 > &axis, T angle)
Returns a normalized quaternion representing a rotation by angle in radians about the provided axis.
Definition linalg.h:2036
constexpr vec< T, 3 > qxdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {1,0,0})
Definition linalg.h:1965
constexpr vec< T, 3 > qrot(const vec< T, 4 > &q, const vec< T, 3 > &v)
Rotate a vector by a quaternion.
Definition linalg.h:1997
constexpr vec< T, 3 > qydir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,1,0})
Definition linalg.h:1973
vec< T, 4 > qinv(const vec< T, 4 > &q)
inverse or reciprocal of quaternion q (undefined for zero-length quaternions)
Definition linalg.h:1899
vec< T, 4 > qexp(const vec< T, 4 > &q)
exponential of quaternion q
Definition linalg.h:1908
vec< T, 4 > qpow(const vec< T, 4 > &q, const T &p)
quaternion q raised to the exponent p
Definition linalg.h:1929
vec< T, 4 > qlog(const vec< T, 4 > &q)
logarithm of quaternion q
Definition linalg.h:1920
constexpr vec< T, 4 > qmul(const vec< T, 4 > &a, const vec< T, 4 > &b)
Hamilton product of quaternions a and b
Definition linalg.h:1941
constexpr vec< T, 4 > qconj(const vec< T, 4 > &q)
conjugate of quaternion q
Definition linalg.h:1890
constexpr apply_t< detail::clamp, X, L, H > clamp(const X &x, const L &l, const H &h)
Clamps the components of x between l and h, provided l[i] < h[i].
Definition linalg.h:1700
constexpr apply_t< detail::select, P, A, B > select(const P &p, const A &a, const B &b)
Returns the component from a if the corresponding component of p is true and from b otherwise.
Definition linalg.h:1709
constexpr apply_t< detail::lerp, A, B, T > lerp(const A &a, const B &b, const T &t)
Linear interpolation from a to b as t goes from 0 -> 1. Values beyond [a, b] will result if t is outs...
Definition linalg.h:1718
constexpr vec< T, sizeof...(I)> swizzle(const vec< T, M > &a)
Returns a vector containing the specified ordered indices, e.g. linalg::swizzle<1,...
Definition linalg.h:1521
constexpr mat< T, I1 - I0, J1 - J0 > submat(const mat< T, M, N > &a)
Returns a matrix containing the specified row and column range: linalg::submat<rowStart,...
Definition linalg.h:1537
constexpr vec< T, I1 - I0 > subvec(const vec< T, M > &a)
Returns a vector containing the specified index range, e.g. linalg::subvec<1, 4>(vec4(4,...
Definition linalg.h:1529
vec< T, 3 > roty(T a, const vec< T, 3 > &v)
vector v rotated counter-clockwise by the angle a in radians around the Y axis
Definition linalg.h:1844
vec< T, 2 > rot(T a, const vec< T, 2 > &v)
vector v rotated counter-clockwise by the angle a in radians
Definition linalg.h:1826
constexpr T distance2(const vec< T, M > &a, const vec< T, M > &b)
square of the Euclidean distance between points a and b
Definition linalg.h:1795
vec< T, 3 > rotx(T a, const vec< T, 3 > &v)
vector v rotated counter-clockwise by the angle a in radians around the X axis
Definition linalg.h:1835
constexpr T length2(const vec< T, M > &a)
square of the length or magnitude of vector a
Definition linalg.h:1770
constexpr T dot(const vec< T, M > &a, const vec< T, M > &b)
dot or inner product of vectors a and b
Definition linalg.h:1763
vec< T, M > nlerp(const vec< T, M > &a, const vec< T, M > &b, T t)
shorthand for normalize(lerp(a,b,t))
Definition linalg.h:1861
vec< T, M > normalize(const vec< T, M > &a)
unit length vector in the same direction as a (undefined for zero-length vectors)
Definition linalg.h:1786
vec< T, M > slerp(const vec< T, M > &a, const vec< T, M > &b, T t)
spherical linear interpolation between unit vectors a and b (undefined for non-unit vectors) by param...
Definition linalg.h:1870
T angle(const vec< T, M > &a, const vec< T, M > &b)
Return the angle in radians between two non-unit vectors.
Definition linalg.h:1818
T uangle(const vec< T, M > &a, const vec< T, M > &b)
Return the angle in radians between two unit vectors.
Definition linalg.h:1810
constexpr T cross(const vec< T, 2 > &a, const vec< T, 2 > &b)
shorthand for cross({a.x,a.y,0}, {b.x,b.y,0}).z
Definition linalg.h:1733
vec< T, 3 > rotz(T a, const vec< T, 3 > &v)
vector v rotated counter-clockwise by the angle a in radians around the Z axis
Definition linalg.h:1853
T length(const vec< T, M > &a)
length or magnitude of a vector a
Definition linalg.h:1777
T distance(const vec< T, M > &a, const vec< T, M > &b)
Euclidean distance between points a and b
Definition linalg.h:1803