Files
vmath.hpp/develop/untests/vmath_vec_fun_tests.cpp
2023-02-05 14:46:19 +07:00

385 lines
15 KiB
C++

/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/vmath.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2020-2023, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#include "vmath_tests.hpp"
namespace
{
using namespace vmath_hpp;
using namespace vmath_tests;
}
TEST_CASE("vmath/vec_fun") {
SUBCASE("Operators") {
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(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(11,12) << 2) == ivec2(44,48));
STATIC_CHECK((ivec2(11,12) >> 2) == ivec2(2,3));
STATIC_CHECK((ivec2(1,0) && 1) == bvec2(1,0));
STATIC_CHECK((ivec2(1,0) || 1) == bvec2(1,1));
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((2 << ivec2(3,4)) == ivec2(16,32));
STATIC_CHECK((48 >> ivec2(3,4)) == ivec2(6,3));
STATIC_CHECK((1 && ivec2(1,0)) == bvec2(1,0));
STATIC_CHECK((1 || ivec2(1,0)) == bvec2(1,1));
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(11,6) << ivec2(2,3)) == ivec2(44,48));
STATIC_CHECK((ivec2(44,48) >> ivec2(2,3)) == ivec2(11,6));
STATIC_CHECK((ivec2(0,1) && ivec2(1,0)) == bvec2(0,0));
STATIC_CHECK((ivec2(0,1) || ivec2(1,0)) == bvec2(1,1));
{
ivec2 v{1,2};
CHECK(&v == &(++v));
CHECK(v == ivec2{2,3});
CHECK(&v == &(--v));
CHECK(v == ivec2{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});
}
{
ivec2 v{1,2};
CHECK(&v == &(v += 3));
CHECK(v == ivec2{4,5});
CHECK(&v == &(v += ivec2{1,2}));
CHECK(v == ivec2{5,7});
}
{
ivec2 v{4,5};
CHECK(&v == &(v -= 3));
CHECK(v == ivec2{1,2});
CHECK(&v == &(v -= ivec2{2,4}));
CHECK(v == ivec2{-1,-2});
}
{
ivec2 v{1,2};
CHECK(&v == &(v *= 3));
CHECK(v == ivec2{3,6});
CHECK(&v == &(v *= ivec2{2,3}));
CHECK(v == ivec2{6,18});
}
{
ivec2 v{6,18};
CHECK(&v == &(v /= 2));
CHECK(v == ivec2{3,9});
CHECK(&v == &(v /= ivec2{3,4}));
CHECK(v == ivec2{1,2});
}
{
ivec2 v1{11,12};
CHECK(&v1 == &(v1 &= 6));
CHECK(v1 == ivec2(2,4));
ivec2 v2{6,7};
CHECK(&v2 == &(v2 &= ivec2(11,12)));
CHECK(v2 == ivec2(2,4));
}
{
ivec2 v1{11,12};
CHECK(&v1 == &(v1 |= 6));
CHECK(v1 == ivec2(15,14));
ivec2 v2{6,7};
CHECK(&v2 == &(v2 |= ivec2(11,12)));
CHECK(v2 == ivec2(15,15));
}
{
ivec2 v1{11,12};
CHECK(&v1 == &(v1 ^= 6));
CHECK(v1 == ivec2(13,10));
ivec2 v2{6,7};
CHECK(&v2 == &(v2 ^= ivec2(11,12)));
CHECK(v2 == ivec2(13,11));
}
{
ivec2 v1{2,3};
CHECK(&v1 == &(v1 <<= 2));
CHECK(v1 == ivec2(8,12));
CHECK(&v1 == &(v1 <<= ivec2(2,3)));
CHECK(v1 == ivec2(32,96));
}
{
ivec2 v1{32,96};
CHECK(&v1 == &(v1 >>= 2));
CHECK(v1 == ivec2(8,24));
CHECK(&v1 == &(v1 >>= ivec2(2,3)));
CHECK(v1 == ivec2(2,3));
}
}
SUBCASE("Operators2") {
STATIC_CHECK(ivec2{} + 0.0 == dvec2{});
STATIC_CHECK(0.0 + ivec2{} == dvec2{});
STATIC_CHECK(ivec2{} + dvec2{} == dvec2{});
STATIC_CHECK(dvec2{} + ivec2{} == dvec2{});
STATIC_CHECK(ivec2{} - 0.0 == dvec2{});
STATIC_CHECK(0.0 - ivec2{} == dvec2{});
STATIC_CHECK(ivec2{} - dvec2{} == dvec2{});
STATIC_CHECK(dvec2{} - ivec2{} == dvec2{});
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(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(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(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(dvec3(ivec2(1,2),3.f) == dvec3(1,2,3));
STATIC_CHECK(dvec3(1.f,ivec2(2,3)) == dvec3(1,2,3));
}
{
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(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(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(fvec2(12.13f))) == uapprox2(12.13f));
STATIC_CHECK(degrees(radians(fvec2(12.13f))) == uapprox2(12.13f));
(void)sin(fvec2(1.f));
(void)cos(fvec2(1.f));
(void)tan(fvec2(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(fvec2(1.f));
(void)cosh(fvec2(1.f));
(void)tanh(fvec2(1.f));
(void)asinh(fvec2(1.f));
(void)acosh(fvec2(1.f));
(void)atanh(fvec2(1.f));
{
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)));
std::tie(out_ss, out_cs) = sincos(fvec2(10.f,15.f));
CHECK(out_ss == uapprox2(sin(10.f), sin(15.f)));
CHECK(out_cs == uapprox2(cos(10.f), cos(15.f)));
}
}
SUBCASE("Exponential Functions") {
(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(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(
fvec4(2.f, -4.f, 2.f, -4.f),
5.f)
== uapprox4(2.f, 4.f, 2.f, 4.f));
CHECK(copysign(
fvec4(2.f, -4.f, 2.f, -4.f),
-5.f)
== uapprox4(-2.f, -4.f, -2.f, -4.f));
CHECK(copysign(
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(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(fvec2(1.7f), 1.2f) == uapprox2(0.5f));
CHECK(fmod(fvec2(1.7f), fvec2(1.2f)) == uapprox2(0.5f));
{
fvec2 out_i{};
CHECK(modf(fvec2(1.7f), &out_i) == uapprox2(0.7f));
CHECK(out_i.x == uapprox(1.f));
}
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(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(ivec2(1,2), 0, 1) == ivec2(1,1));
STATIC_CHECK(clamp(ivec2(1,2), ivec2(0), ivec2(1)) == ivec2(1,1));
STATIC_CHECK(saturate(fvec3(-1.f,0.5,1.5f)) == uapprox3(0.f,0.5f,1.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(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(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(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, 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, 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(fvec2(10.f,0.f)) == uapprox(10.f));
CHECK(length(fvec2(-10.f,0.f)) == uapprox(10.f));
CHECK(rlength(fvec2(10.f,0.f)) == uapprox(0.1f));
CHECK(rlength(fvec2(-10.f,0.f)) == uapprox(0.1f));
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(fvec2(10.f,0.f)) == uapprox(0.01f));
STATIC_CHECK(rlength2(fvec2(-10.f,0.f)) == uapprox(0.01f));
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(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(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(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(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(fvec2(0.5f,0.f)).x == uapprox(1.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(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(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(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(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(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(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(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));
}
}