Browse Source

Changed the way the rotation of a curve at a point is evaluated to match PathFollow2D

Andrés Botero 2 năm trước cách đây
mục cha
commit
acae382010
4 tập tin đã thay đổi với 37 bổ sung19 xóa
  1. 4 6
      doc/classes/Curve2D.xml
  2. 4 4
      scene/2d/path_2d.cpp
  3. 1 1
      scene/resources/curve.cpp
  4. 28 8
      tests/scene/test_curve_2d.h

+ 4 - 6
doc/classes/Curve2D.xml

@@ -107,16 +107,14 @@
 			<param index="0" name="offset" type="float" default="0.0" />
 			<param index="1" name="cubic" type="bool" default="false" />
 			<description>
-				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]
 			</description>
 		</method>

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

+ 1 - 1
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 {

+ 28 - 8
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));
-
-		t = curve->sample_baked_with_rotation(curve->get_closest_offset(Vector2(0, 25)));
+		const real_t half_pi = pi * 0.5;
+		Ref<Curve2D> rot_curve = memnew(Curve2D);
+		Transform2D t;
+
+		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(), pi));
+		CHECK(Math::is_equal_approx(t.get_rotation(), half_pi));
 
-		t = curve->sample_baked_with_rotation(curve->get_closest_offset(Vector2(0, 50)));
-		CHECK(t.get_origin() == Vector2(0, 50));
+		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));
+
+		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") {