Просмотр исходного кода

Merge pull request #13049 from tagcup/pathfollow2d_parallel_transport

Use parallel transport in PathFollow2D.
Rémi Verschelde 7 лет назад
Родитель
Сommit
b1f037eeb9
2 измененных файлов с 22 добавлено и 29 удалено
  1. 21 25
      scene/2d/path_2d.cpp
  2. 1 4
      scene/2d/path_2d.h

+ 21 - 25
scene/2d/path_2d.cpp

@@ -107,28 +107,39 @@ void PathFollow2D::_update_transform() {
 	if (!c.is_valid())
 		return;
 
+	if (delta_offset == 0) {
+		return;
+	}
+
 	float o = offset;
 	if (loop)
 		o = Math::fposmod(o, c->get_baked_length());
 
 	Vector2 pos = c->interpolate_baked(o, cubic);
 
+	Vector2 offset = Vector2(h_offset, v_offset);
+
+	Transform2D t = get_transform();
+	t.set_origin(pos);
+
 	if (rotate) {
 
-		Vector2 n = (c->interpolate_baked(o + lookahead, cubic) - pos).normalized();
-		Vector2 t = -n.tangent();
-		pos += n * h_offset;
-		pos += t * v_offset;
+		Vector2 t_prev = (pos - c->interpolate_baked(o - delta_offset, cubic)).normalized();
+		Vector2 t_cur = (c->interpolate_baked(o + delta_offset, cubic) - pos).normalized();
+
+		float dot = t_prev.dot(t_cur);
+		float angle = Math::acos(CLAMP(dot, -1, 1));
+
+		t.rotate(angle);
 
-		set_rotation(t.angle());
+		t.translate(offset);
 
 	} else {
 
-		pos.x += h_offset;
-		pos.y += v_offset;
+		t.set_origin(t.get_origin() + offset);
 	}
 
-	set_position(pos);
+	set_transform(t);
 }
 
 void PathFollow2D::_notification(int p_what) {
@@ -176,8 +187,6 @@ bool PathFollow2D::_set(const StringName &p_name, const Variant &p_value) {
 		set_cubic_interpolation(p_value);
 	} else if (String(p_name) == "loop") {
 		set_loop(p_value);
-	} else if (String(p_name) == "lookahead") {
-		set_lookahead(p_value);
 	} else
 		return false;
 
@@ -200,8 +209,6 @@ bool PathFollow2D::_get(const StringName &p_name, Variant &r_ret) const {
 		r_ret = cubic;
 	} else if (String(p_name) == "loop") {
 		r_ret = loop;
-	} else if (String(p_name) == "lookahead") {
-		r_ret = lookahead;
 	} else
 		return false;
 
@@ -219,7 +226,6 @@ void PathFollow2D::_get_property_list(List<PropertyInfo> *p_list) const {
 	p_list->push_back(PropertyInfo(Variant::BOOL, "rotate"));
 	p_list->push_back(PropertyInfo(Variant::BOOL, "cubic_interp"));
 	p_list->push_back(PropertyInfo(Variant::BOOL, "loop"));
-	p_list->push_back(PropertyInfo(Variant::REAL, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"));
 }
 
 String PathFollow2D::get_configuration_warning() const {
@@ -259,7 +265,7 @@ void PathFollow2D::_bind_methods() {
 }
 
 void PathFollow2D::set_offset(float p_offset) {
-
+	delta_offset = p_offset - offset;
 	offset = p_offset;
 	if (path)
 		_update_transform();
@@ -310,16 +316,6 @@ float PathFollow2D::get_unit_offset() const {
 		return 0;
 }
 
-void PathFollow2D::set_lookahead(float p_lookahead) {
-
-	lookahead = p_lookahead;
-}
-
-float PathFollow2D::get_lookahead() const {
-
-	return lookahead;
-}
-
 void PathFollow2D::set_rotate(bool p_rotate) {
 
 	rotate = p_rotate;
@@ -344,11 +340,11 @@ bool PathFollow2D::has_loop() const {
 PathFollow2D::PathFollow2D() {
 
 	offset = 0;
+	delta_offset = 0;
 	h_offset = 0;
 	v_offset = 0;
 	path = NULL;
 	rotate = true;
 	cubic = true;
 	loop = true;
-	lookahead = 4;
 }

+ 1 - 4
scene/2d/path_2d.h

@@ -60,9 +60,9 @@ public:
 private:
 	Path2D *path;
 	real_t offset;
+	real_t delta_offset; // change in offset since last _update_transform
 	real_t h_offset;
 	real_t v_offset;
-	real_t lookahead;
 	bool cubic;
 	bool loop;
 	bool rotate;
@@ -90,9 +90,6 @@ public:
 	void set_unit_offset(float p_unit_offset);
 	float get_unit_offset() const;
 
-	void set_lookahead(float p_lookahead);
-	float get_lookahead() const;
-
 	void set_loop(bool p_loop);
 	bool has_loop() const;