From b846cc5829606f06dd3d2643d1a3be9d1ca51191 Mon Sep 17 00:00:00 2001 From: Nghia Truong Date: Wed, 5 Feb 2020 21:24:11 -0700 Subject: [PATCH] Add reflect and refract function --- src/Magnum/Math/Functions.h | 26 ++++++++++++++++++++++++++ src/Magnum/Math/Test/FunctionsTest.cpp | 16 ++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/Magnum/Math/Functions.h b/src/Magnum/Math/Functions.h index d6d699c6d..0f463bb0f 100644 --- a/src/Magnum/Math/Functions.h +++ b/src/Magnum/Math/Functions.h @@ -654,6 +654,32 @@ template inline Vector sqrtInverted(const Ve return Vector(T(1))/Math::sqrt(a); } + +/** +@brief Reflect a vector off a surface given the surface outward normal. Note that the normal vector must be normalized. + +@m_keyword{reflect(),GLSL reflect(),} +*/ +template inline Vector reflect(const Vector& v, const Vector& n) { + return v - T(2) * dot(v, n) * n; +} + + +/** +@brief Refract a vector through a medium given the surface outward normal and ratio of indices of refraction eta. Note that the normal vector must be normalized. + +@m_keyword{refract(),GLSL refract(),} +*/ +template inline Vector refract(const Vector& v, const Vector& n, T eta) { + const Vector vi = v.normalized(); + const T dt = dot(vi, n); + const T k = T(1) - eta * eta * (T(1) - dt * dt); + if(k > 0) { + return eta * (vi - n * dt) - n * std::sqrt(k); + } + return Vector{}; +} + /*@}*/ }} diff --git a/src/Magnum/Math/Test/FunctionsTest.cpp b/src/Magnum/Math/Test/FunctionsTest.cpp index cf2b20cc7..0f35e5ff5 100644 --- a/src/Magnum/Math/Test/FunctionsTest.cpp +++ b/src/Magnum/Math/Test/FunctionsTest.cpp @@ -68,6 +68,9 @@ struct FunctionsTest: Corrade::TestSuite::Tester { void isInfVector(); void isNan(); void isNanfVector(); + + void reflect(); + void refract(); void trigonometric(); void trigonometricWithBase(); @@ -124,6 +127,9 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::isInfVector, &FunctionsTest::isNan, &FunctionsTest::isNanfVector, + + &FunctionsTest::reflect, + &FunctionsTest::refract, &FunctionsTest::trigonometric, &FunctionsTest::trigonometricWithBase, @@ -440,6 +446,16 @@ void FunctionsTest::isNanfVector() { CORRADE_COMPARE(Math::isNan(Vector3{0.3f, -Constants::inf(), 1.0f}), Math::BoolVector<3>{0x00}); } +void FunctionsTest::reflect() { + CORRADE_COMPARE(Math::reflect(Vector3{1.0f, 2.0f, 3.0f}, Vector3{0.0f, 1.0f, 0.0f}), (Vector3{1.0f, -2.0f, 3.0f})); + CORRADE_COMPARE(Math::reflect(Vector3{2.0f, 1.0f, 1.0f}, Vector3{1.0f, -1.0f, 1.0f}.normalized()), (Vector3{2.0f / 3.0f, 2.0f + 1.0f/3.0f, -1.0f/3.0f})); +} + +void FunctionsTest::refract() { + CORRADE_COMPARE(Math::refract(Vector3{1.0f, 0.0f, 1.0f}, Vector3{0.0f, 0.0f, -1.0f}, Float{1.0f / 1.5f}), (Vector3{0.471405, 0, 0.881917})); + CORRADE_COMPARE(Math::refract(Vector3{4.0f, 1.0f, 1.0f}, Vector3{0.0f, -2.0f, -1.0f}.normalized(), Float{1.0f / 1.5f}), (Vector3{0.628539, 0.661393, 0.409264})); +} + void FunctionsTest::trigonometric() { CORRADE_COMPARE(Math::sin(Deg(30.0f)), 0.5f); CORRADE_COMPARE(Math::sin(Rad(Constants::pi()/6)), 0.5f);