32template<
int N,
typename T>
class vecN;
35template<
typename T>
class vecN<2, T>
41 constexpr vecN() : x(T(0)), y(T(0)) {}
44 constexpr explicit vecN(T
t) : x(
t), y(
t) {}
51 template<
int N2>
constexpr explicit vecN(
const vecN<N2, T>& v) : x(v.x), y(v.y) {}
54 constexpr vecN(T a, T b) : x(a), y(b) {}
68 [[nodiscard]]
constexpr const T*
data()
const {
return &x; }
69 [[nodiscard]]
constexpr T*
data() {
return &x; }
72 template<
size_t I> [[nodiscard]]
constexpr T
get() const noexcept {
return (*
this)[I]; }
73 template<
size_t I> [[nodiscard]]
constexpr T&
get() noexcept {
return (*
this)[I]; }
86 return (a.x == b.x) && (a.y == b.y);
94template<
typename T>
class vecN<3, T>
97 constexpr vecN() : x(T(0)), y(T(0)), z(T(0)) {}
98 constexpr explicit vecN(T
t) : x(
t), y(
t), z(
t) {}
102 constexpr vecN(T a, T b, T c) : x(a), y(b), z(c) {}
107 if (i == 0)
return x;
108 if (i == 1)
return y;
109 if (i == 2)
return z;
113 if (i == 0)
return x;
114 if (i == 1)
return y;
115 if (i == 2)
return z;
119 [[nodiscard]]
constexpr const T*
data()
const {
return &x; }
120 [[nodiscard]]
constexpr T*
data() {
return &x; }
122 template<
size_t I> [[nodiscard]]
constexpr T
get() const noexcept {
return (*
this)[I]; }
123 template<
size_t I> [[nodiscard]]
constexpr T&
get() noexcept {
return (*
this)[I]; }
132 return (a.x == b.x) && (a.y == b.y) && (a.z == b.z);
140template<
typename T>
class vecN<4, T>
143 constexpr vecN() : x(T(0)), y(T(0)), z(T(0)), w(T(0)) {}
144 constexpr explicit vecN(T
t) : x(
t), y(
t), z(
t), w(
t) {}
145 template<
typename T2>
146 constexpr explicit vecN(
const vecN<4, T2>& v) : x(T(v.x)), y(T(v.y)), z(T(v.z)), w(T(v.w)) {}
147 constexpr vecN(T a, T b, T c, T d) : x(a), y(b), z(c), w(d) {}
153 if (i == 0)
return x;
154 if (i == 1)
return y;
155 if (i == 2)
return z;
156 if (i == 3)
return w;
160 if (i == 0)
return x;
161 if (i == 1)
return y;
162 if (i == 2)
return z;
163 if (i == 3)
return w;
167 [[nodiscard]]
constexpr const T*
data()
const {
return &x; }
168 [[nodiscard]]
constexpr T*
data() {
return &x; }
170 template<
size_t I> [[nodiscard]]
constexpr T
get() const noexcept {
return (*
this)[I]; }
171 template<
size_t I> [[nodiscard]]
constexpr T&
get() noexcept {
return (*
this)[I]; }
181 return (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w);
197static_assert(
sizeof(
vec2) == 2 *
sizeof(
float));
198static_assert(
sizeof(
vec3) == 3 *
sizeof(
float));
199static_assert(
sizeof(
vec4) == 4 *
sizeof(
float));
200static_assert(
sizeof(
ivec2) == 2 *
sizeof(
int));
201static_assert(
sizeof(
ivec3) == 3 *
sizeof(
int));
202static_assert(
sizeof(
ivec4) == 4 *
sizeof(
int));
208[[nodiscard]]
inline float rsqrt(
float x)
210 return 1.0f / sqrtf(x);
212[[nodiscard]]
inline double rsqrt(
double x)
214 return 1.0 / sqrt(x);
218template<
typename T> [[nodiscard]]
constexpr T
radians(T d)
222template<
typename T> [[nodiscard]]
constexpr T
degrees(T r)
231template<
int N,
typename T>
238template<
int N,
typename T>
242 for (
auto i :
xrange(N)) r[i] = x[i] + y[i];
247template<
int N,
typename T>
251 for (
auto i :
xrange(N)) r[i] = x[i] - y[i];
256template<
int N,
typename T>
260 for (
auto i :
xrange(N)) r[i] = x * y[i];
265template<
int N,
typename T>
269 for (
auto i :
xrange(N)) r[i] = x[i] * y;
274template<
int N,
typename T>
278 for (
auto i :
xrange(N)) r[i] = x[i] * y[i];
283template<
int N,
typename T>
287 for (
auto i :
xrange(N)) r[i] = T(1) / x[i];
292template<
int N,
typename T>
299template<
int N,
typename T>
302 return x * (T(1) / y);
306template<
int N,
typename T>
313template<
int N,
typename T>
317 for (
auto i :
xrange(N)) r[i] = std::min(x[i], y[i]);
322template<
int N,
typename T>
326 for (
auto i :
xrange(1, N)) r = std::min(r, x[i]);
331template<
int N,
typename T>
335 for (
auto i :
xrange(N)) r[i] = std::max(x[i], y[i]);
340template<
int N,
typename T>
343 return min(maxVal,
max(minVal, x));
347template<
int N,
typename T>
354template<
int N,
typename T>
358 for (
auto i :
xrange(N)) result += x[i];
361template<
int N,
typename T>
368template<
int N,
typename T>
373template<
int N,
typename T>
380template<
int N,
typename T>
387template<
int N,
typename T>
394template<
int N,
typename T>
405 a.z * b.x - a.x * b.z,
406 a.x * b.y - a.y * b.x);
410template<
int N,
typename T>
416 for (
auto i :
xrange(N)) r[i] = narrow_cast<int>(lrintf(narrow_cast<float>(x[i])));
422template<
int N,
typename T>
426 for (
auto i :
xrange(N)) r[i] =
int(x[i]);
431template<
int N,
typename T>
435 for (
auto i :
xrange(N)) {
449#if defined(__clang__)
450#pragma clang diagnostic push
451#pragma clang diagnostic ignored "-Wmismatched-tags"
453 template<
int N,
typename T>
class tuple_size<
gl::vecN<N, T>>
454 :
public std::integral_constant<size_t, N> {};
455#if defined(__clang__)
456#pragma clang diagnostic pop
458 template<
size_t I,
int N,
typename T>
class tuple_element<I,
gl::vecN<N, T>> {
friend constexpr bool operator==(const vecN &a, const vecN &b)
constexpr T & get() noexcept
constexpr vecN & operator+=(const vecN &v)
constexpr T operator[](unsigned i) const
constexpr vecN(const vecN< 2, T2 > &v)
constexpr T & operator[](unsigned i)
constexpr vecN & operator*=(T t)
constexpr const T * data() const
constexpr T get() const noexcept
constexpr vecN & operator-=(const vecN &v)
constexpr vecN & operator*=(const vecN &v)
constexpr vecN(const vecN< N2, T > &v)
constexpr vecN & operator-=(const vecN &v)
friend constexpr bool operator==(const vecN &a, const vecN &b)
constexpr vecN(const vecN< 2, T > &a, T b)
constexpr vecN & operator*=(T t)
constexpr T & operator[](unsigned i)
constexpr vecN(const vecN< 3, T2 > &v)
constexpr vecN & operator+=(const vecN &v)
constexpr vecN(T a, T b, T c)
constexpr T operator[](unsigned i) const
constexpr T & get() noexcept
constexpr vecN(const vecN< 4, T > &v)
constexpr vecN(T a, const vecN< 2, T > &b)
constexpr vecN & operator*=(const vecN &v)
constexpr T get() const noexcept
constexpr const T * data() const
friend constexpr bool operator==(const vecN &a, const vecN &b)
constexpr T & get() noexcept
constexpr vecN & operator*=(T t)
constexpr vecN & operator*=(const vecN &v)
constexpr vecN(const vecN< 4, T2 > &v)
constexpr vecN & operator+=(const vecN &v)
constexpr vecN & operator-=(const vecN &v)
constexpr vecN(T a, const vecN< 3, T > &b)
constexpr T & operator[](unsigned i)
constexpr vecN(const vecN< 2, T > &a, const vecN< 2, T > &b)
constexpr T operator[](unsigned i) const
constexpr T get() const noexcept
constexpr vecN(T a, T b, T c, T d)
constexpr vecN(const vecN< 3, T > &a, T b)
constexpr const T * data() const
constexpr vecN< N, T > recip(const vecN< N, T > &x)
constexpr T min_component(const vecN< N, T > &x)
constexpr T dot(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr vecN< 3, T > cross(const vecN< 3, T > &a, const vecN< 3, T > &b)
constexpr vecN< N, int > trunc(const vecN< N, T > &x)
constexpr matMxN< M, N, T > operator*(T x, const matMxN< M, N, T > &A)
T length(const vecN< N, T > &x)
constexpr vecN< N, T > operator/(T x, const vecN< N, T > &y)
vecN< N, int > round(const vecN< N, T > &x)
constexpr T length2(const vecN< N, T > &x)
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr vecN< N, T > dot_broadcast(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr vecN< N, T > sum_broadcast(const vecN< N, T > &x)
constexpr T sum(const vecN< N, T > &x)
std::ostream & operator<<(std::ostream &os, const matMxN< M, N, T > &A)
constexpr matMxN< M, N, T > operator-(const matMxN< M, N, T > &A, const matMxN< M, N, T > &B)
vecN< N, T > normalize(const vecN< N, T > &x)
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr vecN< N, T > clamp(const vecN< N, T > &x, const vecN< N, T > &minVal, const vecN< N, T > &maxVal)
constexpr matMxN< M, N, T > operator+(const matMxN< M, N, T > &A, const matMxN< M, N, T > &B)
constexpr auto xrange(T e)