From 936327aa0ff58fd3055edece1ed8c6da15a36e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Sat, 4 Apr 2020 09:56:16 -0700 Subject: [PATCH] Improved lerp implementation. --- include/bx/inline/math.inl | 11 ++++++++++- include/bx/math.h | 4 ++++ tests/math_test.cpp | 7 +++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/bx/inline/math.inl b/include/bx/inline/math.inl index 760d947..a24afd6 100644 --- a/include/bx/inline/math.inl +++ b/include/bx/inline/math.inl @@ -124,7 +124,11 @@ namespace bx inline BX_CONSTEXPR_FUNC float lerp(float _a, float _b, float _t) { - return _a + (_b - _a) * _t; + // Reference(s): + // - Linear interpolation past, present and future + // https://web.archive.org/web/20200404165201/https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ + // + return mad(_t, _b, nms(_t, _a, _a) ); } inline BX_CONSTEXPR_FUNC float invLerp(float _a, float _b, float _value) @@ -277,6 +281,11 @@ namespace bx return _a - trunc(_a); } + inline BX_CONSTEXPR_FUNC float nms(float _a, float _b, float _c) + { + return _c - _a * _b; + } + inline BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c) { return _a * _b + _c; diff --git a/include/bx/math.h b/include/bx/math.h index e526236..df08b87 100644 --- a/include/bx/math.h +++ b/include/bx/math.h @@ -249,6 +249,10 @@ namespace bx /// BX_CONSTEXPR_FUNC float fract(float _a); + /// Returns result of negated multiply-sub operation -(_a * _b - _c). + /// + BX_CONSTEXPR_FUNC float nms(float _a, float _b, float _c); + /// Returns result of multipla and add (_a * _b + _c). /// BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c); diff --git a/tests/math_test.cpp b/tests/math_test.cpp index 19e054d..005ba26 100644 --- a/tests/math_test.cpp +++ b/tests/math_test.cpp @@ -196,6 +196,13 @@ TEST_CASE("ToBits", "") REQUIRE(UINT64_C(0x123456789abcdef0) == bx::doubleToBits(bx::bitsToDouble(UINT32_C(0x123456789abcdef0) ) ) ); } +TEST_CASE("lerp", "") +{ + REQUIRE(1389.0f == bx::lerp(1389.0f, 1453.0f, 0.0f) ); + REQUIRE(1453.0f == bx::lerp(1389.0f, 1453.0f, 1.0f) ); + REQUIRE(0.5f == bx::lerp(0.0f, 1.0f, 0.5f) ); +} + void mtxCheck(const float* _a, const float* _b) { if (!bx::equal(_a, _b, 16, 0.01f) )