Skip to content

Commit acae382

Browse files
committed
Changed the way the rotation of a curve at a point is evaluated to match PathFollow2D
1 parent f497156 commit acae382

4 files changed

Lines changed: 37 additions & 19 deletions

File tree

doc/classes/Curve2D.xml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,14 @@
107107
<param index="0" name="offset" type="float" default="0.0" />
108108
<param index="1" name="cubic" type="bool" default="false" />
109109
<description>
110-
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].
110+
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].
111111
[codeblock]
112112
var baked = curve.sample_baked_with_rotation(offset)
113-
# This will rotate and position the node with the up direction pointing along the curve.
113+
# The returned Transform2D can be set directly.
114+
transform = baked
115+
# You can also read the origin and rotation separately from the returned Transform2D.
114116
position = baked.get_origin()
115117
rotation = baked.get_rotation()
116-
# Alternatively, not preserving scale.
117-
transform = baked * Transform2D.FLIP_Y
118-
# To match the rotation of PathFollow2D, not preserving scale.
119-
transform = Transform2D(baked.y, baked.x, baked.origin)
120118
[/codeblock]
121119
</description>
122120
</method>

scene/2d/path_2d.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ void Path2D::_notification(int p_what) {
146146

147147
for (int i = 0; i < sample_count; i++) {
148148
const Vector2 p = r[i].get_origin();
149-
const Vector2 side = r[i].columns[0];
150-
const Vector2 forward = r[i].columns[1];
149+
const Vector2 side = r[i].columns[1];
150+
const Vector2 forward = r[i].columns[0];
151151

152152
// Fish Bone.
153153
w[0] = p + (side - forward) * 5;
@@ -232,8 +232,8 @@ void PathFollow2D::_update_transform() {
232232

233233
if (rotates) {
234234
Transform2D xform = c->sample_baked_with_rotation(progress, cubic);
235-
xform.translate_local(v_offset, h_offset);
236-
set_rotation(xform[1].angle());
235+
xform.translate_local(h_offset, v_offset);
236+
set_rotation(xform[0].angle());
237237
set_position(xform[2]);
238238
} else {
239239
Vector2 pos = c->sample_baked(progress, cubic);

scene/resources/curve.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ Transform2D Curve2D::_sample_posture(Interval p_interval) const {
977977
const Vector2 forward = forward_begin.slerp(forward_end, frac).normalized();
978978
const Vector2 side = Vector2(-forward.y, forward.x);
979979

980-
return Transform2D(side, forward, Vector2(0.0, 0.0));
980+
return Transform2D(forward, side, Vector2(0.0, 0.0));
981981
}
982982

983983
Vector2 Curve2D::sample_baked(real_t p_offset, bool p_cubic) const {

tests/scene/test_curve_2d.h

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,17 +155,37 @@ TEST_CASE("[Curve2D] Sampling") {
155155

156156
SUBCASE("sample_baked_with_rotation") {
157157
const real_t pi = 3.14159;
158-
Transform2D t = curve->sample_baked_with_rotation(curve->get_closest_offset(Vector2(0, 0)));
159-
CHECK(t.get_origin() == Vector2(0, 0));
160-
CHECK(Math::is_equal_approx(t.get_rotation(), pi));
161-
162-
t = curve->sample_baked_with_rotation(curve->get_closest_offset(Vector2(0, 25)));
158+
const real_t half_pi = pi * 0.5;
159+
Ref<Curve2D> rot_curve = memnew(Curve2D);
160+
Transform2D t;
161+
162+
rot_curve->clear_points();
163+
rot_curve->add_point(Vector2());
164+
rot_curve->add_point(Vector2(50, 0));
165+
t = rot_curve->sample_baked_with_rotation(25);
166+
CHECK(t.get_origin() == Vector2(25, 0));
167+
CHECK(Math::is_equal_approx(t.get_rotation(), 0));
168+
169+
rot_curve->clear_points();
170+
rot_curve->add_point(Vector2());
171+
rot_curve->add_point(Vector2(0, 50));
172+
t = rot_curve->sample_baked_with_rotation(25);
163173
CHECK(t.get_origin() == Vector2(0, 25));
164-
CHECK(Math::is_equal_approx(t.get_rotation(), pi));
174+
CHECK(Math::is_equal_approx(t.get_rotation(), half_pi));
165175

166-
t = curve->sample_baked_with_rotation(curve->get_closest_offset(Vector2(0, 50)));
167-
CHECK(t.get_origin() == Vector2(0, 50));
176+
rot_curve->clear_points();
177+
rot_curve->add_point(Vector2());
178+
rot_curve->add_point(Vector2(-50, 0));
179+
t = rot_curve->sample_baked_with_rotation(25);
180+
CHECK(t.get_origin() == Vector2(-25, 0));
168181
CHECK(Math::is_equal_approx(t.get_rotation(), pi));
182+
183+
rot_curve->clear_points();
184+
rot_curve->add_point(Vector2());
185+
rot_curve->add_point(Vector2(0, -50));
186+
t = rot_curve->sample_baked_with_rotation(25);
187+
CHECK(t.get_origin() == Vector2(0, -25));
188+
CHECK(Math::is_equal_approx(t.get_rotation(), -half_pi));
169189
}
170190

171191
SUBCASE("get_closest_point") {

0 commit comments

Comments
 (0)