| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  path_2d.cpp                                                          */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2022-01-03 21:27:34 +01:00
										 |  |  | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "path_2d.h"
 | 
					
						
							| 
									
										
										
										
											2017-08-19 01:02:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 20:20:45 +03:00
										 |  |  | #include "core/math/geometry_2d.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							|  |  |  | #include "editor/editor_scale.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-21 23:37:07 +02:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | Rect2 Path2D::_edit_get_rect() const { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!curve.is_valid() || curve->get_point_count() == 0) { | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 		return Rect2(0, 0, 0, 0); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Rect2 aabb = Rect2(curve->get_point_position(0), Vector2(0, 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < curve->get_point_count(); i++) { | 
					
						
							|  |  |  | 		for (int j = 0; j <= 8; j++) { | 
					
						
							|  |  |  | 			real_t frac = j / 8.0; | 
					
						
							|  |  |  | 			Vector2 p = curve->interpolate(i, frac); | 
					
						
							|  |  |  | 			aabb.expand_to(p); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return aabb; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-08 21:35:41 +01:00
										 |  |  | bool Path2D::_edit_use_rect() const { | 
					
						
							| 
									
										
										
										
											2019-07-08 12:35:52 +03:00
										 |  |  | 	return curve.is_valid() && curve->get_point_count() != 0; | 
					
						
							| 
									
										
										
										
											2018-03-08 21:35:41 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { | 
					
						
							| 
									
										
										
										
											2018-10-30 14:44:05 +01:00
										 |  |  | 	if (curve.is_null()) { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 	for (int i = 0; i < curve->get_point_count(); i++) { | 
					
						
							|  |  |  | 		Vector2 s[2]; | 
					
						
							|  |  |  | 		s[0] = curve->get_point_position(i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (int j = 1; j <= 8; j++) { | 
					
						
							|  |  |  | 			real_t frac = j / 8.0; | 
					
						
							|  |  |  | 			s[1] = curve->interpolate(i, frac); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-25 20:20:45 +03:00
										 |  |  | 			Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, s); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (p.distance_to(p_point) <= p_tolerance) { | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			s[0] = s[1]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-21 23:37:07 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void Path2D::_notification(int p_what) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (p_what == NOTIFICATION_DRAW && curve.is_valid()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		//draw the curve!!
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-19 01:02:56 +02:00
										 |  |  | 		if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) { | 
					
						
							| 
									
										
										
										
											2015-12-29 19:07:37 -03:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 15:17:41 +05:45
										 |  |  | 		if (curve->get_point_count() < 2) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-05 23:20:20 +02:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | 		const real_t line_width = 2 * EDSCALE; | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | 		const real_t line_width = 2; | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-02-09 00:04:31 +02:00
										 |  |  | 		const Color color = Color(0.5, 0.6, 1.0, 0.7); | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-01 15:23:27 +00:00
										 |  |  | 		_cached_draw_pts.resize(curve->get_point_count() * 8); | 
					
						
							|  |  |  | 		int count = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-01 15:23:27 +00:00
										 |  |  | 		for (int i = 0; i < curve->get_point_count(); i++) { | 
					
						
							|  |  |  | 			for (int j = 0; j < 8; j++) { | 
					
						
							|  |  |  | 				real_t frac = j * (1.0 / 8.0); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				Vector2 p = curve->interpolate(i, frac); | 
					
						
							| 
									
										
										
										
											2021-12-01 15:23:27 +00:00
										 |  |  | 				_cached_draw_pts.set(count++, p); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-12-01 15:23:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		draw_polyline(_cached_draw_pts, color, line_width, true); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Path2D::_curve_changed() { | 
					
						
							| 
									
										
										
										
											2020-02-03 13:59:13 +08:00
										 |  |  | 	if (!is_inside_tree()) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-03 13:59:13 +08:00
										 |  |  | 	update(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void Path2D::set_curve(const Ref<Curve2D> &p_curve) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (curve.is_valid()) { | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 		curve->disconnect("changed", callable_mp(this, &Path2D::_curve_changed)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	curve = p_curve; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (curve.is_valid()) { | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 		curve->connect("changed", callable_mp(this, &Path2D::_curve_changed)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-10 18:01:16 -03:00
										 |  |  | 	_curve_changed(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Ref<Curve2D> Path2D::get_curve() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return curve; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Path2D::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2017-08-09 13:19:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path2D::set_curve); | 
					
						
							| 
									
										
										
										
											2017-08-09 13:54:55 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_curve"), &Path2D::get_curve); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-12 13:16:14 +02:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_curve", "get_curve"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | /////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PathFollow2D::_update_transform() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!path) { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Ref<Curve2D> c = path->get_curve(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!c.is_valid()) { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | 	real_t path_length = c->get_baked_length(); | 
					
						
							| 
									
										
										
										
											2019-02-23 20:07:16 -03:00
										 |  |  | 	if (path_length == 0) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-30 03:16:33 +01:00
										 |  |  | 	Vector2 pos = c->interpolate_baked(offset, cubic); | 
					
						
							| 
									
										
										
										
											2017-11-19 14:26:55 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-25 07:48:27 -05:00
										 |  |  | 	if (rotates) { | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | 		real_t ahead = offset + lookahead; | 
					
						
							| 
									
										
										
										
											2017-12-04 23:03:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (loop && ahead >= path_length) { | 
					
						
							|  |  |  | 			// If our lookahead will loop, we need to check if the path is closed.
 | 
					
						
							|  |  |  | 			int point_count = c->get_point_count(); | 
					
						
							|  |  |  | 			if (point_count > 0) { | 
					
						
							|  |  |  | 				Vector2 start_point = c->get_point_position(0); | 
					
						
							|  |  |  | 				Vector2 end_point = c->get_point_position(point_count - 1); | 
					
						
							|  |  |  | 				if (start_point == end_point) { | 
					
						
							|  |  |  | 					// Since the path is closed we want to 'smooth off'
 | 
					
						
							|  |  |  | 					// the corner at the start/end.
 | 
					
						
							|  |  |  | 					// So we wrap the lookahead back round.
 | 
					
						
							|  |  |  | 					ahead = Math::fmod(ahead, path_length); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Vector2 ahead_pos = c->interpolate_baked(ahead, cubic); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-04 23:03:01 +00:00
										 |  |  | 		Vector2 tangent_to_curve; | 
					
						
							|  |  |  | 		if (ahead_pos == pos) { | 
					
						
							|  |  |  | 			// This will happen at the end of non-looping or non-closed paths.
 | 
					
						
							|  |  |  | 			// We'll try a look behind instead, in order to get a meaningful angle.
 | 
					
						
							|  |  |  | 			tangent_to_curve = | 
					
						
							| 
									
										
										
										
											2019-11-30 03:16:33 +01:00
										 |  |  | 					(pos - c->interpolate_baked(offset - lookahead, cubic)).normalized(); | 
					
						
							| 
									
										
										
										
											2017-12-04 23:03:01 +00:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			tangent_to_curve = (ahead_pos - pos).normalized(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-19 14:26:55 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-06 18:16:06 +00:00
										 |  |  | 		Vector2 normal_of_curve = -tangent_to_curve.orthogonal(); | 
					
						
							| 
									
										
										
										
											2017-11-19 14:26:55 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-04 23:03:01 +00:00
										 |  |  | 		pos += tangent_to_curve * h_offset; | 
					
						
							|  |  |  | 		pos += normal_of_curve * v_offset; | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-04 23:03:01 +00:00
										 |  |  | 		set_rotation(tangent_to_curve.angle()); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2017-12-04 23:03:01 +00:00
										 |  |  | 		pos.x += h_offset; | 
					
						
							|  |  |  | 		pos.y += v_offset; | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 21:57:48 -05:00
										 |  |  | 	set_position(pos); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PathFollow2D::_notification(int p_what) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	switch (p_what) { | 
					
						
							| 
									
										
										
										
											2014-11-05 21:20:42 -03:00
										 |  |  | 		case NOTIFICATION_ENTER_TREE: { | 
					
						
							| 
									
										
										
										
											2017-09-06 23:50:18 +02:00
										 |  |  | 			path = Object::cast_to<Path2D>(get_parent()); | 
					
						
							|  |  |  | 			if (path) { | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 				_update_transform(); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2014-11-05 21:20:42 -03:00
										 |  |  | 		case NOTIFICATION_EXIT_TREE: { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 			path = nullptr; | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PathFollow2D::set_cubic_interpolation(bool p_enable) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	cubic = p_enable; | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool PathFollow2D::get_cubic_interpolation() const { | 
					
						
							|  |  |  | 	return cubic; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-12 00:35:12 +02:00
										 |  |  | void PathFollow2D::_validate_property(PropertyInfo &property) const { | 
					
						
							|  |  |  | 	if (property.name == "offset") { | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | 		real_t max = 10000.0; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (path && path->get_curve().is_valid()) { | 
					
						
							| 
									
										
										
										
											2018-01-12 00:35:12 +02:00
										 |  |  | 			max = path->get_curve()->get_baked_length(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-01-12 00:35:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-24 14:40:33 +01:00
										 |  |  | 		property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater"; | 
					
						
							| 
									
										
										
										
											2018-01-12 00:35:12 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 05:01:28 -05:00
										 |  |  | TypedArray<String> PathFollow2D::get_configuration_warnings() const { | 
					
						
							|  |  |  | 	TypedArray<String> warnings = Node::get_configuration_warnings(); | 
					
						
							| 
									
										
										
										
											2020-05-14 23:59:27 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 05:01:28 -05:00
										 |  |  | 	if (is_visible_in_tree() && is_inside_tree()) { | 
					
						
							|  |  |  | 		if (!Object::cast_to<Path2D>(get_parent())) { | 
					
						
							|  |  |  | 			warnings.push_back(TTR("PathFollow2D only works when set as a child of a Path2D node.")); | 
					
						
							| 
									
										
										
										
											2020-05-14 23:59:27 +03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-05-17 18:27:15 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 05:01:28 -05:00
										 |  |  | 	return warnings; | 
					
						
							| 
									
										
										
										
											2016-05-17 18:27:15 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | void PathFollow2D::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_offset", "offset"), &PathFollow2D::set_offset); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_offset"), &PathFollow2D::get_offset); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_h_offset", "h_offset"), &PathFollow2D::set_h_offset); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_h_offset"), &PathFollow2D::get_h_offset); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_v_offset", "v_offset"), &PathFollow2D::set_v_offset); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_v_offset"), &PathFollow2D::get_v_offset); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_unit_offset", "unit_offset"), &PathFollow2D::set_unit_offset); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_unit_offset"), &PathFollow2D::get_unit_offset); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-25 07:48:27 -05:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_rotates", "enable"), &PathFollow2D::set_rotates); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("is_rotating"), &PathFollow2D::is_rotating); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_cubic_interpolation", "enable"), &PathFollow2D::set_cubic_interpolation); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_cubic_interpolation"), &PathFollow2D::get_cubic_interpolation); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_loop", "loop"), &PathFollow2D::set_loop); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("has_loop"), &PathFollow2D::has_loop); | 
					
						
							| 
									
										
										
										
											2018-01-12 00:35:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_lookahead", "lookahead"), &PathFollow2D::set_lookahead); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_lookahead"), &PathFollow2D::get_lookahead); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
											
										 
											2020-02-24 15:20:53 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater"), "set_offset", "get_offset"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset"), "set_h_offset", "get_h_offset"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset"), "set_v_offset", "get_v_offset"); | 
					
						
							| 
									
										
										
										
											2019-12-25 07:48:27 -05:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotates"), "set_rotates", "is_rotating"); | 
					
						
							| 
									
										
										
										
											2018-01-12 00:35:12 +02:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cubic_interp"), "set_cubic_interpolation", "get_cubic_interpolation"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); | 
					
						
							| 
									
										
										
											
												Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
											
										 
											2020-02-24 15:20:53 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"), "set_lookahead", "get_lookahead"); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | void PathFollow2D::set_offset(real_t p_offset) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	offset = p_offset; | 
					
						
							| 
									
										
										
										
											2019-05-25 18:27:22 +02:00
										 |  |  | 	if (path) { | 
					
						
							| 
									
										
										
										
											2020-04-13 07:42:47 +02:00
										 |  |  | 		if (path->get_curve().is_valid()) { | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | 			real_t path_length = path->get_curve()->get_baked_length(); | 
					
						
							| 
									
										
										
										
											2019-05-25 18:27:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (loop) { | 
					
						
							| 
									
										
										
										
											2020-04-13 07:42:47 +02:00
										 |  |  | 				offset = Math::fposmod(offset, path_length); | 
					
						
							|  |  |  | 				if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) { | 
					
						
							|  |  |  | 					offset = path_length; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-05-25 18:27:22 +02:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				offset = CLAMP(offset, 0, path_length); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 		_update_transform(); | 
					
						
							| 
									
										
										
										
											2019-05-25 18:27:22 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | void PathFollow2D::set_h_offset(real_t p_h_offset) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	h_offset = p_h_offset; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (path) { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 		_update_transform(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | real_t PathFollow2D::get_h_offset() const { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	return h_offset; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | void PathFollow2D::set_v_offset(real_t p_v_offset) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	v_offset = p_v_offset; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (path) { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 		_update_transform(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | real_t PathFollow2D::get_v_offset() const { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	return v_offset; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | real_t PathFollow2D::get_offset() const { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	return offset; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | void PathFollow2D::set_unit_offset(real_t p_unit_offset) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		set_offset(p_unit_offset * path->get_curve()->get_baked_length()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | real_t PathFollow2D::get_unit_offset() const { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		return get_offset() / path->get_curve()->get_baked_length(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | void PathFollow2D::set_lookahead(real_t p_lookahead) { | 
					
						
							| 
									
										
										
										
											2017-12-04 23:03:01 +00:00
										 |  |  | 	lookahead = p_lookahead; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-29 23:10:32 -05:00
										 |  |  | real_t PathFollow2D::get_lookahead() const { | 
					
						
							| 
									
										
										
										
											2017-12-04 23:03:01 +00:00
										 |  |  | 	return lookahead; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-25 07:48:27 -05:00
										 |  |  | void PathFollow2D::set_rotates(bool p_rotates) { | 
					
						
							|  |  |  | 	rotates = p_rotates; | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	_update_transform(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool PathFollow2D::is_rotating() const { | 
					
						
							| 
									
										
										
										
											2019-12-25 07:48:27 -05:00
										 |  |  | 	return rotates; | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PathFollow2D::set_loop(bool p_loop) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	loop = p_loop; | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool PathFollow2D::has_loop() const { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	return loop; | 
					
						
							|  |  |  | } |