diff --git a/doc/classes/Curve2D.xml b/doc/classes/Curve2D.xml
index 197d03f0d87..0e75c65f50a 100644
--- a/doc/classes/Curve2D.xml
+++ b/doc/classes/Curve2D.xml
@@ -107,16 +107,14 @@
- Similar to [method sample_baked], but returns [Transform2D] that includes a rotation along the curve, with [member Transform2D.origin] as the point position, [member Transform2D.x] as the sideways vector, and [member Transform2D.y] as the forward vector. Returns an empty transform if the length of the curve is [code]0[/code].
+ Similar to [method sample_baked], but returns [Transform2D] that includes a rotation along the curve, with [member Transform2D.origin] as the point position and the [member Transform2D.x] vector pointing in the direction of the path at that point. Returns an empty transform if the length of the curve is [code]0[/code].
[codeblock]
var baked = curve.sample_baked_with_rotation(offset)
- # This will rotate and position the node with the up direction pointing along the curve.
+ # The returned Transform2D can be set directly.
+ transform = baked
+ # You can also read the origin and rotation separately from the returned Transform2D.
position = baked.get_origin()
rotation = baked.get_rotation()
- # Alternatively, not preserving scale.
- transform = baked * Transform2D.FLIP_Y
- # To match the rotation of PathFollow2D, not preserving scale.
- transform = Transform2D(baked.y, baked.x, baked.origin)
[/codeblock]
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index ee0ccc42ff8..a0e7e4cf253 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -146,8 +146,8 @@ void Path2D::_notification(int p_what) {
for (int i = 0; i < sample_count; i++) {
const Vector2 p = r[i].get_origin();
- const Vector2 side = r[i].columns[0];
- const Vector2 forward = r[i].columns[1];
+ const Vector2 side = r[i].columns[1];
+ const Vector2 forward = r[i].columns[0];
// Fish Bone.
w[0] = p + (side - forward) * 5;
@@ -232,8 +232,8 @@ void PathFollow2D::_update_transform() {
if (rotates) {
Transform2D xform = c->sample_baked_with_rotation(progress, cubic);
- xform.translate_local(v_offset, h_offset);
- set_rotation(xform[1].angle());
+ xform.translate_local(h_offset, v_offset);
+ set_rotation(xform[0].angle());
set_position(xform[2]);
} else {
Vector2 pos = c->sample_baked(progress, cubic);
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index 909e95dd08f..b6a40a03a16 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -977,7 +977,7 @@ Transform2D Curve2D::_sample_posture(Interval p_interval) const {
const Vector2 forward = forward_begin.slerp(forward_end, frac).normalized();
const Vector2 side = Vector2(-forward.y, forward.x);
- return Transform2D(side, forward, Vector2(0.0, 0.0));
+ return Transform2D(forward, side, Vector2(0.0, 0.0));
}
Vector2 Curve2D::sample_baked(real_t p_offset, bool p_cubic) const {
diff --git a/tests/scene/test_curve_2d.h b/tests/scene/test_curve_2d.h
index fc141f3d090..099f6fefa9a 100644
--- a/tests/scene/test_curve_2d.h
+++ b/tests/scene/test_curve_2d.h
@@ -155,17 +155,37 @@ TEST_CASE("[Curve2D] Sampling") {
SUBCASE("sample_baked_with_rotation") {
const real_t pi = 3.14159;
- Transform2D t = curve->sample_baked_with_rotation(curve->get_closest_offset(Vector2(0, 0)));
- CHECK(t.get_origin() == Vector2(0, 0));
- CHECK(Math::is_equal_approx(t.get_rotation(), pi));
+ const real_t half_pi = pi * 0.5;
+ Ref rot_curve = memnew(Curve2D);
+ Transform2D t;
- t = curve->sample_baked_with_rotation(curve->get_closest_offset(Vector2(0, 25)));
+ rot_curve->clear_points();
+ rot_curve->add_point(Vector2());
+ rot_curve->add_point(Vector2(50, 0));
+ t = rot_curve->sample_baked_with_rotation(25);
+ CHECK(t.get_origin() == Vector2(25, 0));
+ CHECK(Math::is_equal_approx(t.get_rotation(), 0));
+
+ rot_curve->clear_points();
+ rot_curve->add_point(Vector2());
+ rot_curve->add_point(Vector2(0, 50));
+ t = rot_curve->sample_baked_with_rotation(25);
CHECK(t.get_origin() == Vector2(0, 25));
+ CHECK(Math::is_equal_approx(t.get_rotation(), half_pi));
+
+ rot_curve->clear_points();
+ rot_curve->add_point(Vector2());
+ rot_curve->add_point(Vector2(-50, 0));
+ t = rot_curve->sample_baked_with_rotation(25);
+ CHECK(t.get_origin() == Vector2(-25, 0));
CHECK(Math::is_equal_approx(t.get_rotation(), pi));
- t = curve->sample_baked_with_rotation(curve->get_closest_offset(Vector2(0, 50)));
- CHECK(t.get_origin() == Vector2(0, 50));
- CHECK(Math::is_equal_approx(t.get_rotation(), pi));
+ rot_curve->clear_points();
+ rot_curve->add_point(Vector2());
+ rot_curve->add_point(Vector2(0, -50));
+ t = rot_curve->sample_baked_with_rotation(25);
+ CHECK(t.get_origin() == Vector2(0, -25));
+ CHECK(Math::is_equal_approx(t.get_rotation(), -half_pi));
}
SUBCASE("get_closest_point") {