| 
									
										
										
										
											2016-06-18 14:46:12 +02:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-03-27 08:44:44 +01:00
										 |  |  | /*  navigation_region_2d.cpp                                             */ | 
					
						
							| 
									
										
										
										
											2016-06-18 14:46:12 +02:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2016-06-18 14:46:12 +02: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).   */ | 
					
						
							| 
									
										
										
										
											2016-06-18 14:46:12 +02: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-27 08:44:44 +01:00
										 |  |  | #include "navigation_region_2d.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-28 18:29:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/core_string_names.h"
 | 
					
						
							| 
									
										
										
										
											2020-05-25 20:20:45 +03:00
										 |  |  | #include "core/math/geometry_2d.h"
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | #include "core/os/mutex.h"
 | 
					
						
							| 
									
										
										
										
											2022-02-12 02:46:22 +01:00
										 |  |  | #include "scene/resources/world_2d.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | #include "servers/navigation_server_2d.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-28 18:29:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 13:45:31 -05:00
										 |  |  | #include "thirdparty/misc/polypartition.h"
 | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-21 23:37:07 +02:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | Rect2 NavigationPolygon::_edit_get_rect() const { | 
					
						
							|  |  |  | 	if (rect_cache_dirty) { | 
					
						
							|  |  |  | 		item_rect = Rect2(); | 
					
						
							|  |  |  | 		bool first = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (int i = 0; i < outlines.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			const Vector<Vector2> &outline = outlines[i]; | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 			const int outline_size = outline.size(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (outline_size < 3) { | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			const Vector2 *p = outline.ptr(); | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 			for (int j = 0; j < outline_size; j++) { | 
					
						
							|  |  |  | 				if (first) { | 
					
						
							|  |  |  | 					item_rect = Rect2(p[j], Vector2(0, 0)); | 
					
						
							|  |  |  | 					first = false; | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					item_rect.expand_to(p[j]); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		rect_cache_dirty = false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return item_rect; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { | 
					
						
							|  |  |  | 	for (int i = 0; i < outlines.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		const Vector<Vector2> &outline = outlines[i]; | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 		const int outline_size = outline.size(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (outline_size < 3) { | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-05-25 20:20:45 +03:00
										 |  |  | 		if (Geometry2D::is_point_in_polygon(p_point, Variant(outline))) { | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-21 23:37:07 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) { | 
					
						
							| 
									
										
										
										
											2020-02-26 11:28:13 +01:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		MutexLock lock(navmesh_generation); | 
					
						
							|  |  |  | 		navmesh.unref(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	vertices = p_vertices; | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 	rect_cache_dirty = true; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | Vector<Vector2> NavigationPolygon::get_vertices() const { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	return vertices; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 12:16:45 -03:00
										 |  |  | void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array) { | 
					
						
							| 
									
										
										
										
											2020-02-26 11:28:13 +01:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		MutexLock lock(navmesh_generation); | 
					
						
							|  |  |  | 		navmesh.unref(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	polygons.resize(p_array.size()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < p_array.size(); i++) { | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		polygons.write[i].indices = p_array[i]; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 20:58:55 +01:00
										 |  |  | TypedArray<Vector<int32_t>> NavigationPolygon::_get_polygons() const { | 
					
						
							|  |  |  | 	TypedArray<Vector<int32_t>> ret; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	ret.resize(polygons.size()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < ret.size(); i++) { | 
					
						
							|  |  |  | 		ret[i] = polygons[i].indices; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-04 07:39:40 +02:00
										 |  |  | void NavigationPolygon::_set_outlines(const TypedArray<Vector<Vector2>> &p_array) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	outlines.resize(p_array.size()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < p_array.size(); i++) { | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		outlines.write[i] = p_array[i]; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 	rect_cache_dirty = true; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 20:58:55 +01:00
										 |  |  | TypedArray<Vector<Vector2>> NavigationPolygon::_get_outlines() const { | 
					
						
							|  |  |  | 	TypedArray<Vector<Vector2>> ret; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	ret.resize(outlines.size()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < ret.size(); i++) { | 
					
						
							|  |  |  | 		ret[i] = outlines[i]; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	Polygon polygon; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	polygon.indices = p_polygon; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	polygons.push_back(polygon); | 
					
						
							| 
									
										
										
										
											2020-02-26 11:28:13 +01:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		MutexLock lock(navmesh_generation); | 
					
						
							|  |  |  | 		navmesh.unref(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | void NavigationPolygon::add_outline_at_index(const Vector<Vector2> &p_outline, int p_index) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	outlines.insert(p_index, p_outline); | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 	rect_cache_dirty = true; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | int NavigationPolygon::get_polygon_count() const { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	return polygons.size(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Vector<int> NavigationPolygon::get_polygon(int p_idx) { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	return polygons[p_idx].indices; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void NavigationPolygon::clear_polygons() { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	polygons.clear(); | 
					
						
							| 
									
										
										
										
											2020-02-26 11:28:13 +01:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		MutexLock lock(navmesh_generation); | 
					
						
							|  |  |  | 		navmesh.unref(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ref<NavigationMesh> NavigationPolygon::get_mesh() { | 
					
						
							| 
									
										
										
										
											2020-02-26 11:28:13 +01:00
										 |  |  | 	MutexLock lock(navmesh_generation); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	if (navmesh.is_null()) { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:03:09 -06:00
										 |  |  | 		navmesh.instantiate(); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		Vector<Vector3> verts; | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			verts.resize(get_vertices().size()); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			Vector3 *w = verts.ptrw(); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			const Vector2 *r = get_vertices().ptr(); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			for (int i(0); i < get_vertices().size(); i++) { | 
					
						
							|  |  |  | 				w[i] = Vector3(r[i].x, 0.0, r[i].y); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		navmesh->set_vertices(verts); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (int i(0); i < get_polygon_count(); i++) { | 
					
						
							|  |  |  | 			navmesh->add_polygon(get_polygon(i)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-02-26 11:28:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	return navmesh; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | void NavigationPolygon::add_outline(const Vector<Vector2> &p_outline) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	outlines.push_back(p_outline); | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 	rect_cache_dirty = true; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | int NavigationPolygon::get_outline_count() const { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	return outlines.size(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | void NavigationPolygon::set_outline(int p_idx, const Vector<Vector2> &p_outline) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_INDEX(p_idx, outlines.size()); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	outlines.write[p_idx] = p_outline; | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 	rect_cache_dirty = true; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NavigationPolygon::remove_outline(int p_idx) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_INDEX(p_idx, outlines.size()); | 
					
						
							| 
									
										
										
										
											2021-07-03 16:17:03 -06:00
										 |  |  | 	outlines.remove_at(p_idx); | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 	rect_cache_dirty = true; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | Vector<Vector2> NavigationPolygon::get_outline(int p_idx) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, outlines.size(), Vector<Vector2>()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	return outlines[p_idx]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void NavigationPolygon::clear_outlines() { | 
					
						
							| 
									
										
										
										
											2017-01-14 18:03:38 +01:00
										 |  |  | 	outlines.clear(); | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 	rect_cache_dirty = true; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void NavigationPolygon::make_polygons_from_outlines() { | 
					
						
							| 
									
										
										
										
											2020-02-26 11:28:13 +01:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		MutexLock lock(navmesh_generation); | 
					
						
							|  |  |  | 		navmesh.unref(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-01-12 13:45:31 -05:00
										 |  |  | 	List<TPPLPoly> in_poly, out_poly; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Vector2 outside_point(-1e10, -1e10); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < outlines.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		Vector<Vector2> ol = outlines[i]; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		int olsize = ol.size(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (olsize < 3) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		const Vector2 *r = ol.ptr(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int j = 0; j < olsize; j++) { | 
					
						
							|  |  |  | 			outside_point.x = MAX(r[j].x, outside_point.x); | 
					
						
							|  |  |  | 			outside_point.y = MAX(r[j].y, outside_point.y); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	outside_point += Vector2(0.7239784, 0.819238); //avoid precision issues
 | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < outlines.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		Vector<Vector2> ol = outlines[i]; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		int olsize = ol.size(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (olsize < 3) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		const Vector2 *r = ol.ptr(); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		int interscount = 0; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		//test if this is an outer outline
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int k = 0; k < outlines.size(); k++) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (i == k) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 				continue; //no self intersect
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			Vector<Vector2> ol2 = outlines[k]; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			int olsize2 = ol2.size(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (olsize2 < 3) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			const Vector2 *r2 = ol2.ptr(); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (int l = 0; l < olsize2; l++) { | 
					
						
							| 
									
										
										
										
											2020-05-25 20:20:45 +03:00
										 |  |  | 				if (Geometry2D::segment_intersects_segment(r[0], outside_point, r2[l], r2[(l + 1) % olsize2], nullptr)) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 					interscount++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		bool outer = (interscount % 2) == 0; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 13:45:31 -05:00
										 |  |  | 		TPPLPoly tp; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		tp.Init(olsize); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int j = 0; j < olsize; j++) { | 
					
						
							|  |  |  | 			tp[j] = r[j]; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (outer) { | 
					
						
							| 
									
										
										
										
											2021-01-12 13:45:31 -05:00
										 |  |  | 			tp.SetOrientation(TPPL_ORIENTATION_CCW); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2021-01-12 13:45:31 -05:00
										 |  |  | 			tp.SetOrientation(TPPL_ORIENTATION_CW); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			tp.SetHole(true); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		in_poly.push_back(tp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 13:45:31 -05:00
										 |  |  | 	TPPLPartition tpart; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed!
 | 
					
						
							| 
									
										
										
										
											2019-11-06 17:03:04 +01:00
										 |  |  | 		ERR_PRINT("NavigationPolygon: Convex partition failed!"); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	polygons.clear(); | 
					
						
							| 
									
										
										
										
											2022-02-02 00:04:13 +05:45
										 |  |  | 	vertices.clear(); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Map<Vector2, int> points; | 
					
						
							| 
									
										
										
										
											2021-01-12 13:45:31 -05:00
										 |  |  | 	for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) { | 
					
						
							|  |  |  | 		TPPLPoly &tp = I->get(); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		struct Polygon p; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-22 18:45:08 +02:00
										 |  |  | 		for (int64_t i = 0; i < tp.GetNumPoints(); i++) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			Map<Vector2, int>::Element *E = points.find(tp[i]); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			if (!E) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				E = points.insert(tp[i], vertices.size()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 				vertices.push_back(tp[i]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			p.indices.push_back(E->get()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		polygons.push_back(p); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	emit_signal(CoreStringNames::get_singleton()->changed); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NavigationPolygon::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationPolygon::set_vertices); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationPolygon::get_vertices); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("add_polygon", "polygon"), &NavigationPolygon::add_polygon); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_polygon_count"), &NavigationPolygon::get_polygon_count); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_polygon", "idx"), &NavigationPolygon::get_polygon); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("clear_polygons"), &NavigationPolygon::clear_polygons); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("add_outline", "outline"), &NavigationPolygon::add_outline); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("add_outline_at_index", "outline", "index"), &NavigationPolygon::add_outline_at_index); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_outline_count"), &NavigationPolygon::get_outline_count); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_outline", "idx", "outline"), &NavigationPolygon::set_outline); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_outline", "idx"), &NavigationPolygon::get_outline); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("remove_outline", "idx"), &NavigationPolygon::remove_outline); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("clear_outlines"), &NavigationPolygon::clear_outlines); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("make_polygons_from_outlines"), &NavigationPolygon::make_polygons_from_outlines); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_set_polygons", "polygons"), &NavigationPolygon::_set_polygons); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_get_polygons"), &NavigationPolygon::_get_polygons); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_set_outlines", "outlines"), &NavigationPolygon::_set_outlines); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_get_outlines"), &NavigationPolygon::_get_outlines); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-03 23:06:17 +01:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_polygons", "_get_polygons"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_outlines", "_get_outlines"); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | void NavigationRegion2D::set_enabled(bool p_enabled) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (enabled == p_enabled) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	enabled = p_enabled; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!is_inside_tree()) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!enabled) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		NavigationServer2D::get_singleton()->region_set_map(region, RID()); | 
					
						
							| 
									
										
										
										
											2022-01-05 15:34:47 +01:00
										 |  |  | 		NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2021-03-08 09:47:18 +01:00
										 |  |  | 		NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map()); | 
					
						
							| 
									
										
										
										
											2022-01-05 15:34:47 +01:00
										 |  |  | 		NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		update(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | bool NavigationRegion2D::is_enabled() const { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	return enabled; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-08 20:56:33 +01:00
										 |  |  | void NavigationRegion2D::set_layers(uint32_t p_layers) { | 
					
						
							|  |  |  | 	NavigationServer2D::get_singleton()->region_set_layers(region, p_layers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint32_t NavigationRegion2D::get_layers() const { | 
					
						
							|  |  |  | 	return NavigationServer2D::get_singleton()->region_get_layers(region); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | /////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2019-10-21 23:37:07 +02:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | Rect2 NavigationRegion2D::_edit_get_rect() const { | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 	return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | bool NavigationRegion2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 	return navpoly.is_valid() ? navpoly->_edit_is_selected_on_click(p_point, p_tolerance) : false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-21 23:37:07 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | void NavigationRegion2D::_notification(int p_what) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	switch (p_what) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		case NOTIFICATION_ENTER_TREE: { | 
					
						
							| 
									
										
										
										
											2021-03-08 09:47:18 +01:00
										 |  |  | 			if (enabled) { | 
					
						
							|  |  |  | 				NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map()); | 
					
						
							| 
									
										
										
										
											2022-01-05 15:34:47 +01:00
										 |  |  | 				NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case NOTIFICATION_TRANSFORM_CHANGED: { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 			NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		} break; | 
					
						
							|  |  |  | 		case NOTIFICATION_EXIT_TREE: { | 
					
						
							| 
									
										
										
										
											2021-03-08 09:47:18 +01:00
										 |  |  | 			NavigationServer2D::get_singleton()->region_set_map(region, RID()); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 			if (enabled) { | 
					
						
							| 
									
										
										
										
											2022-01-05 15:34:47 +01:00
										 |  |  | 				NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed)); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		} break; | 
					
						
							|  |  |  | 		case NOTIFICATION_DRAW: { | 
					
						
							| 
									
										
										
										
											2017-08-19 01:02:56 +02:00
										 |  |  | 			if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 				Vector<Vector2> verts = navpoly->get_vertices(); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 				if (verts.size() < 3) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 					return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				Color color; | 
					
						
							|  |  |  | 				if (enabled) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					color = get_tree()->get_debug_navigation_color(); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					color = get_tree()->get_debug_navigation_disabled_color(); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 				Color doors_color = color.lightened(0.2); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 				RandomPCG rand; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				for (int i = 0; i < navpoly->get_polygon_count(); i++) { | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 					// An array of vertices for this polygon.
 | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 					Vector<int> polygon = navpoly->get_polygon(i); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 					Vector<Vector2> vertices; | 
					
						
							|  |  |  | 					vertices.resize(polygon.size()); | 
					
						
							|  |  |  | 					for (int j = 0; j < polygon.size(); j++) { | 
					
						
							|  |  |  | 						ERR_FAIL_INDEX(polygon[j], verts.size()); | 
					
						
							|  |  |  | 						vertices.write[j] = verts[polygon[j]]; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					// Generate the polygon color, slightly randomly modified from the settings one.
 | 
					
						
							|  |  |  | 					Color random_variation_color; | 
					
						
							|  |  |  | 					random_variation_color.set_hsv(color.get_h() + rand.random(-1.0, 1.0) * 0.05, color.get_s(), color.get_v() + rand.random(-1.0, 1.0) * 0.1); | 
					
						
							|  |  |  | 					random_variation_color.a = color.a; | 
					
						
							|  |  |  | 					Vector<Color> colors; | 
					
						
							|  |  |  | 					colors.push_back(random_variation_color); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					RS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), vertices, colors); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// Draw the region
 | 
					
						
							|  |  |  | 				Transform2D xform = get_global_transform(); | 
					
						
							|  |  |  | 				const NavigationServer2D *ns = NavigationServer2D::get_singleton(); | 
					
						
							| 
									
										
										
										
											2021-08-09 17:15:17 -05:00
										 |  |  | 				real_t radius = ns->map_get_edge_connection_margin(get_world_2d()->get_navigation_map()) / 2.0; | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 				for (int i = 0; i < ns->region_get_connections_count(region); i++) { | 
					
						
							|  |  |  | 					// Two main points
 | 
					
						
							|  |  |  | 					Vector2 a = ns->region_get_connection_pathway_start(region, i); | 
					
						
							|  |  |  | 					a = xform.affine_inverse().xform(a); | 
					
						
							|  |  |  | 					Vector2 b = ns->region_get_connection_pathway_end(region, i); | 
					
						
							|  |  |  | 					b = xform.affine_inverse().xform(b); | 
					
						
							|  |  |  | 					draw_line(a, b, doors_color); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// Draw a circle to illustrate the margins.
 | 
					
						
							| 
									
										
										
										
											2021-11-17 20:21:53 +03:00
										 |  |  | 					real_t angle = a.angle_to_point(b); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 					draw_arc(a, radius, angle + Math_PI / 2.0, angle - Math_PI / 2.0 + Math_TAU, 10, doors_color); | 
					
						
							|  |  |  | 					draw_arc(b, radius, angle - Math_PI / 2.0, angle + Math_PI / 2.0, 10, doors_color); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) { | 
					
						
							| 
									
										
										
										
											2018-12-06 19:03:26 -02:00
										 |  |  | 	if (p_navpoly == navpoly) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2018-12-06 19:03:26 -02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (navpoly.is_valid()) { | 
					
						
							| 
									
										
										
										
											2020-02-21 23:26:13 +01:00
										 |  |  | 		navpoly->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NavigationRegion2D::_navpoly_changed)); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	navpoly = p_navpoly; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	NavigationServer2D::get_singleton()->region_set_navpoly(region, p_navpoly); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	if (navpoly.is_valid()) { | 
					
						
							| 
									
										
										
										
											2020-02-21 23:26:13 +01:00
										 |  |  | 		navpoly->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NavigationRegion2D::_navpoly_changed)); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-12-06 19:03:26 -02:00
										 |  |  | 	_navpoly_changed(); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 05:01:28 -05:00
										 |  |  | 	update_configuration_warnings(); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | Ref<NavigationPolygon> NavigationRegion2D::get_navigation_polygon() const { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	return navpoly; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | void NavigationRegion2D::_navpoly_changed() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		update(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | void NavigationRegion2D::_map_changed(RID p_map) { | 
					
						
							|  |  |  | 	if (enabled && get_world_2d()->get_navigation_map() == p_map) { | 
					
						
							|  |  |  | 		update(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 05:01:28 -05:00
										 |  |  | TypedArray<String> NavigationRegion2D::get_configuration_warnings() const { | 
					
						
							|  |  |  | 	TypedArray<String> warnings = Node2D::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 (!navpoly.is_valid()) { | 
					
						
							|  |  |  | 			warnings.push_back(TTR("A NavigationMesh resource must be set or created for this node to work. Please set a property or draw a polygon.")); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | void NavigationRegion2D::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navpoly"), &NavigationRegion2D::set_navigation_polygon); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationRegion2D::get_navigation_polygon); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion2D::set_enabled); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion2D::is_enabled); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-08 20:56:33 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_layers", "layers"), &NavigationRegion2D::set_layers); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_layers"), &NavigationRegion2D::get_layers); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationRegion2D::_navpoly_changed); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navpoly", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); | 
					
						
							| 
									
										
										
										
											2021-03-08 20:56:33 +01:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_layers", "get_layers"); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | NavigationRegion2D::NavigationRegion2D() { | 
					
						
							| 
									
										
										
										
											2017-01-12 20:35:46 -03:00
										 |  |  | 	set_notify_transform(true); | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	region = NavigationServer2D::get_singleton()->region_create(); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 08:05:04 +01:00
										 |  |  | NavigationRegion2D::~NavigationRegion2D() { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	NavigationServer2D::get_singleton()->free(region); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } |