| 
									
										
										
										
											2023-01-05 13:25:55 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*  godot_navigation_server.cpp                                           */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*                         This file is part of:                          */ | 
					
						
							|  |  |  | /*                             GODOT ENGINE                               */ | 
					
						
							|  |  |  | /*                        https://godotengine.org                         */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* 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.                 */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | #include "godot_navigation_server.h"
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "core/os/mutex.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef _3D_DISABLED
 | 
					
						
							|  |  |  | #include "navigation_mesh_generator.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-05 17:24:45 -06:00
										 |  |  | using namespace NavigationUtilities; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | /// Creates a struct for each function and a function that once called creates
 | 
					
						
							| 
									
										
										
										
											2020-03-11 13:59:18 -04:00
										 |  |  | /// an instance of that struct with the submitted parameters.
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | /// Then, that struct is stored in an array; the `sync` function consume that array.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-07 13:23:40 +03:00
										 |  |  | #define COMMAND_1(F_NAME, T_0, D_0)                                 \
 | 
					
						
							|  |  |  | 	struct MERGE(F_NAME, _command) : public SetCommand {            \ | 
					
						
							|  |  |  | 		T_0 d_0;                                                    \ | 
					
						
							|  |  |  | 		MERGE(F_NAME, _command)                                     \ | 
					
						
							|  |  |  | 		(T_0 p_d_0) :                                               \ | 
					
						
							|  |  |  | 				d_0(p_d_0) {}                                       \ | 
					
						
							|  |  |  | 		virtual void exec(GodotNavigationServer *server) override { \ | 
					
						
							|  |  |  | 			server->MERGE(_cmd_, F_NAME)(d_0);                      \ | 
					
						
							|  |  |  | 		}                                                           \ | 
					
						
							|  |  |  | 	};                                                              \ | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 	void GodotNavigationServer::F_NAME(T_0 D_0) {                   \ | 
					
						
							| 
									
										
										
										
											2022-04-07 13:23:40 +03:00
										 |  |  | 		auto cmd = memnew(MERGE(F_NAME, _command)(                  \ | 
					
						
							|  |  |  | 				D_0));                                              \ | 
					
						
							|  |  |  | 		add_command(cmd);                                           \ | 
					
						
							|  |  |  | 	}                                                               \ | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | 	void GodotNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-07 13:23:40 +03:00
										 |  |  | #define COMMAND_2(F_NAME, T_0, D_0, T_1, D_1)                       \
 | 
					
						
							|  |  |  | 	struct MERGE(F_NAME, _command) : public SetCommand {            \ | 
					
						
							|  |  |  | 		T_0 d_0;                                                    \ | 
					
						
							|  |  |  | 		T_1 d_1;                                                    \ | 
					
						
							|  |  |  | 		MERGE(F_NAME, _command)                                     \ | 
					
						
							|  |  |  | 		(                                                           \ | 
					
						
							|  |  |  | 				T_0 p_d_0,                                          \ | 
					
						
							|  |  |  | 				T_1 p_d_1) :                                        \ | 
					
						
							|  |  |  | 				d_0(p_d_0),                                         \ | 
					
						
							|  |  |  | 				d_1(p_d_1) {}                                       \ | 
					
						
							|  |  |  | 		virtual void exec(GodotNavigationServer *server) override { \ | 
					
						
							|  |  |  | 			server->MERGE(_cmd_, F_NAME)(d_0, d_1);                 \ | 
					
						
							|  |  |  | 		}                                                           \ | 
					
						
							|  |  |  | 	};                                                              \ | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 	void GodotNavigationServer::F_NAME(T_0 D_0, T_1 D_1) {          \ | 
					
						
							| 
									
										
										
										
											2022-04-07 13:23:40 +03:00
										 |  |  | 		auto cmd = memnew(MERGE(F_NAME, _command)(                  \ | 
					
						
							|  |  |  | 				D_0,                                                \ | 
					
						
							|  |  |  | 				D_1));                                              \ | 
					
						
							|  |  |  | 		add_command(cmd);                                           \ | 
					
						
							|  |  |  | 	}                                                               \ | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | 	void GodotNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | #define COMMAND_4(F_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3)            \
 | 
					
						
							|  |  |  | 	struct MERGE(F_NAME, _command) : public SetCommand {                     \ | 
					
						
							|  |  |  | 		T_0 d_0;                                                             \ | 
					
						
							|  |  |  | 		T_1 d_1;                                                             \ | 
					
						
							|  |  |  | 		T_2 d_2;                                                             \ | 
					
						
							|  |  |  | 		T_3 d_3;                                                             \ | 
					
						
							|  |  |  | 		MERGE(F_NAME, _command)                                              \ | 
					
						
							|  |  |  | 		(                                                                    \ | 
					
						
							|  |  |  | 				T_0 p_d_0,                                                   \ | 
					
						
							|  |  |  | 				T_1 p_d_1,                                                   \ | 
					
						
							|  |  |  | 				T_2 p_d_2,                                                   \ | 
					
						
							|  |  |  | 				T_3 p_d_3) :                                                 \ | 
					
						
							|  |  |  | 				d_0(p_d_0),                                                  \ | 
					
						
							|  |  |  | 				d_1(p_d_1),                                                  \ | 
					
						
							|  |  |  | 				d_2(p_d_2),                                                  \ | 
					
						
							|  |  |  | 				d_3(p_d_3) {}                                                \ | 
					
						
							|  |  |  | 		virtual void exec(GodotNavigationServer *server) override {          \ | 
					
						
							|  |  |  | 			server->MERGE(_cmd_, F_NAME)(d_0, d_1, d_2, d_3);                \ | 
					
						
							|  |  |  | 		}                                                                    \ | 
					
						
							|  |  |  | 	};                                                                       \ | 
					
						
							|  |  |  | 	void GodotNavigationServer::F_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) { \ | 
					
						
							|  |  |  | 		auto cmd = memnew(MERGE(F_NAME, _command)(                           \ | 
					
						
							|  |  |  | 				D_0,                                                         \ | 
					
						
							|  |  |  | 				D_1,                                                         \ | 
					
						
							|  |  |  | 				D_2,                                                         \ | 
					
						
							|  |  |  | 				D_3));                                                       \ | 
					
						
							|  |  |  | 		add_command(cmd);                                                    \ | 
					
						
							|  |  |  | 	}                                                                        \ | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | 	void GodotNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 18:49:05 +02:00
										 |  |  | GodotNavigationServer::GodotNavigationServer() {} | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | GodotNavigationServer::~GodotNavigationServer() { | 
					
						
							| 
									
										
										
										
											2020-02-26 09:42:51 +01:00
										 |  |  | 	flush_queries(); | 
					
						
							| 
									
										
										
										
											2020-02-15 13:45:17 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | void GodotNavigationServer::add_command(SetCommand *command) { | 
					
						
							|  |  |  | 	MutexLock lock(commands_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	commands.push_back(command); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 20:35:08 +02:00
										 |  |  | TypedArray<RID> GodotNavigationServer::get_maps() const { | 
					
						
							|  |  |  | 	TypedArray<RID> all_map_rids; | 
					
						
							| 
									
										
										
										
											2022-06-22 15:33:40 +02:00
										 |  |  | 	List<RID> maps_owned; | 
					
						
							|  |  |  | 	map_owner.get_owned_list(&maps_owned); | 
					
						
							|  |  |  | 	if (maps_owned.size()) { | 
					
						
							|  |  |  | 		for (const RID &E : maps_owned) { | 
					
						
							|  |  |  | 			all_map_rids.push_back(E); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return all_map_rids; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | RID GodotNavigationServer::map_create() { | 
					
						
							|  |  |  | 	MutexLock lock(operations_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-29 10:58:28 -03:00
										 |  |  | 	RID rid = map_owner.make_rid(); | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 	NavMap *map = map_owner.get_or_null(rid); | 
					
						
							|  |  |  | 	map->set_self(rid); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	return rid; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(map_set_active, RID, p_map, bool, p_active) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(map == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (p_active) { | 
					
						
							|  |  |  | 		if (!map_is_active(p_map)) { | 
					
						
							|  |  |  | 			active_maps.push_back(map); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 			active_maps_update_id.push_back(map->get_map_update_id()); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 		int map_index = active_maps.find(map); | 
					
						
							|  |  |  | 		ERR_FAIL_COND(map_index < 0); | 
					
						
							| 
									
										
										
										
											2021-07-03 16:17:03 -06:00
										 |  |  | 		active_maps.remove_at(map_index); | 
					
						
							|  |  |  | 		active_maps_update_id.remove_at(map_index); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | bool GodotNavigationServer::map_is_active(RID p_map) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND_V(map == nullptr, false); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return active_maps.find(map) >= 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(map_set_up, RID, p_map, Vector3, p_up) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(map == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	map->set_up(p_up); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | Vector3 GodotNavigationServer::map_get_up(RID p_map) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND_V(map == nullptr, Vector3()); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return map->get_up(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(map_set_cell_size, RID, p_map, real_t, p_cell_size) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(map == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	map->set_cell_size(p_cell_size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | real_t GodotNavigationServer::map_get_cell_size(RID p_map) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND_V(map == nullptr, 0); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return map->get_cell_size(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(map == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	map->set_edge_connection_margin(p_connection_margin); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | real_t GodotNavigationServer::map_get_edge_connection_margin(RID p_map) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND_V(map == nullptr, 0); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return map->get_edge_connection_margin(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-30 15:39:52 -08:00
										 |  |  | COMMAND_2(map_set_link_connection_radius, RID, p_map, real_t, p_connection_radius) { | 
					
						
							|  |  |  | 	NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(map == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	map->set_link_connection_radius(p_connection_radius); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | real_t GodotNavigationServer::map_get_link_connection_radius(RID p_map) const { | 
					
						
							|  |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(map == nullptr, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return map->get_link_connection_radius(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 23:34:43 +02:00
										 |  |  | Vector<Vector3> GodotNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>()); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-05 17:24:45 -06:00
										 |  |  | 	return map->get_path(p_origin, p_destination, p_optimize, p_navigation_layers, nullptr, nullptr, nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | Vector3 GodotNavigationServer::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND_V(map == nullptr, Vector3()); | 
					
						
							| 
									
										
										
										
											2020-02-18 17:08:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return map->get_closest_point_to_segment(p_from, p_to, p_use_collision); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | Vector3 GodotNavigationServer::map_get_closest_point(RID p_map, const Vector3 &p_point) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND_V(map == nullptr, Vector3()); | 
					
						
							| 
									
										
										
										
											2020-02-18 17:08:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return map->get_closest_point(p_point); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | Vector3 GodotNavigationServer::map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND_V(map == nullptr, Vector3()); | 
					
						
							| 
									
										
										
										
											2020-02-18 17:08:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return map->get_closest_point_normal(p_point); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | RID GodotNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND_V(map == nullptr, RID()); | 
					
						
							| 
									
										
										
										
											2020-02-18 17:08:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return map->get_closest_point_owner(p_point); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-30 15:39:52 -08:00
										 |  |  | TypedArray<RID> GodotNavigationServer::map_get_links(RID p_map) const { | 
					
						
							|  |  |  | 	TypedArray<RID> link_rids; | 
					
						
							|  |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(map == nullptr, link_rids); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const LocalVector<NavLink *> links = map->get_links(); | 
					
						
							|  |  |  | 	link_rids.resize(links.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (uint32_t i = 0; i < links.size(); i++) { | 
					
						
							|  |  |  | 		link_rids[i] = links[i]->get_self(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return link_rids; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 20:35:08 +02:00
										 |  |  | TypedArray<RID> GodotNavigationServer::map_get_regions(RID p_map) const { | 
					
						
							|  |  |  | 	TypedArray<RID> regions_rids; | 
					
						
							| 
									
										
										
										
											2022-05-12 02:52:48 +02:00
										 |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(map == nullptr, regions_rids); | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-28 19:24:14 +02:00
										 |  |  | 	const LocalVector<NavRegion *> regions = map->get_regions(); | 
					
						
							|  |  |  | 	regions_rids.resize(regions.size()); | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-28 19:24:14 +02:00
										 |  |  | 	for (uint32_t i = 0; i < regions.size(); i++) { | 
					
						
							|  |  |  | 		regions_rids[i] = regions[i]->get_self(); | 
					
						
							| 
									
										
										
										
											2022-05-12 02:52:48 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return regions_rids; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 20:35:08 +02:00
										 |  |  | TypedArray<RID> GodotNavigationServer::map_get_agents(RID p_map) const { | 
					
						
							|  |  |  | 	TypedArray<RID> agents_rids; | 
					
						
							| 
									
										
										
										
											2022-05-12 02:52:48 +02:00
										 |  |  | 	const NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(map == nullptr, agents_rids); | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-28 19:24:14 +02:00
										 |  |  | 	const LocalVector<RvoAgent *> agents = map->get_agents(); | 
					
						
							|  |  |  | 	agents_rids.resize(agents.size()); | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-28 19:24:14 +02:00
										 |  |  | 	for (uint32_t i = 0; i < agents.size(); i++) { | 
					
						
							|  |  |  | 		agents_rids[i] = agents[i]->get_self(); | 
					
						
							| 
									
										
										
										
											2022-05-12 02:52:48 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return agents_rids; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RID GodotNavigationServer::region_get_map(RID p_region) const { | 
					
						
							|  |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(region == nullptr, RID()); | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-17 20:08:39 +02:00
										 |  |  | 	if (region->get_map()) { | 
					
						
							|  |  |  | 		return region->get_map()->get_self(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return RID(); | 
					
						
							| 
									
										
										
										
											2022-05-12 02:52:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RID GodotNavigationServer::agent_get_map(RID p_agent) const { | 
					
						
							|  |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(agent == nullptr, RID()); | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-17 20:08:39 +02:00
										 |  |  | 	if (agent->get_map()) { | 
					
						
							|  |  |  | 		return agent->get_map()->get_self(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return RID(); | 
					
						
							| 
									
										
										
										
											2022-05-12 02:52:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | RID GodotNavigationServer::region_create() { | 
					
						
							|  |  |  | 	MutexLock lock(operations_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-29 10:58:28 -03:00
										 |  |  | 	RID rid = region_owner.make_rid(); | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavRegion *reg = region_owner.get_or_null(rid); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	reg->set_self(rid); | 
					
						
							|  |  |  | 	return rid; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(region_set_map, RID, p_region, RID, p_map) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(region == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	if (region->get_map() != nullptr) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (region->get_map()->get_self() == p_map) { | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 			return; // Pointless
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		region->get_map()->remove_region(region); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		region->set_map(nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_map.is_valid()) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 		NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		ERR_FAIL_COND(map == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		map->add_region(region); | 
					
						
							|  |  |  | 		region->set_map(map); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 01:08:21 -04:00
										 |  |  | COMMAND_2(region_set_transform, RID, p_region, Transform3D, p_transform) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(region == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	region->set_transform(p_transform); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 05:24:11 +02:00
										 |  |  | COMMAND_2(region_set_enter_cost, RID, p_region, real_t, p_enter_cost) { | 
					
						
							|  |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(region == nullptr); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(p_enter_cost < 0.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	region->set_enter_cost(p_enter_cost); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | real_t GodotNavigationServer::region_get_enter_cost(RID p_region) const { | 
					
						
							|  |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(region == nullptr, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return region->get_enter_cost(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(region_set_travel_cost, RID, p_region, real_t, p_travel_cost) { | 
					
						
							|  |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(region == nullptr); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(p_travel_cost < 0.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	region->set_travel_cost(p_travel_cost); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | real_t GodotNavigationServer::region_get_travel_cost(RID p_region) const { | 
					
						
							|  |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(region == nullptr, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return region->get_travel_cost(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-30 23:49:39 -06:00
										 |  |  | COMMAND_2(region_set_owner_id, RID, p_region, ObjectID, p_owner_id) { | 
					
						
							|  |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(region == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	region->set_owner_id(p_owner_id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ObjectID GodotNavigationServer::region_get_owner_id(RID p_region) const { | 
					
						
							|  |  |  | 	const NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(region == nullptr, ObjectID()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return region->get_owner_id(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-23 19:16:47 +02:00
										 |  |  | bool GodotNavigationServer::region_owns_point(RID p_region, const Vector3 &p_point) const { | 
					
						
							|  |  |  | 	const NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(region == nullptr, false); | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-23 19:16:47 +02:00
										 |  |  | 	if (region->get_map()) { | 
					
						
							|  |  |  | 		RID closest_point_owner = map_get_closest_point_owner(region->get_map()->get_self(), p_point); | 
					
						
							|  |  |  | 		return closest_point_owner == region->get_self(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 23:34:43 +02:00
										 |  |  | COMMAND_2(region_set_navigation_layers, RID, p_region, uint32_t, p_navigation_layers) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							| 
									
										
										
										
											2021-03-08 20:56:33 +01:00
										 |  |  | 	ERR_FAIL_COND(region == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 23:34:43 +02:00
										 |  |  | 	region->set_navigation_layers(p_navigation_layers); | 
					
						
							| 
									
										
										
										
											2021-03-08 20:56:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 23:34:43 +02:00
										 |  |  | uint32_t GodotNavigationServer::region_get_navigation_layers(RID p_region) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							| 
									
										
										
										
											2021-03-08 20:56:33 +01:00
										 |  |  | 	ERR_FAIL_COND_V(region == nullptr, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 23:34:43 +02:00
										 |  |  | 	return region->get_navigation_layers(); | 
					
						
							| 
									
										
										
										
											2021-03-08 20:56:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 18:02:35 +01:00
										 |  |  | COMMAND_2(region_set_navigation_mesh, RID, p_region, Ref<NavigationMesh>, p_navigation_mesh) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(region == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 18:02:35 +01:00
										 |  |  | 	region->set_mesh(p_navigation_mesh); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | void GodotNavigationServer::region_bake_navigation_mesh(Ref<NavigationMesh> p_navigation_mesh, Node *p_root_node) { | 
					
						
							| 
									
										
										
										
											2022-12-11 18:02:35 +01:00
										 |  |  | 	ERR_FAIL_COND(p_navigation_mesh.is_null()); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(p_root_node == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifndef _3D_DISABLED
 | 
					
						
							| 
									
										
										
										
											2022-12-11 18:02:35 +01:00
										 |  |  | 	NavigationMeshGenerator::get_singleton()->clear(p_navigation_mesh); | 
					
						
							|  |  |  | 	NavigationMeshGenerator::get_singleton()->bake(p_navigation_mesh, p_root_node); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | int GodotNavigationServer::region_get_connections_count(RID p_region) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 	ERR_FAIL_COND_V(!region, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return region->get_connections_count(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | Vector3 GodotNavigationServer::region_get_connection_pathway_start(RID p_region, int p_connection_id) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 	ERR_FAIL_COND_V(!region, Vector3()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return region->get_connection_pathway_start(p_connection_id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | Vector3 GodotNavigationServer::region_get_connection_pathway_end(RID p_region, int p_connection_id) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	NavRegion *region = region_owner.get_or_null(p_region); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 	ERR_FAIL_COND_V(!region, Vector3()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return region->get_connection_pathway_end(p_connection_id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | RID GodotNavigationServer::link_create() { | 
					
						
							|  |  |  | 	MutexLock lock(operations_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-30 15:39:52 -08:00
										 |  |  | 	RID rid = link_owner.make_rid(); | 
					
						
							|  |  |  | 	NavLink *link = link_owner.get_or_null(rid); | 
					
						
							|  |  |  | 	link->set_self(rid); | 
					
						
							|  |  |  | 	return rid; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(link_set_map, RID, p_link, RID, p_map) { | 
					
						
							|  |  |  | 	NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(link == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (link->get_map() != nullptr) { | 
					
						
							|  |  |  | 		if (link->get_map()->get_self() == p_map) { | 
					
						
							|  |  |  | 			return; // Pointless
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		link->get_map()->remove_link(link); | 
					
						
							|  |  |  | 		link->set_map(nullptr); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_map.is_valid()) { | 
					
						
							|  |  |  | 		NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							|  |  |  | 		ERR_FAIL_COND(map == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		map->add_link(link); | 
					
						
							|  |  |  | 		link->set_map(map); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RID GodotNavigationServer::link_get_map(const RID p_link) const { | 
					
						
							|  |  |  | 	const NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(link == nullptr, RID()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (link->get_map()) { | 
					
						
							|  |  |  | 		return link->get_map()->get_self(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return RID(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional) { | 
					
						
							|  |  |  | 	NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(link == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link->set_bidirectional(p_bidirectional); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool GodotNavigationServer::link_is_bidirectional(RID p_link) const { | 
					
						
							|  |  |  | 	const NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(link == nullptr, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return link->is_bidirectional(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers) { | 
					
						
							|  |  |  | 	NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(link == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link->set_navigation_layers(p_navigation_layers); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint32_t GodotNavigationServer::link_get_navigation_layers(const RID p_link) const { | 
					
						
							|  |  |  | 	const NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(link == nullptr, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return link->get_navigation_layers(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(link_set_start_location, RID, p_link, Vector3, p_location) { | 
					
						
							|  |  |  | 	NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(link == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link->set_start_location(p_location); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Vector3 GodotNavigationServer::link_get_start_location(RID p_link) const { | 
					
						
							|  |  |  | 	const NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(link == nullptr, Vector3()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return link->get_start_location(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(link_set_end_location, RID, p_link, Vector3, p_location) { | 
					
						
							|  |  |  | 	NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(link == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link->set_end_location(p_location); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Vector3 GodotNavigationServer::link_get_end_location(RID p_link) const { | 
					
						
							|  |  |  | 	const NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(link == nullptr, Vector3()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return link->get_end_location(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(link_set_enter_cost, RID, p_link, real_t, p_enter_cost) { | 
					
						
							|  |  |  | 	NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(link == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link->set_enter_cost(p_enter_cost); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | real_t GodotNavigationServer::link_get_enter_cost(const RID p_link) const { | 
					
						
							|  |  |  | 	const NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(link == nullptr, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return link->get_enter_cost(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(link_set_travel_cost, RID, p_link, real_t, p_travel_cost) { | 
					
						
							|  |  |  | 	NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(link == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link->set_travel_cost(p_travel_cost); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | real_t GodotNavigationServer::link_get_travel_cost(const RID p_link) const { | 
					
						
							|  |  |  | 	const NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(link == nullptr, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return link->get_travel_cost(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-30 23:49:39 -06:00
										 |  |  | COMMAND_2(link_set_owner_id, RID, p_link, ObjectID, p_owner_id) { | 
					
						
							|  |  |  | 	NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(link == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link->set_owner_id(p_owner_id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ObjectID GodotNavigationServer::link_get_owner_id(RID p_link) const { | 
					
						
							|  |  |  | 	const NavLink *link = link_owner.get_or_null(p_link); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(link == nullptr, ObjectID()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return link->get_owner_id(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | RID GodotNavigationServer::agent_create() { | 
					
						
							|  |  |  | 	MutexLock lock(operations_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-29 10:58:28 -03:00
										 |  |  | 	RID rid = agent_owner.make_rid(); | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(rid); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	agent->set_self(rid); | 
					
						
							|  |  |  | 	return rid; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (agent->get_map()) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (agent->get_map()->get_self() == p_map) { | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 			return; // Pointless
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		agent->get_map()->remove_agent(agent); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	agent->set_map(nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (p_map.is_valid()) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 		NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		ERR_FAIL_COND(map == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		agent->set_map(map); | 
					
						
							|  |  |  | 		map->add_agent(agent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (agent->has_callback()) { | 
					
						
							|  |  |  | 			map->set_agent_as_controlled(agent); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-13 12:26:13 +02:00
										 |  |  | COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_distance) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-13 12:26:13 +02:00
										 |  |  | 	agent->get_agent()->neighborDist_ = p_distance; | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	agent->get_agent()->maxNeighbors_ = p_count; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	agent->get_agent()->timeHorizon_ = p_time; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	agent->get_agent()->radius_ = p_radius; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	agent->get_agent()->maxSpeed_ = p_max_speed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	agent->get_agent()->velocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(agent_set_target_velocity, RID, p_agent, Vector3, p_velocity) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	agent->get_agent()->prefVelocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	agent->get_agent()->position_ = RVO::Vector3(p_position.x, p_position.y, p_position.z); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	agent->get_agent()->ignore_y_ = p_ignore; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | bool GodotNavigationServer::agent_is_map_changed(RID p_agent) const { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND_V(agent == nullptr, false); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return agent->is_map_changed(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-05 23:05:56 +01:00
										 |  |  | COMMAND_4(agent_set_callback, RID, p_agent, ObjectID, p_object_id, StringName, p_method, Variant, p_udata) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 	RvoAgent *agent = agent_owner.get_or_null(p_agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(agent == nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-05 23:05:56 +01:00
										 |  |  | 	agent->set_callback(p_object_id, p_method, p_udata); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (agent->get_map()) { | 
					
						
							| 
									
										
										
										
											2022-12-05 23:05:56 +01:00
										 |  |  | 		if (p_object_id == ObjectID()) { | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 			agent->get_map()->remove_agent_as_controlled(agent); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			agent->get_map()->set_agent_as_controlled(agent); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND_1(free, RID, p_object) { | 
					
						
							|  |  |  | 	if (map_owner.owns(p_object)) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 		NavMap *map = map_owner.get_or_null(p_object); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Removes any assigned region
 | 
					
						
							| 
									
										
										
										
											2022-07-28 19:24:14 +02:00
										 |  |  | 		LocalVector<NavRegion *> regions = map->get_regions(); | 
					
						
							|  |  |  | 		for (uint32_t i = 0; i < regions.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 			map->remove_region(regions[i]); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 			regions[i]->set_map(nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-30 15:39:52 -08:00
										 |  |  | 		// Removes any assigned links
 | 
					
						
							|  |  |  | 		LocalVector<NavLink *> links = map->get_links(); | 
					
						
							|  |  |  | 		for (uint32_t i = 0; i < links.size(); i++) { | 
					
						
							|  |  |  | 			map->remove_link(links[i]); | 
					
						
							|  |  |  | 			links[i]->set_map(nullptr); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		// Remove any assigned agent
 | 
					
						
							| 
									
										
										
										
											2022-07-28 19:24:14 +02:00
										 |  |  | 		LocalVector<RvoAgent *> agents = map->get_agents(); | 
					
						
							|  |  |  | 		for (uint32_t i = 0; i < agents.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 			map->remove_agent(agents[i]); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 			agents[i]->set_map(nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 		int map_index = active_maps.find(map); | 
					
						
							| 
									
										
										
										
											2021-07-03 16:17:03 -06:00
										 |  |  | 		active_maps.remove_at(map_index); | 
					
						
							|  |  |  | 		active_maps_update_id.remove_at(map_index); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		map_owner.free(p_object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (region_owner.owns(p_object)) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 		NavRegion *region = region_owner.get_or_null(p_object); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Removes this region from the map if assigned
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		if (region->get_map() != nullptr) { | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 			region->get_map()->remove_region(region); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 			region->set_map(nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		region_owner.free(p_object); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-30 15:39:52 -08:00
										 |  |  | 	} else if (link_owner.owns(p_object)) { | 
					
						
							|  |  |  | 		NavLink *link = link_owner.get_or_null(p_object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Removes this link from the map if assigned
 | 
					
						
							|  |  |  | 		if (link->get_map() != nullptr) { | 
					
						
							|  |  |  | 			link->get_map()->remove_link(link); | 
					
						
							|  |  |  | 			link->set_map(nullptr); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		link_owner.free(p_object); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	} else if (agent_owner.owns(p_object)) { | 
					
						
							| 
									
										
										
										
											2021-09-29 19:08:41 +02:00
										 |  |  | 		RvoAgent *agent = agent_owner.get_or_null(p_object); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Removes this agent from the map if assigned
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		if (agent->get_map() != nullptr) { | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 			agent->get_map()->remove_agent(agent); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 			agent->set_map(nullptr); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		agent_owner.free(p_object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ERR_FAIL_COND("Invalid ID."); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | void GodotNavigationServer::set_active(bool p_active) { | 
					
						
							|  |  |  | 	MutexLock lock(operations_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	active = p_active; | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | void GodotNavigationServer::flush_queries() { | 
					
						
							| 
									
										
										
										
											2020-02-26 09:42:51 +01:00
										 |  |  | 	// In c++ we can't be sure that this is performed in the main thread
 | 
					
						
							|  |  |  | 	// even with mutable functions.
 | 
					
						
							| 
									
										
										
										
											2020-02-26 11:28:13 +01:00
										 |  |  | 	MutexLock lock(commands_mutex); | 
					
						
							|  |  |  | 	MutexLock lock2(operations_mutex); | 
					
						
							| 
									
										
										
										
											2022-12-21 14:21:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	for (size_t i(0); i < commands.size(); i++) { | 
					
						
							|  |  |  | 		commands[i]->exec(this); | 
					
						
							|  |  |  | 		memdelete(commands[i]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	commands.clear(); | 
					
						
							| 
									
										
										
										
											2020-02-26 09:42:51 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-22 10:16:38 +02:00
										 |  |  | void GodotNavigationServer::map_force_update(RID p_map) { | 
					
						
							|  |  |  | 	NavMap *map = map_owner.get_or_null(p_map); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(map == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	flush_queries(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	map->sync(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 00:16:35 +02:00
										 |  |  | void GodotNavigationServer::process(real_t p_delta_time) { | 
					
						
							| 
									
										
										
										
											2020-02-26 09:42:51 +01:00
										 |  |  | 	flush_queries(); | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-26 09:42:51 +01:00
										 |  |  | 	if (!active) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// In c++ we can't be sure that this is performed in the main thread
 | 
					
						
							|  |  |  | 	// even with mutable functions.
 | 
					
						
							| 
									
										
										
										
											2020-02-26 11:28:13 +01:00
										 |  |  | 	MutexLock lock(operations_mutex); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 	for (uint32_t i(0); i < active_maps.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 		active_maps[i]->sync(); | 
					
						
							|  |  |  | 		active_maps[i]->step(p_delta_time); | 
					
						
							|  |  |  | 		active_maps[i]->dispatch_callbacks(); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Emit a signal if a map changed.
 | 
					
						
							|  |  |  | 		const uint32_t new_map_update_id = active_maps[i]->get_map_update_id(); | 
					
						
							|  |  |  | 		if (new_map_update_id != active_maps_update_id[i]) { | 
					
						
							| 
									
										
										
										
											2021-07-17 18:22:52 -03:00
										 |  |  | 			emit_signal(SNAME("map_changed"), active_maps[i]->get_self()); | 
					
						
							| 
									
										
										
										
											2021-03-15 12:45:28 +01:00
										 |  |  | 			active_maps_update_id[i] = new_map_update_id; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-05 17:24:45 -06:00
										 |  |  | PathQueryResult GodotNavigationServer::_query_path(const PathQueryParameters &p_parameters) const { | 
					
						
							|  |  |  | 	PathQueryResult r_query_result; | 
					
						
							| 
									
										
										
										
											2022-06-26 12:43:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	const NavMap *map = map_owner.get_or_null(p_parameters.map); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(map == nullptr, r_query_result); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// run the pathfinding
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-05 17:24:45 -06:00
										 |  |  | 	if (p_parameters.pathfinding_algorithm == PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR) { | 
					
						
							| 
									
										
										
										
											2022-06-26 12:43:01 +02:00
										 |  |  | 		// while postprocessing is still part of map.get_path() need to check and route it here for the correct "optimize" post-processing
 | 
					
						
							| 
									
										
										
										
											2022-10-05 17:24:45 -06:00
										 |  |  | 		if (p_parameters.path_postprocessing == PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL) { | 
					
						
							|  |  |  | 			r_query_result.path = map->get_path( | 
					
						
							|  |  |  | 					p_parameters.start_position, | 
					
						
							|  |  |  | 					p_parameters.target_position, | 
					
						
							|  |  |  | 					true, | 
					
						
							|  |  |  | 					p_parameters.navigation_layers, | 
					
						
							|  |  |  | 					p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_TYPES) ? &r_query_result.path_types : nullptr, | 
					
						
							|  |  |  | 					p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_RIDS) ? &r_query_result.path_rids : nullptr, | 
					
						
							|  |  |  | 					p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_OWNERS) ? &r_query_result.path_owner_ids : nullptr); | 
					
						
							|  |  |  | 		} else if (p_parameters.path_postprocessing == PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED) { | 
					
						
							|  |  |  | 			r_query_result.path = map->get_path( | 
					
						
							|  |  |  | 					p_parameters.start_position, | 
					
						
							|  |  |  | 					p_parameters.target_position, | 
					
						
							|  |  |  | 					false, | 
					
						
							|  |  |  | 					p_parameters.navigation_layers, | 
					
						
							|  |  |  | 					p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_TYPES) ? &r_query_result.path_types : nullptr, | 
					
						
							|  |  |  | 					p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_RIDS) ? &r_query_result.path_rids : nullptr, | 
					
						
							|  |  |  | 					p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_OWNERS) ? &r_query_result.path_owner_ids : nullptr); | 
					
						
							| 
									
										
										
										
											2022-06-26 12:43:01 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return r_query_result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// add path postprocessing
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// add path stats
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return r_query_result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 12:22:34 +01:00
										 |  |  | #undef COMMAND_1
 | 
					
						
							|  |  |  | #undef COMMAND_2
 | 
					
						
							|  |  |  | #undef COMMAND_4
 |