From 89f9872d96b14bd605832ac30015fce1837a978f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 31 Jan 2021 01:41:29 +0700 Subject: [PATCH] lerp with two scale argumets --- headers/vmath.hpp/vmath_fun.hpp | 12 +++++++ headers/vmath.hpp/vmath_vec_fun.hpp | 52 ++++++++++++++++++++++++++++- untests/vmath_fun_tests.cpp | 7 ++++ untests/vmath_vec_fun_tests.cpp | 8 +++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index bcf54d3..9266993 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -26,6 +26,12 @@ namespace vmath_hpp return x >= T(0) ? x : -x; } + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr sqr(T x) noexcept { + return x * x; + } + template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr sign(T x) noexcept { @@ -158,6 +164,12 @@ namespace vmath_hpp return x * (T(1) - a) + y * a; } + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr lerp(T x, T y, T x_a, T y_a) noexcept { + return x * x_a + y * y_a; + } + template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr step(T edge, T x) noexcept { diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index ad28a25..e8392a4 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -55,6 +55,24 @@ namespace vmath_hpp::detail::impl return { f(a[Is], b[Is], c[Is])... }; } + template < typename A, typename B, typename C, typename D, std::size_t Size, typename F, std::size_t... Is > + [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE + auto map_join_impl( + F&& f, + const vec& a, + const vec& b, + const vec& c, + const vec& d, + std::index_sequence + ) -> vec(), + std::declval(), + std::declval(), + std::declval())), Size> + { + return { f(a[Is], b[Is], c[Is], d[Is])... }; + } + template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE auto fold_join_impl( @@ -125,6 +143,19 @@ namespace vmath_hpp::detail std::forward(f), a, b, c, std::make_index_sequence{}); } + template < typename A, typename B, typename C, typename D, std::size_t Size, typename F > + [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE + auto map_join( + F&& f, + const vec& a, + const vec& b, + const vec& c, + const vec& d + ) { + return impl::map_join_impl( + std::forward(f), a, b, c, d, std::make_index_sequence{}); + } + template < typename A, typename B, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE auto fold_join( @@ -715,10 +746,29 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec lerp(const vec& xs, const vec& ys, const vec& as) { + [[nodiscard]] constexpr vec lerp(const vec& xs, const vec& ys, T x_a, T y_a) { + return map_join([x_a, y_a](T x, T y) { return lerp(x, y, x_a, y_a); }, xs, ys); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec lerp( + const vec& xs, + const vec& ys, + const vec& as) + { return map_join([](T x, T y, T a) { return lerp(x, y, a); }, xs, ys, as); } + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec lerp( + const vec& xs, + const vec& ys, + const vec& xs_a, + const vec& ys_a) + { + return map_join([](T x, T y, T x_a, T y_a) { return lerp(x, y, x_a, y_a); }, xs, ys, xs_a, ys_a); + } + template < typename T, std::size_t Size > [[nodiscard]] constexpr vec step(T edge, const vec& xs) { return map_join([edge](T x) { return step(edge, x); }, xs); diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index 95d9297..cc08b0f 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -55,6 +55,9 @@ TEST_CASE("vmath/fun") { STATIC_REQUIRE(vmath_hpp::abs(1.f) == uapprox(1.f)); STATIC_REQUIRE(vmath_hpp::abs(-1.f) == uapprox(1.f)); + STATIC_REQUIRE(sqr(2) == 4); + STATIC_REQUIRE(sqr(-4.f) == uapprox(16.f)); + STATIC_REQUIRE(sign(2) == 1); STATIC_REQUIRE(sign(-2) == -1); STATIC_REQUIRE(sign(0) == 0); @@ -121,6 +124,10 @@ TEST_CASE("vmath/fun") { STATIC_REQUIRE(lerp(2.f, 10.f, 0.5f) == uapprox(6.f)); STATIC_REQUIRE(lerp(2.f, 10.f, 1.f) == uapprox(10.f)); + STATIC_REQUIRE(lerp(2.f, 10.f, 0.f, 1.f) == uapprox(10.f)); + STATIC_REQUIRE(lerp(2.f, 10.f, 1.f, 0.f) == uapprox(2.f)); + STATIC_REQUIRE(lerp(2.f, 10.f, 0.5f, 0.2f) == uapprox(3.f)); + STATIC_REQUIRE(step(0.5f, 0.4f) == uapprox(0.f)); STATIC_REQUIRE(step(0.5f, 0.6f) == uapprox(1.f)); STATIC_REQUIRE(smoothstep(0.f, 1.f, 0.1f) == uapprox(0.028f)); diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index 1f9c0d7..a44d258 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -206,10 +206,18 @@ TEST_CASE("vmath/vec_fun") { STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 0.5f) == uapprox2(6.f)); STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 1.f) == uapprox2(10.f)); + STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 0.f, 1.f) == uapprox2(10.f)); + STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 1.f, 0.f) == uapprox2(2.f)); + STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 0.5f, 0.2f) == uapprox2(3.f)); + STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(0.f)) == uapprox2(2.f)); STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(0.5f)) == uapprox2(6.f)); STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(1.f)) == uapprox2(10.f)); + STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(0.f), float2(1.f)) == uapprox2(10.f)); + STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(1.f), float2(0.f)) == uapprox2(2.f)); + STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(0.5f), float2(0.2f)) == uapprox2(3.f)); + STATIC_REQUIRE(step(0.5f, float2(0.4f)) == uapprox2(0.f)); STATIC_REQUIRE(step(0.5f, float2(0.6f)) == uapprox2(1.f)); STATIC_REQUIRE(step(float2(0.5f), float2(0.4f)) == uapprox2(0.f));