Merge pull request #17 from BlackMATov/dev

Dev
This commit is contained in:
2021-02-27 08:07:09 +07:00
committed by GitHub
14 changed files with 5685 additions and 1435 deletions

View File

@@ -11,6 +11,10 @@ add_library(${PROJECT_NAME} INTERFACE)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17)
target_include_directories(${PROJECT_NAME} INTERFACE headers)
add_library(${PROJECT_NAME}.singles INTERFACE)
target_compile_features(${PROJECT_NAME}.singles INTERFACE cxx_std_17)
target_include_directories(${PROJECT_NAME}.singles INTERFACE singles)
if(BUILD_AS_STANDALONE)
option(BUILD_WITH_UNTESTS "Build with unit tests" ON)
if(BUILD_WITH_UNTESTS)

189
README.md
View File

@@ -194,33 +194,25 @@ public:
const_reference operator[](size_t index) const;
};
using bool2 = vec<bool, 2>;
using bool3 = vec<bool, 3>;
using bool4 = vec<bool, 4>;
using bvec2 = vec<bool, 2>;
using bvec3 = vec<bool, 3>;
using bvec4 = vec<bool, 4>;
using int2 = vec<int, 2>;
using int3 = vec<int, 3>;
using int4 = vec<int, 4>;
using ivec2 = vec<int, 2>;
using ivec3 = vec<int, 3>;
using ivec4 = vec<int, 4>;
using uint2 = vec<unsigned, 2>;
using uint3 = vec<unsigned, 3>;
using uint4 = vec<unsigned, 4>;
using uvec2 = vec<unsigned, 2>;
using uvec3 = vec<unsigned, 3>;
using uvec4 = vec<unsigned, 4>;
using float2 = vec<float, 2>;
using float3 = vec<float, 3>;
using float4 = vec<float, 4>;
using fvec2 = vec<float, 2>;
using fvec3 = vec<float, 3>;
using fvec4 = vec<float, 4>;
using double2 = vec<double, 2>;
using double3 = vec<double, 3>;
using double4 = vec<double, 4>;
using size2_t = vec<size_t, 2>;
using size3_t = vec<size_t, 3>;
using size4_t = vec<size_t, 4>;
using ptrdiff2_t = vec<ptrdiff_t, 2>;
using ptrdiff3_t = vec<ptrdiff_t, 3>;
using ptrdiff4_t = vec<ptrdiff_t, 4>;
using dvec2 = vec<double, 2>;
using dvec3 = vec<double, 3>;
using dvec4 = vec<double, 4>;
```
### Matrix Types
@@ -379,33 +371,25 @@ public:
const_reference operator[](size_t index) const;
};
using bool2x2 = mat<bool, 2>;
using bool3x3 = mat<bool, 3>;
using bool4x4 = mat<bool, 4>;
using bmat2 = mat<bool, 2>;
using bmat3 = mat<bool, 3>;
using bmat4 = mat<bool, 4>;
using int2x2 = mat<int, 2>;
using int3x3 = mat<int, 3>;
using int4x4 = mat<int, 4>;
using imat2 = mat<int, 2>;
using imat3 = mat<int, 3>;
using imat4 = mat<int, 4>;
using uint2x2 = mat<unsigned, 2>;
using uint3x3 = mat<unsigned, 3>;
using uint4x4 = mat<unsigned, 4>;
using umat2 = mat<unsigned, 2>;
using umat3 = mat<unsigned, 3>;
using umat4 = mat<unsigned, 4>;
using float2x2 = mat<float, 2>;
using float3x3 = mat<float, 3>;
using float4x4 = mat<float, 4>;
using fmat2 = mat<float, 2>;
using fmat3 = mat<float, 3>;
using fmat4 = mat<float, 4>;
using double2x2 = mat<double, 2>;
using double3x3 = mat<double, 3>;
using double4x4 = mat<double, 4>;
using size2x2_t = mat<size_t, 2>;
using size3x3_t = mat<size_t, 3>;
using size4x4_t = mat<size_t, 4>;
using ptrdiff2x2_t = mat<ptrdiff_t, 2>;
using ptrdiff3x3_t = mat<ptrdiff_t, 3>;
using ptrdiff4x4_t = mat<ptrdiff_t, 4>;
using dmat2 = mat<double, 2>;
using dmat3 = mat<double, 3>;
using dmat4 = mat<double, 4>;
```
### Quaternion Types
@@ -481,8 +465,8 @@ public:
const_reference operator[](size_t index) const;
};
using qfloat = qua<float>;
using qdouble = qua<double>;
using fqua = qua<float>;
using dqua = qua<double>;
```
### Vector Operators
@@ -1746,17 +1730,17 @@ template < typename T > inline vec<T, 4> unit4_y;
template < typename T > inline vec<T, 4> unit4_z;
template < typename T > inline vec<T, 4> unit4_w;
template < typename T > inline mat<T, 2> zero2x2;
template < typename T > inline mat<T, 3> zero3x3;
template < typename T > inline mat<T, 4> zero4x4;
template < typename T > inline mat<T, 2> mzero2;
template < typename T > inline mat<T, 3> mzero3;
template < typename T > inline mat<T, 4> mzero4;
template < typename T > inline mat<T, 2> unit2x2;
template < typename T > inline mat<T, 3> unit3x3;
template < typename T > inline mat<T, 4> unit4x4;
template < typename T > inline mat<T, 2> munit2;
template < typename T > inline mat<T, 3> munit3;
template < typename T > inline mat<T, 4> munit4;
template < typename T > inline mat<T, 2> identity2x2;
template < typename T > inline mat<T, 3> identity3x3;
template < typename T > inline mat<T, 4> identity4x4;
template < typename T > inline mat<T, 2> midentity2;
template < typename T > inline mat<T, 3> midentity3;
template < typename T > inline mat<T, 4> midentity4;
template < typename T > inline qua<T> qzero;
template < typename T > inline qua<T> qidentity;
@@ -1816,62 +1800,65 @@ qua<T> imag(qua<T> q, const vec<T, 3>& imag);
```cpp
template < typename T >
mat<T, 4> translate(T x, T y, T z);
mat<T, 4> trs(const vec<T, 3>& t, const mat<T, 3>& r);
template < typename T >
mat<T, 4> translate(const mat<T, 4>& m, T x, T y, T z);
mat<T, 4> trs(const vec<T, 3>& t, const mat<T, 3>& r, const vec<T, 3>& s);
template < typename T >
mat<T, 4> trs(const vec<T, 3>& t, const qua<T>& r);
template < typename T >
mat<T, 4> trs(const vec<T, 3>& t, const qua<T>& r, const vec<T, 3>& s);
template < typename T >
mat<T, 4> translate(const vec<T, 3>& v);
template < typename T >
mat<T, 4> translate(const mat<T, 4>& m, const vec<T, 3>& v);
mat<T, 3> rotate(const qua<T>& q);
template < typename T >
mat<T, 4> rotate(const qua<T>& q);
mat<T, 4> rotate4(const qua<T>& q);
template < typename T >
mat<T, 4> rotate(const mat<T, 4>& m, const qua<T>& q);
mat<T, 3> rotate(T angle, const vec<T, 3>& axis);
template < typename T >
mat<T, 4> rotate(T angle, const vec<T, 3>& axis);
mat<T, 4> rotate4(T angle, const vec<T, 3>& axis);
template < typename T >
mat<T, 4> rotate(const mat<T, 4>& m, T angle, const vec<T, 3>& axis);
mat<T, 3> rotate_x(T angle);
template < typename T >
mat<T, 4> rotate_x(T angle);
mat<T, 4> rotate4_x(T angle);
template < typename T >
mat<T, 4> rotate_x(const mat<T, 4>& m, T angle);
mat<T, 3> rotate_y(T angle);
template < typename T >
mat<T, 4> rotate_y(T angle);
mat<T, 4> rotate4_y(T angle);
template < typename T >
mat<T, 4> rotate_y(const mat<T, 4>& m, T angle);
mat<T, 3> rotate_z(T angle);
template < typename T >
mat<T, 4> rotate_z(T angle);
mat<T, 4> rotate4_z(T angle);
template < typename T >
mat<T, 4> rotate_z(const mat<T, 4>& m, T angle);
mat<T, 3> scale(const vec<T, 3>& v);
template < typename T >
mat<T, 4> scale(T x, T y, T z);
mat<T, 4> scale4(const vec<T, 3>& v);
template < typename T >
mat<T, 4> scale(const mat<T, 4>& m, T x, T y, T z);
template < typename T >
mat<T, 4> scale(const vec<T, 3>& v);
template < typename T >
mat<T, 4> scale(const mat<T, 4>& m, const vec<T, 3>& v);
mat<T, 3> look_at_lh(const vec<T, 3>& dir, const vec<T, 3>& up);
template < typename T >
mat<T, 4> look_at_lh(const vec<T, 3>& eye, const vec<T, 3>& at, const vec<T, 3>& up);
template < typename T >
mat<T, 3> look_at_rh(const vec<T, 3>& dir, const vec<T, 3>& up);
template < typename T >
mat<T, 4> look_at_rh(const vec<T, 3>& eye, const vec<T, 3>& at, const vec<T, 3>& up);
```
@@ -1880,58 +1867,31 @@ mat<T, 4> look_at_rh(const vec<T, 3>& eye, const vec<T, 3>& at, const vec<T, 3>&
```cpp
template < typename T >
mat<T, 3> translate(T x, T y);
mat<T, 3> trs(const vec<T, 2>& t, const mat<T, 2>& r);
template < typename T >
mat<T, 3> translate(const mat<T, 3>& m, T x, T y);
mat<T, 3> trs(const vec<T, 2>& t, const mat<T, 2>& r, const vec<T, 2>& s);
template < typename T >
mat<T, 3> translate(const vec<T, 2>& v);
template < typename T >
mat<T, 3> translate(const mat<T, 3>& m, const vec<T, 2>& v);
mat<T, 2> rotate(T angle);
template < typename T >
mat<T, 3> rotate(T angle);
mat<T, 3> rotate3(T angle);
template < typename T >
mat<T, 3> rotate(const mat<T, 3>& m, T angle);
mat<T, 2> scale(const vec<T, 2>& v);
template < typename T >
mat<T, 3> scale(T x, T y);
mat<T, 3> scale3(const vec<T, 2>& v);
template < typename T >
mat<T, 3> scale(const mat<T, 3>& m, T x, T y);
mat<T, 2> shear(const vec<T, 2>& v);
template < typename T >
mat<T, 3> scale(const vec<T, 2>& v);
template < typename T >
mat<T, 3> scale(const mat<T, 3>& m, const vec<T, 2>& v);
template < typename T >
mat<T, 3> shear(T x, T y);
template < typename T >
mat<T, 3> shear(const mat<T, 3>& m, T x, T y);
template < typename T >
mat<T, 3> shear(const vec<T, 2>& v);
template < typename T >
mat<T, 3> shear(const mat<T, 3>& m, const vec<T, 2>& v);
template < typename T >
mat<T, 3> shear_x(T y);
template < typename T >
mat<T, 3> shear_x(const mat<T, 3>& m, T y);
template < typename T >
mat<T, 3> shear_y(T x);
template < typename T >
mat<T, 3> shear_y(const mat<T, 3>& m, T x);
mat<T, 3> shear3(const vec<T, 2>& v);
```
### Matrix Projections
@@ -1986,9 +1946,6 @@ vec<T, 3> rotate_y(const vec<T, 3>& v, T angle);
template < typename T >
vec<T, 3> rotate_z(const vec<T, 3>& v, T angle);
template < typename T >
vec<T, 3> rotate(const vec<T, 3>& v, const qua<T>& q);
template < typename T >
vec<T, 3> rotate(const vec<T, 3>& v, T angle, const vec<T, 3>& axis);

View File

@@ -39,17 +39,17 @@ namespace vmath_hpp
template < typename T > inline constexpr vec<T, 4> unit4_z{T{0}, T{0}, T{1}, T{0}};
template < typename T > inline constexpr vec<T, 4> unit4_w{T{0}, T{0}, T{0}, T{1}};
template < typename T > inline constexpr mat<T, 2> zero2x2{zero_init};
template < typename T > inline constexpr mat<T, 3> zero3x3{zero_init};
template < typename T > inline constexpr mat<T, 4> zero4x4{zero_init};
template < typename T > inline constexpr mat<T, 2> mzero2{zero_init};
template < typename T > inline constexpr mat<T, 3> mzero3{zero_init};
template < typename T > inline constexpr mat<T, 4> mzero4{zero_init};
template < typename T > inline constexpr mat<T, 2> unit2x2{unit_init};
template < typename T > inline constexpr mat<T, 3> unit3x3{unit_init};
template < typename T > inline constexpr mat<T, 4> unit4x4{unit_init};
template < typename T > inline constexpr mat<T, 2> munit2{unit_init};
template < typename T > inline constexpr mat<T, 3> munit3{unit_init};
template < typename T > inline constexpr mat<T, 4> munit4{unit_init};
template < typename T > inline constexpr mat<T, 2> identity2x2{identity_init};
template < typename T > inline constexpr mat<T, 3> identity3x3{identity_init};
template < typename T > inline constexpr mat<T, 4> identity4x4{identity_init};
template < typename T > inline constexpr mat<T, 2> midentity2{identity_init};
template < typename T > inline constexpr mat<T, 3> midentity3{identity_init};
template < typename T > inline constexpr mat<T, 4> midentity4{identity_init};
template < typename T > inline constexpr qua<T> qzero{zero_init};
template < typename T > inline constexpr qua<T> qidentity{identity_init};
@@ -230,39 +230,54 @@ namespace vmath_hpp
namespace vmath_hpp
{
// trs
template < typename T >
[[nodiscard]] constexpr mat<T, 4> trs(const vec<T, 3>& t, const mat<T, 3>& r) {
return {
{ r[0], T{0} },
{ r[1], T{0} },
{ r[2], T{0} },
{ t, T{1} }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> trs(const vec<T, 3>& t, const mat<T, 3>& r, const vec<T, 3>& s) {
return {
{ r[0] * s[0], T{0} },
{ r[1] * s[1], T{0} },
{ r[2] * s[2], T{0} },
{ t, T{1} }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> trs(const vec<T, 3>& t, const qua<T>& r) {
return trs(t, rotate(r));
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> trs(const vec<T, 3>& t, const qua<T>& r, const vec<T, 3>& s) {
return trs(t, rotate(r), s);
}
// translate
template < typename T >
[[nodiscard]] constexpr mat<T, 4> translate(T x, T y, T z) {
[[nodiscard]] constexpr mat<T, 4> translate(const vec<T, 3>& v) {
/// REFERENCE:
/// https://en.wikipedia.org/wiki/Translation_(geometry)
return {
{T{1}, T{0}, T{0}, T{0}},
{T{0}, T{1}, T{0}, T{0}},
{T{0}, T{0}, T{1}, T{0}},
{ x, y, z, T{1}}};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> translate(const mat<T, 4>& m, T x, T y, T z) {
return m * translate(x, y, z);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> translate(const vec<T, 3>& v) {
return translate(v.x, v.y, v.z);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> translate(const mat<T, 4>& m, const vec<T, 3>& v) {
return m * translate(v);
{ T{1}, T{0}, T{0}, T{0} },
{ T{0}, T{1}, T{0}, T{0} },
{ T{0}, T{0}, T{1}, T{0} },
{ v.x, v.y, v.z, T{1} }};
}
// rotate
template < typename T >
[[nodiscard]] constexpr mat<T, 4> rotate(const qua<T>& q) {
[[nodiscard]] constexpr mat<T, 3> rotate(const qua<T>& q) {
/// REFERENCE:
/// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/
@@ -285,19 +300,18 @@ namespace vmath_hpp
const T zz2 = qv.z * z2;
return {
T{1} - (yy2 + zz2), (xy2 + sz2), (xz2 - sy2), T{0},
(xy2 - sz2), T{1} - (xx2 + zz2), (yz2 + sx2), T{0},
(xz2 + sy2), (yz2 - sx2), T{1} - (xx2 + yy2), T{0},
T{0}, T{0}, T{0}, T{1}};
{ T{1} - (yy2 + zz2), (xy2 + sz2), (xz2 - sy2) },
{ (xy2 - sz2), T{1} - (xx2 + zz2), (yz2 + sx2) },
{ (xz2 + sy2), (yz2 - sx2), T{1} - (xx2 + yy2) }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> rotate(const mat<T, 4>& m, const qua<T>& q) {
return m * rotate(q);
[[nodiscard]] constexpr mat<T, 4> rotate4(const qua<T>& q) {
return mat<T, 4>(rotate(q));
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> rotate(T angle, const vec<T, 3>& axis) {
[[nodiscard]] constexpr mat<T, 3> rotate(T angle, const vec<T, 3>& axis) {
/// REFERENCE:
/// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/
@@ -323,107 +337,120 @@ namespace vmath_hpp
const T yzm = y * z * ic;
return {
xxm + c, xym + zs, xzm - ys, T{0},
xym - zs, yym + c, yzm + xs, T{0},
xzm + ys, yzm - xs, zzm + c, T{0},
T{0}, T{0}, T{0}, T{1}};
{ xxm + c, xym + zs, xzm - ys },
{ xym - zs, yym + c, yzm + xs },
{ xzm + ys, yzm - xs, zzm + c }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> rotate(const mat<T, 4>& m, T angle, const vec<T, 3>& axis) {
return m * rotate(angle, axis);
[[nodiscard]] constexpr mat<T, 4> rotate4(T angle, const vec<T, 3>& axis) {
return mat<T, 4>(rotate(angle, axis));
}
// rotate_x
template < typename T >
[[nodiscard]] constexpr mat<T, 4> rotate_x(T angle) {
[[nodiscard]] constexpr mat<T, 3> rotate_x(T angle) {
/// REFERENCE:
/// http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/
const auto [s, c] = sincos(angle);
return {
T{1}, T{0}, T{0}, T{0},
T{0}, c, s, T{0},
T{0}, -s, c, T{0},
T{0}, T{0}, T{0}, T{1}};
{ T{1}, T{0}, T{0} },
{ T{0}, c, s },
{ T{0}, -s, c }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> rotate_x(const mat<T, 4>& m, T angle) {
return m * rotate_x(angle);
[[nodiscard]] constexpr mat<T, 4> rotate4_x(T angle) {
return mat<T, 4>(rotate_x(angle));
}
// rotate_y
template < typename T >
[[nodiscard]] constexpr mat<T, 4> rotate_y(T angle) {
[[nodiscard]] constexpr mat<T, 3> rotate_y(T angle) {
/// REFERENCE:
/// http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/
const auto [s, c] = sincos(angle);
return {
c, T{0}, -s, T{0},
T{0}, T{1}, T{0}, T{0},
s, T{0}, c, T{0},
T{0}, T{0}, T{0}, T{1}};
{ c, T{0}, -s },
{ T{0}, T{1}, T{0} },
{ s, T{0}, c }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> rotate_y(const mat<T, 4>& m, T angle) {
return m * rotate_y(angle);
[[nodiscard]] constexpr mat<T, 4> rotate4_y(T angle) {
return mat<T, 4>(rotate_y(angle));
}
// rotate_z
template < typename T >
[[nodiscard]] constexpr mat<T, 4> rotate_z(T angle) {
[[nodiscard]] constexpr mat<T, 3> rotate_z(T angle) {
/// REFERENCE:
/// http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/
const auto [s, c] = sincos(angle);
return {
c, s, T{0}, T{0},
-s, c, T{0}, T{0},
T{0}, T{0}, T{1}, T{0},
T{0}, T{0}, T{0}, T{1}};
{ c, s, T{0} },
{ -s, c, T{0} },
{ T{0}, T{0}, T{1} }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> rotate_z(const mat<T, 4>& m, T angle) {
return m * rotate_z(angle);
[[nodiscard]] constexpr mat<T, 4> rotate4_z(T angle) {
return mat<T, 4>(rotate_z(angle));
}
// scale
template < typename T >
[[nodiscard]] constexpr mat<T, 4> scale(T x, T y, T z) {
[[nodiscard]] constexpr mat<T, 3> scale(const vec<T, 3>& v) {
/// REFERENCE:
/// https://en.wikipedia.org/wiki/Scaling_(geometry)
return {
{ x, T{0}, T{0}, T{0}},
{T{0}, y, T{0}, T{0}},
{T{0}, T{0}, z, T{0}},
{T{0}, T{0}, T{0}, T{1}}};
{ v.x, T{0}, T{0} },
{ T{0}, v.y, T{0} },
{ T{0}, T{0}, v.z }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> scale(const mat<T, 4>& m, T x, T y, T z) {
return m * scale(x, y, z);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> scale(const vec<T, 3>& v) {
return scale(v.x, v.y, v.z);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> scale(const mat<T, 4>& m, const vec<T, 3>& v) {
return m * scale(v);
[[nodiscard]] constexpr mat<T, 4> scale4(const vec<T, 3>& v) {
return mat<T, 4>(scale(v));
}
// look_at
template < typename T >
[[nodiscard]] constexpr mat<T, 4> look_at_lh(const vec<T, 3>& eye, const vec<T, 3>& at, const vec<T, 3>& up) {
[[nodiscard]] constexpr mat<T, 3> look_at_lh(
const vec<T, 3>& dir,
const vec<T, 3>& up)
{
/// REFERENCE:
/// https://www.euclideanspace.com/maths/algebra/vectors/lookat/
const vec az = normalize(dir);
const vec ax = normalize(cross(up, az));
const vec ay = cross(az, ax);
return {
{ ax.x, ay.x, az.x },
{ ax.y, ay.y, az.y },
{ ax.z, ay.z, az.z }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> look_at_lh(
const vec<T, 3>& eye,
const vec<T, 3>& at,
const vec<T, 3>& up)
{
/// REFERENCE:
/// https://www.euclideanspace.com/maths/algebra/vectors/lookat/
@@ -436,14 +463,36 @@ namespace vmath_hpp
const T dz = dot(az, eye);
return {
ax.x, ay.x, az.x, T{0},
ax.y, ay.y, az.y, T{0},
ax.z, ay.z, az.z, T{0},
-dx, -dy, -dz, T{1}};
{ ax.x, ay.x, az.x, T{0} },
{ ax.y, ay.y, az.y, T{0} },
{ ax.z, ay.z, az.z, T{0} },
{ -dx, -dy, -dz, T{1} }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> look_at_rh(const vec<T, 3>& eye, const vec<T, 3>& at, const vec<T, 3>& up) {
[[nodiscard]] constexpr mat<T, 3> look_at_rh(
const vec<T, 3>& dir,
const vec<T, 3>& up)
{
/// REFERENCE:
/// https://www.euclideanspace.com/maths/algebra/vectors/lookat/
const vec az = normalize(-dir);
const vec ax = normalize(cross(up, az));
const vec ay = cross(az, ax);
return {
{ ax.x, ay.x, az.x },
{ ax.y, ay.y, az.y },
{ ax.z, ay.z, az.z }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 4> look_at_rh(
const vec<T, 3>& eye,
const vec<T, 3>& at,
const vec<T, 3>& up)
{
/// REFERENCE:
/// https://www.euclideanspace.com/maths/algebra/vectors/lookat/
@@ -456,10 +505,10 @@ namespace vmath_hpp
const T dz = dot(az, eye);
return {
ax.x, ay.x, az.x, T{0},
ax.y, ay.y, az.y, T{0},
ax.z, ay.z, az.z, T{0},
-dx, -dy, -dz, T{1}};
{ ax.x, ay.x, az.x, T{0} },
{ ax.y, ay.y, az.y, T{0} },
{ ax.z, ay.z, az.z, T{0} },
{ -dx, -dy, -dz, T{1} }};
}
}
@@ -469,140 +518,88 @@ namespace vmath_hpp
namespace vmath_hpp
{
// trs
template < typename T >
[[nodiscard]] constexpr mat<T, 3> trs(const vec<T, 2>& t, const mat<T, 2>& r) {
return {
{ r[0], T{0} },
{ r[1], T{0} },
{ t, T{1} }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> trs(const vec<T, 2>& t, const mat<T, 2>& r, const vec<T, 2>& s) {
return {
{ r[0] * s[0], T{0} },
{ r[1] * s[1], T{0} },
{ t, T{1} }};
}
// translate
template < typename T >
[[nodiscard]] constexpr mat<T, 3> translate(T x, T y) {
[[nodiscard]] constexpr mat<T, 3> translate(const vec<T, 2>& v) {
/// REFERENCE:
/// https://en.wikipedia.org/wiki/Translation_(geometry)
return {
{T{1}, T{0}, T{0}},
{T{0}, T{1}, T{0}},
{ x, y, T{1}}};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> translate(const mat<T, 3>& m, T x, T y) {
return m * translate(x, y);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> translate(const vec<T, 2>& v) {
return translate(v.x, v.y);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> translate(const mat<T, 3>& m, const vec<T, 2>& v) {
return m * translate(v);
{ T{1}, T{0}, T{0} },
{ T{0}, T{1}, T{0} },
{ v.x, v.y, T{1} }};
}
// rotate
template < typename T >
[[nodiscard]] constexpr mat<T, 3> rotate(T angle) {
[[nodiscard]] constexpr mat<T, 2> rotate(T angle) {
/// REFERENCE:
/// http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/
const auto [s, c] = sincos(angle);
return {
c, s, T{0},
-s, c, T{0},
T{0}, T{0}, T{1}};
{ c, s },
{ -s, c }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> rotate(const mat<T, 3>& m, T angle) {
return m * rotate(angle);
[[nodiscard]] constexpr mat<T, 3> rotate3(T angle) {
return mat<T, 3>(rotate(angle));
}
// scale
template < typename T >
[[nodiscard]] constexpr mat<T, 3> scale(T x, T y) {
[[nodiscard]] constexpr mat<T, 2> scale(const vec<T, 2>& v) {
/// REFERENCE:
/// https://en.wikipedia.org/wiki/Scaling_(geometry)
return {
{ x, T{0}, T{0}},
{T{0}, y, T{0}},
{T{0}, T{0}, T{1}}};
{ v.x, T{0} },
{ T{0}, v.y }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> scale(const mat<T, 3>& m, T x, T y) {
return m * scale(x, y);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> scale(const vec<T, 2>& v) {
return scale(v.x, v.y);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> scale(const mat<T, 3>& m, const vec<T, 2>& v) {
return m * scale(v);
[[nodiscard]] constexpr mat<T, 3> scale3(const vec<T, 2>& v) {
return mat<T, 3>(scale(v));
}
// shear
template < typename T >
[[nodiscard]] constexpr mat<T, 3> shear(T x, T y) {
[[nodiscard]] constexpr mat<T, 2> shear(const vec<T, 2>& v) {
/// REFERENCE:
/// https://en.wikipedia.org/wiki/Shear_matrix
return {
{T{1}, y, T{0}},
{ x, T{1}, T{0}},
{T{0}, T{0}, T{1}}};
{ T{1}, v.y },
{ v.x, T{1} }};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> shear(const mat<T, 3>& m, T x, T y) {
return m * shear(x, y);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> shear(const vec<T, 2>& v) {
return shear(v.x, v.y);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> shear(const mat<T, 3>& m, const vec<T, 2>& v) {
return m * shear(v);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> shear_x(T x) {
/// REFERENCE:
/// https://en.wikipedia.org/wiki/Shear_matrix
return {
{T{1}, T{0}, T{0}},
{ x, T{1}, T{0}},
{T{0}, T{0}, T{1}}};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> shear_x(const mat<T, 3>& m, T x) {
return m * shear_x(x);
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> shear_y(T y) {
/// REFERENCE:
/// https://en.wikipedia.org/wiki/Shear_matrix
return {
{T{1}, y, T{0}},
{T{0}, T{1}, T{0}},
{T{0}, T{0}, T{1}}};
}
template < typename T >
[[nodiscard]] constexpr mat<T, 3> shear_y(const mat<T, 3>& m, T y) {
return m * shear_y(y);
[[nodiscard]] constexpr mat<T, 3> shear3(const vec<T, 2>& v) {
return mat<T, 3>(shear(v));
}
}
@@ -629,10 +626,10 @@ namespace vmath_hpp
const T tz = -frange * znear;
return {
sx, T{0}, T{0}, T{0},
T{0}, sy, T{0}, T{0},
T{0}, T{0}, sz, T{0},
T{0}, T{0}, tz, T{1}};
{ sx, T{0}, T{0}, T{0} },
{ T{0}, sy, T{0}, T{0} },
{ T{0}, T{0}, sz, T{0} },
{ T{0}, T{0}, tz, T{1} }};
}
template < typename T >
@@ -650,10 +647,10 @@ namespace vmath_hpp
const T tz = frange * znear;
return {
sx, T{0}, T{0}, T{0},
T{0}, sy, T{0}, T{0},
T{0}, T{0}, sz, T{0},
T{0}, T{0}, tz, T{1}};
{ sx, T{0}, T{0}, T{0} },
{ T{0}, sy, T{0}, T{0} },
{ T{0}, T{0}, sz, T{0} },
{ T{0}, T{0}, tz, T{1} }};
}
template < typename T >
@@ -666,10 +663,10 @@ namespace vmath_hpp
const T frange = rcp(zfar - znear);
return {
T{2} * rwidth, T{0}, T{0}, T{0},
T{0}, T{2} * rheight, T{0}, T{0},
T{0}, T{0}, frange, T{0},
-(left + right) * rwidth, -(top + bottom) * rheight, -frange * znear, T{1}};
{ T{2} * rwidth, T{0}, T{0}, T{0} },
{ T{0}, T{2} * rheight, T{0}, T{0} },
{ T{0}, T{0}, frange, T{0} },
{ -(left + right) * rwidth, -(top + bottom) * rheight, -frange * znear, T{1} }};
}
template < typename T >
@@ -682,10 +679,10 @@ namespace vmath_hpp
const T frange = rcp(znear - zfar);
return {
T{2} * rwidth, T{0}, T{0}, T{0},
T{0}, T{2} * rheight, T{0}, T{0},
T{0}, T{0}, frange, T{0},
-(left + right) * rwidth, -(top + bottom) * rheight, frange * znear, T{1}};
{ T{2} * rwidth, T{0}, T{0}, T{0} },
{ T{0}, T{2} * rheight, T{0}, T{0} },
{ T{0}, T{0}, frange, T{0} },
{ -(left + right) * rwidth, -(top + bottom) * rheight, frange * znear, T{1} }};
}
// perspective
@@ -701,10 +698,10 @@ namespace vmath_hpp
const T tz = (znear * zfar) * rcp(znear - zfar);
return {
T{sx}, T{0}, T{0}, T{0},
T{0}, T{sy}, T{0}, T{0},
T{0}, T{0}, T{sz}, T{1},
T{0}, T{0}, T{tz}, T{0}};
{ T{sx}, T{0}, T{0}, T{0} },
{ T{0}, T{sy}, T{0}, T{0} },
{ T{0}, T{0}, T{sz}, T{1} },
{ T{0}, T{0}, T{tz}, T{0} }};
}
template < typename T >
@@ -718,10 +715,10 @@ namespace vmath_hpp
const T tz = (znear * zfar) * rcp(znear - zfar);
return {
sx, T{0}, T{0}, T{0},
T{0}, sy, T{0}, T{0},
T{0}, T{0}, sz, -T{1},
T{0}, T{0}, tz, T{0}};
{ sx, T{0}, T{0}, T{0} },
{ T{0}, sy, T{0}, T{0} },
{ T{0}, T{0}, sz, -T{1} },
{ T{0}, T{0}, tz, T{0} }};
}
template < typename T >
@@ -735,10 +732,10 @@ namespace vmath_hpp
const T frange = zfar * rcp(zfar - znear);
return {
znear2 * rwidth, T{0}, T{0}, T{0},
T{0}, znear2 * rheight, T{0}, T{0},
-(left + right) * rwidth, -(top + bottom) * rheight, frange, T{1},
T{0}, T{0}, -frange * znear, T{0}};
{ znear2 * rwidth, T{0}, T{0}, T{0} },
{ T{0}, znear2 * rheight, T{0}, T{0} },
{ -(left + right) * rwidth, -(top + bottom) * rheight, frange, T{1} },
{ T{0}, T{0}, -frange * znear, T{0} }};
}
template < typename T >
@@ -752,10 +749,10 @@ namespace vmath_hpp
const T frange = zfar * rcp(znear - zfar);
return {
znear2 * rwidth, T{0}, T{0}, T{0},
T{0}, znear2 * rheight, T{0}, T{0},
(left + right) * rwidth, (top + bottom) * rheight, frange, -T{1},
T{0}, T{0}, frange * znear, T{0}};
{ znear2 * rwidth, T{0}, T{0}, T{0} },
{ T{0}, znear2 * rheight, T{0}, T{0} },
{ (left + right) * rwidth, (top + bottom) * rheight, frange, -T{1} },
{ T{0}, T{0}, frange * znear, T{0} }};
}
template < typename T >
@@ -769,10 +766,10 @@ namespace vmath_hpp
const T tz = (znear * zfar) * rcp(znear - zfar);
return {
sx, T{0}, T{0}, T{0},
T{0}, sy, T{0}, T{0},
T{0}, T{0}, sz, T{1},
T{0}, T{0}, tz, T{0}};
{ sx, T{0}, T{0}, T{0} },
{ T{0}, sy, T{0}, T{0} },
{ T{0}, T{0}, sz, T{1} },
{ T{0}, T{0}, tz, T{0} }};
}
template < typename T >
@@ -785,10 +782,10 @@ namespace vmath_hpp
const T sz = zfar * rcp(znear - zfar);
const T tz = (znear * zfar) * rcp(znear - zfar);
return {
sx, T{0}, T{0}, T{0},
T{0}, sy, T{0}, T{0},
T{0}, T{0}, sz, -T{1},
T{0}, T{0}, tz, T{0}};
{ sx, T{0}, T{0}, T{0} },
{ T{0}, sy, T{0}, T{0} },
{ T{0}, T{0}, sz, -T{1} },
{ T{0}, T{0}, tz, T{0} }};
}
}
@@ -810,10 +807,7 @@ namespace vmath_hpp
template < typename T >
[[nodiscard]] constexpr vec<T, 2> rotate(const vec<T, 2>& v, T angle) {
const auto [s, c] = sincos(angle);
return {
v.x * c - v.y * s,
v.x * s + v.y * c};
return v * rotate(angle);
}
template < typename T >
@@ -831,11 +825,6 @@ namespace vmath_hpp
return v * qrotate(angle, unit3_z<T>);
}
template < typename T >
[[nodiscard]] constexpr vec<T, 3> rotate(const vec<T, 3>& v, const qua<T>& q) {
return v * q;
}
template < typename T >
[[nodiscard]] constexpr vec<T, 3> rotate(const vec<T, 3>& v, T angle, const vec<T, 3>& axis) {
return v * qrotate(angle, axis);
@@ -882,11 +871,6 @@ namespace vmath_hpp
T{1}}));
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate(const qua<T>& q, const mat<T, 3>& m) {
return q * qrotate(m);
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate(const vec<T, 3>& from, const vec<T, 3>& to) {
/// REFERENCE:
@@ -904,11 +888,6 @@ namespace vmath_hpp
return normalize(qua{cross(from, to), s});
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate(const qua<T>& q, const vec<T, 3>& from, const vec<T, 3>& to) {
return q * qrotate(from, to);
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate(T angle, const vec<T, 3>& axis) {
/// REFERENCE:
@@ -920,11 +899,6 @@ namespace vmath_hpp
return {vec{x, y, z} * s, c};
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate(const qua<T>& q, T angle, const vec<T, 3>& axis) {
return q * qrotate(angle, axis);
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate_x(T angle) {
/// REFERENCE:
@@ -935,11 +909,6 @@ namespace vmath_hpp
return {vec{s, T{0}, T{0}}, c};
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate_x(const qua<T>& q, T angle) {
return qrotate(q, angle, unit3_x<T>);
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate_y(T angle) {
/// REFERENCE:
@@ -950,11 +919,6 @@ namespace vmath_hpp
return {vec{T{0}, s, T{0}}, c};
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate_y(const qua<T>& q, T angle) {
return qrotate(q, angle, unit3_y<T>);
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate_z(T angle) {
/// REFERENCE:
@@ -965,40 +929,15 @@ namespace vmath_hpp
return {vec{T{0}, T{0}, s}, c};
}
template < typename T >
[[nodiscard]] constexpr qua<T> qrotate_z(const qua<T>& q, T angle) {
return qrotate(q, angle, unit3_z<T>);
}
// look_at
// qlook_at
template < typename T >
[[nodiscard]] constexpr qua<T> qlook_at_lh(const vec<T, 3>& dir, const vec<T, 3>& up) {
/// REFERENCE:
/// https://www.euclideanspace.com/maths/algebra/vectors/lookat/
const vec az = normalize(dir);
const vec ax = normalize(cross(up, az));
const vec ay = cross(az, ax);
return qrotate(mat{
ax.x, ay.x, az.x,
ax.y, ay.y, az.y,
ax.z, ay.z, az.z});
return qrotate(look_at_lh(dir, up));
}
template < typename T >
[[nodiscard]] constexpr qua<T> qlook_at_rh(const vec<T, 3>& dir, const vec<T, 3>& up) {
/// REFERENCE:
/// https://www.euclideanspace.com/maths/algebra/vectors/lookat/
const vec az = normalize(-dir);
const vec ax = normalize(cross(up, az));
const vec ay = cross(az, ax);
return qrotate(mat{
ax.x, ay.x, az.x,
ax.y, ay.y, az.y,
ax.z, ay.z, az.z});
return qrotate(look_at_rh(dir, up));
}
}

View File

@@ -58,33 +58,25 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
class vec;
using bool2 = vec<bool, 2>;
using bool3 = vec<bool, 3>;
using bool4 = vec<bool, 4>;
using bvec2 = vec<bool, 2>;
using bvec3 = vec<bool, 3>;
using bvec4 = vec<bool, 4>;
using int2 = vec<int, 2>;
using int3 = vec<int, 3>;
using int4 = vec<int, 4>;
using ivec2 = vec<int, 2>;
using ivec3 = vec<int, 3>;
using ivec4 = vec<int, 4>;
using uint2 = vec<unsigned, 2>;
using uint3 = vec<unsigned, 3>;
using uint4 = vec<unsigned, 4>;
using uvec2 = vec<unsigned, 2>;
using uvec3 = vec<unsigned, 3>;
using uvec4 = vec<unsigned, 4>;
using float2 = vec<float, 2>;
using float3 = vec<float, 3>;
using float4 = vec<float, 4>;
using fvec2 = vec<float, 2>;
using fvec3 = vec<float, 3>;
using fvec4 = vec<float, 4>;
using double2 = vec<double, 2>;
using double3 = vec<double, 3>;
using double4 = vec<double, 4>;
using size2_t = vec<std::size_t, 2>;
using size3_t = vec<std::size_t, 3>;
using size4_t = vec<std::size_t, 4>;
using ptrdiff2_t = vec<std::ptrdiff_t, 2>;
using ptrdiff3_t = vec<std::ptrdiff_t, 3>;
using ptrdiff4_t = vec<std::ptrdiff_t, 4>;
using dvec2 = vec<double, 2>;
using dvec3 = vec<double, 3>;
using dvec4 = vec<double, 4>;
}
namespace vmath_hpp
@@ -92,33 +84,25 @@ namespace vmath_hpp
template < typename T, std::size_t Size >
class mat;
using bool2x2 = mat<bool, 2>;
using bool3x3 = mat<bool, 3>;
using bool4x4 = mat<bool, 4>;
using bmat2 = mat<bool, 2>;
using bmat3 = mat<bool, 3>;
using bmat4 = mat<bool, 4>;
using int2x2 = mat<int, 2>;
using int3x3 = mat<int, 3>;
using int4x4 = mat<int, 4>;
using imat2 = mat<int, 2>;
using imat3 = mat<int, 3>;
using imat4 = mat<int, 4>;
using uint2x2 = mat<unsigned, 2>;
using uint3x3 = mat<unsigned, 3>;
using uint4x4 = mat<unsigned, 4>;
using umat2 = mat<unsigned, 2>;
using umat3 = mat<unsigned, 3>;
using umat4 = mat<unsigned, 4>;
using float2x2 = mat<float, 2>;
using float3x3 = mat<float, 3>;
using float4x4 = mat<float, 4>;
using fmat2 = mat<float, 2>;
using fmat3 = mat<float, 3>;
using fmat4 = mat<float, 4>;
using double2x2 = mat<double, 2>;
using double3x3 = mat<double, 3>;
using double4x4 = mat<double, 4>;
using size2x2_t = mat<std::size_t, 2>;
using size3x3_t = mat<std::size_t, 3>;
using size4x4_t = mat<std::size_t, 4>;
using ptrdiff2x2_t = mat<std::ptrdiff_t, 2>;
using ptrdiff3x3_t = mat<std::ptrdiff_t, 3>;
using ptrdiff4x4_t = mat<std::ptrdiff_t, 4>;
using dmat2 = mat<double, 2>;
using dmat3 = mat<double, 3>;
using dmat4 = mat<double, 4>;
}
namespace vmath_hpp
@@ -126,6 +110,6 @@ namespace vmath_hpp
template < typename T >
class qua;
using qfloat = qua<float>;
using qdouble = qua<double>;
using fqua = qua<float>;
using dqua = qua<double>;
}

4403
singles/vmath.hpp/vmath.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@ endif()
file(GLOB_RECURSE UNTESTS_SOURCES "*.cpp" "*.hpp")
add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES})
target_link_libraries(${PROJECT_NAME} vmath.hpp)
target_link_libraries(${PROJECT_NAME} vmath.hpp.singles)
target_compile_options(${PROJECT_NAME}
PRIVATE

View File

@@ -18,119 +18,118 @@ namespace
constexpr float pi = radians(180.f);
constexpr float pi_2 = radians(90.f);
constexpr float pi_4 = radians(45.f);
}
TEST_CASE("vmath/ext/units") {
STATIC_CHECK(zero2<int> == int2(0,0));
STATIC_CHECK(zero3<int> == int3(0,0,0));
STATIC_CHECK(zero4<int> == int4(0,0,0,0));
STATIC_CHECK(zero2<int> == ivec2(0,0));
STATIC_CHECK(zero3<int> == ivec3(0,0,0));
STATIC_CHECK(zero4<int> == ivec4(0,0,0,0));
STATIC_CHECK(unit2<int> == int2(1,1));
STATIC_CHECK(unit2_x<int> == int2(1,0));
STATIC_CHECK(unit2_y<int> == int2(0,1));
STATIC_CHECK(unit2<int> == ivec2(1,1));
STATIC_CHECK(unit2_x<int> == ivec2(1,0));
STATIC_CHECK(unit2_y<int> == ivec2(0,1));
STATIC_CHECK(unit3<int> == int3(1,1,1));
STATIC_CHECK(unit3_x<int> == int3(1,0,0));
STATIC_CHECK(unit3_y<int> == int3(0,1,0));
STATIC_CHECK(unit3_z<int> == int3(0,0,1));
STATIC_CHECK(unit3<int> == ivec3(1,1,1));
STATIC_CHECK(unit3_x<int> == ivec3(1,0,0));
STATIC_CHECK(unit3_y<int> == ivec3(0,1,0));
STATIC_CHECK(unit3_z<int> == ivec3(0,0,1));
STATIC_CHECK(unit4<int> == int4(1,1,1,1));
STATIC_CHECK(unit4_x<int> == int4(1,0,0,0));
STATIC_CHECK(unit4_y<int> == int4(0,1,0,0));
STATIC_CHECK(unit4_z<int> == int4(0,0,1,0));
STATIC_CHECK(unit4_w<int> == int4(0,0,0,1));
STATIC_CHECK(unit4<int> == ivec4(1,1,1,1));
STATIC_CHECK(unit4_x<int> == ivec4(1,0,0,0));
STATIC_CHECK(unit4_y<int> == ivec4(0,1,0,0));
STATIC_CHECK(unit4_z<int> == ivec4(0,0,1,0));
STATIC_CHECK(unit4_w<int> == ivec4(0,0,0,1));
STATIC_CHECK(zero2x2<int> == int2x2(0,0,0,0));
STATIC_CHECK(zero3x3<int> == int3x3(0,0,0,0,0,0,0,0,0));
STATIC_CHECK(zero4x4<int> == int4x4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0));
STATIC_CHECK(mzero2<int> == imat2(0,0,0,0));
STATIC_CHECK(mzero3<int> == imat3(0,0,0,0,0,0,0,0,0));
STATIC_CHECK(mzero4<int> == imat4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0));
STATIC_CHECK(unit2x2<int> == int2x2(1,1,1,1));
STATIC_CHECK(unit3x3<int> == int3x3(1,1,1,1,1,1,1,1,1));
STATIC_CHECK(unit4x4<int> == int4x4(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1));
STATIC_CHECK(munit2<int> == imat2(1,1,1,1));
STATIC_CHECK(munit3<int> == imat3(1,1,1,1,1,1,1,1,1));
STATIC_CHECK(munit4<int> == imat4(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1));
STATIC_CHECK(identity2x2<int> == int2x2());
STATIC_CHECK(identity3x3<int> == int3x3());
STATIC_CHECK(identity4x4<int> == int4x4());
STATIC_CHECK(midentity2<int> == imat2());
STATIC_CHECK(midentity3<int> == imat3());
STATIC_CHECK(midentity4<int> == imat4());
STATIC_CHECK(qzero<float> == qfloat(zero_init));
STATIC_CHECK(qidentity<float> == qfloat(identity_init));
STATIC_CHECK(qzero<float> == fqua(zero_init));
STATIC_CHECK(qidentity<float> == fqua(identity_init));
}
TEST_CASE("vmath/ext/hash") {
SUBCASE("vector") {
CHECK(std::hash<int2>{}({1,2}) == std::hash<int2>{}({1,2}));
CHECK_FALSE(std::hash<int2>{}({1,2}) == std::hash<int2>{}({2,1}));
CHECK(std::hash<ivec2>{}({1,2}) == std::hash<ivec2>{}({1,2}));
CHECK_FALSE(std::hash<ivec2>{}({1,2}) == std::hash<ivec2>{}({2,1}));
CHECK(std::hash<int3>{}({1,2,3}) == std::hash<int3>{}({1,2,3}));
CHECK_FALSE(std::hash<int3>{}({1,2,3}) == std::hash<int3>{}({3,2,1}));
CHECK(std::hash<ivec3>{}({1,2,3}) == std::hash<ivec3>{}({1,2,3}));
CHECK_FALSE(std::hash<ivec3>{}({1,2,3}) == std::hash<ivec3>{}({3,2,1}));
CHECK(std::hash<int4>{}({1,2,3,4}) == std::hash<int4>{}({1,2,3,4}));
CHECK_FALSE(std::hash<int4>{}({1,2,3,4}) == std::hash<int4>{}({3,2,1,4}));
CHECK(std::hash<ivec4>{}({1,2,3,4}) == std::hash<ivec4>{}({1,2,3,4}));
CHECK_FALSE(std::hash<ivec4>{}({1,2,3,4}) == std::hash<ivec4>{}({3,2,1,4}));
{
std::set<int2> s;
s.insert(int2(1,2));
CHECK(s.count(int2(1,2)) > 0);
CHECK_FALSE(s.count(int2(1,1)) > 0);
std::set<ivec2> s;
s.insert(ivec2(1,2));
CHECK(s.count(ivec2(1,2)) > 0);
CHECK_FALSE(s.count(ivec2(1,1)) > 0);
}
{
std::map<int2, int> s;
s.emplace(int2(1,2),3);
s.emplace(int2(2,3),5);
CHECK(s[int2(1,2)] == 3);
CHECK(s[int2(2,3)] == 5);
std::map<ivec2, int> s;
s.emplace(ivec2(1,2),3);
s.emplace(ivec2(2,3),5);
CHECK(s[ivec2(1,2)] == 3);
CHECK(s[ivec2(2,3)] == 5);
}
{
std::unordered_set<int2> s;
s.insert(int2(1,2));
CHECK(s.count(int2(1,2)) > 0);
CHECK_FALSE(s.count(int2(1,1)) > 0);
std::unordered_set<ivec2> s;
s.insert(ivec2(1,2));
CHECK(s.count(ivec2(1,2)) > 0);
CHECK_FALSE(s.count(ivec2(1,1)) > 0);
}
{
std::unordered_map<int2, int> s;
s.emplace(int2(1,2),3);
s.emplace(int2(2,3),5);
CHECK(s[int2(1,2)] == 3);
CHECK(s[int2(2,3)] == 5);
std::unordered_map<ivec2, int> s;
s.emplace(ivec2(1,2),3);
s.emplace(ivec2(2,3),5);
CHECK(s[ivec2(1,2)] == 3);
CHECK(s[ivec2(2,3)] == 5);
}
}
SUBCASE("matrix") {
CHECK(std::hash<int2x2>{}({1,2,3,4}) == std::hash<int2x2>{}({1,2,3,4}));
CHECK_FALSE(std::hash<int2x2>{}({1,2,3,4}) == std::hash<int2x2>{}({1,2,4,3}));
CHECK(std::hash<imat2>{}({1,2,3,4}) == std::hash<imat2>{}({1,2,3,4}));
CHECK_FALSE(std::hash<imat2>{}({1,2,3,4}) == std::hash<imat2>{}({1,2,4,3}));
{
std::set<int2x2> s;
s.insert(int2x2(1,2,3,4));
CHECK(s.count(int2x2(1,2,3,4)) > 0);
CHECK_FALSE(s.count(int2x2(1,1,1,1)) > 0);
std::set<imat2> s;
s.insert(imat2(1,2,3,4));
CHECK(s.count(imat2(1,2,3,4)) > 0);
CHECK_FALSE(s.count(imat2(1,1,1,1)) > 0);
}
{
std::map<int2x2, int> s;
s.emplace(int2x2(1,2,3,4),3);
s.emplace(int2x2(2,3,4,5),5);
CHECK(s[int2x2(1,2,3,4)] == 3);
CHECK(s[int2x2(2,3,4,5)] == 5);
std::map<imat2, int> s;
s.emplace(imat2(1,2,3,4),3);
s.emplace(imat2(2,3,4,5),5);
CHECK(s[imat2(1,2,3,4)] == 3);
CHECK(s[imat2(2,3,4,5)] == 5);
}
{
std::unordered_set<int2x2> s;
s.insert(int2x2(1,2,3,4));
CHECK(s.count(int2x2(1,2,3,4)) > 0);
CHECK_FALSE(s.count(int2x2(1,1,1,1)) > 0);
std::unordered_set<imat2> s;
s.insert(imat2(1,2,3,4));
CHECK(s.count(imat2(1,2,3,4)) > 0);
CHECK_FALSE(s.count(imat2(1,1,1,1)) > 0);
}
{
std::unordered_map<int2x2, int> s;
s.emplace(int2x2(1,2,3,4),3);
s.emplace(int2x2(2,3,4,5),5);
CHECK(s[int2x2(1,2,3,4)] == 3);
CHECK(s[int2x2(2,3,4,5)] == 5);
std::unordered_map<imat2, int> s;
s.emplace(imat2(1,2,3,4),3);
s.emplace(imat2(2,3,4,5),5);
CHECK(s[imat2(1,2,3,4)] == 3);
CHECK(s[imat2(2,3,4,5)] == 5);
}
}
SUBCASE("quaternion") {
CHECK(std::hash<qfloat>{}({1,2,3,4}) == std::hash<qfloat>{}({1,2,3,4}));
CHECK_FALSE(std::hash<qfloat>{}({1,2,3,4}) == std::hash<qfloat>{}({3,2,1,4}));
CHECK(std::hash<fqua>{}({1,2,3,4}) == std::hash<fqua>{}({1,2,3,4}));
CHECK_FALSE(std::hash<fqua>{}({1,2,3,4}) == std::hash<fqua>{}({3,2,1,4}));
{
std::set<qua<int>> s;
@@ -167,15 +166,15 @@ TEST_CASE("vmath/ext/cast") {
STATIC_CHECK(i == 1);
STATIC_CHECK(std::is_same_v<decltype(i), const int>);
constexpr auto v = cast_to<int>(float2(1.5f));
STATIC_CHECK(v == int2(1));
constexpr auto v = cast_to<int>(fvec2(1.5f));
STATIC_CHECK(v == ivec2(1));
STATIC_CHECK(std::is_same_v<decltype(v)::component_type, int>);
constexpr auto m = cast_to<int>(float2x2(1.5f));
STATIC_CHECK(m == int2x2(1));
STATIC_CHECK(std::is_same_v<decltype(m)::row_type, int2>);
constexpr auto m = cast_to<int>(fmat2(1.5f));
STATIC_CHECK(m == imat2(1));
STATIC_CHECK(std::is_same_v<decltype(m)::row_type, ivec2>);
constexpr auto q = cast_to<int>(qfloat(1.5f, 2.2f, 3.6f, 4.5f));
constexpr auto q = cast_to<int>(fqua(1.5f, 2.2f, 3.6f, 4.5f));
STATIC_CHECK(q == qua(1,2,3,4));
STATIC_CHECK(std::is_same_v<decltype(q)::component_type, int>);
}
@@ -183,27 +182,27 @@ TEST_CASE("vmath/ext/cast") {
TEST_CASE("vmath/ext/access") {
SUBCASE("component") {
STATIC_CHECK(component(int2{1,2}, 0) == 1);
STATIC_CHECK(component(int2{1,2}, 1) == 2);
STATIC_CHECK(component(ivec2{1,2}, 0) == 1);
STATIC_CHECK(component(ivec2{1,2}, 1) == 2);
STATIC_CHECK(component(int2{0,0}, 0, 1) == int2{1,0});
STATIC_CHECK(component(int2{0,0}, 1, 2) == int2{0,2});
STATIC_CHECK(component(ivec2{0,0}, 0, 1) == ivec2{1,0});
STATIC_CHECK(component(ivec2{0,0}, 1, 2) == ivec2{0,2});
}
SUBCASE("row") {
STATIC_CHECK(row(int2x2(1,2,3,4), 0) == int2(1,2));
STATIC_CHECK(row(int2x2(1,2,3,4), 1) == int2(3,4));
STATIC_CHECK(row(imat2(1,2,3,4), 0) == ivec2(1,2));
STATIC_CHECK(row(imat2(1,2,3,4), 1) == ivec2(3,4));
STATIC_CHECK(row(int2x2(), 0, {1,2}) == int2x2(1,2,0,1));
STATIC_CHECK(row(int2x2(), 1, {3,4}) == int2x2(1,0,3,4));
STATIC_CHECK(row(imat2(), 0, {1,2}) == imat2(1,2,0,1));
STATIC_CHECK(row(imat2(), 1, {3,4}) == imat2(1,0,3,4));
}
SUBCASE("column") {
STATIC_CHECK(column(int2x2(1,2,3,4), 0) == int2(1,3));
STATIC_CHECK(column(int2x2(1,2,3,4), 1) == int2(2,4));
STATIC_CHECK(column(imat2(1,2,3,4), 0) == ivec2(1,3));
STATIC_CHECK(column(imat2(1,2,3,4), 1) == ivec2(2,4));
STATIC_CHECK(column(int2x2(), 0, {2,3}) == int2x2(2,0,3,1));
STATIC_CHECK(column(int2x2(), 1, {3,4}) == int2x2(1,3,0,4));
STATIC_CHECK(column(imat2(), 0, {2,3}) == imat2(2,0,3,1));
STATIC_CHECK(column(imat2(), 1, {3,4}) == imat2(1,3,0,4));
}
SUBCASE("real") {
@@ -218,65 +217,75 @@ TEST_CASE("vmath/ext/access") {
}
TEST_CASE("vmath/ext/matrix_transform") {
SUBCASE("translate") {
STATIC_CHECK(float3(2.f,3.f,1.f) * translate(float2{1.f,2.f}) == uapprox3(3.f,5.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * translate(translate(float2{1.f,2.f}), float2{1.f,2.f}) == uapprox3(4.f,7.f,1.f));
SUBCASE("trs") {
CHECK(all(approx(
trs(fvec3(1,2,3), rotate(pi, fvec3{1,2,3})),
rotate4(pi, fvec3{1,2,3}) * translate(fvec3(1,2,3)))));
CHECK(all(approx(
trs(fvec3(1,2,3), rotate(pi, fvec3{1,2,3}), fvec3(2,3,4)),
scale4(fvec3(2,3,4)) * rotate4(pi, fvec3(1,2,3)) * translate(fvec3(1,2,3)))));
STATIC_CHECK(float4(2.f,3.f,4.f,1.f) * translate(float3{1.f,2.f,3.f}) == uapprox4(3.f,5.f,7.f,1.f));
STATIC_CHECK(float4(2.f,3.f,4.f,1.f) * translate(translate(float3{1.f,2.f,3.f}), float3{1.f,2.f,3.f}) == uapprox4(4.f,7.f,10.f,1.f));
CHECK(all(approx(
trs(fvec3(1,2,3), qrotate(pi, fvec3{1,2,3})),
rotate4(qrotate(pi, fvec3{1,2,3})) * translate(fvec3(1,2,3)))));
CHECK(all(approx(
trs(fvec3(1,2,3), qrotate(pi, fvec3{1,2,3}), fvec3(2,3,4)),
scale4(fvec3(2,3,4)) * rotate4(qrotate(pi, fvec3{1,2,3})) * translate(fvec3(1,2,3)))));
CHECK(all(approx(
trs(fvec2(1,2), rotate(pi)),
rotate3(pi) * translate(fvec2(1,2)))));
CHECK(all(approx(
trs(fvec2(1,2), rotate(pi), fvec2(2,3)),
scale3(fvec2(2,3)) * rotate3(pi) * translate(fvec2(1,2)))));
}
SUBCASE("translate") {
STATIC_CHECK(fvec3(2.f,3.f,1.f) * translate(fvec2{1.f,2.f}) == uapprox3(3.f,5.f,1.f));
STATIC_CHECK(fvec4(2.f,3.f,4.f,1.f) * translate(fvec3{1.f,2.f,3.f}) == uapprox4(3.f,5.f,7.f,1.f));
}
SUBCASE("rotate") {
CHECK(float4(0.f,1.f,0.f,1.f) * rotate_x(pi_2) == uapprox4(0.f,0.f,1.f,1.f));
CHECK(float4(0.f,0.f,1.f,1.f) * rotate_y(pi_2) == uapprox4(1.f,0.f,0.f,1.f));
CHECK(float4(1.f,0.f,0.f,1.f) * rotate_z(pi_2) == uapprox4(0.f,1.f,0.f,1.f));
CHECK(fvec3(0.f,1.f,0.f) * rotate_x(pi_2) == uapprox3(0.f,0.f,1.f));
CHECK(fvec3(0.f,0.f,1.f) * rotate_y(pi_2) == uapprox3(1.f,0.f,0.f));
CHECK(fvec3(1.f,0.f,0.f) * rotate_z(pi_2) == uapprox3(0.f,1.f,0.f));
CHECK(fvec4(0.f,1.f,0.f,1.f) * rotate4_x(pi_2) == uapprox4(0.f,0.f,1.f,1.f));
CHECK(fvec4(0.f,0.f,1.f,1.f) * rotate4_y(pi_2) == uapprox4(1.f,0.f,0.f,1.f));
CHECK(fvec4(1.f,0.f,0.f,1.f) * rotate4_z(pi_2) == uapprox4(0.f,1.f,0.f,1.f));
CHECK(float4(0.f,1.f,0.f,1.f) * rotate_x(rotate_x(pi_4),pi_4) == uapprox4(0.f,0.f,1.f,1.f));
CHECK(float4(0.f,0.f,1.f,1.f) * rotate_y(rotate_y(pi_4),pi_4) == uapprox4(1.f,0.f,0.f,1.f));
CHECK(float4(1.f,0.f,0.f,1.f) * rotate_z(rotate_z(pi_4),pi_4) == uapprox4(0.f,1.f,0.f,1.f));
CHECK(fvec2(2.f,3.f) * rotate(pi) == uapprox2(-2.f,-3.f));
CHECK(fvec3(2.f,3.f,1) * rotate3(pi) == uapprox3(-2.f,-3.f,1.f));
CHECK(float3(2.f,3.f,1.f) * rotate(pi) == uapprox3(-2.f,-3.f,1.f));
CHECK(float4(2.f,3.f,4.f,1.f) * rotate(pi,{0.f,0.f,1.f}) == uapprox4(-2.f,-3.f,4.f,1.f));
CHECK(float4(2.f,3.f,4.f,1.f) * rotate(pi,float3{0.f,0.f,1.f}) == uapprox4(-2.f,-3.f,4.f,1.f));
CHECK(float4(2.f,3.f,4.f,1.f) * rotate(qrotate(pi,float3{0.f,0.f,1.f})) == uapprox4(-2.f,-3.f,4.f,1.f));
CHECK(float3(2.f,3.f,1.f) * rotate(rotate(pi_2),pi_2) == uapprox3(-2.f,-3.f,1.f));
CHECK(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,{0.f,0.f,1.f}),pi_2,{0.f,0.f,1.f}) == uapprox4(-2.f,-3.f,4.f,1.f));
CHECK(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,float3{0.f,0.f,1.f}),pi_2,float3{0.f,0.f,1.f}) == uapprox4(-2.f,-3.f,4.f,1.f));
CHECK(float4(2.f,3.f,4.f,1.f) * rotate(rotate(qrotate(pi_2,float3{0.f,0.f,1.f})),qrotate(pi_2,float3{0.f,0.f,1.f})) == uapprox4(-2.f,-3.f,4.f,1.f));
CHECK(fvec3(2.f,3.f,4.f) * rotate(pi,{0.f,0.f,1.f}) == uapprox3(-2.f,-3.f,4.f));
CHECK(fvec3(2.f,3.f,4.f) * rotate(pi,fvec3{0.f,0.f,1.f}) == uapprox3(-2.f,-3.f,4.f));
CHECK(fvec3(2.f,3.f,4.f) * rotate(qrotate(pi,fvec3{0.f,0.f,1.f})) == uapprox3(-2.f,-3.f,4.f));
CHECK(fvec4(2.f,3.f,4.f,1.f) * rotate4(pi,{0.f,0.f,1.f}) == uapprox4(-2.f,-3.f,4.f,1.f));
CHECK(fvec4(2.f,3.f,4.f,1.f) * rotate4(pi,fvec3{0.f,0.f,1.f}) == uapprox4(-2.f,-3.f,4.f,1.f));
CHECK(fvec4(2.f,3.f,4.f,1.f) * rotate4(qrotate(pi,fvec3{0.f,0.f,1.f})) == uapprox4(-2.f,-3.f,4.f,1.f));
}
SUBCASE("scale") {
STATIC_CHECK(float3(2.f,3.f,1.f) * scale(float2{2.f,3.f}) == uapprox3(4.f,9.f,1.f));
STATIC_CHECK(float4(2.f,3.f,4.f,1.f) * scale(float3{2.f,3.f,4.f}) == uapprox4(4.f,9.f,16.f,1.f));
STATIC_CHECK(float4(2.f,3.f,4.f,1.f) * scale(float3{2.f,3.f,4.f}) == uapprox4(4.f,9.f,16.f,1.f));
SUBCASE("scale2d") {
STATIC_CHECK(fvec2(2.f,3.f) * scale(fvec2{2.f,3.f}) == uapprox2(4.f,9.f));
STATIC_CHECK(fvec3(2.f,3.f,1.f) * scale3(fvec2{2.f,3.f}) == uapprox3(4.f,9.f,1.f));
}
STATIC_CHECK(float3(2.f,3.f,1.f) * scale(scale(float2{2.f,2.f}), {2.f,3.f}) == uapprox3(8.f,18.f,1.f));
STATIC_CHECK(float4(2.f,3.f,4.f,1.f) * scale(scale(float3{2.f,2.f,2.f}), {2.f,3.f,4.f}) == uapprox4(8.f,18.f,32.f,1.f));
STATIC_CHECK(float4(2.f,3.f,4.f,1.f) * scale(scale(float3{2.f,2.f,2.f}), float3{2.f,3.f,4.f}) == uapprox4(8.f,18.f,32.f,1.f));
SUBCASE("scale3d") {
STATIC_CHECK(fvec3(2.f,3.f,4.f) * scale(fvec3{2.f,3.f,4.f}) == uapprox3(4.f,9.f,16.f));
STATIC_CHECK(fvec4(2.f,3.f,4.f,1.f) * scale4(fvec3{2.f,3.f,4.f}) == uapprox4(4.f,9.f,16.f,1.f));
}
SUBCASE("shear") {
STATIC_CHECK(float3(2.f,3.f,1.f) * shear_x(0.f) == uapprox3(2.f,3.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear_x(1.f) == uapprox3(5.f,3.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear_x(2.f) == uapprox3(8.f,3.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear_x(shear_x(1.f),1.f) == uapprox3(8.f,3.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear_y(0.f) == uapprox3(2.f,3.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear_y(1.f) == uapprox3(2.f,5.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear_y(2.f) == uapprox3(2.f,7.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear_y(shear_y(1.f),1.f) == uapprox3(2.f,7.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear(float2(0.f,0.f)) == uapprox3(2.f,3.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear(float2(2.f,0.f)) == uapprox3(8.f,3.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear(float2(0.f,2.f)) == uapprox3(2.f,7.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear(shear(float2(1.f,0.f)),float2(1.f,0.f)) == uapprox3(8.f,3.f,1.f));
STATIC_CHECK(float3(2.f,3.f,1.f) * shear(shear(float2(0.f,1.f)),float2(0.f,1.f)) == uapprox3(2.f,7.f,1.f));
STATIC_CHECK(fvec2(2.f,3.f) * shear(fvec2(0.f,0.f)) == uapprox2(2.f,3.f));
STATIC_CHECK(fvec2(2.f,3.f) * shear(fvec2(2.f,0.f)) == uapprox2(8.f,3.f));
STATIC_CHECK(fvec2(2.f,3.f) * shear(fvec2(0.f,2.f)) == uapprox2(2.f,7.f));
STATIC_CHECK(fvec3(2.f,3.f,1.f) * shear3(fvec2(0.f,0.f)) == uapprox3(2.f,3.f,1.f));
STATIC_CHECK(fvec3(2.f,3.f,1.f) * shear3(fvec2(2.f,0.f)) == uapprox3(8.f,3.f,1.f));
STATIC_CHECK(fvec3(2.f,3.f,1.f) * shear3(fvec2(0.f,2.f)) == uapprox3(2.f,7.f,1.f));
}
SUBCASE("matrix look_at") {
(void)look_at_lh(float3(1,2,3), float3(0,0,0), float3(0,2,0));
(void)look_at_rh(float3(1,2,3), float3(0,0,0), float3(0,2,0));
(void)look_at_lh(fvec3(1,2,3), fvec3(0,0,0), fvec3(0,2,0));
(void)look_at_rh(fvec3(1,2,3), fvec3(0,0,0), fvec3(0,2,0));
}
}
@@ -284,83 +293,72 @@ TEST_CASE("vmath/ext/matrix_projections") {
SUBCASE("orthographic") {
CHECK(all(approx(
orthographic_lh(800.f, 600.f, 5.f, 10.f),
scale(1.f,1.f,-1.f) * orthographic_rh(800.f, 600.f, 5.f, 10.f))));
scale4(vec{1.f,1.f,-1.f}) * orthographic_rh(800.f, 600.f, 5.f, 10.f))));
CHECK(all(approx(
orthographic_lh(100.f, 800.f, 50.f, 640.f, 5.f, 10.f),
scale(1.f,1.f,-1.f) * orthographic_rh(100.f, 800.f, 50.f, 640.f, 5.f, 10.f))));
scale4(vec{1.f,1.f,-1.f}) * orthographic_rh(100.f, 800.f, 50.f, 640.f, 5.f, 10.f))));
}
SUBCASE("perspective") {
CHECK(all(approx(
perspective_lh(800.f, 600.f, 5.f, 10.f),
scale(1.f,1.f,-1.f) * perspective_rh(800.f, 600.f, 5.f, 10.f))));
scale4(vec{1.f,1.f,-1.f}) * perspective_rh(800.f, 600.f, 5.f, 10.f))));
CHECK(all(approx(
perspective_fov_lh(1.5f, 1.3f, 0.f, 10.f),
scale(1.f,1.f,-1.f) * perspective_fov_rh(1.5f, 1.3f, 0.f, 10.f))));
scale4(vec{1.f,1.f,-1.f}) * perspective_fov_rh(1.5f, 1.3f, 0.f, 10.f))));
CHECK(all(approx(
perspective_lh(100.f, 800.f, 50.f, 600.f, 5.f, 10.f),
scale(1.f,1.f,-1.f) * perspective_rh(100.f, 800.f, 50.f, 600.f, 5.f, 10.f))));
scale4(vec{1.f,1.f,-1.f}) * perspective_rh(100.f, 800.f, 50.f, 600.f, 5.f, 10.f))));
}
}
TEST_CASE("vmath/ext/vector_transform") {
SUBCASE("angle") {
CHECK(angle(float2(2.f,0.f), float2(0.f,1.f)) == uapprox(radians(90.f)));
CHECK(angle(float2(0.f,3.f), float2(1.f,0.f)) == uapprox(radians(90.f)));
CHECK(angle(float2(0.5f,0.f), float2(-1.f,0.f)) == uapprox(radians(180.f)));
CHECK(angle(float2(-0.2f,0.f), float2(1.f,0.f)) == uapprox(radians(180.f)));
CHECK(angle(float3(0.f,2.f,0.f), float3(0.f,0.f,1.f)) == uapprox(radians(90.f)));
CHECK(angle(float3(0.f,0.f,3.f), float3(0.f,1.f,0.f)) == uapprox(radians(90.f)));
CHECK(angle(fvec2(2.f,0.f), fvec2(0.f,1.f)) == uapprox(radians(90.f)));
CHECK(angle(fvec2(0.f,3.f), fvec2(1.f,0.f)) == uapprox(radians(90.f)));
CHECK(angle(fvec2(0.5f,0.f), fvec2(-1.f,0.f)) == uapprox(radians(180.f)));
CHECK(angle(fvec2(-0.2f,0.f), fvec2(1.f,0.f)) == uapprox(radians(180.f)));
CHECK(angle(fvec3(0.f,2.f,0.f), fvec3(0.f,0.f,1.f)) == uapprox(radians(90.f)));
CHECK(angle(fvec3(0.f,0.f,3.f), fvec3(0.f,1.f,0.f)) == uapprox(radians(90.f)));
}
SUBCASE("rotate") {
CHECK(rotate(float2(2.f,0.f), radians(90.f)) == uapprox2(0.f,2.f));
CHECK(rotate(float2(1.5f,0.f), radians(-90.f)) == uapprox2(0.f,-1.5f));
CHECK(rotate(fvec2(2.f,0.f), radians(90.f)) == uapprox2(0.f,2.f));
CHECK(rotate(fvec2(1.5f,0.f), radians(-90.f)) == uapprox2(0.f,-1.5f));
CHECK(rotate_x(float3(0.f,1.5f,0.f), radians(90.f)) == uapprox3(0.f,0.f,1.5f));
CHECK(rotate_y(float3(0.f,0.f,1.5f), radians(90.f)) == uapprox3(1.5f,0.f,0.f));
CHECK(rotate_z(float3(1.5f,0.f,0.f), radians(90.f)) == uapprox3(0.f,1.5f,0.f));
CHECK(rotate_x(fvec3(0.f,1.5f,0.f), radians(90.f)) == uapprox3(0.f,0.f,1.5f));
CHECK(rotate_y(fvec3(0.f,0.f,1.5f), radians(90.f)) == uapprox3(1.5f,0.f,0.f));
CHECK(rotate_z(fvec3(1.5f,0.f,0.f), radians(90.f)) == uapprox3(0.f,1.5f,0.f));
CHECK(rotate(float3(1.5f,0.f,0.f), qrotate_z(radians(90.f))) == uapprox3(0.f,1.5f,0.f));
CHECK(rotate(float3(1.5f,0.f,0.f), radians(90.f), float3(0,0,1)) == uapprox3(0.f,1.5f,0.f));
CHECK(rotate(fvec3(1.5f,0.f,0.f), radians(90.f), fvec3(0,0,1)) == uapprox3(0.f,1.5f,0.f));
}
SUBCASE("project") {
STATIC_CHECK(project(float2(2.f, 2.f), float2(0.f, 1.f)) == uapprox2(0.f, 2.f));
STATIC_CHECK(project(float3(2.f, 2.f, 2.f), float3(0.f, 0.f, 1.f)) == uapprox3(0.f, 0.f, 2.f));
STATIC_CHECK(project(fvec2(2.f, 2.f), fvec2(0.f, 1.f)) == uapprox2(0.f, 2.f));
STATIC_CHECK(project(fvec3(2.f, 2.f, 2.f), fvec3(0.f, 0.f, 1.f)) == uapprox3(0.f, 0.f, 2.f));
}
SUBCASE("perpendicular") {
STATIC_CHECK(perpendicular(float2(2.f, 2.f), float2(0.f, 1.f)) == uapprox2(2.f, 0.f));
STATIC_CHECK(perpendicular(float3(2.f, 2.f, 2.f), float3(0.f, 0.f, 1.f)) == uapprox3(2.f, 2.f, 0.f));
STATIC_CHECK(perpendicular(fvec2(2.f, 2.f), fvec2(0.f, 1.f)) == uapprox2(2.f, 0.f));
STATIC_CHECK(perpendicular(fvec3(2.f, 2.f, 2.f), fvec3(0.f, 0.f, 1.f)) == uapprox3(2.f, 2.f, 0.f));
}
}
TEST_CASE("vmath/ext/quaternion_transform") {
SUBCASE("qrotate(m)") {
CHECK(all(approx(
vec{4.f,3.f,2.f,1.f} * rotate(qrotate(float3x3(rotate(0.f, vec{1.f,2.f,3.f})))),
vec{4.f,3.f,2.f,1.f} * rotate(0.f, vec{1.f,2.f,3.f}), 0.001f)));
vec{4.f,3.f,2.f} * rotate(qrotate(rotate(0.f, vec{1.f,2.f,3.f}))),
vec{4.f,3.f,2.f} * rotate(0.f, vec{1.f,2.f,3.f}), 0.001f)));
CHECK(all(approx(
vec{4.f,3.f,2.f,1.f} * rotate(qrotate(float3x3(rotate(radians(12.5f), vec{1.f,2.f,3.f})))),
vec{4.f,3.f,2.f,1.f} * rotate(radians(12.5f), vec{1.f,2.f,3.f}), 0.001f)));
vec{4.f,3.f,2.f} * rotate(qrotate(rotate(radians(12.5f), vec{1.f,2.f,3.f}))),
vec{4.f,3.f,2.f} * rotate(radians(12.5f), vec{1.f,2.f,3.f}), 0.001f)));
CHECK(all(approx(
vec{4.f,3.f,2.f,1.f} * rotate(qrotate(float3x3(rotate(radians(-190.5f), vec{1.f,2.f,3.f})))),
vec{4.f,3.f,2.f,1.f} * rotate(radians(-190.5f), vec{1.f,2.f,3.f}), 0.001f)));
}
SUBCASE("qrotate(q, m)") {
CHECK(all(approx(
vec{4.f,3.f,2.f} * qrotate(
qrotate(float3x3(rotate(0.f, vec{1.f,2.f,3.f}))),
float3x3(rotate(0.f, vec{3.f,2.f,1.f}))),
vec{4.f,3.f,2.f} *
float3x3(rotate(0.f, vec{1.f,2.f,3.f})) *
float3x3(rotate(0.f, vec{3.f,2.f,1.f})))));
vec{4.f,3.f,2.f} * rotate(qrotate(rotate(radians(-190.5f), vec{1.f,2.f,3.f}))),
vec{4.f,3.f,2.f} * rotate(radians(-190.5f), vec{1.f,2.f,3.f}), 0.001f)));
}
SUBCASE("qrotate(from, to)") {
@@ -371,47 +369,29 @@ TEST_CASE("vmath/ext/quaternion_transform") {
CHECK(vec{-2.f,1.f,3.f} * qrotate(vec{-2.f,1.f,3.f}, vec{1.f,2.f,3.f}) == uapprox3(1.f,2.f,3.f));
}
SUBCASE("qrotate(q, from, to)") {
CHECK(vec{1.f,2.f,3.f} *
inverse(qrotate(float3x3(rotate(radians(12.f), {2.f,2.f,2.f})))) *
qrotate(
qrotate(float3x3(rotate(radians(12.f), {2.f,2.f,2.f}))),
vec{1.f,2.f,3.f},
vec{-2.f,1.f,3.f}) == uapprox3(vec{-2.f,1.f,3.f}));
}
SUBCASE("qrotate(angle, axis)") {
CHECK(all(approx(
rotate(12.3f, float3(1.f,2.f,3.f)),
rotate(qrotate(12.3f, float3(1.f,2.f,3.f)) * 2.f))));
rotate(12.3f, fvec3(1.f,2.f,3.f)),
rotate(qrotate(12.3f, fvec3(1.f,2.f,3.f)) * 2.f))));
CHECK(float3(0.f,1.f,0.f) * qrotate_x(pi_2) == uapprox3(0.f,0.f,1.f));
CHECK(float3(0.f,0.f,1.f) * qrotate_y(pi_2) == uapprox3(1.f,0.f,0.f));
CHECK(float3(1.f,0.f,0.f) * qrotate_z(pi_2) == uapprox3(0.f,1.f,0.f));
CHECK(fvec3(0.f,1.f,0.f) * qrotate_x(pi_2) == uapprox3(0.f,0.f,1.f));
CHECK(fvec3(0.f,0.f,1.f) * qrotate_y(pi_2) == uapprox3(1.f,0.f,0.f));
CHECK(fvec3(1.f,0.f,0.f) * qrotate_z(pi_2) == uapprox3(0.f,1.f,0.f));
CHECK(float3(2.f,3.f,4.f) * qrotate(pi,{0.f,0.f,1.f}) == uapprox3(-2.f,-3.f,4.f));
CHECK(float3(2.f,3.f,4.f) * qrotate(pi,float3{0.f,0.f,1.f}) == uapprox3(-2.f,-3.f,4.f));
CHECK(fvec3(2.f,3.f,4.f) * qrotate(pi,{0.f,0.f,1.f}) == uapprox3(-2.f,-3.f,4.f));
CHECK(fvec3(2.f,3.f,4.f) * qrotate(pi,fvec3{0.f,0.f,1.f}) == uapprox3(-2.f,-3.f,4.f));
CHECK(qrotate_x(12.3f) == qrotate(12.3f, unit3_x<float> * 2.f));
CHECK(qrotate_y(12.3f) == qrotate(12.3f, unit3_y<float> * 2.f));
CHECK(qrotate_z(12.3f) == qrotate(12.3f, unit3_z<float> * 2.f));
}
SUBCASE("qrotate(q, angle, axis)") {
CHECK(float3(0.f,1.f,0.f) * qrotate_x(qrotate_x(pi_4),pi_4) == uapprox3(0.f,0.f,1.f));
CHECK(float3(0.f,0.f,1.f) * qrotate_y(qrotate_y(pi_4),pi_4) == uapprox3(1.f,0.f,0.f));
CHECK(float3(1.f,0.f,0.f) * qrotate_z(qrotate_z(pi_4),pi_4) == uapprox3(0.f,1.f,0.f));
CHECK(float3(2.f,3.f,4.f) * qrotate(qrotate(pi_2,{0.f,0.f,1.f}),pi_2,{0.f,0.f,1.f}) == uapprox3(-2.f,-3.f,4.f));
CHECK(float3(2.f,3.f,4.f) * qrotate(qrotate(pi_2,float3{0.f,0.f,1.f}),pi_2,float3{0.f,0.f,1.f}) == uapprox3(-2.f,-3.f,4.f));
}
SUBCASE("qlook_at") {
CHECK(all(approx(
qlook_at_lh(float3(1.f,2.f,3.f), float3(0,1,0)),
qrotate(float3x3(look_at_lh(float3(), float3(1.f,2.f,3.f), float3(0,1,0)))))));
qlook_at_lh(fvec3(1.f,2.f,3.f), fvec3(0,1,0)),
qrotate(fmat3(look_at_lh(fvec3(), fvec3(1.f,2.f,3.f), fvec3(0,1,0)))))));
CHECK(all(approx(
qlook_at_rh(float3(1.f,2.f,3.f), float3(0,1,0)),
qrotate(float3x3(look_at_rh(float3(), float3(1.f,2.f,3.f), float3(0,1,0)))))));
qlook_at_rh(fvec3(1.f,2.f,3.f), fvec3(0,1,0)),
qrotate(fmat3(look_at_rh(fvec3(), fvec3(1.f,2.f,3.f), fvec3(0,1,0)))))));
}
}

View File

@@ -383,31 +383,35 @@ namespace vmath_hpp
namespace vmath_hpp
{
template fix4x4f translate(fix<float> x, fix<float> y, fix<float> z);
template fix4x4f translate(const fix4x4f&, fix<float>, fix<float>, fix<float>);
template fix4x4f trs(const fix3f&, const fix3x3f&);
template fix4x4f trs(const fix3f&, const fix3x3f&, const fix3f&);
template fix4x4f trs(const fix3f&, const qfix&);
template fix4x4f trs(const fix3f&, const qfix&, const fix3f&);
template fix4x4f translate(const fix3f&);
template fix4x4f translate(const fix4x4f&, const fix3f&);
template fix4x4f rotate(const qfix&);
template fix4x4f rotate(const fix4x4f&, const qfix&);
template fix4x4f rotate(fix<float>, const fix3f&);
template fix4x4f rotate(const fix4x4f&, fix<float>, const fix3f&);
template fix3x3f rotate(const qfix&);
template fix4x4f rotate4(const qfix&);
template fix4x4f rotate_x(fix<float>);
template fix4x4f rotate_x(const fix4x4f&, fix<float>);
template fix3x3f rotate(fix<float>, const fix3f&);
template fix4x4f rotate4(fix<float>, const fix3f&);
template fix4x4f rotate_y(fix<float>);
template fix4x4f rotate_y(const fix4x4f&, fix<float>);
template fix3x3f rotate_x(fix<float>);
template fix4x4f rotate4_x(fix<float>);
template fix4x4f rotate_z(fix<float>);
template fix4x4f rotate_z(const fix4x4f&, fix<float>);
template fix3x3f rotate_y(fix<float>);
template fix4x4f rotate4_y(fix<float>);
template fix4x4f scale(fix<float>, fix<float>, fix<float>);
template fix4x4f scale(const fix4x4f&, fix<float>, fix<float>, fix<float>);
template fix4x4f scale(const fix3f&);
template fix4x4f scale(const fix4x4f&, const fix3f&);
template fix3x3f rotate_z(fix<float>);
template fix4x4f rotate4_z(fix<float>);
template fix3x3f scale(const fix3f&);
template fix4x4f scale4(const fix3f&);
template fix3x3f look_at_lh(const fix3f&, const fix3f&);
template fix4x4f look_at_lh(const fix3f&, const fix3f&, const fix3f&);
template fix3x3f look_at_rh(const fix3f&, const fix3f&);
template fix4x4f look_at_rh(const fix3f&, const fix3f&, const fix3f&);
}
@@ -417,29 +421,19 @@ namespace vmath_hpp
namespace vmath_hpp
{
template fix3x3f translate(fix<float>, fix<float>);
template fix3x3f translate(const fix3x3f&, fix<float>, fix<float>);
template fix3x3f trs(const fix2f&, const fix2x2f&);
template fix3x3f trs(const fix2f&, const fix2x2f&, const fix2f&);
template fix3x3f translate(const fix2f&);
template fix3x3f translate(const fix3x3f&, const fix2f&);
template fix3x3f rotate(fix<float>);
template fix3x3f rotate(const fix3x3f&, fix<float>);
template fix2x2f rotate(fix<float>);
template fix3x3f rotate3(fix<float>);
template fix3x3f scale(fix<float>, fix<float>);
template fix3x3f scale(const fix3x3f&, fix<float>, fix<float>);
template fix3x3f scale(const fix2f&);
template fix3x3f scale(const fix3x3f&, const fix2f&);
template fix2x2f scale(const fix2f&);
template fix3x3f scale3(const fix2f&);
template fix3x3f shear(fix<float>, fix<float>);
template fix3x3f shear(const fix3x3f&, fix<float>, fix<float>);
template fix3x3f shear(const fix2f&);
template fix3x3f shear(const fix3x3f&, const fix2f&);
template fix3x3f shear_x(fix<float>);
template fix3x3f shear_x(const fix3x3f&, fix<float>);
template fix3x3f shear_y(fix<float>);
template fix3x3f shear_y(const fix3x3f&, fix<float>);
template fix2x2f shear(const fix2f&);
template fix3x3f shear3(const fix2f&);
}
//
@@ -475,7 +469,6 @@ namespace vmath_hpp
template fix3f rotate_x(const fix3f&, fix<float>);
template fix3f rotate_y(const fix3f&, fix<float>);
template fix3f rotate_z(const fix3f&, fix<float>);
template fix3f rotate(const fix3f&, const qfix&);
template fix3f rotate(const fix3f&, fix<float>, const fix3f&);
template fix3f project(const fix3f&, const fix3f&);
template fix3f perpendicular(const fix3f&, const fix3f&);
@@ -488,22 +481,12 @@ namespace vmath_hpp
namespace vmath_hpp
{
template qfix qrotate(const fix3x3f&);
template qfix qrotate(const qfix&, const fix3x3f&);
template qfix qrotate(const fix3f&, const fix3f&);
template qfix qrotate(const qfix&, const fix3f&, const fix3f&);
template qfix qrotate(fix<float>, const fix3f&);
template qfix qrotate(const qfix&, fix<float>, const fix3f&);
template qfix qrotate_x(fix<float>);
template qfix qrotate_x(const qfix&, fix<float>);
template qfix qrotate_y(fix<float>);
template qfix qrotate_y(const qfix&, fix<float>);
template qfix qrotate_z(fix<float>);
template qfix qrotate_z(const qfix&, fix<float>);
template qfix qlook_at_lh(const fix3f&, const fix3f&);
template qfix qlook_at_rh(const fix3f&, const fix3f&);
@@ -942,42 +925,42 @@ TEST_CASE("vmath/fix_units") {
STATIC_CHECK(unit4_w<fix<float>> == fix4f{fix(0.f),fix(0.f),fix(0.f),fix(1.f)});
}
{
STATIC_CHECK(zero2x2<fix<float>> == fix2x2f{
STATIC_CHECK(mzero2<fix<float>> == fix2x2f{
fix(0.f),fix(0.f),
fix(0.f),fix(0.f)});
STATIC_CHECK(zero3x3<fix<float>> == fix3x3f{
STATIC_CHECK(mzero3<fix<float>> == fix3x3f{
fix(0.f),fix(0.f),fix(0.f),
fix(0.f),fix(0.f),fix(0.f),
fix(0.f),fix(0.f),fix(0.f)});
STATIC_CHECK(zero4x4<fix<float>> == fix4x4f{
STATIC_CHECK(mzero4<fix<float>> == fix4x4f{
fix(0.f),fix(0.f),fix(0.f),fix(0.f),
fix(0.f),fix(0.f),fix(0.f),fix(0.f),
fix(0.f),fix(0.f),fix(0.f),fix(0.f),
fix(0.f),fix(0.f),fix(0.f),fix(0.f)});
}
{
STATIC_CHECK(unit2x2<fix<float>> == fix2x2f{
STATIC_CHECK(munit2<fix<float>> == fix2x2f{
fix(1.f),fix(1.f),
fix(1.f),fix(1.f)});
STATIC_CHECK(unit3x3<fix<float>> == fix3x3f{
STATIC_CHECK(munit3<fix<float>> == fix3x3f{
fix(1.f),fix(1.f),fix(1.f),
fix(1.f),fix(1.f),fix(1.f),
fix(1.f),fix(1.f),fix(1.f)});
STATIC_CHECK(unit4x4<fix<float>> == fix4x4f{
STATIC_CHECK(munit4<fix<float>> == fix4x4f{
fix(1.f),fix(1.f),fix(1.f),fix(1.f),
fix(1.f),fix(1.f),fix(1.f),fix(1.f),
fix(1.f),fix(1.f),fix(1.f),fix(1.f),
fix(1.f),fix(1.f),fix(1.f),fix(1.f)});
}
{
STATIC_CHECK(identity2x2<fix<float>> == fix2x2f{
STATIC_CHECK(midentity2<fix<float>> == fix2x2f{
fix(1.f),fix(0.f),
fix(0.f),fix(1.f)});
STATIC_CHECK(identity3x3<fix<float>> == fix3x3f{
STATIC_CHECK(midentity3<fix<float>> == fix3x3f{
fix(1.f),fix(0.f),fix(0.f),
fix(0.f),fix(1.f),fix(0.f),
fix(0.f),fix(0.f),fix(1.f)});
STATIC_CHECK(identity4x4<fix<float>> == fix4x4f{
STATIC_CHECK(midentity4<fix<float>> == fix4x4f{
fix(1.f),fix(0.f),fix(0.f),fix(0.f),
fix(0.f),fix(1.f),fix(0.f),fix(0.f),
fix(0.f),fix(0.f),fix(1.f),fix(0.f),

View File

@@ -31,241 +31,241 @@ namespace
TEST_CASE("vmath/mat_fun") {
SUBCASE("operators") {
STATIC_CHECK(+int2x2(1,-2,3,-4) == int2x2(1,-2,3,-4));
STATIC_CHECK(-int2x2(1,-2,3,-4) == int2x2(-1,2,-3,4));
STATIC_CHECK(~uint2x2(0xF0F0F0F0,0x0F0F0F0F,0xF0F0F0F0,0x0F0F0F0F) == uint2x2(0x0F0F0F0F,0xF0F0F0F0,0x0F0F0F0F,0xF0F0F0F0));
STATIC_CHECK((!int2x2(-1,0,1,2)) == bool2x2(false,true,false,false));
STATIC_CHECK(+imat2(1,-2,3,-4) == imat2(1,-2,3,-4));
STATIC_CHECK(-imat2(1,-2,3,-4) == imat2(-1,2,-3,4));
STATIC_CHECK(~umat2(0xF0F0F0F0,0x0F0F0F0F,0xF0F0F0F0,0x0F0F0F0F) == umat2(0x0F0F0F0F,0xF0F0F0F0,0x0F0F0F0F,0xF0F0F0F0));
STATIC_CHECK((!imat2(-1,0,1,2)) == bmat2(false,true,false,false));
STATIC_CHECK(int2x2(1,2,3,4) + 2 == int2x2(3,4,5,6));
STATIC_CHECK(int2x2(1,2,3,4) - 2 == int2x2(-1,0,1,2));
STATIC_CHECK(int2x2(1,2,3,4) * 2 == int2x2(2,4,6,8));
STATIC_CHECK(int2x2(1,2,3,4) / 2 == int2x2(0,1,1,2));
STATIC_CHECK((int2x2(11,12,11,12) & 6) == int2x2(2,4,2,4));
STATIC_CHECK((int2x2(11,12,11,12) | 6) == int2x2(15,14,15,14));
STATIC_CHECK((int2x2(11,12,11,12) ^ 6) == int2x2(13,10,13,10));
STATIC_CHECK((int2x2(1,0,1,0) && 1) == bool2x2(1,0,1,0));
STATIC_CHECK((int2x2(1,0,1,0) || 1) == bool2x2(1,1,1,1));
STATIC_CHECK(imat2(1,2,3,4) + 2 == imat2(3,4,5,6));
STATIC_CHECK(imat2(1,2,3,4) - 2 == imat2(-1,0,1,2));
STATIC_CHECK(imat2(1,2,3,4) * 2 == imat2(2,4,6,8));
STATIC_CHECK(imat2(1,2,3,4) / 2 == imat2(0,1,1,2));
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,0,1,0) && 1) == bmat2(1,0,1,0));
STATIC_CHECK((imat2(1,0,1,0) || 1) == bmat2(1,1,1,1));
STATIC_CHECK(4 + int2x2(1,2,3,4) == int2x2(5,6,7,8));
STATIC_CHECK(4 - int2x2(1,2,3,4) == int2x2(3,2,1,0));
STATIC_CHECK(4 * int2x2(1,2,3,4) == int2x2(4,8,12,16));
STATIC_CHECK(4 / int2x2(1,2,3,4) == int2x2(4,2,1,1));
STATIC_CHECK((6 &int2x2(11,12,11,12)) == int2x2(2,4,2,4));
STATIC_CHECK((6 |int2x2(11,12,11,12)) == int2x2(15,14,15,14));
STATIC_CHECK((6 ^ int2x2(11,12,11,12)) == int2x2(13,10,13,10));
STATIC_CHECK((1 && int2x2(1,0,1,0)) == bool2x2(1,0,1,0));
STATIC_CHECK((1 || int2x2(1,0,1,0)) == bool2x2(1,1,1,1));
STATIC_CHECK(4 + imat2(1,2,3,4) == imat2(5,6,7,8));
STATIC_CHECK(4 - imat2(1,2,3,4) == imat2(3,2,1,0));
STATIC_CHECK(4 * imat2(1,2,3,4) == imat2(4,8,12,16));
STATIC_CHECK(4 / imat2(1,2,3,4) == imat2(4,2,1,1));
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((1 && imat2(1,0,1,0)) == bmat2(1,0,1,0));
STATIC_CHECK((1 || imat2(1,0,1,0)) == bmat2(1,1,1,1));
STATIC_CHECK(int2x2(1,2,3,4) + int2x2(5,6,7,8) == int2x2(6,8,10,12));
STATIC_CHECK(int2x2(1,2,3,4) - int2x2(5,6,7,8) == int2x2(-4,-4,-4,-4));
STATIC_CHECK(imat2(1,2,3,4) + imat2(5,6,7,8) == imat2(6,8,10,12));
STATIC_CHECK(imat2(1,2,3,4) - imat2(5,6,7,8) == imat2(-4,-4,-4,-4));
STATIC_CHECK(int2x2() * int2x2() == int2x2());
STATIC_CHECK(int3x3() * int3x3() == int3x3());
STATIC_CHECK(imat2() * imat2() == imat2());
STATIC_CHECK(imat3() * imat3() == imat3());
STATIC_CHECK(int2(1,2) * int2x2() == int2(1,2));
STATIC_CHECK(int3(1,2,3) * int3x3() == int3(1,2,3));
STATIC_CHECK(int4(1,2,3,4) * int4x4() == int4(1,2,3,4));
STATIC_CHECK(ivec2(1,2) * imat2() == ivec2(1,2));
STATIC_CHECK(ivec3(1,2,3) * imat3() == ivec3(1,2,3));
STATIC_CHECK(ivec4(1,2,3,4) * imat4() == ivec4(1,2,3,4));
STATIC_CHECK((int2x2(6,7,6,7) & int2x2(11,12,11,12)) == int2x2(2,4,2,4));
STATIC_CHECK((int2x2(6,7,6,7) | int2x2(11,12,11,12)) == int2x2(15,15,15,15));
STATIC_CHECK((int2x2(6,7,6,7) ^ int2x2(11,12,11,12)) == int2x2(13,11,13,11));
STATIC_CHECK((int2x2(0,1,0,1) && int2x2(1,0,1,0)) == bool2x2(0,0,0,0));
STATIC_CHECK((int2x2(0,1,0,1) || int2x2(1,0,1,0)) == bool2x2(1,1,1,1));
STATIC_CHECK((imat2(6,7,6,7) & imat2(11,12,11,12)) == imat2(2,4,2,4));
STATIC_CHECK((imat2(6,7,6,7) | imat2(11,12,11,12)) == imat2(15,15,15,15));
STATIC_CHECK((imat2(6,7,6,7) ^ imat2(11,12,11,12)) == imat2(13,11,13,11));
STATIC_CHECK((imat2(0,1,0,1) && imat2(1,0,1,0)) == bmat2(0,0,0,0));
STATIC_CHECK((imat2(0,1,0,1) || imat2(1,0,1,0)) == bmat2(1,1,1,1));
{
int2x2 v{1,2,3,4};
imat2 v{1,2,3,4};
CHECK(&v == &(++v));
CHECK(v == int2x2{2,3,4,5});
CHECK(v == imat2{2,3,4,5});
CHECK(&v == &(--v));
CHECK(v == int2x2{1,2,3,4});
CHECK(v == imat2{1,2,3,4});
}
{
int2x2 v{1,2,3,4};
CHECK(v++ == int2x2{1,2,3,4});
CHECK(v == int2x2{2,3,4,5});
CHECK(v-- == int2x2{2,3,4,5});
CHECK(v == int2x2{1,2,3,4});
imat2 v{1,2,3,4};
CHECK(v++ == imat2{1,2,3,4});
CHECK(v == imat2{2,3,4,5});
CHECK(v-- == imat2{2,3,4,5});
CHECK(v == imat2{1,2,3,4});
}
{
int2x2 v{1,2,3,4};
imat2 v{1,2,3,4};
CHECK(&v == &(v += 3));
CHECK(v == int2x2{4,5,6,7});
CHECK(&v == &(v += int2x2{1,2,3,4}));
CHECK(v == int2x2{5,7,9,11});
CHECK(v == imat2{4,5,6,7});
CHECK(&v == &(v += imat2{1,2,3,4}));
CHECK(v == imat2{5,7,9,11});
}
{
int2x2 v{4,5,6,7};
imat2 v{4,5,6,7};
CHECK(&v == &(v -= 3));
CHECK(v == int2x2{1,2,3,4});
CHECK(&v == &(v -= int2x2{2,4,6,8}));
CHECK(v == int2x2{-1,-2,-3,-4});
CHECK(v == imat2{1,2,3,4});
CHECK(&v == &(v -= imat2{2,4,6,8}));
CHECK(v == imat2{-1,-2,-3,-4});
}
{
int2x2 v{1,2,3,4};
imat2 v{1,2,3,4};
CHECK(&v == &(v *= 3));
CHECK(v == int2x2{3,6,9,12});
CHECK(v == imat2{3,6,9,12});
}
{
int4 v{0, 0, 0, 1};
CHECK(&v == &(v *= translate(int3{1,2,3})));
ivec4 v{0, 0, 0, 1};
CHECK(&v == &(v *= translate(ivec3{1,2,3})));
CHECK(v == uapprox4(1,2,3,1));
}
{
int3 v{1, 2, 3};
CHECK(&v == &(v *= int3x3(scale(int3{2,3,4}))));
CHECK(v == int3(2,6,12));
ivec3 v{1, 2, 3};
CHECK(&v == &(v *= imat3(scale(ivec3{2,3,4}))));
CHECK(v == ivec3(2,6,12));
}
{
int4x4 v = translate(int3{1, 2, 3});
CHECK(&v == &(v *= translate(int3{1,2,3})));
CHECK(v == translate(int3{2,4,6}));
imat4 v = translate(ivec3{1, 2, 3});
CHECK(&v == &(v *= translate(ivec3{1,2,3})));
CHECK(v == translate(ivec3{2,4,6}));
}
{
int3x3 v = int3x3(scale(int3{1, 2, 3}));
CHECK(&v == &(v *= int3x3(scale(int3{2,3,4}))));
CHECK(v == int3x3(scale(int3{2,6,12})));
imat3 v = imat3(scale(ivec3{1, 2, 3}));
CHECK(&v == &(v *= imat3(scale(ivec3{2,3,4}))));
CHECK(v == imat3(scale(ivec3{2,6,12})));
}
{
int2x2 v1{11,12,11,12};
imat2 v1{11,12,11,12};
CHECK(&v1 == &(v1 &= 6));
CHECK(v1 == int2x2(2,4,2,4));
int2x2 v2{6,7,6,7};
CHECK(&v2 == &(v2 &= int2x2(11,12,11,12)));
CHECK(v2 == int2x2(2,4,2,4));
CHECK(v1 == imat2(2,4,2,4));
imat2 v2{6,7,6,7};
CHECK(&v2 == &(v2 &= imat2(11,12,11,12)));
CHECK(v2 == imat2(2,4,2,4));
}
{
int2x2 v1{11,12,11,12};
imat2 v1{11,12,11,12};
CHECK(&v1 == &(v1 |= 6));
CHECK(v1 == int2x2(15,14,15,14));
int2x2 v2{6,7,6,7};
CHECK(&v2 == &(v2 |= int2x2(11,12,11,12)));
CHECK(v2 == int2x2(15,15,15,15));
CHECK(v1 == imat2(15,14,15,14));
imat2 v2{6,7,6,7};
CHECK(&v2 == &(v2 |= imat2(11,12,11,12)));
CHECK(v2 == imat2(15,15,15,15));
}
{
int2x2 v1{11,12,11,12};
imat2 v1{11,12,11,12};
CHECK(&v1 == &(v1 ^= 6));
CHECK(v1 == int2x2(13,10,13,10));
int2x2 v2{6,7,6,7};
CHECK(&v2 == &(v2 ^= int2x2(11,12,11,12)));
CHECK(v2 == int2x2(13,11,13,11));
CHECK(v1 == imat2(13,10,13,10));
imat2 v2{6,7,6,7};
CHECK(&v2 == &(v2 ^= imat2(11,12,11,12)));
CHECK(v2 == imat2(13,11,13,11));
}
}
SUBCASE("Operators2") {
STATIC_CHECK(int2x2{} + 0.0 == double2x2{});
STATIC_CHECK(0.0 + int2x2{} == double2x2{});
STATIC_CHECK(int2x2{} + double2x2{} == double2x2{2.0});
STATIC_CHECK(double2x2{} + int2x2{} == double2x2{2.0});
STATIC_CHECK(imat2{} + 0.0 == dmat2{});
STATIC_CHECK(0.0 + imat2{} == dmat2{});
STATIC_CHECK(imat2{} + dmat2{} == dmat2{2.0});
STATIC_CHECK(dmat2{} + imat2{} == dmat2{2.0});
STATIC_CHECK(int2x2{} - 0.0 == double2x2{});
STATIC_CHECK(0.0 - int2x2{} == double2x2{-1.0});
STATIC_CHECK(int2x2{} - double2x2{} == double2x2{0.0});
STATIC_CHECK(double2x2{} - int2x2{} == double2x2{0.0});
STATIC_CHECK(imat2{} - 0.0 == dmat2{});
STATIC_CHECK(0.0 - imat2{} == dmat2{-1.0});
STATIC_CHECK(imat2{} - dmat2{} == dmat2{0.0});
STATIC_CHECK(dmat2{} - imat2{} == dmat2{0.0});
STATIC_CHECK(int2x2{} * 1.0 == double2x2{});
STATIC_CHECK(0.0 * int2x2{1} == double2x2{0.0});
STATIC_CHECK(int2{} * double2x2{} == double2{});
STATIC_CHECK(int2x2{} * double2x2{} == double2x2{});
STATIC_CHECK(double2x2{} * int2x2{1} == double2x2{});
STATIC_CHECK(imat2{} * 1.0 == dmat2{});
STATIC_CHECK(0.0 * imat2{1} == dmat2{0.0});
STATIC_CHECK(ivec2{} * dmat2{} == dvec2{});
STATIC_CHECK(imat2{} * dmat2{} == dmat2{});
STATIC_CHECK(dmat2{} * imat2{1} == dmat2{});
STATIC_CHECK(int2x2{} / 1.0 == double2x2{});
STATIC_CHECK(0.0 / int2x2{1,1,1,1} == double2x2{0.0});
STATIC_CHECK(imat2{} / 1.0 == dmat2{});
STATIC_CHECK(0.0 / imat2{1,1,1,1} == dmat2{0.0});
}
SUBCASE("Conversions2") {
{
STATIC_CHECK(double2x2(1.0) == double2x2(1));
STATIC_CHECK(double2x2(int2(1,2)) == double2x2(double2(1,2)));
STATIC_CHECK(double2x2(int2(1,2),float2(3,4)) == double2x2(1,2,3,4));
STATIC_CHECK(dmat2(1.0) == dmat2(1));
STATIC_CHECK(dmat2(ivec2(1,2)) == dmat2(dvec2(1,2)));
STATIC_CHECK(dmat2(ivec2(1,2),fvec2(3,4)) == dmat2(1,2,3,4));
STATIC_CHECK(double2x2(int2x2(1)) == double2x2(1));
STATIC_CHECK(double2x2(int3x3(1)) == double2x2(1));
STATIC_CHECK(double2x2(int4x4(1)) == double2x2(1));
STATIC_CHECK(dmat2(imat2(1)) == dmat2(1));
STATIC_CHECK(dmat2(imat3(1)) == dmat2(1));
STATIC_CHECK(dmat2(imat4(1)) == dmat2(1));
}
{
STATIC_CHECK(double3x3(1.0) == double3x3(1));
STATIC_CHECK(double3x3(int3(1,2,3)) == double3x3(double3(1,2,3)));
STATIC_CHECK(double3x3(int3(1,2,3),float3(2,3,4),uint3(3,4,5)) == double3x3(1,2,3,2,3,4,3,4,5));
STATIC_CHECK(dmat3(1.0) == dmat3(1));
STATIC_CHECK(dmat3(ivec3(1,2,3)) == dmat3(dvec3(1,2,3)));
STATIC_CHECK(dmat3(ivec3(1,2,3),fvec3(2,3,4),uvec3(3,4,5)) == dmat3(1,2,3,2,3,4,3,4,5));
STATIC_CHECK(double3x3(int2x2(1),uint2(2)) == double3x3(double2x2(1),double2(2)));
STATIC_CHECK(dmat3(imat2(1),uvec2(2)) == dmat3(dmat2(1),dvec2(2)));
STATIC_CHECK(double3x3(int2x2(1)) == double3x3(1));
STATIC_CHECK(double3x3(int3x3(1)) == double3x3(1));
STATIC_CHECK(double3x3(int4x4(1)) == double3x3(1));
STATIC_CHECK(dmat3(imat2(1)) == dmat3(1));
STATIC_CHECK(dmat3(imat3(1)) == dmat3(1));
STATIC_CHECK(dmat3(imat4(1)) == dmat3(1));
}
{
STATIC_CHECK(double4x4(1.0) == double4x4(1));
STATIC_CHECK(double4x4(int4(1,2,3,4)) == double4x4(double4(1,2,3,4)));
STATIC_CHECK(double4x4(int4(1,2,3,4),float4(2,3,4,5),uint4(3,4,5,6),int4(4,5,6,7)) == double4x4(1,2,3,4,2,3,4,5,3,4,5,6,4,5,6,7));
STATIC_CHECK(dmat4(1.0) == dmat4(1));
STATIC_CHECK(dmat4(ivec4(1,2,3,4)) == dmat4(dvec4(1,2,3,4)));
STATIC_CHECK(dmat4(ivec4(1,2,3,4),fvec4(2,3,4,5),uvec4(3,4,5,6),ivec4(4,5,6,7)) == dmat4(1,2,3,4,2,3,4,5,3,4,5,6,4,5,6,7));
STATIC_CHECK(double4x4(int3x3(1),uint3(2)) == double4x4(double3x3(1),double3(2)));
STATIC_CHECK(dmat4(imat3(1),uvec3(2)) == dmat4(dmat3(1),dvec3(2)));
STATIC_CHECK(double4x4(int2x2(1)) == double4x4(1));
STATIC_CHECK(double4x4(int3x3(1)) == double4x4(1));
STATIC_CHECK(double4x4(int4x4(1)) == double4x4(1));
STATIC_CHECK(dmat4(imat2(1)) == dmat4(1));
STATIC_CHECK(dmat4(imat3(1)) == dmat4(1));
STATIC_CHECK(dmat4(imat4(1)) == dmat4(1));
}
}
SUBCASE("relational functions") {
STATIC_CHECK_FALSE(any(bool2x2(false, false, false, false)));
STATIC_CHECK(any(bool2x2(true, false, true, false)));
STATIC_CHECK(any(bool2x2(false, true, false, true)));
STATIC_CHECK(any(bool2x2(true, true, true, true)));
STATIC_CHECK_FALSE(any(bmat2(false, false, false, false)));
STATIC_CHECK(any(bmat2(true, false, true, false)));
STATIC_CHECK(any(bmat2(false, true, false, true)));
STATIC_CHECK(any(bmat2(true, true, true, true)));
STATIC_CHECK_FALSE(any(int2x2(0, 0, 0, 0)));
STATIC_CHECK(any(int2x2(1, 0, 1, 0)));
STATIC_CHECK(any(int2x2(0, 1, 0, 1)));
STATIC_CHECK(any(int2x2(1, 1, 1, 1)));
STATIC_CHECK_FALSE(any(imat2(0, 0, 0, 0)));
STATIC_CHECK(any(imat2(1, 0, 1, 0)));
STATIC_CHECK(any(imat2(0, 1, 0, 1)));
STATIC_CHECK(any(imat2(1, 1, 1, 1)));
STATIC_CHECK_FALSE(all(bool2x2(false, false, false, false)));
STATIC_CHECK_FALSE(all(bool2x2(true, false, true, false)));
STATIC_CHECK_FALSE(all(bool2x2(false, true, false, true)));
STATIC_CHECK(all(bool2x2(true, true, true, true)));
STATIC_CHECK_FALSE(all(bmat2(false, false, false, false)));
STATIC_CHECK_FALSE(all(bmat2(true, false, true, false)));
STATIC_CHECK_FALSE(all(bmat2(false, true, false, true)));
STATIC_CHECK(all(bmat2(true, true, true, true)));
STATIC_CHECK_FALSE(all(int2x2(0, 0, 0, 0)));
STATIC_CHECK_FALSE(all(int2x2(1, 0, 1, 0)));
STATIC_CHECK_FALSE(all(int2x2(0, 1, 0, 1)));
STATIC_CHECK(all(int2x2(1, 1, 1, 1)));
STATIC_CHECK_FALSE(all(imat2(0, 0, 0, 0)));
STATIC_CHECK_FALSE(all(imat2(1, 0, 1, 0)));
STATIC_CHECK_FALSE(all(imat2(0, 1, 0, 1)));
STATIC_CHECK(all(imat2(1, 1, 1, 1)));
STATIC_CHECK(approx(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(false, true, false, false));
STATIC_CHECK(approx(int2x2(1,1,1,1), int2x2(0,1,2,3), 0) == bool2x2(false, true, false, false));
STATIC_CHECK(approx(int2x2(1,1,1,1), int2x2(0,1,2,3), 1) == bool2x2(true, true, true, false));
STATIC_CHECK(approx(int2x2(1,1,1,1), int2x2(0,1,2,3), 2) == bool2x2(true, true, true, true));
STATIC_CHECK(approx(imat2(1,1,1,1), imat2(0,1,2,3)) == bmat2(false, true, false, false));
STATIC_CHECK(approx(imat2(1,1,1,1), imat2(0,1,2,3), 0) == bmat2(false, true, false, false));
STATIC_CHECK(approx(imat2(1,1,1,1), imat2(0,1,2,3), 1) == bmat2(true, true, true, false));
STATIC_CHECK(approx(imat2(1,1,1,1), imat2(0,1,2,3), 2) == bmat2(true, true, true, true));
STATIC_CHECK(less(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(false, false, true, true));
STATIC_CHECK(less_equal(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(false, true, true, true));
STATIC_CHECK(greater(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(true, false, false, false));
STATIC_CHECK(greater_equal(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(true, true, false, false));
STATIC_CHECK(less(imat2(1,1,1,1), imat2(0,1,2,3)) == bmat2(false, false, true, true));
STATIC_CHECK(less_equal(imat2(1,1,1,1), imat2(0,1,2,3)) == bmat2(false, true, true, true));
STATIC_CHECK(greater(imat2(1,1,1,1), imat2(0,1,2,3)) == bmat2(true, false, false, false));
STATIC_CHECK(greater_equal(imat2(1,1,1,1), imat2(0,1,2,3)) == bmat2(true, true, false, false));
STATIC_CHECK(equal_to(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(false, true, false, false));
STATIC_CHECK(not_equal_to(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(true, false, true, true));
STATIC_CHECK(equal_to(imat2(1,1,1,1), imat2(0,1,2,3)) == bmat2(false, true, false, false));
STATIC_CHECK(not_equal_to(imat2(1,1,1,1), imat2(0,1,2,3)) == bmat2(true, false, true, true));
}
SUBCASE("transpose") {
STATIC_CHECK(transpose(int2x2(
STATIC_CHECK(transpose(imat2(
1, 2,
3, 4
)) == int2x2(
)) == imat2(
1, 3,
2, 4
));
STATIC_CHECK(transpose(int3x3(
STATIC_CHECK(transpose(imat3(
1, 2, 3,
4, 5, 6,
7, 8, 9
)) == int3x3(
)) == imat3(
1, 4, 7,
2, 5, 8,
3, 6, 9
));
STATIC_CHECK(transpose(int4x4(
STATIC_CHECK(transpose(imat4(
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16
)) == int4x4(
)) == imat4(
1, 5, 9, 13,
2, 6, 10, 14,
3, 7, 11, 15,
@@ -274,9 +274,9 @@ TEST_CASE("vmath/mat_fun") {
}
SUBCASE("determinant") {
constexpr int2x2 m2{1,2,3,4};
constexpr int3x3 m3{1,2,3,4,5,6,7,8,9};
constexpr int4x4 m4{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
constexpr imat2 m2{1,2,3,4};
constexpr imat3 m3{1,2,3,4,5,6,7,8,9};
constexpr imat4 m4{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
STATIC_CHECK(determinant(m2) == determinant(transpose(m2)));
STATIC_CHECK(determinant(m3) == determinant(transpose(m3)));
STATIC_CHECK(determinant(m4) == determinant(transpose(m4)));
@@ -291,44 +291,44 @@ TEST_CASE("vmath/mat_fun") {
}
SUBCASE("inverse") {
STATIC_CHECK(inverse(float2x2()) == float2x2());
STATIC_CHECK(inverse(float3x3()) == float3x3());
STATIC_CHECK(inverse(float4x4()) == float4x4());
STATIC_CHECK(inverse(fmat2()) == fmat2());
STATIC_CHECK(inverse(fmat3()) == fmat3());
STATIC_CHECK(inverse(fmat4()) == fmat4());
STATIC_CHECK(inverse(float2x2(0.5)) == float2x2(2.f));
STATIC_CHECK(inverse(float3x3(0.5)) == float3x3(2.f));
STATIC_CHECK(inverse(float4x4(0.5)) == float4x4(2.f));
STATIC_CHECK(inverse(fmat2(0.5)) == fmat2(2.f));
STATIC_CHECK(inverse(fmat3(0.5)) == fmat3(2.f));
STATIC_CHECK(inverse(fmat4(0.5)) == fmat4(2.f));
{
constexpr float4x4 m1 = translate(float3(1.f, 2.f, 3.f));
constexpr float4x4 rm1 = inverse(m1);
constexpr fmat4 m1 = translate(fvec3(1.f, 2.f, 3.f));
constexpr fmat4 rm1 = inverse(m1);
STATIC_CHECK(all(approx(
unit4_z<float> * m1 * rm1,
unit4_z<float>)));
}
{
const float3 axis2 = normalize(float3(1.f, 2.f, 3.f));
const float4x4 m2 = rotate(0.5f,axis2);
const float4x4 rm2 = inverse(m2);
const fvec3 axis2 = normalize(fvec3(1.f, 2.f, 3.f));
const fmat4 m2 = fmat4(rotate(0.5f,axis2));
const fmat4 rm2 = inverse(m2);
CHECK(all(approx(
unit4_z<float> * m2 * rm2,
unit4_z<float>)));
}
{
const float3 axis3 = normalize(float3(1.f, 2.f, 3.f));
const float3x3 m3 = float3x3(rotate(0.5f,axis3));
const float3x3 rm3 = inverse(m3);
const fvec3 axis3 = normalize(fvec3(1.f, 2.f, 3.f));
const fmat3 m3 = fmat3(rotate(0.5f,axis3));
const fmat3 rm3 = inverse(m3);
CHECK(all(approx(
unit3_z<float> * m3 * rm3,
unit3_z<float>)));
}
{
const float3 axis4 = normalize(float3(0.f, 0.f, 3.f));
const float2x2 m4 = float2x2(rotate(0.5f,axis4));
const float2x2 rm4 = inverse(m4);
const fvec3 axis4 = normalize(fvec3(0.f, 0.f, 3.f));
const fmat2 m4 = fmat2(rotate(0.5f,axis4));
const fmat2 rm4 = inverse(m4);
CHECK(all(approx(
unit2_y<float> * m4 * rm4,
unit2_y<float>)));

View File

@@ -14,13 +14,13 @@ namespace
TEST_CASE("vmath/mat") {
SUBCASE("size/sizeof") {
STATIC_CHECK(int2x2{}.size == 2);
STATIC_CHECK(int3x3{}.size == 3);
STATIC_CHECK(int4x4{}.size == 4);
STATIC_CHECK(imat2{}.size == 2);
STATIC_CHECK(imat3{}.size == 3);
STATIC_CHECK(imat4{}.size == 4);
STATIC_CHECK(sizeof(int2x2{}) == sizeof(int) * 2 * 2);
STATIC_CHECK(sizeof(int3x3{}) == sizeof(int) * 3 * 3);
STATIC_CHECK(sizeof(int4x4{}) == sizeof(int) * 4 * 4);
STATIC_CHECK(sizeof(imat2{}) == sizeof(int) * 2 * 2);
STATIC_CHECK(sizeof(imat3{}) == sizeof(int) * 3 * 3);
STATIC_CHECK(sizeof(imat4{}) == sizeof(int) * 4 * 4);
}
SUBCASE("guides") {
@@ -42,127 +42,127 @@ TEST_CASE("vmath/mat") {
SUBCASE("ctors") {
{
mat<int, 2> m2;
CHECK(m2.rows[0] == int2(1,0));
CHECK(m2.rows[1] == int2(0,1));
CHECK(m2.rows[0] == ivec2(1,0));
CHECK(m2.rows[1] == ivec2(0,1));
mat<int, 3> m3;
CHECK(m3.rows[0] == int3(1,0,0));
CHECK(m3.rows[1] == int3(0,1,0));
CHECK(m3.rows[2] == int3(0,0,1));
CHECK(m3.rows[0] == ivec3(1,0,0));
CHECK(m3.rows[1] == ivec3(0,1,0));
CHECK(m3.rows[2] == ivec3(0,0,1));
mat<int, 4> m4;
CHECK(m4.rows[0] == int4(1,0,0,0));
CHECK(m4.rows[1] == int4(0,1,0,0));
CHECK(m4.rows[2] == int4(0,0,1,0));
CHECK(m4.rows[3] == int4(0,0,0,1));
CHECK(m4.rows[0] == ivec4(1,0,0,0));
CHECK(m4.rows[1] == ivec4(0,1,0,0));
CHECK(m4.rows[2] == ivec4(0,0,1,0));
CHECK(m4.rows[3] == ivec4(0,0,0,1));
STATIC_CHECK(int2x2() == int2x2({1,0},{0,1}));
STATIC_CHECK(int3x3() == int3x3({1,0,0},{0,1,0},{0,0,1}));
STATIC_CHECK(int4x4() == int4x4({1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}));
STATIC_CHECK(imat2() == imat2({1,0},{0,1}));
STATIC_CHECK(imat3() == imat3({1,0,0},{0,1,0},{0,0,1}));
STATIC_CHECK(imat4() == imat4({1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}));
(void)int2x2(uninit);
(void)int3x3(uninit);
(void)int4x4(uninit);
(void)imat2(uninit);
(void)imat3(uninit);
(void)imat4(uninit);
STATIC_CHECK(int2x2(zero_init) == int2x2({0,0},{0,0}));
STATIC_CHECK(int3x3(zero_init) == int3x3({0,0,0},{0,0,0},{0,0,0}));
STATIC_CHECK(int4x4(zero_init) == int4x4({0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}));
STATIC_CHECK(imat2(zero_init) == imat2({0,0},{0,0}));
STATIC_CHECK(imat3(zero_init) == imat3({0,0,0},{0,0,0},{0,0,0}));
STATIC_CHECK(imat4(zero_init) == imat4({0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}));
STATIC_CHECK(int2x2(unit_init) == int2x2({1,1},{1,1}));
STATIC_CHECK(int3x3(unit_init) == int3x3({1,1,1},{1,1,1},{1,1,1}));
STATIC_CHECK(int4x4(unit_init) == int4x4({1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}));
STATIC_CHECK(imat2(unit_init) == imat2({1,1},{1,1}));
STATIC_CHECK(imat3(unit_init) == imat3({1,1,1},{1,1,1},{1,1,1}));
STATIC_CHECK(imat4(unit_init) == imat4({1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}));
STATIC_CHECK(int2x2(identity_init) == int2x2({1,0},{0,1}));
STATIC_CHECK(int3x3(identity_init) == int3x3({1,0,0},{0,1,0},{0,0,1}));
STATIC_CHECK(int4x4(identity_init) == int4x4({1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}));
STATIC_CHECK(imat2(identity_init) == imat2({1,0},{0,1}));
STATIC_CHECK(imat3(identity_init) == imat3({1,0,0},{0,1,0},{0,0,1}));
STATIC_CHECK(imat4(identity_init) == imat4({1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}));
}
{
STATIC_CHECK(int2x2()[0] == int2(1,0));
STATIC_CHECK(int2x2()[1] == int2(0,1));
STATIC_CHECK(imat2()[0] == ivec2(1,0));
STATIC_CHECK(imat2()[1] == ivec2(0,1));
STATIC_CHECK(int2x2(1,2,3,4)[0] == int2(1,2));
STATIC_CHECK(int2x2(1,2,3,4)[1] == int2(3,4));
STATIC_CHECK(imat2(1,2,3,4)[0] == ivec2(1,2));
STATIC_CHECK(imat2(1,2,3,4)[1] == ivec2(3,4));
STATIC_CHECK(int2x2({1,2},{3,4})[0] == int2(1,2));
STATIC_CHECK(int2x2({1,2},{3,4})[1] == int2(3,4));
STATIC_CHECK(imat2({1,2},{3,4})[0] == ivec2(1,2));
STATIC_CHECK(imat2({1,2},{3,4})[1] == ivec2(3,4));
}
{
constexpr int2x2 v(1,2,3,4);
constexpr int2x2 v2 = v;
STATIC_CHECK(v2 == int2x2(1,2,3,4));
constexpr imat2 v(1,2,3,4);
constexpr imat2 v2 = v;
STATIC_CHECK(v2 == imat2(1,2,3,4));
}
{
constexpr int2x2 v(1,2,3,4);
constexpr int2x2 v2 = std::move(v);
STATIC_CHECK(v2 == int2x2(1,2,3,4));
constexpr imat2 v(1,2,3,4);
constexpr imat2 v2 = std::move(v);
STATIC_CHECK(v2 == imat2(1,2,3,4));
}
{
STATIC_CHECK(int2x2() == int2x2(1,0,0,1));
STATIC_CHECK(int2x2(2) == int2x2(2,0,0,2));
STATIC_CHECK(int2x2(int2{2,3}) == int2x2(2,0,0,3));
STATIC_CHECK(int2x2(1,2,3,4) == int2x2(1,2,3,4));
STATIC_CHECK(int2x2({1,2},{3,4}) == int2x2(1,2,3,4));
STATIC_CHECK(int2x2(int2x2({1,2},{3,4})) == int2x2(1,2,3,4));
STATIC_CHECK(int2x2(int3x3({1,2,3},{4,5,6},{7,8,9})) == int2x2(1,2,4,5));
STATIC_CHECK(int2x2(int4x4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16})) == int2x2(1,2,5,6));
STATIC_CHECK(imat2() == imat2(1,0,0,1));
STATIC_CHECK(imat2(2) == imat2(2,0,0,2));
STATIC_CHECK(imat2(ivec2{2,3}) == imat2(2,0,0,3));
STATIC_CHECK(imat2(1,2,3,4) == imat2(1,2,3,4));
STATIC_CHECK(imat2({1,2},{3,4}) == imat2(1,2,3,4));
STATIC_CHECK(imat2(imat2({1,2},{3,4})) == imat2(1,2,3,4));
STATIC_CHECK(imat2(imat3({1,2,3},{4,5,6},{7,8,9})) == imat2(1,2,4,5));
STATIC_CHECK(imat2(imat4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16})) == imat2(1,2,5,6));
STATIC_CHECK(int3x3() == int3x3(1,0,0,0,1,0,0,0,1));
STATIC_CHECK(int3x3(2) == int3x3(2,0,0,0,2,0,0,0,2));
STATIC_CHECK(int3x3(int3{2,3,4}) == int3x3(2,0,0,0,3,0,0,0,4));
STATIC_CHECK(int3x3(1,2,3,4,5,6,7,8,9) == int3x3(1,2,3,4,5,6,7,8,9));
STATIC_CHECK(int3x3({1,2,3},{4,5,6},{7,8,9}) == int3x3(1,2,3,4,5,6,7,8,9));
STATIC_CHECK(int3x3(int2x2({1,2},{3,4}),int2{5,6}) == int3x3(1,2,0,3,4,0,5,6,1));
STATIC_CHECK(int3x3(int3x3({1,2,3},{4,5,6},{7,8,9})) == int3x3(1,2,3,4,5,6,7,8,9));
STATIC_CHECK(int3x3(int2x2({1,2},{3,4})) == int3x3(1,2,0,3,4,0,0,0,1));
STATIC_CHECK(int3x3(int4x4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16})) == int3x3(1,2,3,5,6,7,9,10,11));
STATIC_CHECK(imat3() == imat3(1,0,0,0,1,0,0,0,1));
STATIC_CHECK(imat3(2) == imat3(2,0,0,0,2,0,0,0,2));
STATIC_CHECK(imat3(ivec3{2,3,4}) == imat3(2,0,0,0,3,0,0,0,4));
STATIC_CHECK(imat3(1,2,3,4,5,6,7,8,9) == imat3(1,2,3,4,5,6,7,8,9));
STATIC_CHECK(imat3({1,2,3},{4,5,6},{7,8,9}) == imat3(1,2,3,4,5,6,7,8,9));
STATIC_CHECK(imat3(imat2({1,2},{3,4}),ivec2{5,6}) == imat3(1,2,0,3,4,0,5,6,1));
STATIC_CHECK(imat3(imat3({1,2,3},{4,5,6},{7,8,9})) == imat3(1,2,3,4,5,6,7,8,9));
STATIC_CHECK(imat3(imat2({1,2},{3,4})) == imat3(1,2,0,3,4,0,0,0,1));
STATIC_CHECK(imat3(imat4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16})) == imat3(1,2,3,5,6,7,9,10,11));
STATIC_CHECK(int4x4() == int4x4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1));
STATIC_CHECK(int4x4(2) == int4x4(2,0,0,0,0,2,0,0,0,0,2,0,0,0,0,2));
STATIC_CHECK(int4x4(int4{2,3,4,5}) == int4x4(2,0,0,0,0,3,0,0,0,0,4,0,0,0,0,5));
STATIC_CHECK(int4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) == int4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
STATIC_CHECK(int4x4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}) == int4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
STATIC_CHECK(int4x4(int3x3({1,2,3},{4,5,6},{7,8,9}),int3{10,11,12}) == int4x4(1,2,3,0,4,5,6,0,7,8,9,0,10,11,12,1));
STATIC_CHECK(int4x4(int4x4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16})) == int4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
STATIC_CHECK(int4x4(int2x2({1,2},{3,4})) == int4x4(1,2,0,0,3,4,0,0,0,0,1,0,0,0,0,1));
STATIC_CHECK(int4x4(int3x3({1,2,3},{4,5,6},{7,8,9})) == int4x4(1,2,3,0,4,5,6,0,7,8,9,0,0,0,0,1));
STATIC_CHECK(imat4() == imat4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1));
STATIC_CHECK(imat4(2) == imat4(2,0,0,0,0,2,0,0,0,0,2,0,0,0,0,2));
STATIC_CHECK(imat4(ivec4{2,3,4,5}) == imat4(2,0,0,0,0,3,0,0,0,0,4,0,0,0,0,5));
STATIC_CHECK(imat4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) == imat4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
STATIC_CHECK(imat4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}) == imat4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
STATIC_CHECK(imat4(imat3({1,2,3},{4,5,6},{7,8,9}),ivec3{10,11,12}) == imat4(1,2,3,0,4,5,6,0,7,8,9,0,10,11,12,1));
STATIC_CHECK(imat4(imat4({1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16})) == imat4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
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));
}
}
SUBCASE("operator=") {
{
int2x2 v(1,2,3,4);
int2x2 v2;
imat2 v(1,2,3,4);
imat2 v2;
v2 = v;
CHECK(v2 == int2x2(1,2,3,4));
CHECK(v2 == imat2(1,2,3,4));
}
{
int2x2 v(1,2,3,4);
int2x2 v2;
imat2 v(1,2,3,4);
imat2 v2;
v2 = std::move(v);
CHECK(v2 == int2x2(1,2,3,4));
CHECK(v2 == imat2(1,2,3,4));
}
}
SUBCASE("swap") {
{
int2x2 v1(1,2,3,4);
int2x2 v2(4,5,6,7);
imat2 v1(1,2,3,4);
imat2 v2(4,5,6,7);
v1.swap(v2);
CHECK(v1 == int2x2(4,5,6,7));
CHECK(v2 == int2x2(1,2,3,4));
CHECK(v1 == imat2(4,5,6,7));
CHECK(v2 == imat2(1,2,3,4));
}
{
int2x2 v1(1,2,3,4);
int2x2 v2(4,5,6,7);
imat2 v1(1,2,3,4);
imat2 v2(4,5,6,7);
swap(v1, v2);
CHECK(v1 == int2x2(4,5,6,7));
CHECK(v2 == int2x2(1,2,3,4));
CHECK(v1 == imat2(4,5,6,7));
CHECK(v2 == imat2(1,2,3,4));
}
}
SUBCASE("iter") {
{
int2x2 m{1,2,3,4};
imat2 m{1,2,3,4};
CHECK(*m.begin() == vec{1,2});
CHECK(*(m.begin() + 1) == vec{3,4});
@@ -193,12 +193,12 @@ TEST_CASE("vmath/mat") {
CHECK(m.crend() - 2 == m.crbegin());
*m.begin() = {5,6};
CHECK(m == int2x2{5,6,3,4});
CHECK(m == imat2{5,6,3,4});
*m.rbegin() = {7,8};
CHECK(m == int2x2{5,6,7,8});
CHECK(m == imat2{5,6,7,8});
}
{
const int2x2 m{1,2,3,4};
const imat2 m{1,2,3,4};
CHECK(*m.begin() == vec{1,2});
CHECK(*(m.begin() + 1) == vec{3,4});
@@ -232,98 +232,98 @@ TEST_CASE("vmath/mat") {
SUBCASE("data") {
{
int2x2 m2;
imat2 m2;
CHECK(m2.data() == &m2[0]);
int3x3 m3;
imat3 m3;
CHECK(m3.data() == &m3[0]);
int4x4 m4;
imat4 m4;
CHECK(m4.data() == &m4[0]);
}
{
const int2x2 m2;
const imat2 m2;
CHECK(m2.data() == &m2[0]);
const int3x3 m3;
const imat3 m3;
CHECK(m3.data() == &m3[0]);
const int4x4 m4;
const imat4 m4;
CHECK(m4.data() == &m4[0]);
}
}
SUBCASE("operator[]") {
{
STATIC_CHECK(int2x2()[0] == int2(1,0));
STATIC_CHECK(int2x2()[1] == int2(0,1));
STATIC_CHECK(imat2()[0] == ivec2(1,0));
STATIC_CHECK(imat2()[1] == ivec2(0,1));
STATIC_CHECK(int3x3()[0] == int3(1,0,0));
STATIC_CHECK(int3x3()[1] == int3(0,1,0));
STATIC_CHECK(int3x3()[2] == int3(0,0,1));
STATIC_CHECK(imat3()[0] == ivec3(1,0,0));
STATIC_CHECK(imat3()[1] == ivec3(0,1,0));
STATIC_CHECK(imat3()[2] == ivec3(0,0,1));
STATIC_CHECK(int4x4()[0] == int4(1,0,0,0));
STATIC_CHECK(int4x4()[1] == int4(0,1,0,0));
STATIC_CHECK(int4x4()[2] == int4(0,0,1,0));
STATIC_CHECK(int4x4()[3] == int4(0,0,0,1));
STATIC_CHECK(imat4()[0] == ivec4(1,0,0,0));
STATIC_CHECK(imat4()[1] == ivec4(0,1,0,0));
STATIC_CHECK(imat4()[2] == ivec4(0,0,1,0));
STATIC_CHECK(imat4()[3] == ivec4(0,0,0,1));
}
{
int2x2 v;
v[0] = int2(1,2);
v[1] = int2(3,4);
CHECK(v == int2x2(1,2,3,4));
CHECK(std::as_const(v).at(0) == int2(1,2));
CHECK(std::as_const(v).at(1) == int2(3,4));
imat2 v;
v[0] = ivec2(1,2);
v[1] = ivec2(3,4);
CHECK(v == imat2(1,2,3,4));
CHECK(std::as_const(v).at(0) == ivec2(1,2));
CHECK(std::as_const(v).at(1) == ivec2(3,4));
}
{
int3x3 v;
v[0] = int3(1,2,3);
v[1] = int3(4,5,6);
v[2] = int3(7,8,9);
CHECK(v == int3x3(1,2,3,4,5,6,7,8,9));
CHECK(std::as_const(v).at(0) == int3(1,2,3));
CHECK(std::as_const(v).at(1) == int3(4,5,6));
CHECK(std::as_const(v).at(2) == int3(7,8,9));
imat3 v;
v[0] = ivec3(1,2,3);
v[1] = ivec3(4,5,6);
v[2] = ivec3(7,8,9);
CHECK(v == imat3(1,2,3,4,5,6,7,8,9));
CHECK(std::as_const(v).at(0) == ivec3(1,2,3));
CHECK(std::as_const(v).at(1) == ivec3(4,5,6));
CHECK(std::as_const(v).at(2) == ivec3(7,8,9));
}
{
int4x4 v;
v[0] = int4(1,2,3,4);
v[1] = int4(5,6,7,8);
v[2] = int4(9,10,11,12);
v[3] = int4(13,14,15,16);
CHECK(v == int4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
CHECK(std::as_const(v).at(0) == int4(1,2,3,4));
CHECK(std::as_const(v).at(1) == int4(5,6,7,8));
CHECK(std::as_const(v).at(2) == int4(9,10,11,12));
CHECK(std::as_const(v).at(3) == int4(13,14,15,16));
imat4 v;
v[0] = ivec4(1,2,3,4);
v[1] = ivec4(5,6,7,8);
v[2] = ivec4(9,10,11,12);
v[3] = ivec4(13,14,15,16);
CHECK(v == imat4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16));
CHECK(std::as_const(v).at(0) == ivec4(1,2,3,4));
CHECK(std::as_const(v).at(1) == ivec4(5,6,7,8));
CHECK(std::as_const(v).at(2) == ivec4(9,10,11,12));
CHECK(std::as_const(v).at(3) == ivec4(13,14,15,16));
}
}
SUBCASE("at") {
STATIC_CHECK(int2x2(1,2,3,4).at(0) == int2(1,2));
STATIC_CHECK(int2x2(1,2,3,4).at(1) == int2(3,4));
STATIC_CHECK(imat2(1,2,3,4).at(0) == ivec2(1,2));
STATIC_CHECK(imat2(1,2,3,4).at(1) == ivec2(3,4));
#ifndef VMATH_HPP_NO_EXCEPTIONS
CHECK_THROWS_AS((void)int2x2(1,2,3,4).at(2), std::out_of_range);
CHECK_THROWS_AS((void)imat2(1,2,3,4).at(2), std::out_of_range);
#endif
}
SUBCASE("operator==/operator!=") {
STATIC_CHECK(int2x2(1,2,3,4) == int2x2(1,2,3,4));
STATIC_CHECK_FALSE(int2x2(1,2,3,4) == int2x2(2,2,3,4));
STATIC_CHECK_FALSE(int2x2(1,2,3,4) == int2x2(1,3,3,4));
STATIC_CHECK(imat2(1,2,3,4) == imat2(1,2,3,4));
STATIC_CHECK_FALSE(imat2(1,2,3,4) == imat2(2,2,3,4));
STATIC_CHECK_FALSE(imat2(1,2,3,4) == imat2(1,3,3,4));
STATIC_CHECK_FALSE(int2x2(1,2,3,4) != int2x2(1,2,3,4));
STATIC_CHECK(int2x2(1,2,3,4) != int2x2(2,2,3,4));
STATIC_CHECK(int2x2(1,2,3,4) != int2x2(1,3,3,4));
STATIC_CHECK_FALSE(imat2(1,2,3,4) != imat2(1,2,3,4));
STATIC_CHECK(imat2(1,2,3,4) != imat2(2,2,3,4));
STATIC_CHECK(imat2(1,2,3,4) != imat2(1,3,3,4));
}
SUBCASE("operator<") {
STATIC_CHECK_FALSE(int2x2(1,2,3,4) < int2x2(1,2,3,4));
STATIC_CHECK_FALSE(imat2(1,2,3,4) < imat2(1,2,3,4));
STATIC_CHECK(int2x2(1,1,3,4) < int2x2(1,2,3,4));
STATIC_CHECK_FALSE(int2x2(1,2,3,4) < int2x2(1,1,3,4));
STATIC_CHECK(imat2(1,1,3,4) < imat2(1,2,3,4));
STATIC_CHECK_FALSE(imat2(1,2,3,4) < imat2(1,1,3,4));
STATIC_CHECK(int2x2(0,3,3,4) < int2x2(1,2,3,4));
STATIC_CHECK_FALSE(int2x2(1,2,3,4) < int2x2(0,3,3,4));
STATIC_CHECK(imat2(0,3,3,4) < imat2(1,2,3,4));
STATIC_CHECK_FALSE(imat2(1,2,3,4) < imat2(0,3,3,4));
}
}

View File

@@ -53,37 +53,37 @@ TEST_CASE("vmath/qua_fun") {
}
{
float3 v{1,0,0};
CHECK(&v == &(v *= qfloat{0,0,0.7071067812f,0.7071067812f}));
fvec3 v{1,0,0};
CHECK(&v == &(v *= fqua{0,0,0.7071067812f,0.7071067812f}));
CHECK(v == uapprox3(0.f,1.f,0.f));
}
STATIC_CHECK(qfloat{} * qfloat{} == qfloat{});
STATIC_CHECK(float3{1,2,3} * qfloat{} == uapprox3(1.f,2.f,3.f));
STATIC_CHECK(float3{1,0,0} * qfloat{0,0,0.7071067812f,0.7071067812f} == uapprox3(0.f,1.f,0.f));
STATIC_CHECK(fqua{} * fqua{} == fqua{});
STATIC_CHECK(fvec3{1,2,3} * fqua{} == uapprox3(1.f,2.f,3.f));
STATIC_CHECK(fvec3{1,0,0} * fqua{0,0,0.7071067812f,0.7071067812f} == uapprox3(0.f,1.f,0.f));
}
SUBCASE("Operators2") {
STATIC_CHECK(qfloat{} + qdouble{} == qdouble{0,0,0,2});
STATIC_CHECK(qfloat{} - qdouble{} == qdouble{0,0,0,0});
STATIC_CHECK(fqua{} + dqua{} == dqua{0,0,0,2});
STATIC_CHECK(fqua{} - dqua{} == dqua{0,0,0,0});
STATIC_CHECK(qfloat{} * 1.0 == qdouble{});
STATIC_CHECK(1.0 * qfloat{} == qdouble{});
STATIC_CHECK(float3{} * qdouble{} == double3{});
STATIC_CHECK(qfloat{} * qdouble{} == qdouble{});
STATIC_CHECK(fqua{} * 1.0 == dqua{});
STATIC_CHECK(1.0 * fqua{} == dqua{});
STATIC_CHECK(fvec3{} * dqua{} == dvec3{});
STATIC_CHECK(fqua{} * dqua{} == dqua{});
STATIC_CHECK(qfloat{} / 1.0 == qdouble{});
STATIC_CHECK(1.0 / qfloat{1,1,1,1} == qdouble{1,1,1,1});
STATIC_CHECK(fqua{} / 1.0 == dqua{});
STATIC_CHECK(1.0 / fqua{1,1,1,1} == dqua{1,1,1,1});
}
SUBCASE("Conversions2") {
STATIC_CHECK(qdouble(1,2.f,3.0,4u) == qdouble(1,2,3,4));
STATIC_CHECK(qdouble(int3(1,2,3),4u) == qdouble(1,2,3,4));
STATIC_CHECK(qdouble(int4(1,2,3,4)) == qdouble(1,2,3,4));
STATIC_CHECK(qdouble(qfloat(1,2,3,4)) == qdouble(1,2,3,4));
STATIC_CHECK(dqua(1,2.f,3.0,4u) == dqua(1,2,3,4));
STATIC_CHECK(dqua(ivec3(1,2,3),4u) == dqua(1,2,3,4));
STATIC_CHECK(dqua(ivec4(1,2,3,4)) == dqua(1,2,3,4));
STATIC_CHECK(dqua(fqua(1,2,3,4)) == dqua(1,2,3,4));
STATIC_CHECK(float4(qfloat(1,2,3,4)) == float4(1,2,3,4));
STATIC_CHECK(double4(qfloat(1,2,3,4)) == double4(1,2,3,4));
STATIC_CHECK(fvec4(fqua(1,2,3,4)) == fvec4(1,2,3,4));
STATIC_CHECK(dvec4(fqua(1,2,3,4)) == dvec4(1,2,3,4));
}
SUBCASE("Common Functions") {
@@ -155,19 +155,19 @@ TEST_CASE("vmath/qua_fun") {
SUBCASE("Geometric Functions") {
STATIC_CHECK(dot(qua(1,2,3,4),qua(3,4,5,6)) == 50);
STATIC_CHECK(dot(qfloat(1,2,3,4),qdouble(3,4,5,6)) == uapprox(50.0));
STATIC_CHECK(dot(fqua(1,2,3,4),dqua(3,4,5,6)) == uapprox(50.0));
CHECK(length(qfloat(10.f,0.f,0.f,0.f)) == uapprox(10.f));
CHECK(length(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(10.f));
CHECK(length(fqua(10.f,0.f,0.f,0.f)) == uapprox(10.f));
CHECK(length(fqua(-10.f,0.f,0.f,0.f)) == uapprox(10.f));
CHECK(rlength(qfloat(10.f,0.f,0.f,0.f)) == uapprox(0.1f));
CHECK(rlength(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(0.1f));
CHECK(rlength(fqua(10.f,0.f,0.f,0.f)) == uapprox(0.1f));
CHECK(rlength(fqua(-10.f,0.f,0.f,0.f)) == uapprox(0.1f));
STATIC_CHECK(length2(qfloat(10.f,0.f,0.f,0.f)) == uapprox(100.f));
STATIC_CHECK(length2(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(100.f));
STATIC_CHECK(length2(fqua(10.f,0.f,0.f,0.f)) == uapprox(100.f));
STATIC_CHECK(length2(fqua(-10.f,0.f,0.f,0.f)) == uapprox(100.f));
STATIC_CHECK(rlength2(qfloat(10.f,0.f,0.f,0.f)) == uapprox(0.01f));
STATIC_CHECK(rlength2(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(0.01f));
STATIC_CHECK(rlength2(fqua(10.f,0.f,0.f,0.f)) == uapprox(0.01f));
STATIC_CHECK(rlength2(fqua(-10.f,0.f,0.f,0.f)) == uapprox(0.01f));
CHECK(distance(qrotate_z(radians(0.f)) * 2.f, qrotate_z(radians(0.f)) * 1.5f) == uapprox(radians(0.f)));
CHECK(distance(qrotate_z(radians(0.f)) * 3.f, qrotate_z(radians(360.f)) * 2.5f) == uapprox(radians(0.f)));
@@ -176,7 +176,7 @@ TEST_CASE("vmath/qua_fun") {
CHECK(distance(qrotate_z(radians(15.f)) * 6.f, qrotate_z(radians(350.f)) * 5.5f) == uapprox(radians(25.f)));
CHECK(distance(qrotate_z(radians(350.f)) * 7.f, qrotate_z(radians(15.f)) * 6.5f) == uapprox(radians(25.f)));
CHECK(normalize(qfloat(0.5f,0.f,0.f,0.f)).v == uapprox3(1.f,0.f,0.f));
CHECK(normalize(fqua(0.5f,0.f,0.f,0.f)).v == uapprox3(1.f,0.f,0.f));
}
SUBCASE("Relational Functions") {
@@ -193,18 +193,18 @@ TEST_CASE("vmath/qua_fun") {
STATIC_CHECK(all(qua(1,1,1,1)));
STATIC_CHECK_FALSE(all(qua(0,0,0,0)));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3)) == bool4(false, true, false, false));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 0) == bool4(false, true, false, false));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 1) == bool4(true, true, true, false));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 2) == bool4(true, true, true, true));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3)) == bvec4(false, true, false, false));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 0) == bvec4(false, true, false, false));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 1) == bvec4(true, true, true, false));
STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 2) == bvec4(true, true, true, true));
STATIC_CHECK(less(qua(1,1,1,1), qua(0,1,2,3)) == bool4(false, false, true, true));
STATIC_CHECK(less_equal(qua(1,1,1,1), qua(0,1,2,3)) == bool4(false, true, true, true));
STATIC_CHECK(greater(qua(1,1,1,1), qua(0,1,2,3)) == bool4(true, false, false, false));
STATIC_CHECK(greater_equal(qua(1,1,1,1), qua(0,1,2,3)) == bool4(true, true, false, false));
STATIC_CHECK(less(qua(1,1,1,1), qua(0,1,2,3)) == bvec4(false, false, true, true));
STATIC_CHECK(less_equal(qua(1,1,1,1), qua(0,1,2,3)) == bvec4(false, true, true, true));
STATIC_CHECK(greater(qua(1,1,1,1), qua(0,1,2,3)) == bvec4(true, false, false, false));
STATIC_CHECK(greater_equal(qua(1,1,1,1), qua(0,1,2,3)) == bvec4(true, true, false, false));
STATIC_CHECK(equal_to(qua(1,1,1,1), qua(0,1,2,3)) == bool4(false, true, false, false));
STATIC_CHECK(not_equal_to(qua(1,1,1,1), qua(0,1,2,3)) == bool4(true, false, true, true));
STATIC_CHECK(equal_to(qua(1,1,1,1), qua(0,1,2,3)) == bvec4(false, true, false, false));
STATIC_CHECK(not_equal_to(qua(1,1,1,1), qua(0,1,2,3)) == bvec4(true, false, true, true));
}
SUBCASE("Quaternion Functions") {

View File

@@ -14,11 +14,11 @@ namespace
TEST_CASE("vmath/qua") {
SUBCASE("size/sizeof") {
STATIC_CHECK(qfloat{}.size == 4);
STATIC_CHECK(qdouble{}.size == 4);
STATIC_CHECK(fqua{}.size == 4);
STATIC_CHECK(dqua{}.size == 4);
STATIC_CHECK(sizeof(qfloat{}) == sizeof(float) * 4);
STATIC_CHECK(sizeof(qdouble{}) == sizeof(double) * 4);
STATIC_CHECK(sizeof(fqua{}) == sizeof(float) * 4);
STATIC_CHECK(sizeof(dqua{}) == sizeof(double) * 4);
}
SUBCASE("guides") {
@@ -32,7 +32,7 @@ TEST_CASE("vmath/qua") {
SUBCASE("ctors") {
{
qua<int> q;
CHECK(q.v == int3(0,0,0));
CHECK(q.v == ivec3(0,0,0));
CHECK(q.s == 1);
STATIC_CHECK(qua<int>() == qua<int>({0,0,0},1));
@@ -41,64 +41,64 @@ TEST_CASE("vmath/qua") {
STATIC_CHECK(qua<int>(identity_init) == qua<int>({0,0,0},1));
}
{
STATIC_CHECK(qfloat{}.v == uapprox3(0.f));
STATIC_CHECK(qfloat{}.s == uapprox(1.f));
STATIC_CHECK(fqua{}.v == uapprox3(0.f));
STATIC_CHECK(fqua{}.s == uapprox(1.f));
STATIC_CHECK(qfloat{1,2,3,4}.v == uapprox3(1.f,2.f,3.f));
STATIC_CHECK(qfloat{1,2,3,4}.s == uapprox(4.f));
STATIC_CHECK(fqua{1,2,3,4}.v == uapprox3(1.f,2.f,3.f));
STATIC_CHECK(fqua{1,2,3,4}.s == uapprox(4.f));
STATIC_CHECK(qfloat{{1,2,3},4}.v == uapprox3(1.f,2.f,3.f));
STATIC_CHECK(qfloat{{1,2,3},4}.s == uapprox(4.f));
STATIC_CHECK(fqua{{1,2,3},4}.v == uapprox3(1.f,2.f,3.f));
STATIC_CHECK(fqua{{1,2,3},4}.s == uapprox(4.f));
STATIC_CHECK(qfloat{{1,2,3,4}}.v == uapprox3(1.f,2.f,3.f));
STATIC_CHECK(qfloat{{1,2,3,4}}.s == uapprox(4.f));
STATIC_CHECK(fqua{{1,2,3,4}}.v == uapprox3(1.f,2.f,3.f));
STATIC_CHECK(fqua{{1,2,3,4}}.s == uapprox(4.f));
}
{
constexpr qfloat q(1,2,3,4);
constexpr qfloat q2 = q;
STATIC_CHECK(q2 == qfloat(1,2,3,4));
constexpr fqua q(1,2,3,4);
constexpr fqua q2 = q;
STATIC_CHECK(q2 == fqua(1,2,3,4));
}
{
constexpr qfloat q(1,2,3,4);
constexpr qfloat q2 = std::move(q);
STATIC_CHECK(q2 == qfloat(1,2,3,4));
constexpr fqua q(1,2,3,4);
constexpr fqua q2 = std::move(q);
STATIC_CHECK(q2 == fqua(1,2,3,4));
}
{
STATIC_CHECK(qfloat(1,2,3,4) == qfloat(1,2,3,4));
STATIC_CHECK(qfloat(float3(1,2,3),4) == qfloat(1,2,3,4));
STATIC_CHECK(qfloat(float4(1,2,3,4)) == qfloat(1,2,3,4));
STATIC_CHECK(fqua(1,2,3,4) == fqua(1,2,3,4));
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));
}
}
SUBCASE("operator=") {
{
qfloat v(1,2,3,4);
qfloat v2;
fqua v(1,2,3,4);
fqua v2;
v2 = v;
CHECK(v2 == qfloat(1,2,3,4));
CHECK(v2 == fqua(1,2,3,4));
}
{
qfloat v(1,2,3,4);
qfloat v2;
fqua v(1,2,3,4);
fqua v2;
v2 = std::move(v);
CHECK(v2 == qfloat(1,2,3,4));
CHECK(v2 == fqua(1,2,3,4));
}
}
SUBCASE("swap") {
{
qfloat v1(1,2,3,4);
qfloat v2(4,5,6,7);
fqua v1(1,2,3,4);
fqua v2(4,5,6,7);
v1.swap(v2);
CHECK(v1 == qfloat(4,5,6,7));
CHECK(v2 == qfloat(1,2,3,4));
CHECK(v1 == fqua(4,5,6,7));
CHECK(v2 == fqua(1,2,3,4));
}
{
qfloat v1(1,2,3,4);
qfloat v2(4,5,6,7);
fqua v1(1,2,3,4);
fqua v2(4,5,6,7);
swap(v1, v2);
CHECK(v1 == qfloat(4,5,6,7));
CHECK(v2 == qfloat(1,2,3,4));
CHECK(v1 == fqua(4,5,6,7));
CHECK(v2 == fqua(1,2,3,4));
}
}
@@ -174,11 +174,11 @@ TEST_CASE("vmath/qua") {
SUBCASE("data") {
{
qfloat i2;
fqua i2;
CHECK(i2.data() == &i2[0]);
}
{
const qfloat i2;
const fqua i2;
CHECK(i2.data() == &i2[0]);
}
}
@@ -240,29 +240,29 @@ TEST_CASE("vmath/qua") {
}
SUBCASE("operator==/operator!=") {
STATIC_CHECK(qfloat(1,2,3,4) == qfloat(1,2,3,4));
STATIC_CHECK_FALSE(qfloat(1,2,3,4) == qfloat(2,2,3,4));
STATIC_CHECK_FALSE(qfloat(1,2,3,4) == qfloat(1,3,3,4));
STATIC_CHECK(fqua(1,2,3,4) == fqua(1,2,3,4));
STATIC_CHECK_FALSE(fqua(1,2,3,4) == fqua(2,2,3,4));
STATIC_CHECK_FALSE(fqua(1,2,3,4) == fqua(1,3,3,4));
STATIC_CHECK_FALSE(qfloat(1,2,3,4) != qfloat(1,2,3,4));
STATIC_CHECK(qfloat(1,2,3,4) != qfloat(2,2,3,4));
STATIC_CHECK(qfloat(1,2,3,4) != qfloat(1,3,3,4));
STATIC_CHECK_FALSE(fqua(1,2,3,4) != fqua(1,2,3,4));
STATIC_CHECK(fqua(1,2,3,4) != fqua(2,2,3,4));
STATIC_CHECK(fqua(1,2,3,4) != fqua(1,3,3,4));
}
SUBCASE("operator<") {
STATIC_CHECK_FALSE(qfloat(1,2,3,4) < qfloat(1,2,3,4));
STATIC_CHECK_FALSE(fqua(1,2,3,4) < fqua(1,2,3,4));
STATIC_CHECK(qfloat(0,2,3,4) < qfloat(1,2,3,4));
STATIC_CHECK(qfloat(1,1,3,4) < qfloat(1,2,3,4));
STATIC_CHECK(qfloat(1,2,2,4) < qfloat(1,2,3,4));
STATIC_CHECK(qfloat(1,2,3,3) < qfloat(1,2,3,4));
STATIC_CHECK(fqua(0,2,3,4) < fqua(1,2,3,4));
STATIC_CHECK(fqua(1,1,3,4) < fqua(1,2,3,4));
STATIC_CHECK(fqua(1,2,2,4) < fqua(1,2,3,4));
STATIC_CHECK(fqua(1,2,3,3) < fqua(1,2,3,4));
STATIC_CHECK_FALSE(qfloat(1,2,3,4) < qfloat(0,2,3,4));
STATIC_CHECK_FALSE(qfloat(1,2,3,4) < qfloat(1,1,3,4));
STATIC_CHECK_FALSE(qfloat(1,2,3,4) < qfloat(1,2,2,4));
STATIC_CHECK_FALSE(qfloat(1,2,3,4) < qfloat(1,2,3,3));
STATIC_CHECK_FALSE(fqua(1,2,3,4) < fqua(0,2,3,4));
STATIC_CHECK_FALSE(fqua(1,2,3,4) < fqua(1,1,3,4));
STATIC_CHECK_FALSE(fqua(1,2,3,4) < fqua(1,2,2,4));
STATIC_CHECK_FALSE(fqua(1,2,3,4) < fqua(1,2,3,3));
STATIC_CHECK(qfloat(0,3,3,4) < qfloat(1,2,3,4));
STATIC_CHECK_FALSE(qfloat(1,2,3,4) < qfloat(0,3,3,4));
STATIC_CHECK(fqua(0,3,3,4) < fqua(1,2,3,4));
STATIC_CHECK_FALSE(fqua(1,2,3,4) < fqua(0,3,3,4));
}
}

View File

@@ -14,351 +14,351 @@ namespace
TEST_CASE("vmath/vec_fun") {
SUBCASE("Operators") {
STATIC_CHECK(+int2(1,-2) == int2(1,-2));
STATIC_CHECK(-int2(1,-2) == int2(-1,2));
STATIC_CHECK(~uint2(0xF0F0F0F0,0x0F0F0F0F) == uint2(0x0F0F0F0F,0xF0F0F0F0));
STATIC_CHECK((!int3(-1,0,1)) == bool3(false, true, false));
STATIC_CHECK(+ivec2(1,-2) == ivec2(1,-2));
STATIC_CHECK(-ivec2(1,-2) == ivec2(-1,2));
STATIC_CHECK(~uvec2(0xF0F0F0F0,0x0F0F0F0F) == uvec2(0x0F0F0F0F,0xF0F0F0F0));
STATIC_CHECK((!ivec3(-1,0,1)) == bvec3(false, true, false));
STATIC_CHECK(int2(1,2) + 3 == int2(4,5));
STATIC_CHECK(int2(1,2) - 3 == int2(-2,-1));
STATIC_CHECK(int2(1,2) * 3 == int2(3,6));
STATIC_CHECK(int2(2,4) / 2 == int2(1,2));
STATIC_CHECK((int2(11,12) & 6) == int2(2,4));
STATIC_CHECK((int2(11,12) | 6) == int2(15,14));
STATIC_CHECK((int2(11,12) ^ 6) == int2(13,10));
STATIC_CHECK((int2(1,0) && 1) == bool2(1,0));
STATIC_CHECK((int2(1,0) || 1) == bool2(1,1));
STATIC_CHECK(ivec2(1,2) + 3 == ivec2(4,5));
STATIC_CHECK(ivec2(1,2) - 3 == ivec2(-2,-1));
STATIC_CHECK(ivec2(1,2) * 3 == ivec2(3,6));
STATIC_CHECK(ivec2(2,4) / 2 == ivec2(1,2));
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(1,0) && 1) == bvec2(1,0));
STATIC_CHECK((ivec2(1,0) || 1) == bvec2(1,1));
STATIC_CHECK(3 + int2(1,2) == int2(4,5));
STATIC_CHECK(3 - int2(1,2) == int2(2,1));
STATIC_CHECK(3 * int2(1,2) == int2(3,6));
STATIC_CHECK(4 / int2(2,4) == int2(2,1));
STATIC_CHECK((6 & int2(11,12)) == int2(2,4));
STATIC_CHECK((6 | int2(11,12)) == int2(15,14));
STATIC_CHECK((6 ^ int2(11,12)) == int2(13,10));
STATIC_CHECK((1 && int2(1,0)) == bool2(1,0));
STATIC_CHECK((1 || int2(1,0)) == bool2(1,1));
STATIC_CHECK(3 + ivec2(1,2) == ivec2(4,5));
STATIC_CHECK(3 - ivec2(1,2) == ivec2(2,1));
STATIC_CHECK(3 * ivec2(1,2) == ivec2(3,6));
STATIC_CHECK(4 / ivec2(2,4) == ivec2(2,1));
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((1 && ivec2(1,0)) == bvec2(1,0));
STATIC_CHECK((1 || ivec2(1,0)) == bvec2(1,1));
STATIC_CHECK(int2(1,2) + int2(3,4) == int2(4,6));
STATIC_CHECK(int2(1,2) - int2(3,4) == int2(-2,-2));
STATIC_CHECK(int2(1,2) * int2(3,4) == int2(3,8));
STATIC_CHECK(int2(3,4) / int2(1,2) == int2(3,2));
STATIC_CHECK((int2(6,7) & int2(11,12)) == int2(2,4));
STATIC_CHECK((int2(6,7) | int2(11,12)) == int2(15,15));
STATIC_CHECK((int2(6,7) ^ int2(11,12)) == int2(13,11));
STATIC_CHECK((int2(0,1) && int2(1,0)) == bool2(0,0));
STATIC_CHECK((int2(0,1) || int2(1,0)) == bool2(1,1));
STATIC_CHECK(ivec2(1,2) + ivec2(3,4) == ivec2(4,6));
STATIC_CHECK(ivec2(1,2) - ivec2(3,4) == ivec2(-2,-2));
STATIC_CHECK(ivec2(1,2) * ivec2(3,4) == ivec2(3,8));
STATIC_CHECK(ivec2(3,4) / ivec2(1,2) == ivec2(3,2));
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(0,1) && ivec2(1,0)) == bvec2(0,0));
STATIC_CHECK((ivec2(0,1) || ivec2(1,0)) == bvec2(1,1));
{
int2 v{1,2};
ivec2 v{1,2};
CHECK(&v == &(++v));
CHECK(v == int2{2,3});
CHECK(v == ivec2{2,3});
CHECK(&v == &(--v));
CHECK(v == int2{1,2});
CHECK(v == ivec2{1,2});
}
{
int2 v{1,2};
CHECK(v++ == int2{1,2});
CHECK(v == int2{2,3});
CHECK(v-- == int2{2,3});
CHECK(v == int2{1,2});
ivec2 v{1,2};
CHECK(v++ == ivec2{1,2});
CHECK(v == ivec2{2,3});
CHECK(v-- == ivec2{2,3});
CHECK(v == ivec2{1,2});
}
{
int2 v{1,2};
ivec2 v{1,2};
CHECK(&v == &(v += 3));
CHECK(v == int2{4,5});
CHECK(&v == &(v += int2{1,2}));
CHECK(v == int2{5,7});
CHECK(v == ivec2{4,5});
CHECK(&v == &(v += ivec2{1,2}));
CHECK(v == ivec2{5,7});
}
{
int2 v{4,5};
ivec2 v{4,5};
CHECK(&v == &(v -= 3));
CHECK(v == int2{1,2});
CHECK(&v == &(v -= int2{2,4}));
CHECK(v == int2{-1,-2});
CHECK(v == ivec2{1,2});
CHECK(&v == &(v -= ivec2{2,4}));
CHECK(v == ivec2{-1,-2});
}
{
int2 v{1,2};
ivec2 v{1,2};
CHECK(&v == &(v *= 3));
CHECK(v == int2{3,6});
CHECK(&v == &(v *= int2{2,3}));
CHECK(v == int2{6,18});
CHECK(v == ivec2{3,6});
CHECK(&v == &(v *= ivec2{2,3}));
CHECK(v == ivec2{6,18});
}
{
int2 v{6,18};
ivec2 v{6,18};
CHECK(&v == &(v /= 2));
CHECK(v == int2{3,9});
CHECK(&v == &(v /= int2{3,4}));
CHECK(v == int2{1,2});
CHECK(v == ivec2{3,9});
CHECK(&v == &(v /= ivec2{3,4}));
CHECK(v == ivec2{1,2});
}
{
int2 v1{11,12};
ivec2 v1{11,12};
CHECK(&v1 == &(v1 &= 6));
CHECK(v1 == int2(2,4));
int2 v2{6,7};
CHECK(&v2 == &(v2 &= int2(11,12)));
CHECK(v2 == int2(2,4));
CHECK(v1 == ivec2(2,4));
ivec2 v2{6,7};
CHECK(&v2 == &(v2 &= ivec2(11,12)));
CHECK(v2 == ivec2(2,4));
}
{
int2 v1{11,12};
ivec2 v1{11,12};
CHECK(&v1 == &(v1 |= 6));
CHECK(v1 == int2(15,14));
int2 v2{6,7};
CHECK(&v2 == &(v2 |= int2(11,12)));
CHECK(v2 == int2(15,15));
CHECK(v1 == ivec2(15,14));
ivec2 v2{6,7};
CHECK(&v2 == &(v2 |= ivec2(11,12)));
CHECK(v2 == ivec2(15,15));
}
{
int2 v1{11,12};
ivec2 v1{11,12};
CHECK(&v1 == &(v1 ^= 6));
CHECK(v1 == int2(13,10));
int2 v2{6,7};
CHECK(&v2 == &(v2 ^= int2(11,12)));
CHECK(v2 == int2(13,11));
CHECK(v1 == ivec2(13,10));
ivec2 v2{6,7};
CHECK(&v2 == &(v2 ^= ivec2(11,12)));
CHECK(v2 == ivec2(13,11));
}
}
SUBCASE("Operators2") {
STATIC_CHECK(int2{} + 0.0 == double2{});
STATIC_CHECK(0.0 + int2{} == double2{});
STATIC_CHECK(int2{} + double2{} == double2{});
STATIC_CHECK(double2{} + int2{} == double2{});
STATIC_CHECK(ivec2{} + 0.0 == dvec2{});
STATIC_CHECK(0.0 + ivec2{} == dvec2{});
STATIC_CHECK(ivec2{} + dvec2{} == dvec2{});
STATIC_CHECK(dvec2{} + ivec2{} == dvec2{});
STATIC_CHECK(int2{} - 0.0 == double2{});
STATIC_CHECK(0.0 - int2{} == double2{});
STATIC_CHECK(int2{} - double2{} == double2{});
STATIC_CHECK(double2{} - int2{} == double2{});
STATIC_CHECK(ivec2{} - 0.0 == dvec2{});
STATIC_CHECK(0.0 - ivec2{} == dvec2{});
STATIC_CHECK(ivec2{} - dvec2{} == dvec2{});
STATIC_CHECK(dvec2{} - ivec2{} == dvec2{});
STATIC_CHECK(int2{} * 1.0 == double2{});
STATIC_CHECK(0.0 * int2{1} == double2{});
STATIC_CHECK(int2{} * double2{1.0} == double2{});
STATIC_CHECK(double2{} * int2{1} == double2{});
STATIC_CHECK(ivec2{} * 1.0 == dvec2{});
STATIC_CHECK(0.0 * ivec2{1} == dvec2{});
STATIC_CHECK(ivec2{} * dvec2{1.0} == dvec2{});
STATIC_CHECK(dvec2{} * ivec2{1} == dvec2{});
STATIC_CHECK(int2{} / 1.0 == double2{});
STATIC_CHECK(0.0 / int2{1} == double2{});
STATIC_CHECK(int2{} / double2{1.0} == double2{});
STATIC_CHECK(double2{} / int2{1} == double2{});
STATIC_CHECK(ivec2{} / 1.0 == dvec2{});
STATIC_CHECK(0.0 / ivec2{1} == dvec2{});
STATIC_CHECK(ivec2{} / dvec2{1.0} == dvec2{});
STATIC_CHECK(dvec2{} / ivec2{1} == dvec2{});
}
SUBCASE("Conversions2") {
{
STATIC_CHECK(double2(1) == double2(1,1));
STATIC_CHECK(double2(1,2.f) == double2(1,2));
STATIC_CHECK(double2(int2(1,2)) == double2(1,2));
STATIC_CHECK(double2(int3(1,2,3)) == double2(1,2));
STATIC_CHECK(double2(int4(1,2,3,4)) == double2(1,2));
STATIC_CHECK(dvec2(1) == dvec2(1,1));
STATIC_CHECK(dvec2(1,2.f) == dvec2(1,2));
STATIC_CHECK(dvec2(ivec2(1,2)) == dvec2(1,2));
STATIC_CHECK(dvec2(ivec3(1,2,3)) == dvec2(1,2));
STATIC_CHECK(dvec2(ivec4(1,2,3,4)) == dvec2(1,2));
}
{
STATIC_CHECK(double3(1) == double3(1,1,1));
STATIC_CHECK(double3(1,2.f,3u) == double3(1,2,3));
STATIC_CHECK(double3(int3(1,2,3)) == double3(1,2,3));
STATIC_CHECK(double3(int4(1,2,3,4)) == double3(1,2,3));
STATIC_CHECK(dvec3(1) == dvec3(1,1,1));
STATIC_CHECK(dvec3(1,2.f,3u) == dvec3(1,2,3));
STATIC_CHECK(dvec3(ivec3(1,2,3)) == dvec3(1,2,3));
STATIC_CHECK(dvec3(ivec4(1,2,3,4)) == dvec3(1,2,3));
STATIC_CHECK(double3(int2(1,2),3.f) == double3(1,2,3));
STATIC_CHECK(double3(1.f,int2(2,3)) == double3(1,2,3));
STATIC_CHECK(dvec3(ivec2(1,2),3.f) == dvec3(1,2,3));
STATIC_CHECK(dvec3(1.f,ivec2(2,3)) == dvec3(1,2,3));
}
{
STATIC_CHECK(double4(1) == double4(1,1,1,1));
STATIC_CHECK(double4(1,2.f,3u,4) == double4(1,2,3,4));
STATIC_CHECK(double4(int4(1,2,3,4)) == double4(1,2,3,4));
STATIC_CHECK(dvec4(1) == dvec4(1,1,1,1));
STATIC_CHECK(dvec4(1,2.f,3u,4) == dvec4(1,2,3,4));
STATIC_CHECK(dvec4(ivec4(1,2,3,4)) == dvec4(1,2,3,4));
STATIC_CHECK(double4(int2{1,2},3u,4.f) == double4(1,2,3,4));
STATIC_CHECK(double4(1,int2{2,3},4.f) == double4(1,2,3,4));
STATIC_CHECK(double4(1,2.f,int2{3,4}) == double4(1,2,3,4));
STATIC_CHECK(double4(int2{1,2},double2{3,4}) == double4(1,2,3,4));
STATIC_CHECK(dvec4(ivec2{1,2},3u,4.f) == dvec4(1,2,3,4));
STATIC_CHECK(dvec4(1,ivec2{2,3},4.f) == dvec4(1,2,3,4));
STATIC_CHECK(dvec4(1,2.f,ivec2{3,4}) == dvec4(1,2,3,4));
STATIC_CHECK(dvec4(ivec2{1,2},dvec2{3,4}) == dvec4(1,2,3,4));
STATIC_CHECK(double4(int3{1,2,3},4.f) == double4(1,2,3,4));
STATIC_CHECK(double4(1.f,int3{2,3,4}) == double4(1,2,3,4));
STATIC_CHECK(dvec4(ivec3{1,2,3},4.f) == dvec4(1,2,3,4));
STATIC_CHECK(dvec4(1.f,ivec3{2,3,4}) == dvec4(1,2,3,4));
}
}
SUBCASE("Angle and Trigonometric Functions") {
STATIC_CHECK(radians(degrees(float2(12.13f))) == uapprox2(12.13f));
STATIC_CHECK(degrees(radians(float2(12.13f))) == uapprox2(12.13f));
STATIC_CHECK(radians(degrees(fvec2(12.13f))) == uapprox2(12.13f));
STATIC_CHECK(degrees(radians(fvec2(12.13f))) == uapprox2(12.13f));
(void)sin(float2(1.f));
(void)cos(float2(1.f));
(void)tan(float2(1.f));
(void)sin(fvec2(1.f));
(void)cos(fvec2(1.f));
(void)tan(fvec2(1.f));
(void)asin(float2(1.f));
(void)acos(float2(1.f));
(void)atan(float2(1.f));
(void)atan2(float2(1.f), float2(1.f));
(void)asin(fvec2(1.f));
(void)acos(fvec2(1.f));
(void)atan(fvec2(1.f));
(void)atan2(fvec2(1.f), fvec2(1.f));
(void)sinh(float2(1.f));
(void)cosh(float2(1.f));
(void)tanh(float2(1.f));
(void)sinh(fvec2(1.f));
(void)cosh(fvec2(1.f));
(void)tanh(fvec2(1.f));
(void)asinh(float2(1.f));
(void)acosh(float2(1.f));
(void)atanh(float2(1.f));
(void)asinh(fvec2(1.f));
(void)acosh(fvec2(1.f));
(void)atanh(fvec2(1.f));
{
float2 out_ss{}, out_cs{};
sincos(float2(10.f,15.f), &out_ss, &out_cs);
fvec2 out_ss{}, out_cs{};
sincos(fvec2(10.f,15.f), &out_ss, &out_cs);
CHECK(out_ss == uapprox2(sin(10.f), sin(15.f)));
CHECK(out_cs == uapprox2(cos(10.f), cos(15.f)));
const auto [out_ss2, out_cs2] = sincos(float2(10.f,15.f));
const auto [out_ss2, out_cs2] = sincos(fvec2(10.f,15.f));
CHECK(out_ss2 == uapprox2(sin(10.f), sin(15.f)));
CHECK(out_cs2 == uapprox2(cos(10.f), cos(15.f)));
}
}
SUBCASE("Exponential Functions") {
(void)pow(float2(1.f), float2(2.f));
(void)exp(float2(1.f));
(void)log(float2(1.f));
(void)exp2(float2(1.f));
(void)log2(float2(1.f));
(void)sqrt(float2(1.f));
(void)rsqrt(float2(1.f));
(void)pow(fvec2(1.f), fvec2(2.f));
(void)exp(fvec2(1.f));
(void)log(fvec2(1.f));
(void)exp2(fvec2(1.f));
(void)log2(fvec2(1.f));
(void)sqrt(fvec2(1.f));
(void)rsqrt(fvec2(1.f));
}
SUBCASE("Common Functions") {
STATIC_CHECK(abs(float2(1.f, -1.f)) == uapprox2(1.f,1.f));
STATIC_CHECK(sqr(float2(2.f, -3.f)) == uapprox2(4.f,9.f));
STATIC_CHECK(sign(float3(1.f, -1.f, 0.f)) == uapprox3(1.f,-1.f,0.f));
STATIC_CHECK(rcp(float2(2.f, 4.f)) == uapprox2(0.5f,0.25f));
STATIC_CHECK(abs(fvec2(1.f, -1.f)) == uapprox2(1.f,1.f));
STATIC_CHECK(sqr(fvec2(2.f, -3.f)) == uapprox2(4.f,9.f));
STATIC_CHECK(sign(fvec3(1.f, -1.f, 0.f)) == uapprox3(1.f,-1.f,0.f));
STATIC_CHECK(rcp(fvec2(2.f, 4.f)) == uapprox2(0.5f,0.25f));
CHECK(copysign(
float4(2.f, -4.f, 2.f, -4.f),
fvec4(2.f, -4.f, 2.f, -4.f),
5.f)
== uapprox4(2.f, 4.f, 2.f, 4.f));
CHECK(copysign(
float4(2.f, -4.f, 2.f, -4.f),
fvec4(2.f, -4.f, 2.f, -4.f),
-5.f)
== uapprox4(-2.f, -4.f, -2.f, -4.f));
CHECK(copysign(
float4(2.f, -4.f, 2.f, -4.f),
float4(10.f, 5.f, -4.f, -0.4f))
fvec4(2.f, -4.f, 2.f, -4.f),
fvec4(10.f, 5.f, -4.f, -0.4f))
== uapprox4(2.f, 4.f, -2.f, -4.f));
(void)floor(float2(1.f, -1.f));
(void)trunc(float2(1.f, -1.f));
(void)round(float2(1.f, -1.f));
(void)ceil(float2(1.f, -1.f));
(void)fract(float2(1.f, -1.f));
(void)floor(fvec2(1.f, -1.f));
(void)trunc(fvec2(1.f, -1.f));
(void)round(fvec2(1.f, -1.f));
(void)ceil(fvec2(1.f, -1.f));
(void)fract(fvec2(1.f, -1.f));
CHECK(fmod(float2(1.7f), 1.2f) == uapprox2(0.5f));
CHECK(fmod(float2(1.7f), float2(1.2f)) == uapprox2(0.5f));
CHECK(fmod(fvec2(1.7f), 1.2f) == uapprox2(0.5f));
CHECK(fmod(fvec2(1.7f), fvec2(1.2f)) == uapprox2(0.5f));
{
float2 out_i{};
CHECK(modf(float2(1.7f), &out_i) == uapprox2(0.7f));
fvec2 out_i{};
CHECK(modf(fvec2(1.7f), &out_i) == uapprox2(0.7f));
CHECK(out_i.x == uapprox(1.f));
}
STATIC_CHECK(min(int2(1,2)) == 1);
STATIC_CHECK(min(int2(1,2), 1) == int2(1,1));
STATIC_CHECK(min(1, int2(1,2)) == int2(1,1));
STATIC_CHECK(min(int2(1,1), int2(0,2)) == int2(0,1));
STATIC_CHECK(min(ivec2(1,2)) == 1);
STATIC_CHECK(min(ivec2(1,2), 1) == ivec2(1,1));
STATIC_CHECK(min(1, ivec2(1,2)) == ivec2(1,1));
STATIC_CHECK(min(ivec2(1,1), ivec2(0,2)) == ivec2(0,1));
STATIC_CHECK(max(int2(1,2)) == 2);
STATIC_CHECK(max(int2(1,2), 1) == int2(1,2));
STATIC_CHECK(max(1, int2(1,2)) == int2(1,2));
STATIC_CHECK(max(int2(1,1), int2(0,2)) == int2(1,2));
STATIC_CHECK(max(ivec2(1,2)) == 2);
STATIC_CHECK(max(ivec2(1,2), 1) == ivec2(1,2));
STATIC_CHECK(max(1, ivec2(1,2)) == ivec2(1,2));
STATIC_CHECK(max(ivec2(1,1), ivec2(0,2)) == ivec2(1,2));
STATIC_CHECK(clamp(int2(1,2), 0, 1) == int2(1,1));
STATIC_CHECK(clamp(int2(1,2), int2(0), int2(1)) == int2(1,1));
STATIC_CHECK(clamp(ivec2(1,2), 0, 1) == ivec2(1,1));
STATIC_CHECK(clamp(ivec2(1,2), ivec2(0), ivec2(1)) == ivec2(1,1));
STATIC_CHECK(saturate(float3(-1.f,0.5,1.5f)) == uapprox3(0.f,0.5f,1.f));
STATIC_CHECK(saturate(fvec3(-1.f,0.5,1.5f)) == uapprox3(0.f,0.5f,1.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), 0.f) == uapprox2(2.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), 0.5f) == uapprox2(6.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), 1.f) == uapprox2(10.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), 0.f) == uapprox2(2.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), 0.5f) == uapprox2(6.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), 1.f) == uapprox2(10.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), 0.f, 1.f) == uapprox2(10.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), 1.f, 0.f) == uapprox2(2.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), 0.5f, 0.2f) == uapprox2(3.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), 0.f, 1.f) == uapprox2(10.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), 1.f, 0.f) == uapprox2(2.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), 0.5f, 0.2f) == uapprox2(3.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), float2(0.f)) == uapprox2(2.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), float2(0.5f)) == uapprox2(6.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), float2(1.f)) == uapprox2(10.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), fvec2(0.f)) == uapprox2(2.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), fvec2(0.5f)) == uapprox2(6.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), fvec2(1.f)) == uapprox2(10.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), float2(0.f), float2(1.f)) == uapprox2(10.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), float2(1.f), float2(0.f)) == uapprox2(2.f));
STATIC_CHECK(lerp(float2(2.f), float2(10.f), float2(0.5f), float2(0.2f)) == uapprox2(3.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), fvec2(0.f), fvec2(1.f)) == uapprox2(10.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), fvec2(1.f), fvec2(0.f)) == uapprox2(2.f));
STATIC_CHECK(lerp(fvec2(2.f), fvec2(10.f), fvec2(0.5f), fvec2(0.2f)) == uapprox2(3.f));
STATIC_CHECK(step(0.5f, float2(0.4f)) == uapprox2(0.f));
STATIC_CHECK(step(0.5f, float2(0.6f)) == uapprox2(1.f));
STATIC_CHECK(step(float2(0.5f), float2(0.4f)) == uapprox2(0.f));
STATIC_CHECK(step(float2(0.5f), float2(0.6f)) == uapprox2(1.f));
STATIC_CHECK(step(0.5f, fvec2(0.4f)) == uapprox2(0.f));
STATIC_CHECK(step(0.5f, fvec2(0.6f)) == uapprox2(1.f));
STATIC_CHECK(step(fvec2(0.5f), fvec2(0.4f)) == uapprox2(0.f));
STATIC_CHECK(step(fvec2(0.5f), fvec2(0.6f)) == uapprox2(1.f));
STATIC_CHECK(smoothstep(0.f, 1.f, float2(0.1f)) == uapprox2(0.028f));
STATIC_CHECK(smoothstep(float2(0.f), float2(1.f), float2(0.1f)) == uapprox2(0.028f));
STATIC_CHECK(smoothstep(0.f, 1.f, fvec2(0.1f)) == uapprox2(0.028f));
STATIC_CHECK(smoothstep(fvec2(0.f), fvec2(1.f), fvec2(0.1f)) == uapprox2(0.028f));
}
SUBCASE("Geometric Functions") {
CHECK(length(float2(10.f,0.f)) == uapprox(10.f));
CHECK(length(float2(-10.f,0.f)) == uapprox(10.f));
CHECK(length(fvec2(10.f,0.f)) == uapprox(10.f));
CHECK(length(fvec2(-10.f,0.f)) == uapprox(10.f));
CHECK(rlength(float2(10.f,0.f)) == uapprox(0.1f));
CHECK(rlength(float2(-10.f,0.f)) == uapprox(0.1f));
CHECK(rlength(fvec2(10.f,0.f)) == uapprox(0.1f));
CHECK(rlength(fvec2(-10.f,0.f)) == uapprox(0.1f));
STATIC_CHECK(length2(float2(10.f,0.f)) == uapprox(100.f));
STATIC_CHECK(length2(float2(-10.f,0.f)) == uapprox(100.f));
STATIC_CHECK(length2(fvec2(10.f,0.f)) == uapprox(100.f));
STATIC_CHECK(length2(fvec2(-10.f,0.f)) == uapprox(100.f));
STATIC_CHECK(rlength2(float2(10.f,0.f)) == uapprox(0.01f));
STATIC_CHECK(rlength2(float2(-10.f,0.f)) == uapprox(0.01f));
STATIC_CHECK(rlength2(fvec2(10.f,0.f)) == uapprox(0.01f));
STATIC_CHECK(rlength2(fvec2(-10.f,0.f)) == uapprox(0.01f));
CHECK(distance(float2(5.f,0.f), float2(10.f,0.f)) == uapprox(5.f));
CHECK(distance(float2(-5.f,0.f), float2(-10.f,0.f)) == uapprox(5.f));
CHECK(distance(fvec2(5.f,0.f), fvec2(10.f,0.f)) == uapprox(5.f));
CHECK(distance(fvec2(-5.f,0.f), fvec2(-10.f,0.f)) == uapprox(5.f));
STATIC_CHECK(distance2(float2(5.f,0.f), float2(10.f,0.f)) == uapprox(25.f));
STATIC_CHECK(distance2(float2(-5.f,0.f), float2(-10.f,0.f)) == uapprox(25.f));
STATIC_CHECK(distance2(fvec2(5.f,0.f), fvec2(10.f,0.f)) == uapprox(25.f));
STATIC_CHECK(distance2(fvec2(-5.f,0.f), fvec2(-10.f,0.f)) == uapprox(25.f));
STATIC_CHECK(dot(int2(1,2),int2(3,4)) == 11);
STATIC_CHECK(dot(int2(1,2),double2(3,4)) == uapprox(11.0));
STATIC_CHECK(dot(double2(3,4),int2(1,2)) == uapprox(11.0));
STATIC_CHECK(dot(ivec2(1,2),ivec2(3,4)) == 11);
STATIC_CHECK(dot(ivec2(1,2),dvec2(3,4)) == uapprox(11.0));
STATIC_CHECK(dot(dvec2(3,4),ivec2(1,2)) == uapprox(11.0));
STATIC_CHECK(cross(int2(1,0),int2(0,1)) == 1);
STATIC_CHECK(cross(int2(1,0),double2(0,1)) == uapprox(1.0));
STATIC_CHECK(cross(double2(0,1),int2(1,0)) == uapprox(-1.0));
STATIC_CHECK(cross(ivec2(1,0),ivec2(0,1)) == 1);
STATIC_CHECK(cross(ivec2(1,0),dvec2(0,1)) == uapprox(1.0));
STATIC_CHECK(cross(dvec2(0,1),ivec2(1,0)) == uapprox(-1.0));
STATIC_CHECK(cross(int3(1,0,0),int3(0,1,0)) == int3(0,0,1));
STATIC_CHECK(cross(int3(1,0,0),double3(0,1,0)) == uapprox3(0.0,0.0,1.0));
STATIC_CHECK(cross(double3(0,1,0),int3(1,0,0)) == uapprox3(0.0,0.0,-1.0));
STATIC_CHECK(cross(ivec3(1,0,0),ivec3(0,1,0)) == ivec3(0,0,1));
STATIC_CHECK(cross(ivec3(1,0,0),dvec3(0,1,0)) == uapprox3(0.0,0.0,1.0));
STATIC_CHECK(cross(dvec3(0,1,0),ivec3(1,0,0)) == uapprox3(0.0,0.0,-1.0));
CHECK(normalize(float2(0.5f,0.f)).x == uapprox(1.f));
CHECK(normalize(fvec2(0.5f,0.f)).x == uapprox(1.f));
STATIC_CHECK(faceforward(float2(1.f), float2(2.f), float2(3.f)).x == uapprox(-1.f));
STATIC_CHECK(reflect(float2(1.f), float2(2.f)).x == uapprox(-15.f));
CHECK(refract(float2(1.f), float2(2.f), 1.f).x == uapprox(-15.f));
STATIC_CHECK(faceforward(fvec2(1.f), fvec2(2.f), fvec2(3.f)).x == uapprox(-1.f));
STATIC_CHECK(reflect(fvec2(1.f), fvec2(2.f)).x == uapprox(-15.f));
CHECK(refract(fvec2(1.f), fvec2(2.f), 1.f).x == uapprox(-15.f));
}
SUBCASE("Relational Functions") {
STATIC_CHECK_FALSE(any(bool2(false, false)));
STATIC_CHECK(any(bool2(true, false)));
STATIC_CHECK(any(bool2(false, true)));
STATIC_CHECK(any(bool2(true, true)));
STATIC_CHECK_FALSE(any(bvec2(false, false)));
STATIC_CHECK(any(bvec2(true, false)));
STATIC_CHECK(any(bvec2(false, true)));
STATIC_CHECK(any(bvec2(true, true)));
STATIC_CHECK_FALSE(any(int2(0, 0)));
STATIC_CHECK(any(int2(1, 0)));
STATIC_CHECK(any(int2(0, 1)));
STATIC_CHECK(any(int2(1, 1)));
STATIC_CHECK_FALSE(any(ivec2(0, 0)));
STATIC_CHECK(any(ivec2(1, 0)));
STATIC_CHECK(any(ivec2(0, 1)));
STATIC_CHECK(any(ivec2(1, 1)));
STATIC_CHECK_FALSE(all(bool2(false, false)));
STATIC_CHECK_FALSE(all(bool2(true, false)));
STATIC_CHECK_FALSE(all(bool2(false, true)));
STATIC_CHECK(all(bool2(true, true)));
STATIC_CHECK_FALSE(all(bvec2(false, false)));
STATIC_CHECK_FALSE(all(bvec2(true, false)));
STATIC_CHECK_FALSE(all(bvec2(false, true)));
STATIC_CHECK(all(bvec2(true, true)));
STATIC_CHECK_FALSE(all(int2(0, 0)));
STATIC_CHECK_FALSE(all(int2(1, 0)));
STATIC_CHECK_FALSE(all(int2(0, 1)));
STATIC_CHECK(all(int2(1, 1)));
STATIC_CHECK_FALSE(all(ivec2(0, 0)));
STATIC_CHECK_FALSE(all(ivec2(1, 0)));
STATIC_CHECK_FALSE(all(ivec2(0, 1)));
STATIC_CHECK(all(ivec2(1, 1)));
STATIC_CHECK(approx(int3(1,1,1), int3(0,1,2)) == bool3(false, true, false));
STATIC_CHECK(approx(int4(1,1,1,1), int4(0,1,2,3), 0) == bool4(false, true, false, false));
STATIC_CHECK(approx(int4(1,1,1,1), int4(0,1,2,3), 1) == bool4(true, true, true, false));
STATIC_CHECK(approx(int4(1,1,1,1), int4(0,1,2,3), 2) == bool4(true, true, true, true));
STATIC_CHECK(approx(ivec3(1,1,1), ivec3(0,1,2)) == bvec3(false, true, false));
STATIC_CHECK(approx(ivec4(1,1,1,1), ivec4(0,1,2,3), 0) == bvec4(false, true, false, false));
STATIC_CHECK(approx(ivec4(1,1,1,1), ivec4(0,1,2,3), 1) == bvec4(true, true, true, false));
STATIC_CHECK(approx(ivec4(1,1,1,1), ivec4(0,1,2,3), 2) == bvec4(true, true, true, true));
STATIC_CHECK(less(int3(1,1,1), int3(0,1,2)) == bool3(false, false, true));
STATIC_CHECK(less_equal(int3(1,1,1), int3(0,1,2)) == bool3(false, true, true));
STATIC_CHECK(greater(int3(1,1,1), int3(0,1,2)) == bool3(true, false, false));
STATIC_CHECK(greater_equal(int3(1,1,1), int3(0,1,2)) == bool3(true, true, false));
STATIC_CHECK(less(ivec3(1,1,1), ivec3(0,1,2)) == bvec3(false, false, true));
STATIC_CHECK(less_equal(ivec3(1,1,1), ivec3(0,1,2)) == bvec3(false, true, true));
STATIC_CHECK(greater(ivec3(1,1,1), ivec3(0,1,2)) == bvec3(true, false, false));
STATIC_CHECK(greater_equal(ivec3(1,1,1), ivec3(0,1,2)) == bvec3(true, true, false));
STATIC_CHECK(equal_to(int3(1,1,1), int3(0,1,2)) == bool3(false, true, false));
STATIC_CHECK(not_equal_to(int3(1,1,1), int3(0,1,2)) == bool3(true, false, true));
STATIC_CHECK(equal_to(ivec3(1,1,1), ivec3(0,1,2)) == bvec3(false, true, false));
STATIC_CHECK(not_equal_to(ivec3(1,1,1), ivec3(0,1,2)) == bvec3(true, false, true));
}
}

View File

@@ -14,13 +14,13 @@ namespace
TEST_CASE("vmath/vec") {
SUBCASE("size/sizeof") {
STATIC_CHECK(int2{}.size == 2);
STATIC_CHECK(int3{}.size == 3);
STATIC_CHECK(int4{}.size == 4);
STATIC_CHECK(ivec2{}.size == 2);
STATIC_CHECK(ivec3{}.size == 3);
STATIC_CHECK(ivec4{}.size == 4);
STATIC_CHECK(sizeof(int2{}) == sizeof(int) * 2);
STATIC_CHECK(sizeof(int3{}) == sizeof(int) * 3);
STATIC_CHECK(sizeof(int4{}) == sizeof(int) * 4);
STATIC_CHECK(sizeof(ivec2{}) == sizeof(int) * 2);
STATIC_CHECK(sizeof(ivec3{}) == sizeof(int) * 3);
STATIC_CHECK(sizeof(ivec4{}) == sizeof(int) * 4);
}
SUBCASE("guides") {
@@ -56,102 +56,102 @@ TEST_CASE("vmath/vec") {
CHECK(i4.z == 0);
CHECK(i4.w == 0);
STATIC_CHECK(int2() == int2(0,0));
STATIC_CHECK(int3() == int3(0,0,0));
STATIC_CHECK(int4() == int4(0,0,0,0));
STATIC_CHECK(ivec2() == ivec2(0,0));
STATIC_CHECK(ivec3() == ivec3(0,0,0));
STATIC_CHECK(ivec4() == ivec4(0,0,0,0));
(void)int2(uninit);
(void)int3(uninit);
(void)int4(uninit);
(void)ivec2(uninit);
(void)ivec3(uninit);
(void)ivec4(uninit);
STATIC_CHECK(int2(zero_init) == int2(0,0));
STATIC_CHECK(int3(zero_init) == int3(0,0,0));
STATIC_CHECK(int4(zero_init) == int4(0,0,0,0));
STATIC_CHECK(ivec2(zero_init) == ivec2(0,0));
STATIC_CHECK(ivec3(zero_init) == ivec3(0,0,0));
STATIC_CHECK(ivec4(zero_init) == ivec4(0,0,0,0));
STATIC_CHECK(int2(unit_init) == int2(1,1));
STATIC_CHECK(int3(unit_init) == int3(1,1,1));
STATIC_CHECK(int4(unit_init) == int4(1,1,1,1));
STATIC_CHECK(ivec2(unit_init) == ivec2(1,1));
STATIC_CHECK(ivec3(unit_init) == ivec3(1,1,1));
STATIC_CHECK(ivec4(unit_init) == ivec4(1,1,1,1));
}
{
STATIC_CHECK(int2().x == 0);
STATIC_CHECK(int2().y == 0);
STATIC_CHECK(ivec2().x == 0);
STATIC_CHECK(ivec2().y == 0);
STATIC_CHECK(int2(1).x == 1);
STATIC_CHECK(int2(1).y == 1);
STATIC_CHECK(ivec2(1).x == 1);
STATIC_CHECK(ivec2(1).y == 1);
STATIC_CHECK(int2(1,2).x == 1);
STATIC_CHECK(int2(1,2).y == 2);
STATIC_CHECK(ivec2(1,2).x == 1);
STATIC_CHECK(ivec2(1,2).y == 2);
}
{
constexpr int2 v(1,2);
constexpr int2 v2 = v;
STATIC_CHECK(v2 == int2(1,2));
constexpr ivec2 v(1,2);
constexpr ivec2 v2 = v;
STATIC_CHECK(v2 == ivec2(1,2));
}
{
constexpr int2 v(1,2);
constexpr int2 v2 = std::move(v);
STATIC_CHECK(v2 == int2(1,2));
constexpr ivec2 v(1,2);
constexpr ivec2 v2 = std::move(v);
STATIC_CHECK(v2 == ivec2(1,2));
}
{
STATIC_CHECK(int2(1) == int2(1,1));
STATIC_CHECK(int2(1,2) == int2(1,2));
STATIC_CHECK(int2(int2(1,2)) == int2(1,2));
STATIC_CHECK(int2(int3(1,2,3)) == int2(1,2));
STATIC_CHECK(int2(int4(1,2,3,4)) == int2(1,2));
STATIC_CHECK(ivec2(1) == ivec2(1,1));
STATIC_CHECK(ivec2(1,2) == ivec2(1,2));
STATIC_CHECK(ivec2(ivec2(1,2)) == ivec2(1,2));
STATIC_CHECK(ivec2(ivec3(1,2,3)) == ivec2(1,2));
STATIC_CHECK(ivec2(ivec4(1,2,3,4)) == ivec2(1,2));
STATIC_CHECK(int3(1) == int3(1,1,1));
STATIC_CHECK(int3(1,2,3) == int3(1,2,3));
STATIC_CHECK(int3(int2(1,2),3) == int3(1,2,3));
STATIC_CHECK(int3(1,int2(2,3)) == int3(1,2,3));
STATIC_CHECK(int3(int3(1,2,3)) == int3(1,2,3));
STATIC_CHECK(int3(int4(1,2,3,4)) == int3(1,2,3));
STATIC_CHECK(ivec3(1) == ivec3(1,1,1));
STATIC_CHECK(ivec3(1,2,3) == ivec3(1,2,3));
STATIC_CHECK(ivec3(ivec2(1,2),3) == ivec3(1,2,3));
STATIC_CHECK(ivec3(1,ivec2(2,3)) == ivec3(1,2,3));
STATIC_CHECK(ivec3(ivec3(1,2,3)) == ivec3(1,2,3));
STATIC_CHECK(ivec3(ivec4(1,2,3,4)) == ivec3(1,2,3));
STATIC_CHECK(int4(1) == int4(1,1,1,1));
STATIC_CHECK(int4(1,2,3,4) == int4(1,2,3,4));
STATIC_CHECK(int4(int2(1,2),3,4) == int4(1,2,3,4));
STATIC_CHECK(int4(1,int2(2,3),4) == int4(1,2,3,4));
STATIC_CHECK(int4(1,2,int2(3,4)) == int4(1,2,3,4));
STATIC_CHECK(int4(int2(1,2),int2(3,4)) == int4(1,2,3,4));
STATIC_CHECK(int4(int3(1,2,3),4) == int4(1,2,3,4));
STATIC_CHECK(int4(1,int3(2,3,4)) == int4(1,2,3,4));
STATIC_CHECK(ivec4(1) == ivec4(1,1,1,1));
STATIC_CHECK(ivec4(1,2,3,4) == ivec4(1,2,3,4));
STATIC_CHECK(ivec4(ivec2(1,2),3,4) == ivec4(1,2,3,4));
STATIC_CHECK(ivec4(1,ivec2(2,3),4) == ivec4(1,2,3,4));
STATIC_CHECK(ivec4(1,2,ivec2(3,4)) == ivec4(1,2,3,4));
STATIC_CHECK(ivec4(ivec2(1,2),ivec2(3,4)) == ivec4(1,2,3,4));
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));
}
}
SUBCASE("operator=") {
{
int2 v(1,2);
int2 v2;
ivec2 v(1,2);
ivec2 v2;
v2 = v;
CHECK(v2 == int2(1,2));
CHECK(v2 == ivec2(1,2));
}
{
int2 v(1,2);
int2 v2;
ivec2 v(1,2);
ivec2 v2;
v2 = std::move(v);
CHECK(v2 == int2(1,2));
CHECK(v2 == ivec2(1,2));
}
}
SUBCASE("swap") {
{
int2 v1(1,2);
int2 v2(4,5);
ivec2 v1(1,2);
ivec2 v2(4,5);
v1.swap(v2);
CHECK(v1 == int2(4,5));
CHECK(v2 == int2(1,2));
CHECK(v1 == ivec2(4,5));
CHECK(v2 == ivec2(1,2));
}
{
int2 v1(1,2);
int2 v2(4,5);
ivec2 v1(1,2);
ivec2 v2(4,5);
swap(v1, v2);
CHECK(v1 == int2(4,5));
CHECK(v2 == int2(1,2));
CHECK(v1 == ivec2(4,5));
CHECK(v2 == ivec2(1,2));
}
}
SUBCASE("iter") {
{
int2 v{1,2};
ivec2 v{1,2};
CHECK(*v.begin() == 1);
CHECK(*(v.begin() + 1) == 2);
@@ -182,12 +182,12 @@ TEST_CASE("vmath/vec") {
CHECK(v.crend() - 2 == v.crbegin());
*v.begin() = 3;
CHECK(v == int2{3,2});
CHECK(v == ivec2{3,2});
*v.rbegin() = 4;
CHECK(v == int2{3,4});
CHECK(v == ivec2{3,4});
}
{
const int2 v{1,2};
const ivec2 v{1,2};
CHECK(*v.begin() == 1);
CHECK(*(v.begin() + 1) == 2);
@@ -221,70 +221,70 @@ TEST_CASE("vmath/vec") {
SUBCASE("data") {
{
int2 i2;
ivec2 i2;
CHECK(i2.data() == &i2[0]);
int3 i3;
ivec3 i3;
CHECK(i3.data() == &i3[0]);
int4 i4;
ivec4 i4;
CHECK(i4.data() == &i4[0]);
}
{
const int2 i2;
const ivec2 i2;
CHECK(i2.data() == &i2[0]);
const int3 i3;
const ivec3 i3;
CHECK(i3.data() == &i3[0]);
const int4 i4;
const ivec4 i4;
CHECK(i4.data() == &i4[0]);
}
}
SUBCASE("operator[]") {
{
STATIC_CHECK(int2(1,2).x == 1);
STATIC_CHECK(int2(1,2).y == 2);
STATIC_CHECK(ivec2(1,2).x == 1);
STATIC_CHECK(ivec2(1,2).y == 2);
STATIC_CHECK(int3(1,2,3).x == 1);
STATIC_CHECK(int3(1,2,3).y == 2);
STATIC_CHECK(int3(1,2,3).z == 3);
STATIC_CHECK(ivec3(1,2,3).x == 1);
STATIC_CHECK(ivec3(1,2,3).y == 2);
STATIC_CHECK(ivec3(1,2,3).z == 3);
STATIC_CHECK(int4(1,2,3,4).x == 1);
STATIC_CHECK(int4(1,2,3,4).y == 2);
STATIC_CHECK(int4(1,2,3,4).z == 3);
STATIC_CHECK(int4(1,2,3,4).w == 4);
STATIC_CHECK(ivec4(1,2,3,4).x == 1);
STATIC_CHECK(ivec4(1,2,3,4).y == 2);
STATIC_CHECK(ivec4(1,2,3,4).z == 3);
STATIC_CHECK(ivec4(1,2,3,4).w == 4);
}
{
STATIC_CHECK(int2(1,2)[0] == 1);
STATIC_CHECK(int2(1,2)[1] == 2);
STATIC_CHECK(ivec2(1,2)[0] == 1);
STATIC_CHECK(ivec2(1,2)[1] == 2);
}
{
int2 v;
ivec2 v;
v.x = 1;
v.y = 2;
CHECK(v == int2(1,2));
CHECK(v == ivec2(1,2));
CHECK(std::as_const(v).at(0) == 1);
CHECK(std::as_const(v).at(1) == 2);
}
{
int3 v;
ivec3 v;
v.x = 1;
v.y = 2;
v.z = 3;
CHECK(v == int3(1,2,3));
CHECK(v == ivec3(1,2,3));
CHECK(std::as_const(v).at(0) == 1);
CHECK(std::as_const(v).at(1) == 2);
CHECK(std::as_const(v).at(2) == 3);
}
{
int4 v;
ivec4 v;
v.x = 1;
v.y = 2;
v.z = 3;
v.w = 4;
CHECK(v == int4(1,2,3,4));
CHECK(v == ivec4(1,2,3,4));
CHECK(std::as_const(v).at(0) == 1);
CHECK(std::as_const(v).at(1) == 2);
CHECK(std::as_const(v).at(2) == 3);
@@ -293,30 +293,30 @@ TEST_CASE("vmath/vec") {
}
SUBCASE("at") {
STATIC_CHECK(int2(1,2).at(0) == 1);
STATIC_CHECK(int2(1,2).at(1) == 2);
STATIC_CHECK(ivec2(1,2).at(0) == 1);
STATIC_CHECK(ivec2(1,2).at(1) == 2);
#ifndef VMATH_HPP_NO_EXCEPTIONS
CHECK_THROWS_AS((void)int2(1,2).at(2), std::out_of_range);
CHECK_THROWS_AS((void)ivec2(1,2).at(2), std::out_of_range);
#endif
}
SUBCASE("operator==/operator!=") {
STATIC_CHECK(int2(1,2) == int2(1,2));
STATIC_CHECK_FALSE(int2(1,2) == int2(2,2));
STATIC_CHECK_FALSE(int2(1,2) == int2(1,3));
STATIC_CHECK(ivec2(1,2) == ivec2(1,2));
STATIC_CHECK_FALSE(ivec2(1,2) == ivec2(2,2));
STATIC_CHECK_FALSE(ivec2(1,2) == ivec2(1,3));
STATIC_CHECK_FALSE(int2(1,2) != int2(1,2));
STATIC_CHECK(int2(1,2) != int2(2,2));
STATIC_CHECK(int2(1,2) != int2(1,3));
STATIC_CHECK_FALSE(ivec2(1,2) != ivec2(1,2));
STATIC_CHECK(ivec2(1,2) != ivec2(2,2));
STATIC_CHECK(ivec2(1,2) != ivec2(1,3));
}
SUBCASE("operator<") {
STATIC_CHECK_FALSE(int2(1,2) < int2(1,2));
STATIC_CHECK_FALSE(ivec2(1,2) < ivec2(1,2));
STATIC_CHECK(int2(1,1) < int2(1,2));
STATIC_CHECK_FALSE(int2(1,2) < int2(1,1));
STATIC_CHECK(ivec2(1,1) < ivec2(1,2));
STATIC_CHECK_FALSE(ivec2(1,2) < ivec2(1,1));
STATIC_CHECK(int2(0,3) < int2(1,2));
STATIC_CHECK_FALSE(int2(1,2) < int2(0,3));
STATIC_CHECK(ivec2(0,3) < ivec2(1,2));
STATIC_CHECK_FALSE(ivec2(1,2) < ivec2(0,3));
}
}