| 
									
										
										
										
											2016-06-18 14:46:12 +02:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  navigation_polygon.cpp                                               */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       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
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-01-01 11:16:22 +01:00
										 |  |  | /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2020 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | #include "navigation_polygon.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-28 18:29:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/core_string_names.h"
 | 
					
						
							|  |  |  | #include "core/engine.h"
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | #include "core/os/mutex.h"
 | 
					
						
							| 
									
										
										
										
											2019-02-12 17:18:13 +01:00
										 |  |  | #include "navigation_2d.h"
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | #include "servers/navigation_2d_server.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-28 18:29:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "thirdparty/misc/triangulator.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(); | 
					
						
							|  |  |  | 			if (outline_size < 3) | 
					
						
							|  |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							|  |  |  | 		if (outline_size < 3) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		if (Geometry::is_point_in_polygon(p_point, Variant(outline))) | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	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) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	navmesh_generation->lock(); | 
					
						
							|  |  |  | 	navmesh.unref(); | 
					
						
							|  |  |  | 	navmesh_generation->unlock(); | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void NavigationPolygon::_set_polygons(const Array &p_array) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	navmesh_generation->lock(); | 
					
						
							|  |  |  | 	navmesh.unref(); | 
					
						
							|  |  |  | 	navmesh_generation->unlock(); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Array NavigationPolygon::_get_polygons() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Array ret; | 
					
						
							|  |  |  | 	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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void NavigationPolygon::_set_outlines(const Array &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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Array NavigationPolygon::_get_outlines() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Array ret; | 
					
						
							|  |  |  | 	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-01-10 12:22:34 +01:00
										 |  |  | 	navmesh_generation->lock(); | 
					
						
							|  |  |  | 	navmesh.unref(); | 
					
						
							|  |  |  | 	navmesh_generation->unlock(); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Vector<int> NavigationPolygon::get_polygon(int p_idx) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	return polygons[p_idx].indices; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void NavigationPolygon::clear_polygons() { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	polygons.clear(); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	navmesh_generation->lock(); | 
					
						
							|  |  |  | 	navmesh.unref(); | 
					
						
							|  |  |  | 	navmesh_generation->unlock(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ref<NavigationMesh> NavigationPolygon::get_mesh() { | 
					
						
							|  |  |  | 	navmesh_generation->lock(); | 
					
						
							|  |  |  | 	if (navmesh.is_null()) { | 
					
						
							|  |  |  | 		navmesh.instance(); | 
					
						
							| 
									
										
										
										
											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)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	navmesh_generation->unlock(); | 
					
						
							|  |  |  | 	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()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	outlines.remove(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() { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void NavigationPolygon::make_polygons_from_outlines() { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	navmesh_generation->lock(); | 
					
						
							|  |  |  | 	navmesh.unref(); | 
					
						
							|  |  |  | 	navmesh_generation->unlock(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	List<TriangulatorPoly> 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++) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (olsize < 3) | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											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++) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (olsize < 3) | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											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++) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (i == k) | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 				continue; //no self intersect
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (olsize2 < 3) | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											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++) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				if (Geometry::segment_intersects_segment_2d(r[0], outside_point, r2[l], r2[(l + 1) % olsize2], NULL)) { | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  | 		TriangulatorPoly tp; | 
					
						
							|  |  |  | 		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
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (outer) | 
					
						
							|  |  |  | 			tp.SetOrientation(TRIANGULATOR_CCW); | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			tp.SetOrientation(TRIANGULATOR_CW); | 
					
						
							|  |  |  | 			tp.SetHole(true); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		in_poly.push_back(tp); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	TriangulatorPartition 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(); | 
					
						
							|  |  |  | 	vertices.resize(0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Map<Vector2, int> points; | 
					
						
							|  |  |  | 	for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		TriangulatorPoly &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++) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices"); | 
					
						
							| 
									
										
										
										
											2018-01-12 00:35:12 +02:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_polygons", "_get_polygons"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_outlines", "_get_outlines"); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | NavigationPolygon::NavigationPolygon() : | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		rect_cache_dirty(true), | 
					
						
							| 
									
										
										
										
											2020-02-14 10:35:09 +08:00
										 |  |  | 		navmesh_generation(Mutex::create()) { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NavigationPolygon::~NavigationPolygon() { | 
					
						
							|  |  |  | 	memdelete(navmesh_generation); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NavigationPolygonInstance::set_enabled(bool p_enabled) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (enabled == p_enabled) | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	enabled = p_enabled; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!is_inside_tree()) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!enabled) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		Navigation2DServer::get_singleton()->region_set_map(region, RID()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (navigation) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 			Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-19 01:02:56 +02:00
										 |  |  | 	if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 		update(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool NavigationPolygonInstance::is_enabled() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return enabled; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2019-10-21 23:37:07 +02:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-12-27 09:28:02 +01:00
										 |  |  | Rect2 NavigationPolygonInstance::_edit_get_rect() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool NavigationPolygonInstance::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | void NavigationPolygonInstance::_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: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			Node2D *c = this; | 
					
						
							|  |  |  | 			while (c) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 				navigation = Object::cast_to<Navigation2D>(c); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 				if (navigation) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 					if (enabled) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 						Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-20 16:55:47 +03:00
										 |  |  | 				c = Object::cast_to<Node2D>(c->get_parent()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case NOTIFICATION_TRANSFORM_CHANGED: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 			Navigation2DServer::get_singleton()->region_set_transform(region, get_global_transform()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case NOTIFICATION_EXIT_TREE: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (navigation) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 				Navigation2DServer::get_singleton()->region_set_map(region, RID()); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			navigation = NULL; | 
					
						
							| 
									
										
										
										
											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()) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 				Vector<Vector2> verts = navpoly->get_vertices(); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 				int vsize = verts.size(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				if (vsize < 3) | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 					return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				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
										 |  |  | 				} | 
					
						
							|  |  |  | 				Vector<Color> colors; | 
					
						
							|  |  |  | 				Vector<Vector2> vertices; | 
					
						
							|  |  |  | 				vertices.resize(vsize); | 
					
						
							|  |  |  | 				colors.resize(vsize); | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 					const Vector2 *vr = verts.ptr(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					for (int i = 0; i < vsize; i++) { | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 						vertices.write[i] = vr[i]; | 
					
						
							|  |  |  | 						colors.write[i] = color; | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				Vector<int> indices; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				for (int i = 0; i < navpoly->get_polygon_count(); i++) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 					Vector<int> polygon = navpoly->get_polygon(i); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					for (int j = 2; j < polygon.size(); j++) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						int kofs[3] = { 0, j - 1, j }; | 
					
						
							|  |  |  | 						for (int k = 0; k < 3; k++) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 							int idx = polygon[kofs[k]]; | 
					
						
							|  |  |  | 							ERR_FAIL_INDEX(idx, vsize); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 							indices.push_back(idx); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, vertices, colors); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-19 16:27:19 -03:00
										 |  |  | 		navpoly->disconnect_compat(CoreStringNames::get_singleton()->changed, this, "_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-01-10 12:22:34 +01:00
										 |  |  | 	Navigation2DServer::get_singleton()->region_set_navpoly(region, p_navpoly); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 	if (navpoly.is_valid()) { | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 		navpoly->connect_compat(CoreStringNames::get_singleton()->changed, this, "_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
										 |  |  | 
 | 
					
						
							|  |  |  | 	_change_notify("navpoly"); | 
					
						
							| 
									
										
										
										
											2016-05-17 18:27:15 -03:00
										 |  |  | 	update_configuration_warning(); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Ref<NavigationPolygon> NavigationPolygonInstance::get_navigation_polygon() const { | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return navpoly; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void NavigationPolygonInstance::_navpoly_changed() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-19 01:02:56 +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(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-17 18:27:15 -03:00
										 |  |  | String NavigationPolygonInstance::get_configuration_warning() const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-13 10:45:50 -03:00
										 |  |  | 	if (!is_visible_in_tree() || !is_inside_tree()) | 
					
						
							| 
									
										
										
										
											2016-05-17 18:27:15 -03:00
										 |  |  | 		return String(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!navpoly.is_valid()) { | 
					
						
							|  |  |  | 		return TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon."); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	const Node2D *c = this; | 
					
						
							|  |  |  | 	while (c) { | 
					
						
							| 
									
										
										
										
											2016-05-17 18:27:15 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 		if (Object::cast_to<Navigation2D>(c)) { | 
					
						
							| 
									
										
										
										
											2016-05-17 18:27:15 -03:00
										 |  |  | 			return String(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-26 13:02:04 +02:00
										 |  |  | 		c = Object::cast_to<Node2D>(c->get_parent()); | 
					
						
							| 
									
										
										
										
											2016-05-17 18:27:15 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return TTR("NavigationPolygonInstance must be a child or grandchild to a Navigation2D node. It only provides navigation data."); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | void NavigationPolygonInstance::_bind_methods() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-09 13:19:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navpoly"), &NavigationPolygonInstance::set_navigation_polygon); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationPolygonInstance::get_navigation_polygon); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationPolygonInstance::set_enabled); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationPolygonInstance::is_enabled); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationPolygonInstance::_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"); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NavigationPolygonInstance::NavigationPolygonInstance() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	enabled = true; | 
					
						
							| 
									
										
										
										
											2017-01-12 20:35:46 -03:00
										 |  |  | 	set_notify_transform(true); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	region = Navigation2DServer::get_singleton()->region_create(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	navigation = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NavigationPolygonInstance::~NavigationPolygonInstance() { | 
					
						
							|  |  |  | 	Navigation2DServer::get_singleton()->free(region); | 
					
						
							| 
									
										
										
										
											2015-02-14 12:09:52 -03:00
										 |  |  | } |