Skip to content

Commit

Permalink
Fix Curve3D baking up vectors for nontrivial curves.
Browse files Browse the repository at this point in the history
The code was modified in 42aa539 to have a different basis vector, but
this line was missed and caused up vectors to invert sometimes.

Fixes godotengine#81879
  • Loading branch information
rmmh committed Sep 19, 2023
1 parent e3e2528 commit 734b9d2
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
4 changes: 2 additions & 2 deletions scene/resources/curve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1662,7 +1662,7 @@ void Curve3D::_bake() const {
const Vector3 *forward_ptr = baked_forward_vector_cache.ptr();
const Vector3 *points_ptr = baked_point_cache.ptr();

Basis frame; // X-right, Y-up, Z-forward.
Basis frame; // X-right, Y-up, -Z-forward.
Basis frame_prev;

// Set the initial frame based on Y-up rule.
Expand All @@ -1683,7 +1683,7 @@ void Curve3D::_bake() const {
Vector3 forward = forward_ptr[idx];

Basis rotate;
rotate.rotate_to_align(frame_prev.get_column(2), forward);
rotate.rotate_to_align(-frame_prev.get_column(2), forward);
frame = rotate * frame_prev;
frame.orthonormalize(); // guard against float error accumulation

Expand Down
8 changes: 8 additions & 0 deletions tests/scene/test_curve_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@ TEST_CASE("[Curve3D] Sampling") {
CHECK(curve->get_closest_point(Vector3(50, 50, 0)) == Vector3(0, 50, 0));
CHECK(curve->get_closest_point(Vector3(0, 100, 0)) == Vector3(0, 50, 0));
}

SUBCASE("sample_baked_up_vector, off-axis") {
// Regression test for issue #81879
Ref<Curve3D> c = memnew(Curve3D);
c->add_point(Vector3());
c->add_point(Vector3(0, .1, 1));
CHECK_LT((c->sample_baked_up_vector(c->get_closest_offset(Vector3(0, 0, .9))) - Vector3(0, 0.995037, -0.099504)).length(), 0.01);
}
}

TEST_CASE("[Curve3D] Tessellation") {
Expand Down

0 comments on commit 734b9d2

Please sign in to comment.