소스 검색

Improved lerp implementation.

Бранимир Караџић 5 년 전
부모
커밋
936327aa0f
3개의 변경된 파일21개의 추가작업 그리고 1개의 파일을 삭제
  1. 10 1
      include/bx/inline/math.inl
  2. 4 0
      include/bx/math.h
  3. 7 0
      tests/math_test.cpp

+ 10 - 1
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;

+ 4 - 0
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);

+ 7 - 0
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) )