diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 97ab91e26d8..a0bd22c79bf 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -452,7 +452,7 @@ void Curve::bake() { _baked_cache.resize(_bake_resolution); for (int i = 1; i < _bake_resolution - 1; ++i) { - real_t x = i / static_cast(_bake_resolution); + real_t x = i / static_cast(_bake_resolution - 1); real_t y = sample(x); _baked_cache.write[i] = y; } @@ -489,7 +489,7 @@ real_t Curve::sample_baked(real_t p_offset) const { } // Get interpolation index - real_t fi = p_offset * _baked_cache.size(); + real_t fi = p_offset * (_baked_cache.size() - 1); int i = Math::floor(fi); if (i < 0) { i = 0; diff --git a/tests/scene/test_curve.h b/tests/scene/test_curve.h index bfa37e8f691..d67550f9f72 100644 --- a/tests/scene/test_curve.h +++ b/tests/scene/test_curve.h @@ -62,6 +62,7 @@ TEST_CASE("[Curve] Custom curve with free tangents") { curve->add_point(Vector2(0.25, 1)); curve->add_point(Vector2(0.5, 0)); curve->add_point(Vector2(0.75, 1)); + curve->set_bake_resolution(11); CHECK_MESSAGE( Math::is_zero_approx(curve->get_point_left_tangent(0)), @@ -82,41 +83,41 @@ TEST_CASE("[Curve] Custom curve with free tangents") { CHECK_MESSAGE( Math::is_zero_approx(curve->sample(-0.1)), - "Custom free curve should return the expected value at offset 0.1."); + "Custom free curve should return the expected value at offset -0.1."); CHECK_MESSAGE( curve->sample(0.1) == doctest::Approx((real_t)0.352), "Custom free curve should return the expected value at offset 0.1."); CHECK_MESSAGE( curve->sample(0.4) == doctest::Approx((real_t)0.352), - "Custom free curve should return the expected value at offset 0.1."); + "Custom free curve should return the expected value at offset 0.4."); CHECK_MESSAGE( curve->sample(0.7) == doctest::Approx((real_t)0.896), - "Custom free curve should return the expected value at offset 0.1."); + "Custom free curve should return the expected value at offset 0.7."); CHECK_MESSAGE( curve->sample(1) == doctest::Approx(1), - "Custom free curve should return the expected value at offset 0.1."); + "Custom free curve should return the expected value at offset 1."); CHECK_MESSAGE( curve->sample(2) == doctest::Approx(1), - "Custom free curve should return the expected value at offset 0.1."); + "Custom free curve should return the expected value at offset 2."); CHECK_MESSAGE( Math::is_zero_approx(curve->sample_baked(-0.1)), - "Custom free curve should return the expected baked value at offset 0.1."); + "Custom free curve should return the expected baked value at offset -0.1."); CHECK_MESSAGE( curve->sample_baked(0.1) == doctest::Approx((real_t)0.352), "Custom free curve should return the expected baked value at offset 0.1."); CHECK_MESSAGE( curve->sample_baked(0.4) == doctest::Approx((real_t)0.352), - "Custom free curve should return the expected baked value at offset 0.1."); + "Custom free curve should return the expected baked value at offset 0.4."); CHECK_MESSAGE( curve->sample_baked(0.7) == doctest::Approx((real_t)0.896), - "Custom free curve should return the expected baked value at offset 0.1."); + "Custom free curve should return the expected baked value at offset 0.7."); CHECK_MESSAGE( curve->sample_baked(1) == doctest::Approx(1), - "Custom free curve should return the expected baked value at offset 0.1."); + "Custom free curve should return the expected baked value at offset 1."); CHECK_MESSAGE( curve->sample_baked(2) == doctest::Approx(1), - "Custom free curve should return the expected baked value at offset 0.1."); + "Custom free curve should return the expected baked value at offset 2."); curve->remove_point(1); CHECK_MESSAGE( @@ -218,6 +219,16 @@ TEST_CASE("[Curve] Custom curve with linear tangents") { "Custom free curve should return the expected baked value at offset 0.7 after removing point at invalid index 10."); } +TEST_CASE("[Curve] Straight line offset test") { + Ref curve = memnew(Curve); + curve->add_point(Vector2(0, 0)); + curve->add_point(Vector2(1, 1)); + + CHECK_MESSAGE( + curve->sample_baked(1.0 - (0.5 / curve->get_bake_resolution())) != curve->sample_baked(1), + "Straight line curve should return different baked values at offset 1 vs offset (1 - 0.5 / bake resolution) ."); +} + TEST_CASE("[Curve2D] Linear sampling should return exact value") { Ref curve = memnew(Curve2D); real_t len = 2048.0;