mirror of
https://github.com/BlackMATov/vmath.hpp.git
synced 2026-02-05 01:23:02 +07:00
131
README.md
131
README.md
@@ -99,6 +99,8 @@ public:
|
||||
template < typename U > vec_base(const vec_base<U, 2>& other);
|
||||
template < typename U > explicit vec_base(const vec_base<U, 3>& other);
|
||||
template < typename U > explicit vec_base(const vec_base<U, 4>& other);
|
||||
|
||||
template < typename U > explicit vec_base(const U* p);
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
@@ -120,6 +122,8 @@ public:
|
||||
|
||||
template < typename U > vec_base(const vec_base<U, 3>& other);
|
||||
template < typename U > explicit vec_base(const vec_base<U, 4>& other);
|
||||
|
||||
template < typename U > explicit vec_base(const U* p);
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
@@ -145,6 +149,8 @@ public:
|
||||
vec_base(T x, const vec_base<T, 3>& yzw);
|
||||
|
||||
template < typename U > vec_base(const vec_base<U, 4>& other);
|
||||
|
||||
template < typename U > explicit vec_base(const U* p);
|
||||
};
|
||||
|
||||
template < typename T, size_t Size >
|
||||
@@ -248,6 +254,8 @@ public:
|
||||
template < typename U > mat_base(const mat_base<U, 2>& other);
|
||||
template < typename U > explicit mat_base(const mat_base<U, 3>& other);
|
||||
template < typename U > explicit mat_base(const mat_base<U, 4>& other);
|
||||
|
||||
template < typename U > explicit mat_base(const U* p);
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
@@ -283,6 +291,8 @@ public:
|
||||
template < typename U > mat_base(const mat_base<U, 3>& other);
|
||||
template < typename U > explicit mat_base(const mat_base<U, 2>& other);
|
||||
template < typename U > explicit mat_base(const mat_base<U, 4>& other);
|
||||
|
||||
template < typename U > explicit mat_base(const U* p);
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
@@ -320,6 +330,8 @@ public:
|
||||
template < typename U > mat_base(const mat_base<U, 4>& other);
|
||||
template < typename U > explicit mat_base(const mat_base<U, 2>& other);
|
||||
template < typename U > explicit mat_base(const mat_base<U, 3>& other);
|
||||
|
||||
template < typename U > explicit mat_base(const U* p);
|
||||
};
|
||||
|
||||
template < typename T, size_t Size >
|
||||
@@ -413,6 +425,8 @@ public:
|
||||
|
||||
template < typename U > qua_base(const qua_base<U, 4>& other);
|
||||
template < typename U > explicit operator vec<U, 4>() const;
|
||||
|
||||
template < typename U > explicit qua_base(const U* p);
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
@@ -645,6 +659,44 @@ vec<T, Size>& operator^=(vec<T, Size>& xs, T y);
|
||||
template < typename T, size_t Size >
|
||||
vec<T, Size>& operator^=(vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
|
||||
// operator<<
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator<<(const vec<T, Size>& xs, T y);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator<<(T x, const vec<T, Size>& ys);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator<<(const vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
|
||||
// operator<<=
|
||||
|
||||
template < typename T, size_t Size >
|
||||
vec<T, Size>& operator<<=(vec<T, Size>& xs, T y);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
vec<T, Size>& operator<<=(vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
|
||||
// operator>>
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator>>(const vec<T, Size>& xs, T y);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator>>(T x, const vec<T, Size>& ys);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator>>(const vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
|
||||
// operator>>=
|
||||
|
||||
template < typename T, size_t Size >
|
||||
vec<T, Size>& operator>>=(vec<T, Size>& xs, T y);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
vec<T, Size>& operator>>=(vec<T, Size>& xs, const vec<T, Size>& ys);
|
||||
|
||||
// operator&&
|
||||
|
||||
template < typename T, size_t Size >
|
||||
@@ -859,6 +911,44 @@ mat<T, Size>& operator^=(mat<T, Size>& xs, T y);
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size>& operator^=(mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
|
||||
// operator<<
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator<<(const mat<T, Size>& xs, T y);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator<<(T x, const mat<T, Size>& ys);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator<<(const mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
|
||||
// operator<<=
|
||||
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size>& operator<<=(mat<T, Size>& xs, T y);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size>& operator<<=(mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
|
||||
// operator>>
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator>>(const mat<T, Size>& xs, T y);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator>>(T x, const mat<T, Size>& ys);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
auto operator>>(const mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
|
||||
// operator>>=
|
||||
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size>& operator>>=(mat<T, Size>& xs, T y);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size>& operator>>=(mat<T, Size>& xs, const mat<T, Size>& ys);
|
||||
|
||||
// operator&&
|
||||
|
||||
template < typename T, size_t Size >
|
||||
@@ -1669,32 +1759,17 @@ vec<U, 4> not_equal_to(const qua<T>& xs, const qua<T>& ys);
|
||||
### Matrix Functions
|
||||
|
||||
```cpp
|
||||
template < typename T >
|
||||
mat<T, 2> transpose(const mat<T, 2>& m);
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size> transpose(const mat<T, Size>& m);
|
||||
|
||||
template < typename T >
|
||||
mat<T, 3> transpose(const mat<T, 3>& m);
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size> adjugate(const mat<T, Size>& m);
|
||||
|
||||
template < typename T >
|
||||
mat<T, 4> transpose(const mat<T, 4>& m);
|
||||
template < typename T, size_t Size >
|
||||
T determinant(const mat<T, Size>& m);
|
||||
|
||||
template < typename T >
|
||||
T determinant(const mat<T, 2>& m);
|
||||
|
||||
template < typename T >
|
||||
T determinant(const mat<T, 3>& m);
|
||||
|
||||
template < typename T >
|
||||
T determinant(const mat<T, 4>& m);
|
||||
|
||||
template < typename T >
|
||||
mat<T, 2> inverse(const mat<T, 2>& m);
|
||||
|
||||
template < typename T >
|
||||
mat<T, 3> inverse(const mat<T, 3>& m);
|
||||
|
||||
template < typename T >
|
||||
mat<T, 4> inverse(const mat<T, 4>& m);
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size> inverse(const mat<T, Size>& m);
|
||||
```
|
||||
|
||||
### Quaternion Functions
|
||||
@@ -1769,13 +1844,13 @@ template < typename T, size_t Size >
|
||||
T component(const vec<T, Size>& v, size_t index);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
vec<T, Size> component(vec<T, Size> v, size_t index, T x);
|
||||
vec<T, Size> component(const vec<T, Size>& v, size_t index, T x);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
vec<T, Size> row(const mat<T, Size>& m, size_t index);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size> row(mat<T, Size> m, size_t index, const vec<T, Size>& v);
|
||||
mat<T, Size> row(const mat<T, Size>& m, size_t index, const vec<T, Size>& v);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
vec<T, Size> column(const mat<T, Size>& m, size_t index);
|
||||
@@ -1783,6 +1858,12 @@ vec<T, Size> column(const mat<T, Size>& m, size_t index);
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size> column(const mat<T, Size>& m, size_t index, const vec<T, Size>& v);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
vec<T, Size> diagonal(const mat<T, Size>& m);
|
||||
|
||||
template < typename T, size_t Size >
|
||||
mat<T, Size> diagonal(const mat<T, Size>& m, const vec<T, Size>& diagonal);
|
||||
|
||||
template < typename T >
|
||||
T real(const qua<T>& q);
|
||||
|
||||
|
||||
@@ -152,9 +152,10 @@ namespace vmath_hpp
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr vec<T, Size> component(vec<T, Size> v, std::size_t index, T component) {
|
||||
v[index] = component;
|
||||
return v;
|
||||
[[nodiscard]] constexpr vec<T, Size> component(const vec<T, Size>& v, std::size_t index, T component) {
|
||||
vec vv = v;
|
||||
vv[index] = component;
|
||||
return vv;
|
||||
}
|
||||
|
||||
// row
|
||||
@@ -165,9 +166,10 @@ namespace vmath_hpp
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<T, Size> row(mat<T, Size> m, std::size_t index, const vec<T, Size>& row) {
|
||||
m.rows[index] = row;
|
||||
return m;
|
||||
[[nodiscard]] constexpr mat<T, Size> row(const mat<T, Size>& m, std::size_t index, const vec<T, Size>& row) {
|
||||
mat mm = m;
|
||||
mm[index] = row;
|
||||
return mm;
|
||||
}
|
||||
|
||||
// column
|
||||
@@ -197,6 +199,31 @@ namespace vmath_hpp
|
||||
return impl::column_impl(m, index, column, std::make_index_sequence<Size>{});
|
||||
}
|
||||
|
||||
// diagonal
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T, std::size_t Size, std::size_t... Is >
|
||||
[[nodiscard]] constexpr vec<T, Size> diagonal_impl(const mat<T, Size>& m, std::index_sequence<Is...>) {
|
||||
return { m[Is][Is]... };
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size, std::size_t... Is >
|
||||
[[nodiscard]] constexpr mat<T, Size> diagonal_impl(const mat<T, Size>& m, const vec<T, Size>& diagonal, std::index_sequence<Is...>) {
|
||||
return { component(m[Is], Is, diagonal[Is])... };
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr vec<T, Size> diagonal(const mat<T, Size>& m) {
|
||||
return impl::diagonal_impl(m, std::make_index_sequence<Size>{});
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<T, Size> diagonal(const mat<T, Size>& m, const vec<T, Size>& diagonal) {
|
||||
return impl::diagonal_impl(m, diagonal, std::make_index_sequence<Size>{});
|
||||
}
|
||||
|
||||
// real
|
||||
|
||||
template < typename T >
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
|
||||
@@ -66,6 +66,11 @@ namespace vmath_hpp::detail
|
||||
constexpr explicit mat_base(const mat_base<U, 4>& other): mat_base(
|
||||
row_type{other.rows[0]},
|
||||
row_type{other.rows[1]}) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit mat_base(const U* p): mat_base(
|
||||
row_type{p + 0u * row_type::size},
|
||||
row_type{p + 1u * row_type::size}) {}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
@@ -134,6 +139,12 @@ namespace vmath_hpp::detail
|
||||
row_type{other.rows[0]},
|
||||
row_type{other.rows[1]},
|
||||
row_type{other.rows[2]}) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit mat_base(const U* p): mat_base(
|
||||
row_type{p + 0u * row_type::size},
|
||||
row_type{p + 1u * row_type::size},
|
||||
row_type{p + 2u * row_type::size}) {}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
@@ -211,6 +222,13 @@ namespace vmath_hpp::detail
|
||||
row_type{other.rows[1], T{0}},
|
||||
row_type{other.rows[2], T{0}},
|
||||
row_type{T{0}, T{0}, T{0}, T{1}}) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit mat_base(const U* p): mat_base(
|
||||
row_type{p + 0u * row_type::size},
|
||||
row_type{p + 1u * row_type::size},
|
||||
row_type{p + 2u * row_type::size},
|
||||
row_type{p + 3u * row_type::size}) {}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -422,6 +422,64 @@ namespace vmath_hpp
|
||||
return (xs = (xs ^ ys));
|
||||
}
|
||||
|
||||
// operator<<
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(const mat<T, Size>& xs, T y) {
|
||||
return map_join([y](const vec<T, Size>& x){ return x << y; }, xs);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(T x, const mat<T, Size>& ys) {
|
||||
return map_join([x](const vec<T, Size>& y){ return x << y; }, ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(const mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return x << y; }, xs, ys);
|
||||
}
|
||||
|
||||
// operator<<=
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size>& operator<<=(mat<T, Size>& xs, T y) {
|
||||
return (xs = (xs << y));
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size>& operator<<=(mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
return (xs = (xs << ys));
|
||||
}
|
||||
|
||||
// operator>>
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(const mat<T, Size>& xs, T y) {
|
||||
return map_join([y](const vec<T, Size>& x){ return x >> y; }, xs);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(T x, const mat<T, Size>& ys) {
|
||||
return map_join([x](const vec<T, Size>& y){ return x >> y; }, ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(const mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return x >> y; }, xs, ys);
|
||||
}
|
||||
|
||||
// operator>>=
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size>& operator>>=(mat<T, Size>& xs, T y) {
|
||||
return (xs = (xs >> y));
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size>& operator>>=(mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
return (xs = (xs >> ys));
|
||||
}
|
||||
|
||||
// operator&&
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
@@ -576,6 +634,10 @@ namespace vmath_hpp
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
//
|
||||
// transpose
|
||||
//
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T >
|
||||
@@ -642,6 +704,98 @@ namespace vmath_hpp
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||
}
|
||||
|
||||
//
|
||||
// adjugate
|
||||
//
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 2> adjugate_2x2_impl(
|
||||
T a, T b,
|
||||
T c, T d)
|
||||
{
|
||||
return {
|
||||
+d, -b,
|
||||
-c, +a};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 3> adjugate_3x3_impl(
|
||||
T a, T b, T c,
|
||||
T d, T e, T f,
|
||||
T g, T h, T i)
|
||||
{
|
||||
return {
|
||||
e * i - f * h,
|
||||
c * h - b * i,
|
||||
b * f - c * e,
|
||||
f * g - d * i,
|
||||
a * i - c * g,
|
||||
c * d - a * f,
|
||||
d * h - e * g,
|
||||
b * g - a * h,
|
||||
a * e - b * d};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 4> adjugate_4x4_impl(
|
||||
T a, T b, T c, T d,
|
||||
T e, T f, T g, T h,
|
||||
T i, T j, T k, T l,
|
||||
T m, T n, T o, T p)
|
||||
{
|
||||
return {
|
||||
f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n),
|
||||
j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n),
|
||||
n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f),
|
||||
b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k),
|
||||
g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p),
|
||||
k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p),
|
||||
o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h),
|
||||
c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k),
|
||||
h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p),
|
||||
l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p),
|
||||
p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h),
|
||||
d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i),
|
||||
e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n),
|
||||
i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n),
|
||||
m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f),
|
||||
a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i)};
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 2> adjugate(const mat<T, 2>& m) {
|
||||
return impl::adjugate_2x2_impl(
|
||||
m[0][0], m[0][1],
|
||||
m[1][0], m[1][1]);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 3> adjugate(const mat<T, 3>& m) {
|
||||
return impl::adjugate_3x3_impl(
|
||||
m[0][0], m[0][1], m[0][2],
|
||||
m[1][0], m[1][1], m[1][2],
|
||||
m[2][0], m[2][1], m[2][2]);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 4> adjugate(const mat<T, 4>& m) {
|
||||
return impl::adjugate_4x4_impl(
|
||||
m[0][0], m[0][1], m[0][2], m[0][3],
|
||||
m[1][0], m[1][1], m[1][2], m[1][3],
|
||||
m[2][0], m[2][1], m[2][2], m[2][3],
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||
}
|
||||
|
||||
//
|
||||
// determinant
|
||||
//
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T >
|
||||
@@ -650,12 +804,7 @@ namespace vmath_hpp
|
||||
T a, T b,
|
||||
T c, T d)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/determinant/twoD/
|
||||
|
||||
return
|
||||
+ a * d
|
||||
- b * c;
|
||||
return a * d - b * c;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
@@ -665,14 +814,10 @@ namespace vmath_hpp
|
||||
T d, T e, T f,
|
||||
T g, T h, T i)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/determinant/threeD/
|
||||
|
||||
return
|
||||
+ a * determinant_2x2_impl(e, f, h, i)
|
||||
- b * determinant_2x2_impl(d, f, g, i)
|
||||
+ c * determinant_2x2_impl(d, e, g, h);
|
||||
|
||||
+ a * (e * i - f * h)
|
||||
- b * (d * i - f * g)
|
||||
+ c * (d * h - e * g);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
@@ -683,14 +828,11 @@ namespace vmath_hpp
|
||||
T i, T j, T k, T l,
|
||||
T m, T n, T o, T p)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/determinant/fourD/
|
||||
|
||||
return
|
||||
+ a * determinant_3x3_impl(f, g, h, j, k, l, n, o, p)
|
||||
- b * determinant_3x3_impl(e, g, h, i, k, l, m, o, p)
|
||||
+ c * determinant_3x3_impl(e, f, h, i, j, l, m, n, p)
|
||||
- d * determinant_3x3_impl(e, f, g, i, j, k, m, n, o);
|
||||
+ a * (f * (k * p - l * o) - (j * (g * p - h * o)) + (n * (g * l - h * k)))
|
||||
- b * (e * (k * p - l * o) - (i * (g * p - h * o)) + (m * (g * l - h * k)))
|
||||
+ c * (e * (j * p - l * n) - (i * (f * p - h * n)) + (m * (f * l - h * j)))
|
||||
- d * (e * (j * o - k * n) - (i * (f * o - g * n)) + (m * (f * k - g * j)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,117 +860,12 @@ namespace vmath_hpp
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||
}
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 2> inverse_2x2_impl(
|
||||
T a, T b,
|
||||
T c, T d)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/twoD/
|
||||
//
|
||||
// inverse
|
||||
//
|
||||
|
||||
const T inv_det = rcp(determinant_2x2_impl(
|
||||
a, b,
|
||||
c, d));
|
||||
|
||||
const mat inv_m{
|
||||
d, -b,
|
||||
-c, a};
|
||||
|
||||
return inv_m * inv_det;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 3> inverse_3x3_impl(
|
||||
T a, T b, T c,
|
||||
T d, T e, T f,
|
||||
T g, T h, T i)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/threeD/
|
||||
|
||||
const T inv_det = rcp(determinant_3x3_impl(
|
||||
a, b, c,
|
||||
d, e, f,
|
||||
g, h, i));
|
||||
|
||||
const mat inv_m{
|
||||
e * i - f * h,
|
||||
c * h - b * i,
|
||||
b * f - c * e,
|
||||
f * g - d * i,
|
||||
a * i - c * g,
|
||||
c * d - a * f,
|
||||
d * h - e * g,
|
||||
b * g - a * h,
|
||||
a * e - b * d};
|
||||
|
||||
return inv_m * inv_det;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 4> inverse_4x4_impl(
|
||||
T a, T b, T c, T d,
|
||||
T e, T f, T g, T h,
|
||||
T i, T j, T k, T l,
|
||||
T m, T n, T o, T p)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/
|
||||
|
||||
const T inv_det = rcp(determinant_4x4_impl(
|
||||
a, b, c, d,
|
||||
e, f, g, h,
|
||||
i, j, k, l,
|
||||
m, n, o, p));
|
||||
|
||||
const mat inv_m{
|
||||
(f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n)),
|
||||
(j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n)),
|
||||
(n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f)),
|
||||
(b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k)),
|
||||
(g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p)),
|
||||
(k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p)),
|
||||
(o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h)),
|
||||
(c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k)),
|
||||
(h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p)),
|
||||
(l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p)),
|
||||
(p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h)),
|
||||
(d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i)),
|
||||
(e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n)),
|
||||
(i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n)),
|
||||
(m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f)),
|
||||
(a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i))};
|
||||
|
||||
return inv_m * inv_det;
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 2> inverse(const mat<T, 2>& m) {
|
||||
return impl::inverse_2x2_impl(
|
||||
m[0][0], m[0][1],
|
||||
m[1][0], m[1][1]);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 3> inverse(const mat<T, 3>& m) {
|
||||
return impl::inverse_3x3_impl(
|
||||
m[0][0], m[0][1], m[0][2],
|
||||
m[1][0], m[1][1], m[1][2],
|
||||
m[2][0], m[2][1], m[2][2]);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 4> inverse(const mat<T, 4>& m) {
|
||||
return impl::inverse_4x4_impl(
|
||||
m[0][0], m[0][1], m[0][2], m[0][3],
|
||||
m[1][0], m[1][1], m[1][2], m[1][3],
|
||||
m[2][0], m[2][1], m[2][2], m[2][3],
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<T, Size> inverse(const mat<T, Size>& m) {
|
||||
return adjugate(m) * rcp(determinant(m));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ namespace vmath_hpp::detail
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<T, U>, int> = 0 >
|
||||
constexpr explicit operator vec<U, 4>() const { return vec<U, 4>(v, s); }
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit qua_base(const U* p): qua_base(p[0], p[1], p[2], p[3]) {}
|
||||
|
||||
[[nodiscard]] constexpr T& operator[](std::size_t index) noexcept {
|
||||
switch ( index ) {
|
||||
default:
|
||||
|
||||
@@ -37,6 +37,9 @@ namespace vmath_hpp::detail
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit vec_base(const vec_base<U, 4>& other): vec_base(other[0], other[1]) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit vec_base(const U* p): vec_base(p[0], p[1]) {}
|
||||
|
||||
[[nodiscard]] constexpr T& operator[](std::size_t index) noexcept {
|
||||
switch ( index ) {
|
||||
default:
|
||||
@@ -78,6 +81,9 @@ namespace vmath_hpp::detail
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit vec_base(const vec_base<U, 4>& other): vec_base(other[0], other[1], other[2]) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit vec_base(const U* p): vec_base(p[0], p[1], p[2]) {}
|
||||
|
||||
[[nodiscard]] constexpr T& operator[](std::size_t index) noexcept {
|
||||
switch ( index ) {
|
||||
default:
|
||||
@@ -123,6 +129,9 @@ namespace vmath_hpp::detail
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr vec_base(const vec_base<U, 4>& other): vec_base(other[0], other[1], other[2], other[3]) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit vec_base(const U* p): vec_base(p[0], p[1], p[2], p[3]) {}
|
||||
|
||||
[[nodiscard]] constexpr T& operator[](std::size_t index) noexcept {
|
||||
switch ( index ) {
|
||||
default:
|
||||
|
||||
@@ -473,6 +473,64 @@ namespace vmath_hpp
|
||||
return (xs = (xs ^ ys));
|
||||
}
|
||||
|
||||
// operator<<
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(const vec<T, Size>& xs, T y) {
|
||||
return map_join([y](T x){ return x << y; }, xs);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(T x, const vec<T, Size>& ys) {
|
||||
return map_join([x](T y){ return x << y; }, ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return map_join([](T x, T y){ return x << y; }, xs, ys);
|
||||
}
|
||||
|
||||
// operator<<=
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size>& operator<<=(vec<T, Size>& xs, T y) {
|
||||
return (xs = (xs << y));
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size>& operator<<=(vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return (xs = (xs << ys));
|
||||
}
|
||||
|
||||
// operator>>
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(const vec<T, Size>& xs, T y) {
|
||||
return map_join([y](T x){ return x >> y; }, xs);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(T x, const vec<T, Size>& ys) {
|
||||
return map_join([x](T y){ return x >> y; }, ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return map_join([](T x, T y){ return x >> y; }, xs, ys);
|
||||
}
|
||||
|
||||
// operator>>=
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size>& operator>>=(vec<T, Size>& xs, T y) {
|
||||
return (xs = (xs >> y));
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size>& operator>>=(vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return (xs = (xs >> ys));
|
||||
}
|
||||
|
||||
// operator&&
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
@@ -590,6 +591,9 @@ namespace vmath_hpp::detail
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit vec_base(const vec_base<U, 4>& other): vec_base(other[0], other[1]) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit vec_base(const U* p): vec_base(p[0], p[1]) {}
|
||||
|
||||
[[nodiscard]] constexpr T& operator[](std::size_t index) noexcept {
|
||||
switch ( index ) {
|
||||
default:
|
||||
@@ -631,6 +635,9 @@ namespace vmath_hpp::detail
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit vec_base(const vec_base<U, 4>& other): vec_base(other[0], other[1], other[2]) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit vec_base(const U* p): vec_base(p[0], p[1], p[2]) {}
|
||||
|
||||
[[nodiscard]] constexpr T& operator[](std::size_t index) noexcept {
|
||||
switch ( index ) {
|
||||
default:
|
||||
@@ -676,6 +683,9 @@ namespace vmath_hpp::detail
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr vec_base(const vec_base<U, 4>& other): vec_base(other[0], other[1], other[2], other[3]) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit vec_base(const U* p): vec_base(p[0], p[1], p[2], p[3]) {}
|
||||
|
||||
[[nodiscard]] constexpr T& operator[](std::size_t index) noexcept {
|
||||
switch ( index ) {
|
||||
default:
|
||||
@@ -1276,6 +1286,64 @@ namespace vmath_hpp
|
||||
return (xs = (xs ^ ys));
|
||||
}
|
||||
|
||||
// operator<<
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(const vec<T, Size>& xs, T y) {
|
||||
return map_join([y](T x){ return x << y; }, xs);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(T x, const vec<T, Size>& ys) {
|
||||
return map_join([x](T y){ return x << y; }, ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return map_join([](T x, T y){ return x << y; }, xs, ys);
|
||||
}
|
||||
|
||||
// operator<<=
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size>& operator<<=(vec<T, Size>& xs, T y) {
|
||||
return (xs = (xs << y));
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size>& operator<<=(vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return (xs = (xs << ys));
|
||||
}
|
||||
|
||||
// operator>>
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(const vec<T, Size>& xs, T y) {
|
||||
return map_join([y](T x){ return x >> y; }, xs);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(T x, const vec<T, Size>& ys) {
|
||||
return map_join([x](T y){ return x >> y; }, ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(const vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return map_join([](T x, T y){ return x >> y; }, xs, ys);
|
||||
}
|
||||
|
||||
// operator>>=
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size>& operator>>=(vec<T, Size>& xs, T y) {
|
||||
return (xs = (xs >> y));
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size>& operator>>=(vec<T, Size>& xs, const vec<T, Size>& ys) {
|
||||
return (xs = (xs >> ys));
|
||||
}
|
||||
|
||||
// operator&&
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
@@ -1884,6 +1952,11 @@ namespace vmath_hpp::detail
|
||||
constexpr explicit mat_base(const mat_base<U, 4>& other): mat_base(
|
||||
row_type{other.rows[0]},
|
||||
row_type{other.rows[1]}) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit mat_base(const U* p): mat_base(
|
||||
row_type{p + 0u * row_type::size},
|
||||
row_type{p + 1u * row_type::size}) {}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
@@ -1952,6 +2025,12 @@ namespace vmath_hpp::detail
|
||||
row_type{other.rows[0]},
|
||||
row_type{other.rows[1]},
|
||||
row_type{other.rows[2]}) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit mat_base(const U* p): mat_base(
|
||||
row_type{p + 0u * row_type::size},
|
||||
row_type{p + 1u * row_type::size},
|
||||
row_type{p + 2u * row_type::size}) {}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
@@ -2029,6 +2108,13 @@ namespace vmath_hpp::detail
|
||||
row_type{other.rows[1], T{0}},
|
||||
row_type{other.rows[2], T{0}},
|
||||
row_type{T{0}, T{0}, T{0}, T{1}}) {}
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit mat_base(const U* p): mat_base(
|
||||
row_type{p + 0u * row_type::size},
|
||||
row_type{p + 1u * row_type::size},
|
||||
row_type{p + 2u * row_type::size},
|
||||
row_type{p + 3u * row_type::size}) {}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2566,6 +2652,64 @@ namespace vmath_hpp
|
||||
return (xs = (xs ^ ys));
|
||||
}
|
||||
|
||||
// operator<<
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(const mat<T, Size>& xs, T y) {
|
||||
return map_join([y](const vec<T, Size>& x){ return x << y; }, xs);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(T x, const mat<T, Size>& ys) {
|
||||
return map_join([x](const vec<T, Size>& y){ return x << y; }, ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator<<(const mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return x << y; }, xs, ys);
|
||||
}
|
||||
|
||||
// operator<<=
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size>& operator<<=(mat<T, Size>& xs, T y) {
|
||||
return (xs = (xs << y));
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size>& operator<<=(mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
return (xs = (xs << ys));
|
||||
}
|
||||
|
||||
// operator>>
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(const mat<T, Size>& xs, T y) {
|
||||
return map_join([y](const vec<T, Size>& x){ return x >> y; }, xs);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(T x, const mat<T, Size>& ys) {
|
||||
return map_join([x](const vec<T, Size>& y){ return x >> y; }, ys);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr auto operator>>(const mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
return map_join([](const vec<T, Size>& x, const vec<T, Size>& y){ return x >> y; }, xs, ys);
|
||||
}
|
||||
|
||||
// operator>>=
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size>& operator>>=(mat<T, Size>& xs, T y) {
|
||||
return (xs = (xs >> y));
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size>& operator>>=(mat<T, Size>& xs, const mat<T, Size>& ys) {
|
||||
return (xs = (xs >> ys));
|
||||
}
|
||||
|
||||
// operator&&
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
@@ -2720,6 +2864,10 @@ namespace vmath_hpp
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
//
|
||||
// transpose
|
||||
//
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T >
|
||||
@@ -2786,6 +2934,98 @@ namespace vmath_hpp
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||
}
|
||||
|
||||
//
|
||||
// adjugate
|
||||
//
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 2> adjugate_2x2_impl(
|
||||
T a, T b,
|
||||
T c, T d)
|
||||
{
|
||||
return {
|
||||
+d, -b,
|
||||
-c, +a};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 3> adjugate_3x3_impl(
|
||||
T a, T b, T c,
|
||||
T d, T e, T f,
|
||||
T g, T h, T i)
|
||||
{
|
||||
return {
|
||||
e * i - f * h,
|
||||
c * h - b * i,
|
||||
b * f - c * e,
|
||||
f * g - d * i,
|
||||
a * i - c * g,
|
||||
c * d - a * f,
|
||||
d * h - e * g,
|
||||
b * g - a * h,
|
||||
a * e - b * d};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 4> adjugate_4x4_impl(
|
||||
T a, T b, T c, T d,
|
||||
T e, T f, T g, T h,
|
||||
T i, T j, T k, T l,
|
||||
T m, T n, T o, T p)
|
||||
{
|
||||
return {
|
||||
f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n),
|
||||
j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n),
|
||||
n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f),
|
||||
b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k),
|
||||
g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p),
|
||||
k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p),
|
||||
o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h),
|
||||
c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k),
|
||||
h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p),
|
||||
l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p),
|
||||
p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h),
|
||||
d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i),
|
||||
e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n),
|
||||
i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n),
|
||||
m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f),
|
||||
a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i)};
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 2> adjugate(const mat<T, 2>& m) {
|
||||
return impl::adjugate_2x2_impl(
|
||||
m[0][0], m[0][1],
|
||||
m[1][0], m[1][1]);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 3> adjugate(const mat<T, 3>& m) {
|
||||
return impl::adjugate_3x3_impl(
|
||||
m[0][0], m[0][1], m[0][2],
|
||||
m[1][0], m[1][1], m[1][2],
|
||||
m[2][0], m[2][1], m[2][2]);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 4> adjugate(const mat<T, 4>& m) {
|
||||
return impl::adjugate_4x4_impl(
|
||||
m[0][0], m[0][1], m[0][2], m[0][3],
|
||||
m[1][0], m[1][1], m[1][2], m[1][3],
|
||||
m[2][0], m[2][1], m[2][2], m[2][3],
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||
}
|
||||
|
||||
//
|
||||
// determinant
|
||||
//
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T >
|
||||
@@ -2794,12 +3034,7 @@ namespace vmath_hpp
|
||||
T a, T b,
|
||||
T c, T d)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/determinant/twoD/
|
||||
|
||||
return
|
||||
+ a * d
|
||||
- b * c;
|
||||
return a * d - b * c;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
@@ -2809,14 +3044,10 @@ namespace vmath_hpp
|
||||
T d, T e, T f,
|
||||
T g, T h, T i)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/determinant/threeD/
|
||||
|
||||
return
|
||||
+ a * determinant_2x2_impl(e, f, h, i)
|
||||
- b * determinant_2x2_impl(d, f, g, i)
|
||||
+ c * determinant_2x2_impl(d, e, g, h);
|
||||
|
||||
+ a * (e * i - f * h)
|
||||
- b * (d * i - f * g)
|
||||
+ c * (d * h - e * g);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
@@ -2827,14 +3058,11 @@ namespace vmath_hpp
|
||||
T i, T j, T k, T l,
|
||||
T m, T n, T o, T p)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/determinant/fourD/
|
||||
|
||||
return
|
||||
+ a * determinant_3x3_impl(f, g, h, j, k, l, n, o, p)
|
||||
- b * determinant_3x3_impl(e, g, h, i, k, l, m, o, p)
|
||||
+ c * determinant_3x3_impl(e, f, h, i, j, l, m, n, p)
|
||||
- d * determinant_3x3_impl(e, f, g, i, j, k, m, n, o);
|
||||
+ a * (f * (k * p - l * o) - (j * (g * p - h * o)) + (n * (g * l - h * k)))
|
||||
- b * (e * (k * p - l * o) - (i * (g * p - h * o)) + (m * (g * l - h * k)))
|
||||
+ c * (e * (j * p - l * n) - (i * (f * p - h * n)) + (m * (f * l - h * j)))
|
||||
- d * (e * (j * o - k * n) - (i * (f * o - g * n)) + (m * (f * k - g * j)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2862,118 +3090,13 @@ namespace vmath_hpp
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||
}
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 2> inverse_2x2_impl(
|
||||
T a, T b,
|
||||
T c, T d)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/twoD/
|
||||
//
|
||||
// inverse
|
||||
//
|
||||
|
||||
const T inv_det = rcp(determinant_2x2_impl(
|
||||
a, b,
|
||||
c, d));
|
||||
|
||||
const mat inv_m{
|
||||
d, -b,
|
||||
-c, a};
|
||||
|
||||
return inv_m * inv_det;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 3> inverse_3x3_impl(
|
||||
T a, T b, T c,
|
||||
T d, T e, T f,
|
||||
T g, T h, T i)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/threeD/
|
||||
|
||||
const T inv_det = rcp(determinant_3x3_impl(
|
||||
a, b, c,
|
||||
d, e, f,
|
||||
g, h, i));
|
||||
|
||||
const mat inv_m{
|
||||
e * i - f * h,
|
||||
c * h - b * i,
|
||||
b * f - c * e,
|
||||
f * g - d * i,
|
||||
a * i - c * g,
|
||||
c * d - a * f,
|
||||
d * h - e * g,
|
||||
b * g - a * h,
|
||||
a * e - b * d};
|
||||
|
||||
return inv_m * inv_det;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
|
||||
mat<T, 4> inverse_4x4_impl(
|
||||
T a, T b, T c, T d,
|
||||
T e, T f, T g, T h,
|
||||
T i, T j, T k, T l,
|
||||
T m, T n, T o, T p)
|
||||
{
|
||||
/// REFERENCE:
|
||||
/// http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/
|
||||
|
||||
const T inv_det = rcp(determinant_4x4_impl(
|
||||
a, b, c, d,
|
||||
e, f, g, h,
|
||||
i, j, k, l,
|
||||
m, n, o, p));
|
||||
|
||||
const mat inv_m{
|
||||
(f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n)),
|
||||
(j * (c * p - d * o) + k * (d * n - b * p) + l * (b * o - c * n)),
|
||||
(n * (c * h - d * g) + o * (d * f - b * h) + p * (b * g - c * f)),
|
||||
(b * (h * k - g * l) + c * (f * l - h * j) + d * (g * j - f * k)),
|
||||
(g * (i * p - l * m) + h * (k * m - i * o) + e * (l * o - k * p)),
|
||||
(k * (a * p - d * m) + l * (c * m - a * o) + i * (d * o - c * p)),
|
||||
(o * (a * h - d * e) + p * (c * e - a * g) + m * (d * g - c * h)),
|
||||
(c * (h * i - e * l) + d * (e * k - g * i) + a * (g * l - h * k)),
|
||||
(h * (i * n - j * m) + e * (j * p - l * n) + f * (l * m - i * p)),
|
||||
(l * (a * n - b * m) + i * (b * p - d * n) + j * (d * m - a * p)),
|
||||
(p * (a * f - b * e) + m * (b * h - d * f) + n * (d * e - a * h)),
|
||||
(d * (f * i - e * j) + a * (h * j - f * l) + b * (e * l - h * i)),
|
||||
(e * (k * n - j * o) + f * (i * o - k * m) + g * (j * m - i * n)),
|
||||
(i * (c * n - b * o) + j * (a * o - c * m) + k * (b * m - a * n)),
|
||||
(m * (c * f - b * g) + n * (a * g - c * e) + o * (b * e - a * f)),
|
||||
(a * (f * k - g * j) + b * (g * i - e * k) + c * (e * j - f * i))};
|
||||
|
||||
return inv_m * inv_det;
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 2> inverse(const mat<T, 2>& m) {
|
||||
return impl::inverse_2x2_impl(
|
||||
m[0][0], m[0][1],
|
||||
m[1][0], m[1][1]);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 3> inverse(const mat<T, 3>& m) {
|
||||
return impl::inverse_3x3_impl(
|
||||
m[0][0], m[0][1], m[0][2],
|
||||
m[1][0], m[1][1], m[1][2],
|
||||
m[2][0], m[2][1], m[2][2]);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr mat<T, 4> inverse(const mat<T, 4>& m) {
|
||||
return impl::inverse_4x4_impl(
|
||||
m[0][0], m[0][1], m[0][2], m[0][3],
|
||||
m[1][0], m[1][1], m[1][2], m[1][3],
|
||||
m[2][0], m[2][1], m[2][2], m[2][3],
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]);
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<T, Size> inverse(const mat<T, Size>& m) {
|
||||
return adjugate(m) * rcp(determinant(m));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3002,6 +3125,9 @@ namespace vmath_hpp::detail
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<T, U>, int> = 0 >
|
||||
constexpr explicit operator vec<U, 4>() const { return vec<U, 4>(v, s); }
|
||||
|
||||
template < typename U, std::enable_if_t<std::is_convertible_v<U, T>, int> = 0 >
|
||||
constexpr explicit qua_base(const U* p): qua_base(p[0], p[1], p[2], p[3]) {}
|
||||
|
||||
[[nodiscard]] constexpr T& operator[](std::size_t index) noexcept {
|
||||
switch ( index ) {
|
||||
default:
|
||||
@@ -3612,9 +3738,10 @@ namespace vmath_hpp
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr vec<T, Size> component(vec<T, Size> v, std::size_t index, T component) {
|
||||
v[index] = component;
|
||||
return v;
|
||||
[[nodiscard]] constexpr vec<T, Size> component(const vec<T, Size>& v, std::size_t index, T component) {
|
||||
vec vv = v;
|
||||
vv[index] = component;
|
||||
return vv;
|
||||
}
|
||||
|
||||
// row
|
||||
@@ -3625,9 +3752,10 @@ namespace vmath_hpp
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<T, Size> row(mat<T, Size> m, std::size_t index, const vec<T, Size>& row) {
|
||||
m.rows[index] = row;
|
||||
return m;
|
||||
[[nodiscard]] constexpr mat<T, Size> row(const mat<T, Size>& m, std::size_t index, const vec<T, Size>& row) {
|
||||
mat mm = m;
|
||||
mm[index] = row;
|
||||
return mm;
|
||||
}
|
||||
|
||||
// column
|
||||
@@ -3657,6 +3785,31 @@ namespace vmath_hpp
|
||||
return impl::column_impl(m, index, column, std::make_index_sequence<Size>{});
|
||||
}
|
||||
|
||||
// diagonal
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T, std::size_t Size, std::size_t... Is >
|
||||
[[nodiscard]] constexpr vec<T, Size> diagonal_impl(const mat<T, Size>& m, std::index_sequence<Is...>) {
|
||||
return { m[Is][Is]... };
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size, std::size_t... Is >
|
||||
[[nodiscard]] constexpr mat<T, Size> diagonal_impl(const mat<T, Size>& m, const vec<T, Size>& diagonal, std::index_sequence<Is...>) {
|
||||
return { component(m[Is], Is, diagonal[Is])... };
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr vec<T, Size> diagonal(const mat<T, Size>& m) {
|
||||
return impl::diagonal_impl(m, std::make_index_sequence<Size>{});
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
[[nodiscard]] constexpr mat<T, Size> diagonal(const mat<T, Size>& m, const vec<T, Size>& diagonal) {
|
||||
return impl::diagonal_impl(m, diagonal, std::make_index_sequence<Size>{});
|
||||
}
|
||||
|
||||
// real
|
||||
|
||||
template < typename T >
|
||||
|
||||
@@ -205,6 +205,14 @@ TEST_CASE("vmath/ext/access") {
|
||||
STATIC_CHECK(column(imat2(), 1, {3,4}) == imat2(1,3,0,4));
|
||||
}
|
||||
|
||||
SUBCASE("diagonal") {
|
||||
STATIC_CHECK(diagonal(imat2(1,2,3,4)) == ivec2(1,4));
|
||||
STATIC_CHECK(diagonal(imat2(1,2,3,4), ivec2(10,40)) == imat2(10,2,3,40));
|
||||
|
||||
STATIC_CHECK(diagonal(imat3(1,2,3,4,5,6,7,8,9)) == ivec3(1,5,9));
|
||||
STATIC_CHECK(diagonal(imat3(1,2,3,4,5,6,7,8,9), ivec3(10,50,90)) == imat3(10,2,3,4,50,6,7,8,90));
|
||||
}
|
||||
|
||||
SUBCASE("real") {
|
||||
STATIC_CHECK(real(qua{1,2,3,4}) == 4);
|
||||
STATIC_CHECK(real(qua{1,2,3,4}, 5) == qua{1,2,3,5});
|
||||
|
||||
@@ -336,6 +336,10 @@ namespace vmath_hpp
|
||||
template fix3x3f transpose(const fix3x3f&);
|
||||
template fix4x4f transpose(const fix4x4f&);
|
||||
|
||||
template fix2x2f adjugate(const fix2x2f&);
|
||||
template fix3x3f adjugate(const fix3x3f&);
|
||||
template fix4x4f adjugate(const fix4x4f&);
|
||||
|
||||
template fix<float> determinant(const fix2x2f&);
|
||||
template fix<float> determinant(const fix3x3f&);
|
||||
template fix<float> determinant(const fix4x4f&);
|
||||
@@ -362,10 +366,10 @@ namespace vmath_hpp
|
||||
namespace vmath_hpp
|
||||
{
|
||||
template fix<float> component(const fix2f&, std::size_t);
|
||||
template fix2f component(fix2f, std::size_t, fix<float>);
|
||||
template fix2f component(const fix2f&, std::size_t, fix<float>);
|
||||
|
||||
template fix2f row(const fix2x2f&, std::size_t);
|
||||
template fix2x2f row(fix2x2f, std::size_t, const fix2f&);
|
||||
template fix2x2f row(const fix2x2f&, std::size_t, const fix2f&);
|
||||
|
||||
template fix2f column(const fix2x2f&, std::size_t);
|
||||
template fix2x2f column(const fix2x2f&, std::size_t, const fix2f&);
|
||||
|
||||
@@ -43,6 +43,8 @@ TEST_CASE("vmath/mat_fun") {
|
||||
STATIC_CHECK((imat2(11,12,11,12) & 6) == imat2(2,4,2,4));
|
||||
STATIC_CHECK((imat2(11,12,11,12) | 6) == imat2(15,14,15,14));
|
||||
STATIC_CHECK((imat2(11,12,11,12) ^ 6) == imat2(13,10,13,10));
|
||||
STATIC_CHECK((imat2(1,2,3,4) << 2) == imat2(4,8,12,16));
|
||||
STATIC_CHECK((imat2(4,8,12,16) >> 2) == imat2(1,2,3,4));
|
||||
STATIC_CHECK((imat2(1,0,1,0) && 1) == bmat2(1,0,1,0));
|
||||
STATIC_CHECK((imat2(1,0,1,0) || 1) == bmat2(1,1,1,1));
|
||||
|
||||
@@ -53,6 +55,8 @@ TEST_CASE("vmath/mat_fun") {
|
||||
STATIC_CHECK((6 &imat2(11,12,11,12)) == imat2(2,4,2,4));
|
||||
STATIC_CHECK((6 |imat2(11,12,11,12)) == imat2(15,14,15,14));
|
||||
STATIC_CHECK((6 ^ imat2(11,12,11,12)) == imat2(13,10,13,10));
|
||||
STATIC_CHECK((2 << imat2(1,2,3,4)) == imat2(4,8,16,32));
|
||||
STATIC_CHECK((16 >> imat2(1,2,3,4)) == imat2(8,4,2,1));
|
||||
STATIC_CHECK((1 && imat2(1,0,1,0)) == bmat2(1,0,1,0));
|
||||
STATIC_CHECK((1 || imat2(1,0,1,0)) == bmat2(1,1,1,1));
|
||||
|
||||
@@ -149,6 +153,20 @@ TEST_CASE("vmath/mat_fun") {
|
||||
CHECK(&v2 == &(v2 ^= imat2(11,12,11,12)));
|
||||
CHECK(v2 == imat2(13,11,13,11));
|
||||
}
|
||||
{
|
||||
imat2 v1{2,3,4,5};
|
||||
CHECK(&v1 == &(v1 <<= 2));
|
||||
CHECK(v1 == imat2(8,12,16,20));
|
||||
CHECK(&v1 == &(v1 <<= imat2(1,2,3,4)));
|
||||
CHECK(v1 == imat2(16,48,128,320));
|
||||
}
|
||||
{
|
||||
imat2 v1{16,48,128,320};
|
||||
CHECK(&v1 == &(v1 >>= 2));
|
||||
CHECK(v1 == imat2(4,12,32,80));
|
||||
CHECK(&v1 == &(v1 >>= imat2(1,2,3,4)));
|
||||
CHECK(v1 == imat2(2,3,4,5));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Operators2") {
|
||||
|
||||
@@ -126,6 +126,12 @@ TEST_CASE("vmath/mat") {
|
||||
STATIC_CHECK(imat4(imat2({1,2},{3,4})) == imat4(1,2,0,0,3,4,0,0,0,0,1,0,0,0,0,1));
|
||||
STATIC_CHECK(imat4(imat3({1,2,3},{4,5,6},{7,8,9})) == imat4(1,2,3,0,4,5,6,0,7,8,9,0,0,0,0,1));
|
||||
}
|
||||
{
|
||||
constexpr float is[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
|
||||
STATIC_CHECK(dmat2(is) == dmat2(1,2,3,4));
|
||||
STATIC_CHECK(dmat3(is) == dmat3(1,2,3,4,5,6,7,8,9));
|
||||
STATIC_CHECK(dmat4(is) == dmat4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("operator=") {
|
||||
|
||||
@@ -68,6 +68,10 @@ TEST_CASE("vmath/qua") {
|
||||
STATIC_CHECK(fqua(fvec3(1,2,3),4) == fqua(1,2,3,4));
|
||||
STATIC_CHECK(fqua(fvec4(1,2,3,4)) == fqua(1,2,3,4));
|
||||
}
|
||||
{
|
||||
constexpr float is[] = {1,2,3,4};
|
||||
STATIC_CHECK(dqua(is) == dqua(1,2,3,4));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("operator=") {
|
||||
|
||||
@@ -26,6 +26,8 @@ TEST_CASE("vmath/vec_fun") {
|
||||
STATIC_CHECK((ivec2(11,12) & 6) == ivec2(2,4));
|
||||
STATIC_CHECK((ivec2(11,12) | 6) == ivec2(15,14));
|
||||
STATIC_CHECK((ivec2(11,12) ^ 6) == ivec2(13,10));
|
||||
STATIC_CHECK((ivec2(11,12) << 2) == ivec2(44,48));
|
||||
STATIC_CHECK((ivec2(11,12) >> 2) == ivec2(2,3));
|
||||
STATIC_CHECK((ivec2(1,0) && 1) == bvec2(1,0));
|
||||
STATIC_CHECK((ivec2(1,0) || 1) == bvec2(1,1));
|
||||
|
||||
@@ -36,6 +38,8 @@ TEST_CASE("vmath/vec_fun") {
|
||||
STATIC_CHECK((6 & ivec2(11,12)) == ivec2(2,4));
|
||||
STATIC_CHECK((6 | ivec2(11,12)) == ivec2(15,14));
|
||||
STATIC_CHECK((6 ^ ivec2(11,12)) == ivec2(13,10));
|
||||
STATIC_CHECK((2 << ivec2(3,4)) == ivec2(16,32));
|
||||
STATIC_CHECK((48 >> ivec2(3,4)) == ivec2(6,3));
|
||||
STATIC_CHECK((1 && ivec2(1,0)) == bvec2(1,0));
|
||||
STATIC_CHECK((1 || ivec2(1,0)) == bvec2(1,1));
|
||||
|
||||
@@ -46,6 +50,8 @@ TEST_CASE("vmath/vec_fun") {
|
||||
STATIC_CHECK((ivec2(6,7) & ivec2(11,12)) == ivec2(2,4));
|
||||
STATIC_CHECK((ivec2(6,7) | ivec2(11,12)) == ivec2(15,15));
|
||||
STATIC_CHECK((ivec2(6,7) ^ ivec2(11,12)) == ivec2(13,11));
|
||||
STATIC_CHECK((ivec2(11,6) << ivec2(2,3)) == ivec2(44,48));
|
||||
STATIC_CHECK((ivec2(44,48) >> ivec2(2,3)) == ivec2(11,6));
|
||||
STATIC_CHECK((ivec2(0,1) && ivec2(1,0)) == bvec2(0,0));
|
||||
STATIC_CHECK((ivec2(0,1) || ivec2(1,0)) == bvec2(1,1));
|
||||
|
||||
@@ -115,6 +121,20 @@ TEST_CASE("vmath/vec_fun") {
|
||||
CHECK(&v2 == &(v2 ^= ivec2(11,12)));
|
||||
CHECK(v2 == ivec2(13,11));
|
||||
}
|
||||
{
|
||||
ivec2 v1{2,3};
|
||||
CHECK(&v1 == &(v1 <<= 2));
|
||||
CHECK(v1 == ivec2(8,12));
|
||||
CHECK(&v1 == &(v1 <<= ivec2(2,3)));
|
||||
CHECK(v1 == ivec2(32,96));
|
||||
}
|
||||
{
|
||||
ivec2 v1{32,96};
|
||||
CHECK(&v1 == &(v1 >>= 2));
|
||||
CHECK(v1 == ivec2(8,24));
|
||||
CHECK(&v1 == &(v1 >>= ivec2(2,3)));
|
||||
CHECK(v1 == ivec2(2,3));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Operators2") {
|
||||
|
||||
@@ -115,6 +115,12 @@ TEST_CASE("vmath/vec") {
|
||||
STATIC_CHECK(ivec4(ivec3(1,2,3),4) == ivec4(1,2,3,4));
|
||||
STATIC_CHECK(ivec4(1,ivec3(2,3,4)) == ivec4(1,2,3,4));
|
||||
}
|
||||
{
|
||||
constexpr float is[] = {1,2,3,4};
|
||||
STATIC_CHECK(dvec2(is) == dvec2(1,2));
|
||||
STATIC_CHECK(dvec3(is) == dvec3(1,2,3));
|
||||
STATIC_CHECK(dvec4(is) == dvec4(1,2,3,4));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("operator=") {
|
||||
|
||||
Reference in New Issue
Block a user