| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2022-07-24 18:47:57 +02:00
										 |  |  | 			Vector2 p = curve->sample(i, frac); | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 			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; | 
					
						
							| 
									
										
										
										
											2022-07-24 18:47:57 +02:00
										 |  |  | 			s[1] = curve->sample(i, frac); | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 	switch (p_what) { | 
					
						
							| 
									
										
										
										
											2022-06-15 23:24:06 +02:00
										 |  |  | 		// Draw the curve if path debugging is enabled.
 | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 		case NOTIFICATION_DRAW: { | 
					
						
							|  |  |  | 			if (!curve.is_valid()) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-15 23:24:06 +02:00
										 |  |  | 			if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_paths_hint()) { | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-12-29 19:07:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 			if (curve->get_point_count() < 2) { | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-01-09 15:17:41 +05:45
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-05 23:20:20 +02:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2022-06-15 23:24:06 +02:00
										 |  |  | 			const real_t line_width = get_tree()->get_debug_paths_width() * EDSCALE; | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2022-06-15 23:24:06 +02:00
										 |  |  | 			const real_t line_width = get_tree()->get_debug_paths_width(); | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-13 08:24:54 +08:00
										 |  |  | 			real_t interval = 10; | 
					
						
							|  |  |  | 			const real_t length = curve->get_baked_length(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (length > CMP_EPSILON) { | 
					
						
							|  |  |  | 				const int sample_count = int(length / interval) + 2; | 
					
						
							|  |  |  | 				interval = length / (sample_count - 1); // Recalculate real interval length.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				Vector<Transform2D> frames; | 
					
						
							|  |  |  | 				frames.resize(sample_count); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					Transform2D *w = frames.ptrw(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					for (int i = 0; i < sample_count; i++) { | 
					
						
							| 
									
										
										
										
											2022-12-06 11:22:11 +01:00
										 |  |  | 						w[i] = curve->sample_baked_with_rotation(i * interval, true); | 
					
						
							| 
									
										
										
										
											2022-11-13 08:24:54 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-12-01 15:23:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-13 08:24:54 +08:00
										 |  |  | 				const Transform2D *r = frames.ptr(); | 
					
						
							|  |  |  | 				// Draw curve segments
 | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					PackedVector2Array v2p; | 
					
						
							|  |  |  | 					v2p.resize(sample_count); | 
					
						
							|  |  |  | 					Vector2 *w = v2p.ptrw(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					for (int i = 0; i < sample_count; i++) { | 
					
						
							|  |  |  | 						w[i] = r[i].get_origin(); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					draw_polyline(v2p, get_tree()->get_debug_paths_color(), line_width, false); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// Draw fish bones
 | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					PackedVector2Array v2p; | 
					
						
							|  |  |  | 					v2p.resize(3); | 
					
						
							|  |  |  | 					Vector2 *w = v2p.ptrw(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					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]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						// Fish Bone.
 | 
					
						
							|  |  |  | 						w[0] = p + (side - forward) * 5; | 
					
						
							|  |  |  | 						w[1] = p; | 
					
						
							|  |  |  | 						w[2] = p + (-side - forward) * 5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						draw_polyline(v2p, get_tree()->get_debug_paths_color(), line_width * 0.5, false); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-15 23:24:06 +02:00
										 |  |  | 	if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_paths_hint()) { | 
					
						
							| 
									
										
										
										
											2020-02-03 13:59:13 +08:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-13 23:21:24 +02:00
										 |  |  | 	queue_redraw(); | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-19 14:26:55 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-25 07:48:27 -05:00
										 |  |  | 	if (rotates) { | 
					
						
							| 
									
										
										
										
											2022-11-24 20:43:34 +08:00
										 |  |  | 		Transform2D xform = c->sample_baked_with_rotation(progress, cubic); | 
					
						
							| 
									
										
										
										
											2022-08-05 17:03:00 +08:00
										 |  |  | 		xform.translate_local(v_offset, h_offset); | 
					
						
							|  |  |  | 		set_rotation(xform[1].angle()); | 
					
						
							|  |  |  | 		set_position(xform[2]); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2022-08-05 17:03:00 +08:00
										 |  |  | 		Vector2 pos = c->sample_baked(progress, cubic); | 
					
						
							| 
									
										
										
										
											2017-12-04 23:03:01 +00:00
										 |  |  | 		pos.x += h_offset; | 
					
						
							|  |  |  | 		pos.y += v_offset; | 
					
						
							| 
									
										
										
										
											2022-08-05 17:03:00 +08: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; | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-12 23:57:11 +03:00
										 |  |  | void PathFollow2D::_validate_property(PropertyInfo &p_property) const { | 
					
						
							|  |  |  | 	if (p_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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-27 19:16:03 +02:00
										 |  |  | 		p_property.hint_string = "0," + rtos(max) + ",0.01,or_less,or_greater"; | 
					
						
							| 
									
										
										
										
											2018-01-12 00:35:12 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 16:43:15 +01:00
										 |  |  | PackedStringArray PathFollow2D::get_configuration_warnings() const { | 
					
						
							|  |  |  | 	PackedStringArray 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())) { | 
					
						
							| 
									
										
										
										
											2022-03-28 15:24:14 +02:00
										 |  |  | 			warnings.push_back(RTR("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() { | 
					
						
							| 
									
										
										
										
											2022-08-23 23:41:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_progress", "progress"), &PathFollow2D::set_progress); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_progress"), &PathFollow2D::get_progress); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 23:41:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_progress_ratio", "ratio"), &PathFollow2D::set_progress_ratio); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_progress_ratio"), &PathFollow2D::get_progress_ratio); | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-27 19:16:03 +02:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress", PROPERTY_HINT_RANGE, "0,10000,0.01,or_less,or_greater,suffix:px"), "set_progress", "get_progress"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "progress_ratio", PROPERTY_HINT_RANGE, "0,1,0.0001,or_less,or_greater", PROPERTY_USAGE_EDITOR), "set_progress_ratio", "get_progress_ratio"); | 
					
						
							| 
									
										
										
											
												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, "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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 23:41:41 +02:00
										 |  |  | void PathFollow2D::set_progress(real_t p_progress) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!isfinite(p_progress)); | 
					
						
							|  |  |  | 	progress = p_progress; | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-17 17:26:05 +02:00
										 |  |  | 			if (loop && path_length) { | 
					
						
							| 
									
										
										
										
											2022-08-23 23:41:41 +02:00
										 |  |  | 				progress = Math::fposmod(progress, path_length); | 
					
						
							|  |  |  | 				if (!Math::is_zero_approx(p_progress) && Math::is_zero_approx(progress)) { | 
					
						
							|  |  |  | 					progress = path_length; | 
					
						
							| 
									
										
										
										
											2020-04-13 07:42:47 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-05-25 18:27:22 +02:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2022-08-23 23:41:41 +02:00
										 |  |  | 				progress = CLAMP(progress, 0, path_length); | 
					
						
							| 
									
										
										
										
											2019-05-25 18:27:22 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 23:41:41 +02:00
										 |  |  | real_t PathFollow2D::get_progress() const { | 
					
						
							|  |  |  | 	return progress; | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 23:41:41 +02:00
										 |  |  | void PathFollow2D::set_progress_ratio(real_t p_ratio) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { | 
					
						
							| 
									
										
										
										
											2022-08-23 23:41:41 +02:00
										 |  |  | 		set_progress(p_ratio * path->get_curve()->get_baked_length()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 23:41:41 +02:00
										 |  |  | real_t PathFollow2D::get_progress_ratio() const { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { | 
					
						
							| 
									
										
										
										
											2022-08-23 23:41:41 +02:00
										 |  |  | 		return get_progress() / 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; | 
					
						
							|  |  |  | } |