From e95b9cf8987936eb40d93b39dd852d70570385e7 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 24 Feb 2021 03:40:22 +0700 Subject: [PATCH] return faceforward, reflect and refract functions --- .github/workflows/windows.yml | 2 +- README.md | 18 ++++++++++++++++++ headers/vmath.hpp/vmath_fun.hpp | 20 ++++++++++++++++++++ headers/vmath.hpp/vmath_vec_fun.hpp | 17 +++++++++++++++++ untests/vmath_fix_tests.cpp | 3 +++ untests/vmath_fun_tests.cpp | 4 ++++ untests/vmath_vec_fun_tests.cpp | 4 ++++ 7 files changed, 67 insertions(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 86957a4..1c48908 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -14,7 +14,7 @@ jobs: - { os: "windows-2016", vs: "Visual Studio 2017", arch: "x64" } - { os: "windows-2019", vs: "Visual Studio 2019", arch: "x86" } - { os: "windows-2019", vs: "Visual Studio 2019", arch: "x64" } - name: "${{matrix.config.vs}}" + name: "${{matrix.config.vs}} ${{matrix.config.arch}}" steps: - uses: actions/checkout@v2 - name: Build && Test diff --git a/README.md b/README.md index 55ae01e..9cf8abb 100644 --- a/README.md +++ b/README.md @@ -1325,6 +1325,15 @@ constexpr T distance2(T x, T y) noexcept; template < floating_point T > T normalize(T x) noexcept; + +template < floating_point T > +constexpr T faceforward(T n, T i, T nref) noexcept; + +template < floating_point T > +constexpr T reflect(T i, T n) noexcept; + +template < floating_point T > +T refract(T i, T n, T eta) noexcept; ``` #### Vector @@ -1359,6 +1368,15 @@ constexpr vec cross(const vec& xs, const vec& ys); template < typename T, size_t Size > vec normalize(const vec& xs); + +template < typename T, size_t Size > +constexpr vec faceforward(const vec& n, const vec& i, const vec& nref); + +template < typename T, size_t Size > +constexpr vec reflect(const vec& i, const vec& n); + +template < typename T, size_t Size > +vec refract(const vec& i, const vec& n, T eta); ``` #### Quaternion diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index 5417869..e753dd9 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -358,6 +358,26 @@ namespace vmath_hpp normalize(T x) noexcept { return x * rlength(x); } + + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr faceforward(T n, T i, T nref) noexcept { + return dot(nref, i) < T{0} ? n : -n; + } + + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr reflect(T i, T n) noexcept { + return i - T{2} * dot(n, i) * n; + } + + template < typename T > + [[nodiscard]] std::enable_if_t, T> + refract(T i, T n, T eta) noexcept { + const T d = dot(n, i); + const T k = T{1} - sqr(eta) * (T{1} - sqr(d)); + return k < T{0} ? T{0} : (eta * i - (eta * d + sqrt(k)) * n); + } } // diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 4404f37..4a4647b 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -834,6 +834,23 @@ namespace vmath_hpp [[nodiscard]] vec normalize(const vec& xs) { return xs * rlength(xs); } + + template < typename T, std::size_t Size > + [[nodiscard]] 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 > + [[nodiscard]] constexpr vec reflect(const vec& i, const vec& n) { + return i - T{2} * dot(n, i) * n; + } + + template < typename T, std::size_t Size > + [[nodiscard]] vec refract(const vec& i, const vec& n, T eta) { + const T d = dot(n, i); + const T k = T{1} - sqr(eta) * (T{1} - sqr(d)); + return k < T{0} ? vec{T{0}} : (eta * i - (eta * d + sqrt(k)) * n); + } } // diff --git a/untests/vmath_fix_tests.cpp b/untests/vmath_fix_tests.cpp index 0a9e21e..1d0d4ad 100644 --- a/untests/vmath_fix_tests.cpp +++ b/untests/vmath_fix_tests.cpp @@ -267,6 +267,9 @@ namespace vmath_hpp template fix cross(const fix2f&, const fix2f&); template fix3f cross(const fix3f&, const fix3f&); template fix2f normalize(const fix2f&); + template fix3f faceforward(const fix3f&, const fix3f&, const fix3f&); + template fix3f reflect(const fix3f&, const fix3f&); + template fix3f refract(const fix3f&, const fix3f&, fix); } namespace vmath_hpp diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index a681dc0..c2e5bf7 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -130,6 +130,10 @@ TEST_CASE("vmath/fun") { STATIC_CHECK(dot(2.f, 5.f) == uapprox(10.f)); CHECK(normalize(0.5f) == uapprox(1.f)); + + STATIC_CHECK(faceforward(1.f, 2.f, 3.f) == uapprox(-1.f)); + STATIC_CHECK(reflect(1.f, 2.f) == uapprox(-7.f)); + CHECK(refract(1.f, 2.f, 1.f) == uapprox(-7.f)); } SUBCASE("Relational Functions") { diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index ea893fe..31b4915 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -276,6 +276,10 @@ TEST_CASE("vmath/vec_fun") { STATIC_CHECK(cross(int2(1,0),int2(0,1)) == 1); STATIC_CHECK(cross(int3(1,0,0),int3(0,1,0)) == int3(0,0,1)); CHECK(normalize(float2(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)); } SUBCASE("Relational Functions") {