diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index d317b20..aca7938 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -131,19 +131,29 @@ namespace vmath_hpp namespace vmath_hpp { + template < typename T > + constexpr T dot(T x, T y) noexcept { + return x * y; + } + template < typename T > T length(T x) noexcept { return abs(x); } template < typename T > - T distance(T x, T y) noexcept { - return length(x - y); + constexpr T length2(T x) noexcept { + return dot(x, x); } template < typename T > - T dot(T x, T y) noexcept { - return x * y; + T distance(T x, T y) noexcept { + return length(y - x); + } + + template < typename T > + constexpr T distance2(T x, T y) noexcept { + return length2(y - x); } template < typename T > @@ -152,12 +162,12 @@ namespace vmath_hpp } template < typename T > - T faceforward(T n, T i, T nref) noexcept { + constexpr T faceforward(T n, T i, T nref) noexcept { return dot(nref, i) < T(0) ? n : -n; } template < typename T > - T reflect(T i, T n) noexcept { + constexpr T reflect(T i, T n) noexcept { return i - n * dot(n, i) * T(2); } diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 7429762..9e914a1 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -536,19 +536,31 @@ namespace vmath_hpp namespace vmath_hpp { + template < typename T, std::size_t Size > + constexpr T dot(const vec& xs, const vec& ys) { + return fold([](T acc, T x, T y){ + return acc + (x * y); + }, T(0), xs, ys); + } + template < typename T, std::size_t Size > T length(const vec& xs) { return sqrt(dot(xs, xs)); } template < typename T, std::size_t Size > - T distance(const vec& xs, const vec& ys) { - return length(xs - ys); + constexpr T length2(const vec& xs) { + return dot(xs, xs); } template < typename T, std::size_t Size > - constexpr T dot(const vec& xs, const vec& ys) { - return fold(std::plus<>(), T(0), zip(std::multiplies<>(), xs, ys)); + T distance(const vec& xs, const vec& ys) { + return length(ys - xs); + } + + template < typename T, std::size_t Size > + constexpr T distance2(const vec& xs, const vec& ys) { + return length2(ys - xs); } template < typename T > @@ -565,12 +577,12 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - vec faceforward(const vec& n, const vec& i, const vec& nref) { + constexpr vec faceforward(const vec& n, const vec& i, const vec& nref) { return dot(nref, i) < T(0) ? n : -n; } template < typename T, std::size_t Size > - vec reflect(const vec& i, const vec& n) { + constexpr vec reflect(const vec& i, const vec& n) { return i - n * dot(n, i) * T(2); } diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index 419a4f3..72ed18c 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -114,14 +114,20 @@ TEST_CASE("vmath/fun") { REQUIRE(length(10.f) == approx(10.f)); REQUIRE(length(-10.f) == approx(10.f)); + STATIC_REQUIRE(length2(10.f) == approx(100.f)); + STATIC_REQUIRE(length2(-10.f) == approx(100.f)); + REQUIRE(distance(5.f, 10.f) == approx(5.f)); REQUIRE(distance(-5.f, -10.f) == approx(5.f)); + STATIC_REQUIRE(distance2(5.f, 10.f) == approx(25.f)); + STATIC_REQUIRE(distance2(-5.f, -10.f) == approx(25.f)); + REQUIRE(dot(2.f, 5.f) == approx(10.f)); REQUIRE(normalize(0.5f) == approx(1.f)); - REQUIRE(faceforward(1.f, 2.f, 3.f) == approx(-1.f)); - REQUIRE(reflect(1.f, 2.f) == approx(-7.f)); + STATIC_REQUIRE(faceforward(1.f, 2.f, 3.f) == approx(-1.f)); + STATIC_REQUIRE(reflect(1.f, 2.f) == approx(-7.f)); REQUIRE(refract(1.f, 2.f, 1.f) == approx(-7.f)); } } diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index 6cd0631..11f4221 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -158,15 +158,21 @@ TEST_CASE("vmath/vec_fun") { REQUIRE(length(vec2f(10.f,0.f)) == Approx(10.f)); REQUIRE(length(vec2f(-10.f,0.f)) == Approx(10.f)); + STATIC_REQUIRE(length2(vec2f(10.f,0.f)) == approx(100.f)); + STATIC_REQUIRE(length2(vec2f(-10.f,0.f)) == approx(100.f)); + REQUIRE(distance(vec2f(5.f,0.f), vec2f(10.f,0.f)) == Approx(5.f)); REQUIRE(distance(vec2f(-5.f,0.f), vec2f(-10.f,0.f)) == Approx(5.f)); + STATIC_REQUIRE(distance2(vec2f(5.f,0.f), vec2f(10.f,0.f)) == approx(25.f)); + STATIC_REQUIRE(distance2(vec2f(-5.f,0.f), vec2f(-10.f,0.f)) == approx(25.f)); + STATIC_REQUIRE(dot(vec2i(1,2),vec2i(3,4)) == 11); STATIC_REQUIRE(cross(vec3i(1,0,0),vec3i(0,1,0)) == vec3i(0,0,1)); REQUIRE(normalize(vec2f(0.5f,0.f)).x == Approx(1.f)); - REQUIRE(faceforward(vec2f(1.f), vec2f(2.f), vec2f(3.f)).x == Approx(-1.f)); - REQUIRE(reflect(vec2f(1.f), vec2f(2.f)).x == Approx(-15.f)); + STATIC_REQUIRE(faceforward(vec2f(1.f), vec2f(2.f), vec2f(3.f)).x == approx(-1.f)); + STATIC_REQUIRE(reflect(vec2f(1.f), vec2f(2.f)).x == approx(-15.f)); REQUIRE(refract(vec2f(1.f), vec2f(2.f), 1.f).x == Approx(-15.f)); }