mirror of
https://github.com/Relintai/pandemonium_engine_minimal.git
synced 2025-01-19 01:07:17 +01:00
Removed the navigation servers.
This commit is contained in:
parent
78b916e688
commit
cf46fb8237
107
main/main.cpp
107
main/main.cpp
@ -61,10 +61,6 @@
|
||||
#include "scene/register_scene_types.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "servers/audio_server.h"
|
||||
#include "servers/navigation/navigation_mesh_generator.h"
|
||||
#include "servers/navigation/navigation_mesh_generator_dummy.h"
|
||||
#include "servers/navigation_2d_server.h"
|
||||
#include "servers/navigation_server.h"
|
||||
#include "servers/physics_2d_server.h"
|
||||
#include "servers/register_server_types.h"
|
||||
|
||||
@ -110,10 +106,6 @@ static MessageQueue *message_queue = nullptr;
|
||||
// Initialized in setup2()
|
||||
static AudioServer *audio_server = nullptr;
|
||||
static Physics2DServer *physics_2d_server = nullptr;
|
||||
static NavigationMeshGeneratorManager *navigation_mesh_generator_manager = nullptr;
|
||||
static NavigationMeshGenerator *navigation_mesh_generator = nullptr;
|
||||
static NavigationServer *navigation_server = nullptr;
|
||||
static Navigation2DServer *navigation_2d_server = nullptr;
|
||||
|
||||
// We error out if setup2() doesn't turn this true
|
||||
static bool _start_success = false;
|
||||
@ -208,78 +200,6 @@ void finalize_physics() {
|
||||
memdelete(physics_2d_server);
|
||||
}
|
||||
|
||||
void initialize_navigation_mesh_generator() {
|
||||
ERR_FAIL_COND(navigation_mesh_generator != NULL);
|
||||
|
||||
// Init chosen NavigationMeshGenerator
|
||||
const String &server_name = GLOBAL_GET(NavigationMeshGeneratorManager::setting_property_name);
|
||||
navigation_mesh_generator = NavigationMeshGeneratorManager::get_singleton()->new_server(server_name);
|
||||
|
||||
// Fall back to default if not found
|
||||
if (!navigation_mesh_generator) {
|
||||
// Navigation server not found, so use the default.
|
||||
navigation_mesh_generator = NavigationMeshGeneratorManager::get_singleton()->new_default_server();
|
||||
}
|
||||
|
||||
// Fall back to dummy if no default server has been registered.
|
||||
if (!navigation_mesh_generator) {
|
||||
ERR_PRINT("No NavigationMeshGenerator implementation has been registered! Falling back to a dummy implementation: navigation mesh baking features will be unavailable.");
|
||||
navigation_mesh_generator = memnew(NavigationMeshGeneratorDummy);
|
||||
}
|
||||
|
||||
if (navigation_mesh_generator) {
|
||||
navigation_mesh_generator->init();
|
||||
|
||||
// need to register singleton earlier so modules / extensions / addons can use it on SCENE / SERVER init level
|
||||
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationMeshGenerator", NavigationMeshGenerator::get_singleton()));
|
||||
}
|
||||
|
||||
ERR_FAIL_NULL_MSG(navigation_mesh_generator, "Failed to initialize NavigationMeshGenerator.");
|
||||
}
|
||||
|
||||
void finalize_navigation_mesh_generator() {
|
||||
ERR_FAIL_COND(!navigation_mesh_generator);
|
||||
|
||||
navigation_mesh_generator->finish();
|
||||
|
||||
memdelete(navigation_mesh_generator);
|
||||
navigation_mesh_generator = nullptr;
|
||||
}
|
||||
|
||||
void initialize_navigation_server() {
|
||||
ERR_FAIL_COND(navigation_server != nullptr);
|
||||
ERR_FAIL_COND(navigation_2d_server != nullptr);
|
||||
|
||||
/// 3D Navigation Server
|
||||
navigation_server = NavigationServerManager::new_server(ProjectSettings::get_singleton()->get(NavigationServerManager::setting_property_name));
|
||||
if (!navigation_server) {
|
||||
// Navigation server not found, Use the default physics
|
||||
navigation_server = NavigationServerManager::new_default_server();
|
||||
}
|
||||
ERR_FAIL_COND(!navigation_server);
|
||||
navigation_server->init();
|
||||
|
||||
/// 2D Navigation server
|
||||
navigation_2d_server = Navigation2DServerManager::new_server(ProjectSettings::get_singleton()->get(Navigation2DServerManager::setting_property_name));
|
||||
if (!navigation_2d_server) {
|
||||
// Navigation server not found, Use the default physics
|
||||
navigation_2d_server = Navigation2DServerManager::new_default_server();
|
||||
}
|
||||
ERR_FAIL_COND(!navigation_2d_server);
|
||||
navigation_2d_server->init();
|
||||
}
|
||||
|
||||
void finalize_navigation_server() {
|
||||
navigation_2d_server->finish();
|
||||
navigation_server->finish();
|
||||
|
||||
memdelete(navigation_2d_server);
|
||||
navigation_2d_server = nullptr;
|
||||
|
||||
memdelete(navigation_server);
|
||||
navigation_server = nullptr;
|
||||
}
|
||||
|
||||
//#define DEBUG_INIT
|
||||
#ifdef DEBUG_INIT
|
||||
#define MAIN_PRINT(m_txt) print_line(m_txt)
|
||||
@ -455,8 +375,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
||||
|
||||
translation_server = memnew(TranslationServer);
|
||||
|
||||
navigation_mesh_generator_manager = memnew(NavigationMeshGeneratorManager);
|
||||
|
||||
performance = memnew(Performance);
|
||||
ClassDB::register_class<Performance>();
|
||||
engine->add_singleton(Engine::Singleton("Performance", performance));
|
||||
@ -1360,9 +1278,6 @@ error:
|
||||
if (translation_server) {
|
||||
memdelete(translation_server);
|
||||
}
|
||||
if (navigation_mesh_generator_manager) {
|
||||
memdelete(navigation_mesh_generator_manager);
|
||||
}
|
||||
if (globals) {
|
||||
memdelete(globals);
|
||||
}
|
||||
@ -1533,8 +1448,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
|
||||
register_module_types(ModuleRegistrationLevel::MODULE_REGISTRATION_LEVEL_SERVER);
|
||||
|
||||
initialize_physics();
|
||||
initialize_navigation_mesh_generator();
|
||||
initialize_navigation_server();
|
||||
|
||||
register_server_singletons();
|
||||
|
||||
@ -1833,20 +1746,9 @@ bool Main::start() {
|
||||
if (debug_collisions) {
|
||||
sml->set_debug_collisions_hint(true);
|
||||
}
|
||||
if (debug_navigation) {
|
||||
sml->set_debug_navigation_hint(true);
|
||||
NavigationServer::get_singleton()->set_debug_navigation_enabled(true);
|
||||
}
|
||||
if (debug_avoidance) {
|
||||
NavigationServer::get_singleton()->set_debug_avoidance_enabled(true);
|
||||
}
|
||||
if (debug_paths) {
|
||||
sml->set_debug_paths_hint(true);
|
||||
}
|
||||
if (debug_navigation || debug_avoidance) {
|
||||
NavigationServer::get_singleton()->set_active(true);
|
||||
NavigationServer::get_singleton()->set_debug_enabled(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
ResourceLoader::add_custom_loaders();
|
||||
@ -2273,8 +2175,6 @@ bool Main::iteration() {
|
||||
|
||||
uint64_t navigation_begin = OS::get_singleton()->get_ticks_usec();
|
||||
|
||||
NavigationServer::get_singleton()->process(frame_slice * time_scale);
|
||||
|
||||
navigation_process_ticks = MAX(navigation_process_ticks, OS::get_singleton()->get_ticks_usec() - navigation_begin); // keep the largest one for reference
|
||||
navigation_process_max = MAX(OS::get_singleton()->get_ticks_usec() - navigation_begin, navigation_process_max);
|
||||
|
||||
@ -2306,8 +2206,6 @@ bool Main::iteration() {
|
||||
|
||||
message_queue->flush();
|
||||
|
||||
NavigationMeshGenerator::get_singleton()->process();
|
||||
|
||||
RenderingServer::get_singleton()->sync(); //sync if still drawing from previous frames.
|
||||
|
||||
if (OS::get_singleton()->can_draw() && RenderingServer::get_singleton()->is_render_loop_enabled()) {
|
||||
@ -2488,8 +2386,6 @@ void Main::cleanup(bool p_force) {
|
||||
memdelete(audio_server);
|
||||
}
|
||||
|
||||
finalize_navigation_server();
|
||||
finalize_navigation_mesh_generator();
|
||||
OS::get_singleton()->finalize();
|
||||
finalize_physics();
|
||||
|
||||
@ -2511,9 +2407,6 @@ void Main::cleanup(bool p_force) {
|
||||
if (translation_server) {
|
||||
memdelete(translation_server);
|
||||
}
|
||||
if (navigation_mesh_generator_manager) {
|
||||
memdelete(navigation_mesh_generator_manager);
|
||||
}
|
||||
if (globals) {
|
||||
memdelete(globals);
|
||||
}
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "scene/main/node.h"
|
||||
#include "scene/main/scene_tree.h"
|
||||
#include "servers/audio_server.h"
|
||||
#include "servers/navigation_server.h"
|
||||
#include "servers/physics_2d_server.h"
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
@ -73,15 +72,6 @@ void Performance::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(PHYSICS_2D_COLLISION_PAIRS);
|
||||
BIND_ENUM_CONSTANT(PHYSICS_2D_ISLAND_COUNT);
|
||||
BIND_ENUM_CONSTANT(AUDIO_OUTPUT_LATENCY);
|
||||
BIND_ENUM_CONSTANT(NAVIGATION_ACTIVE_MAPS);
|
||||
BIND_ENUM_CONSTANT(NAVIGATION_REGION_COUNT);
|
||||
BIND_ENUM_CONSTANT(NAVIGATION_AGENT_COUNT);
|
||||
BIND_ENUM_CONSTANT(NAVIGATION_LINK_COUNT);
|
||||
BIND_ENUM_CONSTANT(NAVIGATION_POLYGON_COUNT);
|
||||
BIND_ENUM_CONSTANT(NAVIGATION_EDGE_COUNT);
|
||||
BIND_ENUM_CONSTANT(NAVIGATION_EDGE_MERGE_COUNT);
|
||||
BIND_ENUM_CONSTANT(NAVIGATION_EDGE_CONNECTION_COUNT);
|
||||
BIND_ENUM_CONSTANT(NAVIGATION_EDGE_FREE_COUNT);
|
||||
|
||||
BIND_ENUM_CONSTANT(MONITOR_MAX);
|
||||
}
|
||||
@ -128,16 +118,6 @@ String Performance::get_monitor_name(Monitor p_monitor) const {
|
||||
"physics_2d/collision_pairs",
|
||||
"physics_2d/islands",
|
||||
"audio/output_latency",
|
||||
"navigation/active_maps",
|
||||
"navigation/regions",
|
||||
"navigation/agents",
|
||||
"navigation/links",
|
||||
"navigation/polygons",
|
||||
"navigation/edges",
|
||||
"navigation/edges_merged",
|
||||
"navigation/edges_connected",
|
||||
"navigation/edges_free",
|
||||
|
||||
};
|
||||
|
||||
return names[p_monitor];
|
||||
@ -203,24 +183,6 @@ float Performance::get_monitor(Monitor p_monitor) const {
|
||||
return Physics2DServer::get_singleton()->get_process_info(Physics2DServer::INFO_ISLAND_COUNT);
|
||||
case AUDIO_OUTPUT_LATENCY:
|
||||
return AudioServer::get_singleton()->get_output_latency();
|
||||
case NAVIGATION_ACTIVE_MAPS:
|
||||
return NavigationServer::get_singleton()->get_process_info(NavigationServer::INFO_ACTIVE_MAPS);
|
||||
case NAVIGATION_REGION_COUNT:
|
||||
return NavigationServer::get_singleton()->get_process_info(NavigationServer::INFO_REGION_COUNT);
|
||||
case NAVIGATION_AGENT_COUNT:
|
||||
return NavigationServer::get_singleton()->get_process_info(NavigationServer::INFO_AGENT_COUNT);
|
||||
case NAVIGATION_LINK_COUNT:
|
||||
return NavigationServer::get_singleton()->get_process_info(NavigationServer::INFO_LINK_COUNT);
|
||||
case NAVIGATION_POLYGON_COUNT:
|
||||
return NavigationServer::get_singleton()->get_process_info(NavigationServer::INFO_POLYGON_COUNT);
|
||||
case NAVIGATION_EDGE_COUNT:
|
||||
return NavigationServer::get_singleton()->get_process_info(NavigationServer::INFO_EDGE_COUNT);
|
||||
case NAVIGATION_EDGE_MERGE_COUNT:
|
||||
return NavigationServer::get_singleton()->get_process_info(NavigationServer::INFO_EDGE_MERGE_COUNT);
|
||||
case NAVIGATION_EDGE_CONNECTION_COUNT:
|
||||
return NavigationServer::get_singleton()->get_process_info(NavigationServer::INFO_EDGE_CONNECTION_COUNT);
|
||||
case NAVIGATION_EDGE_FREE_COUNT:
|
||||
return NavigationServer::get_singleton()->get_process_info(NavigationServer::INFO_EDGE_FREE_COUNT);
|
||||
|
||||
default: {
|
||||
}
|
||||
@ -263,15 +225,6 @@ Performance::MonitorType Performance::get_monitor_type(Monitor p_monitor) const
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
MONITOR_TYPE_TIME,
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
MONITOR_TYPE_QUANTITY,
|
||||
};
|
||||
|
||||
return types[p_monitor];
|
||||
|
@ -79,15 +79,6 @@ public:
|
||||
PHYSICS_2D_COLLISION_PAIRS,
|
||||
PHYSICS_2D_ISLAND_COUNT,
|
||||
AUDIO_OUTPUT_LATENCY,
|
||||
NAVIGATION_ACTIVE_MAPS,
|
||||
NAVIGATION_REGION_COUNT,
|
||||
NAVIGATION_AGENT_COUNT,
|
||||
NAVIGATION_LINK_COUNT,
|
||||
NAVIGATION_POLYGON_COUNT,
|
||||
NAVIGATION_EDGE_COUNT,
|
||||
NAVIGATION_EDGE_MERGE_COUNT,
|
||||
NAVIGATION_EDGE_CONNECTION_COUNT,
|
||||
NAVIGATION_EDGE_FREE_COUNT,
|
||||
MONITOR_MAX
|
||||
};
|
||||
|
||||
|
@ -1,82 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import("env")
|
||||
Import("env_modules")
|
||||
|
||||
env_navigation = env_modules.Clone()
|
||||
|
||||
# Thirdparty source files
|
||||
|
||||
thirdparty_obj = []
|
||||
|
||||
# Recast
|
||||
if env["builtin_recast"]:
|
||||
thirdparty_dir = "#thirdparty/recastnavigation/Recast/"
|
||||
thirdparty_sources = [
|
||||
"Source/Recast.cpp",
|
||||
"Source/RecastAlloc.cpp",
|
||||
"Source/RecastArea.cpp",
|
||||
"Source/RecastAssert.cpp",
|
||||
"Source/RecastContour.cpp",
|
||||
"Source/RecastFilter.cpp",
|
||||
"Source/RecastLayers.cpp",
|
||||
"Source/RecastMesh.cpp",
|
||||
"Source/RecastMeshDetail.cpp",
|
||||
"Source/RecastRasterization.cpp",
|
||||
"Source/RecastRegion.cpp",
|
||||
]
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
env_navigation.Prepend(CPPPATH=[thirdparty_dir + "Include"])
|
||||
|
||||
env_thirdparty = env_navigation.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
|
||||
env.modules_sources += thirdparty_obj
|
||||
|
||||
# RVO 2D Thirdparty source files
|
||||
if env["builtin_rvo2_2d"]:
|
||||
thirdparty_dir = "#thirdparty/rvo2/rvo2_2d/"
|
||||
thirdparty_sources = [
|
||||
"Agent2d.cpp",
|
||||
"Obstacle2d.cpp",
|
||||
"KdTree2d.cpp",
|
||||
"RVOSimulator2d.cpp",
|
||||
]
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
env_navigation.Prepend(CPPPATH=[thirdparty_dir])
|
||||
|
||||
env_thirdparty = env_navigation.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
|
||||
#env.modules_sources += thirdparty_obj
|
||||
|
||||
# RVO 3D Thirdparty source files
|
||||
if env["builtin_rvo2_3d"]:
|
||||
thirdparty_dir = "#thirdparty/rvo2/rvo2_3d/"
|
||||
thirdparty_sources = [
|
||||
"Agent3d.cpp",
|
||||
"KdTree3d.cpp",
|
||||
"RVOSimulator3d.cpp",
|
||||
]
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
env_navigation.Prepend(CPPPATH=[thirdparty_dir])
|
||||
|
||||
env_thirdparty = env_navigation.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
|
||||
|
||||
env.modules_sources += thirdparty_obj
|
||||
|
||||
# Pandemonium source files
|
||||
|
||||
module_obj = []
|
||||
|
||||
env_navigation.add_source_files(module_obj, "*.cpp")
|
||||
|
||||
env.modules_sources += module_obj
|
||||
|
||||
# Needed to force rebuilding the module files when the thirdparty library is updated.
|
||||
env.Depends(module_obj, thirdparty_obj)
|
@ -1,6 +0,0 @@
|
||||
def can_build(env, platform):
|
||||
return True
|
||||
|
||||
|
||||
def configure(env):
|
||||
pass
|
@ -1,394 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* nav_agent.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "nav_agent.h"
|
||||
|
||||
#include "nav_map.h"
|
||||
|
||||
NavAgent::NavAgent() {
|
||||
height = 1.0;
|
||||
radius = 1.0;
|
||||
max_speed = 1.0;
|
||||
time_horizon_agents = 1.0;
|
||||
time_horizon_obstacles = 0.0;
|
||||
max_neighbors = 5;
|
||||
neighbor_distance = 5.0;
|
||||
clamp_speed = true; // Experimental, clamps velocity to max_speed.
|
||||
|
||||
map = nullptr;
|
||||
|
||||
use_3d_avoidance = false;
|
||||
avoidance_enabled = false;
|
||||
|
||||
avoidance_layers = 1;
|
||||
avoidance_mask = 1;
|
||||
avoidance_priority = 1.0;
|
||||
|
||||
avoidance_callback.id = ObjectID(0);
|
||||
agent_dirty = true;
|
||||
|
||||
map_update_id = 0;
|
||||
paused = false;
|
||||
}
|
||||
|
||||
void NavAgent::set_avoidance_enabled(bool p_enabled) {
|
||||
avoidance_enabled = p_enabled;
|
||||
_update_rvo_agent_properties();
|
||||
}
|
||||
|
||||
void NavAgent::set_use_3d_avoidance(bool p_enabled) {
|
||||
use_3d_avoidance = p_enabled;
|
||||
_update_rvo_agent_properties();
|
||||
}
|
||||
|
||||
void NavAgent::_update_rvo_agent_properties() {
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.neighborDist_ = neighbor_distance;
|
||||
rvo_agent_3d.maxNeighbors_ = max_neighbors;
|
||||
rvo_agent_3d.timeHorizon_ = time_horizon_agents;
|
||||
rvo_agent_3d.timeHorizonObst_ = time_horizon_obstacles;
|
||||
rvo_agent_3d.radius_ = radius;
|
||||
rvo_agent_3d.maxSpeed_ = max_speed;
|
||||
rvo_agent_3d.position_ = RVO3D::Vector3(position.x, position.y, position.z);
|
||||
// Replacing the internal velocity directly causes major jitter / bugs due to unpredictable velocity jumps, left line here for testing.
|
||||
//rvo_agent_3d.velocity_ = RVO3D::Vector3(velocity.x, velocity.y ,velocity.z);
|
||||
rvo_agent_3d.prefVelocity_ = RVO3D::Vector3(velocity.x, velocity.y, velocity.z);
|
||||
rvo_agent_3d.height_ = height;
|
||||
rvo_agent_3d.avoidance_layers_ = avoidance_layers;
|
||||
rvo_agent_3d.avoidance_mask_ = avoidance_mask;
|
||||
rvo_agent_3d.avoidance_priority_ = avoidance_priority;
|
||||
} else {
|
||||
rvo_agent_2d.neighborDist_ = neighbor_distance;
|
||||
rvo_agent_2d.maxNeighbors_ = max_neighbors;
|
||||
rvo_agent_2d.timeHorizon_ = time_horizon_agents;
|
||||
rvo_agent_2d.timeHorizonObst_ = time_horizon_obstacles;
|
||||
rvo_agent_2d.radius_ = radius;
|
||||
rvo_agent_2d.maxSpeed_ = max_speed;
|
||||
rvo_agent_2d.position_ = RVO2D::Vector2(position.x, position.z);
|
||||
rvo_agent_2d.elevation_ = position.y;
|
||||
// Replacing the internal velocity directly causes major jitter / bugs due to unpredictable velocity jumps, left line here for testing.
|
||||
//rvo_agent_2d.velocity_ = RVO2D::Vector2(velocity.x, velocity.z);
|
||||
rvo_agent_2d.prefVelocity_ = RVO2D::Vector2(velocity.x, velocity.z);
|
||||
rvo_agent_2d.height_ = height;
|
||||
rvo_agent_2d.avoidance_layers_ = avoidance_layers;
|
||||
rvo_agent_2d.avoidance_mask_ = avoidance_mask;
|
||||
rvo_agent_2d.avoidance_priority_ = avoidance_priority;
|
||||
}
|
||||
|
||||
if (map != nullptr) {
|
||||
if (avoidance_enabled) {
|
||||
map->set_agent_as_controlled(this);
|
||||
} else {
|
||||
map->remove_agent_as_controlled(this);
|
||||
}
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_map(NavMap *p_map) {
|
||||
map = p_map;
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
bool NavAgent::is_map_changed() {
|
||||
if (map) {
|
||||
bool is_changed = map->get_map_update_id() != map_update_id;
|
||||
map_update_id = map->get_map_update_id();
|
||||
return is_changed;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void NavAgent::set_neighbor_distance(real_t p_neighbor_distance) {
|
||||
neighbor_distance = p_neighbor_distance;
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.neighborDist_ = neighbor_distance;
|
||||
} else {
|
||||
rvo_agent_2d.neighborDist_ = neighbor_distance;
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_max_neighbors(int p_max_neighbors) {
|
||||
max_neighbors = p_max_neighbors;
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.maxNeighbors_ = max_neighbors;
|
||||
} else {
|
||||
rvo_agent_2d.maxNeighbors_ = max_neighbors;
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_time_horizon_agents(real_t p_time_horizon) {
|
||||
time_horizon_agents = p_time_horizon;
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.timeHorizon_ = time_horizon_agents;
|
||||
} else {
|
||||
rvo_agent_2d.timeHorizon_ = time_horizon_agents;
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_time_horizon_obstacles(real_t p_time_horizon) {
|
||||
time_horizon_obstacles = p_time_horizon;
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.timeHorizonObst_ = time_horizon_obstacles;
|
||||
} else {
|
||||
rvo_agent_2d.timeHorizonObst_ = time_horizon_obstacles;
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_radius(real_t p_radius) {
|
||||
radius = p_radius;
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.radius_ = radius;
|
||||
} else {
|
||||
rvo_agent_2d.radius_ = radius;
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_height(real_t p_height) {
|
||||
height = p_height;
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.height_ = height;
|
||||
} else {
|
||||
rvo_agent_2d.height_ = height;
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_max_speed(real_t p_max_speed) {
|
||||
max_speed = p_max_speed;
|
||||
if (avoidance_enabled) {
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.maxSpeed_ = max_speed;
|
||||
} else {
|
||||
rvo_agent_2d.maxSpeed_ = max_speed;
|
||||
}
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_position(const Vector3 p_position) {
|
||||
position = p_position;
|
||||
if (avoidance_enabled) {
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.position_ = RVO3D::Vector3(p_position.x, p_position.y, p_position.z);
|
||||
} else {
|
||||
rvo_agent_2d.elevation_ = p_position.y;
|
||||
rvo_agent_2d.position_ = RVO2D::Vector2(p_position.x, p_position.z);
|
||||
}
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_target_position(const Vector3 p_target_position) {
|
||||
target_position = p_target_position;
|
||||
}
|
||||
|
||||
void NavAgent::set_velocity(const Vector3 p_velocity) {
|
||||
// Sets the "wanted" velocity for an agent as a suggestion
|
||||
// This velocity is not guaranteed, RVO simulation will only try to fulfill it
|
||||
velocity = p_velocity;
|
||||
if (avoidance_enabled) {
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.prefVelocity_ = RVO3D::Vector3(velocity.x, velocity.y, velocity.z);
|
||||
} else {
|
||||
rvo_agent_2d.prefVelocity_ = RVO2D::Vector2(velocity.x, velocity.z);
|
||||
}
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_velocity_forced(const Vector3 p_velocity) {
|
||||
// This function replaces the internal rvo simulation velocity
|
||||
// should only be used after the agent was teleported
|
||||
// as it destroys consistency in movement in cramped situations
|
||||
// use velocity instead to update with a safer "suggestion"
|
||||
velocity_forced = p_velocity;
|
||||
if (avoidance_enabled) {
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.velocity_ = RVO3D::Vector3(p_velocity.x, p_velocity.y, p_velocity.z);
|
||||
} else {
|
||||
rvo_agent_2d.velocity_ = RVO2D::Vector2(p_velocity.x, p_velocity.z);
|
||||
}
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::update() {
|
||||
// Updates this agent with the calculated results from the rvo simulation
|
||||
if (avoidance_enabled) {
|
||||
if (use_3d_avoidance) {
|
||||
velocity = Vector3(rvo_agent_3d.velocity_.x(), rvo_agent_3d.velocity_.y(), rvo_agent_3d.velocity_.z());
|
||||
} else {
|
||||
velocity = Vector3(rvo_agent_2d.velocity_.x(), 0.0, rvo_agent_2d.velocity_.y());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavAgent::set_avoidance_mask(uint32_t p_mask) {
|
||||
avoidance_mask = p_mask;
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.avoidance_mask_ = avoidance_mask;
|
||||
} else {
|
||||
rvo_agent_2d.avoidance_mask_ = avoidance_mask;
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_avoidance_layers(uint32_t p_layers) {
|
||||
avoidance_layers = p_layers;
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.avoidance_layers_ = avoidance_layers;
|
||||
} else {
|
||||
rvo_agent_2d.avoidance_layers_ = avoidance_layers;
|
||||
}
|
||||
agent_dirty = true;
|
||||
}
|
||||
|
||||
void NavAgent::set_avoidance_priority(real_t p_priority) {
|
||||
ERR_FAIL_COND_MSG(p_priority < 0.0, "Avoidance priority must be between 0.0 and 1.0 inclusive.");
|
||||
ERR_FAIL_COND_MSG(p_priority > 1.0, "Avoidance priority must be between 0.0 and 1.0 inclusive.");
|
||||
avoidance_priority = p_priority;
|
||||
if (use_3d_avoidance) {
|
||||
rvo_agent_3d.avoidance_priority_ = avoidance_priority;
|
||||
} else {
|
||||
rvo_agent_2d.avoidance_priority_ = avoidance_priority;
|
||||
}
|
||||
agent_dirty = true;
|
||||
};
|
||||
|
||||
bool NavAgent::check_dirty() {
|
||||
const bool was_dirty = agent_dirty;
|
||||
agent_dirty = false;
|
||||
return was_dirty;
|
||||
}
|
||||
|
||||
const Dictionary NavAgent::get_avoidance_data() const {
|
||||
// Returns debug data from RVO simulation internals of this agent.
|
||||
Dictionary _avoidance_data;
|
||||
if (use_3d_avoidance) {
|
||||
_avoidance_data["max_neighbors"] = int(rvo_agent_3d.maxNeighbors_);
|
||||
_avoidance_data["max_speed"] = float(rvo_agent_3d.maxSpeed_);
|
||||
_avoidance_data["neighbor_distance"] = float(rvo_agent_3d.neighborDist_);
|
||||
_avoidance_data["new_velocity"] = Vector3(rvo_agent_3d.newVelocity_.x(), rvo_agent_3d.newVelocity_.y(), rvo_agent_3d.newVelocity_.z());
|
||||
_avoidance_data["velocity"] = Vector3(rvo_agent_3d.velocity_.x(), rvo_agent_3d.velocity_.y(), rvo_agent_3d.velocity_.z());
|
||||
_avoidance_data["position"] = Vector3(rvo_agent_3d.position_.x(), rvo_agent_3d.position_.y(), rvo_agent_3d.position_.z());
|
||||
_avoidance_data["prefered_velocity"] = Vector3(rvo_agent_3d.prefVelocity_.x(), rvo_agent_3d.prefVelocity_.y(), rvo_agent_3d.prefVelocity_.z());
|
||||
_avoidance_data["radius"] = float(rvo_agent_3d.radius_);
|
||||
_avoidance_data["time_horizon_agents"] = float(rvo_agent_3d.timeHorizon_);
|
||||
_avoidance_data["time_horizon_obstacles"] = 0.0;
|
||||
_avoidance_data["height"] = float(rvo_agent_3d.height_);
|
||||
_avoidance_data["avoidance_layers"] = int(rvo_agent_3d.avoidance_layers_);
|
||||
_avoidance_data["avoidance_mask"] = int(rvo_agent_3d.avoidance_mask_);
|
||||
_avoidance_data["avoidance_priority"] = float(rvo_agent_3d.avoidance_priority_);
|
||||
} else {
|
||||
_avoidance_data["max_neighbors"] = int(rvo_agent_2d.maxNeighbors_);
|
||||
_avoidance_data["max_speed"] = float(rvo_agent_2d.maxSpeed_);
|
||||
_avoidance_data["neighbor_distance"] = float(rvo_agent_2d.neighborDist_);
|
||||
_avoidance_data["new_velocity"] = Vector3(rvo_agent_2d.newVelocity_.x(), 0.0, rvo_agent_2d.newVelocity_.y());
|
||||
_avoidance_data["velocity"] = Vector3(rvo_agent_2d.velocity_.x(), 0.0, rvo_agent_2d.velocity_.y());
|
||||
_avoidance_data["position"] = Vector3(rvo_agent_2d.position_.x(), 0.0, rvo_agent_2d.position_.y());
|
||||
_avoidance_data["prefered_velocity"] = Vector3(rvo_agent_2d.prefVelocity_.x(), 0.0, rvo_agent_2d.prefVelocity_.y());
|
||||
_avoidance_data["radius"] = float(rvo_agent_2d.radius_);
|
||||
_avoidance_data["time_horizon_agents"] = float(rvo_agent_2d.timeHorizon_);
|
||||
_avoidance_data["time_horizon_obstacles"] = float(rvo_agent_2d.timeHorizonObst_);
|
||||
_avoidance_data["height"] = float(rvo_agent_2d.height_);
|
||||
_avoidance_data["avoidance_layers"] = int(rvo_agent_2d.avoidance_layers_);
|
||||
_avoidance_data["avoidance_mask"] = int(rvo_agent_2d.avoidance_mask_);
|
||||
_avoidance_data["avoidance_priority"] = float(rvo_agent_2d.avoidance_priority_);
|
||||
}
|
||||
return _avoidance_data;
|
||||
}
|
||||
|
||||
void NavAgent::set_paused(bool p_paused) {
|
||||
if (paused == p_paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
paused = p_paused;
|
||||
|
||||
if (map) {
|
||||
if (paused) {
|
||||
map->remove_agent_as_controlled(this);
|
||||
} else {
|
||||
map->set_agent_as_controlled(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool NavAgent::get_paused() const {
|
||||
return paused;
|
||||
}
|
||||
|
||||
void NavAgent::set_avoidance_callback(ObjectID p_id, const StringName p_method, const Variant p_udata) {
|
||||
avoidance_callback.id = p_id;
|
||||
avoidance_callback.method = p_method;
|
||||
avoidance_callback.udata = p_udata;
|
||||
}
|
||||
|
||||
bool NavAgent::has_avoidance_callback() const {
|
||||
return avoidance_callback.id != 0;
|
||||
}
|
||||
|
||||
void NavAgent::dispatch_avoidance_callback() {
|
||||
if (avoidance_callback.id == 0) {
|
||||
return;
|
||||
}
|
||||
Object *obj = ObjectDB::get_instance(avoidance_callback.id);
|
||||
if (!obj) {
|
||||
avoidance_callback.id = ObjectID(0);
|
||||
return;
|
||||
}
|
||||
|
||||
Variant::CallError responseCallError;
|
||||
|
||||
Vector3 new_velocity;
|
||||
|
||||
if (use_3d_avoidance) {
|
||||
new_velocity = Vector3(rvo_agent_3d.velocity_.x(), rvo_agent_3d.velocity_.y(), rvo_agent_3d.velocity_.z());
|
||||
} else {
|
||||
new_velocity = Vector3(rvo_agent_2d.velocity_.x(), 0.0, rvo_agent_2d.velocity_.y());
|
||||
}
|
||||
|
||||
if (clamp_speed) {
|
||||
new_velocity = new_velocity.limit_length(max_speed);
|
||||
}
|
||||
|
||||
avoidance_callback.new_velocity = new_velocity;
|
||||
|
||||
const Variant *vp[2] = { &avoidance_callback.new_velocity, &avoidance_callback.udata };
|
||||
int argc = (avoidance_callback.udata.get_type() == Variant::NIL) ? 1 : 2;
|
||||
obj->call(avoidance_callback.method, vp, argc, responseCallError);
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
|
||||
#ifndef NAV_AGENT_H
|
||||
#define NAV_AGENT_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* nav_agent.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "core/containers/local_vector.h"
|
||||
#include "core/object/class_db.h"
|
||||
#include "nav_agent.h"
|
||||
#include "nav_rid.h"
|
||||
|
||||
#include <Agent2d.h>
|
||||
#include <Agent3d.h>
|
||||
|
||||
class NavMap;
|
||||
|
||||
class NavAgent : public NavRid {
|
||||
struct AvoidanceComputedCallback {
|
||||
ObjectID id;
|
||||
StringName method;
|
||||
Variant udata;
|
||||
Variant new_velocity;
|
||||
};
|
||||
|
||||
Vector3 position;
|
||||
Vector3 target_position;
|
||||
Vector3 velocity;
|
||||
Vector3 velocity_forced;
|
||||
real_t height;
|
||||
real_t radius;
|
||||
real_t max_speed;
|
||||
real_t time_horizon_agents;
|
||||
real_t time_horizon_obstacles;
|
||||
int max_neighbors;
|
||||
real_t neighbor_distance;
|
||||
Vector3 safe_velocity;
|
||||
bool clamp_speed; // Experimental, clamps velocity to max_speed.
|
||||
|
||||
NavMap *map = nullptr;
|
||||
|
||||
RVO2D::Agent2D rvo_agent_2d;
|
||||
RVO3D::Agent3D rvo_agent_3d;
|
||||
bool use_3d_avoidance;
|
||||
bool avoidance_enabled;
|
||||
|
||||
uint32_t avoidance_layers;
|
||||
uint32_t avoidance_mask;
|
||||
real_t avoidance_priority;
|
||||
|
||||
AvoidanceComputedCallback avoidance_callback;
|
||||
|
||||
bool agent_dirty;
|
||||
|
||||
uint32_t map_update_id;
|
||||
bool paused;
|
||||
|
||||
public:
|
||||
NavAgent();
|
||||
|
||||
void set_avoidance_enabled(bool p_enabled);
|
||||
bool is_avoidance_enabled() { return avoidance_enabled; }
|
||||
|
||||
void set_use_3d_avoidance(bool p_enabled);
|
||||
bool get_use_3d_avoidance() { return use_3d_avoidance; }
|
||||
|
||||
void set_map(NavMap *p_map);
|
||||
NavMap *get_map() { return map; }
|
||||
|
||||
bool is_map_changed();
|
||||
|
||||
RVO2D::Agent2D *get_rvo_agent_2d() { return &rvo_agent_2d; }
|
||||
RVO3D::Agent3D *get_rvo_agent_3d() { return &rvo_agent_3d; }
|
||||
|
||||
void set_neighbor_distance(real_t p_neighbor_distance);
|
||||
real_t get_neighbor_distance() const { return neighbor_distance; }
|
||||
|
||||
void set_max_neighbors(int p_max_neighbors);
|
||||
int get_max_neighbors() const { return max_neighbors; }
|
||||
|
||||
void set_time_horizon_agents(real_t p_time_horizon);
|
||||
real_t get_time_horizon_agents() const { return time_horizon_agents; }
|
||||
|
||||
void set_time_horizon_obstacles(real_t p_time_horizon);
|
||||
real_t get_time_horizon_obstacles() const { return time_horizon_obstacles; }
|
||||
|
||||
void set_radius(real_t p_radius);
|
||||
real_t get_radius() const { return radius; }
|
||||
|
||||
void set_height(real_t p_height);
|
||||
real_t get_height() const { return height; }
|
||||
|
||||
void set_max_speed(real_t p_max_speed);
|
||||
real_t get_max_speed() const { return max_speed; }
|
||||
|
||||
void set_position(const Vector3 p_position);
|
||||
const Vector3 &get_position() const { return position; }
|
||||
|
||||
void set_target_position(const Vector3 p_target_position);
|
||||
const Vector3 &get_target_position() const { return target_position; }
|
||||
|
||||
void set_velocity(const Vector3 p_velocity);
|
||||
const Vector3 &get_velocity() const { return velocity; }
|
||||
|
||||
void set_velocity_forced(const Vector3 p_velocity);
|
||||
const Vector3 &get_velocity_forced() const { return velocity_forced; }
|
||||
|
||||
void set_avoidance_layers(uint32_t p_layers);
|
||||
uint32_t get_avoidance_layers() const { return avoidance_layers; };
|
||||
|
||||
void set_avoidance_mask(uint32_t p_mask);
|
||||
uint32_t get_avoidance_mask() const { return avoidance_mask; };
|
||||
|
||||
void set_avoidance_priority(real_t p_priority);
|
||||
real_t get_avoidance_priority() const { return avoidance_priority; };
|
||||
|
||||
void set_paused(bool p_paused);
|
||||
bool get_paused() const;
|
||||
|
||||
bool check_dirty();
|
||||
|
||||
// Updates this agent with rvo data after the rvo simulation avoidance step.
|
||||
void update();
|
||||
|
||||
// RVO debug data from the last frame update.
|
||||
const Dictionary get_avoidance_data() const;
|
||||
|
||||
void set_avoidance_callback(ObjectID p_id, const StringName p_method, const Variant p_udata = Variant());
|
||||
bool has_avoidance_callback() const;
|
||||
|
||||
void dispatch_avoidance_callback();
|
||||
|
||||
private:
|
||||
void _update_rvo_agent_properties();
|
||||
};
|
||||
|
||||
#endif // NAV_AGENT_H
|
@ -1,75 +0,0 @@
|
||||
|
||||
#ifndef NAV_BASE_H
|
||||
#define NAV_BASE_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* nav_base.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "nav_rid.h"
|
||||
#include "nav_utils.h"
|
||||
#include "servers/navigation/navigation_utilities.h"
|
||||
|
||||
class NavMap;
|
||||
|
||||
class NavBase : public NavRid {
|
||||
protected:
|
||||
uint32_t navigation_layers;
|
||||
real_t enter_cost;
|
||||
real_t travel_cost;
|
||||
ObjectID owner_id;
|
||||
NavigationUtilities::PathSegmentType type;
|
||||
|
||||
public:
|
||||
NavigationUtilities::PathSegmentType get_type() const { return type; }
|
||||
|
||||
virtual void set_use_edge_connections(bool p_enabled) {}
|
||||
virtual bool get_use_edge_connections() const { return false; }
|
||||
|
||||
void set_navigation_layers(uint32_t p_navigation_layers) { navigation_layers = p_navigation_layers; }
|
||||
uint32_t get_navigation_layers() const { return navigation_layers; }
|
||||
|
||||
void set_enter_cost(real_t p_enter_cost) { enter_cost = MAX(p_enter_cost, 0.0); }
|
||||
real_t get_enter_cost() const { return enter_cost; }
|
||||
|
||||
void set_travel_cost(real_t p_travel_cost) { travel_cost = MAX(p_travel_cost, 0.0); }
|
||||
real_t get_travel_cost() const { return travel_cost; }
|
||||
|
||||
void set_owner_id(ObjectID p_owner_id) { owner_id = p_owner_id; }
|
||||
ObjectID get_owner_id() const { return owner_id; }
|
||||
|
||||
NavBase() {
|
||||
navigation_layers = 1;
|
||||
enter_cost = 0.0;
|
||||
travel_cost = 1.0;
|
||||
};
|
||||
virtual ~NavBase(){};
|
||||
};
|
||||
|
||||
#endif // NAV_BASE_H
|
@ -1,82 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* nav_link.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "nav_link.h"
|
||||
|
||||
#include "nav_map.h"
|
||||
|
||||
void NavLink::set_map(NavMap *p_map) {
|
||||
if (map == p_map) {
|
||||
return;
|
||||
}
|
||||
map = p_map;
|
||||
link_dirty = true;
|
||||
}
|
||||
|
||||
void NavLink::set_enabled(bool p_enabled) {
|
||||
if (enabled == p_enabled) {
|
||||
return;
|
||||
}
|
||||
enabled = p_enabled;
|
||||
|
||||
// TODO: This should not require a full rebuild as the link has not really changed.
|
||||
link_dirty = true;
|
||||
};
|
||||
|
||||
void NavLink::set_bidirectional(bool p_bidirectional) {
|
||||
if (bidirectional == p_bidirectional) {
|
||||
return;
|
||||
}
|
||||
bidirectional = p_bidirectional;
|
||||
link_dirty = true;
|
||||
}
|
||||
|
||||
void NavLink::set_start_position(const Vector3 p_position) {
|
||||
if (start_position == p_position) {
|
||||
return;
|
||||
}
|
||||
start_position = p_position;
|
||||
link_dirty = true;
|
||||
}
|
||||
|
||||
void NavLink::set_end_position(const Vector3 p_position) {
|
||||
if (end_position == p_position) {
|
||||
return;
|
||||
}
|
||||
end_position = p_position;
|
||||
link_dirty = true;
|
||||
}
|
||||
|
||||
bool NavLink::check_dirty() {
|
||||
const bool was_dirty = link_dirty;
|
||||
|
||||
link_dirty = false;
|
||||
return was_dirty;
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
|
||||
#ifndef NAV_LINK_H
|
||||
#define NAV_LINK_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* nav_link.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "nav_base.h"
|
||||
#include "nav_utils.h"
|
||||
|
||||
class NavLink : public NavBase {
|
||||
NavMap *map;
|
||||
bool bidirectional;
|
||||
Vector3 start_position;
|
||||
Vector3 end_position;
|
||||
bool enabled;
|
||||
|
||||
bool link_dirty;
|
||||
|
||||
public:
|
||||
NavLink() {
|
||||
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_LINK;
|
||||
map = nullptr;
|
||||
bidirectional = true;
|
||||
enabled = true;
|
||||
link_dirty = true;
|
||||
}
|
||||
|
||||
void set_map(NavMap *p_map);
|
||||
NavMap *get_map() const {
|
||||
return map;
|
||||
}
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool get_enabled() const { return enabled; }
|
||||
|
||||
void set_bidirectional(bool p_bidirectional);
|
||||
bool is_bidirectional() const {
|
||||
return bidirectional;
|
||||
}
|
||||
|
||||
void set_start_position(Vector3 p_position);
|
||||
Vector3 get_start_position() const {
|
||||
return start_position;
|
||||
}
|
||||
|
||||
void set_end_position(Vector3 p_position);
|
||||
Vector3 get_end_position() const {
|
||||
return end_position;
|
||||
}
|
||||
|
||||
bool check_dirty();
|
||||
};
|
||||
|
||||
#endif // NAV_LINK_H
|
File diff suppressed because it is too large
Load Diff
@ -1,230 +0,0 @@
|
||||
#ifndef NAV_MAP_H
|
||||
#define NAV_MAP_H
|
||||
|
||||
/*************************************************************************/
|
||||
/* nav_map.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "nav_rid.h"
|
||||
|
||||
#include "core/containers/rb_map.h"
|
||||
#include "core/math/math_defs.h"
|
||||
#include "core/os/thread_work_pool.h"
|
||||
#include "nav_utils.h"
|
||||
|
||||
#include <KdTree2d.h>
|
||||
#include <RVOSimulator2d.h>
|
||||
|
||||
#include <KdTree3d.h>
|
||||
#include <RVOSimulator3d.h>
|
||||
|
||||
class NavLink;
|
||||
class NavRegion;
|
||||
class NavAgent;
|
||||
class NavRegion;
|
||||
class NavObstacle;
|
||||
|
||||
class NavMap : public NavRid {
|
||||
/// Map Up
|
||||
Vector3 up;
|
||||
|
||||
/// To find the polygons edges the vertices are displaced in a grid where
|
||||
/// each cell has the following cell_size and cell_height.
|
||||
real_t cell_size;
|
||||
real_t cell_height;
|
||||
|
||||
bool use_edge_connections;
|
||||
|
||||
/// This value is used to detect the near edges to connect.
|
||||
real_t edge_connection_margin;
|
||||
|
||||
/// This value is used to limit how far links search to find polygons to connect to.
|
||||
real_t link_connection_radius;
|
||||
|
||||
bool regenerate_polygons;
|
||||
bool regenerate_links;
|
||||
|
||||
/// Map regions
|
||||
LocalVector<NavRegion *> regions;
|
||||
|
||||
/// Map links
|
||||
LocalVector<NavLink *> links;
|
||||
LocalVector<gd::Polygon> link_polygons;
|
||||
|
||||
/// Map polygons
|
||||
LocalVector<gd::Polygon> polygons;
|
||||
|
||||
/// RVO avoidance worlds
|
||||
RVO2D::RVOSimulator2D rvo_simulation_2d;
|
||||
RVO3D::RVOSimulator3D rvo_simulation_3d;
|
||||
|
||||
/// avoidance controlled agents
|
||||
LocalVector<NavAgent *> active_2d_avoidance_agents;
|
||||
LocalVector<NavAgent *> active_3d_avoidance_agents;
|
||||
|
||||
/// dirty flag when one of the agent's arrays are modified
|
||||
bool agents_dirty = true;
|
||||
|
||||
/// All the Agents (even the controlled one)
|
||||
LocalVector<NavAgent *> agents;
|
||||
|
||||
/// All the avoidance obstacles (both static and dynamic)
|
||||
LocalVector<NavObstacle *> obstacles;
|
||||
|
||||
/// Are rvo obstacles modified?
|
||||
bool obstacles_dirty;
|
||||
|
||||
/// Physics delta time
|
||||
real_t deltatime;
|
||||
|
||||
/// Change the id each time the map is updated.
|
||||
uint32_t map_update_id;
|
||||
|
||||
bool use_threads;
|
||||
bool avoidance_use_multiple_threads;
|
||||
bool avoidance_use_high_priority_threads;
|
||||
|
||||
// Performance Monitor
|
||||
int pm_region_count;
|
||||
int pm_agent_count;
|
||||
int pm_link_count;
|
||||
int pm_polygon_count;
|
||||
int pm_edge_count;
|
||||
int pm_edge_merge_count;
|
||||
int pm_edge_connection_count;
|
||||
int pm_edge_free_count;
|
||||
|
||||
#ifndef NO_THREADS
|
||||
/// Pooled threads for computing steps
|
||||
ThreadWorkPool step_work_pool;
|
||||
#endif // NO_THREADS
|
||||
|
||||
public:
|
||||
NavMap();
|
||||
~NavMap();
|
||||
|
||||
void set_up(Vector3 p_up);
|
||||
Vector3 get_up() const {
|
||||
return up;
|
||||
}
|
||||
|
||||
void set_cell_size(real_t p_cell_size);
|
||||
real_t get_cell_size() const {
|
||||
return cell_size;
|
||||
}
|
||||
|
||||
void set_cell_height(real_t p_cell_height);
|
||||
real_t get_cell_height() const {
|
||||
return cell_height;
|
||||
}
|
||||
|
||||
void set_use_edge_connections(bool p_enabled);
|
||||
bool get_use_edge_connections() const {
|
||||
return use_edge_connections;
|
||||
}
|
||||
|
||||
void set_edge_connection_margin(real_t p_edge_connection_margin);
|
||||
real_t get_edge_connection_margin() const {
|
||||
return edge_connection_margin;
|
||||
}
|
||||
|
||||
void set_link_connection_radius(real_t p_link_connection_radius);
|
||||
real_t get_link_connection_radius() const {
|
||||
return link_connection_radius;
|
||||
}
|
||||
|
||||
gd::PointKey get_point_key(const Vector3 &p_pos) const;
|
||||
|
||||
Vector<Vector3> get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers, Vector<int32_t> *r_path_types, Array *r_path_rids, Vector<uint64_t> *r_path_owners) const;
|
||||
Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const;
|
||||
Vector3 get_closest_point(const Vector3 &p_point) const;
|
||||
Vector3 get_closest_point_normal(const Vector3 &p_point) const;
|
||||
gd::ClosestPointQueryResult get_closest_point_info(const Vector3 &p_point) const;
|
||||
RID get_closest_point_owner(const Vector3 &p_point) const;
|
||||
|
||||
void add_region(NavRegion *p_region);
|
||||
void remove_region(NavRegion *p_region);
|
||||
const LocalVector<NavRegion *> &get_regions() const {
|
||||
return regions;
|
||||
}
|
||||
|
||||
void add_link(NavLink *p_link);
|
||||
void remove_link(NavLink *p_link);
|
||||
const LocalVector<NavLink *> &get_links() const {
|
||||
return links;
|
||||
}
|
||||
|
||||
bool has_agent(NavAgent *agent) const;
|
||||
void add_agent(NavAgent *agent);
|
||||
void remove_agent(NavAgent *agent);
|
||||
const LocalVector<NavAgent *> &get_agents() const {
|
||||
return agents;
|
||||
}
|
||||
|
||||
void set_agent_as_controlled(NavAgent *agent);
|
||||
void remove_agent_as_controlled(NavAgent *agent);
|
||||
|
||||
bool has_obstacle(NavObstacle *obstacle) const;
|
||||
void add_obstacle(NavObstacle *obstacle);
|
||||
void remove_obstacle(NavObstacle *obstacle);
|
||||
const LocalVector<NavObstacle *> &get_obstacles() const {
|
||||
return obstacles;
|
||||
}
|
||||
|
||||
uint32_t get_map_update_id() const {
|
||||
return map_update_id;
|
||||
}
|
||||
|
||||
void sync();
|
||||
void step(real_t p_deltatime);
|
||||
void dispatch_callbacks();
|
||||
|
||||
// Performance Monitor
|
||||
int get_pm_region_count() const { return pm_region_count; }
|
||||
int get_pm_agent_count() const { return pm_agent_count; }
|
||||
int get_pm_link_count() const { return pm_link_count; }
|
||||
int get_pm_polygon_count() const { return pm_polygon_count; }
|
||||
int get_pm_edge_count() const { return pm_edge_count; }
|
||||
int get_pm_edge_merge_count() const { return pm_edge_merge_count; }
|
||||
int get_pm_edge_connection_count() const { return pm_edge_connection_count; }
|
||||
int get_pm_edge_free_count() const { return pm_edge_free_count; }
|
||||
|
||||
private:
|
||||
void compute_single_avoidance_step_2d(uint32_t index, NavAgent **agent);
|
||||
void compute_single_avoidance_step_3d(uint32_t index, NavAgent **agent);
|
||||
|
||||
void clip_path(const LocalVector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly, Vector<int32_t> *r_path_types, Array *r_path_rids, Vector<uint64_t> *r_path_owners) const;
|
||||
|
||||
void _update_rvo_simulation();
|
||||
void _update_rvo_obstacles_tree_2d();
|
||||
void _update_rvo_agents_tree_2d();
|
||||
void _update_rvo_agents_tree_3d();
|
||||
};
|
||||
|
||||
#endif // NAV_MAP_H
|
@ -1,225 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* nav_obstacle.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "nav_obstacle.h"
|
||||
|
||||
#include "nav_agent.h"
|
||||
#include "nav_map.h"
|
||||
|
||||
NavObstacle::NavObstacle() {
|
||||
agent = nullptr;
|
||||
map = nullptr;
|
||||
radius = 0.0;
|
||||
height = 0.0;
|
||||
avoidance_enabled = false;
|
||||
use_3d_avoidance = false;
|
||||
avoidance_layers = 1;
|
||||
obstacle_dirty = true;
|
||||
map_update_id = 0;
|
||||
paused = false;
|
||||
}
|
||||
|
||||
NavObstacle::~NavObstacle() {}
|
||||
|
||||
void NavObstacle::set_agent(NavAgent *p_agent) {
|
||||
if (agent == p_agent) {
|
||||
return;
|
||||
}
|
||||
|
||||
agent = p_agent;
|
||||
|
||||
internal_update_agent();
|
||||
}
|
||||
|
||||
void NavObstacle::set_avoidance_enabled(bool p_enabled) {
|
||||
if (avoidance_enabled == p_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
avoidance_enabled = p_enabled;
|
||||
obstacle_dirty = true;
|
||||
|
||||
internal_update_agent();
|
||||
}
|
||||
|
||||
void NavObstacle::set_use_3d_avoidance(bool p_enabled) {
|
||||
if (use_3d_avoidance == p_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
use_3d_avoidance = p_enabled;
|
||||
obstacle_dirty = true;
|
||||
|
||||
if (agent) {
|
||||
agent->set_use_3d_avoidance(use_3d_avoidance);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_map(NavMap *p_map) {
|
||||
if (map == p_map) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (map) {
|
||||
map->remove_obstacle(this);
|
||||
if (agent) {
|
||||
agent->set_map(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
map = p_map;
|
||||
obstacle_dirty = true;
|
||||
|
||||
if (map) {
|
||||
map->add_obstacle(this);
|
||||
internal_update_agent();
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_position(const Vector3 p_position) {
|
||||
if (position == p_position) {
|
||||
return;
|
||||
}
|
||||
|
||||
position = p_position;
|
||||
obstacle_dirty = true;
|
||||
|
||||
if (agent) {
|
||||
agent->set_position(position);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_radius(real_t p_radius) {
|
||||
if (radius == p_radius) {
|
||||
return;
|
||||
}
|
||||
|
||||
radius = p_radius;
|
||||
|
||||
if (agent) {
|
||||
agent->set_radius(radius);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_height(const real_t p_height) {
|
||||
if (height == p_height) {
|
||||
return;
|
||||
}
|
||||
|
||||
height = p_height;
|
||||
obstacle_dirty = true;
|
||||
|
||||
if (agent) {
|
||||
agent->set_height(height);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_velocity(const Vector3 p_velocity) {
|
||||
velocity = p_velocity;
|
||||
|
||||
if (agent) {
|
||||
agent->set_velocity(velocity);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_vertices(const Vector<Vector3> &p_vertices) {
|
||||
vertices = p_vertices;
|
||||
obstacle_dirty = true;
|
||||
}
|
||||
|
||||
bool NavObstacle::is_map_changed() {
|
||||
if (map) {
|
||||
bool is_changed = map->get_map_update_id() != map_update_id;
|
||||
map_update_id = map->get_map_update_id();
|
||||
return is_changed;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_avoidance_layers(uint32_t p_layers) {
|
||||
if (avoidance_layers == p_layers) {
|
||||
return;
|
||||
}
|
||||
|
||||
avoidance_layers = p_layers;
|
||||
obstacle_dirty = true;
|
||||
|
||||
if (agent) {
|
||||
agent->set_avoidance_layers(avoidance_layers);
|
||||
}
|
||||
}
|
||||
|
||||
bool NavObstacle::check_dirty() {
|
||||
const bool was_dirty = obstacle_dirty;
|
||||
obstacle_dirty = false;
|
||||
return was_dirty;
|
||||
}
|
||||
|
||||
void NavObstacle::internal_update_agent() {
|
||||
if (agent) {
|
||||
agent->set_neighbor_distance(0.0);
|
||||
agent->set_max_neighbors(0.0);
|
||||
agent->set_time_horizon_agents(0.0);
|
||||
agent->set_time_horizon_obstacles(0.0);
|
||||
agent->set_avoidance_mask(0.0);
|
||||
agent->set_neighbor_distance(0.0);
|
||||
agent->set_avoidance_priority(1.0);
|
||||
agent->set_map(map);
|
||||
agent->set_paused(paused);
|
||||
agent->set_radius(radius);
|
||||
agent->set_height(height);
|
||||
agent->set_position(position);
|
||||
agent->set_avoidance_layers(avoidance_layers);
|
||||
agent->set_avoidance_enabled(avoidance_enabled);
|
||||
agent->set_use_3d_avoidance(use_3d_avoidance);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_paused(bool p_paused) {
|
||||
if (paused == p_paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
paused = p_paused;
|
||||
|
||||
if (map) {
|
||||
if (paused) {
|
||||
map->remove_obstacle(this);
|
||||
} else {
|
||||
map->add_obstacle(this);
|
||||
}
|
||||
}
|
||||
internal_update_agent();
|
||||
}
|
||||
|
||||
bool NavObstacle::get_paused() const {
|
||||
return paused;
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
|
||||
#ifndef NAV_OBSTACLE_H
|
||||
#define NAV_OBSTACLE_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* nav_obstacle.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "core/containers/local_vector.h"
|
||||
#include "core/object/class_db.h"
|
||||
#include "nav_rid.h"
|
||||
|
||||
class NavAgent;
|
||||
class NavMap;
|
||||
|
||||
class NavObstacle : public NavRid {
|
||||
NavAgent *agent;
|
||||
NavMap *map;
|
||||
Vector3 velocity;
|
||||
Vector3 position;
|
||||
Vector<Vector3> vertices;
|
||||
|
||||
real_t radius;
|
||||
real_t height;
|
||||
|
||||
bool avoidance_enabled;
|
||||
bool use_3d_avoidance;
|
||||
uint32_t avoidance_layers;
|
||||
|
||||
bool obstacle_dirty;
|
||||
|
||||
uint32_t map_update_id;
|
||||
bool paused;
|
||||
|
||||
public:
|
||||
NavObstacle();
|
||||
~NavObstacle();
|
||||
|
||||
void set_avoidance_enabled(bool p_enabled);
|
||||
bool is_avoidance_enabled() { return avoidance_enabled; }
|
||||
|
||||
void set_use_3d_avoidance(bool p_enabled);
|
||||
bool get_use_3d_avoidance() { return use_3d_avoidance; }
|
||||
|
||||
void set_map(NavMap *p_map);
|
||||
NavMap *get_map() { return map; }
|
||||
|
||||
void set_agent(NavAgent *p_agent);
|
||||
NavAgent *get_agent() { return agent; }
|
||||
|
||||
void set_position(const Vector3 p_position);
|
||||
const Vector3 &get_position() const { return position; }
|
||||
|
||||
void set_radius(real_t p_radius);
|
||||
real_t get_radius() const { return radius; }
|
||||
|
||||
void set_height(const real_t p_height);
|
||||
real_t get_height() const { return height; }
|
||||
|
||||
void set_velocity(const Vector3 p_velocity);
|
||||
const Vector3 &get_velocity() const { return velocity; }
|
||||
|
||||
void set_vertices(const Vector<Vector3> &p_vertices);
|
||||
const Vector<Vector3> &get_vertices() const { return vertices; }
|
||||
|
||||
bool is_map_changed();
|
||||
|
||||
void set_avoidance_layers(uint32_t p_layers);
|
||||
uint32_t get_avoidance_layers() const { return avoidance_layers; };
|
||||
|
||||
void set_paused(bool p_paused);
|
||||
bool get_paused() const;
|
||||
|
||||
bool check_dirty();
|
||||
|
||||
private:
|
||||
void internal_update_agent();
|
||||
};
|
||||
|
||||
#endif // NAV_OBSTACLE_H
|
@ -1,201 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* nav_region.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "nav_region.h"
|
||||
|
||||
#include "nav_map.h"
|
||||
|
||||
void NavRegion::set_map(NavMap *p_map) {
|
||||
if (map == p_map) {
|
||||
return;
|
||||
}
|
||||
|
||||
map = p_map;
|
||||
polygons_dirty = true;
|
||||
|
||||
if (!map) {
|
||||
connections.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void NavRegion::set_enabled(bool p_enabled) {
|
||||
if (enabled == p_enabled) {
|
||||
return;
|
||||
}
|
||||
enabled = p_enabled;
|
||||
|
||||
// TODO: This should not require a full rebuild as the region has not really changed.
|
||||
polygons_dirty = true;
|
||||
};
|
||||
|
||||
void NavRegion::set_use_edge_connections(bool p_enabled) {
|
||||
if (use_edge_connections != p_enabled) {
|
||||
use_edge_connections = p_enabled;
|
||||
polygons_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void NavRegion::set_transform(Transform p_transform) {
|
||||
if (transform == p_transform) {
|
||||
return;
|
||||
}
|
||||
|
||||
transform = p_transform;
|
||||
polygons_dirty = true;
|
||||
}
|
||||
|
||||
void NavRegion::set_mesh(Ref<NavigationMesh> p_mesh) {
|
||||
mesh = p_mesh;
|
||||
polygons_dirty = true;
|
||||
}
|
||||
|
||||
int NavRegion::get_connections_count() const {
|
||||
if (!map) {
|
||||
return 0;
|
||||
}
|
||||
return connections.size();
|
||||
}
|
||||
|
||||
Vector3 NavRegion::get_connection_pathway_start(int p_connection_id) const {
|
||||
ERR_FAIL_COND_V(!map, Vector3());
|
||||
ERR_FAIL_INDEX_V(p_connection_id, connections.size(), Vector3());
|
||||
return connections[p_connection_id].pathway_start;
|
||||
}
|
||||
|
||||
Vector3 NavRegion::get_connection_pathway_end(int p_connection_id) const {
|
||||
ERR_FAIL_COND_V(!map, Vector3());
|
||||
ERR_FAIL_INDEX_V(p_connection_id, connections.size(), Vector3());
|
||||
return connections[p_connection_id].pathway_end;
|
||||
}
|
||||
|
||||
bool NavRegion::sync() {
|
||||
bool something_changed = polygons_dirty /* || something_dirty? */;
|
||||
|
||||
update_polygons();
|
||||
|
||||
return something_changed;
|
||||
}
|
||||
|
||||
void NavRegion::update_polygons() {
|
||||
if (!polygons_dirty) {
|
||||
return;
|
||||
}
|
||||
polygons.clear();
|
||||
polygons_dirty = false;
|
||||
|
||||
if (map == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mesh.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (!Math::is_equal_approx(double(map->get_cell_size()), double(mesh->get_cell_size()))) {
|
||||
ERR_PRINT_ONCE(vformat("Navigation map synchronization error. Attempted to update a navigation region with a navigation mesh that uses a `cell_size` of %s while assigned to a navigation map set to a `cell_size` of %s. The cell size for navigation maps can be changed by using the NavigationServer map_set_cell_size() function. The cell size for default navigation maps can also be changed in the ProjectSettings.", double(map->get_cell_size()), double(mesh->get_cell_size())));
|
||||
}
|
||||
|
||||
if (!Math::is_equal_approx(double(map->get_cell_height()), double(mesh->get_cell_height()))) {
|
||||
ERR_PRINT_ONCE("Navigation map synchronization error. Attempted to update a navigation region with a navigation mesh that uses a different `cell_height` than the `cell_height` set on the navigation map.");
|
||||
}
|
||||
|
||||
if (map && Math::rad2deg(map->get_up().angle_to(transform.basis.get_column(1))) >= 90.0f) {
|
||||
ERR_PRINT_ONCE(vformat("Navigation map synchronization error. Attempted to update a navigation region with a navigation mesh that uses a `cell_height` of %s while assigned to a navigation map set to a `cell_height` of %s. The cell height for navigation maps can be changed by using the NavigationServer map_set_cell_height() function. The cell height for default navigation maps can also be changed in the ProjectSettings.", double(map->get_cell_height()), double(mesh->get_cell_height())));
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
PoolVector<Vector3> vertices = mesh->get_vertices();
|
||||
int len = vertices.size();
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
PoolVector<Vector3>::Read vertices_r = vertices.read();
|
||||
|
||||
polygons.resize(mesh->get_polygon_count());
|
||||
|
||||
// Build
|
||||
for (size_t i(0); i < polygons.size(); i++) {
|
||||
gd::Polygon &p = polygons[i];
|
||||
p.owner = this;
|
||||
|
||||
Vector<int> mesh_poly = mesh->get_polygon(i);
|
||||
const int *indices = mesh_poly.ptr();
|
||||
bool valid(true);
|
||||
p.points.resize(mesh_poly.size());
|
||||
p.edges.resize(mesh_poly.size());
|
||||
|
||||
Vector3 center;
|
||||
real_t sum(0);
|
||||
|
||||
for (int j(0); j < mesh_poly.size(); j++) {
|
||||
int idx = indices[j];
|
||||
if (idx < 0 || idx >= len) {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Vector3 point_position = transform.xform(vertices_r[idx]);
|
||||
p.points[j].pos = point_position;
|
||||
p.points[j].key = map->get_point_key(point_position);
|
||||
|
||||
center += point_position; // Composing the center of the polygon
|
||||
|
||||
if (j >= 2) {
|
||||
Vector3 epa = transform.xform(vertices_r[indices[j - 2]]);
|
||||
Vector3 epb = transform.xform(vertices_r[indices[j - 1]]);
|
||||
|
||||
sum += map->get_up().dot((epb - epa).cross(point_position - epa));
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
ERR_BREAK_MSG(!valid, "The navigation mesh set in this region is not valid!");
|
||||
}
|
||||
|
||||
p.clockwise = sum > 0;
|
||||
if (mesh_poly.size() != 0) {
|
||||
p.center = center / real_t(mesh_poly.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NavRegion::NavRegion() {
|
||||
map = nullptr;
|
||||
navigation_layers = 1;
|
||||
enter_cost = 0.0;
|
||||
travel_cost = 1.0;
|
||||
polygons_dirty = true;
|
||||
enabled = true;
|
||||
use_edge_connections = true;
|
||||
}
|
||||
|
||||
NavRegion::~NavRegion() {}
|
@ -1,101 +0,0 @@
|
||||
#ifndef NAV_REGION_H
|
||||
#define NAV_REGION_H
|
||||
|
||||
/*************************************************************************/
|
||||
/* nav_region.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "nav_base.h"
|
||||
|
||||
#include "nav_utils.h"
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
|
||||
class NavRegion : public NavBase {
|
||||
NavMap *map;
|
||||
Transform transform;
|
||||
Ref<NavigationMesh> mesh;
|
||||
Vector<gd::Edge::Connection> connections;
|
||||
bool enabled;
|
||||
|
||||
bool use_edge_connections;
|
||||
|
||||
bool polygons_dirty;
|
||||
|
||||
/// Cache
|
||||
LocalVector<gd::Polygon> polygons;
|
||||
|
||||
public:
|
||||
void scratch_polygons() {
|
||||
polygons_dirty = true;
|
||||
}
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool get_enabled() const { return enabled; }
|
||||
|
||||
void set_map(NavMap *p_map);
|
||||
NavMap *get_map() const {
|
||||
return map;
|
||||
}
|
||||
|
||||
void set_use_edge_connections(bool p_enabled);
|
||||
bool get_use_edge_connections() const {
|
||||
return use_edge_connections;
|
||||
}
|
||||
|
||||
void set_transform(Transform transform);
|
||||
const Transform &get_transform() const {
|
||||
return transform;
|
||||
}
|
||||
|
||||
void set_mesh(Ref<NavigationMesh> p_mesh);
|
||||
const Ref<NavigationMesh> get_mesh() const {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
Vector<gd::Edge::Connection> &get_connections() {
|
||||
return connections;
|
||||
}
|
||||
int get_connections_count() const;
|
||||
Vector3 get_connection_pathway_start(int p_connection_id) const;
|
||||
Vector3 get_connection_pathway_end(int p_connection_id) const;
|
||||
|
||||
LocalVector<gd::Polygon> const &get_polygons() const {
|
||||
return polygons;
|
||||
}
|
||||
|
||||
bool sync();
|
||||
|
||||
NavRegion();
|
||||
~NavRegion();
|
||||
|
||||
private:
|
||||
void update_polygons();
|
||||
};
|
||||
|
||||
#endif // NAV_REGION_H
|
@ -1,43 +0,0 @@
|
||||
#ifndef NAV_RID_H
|
||||
#define NAV_RID_H
|
||||
/*************************************************************************/
|
||||
/* nav_rid.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "core/containers/rid.h"
|
||||
|
||||
class NavRid : public RID_Data {
|
||||
RID self;
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; }
|
||||
_FORCE_INLINE_ RID get_self() const { return self; }
|
||||
};
|
||||
|
||||
#endif // NAV_RID_H
|
@ -1,175 +0,0 @@
|
||||
#ifndef NAV_UTILS_H
|
||||
#define NAV_UTILS_H
|
||||
/*************************************************************************/
|
||||
/* nav_utils.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "core/containers/hashfuncs.h"
|
||||
#include "core/containers/rid.h"
|
||||
#include "core/math/vector3.h"
|
||||
|
||||
class NavBase;
|
||||
|
||||
namespace gd {
|
||||
struct Polygon;
|
||||
|
||||
union PointKey {
|
||||
struct {
|
||||
int64_t x : 21;
|
||||
int64_t y : 22;
|
||||
int64_t z : 21;
|
||||
};
|
||||
|
||||
uint64_t key = 0;
|
||||
};
|
||||
|
||||
struct EdgeKey {
|
||||
PointKey a;
|
||||
PointKey b;
|
||||
|
||||
static uint32_t hash(const EdgeKey &p_val) {
|
||||
return hash_one_uint64(p_val.a.key) ^ hash_one_uint64(p_val.b.key);
|
||||
}
|
||||
|
||||
bool operator<(const EdgeKey &p_key) const {
|
||||
return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key);
|
||||
}
|
||||
|
||||
bool operator==(const EdgeKey &p_key) const {
|
||||
return (a.key == p_key.a.key) && (b.key == p_key.b.key);
|
||||
}
|
||||
|
||||
EdgeKey(const PointKey &p_a = PointKey(), const PointKey &p_b = PointKey()) :
|
||||
a(p_a),
|
||||
b(p_b) {
|
||||
if (a.key > b.key) {
|
||||
SWAP(a, b);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Point {
|
||||
Vector3 pos;
|
||||
PointKey key;
|
||||
};
|
||||
|
||||
struct Edge {
|
||||
/// The gateway in the edge, as, in some case, the whole edge might not be navigable.
|
||||
struct Connection {
|
||||
/// Polygon that this connection leads to.
|
||||
Polygon *polygon;
|
||||
|
||||
/// Edge of the source polygon where this connection starts from.
|
||||
int edge;
|
||||
|
||||
/// Point on the edge where the gateway leading to the poly starts.
|
||||
Vector3 pathway_start;
|
||||
|
||||
/// Point on the edge where the gateway leading to the poly ends.
|
||||
Vector3 pathway_end;
|
||||
|
||||
Connection() {
|
||||
polygon = nullptr;
|
||||
edge = -1;
|
||||
}
|
||||
};
|
||||
|
||||
/// Connections from this edge to other polygons.
|
||||
Vector<Connection> connections;
|
||||
|
||||
Edge() {
|
||||
}
|
||||
};
|
||||
|
||||
struct Polygon {
|
||||
/// Navigation region or link that contains this polygon.
|
||||
NavBase *owner;
|
||||
|
||||
/// The points of this `Polygon`
|
||||
LocalVector<Point> points;
|
||||
|
||||
/// Are the points clockwise?
|
||||
bool clockwise;
|
||||
|
||||
/// The edges of this `Polygon`
|
||||
LocalVector<Edge> edges;
|
||||
|
||||
/// The center of this `Polygon`
|
||||
Vector3 center;
|
||||
|
||||
Polygon() {
|
||||
owner = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct NavigationPoly {
|
||||
uint32_t self_id;
|
||||
/// This poly.
|
||||
const Polygon *poly;
|
||||
|
||||
/// Those 4 variables are used to travel the path backwards.
|
||||
int back_navigation_poly_id;
|
||||
int back_navigation_edge;
|
||||
Vector3 back_navigation_edge_pathway_start;
|
||||
Vector3 back_navigation_edge_pathway_end;
|
||||
|
||||
/// The entry position of this poly.
|
||||
Vector3 entry;
|
||||
/// The distance to the destination.
|
||||
real_t traveled_distance;
|
||||
|
||||
NavigationPoly() { poly = nullptr; }
|
||||
|
||||
NavigationPoly(const Polygon *p_poly) {
|
||||
self_id = 0;
|
||||
poly = p_poly;
|
||||
|
||||
back_navigation_poly_id = -1;
|
||||
back_navigation_edge = -1;
|
||||
traveled_distance = 0.0;
|
||||
}
|
||||
|
||||
bool operator==(const NavigationPoly &other) const {
|
||||
return this->poly == other.poly;
|
||||
}
|
||||
|
||||
bool operator!=(const NavigationPoly &other) const {
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
struct ClosestPointQueryResult {
|
||||
Vector3 point;
|
||||
Vector3 normal;
|
||||
RID owner;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // NAV_UTILS_H
|
@ -1,395 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* navigation_2d_server.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "pandemonium_navigation_2d_server.h"
|
||||
|
||||
#include "core/math/transform.h"
|
||||
#include "core/math/transform_2d.h"
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
#include "servers/navigation_server.h"
|
||||
|
||||
#define FORWARD_0(FUNC_NAME) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME() { \
|
||||
return NavigationServer::get_singleton()->FUNC_NAME(); \
|
||||
}
|
||||
|
||||
#define FORWARD_0_C(FUNC_NAME) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME() \
|
||||
const { \
|
||||
return NavigationServer::get_singleton()->FUNC_NAME(); \
|
||||
}
|
||||
|
||||
#define FORWARD_1(FUNC_NAME, T_0, D_0, CONV_0) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0) { \
|
||||
return NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0)); \
|
||||
}
|
||||
|
||||
#define FORWARD_1_C(FUNC_NAME, T_0, D_0, CONV_0) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0) \
|
||||
const { \
|
||||
return NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0)); \
|
||||
}
|
||||
|
||||
#define FORWARD_1_R_C(CONV_R, FUNC_NAME, T_0, D_0, CONV_0) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0) \
|
||||
const { \
|
||||
return CONV_R(NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0))); \
|
||||
}
|
||||
|
||||
#define FORWARD_2(FUNC_NAME, T_0, D_0, T_1, D_1, CONV_0, CONV_1) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1) { \
|
||||
return NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1)); \
|
||||
}
|
||||
|
||||
#define FORWARD_2_C(FUNC_NAME, T_0, D_0, T_1, D_1, CONV_0, CONV_1) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1) \
|
||||
const { \
|
||||
return NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1)); \
|
||||
}
|
||||
|
||||
#define FORWARD_2_R_C(CONV_R, FUNC_NAME, T_0, D_0, T_1, D_1, CONV_0, CONV_1) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1) \
|
||||
const { \
|
||||
return CONV_R(NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1))); \
|
||||
}
|
||||
|
||||
#define FORWARD_3_R_C(CONV_R, FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, CONV_0, CONV_1, CONV_2) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2) \
|
||||
const { \
|
||||
return CONV_R(NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2))); \
|
||||
}
|
||||
|
||||
#define FORWARD_3_C(FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, CONV_0, CONV_1, CONV_2) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2) \
|
||||
const { \
|
||||
return NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2)); \
|
||||
}
|
||||
|
||||
#define FORWARD_4(FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, CONV_0, CONV_1, CONV_2, CONV_3) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) { \
|
||||
return NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3)); \
|
||||
}
|
||||
|
||||
#define FORWARD_4_R_C(CONV_R, FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, CONV_0, CONV_1, CONV_2, CONV_3) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) \
|
||||
const { \
|
||||
return CONV_R(NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3))); \
|
||||
}
|
||||
|
||||
#define FORWARD_4_C(FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, CONV_0, CONV_1, CONV_2, CONV_3) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) \
|
||||
const { \
|
||||
return NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3)); \
|
||||
}
|
||||
|
||||
#define FORWARD_5_R_C(CONV_R, FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, T_4, D_4, CONV_0, CONV_1, CONV_2, CONV_3, CONV_4) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3, T_4 D_4) \
|
||||
const { \
|
||||
return CONV_R(NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3), CONV_4(D_4))); \
|
||||
}
|
||||
|
||||
#define FORWARD_5_C(FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, T_4, D_4, CONV_0, CONV_1, CONV_2, CONV_3, CONV_4) \
|
||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3, T_4 D_4) \
|
||||
const { \
|
||||
return NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3), CONV_4(D_4)); \
|
||||
}
|
||||
|
||||
RID rid_to_rid(const RID d) {
|
||||
return d;
|
||||
}
|
||||
|
||||
bool bool_to_bool(const bool d) {
|
||||
return d;
|
||||
}
|
||||
|
||||
int int_to_int(const int d) {
|
||||
return d;
|
||||
}
|
||||
|
||||
uint32_t uint32_to_uint32(const uint32_t d) {
|
||||
return d;
|
||||
}
|
||||
|
||||
real_t real_to_real(const real_t d) {
|
||||
return d;
|
||||
}
|
||||
|
||||
Vector3 v2_to_v3(const Vector2 d) {
|
||||
return Vector3(d.x, 0.0, d.y);
|
||||
}
|
||||
|
||||
Vector2 v3_to_v2(const Vector3 &d) {
|
||||
return Vector2(d.x, d.z);
|
||||
}
|
||||
|
||||
Vector<Vector2> vector_v3_to_v2(const Vector<Vector3> &d) {
|
||||
Vector<Vector2> nd;
|
||||
nd.resize(d.size());
|
||||
for (int i(0); i < nd.size(); i++) {
|
||||
nd.write[i] = v3_to_v2(d[i]);
|
||||
}
|
||||
return nd;
|
||||
}
|
||||
|
||||
static Vector<Vector3> vector_v2_to_v3(const Vector<Vector2> &d) {
|
||||
Vector<Vector3> nd;
|
||||
nd.resize(d.size());
|
||||
for (int i(0); i < nd.size(); i++) {
|
||||
nd.write[i] = v2_to_v3(d[i]);
|
||||
}
|
||||
return nd;
|
||||
}
|
||||
|
||||
PoolVector<Vector2> poolvector_v3_to_v2(const PoolVector<Vector3> &d) {
|
||||
PoolVector<Vector2> nd;
|
||||
nd.resize(d.size());
|
||||
PoolVector2Array::Write w = nd.write();
|
||||
Vector2 *wptr = w.ptr();
|
||||
for (int i(0); i < nd.size(); i++) {
|
||||
wptr[i] = v3_to_v2(d[i]);
|
||||
}
|
||||
return nd;
|
||||
}
|
||||
|
||||
Transform trf2_to_trf3(const Transform2D &d) {
|
||||
Vector3 o(v2_to_v3(d.get_origin()));
|
||||
Basis b;
|
||||
b.rotate(Vector3(0, -1, 0), d.get_rotation());
|
||||
b.scale(v2_to_v3(d.get_scale()));
|
||||
return Transform(b, o);
|
||||
}
|
||||
|
||||
StringName sn_to_sn(StringName &d) {
|
||||
return d;
|
||||
}
|
||||
|
||||
Variant var_to_var(Variant &d) {
|
||||
return d;
|
||||
}
|
||||
|
||||
ObjectID id_to_id(const ObjectID &id) {
|
||||
return id;
|
||||
}
|
||||
|
||||
Ref<NavigationMesh> poly_to_mesh(Ref<NavigationPolygon> d) {
|
||||
if (d.is_valid()) {
|
||||
return d->get_navigation_mesh();
|
||||
} else {
|
||||
return Ref<NavigationMesh>();
|
||||
}
|
||||
}
|
||||
|
||||
void PandemoniumNavigation2DServer::_emit_map_changed(RID p_map) {
|
||||
emit_signal("map_changed", p_map);
|
||||
}
|
||||
|
||||
void PandemoniumNavigation2DServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_emit_map_changed"), &PandemoniumNavigation2DServer::_emit_map_changed);
|
||||
}
|
||||
|
||||
PandemoniumNavigation2DServer::PandemoniumNavigation2DServer() {
|
||||
ERR_FAIL_COND_MSG(!NavigationServer::get_singleton(), "The NavigationServer singleton should be initialized before the PandemoniumNavigation2DServer one.");
|
||||
NavigationServer::get_singleton()->connect("map_changed", this, "_emit_map_changed");
|
||||
}
|
||||
|
||||
PandemoniumNavigation2DServer::~PandemoniumNavigation2DServer() {
|
||||
}
|
||||
|
||||
Array FORWARD_0_C(get_maps);
|
||||
|
||||
Array FORWARD_1_C(map_get_links, RID, p_map, rid_to_rid);
|
||||
|
||||
Array FORWARD_1_C(map_get_regions, RID, p_map, rid_to_rid);
|
||||
|
||||
Array FORWARD_1_C(map_get_agents, RID, p_map, rid_to_rid);
|
||||
|
||||
Array FORWARD_1_C(map_get_obstacles, RID, p_map, rid_to_rid);
|
||||
|
||||
RID FORWARD_1_C(region_get_map, RID, p_region, rid_to_rid);
|
||||
|
||||
RID FORWARD_1_C(agent_get_map, RID, p_agent, rid_to_rid);
|
||||
|
||||
RID FORWARD_0(map_create);
|
||||
|
||||
void FORWARD_2(map_set_active, RID, p_map, bool, p_active, rid_to_rid, bool_to_bool);
|
||||
|
||||
bool FORWARD_1_C(map_is_active, RID, p_map, rid_to_rid);
|
||||
|
||||
void PandemoniumNavigation2DServer::map_force_update(RID p_map) {
|
||||
NavigationServer::get_singleton()->map_force_update(p_map);
|
||||
}
|
||||
|
||||
void FORWARD_2(map_set_cell_size, RID, p_map, real_t, p_cell_size, rid_to_rid, real_to_real);
|
||||
real_t FORWARD_1_C(map_get_cell_size, RID, p_map, rid_to_rid);
|
||||
|
||||
void FORWARD_2(map_set_use_edge_connections, RID, p_map, bool, p_enabled, rid_to_rid, bool_to_bool);
|
||||
bool FORWARD_1_C(map_get_use_edge_connections, RID, p_map, rid_to_rid);
|
||||
|
||||
void FORWARD_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin, rid_to_rid, real_to_real);
|
||||
real_t FORWARD_1_C(map_get_edge_connection_margin, RID, p_map, rid_to_rid);
|
||||
|
||||
void FORWARD_2(map_set_link_connection_radius, RID, p_map, real_t, p_connection_radius, rid_to_rid, real_to_real);
|
||||
real_t FORWARD_1_C(map_get_link_connection_radius, RID, p_map, rid_to_rid);
|
||||
|
||||
Vector<Vector2> FORWARD_5_R_C(vector_v3_to_v2, map_get_path, RID, p_map, Vector2, p_origin, Vector2, p_destination, bool, p_optimize, uint32_t, p_navigation_layers, rid_to_rid, v2_to_v3, v2_to_v3, bool_to_bool, uint32_to_uint32);
|
||||
|
||||
Vector2 FORWARD_2_R_C(v3_to_v2, map_get_closest_point, RID, p_map, const Vector2 &, p_point, rid_to_rid, v2_to_v3);
|
||||
RID FORWARD_2_C(map_get_closest_point_owner, RID, p_map, const Vector2 &, p_point, rid_to_rid, v2_to_v3);
|
||||
|
||||
RID FORWARD_0(region_create);
|
||||
|
||||
void FORWARD_2(region_set_enabled, RID, p_region, bool, p_enabled, rid_to_rid, bool_to_bool);
|
||||
bool FORWARD_1_C(region_get_enabled, RID, p_region, rid_to_rid);
|
||||
void FORWARD_2(region_set_use_edge_connections, RID, p_region, bool, p_enabled, rid_to_rid, bool_to_bool);
|
||||
bool FORWARD_1_C(region_get_use_edge_connections, RID, p_region, rid_to_rid);
|
||||
|
||||
void FORWARD_2(region_set_enter_cost, RID, p_region, real_t, p_enter_cost, rid_to_rid, real_to_real);
|
||||
real_t FORWARD_1_C(region_get_enter_cost, RID, p_region, rid_to_rid);
|
||||
void FORWARD_2(region_set_travel_cost, RID, p_region, real_t, p_travel_cost, rid_to_rid, real_to_real);
|
||||
real_t FORWARD_1_C(region_get_travel_cost, RID, p_region, rid_to_rid);
|
||||
void FORWARD_2(region_set_owner_id, RID, p_region, ObjectID, p_owner_id, rid_to_rid, id_to_id);
|
||||
ObjectID FORWARD_1_C(region_get_owner_id, RID, p_region, rid_to_rid);
|
||||
bool FORWARD_2_C(region_owns_point, RID, p_region, const Vector2 &, p_point, rid_to_rid, v2_to_v3);
|
||||
|
||||
void FORWARD_2(region_set_map, RID, p_region, RID, p_map, rid_to_rid, rid_to_rid);
|
||||
void FORWARD_2(region_set_navigation_layers, RID, p_region, uint32_t, p_navigation_layers, rid_to_rid, uint32_to_uint32);
|
||||
uint32_t FORWARD_1_C(region_get_navigation_layers, RID, p_region, rid_to_rid);
|
||||
void FORWARD_2(region_set_transform, RID, p_region, Transform2D, p_transform, rid_to_rid, trf2_to_trf3);
|
||||
|
||||
void PandemoniumNavigation2DServer::region_set_navigation_polygon(RID p_region, Ref<NavigationPolygon> p_navigation_mesh) {
|
||||
NavigationServer::get_singleton()->region_set_navigation_mesh(p_region, poly_to_mesh(p_navigation_mesh));
|
||||
}
|
||||
|
||||
int FORWARD_1_C(region_get_connections_count, RID, p_region, rid_to_rid);
|
||||
Vector2 FORWARD_2_R_C(v3_to_v2, region_get_connection_pathway_start, RID, p_region, int, p_connection_id, rid_to_rid, int_to_int);
|
||||
Vector2 FORWARD_2_R_C(v3_to_v2, region_get_connection_pathway_end, RID, p_region, int, p_connection_id, rid_to_rid, int_to_int);
|
||||
|
||||
RID FORWARD_0(link_create);
|
||||
|
||||
void FORWARD_2(link_set_map, RID, p_link, RID, p_map, rid_to_rid, rid_to_rid);
|
||||
RID FORWARD_1_C(link_get_map, RID, p_link, rid_to_rid);
|
||||
void FORWARD_2(link_set_enabled, RID, p_link, bool, p_enabled, rid_to_rid, bool_to_bool);
|
||||
bool FORWARD_1_C(link_get_enabled, RID, p_link, rid_to_rid);
|
||||
void FORWARD_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional, rid_to_rid, bool_to_bool);
|
||||
bool FORWARD_1_C(link_is_bidirectional, RID, p_link, rid_to_rid);
|
||||
void FORWARD_2(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers, rid_to_rid, uint32_to_uint32);
|
||||
uint32_t FORWARD_1_C(link_get_navigation_layers, RID, p_link, rid_to_rid);
|
||||
void FORWARD_2(link_set_start_position, RID, p_link, Vector2, p_position, rid_to_rid, v2_to_v3);
|
||||
Vector2 FORWARD_1_R_C(v3_to_v2, link_get_start_position, RID, p_link, rid_to_rid);
|
||||
void FORWARD_2(link_set_end_position, RID, p_link, Vector2, p_position, rid_to_rid, v2_to_v3);
|
||||
Vector2 FORWARD_1_R_C(v3_to_v2, link_get_end_position, RID, p_link, rid_to_rid);
|
||||
void FORWARD_2(link_set_enter_cost, RID, p_link, real_t, p_enter_cost, rid_to_rid, real_to_real);
|
||||
real_t FORWARD_1_C(link_get_enter_cost, RID, p_link, rid_to_rid);
|
||||
void FORWARD_2(link_set_travel_cost, RID, p_link, real_t, p_travel_cost, rid_to_rid, real_to_real);
|
||||
real_t FORWARD_1_C(link_get_travel_cost, RID, p_link, rid_to_rid);
|
||||
void FORWARD_2(link_set_owner_id, RID, p_link, ObjectID, p_owner_id, rid_to_rid, id_to_id);
|
||||
ObjectID FORWARD_1_C(link_get_owner_id, RID, p_link, rid_to_rid);
|
||||
|
||||
RID PandemoniumNavigation2DServer::agent_create() {
|
||||
RID agent = NavigationServer::get_singleton()->agent_create();
|
||||
return agent;
|
||||
}
|
||||
|
||||
void FORWARD_2(agent_set_avoidance_enabled, RID, p_agent, bool, p_enabled, rid_to_rid, bool_to_bool);
|
||||
|
||||
bool FORWARD_1_C(agent_get_avoidance_enabled, RID, p_agent, rid_to_rid);
|
||||
|
||||
void FORWARD_2(agent_set_map, RID, p_agent, RID, p_map, rid_to_rid, rid_to_rid);
|
||||
|
||||
void FORWARD_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_dist, rid_to_rid, real_to_real);
|
||||
|
||||
void FORWARD_2(agent_set_max_neighbors, RID, p_agent, int, p_count, rid_to_rid, int_to_int);
|
||||
|
||||
void FORWARD_2(agent_set_time_horizon_agents, RID, p_agent, real_t, p_time_horizon, rid_to_rid, real_to_real);
|
||||
|
||||
void FORWARD_2(agent_set_time_horizon_obstacles, RID, p_agent, real_t, p_time_horizon, rid_to_rid, real_to_real);
|
||||
|
||||
void FORWARD_2(agent_set_radius, RID, p_agent, real_t, p_radius, rid_to_rid, real_to_real);
|
||||
|
||||
void FORWARD_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed, rid_to_rid, real_to_real);
|
||||
|
||||
void FORWARD_2(agent_set_velocity_forced, RID, p_agent, Vector2, p_velocity, rid_to_rid, v2_to_v3);
|
||||
|
||||
void FORWARD_2(agent_set_velocity, RID, p_agent, Vector2, p_velocity, rid_to_rid, v2_to_v3);
|
||||
|
||||
void FORWARD_2(agent_set_position, RID, p_agent, Vector2, p_position, rid_to_rid, v2_to_v3);
|
||||
|
||||
bool FORWARD_1_C(agent_is_map_changed, RID, p_agent, rid_to_rid);
|
||||
|
||||
void FORWARD_2(agent_set_paused, RID, p_agent, bool, p_paused, rid_to_rid, bool_to_bool);
|
||||
bool FORWARD_1_C(agent_get_paused, RID, p_agent, rid_to_rid);
|
||||
|
||||
void FORWARD_1(free, RID, p_object, rid_to_rid);
|
||||
|
||||
void FORWARD_4(agent_set_avoidance_callback, RID, p_agent, ObjectID, p_object_id, StringName, p_method, Variant, p_udata, rid_to_rid, id_to_id, sn_to_sn, var_to_var);
|
||||
|
||||
void FORWARD_2(agent_set_avoidance_layers, RID, p_agent, uint32_t, p_layers, rid_to_rid, uint32_to_uint32);
|
||||
void FORWARD_2(agent_set_avoidance_mask, RID, p_agent, uint32_t, p_mask, rid_to_rid, uint32_to_uint32);
|
||||
void FORWARD_2(agent_set_avoidance_priority, RID, p_agent, real_t, p_priority, rid_to_rid, real_to_real);
|
||||
|
||||
RID PandemoniumNavigation2DServer::obstacle_create() {
|
||||
RID obstacle = NavigationServer::get_singleton()->obstacle_create();
|
||||
return obstacle;
|
||||
}
|
||||
void FORWARD_2(obstacle_set_avoidance_enabled, RID, p_obstacle, bool, p_enabled, rid_to_rid, bool_to_bool);
|
||||
bool FORWARD_1_C(obstacle_get_avoidance_enabled, RID, p_obstacle, rid_to_rid);
|
||||
void FORWARD_2(obstacle_set_map, RID, p_obstacle, RID, p_map, rid_to_rid, rid_to_rid);
|
||||
RID FORWARD_1_C(obstacle_get_map, RID, p_obstacle, rid_to_rid);
|
||||
void FORWARD_2(obstacle_set_radius, RID, p_obstacle, real_t, p_radius, rid_to_rid, real_to_real);
|
||||
void FORWARD_2(obstacle_set_velocity, RID, p_obstacle, Vector2, p_velocity, rid_to_rid, v2_to_v3);
|
||||
void FORWARD_2(obstacle_set_paused, RID, p_obstacle, bool, p_paused, rid_to_rid, bool_to_bool);
|
||||
bool FORWARD_1_C(obstacle_get_paused, RID, p_obstacle, rid_to_rid);
|
||||
void FORWARD_2(obstacle_set_position, RID, p_obstacle, Vector2, p_position, rid_to_rid, v2_to_v3);
|
||||
void FORWARD_2(obstacle_set_avoidance_layers, RID, p_obstacle, uint32_t, p_layers, rid_to_rid, uint32_to_uint32);
|
||||
|
||||
void PandemoniumNavigation2DServer::obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices) {
|
||||
NavigationServer::get_singleton()->obstacle_set_vertices(p_obstacle, vector_v2_to_v3(p_vertices));
|
||||
}
|
||||
|
||||
NavigationUtilities::PathQueryResult2D PandemoniumNavigation2DServer::_query_path(const NavigationUtilities::PathQueryParameters2D &p_parameters) const {
|
||||
NavigationUtilities::PathQueryParameters params;
|
||||
params.pathfinding_algorithm = p_parameters.pathfinding_algorithm;
|
||||
params.path_postprocessing = p_parameters.path_postprocessing;
|
||||
params.map = p_parameters.map;
|
||||
params.start_position = Vector3(p_parameters.start_position.x, 0.0, p_parameters.start_position.y);
|
||||
params.target_position = Vector3(p_parameters.target_position.x, 0.0, p_parameters.target_position.y);
|
||||
params.navigation_layers = p_parameters.navigation_layers;
|
||||
params.metadata_flags = p_parameters.metadata_flags;
|
||||
|
||||
NavigationUtilities::PathQueryResult res = NavigationServer::get_singleton()->_query_path(params);
|
||||
|
||||
NavigationUtilities::PathQueryResult2D resf;
|
||||
resf.path = vector_v3_to_v2(res.path);
|
||||
resf.path_types = res.path_types;
|
||||
resf.path_rids = res.path_rids;
|
||||
resf.path_owner_ids = res.path_owner_ids;
|
||||
|
||||
return resf;
|
||||
}
|
@ -1,266 +0,0 @@
|
||||
#ifndef PANDEMONIUM_NAVIGATION_2D_SERVER_H
|
||||
#define PANDEMONIUM_NAVIGATION_2D_SERVER_H
|
||||
|
||||
/*************************************************************************/
|
||||
/* navigation_2d_server.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "core/containers/rid.h"
|
||||
#include "core/object/object.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
#include "servers/navigation_2d_server.h"
|
||||
|
||||
// This server exposes the 3D `NavigationServer` features in the 2D world.
|
||||
class PandemoniumNavigation2DServer : public Navigation2DServer {
|
||||
GDCLASS(PandemoniumNavigation2DServer, Navigation2DServer);
|
||||
|
||||
void _emit_map_changed(RID p_map);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual Array get_maps() const;
|
||||
|
||||
/// Create a new map.
|
||||
virtual RID map_create();
|
||||
|
||||
/// Set map active.
|
||||
virtual void map_set_active(RID p_map, bool p_active);
|
||||
|
||||
/// Returns true if the map is active.
|
||||
virtual bool map_is_active(RID p_map) const;
|
||||
|
||||
/// Set the map cell size used to weld the navigation mesh polygons.
|
||||
virtual void map_set_cell_size(RID p_map, real_t p_cell_size);
|
||||
|
||||
/// Returns the map cell size.
|
||||
virtual real_t map_get_cell_size(RID p_map) const;
|
||||
|
||||
virtual void map_set_use_edge_connections(RID p_map, bool p_enabled);
|
||||
virtual bool map_get_use_edge_connections(RID p_map) const;
|
||||
|
||||
/// Set the map edge connection margin used to weld the compatible region edges.
|
||||
virtual void map_set_edge_connection_margin(RID p_map, real_t p_connection_margin);
|
||||
|
||||
/// Returns the edge connection margin of this map.
|
||||
virtual real_t map_get_edge_connection_margin(RID p_map) const;
|
||||
|
||||
/// Set the map link connection radius used to attach links to the nav mesh.
|
||||
virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius);
|
||||
|
||||
/// Returns the link connection radius of this map.
|
||||
virtual real_t map_get_link_connection_radius(RID p_map) const;
|
||||
|
||||
/// Returns the navigation path to reach the destination from the origin.
|
||||
virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const;
|
||||
|
||||
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const;
|
||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const;
|
||||
|
||||
virtual Array map_get_links(RID p_map) const;
|
||||
virtual Array map_get_regions(RID p_map) const;
|
||||
virtual Array map_get_agents(RID p_map) const;
|
||||
virtual Array map_get_obstacles(RID p_map) const;
|
||||
|
||||
virtual void map_force_update(RID p_map);
|
||||
|
||||
/// Creates a new region.
|
||||
virtual RID region_create();
|
||||
|
||||
virtual void region_set_enabled(RID p_region, bool p_enabled);
|
||||
virtual bool region_get_enabled(RID p_region) const;
|
||||
|
||||
virtual void region_set_use_edge_connections(RID p_region, bool p_enabled);
|
||||
virtual bool region_get_use_edge_connections(RID p_region) const;
|
||||
|
||||
/// Set the enter_cost of a region
|
||||
virtual void region_set_enter_cost(RID p_region, real_t p_enter_cost);
|
||||
virtual real_t region_get_enter_cost(RID p_region) const;
|
||||
|
||||
/// Set the travel_cost of a region
|
||||
virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost);
|
||||
virtual real_t region_get_travel_cost(RID p_region) const;
|
||||
|
||||
/// Set the node which manages this region.
|
||||
virtual void region_set_owner_id(RID p_region, ObjectID p_owner_id);
|
||||
virtual ObjectID region_get_owner_id(RID p_region) const;
|
||||
|
||||
virtual bool region_owns_point(RID p_region, const Vector2 &p_point) const;
|
||||
|
||||
/// Set the map of this region.
|
||||
virtual void region_set_map(RID p_region, RID p_map);
|
||||
virtual RID region_get_map(RID p_region) const;
|
||||
|
||||
/// Set the region's layers
|
||||
virtual void region_set_navigation_layers(RID p_region, uint32_t p_navigation_layers);
|
||||
virtual uint32_t region_get_navigation_layers(RID p_region) const;
|
||||
|
||||
/// Set the global transformation of this region.
|
||||
virtual void region_set_transform(RID p_region, Transform2D p_transform);
|
||||
|
||||
/// Set the navigation poly of this region.
|
||||
virtual void region_set_navigation_polygon(RID p_region, Ref<NavigationPolygon> p_navigation_mesh);
|
||||
|
||||
/// Get a list of a region's connection to other regions.
|
||||
virtual int region_get_connections_count(RID p_region) const;
|
||||
virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const;
|
||||
virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const;
|
||||
|
||||
/// Creates a new link between positions in the nav map.
|
||||
virtual RID link_create();
|
||||
|
||||
/// Set the map of this link.
|
||||
virtual void link_set_map(RID p_link, RID p_map);
|
||||
virtual RID link_get_map(RID p_link) const;
|
||||
|
||||
virtual void link_set_enabled(RID p_link, bool p_enabled);
|
||||
virtual bool link_get_enabled(RID p_link) const;
|
||||
|
||||
/// Set whether this link travels in both directions.
|
||||
virtual void link_set_bidirectional(RID p_link, bool p_bidirectional);
|
||||
virtual bool link_is_bidirectional(RID p_link) const;
|
||||
|
||||
/// Set the link's layers.
|
||||
virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers);
|
||||
virtual uint32_t link_get_navigation_layers(RID p_link) const;
|
||||
|
||||
/// Set the start position of the link.
|
||||
virtual void link_set_start_position(RID p_link, Vector2 p_position);
|
||||
virtual Vector2 link_get_start_position(RID p_link) const;
|
||||
|
||||
/// Set the end position of the link.
|
||||
virtual void link_set_end_position(RID p_link, Vector2 p_position);
|
||||
virtual Vector2 link_get_end_position(RID p_link) const;
|
||||
|
||||
/// Set the enter cost of the link.
|
||||
virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost);
|
||||
virtual real_t link_get_enter_cost(RID p_link) const;
|
||||
|
||||
/// Set the travel cost of the link.
|
||||
virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost);
|
||||
virtual real_t link_get_travel_cost(RID p_link) const;
|
||||
|
||||
/// Set the node which manages this link.
|
||||
virtual void link_set_owner_id(RID p_link, ObjectID p_owner_id);
|
||||
virtual ObjectID link_get_owner_id(RID p_link) const;
|
||||
|
||||
/// Creates the agent.
|
||||
virtual RID agent_create();
|
||||
|
||||
/// Put the agent in the map.
|
||||
virtual void agent_set_map(RID p_agent, RID p_map);
|
||||
virtual RID agent_get_map(RID p_agent) const;
|
||||
|
||||
virtual void agent_set_paused(RID p_agent, bool p_paused);
|
||||
virtual bool agent_get_paused(RID p_agent) const;
|
||||
|
||||
virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled);
|
||||
virtual bool agent_get_avoidance_enabled(RID p_agent) const;
|
||||
|
||||
/// The maximum distance (center point to
|
||||
/// center point) to other agents this agent
|
||||
/// takes into account in the navigation. The
|
||||
/// larger this number, the longer the running
|
||||
/// time of the simulation. If the number is too
|
||||
/// low, the simulation will not be safe.
|
||||
/// Must be non-negative.
|
||||
virtual void agent_set_neighbor_distance(RID p_agent, real_t p_dist);
|
||||
|
||||
/// The maximum number of other agents this
|
||||
/// agent takes into account in the navigation.
|
||||
/// The larger this number, the longer the
|
||||
/// running time of the simulation. If the
|
||||
/// number is too low, the simulation will not
|
||||
/// be safe.
|
||||
virtual void agent_set_max_neighbors(RID p_agent, int p_count);
|
||||
|
||||
/// The minimal amount of time for which this
|
||||
/// agent's velocities that are computed by the
|
||||
/// simulation are safe with respect to other
|
||||
/// agents. The larger this number, the sooner
|
||||
/// this agent will respond to the presence of
|
||||
/// other agents, but the less freedom this
|
||||
/// agent has in choosing its velocities.
|
||||
/// Must be positive.
|
||||
virtual void agent_set_time_horizon_agents(RID p_agent, real_t p_time_horizon);
|
||||
virtual void agent_set_time_horizon_obstacles(RID p_agent, real_t p_time_horizon);
|
||||
|
||||
/// The radius of this agent.
|
||||
/// Must be non-negative.
|
||||
virtual void agent_set_radius(RID p_agent, real_t p_radius);
|
||||
|
||||
/// The maximum speed of this agent.
|
||||
/// Must be non-negative.
|
||||
virtual void agent_set_max_speed(RID p_agent, real_t p_max_speed);
|
||||
|
||||
/// forces and agent velocity change in the avoidance simulation, adds simulation instability if done recklessly
|
||||
virtual void agent_set_velocity_forced(RID p_agent, Vector2 p_velocity);
|
||||
|
||||
/// The wanted velocity for the agent as a "suggestion" to the avoidance simulation.
|
||||
/// The simulation will try to fulfil this velocity wish if possible but may change the velocity depending on other agent's and obstacles'.
|
||||
virtual void agent_set_velocity(RID p_agent, Vector2 p_velocity);
|
||||
|
||||
/// Position of the agent in world space.
|
||||
virtual void agent_set_position(RID p_agent, Vector2 p_position);
|
||||
|
||||
/// Returns true if the map got changed the previous frame.
|
||||
virtual bool agent_is_map_changed(RID p_agent) const;
|
||||
|
||||
/// Callback called at the end of the RVO process
|
||||
virtual void agent_set_avoidance_callback(RID p_agent, ObjectID p_object_id, StringName p_method, Variant p_udata = Variant());
|
||||
|
||||
virtual void agent_set_avoidance_layers(RID p_agent, uint32_t p_layers);
|
||||
virtual void agent_set_avoidance_mask(RID p_agent, uint32_t p_mask);
|
||||
virtual void agent_set_avoidance_priority(RID p_agent, real_t p_priority);
|
||||
|
||||
/// Creates the obstacle.
|
||||
virtual RID obstacle_create();
|
||||
virtual void obstacle_set_avoidance_enabled(RID p_obstacle, bool p_enabled);
|
||||
virtual bool obstacle_get_avoidance_enabled(RID p_obstacle) const;
|
||||
virtual void obstacle_set_map(RID p_obstacle, RID p_map);
|
||||
virtual RID obstacle_get_map(RID p_obstacle) const;
|
||||
virtual void obstacle_set_radius(RID p_obstacle, real_t p_radius);
|
||||
virtual void obstacle_set_velocity(RID p_obstacle, Vector2 p_velocity);
|
||||
virtual void obstacle_set_paused(RID p_obstacle, bool p_paused);
|
||||
virtual bool obstacle_get_paused(RID p_obstacle) const;
|
||||
virtual void obstacle_set_position(RID p_obstacle, Vector2 p_position);
|
||||
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices);
|
||||
virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers);
|
||||
|
||||
/// Destroy the `RID`
|
||||
virtual void free(RID p_object);
|
||||
|
||||
virtual NavigationUtilities::PathQueryResult2D _query_path(const NavigationUtilities::PathQueryParameters2D &p_parameters) const;
|
||||
|
||||
PandemoniumNavigation2DServer();
|
||||
virtual ~PandemoniumNavigation2DServer();
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,249 +0,0 @@
|
||||
#ifndef PANDEMONIUM_NAVIGATION_SERVER_H
|
||||
#define PANDEMONIUM_NAVIGATION_SERVER_H
|
||||
/*************************************************************************/
|
||||
/* pandemonium_navigation_server.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* PANDEMONIUM ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "servers/navigation_server.h"
|
||||
|
||||
#include "core/containers/rid.h"
|
||||
|
||||
#include "nav_agent.h"
|
||||
#include "nav_link.h"
|
||||
#include "nav_map.h"
|
||||
#include "nav_obstacle.h"
|
||||
#include "nav_region.h"
|
||||
|
||||
/// The commands are functions executed during the `sync` phase.
|
||||
|
||||
#define MERGE_INTERNAL(A, B) A##B
|
||||
#define MERGE(A, B) MERGE_INTERNAL(A, B)
|
||||
|
||||
#define COMMAND_1(F_NAME, T_0, D_0) \
|
||||
virtual void F_NAME(T_0 D_0); \
|
||||
void MERGE(_cmd_, F_NAME)(T_0 D_0)
|
||||
|
||||
#define COMMAND_2(F_NAME, T_0, D_0, T_1, D_1) \
|
||||
virtual void F_NAME(T_0 D_0, T_1 D_1); \
|
||||
void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1)
|
||||
|
||||
#define COMMAND_4_DEF(F_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, D_3_DEF) \
|
||||
virtual void F_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3 = D_3_DEF); \
|
||||
void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3)
|
||||
|
||||
class PandemoniumNavigationServer;
|
||||
|
||||
struct SetCommand {
|
||||
virtual ~SetCommand() {}
|
||||
virtual void exec(PandemoniumNavigationServer *server) = 0;
|
||||
};
|
||||
|
||||
class PandemoniumNavigationServer : public NavigationServer {
|
||||
Mutex commands_mutex;
|
||||
/// Mutex used to make any operation threadsafe.
|
||||
Mutex operations_mutex;
|
||||
|
||||
LocalVector<SetCommand *> commands;
|
||||
|
||||
mutable RID_Owner<NavLink> link_owner;
|
||||
mutable RID_Owner<NavMap> map_owner;
|
||||
mutable RID_Owner<NavRegion> region_owner;
|
||||
mutable RID_Owner<NavAgent> agent_owner;
|
||||
mutable RID_Owner<NavObstacle> obstacle_owner;
|
||||
|
||||
bool active;
|
||||
LocalVector<NavMap *> active_maps;
|
||||
LocalVector<uint32_t> active_maps_update_id;
|
||||
|
||||
// Performance Monitor
|
||||
int pm_region_count;
|
||||
int pm_agent_count;
|
||||
int pm_link_count;
|
||||
int pm_polygon_count;
|
||||
int pm_edge_count;
|
||||
int pm_edge_merge_count;
|
||||
int pm_edge_connection_count;
|
||||
int pm_edge_free_count;
|
||||
|
||||
public:
|
||||
PandemoniumNavigationServer();
|
||||
virtual ~PandemoniumNavigationServer();
|
||||
|
||||
void add_command(SetCommand *command) const;
|
||||
|
||||
virtual Array get_maps() const;
|
||||
|
||||
virtual RID map_create();
|
||||
COMMAND_2(map_set_active, RID, p_map, bool, p_active);
|
||||
virtual bool map_is_active(RID p_map) const;
|
||||
|
||||
COMMAND_2(map_set_up, RID, p_map, Vector3, p_up);
|
||||
virtual Vector3 map_get_up(RID p_map) const;
|
||||
|
||||
COMMAND_2(map_set_cell_size, RID, p_map, real_t, p_cell_size);
|
||||
virtual real_t map_get_cell_size(RID p_map) const;
|
||||
|
||||
COMMAND_2(map_set_cell_height, RID, p_map, real_t, p_cell_height);
|
||||
virtual real_t map_get_cell_height(RID p_map) const;
|
||||
|
||||
COMMAND_2(map_set_use_edge_connections, RID, p_map, bool, p_enabled);
|
||||
virtual bool map_get_use_edge_connections(RID p_map) const;
|
||||
|
||||
COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin);
|
||||
virtual real_t map_get_edge_connection_margin(RID p_map) const;
|
||||
|
||||
COMMAND_2(map_set_link_connection_radius, RID, p_map, real_t, p_connection_radius);
|
||||
virtual real_t map_get_link_connection_radius(RID p_map) const;
|
||||
|
||||
virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers = 1) const;
|
||||
|
||||
virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const;
|
||||
virtual Vector3 map_get_closest_point(RID p_map, const Vector3 &p_point) const;
|
||||
virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const;
|
||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const;
|
||||
|
||||
virtual Array map_get_links(RID p_map) const;
|
||||
virtual Array map_get_regions(RID p_map) const;
|
||||
virtual Array map_get_agents(RID p_map) const;
|
||||
virtual Array map_get_obstacles(RID p_map) const;
|
||||
|
||||
virtual void map_force_update(RID p_map);
|
||||
|
||||
virtual RID region_create();
|
||||
|
||||
COMMAND_2(region_set_enabled, RID, p_region, bool, p_enabled);
|
||||
virtual bool region_get_enabled(RID p_region) const;
|
||||
|
||||
COMMAND_2(region_set_use_edge_connections, RID, p_region, bool, p_enabled);
|
||||
virtual bool region_get_use_edge_connections(RID p_region) const;
|
||||
|
||||
COMMAND_2(region_set_enter_cost, RID, p_region, real_t, p_enter_cost);
|
||||
virtual real_t region_get_enter_cost(RID p_region) const;
|
||||
COMMAND_2(region_set_travel_cost, RID, p_region, real_t, p_travel_cost);
|
||||
virtual real_t region_get_travel_cost(RID p_region) const;
|
||||
COMMAND_2(region_set_owner_id, RID, p_region, ObjectID, p_owner_id);
|
||||
virtual ObjectID region_get_owner_id(RID p_region) const;
|
||||
|
||||
virtual bool region_owns_point(RID p_region, const Vector3 &p_point) const;
|
||||
|
||||
COMMAND_2(region_set_map, RID, p_region, RID, p_map);
|
||||
virtual RID region_get_map(RID p_region) const;
|
||||
COMMAND_2(region_set_navigation_layers, RID, p_region, uint32_t, p_navigation_layers);
|
||||
virtual uint32_t region_get_navigation_layers(RID p_region) const;
|
||||
COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform);
|
||||
COMMAND_2(region_set_navigation_mesh, RID, p_region, Ref<NavigationMesh>, p_navigation_mesh);
|
||||
|
||||
virtual int region_get_connections_count(RID p_region) const;
|
||||
virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const;
|
||||
virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const;
|
||||
|
||||
virtual RID link_create();
|
||||
COMMAND_2(link_set_map, RID, p_link, RID, p_map);
|
||||
virtual RID link_get_map(RID p_link) const;
|
||||
COMMAND_2(link_set_enabled, RID, p_link, bool, p_enabled);
|
||||
virtual bool link_get_enabled(RID p_link) const;
|
||||
COMMAND_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional);
|
||||
virtual bool link_is_bidirectional(RID p_link) const;
|
||||
COMMAND_2(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers);
|
||||
virtual uint32_t link_get_navigation_layers(RID p_link) const;
|
||||
COMMAND_2(link_set_start_position, RID, p_link, Vector3, p_position);
|
||||
virtual Vector3 link_get_start_position(RID p_link) const;
|
||||
COMMAND_2(link_set_end_position, RID, p_link, Vector3, p_position);
|
||||
virtual Vector3 link_get_end_position(RID p_link) const;
|
||||
COMMAND_2(link_set_enter_cost, RID, p_link, real_t, p_enter_cost);
|
||||
virtual real_t link_get_enter_cost(RID p_link) const;
|
||||
COMMAND_2(link_set_travel_cost, RID, p_link, real_t, p_travel_cost);
|
||||
virtual real_t link_get_travel_cost(RID p_link) const;
|
||||
COMMAND_2(link_set_owner_id, RID, p_link, ObjectID, p_owner_id);
|
||||
virtual ObjectID link_get_owner_id(RID p_link) const;
|
||||
|
||||
virtual RID agent_create();
|
||||
COMMAND_2(agent_set_avoidance_enabled, RID, p_agent, bool, p_enabled);
|
||||
virtual bool agent_get_avoidance_enabled(RID p_agent) const;
|
||||
COMMAND_2(agent_set_use_3d_avoidance, RID, p_agent, bool, p_enabled);
|
||||
virtual bool agent_get_use_3d_avoidance(RID p_agent) const;
|
||||
COMMAND_2(agent_set_map, RID, p_agent, RID, p_map);
|
||||
virtual RID agent_get_map(RID p_agent) const;
|
||||
COMMAND_2(agent_set_paused, RID, p_agent, bool, p_paused);
|
||||
virtual bool agent_get_paused(RID p_agent) const;
|
||||
COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_dist);
|
||||
COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count);
|
||||
COMMAND_2(agent_set_time_horizon_agents, RID, p_agent, real_t, p_time_horizon);
|
||||
COMMAND_2(agent_set_time_horizon_obstacles, RID, p_agent, real_t, p_time_horizon);
|
||||
COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius);
|
||||
COMMAND_2(agent_set_height, RID, p_agent, real_t, p_height);
|
||||
COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed);
|
||||
COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity);
|
||||
COMMAND_2(agent_set_velocity_forced, RID, p_agent, Vector3, p_velocity);
|
||||
COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position);
|
||||
virtual bool agent_is_map_changed(RID p_agent) const;
|
||||
COMMAND_4_DEF(agent_set_avoidance_callback, RID, p_agent, ObjectID, p_object_id, StringName, p_method, Variant, p_udata, Variant());
|
||||
|
||||
COMMAND_2(agent_set_avoidance_layers, RID, p_agent, uint32_t, p_layers);
|
||||
COMMAND_2(agent_set_avoidance_mask, RID, p_agent, uint32_t, p_mask);
|
||||
COMMAND_2(agent_set_avoidance_priority, RID, p_agent, real_t, p_priority);
|
||||
|
||||
virtual RID obstacle_create();
|
||||
COMMAND_2(obstacle_set_avoidance_enabled, RID, p_obstacle, bool, p_enabled);
|
||||
virtual bool obstacle_get_avoidance_enabled(RID p_obstacle) const;
|
||||
COMMAND_2(obstacle_set_use_3d_avoidance, RID, p_obstacle, bool, p_enabled);
|
||||
virtual bool obstacle_get_use_3d_avoidance(RID p_obstacle) const;
|
||||
COMMAND_2(obstacle_set_map, RID, p_obstacle, RID, p_map);
|
||||
virtual RID obstacle_get_map(RID p_obstacle) const;
|
||||
COMMAND_2(obstacle_set_radius, RID, p_obstacle, real_t, p_radius);
|
||||
COMMAND_2(obstacle_set_velocity, RID, p_obstacle, Vector3, p_velocity);
|
||||
COMMAND_2(obstacle_set_paused, RID, p_obstacle, bool, p_paused);
|
||||
virtual bool obstacle_get_paused(RID p_obstacle) const;
|
||||
COMMAND_2(obstacle_set_position, RID, p_obstacle, Vector3, p_position);
|
||||
COMMAND_2(obstacle_set_height, RID, p_obstacle, real_t, p_height);
|
||||
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices);
|
||||
COMMAND_2(obstacle_set_avoidance_layers, RID, p_obstacle, uint32_t, p_layers);
|
||||
|
||||
COMMAND_1(free, RID, p_object);
|
||||
|
||||
virtual void set_active(bool p_active);
|
||||
|
||||
void flush_queries();
|
||||
virtual void process(real_t p_delta_time);
|
||||
|
||||
virtual int get_process_info(ProcessInfo p_info) const;
|
||||
|
||||
virtual NavigationUtilities::PathQueryResult _query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const;
|
||||
|
||||
private:
|
||||
void internal_free_agent(RID p_object);
|
||||
void internal_free_obstacle(RID p_object);
|
||||
};
|
||||
|
||||
#undef COMMAND_1
|
||||
#undef COMMAND_2
|
||||
#undef COMMAND_2N
|
||||
#undef COMMAND_4_DEF
|
||||
|
||||
#endif // PANDEMONIUM_NAVIGATION_SERVER_H
|
@ -1,59 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* register_types.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "register_types.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "pandemonium_navigation_server.h"
|
||||
#include "servers/navigation_server.h"
|
||||
|
||||
#include "pandemonium_navigation_2d_server.h"
|
||||
#include "servers/navigation_2d_server.h"
|
||||
|
||||
NavigationServer *new_server() {
|
||||
return memnew(PandemoniumNavigationServer);
|
||||
}
|
||||
|
||||
Navigation2DServer *new_2d_server() {
|
||||
return memnew(PandemoniumNavigation2DServer);
|
||||
}
|
||||
|
||||
void register_navigation_types(ModuleRegistrationLevel p_level) {
|
||||
if (p_level == MODULE_REGISTRATION_LEVEL_SINGLETON) {
|
||||
NavigationServerManager::register_server("PandemoniumNavigation", new_server);
|
||||
NavigationServerManager::set_default_server("PandemoniumNavigation", 10);
|
||||
|
||||
Navigation2DServerManager::register_server("PandemoniumNavigation", new_2d_server);
|
||||
Navigation2DServerManager::set_default_server("PandemoniumNavigation", 10);
|
||||
}
|
||||
}
|
||||
|
||||
void unregister_navigation_types(ModuleRegistrationLevel p_level) {
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
#ifndef NAVIGATION_REGISTER_TYPES_H
|
||||
#define NAVIGATION_REGISTER_TYPES_H
|
||||
|
||||
/*************************************************************************/
|
||||
/* register_types.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "modules/register_module_types.h"
|
||||
|
||||
void register_navigation_types(ModuleRegistrationLevel p_level);
|
||||
void unregister_navigation_types(ModuleRegistrationLevel p_level);
|
||||
|
||||
#endif
|
@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import("env")
|
||||
Import("env_modules")
|
||||
|
||||
env_navigation = env_modules.Clone()
|
||||
|
||||
# Pandemonium source files
|
||||
|
||||
module_obj = []
|
||||
|
||||
env_navigation.add_source_files(module_obj, "*.cpp")
|
||||
|
||||
env.modules_sources += module_obj
|
@ -1,7 +0,0 @@
|
||||
|
||||
def can_build(env, platform):
|
||||
return True
|
||||
|
||||
|
||||
def configure(env):
|
||||
pass
|
@ -1,46 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* navigation_2d_server.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "dummy_navigation_2d_server.h"
|
||||
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
|
||||
void DummyNavigation2DServer::region_set_navigation_polygon(RID p_region, Ref<NavigationPolygon> p_navigation_mesh) {
|
||||
}
|
||||
|
||||
NavigationUtilities::PathQueryResult2D DummyNavigation2DServer::_query_path(const NavigationUtilities::PathQueryParameters2D &p_parameters) const {
|
||||
return NavigationUtilities::PathQueryResult2D();
|
||||
}
|
||||
|
||||
DummyNavigation2DServer::DummyNavigation2DServer() {
|
||||
}
|
||||
|
||||
DummyNavigation2DServer::~DummyNavigation2DServer() {
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
#ifndef DUMMY_NAVIGATION_2D_SERVER_H
|
||||
#define DUMMY_NAVIGATION_2D_SERVER_H
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
#include "servers/navigation_2d_server.h"
|
||||
|
||||
class NavigationPolygon;
|
||||
|
||||
class DummyNavigation2DServer : public Navigation2DServer {
|
||||
public:
|
||||
virtual Array get_maps() const { return Array(); }
|
||||
|
||||
virtual RID map_create() { return RID(); }
|
||||
virtual void map_set_active(RID p_map, bool p_active) {}
|
||||
virtual bool map_is_active(RID p_map) const { return false; }
|
||||
virtual void map_set_cell_size(RID p_map, real_t p_cell_size) {}
|
||||
virtual real_t map_get_cell_size(RID p_map) const { return 0; }
|
||||
virtual void map_set_use_edge_connections(RID p_map, bool p_enabled) {}
|
||||
virtual bool map_get_use_edge_connections(RID p_map) const { return false; }
|
||||
virtual void map_set_edge_connection_margin(RID p_map, real_t p_connection_margin) {}
|
||||
virtual real_t map_get_edge_connection_margin(RID p_map) const { return 0; }
|
||||
|
||||
virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) {}
|
||||
virtual real_t map_get_link_connection_radius(RID p_map) const { return 0; }
|
||||
|
||||
virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const { return Vector<Vector2>(); }
|
||||
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const { return Vector2(); }
|
||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const { return RID(); }
|
||||
|
||||
virtual Array map_get_links(RID p_map) const { return Array(); }
|
||||
virtual Array map_get_regions(RID p_map) const { return Array(); }
|
||||
virtual Array map_get_agents(RID p_map) const { return Array(); }
|
||||
virtual Array map_get_obstacles(RID p_map) const { return Array(); }
|
||||
virtual void map_force_update(RID p_map) {}
|
||||
|
||||
virtual RID region_create() { return RID(); }
|
||||
virtual void region_set_enabled(RID p_region, bool p_enabled) {}
|
||||
virtual bool region_get_enabled(RID p_region) const { return false; }
|
||||
virtual void region_set_use_edge_connections(RID p_region, bool p_enabled) {}
|
||||
virtual bool region_get_use_edge_connections(RID p_region) const { return false; }
|
||||
virtual void region_set_enter_cost(RID p_region, real_t p_enter_cost) {}
|
||||
virtual real_t region_get_enter_cost(RID p_region) const { return 0; }
|
||||
virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) {}
|
||||
virtual real_t region_get_travel_cost(RID p_region) const { return 0; }
|
||||
virtual void region_set_owner_id(RID p_region, ObjectID p_owner_id) {}
|
||||
virtual ObjectID region_get_owner_id(RID p_region) const { return 0; }
|
||||
virtual bool region_owns_point(RID p_region, const Vector2 &p_point) const { return false; }
|
||||
virtual void region_set_map(RID p_region, RID p_map) {}
|
||||
virtual RID region_get_map(RID p_region) const { return RID(); }
|
||||
virtual void region_set_navigation_layers(RID p_region, uint32_t p_navigation_layers) {}
|
||||
virtual uint32_t region_get_navigation_layers(RID p_region) const { return 0; }
|
||||
virtual void region_set_transform(RID p_region, Transform2D p_transform) {}
|
||||
virtual void region_set_navigation_polygon(RID p_region, Ref<NavigationPolygon> p_navigation_mesh);
|
||||
virtual int region_get_connections_count(RID p_region) const { return 0; }
|
||||
virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const { return Vector2(); }
|
||||
virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const { return Vector2(); }
|
||||
|
||||
virtual RID link_create() { return RID(); }
|
||||
virtual void link_set_map(RID p_link, RID p_map) {}
|
||||
virtual RID link_get_map(RID p_link) const { return RID(); }
|
||||
virtual void link_set_enabled(RID p_link, bool p_enabled) {}
|
||||
virtual bool link_get_enabled(RID p_link) const { return false; }
|
||||
virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) {}
|
||||
virtual bool link_is_bidirectional(RID p_link) const { return false; }
|
||||
virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) {}
|
||||
virtual uint32_t link_get_navigation_layers(RID p_link) const { return 0; }
|
||||
virtual void link_set_start_position(RID p_link, Vector2 p_position) {}
|
||||
virtual Vector2 link_get_start_position(RID p_link) const { return Vector2(); }
|
||||
virtual void link_set_end_position(RID p_link, Vector2 p_position) {}
|
||||
virtual Vector2 link_get_end_position(RID p_link) const { return Vector2(); }
|
||||
virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) {}
|
||||
virtual real_t link_get_enter_cost(RID p_link) const { return 0; }
|
||||
virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) {}
|
||||
virtual real_t link_get_travel_cost(RID p_link) const { return 0; }
|
||||
virtual void link_set_owner_id(RID p_link, ObjectID p_owner_id) {}
|
||||
virtual ObjectID link_get_owner_id(RID p_link) const { return 0; }
|
||||
|
||||
virtual RID agent_create() { return RID(); }
|
||||
virtual void agent_set_map(RID p_agent, RID p_map) {}
|
||||
virtual RID agent_get_map(RID p_agent) const { return RID(); }
|
||||
virtual void agent_set_paused(RID p_agent, bool p_paused) {}
|
||||
virtual bool agent_get_paused(RID p_agent) const { return false; }
|
||||
virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) {}
|
||||
virtual bool agent_get_avoidance_enabled(RID p_agent) const { return false; }
|
||||
virtual void agent_set_neighbor_distance(RID p_agent, real_t p_dist) {}
|
||||
virtual void agent_set_max_neighbors(RID p_agent, int p_count) {}
|
||||
virtual void agent_set_time_horizon_agents(RID p_agent, real_t p_time_horizon) {}
|
||||
virtual void agent_set_time_horizon_obstacles(RID p_agent, real_t p_time_horizon) {}
|
||||
virtual void agent_set_radius(RID p_agent, real_t p_radius) {}
|
||||
virtual void agent_set_max_speed(RID p_agent, real_t p_max_speed) {}
|
||||
virtual void agent_set_velocity_forced(RID p_agent, Vector2 p_velocity) {}
|
||||
virtual void agent_set_velocity(RID p_agent, Vector2 p_velocity) {}
|
||||
virtual void agent_set_position(RID p_agent, Vector2 p_position) {}
|
||||
virtual bool agent_is_map_changed(RID p_agent) const { return false; }
|
||||
virtual void agent_set_avoidance_callback(RID p_agent, ObjectID p_object_id, StringName p_method, Variant p_udata = Variant()) {}
|
||||
|
||||
virtual void agent_set_avoidance_layers(RID p_agent, uint32_t p_layers) {}
|
||||
virtual void agent_set_avoidance_mask(RID p_agent, uint32_t p_mask) {}
|
||||
virtual void agent_set_avoidance_priority(RID p_agent, real_t p_priority) {}
|
||||
|
||||
/// Creates the obstacle.
|
||||
virtual RID obstacle_create() { return RID(); }
|
||||
virtual void obstacle_set_map(RID p_obstacle, RID p_map) {}
|
||||
virtual RID obstacle_get_map(RID p_obstacle) const { return RID(); }
|
||||
virtual void obstacle_set_avoidance_enabled(RID p_obstacle, bool p_enabled) {}
|
||||
virtual bool obstacle_get_avoidance_enabled(RID p_obstacle) const { return false; }
|
||||
virtual void obstacle_set_radius(RID p_obstacle, real_t p_radius) {}
|
||||
virtual void obstacle_set_paused(RID p_obstacle, bool p_paused) {}
|
||||
virtual bool obstacle_get_paused(RID p_obstacle) const { return false; }
|
||||
virtual void obstacle_set_velocity(RID p_obstacle, Vector2 p_velocity) {}
|
||||
virtual void obstacle_set_position(RID p_obstacle, Vector2 p_position) {}
|
||||
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices) {}
|
||||
virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers) {}
|
||||
|
||||
virtual void free(RID p_object) {}
|
||||
|
||||
virtual NavigationUtilities::PathQueryResult2D _query_path(const NavigationUtilities::PathQueryParameters2D &p_parameters) const;
|
||||
|
||||
DummyNavigation2DServer();
|
||||
virtual ~DummyNavigation2DServer();
|
||||
};
|
||||
|
||||
#endif
|
@ -1,17 +0,0 @@
|
||||
|
||||
#include "dummy_navigation_server.h"
|
||||
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
|
||||
void DummyNavigationServer::region_set_navigation_mesh(RID p_region, Ref<NavigationMesh> p_navigation_mesh) {
|
||||
}
|
||||
|
||||
NavigationUtilities::PathQueryResult DummyNavigationServer::_query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const {
|
||||
return NavigationUtilities::PathQueryResult();
|
||||
}
|
||||
|
||||
DummyNavigationServer::DummyNavigationServer() {
|
||||
}
|
||||
|
||||
DummyNavigationServer::~DummyNavigationServer() {
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
#ifndef DUMMY_NAVIGATION_SERVER_H
|
||||
#define DUMMY_NAVIGATION_SERVER_H
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
#include "servers/navigation_server.h"
|
||||
|
||||
class NavigationMesh;
|
||||
class DummyNavigationServer : public NavigationServer {
|
||||
public:
|
||||
virtual Array get_maps() const { return Array(); }
|
||||
|
||||
virtual RID map_create() { return RID(); }
|
||||
virtual void map_set_active(RID p_map, bool p_active) {}
|
||||
virtual bool map_is_active(RID p_map) const { return false; }
|
||||
virtual void map_set_up(RID p_map, Vector3 p_up) {}
|
||||
virtual Vector3 map_get_up(RID p_map) const { return Vector3(); }
|
||||
virtual void map_set_cell_size(RID p_map, real_t p_cell_size) {}
|
||||
virtual real_t map_get_cell_size(RID p_map) const { return 0; }
|
||||
virtual void map_set_cell_height(RID p_map, real_t p_cell_height) {}
|
||||
virtual real_t map_get_cell_height(RID p_map) const { return 0; }
|
||||
virtual void map_set_use_edge_connections(RID p_map, bool p_enabled) {}
|
||||
virtual bool map_get_use_edge_connections(RID p_map) const { return false; }
|
||||
virtual void map_set_edge_connection_margin(RID p_map, real_t p_connection_margin) {}
|
||||
virtual real_t map_get_edge_connection_margin(RID p_map) const { return 0; }
|
||||
virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) {}
|
||||
virtual real_t map_get_link_connection_radius(RID p_map) const { return 0; }
|
||||
|
||||
virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const { return Vector<Vector3>(); }
|
||||
virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const { return Vector3(); }
|
||||
virtual Vector3 map_get_closest_point(RID p_map, const Vector3 &p_point) const { return Vector3(); }
|
||||
virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const { return Vector3(); }
|
||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const { return RID(); }
|
||||
|
||||
virtual Array map_get_links(RID p_map) const { return Array(); }
|
||||
virtual Array map_get_regions(RID p_map) const { return Array(); }
|
||||
virtual Array map_get_agents(RID p_map) const { return Array(); }
|
||||
virtual Array map_get_obstacles(RID p_map) const { return Array(); }
|
||||
virtual void map_force_update(RID p_map) {}
|
||||
|
||||
virtual RID region_create() { return RID(); }
|
||||
virtual void region_set_enabled(RID p_region, bool p_enabled) {}
|
||||
virtual bool region_get_enabled(RID p_region) const { return false; }
|
||||
virtual void region_set_use_edge_connections(RID p_region, bool p_enabled) {}
|
||||
virtual bool region_get_use_edge_connections(RID p_region) const { return false; }
|
||||
virtual void region_set_enter_cost(RID p_region, real_t p_enter_cost) {}
|
||||
virtual real_t region_get_enter_cost(RID p_region) const { return 0; }
|
||||
virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) {}
|
||||
virtual real_t region_get_travel_cost(RID p_region) const { return 0; }
|
||||
virtual void region_set_owner_id(RID p_region, ObjectID p_owner_id) {}
|
||||
virtual ObjectID region_get_owner_id(RID p_region) const { return 0; }
|
||||
virtual bool region_owns_point(RID p_region, const Vector3 &p_point) const { return false; }
|
||||
virtual void region_set_map(RID p_region, RID p_map) {}
|
||||
virtual RID region_get_map(RID p_region) const { return RID(); }
|
||||
virtual void region_set_navigation_layers(RID p_region, uint32_t p_navigation_layers) {}
|
||||
virtual uint32_t region_get_navigation_layers(RID p_region) const { return 0; }
|
||||
virtual void region_set_transform(RID p_region, Transform p_transform) {}
|
||||
virtual void region_set_navigation_mesh(RID p_region, Ref<NavigationMesh> p_navigation_mesh);
|
||||
virtual int region_get_connections_count(RID p_region) const { return 0; }
|
||||
virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const { return Vector3(); }
|
||||
virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const { return Vector3(); }
|
||||
|
||||
virtual RID link_create() { return RID(); }
|
||||
virtual void link_set_map(RID p_link, RID p_map) {}
|
||||
virtual RID link_get_map(RID p_link) const { return RID(); }
|
||||
virtual void link_set_enabled(RID p_link, bool p_enabled) {}
|
||||
virtual bool link_get_enabled(RID p_link) const { return false; }
|
||||
virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) {}
|
||||
virtual bool link_is_bidirectional(RID p_link) const { return false; }
|
||||
virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) {}
|
||||
virtual uint32_t link_get_navigation_layers(RID p_link) const { return 0; }
|
||||
virtual void link_set_start_position(RID p_link, Vector3 p_position) {}
|
||||
virtual Vector3 link_get_start_position(RID p_link) const { return Vector3(); }
|
||||
virtual void link_set_end_position(RID p_link, Vector3 p_position) {}
|
||||
virtual Vector3 link_get_end_position(RID p_link) const { return Vector3(); }
|
||||
virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) {}
|
||||
virtual real_t link_get_enter_cost(RID p_link) const { return 0; }
|
||||
virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) {}
|
||||
virtual real_t link_get_travel_cost(RID p_link) const { return 0; }
|
||||
virtual void link_set_owner_id(RID p_link, ObjectID p_owner_id) {}
|
||||
virtual ObjectID link_get_owner_id(RID p_link) const { return 0; }
|
||||
|
||||
virtual RID agent_create() { return RID(); }
|
||||
virtual void agent_set_map(RID p_agent, RID p_map) {}
|
||||
virtual RID agent_get_map(RID p_agent) const { return RID(); }
|
||||
virtual void agent_set_paused(RID p_agent, bool p_paused) {}
|
||||
virtual bool agent_get_paused(RID p_agent) const { return false; }
|
||||
virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) {}
|
||||
virtual bool agent_get_avoidance_enabled(RID p_agent) const { return false; }
|
||||
virtual void agent_set_use_3d_avoidance(RID p_agent, bool p_enabled) {}
|
||||
virtual bool agent_get_use_3d_avoidance(RID p_agent) const { return false; }
|
||||
virtual void agent_set_neighbor_distance(RID p_agent, real_t p_dist) {}
|
||||
virtual void agent_set_max_neighbors(RID p_agent, int p_count) {}
|
||||
virtual void agent_set_time_horizon_agents(RID p_agent, real_t p_time_horizon) {}
|
||||
virtual void agent_set_time_horizon_obstacles(RID p_agent, real_t p_time_horizon) {}
|
||||
virtual void agent_set_radius(RID p_agent, real_t p_radius) {}
|
||||
virtual void agent_set_height(RID p_agent, real_t p_height) {}
|
||||
virtual void agent_set_max_speed(RID p_agent, real_t p_max_speed) {}
|
||||
virtual void agent_set_velocity_forced(RID p_agent, Vector3 p_velocity) {}
|
||||
virtual void agent_set_velocity(RID p_agent, Vector3 p_velocity) {}
|
||||
virtual void agent_set_position(RID p_agent, Vector3 p_position) {}
|
||||
virtual bool agent_is_map_changed(RID p_agent) const { return false; }
|
||||
virtual void agent_set_avoidance_callback(RID p_agent, ObjectID p_object_id, StringName p_method, Variant p_udata = Variant()) {}
|
||||
|
||||
virtual void agent_set_avoidance_layers(RID p_agent, uint32_t p_layers) {}
|
||||
virtual void agent_set_avoidance_mask(RID p_agent, uint32_t p_mask) {}
|
||||
virtual void agent_set_avoidance_priority(RID p_agent, real_t p_priority) {}
|
||||
|
||||
virtual RID obstacle_create() { return RID(); }
|
||||
virtual void obstacle_set_map(RID p_obstacle, RID p_map) {}
|
||||
virtual RID obstacle_get_map(RID p_obstacle) const { return RID(); }
|
||||
virtual void obstacle_set_avoidance_enabled(RID p_obstacle, bool p_enabled) {}
|
||||
virtual bool obstacle_get_avoidance_enabled(RID p_obstacle) const { return false; }
|
||||
virtual void obstacle_set_use_3d_avoidance(RID p_obstacle, bool p_enabled) {}
|
||||
virtual bool obstacle_get_use_3d_avoidance(RID p_obstacle) const { return false; }
|
||||
virtual void obstacle_set_radius(RID p_obstacle, real_t p_radius) {}
|
||||
virtual void obstacle_set_paused(RID p_obstacle, bool p_paused) {}
|
||||
virtual bool obstacle_get_paused(RID p_obstacle) const { return false; }
|
||||
virtual void obstacle_set_height(RID p_obstacle, real_t p_height) {}
|
||||
virtual void obstacle_set_velocity(RID p_obstacle, Vector3 p_velocity) {}
|
||||
virtual void obstacle_set_position(RID p_obstacle, Vector3 p_position) {}
|
||||
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices) {}
|
||||
virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers) {}
|
||||
|
||||
virtual void free(RID p_object){};
|
||||
|
||||
virtual void set_active(bool p_active){};
|
||||
|
||||
virtual void process(real_t delta_time){};
|
||||
|
||||
virtual int get_process_info(ProcessInfo p_info) const { return 0; };
|
||||
|
||||
virtual NavigationUtilities::PathQueryResult _query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const;
|
||||
|
||||
DummyNavigationServer();
|
||||
virtual ~DummyNavigationServer();
|
||||
};
|
||||
|
||||
#endif
|
@ -1,57 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* register_types.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "register_types.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
|
||||
#include "dummy_navigation_2d_server.h"
|
||||
#include "dummy_navigation_server.h"
|
||||
|
||||
NavigationServer *new_dummy_server() {
|
||||
return memnew(DummyNavigationServer);
|
||||
}
|
||||
|
||||
Navigation2DServer *new_dummy_2d_server() {
|
||||
return memnew(DummyNavigation2DServer);
|
||||
}
|
||||
|
||||
void register_navigation_dummy_types(ModuleRegistrationLevel p_level) {
|
||||
if (p_level == MODULE_REGISTRATION_LEVEL_SINGLETON) {
|
||||
NavigationServerManager::register_server("Dummy", new_dummy_server);
|
||||
NavigationServerManager::set_default_server("Dummy");
|
||||
|
||||
Navigation2DServerManager::register_server("Dummy", new_dummy_2d_server);
|
||||
Navigation2DServerManager::set_default_server("Dummy");
|
||||
}
|
||||
}
|
||||
|
||||
void unregister_navigation_dummy_types(ModuleRegistrationLevel p_level) {
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
#ifndef NAVIGATION_DUMMY_REGISTER_TYPES_H
|
||||
#define NAVIGATION_DUMMY_REGISTER_TYPES_H
|
||||
|
||||
/*************************************************************************/
|
||||
/* register_types.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "modules/register_module_types.h"
|
||||
|
||||
void register_navigation_dummy_types(ModuleRegistrationLevel p_level);
|
||||
void unregister_navigation_dummy_types(ModuleRegistrationLevel p_level);
|
||||
|
||||
#endif
|
@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import("env")
|
||||
Import("env_modules")
|
||||
|
||||
env_navigation = env_modules.Clone()
|
||||
|
||||
# Pandemonium source files
|
||||
|
||||
module_obj = []
|
||||
|
||||
env_navigation.add_source_files(module_obj, "*.cpp")
|
||||
env_navigation.add_source_files(module_obj, "geometry_parser_2d/*.cpp")
|
||||
env_navigation.add_source_files(module_obj, "geometry_parser_3d/*.cpp")
|
||||
|
||||
env.modules_sources += module_obj
|
@ -1,9 +0,0 @@
|
||||
|
||||
def can_build(env, platform):
|
||||
#env.module_add_dependencies("navigation_geometry_parsers", ["navigation_mesh_generator"], False)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def configure(env):
|
||||
pass
|
@ -1,115 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* meshinstance2d_navigation_geometry_parser_2d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "meshinstance2d_navigation_geometry_parser_2d.h"
|
||||
|
||||
#include "scene/2d/mesh_instance_2d.h"
|
||||
#include "scene/resources/mesh/mesh.h"
|
||||
|
||||
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
|
||||
bool MeshInstance2DNavigationGeometryParser2D::parses_node(Node *p_node) {
|
||||
return (Object::cast_to<MeshInstance2D>(p_node) != nullptr);
|
||||
}
|
||||
|
||||
void MeshInstance2DNavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) {
|
||||
NavigationPolygon::ParsedGeometryType parsed_geometry_type = p_navigation_polygon->get_parsed_geometry_type();
|
||||
|
||||
if (Object::cast_to<MeshInstance2D>(p_node) && parsed_geometry_type != NavigationPolygon::PARSED_GEOMETRY_STATIC_COLLIDERS) {
|
||||
MeshInstance2D *mesh_instance = Object::cast_to<MeshInstance2D>(p_node);
|
||||
Ref<Mesh> mesh = mesh_instance->get_mesh();
|
||||
if (!mesh.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Transform2D transform = mesh_instance->get_transform();
|
||||
|
||||
Vector<Vector<Point2>> mesh_subject_paths, dummy_clip_paths;
|
||||
|
||||
for (int i = 0; i < mesh->get_surface_count(); i++) {
|
||||
if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(mesh->surface_get_format(i) & Mesh::ARRAY_FLAG_USE_2D_VERTICES)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector<Point2> subject_path;
|
||||
|
||||
int index_count = 0;
|
||||
if (mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) {
|
||||
index_count = mesh->surface_get_array_index_len(i);
|
||||
} else {
|
||||
index_count = mesh->surface_get_array_len(i);
|
||||
}
|
||||
|
||||
ERR_CONTINUE((index_count == 0 || (index_count % 3) != 0));
|
||||
|
||||
Array a = mesh->surface_get_arrays(i);
|
||||
|
||||
Vector<Vector2> mesh_vertices = a[Mesh::ARRAY_VERTEX];
|
||||
|
||||
if (mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) {
|
||||
Vector<int> mesh_indices = a[Mesh::ARRAY_INDEX];
|
||||
for (int j = 0; j < mesh_indices.size(); ++j) {
|
||||
int vertex_index = mesh_indices[j];
|
||||
|
||||
const Vector2 &vertex = mesh_vertices[vertex_index];
|
||||
subject_path.push_back(vertex);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < mesh_vertices.size(); ++j) {
|
||||
const Vector2 &vertex = mesh_vertices[j];
|
||||
subject_path.push_back(vertex);
|
||||
}
|
||||
}
|
||||
mesh_subject_paths.push_back(subject_path);
|
||||
}
|
||||
|
||||
Vector<Vector<Point2>> mesh_path_solution = Geometry::merge_all2_polygons_2d(mesh_subject_paths, dummy_clip_paths, Geometry::POLYGON_FILL_TYPE_NON_ZERO);
|
||||
|
||||
Vector<Vector<Vector2>> polypaths;
|
||||
|
||||
for (int k = 0; k < mesh_path_solution.size(); ++k) {
|
||||
const Vector<Point2> &mesh_path = mesh_path_solution[k];
|
||||
|
||||
PoolVector<Vector2> shape_outline;
|
||||
|
||||
for (int j = 0; j < mesh_path.size(); j++) {
|
||||
const Vector2 &mesh_path_point = mesh_path[j];
|
||||
shape_outline.push_back(transform.xform(mesh_path_point));
|
||||
}
|
||||
|
||||
p_source_geometry->add_obstruction_outline(shape_outline);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* meshinstance2d_navigation_geometry_parser_2d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef MESHINSTANCE2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
||||
#define MESHINSTANCE2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
||||
|
||||
#include "scene/2d/navigation_geometry_parser_2d.h"
|
||||
|
||||
class MeshInstance2DNavigationGeometryParser2D : public NavigationGeometryParser2D {
|
||||
public:
|
||||
virtual bool parses_node(Node *p_node) ;
|
||||
|
||||
virtual void parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) ;
|
||||
};
|
||||
|
||||
#endif // MESHINSTANCE2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
@ -1,122 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* multimeshinstance2d_navigation_geometry_parser_2d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "multimeshinstance2d_navigation_geometry_parser_2d.h"
|
||||
|
||||
#include "core/math/geometry.h"
|
||||
#include "scene/2d/multimesh_instance_2d.h"
|
||||
#include "scene/resources/mesh/multimesh.h"
|
||||
|
||||
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
|
||||
bool MultiMeshInstance2DNavigationGeometryParser2D::parses_node(Node *p_node) {
|
||||
return (Object::cast_to<MultiMeshInstance2D>(p_node) != nullptr);
|
||||
}
|
||||
|
||||
void MultiMeshInstance2DNavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) {
|
||||
NavigationPolygon::ParsedGeometryType parsed_geometry_type = p_navigation_polygon->get_parsed_geometry_type();
|
||||
|
||||
if (Object::cast_to<MultiMeshInstance2D>(p_node) && parsed_geometry_type != NavigationPolygon::PARSED_GEOMETRY_STATIC_COLLIDERS) {
|
||||
MultiMeshInstance2D *multimesh_instance = Object::cast_to<MultiMeshInstance2D>(p_node);
|
||||
Ref<MultiMesh> multimesh = multimesh_instance->get_multimesh();
|
||||
if (multimesh.is_valid() && multimesh->get_transform_format() == MultiMesh::TRANSFORM_2D) {
|
||||
Ref<Mesh> mesh = multimesh->get_mesh();
|
||||
if (mesh.is_valid()) {
|
||||
Vector<Vector<Point2>> mesh_subject_paths, dummy_clip_paths;
|
||||
|
||||
for (int i = 0; i < mesh->get_surface_count(); i++) {
|
||||
if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(mesh->surface_get_format(i) & Mesh::ARRAY_FLAG_USE_2D_VERTICES)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector<Point2> subject_path;
|
||||
|
||||
int index_count = 0;
|
||||
if (mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) {
|
||||
index_count = mesh->surface_get_array_index_len(i);
|
||||
} else {
|
||||
index_count = mesh->surface_get_array_len(i);
|
||||
}
|
||||
|
||||
ERR_CONTINUE((index_count == 0 || (index_count % 3) != 0));
|
||||
|
||||
Array a = mesh->surface_get_arrays(i);
|
||||
|
||||
Vector<Vector2> mesh_vertices = a[Mesh::ARRAY_VERTEX];
|
||||
|
||||
if (mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) {
|
||||
Vector<int> mesh_indices = a[Mesh::ARRAY_INDEX];
|
||||
|
||||
for (int j = 0; j < mesh_indices.size(); ++j) {
|
||||
int vertex_index = mesh_indices[j];
|
||||
const Vector2 &vertex = mesh_vertices[vertex_index];
|
||||
subject_path.push_back(vertex);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < mesh_vertices.size(); ++j) {
|
||||
const Vector2 &vertex = mesh_vertices[j];
|
||||
subject_path.push_back(vertex);
|
||||
}
|
||||
}
|
||||
mesh_subject_paths.push_back(subject_path);
|
||||
}
|
||||
|
||||
Vector<Vector<Point2>> mesh_path_solution = Geometry::merge_all2_polygons_2d(mesh_subject_paths, dummy_clip_paths, Geometry::POLYGON_FILL_TYPE_NON_ZERO);
|
||||
|
||||
int multimesh_instance_count = multimesh->get_visible_instance_count();
|
||||
if (multimesh_instance_count == -1) {
|
||||
multimesh_instance_count = multimesh->get_instance_count();
|
||||
}
|
||||
|
||||
for (int i = 0; i < multimesh_instance_count; i++) {
|
||||
const Transform2D multimesh_instance_transform = multimesh_instance->get_transform() * multimesh->get_instance_transform_2d(i);
|
||||
|
||||
for (int k = 0; k < mesh_path_solution.size(); ++k) {
|
||||
const Vector<Point2> &mesh_path = mesh_path_solution[k];
|
||||
|
||||
PoolVector<Vector2> shape_outline;
|
||||
|
||||
for (int j = 0; j < mesh_path.size(); j++) {
|
||||
const Vector2 &mesh_path_point = mesh_path[j];
|
||||
shape_outline.push_back(multimesh_instance_transform.xform(mesh_path_point));
|
||||
}
|
||||
|
||||
p_source_geometry->add_obstruction_outline(shape_outline);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* multimeshinstance2d_navigation_geometry_parser_2d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef MULTIMESHINSTANCE2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
||||
#define MULTIMESHINSTANCE2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
||||
|
||||
#include "scene/2d/navigation_geometry_parser_2d.h"
|
||||
|
||||
class MultiMeshInstance2DNavigationGeometryParser2D : public NavigationGeometryParser2D {
|
||||
public:
|
||||
virtual bool parses_node(Node *p_node) ;
|
||||
|
||||
virtual void parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) ;
|
||||
};
|
||||
|
||||
#endif // MULTIMESHINSTANCE2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
@ -1,58 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* polygon2d_navigation_geometry_parser_2d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "polygon2d_navigation_geometry_parser_2d.h"
|
||||
|
||||
#include "scene/2d/polygon_2d.h"
|
||||
|
||||
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
|
||||
bool Polygon2DNavigationGeometryParser2D::parses_node(Node *p_node) {
|
||||
return (Object::cast_to<Polygon2D>(p_node) != nullptr);
|
||||
}
|
||||
|
||||
void Polygon2DNavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) {
|
||||
NavigationPolygon::ParsedGeometryType parsed_geometry_type = p_navigation_polygon->get_parsed_geometry_type();
|
||||
|
||||
if (Object::cast_to<Polygon2D>(p_node) && parsed_geometry_type != NavigationPolygon::PARSED_GEOMETRY_STATIC_COLLIDERS) {
|
||||
Polygon2D *polygon_2d = Object::cast_to<Polygon2D>(p_node);
|
||||
|
||||
const Transform2D transform = polygon_2d->get_global_transform();
|
||||
|
||||
PoolVector<Vector2> shape_outline = polygon_2d->get_polygon();
|
||||
PoolVector<Vector2>::Write shape_outline_write = shape_outline.write();
|
||||
for (int i = 0; i < shape_outline.size(); i++) {
|
||||
shape_outline_write[i] = transform.xform(shape_outline[i]);
|
||||
}
|
||||
|
||||
p_source_geometry->add_obstruction_outline(shape_outline);
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* polygon2d_navigation_geometry_parser_2d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef POLYGON2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
||||
#define POLYGON2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
||||
|
||||
#include "scene/2d/navigation_geometry_parser_2d.h"
|
||||
|
||||
class Polygon2DNavigationGeometryParser2D : public NavigationGeometryParser2D {
|
||||
public:
|
||||
virtual bool parses_node(Node *p_node);
|
||||
|
||||
virtual void parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry);
|
||||
};
|
||||
|
||||
#endif // POLYGON2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
@ -1,158 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* staticbody2d_navigation_geometry_parser_2d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "staticbody2d_navigation_geometry_parser_2d.h"
|
||||
|
||||
#include "core/math/convex_hull.h"
|
||||
#include "scene/2d/mesh_instance_2d.h"
|
||||
#include "scene/2d/physics_body_2d.h"
|
||||
#include "scene/resources/shapes_2d/capsule_shape_2d.h"
|
||||
#include "scene/resources/shapes_2d/circle_shape_2d.h"
|
||||
#include "scene/resources/shapes_2d/concave_polygon_shape_2d.h"
|
||||
#include "scene/resources/shapes_2d/convex_polygon_shape_2d.h"
|
||||
#include "scene/resources/shapes_2d/rectangle_shape_2d.h"
|
||||
#include "scene/resources/shapes_2d/shape_2d.h"
|
||||
|
||||
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
|
||||
bool StaticBody2DNavigationGeometryParser2D::parses_node(Node *p_node) {
|
||||
return (Object::cast_to<StaticBody2D>(p_node) != nullptr);
|
||||
}
|
||||
|
||||
void StaticBody2DNavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) {
|
||||
NavigationPolygon::ParsedGeometryType parsed_geometry_type = p_navigation_polygon->get_parsed_geometry_type();
|
||||
uint32_t navigation_polygon_collision_mask = p_navigation_polygon->get_collision_mask();
|
||||
|
||||
if (Object::cast_to<StaticBody2D>(p_node) && parsed_geometry_type != NavigationPolygon::PARSED_GEOMETRY_MESH_INSTANCES) {
|
||||
StaticBody2D *static_body = Object::cast_to<StaticBody2D>(p_node);
|
||||
if (static_body->get_collision_layer() & navigation_polygon_collision_mask) {
|
||||
List<uint32_t> shape_owners;
|
||||
static_body->get_shape_owners(&shape_owners);
|
||||
|
||||
for (List<uint32_t>::Element *E = shape_owners.front(); E; E = E->next()) {
|
||||
uint32_t shape_owner = E->get();
|
||||
|
||||
if (static_body->is_shape_owner_disabled(shape_owner)) {
|
||||
continue;
|
||||
}
|
||||
const int shape_count = static_body->shape_owner_get_shape_count(shape_owner);
|
||||
for (int shape_index = 0; shape_index < shape_count; shape_index++) {
|
||||
Ref<Shape2D> s = static_body->shape_owner_get_shape(shape_owner, shape_index);
|
||||
|
||||
if (s.is_null()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Transform2D transform = static_body->get_transform() * static_body->shape_owner_get_transform(shape_owner);
|
||||
|
||||
RectangleShape2D *rectangle_shape = Object::cast_to<RectangleShape2D>(*s);
|
||||
if (rectangle_shape) {
|
||||
PoolVector<Vector2> shape_outline;
|
||||
|
||||
const Vector2 rectangle_size = rectangle_shape->get_extents();
|
||||
|
||||
shape_outline.resize(5);
|
||||
PoolVector<Vector2>::Write shape_outline_write = shape_outline.write();
|
||||
shape_outline_write[0] = transform.xform(-rectangle_size);
|
||||
shape_outline_write[1] = transform.xform(Vector2(rectangle_size.x, -rectangle_size.y));
|
||||
shape_outline_write[2] = transform.xform(rectangle_size);
|
||||
shape_outline_write[3] = transform.xform(Vector2(-rectangle_size.x, rectangle_size.y));
|
||||
shape_outline_write[4] = transform.xform(-rectangle_size);
|
||||
|
||||
p_source_geometry->add_obstruction_outline(shape_outline);
|
||||
}
|
||||
|
||||
CapsuleShape2D *capsule_shape = Object::cast_to<CapsuleShape2D>(*s);
|
||||
if (capsule_shape) {
|
||||
PoolVector<Vector2> shape_outline;
|
||||
|
||||
Vector<Vector2> points = capsule_shape->get_points();
|
||||
|
||||
shape_outline.resize(points.size() + 1);
|
||||
PoolVector<Vector2>::Write shape_outline_write = shape_outline.write();
|
||||
|
||||
for (int i = 0; i < points.size(); ++i) {
|
||||
shape_outline_write[i] = transform.xform(points[i]);
|
||||
}
|
||||
|
||||
if (points.size() > 0) {
|
||||
shape_outline_write[points.size()] = transform.xform(points[0]);
|
||||
}
|
||||
|
||||
p_source_geometry->add_obstruction_outline(shape_outline);
|
||||
}
|
||||
|
||||
CircleShape2D *circle_shape = Object::cast_to<CircleShape2D>(*s);
|
||||
if (circle_shape) {
|
||||
PoolVector<Vector2> shape_outline;
|
||||
int circle_edge_count = 12;
|
||||
shape_outline.resize(circle_edge_count);
|
||||
PoolVector<Vector2>::Write shape_outline_write = shape_outline.write();
|
||||
|
||||
const real_t turn_step = Math_TAU / real_t(circle_edge_count);
|
||||
for (int i = 0; i < circle_edge_count; i++) {
|
||||
shape_outline_write[i] = transform.xform(Vector2(Math::cos(i * turn_step), Math::sin(i * turn_step)) * circle_shape->get_radius());
|
||||
}
|
||||
|
||||
p_source_geometry->add_obstruction_outline(shape_outline);
|
||||
}
|
||||
|
||||
ConcavePolygonShape2D *concave_polygon_shape = Object::cast_to<ConcavePolygonShape2D>(*s);
|
||||
if (concave_polygon_shape) {
|
||||
PoolVector<Vector2> shape_outline = concave_polygon_shape->get_segments();
|
||||
PoolVector<Vector2>::Write shape_outline_write = shape_outline.write();
|
||||
|
||||
for (int i = 0; i < shape_outline.size(); i++) {
|
||||
shape_outline_write[i] = transform.xform(shape_outline[i]);
|
||||
}
|
||||
|
||||
p_source_geometry->add_obstruction_outline(shape_outline);
|
||||
}
|
||||
|
||||
ConvexPolygonShape2D *convex_polygon_shape = Object::cast_to<ConvexPolygonShape2D>(*s);
|
||||
if (convex_polygon_shape) {
|
||||
Vector<Vector2> shape_outlinev = convex_polygon_shape->get_points();
|
||||
|
||||
PoolVector<Vector2> shape_outline;
|
||||
shape_outline.resize(shape_outlinev.size());
|
||||
PoolVector<Vector2>::Write shape_outline_write = shape_outline.write();
|
||||
|
||||
for (int i = 0; i < shape_outline.size(); i++) {
|
||||
shape_outline_write[i] = transform.xform(shape_outlinev[i]);
|
||||
}
|
||||
|
||||
p_source_geometry->add_obstruction_outline(shape_outline);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* staticbody2d_navigation_geometry_parser_2d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef STATICBODY2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
||||
#define STATICBODY2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
||||
|
||||
#include "scene/2d/navigation_geometry_parser_2d.h"
|
||||
|
||||
class StaticBody2DNavigationGeometryParser2D : public NavigationGeometryParser2D {
|
||||
public:
|
||||
virtual bool parses_node(Node *p_node);
|
||||
|
||||
virtual void parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry);
|
||||
};
|
||||
|
||||
#endif // STATICBODY2D_NAVIGATION_GEOMETRY_PARSER_2D_H
|
@ -1,53 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* register_types.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "register_types.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
|
||||
#include "servers/navigation/navigation_mesh_generator.h"
|
||||
|
||||
#include "geometry_parser_2d/meshinstance2d_navigation_geometry_parser_2d.h"
|
||||
#include "geometry_parser_2d/multimeshinstance2d_navigation_geometry_parser_2d.h"
|
||||
#include "geometry_parser_2d/polygon2d_navigation_geometry_parser_2d.h"
|
||||
#include "geometry_parser_2d/staticbody2d_navigation_geometry_parser_2d.h"
|
||||
|
||||
|
||||
void register_navigation_geometry_parsers_types(ModuleRegistrationLevel p_level) {
|
||||
if (p_level == MODULE_REGISTRATION_LEVEL_SCENE) {
|
||||
NavigationMeshGenerator::get_singleton()->register_geometry_parser_2d(memnew(MeshInstance2DNavigationGeometryParser2D));
|
||||
NavigationMeshGenerator::get_singleton()->register_geometry_parser_2d(memnew(MultiMeshInstance2DNavigationGeometryParser2D));
|
||||
NavigationMeshGenerator::get_singleton()->register_geometry_parser_2d(memnew(Polygon2DNavigationGeometryParser2D));
|
||||
NavigationMeshGenerator::get_singleton()->register_geometry_parser_2d(memnew(StaticBody2DNavigationGeometryParser2D));
|
||||
}
|
||||
}
|
||||
|
||||
void unregister_navigation_geometry_parsers_types(ModuleRegistrationLevel p_level) {
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
#ifndef NAVIGATION_GEOMETRY_PARSERS_H
|
||||
#define NAVIGATION_GEOMETRY_PARSERS_H
|
||||
|
||||
/*************************************************************************/
|
||||
/* register_types.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "modules/register_module_types.h"
|
||||
|
||||
void register_navigation_geometry_parsers_types(ModuleRegistrationLevel p_level);
|
||||
void unregister_navigation_geometry_parsers_types(ModuleRegistrationLevel p_level);
|
||||
|
||||
#endif
|
@ -1,51 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import("env")
|
||||
Import("env_modules")
|
||||
|
||||
env_navigation_mesh_generator = env_modules.Clone()
|
||||
|
||||
# Thirdparty source files
|
||||
|
||||
#thirdparty_obj = []
|
||||
|
||||
# Recast Thirdparty source files
|
||||
if env["builtin_recast"]:
|
||||
thirdparty_dir = "#thirdparty/recastnavigation/Recast/"
|
||||
|
||||
#thirdparty_sources = [
|
||||
# "Source/Recast.cpp",
|
||||
# "Source/RecastAlloc.cpp",
|
||||
# "Source/RecastArea.cpp",
|
||||
# "Source/RecastAssert.cpp",
|
||||
# "Source/RecastContour.cpp",
|
||||
# "Source/RecastFilter.cpp",
|
||||
# "Source/RecastLayers.cpp",
|
||||
# "Source/RecastMesh.cpp",
|
||||
# "Source/RecastMeshDetail.cpp",
|
||||
# "Source/RecastRasterization.cpp",
|
||||
# "Source/RecastRegion.cpp",
|
||||
#]
|
||||
#thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
env_navigation_mesh_generator.Prepend(CPPPATH=[thirdparty_dir + "Include"])
|
||||
|
||||
#env_thirdparty = env_navigation_mesh_generator.Clone()
|
||||
#env_thirdparty.disable_warnings()
|
||||
#env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
|
||||
|
||||
#env.modules_sources += thirdparty_obj
|
||||
|
||||
# Godot source files
|
||||
|
||||
module_obj = []
|
||||
|
||||
env_navigation_mesh_generator.add_source_files(module_obj, "*.cpp")
|
||||
|
||||
if env["tools"]:
|
||||
env_navigation_mesh_generator.add_source_files(module_obj, "editor/*.cpp")
|
||||
|
||||
env.modules_sources += module_obj
|
||||
|
||||
# Needed to force rebuilding the module files when the thirdparty library is updated.
|
||||
#env.Depends(module_obj, thirdparty_obj)
|
@ -1,10 +0,0 @@
|
||||
|
||||
|
||||
def can_build(env, platform):
|
||||
env.module_add_dependencies("navigation_mesh_generator", ["navigation"], False)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def configure(env):
|
||||
pass
|
@ -1,446 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* godot_navigation_mesh_generator.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Pandemonium 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "pandemonium_navigation_mesh_generator.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/core_string_names.h"
|
||||
|
||||
#include "scene/2d/navigation_geometry_parser_2d.h"
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
#include <Recast.h>
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
// todo port p_navigation_polygon->get_source_geometry_mode()
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::NavigationGeneratorTask2D::call_callback() {
|
||||
if (callback.is_valid() && callback->is_valid()) {
|
||||
Array arr;
|
||||
arr.push_back(navigation_polygon);
|
||||
callback->call_funcv(arr);
|
||||
}
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::NavigationGeneratorTask2D::_execute() {
|
||||
if (navigation_polygon.is_null() || source_geometry_data.is_null() || !source_geometry_data->has_data()) {
|
||||
set_complete(true);
|
||||
return;
|
||||
}
|
||||
|
||||
_static_bake_2d_from_source_geometry_data(navigation_polygon, source_geometry_data);
|
||||
|
||||
set_complete(true);
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::NavigationGeneratorTask2D::_bind_methods() {
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::process() {
|
||||
_generator_mutex.lock();
|
||||
|
||||
_process_2d_tasks();
|
||||
|
||||
_generator_mutex.unlock();
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::cleanup() {
|
||||
_baking_navigation_polygons.clear();
|
||||
_geometry_2d_parsers.clear();
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_process_2d_tasks() {
|
||||
if (_2d_parse_jobs.size() == 0 && _2d_running_jobs.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
_process_2d_parse_tasks();
|
||||
_process_2d_bake_cleanup_tasks();
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_process_2d_parse_tasks() {
|
||||
// Note that this cannot be parallelized in a simple way, because we need mainloop to not delete nodes under it while processing.
|
||||
// If parallelization is implemented, it needs to wait for the tasks to complete. (Like in the original pr.)
|
||||
// Also the RenderingServer has locks that need the main thread to be active, so it can deadlock.
|
||||
|
||||
// TODO implement ThreadPool like max processing per frame support
|
||||
|
||||
if (_2d_parse_jobs.size() > 0) {
|
||||
while (_2d_parse_jobs.size() > 0) {
|
||||
Ref<NavigationGeneratorTask2D> navigation_generator_task = _2d_parse_jobs[0];
|
||||
|
||||
_2d_parse_jobs.remove(0);
|
||||
|
||||
if (navigation_generator_task.is_null()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Ref<NavigationPolygon> navigation_polygon = navigation_generator_task->navigation_polygon;
|
||||
Ref<NavigationMeshSourceGeometryData2D> source_geometry_data = navigation_generator_task->source_geometry_data;
|
||||
ObjectID parse_root_object_id = navigation_generator_task->parse_root_object_id;
|
||||
|
||||
if (navigation_polygon.is_null() || parse_root_object_id == ObjectID()) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
navigation_generator_task->call_callback();
|
||||
continue;
|
||||
}
|
||||
Object *parse_root_obj = ObjectDB::get_instance(parse_root_object_id);
|
||||
if (parse_root_obj == nullptr) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
navigation_generator_task->call_callback();
|
||||
return;
|
||||
}
|
||||
Node *parse_root_node = Object::cast_to<Node>(parse_root_obj);
|
||||
if (parse_root_node == nullptr) {
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FAILED;
|
||||
navigation_generator_task->call_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
_static_parse_2d_source_geometry_data(navigation_polygon, parse_root_node, source_geometry_data, navigation_generator_task->geometry_parsers);
|
||||
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_FINISHED;
|
||||
|
||||
// Submit resulting class To threadpool
|
||||
navigation_generator_task->set_complete(false);
|
||||
if (_use_thread_pool) {
|
||||
ThreadPool::get_singleton()->add_job(navigation_generator_task);
|
||||
} else {
|
||||
navigation_generator_task->execute();
|
||||
}
|
||||
_2d_running_jobs.push_back(navigation_generator_task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_process_2d_bake_cleanup_tasks() {
|
||||
for (uint32_t i = 0; i < _2d_running_jobs.size(); ++i) {
|
||||
Ref<NavigationGeneratorTask2D> &e = _2d_running_jobs[i];
|
||||
|
||||
if (e->get_complete()) {
|
||||
_2d_running_jobs.remove_unordered(i);
|
||||
--i;
|
||||
|
||||
int indx = _baking_navigation_polygons.find(e->navigation_polygon);
|
||||
_baking_navigation_polygons.remove_unordered(indx);
|
||||
|
||||
e->call_callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::register_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser) {
|
||||
_generator_mutex.lock();
|
||||
if (_geometry_2d_parsers.find(p_geometry_parser) < 0) {
|
||||
_geometry_2d_parsers.push_back(p_geometry_parser);
|
||||
}
|
||||
_generator_mutex.unlock();
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::unregister_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser) {
|
||||
_generator_mutex.lock();
|
||||
_geometry_2d_parsers.erase(p_geometry_parser);
|
||||
_generator_mutex.unlock();
|
||||
}
|
||||
|
||||
Ref<NavigationMeshSourceGeometryData2D> PandemoniumNavigationMeshGenerator::parse_2d_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback) {
|
||||
ERR_FAIL_COND_V_MSG(!p_navigation_polygon.is_valid(), Ref<NavigationMeshSourceGeometryData2D>(), "Invalid navigation mesh.");
|
||||
ERR_FAIL_COND_V_MSG(p_root_node == nullptr, Ref<NavigationMeshSourceGeometryData2D>(), "No parsing root node specified.");
|
||||
|
||||
ObjectID root_node_object_id = p_root_node->get_instance_id();
|
||||
ERR_FAIL_COND_V_MSG(root_node_object_id == ObjectID(), Ref<NavigationMeshSourceGeometryData2D>(), "No root node object invalid.");
|
||||
|
||||
Ref<NavigationMeshSourceGeometryData2D> source_geometry_data = Ref<NavigationMeshSourceGeometryData2D>(memnew(NavigationMeshSourceGeometryData2D));
|
||||
|
||||
_static_parse_2d_source_geometry_data(p_navigation_polygon, p_root_node, source_geometry_data, _geometry_2d_parsers);
|
||||
|
||||
return source_geometry_data;
|
||||
};
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::bake_2d_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, Ref<FuncRef> p_callback) {
|
||||
ERR_FAIL_COND_MSG(!p_navigation_polygon.is_valid(), "Invalid navigation mesh.");
|
||||
ERR_FAIL_COND_MSG(!p_source_geometry_data.is_valid(), "Invalid NavigationMeshSourceGeometryData2D.");
|
||||
ERR_FAIL_COND_MSG(p_navigation_polygon->get_outline_count() == 0 && !p_source_geometry_data->has_data(), "NavigationMeshSourceGeometryData2D is empty. Parse source geometry first.");
|
||||
ERR_FAIL_COND_MSG(_baking_navigation_polygons.find(p_navigation_polygon) >= 0, "NavigationPolygon is already baking. Wait for current bake task to finish.");
|
||||
|
||||
_generator_mutex.lock();
|
||||
_baking_navigation_polygons.push_back(p_navigation_polygon);
|
||||
_generator_mutex.unlock();
|
||||
|
||||
_static_bake_2d_from_source_geometry_data(p_navigation_polygon, p_source_geometry_data);
|
||||
|
||||
_generator_mutex.lock();
|
||||
int64_t navigation_polygon_index = _baking_navigation_polygons.find(p_navigation_polygon);
|
||||
if (navigation_polygon_index >= 0) {
|
||||
_baking_navigation_polygons.remove_unordered(navigation_polygon_index);
|
||||
}
|
||||
_generator_mutex.unlock();
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_static_parse_2d_geometry_node(Ref<NavigationPolygon> p_navigation_polygon, Node *p_node, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, bool p_recurse_children, LocalVector<Ref<NavigationGeometryParser2D>> &p_geometry_2d_parsers) {
|
||||
for (uint32_t i = 0; i < p_geometry_2d_parsers.size(); ++i) {
|
||||
Ref<NavigationGeometryParser2D> &geometry_2d_parser = p_geometry_2d_parsers[i];
|
||||
|
||||
if (geometry_2d_parser->parses_node(p_node)) {
|
||||
geometry_2d_parser->parse_node_geometry(p_navigation_polygon, p_node, p_source_geometry_data);
|
||||
};
|
||||
};
|
||||
|
||||
if (p_recurse_children) {
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
_static_parse_2d_geometry_node(p_navigation_polygon, p_node->get_child(i), p_source_geometry_data, p_recurse_children, p_geometry_2d_parsers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_static_parse_2d_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, LocalVector<Ref<NavigationGeometryParser2D>> &p_geometry_2d_parsers) {
|
||||
ERR_FAIL_COND_MSG(!p_navigation_polygon.is_valid(), "Invalid navigation polygon.");
|
||||
ERR_FAIL_COND_MSG(p_root_node == nullptr, "Invalid parse root node.");
|
||||
ERR_FAIL_COND_MSG(!p_source_geometry_data.is_valid(), "Invalid source geometry data.");
|
||||
|
||||
List<Node *> parse_nodes;
|
||||
|
||||
if (p_navigation_polygon->get_source_geometry_mode() == NavigationPolygon::SOURCE_GEOMETRY_ROOT_NODE_CHILDREN) {
|
||||
parse_nodes.push_back(p_root_node);
|
||||
} else {
|
||||
p_root_node->get_tree()->get_nodes_in_group(p_navigation_polygon->get_source_group_name(), &parse_nodes);
|
||||
}
|
||||
|
||||
Transform2D root_node_transform = Object::cast_to<Node2D>(p_root_node)->get_global_transform().affine_inverse();
|
||||
bool recurse_children = p_navigation_polygon->get_source_geometry_mode() != NavigationPolygon::SOURCE_GEOMETRY_GROUPS_EXPLICIT;
|
||||
|
||||
p_source_geometry_data->clear();
|
||||
p_source_geometry_data->root_node_transform = root_node_transform;
|
||||
|
||||
for (List<Node *>::Element *E = parse_nodes.front(); E; E = E->next()) {
|
||||
_static_parse_2d_geometry_node(p_navigation_polygon, E->get(), p_source_geometry_data, recurse_children, p_geometry_2d_parsers);
|
||||
}
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::_static_bake_2d_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data) {
|
||||
ERR_FAIL_COND_MSG(!p_navigation_polygon.is_valid(), "Invalid navigation polygon.");
|
||||
ERR_FAIL_COND_MSG(!p_source_geometry_data.is_valid(), "Invalid source geometry data.");
|
||||
ERR_FAIL_COND_MSG(p_navigation_polygon->get_outline_count() == 0 && !p_source_geometry_data->has_data(), "NavigationMeshSourceGeometryData2D is empty. Parse source geometry first.");
|
||||
|
||||
const Vector<Vector<Vector2>> &traversable_outlines = p_source_geometry_data->_get_traversable_outlines();
|
||||
const Vector<Vector<Vector2>> &obstruction_outlines = p_source_geometry_data->_get_obstruction_outlines();
|
||||
|
||||
int outline_count = p_navigation_polygon->get_outline_count();
|
||||
|
||||
Vector<Vector<Point2>> s_traversable_polygon_paths;
|
||||
|
||||
for (int i = 0; i < outline_count; i++) {
|
||||
PoolVector<Vector2> traversable_outline = p_navigation_polygon->get_outline(i);
|
||||
Vector<Point2> subject_path;
|
||||
for (int j = 0; j < traversable_outline.size(); ++j) {
|
||||
Vector2 traversable_point = traversable_outline[j];
|
||||
subject_path.push_back(traversable_point);
|
||||
}
|
||||
s_traversable_polygon_paths.push_back(subject_path);
|
||||
}
|
||||
|
||||
Vector<Vector<Point2>> s_traversable_outlines;
|
||||
|
||||
for (int i = 0; i < traversable_outlines.size(); i++) {
|
||||
Vector<Vector2> traversable_outline = traversable_outlines[i];
|
||||
|
||||
Vector<Point2> subject_path;
|
||||
for (int j = 0; j < traversable_outline.size(); ++j) {
|
||||
Vector2 traversable_point = traversable_outline[j];
|
||||
subject_path.push_back(traversable_point);
|
||||
}
|
||||
s_traversable_outlines.push_back(subject_path);
|
||||
}
|
||||
|
||||
Vector<Vector<Point2>> s_obstruction_polygon_paths;
|
||||
|
||||
for (int i = 0; i < obstruction_outlines.size(); i++) {
|
||||
Vector<Vector2> obstruction_outline = obstruction_outlines[i];
|
||||
|
||||
Vector<Point2> clip_path;
|
||||
|
||||
for (int j = 0; j < obstruction_outline.size(); ++j) {
|
||||
Vector2 traversable_point = obstruction_outline[j];
|
||||
clip_path.push_back(traversable_point);
|
||||
}
|
||||
s_obstruction_polygon_paths.push_back(clip_path);
|
||||
}
|
||||
|
||||
Geometry::PolygonFillType geom_fillrule = Geometry::POLYGON_FILL_TYPE_EVEN_ODD;
|
||||
|
||||
switch (p_navigation_polygon->get_polygon_bake_fillrule()) {
|
||||
case NavigationPolygon::POLYGON_FILLRULE_EVENODD: {
|
||||
geom_fillrule = Geometry::POLYGON_FILL_TYPE_EVEN_ODD;
|
||||
} break;
|
||||
case NavigationPolygon::POLYGON_FILLRULE_NONZERO: {
|
||||
geom_fillrule = Geometry::POLYGON_FILL_TYPE_NON_ZERO;
|
||||
} break;
|
||||
case NavigationPolygon::POLYGON_FILLRULE_POSITIVE: {
|
||||
geom_fillrule = Geometry::POLYGON_FILL_TYPE_POSITIVE;
|
||||
} break;
|
||||
case NavigationPolygon::POLYGON_FILLRULE_NEGATIVE: {
|
||||
geom_fillrule = Geometry::POLYGON_FILL_TYPE_NEGATIVE;
|
||||
} break;
|
||||
default: {
|
||||
WARN_PRINT_ONCE("No match for used NavigationPolygon::POLYGON_FILLRULE - fallback to default");
|
||||
geom_fillrule = Geometry::POLYGON_FILL_TYPE_EVEN_ODD;
|
||||
} break;
|
||||
}
|
||||
|
||||
// first merge all traversable polygons according to user specified fill rule
|
||||
s_traversable_polygon_paths = Geometry::merge_all_polygons_2d(s_traversable_polygon_paths, Vector<Point2>(), geom_fillrule);
|
||||
// merge all obstruction polygons, don't allow holes for what is considered "solid" 2D geometry
|
||||
s_obstruction_polygon_paths = Geometry::merge_all_polygons_2d(s_obstruction_polygon_paths, Vector<Point2>(), Geometry::POLYGON_FILL_TYPE_NON_ZERO);
|
||||
|
||||
Vector<Vector<Point2>> s_path_solution;
|
||||
s_path_solution = Geometry::clip_all2_polygons_2d(s_traversable_polygon_paths, s_obstruction_polygon_paths, geom_fillrule);
|
||||
|
||||
// Seems to be bugged when dealing with 2d
|
||||
/*
|
||||
JoinType clipper_jointype = JoinType::Square;
|
||||
|
||||
switch (p_navigation_polygon->get_offsetting_jointype()) {
|
||||
case NavigationPolygon::OFFSETTING_JOINTYPE_SQUARE: {
|
||||
clipper_jointype = JoinType::Square;
|
||||
} break;
|
||||
case NavigationPolygon::OFFSETTING_JOINTYPE_ROUND: {
|
||||
clipper_jointype = JoinType::Round;
|
||||
} break;
|
||||
case NavigationPolygon::OFFSETTING_JOINTYPE_MITER: {
|
||||
clipper_jointype = JoinType::Miter;
|
||||
} break;
|
||||
default: {
|
||||
WARN_PRINT_ONCE("No match for used NavigationPolygon::OFFSETTING_JOINTYPE - fallback to default");
|
||||
clipper_jointype = JoinType::Square;
|
||||
} break;
|
||||
}
|
||||
|
||||
real_t agent_radius_offset = p_navigation_polygon->get_agent_radius();
|
||||
if (agent_radius_offset > 0.0) {
|
||||
path_solution = InflatePaths(path_solution, -agent_radius_offset, clipper_jointype, EndType::Polygon);
|
||||
}
|
||||
*/
|
||||
//path_solution = RamerDouglasPeucker(path_solution, 0.025); //
|
||||
|
||||
Vector<PoolVector<Vector2>> new_baked_outlines;
|
||||
|
||||
for (int i = 0; i < s_path_solution.size(); i++) {
|
||||
const Vector<Point2> &scaled_path = s_path_solution[i];
|
||||
|
||||
PoolVector<Vector2> polypath;
|
||||
for (int j = 0; j < scaled_path.size(); ++j) {
|
||||
const Vector2 &scaled_point = scaled_path[j];
|
||||
|
||||
polypath.push_back(Vector2(static_cast<real_t>(scaled_point.x), static_cast<real_t>(scaled_point.y)));
|
||||
}
|
||||
|
||||
new_baked_outlines.push_back(polypath);
|
||||
}
|
||||
|
||||
p_navigation_polygon->set_baked_outlines(new_baked_outlines);
|
||||
|
||||
if (new_baked_outlines.size() == 0) {
|
||||
p_navigation_polygon->set_vertices(PoolVector<Vector2>());
|
||||
p_navigation_polygon->set_polygons(Vector<Vector<int>>());
|
||||
p_navigation_polygon->commit_changes();
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<Vector<Point2>> s_polygon_paths;
|
||||
|
||||
for (int i = 0; i < new_baked_outlines.size(); i++) {
|
||||
const PoolVector<Vector2> &baked_outline = new_baked_outlines[i];
|
||||
|
||||
Vector<Point2> polygon_path;
|
||||
for (int j = 0; j < baked_outline.size(); ++j) {
|
||||
const Vector2 &baked_outline_point = baked_outline[j];
|
||||
polygon_path.push_back(baked_outline_point);
|
||||
}
|
||||
s_polygon_paths.push_back(polygon_path);
|
||||
}
|
||||
|
||||
PoolVector<Vector2> s_new_vertices;
|
||||
Vector<Vector<int>> s_new_polygons;
|
||||
|
||||
if (!Geometry::merge_convex_decompose_polygon_2d(s_polygon_paths, s_new_vertices, s_new_polygons)) {
|
||||
ERR_PRINT("NavigationPolygon Convex partition failed. Unable to create a valid NavigationMesh from defined polygon outline paths.");
|
||||
p_navigation_polygon->set_vertices(PoolVector<Vector2>());
|
||||
p_navigation_polygon->set_polygons(Vector<Vector<int>>());
|
||||
p_navigation_polygon->commit_changes();
|
||||
return;
|
||||
}
|
||||
|
||||
p_navigation_polygon->set_vertices(s_new_vertices);
|
||||
p_navigation_polygon->set_polygons(s_new_polygons);
|
||||
p_navigation_polygon->commit_changes();
|
||||
}
|
||||
|
||||
void PandemoniumNavigationMeshGenerator::parse_and_bake_2d(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback) {
|
||||
ERR_FAIL_COND_MSG(_baking_navigation_polygons.find(p_navigation_polygon) >= 0, "NavigationPolygon was already added to baking queue. Wait for current bake task to finish.");
|
||||
ERR_FAIL_COND_MSG(p_root_node == nullptr, "NavigationPolygon requires a valid root node.");
|
||||
|
||||
_generator_mutex.lock();
|
||||
_baking_navigation_polygons.push_back(p_navigation_polygon);
|
||||
_generator_mutex.unlock();
|
||||
|
||||
Ref<NavigationGeneratorTask2D> navigation_generator_task;
|
||||
navigation_generator_task.instance();
|
||||
navigation_generator_task->navigation_polygon = p_navigation_polygon;
|
||||
navigation_generator_task->parse_root_object_id = p_root_node->get_instance_id();
|
||||
navigation_generator_task->source_geometry_data = Ref<NavigationMeshSourceGeometryData2D>(memnew(NavigationMeshSourceGeometryData2D));
|
||||
navigation_generator_task->callback = p_callback;
|
||||
navigation_generator_task->status = NavigationGeneratorTask2D::TaskStatus::PARSING_REQUIRED;
|
||||
navigation_generator_task->geometry_parsers = _geometry_2d_parsers;
|
||||
|
||||
_generator_mutex.lock();
|
||||
_2d_parse_jobs.push_back(navigation_generator_task);
|
||||
_generator_mutex.unlock();
|
||||
}
|
||||
|
||||
bool PandemoniumNavigationMeshGenerator::is_navigation_polygon_baking(Ref<NavigationPolygon> p_navigation_polygon) const {
|
||||
ERR_FAIL_COND_V(!p_navigation_polygon.is_valid(), false);
|
||||
return _baking_navigation_polygons.find(p_navigation_polygon) >= 0;
|
||||
}
|
||||
|
||||
PandemoniumNavigationMeshGenerator::PandemoniumNavigationMeshGenerator() {
|
||||
_use_thread_pool = GLOBAL_GET("navigation/baking/thread_model/use_thread_pool");
|
||||
// Can't use threads in Editor as parsing gets stuck on RenderingServer / PhysicsServer locks.
|
||||
// (TODO needs to be tested) The way I have it now, it should work.
|
||||
//_use_thread_pool = !Engine::get_singleton()->is_editor_hint();
|
||||
|
||||
//_baking_use_high_priority_threads = GLOBAL_DEF("navigation/baking/thread_model/baking_use_high_priority_threads");
|
||||
}
|
||||
|
||||
PandemoniumNavigationMeshGenerator::~PandemoniumNavigationMeshGenerator() {
|
||||
cleanup();
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
#ifndef PANDEMONIUM_NAVIGATION_MESH_GENERATOR_H
|
||||
#define PANDEMONIUM_NAVIGATION_MESH_GENERATOR_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* godot_navigation_mesh_generator.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Pandemonium 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "servers/navigation/navigation_mesh_generator.h"
|
||||
|
||||
#include "core/os/thread_pool.h"
|
||||
#include "core/os/thread_pool_job.h"
|
||||
|
||||
#include "core/object/func_ref.h"
|
||||
|
||||
class NavigationPolygon;
|
||||
class NavigationMeshSourceGeometryData2D;
|
||||
class NavigationGeometryParser2D;
|
||||
class NavigationMeshSourceGeometryData3D;
|
||||
class NavigationGeometryParser3D;
|
||||
|
||||
class PandemoniumNavigationMeshGenerator : public NavigationMeshGenerator {
|
||||
GDCLASS(PandemoniumNavigationMeshGenerator, NavigationMeshGenerator);
|
||||
|
||||
public:
|
||||
// ======= TASKS =======
|
||||
|
||||
class NavigationGeneratorTask2D : public ThreadPoolJob {
|
||||
GDCLASS(NavigationGeneratorTask2D, ThreadPoolJob);
|
||||
|
||||
public:
|
||||
enum TaskStatus {
|
||||
PARSING_REQUIRED,
|
||||
PARSING_STARTED,
|
||||
PARSING_FINISHED,
|
||||
PARSING_FAILED,
|
||||
BAKING_STARTED,
|
||||
BAKING_FINISHED,
|
||||
BAKING_FAILED,
|
||||
};
|
||||
|
||||
Ref<NavigationPolygon> navigation_polygon;
|
||||
ObjectID parse_root_object_id;
|
||||
Ref<NavigationMeshSourceGeometryData2D> source_geometry_data;
|
||||
Ref<FuncRef> callback;
|
||||
NavigationGeneratorTask2D::TaskStatus status = NavigationGeneratorTask2D::TaskStatus::PARSING_REQUIRED;
|
||||
LocalVector<Ref<NavigationGeometryParser2D>> geometry_parsers;
|
||||
|
||||
void call_callback();
|
||||
|
||||
void _execute();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
// ======= TASKS END =======
|
||||
|
||||
public:
|
||||
virtual void process();
|
||||
virtual void cleanup();
|
||||
|
||||
// 2D ////////////////////////////////////
|
||||
virtual void register_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser);
|
||||
virtual void unregister_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser);
|
||||
|
||||
virtual Ref<NavigationMeshSourceGeometryData2D> parse_2d_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback = Ref<FuncRef>());
|
||||
virtual void bake_2d_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, Ref<FuncRef> p_callback = Ref<FuncRef>());
|
||||
|
||||
virtual void parse_and_bake_2d(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback = Ref<FuncRef>());
|
||||
|
||||
static void _static_parse_2d_geometry_node(Ref<NavigationPolygon> p_navigation_polygon, Node *p_node, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, bool p_recurse_children, LocalVector<Ref<NavigationGeometryParser2D>> &p_geometry_2d_parsers);
|
||||
static void _static_parse_2d_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, LocalVector<Ref<NavigationGeometryParser2D>> &p_geometry_2d_parsers);
|
||||
static void _static_bake_2d_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data);
|
||||
|
||||
virtual bool is_navigation_polygon_baking(Ref<NavigationPolygon> p_navigation_polygon) const;
|
||||
|
||||
PandemoniumNavigationMeshGenerator();
|
||||
~PandemoniumNavigationMeshGenerator();
|
||||
|
||||
private:
|
||||
void _process_2d_tasks();
|
||||
void _process_2d_parse_tasks();
|
||||
void _process_2d_bake_cleanup_tasks();
|
||||
|
||||
private:
|
||||
Mutex _generator_mutex;
|
||||
|
||||
bool _use_thread_pool = true;
|
||||
// TODO implement support into ThreadPool
|
||||
//bool _baking_use_high_priority_threads = true;
|
||||
|
||||
LocalVector<Ref<NavigationGeometryParser2D>> _geometry_2d_parsers;
|
||||
|
||||
LocalVector<Ref<NavigationPolygon>> _baking_navigation_polygons;
|
||||
LocalVector<Ref<NavigationGeneratorTask2D>> _2d_parse_jobs;
|
||||
LocalVector<Ref<NavigationGeneratorTask2D>> _2d_running_jobs;
|
||||
};
|
||||
|
||||
#endif // GODOT_NAVIGATION_MESH_GENERATOR_H
|
@ -1,52 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* register_types.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "register_types.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "servers/navigation/navigation_mesh_generator.h"
|
||||
|
||||
#include "pandemonium_navigation_mesh_generator.h"
|
||||
|
||||
NavigationMeshGenerator *new_navigation_mesh_generator_server() {
|
||||
return memnew(PandemoniumNavigationMeshGenerator);
|
||||
}
|
||||
|
||||
void register_navigation_mesh_generator_types(ModuleRegistrationLevel p_level) {
|
||||
if (p_level == MODULE_REGISTRATION_LEVEL_SERVER) {
|
||||
NavigationMeshGeneratorManager::get_singleton()->register_server("PandemoniumNavigationMeshGenerator", new_navigation_mesh_generator_server);
|
||||
NavigationMeshGeneratorManager::get_singleton()->set_default_server("PandemoniumNavigationMeshGenerator");
|
||||
}
|
||||
}
|
||||
|
||||
void unregister_navigation_mesh_generator_types(ModuleRegistrationLevel p_level) {
|
||||
if (p_level == MODULE_REGISTRATION_LEVEL_SERVER) {
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
#ifndef NAVIGATION_MESH_GENERATOR_REGISTER_TYPES_H
|
||||
#define NAVIGATION_MESH_GENERATOR_REGISTER_TYPES_H
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* register_types.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "modules/register_module_types.h"
|
||||
|
||||
void register_navigation_mesh_generator_types(ModuleRegistrationLevel p_level);
|
||||
void unregister_navigation_mesh_generator_types(ModuleRegistrationLevel p_level);
|
||||
|
||||
#endif // NAVIGATION_MESH_GENERATOR_REGISTER_TYPES_H
|
@ -1,116 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* navigation_2d.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "navigation_2d.h"
|
||||
|
||||
#include "scene/2d/navigation_polygon_instance.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
#include "servers/navigation_2d_server.h"
|
||||
|
||||
void Navigation2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_rid"), &Navigation2D::get_rid);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation2D::get_closest_point);
|
||||
ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation2D::get_closest_point_owner);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation2D::set_cell_size);
|
||||
ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation2D::get_cell_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation2D::set_edge_connection_margin);
|
||||
ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation2D::get_edge_connection_margin);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &Navigation2D::set_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layers"), &Navigation2D::get_navigation_layers);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size"), "set_cell_size", "get_cell_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
|
||||
}
|
||||
|
||||
void Navigation2D::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_READY: {
|
||||
Navigation2DServer::get_singleton()->map_set_active(map, true);
|
||||
} break;
|
||||
// FIXME 3.5 with this old navigation 2d node only
|
||||
// if the node gets deleted this exit causes annoying error prints in debug
|
||||
// It tries to deactivate a map that itself has send a free command to the server.
|
||||
//case NOTIFICATION_EXIT_TREE: {
|
||||
// Navigation2DServer::get_singleton()->map_set_active(map, false);
|
||||
//} break;
|
||||
}
|
||||
}
|
||||
|
||||
void Navigation2D::set_cell_size(float p_cell_size) {
|
||||
cell_size = p_cell_size;
|
||||
Navigation2DServer::get_singleton()->map_set_cell_size(map, cell_size);
|
||||
}
|
||||
|
||||
void Navigation2D::set_edge_connection_margin(float p_edge_connection_margin) {
|
||||
edge_connection_margin = p_edge_connection_margin;
|
||||
Navigation2DServer::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin);
|
||||
}
|
||||
|
||||
Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) const {
|
||||
return Navigation2DServer::get_singleton()->map_get_path(map, p_start, p_end, p_optimize, navigation_layers);
|
||||
}
|
||||
|
||||
Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) const {
|
||||
return Navigation2DServer::get_singleton()->map_get_closest_point(map, p_point);
|
||||
}
|
||||
|
||||
RID Navigation2D::get_closest_point_owner(const Vector2 &p_point) const {
|
||||
return Navigation2DServer::get_singleton()->map_get_closest_point_owner(map, p_point);
|
||||
}
|
||||
|
||||
void Navigation2D::set_navigation_layers(uint32_t p_navigation_layers) {
|
||||
navigation_layers = p_navigation_layers;
|
||||
}
|
||||
|
||||
uint32_t Navigation2D::get_navigation_layers() const {
|
||||
return navigation_layers;
|
||||
}
|
||||
|
||||
Navigation2D::Navigation2D() {
|
||||
cell_size = 1.0;
|
||||
edge_connection_margin = 1.0;
|
||||
navigation_layers = 1;
|
||||
|
||||
map = Navigation2DServer::get_singleton()->map_create();
|
||||
|
||||
Navigation2DServer::get_singleton()->map_set_active(map, true);
|
||||
Navigation2DServer::get_singleton()->map_set_cell_size(map, get_cell_size());
|
||||
Navigation2DServer::get_singleton()->map_set_edge_connection_margin(map, get_edge_connection_margin());
|
||||
}
|
||||
|
||||
Navigation2D::~Navigation2D() {
|
||||
Navigation2DServer::get_singleton()->free(map);
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
#ifndef NAVIGATION_2D_H
|
||||
#define NAVIGATION_2D_H
|
||||
/*************************************************************************/
|
||||
/* navigation_2d.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "scene/main/node_2d.h"
|
||||
|
||||
class Navigation2D : public Node2D {
|
||||
GDCLASS(Navigation2D, Node2D);
|
||||
|
||||
RID map;
|
||||
real_t cell_size;
|
||||
real_t edge_connection_margin;
|
||||
uint32_t navigation_layers;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
RID get_rid() const {
|
||||
return map;
|
||||
}
|
||||
|
||||
void set_cell_size(float p_cell_size);
|
||||
float get_cell_size() const {
|
||||
return cell_size;
|
||||
}
|
||||
|
||||
void set_navigation_layers(uint32_t p_navigation_layers);
|
||||
uint32_t get_navigation_layers() const;
|
||||
|
||||
void set_edge_connection_margin(float p_edge_connection_margin);
|
||||
float get_edge_connection_margin() const {
|
||||
return edge_connection_margin;
|
||||
}
|
||||
|
||||
Vector<Vector2> get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize = true) const;
|
||||
Vector2 get_closest_point(const Vector2 &p_point) const;
|
||||
RID get_closest_point_owner(const Vector2 &p_point) const;
|
||||
|
||||
Navigation2D();
|
||||
~Navigation2D();
|
||||
};
|
||||
|
||||
#endif // NAVIGATION_2D_H
|
@ -1,957 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* navigation_agent_2d.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "navigation_agent_2d.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "core/containers/vector.h"
|
||||
#include "scene/2d/navigation_2d.h"
|
||||
#include "scene/2d/navigation_link_2d.h"
|
||||
#include "scene/resources/world_2d.h"
|
||||
#include "servers/navigation/navigation_path_query_result_2d.h"
|
||||
#include "servers/navigation_2d_server.h"
|
||||
|
||||
void NavigationAgent2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_rid"), &NavigationAgent2D::get_rid);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_enabled", "enabled"), &NavigationAgent2D::set_avoidance_enabled);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_enabled"), &NavigationAgent2D::get_avoidance_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_desired_distance", "desired_distance"), &NavigationAgent2D::set_path_desired_distance);
|
||||
ClassDB::bind_method(D_METHOD("get_path_desired_distance"), &NavigationAgent2D::get_path_desired_distance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent2D::set_target_desired_distance);
|
||||
ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent2D::get_target_desired_distance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationAgent2D::set_radius);
|
||||
ClassDB::bind_method(D_METHOD("get_radius"), &NavigationAgent2D::get_radius);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent2D::set_navigation_node);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent2D::get_navigation_node);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_neighbor_distance", "neighbor_distance"), &NavigationAgent2D::set_neighbor_distance);
|
||||
ClassDB::bind_method(D_METHOD("get_neighbor_distance"), &NavigationAgent2D::get_neighbor_distance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_max_neighbors", "max_neighbors"), &NavigationAgent2D::set_max_neighbors);
|
||||
ClassDB::bind_method(D_METHOD("get_max_neighbors"), &NavigationAgent2D::get_max_neighbors);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_time_horizon_agents", "time_horizon"), &NavigationAgent2D::set_time_horizon_agents);
|
||||
ClassDB::bind_method(D_METHOD("get_time_horizon_agents"), &NavigationAgent2D::get_time_horizon_agents);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_time_horizon_obstacles", "time_horizon"), &NavigationAgent2D::set_time_horizon_obstacles);
|
||||
ClassDB::bind_method(D_METHOD("get_time_horizon_obstacles"), &NavigationAgent2D::get_time_horizon_obstacles);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_max_speed", "max_speed"), &NavigationAgent2D::set_max_speed);
|
||||
ClassDB::bind_method(D_METHOD("get_max_speed"), &NavigationAgent2D::get_max_speed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_max_distance", "max_speed"), &NavigationAgent2D::set_path_max_distance);
|
||||
ClassDB::bind_method(D_METHOD("get_path_max_distance"), &NavigationAgent2D::get_path_max_distance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationAgent2D::set_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationAgent2D::get_navigation_layers);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationAgent2D::set_navigation_layer_value);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationAgent2D::get_navigation_layer_value);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationAgent2D::set_pathfinding_algorithm);
|
||||
ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationAgent2D::get_pathfinding_algorithm);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_postprocessing", "path_postprocessing"), &NavigationAgent2D::set_path_postprocessing);
|
||||
ClassDB::bind_method(D_METHOD("get_path_postprocessing"), &NavigationAgent2D::get_path_postprocessing);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_metadata_flags", "flags"), &NavigationAgent2D::set_path_metadata_flags);
|
||||
ClassDB::bind_method(D_METHOD("get_path_metadata_flags"), &NavigationAgent2D::get_path_metadata_flags);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent2D::set_navigation_map);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent2D::get_navigation_map);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_target_position", "position"), &NavigationAgent2D::set_target_position);
|
||||
ClassDB::bind_method(D_METHOD("get_target_position"), &NavigationAgent2D::get_target_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_next_position"), &NavigationAgent2D::get_next_position);
|
||||
ClassDB::bind_method(D_METHOD("set_velocity_forced", "velocity"), &NavigationAgent2D::set_velocity_forced);
|
||||
ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent2D::set_velocity);
|
||||
ClassDB::bind_method(D_METHOD("get_velocity"), &NavigationAgent2D::get_velocity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent2D::distance_to_target);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_current_navigation_result"), &NavigationAgent2D::get_current_navigation_result);
|
||||
ClassDB::bind_method(D_METHOD("get_current_navigation_path"), &NavigationAgent2D::get_current_navigation_path);
|
||||
ClassDB::bind_method(D_METHOD("get_current_navigation_path_index"), &NavigationAgent2D::get_current_navigation_path_index);
|
||||
ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent2D::is_target_reached);
|
||||
ClassDB::bind_method(D_METHOD("is_target_reachable"), &NavigationAgent2D::is_target_reachable);
|
||||
ClassDB::bind_method(D_METHOD("is_navigation_finished"), &NavigationAgent2D::is_navigation_finished);
|
||||
ClassDB::bind_method(D_METHOD("get_final_position"), &NavigationAgent2D::get_final_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent2D::_avoidance_done);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_layers", "layers"), &NavigationAgent2D::set_avoidance_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_layers"), &NavigationAgent2D::get_avoidance_layers);
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_mask", "mask"), &NavigationAgent2D::set_avoidance_mask);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_mask"), &NavigationAgent2D::get_avoidance_mask);
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_layer_value", "layer_number", "value"), &NavigationAgent2D::set_avoidance_layer_value);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_layer_value", "layer_number"), &NavigationAgent2D::get_avoidance_layer_value);
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_mask_value", "mask_number", "value"), &NavigationAgent2D::set_avoidance_mask_value);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_mask_value", "mask_number"), &NavigationAgent2D::get_avoidance_mask_value);
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_priority", "priority"), &NavigationAgent2D::set_avoidance_priority);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_priority"), &NavigationAgent2D::get_avoidance_priority);
|
||||
|
||||
ADD_GROUP("Pathfinding", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_target_position", "get_target_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,or_greater,suffix:px"), "set_path_desired_distance", "get_path_desired_distance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,or_greater,suffix:px"), "set_target_desired_distance", "get_target_desired_distance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "10,1000,1,or_greater,suffix:px"), "set_path_max_distance", "get_path_max_distance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags");
|
||||
|
||||
ADD_GROUP("Avoidance", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_velocity", "get_velocity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01,or_greater,suffix:px"), "set_radius", "get_radius");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "neighbor_distance", PROPERTY_HINT_RANGE, "0.1,100000,0.01,or_greater,suffix:px"), "set_neighbor_distance", "get_neighbor_distance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1,or_greater"), "set_max_neighbors", "get_max_neighbors");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_horizon_agents", PROPERTY_HINT_RANGE, "0.0,10,0.01,or_greater,suffix:s"), "set_time_horizon_agents", "get_time_horizon_agents");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_horizon_obstacles", PROPERTY_HINT_RANGE, "0.0,10,0.01,or_greater,suffix:s"), "set_time_horizon_obstacles", "get_time_horizon_obstacles");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.01,10000,0.01,or_greater,suffix:px/s"), "set_max_speed", "get_max_speed");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "avoidance_layers", PROPERTY_HINT_LAYERS_AVOIDANCE), "set_avoidance_layers", "get_avoidance_layers");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "avoidance_mask", PROPERTY_HINT_LAYERS_AVOIDANCE), "set_avoidance_mask", "get_avoidance_mask");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "avoidance_priority", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_avoidance_priority", "get_avoidance_priority");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationAgent2D::set_debug_enabled);
|
||||
ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationAgent2D::get_debug_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_debug_use_custom", "enabled"), &NavigationAgent2D::set_debug_use_custom);
|
||||
ClassDB::bind_method(D_METHOD("get_debug_use_custom"), &NavigationAgent2D::get_debug_use_custom);
|
||||
ClassDB::bind_method(D_METHOD("set_debug_path_custom_color", "color"), &NavigationAgent2D::set_debug_path_custom_color);
|
||||
ClassDB::bind_method(D_METHOD("get_debug_path_custom_color"), &NavigationAgent2D::get_debug_path_custom_color);
|
||||
ClassDB::bind_method(D_METHOD("set_debug_path_custom_point_size", "point_size"), &NavigationAgent2D::set_debug_path_custom_point_size);
|
||||
ClassDB::bind_method(D_METHOD("get_debug_path_custom_point_size"), &NavigationAgent2D::get_debug_path_custom_point_size);
|
||||
ClassDB::bind_method(D_METHOD("set_debug_path_custom_line_width", "line_width"), &NavigationAgent2D::set_debug_path_custom_line_width);
|
||||
ClassDB::bind_method(D_METHOD("get_debug_path_custom_line_width"), &NavigationAgent2D::get_debug_path_custom_line_width);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
ClassDB::bind_method(D_METHOD("_navigation_debug_changed"), &NavigationAgent2D::_navigation_debug_changed);
|
||||
#endif
|
||||
|
||||
ADD_GROUP("Debug", "debug_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_enabled"), "set_debug_enabled", "get_debug_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_use_custom"), "set_debug_use_custom", "get_debug_use_custom");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_path_custom_color"), "set_debug_path_custom_color", "get_debug_path_custom_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "debug_path_custom_point_size", PROPERTY_HINT_RANGE, "0,50,0.01,or_greater,suffix:px"), "set_debug_path_custom_point_size", "get_debug_path_custom_point_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "debug_path_custom_line_width", PROPERTY_HINT_RANGE, "-1,50,0.01,or_greater,suffix:px"), "set_debug_path_custom_line_width", "get_debug_path_custom_line_width");
|
||||
|
||||
ADD_SIGNAL(MethodInfo("path_changed"));
|
||||
ADD_SIGNAL(MethodInfo("target_reached"));
|
||||
ADD_SIGNAL(MethodInfo("waypoint_reached", PropertyInfo(Variant::DICTIONARY, "details")));
|
||||
ADD_SIGNAL(MethodInfo("link_reached", PropertyInfo(Variant::DICTIONARY, "details")));
|
||||
ADD_SIGNAL(MethodInfo("navigation_finished"));
|
||||
ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR2, "safe_velocity")));
|
||||
}
|
||||
|
||||
void NavigationAgent2D::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_POST_ENTER_TREE: {
|
||||
// Search the navigation node and set it
|
||||
{
|
||||
Navigation2D *nav = nullptr;
|
||||
Node *p = get_parent();
|
||||
while (p != nullptr) {
|
||||
nav = Object::cast_to<Navigation2D>(p);
|
||||
if (nav != nullptr) {
|
||||
p = nullptr;
|
||||
} else {
|
||||
p = p->get_parent();
|
||||
}
|
||||
}
|
||||
|
||||
set_navigation(nav);
|
||||
}
|
||||
|
||||
// need to use POST_ENTER_TREE cause with normal ENTER_TREE not all required Nodes are ready.
|
||||
// cannot use READY as ready does not get called if Node is readded to SceneTree
|
||||
set_agent_parent(get_parent());
|
||||
set_physics_process_internal(true);
|
||||
|
||||
if (agent_parent && avoidance_enabled) {
|
||||
Navigation2DServer::get_singleton()->agent_set_position(agent, agent_parent->get_global_position());
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (Navigation2DServer::get_singleton()->get_debug_enabled()) {
|
||||
debug_path_dirty = true;
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
} break;
|
||||
case NOTIFICATION_PARENTED: {
|
||||
if (is_inside_tree() && (get_parent() != agent_parent)) {
|
||||
// only react to PARENTED notifications when already inside_tree and parent changed, e.g. users switch nodes around
|
||||
// PARENTED notification fires also when Node is added in scripts to a parent
|
||||
// this would spam transforms fails and world fails while Node is outside SceneTree
|
||||
// when node gets reparented when joining the tree POST_ENTER_TREE takes care of this
|
||||
set_agent_parent(get_parent());
|
||||
set_physics_process_internal(true);
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_UNPARENTED: {
|
||||
// if agent has no parent no point in processing it until reparented
|
||||
set_agent_parent(nullptr);
|
||||
set_physics_process_internal(false);
|
||||
} break;
|
||||
case NOTIFICATION_PAUSED: {
|
||||
if (agent_parent) {
|
||||
Navigation2DServer::get_singleton()->agent_set_paused(get_rid(), !agent_parent->can_process());
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_UNPAUSED: {
|
||||
if (agent_parent) {
|
||||
Navigation2DServer::get_singleton()->agent_set_paused(get_rid(), !agent_parent->can_process());
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
set_agent_parent(nullptr);
|
||||
set_navigation(nullptr);
|
||||
set_physics_process_internal(false);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (debug_path_instance.is_valid()) {
|
||||
RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, false);
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
} break;
|
||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||
if (agent_parent && avoidance_enabled) {
|
||||
Navigation2DServer::get_singleton()->agent_set_position(agent, agent_parent->get_global_position());
|
||||
}
|
||||
|
||||
if (agent_parent && target_position_submitted) {
|
||||
if (velocity_submitted) {
|
||||
velocity_submitted = false;
|
||||
if (avoidance_enabled) {
|
||||
Navigation2DServer::get_singleton()->agent_set_velocity(agent, velocity);
|
||||
}
|
||||
}
|
||||
if (velocity_forced_submitted) {
|
||||
velocity_forced_submitted = false;
|
||||
if (avoidance_enabled) {
|
||||
Navigation2DServer::get_singleton()->agent_set_velocity_forced(agent, velocity_forced);
|
||||
}
|
||||
}
|
||||
_check_distance_to_target();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (debug_path_dirty) {
|
||||
_update_debug_path();
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
NavigationAgent2D::NavigationAgent2D() {
|
||||
agent_parent = nullptr;
|
||||
navigation = nullptr;
|
||||
|
||||
avoidance_enabled = false;
|
||||
avoidance_layers = 1;
|
||||
avoidance_mask = 1;
|
||||
avoidance_priority = 1.0;
|
||||
navigation_layers = 1;
|
||||
pathfinding_algorithm = NavigationPathQueryParameters2D::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR;
|
||||
path_postprocessing = NavigationPathQueryParameters2D::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
path_metadata_flags = NavigationPathQueryParameters2D::PATH_METADATA_INCLUDE_ALL;
|
||||
|
||||
path_desired_distance = 20.0;
|
||||
target_desired_distance = 10.0;
|
||||
radius = 10.0;
|
||||
neighbor_distance = 500.0;
|
||||
max_neighbors = 10;
|
||||
time_horizon_agents = 1.0;
|
||||
time_horizon_obstacles = 0;
|
||||
max_speed = 100.0;
|
||||
path_max_distance = 100.0;
|
||||
|
||||
velocity_submitted = false;
|
||||
target_reached = false;
|
||||
navigation_finished = true;
|
||||
|
||||
velocity_forced_submitted = false;
|
||||
target_position_submitted = false;
|
||||
|
||||
nav_path_index = 0;
|
||||
update_frame_id = 0;
|
||||
|
||||
agent = Navigation2DServer::get_singleton()->agent_create();
|
||||
|
||||
Navigation2DServer::get_singleton()->agent_set_neighbor_distance(agent, neighbor_distance);
|
||||
Navigation2DServer::get_singleton()->agent_set_max_neighbors(agent, max_neighbors);
|
||||
Navigation2DServer::get_singleton()->agent_set_time_horizon_agents(agent, time_horizon_agents);
|
||||
Navigation2DServer::get_singleton()->agent_set_time_horizon_obstacles(agent, time_horizon_obstacles);
|
||||
Navigation2DServer::get_singleton()->agent_set_radius(agent, radius);
|
||||
Navigation2DServer::get_singleton()->agent_set_max_speed(agent, max_speed);
|
||||
|
||||
navigation_query.instance();
|
||||
navigation_result.instance();
|
||||
|
||||
set_avoidance_layers(avoidance_layers);
|
||||
set_avoidance_mask(avoidance_mask);
|
||||
set_avoidance_priority(avoidance_priority);
|
||||
set_avoidance_enabled(avoidance_enabled);
|
||||
|
||||
debug_enabled = false;
|
||||
debug_path_dirty = true;
|
||||
debug_path_custom_point_size = 4.0;
|
||||
debug_path_custom_line_width = -1.0;
|
||||
debug_use_custom = false;
|
||||
debug_path_custom_color = Color(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
Navigation2DServer::get_singleton()->connect("navigation_debug_changed", this, "_navigation_debug_changed");
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
NavigationAgent2D::~NavigationAgent2D() {
|
||||
Navigation2DServer::get_singleton()->free(agent);
|
||||
agent = RID(); // Pointless
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
Navigation2DServer::get_singleton()->disconnect("navigation_debug_changed", this, "_navigation_debug_changed");
|
||||
|
||||
ERR_FAIL_NULL(RenderingServer::get_singleton());
|
||||
if (debug_path_instance.is_valid()) {
|
||||
RenderingServer::get_singleton()->free(debug_path_instance);
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_avoidance_enabled(bool p_enabled) {
|
||||
avoidance_enabled = p_enabled;
|
||||
if (avoidance_enabled) {
|
||||
Navigation2DServer::get_singleton()->agent_set_avoidance_enabled(agent, true);
|
||||
Navigation2DServer::get_singleton()->agent_set_avoidance_callback(agent, get_instance_id(), "_avoidance_done");
|
||||
} else {
|
||||
Navigation2DServer::get_singleton()->agent_set_avoidance_enabled(agent, false);
|
||||
Navigation2DServer::get_singleton()->agent_set_avoidance_callback(agent, ObjectID(), "_avoidance_done");
|
||||
}
|
||||
}
|
||||
|
||||
bool NavigationAgent2D::get_avoidance_enabled() const {
|
||||
return avoidance_enabled;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_agent_parent(Node *p_agent_parent) {
|
||||
// remove agent from any avoidance map before changing parent or there will be leftovers on the RVO map
|
||||
Navigation2DServer::get_singleton()->agent_set_avoidance_callback(agent, ObjectID(), "_avoidance_done");
|
||||
if (Object::cast_to<Node2D>(p_agent_parent) != nullptr) {
|
||||
// place agent on navigation map first or else the RVO agent callback creation fails silently later
|
||||
agent_parent = Object::cast_to<Node2D>(p_agent_parent);
|
||||
|
||||
Navigation2DServer::get_singleton()->agent_set_map(get_rid(), get_navigation_map());
|
||||
|
||||
// create new avoidance callback if enabled
|
||||
Navigation2DServer::get_singleton()->agent_set_avoidance_callback(agent, get_instance_id(), "_avoidance_done");
|
||||
} else {
|
||||
agent_parent = nullptr;
|
||||
Navigation2DServer::get_singleton()->agent_set_map(get_rid(), RID());
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_navigation(Navigation2D *p_nav) {
|
||||
if (navigation == p_nav) {
|
||||
return; // Pointless
|
||||
}
|
||||
|
||||
navigation = p_nav;
|
||||
Navigation2DServer::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_navigation_node(Node *p_nav) {
|
||||
Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav);
|
||||
ERR_FAIL_NULL(nav);
|
||||
set_navigation(nav);
|
||||
}
|
||||
|
||||
Node *NavigationAgent2D::get_navigation_node() const {
|
||||
return Object::cast_to<Node>(navigation);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_navigation_layers(uint32_t p_navigation_layers) {
|
||||
bool _navigation_layers_changed = navigation_layers != p_navigation_layers;
|
||||
navigation_layers = p_navigation_layers;
|
||||
if (_navigation_layers_changed) {
|
||||
_request_repath();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t NavigationAgent2D::get_navigation_layers() const {
|
||||
return navigation_layers;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_navigation_layer_value(int p_layer_number, bool p_value) {
|
||||
ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
uint32_t _navigation_layers = get_navigation_layers();
|
||||
if (p_value) {
|
||||
_navigation_layers |= 1 << (p_layer_number - 1);
|
||||
} else {
|
||||
_navigation_layers &= ~(1 << (p_layer_number - 1));
|
||||
}
|
||||
set_navigation_layers(_navigation_layers);
|
||||
}
|
||||
|
||||
bool NavigationAgent2D::get_navigation_layer_value(int p_layer_number) const {
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
return get_navigation_layers() & (1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_avoidance_layers(uint32_t p_layers) {
|
||||
avoidance_layers = p_layers;
|
||||
Navigation2DServer::get_singleton()->agent_set_avoidance_layers(get_rid(), avoidance_layers);
|
||||
}
|
||||
|
||||
uint32_t NavigationAgent2D::get_avoidance_layers() const {
|
||||
return avoidance_layers;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_avoidance_mask(uint32_t p_mask) {
|
||||
avoidance_mask = p_mask;
|
||||
Navigation2DServer::get_singleton()->agent_set_avoidance_mask(get_rid(), p_mask);
|
||||
}
|
||||
|
||||
uint32_t NavigationAgent2D::get_avoidance_mask() const {
|
||||
return avoidance_mask;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_avoidance_layer_value(int p_layer_number, bool p_value) {
|
||||
ERR_FAIL_COND_MSG(p_layer_number < 1, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_MSG(p_layer_number > 32, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
uint32_t avoidance_layers_new = get_avoidance_layers();
|
||||
if (p_value) {
|
||||
avoidance_layers_new |= 1 << (p_layer_number - 1);
|
||||
} else {
|
||||
avoidance_layers_new &= ~(1 << (p_layer_number - 1));
|
||||
}
|
||||
set_avoidance_layers(avoidance_layers_new);
|
||||
}
|
||||
|
||||
bool NavigationAgent2D::get_avoidance_layer_value(int p_layer_number) const {
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
return get_avoidance_layers() & (1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_avoidance_mask_value(int p_mask_number, bool p_value) {
|
||||
ERR_FAIL_COND_MSG(p_mask_number < 1, "Avoidance mask number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_MSG(p_mask_number > 32, "Avoidance mask number must be between 1 and 32 inclusive.");
|
||||
uint32_t mask = get_avoidance_mask();
|
||||
if (p_value) {
|
||||
mask |= 1 << (p_mask_number - 1);
|
||||
} else {
|
||||
mask &= ~(1 << (p_mask_number - 1));
|
||||
}
|
||||
set_avoidance_mask(mask);
|
||||
}
|
||||
|
||||
bool NavigationAgent2D::get_avoidance_mask_value(int p_mask_number) const {
|
||||
ERR_FAIL_COND_V_MSG(p_mask_number < 1, false, "Avoidance mask number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_V_MSG(p_mask_number > 32, false, "Avoidance mask number must be between 1 and 32 inclusive.");
|
||||
return get_avoidance_mask() & (1 << (p_mask_number - 1));
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_avoidance_priority(real_t p_priority) {
|
||||
ERR_FAIL_COND_MSG(p_priority < 0.0, "Avoidance priority must be between 0.0 and 1.0 inclusive.");
|
||||
ERR_FAIL_COND_MSG(p_priority > 1.0, "Avoidance priority must be between 0.0 and 1.0 inclusive.");
|
||||
avoidance_priority = p_priority;
|
||||
Navigation2DServer::get_singleton()->agent_set_avoidance_priority(get_rid(), p_priority);
|
||||
}
|
||||
|
||||
real_t NavigationAgent2D::get_avoidance_priority() const {
|
||||
return avoidance_priority;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_pathfinding_algorithm(const NavigationPathQueryParameters2D::PathfindingAlgorithm p_pathfinding_algorithm) {
|
||||
if (pathfinding_algorithm == p_pathfinding_algorithm) {
|
||||
return;
|
||||
}
|
||||
|
||||
pathfinding_algorithm = p_pathfinding_algorithm;
|
||||
|
||||
navigation_query->set_pathfinding_algorithm(pathfinding_algorithm);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_path_postprocessing(const NavigationPathQueryParameters2D::PathPostProcessing p_path_postprocessing) {
|
||||
if (path_postprocessing == p_path_postprocessing) {
|
||||
return;
|
||||
}
|
||||
|
||||
path_postprocessing = p_path_postprocessing;
|
||||
|
||||
navigation_query->set_path_postprocessing(path_postprocessing);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_path_metadata_flags(const int p_flags) {
|
||||
path_metadata_flags = p_flags;
|
||||
}
|
||||
int NavigationAgent2D::get_path_metadata_flags() const {
|
||||
return path_metadata_flags;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_navigation_map(RID p_navigation_map) {
|
||||
map_override = p_navigation_map;
|
||||
Navigation2DServer::get_singleton()->agent_set_map(agent, map_override);
|
||||
_request_repath();
|
||||
}
|
||||
|
||||
RID NavigationAgent2D::get_navigation_map() const {
|
||||
if (map_override.is_valid()) {
|
||||
return map_override;
|
||||
} else if (navigation != nullptr) {
|
||||
return navigation->get_rid();
|
||||
} else if (agent_parent != nullptr) {
|
||||
return agent_parent->get_world_2d()->get_navigation_map();
|
||||
}
|
||||
return RID();
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_path_desired_distance(real_t p_dd) {
|
||||
path_desired_distance = p_dd;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_target_desired_distance(real_t p_dd) {
|
||||
target_desired_distance = p_dd;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_radius(real_t p_radius) {
|
||||
ERR_FAIL_COND_MSG(p_radius < 0.0, "Radius must be positive.");
|
||||
radius = p_radius;
|
||||
Navigation2DServer::get_singleton()->agent_set_radius(agent, radius);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_neighbor_distance(real_t p_dist) {
|
||||
neighbor_distance = p_dist;
|
||||
Navigation2DServer::get_singleton()->agent_set_neighbor_distance(agent, neighbor_distance);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_max_neighbors(int p_count) {
|
||||
max_neighbors = p_count;
|
||||
Navigation2DServer::get_singleton()->agent_set_max_neighbors(agent, max_neighbors);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_time_horizon_agents(real_t p_time_horizon) {
|
||||
ERR_FAIL_COND_MSG(p_time_horizon < 0.0, "Time horizion must be positive.");
|
||||
if (Math::is_equal_approx(time_horizon_agents, p_time_horizon)) {
|
||||
return;
|
||||
}
|
||||
time_horizon_agents = p_time_horizon;
|
||||
Navigation2DServer::get_singleton()->agent_set_time_horizon_agents(agent, time_horizon_agents);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_time_horizon_obstacles(real_t p_time_horizon) {
|
||||
ERR_FAIL_COND_MSG(p_time_horizon < 0.0, "Time horizion must be positive.");
|
||||
if (Math::is_equal_approx(time_horizon_obstacles, p_time_horizon)) {
|
||||
return;
|
||||
}
|
||||
time_horizon_obstacles = p_time_horizon;
|
||||
Navigation2DServer::get_singleton()->agent_set_time_horizon_obstacles(agent, time_horizon_obstacles);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_max_speed(real_t p_max_speed) {
|
||||
ERR_FAIL_COND_MSG(p_max_speed < 0.0, "Max speed must be positive.");
|
||||
max_speed = p_max_speed;
|
||||
Navigation2DServer::get_singleton()->agent_set_max_speed(agent, max_speed);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_path_max_distance(real_t p_pmd) {
|
||||
path_max_distance = p_pmd;
|
||||
}
|
||||
|
||||
real_t NavigationAgent2D::get_path_max_distance() {
|
||||
return path_max_distance;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_target_position(Vector2 p_position) {
|
||||
target_position = p_position;
|
||||
target_position_submitted = true;
|
||||
_request_repath();
|
||||
}
|
||||
|
||||
Vector2 NavigationAgent2D::get_target_position() const {
|
||||
return target_position;
|
||||
}
|
||||
|
||||
Vector2 NavigationAgent2D::get_next_position() {
|
||||
update_navigation();
|
||||
|
||||
const Vector<Vector2> navigation_path = navigation_result->get_path();
|
||||
if (navigation_path.size() == 0) {
|
||||
ERR_FAIL_COND_V(agent_parent == nullptr, Vector2());
|
||||
return agent_parent->get_global_transform().get_origin();
|
||||
} else {
|
||||
return navigation_path[nav_path_index];
|
||||
}
|
||||
}
|
||||
|
||||
Ref<NavigationPathQueryResult2D> NavigationAgent2D::get_current_navigation_result() const {
|
||||
return navigation_result;
|
||||
}
|
||||
|
||||
Vector<Vector2> NavigationAgent2D::get_current_navigation_path() const {
|
||||
return navigation_result->get_path();
|
||||
}
|
||||
|
||||
real_t NavigationAgent2D::distance_to_target() const {
|
||||
ERR_FAIL_COND_V(agent_parent == nullptr, 0.0);
|
||||
return agent_parent->get_global_transform().get_origin().distance_to(target_position);
|
||||
}
|
||||
|
||||
bool NavigationAgent2D::is_target_reached() const {
|
||||
return target_reached;
|
||||
}
|
||||
|
||||
bool NavigationAgent2D::is_target_reachable() {
|
||||
return target_desired_distance >= get_final_position().distance_to(target_position);
|
||||
}
|
||||
|
||||
bool NavigationAgent2D::is_navigation_finished() {
|
||||
update_navigation();
|
||||
return navigation_finished;
|
||||
}
|
||||
|
||||
Vector2 NavigationAgent2D::get_final_position() {
|
||||
update_navigation();
|
||||
|
||||
const Vector<Vector2> navigation_path = navigation_result->get_path();
|
||||
if (navigation_path.size() == 0) {
|
||||
return Vector2();
|
||||
}
|
||||
return navigation_path[navigation_path.size() - 1];
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_velocity_forced(Vector2 p_velocity) {
|
||||
velocity_forced = p_velocity;
|
||||
velocity_forced_submitted = true;
|
||||
|
||||
Navigation2DServer::get_singleton()->agent_set_velocity_forced(agent, velocity_forced);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_velocity(const Vector2 p_velocity) {
|
||||
velocity = p_velocity;
|
||||
velocity_submitted = true;
|
||||
Navigation2DServer::get_singleton()->agent_set_velocity(agent, velocity);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) {
|
||||
const Vector2 new_safe_velocity = Vector2(p_new_velocity.x, p_new_velocity.z);
|
||||
safe_velocity = new_safe_velocity;
|
||||
emit_signal("velocity_computed", safe_velocity);
|
||||
}
|
||||
|
||||
String NavigationAgent2D::get_configuration_warning() const {
|
||||
if (!Object::cast_to<Node2D>(get_parent())) {
|
||||
return TTR("The NavigationAgent2D can be used only under a Node2D inheriting parent node.");
|
||||
}
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
void NavigationAgent2D::update_navigation() {
|
||||
if (agent_parent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!agent_parent->is_inside_tree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target_position_submitted) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_frame_id = Engine::get_singleton()->get_physics_frames();
|
||||
|
||||
Vector2 origin = agent_parent->get_global_transform().get_origin();
|
||||
|
||||
bool reload_path = false;
|
||||
|
||||
if (Navigation2DServer::get_singleton()->agent_is_map_changed(agent)) {
|
||||
reload_path = true;
|
||||
} else if (navigation_result->get_path().size() == 0) {
|
||||
reload_path = true;
|
||||
} else {
|
||||
// Check if too far from the navigation path
|
||||
if (nav_path_index > 0) {
|
||||
const Vector<Vector2> navigation_path = navigation_result->get_path();
|
||||
|
||||
Vector2 segment[2];
|
||||
segment[0] = navigation_path[nav_path_index - 1];
|
||||
segment[1] = navigation_path[nav_path_index];
|
||||
Vector2 p = Geometry::get_closest_point_to_segment_2d(origin, segment);
|
||||
if (origin.distance_to(p) >= path_max_distance) {
|
||||
// To faraway, reload path
|
||||
reload_path = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reload_path) {
|
||||
navigation_query->set_start_position(origin);
|
||||
navigation_query->set_target_position(target_position);
|
||||
navigation_query->set_navigation_layers(navigation_layers);
|
||||
navigation_query->set_metadata_flags(path_metadata_flags);
|
||||
|
||||
navigation_query->set_map(get_navigation_map());
|
||||
|
||||
Navigation2DServer::get_singleton()->query_path(navigation_query, navigation_result);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
debug_path_dirty = true;
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
navigation_finished = false;
|
||||
nav_path_index = 0;
|
||||
emit_signal("path_changed");
|
||||
}
|
||||
|
||||
if (navigation_result->get_path().size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we can advance the navigation path
|
||||
if (navigation_finished == false) {
|
||||
// Advances to the next far away position.
|
||||
const Vector<Vector2> navigation_path = navigation_result->get_path();
|
||||
const Vector<int32_t> navigation_path_types = navigation_result->get_path_types();
|
||||
const Array navigation_path_rids = navigation_result->get_path_rids();
|
||||
const Vector<uint64_t> navigation_path_owners = navigation_result->get_path_owner_ids();
|
||||
|
||||
while (origin.distance_to(navigation_path[nav_path_index]) < path_desired_distance) {
|
||||
Dictionary details;
|
||||
|
||||
const Vector2 waypoint = navigation_path[nav_path_index];
|
||||
details["location"] = waypoint;
|
||||
|
||||
int waypoint_type = -1;
|
||||
if ((path_metadata_flags & NavigationPathQueryParameters2D::PATH_METADATA_INCLUDE_TYPES) != 0) {
|
||||
const NavigationPathQueryResult2D::PathSegmentType type = NavigationPathQueryResult2D::PathSegmentType(navigation_path_types[nav_path_index]);
|
||||
|
||||
details["type"] = type;
|
||||
waypoint_type = type;
|
||||
}
|
||||
|
||||
if ((path_metadata_flags & NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_RIDS) != 0) {
|
||||
details["rid"] = navigation_path_rids[nav_path_index];
|
||||
}
|
||||
|
||||
if ((path_metadata_flags & NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_OWNERS) != 0) {
|
||||
const ObjectID waypoint_owner_id = ObjectID(navigation_path_owners[nav_path_index]);
|
||||
|
||||
// Get a reference to the owning object.
|
||||
Object *owner = nullptr;
|
||||
if (waypoint_owner_id != 0) {
|
||||
owner = ObjectDB::get_instance(waypoint_owner_id);
|
||||
}
|
||||
|
||||
details["owner"] = owner;
|
||||
|
||||
if (waypoint_type == NavigationPathQueryResult2D::PATH_SEGMENT_TYPE_LINK) {
|
||||
const NavigationLink2D *navlink = Object::cast_to<NavigationLink2D>(owner);
|
||||
if (navlink) {
|
||||
Vector2 link_global_start_position = navlink->get_global_start_position();
|
||||
Vector2 link_global_end_position = navlink->get_global_end_position();
|
||||
if (waypoint.distance_to(link_global_start_position) < waypoint.distance_to(link_global_end_position)) {
|
||||
details["link_entry_position"] = link_global_start_position;
|
||||
details["link_exit_position"] = link_global_end_position;
|
||||
} else {
|
||||
details["link_entry_position"] = link_global_end_position;
|
||||
details["link_exit_position"] = link_global_start_position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emit a signal for the waypoint
|
||||
emit_signal("waypoint_reached", details);
|
||||
|
||||
// Emit a signal if we've reached a navigation link
|
||||
if (waypoint_type == NavigationPathQueryResult2D::PATH_SEGMENT_TYPE_LINK) {
|
||||
emit_signal("link_reached", details);
|
||||
}
|
||||
|
||||
// Move to the next waypoint on the list
|
||||
|
||||
nav_path_index += 1;
|
||||
|
||||
// Check to see if we've finished our route
|
||||
if (nav_path_index == navigation_path.size()) {
|
||||
_check_distance_to_target();
|
||||
nav_path_index -= 1;
|
||||
navigation_finished = true;
|
||||
target_position_submitted = false;
|
||||
if (avoidance_enabled) {
|
||||
Navigation2DServer::get_singleton()->agent_set_position(agent, agent_parent->get_global_position());
|
||||
Navigation2DServer::get_singleton()->agent_set_velocity(agent, Vector2(0.0, 0.0));
|
||||
Navigation2DServer::get_singleton()->agent_set_velocity_forced(agent, Vector2(0.0, 0.0));
|
||||
}
|
||||
emit_signal("navigation_finished");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationAgent2D::_request_repath() {
|
||||
navigation_result->reset();
|
||||
target_reached = false;
|
||||
navigation_finished = false;
|
||||
update_frame_id = 0;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::_check_distance_to_target() {
|
||||
if (!target_reached) {
|
||||
if (distance_to_target() < target_desired_distance) {
|
||||
target_reached = true;
|
||||
emit_signal("target_reached");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////DEBUG////////////////////////////////////////////////////////////
|
||||
|
||||
void NavigationAgent2D::set_debug_enabled(bool p_enabled) {
|
||||
debug_enabled = p_enabled;
|
||||
debug_path_dirty = true;
|
||||
}
|
||||
|
||||
bool NavigationAgent2D::get_debug_enabled() const {
|
||||
return debug_enabled;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_debug_use_custom(bool p_enabled) {
|
||||
debug_use_custom = p_enabled;
|
||||
debug_path_dirty = true;
|
||||
}
|
||||
|
||||
bool NavigationAgent2D::get_debug_use_custom() const {
|
||||
return debug_use_custom;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_debug_path_custom_color(Color p_color) {
|
||||
debug_path_custom_color = p_color;
|
||||
debug_path_dirty = true;
|
||||
}
|
||||
|
||||
Color NavigationAgent2D::get_debug_path_custom_color() const {
|
||||
return debug_path_custom_color;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_debug_path_custom_point_size(float p_point_size) {
|
||||
debug_path_custom_point_size = MAX(0.0, p_point_size);
|
||||
debug_path_dirty = true;
|
||||
}
|
||||
|
||||
float NavigationAgent2D::get_debug_path_custom_point_size() const {
|
||||
return debug_path_custom_point_size;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_debug_path_custom_line_width(float p_line_width) {
|
||||
debug_path_custom_line_width = p_line_width;
|
||||
debug_path_dirty = true;
|
||||
}
|
||||
|
||||
float NavigationAgent2D::get_debug_path_custom_line_width() const {
|
||||
return debug_path_custom_line_width;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void NavigationAgent2D::_navigation_debug_changed() {
|
||||
debug_path_dirty = true;
|
||||
}
|
||||
|
||||
void NavigationAgent2D::_update_debug_path() {
|
||||
if (!debug_path_dirty) {
|
||||
return;
|
||||
}
|
||||
debug_path_dirty = false;
|
||||
|
||||
if (!debug_path_instance.is_valid()) {
|
||||
debug_path_instance = RenderingServer::get_singleton()->canvas_item_create();
|
||||
}
|
||||
|
||||
RenderingServer::get_singleton()->canvas_item_clear(debug_path_instance);
|
||||
|
||||
if (!(debug_enabled && Navigation2DServer::get_singleton()->get_debug_navigation_enable_agent_paths())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(agent_parent && agent_parent->is_inside_tree())) {
|
||||
return;
|
||||
}
|
||||
|
||||
RenderingServer::get_singleton()->canvas_item_set_parent(debug_path_instance, agent_parent->get_canvas());
|
||||
RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, agent_parent->is_visible_in_tree());
|
||||
|
||||
const Vector<Vector2> navigation_path = navigation_result->get_path();
|
||||
|
||||
if (navigation_path.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Color debug_path_color = Navigation2DServer::get_singleton()->get_debug_navigation_agent_path_color();
|
||||
if (debug_use_custom) {
|
||||
debug_path_color = debug_path_custom_color;
|
||||
}
|
||||
|
||||
Vector<Color> debug_path_colors;
|
||||
debug_path_colors.resize(navigation_path.size());
|
||||
debug_path_colors.fill(debug_path_color);
|
||||
|
||||
RenderingServer::get_singleton()->canvas_item_add_polyline(debug_path_instance, navigation_path, debug_path_colors, debug_path_custom_line_width, false);
|
||||
|
||||
if (debug_path_custom_point_size <= 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
float point_size = Navigation2DServer::get_singleton()->get_debug_navigation_agent_path_point_size();
|
||||
float half_point_size = point_size * 0.5;
|
||||
|
||||
if (debug_use_custom) {
|
||||
point_size = debug_path_custom_point_size;
|
||||
half_point_size = debug_path_custom_point_size * 0.5;
|
||||
}
|
||||
|
||||
for (int i = 0; i < navigation_path.size(); i++) {
|
||||
const Vector2 &vert = navigation_path[i];
|
||||
Rect2 path_point_rect = Rect2(vert.x - half_point_size, vert.y - half_point_size, point_size, point_size);
|
||||
RenderingServer::get_singleton()->canvas_item_add_rect(debug_path_instance, path_point_rect, debug_path_color);
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
@ -1,260 +0,0 @@
|
||||
#ifndef NAVIGATION_AGENT_2D_H
|
||||
#define NAVIGATION_AGENT_2D_H
|
||||
/*************************************************************************/
|
||||
/* navigation_agent_2d.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "scene/main/node.h"
|
||||
|
||||
#include "servers/navigation/navigation_path_query_parameters_2d.h"
|
||||
|
||||
class Node2D;
|
||||
class Navigation2D;
|
||||
class NavigationPathQueryParameters2D;
|
||||
class NavigationPathQueryResult2D;
|
||||
|
||||
class NavigationAgent2D : public Node {
|
||||
GDCLASS(NavigationAgent2D, Node);
|
||||
|
||||
Node2D *agent_parent;
|
||||
Navigation2D *navigation;
|
||||
|
||||
RID agent;
|
||||
RID map_override;
|
||||
|
||||
bool avoidance_enabled;
|
||||
uint32_t avoidance_layers;
|
||||
uint32_t avoidance_mask;
|
||||
real_t avoidance_priority;
|
||||
uint32_t navigation_layers;
|
||||
NavigationPathQueryParameters2D::PathfindingAlgorithm pathfinding_algorithm;
|
||||
NavigationPathQueryParameters2D::PathPostProcessing path_postprocessing;
|
||||
int path_metadata_flags;
|
||||
|
||||
real_t path_desired_distance;
|
||||
real_t target_desired_distance;
|
||||
real_t radius;
|
||||
real_t neighbor_distance;
|
||||
int max_neighbors;
|
||||
real_t time_horizon_agents;
|
||||
real_t time_horizon_obstacles;
|
||||
real_t max_speed;
|
||||
|
||||
real_t path_max_distance;
|
||||
|
||||
Vector2 target_position;
|
||||
bool target_position_submitted;
|
||||
|
||||
Ref<NavigationPathQueryParameters2D> navigation_query;
|
||||
Ref<NavigationPathQueryResult2D> navigation_result;
|
||||
int nav_path_index;
|
||||
|
||||
// the velocity result of the avoidance simulation step
|
||||
Vector2 safe_velocity;
|
||||
|
||||
/// The submitted target velocity, sets the "wanted" rvo agent velocity on the next update
|
||||
// this velocity is not guaranteed, the simulation will try to fulfil it if possible
|
||||
// if other agents or obstacles interfere it will be changed accordingly
|
||||
Vector2 velocity;
|
||||
bool velocity_submitted;
|
||||
|
||||
/// The submitted forced velocity, overrides the rvo agent velocity on the next update
|
||||
// should only be used very intentionally and not every frame as it interferes with the simulation stability
|
||||
Vector2 velocity_forced;
|
||||
bool velocity_forced_submitted;
|
||||
|
||||
bool target_reached;
|
||||
bool navigation_finished;
|
||||
// No initialized on purpose
|
||||
uint32_t update_frame_id;
|
||||
|
||||
bool debug_enabled;
|
||||
bool debug_path_dirty;
|
||||
RID debug_path_instance;
|
||||
float debug_path_custom_point_size;
|
||||
float debug_path_custom_line_width;
|
||||
bool debug_use_custom;
|
||||
Color debug_path_custom_color;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
NavigationAgent2D();
|
||||
virtual ~NavigationAgent2D();
|
||||
|
||||
void set_navigation(Navigation2D *p_nav);
|
||||
const Navigation2D *get_navigation() const {
|
||||
return navigation;
|
||||
}
|
||||
|
||||
void set_navigation_node(Node *p_nav);
|
||||
Node *get_navigation_node() const;
|
||||
|
||||
RID get_rid() const {
|
||||
return agent;
|
||||
}
|
||||
|
||||
void set_avoidance_enabled(bool p_enabled);
|
||||
bool get_avoidance_enabled() const;
|
||||
|
||||
void set_agent_parent(Node *p_agent_parent);
|
||||
|
||||
void set_navigation_layers(uint32_t p_navigation_layers);
|
||||
uint32_t get_navigation_layers() const;
|
||||
|
||||
void set_navigation_layer_value(int p_layer_number, bool p_value);
|
||||
bool get_navigation_layer_value(int p_layer_number) const;
|
||||
|
||||
void set_pathfinding_algorithm(const NavigationPathQueryParameters2D::PathfindingAlgorithm p_pathfinding_algorithm);
|
||||
NavigationPathQueryParameters2D::PathfindingAlgorithm get_pathfinding_algorithm() const {
|
||||
return pathfinding_algorithm;
|
||||
}
|
||||
|
||||
void set_path_postprocessing(const NavigationPathQueryParameters2D::PathPostProcessing p_path_postprocessing);
|
||||
NavigationPathQueryParameters2D::PathPostProcessing get_path_postprocessing() const {
|
||||
return path_postprocessing;
|
||||
}
|
||||
|
||||
void set_avoidance_layers(uint32_t p_layers);
|
||||
uint32_t get_avoidance_layers() const;
|
||||
|
||||
void set_avoidance_mask(uint32_t p_mask);
|
||||
uint32_t get_avoidance_mask() const;
|
||||
|
||||
void set_avoidance_layer_value(int p_layer_number, bool p_value);
|
||||
bool get_avoidance_layer_value(int p_layer_number) const;
|
||||
|
||||
void set_avoidance_mask_value(int p_mask_number, bool p_value);
|
||||
bool get_avoidance_mask_value(int p_mask_number) const;
|
||||
|
||||
void set_avoidance_priority(real_t p_priority);
|
||||
real_t get_avoidance_priority() const;
|
||||
|
||||
void set_path_metadata_flags(const int p_flags);
|
||||
int get_path_metadata_flags() const;
|
||||
|
||||
void set_navigation_map(RID p_navigation_map);
|
||||
RID get_navigation_map() const;
|
||||
|
||||
void set_path_desired_distance(real_t p_dd);
|
||||
real_t get_path_desired_distance() const {
|
||||
return path_desired_distance;
|
||||
}
|
||||
|
||||
void set_target_desired_distance(real_t p_dd);
|
||||
real_t get_target_desired_distance() const {
|
||||
return target_desired_distance;
|
||||
}
|
||||
|
||||
void set_radius(real_t p_radius);
|
||||
real_t get_radius() const {
|
||||
return radius;
|
||||
}
|
||||
|
||||
void set_neighbor_distance(real_t p_dist);
|
||||
real_t get_neighbor_distance() const {
|
||||
return neighbor_distance;
|
||||
}
|
||||
|
||||
void set_max_neighbors(int p_count);
|
||||
int get_max_neighbors() const {
|
||||
return max_neighbors;
|
||||
}
|
||||
|
||||
void set_time_horizon_agents(real_t p_time_horizon);
|
||||
real_t get_time_horizon_agents() const { return time_horizon_agents; }
|
||||
|
||||
void set_time_horizon_obstacles(real_t p_time_horizon);
|
||||
real_t get_time_horizon_obstacles() const { return time_horizon_obstacles; }
|
||||
|
||||
void set_max_speed(real_t p_max_speed);
|
||||
real_t get_max_speed() const {
|
||||
return max_speed;
|
||||
}
|
||||
|
||||
void set_path_max_distance(real_t p_pmd);
|
||||
real_t get_path_max_distance();
|
||||
|
||||
void set_target_position(Vector2 p_position);
|
||||
Vector2 get_target_position() const;
|
||||
|
||||
Vector2 get_next_position();
|
||||
|
||||
Ref<NavigationPathQueryResult2D> get_current_navigation_result() const;
|
||||
|
||||
Vector<Vector2> get_current_navigation_path() const;
|
||||
|
||||
int get_current_navigation_path_index() const {
|
||||
return nav_path_index;
|
||||
}
|
||||
|
||||
real_t distance_to_target() const;
|
||||
bool is_target_reached() const;
|
||||
bool is_target_reachable();
|
||||
bool is_navigation_finished();
|
||||
Vector2 get_final_position();
|
||||
|
||||
void set_velocity(const Vector2 p_velocity);
|
||||
Vector2 get_velocity() { return velocity; }
|
||||
|
||||
void set_velocity_forced(const Vector2 p_velocity);
|
||||
|
||||
void _avoidance_done(Vector3 p_new_velocity);
|
||||
|
||||
virtual String get_configuration_warning() const;
|
||||
|
||||
void set_debug_enabled(bool p_enabled);
|
||||
bool get_debug_enabled() const;
|
||||
|
||||
void set_debug_use_custom(bool p_enabled);
|
||||
bool get_debug_use_custom() const;
|
||||
|
||||
void set_debug_path_custom_color(Color p_color);
|
||||
Color get_debug_path_custom_color() const;
|
||||
|
||||
void set_debug_path_custom_point_size(float p_point_size);
|
||||
float get_debug_path_custom_point_size() const;
|
||||
|
||||
void set_debug_path_custom_line_width(float p_line_width);
|
||||
float get_debug_path_custom_line_width() const;
|
||||
|
||||
private:
|
||||
void update_navigation();
|
||||
void _request_repath();
|
||||
void _check_distance_to_target();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void _navigation_debug_changed();
|
||||
void _update_debug_path();
|
||||
#endif // DEBUG_ENABLED
|
||||
};
|
||||
|
||||
#endif
|
@ -1,66 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* navigation_geometry_parser_2d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "navigation_geometry_parser_2d.h"
|
||||
|
||||
#include "scene/main/node_2d.h"
|
||||
|
||||
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
|
||||
bool NavigationGeometryParser2D::parses_node(Node *p_node) {
|
||||
if (Object::cast_to<Node2D>(p_node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (has_method("_parses_node")) {
|
||||
return call("_parses_node", p_node);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void NavigationGeometryParser2D::parse_node_geometry(Ref<NavigationPolygon> p_navigation_polygon, Node *p_node, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) {
|
||||
parse_geometry(p_node, p_navigation_polygon, p_source_geometry);
|
||||
}
|
||||
|
||||
void NavigationGeometryParser2D::parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry) {
|
||||
if (has_method("_parse_geometry")) {
|
||||
call("_parse_geometry", p_node, p_navigation_polygon, p_source_geometry);
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationGeometryParser2D::_bind_methods() {
|
||||
BIND_VMETHOD(MethodInfo(Variant::BOOL, "_parses_node", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
|
||||
BIND_VMETHOD(MethodInfo("_parse_geometry",
|
||||
PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"),
|
||||
PropertyInfo(Variant::OBJECT, "navigation_polygon", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"),
|
||||
PropertyInfo(Variant::OBJECT, "source_geometry", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMeshSourceGeometryData2D")));
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
#ifndef NAVIGATION_GEOMETRY_PARSER_2D_H
|
||||
#define NAVIGATION_GEOMETRY_PARSER_2D_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* navigation_geometry_parser_2d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
class NavigationPolygon;
|
||||
class NavigationMeshSourceGeometryData2D;
|
||||
class Node;
|
||||
|
||||
class NavigationGeometryParser2D : public Reference {
|
||||
GDCLASS(NavigationGeometryParser2D, Reference);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual bool parses_node(Node *p_node);
|
||||
virtual void parse_geometry(Node *p_node, Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry);
|
||||
|
||||
void parse_node_geometry(Ref<NavigationPolygon> p_navigation_polygon, Node *p_node, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry);
|
||||
};
|
||||
|
||||
#endif // NAVIGATION_GEOMETRY_PARSER_2D_H
|
@ -1,336 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* navigation_link_2d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "navigation_link_2d.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "core/math/geometry.h"
|
||||
#include "scene/resources/world_2d.h"
|
||||
#include "servers/navigation_2d_server.h"
|
||||
#include "servers/navigation_server.h"
|
||||
|
||||
void NavigationLink2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationLink2D::set_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationLink2D::is_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_bidirectional", "bidirectional"), &NavigationLink2D::set_bidirectional);
|
||||
ClassDB::bind_method(D_METHOD("is_bidirectional"), &NavigationLink2D::is_bidirectional);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationLink2D::set_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationLink2D::get_navigation_layers);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationLink2D::set_navigation_layer_value);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationLink2D::get_navigation_layer_value);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_start_position", "position"), &NavigationLink2D::set_start_position);
|
||||
ClassDB::bind_method(D_METHOD("get_start_position"), &NavigationLink2D::get_start_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_end_position", "position"), &NavigationLink2D::set_end_position);
|
||||
ClassDB::bind_method(D_METHOD("get_end_position"), &NavigationLink2D::get_end_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_global_start_position", "position"), &NavigationLink2D::set_global_start_position);
|
||||
ClassDB::bind_method(D_METHOD("get_global_start_position"), &NavigationLink2D::get_global_start_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_global_end_position", "position"), &NavigationLink2D::set_global_end_position);
|
||||
ClassDB::bind_method(D_METHOD("get_global_end_position"), &NavigationLink2D::get_global_end_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink2D::set_enter_cost);
|
||||
ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink2D::get_enter_cost);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_travel_cost", "travel_cost"), &NavigationLink2D::set_travel_cost);
|
||||
ClassDB::bind_method(D_METHOD("get_travel_cost"), &NavigationLink2D::get_travel_cost);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bidirectional"), "set_bidirectional", "is_bidirectional");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_position"), "set_start_position", "get_start_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "end_position"), "set_end_position", "get_end_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "enter_cost"), "set_enter_cost", "get_enter_cost");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "travel_cost"), "set_travel_cost", "get_travel_cost");
|
||||
}
|
||||
|
||||
void NavigationLink2D::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
if (enabled) {
|
||||
Navigation2DServer::get_singleton()->link_set_map(link, get_world_2d()->get_navigation_map());
|
||||
}
|
||||
current_global_transform = get_global_transform();
|
||||
Navigation2DServer::get_singleton()->link_set_start_position(link, current_global_transform.xform(start_position));
|
||||
Navigation2DServer::get_singleton()->link_set_end_position(link, current_global_transform.xform(end_position));
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
set_physics_process_internal(true);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||
set_physics_process_internal(false);
|
||||
if (is_inside_tree()) {
|
||||
Transform2D new_global_transform = get_global_transform();
|
||||
if (current_global_transform != new_global_transform) {
|
||||
current_global_transform = new_global_transform;
|
||||
Navigation2DServer::get_singleton()->link_set_start_position(link, current_global_transform.xform(start_position));
|
||||
Navigation2DServer::get_singleton()->link_set_end_position(link, current_global_transform.xform(end_position));
|
||||
update();
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
Navigation2DServer::get_singleton()->link_set_map(link, RID());
|
||||
} break;
|
||||
case NOTIFICATION_DRAW: {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || Navigation2DServer::get_singleton()->get_debug_navigation_enabled())) {
|
||||
Color color;
|
||||
if (enabled) {
|
||||
color = Navigation2DServer::get_singleton()->get_debug_navigation_link_connection_color();
|
||||
} else {
|
||||
color = Navigation2DServer::get_singleton()->get_debug_navigation_link_connection_disabled_color();
|
||||
}
|
||||
|
||||
real_t radius = Navigation2DServer::get_singleton()->map_get_link_connection_radius(get_world_2d()->get_navigation_map());
|
||||
|
||||
draw_line(get_start_position(), get_end_position(), color);
|
||||
draw_arc(get_start_position(), radius, 0, Math_TAU, 10, color);
|
||||
draw_arc(get_end_position(), radius, 0, Math_TAU, 10, color);
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Rect2 NavigationLink2D::_edit_get_rect() const {
|
||||
if (!is_inside_tree()) {
|
||||
return Rect2();
|
||||
}
|
||||
|
||||
real_t radius = Navigation2DServer::get_singleton()->map_get_link_connection_radius(get_world_2d()->get_navigation_map());
|
||||
|
||||
Rect2 rect(get_start_position(), Size2());
|
||||
rect.expand_to(get_end_position());
|
||||
rect.grow_by(radius);
|
||||
return rect;
|
||||
}
|
||||
|
||||
bool NavigationLink2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
|
||||
Point2 segment[2] = { get_start_position(), get_end_position() };
|
||||
|
||||
Vector2 closest_point = Geometry::get_closest_point_to_segment_2d(p_point, segment);
|
||||
return p_point.distance_to(closest_point) < p_tolerance;
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
void NavigationLink2D::set_enabled(bool p_enabled) {
|
||||
if (enabled == p_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
enabled = p_enabled;
|
||||
|
||||
Navigation2DServer::get_singleton()->link_set_enabled(link, enabled);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (Engine::get_singleton()->is_editor_hint() || Navigation2DServer::get_singleton()->get_debug_navigation_enabled()) {
|
||||
update();
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
void NavigationLink2D::set_bidirectional(bool p_bidirectional) {
|
||||
if (bidirectional == p_bidirectional) {
|
||||
return;
|
||||
}
|
||||
|
||||
bidirectional = p_bidirectional;
|
||||
|
||||
Navigation2DServer::get_singleton()->link_set_bidirectional(link, bidirectional);
|
||||
}
|
||||
|
||||
void NavigationLink2D::set_navigation_layers(uint32_t p_navigation_layers) {
|
||||
if (navigation_layers == p_navigation_layers) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigation_layers = p_navigation_layers;
|
||||
|
||||
Navigation2DServer::get_singleton()->link_set_navigation_layers(link, navigation_layers);
|
||||
}
|
||||
|
||||
void NavigationLink2D::set_navigation_layer_value(int p_layer_number, bool p_value) {
|
||||
ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
|
||||
uint32_t _navigation_layers = get_navigation_layers();
|
||||
|
||||
if (p_value) {
|
||||
_navigation_layers |= 1 << (p_layer_number - 1);
|
||||
} else {
|
||||
_navigation_layers &= ~(1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
set_navigation_layers(_navigation_layers);
|
||||
}
|
||||
|
||||
bool NavigationLink2D::get_navigation_layer_value(int p_layer_number) const {
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
|
||||
return get_navigation_layers() & (1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
void NavigationLink2D::set_start_position(Vector2 p_position) {
|
||||
if (start_position.is_equal_approx(p_position)) {
|
||||
return;
|
||||
}
|
||||
|
||||
start_position = p_position;
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Navigation2DServer::get_singleton()->link_set_start_position(link, current_global_transform.xform(start_position));
|
||||
|
||||
update_configuration_warning();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (Engine::get_singleton()->is_editor_hint() || Navigation2DServer::get_singleton()->get_debug_navigation_enabled()) {
|
||||
update();
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
void NavigationLink2D::set_end_position(Vector2 p_position) {
|
||||
if (end_position.is_equal_approx(p_position)) {
|
||||
return;
|
||||
}
|
||||
|
||||
end_position = p_position;
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Navigation2DServer::get_singleton()->link_set_end_position(link, current_global_transform.xform(end_position));
|
||||
|
||||
update_configuration_warning();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (Engine::get_singleton()->is_editor_hint() || Navigation2DServer::get_singleton()->get_debug_navigation_enabled()) {
|
||||
update();
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
void NavigationLink2D::set_global_start_position(Vector2 p_position) {
|
||||
if (is_inside_tree()) {
|
||||
set_start_position(to_local(p_position));
|
||||
} else {
|
||||
set_start_position(p_position);
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 NavigationLink2D::get_global_start_position() const {
|
||||
if (is_inside_tree()) {
|
||||
return to_global(start_position);
|
||||
} else {
|
||||
return start_position;
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationLink2D::set_global_end_position(Vector2 p_position) {
|
||||
if (is_inside_tree()) {
|
||||
set_end_position(to_local(p_position));
|
||||
} else {
|
||||
set_end_position(p_position);
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 NavigationLink2D::get_global_end_position() const {
|
||||
if (is_inside_tree()) {
|
||||
return to_global(end_position);
|
||||
} else {
|
||||
return end_position;
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationLink2D::set_enter_cost(real_t p_enter_cost) {
|
||||
ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive.");
|
||||
if (Math::is_equal_approx(enter_cost, p_enter_cost)) {
|
||||
return;
|
||||
}
|
||||
|
||||
enter_cost = p_enter_cost;
|
||||
|
||||
Navigation2DServer::get_singleton()->link_set_enter_cost(link, enter_cost);
|
||||
}
|
||||
|
||||
void NavigationLink2D::set_travel_cost(real_t p_travel_cost) {
|
||||
ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive.");
|
||||
if (Math::is_equal_approx(travel_cost, p_travel_cost)) {
|
||||
return;
|
||||
}
|
||||
|
||||
travel_cost = p_travel_cost;
|
||||
|
||||
Navigation2DServer::get_singleton()->link_set_travel_cost(link, travel_cost);
|
||||
}
|
||||
|
||||
String NavigationLink2D::get_configuration_warning() const {
|
||||
String warnings = Node::get_configuration_warning();
|
||||
|
||||
if (start_position.is_equal_approx(end_position)) {
|
||||
warnings += RTR("NavigationLink2D start position should be different than the end position to be useful.");
|
||||
}
|
||||
|
||||
return warnings;
|
||||
}
|
||||
|
||||
NavigationLink2D::NavigationLink2D() {
|
||||
enabled = true;
|
||||
bidirectional = true;
|
||||
navigation_layers = 1;
|
||||
enter_cost = 0.0;
|
||||
travel_cost = 1.0;
|
||||
|
||||
link = Navigation2DServer::get_singleton()->link_create();
|
||||
Navigation2DServer::get_singleton()->link_set_owner_id(link, get_instance_id());
|
||||
|
||||
set_notify_transform(true);
|
||||
}
|
||||
|
||||
NavigationLink2D::~NavigationLink2D() {
|
||||
ERR_FAIL_NULL(Navigation2DServer::get_singleton());
|
||||
Navigation2DServer::get_singleton()->free(link);
|
||||
link = RID();
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
#ifndef NAVIGATION_LINK_2D_H
|
||||
#define NAVIGATION_LINK_2D_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* navigation_link_2d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "scene/main/node_2d.h"
|
||||
|
||||
class NavigationLink2D : public Node2D {
|
||||
GDCLASS(NavigationLink2D, Node2D);
|
||||
|
||||
bool enabled;
|
||||
RID link;
|
||||
bool bidirectional;
|
||||
uint32_t navigation_layers;
|
||||
Vector2 end_position;
|
||||
Vector2 start_position;
|
||||
real_t enter_cost;
|
||||
real_t travel_cost;
|
||||
|
||||
Transform2D current_global_transform;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
#ifdef TOOLS_ENABLED
|
||||
virtual Rect2 _edit_get_rect() const;
|
||||
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
|
||||
#endif
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const { return enabled; }
|
||||
|
||||
void set_bidirectional(bool p_bidirectional);
|
||||
bool is_bidirectional() const { return bidirectional; }
|
||||
|
||||
void set_navigation_layers(uint32_t p_navigation_layers);
|
||||
uint32_t get_navigation_layers() const { return navigation_layers; }
|
||||
|
||||
void set_navigation_layer_value(int p_layer_number, bool p_value);
|
||||
bool get_navigation_layer_value(int p_layer_number) const;
|
||||
|
||||
void set_start_position(Vector2 p_position);
|
||||
Vector2 get_start_position() const { return start_position; }
|
||||
|
||||
void set_end_position(Vector2 p_position);
|
||||
Vector2 get_end_position() const { return end_position; }
|
||||
|
||||
void set_global_start_position(Vector2 p_position);
|
||||
Vector2 get_global_start_position() const;
|
||||
|
||||
void set_global_end_position(Vector2 p_position);
|
||||
Vector2 get_global_end_position() const;
|
||||
|
||||
void set_enter_cost(real_t p_enter_cost);
|
||||
real_t get_enter_cost() const { return enter_cost; }
|
||||
|
||||
void set_travel_cost(real_t p_travel_cost);
|
||||
real_t get_travel_cost() const { return travel_cost; }
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
NavigationLink2D();
|
||||
~NavigationLink2D();
|
||||
};
|
||||
|
||||
#endif // NAVIGATION_LINK_2D_H
|
@ -1,371 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* navigation_obstacle_2d.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "navigation_obstacle_2d.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "scene/2d/collision_shape_2d.h"
|
||||
#include "scene/2d/navigation_2d.h"
|
||||
#include "scene/main/node_2d.h"
|
||||
#include "scene/2d/physics_body_2d.h"
|
||||
#include "scene/resources/world_2d.h"
|
||||
#include "servers/navigation_2d_server.h"
|
||||
|
||||
void NavigationObstacle2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_rid"), &NavigationObstacle2D::get_rid);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_enabled", "enabled"), &NavigationObstacle2D::set_avoidance_enabled);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_enabled"), &NavigationObstacle2D::get_avoidance_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle2D::set_navigation_node);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle2D::get_navigation_node);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationObstacle2D::set_navigation_map);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationObstacle2D::get_navigation_map);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationObstacle2D::set_radius);
|
||||
ClassDB::bind_method(D_METHOD("get_radius"), &NavigationObstacle2D::get_radius);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationObstacle2D::set_velocity);
|
||||
ClassDB::bind_method(D_METHOD("get_velocity"), &NavigationObstacle2D::get_velocity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationObstacle2D::set_vertices);
|
||||
ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationObstacle2D::get_vertices);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_layers", "layers"), &NavigationObstacle2D::set_avoidance_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_layers"), &NavigationObstacle2D::get_avoidance_layers);
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_layer_value", "layer_number", "value"), &NavigationObstacle2D::set_avoidance_layer_value);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_layer_value", "layer_number"), &NavigationObstacle2D::get_avoidance_layer_value);
|
||||
|
||||
ADD_GROUP("Avoidance", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_velocity", "get_velocity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.0,500,0.01,suffix:px"), "set_radius", "get_radius");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "vertices"), "set_vertices", "get_vertices");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "avoidance_layers", PROPERTY_HINT_LAYERS_AVOIDANCE), "set_avoidance_layers", "get_avoidance_layers");
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
// Search the navigation node and set it
|
||||
{
|
||||
Navigation2D *nav = nullptr;
|
||||
Node *p = get_parent();
|
||||
while (p != nullptr) {
|
||||
nav = Object::cast_to<Navigation2D>(p);
|
||||
if (nav != nullptr) {
|
||||
p = nullptr;
|
||||
} else {
|
||||
p = p->get_parent();
|
||||
}
|
||||
}
|
||||
|
||||
navigation = nav;
|
||||
}
|
||||
|
||||
_update_map(get_navigation_map());
|
||||
|
||||
previous_transform = get_global_transform();
|
||||
// need to trigger map controlled agent assignment somehow for the fake_agent since obstacles use no callback like regular agents
|
||||
Navigation2DServer::get_singleton()->obstacle_set_avoidance_enabled(obstacle, avoidance_enabled);
|
||||
_update_position(get_global_transform().get_origin());
|
||||
|
||||
set_physics_process_internal(true);
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
set_navigation(nullptr);
|
||||
set_physics_process_internal(false);
|
||||
_update_map(RID());
|
||||
request_ready(); // required to solve an issue with losing the navigation
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_PAUSED: {
|
||||
if (!can_process()) {
|
||||
map_before_pause = map_current;
|
||||
_update_map(RID());
|
||||
} else if (can_process() && !(map_before_pause == RID())) {
|
||||
_update_map(map_before_pause);
|
||||
map_before_pause = RID();
|
||||
}
|
||||
Navigation2DServer::get_singleton()->obstacle_set_paused(obstacle, !can_process());
|
||||
} break;
|
||||
case NOTIFICATION_UNPAUSED: {
|
||||
if (!can_process()) {
|
||||
map_before_pause = map_current;
|
||||
_update_map(RID());
|
||||
} else if (can_process() && !(map_before_pause == RID())) {
|
||||
_update_map(map_before_pause);
|
||||
map_before_pause = RID();
|
||||
}
|
||||
Navigation2DServer::get_singleton()->obstacle_set_paused(obstacle, !can_process());
|
||||
} break;
|
||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||
if (is_inside_tree()) {
|
||||
_update_position(get_global_transform().get_origin());
|
||||
|
||||
if (velocity_submitted) {
|
||||
velocity_submitted = false;
|
||||
// only update if there is a noticeable change, else the rvo agent preferred velocity stays the same
|
||||
if (!previous_velocity.is_equal_approx(velocity)) {
|
||||
Navigation2DServer::get_singleton()->obstacle_set_velocity(obstacle, velocity);
|
||||
}
|
||||
previous_velocity = velocity;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_DRAW: {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (is_inside_tree()) {
|
||||
bool is_debug_enabled = false;
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
is_debug_enabled = true;
|
||||
} else if (Navigation2DServer::get_singleton()->get_debug_enabled() && Navigation2DServer::get_singleton()->get_debug_avoidance_enabled()) {
|
||||
is_debug_enabled = true;
|
||||
}
|
||||
|
||||
if (is_debug_enabled) {
|
||||
_update_fake_agent_radius_debug();
|
||||
_update_static_obstacle_debug();
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
NavigationObstacle2D::NavigationObstacle2D() {
|
||||
navigation = NULL;
|
||||
|
||||
obstacle = Navigation2DServer::get_singleton()->obstacle_create();
|
||||
|
||||
radius = 0.0;
|
||||
|
||||
avoidance_enabled = true;
|
||||
avoidance_layers = 1;
|
||||
|
||||
velocity_submitted = false;
|
||||
|
||||
set_radius(radius);
|
||||
set_vertices(vertices);
|
||||
set_avoidance_layers(avoidance_layers);
|
||||
set_avoidance_enabled(avoidance_enabled);
|
||||
}
|
||||
|
||||
NavigationObstacle2D::~NavigationObstacle2D() {
|
||||
ERR_FAIL_NULL(Navigation2DServer::get_singleton());
|
||||
Navigation2DServer::get_singleton()->free(obstacle);
|
||||
obstacle = RID();
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_navigation(Navigation2D *p_nav) {
|
||||
if (navigation == p_nav && navigation != nullptr) {
|
||||
return; // Pointless
|
||||
}
|
||||
|
||||
navigation = p_nav;
|
||||
|
||||
_update_map(get_navigation_map());
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_navigation_node(Node *p_nav) {
|
||||
Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav);
|
||||
ERR_FAIL_COND(nav == nullptr);
|
||||
set_navigation(nav);
|
||||
}
|
||||
|
||||
Node *NavigationObstacle2D::get_navigation_node() const {
|
||||
return Object::cast_to<Node>(navigation);
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_vertices(const Vector<Vector2> &p_vertices) {
|
||||
vertices = p_vertices;
|
||||
Navigation2DServer::get_singleton()->obstacle_set_vertices(obstacle, vertices);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
update();
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_navigation_map(RID p_navigation_map) {
|
||||
if (map_override == p_navigation_map) {
|
||||
return;
|
||||
}
|
||||
|
||||
map_override = p_navigation_map;
|
||||
|
||||
_update_map(get_navigation_map());
|
||||
}
|
||||
|
||||
RID NavigationObstacle2D::get_navigation_map() const {
|
||||
if (map_override.is_valid()) {
|
||||
return map_override;
|
||||
} else if (navigation) {
|
||||
return navigation->get_rid();
|
||||
} else if (is_inside_tree()) {
|
||||
return get_world_2d()->get_navigation_map();
|
||||
}
|
||||
|
||||
return RID();
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_radius(real_t p_radius) {
|
||||
ERR_FAIL_COND_MSG(p_radius < 0.0, "Radius must be positive.");
|
||||
if (Math::is_equal_approx(radius, p_radius)) {
|
||||
return;
|
||||
}
|
||||
|
||||
radius = p_radius;
|
||||
|
||||
Navigation2DServer::get_singleton()->obstacle_set_radius(obstacle, radius);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
update();
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_avoidance_layers(uint32_t p_layers) {
|
||||
if (avoidance_layers == p_layers) {
|
||||
return;
|
||||
}
|
||||
|
||||
avoidance_layers = p_layers;
|
||||
Navigation2DServer::get_singleton()->obstacle_set_avoidance_layers(obstacle, avoidance_layers);
|
||||
}
|
||||
|
||||
uint32_t NavigationObstacle2D::get_avoidance_layers() const {
|
||||
return avoidance_layers;
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_avoidance_layer_value(int p_layer_number, bool p_value) {
|
||||
ERR_FAIL_COND_MSG(p_layer_number < 1, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_MSG(p_layer_number > 32, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
uint32_t avoidance_layers_new = get_avoidance_layers();
|
||||
if (p_value) {
|
||||
avoidance_layers_new |= 1 << (p_layer_number - 1);
|
||||
} else {
|
||||
avoidance_layers_new &= ~(1 << (p_layer_number - 1));
|
||||
}
|
||||
set_avoidance_layers(avoidance_layers_new);
|
||||
}
|
||||
|
||||
bool NavigationObstacle2D::get_avoidance_layer_value(int p_layer_number) const {
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
return get_avoidance_layers() & (1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_avoidance_enabled(bool p_enabled) {
|
||||
if (avoidance_enabled == p_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
avoidance_enabled = p_enabled;
|
||||
Navigation2DServer::get_singleton()->obstacle_set_avoidance_enabled(obstacle, avoidance_enabled);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
update();
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
bool NavigationObstacle2D::get_avoidance_enabled() const {
|
||||
return avoidance_enabled;
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_velocity(const Vector2 p_velocity) {
|
||||
velocity = p_velocity;
|
||||
velocity_submitted = true;
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::_update_map(RID p_map) {
|
||||
map_current = p_map;
|
||||
Navigation2DServer::get_singleton()->obstacle_set_map(obstacle, p_map);
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::_update_position(const Vector2 p_position) {
|
||||
Navigation2DServer::get_singleton()->obstacle_set_position(obstacle, p_position);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
update();
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void NavigationObstacle2D::_update_fake_agent_radius_debug() {
|
||||
if (radius > 0.0 && Navigation2DServer::get_singleton()->get_debug_navigation_avoidance_enable_obstacles_radius()) {
|
||||
Color debug_radius_color = Navigation2DServer::get_singleton()->get_debug_navigation_avoidance_obstacles_radius_color();
|
||||
|
||||
RS::get_singleton()->canvas_item_add_circle(get_canvas_item(), Vector2(), radius, debug_radius_color);
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void NavigationObstacle2D::_update_static_obstacle_debug() {
|
||||
if (get_vertices().size() > 2 && Navigation2DServer::get_singleton()->get_debug_navigation_avoidance_enable_obstacles_static()) {
|
||||
bool obstacle_pushes_inward = Geometry::is_polygon_clockwise(get_vertices());
|
||||
|
||||
Color debug_static_obstacle_face_color;
|
||||
|
||||
if (obstacle_pushes_inward) {
|
||||
debug_static_obstacle_face_color = Navigation2DServer::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushin_face_color();
|
||||
} else {
|
||||
debug_static_obstacle_face_color = Navigation2DServer::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushout_face_color();
|
||||
}
|
||||
|
||||
Vector<Vector2> debug_obstacle_polygon_vertices = get_vertices();
|
||||
|
||||
Vector<Color> debug_obstacle_polygon_colors;
|
||||
debug_obstacle_polygon_colors.resize(debug_obstacle_polygon_vertices.size());
|
||||
debug_obstacle_polygon_colors.fill(debug_static_obstacle_face_color);
|
||||
|
||||
RS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), debug_obstacle_polygon_vertices, debug_obstacle_polygon_colors);
|
||||
|
||||
Color debug_static_obstacle_edge_color;
|
||||
|
||||
if (obstacle_pushes_inward) {
|
||||
debug_static_obstacle_edge_color = Navigation2DServer::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushin_edge_color();
|
||||
} else {
|
||||
debug_static_obstacle_edge_color = Navigation2DServer::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushout_edge_color();
|
||||
}
|
||||
|
||||
Vector<Vector2> debug_obstacle_line_vertices = get_vertices();
|
||||
debug_obstacle_line_vertices.push_back(debug_obstacle_line_vertices[0]);
|
||||
debug_obstacle_line_vertices.resize(debug_obstacle_line_vertices.size());
|
||||
|
||||
Vector<Color> debug_obstacle_line_colors;
|
||||
debug_obstacle_line_colors.resize(debug_obstacle_line_vertices.size());
|
||||
debug_obstacle_line_colors.fill(debug_static_obstacle_edge_color);
|
||||
|
||||
RS::get_singleton()->canvas_item_add_polyline(get_canvas_item(), debug_obstacle_line_vertices, debug_obstacle_line_colors, 4.0);
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
@ -1,118 +0,0 @@
|
||||
#ifndef NAVIGATION_OBSTACLE_2D_H
|
||||
#define NAVIGATION_OBSTACLE_2D_H
|
||||
/*************************************************************************/
|
||||
/* navigation_obstacle_2d.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "scene/main/node_2d.h"
|
||||
|
||||
class Navigation2D;
|
||||
class Node2D;
|
||||
|
||||
class NavigationObstacle2D : public Node2D {
|
||||
GDCLASS(NavigationObstacle2D, Node2D);
|
||||
|
||||
Navigation2D *navigation;
|
||||
|
||||
RID obstacle;
|
||||
RID map_before_pause;
|
||||
RID map_override;
|
||||
RID map_current;
|
||||
|
||||
real_t radius;
|
||||
|
||||
Vector<Vector2> vertices;
|
||||
|
||||
bool avoidance_enabled;
|
||||
uint32_t avoidance_layers;
|
||||
|
||||
Transform2D previous_transform;
|
||||
|
||||
Vector2 velocity;
|
||||
Vector2 previous_velocity;
|
||||
bool velocity_submitted;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
private:
|
||||
void _update_fake_agent_radius_debug();
|
||||
void _update_static_obstacle_debug();
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
NavigationObstacle2D();
|
||||
virtual ~NavigationObstacle2D();
|
||||
|
||||
void set_navigation(Navigation2D *p_nav);
|
||||
const Navigation2D *get_navigation() const {
|
||||
return navigation;
|
||||
}
|
||||
|
||||
void set_navigation_node(Node *p_nav);
|
||||
Node *get_navigation_node() const;
|
||||
|
||||
RID get_rid() const { return obstacle; }
|
||||
|
||||
void set_avoidance_enabled(bool p_enabled);
|
||||
bool get_avoidance_enabled() const;
|
||||
|
||||
void set_navigation_map(RID p_navigation_map);
|
||||
RID get_navigation_map() const;
|
||||
|
||||
void set_radius(real_t p_radius);
|
||||
real_t get_radius() const {
|
||||
return radius;
|
||||
}
|
||||
|
||||
void set_vertices(const Vector<Vector2> &p_vertices);
|
||||
Vector<Vector2> get_vertices() const { return vertices; };
|
||||
|
||||
void set_avoidance_layers(uint32_t p_layers);
|
||||
uint32_t get_avoidance_layers() const;
|
||||
|
||||
void set_avoidance_mask(uint32_t p_mask);
|
||||
uint32_t get_avoidance_mask() const;
|
||||
|
||||
void set_avoidance_layer_value(int p_layer_number, bool p_value);
|
||||
bool get_avoidance_layer_value(int p_layer_number) const;
|
||||
|
||||
void set_velocity(const Vector2 p_velocity);
|
||||
Vector2 get_velocity() const { return velocity; };
|
||||
|
||||
void _avoidance_done(Vector3 p_new_velocity); // Dummy
|
||||
|
||||
private:
|
||||
void _update_map(RID p_map);
|
||||
void _update_position(const Vector2 p_position);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,694 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* navigation_polygon.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "navigation_polygon_instance.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "core/core_string_names.h"
|
||||
#include "core/math/geometry.h"
|
||||
#include "core/object/func_ref.h"
|
||||
#include "core/os/mutex.h"
|
||||
#include "core/os/os.h"
|
||||
#include "navigation_2d.h"
|
||||
#include "scene/2d/navigation_obstacle_2d.h"
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
#include "scene/resources/world_2d.h"
|
||||
#include "servers/navigation/navigation_mesh_generator.h"
|
||||
#include "servers/navigation_2d_server.h"
|
||||
#include "servers/navigation_server.h"
|
||||
|
||||
#include "thirdparty/misc/triangulator.h"
|
||||
|
||||
void NavigationPolygonInstance::set_enabled(bool p_enabled) {
|
||||
if (enabled == p_enabled) {
|
||||
return;
|
||||
}
|
||||
enabled = p_enabled;
|
||||
|
||||
Navigation2DServer::get_singleton()->region_set_enabled(region, enabled);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (Engine::get_singleton()->is_editor_hint() || Navigation2DServer::get_singleton()->get_debug_navigation_enabled()) {
|
||||
update();
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
bool NavigationPolygonInstance::is_enabled() const {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::set_use_edge_connections(bool p_enabled) {
|
||||
if (use_edge_connections == p_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
use_edge_connections = p_enabled;
|
||||
|
||||
Navigation2DServer::get_singleton()->region_set_use_edge_connections(region, use_edge_connections);
|
||||
}
|
||||
|
||||
bool NavigationPolygonInstance::get_use_edge_connections() const {
|
||||
return use_edge_connections;
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::set_navigation_layers(uint32_t p_navigation_layers) {
|
||||
navigation_layers = p_navigation_layers;
|
||||
Navigation2DServer::get_singleton()->region_set_navigation_layers(region, navigation_layers);
|
||||
}
|
||||
|
||||
uint32_t NavigationPolygonInstance::get_navigation_layers() const {
|
||||
return navigation_layers;
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::set_navigation_layer_value(int p_layer_number, bool p_value) {
|
||||
ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
uint32_t _navigation_layers = get_navigation_layers();
|
||||
if (p_value) {
|
||||
_navigation_layers |= 1 << (p_layer_number - 1);
|
||||
} else {
|
||||
_navigation_layers &= ~(1 << (p_layer_number - 1));
|
||||
}
|
||||
set_navigation_layers(_navigation_layers);
|
||||
}
|
||||
|
||||
bool NavigationPolygonInstance::get_navigation_layer_value(int p_layer_number) const {
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||
return get_navigation_layers() & (1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::set_enter_cost(real_t p_enter_cost) {
|
||||
ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive.");
|
||||
if (Math::is_equal_approx(enter_cost, p_enter_cost)) {
|
||||
return;
|
||||
}
|
||||
|
||||
enter_cost = p_enter_cost;
|
||||
|
||||
Navigation2DServer::get_singleton()->region_set_enter_cost(region, p_enter_cost);
|
||||
}
|
||||
|
||||
real_t NavigationPolygonInstance::get_enter_cost() const {
|
||||
return enter_cost;
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::set_travel_cost(real_t p_travel_cost) {
|
||||
ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive.");
|
||||
if (Math::is_equal_approx(travel_cost, p_travel_cost)) {
|
||||
return;
|
||||
}
|
||||
|
||||
travel_cost = p_travel_cost;
|
||||
|
||||
Navigation2DServer::get_singleton()->region_set_travel_cost(region, travel_cost);
|
||||
}
|
||||
|
||||
real_t NavigationPolygonInstance::get_travel_cost() const {
|
||||
return travel_cost;
|
||||
}
|
||||
|
||||
RID NavigationPolygonInstance::get_region_rid() const {
|
||||
return region;
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
#ifdef TOOLS_ENABLED
|
||||
Rect2 NavigationPolygonInstance::_edit_get_rect() const {
|
||||
return navigation_polygon.is_valid() ? navigation_polygon->_edit_get_rect() : Rect2();
|
||||
}
|
||||
|
||||
bool NavigationPolygonInstance::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
|
||||
return navigation_polygon.is_valid() ? navigation_polygon->_edit_is_selected_on_click(p_point, p_tolerance) : false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void NavigationPolygonInstance::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
Node2D *c = this;
|
||||
while (c) {
|
||||
navigation = Object::cast_to<Navigation2D>(c);
|
||||
|
||||
if (navigation) {
|
||||
break;
|
||||
}
|
||||
|
||||
c = Object::cast_to<Node2D>(c->get_parent());
|
||||
}
|
||||
|
||||
_region_enter_navigation_map();
|
||||
} break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
set_physics_process_internal(true);
|
||||
} break;
|
||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||
set_physics_process_internal(false);
|
||||
|
||||
_region_update_transform();
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
_region_exit_navigation_map();
|
||||
|
||||
navigation = nullptr;
|
||||
} break;
|
||||
case NOTIFICATION_DRAW: {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || Navigation2DServer::get_singleton()->get_debug_navigation_enabled()) && navigation_polygon.is_valid()) {
|
||||
_update_debug_mesh();
|
||||
_update_debug_edge_connections_mesh();
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolygon> &p_navigation_polygon) {
|
||||
if (p_navigation_polygon == navigation_polygon) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (navigation_polygon.is_valid()) {
|
||||
navigation_polygon->disconnect(CoreStringNames::get_singleton()->changed, this, "_navigation_polygon_changed");
|
||||
}
|
||||
|
||||
navigation_polygon = p_navigation_polygon;
|
||||
Navigation2DServer::get_singleton()->region_set_navigation_polygon(region, p_navigation_polygon);
|
||||
|
||||
if (navigation_polygon.is_valid()) {
|
||||
navigation_polygon->connect(CoreStringNames::get_singleton()->changed, this, "_navigation_polygon_changed");
|
||||
}
|
||||
|
||||
_navigation_polygon_changed();
|
||||
}
|
||||
|
||||
Ref<NavigationPolygon> NavigationPolygonInstance::get_navigation_polygon() const {
|
||||
return navigation_polygon;
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::set_navigation_map(RID p_navigation_map) {
|
||||
if (map_override == p_navigation_map) {
|
||||
return;
|
||||
}
|
||||
|
||||
map_override = p_navigation_map;
|
||||
|
||||
Navigation2DServer::get_singleton()->region_set_map(region, map_override);
|
||||
}
|
||||
|
||||
RID NavigationPolygonInstance::get_navigation_map() const {
|
||||
if (map_override.is_valid()) {
|
||||
return map_override;
|
||||
} else if (navigation) {
|
||||
return navigation->get_rid();
|
||||
} else if (is_inside_tree()) {
|
||||
return get_world_2d()->get_navigation_map();
|
||||
}
|
||||
return RID();
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::bake_navigation_polygon(bool p_on_thread) {
|
||||
ERR_FAIL_COND_MSG(!get_navigation_polygon().is_valid(), "Can't bake the navigation polygon if the `NavigationPolygon` resource doesn't exist");
|
||||
if (baking_started) {
|
||||
WARN_PRINT("NavigationPolygon baking already started. Wait for it to finish.");
|
||||
return;
|
||||
}
|
||||
baking_started = true;
|
||||
|
||||
navigation_polygon->clear();
|
||||
if (p_on_thread && OS::get_singleton()->can_use_threads()) {
|
||||
Ref<FuncRef> f;
|
||||
f.instance();
|
||||
f->set_instance(this);
|
||||
f->set_function("_bake_finished");
|
||||
|
||||
NavigationMeshGenerator::get_singleton()->parse_and_bake_2d(navigation_polygon, this, f);
|
||||
} else {
|
||||
Ref<NavigationMeshSourceGeometryData2D> source_geometry_data = NavigationMeshGenerator::get_singleton()->parse_2d_source_geometry_data(navigation_polygon, this);
|
||||
NavigationMeshGenerator::get_singleton()->bake_2d_from_source_geometry_data(navigation_polygon, source_geometry_data);
|
||||
_bake_finished();
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::_bake_finished() {
|
||||
baking_started = false;
|
||||
set_navigation_polygon(navigation_polygon);
|
||||
emit_signal("bake_finished");
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::_navigation_polygon_changed() {
|
||||
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) {
|
||||
update();
|
||||
}
|
||||
if (navigation_polygon.is_valid()) {
|
||||
Navigation2DServer::get_singleton()->region_set_navigation_polygon(region, navigation_polygon);
|
||||
}
|
||||
|
||||
_update_avoidance_constrain();
|
||||
|
||||
emit_signal("navigation_polygon_changed");
|
||||
_change_notify("navigation_polygon");
|
||||
|
||||
update_configuration_warning();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void NavigationPolygonInstance::_navigation_map_changed(RID p_map) {
|
||||
if (navigation != nullptr && enabled && (navigation->get_rid() == p_map)) {
|
||||
update();
|
||||
} else if (is_inside_tree() && enabled && (get_world_2d()->get_navigation_map() == p_map)) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
void NavigationPolygonInstance::_navigation_debug_changed() {
|
||||
if (navigation != nullptr && enabled) {
|
||||
update();
|
||||
} else if (is_inside_tree() && enabled) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
String NavigationPolygonInstance::get_configuration_warning() const {
|
||||
if (!is_visible_in_tree() || !is_inside_tree()) {
|
||||
return String();
|
||||
}
|
||||
|
||||
String warning = Node2D::get_configuration_warning();
|
||||
if (!navigation_polygon.is_valid()) {
|
||||
if (warning != String()) {
|
||||
warning += "\n\n";
|
||||
}
|
||||
warning += TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon.");
|
||||
}
|
||||
|
||||
return warning;
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationPolygonInstance::set_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationPolygonInstance::is_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_use_edge_connections", "enabled"), &NavigationPolygonInstance::set_use_edge_connections);
|
||||
ClassDB::bind_method(D_METHOD("get_use_edge_connections"), &NavigationPolygonInstance::get_use_edge_connections);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationPolygonInstance::set_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationPolygonInstance::get_navigation_layers);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationPolygonInstance::set_navigation_layer_value);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationPolygonInstance::get_navigation_layer_value);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_constrain_avoidance", "enabled"), &NavigationPolygonInstance::set_constrain_avoidance);
|
||||
ClassDB::bind_method(D_METHOD("get_constrain_avoidance"), &NavigationPolygonInstance::get_constrain_avoidance);
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_layers", "layers"), &NavigationPolygonInstance::set_avoidance_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_layers"), &NavigationPolygonInstance::get_avoidance_layers);
|
||||
ClassDB::bind_method(D_METHOD("set_avoidance_layer_value", "layer_number", "value"), &NavigationPolygonInstance::set_avoidance_layer_value);
|
||||
ClassDB::bind_method(D_METHOD("get_avoidance_layer_value", "layer_number"), &NavigationPolygonInstance::get_avoidance_layer_value);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationPolygonInstance::set_enter_cost);
|
||||
ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationPolygonInstance::get_enter_cost);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_travel_cost", "travel_cost"), &NavigationPolygonInstance::set_travel_cost);
|
||||
ClassDB::bind_method(D_METHOD("get_travel_cost"), &NavigationPolygonInstance::get_travel_cost);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navigation_polygon"), &NavigationPolygonInstance::set_navigation_polygon);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationPolygonInstance::get_navigation_polygon);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationPolygonInstance::set_navigation_map);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationPolygonInstance::get_navigation_map);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("bake_navigation_polygon", "on_thread"), &NavigationPolygonInstance::bake_navigation_polygon);
|
||||
ClassDB::bind_method(D_METHOD("_bake_finished"), &NavigationPolygonInstance::_bake_finished);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_region_rid"), &NavigationPolygonInstance::get_region_rid);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navigation_polygon", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_edge_connections"), "set_use_edge_connections", "get_use_edge_connections");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "enter_cost"), "set_enter_cost", "get_enter_cost");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "travel_cost"), "set_travel_cost", "get_travel_cost");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "constrain_avoidance"), "set_constrain_avoidance", "get_constrain_avoidance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "avoidance_layers", PROPERTY_HINT_LAYERS_AVOIDANCE), "set_avoidance_layers", "get_avoidance_layers");
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
ClassDB::bind_method(D_METHOD("_navigation_debug_changed"), &NavigationPolygonInstance::_navigation_debug_changed);
|
||||
ClassDB::bind_method(D_METHOD("_navigation_map_changed"), &NavigationPolygonInstance::_navigation_map_changed);
|
||||
#endif
|
||||
ClassDB::bind_method(D_METHOD("_navigation_polygon_changed"), &NavigationPolygonInstance::_navigation_polygon_changed);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("navigation_polygon_changed"));
|
||||
ADD_SIGNAL(MethodInfo("bake_finished"));
|
||||
}
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
//Renamed after 4.0
|
||||
bool NavigationPolygonInstance::_set(const StringName &p_name, const Variant &p_value) {
|
||||
if (p_name == "navpoly") {
|
||||
set_navigation_polygon(p_value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NavigationPolygonInstance::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
if (p_name == "navpoly") {
|
||||
r_ret = get_navigation_polygon();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
||||
NavigationPolygonInstance::NavigationPolygonInstance() {
|
||||
enabled = true;
|
||||
use_edge_connections = true;
|
||||
set_notify_transform(true);
|
||||
region = Navigation2DServer::get_singleton()->region_create();
|
||||
|
||||
navigation = nullptr;
|
||||
|
||||
enter_cost = 0.0;
|
||||
travel_cost = 1.0;
|
||||
|
||||
navigation_layers = 1;
|
||||
|
||||
constrain_avoidance = false;
|
||||
avoidance_layers = 1;
|
||||
|
||||
baking_started = false;
|
||||
Navigation2DServer::get_singleton()->region_set_owner_id(region, get_instance_id());
|
||||
Navigation2DServer::get_singleton()->region_set_enter_cost(region, get_enter_cost());
|
||||
Navigation2DServer::get_singleton()->region_set_travel_cost(region, get_travel_cost());
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
Navigation2DServer::get_singleton()->connect("map_changed", this, "_navigation_map_changed");
|
||||
NavigationServer::get_singleton()->connect("navigation_debug_changed", this, "_navigation_debug_changed");
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
NavigationPolygonInstance::~NavigationPolygonInstance() {
|
||||
ERR_FAIL_NULL(Navigation2DServer::get_singleton());
|
||||
|
||||
Navigation2DServer::get_singleton()->free(region);
|
||||
|
||||
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
|
||||
if (constrain_avoidance_obstacles[i].is_valid()) {
|
||||
Navigation2DServer::get_singleton()->free(constrain_avoidance_obstacles[i]);
|
||||
}
|
||||
}
|
||||
constrain_avoidance_obstacles.clear();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
Navigation2DServer::get_singleton()->disconnect("map_changed", this, "_navigation_map_changed");
|
||||
NavigationServer::get_singleton()->disconnect("navigation_debug_changed", this, "_navigation_debug_changed");
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::_update_avoidance_constrain() {
|
||||
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
|
||||
if (constrain_avoidance_obstacles[i].is_valid()) {
|
||||
Navigation2DServer::get_singleton()->free(constrain_avoidance_obstacles[i]);
|
||||
constrain_avoidance_obstacles[i] = RID();
|
||||
}
|
||||
}
|
||||
constrain_avoidance_obstacles.clear();
|
||||
|
||||
if (!constrain_avoidance) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_navigation_polygon() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<NavigationPolygon> _navigation_polygon = get_navigation_polygon();
|
||||
int _outline_count = _navigation_polygon->get_outline_count();
|
||||
if (_outline_count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int outline_index(0); outline_index < _outline_count; outline_index++) {
|
||||
//TODO navigation_polygon should probably use normal vectors internally
|
||||
const PoolVector<Vector2> &_outline = _navigation_polygon->get_outline(outline_index);
|
||||
|
||||
Vector<Vector2> outline;
|
||||
outline.resize(_outline.size());
|
||||
for (int i = 0; i < _outline.size(); ++i) {
|
||||
outline.write[i] = outline[i];
|
||||
}
|
||||
|
||||
const int outline_size = _outline.size();
|
||||
if (outline_size < 3) {
|
||||
ERR_FAIL_COND_MSG(_outline.size() < 3, "NavigationPolygon outline needs to have at least 3 vertex to create avoidance obstacles to constrain avoidance agent's");
|
||||
continue;
|
||||
}
|
||||
|
||||
RID obstacle_rid = Navigation2DServer::get_singleton()->obstacle_create();
|
||||
constrain_avoidance_obstacles.push_back(obstacle_rid);
|
||||
|
||||
Vector<Vector2> new_obstacle_outline;
|
||||
|
||||
if (outline_index == 0) {
|
||||
for (int i(0); i < outline_size; i++) {
|
||||
new_obstacle_outline.push_back(_outline[outline_size - i - 1]);
|
||||
}
|
||||
ERR_FAIL_COND_MSG(Geometry::is_polygon_clockwise(outline), "Outermost outline needs to be clockwise to push avoidance agent inside");
|
||||
} else {
|
||||
for (int i(0); i < outline_size; i++) {
|
||||
new_obstacle_outline.push_back(_outline[i]);
|
||||
}
|
||||
}
|
||||
new_obstacle_outline.resize(outline_size);
|
||||
|
||||
Navigation2DServer::get_singleton()->obstacle_set_vertices(obstacle_rid, new_obstacle_outline);
|
||||
Navigation2DServer::get_singleton()->obstacle_set_avoidance_layers(obstacle_rid, avoidance_layers);
|
||||
if (is_inside_tree()) {
|
||||
Navigation2DServer::get_singleton()->obstacle_set_map(obstacle_rid, get_world_2d()->get_navigation_map());
|
||||
Navigation2DServer::get_singleton()->obstacle_set_position(obstacle_rid, get_global_position());
|
||||
}
|
||||
}
|
||||
constrain_avoidance_obstacles.resize(_outline_count);
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::set_constrain_avoidance(bool p_enabled) {
|
||||
constrain_avoidance = p_enabled;
|
||||
_update_avoidance_constrain();
|
||||
property_list_changed_notify();
|
||||
}
|
||||
|
||||
bool NavigationPolygonInstance::get_constrain_avoidance() const {
|
||||
return constrain_avoidance;
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::_validate_property(PropertyInfo &p_property) const {
|
||||
if (p_property.name == "avoidance_layers") {
|
||||
if (!constrain_avoidance) {
|
||||
p_property.usage = PROPERTY_USAGE_NOEDITOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::set_avoidance_layers(uint32_t p_layers) {
|
||||
avoidance_layers = p_layers;
|
||||
if (constrain_avoidance_obstacles.size() > 0) {
|
||||
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
|
||||
Navigation2DServer::get_singleton()->obstacle_set_avoidance_layers(constrain_avoidance_obstacles[i], avoidance_layers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t NavigationPolygonInstance::get_avoidance_layers() const {
|
||||
return avoidance_layers;
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::set_avoidance_layer_value(int p_layer_number, bool p_value) {
|
||||
ERR_FAIL_COND_MSG(p_layer_number < 1, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_MSG(p_layer_number > 32, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
uint32_t avoidance_layers_new = get_avoidance_layers();
|
||||
if (p_value) {
|
||||
avoidance_layers_new |= 1 << (p_layer_number - 1);
|
||||
} else {
|
||||
avoidance_layers_new &= ~(1 << (p_layer_number - 1));
|
||||
}
|
||||
set_avoidance_layers(avoidance_layers_new);
|
||||
}
|
||||
|
||||
bool NavigationPolygonInstance::get_avoidance_layer_value(int p_layer_number) const {
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Avoidance layer number must be between 1 and 32 inclusive.");
|
||||
return get_avoidance_layers() & (1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::_region_enter_navigation_map() {
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
RID map = get_navigation_map();
|
||||
|
||||
Navigation2DServer::get_singleton()->region_set_map(region, map);
|
||||
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
|
||||
if (constrain_avoidance_obstacles[i].is_valid()) {
|
||||
Navigation2DServer::get_singleton()->obstacle_set_map(constrain_avoidance_obstacles[i], map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current_global_transform = get_global_transform();
|
||||
Navigation2DServer::get_singleton()->region_set_transform(region, current_global_transform);
|
||||
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
|
||||
if (constrain_avoidance_obstacles[i].is_valid()) {
|
||||
Navigation2DServer::get_singleton()->obstacle_set_position(constrain_avoidance_obstacles[i], get_global_position());
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::_region_exit_navigation_map() {
|
||||
Navigation2DServer::get_singleton()->region_set_map(region, RID());
|
||||
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
|
||||
if (constrain_avoidance_obstacles[i].is_valid()) {
|
||||
Navigation2DServer::get_singleton()->obstacle_set_map(constrain_avoidance_obstacles[i], RID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationPolygonInstance::_region_update_transform() {
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Transform2D new_global_transform = get_global_transform();
|
||||
if (current_global_transform != new_global_transform) {
|
||||
current_global_transform = new_global_transform;
|
||||
Navigation2DServer::get_singleton()->region_set_transform(region, current_global_transform);
|
||||
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
|
||||
if (constrain_avoidance_obstacles[i].is_valid()) {
|
||||
Navigation2DServer::get_singleton()->obstacle_set_position(constrain_avoidance_obstacles[i], get_global_position());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void NavigationPolygonInstance::_update_debug_mesh() {
|
||||
PoolVector<Vector2> navigation_polygon_vertices = navigation_polygon->get_vertices();
|
||||
if (navigation_polygon_vertices.size() < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Navigation2DServer *ns2d = Navigation2DServer::get_singleton();
|
||||
|
||||
bool enabled_geometry_face_random_color = ns2d->get_debug_navigation_enable_geometry_face_random_color();
|
||||
bool enabled_edge_lines = ns2d->get_debug_navigation_enable_edge_lines();
|
||||
//bool enable_edge_connections = use_edge_connections && ns2d->get_debug_navigation_enable_edge_connections() && ns2d->map_get_use_edge_connections(get_world_2d()->get_navigation_map());
|
||||
|
||||
Color debug_face_color = ns2d->get_debug_navigation_geometry_face_color();
|
||||
Color debug_edge_color = ns2d->get_debug_navigation_geometry_edge_color();
|
||||
//Color debug_edge_connection_color = ns2d->get_debug_navigation_edge_connection_color();
|
||||
|
||||
if (!enabled) {
|
||||
debug_face_color = ns2d->get_debug_navigation_geometry_face_disabled_color();
|
||||
debug_edge_color = ns2d->get_debug_navigation_geometry_edge_disabled_color();
|
||||
}
|
||||
|
||||
RandomPCG rand;
|
||||
|
||||
for (int i = 0; i < navigation_polygon->get_polygon_count(); i++) {
|
||||
// An array of vertices for this polygon.
|
||||
Vector<int> polygon = navigation_polygon->get_polygon(i);
|
||||
|
||||
Vector<Vector2> debug_polygon_vertices;
|
||||
debug_polygon_vertices.resize(polygon.size());
|
||||
for (int j = 0; j < polygon.size(); j++) {
|
||||
ERR_FAIL_INDEX(polygon[j], navigation_polygon_vertices.size());
|
||||
debug_polygon_vertices.write[j] = navigation_polygon_vertices[polygon[j]];
|
||||
}
|
||||
// Generate the polygon color, slightly randomly modified from the settings one.
|
||||
Color random_variation_color = debug_face_color;
|
||||
if (enabled_geometry_face_random_color) {
|
||||
random_variation_color.set_hsv(debug_face_color.get_h() + rand.random(-1.0, 1.0) * 0.1, debug_face_color.get_s(), debug_face_color.get_v() + rand.random(-1.0, 1.0) * 0.2);
|
||||
}
|
||||
random_variation_color.a = debug_face_color.a;
|
||||
|
||||
Vector<Color> debug_face_colors;
|
||||
debug_face_colors.push_back(random_variation_color);
|
||||
RS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), debug_polygon_vertices, debug_face_colors);
|
||||
|
||||
if (enabled_edge_lines) {
|
||||
Vector<Color> debug_edge_colors;
|
||||
debug_edge_colors.push_back(debug_edge_color);
|
||||
debug_polygon_vertices.push_back(debug_polygon_vertices[0]); // Add first again for closing polyline.
|
||||
RS::get_singleton()->canvas_item_add_polyline(get_canvas_item(), debug_polygon_vertices, debug_edge_colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void NavigationPolygonInstance::_update_debug_edge_connections_mesh() {
|
||||
const Navigation2DServer *ns2d = Navigation2DServer::get_singleton();
|
||||
bool enable_edge_connections = ns2d->get_debug_navigation_enable_edge_connections();
|
||||
|
||||
if (enable_edge_connections) {
|
||||
Color debug_edge_connection_color = ns2d->get_debug_navigation_edge_connection_color();
|
||||
|
||||
// Draw the region edge connections.
|
||||
Transform2D xform = get_global_transform();
|
||||
|
||||
RID map = get_navigation_map();
|
||||
|
||||
real_t radius = 1.0;
|
||||
radius = ns2d->map_get_edge_connection_margin(map) / 2.0;
|
||||
|
||||
for (int i = 0; i < ns2d->region_get_connections_count(region); i++) {
|
||||
// Two main points
|
||||
Vector2 a = ns2d->region_get_connection_pathway_start(region, i);
|
||||
a = xform.affine_inverse().xform(a);
|
||||
Vector2 b = ns2d->region_get_connection_pathway_end(region, i);
|
||||
b = xform.affine_inverse().xform(b);
|
||||
draw_line(a, b, debug_edge_connection_color);
|
||||
|
||||
// Draw a circle to illustrate the margins.
|
||||
real_t angle = a.angle_to_point(b);
|
||||
draw_arc(a, radius, angle + Math_PI / 2.0, angle - Math_PI / 2.0 + Math_TAU, 10, debug_edge_connection_color);
|
||||
draw_arc(b, radius, angle - Math_PI / 2.0, angle + Math_PI / 2.0, 10, debug_edge_connection_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
@ -1,139 +0,0 @@
|
||||
#ifndef NAVIGATION_REGION_2D_H
|
||||
#define NAVIGATION_REGION_2D_H
|
||||
|
||||
/*************************************************************************/
|
||||
/* navigation_polygon.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "core/object/resource.h"
|
||||
#include "scene/main/node_2d.h"
|
||||
|
||||
class NavigationMesh;
|
||||
class Navigation2D;
|
||||
class NavigationPolygon;
|
||||
|
||||
class NavigationPolygonInstance : public Node2D {
|
||||
GDCLASS(NavigationPolygonInstance, Node2D);
|
||||
|
||||
bool enabled;
|
||||
bool use_edge_connections;
|
||||
|
||||
RID region;
|
||||
RID map_override;
|
||||
Navigation2D *navigation;
|
||||
Ref<NavigationPolygon> navigation_polygon;
|
||||
bool baking_started;
|
||||
|
||||
real_t enter_cost;
|
||||
real_t travel_cost;
|
||||
|
||||
uint32_t navigation_layers;
|
||||
|
||||
Transform2D current_global_transform;
|
||||
|
||||
bool constrain_avoidance;
|
||||
LocalVector<RID> constrain_avoidance_obstacles;
|
||||
uint32_t avoidance_layers;
|
||||
|
||||
void _navigation_polygon_changed();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void _update_debug_mesh();
|
||||
void _update_debug_edge_connections_mesh();
|
||||
void _navigation_map_changed(RID p_map);
|
||||
void _navigation_debug_changed();
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
void _validate_property(PropertyInfo &p_property) const;
|
||||
static void _bind_methods();
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
||||
public:
|
||||
#ifdef TOOLS_ENABLED
|
||||
virtual Rect2 _edit_get_rect() const;
|
||||
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
|
||||
#endif
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
|
||||
void set_use_edge_connections(bool p_enabled);
|
||||
bool get_use_edge_connections() const;
|
||||
|
||||
void set_navigation_layers(uint32_t p_navigation_layers);
|
||||
uint32_t get_navigation_layers() const;
|
||||
|
||||
void set_navigation_layer_value(int p_layer_number, bool p_value);
|
||||
bool get_navigation_layer_value(int p_layer_number) const;
|
||||
|
||||
RID get_region_rid() const;
|
||||
|
||||
void set_enter_cost(real_t p_enter_cost);
|
||||
real_t get_enter_cost() const;
|
||||
|
||||
void set_travel_cost(real_t p_travel_cost);
|
||||
real_t get_travel_cost() const;
|
||||
|
||||
void set_navigation_polygon(const Ref<NavigationPolygon> &p_navigation_polygon);
|
||||
Ref<NavigationPolygon> get_navigation_polygon() const;
|
||||
|
||||
void set_constrain_avoidance(bool p_enabled);
|
||||
bool get_constrain_avoidance() const;
|
||||
|
||||
void set_avoidance_layers(uint32_t p_layers);
|
||||
uint32_t get_avoidance_layers() const;
|
||||
|
||||
void set_avoidance_layer_value(int p_layer_number, bool p_value);
|
||||
bool get_avoidance_layer_value(int p_layer_number) const;
|
||||
|
||||
void set_navigation_map(RID p_navigation_map);
|
||||
RID get_navigation_map() const;
|
||||
|
||||
void bake_navigation_polygon(bool p_on_thread);
|
||||
void _bake_finished();
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
NavigationPolygonInstance();
|
||||
~NavigationPolygonInstance();
|
||||
|
||||
private:
|
||||
void _update_avoidance_constrain();
|
||||
void _region_enter_navigation_map();
|
||||
void _region_exit_navigation_map();
|
||||
void _region_update_transform();
|
||||
};
|
||||
|
||||
#endif // NAVIGATIONPOLYGON_H
|
@ -54,7 +54,6 @@
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "scene/resources/world_2d.h"
|
||||
#include "servers/audio_server.h"
|
||||
#include "servers/navigation_server.h"
|
||||
#include "servers/physics_2d_server.h"
|
||||
#include "viewport.h"
|
||||
|
||||
|
@ -49,12 +49,6 @@
|
||||
#include "scene/2d/listener_2d.h"
|
||||
#include "scene/2d/mesh_instance_2d.h"
|
||||
#include "scene/2d/multimesh_instance_2d.h"
|
||||
#include "scene/2d/navigation_2d.h"
|
||||
#include "scene/2d/navigation_agent_2d.h"
|
||||
#include "scene/2d/navigation_geometry_parser_2d.h"
|
||||
#include "scene/2d/navigation_link_2d.h"
|
||||
#include "scene/2d/navigation_obstacle_2d.h"
|
||||
#include "scene/2d/navigation_polygon_instance.h"
|
||||
#include "scene/2d/parallax_background.h"
|
||||
#include "scene/2d/parallax_layer.h"
|
||||
#include "scene/2d/path_2d.h"
|
||||
@ -148,9 +142,6 @@
|
||||
#include "scene/resources/mesh/mesh.h"
|
||||
#include "scene/resources/mesh/mesh_data_tool.h"
|
||||
#include "scene/resources/mesh/multimesh.h"
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "scene/resources/mesh/polygon_path_finder.h"
|
||||
#include "scene/resources/mesh/primitive_meshes.h"
|
||||
@ -366,16 +357,10 @@ void register_scene_types() {
|
||||
OS::get_singleton()->yield(); //may take time to init
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
ClassDB::register_class<NavigationMesh>();
|
||||
|
||||
OS::get_singleton()->yield(); //may take time to init
|
||||
|
||||
ClassDB::register_class<Curve3D>();
|
||||
|
||||
OS::get_singleton()->yield(); //may take time to init
|
||||
|
||||
#endif
|
||||
ClassDB::register_class<NavigationMesh>();
|
||||
|
||||
AcceptDialog::set_swap_ok_cancel(GLOBAL_DEF_NOVAL("gui/common/swap_ok_cancel", bool(OS::get_singleton()->get_swap_ok_cancel())));
|
||||
|
||||
@ -521,16 +506,6 @@ void register_scene_types() {
|
||||
ClassDB::register_class<Path2D>();
|
||||
ClassDB::register_class<PathFollow2D>();
|
||||
|
||||
ClassDB::register_class<Navigation2D>();
|
||||
ClassDB::register_class<NavigationPolygon>();
|
||||
ClassDB::register_class<NavigationPolygonInstance>();
|
||||
ClassDB::register_class<NavigationAgent2D>();
|
||||
ClassDB::register_class<NavigationObstacle2D>();
|
||||
ClassDB::register_class<NavigationLink2D>();
|
||||
|
||||
ClassDB::register_class<NavigationMeshSourceGeometryData2D>();
|
||||
ClassDB::register_class<NavigationGeometryParser2D>();
|
||||
|
||||
OS::get_singleton()->yield(); //may take time to init
|
||||
|
||||
ClassDB::register_virtual_class<SceneState>();
|
||||
@ -548,14 +523,6 @@ void register_scene_types() {
|
||||
for (int i = 0; i < 32; i++) {
|
||||
GLOBAL_DEF("layer_names/2d_physics/layer_" + itos(i + 1), "");
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
GLOBAL_DEF("layer_names/2d_navigation/layer_" + itos(i + 1), "");
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
GLOBAL_DEF("layer_names/avoidance/layer_" + itos(i + 1), "");
|
||||
}
|
||||
}
|
||||
|
||||
void initialize_theme() {
|
||||
|
@ -422,54 +422,6 @@ Vector<Face3> ImporterMesh::get_faces() const {
|
||||
return faces;
|
||||
}
|
||||
|
||||
Ref<NavigationMesh> ImporterMesh::create_navigation_mesh() {
|
||||
Vector<Face3> faces = get_faces();
|
||||
if (faces.size() == 0) {
|
||||
return Ref<NavigationMesh>();
|
||||
}
|
||||
|
||||
HashMap<Vector3, int> unique_vertices;
|
||||
LocalVector<int> face_indices;
|
||||
|
||||
for (int i = 0; i < faces.size(); i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
Vector3 v = faces[i].vertex[j];
|
||||
int idx;
|
||||
if (unique_vertices.has(v)) {
|
||||
idx = unique_vertices[v];
|
||||
} else {
|
||||
idx = unique_vertices.size();
|
||||
unique_vertices[v] = idx;
|
||||
}
|
||||
face_indices.push_back(idx);
|
||||
}
|
||||
}
|
||||
|
||||
PoolVector<Vector3> vertices;
|
||||
vertices.resize(unique_vertices.size());
|
||||
|
||||
const Vector3 *key = NULL;
|
||||
while ((key = unique_vertices.next(key))) {
|
||||
Vector3 k = *key;
|
||||
vertices.set(unique_vertices[k], k);
|
||||
}
|
||||
|
||||
Ref<NavigationMesh> nm;
|
||||
nm.instance();
|
||||
nm->set_vertices(vertices);
|
||||
|
||||
Vector<int> v3;
|
||||
v3.resize(3);
|
||||
for (uint32_t i = 0; i < face_indices.size(); i += 3) {
|
||||
v3.write[0] = face_indices[i + 0];
|
||||
v3.write[1] = face_indices[i + 1];
|
||||
v3.write[2] = face_indices[i + 2];
|
||||
nm->add_polygon(v3);
|
||||
}
|
||||
|
||||
return nm;
|
||||
}
|
||||
|
||||
struct EditorSceneFormatImporterMeshLightmapSurface {
|
||||
Ref<Material> material;
|
||||
LocalVector<SurfaceTool::Vertex> vertices;
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "core/object/resource.h"
|
||||
#include "core/containers/local_vector.h"
|
||||
#include "scene/resources/mesh/mesh.h"
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@ -114,7 +113,6 @@ public:
|
||||
void set_surface_material(int p_surface, const Ref<Material> &p_material);
|
||||
|
||||
Vector<Face3> get_faces() const;
|
||||
Ref<NavigationMesh> create_navigation_mesh();
|
||||
|
||||
bool has_mesh() const;
|
||||
Ref<ArrayMesh> get_mesh(const Ref<ArrayMesh> &p_base = Ref<ArrayMesh>());
|
||||
|
@ -1,691 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* navigation_mesh.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "navigation_mesh.h"
|
||||
|
||||
#include "servers/navigation_server.h"
|
||||
|
||||
void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) {
|
||||
ERR_FAIL_COND(p_mesh.is_null());
|
||||
|
||||
vertices = PoolVector<Vector3>();
|
||||
clear_polygons();
|
||||
|
||||
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
|
||||
if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
|
||||
WARN_PRINT("A mesh surface was skipped when creating a NavigationMesh due to wrong primitive type in the source mesh. Mesh surface must be made out of triangles.");
|
||||
continue;
|
||||
}
|
||||
|
||||
Array arr = p_mesh->surface_get_arrays(i);
|
||||
|
||||
ERR_CONTINUE(arr.size() != Mesh::ARRAY_MAX);
|
||||
|
||||
PoolVector<Vector3> varr = arr[Mesh::ARRAY_VERTEX];
|
||||
PoolVector<int> iarr = arr[Mesh::ARRAY_INDEX];
|
||||
if (varr.size() == 0 || iarr.size() == 0) {
|
||||
WARN_PRINT("A mesh surface was skipped when creating a NavigationMesh due to an empty vertex or index array.");
|
||||
continue;
|
||||
}
|
||||
|
||||
int from = vertices.size();
|
||||
vertices.append_array(varr);
|
||||
int rlen = iarr.size();
|
||||
PoolVector<int>::Read r = iarr.read();
|
||||
|
||||
for (int j = 0; j < rlen; j += 3) {
|
||||
Vector<int> vi;
|
||||
vi.resize(3);
|
||||
vi.write[0] = r[j + 0] + from;
|
||||
vi.write[1] = r[j + 1] + from;
|
||||
vi.write[2] = r[j + 2] + from;
|
||||
|
||||
add_polygon(vi);
|
||||
}
|
||||
}
|
||||
|
||||
navigation_mesh_dirty = true;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_sample_partition_type(SamplePartitionType p_value) {
|
||||
ERR_FAIL_INDEX(p_value, SAMPLE_PARTITION_MAX);
|
||||
partition_type = p_value;
|
||||
}
|
||||
|
||||
NavigationMesh::SamplePartitionType NavigationMesh::get_sample_partition_type() const {
|
||||
return partition_type;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_parsed_geometry_type(ParsedGeometryType p_value) {
|
||||
ERR_FAIL_INDEX(p_value, PARSED_GEOMETRY_MAX);
|
||||
parsed_geometry_type = p_value;
|
||||
_change_notify();
|
||||
}
|
||||
|
||||
NavigationMesh::ParsedGeometryType NavigationMesh::get_parsed_geometry_type() const {
|
||||
return parsed_geometry_type;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_collision_mask(uint32_t p_mask) {
|
||||
collision_mask = p_mask;
|
||||
}
|
||||
|
||||
uint32_t NavigationMesh::get_collision_mask() const {
|
||||
return collision_mask;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_collision_mask_bit(int p_bit, bool p_value) {
|
||||
ERR_FAIL_INDEX_MSG(p_bit, 32, "Collision mask bit must be between 0 and 31 inclusive.");
|
||||
uint32_t mask = get_collision_mask();
|
||||
if (p_value) {
|
||||
mask |= 1 << p_bit;
|
||||
} else {
|
||||
mask &= ~(1 << p_bit);
|
||||
}
|
||||
set_collision_mask(mask);
|
||||
}
|
||||
|
||||
bool NavigationMesh::get_collision_mask_bit(int p_bit) const {
|
||||
ERR_FAIL_INDEX_V_MSG(p_bit, 32, false, "Collision mask bit must be between 0 and 31 inclusive.");
|
||||
return get_collision_mask() & (1 << p_bit);
|
||||
}
|
||||
|
||||
void NavigationMesh::set_source_geometry_mode(SourceGeometryMode p_geometry_mode) {
|
||||
ERR_FAIL_INDEX(p_geometry_mode, SOURCE_GEOMETRY_MAX);
|
||||
source_geometry_mode = p_geometry_mode;
|
||||
_change_notify();
|
||||
}
|
||||
|
||||
NavigationMesh::SourceGeometryMode NavigationMesh::get_source_geometry_mode() const {
|
||||
return source_geometry_mode;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_source_group_name(StringName p_group_name) {
|
||||
source_group_name = p_group_name;
|
||||
}
|
||||
|
||||
StringName NavigationMesh::get_source_group_name() const {
|
||||
return source_group_name;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_cell_size(float p_value) {
|
||||
ERR_FAIL_COND(p_value <= 0);
|
||||
cell_size = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_cell_size() const {
|
||||
return cell_size;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_cell_height(float p_value) {
|
||||
ERR_FAIL_COND(p_value <= 0);
|
||||
cell_height = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_cell_height() const {
|
||||
return cell_height;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_agent_height(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 0);
|
||||
agent_height = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_agent_height() const {
|
||||
return agent_height;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_agent_radius(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 0);
|
||||
agent_radius = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_agent_radius() {
|
||||
return agent_radius;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_agent_max_climb(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 0);
|
||||
agent_max_climb = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_agent_max_climb() const {
|
||||
return agent_max_climb;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_agent_max_slope(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 0 || p_value > 90);
|
||||
agent_max_slope = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_agent_max_slope() const {
|
||||
return agent_max_slope;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_region_min_size(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 0);
|
||||
region_min_size = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_region_min_size() const {
|
||||
return region_min_size;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_region_merge_size(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 0);
|
||||
region_merge_size = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_region_merge_size() const {
|
||||
return region_merge_size;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_edge_max_length(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 0);
|
||||
edge_max_length = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_edge_max_length() const {
|
||||
return edge_max_length;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_edge_max_error(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 0);
|
||||
edge_max_error = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_edge_max_error() const {
|
||||
return edge_max_error;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_vertices_per_polygon(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 3);
|
||||
vertices_per_polygon = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_vertices_per_polygon() const {
|
||||
return vertices_per_polygon;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_detail_sample_distance(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 0.1);
|
||||
detail_sample_distance = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_detail_sample_distance() const {
|
||||
return detail_sample_distance;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_detail_sample_max_error(float p_value) {
|
||||
ERR_FAIL_COND(p_value < 0);
|
||||
detail_sample_max_error = p_value;
|
||||
}
|
||||
|
||||
float NavigationMesh::get_detail_sample_max_error() const {
|
||||
return detail_sample_max_error;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_filter_low_hanging_obstacles(bool p_value) {
|
||||
filter_low_hanging_obstacles = p_value;
|
||||
}
|
||||
|
||||
bool NavigationMesh::get_filter_low_hanging_obstacles() const {
|
||||
return filter_low_hanging_obstacles;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_filter_ledge_spans(bool p_value) {
|
||||
filter_ledge_spans = p_value;
|
||||
}
|
||||
|
||||
bool NavigationMesh::get_filter_ledge_spans() const {
|
||||
return filter_ledge_spans;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_filter_walkable_low_height_spans(bool p_value) {
|
||||
filter_walkable_low_height_spans = p_value;
|
||||
}
|
||||
|
||||
bool NavigationMesh::get_filter_walkable_low_height_spans() const {
|
||||
return filter_walkable_low_height_spans;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_filter_baking_aabb(const AABB &p_aabb) {
|
||||
filter_baking_aabb = p_aabb;
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
AABB NavigationMesh::get_filter_baking_aabb() const {
|
||||
return filter_baking_aabb;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_filter_baking_aabb_offset(const Vector3 &p_aabb_offset) {
|
||||
filter_baking_aabb_offset = p_aabb_offset;
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
Vector3 NavigationMesh::get_filter_baking_aabb_offset() const {
|
||||
return filter_baking_aabb_offset;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_vertices(const PoolVector<Vector3> &p_vertices) {
|
||||
vertices = p_vertices;
|
||||
navigation_mesh_dirty = true;
|
||||
}
|
||||
|
||||
PoolVector<Vector3> NavigationMesh::get_vertices() const {
|
||||
return vertices;
|
||||
}
|
||||
|
||||
void NavigationMesh::add_polygon(const Vector<int> &p_polygon) {
|
||||
polygons.push_back(p_polygon);
|
||||
navigation_mesh_dirty = true;
|
||||
}
|
||||
int NavigationMesh::get_polygon_count() const {
|
||||
return polygons.size();
|
||||
}
|
||||
Vector<int> NavigationMesh::get_polygon(int p_idx) {
|
||||
ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>());
|
||||
return polygons[p_idx];
|
||||
}
|
||||
void NavigationMesh::clear_polygons() {
|
||||
polygons.clear();
|
||||
navigation_mesh_dirty = true;
|
||||
}
|
||||
|
||||
void NavigationMesh::clear() {
|
||||
polygons.clear();
|
||||
vertices.clear();
|
||||
navigation_mesh_dirty = true;
|
||||
}
|
||||
void NavigationMesh::commit_changes() {
|
||||
// Function to synchronize the navigation mesh with the NavigationServer
|
||||
// Placeholder function that gets fleshed out with PR 'Add NavigationServer Navmesh and NavMesh Instances'
|
||||
// Function was already added so users and tutorials and documentation only have to adapt once to the procedural workflow changes
|
||||
if (navigation_mesh_dirty) {
|
||||
navigation_mesh_dirty = false;
|
||||
/*
|
||||
Vector<Vector3> new_navigation_mesh_vertices;
|
||||
Vector<Vector<int32_t>> new_navigation_mesh_polygons;
|
||||
new_navigation_mesh_vertices.resize(vertices.size());
|
||||
new_navigation_mesh_polygons.resize(polygons.size());
|
||||
Vector3 *new_navigation_mesh_vertices_ptrw = new_navigation_mesh_vertices.ptrw();
|
||||
Vector<int32_t> *new_navigation_mesh_polygons_ptrw = new_navigation_mesh_polygons.ptrw();
|
||||
for (int i = 0; i < vertices.size(); i++) {
|
||||
new_navigation_mesh_vertices_ptrw[i] = vertices[i];
|
||||
}
|
||||
for (int i = 0; i < polygons.size(); i++) {
|
||||
new_navigation_mesh_polygons_ptrw[i] = polygons[i];
|
||||
}
|
||||
NavigationServer3D::get_singleton()->navigation_mesh_set_data(navigation_mesh_rid, new_navigation_mesh_vertices, new_navigation_mesh_polygons);
|
||||
*/
|
||||
emit_changed();
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationMesh::set_polygons(const Vector<Vector<int>> &p_polygons) {
|
||||
polygons = p_polygons;
|
||||
navigation_mesh_dirty = true;
|
||||
}
|
||||
const Vector<Vector<int>> &NavigationMesh::get_polygons() const {
|
||||
return polygons;
|
||||
}
|
||||
|
||||
void NavigationMesh::_set_polygons(const Array &p_array) {
|
||||
polygons.resize(p_array.size());
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
polygons.write[i] = p_array[i];
|
||||
}
|
||||
navigation_mesh_dirty = true;
|
||||
}
|
||||
|
||||
Array NavigationMesh::_get_polygons() const {
|
||||
Array ret;
|
||||
ret.resize(polygons.size());
|
||||
for (int i = 0; i < ret.size(); i++) {
|
||||
ret[i] = polygons[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RID NavigationMesh::get_rid() const {
|
||||
if (navigation_mesh_rid.is_valid()) {
|
||||
return navigation_mesh_rid;
|
||||
}
|
||||
return RID();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
Ref<ArrayMesh> NavigationMesh::get_debug_mesh() {
|
||||
if (debug_mesh.is_valid()) {
|
||||
// Blocks further updates for now, code below is intended for dynamic updates e.g. when settings change.
|
||||
return debug_mesh;
|
||||
}
|
||||
|
||||
if (!debug_mesh.is_valid()) {
|
||||
debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
|
||||
} else {
|
||||
debug_mesh->clear_surfaces();
|
||||
}
|
||||
|
||||
if (vertices.size() == 0) {
|
||||
return debug_mesh;
|
||||
}
|
||||
|
||||
int polygon_count = get_polygon_count();
|
||||
|
||||
if (polygon_count < 1) {
|
||||
// no face, no play
|
||||
return debug_mesh;
|
||||
}
|
||||
|
||||
// build geometry face surface
|
||||
Vector<Vector3> face_vertex_array;
|
||||
face_vertex_array.resize(polygon_count * 3);
|
||||
|
||||
for (int i = 0; i < polygon_count; i++) {
|
||||
Vector<int> polygon = get_polygon(i);
|
||||
|
||||
face_vertex_array.push_back(vertices[polygon[0]]);
|
||||
face_vertex_array.push_back(vertices[polygon[1]]);
|
||||
face_vertex_array.push_back(vertices[polygon[2]]);
|
||||
}
|
||||
|
||||
Array face_mesh_array;
|
||||
face_mesh_array.resize(Mesh::ARRAY_MAX);
|
||||
face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array;
|
||||
|
||||
// if enabled add vertex colors to colorize each face individually
|
||||
bool enabled_geometry_face_random_color = NavigationServer::get_singleton()->get_debug_navigation_enable_geometry_face_random_color();
|
||||
if (enabled_geometry_face_random_color) {
|
||||
Color debug_navigation_geometry_face_color = NavigationServer::get_singleton()->get_debug_navigation_geometry_face_color();
|
||||
Color polygon_color = debug_navigation_geometry_face_color;
|
||||
|
||||
Vector<Color> face_color_array;
|
||||
face_color_array.resize(polygon_count * 3);
|
||||
|
||||
for (int i = 0; i < polygon_count; i++) {
|
||||
polygon_color = debug_navigation_geometry_face_color * (Color(Math::randf(), Math::randf(), Math::randf()));
|
||||
|
||||
Vector<int> polygon = get_polygon(i);
|
||||
|
||||
face_color_array.push_back(polygon_color);
|
||||
face_color_array.push_back(polygon_color);
|
||||
face_color_array.push_back(polygon_color);
|
||||
}
|
||||
face_mesh_array[Mesh::ARRAY_COLOR] = face_color_array;
|
||||
}
|
||||
|
||||
debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, face_mesh_array);
|
||||
|
||||
// if enabled build geometry edge line surface
|
||||
bool enabled_edge_lines = NavigationServer::get_singleton()->get_debug_navigation_enable_edge_lines();
|
||||
|
||||
if (enabled_edge_lines) {
|
||||
Vector<Vector3> line_vertex_array;
|
||||
line_vertex_array.resize(polygon_count * 6);
|
||||
|
||||
for (int i = 0; i < polygon_count; i++) {
|
||||
Vector<int> polygon = get_polygon(i);
|
||||
|
||||
line_vertex_array.push_back(vertices[polygon[0]]);
|
||||
line_vertex_array.push_back(vertices[polygon[1]]);
|
||||
line_vertex_array.push_back(vertices[polygon[1]]);
|
||||
line_vertex_array.push_back(vertices[polygon[2]]);
|
||||
line_vertex_array.push_back(vertices[polygon[2]]);
|
||||
line_vertex_array.push_back(vertices[polygon[0]]);
|
||||
}
|
||||
|
||||
Array line_mesh_array;
|
||||
line_mesh_array.resize(Mesh::ARRAY_MAX);
|
||||
line_mesh_array[Mesh::ARRAY_VERTEX] = line_vertex_array;
|
||||
debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, line_mesh_array);
|
||||
}
|
||||
|
||||
return debug_mesh;
|
||||
}
|
||||
#endif
|
||||
|
||||
void NavigationMesh::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_sample_partition_type", "sample_partition_type"), &NavigationMesh::set_sample_partition_type);
|
||||
ClassDB::bind_method(D_METHOD("get_sample_partition_type"), &NavigationMesh::get_sample_partition_type);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_parsed_geometry_type", "geometry_type"), &NavigationMesh::set_parsed_geometry_type);
|
||||
ClassDB::bind_method(D_METHOD("get_parsed_geometry_type"), &NavigationMesh::get_parsed_geometry_type);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &NavigationMesh::set_collision_mask);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_mask"), &NavigationMesh::get_collision_mask);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &NavigationMesh::set_collision_mask_bit);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &NavigationMesh::get_collision_mask_bit);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_source_geometry_mode", "mask"), &NavigationMesh::set_source_geometry_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_source_geometry_mode"), &NavigationMesh::get_source_geometry_mode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_source_group_name", "mask"), &NavigationMesh::set_source_group_name);
|
||||
ClassDB::bind_method(D_METHOD("get_source_group_name"), &NavigationMesh::get_source_group_name);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &NavigationMesh::set_cell_size);
|
||||
ClassDB::bind_method(D_METHOD("get_cell_size"), &NavigationMesh::get_cell_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_cell_height", "cell_height"), &NavigationMesh::set_cell_height);
|
||||
ClassDB::bind_method(D_METHOD("get_cell_height"), &NavigationMesh::get_cell_height);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_agent_height", "agent_height"), &NavigationMesh::set_agent_height);
|
||||
ClassDB::bind_method(D_METHOD("get_agent_height"), &NavigationMesh::get_agent_height);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_agent_radius", "agent_radius"), &NavigationMesh::set_agent_radius);
|
||||
ClassDB::bind_method(D_METHOD("get_agent_radius"), &NavigationMesh::get_agent_radius);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_agent_max_climb", "agent_max_climb"), &NavigationMesh::set_agent_max_climb);
|
||||
ClassDB::bind_method(D_METHOD("get_agent_max_climb"), &NavigationMesh::get_agent_max_climb);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_agent_max_slope", "agent_max_slope"), &NavigationMesh::set_agent_max_slope);
|
||||
ClassDB::bind_method(D_METHOD("get_agent_max_slope"), &NavigationMesh::get_agent_max_slope);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_region_min_size", "region_min_size"), &NavigationMesh::set_region_min_size);
|
||||
ClassDB::bind_method(D_METHOD("get_region_min_size"), &NavigationMesh::get_region_min_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_region_merge_size", "region_merge_size"), &NavigationMesh::set_region_merge_size);
|
||||
ClassDB::bind_method(D_METHOD("get_region_merge_size"), &NavigationMesh::get_region_merge_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_edge_max_length", "edge_max_length"), &NavigationMesh::set_edge_max_length);
|
||||
ClassDB::bind_method(D_METHOD("get_edge_max_length"), &NavigationMesh::get_edge_max_length);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_edge_max_error", "edge_max_error"), &NavigationMesh::set_edge_max_error);
|
||||
ClassDB::bind_method(D_METHOD("get_edge_max_error"), &NavigationMesh::get_edge_max_error);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_vertices_per_polygon", "vertices_per_polygon"), &NavigationMesh::set_vertices_per_polygon);
|
||||
ClassDB::bind_method(D_METHOD("get_vertices_per_polygon"), &NavigationMesh::get_vertices_per_polygon);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_detail_sample_distance", "detail_sample_dist"), &NavigationMesh::set_detail_sample_distance);
|
||||
ClassDB::bind_method(D_METHOD("get_detail_sample_distance"), &NavigationMesh::get_detail_sample_distance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_detail_sample_max_error", "detail_sample_max_error"), &NavigationMesh::set_detail_sample_max_error);
|
||||
ClassDB::bind_method(D_METHOD("get_detail_sample_max_error"), &NavigationMesh::get_detail_sample_max_error);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_filter_low_hanging_obstacles", "filter_low_hanging_obstacles"), &NavigationMesh::set_filter_low_hanging_obstacles);
|
||||
ClassDB::bind_method(D_METHOD("get_filter_low_hanging_obstacles"), &NavigationMesh::get_filter_low_hanging_obstacles);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_filter_ledge_spans", "filter_ledge_spans"), &NavigationMesh::set_filter_ledge_spans);
|
||||
ClassDB::bind_method(D_METHOD("get_filter_ledge_spans"), &NavigationMesh::get_filter_ledge_spans);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_filter_walkable_low_height_spans", "filter_walkable_low_height_spans"), &NavigationMesh::set_filter_walkable_low_height_spans);
|
||||
ClassDB::bind_method(D_METHOD("get_filter_walkable_low_height_spans"), &NavigationMesh::get_filter_walkable_low_height_spans);
|
||||
ClassDB::bind_method(D_METHOD("set_filter_baking_aabb", "baking_aabb"), &NavigationMesh::set_filter_baking_aabb);
|
||||
ClassDB::bind_method(D_METHOD("get_filter_baking_aabb"), &NavigationMesh::get_filter_baking_aabb);
|
||||
ClassDB::bind_method(D_METHOD("set_filter_baking_aabb_offset", "baking_aabb_offset"), &NavigationMesh::set_filter_baking_aabb_offset);
|
||||
ClassDB::bind_method(D_METHOD("get_filter_baking_aabb_offset"), &NavigationMesh::get_filter_baking_aabb_offset);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationMesh::set_vertices);
|
||||
ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationMesh::get_vertices);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_polygon", "polygon"), &NavigationMesh::add_polygon);
|
||||
ClassDB::bind_method(D_METHOD("get_polygon_count"), &NavigationMesh::get_polygon_count);
|
||||
ClassDB::bind_method(D_METHOD("get_polygon", "idx"), &NavigationMesh::get_polygon);
|
||||
ClassDB::bind_method(D_METHOD("clear_polygons"), &NavigationMesh::clear_polygons);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("create_from_mesh", "mesh"), &NavigationMesh::create_from_mesh);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("clear"), &NavigationMesh::clear);
|
||||
ClassDB::bind_method(D_METHOD("commit_changes"), &NavigationMesh::commit_changes);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_set_polygons", "polygons"), &NavigationMesh::_set_polygons);
|
||||
ClassDB::bind_method(D_METHOD("_get_polygons"), &NavigationMesh::_get_polygons);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_polygons", "_get_polygons");
|
||||
|
||||
ADD_GROUP("Sampling", "sample_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "sample_partition_type", PROPERTY_HINT_ENUM, "Watershed,Monotone,Layers"), "set_sample_partition_type", "get_sample_partition_type");
|
||||
|
||||
ADD_GROUP("Geometry", "geometry_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry_parsed_geometry_type", PROPERTY_HINT_ENUM, "Mesh Instances,Static Colliders,Both"), "set_parsed_geometry_type", "get_parsed_geometry_type");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry_collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry_source_geometry_mode", PROPERTY_HINT_ENUM, "Navmesh Children,Group With Children,Group Explicit"), "set_source_geometry_mode", "get_source_geometry_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry_source_group_name"), "set_source_group_name", "get_source_group_name");
|
||||
|
||||
ADD_GROUP("Cells", "cell_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_RANGE, "0.01,500.0,0.01,or_greater"), "set_cell_size", "get_cell_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_height", PROPERTY_HINT_RANGE, "0.01,500.0,0.01,or_greater"), "set_cell_height", "get_cell_height");
|
||||
|
||||
ADD_GROUP("Agents", "agent_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent_height", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater"), "set_agent_height", "get_agent_height");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent_radius", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater"), "set_agent_radius", "get_agent_radius");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent_max_climb", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater"), "set_agent_max_climb", "get_agent_max_climb");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent_max_slope", PROPERTY_HINT_RANGE, "0.02,90.0,0.01"), "set_agent_max_slope", "get_agent_max_slope");
|
||||
|
||||
ADD_GROUP("Regions", "region_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "region_min_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_min_size", "get_region_min_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "region_merge_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_merge_size", "get_region_merge_size");
|
||||
|
||||
ADD_GROUP("Edges", "edge_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge_max_length", PROPERTY_HINT_RANGE, "0.0,50.0,0.01,or_greater"), "set_edge_max_length", "get_edge_max_length");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge_max_error", PROPERTY_HINT_RANGE, "0.1,3.0,0.01,or_greater"), "set_edge_max_error", "get_edge_max_error");
|
||||
|
||||
ADD_GROUP("Polygons", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "vertices_per_polygon", PROPERTY_HINT_RANGE, "3.0,12.0,1.0,or_greater"), "set_vertices_per_polygon", "get_vertices_per_polygon");
|
||||
|
||||
ADD_GROUP("Details", "detail_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "detail_sample_distance", PROPERTY_HINT_RANGE, "0.1,16.0,0.01,or_greater"), "set_detail_sample_distance", "get_detail_sample_distance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "detail_sample_max_error", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_max_error", "get_detail_sample_max_error");
|
||||
|
||||
ADD_GROUP("Filters", "filter_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_low_hanging_obstacles"), "set_filter_low_hanging_obstacles", "get_filter_low_hanging_obstacles");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_ledge_spans"), "set_filter_ledge_spans", "get_filter_ledge_spans");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_walkable_low_height_spans"), "set_filter_walkable_low_height_spans", "get_filter_walkable_low_height_spans");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::AABB, "filter_baking_aabb"), "set_filter_baking_aabb", "get_filter_baking_aabb");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "filter_baking_aabb_offset"), "set_filter_baking_aabb_offset", "get_filter_baking_aabb_offset");
|
||||
|
||||
BIND_ENUM_CONSTANT(SAMPLE_PARTITION_WATERSHED);
|
||||
BIND_ENUM_CONSTANT(SAMPLE_PARTITION_MONOTONE);
|
||||
BIND_ENUM_CONSTANT(SAMPLE_PARTITION_LAYERS);
|
||||
BIND_ENUM_CONSTANT(SAMPLE_PARTITION_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(PARSED_GEOMETRY_MESH_INSTANCES);
|
||||
BIND_ENUM_CONSTANT(PARSED_GEOMETRY_STATIC_COLLIDERS);
|
||||
BIND_ENUM_CONSTANT(PARSED_GEOMETRY_BOTH);
|
||||
BIND_ENUM_CONSTANT(PARSED_GEOMETRY_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_ROOT_NODE_CHILDREN);
|
||||
BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN);
|
||||
BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_GROUPS_EXPLICIT);
|
||||
BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_MAX);
|
||||
}
|
||||
|
||||
void NavigationMesh::_validate_property(PropertyInfo &property) const {
|
||||
if (property.name == "geometry/collision_mask") {
|
||||
if (parsed_geometry_type == PARSED_GEOMETRY_MESH_INSTANCES) {
|
||||
property.usage = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (property.name == "geometry/source_group_name") {
|
||||
if (source_geometry_mode == SOURCE_GEOMETRY_ROOT_NODE_CHILDREN) {
|
||||
property.usage = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
//Renamed after 4.0
|
||||
bool NavigationMesh::_set(const StringName &p_name, const Variant &p_value) {
|
||||
if (p_name == "polygon_vertices_per_polyon") { // Renamed after 4.0
|
||||
set_vertices_per_polygon(p_value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NavigationMesh::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
if (p_name == "polygon_vertices_per_polyon") { // Renamed after 4.0
|
||||
r_ret = get_vertices_per_polygon();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
||||
NavigationMesh::NavigationMesh() {
|
||||
cell_size = 0.25f; // Must match ProjectSettings default 3D cell_size and NavigationServer NavMap cell_size.
|
||||
cell_height = 0.25f; // Must match ProjectSettings default 3D cell_height and NavigationServer NavMap cell_height.
|
||||
agent_height = 1.5f;
|
||||
agent_radius = 0.5f;
|
||||
agent_max_climb = 0.25f;
|
||||
agent_max_slope = 45.0f;
|
||||
region_min_size = 2.0f;
|
||||
region_merge_size = 20.0f;
|
||||
edge_max_length = 0.0f;
|
||||
edge_max_error = 1.3f;
|
||||
vertices_per_polygon = 6.0f;
|
||||
detail_sample_distance = 6.0f;
|
||||
detail_sample_max_error = 5.0f;
|
||||
|
||||
partition_type = SAMPLE_PARTITION_WATERSHED;
|
||||
parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES;
|
||||
collision_mask = 0xFFFFFFFF;
|
||||
source_geometry_mode = SOURCE_GEOMETRY_ROOT_NODE_CHILDREN;
|
||||
source_group_name = "navigation_mesh";
|
||||
filter_low_hanging_obstacles = false;
|
||||
filter_ledge_spans = false;
|
||||
filter_walkable_low_height_spans = false;
|
||||
|
||||
navigation_mesh_dirty = true;
|
||||
|
||||
//navigation_mesh_rid = NavigationServer3D::get_singleton()->navigation_mesh_create();
|
||||
call_deferred("commit_changes");
|
||||
}
|
||||
|
||||
NavigationMesh::~NavigationMesh() {
|
||||
//ERR_FAIL_NULL(NavigationServer::get_singleton());
|
||||
//NavigationServer::get_singleton()->free(navigation_mesh_rid);
|
||||
}
|
@ -1,219 +0,0 @@
|
||||
#ifndef NAVIGATION_MESH_H
|
||||
#define NAVIGATION_MESH_H
|
||||
/*************************************************************************/
|
||||
/* navigation_mesh.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "scene/resources/mesh/mesh.h"
|
||||
|
||||
class Mesh;
|
||||
class NavigationMeshGenerator;
|
||||
|
||||
class NavigationMesh : public Resource {
|
||||
GDCLASS(NavigationMesh, Resource);
|
||||
|
||||
friend class NavigationMeshGenerator;
|
||||
|
||||
public:
|
||||
enum SamplePartitionType {
|
||||
SAMPLE_PARTITION_WATERSHED = 0,
|
||||
SAMPLE_PARTITION_MONOTONE,
|
||||
SAMPLE_PARTITION_LAYERS,
|
||||
SAMPLE_PARTITION_MAX
|
||||
};
|
||||
|
||||
enum ParsedGeometryType {
|
||||
PARSED_GEOMETRY_MESH_INSTANCES = 0,
|
||||
PARSED_GEOMETRY_STATIC_COLLIDERS,
|
||||
PARSED_GEOMETRY_BOTH,
|
||||
PARSED_GEOMETRY_MAX
|
||||
};
|
||||
|
||||
enum SourceGeometryMode {
|
||||
SOURCE_GEOMETRY_ROOT_NODE_CHILDREN = 0,
|
||||
SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN,
|
||||
SOURCE_GEOMETRY_GROUPS_EXPLICIT,
|
||||
SOURCE_GEOMETRY_MAX
|
||||
};
|
||||
|
||||
public:
|
||||
// Recast settings
|
||||
void set_sample_partition_type(SamplePartitionType p_value);
|
||||
SamplePartitionType get_sample_partition_type() const;
|
||||
|
||||
void set_parsed_geometry_type(ParsedGeometryType p_value);
|
||||
ParsedGeometryType get_parsed_geometry_type() const;
|
||||
|
||||
void set_collision_mask(uint32_t p_mask);
|
||||
uint32_t get_collision_mask() const;
|
||||
|
||||
void set_collision_mask_bit(int p_bit, bool p_value);
|
||||
bool get_collision_mask_bit(int p_bit) const;
|
||||
|
||||
void set_source_geometry_mode(SourceGeometryMode p_geometry_mode);
|
||||
SourceGeometryMode get_source_geometry_mode() const;
|
||||
|
||||
void set_source_group_name(StringName p_group_name);
|
||||
StringName get_source_group_name() const;
|
||||
|
||||
void set_cell_size(float p_value);
|
||||
float get_cell_size() const;
|
||||
|
||||
void set_cell_height(float p_value);
|
||||
float get_cell_height() const;
|
||||
|
||||
void set_agent_height(float p_value);
|
||||
float get_agent_height() const;
|
||||
|
||||
void set_agent_radius(float p_value);
|
||||
float get_agent_radius();
|
||||
|
||||
void set_agent_max_climb(float p_value);
|
||||
float get_agent_max_climb() const;
|
||||
|
||||
void set_agent_max_slope(float p_value);
|
||||
float get_agent_max_slope() const;
|
||||
|
||||
void set_region_min_size(float p_value);
|
||||
float get_region_min_size() const;
|
||||
|
||||
void set_region_merge_size(float p_value);
|
||||
float get_region_merge_size() const;
|
||||
|
||||
void set_edge_max_length(float p_value);
|
||||
float get_edge_max_length() const;
|
||||
|
||||
void set_edge_max_error(float p_value);
|
||||
float get_edge_max_error() const;
|
||||
|
||||
void set_vertices_per_polygon(float p_value);
|
||||
float get_vertices_per_polygon() const;
|
||||
|
||||
void set_detail_sample_distance(float p_value);
|
||||
float get_detail_sample_distance() const;
|
||||
|
||||
void set_detail_sample_max_error(float p_value);
|
||||
float get_detail_sample_max_error() const;
|
||||
|
||||
void set_filter_low_hanging_obstacles(bool p_value);
|
||||
bool get_filter_low_hanging_obstacles() const;
|
||||
|
||||
void set_filter_ledge_spans(bool p_value);
|
||||
bool get_filter_ledge_spans() const;
|
||||
|
||||
void set_filter_walkable_low_height_spans(bool p_value);
|
||||
bool get_filter_walkable_low_height_spans() const;
|
||||
|
||||
void set_filter_baking_aabb(const AABB &p_aabb);
|
||||
AABB get_filter_baking_aabb() const;
|
||||
|
||||
void set_filter_baking_aabb_offset(const Vector3 &p_aabb_offset);
|
||||
Vector3 get_filter_baking_aabb_offset() const;
|
||||
|
||||
void create_from_mesh(const Ref<Mesh> &p_mesh);
|
||||
|
||||
void set_vertices(const PoolVector<Vector3> &p_vertices);
|
||||
PoolVector<Vector3> get_vertices() const;
|
||||
|
||||
void add_polygon(const Vector<int> &p_polygon);
|
||||
int get_polygon_count() const;
|
||||
Vector<int> get_polygon(int p_idx);
|
||||
void clear_polygons();
|
||||
|
||||
void clear();
|
||||
void commit_changes();
|
||||
|
||||
void set_polygons(const Vector<Vector<int>> &p_polygons);
|
||||
const Vector<Vector<int>> &get_polygons() const;
|
||||
|
||||
void _set_polygons(const Array &p_array);
|
||||
Array _get_polygons() const;
|
||||
|
||||
RID get_rid() const;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
Ref<ArrayMesh> get_debug_mesh();
|
||||
#endif
|
||||
|
||||
NavigationMesh();
|
||||
~NavigationMesh();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
virtual void _validate_property(PropertyInfo &property) const;
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
||||
float cell_size;
|
||||
float cell_height;
|
||||
float agent_height;
|
||||
float agent_radius;
|
||||
float agent_max_climb;
|
||||
float agent_max_slope;
|
||||
float region_min_size;
|
||||
float region_merge_size;
|
||||
float edge_max_length;
|
||||
float edge_max_error;
|
||||
float vertices_per_polygon;
|
||||
float detail_sample_distance;
|
||||
float detail_sample_max_error;
|
||||
|
||||
SamplePartitionType partition_type;
|
||||
ParsedGeometryType parsed_geometry_type;
|
||||
uint32_t collision_mask;
|
||||
|
||||
SourceGeometryMode source_geometry_mode;
|
||||
StringName source_group_name;
|
||||
|
||||
bool filter_low_hanging_obstacles;
|
||||
bool filter_ledge_spans;
|
||||
bool filter_walkable_low_height_spans;
|
||||
AABB filter_baking_aabb;
|
||||
Vector3 filter_baking_aabb_offset;
|
||||
|
||||
private:
|
||||
RID navigation_mesh_rid;
|
||||
|
||||
PoolVector<Vector3> vertices;
|
||||
|
||||
Vector<Vector<int>> polygons;
|
||||
|
||||
Ref<ArrayMesh> debug_mesh;
|
||||
|
||||
bool navigation_mesh_dirty;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(NavigationMesh::SamplePartitionType);
|
||||
VARIANT_ENUM_CAST(NavigationMesh::ParsedGeometryType);
|
||||
VARIANT_ENUM_CAST(NavigationMesh::SourceGeometryMode);
|
||||
|
||||
#endif // NAVIGATION_MESH_H
|
@ -1,138 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* navigation_mesh_source_geometry_data_2d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "navigation_mesh_source_geometry_data_2d.h"
|
||||
|
||||
#include "scene/resources/mesh/mesh.h"
|
||||
|
||||
void NavigationMeshSourceGeometryData2D::clear() {
|
||||
traversable_outlines.clear();
|
||||
obstruction_outlines.clear();
|
||||
}
|
||||
|
||||
void NavigationMeshSourceGeometryData2D::_set_traversable_outlines(const Vector<Vector<Vector2>> &p_traversable_outlines) {
|
||||
traversable_outlines = p_traversable_outlines;
|
||||
}
|
||||
|
||||
void NavigationMeshSourceGeometryData2D::_set_obstruction_outlines(const Vector<Vector<Vector2>> &p_obstruction_outlines) {
|
||||
obstruction_outlines = p_obstruction_outlines;
|
||||
}
|
||||
|
||||
void NavigationMeshSourceGeometryData2D::_add_traversable_outline(const Vector<Vector2> &p_shape_outline) {
|
||||
if (p_shape_outline.size() > 1) {
|
||||
traversable_outlines.push_back(p_shape_outline);
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationMeshSourceGeometryData2D::_add_obstruction_outline(const Vector<Vector2> &p_shape_outline) {
|
||||
if (p_shape_outline.size() > 1) {
|
||||
obstruction_outlines.push_back(p_shape_outline);
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationMeshSourceGeometryData2D::set_traversable_outlines(const Array &p_traversable_outlines) {
|
||||
traversable_outlines.resize(p_traversable_outlines.size());
|
||||
for (int i = 0; i < p_traversable_outlines.size(); i++) {
|
||||
traversable_outlines.write[i] = p_traversable_outlines[i];
|
||||
}
|
||||
}
|
||||
|
||||
Array NavigationMeshSourceGeometryData2D::get_traversable_outlines() const {
|
||||
Array array_traversable_outlines;
|
||||
array_traversable_outlines.resize(traversable_outlines.size());
|
||||
for (int i = 0; i < array_traversable_outlines.size(); i++) {
|
||||
array_traversable_outlines[i] = traversable_outlines[i];
|
||||
}
|
||||
|
||||
return array_traversable_outlines;
|
||||
}
|
||||
|
||||
void NavigationMeshSourceGeometryData2D::set_obstruction_outlines(const Array &p_obstruction_outlines) {
|
||||
obstruction_outlines.resize(p_obstruction_outlines.size());
|
||||
for (int i = 0; i < p_obstruction_outlines.size(); i++) {
|
||||
obstruction_outlines.write[i] = p_obstruction_outlines[i];
|
||||
}
|
||||
}
|
||||
|
||||
Array NavigationMeshSourceGeometryData2D::get_obstruction_outlines() const {
|
||||
Array array_obstruction_outlines;
|
||||
array_obstruction_outlines.resize(obstruction_outlines.size());
|
||||
for (int i = 0; i < array_obstruction_outlines.size(); i++) {
|
||||
array_obstruction_outlines[i] = obstruction_outlines[i];
|
||||
}
|
||||
|
||||
return array_obstruction_outlines;
|
||||
}
|
||||
|
||||
void NavigationMeshSourceGeometryData2D::add_traversable_outline(const PoolVector2Array &p_shape_outline) {
|
||||
if (p_shape_outline.size() > 1) {
|
||||
Vector<Vector2> traversable_outline;
|
||||
traversable_outline.resize(p_shape_outline.size());
|
||||
for (int i = 0; i < p_shape_outline.size(); i++) {
|
||||
traversable_outline.write[i] = p_shape_outline[i];
|
||||
}
|
||||
traversable_outlines.push_back(traversable_outline);
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationMeshSourceGeometryData2D::add_obstruction_outline(const PoolVector2Array &p_shape_outline) {
|
||||
if (p_shape_outline.size() > 1) {
|
||||
Vector<Vector2> obstruction_outline;
|
||||
obstruction_outline.resize(p_shape_outline.size());
|
||||
for (int i = 0; i < p_shape_outline.size(); i++) {
|
||||
obstruction_outline.write[i] = p_shape_outline[i];
|
||||
}
|
||||
obstruction_outlines.push_back(obstruction_outline);
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationMeshSourceGeometryData2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("clear"), &NavigationMeshSourceGeometryData2D::clear);
|
||||
ClassDB::bind_method(D_METHOD("has_data"), &NavigationMeshSourceGeometryData2D::has_data);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_traversable_outlines", "traversable_outlines"), &NavigationMeshSourceGeometryData2D::set_traversable_outlines);
|
||||
ClassDB::bind_method(D_METHOD("get_traversable_outlines"), &NavigationMeshSourceGeometryData2D::get_traversable_outlines);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_obstruction_outlines", "obstruction_outlines"), &NavigationMeshSourceGeometryData2D::set_obstruction_outlines);
|
||||
ClassDB::bind_method(D_METHOD("get_obstruction_outlines"), &NavigationMeshSourceGeometryData2D::get_obstruction_outlines);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_traversable_outline", "shape_outline"), &NavigationMeshSourceGeometryData2D::add_traversable_outline);
|
||||
ClassDB::bind_method(D_METHOD("add_obstruction_outline", "shape_outline"), &NavigationMeshSourceGeometryData2D::add_obstruction_outline);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "traversable_outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_traversable_outlines", "get_traversable_outlines");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "obstruction_outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_obstruction_outlines", "get_obstruction_outlines");
|
||||
}
|
||||
|
||||
NavigationMeshSourceGeometryData2D::NavigationMeshSourceGeometryData2D() {
|
||||
}
|
||||
|
||||
NavigationMeshSourceGeometryData2D::~NavigationMeshSourceGeometryData2D() {
|
||||
clear();
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
#ifndef NAVIGATION_MESH_SOURCE_GEOMETRY_DATA_2D_H
|
||||
#define NAVIGATION_MESH_SOURCE_GEOMETRY_DATA_2D_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* navigation_mesh_source_geometry_data_2d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "scene/main/node_2d.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
|
||||
class NavigationMeshSourceGeometryData2D : public Resource {
|
||||
GDCLASS(NavigationMeshSourceGeometryData2D, Resource);
|
||||
|
||||
Vector<Vector<Vector2>> traversable_outlines;
|
||||
Vector<Vector<Vector2>> obstruction_outlines;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void _set_traversable_outlines(const Vector<Vector<Vector2>> &p_traversable_outlines);
|
||||
const Vector<Vector<Vector2>> &_get_traversable_outlines() const { return traversable_outlines; }
|
||||
|
||||
void _set_obstruction_outlines(const Vector<Vector<Vector2>> &p_obstruction_outlines);
|
||||
const Vector<Vector<Vector2>> &_get_obstruction_outlines() const { return obstruction_outlines; }
|
||||
|
||||
void _add_traversable_outline(const Vector<Vector2> &p_shape_outline);
|
||||
void _add_obstruction_outline(const Vector<Vector2> &p_shape_outline);
|
||||
|
||||
// kept root node transform here on the geometry data
|
||||
// if we add this transform to all exposed functions we need to break comp on all functions later
|
||||
// when navigation_mesh changes from global transfrom to relative to navregion
|
||||
// but if it stays here we can just remove it and change the internal functions only
|
||||
Transform2D root_node_transform;
|
||||
|
||||
void set_traversable_outlines(const Array &p_traversable_outlines);
|
||||
Array get_traversable_outlines() const;
|
||||
|
||||
void set_obstruction_outlines(const Array &p_obstruction_outlines);
|
||||
Array get_obstruction_outlines() const;
|
||||
|
||||
void add_traversable_outline(const PoolVector2Array &p_shape_outline);
|
||||
void add_obstruction_outline(const PoolVector2Array &p_shape_outline);
|
||||
|
||||
bool has_data() { return traversable_outlines.size(); };
|
||||
void clear();
|
||||
|
||||
NavigationMeshSourceGeometryData2D();
|
||||
~NavigationMeshSourceGeometryData2D();
|
||||
};
|
||||
|
||||
#endif // NAVIGATION_MESH_SOURCE_GEOMETRY_DATA_2D_H
|
@ -1,672 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* navigation_polygon.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "navigation_polygon.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "core/core_string_names.h"
|
||||
#include "core/os/mutex.h"
|
||||
#include "scene/2d/navigation_2d.h"
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
#include "scene/resources/world_2d.h"
|
||||
#include "servers/navigation/navigation_mesh_generator.h"
|
||||
#include "servers/navigation_2d_server.h"
|
||||
|
||||
#include "navigation_mesh_source_geometry_data_2d.h"
|
||||
|
||||
//#include "thirdparty/misc/triangulator.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Rect2 NavigationPolygon::_edit_get_rect() const {
|
||||
if (rect_cache_dirty) {
|
||||
item_rect = Rect2();
|
||||
bool first = true;
|
||||
|
||||
for (int i = 0; i < outlines.size(); i++) {
|
||||
const PoolVector<Vector2> &outline = outlines[i];
|
||||
const int outline_size = outline.size();
|
||||
if (outline_size < 3) {
|
||||
continue;
|
||||
}
|
||||
PoolVector<Vector2>::Read p = outline.read();
|
||||
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++) {
|
||||
const PoolVector<Vector2> &outline = outlines[i];
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
void NavigationPolygon::set_parsed_geometry_type(ParsedGeometryType p_value) {
|
||||
ERR_FAIL_INDEX(p_value, PARSED_GEOMETRY_MAX);
|
||||
parsed_geometry_type = p_value;
|
||||
property_list_changed_notify();
|
||||
}
|
||||
|
||||
NavigationPolygon::ParsedGeometryType NavigationPolygon::get_parsed_geometry_type() const {
|
||||
return parsed_geometry_type;
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_collision_mask(uint32_t p_mask) {
|
||||
collision_mask = p_mask;
|
||||
}
|
||||
|
||||
uint32_t NavigationPolygon::get_collision_mask() const {
|
||||
return collision_mask;
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_collision_mask_value(int p_layer_number, bool p_value) {
|
||||
ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive.");
|
||||
uint32_t mask = get_collision_mask();
|
||||
if (p_value) {
|
||||
mask |= 1 << (p_layer_number - 1);
|
||||
} else {
|
||||
mask &= ~(1 << (p_layer_number - 1));
|
||||
}
|
||||
set_collision_mask(mask);
|
||||
}
|
||||
|
||||
bool NavigationPolygon::get_collision_mask_value(int p_layer_number) const {
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive.");
|
||||
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive.");
|
||||
return get_collision_mask() & (1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_source_geometry_mode(SourceGeometryMode p_geometry_mode) {
|
||||
ERR_FAIL_INDEX(p_geometry_mode, SOURCE_GEOMETRY_MAX);
|
||||
source_geometry_mode = p_geometry_mode;
|
||||
property_list_changed_notify();
|
||||
}
|
||||
|
||||
NavigationPolygon::SourceGeometryMode NavigationPolygon::get_source_geometry_mode() const {
|
||||
return source_geometry_mode;
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_polygon_bake_fillrule(PolygonFillRule p_polygon_fillrule) {
|
||||
ERR_FAIL_INDEX(p_polygon_fillrule, POLYGON_FILLRULE_MAX);
|
||||
polygon_bake_fillrule = p_polygon_fillrule;
|
||||
property_list_changed_notify();
|
||||
}
|
||||
|
||||
NavigationPolygon::PolygonFillRule NavigationPolygon::get_polygon_bake_fillrule() const {
|
||||
return polygon_bake_fillrule;
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_offsetting_jointype(OffsettingJoinType p_offsetting_jointype) {
|
||||
ERR_FAIL_INDEX(p_offsetting_jointype, OFFSETTING_JOINTYPE_MAX);
|
||||
offsetting_jointype = p_offsetting_jointype;
|
||||
property_list_changed_notify();
|
||||
}
|
||||
|
||||
NavigationPolygon::OffsettingJoinType NavigationPolygon::get_offsetting_jointype() const {
|
||||
return offsetting_jointype;
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_source_group_name(StringName p_group_name) {
|
||||
source_group_name = p_group_name;
|
||||
}
|
||||
|
||||
StringName NavigationPolygon::get_source_group_name() const {
|
||||
return source_group_name;
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_agent_radius(real_t p_value) {
|
||||
ERR_FAIL_COND(p_value < 0);
|
||||
agent_radius = p_value;
|
||||
}
|
||||
|
||||
real_t NavigationPolygon::get_agent_radius() const {
|
||||
return agent_radius;
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_vertices(const PoolVector<Vector2> &p_vertices) {
|
||||
vertices = p_vertices;
|
||||
rect_cache_dirty = true;
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
|
||||
PoolVector<Vector2> NavigationPolygon::get_vertices() const {
|
||||
return vertices;
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_cell_size(real_t p_cell_size) {
|
||||
cell_size = p_cell_size;
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
|
||||
real_t NavigationPolygon::get_cell_size() const {
|
||||
return cell_size;
|
||||
}
|
||||
|
||||
void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) {
|
||||
polygons.push_back(p_polygon);
|
||||
}
|
||||
|
||||
Vector<int> NavigationPolygon::get_polygon(int p_idx) {
|
||||
ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>());
|
||||
return polygons[p_idx];
|
||||
}
|
||||
|
||||
int NavigationPolygon::get_polygon_count() const {
|
||||
return polygons.size();
|
||||
}
|
||||
|
||||
void NavigationPolygon::clear_polygons() {
|
||||
polygons.clear();
|
||||
}
|
||||
void NavigationPolygon::clear_outlines() {
|
||||
outlines.clear();
|
||||
baked_outlines.clear();
|
||||
rect_cache_dirty = true;
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
void NavigationPolygon::clear_baked_outlines() {
|
||||
baked_outlines.clear();
|
||||
rect_cache_dirty = true;
|
||||
}
|
||||
|
||||
void NavigationPolygon::clear() {
|
||||
clear_outlines();
|
||||
clear_polygons();
|
||||
clear_baked_outlines();
|
||||
vertices.clear();
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
void NavigationPolygon::commit_changes() {
|
||||
if (navigation_polygon_dirty) {
|
||||
navigation_polygon_dirty = false;
|
||||
|
||||
PoolVector<Vector3> new_navigation_mesh_vertices;
|
||||
Vector<Vector<int>> new_navigation_mesh_polygons;
|
||||
|
||||
new_navigation_mesh_vertices.resize(vertices.size());
|
||||
|
||||
PoolVector3Array::Write new_navigation_mesh_vertices_write = new_navigation_mesh_vertices.write();
|
||||
Vector3 *new_navigation_mesh_vertices_ptrw = new_navigation_mesh_vertices_write.ptr();
|
||||
|
||||
PoolVector2Array::Read vertices_read = vertices.read();
|
||||
const Vector2 *vertices_ptr = vertices_read.ptr();
|
||||
|
||||
for (int i = 0; i < vertices.size(); i++) {
|
||||
new_navigation_mesh_vertices_ptrw[i] = Vector3(vertices_ptr[i].x, 0.0, vertices_ptr[i].y);
|
||||
}
|
||||
|
||||
for (int i = 0; i < get_polygon_count(); i++) {
|
||||
Vector<int> new_navigation_mesh_polygon = get_polygon(i);
|
||||
new_navigation_mesh_polygons.push_back(new_navigation_mesh_polygon);
|
||||
}
|
||||
|
||||
navigation_mesh->set_cell_size(cell_size); // Needed to not fail the cell size check on the server
|
||||
navigation_mesh->set_vertices(new_navigation_mesh_vertices);
|
||||
navigation_mesh->set_polygons(new_navigation_mesh_polygons);
|
||||
navigation_mesh->commit_changes();
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
}
|
||||
|
||||
Ref<NavigationMesh> NavigationPolygon::get_navigation_mesh() {
|
||||
if (navigation_polygon_dirty) {
|
||||
commit_changes();
|
||||
}
|
||||
return navigation_mesh;
|
||||
}
|
||||
|
||||
void NavigationPolygon::add_outline(const PoolVector<Vector2> &p_outline) {
|
||||
outlines.push_back(p_outline);
|
||||
set_baked_outlines(outlines);
|
||||
rect_cache_dirty = true;
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
|
||||
void NavigationPolygon::add_outline_at_index(const PoolVector<Vector2> &p_outline, int p_index) {
|
||||
outlines.insert(p_index, p_outline);
|
||||
set_baked_outlines(outlines);
|
||||
rect_cache_dirty = true;
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
|
||||
int NavigationPolygon::get_outline_count() const {
|
||||
return outlines.size();
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_outline(int p_idx, const PoolVector<Vector2> &p_outline) {
|
||||
ERR_FAIL_INDEX(p_idx, outlines.size());
|
||||
outlines.write[p_idx] = p_outline;
|
||||
set_baked_outlines(outlines);
|
||||
rect_cache_dirty = true;
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
|
||||
void NavigationPolygon::remove_outline(int p_idx) {
|
||||
ERR_FAIL_INDEX(p_idx, outlines.size());
|
||||
outlines.remove(p_idx);
|
||||
set_baked_outlines(outlines);
|
||||
rect_cache_dirty = true;
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
|
||||
PoolVector<Vector2> NavigationPolygon::get_outline(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx, outlines.size(), PoolVector<Vector2>());
|
||||
return outlines[p_idx];
|
||||
}
|
||||
|
||||
/*
|
||||
//Old clipper version
|
||||
void NavigationPolygon::make_polygons_from_outlines() {
|
||||
//navigation_mesh.unref();
|
||||
|
||||
List<TriangulatorPoly> in_poly, out_poly;
|
||||
|
||||
Vector2 outside_point(-1e10, -1e10);
|
||||
|
||||
for (int i = 0; i < outlines.size(); i++) {
|
||||
PoolVector<Vector2> ol = outlines[i];
|
||||
int olsize = ol.size();
|
||||
if (olsize < 3) {
|
||||
continue;
|
||||
}
|
||||
PoolVector<Vector2>::Read r = ol.read();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
outside_point += Vector2(0.7239784, 0.819238); //avoid precision issues
|
||||
|
||||
for (int i = 0; i < outlines.size(); i++) {
|
||||
PoolVector<Vector2> ol = outlines[i];
|
||||
int olsize = ol.size();
|
||||
if (olsize < 3) {
|
||||
continue;
|
||||
}
|
||||
PoolVector<Vector2>::Read r = ol.read();
|
||||
|
||||
int interscount = 0;
|
||||
//test if this is an outer outline
|
||||
for (int k = 0; k < outlines.size(); k++) {
|
||||
if (i == k) {
|
||||
continue; //no self intersect
|
||||
}
|
||||
|
||||
PoolVector<Vector2> ol2 = outlines[k];
|
||||
int olsize2 = ol2.size();
|
||||
if (olsize2 < 3) {
|
||||
continue;
|
||||
}
|
||||
PoolVector<Vector2>::Read r2 = ol2.read();
|
||||
|
||||
for (int l = 0; l < olsize2; l++) {
|
||||
if (Geometry::segment_intersects_segment_2d(r[0], outside_point, r2[l], r2[(l + 1) % olsize2], nullptr)) {
|
||||
interscount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool outer = (interscount % 2) == 0;
|
||||
|
||||
TriangulatorPoly tp;
|
||||
tp.Init(olsize);
|
||||
for (int j = 0; j < olsize; j++) {
|
||||
tp[j] = r[j];
|
||||
}
|
||||
|
||||
if (outer) {
|
||||
tp.SetOrientation(TRIANGULATOR_CCW);
|
||||
} else {
|
||||
tp.SetOrientation(TRIANGULATOR_CW);
|
||||
tp.SetHole(true);
|
||||
}
|
||||
|
||||
in_poly.push_back(tp);
|
||||
}
|
||||
|
||||
TriangulatorPartition tpart;
|
||||
if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed!
|
||||
ERR_PRINT("NavigationPolygon: Convex partition failed! Failed to convert outlines to a valid NavigationMesh."
|
||||
"\nNavigationPolygon outlines can not overlap vertices or edges inside same outline or with other outlines or have any intersections."
|
||||
"\nAdd the outmost and largest outline first. To add holes inside this outline add the smaller outlines with same winding order.");
|
||||
return;
|
||||
}
|
||||
|
||||
polygons.clear();
|
||||
vertices.resize(0);
|
||||
|
||||
RBMap<Vector2, int> points;
|
||||
for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
|
||||
TriangulatorPoly &tp = I->get();
|
||||
|
||||
Vector<int> p;
|
||||
|
||||
for (int64_t i = 0; i < tp.GetNumPoints(); i++) {
|
||||
RBMap<Vector2, int>::Element *E = points.find(tp[i]);
|
||||
if (!E) {
|
||||
E = points.insert(tp[i], vertices.size());
|
||||
vertices.push_back(tp[i]);
|
||||
}
|
||||
p.push_back(E->get());
|
||||
}
|
||||
|
||||
polygons.push_back(p);
|
||||
}
|
||||
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
}
|
||||
*/
|
||||
|
||||
void NavigationPolygon::make_polygons_from_outlines() {
|
||||
if (outlines.size() == 0) {
|
||||
set_vertices(PoolVector<Vector2>());
|
||||
set_polygons(Vector<Vector<int>>());
|
||||
commit_changes();
|
||||
return;
|
||||
}
|
||||
|
||||
NavigationMeshGenerator::get_singleton()->bake_2d_from_source_geometry_data(this, Ref<NavigationMeshSourceGeometryData2D>());
|
||||
commit_changes();
|
||||
}
|
||||
|
||||
RID NavigationPolygon::get_rid() const {
|
||||
if (navigation_mesh.is_valid()) {
|
||||
navigation_mesh->get_rid();
|
||||
}
|
||||
return RID();
|
||||
}
|
||||
|
||||
NavigationPolygon::NavigationPolygon() {
|
||||
agent_radius = 10.0f;
|
||||
cell_size = 1.0f; // Must match ProjectSettings default 2D cell_size.
|
||||
|
||||
parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES;
|
||||
collision_mask = 0xFFFFFFFF;
|
||||
|
||||
source_geometry_mode = SOURCE_GEOMETRY_ROOT_NODE_CHILDREN;
|
||||
source_group_name = "navigation_polygon_source_group";
|
||||
|
||||
polygon_bake_fillrule = POLYGON_FILLRULE_EVENODD;
|
||||
offsetting_jointype = OFFSETTING_JOINTYPE_MITER;
|
||||
|
||||
navigation_polygon_dirty = true;
|
||||
|
||||
rect_cache_dirty = true;
|
||||
|
||||
navigation_mesh.instance();
|
||||
}
|
||||
|
||||
NavigationPolygon::~NavigationPolygon() {
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_polygons(const Vector<Vector<int>> &p_array) {
|
||||
polygons.resize(p_array.size());
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
polygons.write[i] = p_array[i];
|
||||
}
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
|
||||
Vector<Vector<int>> NavigationPolygon::get_polygons() const {
|
||||
Vector<Vector<int>> ret;
|
||||
ret.resize(polygons.size());
|
||||
for (int i = 0; i < ret.size(); i++) {
|
||||
ret.write[i] = polygons[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_outlines(const Vector<PoolVector<Vector2>> &p_array) {
|
||||
outlines.resize(p_array.size());
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
outlines.write[i] = p_array[i];
|
||||
}
|
||||
rect_cache_dirty = true;
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
|
||||
Vector<PoolVector<Vector2>> NavigationPolygon::get_outlines() const {
|
||||
Vector<PoolVector<Vector2>> ret;
|
||||
ret.resize(outlines.size());
|
||||
for (int i = 0; i < ret.size(); i++) {
|
||||
ret.write[i] = outlines[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NavigationPolygon::set_baked_outlines(const Vector<PoolVector<Vector2>> &p_array) {
|
||||
baked_outlines.resize(p_array.size());
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
baked_outlines.write[i] = p_array[i];
|
||||
}
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
|
||||
Vector<PoolVector<Vector2>> NavigationPolygon::get_baked_outlines() const {
|
||||
Vector<PoolVector<Vector2>> _typed_baked_outlines;
|
||||
_typed_baked_outlines.resize(baked_outlines.size());
|
||||
for (int i = 0; i < _typed_baked_outlines.size(); i++) {
|
||||
_typed_baked_outlines.write[i] = baked_outlines[i];
|
||||
}
|
||||
|
||||
return _typed_baked_outlines;
|
||||
}
|
||||
|
||||
void NavigationPolygon::_set_polygons(const Array &p_array) {
|
||||
polygons.resize(p_array.size());
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
polygons.write[i] = p_array[i];
|
||||
}
|
||||
}
|
||||
|
||||
Array NavigationPolygon::_get_polygons() const {
|
||||
Array ret;
|
||||
ret.resize(polygons.size());
|
||||
for (int i = 0; i < ret.size(); i++) {
|
||||
ret[i] = polygons[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NavigationPolygon::_set_outlines(const Array &p_array) {
|
||||
outlines.resize(p_array.size());
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
outlines.write[i] = p_array[i];
|
||||
}
|
||||
rect_cache_dirty = true;
|
||||
}
|
||||
|
||||
Array NavigationPolygon::_get_outlines() const {
|
||||
Array ret;
|
||||
ret.resize(outlines.size());
|
||||
for (int i = 0; i < ret.size(); i++) {
|
||||
ret[i] = outlines[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NavigationPolygon::_set_baked_outlines(const Array &p_array) {
|
||||
baked_outlines.resize(p_array.size());
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
baked_outlines.write[i] = p_array[i];
|
||||
}
|
||||
navigation_polygon_dirty = true;
|
||||
}
|
||||
|
||||
Array NavigationPolygon::_get_baked_outlines() const {
|
||||
Array ret;
|
||||
ret.resize(baked_outlines.size());
|
||||
for (int i = 0; i < ret.size(); i++) {
|
||||
ret[i] = baked_outlines[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NavigationPolygon::_validate_property(PropertyInfo &p_property) const {
|
||||
if (p_property.name == "geometry_collision_mask") {
|
||||
if (parsed_geometry_type == PARSED_GEOMETRY_MESH_INSTANCES) {
|
||||
p_property.usage = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_property.name == "geometry_source_group_name") {
|
||||
if (source_geometry_mode == SOURCE_GEOMETRY_ROOT_NODE_CHILDREN) {
|
||||
p_property.usage = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationPolygon::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_parsed_geometry_type", "geometry_type"), &NavigationPolygon::set_parsed_geometry_type);
|
||||
ClassDB::bind_method(D_METHOD("get_parsed_geometry_type"), &NavigationPolygon::get_parsed_geometry_type);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &NavigationPolygon::set_collision_mask);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_mask"), &NavigationPolygon::get_collision_mask);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &NavigationPolygon::set_collision_mask_value);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &NavigationPolygon::get_collision_mask_value);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_source_geometry_mode", "mask"), &NavigationPolygon::set_source_geometry_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_source_geometry_mode"), &NavigationPolygon::get_source_geometry_mode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_source_group_name", "mask"), &NavigationPolygon::set_source_group_name);
|
||||
ClassDB::bind_method(D_METHOD("get_source_group_name"), &NavigationPolygon::get_source_group_name);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_polygon_bake_fillrule", "polygon_fillrule"), &NavigationPolygon::set_polygon_bake_fillrule);
|
||||
ClassDB::bind_method(D_METHOD("get_polygon_bake_fillrule"), &NavigationPolygon::get_polygon_bake_fillrule);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_offsetting_jointype", "offsetting_jointype"), &NavigationPolygon::set_offsetting_jointype);
|
||||
ClassDB::bind_method(D_METHOD("get_offsetting_jointype"), &NavigationPolygon::get_offsetting_jointype);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_agent_radius", "agent_radius"), &NavigationPolygon::set_agent_radius);
|
||||
ClassDB::bind_method(D_METHOD("get_agent_radius"), &NavigationPolygon::get_agent_radius);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &NavigationPolygon::set_cell_size);
|
||||
ClassDB::bind_method(D_METHOD("get_cell_size"), &NavigationPolygon::get_cell_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationPolygon::set_vertices);
|
||||
ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationPolygon::get_vertices);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("commit_changes"), &NavigationPolygon::commit_changes);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationPolygon::get_navigation_mesh);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_polygons", "polygons"), &NavigationPolygon::_set_polygons);
|
||||
ClassDB::bind_method(D_METHOD("get_polygons"), &NavigationPolygon::_get_polygons);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_outlines", "outlines"), &NavigationPolygon::_set_outlines);
|
||||
ClassDB::bind_method(D_METHOD("get_outlines"), &NavigationPolygon::_get_outlines);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_baked_outlines", "outlines"), &NavigationPolygon::_set_baked_outlines);
|
||||
ClassDB::bind_method(D_METHOD("get_baked_outlines"), &NavigationPolygon::_get_baked_outlines);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices");
|
||||
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");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "baked_outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_baked_outlines", "get_baked_outlines");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_RANGE, "0.01,500.0,0.01,or_greater,suffix:px"), "set_cell_size", "get_cell_size");
|
||||
|
||||
ADD_GROUP("Polygons", "polygon_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "polygon_bake_fillrule", PROPERTY_HINT_ENUM, "EvenOdd,NonZero,Positive,Negative"), "set_polygon_bake_fillrule", "get_polygon_bake_fillrule");
|
||||
ADD_GROUP("Geometry", "geometry_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry_parsed_geometry_type", PROPERTY_HINT_ENUM, "Mesh Instances,Static Colliders,Both"), "set_parsed_geometry_type", "get_parsed_geometry_type");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry_collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
|
||||
ADD_PROPERTY_DEFAULT("geometry_collision_mask", 0xFFFFFFFF);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry_source_geometry_mode", PROPERTY_HINT_ENUM, "Root Node Children,Group With Children,Group Explicit"), "set_source_geometry_mode", "get_source_geometry_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry_source_group_name"), "set_source_group_name", "get_source_group_name");
|
||||
ADD_PROPERTY_DEFAULT("geometry_source_group_name", StringName("navigation_polygon_source_group"));
|
||||
ADD_GROUP("Agents", "agent_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent_radius", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater,suffix:px"), "set_agent_radius", "get_agent_radius");
|
||||
ADD_GROUP("Offsetting", "offsetting_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "offsetting_jointype", PROPERTY_HINT_ENUM, "Square,Round,Miter"), "set_offsetting_jointype", "get_offsetting_jointype");
|
||||
|
||||
BIND_ENUM_CONSTANT(PARSED_GEOMETRY_MESH_INSTANCES);
|
||||
BIND_ENUM_CONSTANT(PARSED_GEOMETRY_STATIC_COLLIDERS);
|
||||
BIND_ENUM_CONSTANT(PARSED_GEOMETRY_BOTH);
|
||||
BIND_ENUM_CONSTANT(PARSED_GEOMETRY_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_ROOT_NODE_CHILDREN);
|
||||
BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN);
|
||||
BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_GROUPS_EXPLICIT);
|
||||
BIND_ENUM_CONSTANT(SOURCE_GEOMETRY_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(POLYGON_FILLRULE_EVENODD);
|
||||
BIND_ENUM_CONSTANT(POLYGON_FILLRULE_NONZERO);
|
||||
BIND_ENUM_CONSTANT(POLYGON_FILLRULE_POSITIVE);
|
||||
BIND_ENUM_CONSTANT(POLYGON_FILLRULE_NEGATIVE);
|
||||
BIND_ENUM_CONSTANT(POLYGON_FILLRULE_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(OFFSETTING_JOINTYPE_SQUARE);
|
||||
BIND_ENUM_CONSTANT(OFFSETTING_JOINTYPE_ROUND);
|
||||
BIND_ENUM_CONSTANT(OFFSETTING_JOINTYPE_MITER);
|
||||
BIND_ENUM_CONSTANT(OFFSETTING_JOINTYPE_MAX);
|
||||
}
|
@ -1,188 +0,0 @@
|
||||
#ifndef NAVIGATION_POLYGON_H
|
||||
#define NAVIGATION_POLYGON_H
|
||||
/*************************************************************************/
|
||||
/* navigation_polygon.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "core/object/resource.h"
|
||||
#include "scene/main/node_2d.h"
|
||||
|
||||
class NavigationMesh;
|
||||
|
||||
class NavigationPolygon : public Resource {
|
||||
GDCLASS(NavigationPolygon, Resource);
|
||||
|
||||
public:
|
||||
enum ParsedGeometryType {
|
||||
PARSED_GEOMETRY_MESH_INSTANCES = 0,
|
||||
PARSED_GEOMETRY_STATIC_COLLIDERS,
|
||||
PARSED_GEOMETRY_BOTH,
|
||||
PARSED_GEOMETRY_MAX
|
||||
};
|
||||
|
||||
enum SourceGeometryMode {
|
||||
SOURCE_GEOMETRY_ROOT_NODE_CHILDREN = 0,
|
||||
SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN,
|
||||
SOURCE_GEOMETRY_GROUPS_EXPLICIT,
|
||||
SOURCE_GEOMETRY_MAX
|
||||
};
|
||||
|
||||
enum PolygonFillRule {
|
||||
POLYGON_FILLRULE_EVENODD = 0,
|
||||
POLYGON_FILLRULE_NONZERO,
|
||||
POLYGON_FILLRULE_POSITIVE,
|
||||
POLYGON_FILLRULE_NEGATIVE,
|
||||
POLYGON_FILLRULE_MAX
|
||||
};
|
||||
|
||||
enum OffsettingJoinType {
|
||||
OFFSETTING_JOINTYPE_SQUARE = 0,
|
||||
OFFSETTING_JOINTYPE_ROUND,
|
||||
OFFSETTING_JOINTYPE_MITER,
|
||||
OFFSETTING_JOINTYPE_MAX
|
||||
};
|
||||
|
||||
public:
|
||||
#ifdef TOOLS_ENABLED
|
||||
Rect2 _edit_get_rect() const;
|
||||
bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
|
||||
#endif
|
||||
|
||||
void set_parsed_geometry_type(ParsedGeometryType p_value);
|
||||
ParsedGeometryType get_parsed_geometry_type() const;
|
||||
|
||||
void set_collision_mask(uint32_t p_mask);
|
||||
uint32_t get_collision_mask() const;
|
||||
|
||||
void set_collision_mask_value(int p_layer_number, bool p_value);
|
||||
bool get_collision_mask_value(int p_layer_number) const;
|
||||
|
||||
void set_source_geometry_mode(SourceGeometryMode p_geometry_mode);
|
||||
SourceGeometryMode get_source_geometry_mode() const;
|
||||
|
||||
void set_source_group_name(StringName p_group_name);
|
||||
StringName get_source_group_name() const;
|
||||
|
||||
void set_polygon_bake_fillrule(PolygonFillRule p_polygon_fillrule);
|
||||
PolygonFillRule get_polygon_bake_fillrule() const;
|
||||
|
||||
void set_offsetting_jointype(OffsettingJoinType p_offsetting_jointype);
|
||||
OffsettingJoinType get_offsetting_jointype() const;
|
||||
|
||||
void set_agent_radius(real_t p_value);
|
||||
real_t get_agent_radius() const;
|
||||
|
||||
void set_cell_size(real_t p_cell_size);
|
||||
real_t get_cell_size() const;
|
||||
|
||||
void set_vertices(const PoolVector<Vector2> &p_vertices);
|
||||
PoolVector<Vector2> get_vertices() const;
|
||||
|
||||
void add_polygon(const Vector<int> &p_polygon);
|
||||
Vector<int> get_polygon(int p_idx);
|
||||
int get_polygon_count() const;
|
||||
|
||||
void clear_polygons();
|
||||
void clear_outlines();
|
||||
void clear_baked_outlines();
|
||||
void clear();
|
||||
void commit_changes();
|
||||
|
||||
void add_outline(const PoolVector<Vector2> &p_outline);
|
||||
void add_outline_at_index(const PoolVector<Vector2> &p_outline, int p_index);
|
||||
void set_outline(int p_idx, const PoolVector<Vector2> &p_outline);
|
||||
PoolVector<Vector2> get_outline(int p_idx) const;
|
||||
void remove_outline(int p_idx);
|
||||
int get_outline_count() const;
|
||||
|
||||
void make_polygons_from_outlines();
|
||||
|
||||
RID get_rid() const;
|
||||
|
||||
Ref<NavigationMesh> get_navigation_mesh();
|
||||
|
||||
void set_polygons(const Vector<Vector<int>> &p_array);
|
||||
Vector<Vector<int>> get_polygons() const;
|
||||
|
||||
void set_outlines(const Vector<PoolVector<Vector2>> &p_array);
|
||||
Vector<PoolVector<Vector2>> get_outlines() const;
|
||||
|
||||
void set_baked_outlines(const Vector<PoolVector<Vector2>> &p_array);
|
||||
Vector<PoolVector<Vector2>> get_baked_outlines() const;
|
||||
|
||||
void _set_polygons(const Array &p_array);
|
||||
Array _get_polygons() const;
|
||||
|
||||
void _set_outlines(const Array &p_array);
|
||||
Array _get_outlines() const;
|
||||
|
||||
void _set_baked_outlines(const Array &p_array);
|
||||
Array _get_baked_outlines() const;
|
||||
|
||||
NavigationPolygon();
|
||||
~NavigationPolygon();
|
||||
|
||||
protected:
|
||||
void _validate_property(PropertyInfo &p_property) const;
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
RID navigation_mesh_rid;
|
||||
|
||||
real_t agent_radius;
|
||||
|
||||
ParsedGeometryType parsed_geometry_type;
|
||||
uint32_t collision_mask;
|
||||
|
||||
SourceGeometryMode source_geometry_mode;
|
||||
StringName source_group_name;
|
||||
|
||||
PolygonFillRule polygon_bake_fillrule;
|
||||
OffsettingJoinType offsetting_jointype;
|
||||
|
||||
bool navigation_polygon_dirty;
|
||||
|
||||
real_t cell_size;
|
||||
PoolVector<Vector2> vertices;
|
||||
Vector<Vector<int>> polygons;
|
||||
Vector<PoolVector<Vector2>> outlines;
|
||||
Vector<PoolVector<Vector2>> baked_outlines;
|
||||
|
||||
mutable Rect2 item_rect;
|
||||
mutable bool rect_cache_dirty;
|
||||
|
||||
Ref<NavigationMesh> navigation_mesh;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(NavigationPolygon::ParsedGeometryType);
|
||||
VARIANT_ENUM_CAST(NavigationPolygon::SourceGeometryMode);
|
||||
VARIANT_ENUM_CAST(NavigationPolygon::PolygonFillRule);
|
||||
VARIANT_ENUM_CAST(NavigationPolygon::OffsettingJoinType);
|
||||
|
||||
#endif // NAVIGATIONPOLYGON_H
|
@ -35,7 +35,6 @@
|
||||
#include "scene/2d/visibility_notifier_2d.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "scene/main/world.h"
|
||||
#include "servers/navigation_2d_server.h"
|
||||
#include "servers/physics_2d_server.h"
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
@ -328,10 +327,6 @@ RID World2D::get_space() {
|
||||
return space;
|
||||
}
|
||||
|
||||
RID World2D::get_navigation_map() const {
|
||||
return navigation_map;
|
||||
}
|
||||
|
||||
void World2D::get_world_list(List<World *> *r_worlds) {
|
||||
for (RBMap<World *, SpatialIndexer2D::WorldData>::Element *E = indexer->worlds.front(); E; E = E->next()) {
|
||||
r_worlds->push_back(E->key());
|
||||
@ -351,7 +346,6 @@ void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
|
||||
void World2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas);
|
||||
ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_map"), &World2D::get_navigation_map);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World2D::get_direct_space_state);
|
||||
|
||||
@ -378,20 +372,11 @@ World2D::World2D() {
|
||||
Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1.0));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::REAL, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
|
||||
|
||||
// Create default navigation map
|
||||
navigation_map = Navigation2DServer::get_singleton()->map_create();
|
||||
Navigation2DServer::get_singleton()->map_set_active(navigation_map, true);
|
||||
Navigation2DServer::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_size", 1.0));
|
||||
Navigation2DServer::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/2d/default_edge_connection_margin", 1.0));
|
||||
Navigation2DServer::get_singleton()->map_set_link_connection_radius(navigation_map, GLOBAL_DEF("navigation/2d/default_link_connection_radius", 4.0));
|
||||
Navigation2DServer::get_singleton()->map_set_use_edge_connections(navigation_map, GLOBAL_DEF("navigation/2d/use_edge_connections", true));
|
||||
|
||||
indexer = memnew(SpatialIndexer2D);
|
||||
}
|
||||
|
||||
World2D::~World2D() {
|
||||
RenderingServer::get_singleton()->free(canvas);
|
||||
Physics2DServer::get_singleton()->free(space);
|
||||
Navigation2DServer::get_singleton()->free(navigation_map);
|
||||
memdelete(indexer);
|
||||
}
|
||||
|
@ -67,7 +67,6 @@ protected:
|
||||
public:
|
||||
RID get_canvas();
|
||||
RID get_space();
|
||||
RID get_navigation_map() const;
|
||||
|
||||
Physics2DDirectSpaceState *get_direct_space_state();
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import("env")
|
||||
|
||||
env.add_source_files(env.servers_sources, "*.cpp")
|
@ -1,158 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* navigation_mesh_generator.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "navigation_mesh_generator.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
|
||||
#include "scene/2d/navigation_geometry_parser_2d.h"
|
||||
#include "scene/main/node.h"
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
|
||||
|
||||
NavigationMeshGenerator *NavigationMeshGenerator::singleton = nullptr;
|
||||
|
||||
void NavigationMeshGenerator::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("register_geometry_parser_2d", "geometry_parser"), &NavigationMeshGenerator::register_geometry_parser_2d);
|
||||
ClassDB::bind_method(D_METHOD("unregister_geometry_parser_2d", "geometry_parser"), &NavigationMeshGenerator::unregister_geometry_parser_2d);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("parse_2d_source_geometry_data", "navigation_polygon", "root_node", "callback"), &NavigationMeshGenerator::parse_2d_source_geometry_data, DEFVAL(Ref<FuncRef>()));
|
||||
ClassDB::bind_method(D_METHOD("bake_2d_from_source_geometry_data", "navigation_polygon", "source_geometry_data", "callback"), &NavigationMeshGenerator::bake_2d_from_source_geometry_data, DEFVAL(Ref<FuncRef>()));
|
||||
ClassDB::bind_method(D_METHOD("parse_and_bake_2d", "navigation_polygon", "root_node", "callback"), &NavigationMeshGenerator::parse_and_bake_2d, DEFVAL(Ref<FuncRef>()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_navigation_polygon_baking", "navigation_polygon"), &NavigationMeshGenerator::is_navigation_polygon_baking);
|
||||
}
|
||||
|
||||
NavigationMeshGenerator *NavigationMeshGenerator::get_singleton() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
void NavigationMeshGenerator::init() {
|
||||
}
|
||||
|
||||
void NavigationMeshGenerator::finish() {
|
||||
}
|
||||
|
||||
NavigationMeshGenerator::NavigationMeshGenerator() {
|
||||
ERR_FAIL_COND(singleton != nullptr);
|
||||
singleton = this;
|
||||
}
|
||||
|
||||
NavigationMeshGenerator::~NavigationMeshGenerator() {
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
/// NavigationMeshGeneratorManager ////////////////////////////////////////////////////
|
||||
|
||||
NavigationMeshGeneratorManager *NavigationMeshGeneratorManager::singleton = nullptr;
|
||||
const String NavigationMeshGeneratorManager::setting_property_name("navigation/baking/generator/navigation_mesh_generator");
|
||||
|
||||
void NavigationMeshGeneratorManager::on_servers_changed() {
|
||||
String nav_server_names("DEFAULT");
|
||||
|
||||
for (int i = 0; i < navigation_mesh_generators.size(); ++i) {
|
||||
const ClassInfo &server = navigation_mesh_generators[i];
|
||||
nav_server_names += "," + server.name;
|
||||
}
|
||||
|
||||
ProjectSettings::get_singleton()->set_custom_property_info(setting_property_name, PropertyInfo(Variant::STRING, setting_property_name, PROPERTY_HINT_ENUM, nav_server_names));
|
||||
}
|
||||
|
||||
void NavigationMeshGeneratorManager::_bind_methods() {
|
||||
//ClassDB::bind_method(D_METHOD("register_server", "name", "create_callback"), &NavigationMeshGeneratorManager::register_server);
|
||||
//ClassDB::bind_method(D_METHOD("set_default_server", "name", "priority"), &NavigationMeshGeneratorManager::set_default_server);
|
||||
}
|
||||
|
||||
NavigationMeshGeneratorManager *NavigationMeshGeneratorManager::get_singleton() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
void NavigationMeshGeneratorManager::register_server(const String &p_name, CreateNavigationMeshGeneratorCallback p_create_callback) {
|
||||
ERR_FAIL_COND(!p_create_callback);
|
||||
ERR_FAIL_COND_MSG(find_server_id(p_name) != -1, "NavigationMeshGenerator with the same name was already registered.");
|
||||
|
||||
navigation_mesh_generators.push_back(ClassInfo{ p_name, p_create_callback });
|
||||
on_servers_changed();
|
||||
}
|
||||
|
||||
void NavigationMeshGeneratorManager::set_default_server(const String &p_name, int p_priority) {
|
||||
const int id = find_server_id(p_name);
|
||||
ERR_FAIL_COND_MSG(id == -1, "NavigationMeshGenerator not found"); // Not found
|
||||
|
||||
// Only change the server if it is registered with a higher priority
|
||||
if (default_server_priority < p_priority) {
|
||||
default_server_id = id;
|
||||
default_server_priority = p_priority;
|
||||
}
|
||||
}
|
||||
|
||||
int NavigationMeshGeneratorManager::find_server_id(const String &p_name) const {
|
||||
for (int i = 0; i < navigation_mesh_generators.size(); ++i) {
|
||||
if (p_name == navigation_mesh_generators[i].name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
NavigationMeshGenerator *NavigationMeshGeneratorManager::new_default_server() const {
|
||||
ERR_FAIL_COND_V(default_server_id == -1, nullptr);
|
||||
|
||||
NavigationMeshGenerator *gen = navigation_mesh_generators[default_server_id].create_callback();
|
||||
|
||||
ERR_FAIL_COND_V(!gen, nullptr);
|
||||
|
||||
return gen;
|
||||
}
|
||||
|
||||
NavigationMeshGenerator *NavigationMeshGeneratorManager::new_server(const String &p_name) const {
|
||||
const int id = find_server_id(p_name);
|
||||
|
||||
if (id == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NavigationMeshGenerator *gen = navigation_mesh_generators[id].create_callback();
|
||||
|
||||
ERR_FAIL_COND_V(!gen, nullptr);
|
||||
|
||||
return gen;
|
||||
}
|
||||
|
||||
NavigationMeshGeneratorManager::NavigationMeshGeneratorManager() {
|
||||
singleton = this;
|
||||
|
||||
GLOBAL_DEF("navigation/baking/thread_model/use_thread_pool", true);
|
||||
}
|
||||
|
||||
NavigationMeshGeneratorManager::~NavigationMeshGeneratorManager() {
|
||||
singleton = nullptr;
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
#ifndef NAVIGATION_MESH_GENERATOR_H
|
||||
#define NAVIGATION_MESH_GENERATOR_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* navigation_mesh_generator.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "core/object/object.h"
|
||||
|
||||
#include "core/containers/rid.h"
|
||||
#include "core/object/class_db.h"
|
||||
#include "core/object/func_ref.h"
|
||||
#include "core/object/reference.h"
|
||||
|
||||
class Node;
|
||||
class NavigationGeometryParser2D;
|
||||
class NavigationGeometryParser3D;
|
||||
class NavigationMeshSourceGeometryData2D;
|
||||
class NavigationMeshSourceGeometryData3D;
|
||||
class NavigationPolygon;
|
||||
class NavigationMesh;
|
||||
class FuncRef;
|
||||
|
||||
class NavigationMeshGenerator : public Object {
|
||||
GDCLASS(NavigationMeshGenerator, Object);
|
||||
|
||||
static NavigationMeshGenerator *singleton;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
static NavigationMeshGenerator *get_singleton();
|
||||
|
||||
virtual void process() = 0;
|
||||
virtual void cleanup() = 0;
|
||||
|
||||
// 2D //////////////////////////////
|
||||
virtual void register_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser) = 0;
|
||||
virtual void unregister_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser) = 0;
|
||||
|
||||
virtual Ref<NavigationMeshSourceGeometryData2D> parse_2d_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback = Ref<FuncRef>()) = 0;
|
||||
virtual void bake_2d_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, Ref<FuncRef> p_callback = Ref<FuncRef>()) = 0;
|
||||
|
||||
virtual void parse_and_bake_2d(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback = Ref<FuncRef>()) = 0;
|
||||
|
||||
virtual bool is_navigation_polygon_baking(Ref<NavigationPolygon> p_navigation_polygon) const = 0;
|
||||
|
||||
virtual void init();
|
||||
virtual void finish();
|
||||
|
||||
NavigationMeshGenerator();
|
||||
~NavigationMeshGenerator();
|
||||
};
|
||||
|
||||
/// NavigationMeshGeneratorManager ////////////////////////////////////////////////////
|
||||
|
||||
typedef NavigationMeshGenerator *(*CreateNavigationMeshGeneratorCallback)();
|
||||
|
||||
class NavigationMeshGeneratorManager : public Object {
|
||||
GDCLASS(NavigationMeshGeneratorManager, Object);
|
||||
|
||||
static NavigationMeshGeneratorManager *singleton;
|
||||
|
||||
struct ClassInfo {
|
||||
String name;
|
||||
CreateNavigationMeshGeneratorCallback create_callback;
|
||||
};
|
||||
|
||||
Vector<ClassInfo> navigation_mesh_generators;
|
||||
int default_server_id = -1;
|
||||
int default_server_priority = -1;
|
||||
|
||||
void on_servers_changed();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
static const String setting_property_name;
|
||||
|
||||
static NavigationMeshGeneratorManager *get_singleton();
|
||||
|
||||
void register_server(const String &p_name, CreateNavigationMeshGeneratorCallback p_create_callback);
|
||||
void set_default_server(const String &p_name, int p_priority = 0);
|
||||
int find_server_id(const String &p_name) const;
|
||||
|
||||
NavigationMeshGenerator *new_default_server() const;
|
||||
NavigationMeshGenerator *new_server(const String &p_name) const;
|
||||
|
||||
NavigationMeshGeneratorManager();
|
||||
~NavigationMeshGeneratorManager();
|
||||
};
|
||||
|
||||
#endif // NAVIGATION_MESH_GENERATOR_H
|
@ -1,28 +0,0 @@
|
||||
|
||||
#include "navigation_mesh_generator_dummy.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
|
||||
#include "scene/2d/navigation_geometry_parser_2d.h"
|
||||
#include "scene/main/node.h"
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
|
||||
|
||||
void NavigationMeshGeneratorDummy::cleanup() {}
|
||||
void NavigationMeshGeneratorDummy::process() {}
|
||||
|
||||
// 2D //////////////////////////////
|
||||
void NavigationMeshGeneratorDummy::register_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser) {}
|
||||
void NavigationMeshGeneratorDummy::unregister_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser) {}
|
||||
|
||||
Ref<NavigationMeshSourceGeometryData2D> NavigationMeshGeneratorDummy::parse_2d_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback) {
|
||||
return Ref<NavigationMeshSourceGeometryData2D>();
|
||||
}
|
||||
void NavigationMeshGeneratorDummy::bake_2d_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, Ref<FuncRef> p_callback) {}
|
||||
|
||||
void NavigationMeshGeneratorDummy::parse_and_bake_2d(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback) {}
|
||||
|
||||
bool NavigationMeshGeneratorDummy::is_navigation_polygon_baking(Ref<NavigationPolygon> p_navigation_polygon) const {
|
||||
return false;
|
||||
}
|
||||
|
@ -1,66 +0,0 @@
|
||||
#ifndef NAVIGATION_MESH_GENERATOR_DUMMY_H
|
||||
#define NAVIGATION_MESH_GENERATOR_DUMMY_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* navigation_mesh_generator_dummy.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "servers/navigation/navigation_mesh_generator.h"
|
||||
|
||||
#include "core/object/func_ref.h"
|
||||
|
||||
class Node;
|
||||
class NavigationGeometryParser2D;
|
||||
class NavigationGeometryParser3D;
|
||||
class NavigationMeshSourceGeometryData2D;
|
||||
class NavigationMeshSourceGeometryData3D;
|
||||
class NavigationPolygon;
|
||||
class NavigationMesh;
|
||||
class FuncRef;
|
||||
|
||||
class NavigationMeshGeneratorDummy : public NavigationMeshGenerator {
|
||||
GDCLASS(NavigationMeshGeneratorDummy, NavigationMeshGenerator);
|
||||
|
||||
public:
|
||||
virtual void cleanup();
|
||||
virtual void process();
|
||||
|
||||
// 2D //////////////////////////////
|
||||
virtual void register_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser);
|
||||
virtual void unregister_geometry_parser_2d(Ref<NavigationGeometryParser2D> p_geometry_parser);
|
||||
|
||||
virtual Ref<NavigationMeshSourceGeometryData2D> parse_2d_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback = Ref<FuncRef>());
|
||||
virtual void bake_2d_from_source_geometry_data(Ref<NavigationPolygon> p_navigation_polygon, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, Ref<FuncRef> p_callback = Ref<FuncRef>());
|
||||
|
||||
virtual void parse_and_bake_2d(Ref<NavigationPolygon> p_navigation_polygon, Node *p_root_node, Ref<FuncRef> p_callback = Ref<FuncRef>());
|
||||
|
||||
virtual bool is_navigation_polygon_baking(Ref<NavigationPolygon> p_navigation_polygon) const;
|
||||
};
|
||||
|
||||
#endif // NAVIGATION_MESH_GENERATOR_DUMMY_H
|
@ -1,162 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* navigation_path_query_parameters_2d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "navigation_path_query_parameters_2d.h"
|
||||
|
||||
void NavigationPathQueryParameters2D::set_pathfinding_algorithm(const NavigationPathQueryParameters2D::PathfindingAlgorithm p_pathfinding_algorithm) {
|
||||
switch (p_pathfinding_algorithm) {
|
||||
case PATHFINDING_ALGORITHM_ASTAR: {
|
||||
parameters.pathfinding_algorithm = NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR;
|
||||
} break;
|
||||
default: {
|
||||
WARN_PRINT_ONCE("No match for used PathfindingAlgorithm - fallback to default");
|
||||
parameters.pathfinding_algorithm = NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
NavigationPathQueryParameters2D::PathfindingAlgorithm NavigationPathQueryParameters2D::get_pathfinding_algorithm() const {
|
||||
switch (parameters.pathfinding_algorithm) {
|
||||
case NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR:
|
||||
return PATHFINDING_ALGORITHM_ASTAR;
|
||||
default:
|
||||
WARN_PRINT_ONCE("No match for used PathfindingAlgorithm - fallback to default");
|
||||
return PATHFINDING_ALGORITHM_ASTAR;
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters2D::set_path_postprocessing(const NavigationPathQueryParameters2D::PathPostProcessing p_path_postprocessing) {
|
||||
switch (p_path_postprocessing) {
|
||||
case PATH_POSTPROCESSING_CORRIDORFUNNEL: {
|
||||
parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
} break;
|
||||
case PATH_POSTPROCESSING_EDGECENTERED: {
|
||||
parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED;
|
||||
} break;
|
||||
default: {
|
||||
WARN_PRINT_ONCE("No match for used PathPostProcessing - fallback to default");
|
||||
parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
NavigationPathQueryParameters2D::PathPostProcessing NavigationPathQueryParameters2D::get_path_postprocessing() const {
|
||||
switch (parameters.path_postprocessing) {
|
||||
case NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL:
|
||||
return PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
case NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED:
|
||||
return PATH_POSTPROCESSING_EDGECENTERED;
|
||||
default:
|
||||
WARN_PRINT_ONCE("No match for used PathPostProcessing - fallback to default");
|
||||
return PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters2D::set_map(const RID &p_map) {
|
||||
parameters.map = p_map;
|
||||
}
|
||||
|
||||
RID NavigationPathQueryParameters2D::get_map() const {
|
||||
return parameters.map;
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters2D::set_start_position(const Vector2 p_start_position) {
|
||||
parameters.start_position = p_start_position;
|
||||
}
|
||||
|
||||
Vector2 NavigationPathQueryParameters2D::get_start_position() const {
|
||||
return parameters.start_position;
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters2D::set_target_position(const Vector2 p_target_position) {
|
||||
parameters.target_position = p_target_position;
|
||||
}
|
||||
|
||||
Vector2 NavigationPathQueryParameters2D::get_target_position() const {
|
||||
return parameters.target_position;
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters2D::set_navigation_layers(uint32_t p_navigation_layers) {
|
||||
parameters.navigation_layers = p_navigation_layers;
|
||||
}
|
||||
|
||||
uint32_t NavigationPathQueryParameters2D::get_navigation_layers() const {
|
||||
return parameters.navigation_layers;
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters2D::set_metadata_flags(const int p_flags) {
|
||||
parameters.metadata_flags = (int64_t)p_flags;
|
||||
}
|
||||
|
||||
int NavigationPathQueryParameters2D::get_metadata_flags() const {
|
||||
return (int64_t)parameters.metadata_flags;
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters2D::set_pathfinding_algorithm);
|
||||
ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationPathQueryParameters2D::get_pathfinding_algorithm);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_postprocessing", "path_postprocessing"), &NavigationPathQueryParameters2D::set_path_postprocessing);
|
||||
ClassDB::bind_method(D_METHOD("get_path_postprocessing"), &NavigationPathQueryParameters2D::get_path_postprocessing);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_map", "map"), &NavigationPathQueryParameters2D::set_map);
|
||||
ClassDB::bind_method(D_METHOD("get_map"), &NavigationPathQueryParameters2D::get_map);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_start_position", "start_position"), &NavigationPathQueryParameters2D::set_start_position);
|
||||
ClassDB::bind_method(D_METHOD("get_start_position"), &NavigationPathQueryParameters2D::get_start_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_target_position", "target_position"), &NavigationPathQueryParameters2D::set_target_position);
|
||||
ClassDB::bind_method(D_METHOD("get_target_position"), &NavigationPathQueryParameters2D::get_target_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationPathQueryParameters2D::set_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationPathQueryParameters2D::get_navigation_layers);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_metadata_flags", "flags"), &NavigationPathQueryParameters2D::set_metadata_flags);
|
||||
ClassDB::bind_method(D_METHOD("get_metadata_flags"), &NavigationPathQueryParameters2D::get_metadata_flags);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_position"), "set_start_position", "get_start_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position"), "set_target_position", "get_target_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_metadata_flags", "get_metadata_flags");
|
||||
|
||||
BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR);
|
||||
|
||||
BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_CORRIDORFUNNEL);
|
||||
BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_EDGECENTERED);
|
||||
|
||||
BIND_ENUM_CONSTANT(PATH_METADATA_INCLUDE_NONE);
|
||||
BIND_ENUM_CONSTANT(PATH_METADATA_INCLUDE_TYPES);
|
||||
BIND_ENUM_CONSTANT(PATH_METADATA_INCLUDE_RIDS);
|
||||
BIND_ENUM_CONSTANT(PATH_METADATA_INCLUDE_OWNERS);
|
||||
BIND_ENUM_CONSTANT(PATH_METADATA_INCLUDE_ALL);
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
|
||||
#ifndef NAVIGATION_PATH_QUERY_PARAMETERS_2D_H
|
||||
#define NAVIGATION_PATH_QUERY_PARAMETERS_2D_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* navigation_path_query_parameters_2d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "core/object/reference.h"
|
||||
#include "servers/navigation/navigation_utilities.h"
|
||||
|
||||
class NavigationPathQueryParameters2D : public Reference {
|
||||
GDCLASS(NavigationPathQueryParameters2D, Reference);
|
||||
|
||||
NavigationUtilities::PathQueryParameters2D parameters;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
enum PathfindingAlgorithm {
|
||||
PATHFINDING_ALGORITHM_ASTAR = 0,
|
||||
};
|
||||
|
||||
enum PathPostProcessing {
|
||||
PATH_POSTPROCESSING_CORRIDORFUNNEL = 0,
|
||||
PATH_POSTPROCESSING_EDGECENTERED,
|
||||
};
|
||||
|
||||
enum PathMetadataFlags {
|
||||
PATH_METADATA_INCLUDE_NONE = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_NONE,
|
||||
PATH_METADATA_INCLUDE_TYPES = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_TYPES,
|
||||
PATH_METADATA_INCLUDE_RIDS = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_RIDS,
|
||||
PATH_METADATA_INCLUDE_OWNERS = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_OWNERS,
|
||||
PATH_METADATA_INCLUDE_ALL = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_ALL
|
||||
};
|
||||
|
||||
const NavigationUtilities::PathQueryParameters2D &get_parameters() const { return parameters; }
|
||||
|
||||
void set_pathfinding_algorithm(const PathfindingAlgorithm p_pathfinding_algorithm);
|
||||
PathfindingAlgorithm get_pathfinding_algorithm() const;
|
||||
|
||||
void set_path_postprocessing(const PathPostProcessing p_path_postprocessing);
|
||||
PathPostProcessing get_path_postprocessing() const;
|
||||
|
||||
void set_map(const RID &p_map);
|
||||
RID get_map() const;
|
||||
|
||||
void set_start_position(const Vector2 p_start_position);
|
||||
Vector2 get_start_position() const;
|
||||
|
||||
void set_target_position(const Vector2 p_target_position);
|
||||
Vector2 get_target_position() const;
|
||||
|
||||
void set_navigation_layers(uint32_t p_navigation_layers);
|
||||
uint32_t get_navigation_layers() const;
|
||||
|
||||
void set_metadata_flags(const int p_flags);
|
||||
int get_metadata_flags() const;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathfindingAlgorithm);
|
||||
VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathPostProcessing);
|
||||
VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathMetadataFlags);
|
||||
|
||||
#endif // NAVIGATION_PATH_QUERY_PARAMETERS_2D_H
|
@ -1,162 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* navigation_path_query_parameters_3d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "navigation_path_query_parameters_3d.h"
|
||||
|
||||
void NavigationPathQueryParameters3D::set_pathfinding_algorithm(const NavigationPathQueryParameters3D::PathfindingAlgorithm p_pathfinding_algorithm) {
|
||||
switch (p_pathfinding_algorithm) {
|
||||
case PATHFINDING_ALGORITHM_ASTAR: {
|
||||
parameters.pathfinding_algorithm = NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR;
|
||||
} break;
|
||||
default: {
|
||||
WARN_PRINT_ONCE("No match for used PathfindingAlgorithm - fallback to default");
|
||||
parameters.pathfinding_algorithm = NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
NavigationPathQueryParameters3D::PathfindingAlgorithm NavigationPathQueryParameters3D::get_pathfinding_algorithm() const {
|
||||
switch (parameters.pathfinding_algorithm) {
|
||||
case NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR:
|
||||
return PATHFINDING_ALGORITHM_ASTAR;
|
||||
default:
|
||||
WARN_PRINT_ONCE("No match for used PathfindingAlgorithm - fallback to default");
|
||||
return PATHFINDING_ALGORITHM_ASTAR;
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters3D::set_path_postprocessing(const NavigationPathQueryParameters3D::PathPostProcessing p_path_postprocessing) {
|
||||
switch (p_path_postprocessing) {
|
||||
case PATH_POSTPROCESSING_CORRIDORFUNNEL: {
|
||||
parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
} break;
|
||||
case PATH_POSTPROCESSING_EDGECENTERED: {
|
||||
parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED;
|
||||
} break;
|
||||
default: {
|
||||
WARN_PRINT_ONCE("No match for used PathPostProcessing - fallback to default");
|
||||
parameters.path_postprocessing = NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
NavigationPathQueryParameters3D::PathPostProcessing NavigationPathQueryParameters3D::get_path_postprocessing() const {
|
||||
switch (parameters.path_postprocessing) {
|
||||
case NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL:
|
||||
return PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
case NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED:
|
||||
return PATH_POSTPROCESSING_EDGECENTERED;
|
||||
default:
|
||||
WARN_PRINT_ONCE("No match for used PathPostProcessing - fallback to default");
|
||||
return PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters3D::set_map(const RID &p_map) {
|
||||
parameters.map = p_map;
|
||||
}
|
||||
|
||||
RID NavigationPathQueryParameters3D::get_map() const {
|
||||
return parameters.map;
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters3D::set_start_position(const Vector3 &p_start_position) {
|
||||
parameters.start_position = p_start_position;
|
||||
}
|
||||
|
||||
Vector3 NavigationPathQueryParameters3D::get_start_position() const {
|
||||
return parameters.start_position;
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters3D::set_target_position(const Vector3 &p_target_position) {
|
||||
parameters.target_position = p_target_position;
|
||||
}
|
||||
|
||||
Vector3 NavigationPathQueryParameters3D::get_target_position() const {
|
||||
return parameters.target_position;
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters3D::set_navigation_layers(uint32_t p_navigation_layers) {
|
||||
parameters.navigation_layers = p_navigation_layers;
|
||||
}
|
||||
|
||||
uint32_t NavigationPathQueryParameters3D::get_navigation_layers() const {
|
||||
return parameters.navigation_layers;
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters3D::set_metadata_flags(const int p_flags) {
|
||||
parameters.metadata_flags = p_flags;
|
||||
}
|
||||
|
||||
int NavigationPathQueryParameters3D::get_metadata_flags() const {
|
||||
return parameters.metadata_flags;
|
||||
}
|
||||
|
||||
void NavigationPathQueryParameters3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters3D::set_pathfinding_algorithm);
|
||||
ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationPathQueryParameters3D::get_pathfinding_algorithm);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_postprocessing", "path_postprocessing"), &NavigationPathQueryParameters3D::set_path_postprocessing);
|
||||
ClassDB::bind_method(D_METHOD("get_path_postprocessing"), &NavigationPathQueryParameters3D::get_path_postprocessing);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_map", "map"), &NavigationPathQueryParameters3D::set_map);
|
||||
ClassDB::bind_method(D_METHOD("get_map"), &NavigationPathQueryParameters3D::get_map);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_start_position", "start_position"), &NavigationPathQueryParameters3D::set_start_position);
|
||||
ClassDB::bind_method(D_METHOD("get_start_position"), &NavigationPathQueryParameters3D::get_start_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_target_position", "target_position"), &NavigationPathQueryParameters3D::set_target_position);
|
||||
ClassDB::bind_method(D_METHOD("get_target_position"), &NavigationPathQueryParameters3D::get_target_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationPathQueryParameters3D::set_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationPathQueryParameters3D::get_navigation_layers);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_metadata_flags", "flags"), &NavigationPathQueryParameters3D::set_metadata_flags);
|
||||
ClassDB::bind_method(D_METHOD("get_metadata_flags"), &NavigationPathQueryParameters3D::get_metadata_flags);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_position"), "set_start_position", "get_start_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position"), "set_target_position", "get_target_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_metadata_flags", "get_metadata_flags");
|
||||
|
||||
BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR);
|
||||
|
||||
BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_CORRIDORFUNNEL);
|
||||
BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_EDGECENTERED);
|
||||
|
||||
BIND_ENUM_CONSTANT(PATH_METADATA_INCLUDE_NONE);
|
||||
BIND_ENUM_CONSTANT(PATH_METADATA_INCLUDE_TYPES);
|
||||
BIND_ENUM_CONSTANT(PATH_METADATA_INCLUDE_RIDS);
|
||||
BIND_ENUM_CONSTANT(PATH_METADATA_INCLUDE_OWNERS);
|
||||
BIND_ENUM_CONSTANT(PATH_METADATA_INCLUDE_ALL);
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
#ifndef NAVIGATION_PATH_QUERY_PARAMETERS_3D_H
|
||||
#define NAVIGATION_PATH_QUERY_PARAMETERS_3D_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* navigation_path_query_parameters_3d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "core/object/reference.h"
|
||||
#include "servers/navigation/navigation_utilities.h"
|
||||
|
||||
class NavigationPathQueryParameters3D : public Reference {
|
||||
GDCLASS(NavigationPathQueryParameters3D, Reference);
|
||||
|
||||
NavigationUtilities::PathQueryParameters parameters;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
enum PathfindingAlgorithm {
|
||||
PATHFINDING_ALGORITHM_ASTAR = 0,
|
||||
};
|
||||
|
||||
enum PathPostProcessing {
|
||||
PATH_POSTPROCESSING_CORRIDORFUNNEL = 0,
|
||||
PATH_POSTPROCESSING_EDGECENTERED,
|
||||
};
|
||||
|
||||
enum PathMetadataFlags {
|
||||
PATH_METADATA_INCLUDE_NONE = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_NONE,
|
||||
PATH_METADATA_INCLUDE_TYPES = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_TYPES,
|
||||
PATH_METADATA_INCLUDE_RIDS = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_RIDS,
|
||||
PATH_METADATA_INCLUDE_OWNERS = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_OWNERS,
|
||||
PATH_METADATA_INCLUDE_ALL = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_ALL
|
||||
};
|
||||
|
||||
const NavigationUtilities::PathQueryParameters &get_parameters() const { return parameters; }
|
||||
|
||||
void set_pathfinding_algorithm(const PathfindingAlgorithm p_pathfinding_algorithm);
|
||||
PathfindingAlgorithm get_pathfinding_algorithm() const;
|
||||
|
||||
void set_path_postprocessing(const PathPostProcessing p_path_postprocessing);
|
||||
PathPostProcessing get_path_postprocessing() const;
|
||||
|
||||
void set_map(const RID &p_map);
|
||||
RID get_map() const;
|
||||
|
||||
void set_start_position(const Vector3 &p_start_position);
|
||||
Vector3 get_start_position() const;
|
||||
|
||||
void set_target_position(const Vector3 &p_target_position);
|
||||
Vector3 get_target_position() const;
|
||||
|
||||
void set_navigation_layers(uint32_t p_navigation_layers);
|
||||
uint32_t get_navigation_layers() const;
|
||||
|
||||
void set_metadata_flags(const int p_flags);
|
||||
int get_metadata_flags() const;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(NavigationPathQueryParameters3D::PathfindingAlgorithm);
|
||||
VARIANT_ENUM_CAST(NavigationPathQueryParameters3D::PathPostProcessing);
|
||||
VARIANT_ENUM_CAST(NavigationPathQueryParameters3D::PathMetadataFlags);
|
||||
|
||||
#endif // NAVIGATION_PATH_QUERY_PARAMETERS_3D_H
|
@ -1,120 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* navigation_path_query_result_2d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "navigation_path_query_result_2d.h"
|
||||
|
||||
void NavigationPathQueryResult2D::set_path(const Vector<Vector2> &p_path) {
|
||||
path = p_path;
|
||||
}
|
||||
|
||||
Vector<Vector2> NavigationPathQueryResult2D::get_path() const {
|
||||
return path;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult2D::set_path_types(const Vector<int32_t> &p_path_types) {
|
||||
path_types = p_path_types;
|
||||
}
|
||||
|
||||
Vector<int32_t> NavigationPathQueryResult2D::get_path_types() const {
|
||||
return path_types;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult2D::set_path_rids(const Array &p_path_rids) {
|
||||
path_rids = p_path_rids;
|
||||
}
|
||||
|
||||
Array NavigationPathQueryResult2D::get_path_rids() const {
|
||||
return path_rids;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult2D::set_path_owner_ids(const Vector<ObjectID> &p_path_owner_ids) {
|
||||
path_owner_ids = p_path_owner_ids;
|
||||
}
|
||||
|
||||
Vector<ObjectID> NavigationPathQueryResult2D::get_path_owner_ids() const {
|
||||
return path_owner_ids;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult2D::set_path_owner_ids_bind(const Array p_path_owner_ids) {
|
||||
path_owner_ids.resize(p_path_owner_ids.size());
|
||||
|
||||
for (int i = 0; i < path_owner_ids.size(); ++i) {
|
||||
path_owner_ids.write[i] = p_path_owner_ids[i];
|
||||
}
|
||||
}
|
||||
Array NavigationPathQueryResult2D::get_path_owner_ids_bind() const {
|
||||
Array ret;
|
||||
|
||||
ret.resize(path_owner_ids.size());
|
||||
|
||||
for (int i = 0; i < path_owner_ids.size(); ++i) {
|
||||
ret[i] = path_owner_ids[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult2D::set_from_query_result(const NavigationUtilities::PathQueryResult2D &p_result) {
|
||||
path = p_result.path;
|
||||
path_types = p_result.path_types;
|
||||
path_rids = p_result.path_rids;
|
||||
path_owner_ids = p_result.path_owner_ids;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult2D::reset() {
|
||||
path.clear();
|
||||
path_types.clear();
|
||||
path_rids.clear();
|
||||
path_owner_ids.clear();
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_path", "path"), &NavigationPathQueryResult2D::set_path);
|
||||
ClassDB::bind_method(D_METHOD("get_path"), &NavigationPathQueryResult2D::get_path);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_types", "path_types"), &NavigationPathQueryResult2D::set_path_types);
|
||||
ClassDB::bind_method(D_METHOD("get_path_types"), &NavigationPathQueryResult2D::get_path_types);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_rids", "path_rids"), &NavigationPathQueryResult2D::set_path_rids);
|
||||
ClassDB::bind_method(D_METHOD("get_path_rids"), &NavigationPathQueryResult2D::get_path_rids);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_owner_ids", "path_owner_ids"), &NavigationPathQueryResult2D::set_path_owner_ids_bind);
|
||||
ClassDB::bind_method(D_METHOD("get_path_owner_ids"), &NavigationPathQueryResult2D::get_path_owner_ids_bind);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("reset"), &NavigationPathQueryResult2D::reset);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "path"), "set_path", "get_path");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "path_types"), "set_path_types", "get_path_types");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "path_rids"), "set_path_rids", "get_path_rids");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "path_owner_ids"), "set_path_owner_ids", "get_path_owner_ids");
|
||||
|
||||
BIND_ENUM_CONSTANT(PATH_SEGMENT_TYPE_REGION);
|
||||
BIND_ENUM_CONSTANT(PATH_SEGMENT_TYPE_LINK);
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
#ifndef NAVIGATION_PATH_QUERY_RESULT_2D_H
|
||||
#define NAVIGATION_PATH_QUERY_RESULT_2D_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* navigation_path_query_result_2d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "core/object/reference.h"
|
||||
#include "servers/navigation/navigation_utilities.h"
|
||||
|
||||
class NavigationPathQueryResult2D : public Reference {
|
||||
GDCLASS(NavigationPathQueryResult2D, Reference);
|
||||
|
||||
Vector<Vector2> path;
|
||||
Vector<int> path_types;
|
||||
Array path_rids;
|
||||
Vector<ObjectID> path_owner_ids;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
enum PathSegmentType {
|
||||
PATH_SEGMENT_TYPE_REGION = 0,
|
||||
PATH_SEGMENT_TYPE_LINK = 1,
|
||||
};
|
||||
|
||||
void set_path(const Vector<Vector2> &p_path);
|
||||
Vector<Vector2> get_path() const;
|
||||
|
||||
void set_path_types(const Vector<int> &p_path_types);
|
||||
Vector<int> get_path_types() const;
|
||||
|
||||
void set_path_rids(const Array &p_path_rids);
|
||||
Array get_path_rids() const;
|
||||
|
||||
void set_path_owner_ids(const Vector<ObjectID> &p_path_owner_ids);
|
||||
Vector<ObjectID> get_path_owner_ids() const;
|
||||
|
||||
void set_path_owner_ids_bind(const Array p_path_owner_ids);
|
||||
Array get_path_owner_ids_bind() const;
|
||||
|
||||
void set_from_query_result(const NavigationUtilities::PathQueryResult2D &p_result);
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(NavigationPathQueryResult2D::PathSegmentType);
|
||||
|
||||
#endif // NAVIGATION_PATH_QUERY_RESULT_2D_H
|
@ -1,120 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* navigation_path_query_result_3d.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "navigation_path_query_result_3d.h"
|
||||
|
||||
void NavigationPathQueryResult3D::set_path(const Vector<Vector3> &p_path) {
|
||||
path = p_path;
|
||||
}
|
||||
|
||||
Vector<Vector3> NavigationPathQueryResult3D::get_path() const {
|
||||
return path;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult3D::set_path_types(const Vector<int> &p_path_types) {
|
||||
path_types = p_path_types;
|
||||
}
|
||||
|
||||
Vector<int> NavigationPathQueryResult3D::get_path_types() const {
|
||||
return path_types;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult3D::set_path_rids(const Array &p_path_rids) {
|
||||
path_rids = p_path_rids;
|
||||
}
|
||||
|
||||
Array NavigationPathQueryResult3D::get_path_rids() const {
|
||||
return path_rids;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult3D::set_path_owner_ids(const Vector<ObjectID> &p_path_owner_ids) {
|
||||
path_owner_ids = p_path_owner_ids;
|
||||
}
|
||||
|
||||
Vector<ObjectID> NavigationPathQueryResult3D::get_path_owner_ids() const {
|
||||
return path_owner_ids;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult3D::set_path_owner_ids_bind(const Array p_path_owner_ids) {
|
||||
path_owner_ids.resize(p_path_owner_ids.size());
|
||||
|
||||
for (int i = 0; i < path_owner_ids.size(); ++i) {
|
||||
path_owner_ids.write[i] = p_path_owner_ids[i];
|
||||
}
|
||||
}
|
||||
Array NavigationPathQueryResult3D::get_path_owner_ids_bind() const {
|
||||
Array ret;
|
||||
|
||||
ret.resize(path_owner_ids.size());
|
||||
|
||||
for (int i = 0; i < path_owner_ids.size(); ++i) {
|
||||
ret[i] = path_owner_ids[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult3D::set_from_query_result(const NavigationUtilities::PathQueryResult &p_result) {
|
||||
path = p_result.path;
|
||||
path_types = p_result.path_types;
|
||||
path_rids = p_result.path_rids;
|
||||
path_owner_ids = p_result.path_owner_ids;
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult3D::reset() {
|
||||
path.clear();
|
||||
path_types.clear();
|
||||
path_rids.clear();
|
||||
path_owner_ids.clear();
|
||||
}
|
||||
|
||||
void NavigationPathQueryResult3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_path", "path"), &NavigationPathQueryResult3D::set_path);
|
||||
ClassDB::bind_method(D_METHOD("get_path"), &NavigationPathQueryResult3D::get_path);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_types", "path_types"), &NavigationPathQueryResult3D::set_path_types);
|
||||
ClassDB::bind_method(D_METHOD("get_path_types"), &NavigationPathQueryResult3D::get_path_types);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_rids", "path_rids"), &NavigationPathQueryResult3D::set_path_rids);
|
||||
ClassDB::bind_method(D_METHOD("get_path_rids"), &NavigationPathQueryResult3D::get_path_rids);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_owner_ids", "path_owner_ids"), &NavigationPathQueryResult3D::set_path_owner_ids_bind);
|
||||
ClassDB::bind_method(D_METHOD("get_path_owner_ids"), &NavigationPathQueryResult3D::get_path_owner_ids_bind);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("reset"), &NavigationPathQueryResult3D::reset);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "path"), "set_path", "get_path");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "path_types"), "set_path_types", "get_path_types");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "path_rids"), "set_path_rids", "get_path_rids");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "path_owner_ids"), "set_path_owner_ids", "get_path_owner_ids");
|
||||
|
||||
BIND_ENUM_CONSTANT(PATH_SEGMENT_TYPE_REGION);
|
||||
BIND_ENUM_CONSTANT(PATH_SEGMENT_TYPE_LINK);
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
#ifndef NAVIGATION_PATH_QUERY_RESULT_3D_H
|
||||
#define NAVIGATION_PATH_QUERY_RESULT_3D_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* navigation_path_query_result_3d.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "core/object/reference.h"
|
||||
#include "core/variant/array.h"
|
||||
#include "servers/navigation/navigation_utilities.h"
|
||||
|
||||
class NavigationPathQueryResult3D : public Reference {
|
||||
GDCLASS(NavigationPathQueryResult3D, Reference);
|
||||
|
||||
Vector<Vector3> path;
|
||||
Vector<int> path_types;
|
||||
Array path_rids;
|
||||
Vector<ObjectID> path_owner_ids;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
enum PathSegmentType {
|
||||
PATH_SEGMENT_TYPE_REGION = 0,
|
||||
PATH_SEGMENT_TYPE_LINK = 1,
|
||||
};
|
||||
|
||||
void set_path(const Vector<Vector3> &p_path);
|
||||
Vector<Vector3> get_path() const;
|
||||
|
||||
void set_path_types(const Vector<int> &p_path_types);
|
||||
Vector<int> get_path_types() const;
|
||||
|
||||
void set_path_rids(const Array &p_path_rids);
|
||||
Array get_path_rids() const;
|
||||
|
||||
void set_path_owner_ids(const Vector<ObjectID> &p_path_owner_ids);
|
||||
Vector<ObjectID> get_path_owner_ids() const;
|
||||
|
||||
void set_path_owner_ids_bind(const Array p_path_owner_ids);
|
||||
Array get_path_owner_ids_bind() const;
|
||||
|
||||
void set_from_query_result(const NavigationUtilities::PathQueryResult &p_result);
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(NavigationPathQueryResult3D::PathSegmentType);
|
||||
|
||||
#endif // NAVIGATION_PATH_QUERY_RESULT_3D_H
|
@ -1,100 +0,0 @@
|
||||
|
||||
#ifndef NAVIGATION_UTILITIES_H
|
||||
#define NAVIGATION_UTILITIES_H
|
||||
|
||||
/**************************************************************************/
|
||||
/* navigation_utilities.h */
|
||||
/**************************************************************************/
|
||||
/* 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "core/containers/rid.h"
|
||||
#include "core/math/vector3.h"
|
||||
#include "core/variant/array.h"
|
||||
#include "core/variant/variant.h"
|
||||
|
||||
namespace NavigationUtilities {
|
||||
|
||||
enum PathfindingAlgorithm {
|
||||
PATHFINDING_ALGORITHM_ASTAR = 0,
|
||||
};
|
||||
|
||||
enum PathPostProcessing {
|
||||
PATH_POSTPROCESSING_CORRIDORFUNNEL = 0,
|
||||
PATH_POSTPROCESSING_EDGECENTERED,
|
||||
};
|
||||
|
||||
enum PathSegmentType {
|
||||
PATH_SEGMENT_TYPE_REGION = 0,
|
||||
PATH_SEGMENT_TYPE_LINK
|
||||
};
|
||||
|
||||
enum PathMetadataFlags {
|
||||
PATH_INCLUDE_NONE = 0,
|
||||
PATH_INCLUDE_TYPES = 1,
|
||||
PATH_INCLUDE_RIDS = 2,
|
||||
PATH_INCLUDE_OWNERS = 4,
|
||||
PATH_INCLUDE_ALL = PATH_INCLUDE_TYPES | PATH_INCLUDE_RIDS | PATH_INCLUDE_OWNERS
|
||||
};
|
||||
|
||||
struct PathQueryParameters {
|
||||
PathfindingAlgorithm pathfinding_algorithm = PATHFINDING_ALGORITHM_ASTAR;
|
||||
PathPostProcessing path_postprocessing = PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
RID map;
|
||||
Vector3 start_position;
|
||||
Vector3 target_position;
|
||||
uint32_t navigation_layers = 1;
|
||||
int metadata_flags = PATH_INCLUDE_ALL;
|
||||
};
|
||||
|
||||
struct PathQueryParameters2D {
|
||||
PathfindingAlgorithm pathfinding_algorithm = PATHFINDING_ALGORITHM_ASTAR;
|
||||
PathPostProcessing path_postprocessing = PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
RID map;
|
||||
Vector2 start_position;
|
||||
Vector2 target_position;
|
||||
uint32_t navigation_layers = 1;
|
||||
int metadata_flags = PATH_INCLUDE_ALL;
|
||||
};
|
||||
|
||||
struct PathQueryResult {
|
||||
Vector<Vector3> path;
|
||||
Vector<int> path_types;
|
||||
Array path_rids;
|
||||
Vector<uint64_t> path_owner_ids;
|
||||
};
|
||||
|
||||
struct PathQueryResult2D {
|
||||
Vector<Vector2> path;
|
||||
Vector<int> path_types;
|
||||
Array path_rids;
|
||||
Vector<uint64_t> path_owner_ids;
|
||||
};
|
||||
|
||||
} //namespace NavigationUtilities
|
||||
|
||||
#endif // NAVIGATION_UTILITIES_H
|
@ -1,445 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* navigation_2d_server.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "servers/navigation_2d_server.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "navigation/navigation_path_query_parameters_2d.h"
|
||||
#include "navigation/navigation_path_query_result_2d.h"
|
||||
#include "servers/navigation_server.h"
|
||||
|
||||
Navigation2DServer *Navigation2DServer::singleton = nullptr;
|
||||
|
||||
void Navigation2DServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_maps"), &Navigation2DServer::get_maps);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("map_create"), &Navigation2DServer::map_create);
|
||||
ClassDB::bind_method(D_METHOD("map_set_active", "map", "active"), &Navigation2DServer::map_set_active);
|
||||
ClassDB::bind_method(D_METHOD("map_is_active", "map"), &Navigation2DServer::map_is_active);
|
||||
ClassDB::bind_method(D_METHOD("map_set_cell_size", "map", "cell_size"), &Navigation2DServer::map_set_cell_size);
|
||||
ClassDB::bind_method(D_METHOD("map_get_cell_size", "map"), &Navigation2DServer::map_get_cell_size);
|
||||
ClassDB::bind_method(D_METHOD("map_set_use_edge_connections", "map", "enabled"), &Navigation2DServer::map_set_use_edge_connections);
|
||||
ClassDB::bind_method(D_METHOD("map_get_use_edge_connections", "map"), &Navigation2DServer::map_get_use_edge_connections);
|
||||
ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &Navigation2DServer::map_set_edge_connection_margin);
|
||||
ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &Navigation2DServer::map_get_edge_connection_margin);
|
||||
ClassDB::bind_method(D_METHOD("map_set_link_connection_radius", "map", "radius"), &Navigation2DServer::map_set_link_connection_radius);
|
||||
ClassDB::bind_method(D_METHOD("map_get_link_connection_radius", "map"), &Navigation2DServer::map_get_link_connection_radius);
|
||||
ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "navigation_layers"), &Navigation2DServer::map_get_path, 1);
|
||||
ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &Navigation2DServer::map_get_closest_point);
|
||||
ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &Navigation2DServer::map_get_closest_point_owner);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("map_get_links", "map"), &Navigation2DServer::map_get_links);
|
||||
ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &Navigation2DServer::map_get_regions);
|
||||
ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &Navigation2DServer::map_get_agents);
|
||||
ClassDB::bind_method(D_METHOD("map_get_obstacles", "map"), &Navigation2DServer::map_get_obstacles);
|
||||
ClassDB::bind_method(D_METHOD("map_force_update", "map"), &Navigation2DServer::map_force_update);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("region_create"), &Navigation2DServer::region_create);
|
||||
ClassDB::bind_method(D_METHOD("region_set_enabled", "region", "enabled"), &Navigation2DServer::region_set_enabled);
|
||||
ClassDB::bind_method(D_METHOD("region_get_enabled", "region"), &Navigation2DServer::region_get_enabled);
|
||||
ClassDB::bind_method(D_METHOD("region_set_use_edge_connections", "region", "enabled"), &Navigation2DServer::region_set_use_edge_connections);
|
||||
ClassDB::bind_method(D_METHOD("region_get_use_edge_connections", "region"), &Navigation2DServer::region_get_use_edge_connections);
|
||||
ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &Navigation2DServer::region_set_enter_cost);
|
||||
ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &Navigation2DServer::region_get_enter_cost);
|
||||
ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &Navigation2DServer::region_set_travel_cost);
|
||||
ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &Navigation2DServer::region_get_travel_cost);
|
||||
ClassDB::bind_method(D_METHOD("region_set_owner_id", "region", "owner_id"), &Navigation2DServer::region_set_owner_id);
|
||||
ClassDB::bind_method(D_METHOD("region_get_owner_id", "region"), &Navigation2DServer::region_get_owner_id);
|
||||
ClassDB::bind_method(D_METHOD("region_owns_point", "region", "point"), &Navigation2DServer::region_owns_point);
|
||||
ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &Navigation2DServer::region_set_map);
|
||||
ClassDB::bind_method(D_METHOD("region_get_map", "region"), &Navigation2DServer::region_get_map);
|
||||
ClassDB::bind_method(D_METHOD("region_set_navigation_layers", "region", "navigation_layers"), &Navigation2DServer::region_set_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("region_get_navigation_layers", "region"), &Navigation2DServer::region_get_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &Navigation2DServer::region_set_transform);
|
||||
ClassDB::bind_method(D_METHOD("region_set_navigation_polygon", "region", "nav_poly"), &Navigation2DServer::region_set_navigation_polygon);
|
||||
ClassDB::bind_method(D_METHOD("region_get_connections_count", "region"), &Navigation2DServer::region_get_connections_count);
|
||||
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &Navigation2DServer::region_get_connection_pathway_start);
|
||||
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &Navigation2DServer::region_get_connection_pathway_end);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("link_create"), &Navigation2DServer::link_create);
|
||||
ClassDB::bind_method(D_METHOD("link_set_map", "link", "map"), &Navigation2DServer::link_set_map);
|
||||
ClassDB::bind_method(D_METHOD("link_get_map", "link"), &Navigation2DServer::link_get_map);
|
||||
ClassDB::bind_method(D_METHOD("link_set_enabled", "link", "enabled"), &Navigation2DServer::link_set_enabled);
|
||||
ClassDB::bind_method(D_METHOD("link_get_enabled", "link"), &Navigation2DServer::link_get_enabled);
|
||||
ClassDB::bind_method(D_METHOD("link_set_bidirectional", "link", "bidirectional"), &Navigation2DServer::link_set_bidirectional);
|
||||
ClassDB::bind_method(D_METHOD("link_is_bidirectional", "link"), &Navigation2DServer::link_is_bidirectional);
|
||||
ClassDB::bind_method(D_METHOD("link_set_navigation_layers", "link", "navigation_layers"), &Navigation2DServer::link_set_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("link_get_navigation_layers", "link"), &Navigation2DServer::link_get_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("link_set_start_position", "link", "position"), &Navigation2DServer::link_set_start_position);
|
||||
ClassDB::bind_method(D_METHOD("link_get_start_position", "link"), &Navigation2DServer::link_get_start_position);
|
||||
ClassDB::bind_method(D_METHOD("link_set_end_position", "link", "position"), &Navigation2DServer::link_set_end_position);
|
||||
ClassDB::bind_method(D_METHOD("link_get_end_position", "link"), &Navigation2DServer::link_get_end_position);
|
||||
ClassDB::bind_method(D_METHOD("link_set_enter_cost", "link", "enter_cost"), &Navigation2DServer::link_set_enter_cost);
|
||||
ClassDB::bind_method(D_METHOD("link_get_enter_cost", "link"), &Navigation2DServer::link_get_enter_cost);
|
||||
ClassDB::bind_method(D_METHOD("link_set_travel_cost", "link", "travel_cost"), &Navigation2DServer::link_set_travel_cost);
|
||||
ClassDB::bind_method(D_METHOD("link_get_travel_cost", "link"), &Navigation2DServer::link_get_travel_cost);
|
||||
ClassDB::bind_method(D_METHOD("link_set_owner_id", "link", "owner_id"), &Navigation2DServer::link_set_owner_id);
|
||||
ClassDB::bind_method(D_METHOD("link_get_owner_id", "link"), &Navigation2DServer::link_get_owner_id);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("agent_create"), &Navigation2DServer::agent_create);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_avoidance_enabled", "agent", "enabled"), &Navigation2DServer::agent_set_avoidance_enabled);
|
||||
ClassDB::bind_method(D_METHOD("agent_get_avoidance_enabled", "agent"), &Navigation2DServer::agent_get_avoidance_enabled);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &Navigation2DServer::agent_set_map);
|
||||
ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &Navigation2DServer::agent_get_map);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_paused", "agent", "paused"), &Navigation2DServer::agent_set_paused);
|
||||
ClassDB::bind_method(D_METHOD("agent_get_paused", "agent"), &Navigation2DServer::agent_get_paused);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_neighbor_distance", "agent", "dist"), &Navigation2DServer::agent_set_neighbor_distance);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &Navigation2DServer::agent_set_max_neighbors);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_time_horizon_agents", "agent", "time_horizon"), &Navigation2DServer::agent_set_time_horizon_agents);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_time_horizon_obstacles", "agent", "time_horizon"), &Navigation2DServer::agent_set_time_horizon_obstacles);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_radius", "agent", "radius"), &Navigation2DServer::agent_set_radius);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_max_speed", "agent", "max_speed"), &Navigation2DServer::agent_set_max_speed);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_velocity_forced", "agent", "velocity"), &Navigation2DServer::agent_set_velocity_forced);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_velocity", "agent", "velocity"), &Navigation2DServer::agent_set_velocity);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_position", "agent", "position"), &Navigation2DServer::agent_set_position);
|
||||
ClassDB::bind_method(D_METHOD("agent_is_map_changed", "agent"), &Navigation2DServer::agent_is_map_changed);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_avoidance_callback", "agent", "object_id", "method", "userdata"), &Navigation2DServer::agent_set_avoidance_callback, DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("agent_set_avoidance_layers", "agent", "layers"), &Navigation2DServer::agent_set_avoidance_layers);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_avoidance_mask", "agent", "mask"), &Navigation2DServer::agent_set_avoidance_mask);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_avoidance_priority", "agent", "priority"), &Navigation2DServer::agent_set_avoidance_priority);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("obstacle_create"), &Navigation2DServer::obstacle_create);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_avoidance_enabled", "obstacle", "enabled"), &Navigation2DServer::obstacle_set_avoidance_enabled);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_get_avoidance_enabled", "obstacle"), &Navigation2DServer::obstacle_get_avoidance_enabled);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_map", "obstacle", "map"), &Navigation2DServer::obstacle_set_map);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_get_map", "obstacle"), &Navigation2DServer::obstacle_get_map);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_radius", "obstacle", "radius"), &Navigation2DServer::obstacle_set_radius);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_velocity", "obstacle", "velocity"), &Navigation2DServer::obstacle_set_velocity);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_paused", "obstacle", "paused"), &Navigation2DServer::obstacle_set_paused);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_get_paused", "obstacle"), &Navigation2DServer::obstacle_get_paused);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_position", "obstacle", "position"), &Navigation2DServer::obstacle_set_position);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_vertices", "obstacle", "vertices"), &Navigation2DServer::obstacle_set_vertices);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_avoidance_layers", "obstacle", "layers"), &Navigation2DServer::obstacle_set_avoidance_layers);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &Navigation2DServer::free);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &Navigation2DServer::set_debug_enabled);
|
||||
ClassDB::bind_method(D_METHOD("get_debug_enabled"), &Navigation2DServer::get_debug_enabled);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
ClassDB::bind_method(D_METHOD("_emit_navigation_debug_changed_signal"), &Navigation2DServer::_emit_navigation_debug_changed_signal);
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map")));
|
||||
ADD_SIGNAL(MethodInfo("navigation_debug_changed"));
|
||||
}
|
||||
|
||||
void Navigation2DServer::init() {
|
||||
#ifdef DEBUG_ENABLED
|
||||
NavigationServer::get_singleton()->connect("navigation_debug_changed", this, "_emit_navigation_debug_changed_signal");
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
void Navigation2DServer::finish() {
|
||||
}
|
||||
|
||||
void Navigation2DServer::query_path(const Ref<NavigationPathQueryParameters2D> &p_query_parameters, Ref<NavigationPathQueryResult2D> p_query_result) const {
|
||||
ERR_FAIL_COND(!p_query_parameters.is_valid());
|
||||
ERR_FAIL_COND(!p_query_result.is_valid());
|
||||
|
||||
const NavigationUtilities::PathQueryResult2D _query_result = _query_path(p_query_parameters->get_parameters());
|
||||
|
||||
p_query_result->set_from_query_result(_query_result);
|
||||
}
|
||||
|
||||
Navigation2DServer::Navigation2DServer() {
|
||||
singleton = this;
|
||||
}
|
||||
|
||||
Navigation2DServer::~Navigation2DServer() {
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void Navigation2DServer::_emit_navigation_debug_changed_signal() {
|
||||
emit_signal("navigation_debug_changed");
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
void Navigation2DServer::set_debug_enabled(bool p_enabled) {
|
||||
NavigationServer::get_singleton()->set_debug_enabled(p_enabled);
|
||||
}
|
||||
bool Navigation2DServer::get_debug_enabled() const {
|
||||
return NavigationServer::get_singleton()->get_debug_enabled();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void Navigation2DServer::set_debug_navigation_enabled(bool p_enabled) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_enabled(p_enabled);
|
||||
}
|
||||
|
||||
bool Navigation2DServer::get_debug_navigation_enabled() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_enabled();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_avoidance_enabled(bool p_enabled) {
|
||||
NavigationServer::get_singleton()->set_debug_avoidance_enabled(p_enabled);
|
||||
}
|
||||
|
||||
bool Navigation2DServer::get_debug_avoidance_enabled() const {
|
||||
return NavigationServer::get_singleton()->get_debug_avoidance_enabled();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_edge_connection_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_edge_connection_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_edge_connection_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_edge_connection_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_geometry_face_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_geometry_face_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_geometry_face_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_geometry_face_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_geometry_face_disabled_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_geometry_face_disabled_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_geometry_face_disabled_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_geometry_face_disabled_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_geometry_edge_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_geometry_edge_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_geometry_edge_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_geometry_edge_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_geometry_edge_disabled_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_geometry_edge_disabled_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_geometry_edge_disabled_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_geometry_edge_disabled_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_enable_edge_connections(const bool p_value) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_enable_edge_connections(p_value);
|
||||
}
|
||||
|
||||
bool Navigation2DServer::get_debug_navigation_enable_edge_connections() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_enable_edge_connections();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_enable_geometry_face_random_color(const bool p_value) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_enable_geometry_face_random_color(p_value);
|
||||
}
|
||||
|
||||
bool Navigation2DServer::get_debug_navigation_enable_geometry_face_random_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_enable_geometry_face_random_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_enable_edge_lines(const bool p_value) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_enable_edge_lines(p_value);
|
||||
}
|
||||
|
||||
bool Navigation2DServer::get_debug_navigation_enable_edge_lines() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_enable_edge_lines();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_link_connection_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_link_connection_color(p_color);
|
||||
}
|
||||
Color Navigation2DServer::get_debug_navigation_link_connection_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_link_connection_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_link_connection_disabled_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_link_connection_disabled_color(p_color);
|
||||
}
|
||||
Color Navigation2DServer::get_debug_navigation_link_connection_disabled_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_link_connection_disabled_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_agent_path_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_agent_path_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_agent_path_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_agent_path_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_enable_agent_paths(const bool p_value) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_enable_agent_paths(p_value);
|
||||
}
|
||||
|
||||
bool Navigation2DServer::get_debug_navigation_enable_agent_paths() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_enable_agent_paths();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_agent_path_point_size(float p_point_size) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_agent_path_point_size(p_point_size);
|
||||
}
|
||||
|
||||
float Navigation2DServer::get_debug_navigation_agent_path_point_size() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_agent_path_point_size();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_avoidance_enable_agents_radius(const bool p_value) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_avoidance_enable_agents_radius(p_value);
|
||||
}
|
||||
|
||||
bool Navigation2DServer::get_debug_navigation_avoidance_enable_agents_radius() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_avoidance_enable_agents_radius();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_avoidance_enable_obstacles_radius(const bool p_value) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_avoidance_enable_obstacles_radius(p_value);
|
||||
}
|
||||
|
||||
bool Navigation2DServer::get_debug_navigation_avoidance_enable_obstacles_radius() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_avoidance_enable_obstacles_radius();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_avoidance_agents_radius_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_avoidance_agents_radius_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_avoidance_agents_radius_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_avoidance_agents_radius_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_avoidance_obstacles_radius_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_avoidance_obstacles_radius_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_avoidance_obstacles_radius_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_avoidance_obstacles_radius_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_avoidance_static_obstacle_pushin_face_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_avoidance_static_obstacle_pushin_face_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_avoidance_static_obstacle_pushin_face_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushin_face_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_avoidance_static_obstacle_pushout_face_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_avoidance_static_obstacle_pushout_face_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_avoidance_static_obstacle_pushout_face_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushout_face_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_avoidance_static_obstacle_pushin_edge_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_avoidance_static_obstacle_pushin_edge_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_avoidance_static_obstacle_pushin_edge_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushin_edge_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_avoidance_static_obstacle_pushout_edge_color(const Color &p_color) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_avoidance_static_obstacle_pushout_edge_color(p_color);
|
||||
}
|
||||
|
||||
Color Navigation2DServer::get_debug_navigation_avoidance_static_obstacle_pushout_edge_color() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushout_edge_color();
|
||||
}
|
||||
|
||||
void Navigation2DServer::set_debug_navigation_avoidance_enable_obstacles_static(const bool p_value) {
|
||||
NavigationServer::get_singleton()->set_debug_navigation_avoidance_enable_obstacles_static(p_value);
|
||||
}
|
||||
|
||||
bool Navigation2DServer::get_debug_navigation_avoidance_enable_obstacles_static() const {
|
||||
return NavigationServer::get_singleton()->get_debug_navigation_avoidance_enable_obstacles_static();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Vector<Navigation2DServerManager::ClassInfo> Navigation2DServerManager::navigation_servers;
|
||||
int Navigation2DServerManager::default_server_id = -1;
|
||||
int Navigation2DServerManager::default_server_priority = -1;
|
||||
const String Navigation2DServerManager::setting_property_name("navigation/2d/navigation_engine");
|
||||
|
||||
void Navigation2DServerManager::on_servers_changed() {
|
||||
String navigation_servers2("DEFAULT");
|
||||
for (int i = get_servers_count() - 1; 0 <= i; --i) {
|
||||
navigation_servers2 += "," + get_server_name(i);
|
||||
}
|
||||
ProjectSettings::get_singleton()->set_custom_property_info(setting_property_name, PropertyInfo(Variant::STRING, setting_property_name, PROPERTY_HINT_ENUM, navigation_servers2));
|
||||
}
|
||||
|
||||
void Navigation2DServerManager::register_server(const String &p_name, CreateNavigation2DServerCallback p_creat_callback) {
|
||||
ERR_FAIL_COND(!p_creat_callback);
|
||||
ERR_FAIL_COND(find_server_id(p_name) != -1);
|
||||
navigation_servers.push_back(ClassInfo(p_name, p_creat_callback));
|
||||
on_servers_changed();
|
||||
}
|
||||
|
||||
void Navigation2DServerManager::set_default_server(const String &p_name, int p_priority) {
|
||||
const int id = find_server_id(p_name);
|
||||
ERR_FAIL_COND(id == -1); // Not found
|
||||
if (default_server_priority < p_priority) {
|
||||
default_server_id = id;
|
||||
default_server_priority = p_priority;
|
||||
}
|
||||
}
|
||||
|
||||
int Navigation2DServerManager::find_server_id(const String &p_name) {
|
||||
for (int i = navigation_servers.size() - 1; 0 <= i; --i) {
|
||||
if (p_name == navigation_servers[i].name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Navigation2DServerManager::get_servers_count() {
|
||||
return navigation_servers.size();
|
||||
}
|
||||
|
||||
String Navigation2DServerManager::get_server_name(int p_id) {
|
||||
ERR_FAIL_INDEX_V(p_id, get_servers_count(), "");
|
||||
return navigation_servers[p_id].name;
|
||||
}
|
||||
|
||||
Navigation2DServer *Navigation2DServerManager::new_default_server() {
|
||||
ERR_FAIL_COND_V(default_server_id == -1, nullptr);
|
||||
return navigation_servers[default_server_id].create_callback();
|
||||
}
|
||||
|
||||
Navigation2DServer *Navigation2DServerManager::new_server(const String &p_name) {
|
||||
int id = find_server_id(p_name);
|
||||
if (id == -1) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return navigation_servers[id].create_callback();
|
||||
}
|
||||
}
|
@ -1,406 +0,0 @@
|
||||
#ifndef NAVIGATION_2D_SERVER_H
|
||||
#define NAVIGATION_2D_SERVER_H
|
||||
|
||||
/*************************************************************************/
|
||||
/* navigation_2d_server.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "core/containers/rid.h"
|
||||
#include "core/object/object.h"
|
||||
|
||||
#include "navigation/navigation_utilities.h"
|
||||
#include "scene/2d/navigation_polygon_instance.h"
|
||||
#include "scene/resources/navigation_2d/navigation_polygon.h"
|
||||
|
||||
class NavigationPathQueryParameters2D;
|
||||
class NavigationPathQueryResult2D;
|
||||
|
||||
// This server exposes the 3D `NavigationServer` features in the 2D world.
|
||||
class Navigation2DServer : public Object {
|
||||
GDCLASS(Navigation2DServer, Object);
|
||||
|
||||
static Navigation2DServer *singleton;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
static Navigation2DServer *get_singleton() { return singleton; }
|
||||
|
||||
virtual Array get_maps() const = 0;
|
||||
|
||||
/// Create a new map.
|
||||
virtual RID map_create() = 0;
|
||||
|
||||
/// Set map active.
|
||||
virtual void map_set_active(RID p_map, bool p_active) = 0;
|
||||
|
||||
/// Returns true if the map is active.
|
||||
virtual bool map_is_active(RID p_map) const = 0;
|
||||
|
||||
/// Set the map cell size used to weld the navigation mesh polygons.
|
||||
virtual void map_set_cell_size(RID p_map, real_t p_cell_size) = 0;
|
||||
|
||||
/// Returns the map cell size.
|
||||
virtual real_t map_get_cell_size(RID p_map) const = 0;
|
||||
|
||||
virtual void map_set_use_edge_connections(RID p_map, bool p_enabled) = 0;
|
||||
virtual bool map_get_use_edge_connections(RID p_map) const = 0;
|
||||
|
||||
/// Set the map edge connection margin used to weld the compatible region edges.
|
||||
virtual void map_set_edge_connection_margin(RID p_map, real_t p_connection_margin) = 0;
|
||||
|
||||
/// Returns the edge connection margin of this map.
|
||||
virtual real_t map_get_edge_connection_margin(RID p_map) const = 0;
|
||||
|
||||
/// Set the map link connection radius used to attach links to the nav mesh.
|
||||
virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) = 0;
|
||||
|
||||
/// Returns the link connection radius of this map.
|
||||
virtual real_t map_get_link_connection_radius(RID p_map) const = 0;
|
||||
|
||||
/// Returns the navigation path to reach the destination from the origin.
|
||||
virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const = 0;
|
||||
|
||||
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const = 0;
|
||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const = 0;
|
||||
|
||||
virtual Array map_get_links(RID p_map) const = 0;
|
||||
virtual Array map_get_regions(RID p_map) const = 0;
|
||||
virtual Array map_get_agents(RID p_map) const = 0;
|
||||
virtual Array map_get_obstacles(RID p_map) const = 0;
|
||||
|
||||
virtual void map_force_update(RID p_map) = 0;
|
||||
|
||||
/// Creates a new region.
|
||||
virtual RID region_create() = 0;
|
||||
|
||||
virtual void region_set_enabled(RID p_region, bool p_enabled) = 0;
|
||||
virtual bool region_get_enabled(RID p_region) const = 0;
|
||||
|
||||
virtual void region_set_use_edge_connections(RID p_region, bool p_enabled) = 0;
|
||||
virtual bool region_get_use_edge_connections(RID p_region) const = 0;
|
||||
|
||||
/// Set the enter_cost of a region
|
||||
virtual void region_set_enter_cost(RID p_region, real_t p_enter_cost) = 0;
|
||||
virtual real_t region_get_enter_cost(RID p_region) const = 0;
|
||||
|
||||
/// Set the travel_cost of a region
|
||||
virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) = 0;
|
||||
virtual real_t region_get_travel_cost(RID p_region) const = 0;
|
||||
|
||||
/// Set the node which manages this region.
|
||||
virtual void region_set_owner_id(RID p_region, ObjectID p_owner_id) = 0;
|
||||
virtual ObjectID region_get_owner_id(RID p_region) const = 0;
|
||||
|
||||
virtual bool region_owns_point(RID p_region, const Vector2 &p_point) const = 0;
|
||||
|
||||
/// Set the map of this region.
|
||||
virtual void region_set_map(RID p_region, RID p_map) = 0;
|
||||
virtual RID region_get_map(RID p_region) const = 0;
|
||||
|
||||
/// Set the region's layers
|
||||
virtual void region_set_navigation_layers(RID p_region, uint32_t p_navigation_layers) = 0;
|
||||
virtual uint32_t region_get_navigation_layers(RID p_region) const = 0;
|
||||
|
||||
/// Set the global transformation of this region.
|
||||
virtual void region_set_transform(RID p_region, Transform2D p_transform) = 0;
|
||||
|
||||
/// Set the navigation poly of this region.
|
||||
virtual void region_set_navigation_polygon(RID p_region, Ref<NavigationPolygon> p_navigation_mesh) = 0;
|
||||
|
||||
/// Get a list of a region's connection to other regions.
|
||||
virtual int region_get_connections_count(RID p_region) const = 0;
|
||||
virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const = 0;
|
||||
virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const = 0;
|
||||
|
||||
/// Creates a new link between positions in the nav map.
|
||||
virtual RID link_create() = 0;
|
||||
|
||||
/// Set the map of this link.
|
||||
virtual void link_set_map(RID p_link, RID p_map) = 0;
|
||||
virtual RID link_get_map(RID p_link) const = 0;
|
||||
|
||||
virtual void link_set_enabled(RID p_link, bool p_enabled) = 0;
|
||||
virtual bool link_get_enabled(RID p_link) const = 0;
|
||||
|
||||
/// Set whether this link travels in both directions.
|
||||
virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) = 0;
|
||||
virtual bool link_is_bidirectional(RID p_link) const = 0;
|
||||
|
||||
/// Set the link's layers.
|
||||
virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) = 0;
|
||||
virtual uint32_t link_get_navigation_layers(RID p_link) const = 0;
|
||||
|
||||
/// Set the start position of the link.
|
||||
virtual void link_set_start_position(RID p_link, Vector2 p_position) = 0;
|
||||
virtual Vector2 link_get_start_position(RID p_link) const = 0;
|
||||
|
||||
/// Set the end position of the link.
|
||||
virtual void link_set_end_position(RID p_link, Vector2 p_position) = 0;
|
||||
virtual Vector2 link_get_end_position(RID p_link) const = 0;
|
||||
|
||||
/// Set the enter cost of the link.
|
||||
virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) = 0;
|
||||
virtual real_t link_get_enter_cost(RID p_link) const = 0;
|
||||
|
||||
/// Set the travel cost of the link.
|
||||
virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) = 0;
|
||||
virtual real_t link_get_travel_cost(RID p_link) const = 0;
|
||||
|
||||
/// Set the node which manages this link.
|
||||
virtual void link_set_owner_id(RID p_link, ObjectID p_owner_id) = 0;
|
||||
virtual ObjectID link_get_owner_id(RID p_link) const = 0;
|
||||
|
||||
/// Creates the agent.
|
||||
virtual RID agent_create() = 0;
|
||||
|
||||
/// Put the agent in the map.
|
||||
virtual void agent_set_map(RID p_agent, RID p_map) = 0;
|
||||
virtual RID agent_get_map(RID p_agent) const = 0;
|
||||
|
||||
virtual void agent_set_paused(RID p_agent, bool p_paused) = 0;
|
||||
virtual bool agent_get_paused(RID p_agent) const = 0;
|
||||
|
||||
virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) = 0;
|
||||
virtual bool agent_get_avoidance_enabled(RID p_agent) const = 0;
|
||||
|
||||
/// The maximum distance (center point to
|
||||
/// center point) to other agents this agent
|
||||
/// takes into account in the navigation. The
|
||||
/// larger this number, the longer the running
|
||||
/// time of the simulation. If the number is too
|
||||
/// low, the simulation will not be safe.
|
||||
/// Must be non-negative.
|
||||
virtual void agent_set_neighbor_distance(RID p_agent, real_t p_dist) = 0;
|
||||
|
||||
/// The maximum number of other agents this
|
||||
/// agent takes into account in the navigation.
|
||||
/// The larger this number, the longer the
|
||||
/// running time of the simulation. If the
|
||||
/// number is too low, the simulation will not
|
||||
/// be safe.
|
||||
virtual void agent_set_max_neighbors(RID p_agent, int p_count) = 0;
|
||||
|
||||
/// The minimal amount of time for which this
|
||||
/// agent's velocities that are computed by the
|
||||
/// simulation are safe with respect to other
|
||||
/// agents. The larger this number, the sooner
|
||||
/// this agent will respond to the presence of
|
||||
/// other agents, but the less freedom this
|
||||
/// agent has in choosing its velocities.
|
||||
/// Must be positive.
|
||||
virtual void agent_set_time_horizon_agents(RID p_agent, real_t p_time_horizon) = 0;
|
||||
virtual void agent_set_time_horizon_obstacles(RID p_agent, real_t p_time_horizon) = 0;
|
||||
|
||||
/// The radius of this agent.
|
||||
/// Must be non-negative.
|
||||
virtual void agent_set_radius(RID p_agent, real_t p_radius) = 0;
|
||||
|
||||
/// The maximum speed of this agent.
|
||||
/// Must be non-negative.
|
||||
virtual void agent_set_max_speed(RID p_agent, real_t p_max_speed) = 0;
|
||||
|
||||
/// forces and agent velocity change in the avoidance simulation, adds simulation instability if done recklessly
|
||||
virtual void agent_set_velocity_forced(RID p_agent, Vector2 p_velocity) = 0;
|
||||
|
||||
/// The wanted velocity for the agent as a "suggestion" to the avoidance simulation.
|
||||
/// The simulation will try to fulfil this velocity wish if possible but may change the velocity depending on other agent's and obstacles'.
|
||||
virtual void agent_set_velocity(RID p_agent, Vector2 p_velocity) = 0;
|
||||
|
||||
/// Position of the agent in world space.
|
||||
virtual void agent_set_position(RID p_agent, Vector2 p_position) = 0;
|
||||
|
||||
/// Returns true if the map got changed the previous frame.
|
||||
virtual bool agent_is_map_changed(RID p_agent) const = 0;
|
||||
|
||||
/// Callback called at the end of the RVO process
|
||||
virtual void agent_set_avoidance_callback(RID p_agent, ObjectID p_object_id, StringName p_method, Variant p_udata = Variant()) = 0;
|
||||
|
||||
virtual void agent_set_avoidance_layers(RID p_agent, uint32_t p_layers) = 0;
|
||||
virtual void agent_set_avoidance_mask(RID p_agent, uint32_t p_mask) = 0;
|
||||
virtual void agent_set_avoidance_priority(RID p_agent, real_t p_priority) = 0;
|
||||
|
||||
/// Creates the obstacle.
|
||||
virtual RID obstacle_create() = 0;
|
||||
virtual void obstacle_set_map(RID p_obstacle, RID p_map) = 0;
|
||||
virtual RID obstacle_get_map(RID p_obstacle) const = 0;
|
||||
virtual void obstacle_set_avoidance_enabled(RID p_obstacle, bool p_enabled) = 0;
|
||||
virtual bool obstacle_get_avoidance_enabled(RID p_obstacle) const = 0;
|
||||
virtual void obstacle_set_radius(RID p_obstacle, real_t p_radius) = 0;
|
||||
virtual void obstacle_set_paused(RID p_obstacle, bool p_paused) = 0;
|
||||
virtual bool obstacle_get_paused(RID p_obstacle) const = 0;
|
||||
virtual void obstacle_set_velocity(RID p_obstacle, Vector2 p_velocity) = 0;
|
||||
virtual void obstacle_set_position(RID p_obstacle, Vector2 p_position) = 0;
|
||||
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices) = 0;
|
||||
virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers) = 0;
|
||||
|
||||
/// Destroy the `RID`
|
||||
virtual void free(RID p_object) = 0;
|
||||
|
||||
/// Returns a customized navigation path using a query parameters object
|
||||
void query_path(const Ref<NavigationPathQueryParameters2D> &p_query_parameters, Ref<NavigationPathQueryResult2D> p_query_result) const;
|
||||
|
||||
virtual NavigationUtilities::PathQueryResult2D _query_path(const NavigationUtilities::PathQueryParameters2D &p_parameters) const = 0;
|
||||
|
||||
virtual void init();
|
||||
virtual void finish();
|
||||
|
||||
Navigation2DServer();
|
||||
virtual ~Navigation2DServer();
|
||||
|
||||
void set_debug_enabled(bool p_enabled);
|
||||
bool get_debug_enabled() const;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void set_debug_navigation_enabled(bool p_enabled);
|
||||
bool get_debug_navigation_enabled() const;
|
||||
|
||||
void set_debug_avoidance_enabled(bool p_enabled);
|
||||
bool get_debug_avoidance_enabled() const;
|
||||
|
||||
void set_debug_navigation_edge_connection_color(const Color &p_color);
|
||||
Color get_debug_navigation_edge_connection_color() const;
|
||||
|
||||
void set_debug_navigation_geometry_face_color(const Color &p_color);
|
||||
Color get_debug_navigation_geometry_face_color() const;
|
||||
|
||||
void set_debug_navigation_geometry_face_disabled_color(const Color &p_color);
|
||||
Color get_debug_navigation_geometry_face_disabled_color() const;
|
||||
|
||||
void set_debug_navigation_geometry_edge_color(const Color &p_color);
|
||||
Color get_debug_navigation_geometry_edge_color() const;
|
||||
|
||||
void set_debug_navigation_geometry_edge_disabled_color(const Color &p_color);
|
||||
Color get_debug_navigation_geometry_edge_disabled_color() const;
|
||||
|
||||
void set_debug_navigation_enable_edge_connections(const bool p_value);
|
||||
bool get_debug_navigation_enable_edge_connections() const;
|
||||
|
||||
void set_debug_navigation_enable_geometry_face_random_color(const bool p_value);
|
||||
bool get_debug_navigation_enable_geometry_face_random_color() const;
|
||||
|
||||
void set_debug_navigation_enable_edge_lines(const bool p_value);
|
||||
bool get_debug_navigation_enable_edge_lines() const;
|
||||
|
||||
void set_debug_navigation_link_connection_color(const Color &p_color);
|
||||
Color get_debug_navigation_link_connection_color() const;
|
||||
|
||||
void set_debug_navigation_link_connection_disabled_color(const Color &p_color);
|
||||
Color get_debug_navigation_link_connection_disabled_color() const;
|
||||
|
||||
void set_debug_navigation_agent_path_color(const Color &p_color);
|
||||
Color get_debug_navigation_agent_path_color() const;
|
||||
|
||||
void set_debug_navigation_enable_agent_paths(const bool p_value);
|
||||
bool get_debug_navigation_enable_agent_paths() const;
|
||||
|
||||
void set_debug_navigation_agent_path_point_size(float p_point_size);
|
||||
float get_debug_navigation_agent_path_point_size() const;
|
||||
|
||||
void set_debug_navigation_avoidance_enable_agents_radius(const bool p_value);
|
||||
bool get_debug_navigation_avoidance_enable_agents_radius() const;
|
||||
|
||||
void set_debug_navigation_avoidance_enable_obstacles_radius(const bool p_value);
|
||||
bool get_debug_navigation_avoidance_enable_obstacles_radius() const;
|
||||
|
||||
void set_debug_navigation_avoidance_agents_radius_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_agents_radius_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_obstacles_radius_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_obstacles_radius_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_static_obstacle_pushin_face_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_static_obstacle_pushin_face_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_static_obstacle_pushout_face_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_static_obstacle_pushout_face_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_static_obstacle_pushin_edge_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_static_obstacle_pushin_edge_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_static_obstacle_pushout_edge_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_static_obstacle_pushout_edge_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_enable_obstacles_static(const bool p_value);
|
||||
bool get_debug_navigation_avoidance_enable_obstacles_static() const;
|
||||
|
||||
private:
|
||||
void _emit_navigation_debug_changed_signal();
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef Navigation2DServer *(*CreateNavigation2DServerCallback)();
|
||||
|
||||
/// Manager used for the server singleton registration
|
||||
class Navigation2DServerManager {
|
||||
struct ClassInfo {
|
||||
String name;
|
||||
CreateNavigation2DServerCallback create_callback;
|
||||
|
||||
ClassInfo() :
|
||||
name(""),
|
||||
create_callback(nullptr) {}
|
||||
|
||||
ClassInfo(String p_name, CreateNavigation2DServerCallback p_create_callback) :
|
||||
name(p_name),
|
||||
create_callback(p_create_callback) {}
|
||||
|
||||
ClassInfo(const ClassInfo &p_ci) :
|
||||
name(p_ci.name),
|
||||
create_callback(p_ci.create_callback) {}
|
||||
|
||||
ClassInfo operator=(const ClassInfo &p_ci) {
|
||||
name = p_ci.name;
|
||||
create_callback = p_ci.create_callback;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
static Vector<ClassInfo> navigation_servers;
|
||||
static int default_server_id;
|
||||
static int default_server_priority;
|
||||
|
||||
public:
|
||||
static const String setting_property_name;
|
||||
|
||||
private:
|
||||
static void on_servers_changed();
|
||||
|
||||
public:
|
||||
static void register_server(const String &p_name, CreateNavigation2DServerCallback p_create_callback);
|
||||
static void set_default_server(const String &p_name, int p_priority = 0);
|
||||
static int find_server_id(const String &p_name);
|
||||
static int get_servers_count();
|
||||
static String get_server_name(int p_id);
|
||||
static Navigation2DServer *new_default_server();
|
||||
static Navigation2DServer *new_server(const String &p_name);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,637 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* navigation_server.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "navigation_server.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "navigation/navigation_path_query_parameters_3d.h"
|
||||
#include "navigation/navigation_path_query_result_3d.h"
|
||||
#include "scene/resources/navigation/navigation_mesh.h"
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
#include "core/config/engine.h"
|
||||
#include "core/config/project_settings.h"
|
||||
#include "scene/resources/material/material.h"
|
||||
#endif
|
||||
|
||||
NavigationServer *NavigationServer::singleton = nullptr;
|
||||
|
||||
void NavigationServer::init() {
|
||||
}
|
||||
|
||||
void NavigationServer::finish() {
|
||||
}
|
||||
|
||||
void NavigationServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_maps"), &NavigationServer::get_maps);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("map_create"), &NavigationServer::map_create);
|
||||
ClassDB::bind_method(D_METHOD("map_set_active", "map", "active"), &NavigationServer::map_set_active);
|
||||
ClassDB::bind_method(D_METHOD("map_is_active", "map"), &NavigationServer::map_is_active);
|
||||
ClassDB::bind_method(D_METHOD("map_set_up", "map", "up"), &NavigationServer::map_set_up);
|
||||
ClassDB::bind_method(D_METHOD("map_get_up", "map"), &NavigationServer::map_get_up);
|
||||
ClassDB::bind_method(D_METHOD("map_set_cell_size", "map", "cell_size"), &NavigationServer::map_set_cell_size);
|
||||
ClassDB::bind_method(D_METHOD("map_get_cell_size", "map"), &NavigationServer::map_get_cell_size);
|
||||
ClassDB::bind_method(D_METHOD("map_set_use_edge_connections", "map", "enabled"), &NavigationServer::map_set_use_edge_connections);
|
||||
ClassDB::bind_method(D_METHOD("map_get_use_edge_connections", "map"), &NavigationServer::map_get_use_edge_connections);
|
||||
ClassDB::bind_method(D_METHOD("map_set_cell_height", "map", "cell_height"), &NavigationServer::map_set_cell_height);
|
||||
ClassDB::bind_method(D_METHOD("map_get_cell_height", "map"), &NavigationServer::map_get_cell_height);
|
||||
ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &NavigationServer::map_set_edge_connection_margin);
|
||||
ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &NavigationServer::map_get_edge_connection_margin);
|
||||
ClassDB::bind_method(D_METHOD("map_set_link_connection_radius", "map", "radius"), &NavigationServer::map_set_link_connection_radius);
|
||||
ClassDB::bind_method(D_METHOD("map_get_link_connection_radius", "map"), &NavigationServer::map_get_link_connection_radius);
|
||||
ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "navigation_layers"), &NavigationServer::map_get_path, 1);
|
||||
ClassDB::bind_method(D_METHOD("map_get_closest_point_to_segment", "map", "start", "end", "use_collision"), &NavigationServer::map_get_closest_point_to_segment, false);
|
||||
ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &NavigationServer::map_get_closest_point);
|
||||
ClassDB::bind_method(D_METHOD("map_get_closest_point_normal", "map", "to_point"), &NavigationServer::map_get_closest_point_normal);
|
||||
ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer::map_get_closest_point_owner);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("map_get_links", "map"), &NavigationServer::map_get_links);
|
||||
ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer::map_get_regions);
|
||||
ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer::map_get_agents);
|
||||
ClassDB::bind_method(D_METHOD("map_get_obstacles", "map"), &NavigationServer::map_get_obstacles);
|
||||
ClassDB::bind_method(D_METHOD("map_force_update", "map"), &NavigationServer::map_force_update);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("query_path", "parameters", "result"), &NavigationServer::query_path);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer::region_create);
|
||||
ClassDB::bind_method(D_METHOD("region_set_enabled", "region", "enabled"), &NavigationServer::region_set_enabled);
|
||||
ClassDB::bind_method(D_METHOD("region_get_enabled", "region"), &NavigationServer::region_get_enabled);
|
||||
ClassDB::bind_method(D_METHOD("region_set_use_edge_connections", "region", "enabled"), &NavigationServer::region_set_use_edge_connections);
|
||||
ClassDB::bind_method(D_METHOD("region_get_use_edge_connections", "region"), &NavigationServer::region_get_use_edge_connections);
|
||||
ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer::region_set_enter_cost);
|
||||
ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer::region_get_enter_cost);
|
||||
ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &NavigationServer::region_set_travel_cost);
|
||||
ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &NavigationServer::region_get_travel_cost);
|
||||
ClassDB::bind_method(D_METHOD("region_set_owner_id", "region", "owner_id"), &NavigationServer::region_set_owner_id);
|
||||
ClassDB::bind_method(D_METHOD("region_get_owner_id", "region"), &NavigationServer::region_get_owner_id);
|
||||
ClassDB::bind_method(D_METHOD("region_owns_point", "region", "point"), &NavigationServer::region_owns_point);
|
||||
ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer::region_set_map);
|
||||
ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer::region_get_map);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("region_set_navigation_layers", "region", "navigation_layers"), &NavigationServer::region_set_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("region_get_navigation_layers", "region"), &NavigationServer::region_get_navigation_layers);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer::region_set_transform);
|
||||
ClassDB::bind_method(D_METHOD("region_set_navigation_mesh", "region", "navigation_mesh"), &NavigationServer::region_set_navigation_mesh);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("region_get_connections_count", "region"), &NavigationServer::region_get_connections_count);
|
||||
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &NavigationServer::region_get_connection_pathway_start);
|
||||
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &NavigationServer::region_get_connection_pathway_end);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("link_create"), &NavigationServer::link_create);
|
||||
ClassDB::bind_method(D_METHOD("link_set_map", "link", "map"), &NavigationServer::link_set_map);
|
||||
ClassDB::bind_method(D_METHOD("link_get_map", "link"), &NavigationServer::link_get_map);
|
||||
ClassDB::bind_method(D_METHOD("link_set_enabled", "link", "enabled"), &NavigationServer::link_set_enabled);
|
||||
ClassDB::bind_method(D_METHOD("link_get_enabled", "link"), &NavigationServer::link_get_enabled);
|
||||
ClassDB::bind_method(D_METHOD("link_set_bidirectional", "link", "bidirectional"), &NavigationServer::link_set_bidirectional);
|
||||
ClassDB::bind_method(D_METHOD("link_is_bidirectional", "link"), &NavigationServer::link_is_bidirectional);
|
||||
ClassDB::bind_method(D_METHOD("link_set_navigation_layers", "link", "navigation_layers"), &NavigationServer::link_set_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("link_get_navigation_layers", "link"), &NavigationServer::link_get_navigation_layers);
|
||||
ClassDB::bind_method(D_METHOD("link_set_start_position", "link", "position"), &NavigationServer::link_set_start_position);
|
||||
ClassDB::bind_method(D_METHOD("link_get_start_position", "link"), &NavigationServer::link_get_start_position);
|
||||
ClassDB::bind_method(D_METHOD("link_set_end_position", "link", "position"), &NavigationServer::link_set_end_position);
|
||||
ClassDB::bind_method(D_METHOD("link_get_end_position", "link"), &NavigationServer::link_get_end_position);
|
||||
ClassDB::bind_method(D_METHOD("link_set_enter_cost", "link", "enter_cost"), &NavigationServer::link_set_enter_cost);
|
||||
ClassDB::bind_method(D_METHOD("link_get_enter_cost", "link"), &NavigationServer::link_get_enter_cost);
|
||||
ClassDB::bind_method(D_METHOD("link_set_travel_cost", "link", "travel_cost"), &NavigationServer::link_set_travel_cost);
|
||||
ClassDB::bind_method(D_METHOD("link_get_travel_cost", "link"), &NavigationServer::link_get_travel_cost);
|
||||
ClassDB::bind_method(D_METHOD("link_set_owner_id", "link", "owner_id"), &NavigationServer::link_set_owner_id);
|
||||
ClassDB::bind_method(D_METHOD("link_get_owner_id", "link"), &NavigationServer::link_get_owner_id);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer::agent_create);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_avoidance_enabled", "agent", "enabled"), &NavigationServer::agent_set_avoidance_enabled);
|
||||
ClassDB::bind_method(D_METHOD("agent_get_avoidance_enabled", "agent"), &NavigationServer::agent_get_avoidance_enabled);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_use_3d_avoidance", "agent", "enabled"), &NavigationServer::agent_set_use_3d_avoidance);
|
||||
ClassDB::bind_method(D_METHOD("agent_get_use_3d_avoidance", "agent"), &NavigationServer::agent_get_use_3d_avoidance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer::agent_set_map);
|
||||
ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer::agent_get_map);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_paused", "agent", "paused"), &NavigationServer::agent_set_paused);
|
||||
ClassDB::bind_method(D_METHOD("agent_get_paused", "agent"), &NavigationServer::agent_get_paused);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_neighbor_distance", "agent", "dist"), &NavigationServer::agent_set_neighbor_distance);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &NavigationServer::agent_set_max_neighbors);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_time_horizon_agents", "agent", "time_horizon"), &NavigationServer::agent_set_time_horizon_agents);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_time_horizon_obstacles", "agent", "time_horizon"), &NavigationServer::agent_set_time_horizon_obstacles);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_radius", "agent", "radius"), &NavigationServer::agent_set_radius);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_height", "agent", "height"), &NavigationServer::agent_set_height);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_max_speed", "agent", "max_speed"), &NavigationServer::agent_set_max_speed);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_velocity_forced", "agent", "velocity"), &NavigationServer::agent_set_velocity_forced);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_velocity", "agent", "velocity"), &NavigationServer::agent_set_velocity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("agent_set_position", "agent", "position"), &NavigationServer::agent_set_position);
|
||||
ClassDB::bind_method(D_METHOD("agent_is_map_changed", "agent"), &NavigationServer::agent_is_map_changed);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_avoidance_callback", "agent", "object_id", "method", "userdata"), &NavigationServer::agent_set_avoidance_callback, DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("agent_set_avoidance_layers", "agent", "layers"), &NavigationServer::agent_set_avoidance_layers);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_avoidance_mask", "agent", "mask"), &NavigationServer::agent_set_avoidance_mask);
|
||||
ClassDB::bind_method(D_METHOD("agent_set_avoidance_priority", "agent", "priority"), &NavigationServer::agent_set_avoidance_priority);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("obstacle_create"), &NavigationServer::obstacle_create);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_avoidance_enabled", "obstacle", "enabled"), &NavigationServer::obstacle_set_avoidance_enabled);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_get_avoidance_enabled", "obstacle"), &NavigationServer::obstacle_get_avoidance_enabled);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_use_3d_avoidance", "obstacle", "enabled"), &NavigationServer::obstacle_set_use_3d_avoidance);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_get_use_3d_avoidance", "obstacle"), &NavigationServer::obstacle_get_use_3d_avoidance);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_map", "obstacle", "map"), &NavigationServer::obstacle_set_map);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_get_map", "obstacle"), &NavigationServer::obstacle_get_map);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_radius", "obstacle", "radius"), &NavigationServer::obstacle_set_radius);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_paused", "obstacle", "paused"), &NavigationServer::obstacle_set_paused);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_get_paused", "obstacle"), &NavigationServer::obstacle_get_paused);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_height", "obstacle", "height"), &NavigationServer::obstacle_set_height);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_velocity", "obstacle", "velocity"), &NavigationServer::obstacle_set_velocity);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_position", "obstacle", "position"), &NavigationServer::obstacle_set_position);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_vertices", "obstacle", "vertices"), &NavigationServer::obstacle_set_vertices);
|
||||
ClassDB::bind_method(D_METHOD("obstacle_set_avoidance_layers", "obstacle", "layers"), &NavigationServer::obstacle_set_avoidance_layers);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer::free);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_active", "active"), &NavigationServer::set_active);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &NavigationServer::get_process_info);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationServer::set_debug_enabled);
|
||||
ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationServer::get_debug_enabled);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map")));
|
||||
ADD_SIGNAL(MethodInfo("navigation_debug_changed"));
|
||||
ADD_SIGNAL(MethodInfo("avoidance_debug_changed"));
|
||||
|
||||
BIND_ENUM_CONSTANT(INFO_ACTIVE_MAPS);
|
||||
BIND_ENUM_CONSTANT(INFO_REGION_COUNT);
|
||||
BIND_ENUM_CONSTANT(INFO_AGENT_COUNT);
|
||||
BIND_ENUM_CONSTANT(INFO_LINK_COUNT);
|
||||
BIND_ENUM_CONSTANT(INFO_POLYGON_COUNT);
|
||||
BIND_ENUM_CONSTANT(INFO_EDGE_COUNT);
|
||||
BIND_ENUM_CONSTANT(INFO_EDGE_MERGE_COUNT);
|
||||
BIND_ENUM_CONSTANT(INFO_EDGE_CONNECTION_COUNT);
|
||||
BIND_ENUM_CONSTANT(INFO_EDGE_FREE_COUNT);
|
||||
|
||||
GLOBAL_DEF("navigation/avoidance/thread_model/avoidance_use_multiple_threads", true);
|
||||
GLOBAL_DEF("navigation/avoidance/thread_model/avoidance_use_high_priority_threads", true);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
ClassDB::bind_method(D_METHOD("_emit_navigation_debug_changed_signal"), &NavigationServer::_emit_navigation_debug_changed_signal);
|
||||
ClassDB::bind_method(D_METHOD("_emit_avoidance_debug_changed_signal"), &NavigationServer::_emit_avoidance_debug_changed_signal);
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
NavigationServer *NavigationServer::get_singleton() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
NavigationServer::NavigationServer() {
|
||||
ERR_FAIL_COND(singleton != nullptr);
|
||||
singleton = this;
|
||||
|
||||
GLOBAL_DEF("navigation/3d/use_edge_connections", true);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
_debug_enabled = false;
|
||||
_debug_dirty = true;
|
||||
|
||||
_debug_navigation_enabled = false;
|
||||
_navigation_debug_dirty = true;
|
||||
|
||||
_debug_avoidance_enabled = false;
|
||||
_avoidance_debug_dirty = true;
|
||||
|
||||
_debug_navigation_edge_connection_color = GLOBAL_DEF("debug/shapes/navigation/edge_connection_color", Color(1.0, 0.0, 1.0, 1.0));
|
||||
_debug_navigation_geometry_edge_color = GLOBAL_DEF("debug/shapes/navigation/geometry_edge_color", Color(0.5, 1.0, 1.0, 1.0));
|
||||
_debug_navigation_geometry_face_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_color", Color(0.5, 1.0, 1.0, 0.4));
|
||||
_debug_navigation_geometry_edge_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_edge_disabled_color", Color(0.5, 0.5, 0.5, 1.0));
|
||||
_debug_navigation_geometry_face_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_disabled_color", Color(0.5, 0.5, 0.5, 0.4));
|
||||
_debug_navigation_link_connection_color = GLOBAL_DEF("debug/shapes/navigation/link_connection_color", Color(1.0, 0.5, 1.0, 1.0));
|
||||
_debug_navigation_link_connection_disabled_color = GLOBAL_DEF("debug/shapes/navigation/link_connection_disabled_color", Color(0.5, 0.5, 0.5, 1.0));
|
||||
_debug_navigation_agent_path_color = GLOBAL_DEF("debug/shapes/navigation/agent_path_color", Color(1.0, 0.0, 0.0, 1.0));
|
||||
|
||||
_debug_navigation_enable_edge_connections = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections", true);
|
||||
_debug_navigation_enable_edge_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections_xray", true);
|
||||
_debug_navigation_enable_edge_lines = GLOBAL_DEF("debug/shapes/navigation/enable_edge_lines", true);
|
||||
_debug_navigation_enable_edge_lines_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_lines_xray", true);
|
||||
_debug_navigation_enable_geometry_face_random_color = GLOBAL_DEF("debug/shapes/navigation/enable_geometry_face_random_color", true);
|
||||
_debug_navigation_enable_link_connections = GLOBAL_DEF("debug/shapes/navigation/enable_link_connections", true);
|
||||
_debug_navigation_enable_link_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_link_connections_xray", true);
|
||||
|
||||
_debug_navigation_enable_agent_paths = GLOBAL_DEF("debug/shapes/navigation/enable_agent_paths", true);
|
||||
_debug_navigation_enable_agent_paths_xray = GLOBAL_DEF("debug/shapes/navigation/enable_agent_paths_xray", true);
|
||||
|
||||
_debug_navigation_agent_path_point_size = GLOBAL_DEF("debug/shapes/navigation/agent_path_point_size", 4.0);
|
||||
|
||||
_debug_navigation_avoidance_agents_radius_color = GLOBAL_DEF("debug/shapes/avoidance/agents_radius_color", Color(1.0, 1.0, 0.0, 0.25));
|
||||
_debug_navigation_avoidance_obstacles_radius_color = GLOBAL_DEF("debug/shapes/avoidance/obstacles_radius_color", Color(1.0, 0.5, 0.0, 0.25));
|
||||
_debug_navigation_avoidance_static_obstacle_pushin_face_color = GLOBAL_DEF("debug/shapes/avoidance/obstacles_static_face_pushin_color", Color(1.0, 0.0, 0.0, 0.0));
|
||||
_debug_navigation_avoidance_static_obstacle_pushin_edge_color = GLOBAL_DEF("debug/shapes/avoidance/obstacles_static_edge_pushin_color", Color(1.0, 0.0, 0.0, 1.0));
|
||||
_debug_navigation_avoidance_static_obstacle_pushout_face_color = GLOBAL_DEF("debug/shapes/avoidance/obstacles_static_face_pushout_color", Color(1.0, 1.0, 0.0, 0.5));
|
||||
_debug_navigation_avoidance_static_obstacle_pushout_edge_color = GLOBAL_DEF("debug/shapes/avoidance/obstacles_static_edge_pushout_color", Color(1.0, 1.0, 0.0, 1.0));
|
||||
_debug_navigation_avoidance_enable_agents_radius = GLOBAL_DEF("debug/shapes/avoidance/enable_agents_radius", true);
|
||||
_debug_navigation_avoidance_enable_obstacles_radius = GLOBAL_DEF("debug/shapes/avoidance/enable_obstacles_radius", true);
|
||||
_debug_navigation_avoidance_enable_obstacles_static = GLOBAL_DEF("debug/shapes/avoidance/enable_obstacles_static", true);
|
||||
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
// enable NavigationServer when in Editor or else navigation_mesh edge connections are invisible
|
||||
// on runtime tests SceneTree has "Visible Navigation" set and main iteration takes care of this
|
||||
set_debug_enabled(true);
|
||||
set_debug_navigation_enabled(true);
|
||||
set_debug_avoidance_enabled(true);
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
NavigationServer::~NavigationServer() {
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_enabled(bool p_enabled) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (_debug_enabled != p_enabled) {
|
||||
_debug_dirty = true;
|
||||
}
|
||||
|
||||
_debug_enabled = p_enabled;
|
||||
|
||||
if (_debug_dirty) {
|
||||
call_deferred("_emit_navigation_debug_changed_signal");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_enabled() const {
|
||||
#ifdef DEBUG_ENABLED
|
||||
return _debug_enabled;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void NavigationServer::_emit_navigation_debug_changed_signal() {
|
||||
if (_navigation_debug_dirty) {
|
||||
_navigation_debug_dirty = false;
|
||||
emit_signal("navigation_debug_changed");
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationServer::_emit_avoidance_debug_changed_signal() {
|
||||
if (_avoidance_debug_dirty) {
|
||||
_avoidance_debug_dirty = false;
|
||||
emit_signal("avoidance_debug_changed");
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void NavigationServer::set_debug_navigation_edge_connection_color(const Color &p_color) {
|
||||
_debug_navigation_edge_connection_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_edge_connection_color() const {
|
||||
return _debug_navigation_edge_connection_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_geometry_edge_color(const Color &p_color) {
|
||||
_debug_navigation_geometry_edge_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_geometry_edge_color() const {
|
||||
return _debug_navigation_geometry_edge_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_geometry_face_color(const Color &p_color) {
|
||||
_debug_navigation_geometry_face_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_geometry_face_color() const {
|
||||
return _debug_navigation_geometry_face_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_geometry_edge_disabled_color(const Color &p_color) {
|
||||
_debug_navigation_geometry_edge_disabled_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_geometry_edge_disabled_color() const {
|
||||
return _debug_navigation_geometry_edge_disabled_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_geometry_face_disabled_color(const Color &p_color) {
|
||||
_debug_navigation_geometry_face_disabled_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_geometry_face_disabled_color() const {
|
||||
return _debug_navigation_geometry_face_disabled_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_link_connection_color(const Color &p_color) {
|
||||
_debug_navigation_link_connection_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_link_connection_color() const {
|
||||
return _debug_navigation_link_connection_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_link_connection_disabled_color(const Color &p_color) {
|
||||
_debug_navigation_link_connection_disabled_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_link_connection_disabled_color() const {
|
||||
return _debug_navigation_link_connection_disabled_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_agent_path_point_size(float p_point_size) {
|
||||
_debug_navigation_agent_path_point_size = MAX(0.1, p_point_size);
|
||||
}
|
||||
|
||||
float NavigationServer::get_debug_navigation_agent_path_point_size() const {
|
||||
return _debug_navigation_agent_path_point_size;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_agent_path_color(const Color &p_color) {
|
||||
_debug_navigation_agent_path_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_agent_path_color() const {
|
||||
return _debug_navigation_agent_path_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_enable_edge_connections(const bool p_value) {
|
||||
_debug_navigation_enable_edge_connections = p_value;
|
||||
_navigation_debug_dirty = true;
|
||||
call_deferred("_emit_navigation_debug_changed_signal");
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_enable_edge_connections() const {
|
||||
return _debug_navigation_enable_edge_connections;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_enable_edge_connections_xray(const bool p_value) {
|
||||
_debug_navigation_enable_edge_connections_xray = p_value;
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_enable_edge_connections_xray() const {
|
||||
return _debug_navigation_enable_edge_connections_xray;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_enable_edge_lines(const bool p_value) {
|
||||
_debug_navigation_enable_edge_lines = p_value;
|
||||
_navigation_debug_dirty = true;
|
||||
call_deferred("_emit_navigation_debug_changed_signal");
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_enable_edge_lines() const {
|
||||
return _debug_navigation_enable_edge_lines;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_enable_edge_lines_xray(const bool p_value) {
|
||||
_debug_navigation_enable_edge_lines_xray = p_value;
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_enable_edge_lines_xray() const {
|
||||
return _debug_navigation_enable_edge_lines_xray;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_enable_geometry_face_random_color(const bool p_value) {
|
||||
_debug_navigation_enable_geometry_face_random_color = p_value;
|
||||
_navigation_debug_dirty = true;
|
||||
call_deferred("_emit_navigation_debug_changed_signal");
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_enable_geometry_face_random_color() const {
|
||||
return _debug_navigation_enable_geometry_face_random_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_enable_link_connections(const bool p_value) {
|
||||
_debug_navigation_enable_link_connections = p_value;
|
||||
_navigation_debug_dirty = true;
|
||||
call_deferred("_emit_navigation_debug_changed_signal");
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_enable_link_connections() const {
|
||||
return _debug_navigation_enable_link_connections;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_enable_link_connections_xray(const bool p_value) {
|
||||
_debug_navigation_enable_link_connections_xray = p_value;
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_enable_link_connections_xray() const {
|
||||
return _debug_navigation_enable_link_connections_xray;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_avoidance_enable_agents_radius(const bool p_value) {
|
||||
_debug_navigation_avoidance_enable_agents_radius = p_value;
|
||||
_avoidance_debug_dirty = true;
|
||||
call_deferred("_emit_avoidance_debug_changed_signal");
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_avoidance_enable_agents_radius() const {
|
||||
return _debug_navigation_avoidance_enable_agents_radius;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_avoidance_enable_obstacles_radius(const bool p_value) {
|
||||
_debug_navigation_avoidance_enable_obstacles_radius = p_value;
|
||||
_avoidance_debug_dirty = true;
|
||||
call_deferred("_emit_avoidance_debug_changed_signal");
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_avoidance_enable_obstacles_radius() const {
|
||||
return _debug_navigation_avoidance_enable_obstacles_radius;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_avoidance_enable_obstacles_static(const bool p_value) {
|
||||
_debug_navigation_avoidance_enable_obstacles_static = p_value;
|
||||
_avoidance_debug_dirty = true;
|
||||
call_deferred("_emit_avoidance_debug_changed_signal");
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_avoidance_enable_obstacles_static() const {
|
||||
return _debug_navigation_avoidance_enable_obstacles_static;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_avoidance_agents_radius_color(const Color &p_color) {
|
||||
_debug_navigation_avoidance_agents_radius_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_avoidance_agents_radius_color() const {
|
||||
return _debug_navigation_avoidance_agents_radius_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_avoidance_obstacles_radius_color(const Color &p_color) {
|
||||
_debug_navigation_avoidance_obstacles_radius_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_avoidance_obstacles_radius_color() const {
|
||||
return _debug_navigation_avoidance_obstacles_radius_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_avoidance_static_obstacle_pushin_face_color(const Color &p_color) {
|
||||
_debug_navigation_avoidance_static_obstacle_pushin_face_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_avoidance_static_obstacle_pushin_face_color() const {
|
||||
return _debug_navigation_avoidance_static_obstacle_pushin_face_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_avoidance_static_obstacle_pushout_face_color(const Color &p_color) {
|
||||
_debug_navigation_avoidance_static_obstacle_pushout_face_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_avoidance_static_obstacle_pushout_face_color() const {
|
||||
return _debug_navigation_avoidance_static_obstacle_pushout_face_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_avoidance_static_obstacle_pushin_edge_color(const Color &p_color) {
|
||||
_debug_navigation_avoidance_static_obstacle_pushin_edge_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_avoidance_static_obstacle_pushin_edge_color() const {
|
||||
return _debug_navigation_avoidance_static_obstacle_pushin_edge_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_avoidance_static_obstacle_pushout_edge_color(const Color &p_color) {
|
||||
_debug_navigation_avoidance_static_obstacle_pushout_edge_color = p_color;
|
||||
}
|
||||
|
||||
Color NavigationServer::get_debug_navigation_avoidance_static_obstacle_pushout_edge_color() const {
|
||||
return _debug_navigation_avoidance_static_obstacle_pushout_edge_color;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_enable_agent_paths(const bool p_value) {
|
||||
if (_debug_navigation_enable_agent_paths != p_value) {
|
||||
_debug_dirty = true;
|
||||
}
|
||||
|
||||
_debug_navigation_enable_agent_paths = p_value;
|
||||
|
||||
if (_debug_dirty) {
|
||||
call_deferred("_emit_navigation_debug_changed_signal");
|
||||
}
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_enable_agent_paths() const {
|
||||
return _debug_navigation_enable_agent_paths;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_enable_agent_paths_xray(const bool p_value) {
|
||||
_debug_navigation_enable_agent_paths_xray = p_value;
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_enable_agent_paths_xray() const {
|
||||
return _debug_navigation_enable_agent_paths_xray;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_navigation_enabled(bool p_enabled) {
|
||||
_debug_navigation_enabled = p_enabled;
|
||||
_navigation_debug_dirty = true;
|
||||
call_deferred("_emit_navigation_debug_changed_signal");
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_navigation_enabled() const {
|
||||
return _debug_navigation_enabled;
|
||||
}
|
||||
|
||||
void NavigationServer::set_debug_avoidance_enabled(bool p_enabled) {
|
||||
_debug_avoidance_enabled = p_enabled;
|
||||
_avoidance_debug_dirty = true;
|
||||
call_deferred("_emit_avoidance_debug_changed_signal");
|
||||
}
|
||||
|
||||
bool NavigationServer::get_debug_avoidance_enabled() const {
|
||||
return _debug_avoidance_enabled;
|
||||
}
|
||||
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
void NavigationServer::query_path(const Ref<NavigationPathQueryParameters3D> &p_query_parameters, Ref<NavigationPathQueryResult3D> p_query_result) const {
|
||||
ERR_FAIL_COND(!p_query_parameters.is_valid());
|
||||
ERR_FAIL_COND(!p_query_result.is_valid());
|
||||
|
||||
const NavigationUtilities::PathQueryResult _query_result = _query_path(p_query_parameters->get_parameters());
|
||||
|
||||
p_query_result->set_from_query_result(_query_result);
|
||||
}
|
||||
|
||||
Vector<NavigationServerManager::ClassInfo> NavigationServerManager::navigation_servers;
|
||||
int NavigationServerManager::default_server_id = -1;
|
||||
int NavigationServerManager::default_server_priority = -1;
|
||||
const String NavigationServerManager::setting_property_name("navigation/3d/navigation_engine");
|
||||
|
||||
void NavigationServerManager::on_servers_changed() {
|
||||
String navigation_servers2("DEFAULT");
|
||||
for (int i = get_servers_count() - 1; 0 <= i; --i) {
|
||||
navigation_servers2 += "," + get_server_name(i);
|
||||
}
|
||||
ProjectSettings::get_singleton()->set_custom_property_info(setting_property_name, PropertyInfo(Variant::STRING, setting_property_name, PROPERTY_HINT_ENUM, navigation_servers2));
|
||||
}
|
||||
|
||||
void NavigationServerManager::register_server(const String &p_name, CreateNavigationServerCallback p_creat_callback) {
|
||||
ERR_FAIL_COND(!p_creat_callback);
|
||||
ERR_FAIL_COND(find_server_id(p_name) != -1);
|
||||
navigation_servers.push_back(ClassInfo(p_name, p_creat_callback));
|
||||
on_servers_changed();
|
||||
}
|
||||
|
||||
void NavigationServerManager::set_default_server(const String &p_name, int p_priority) {
|
||||
const int id = find_server_id(p_name);
|
||||
ERR_FAIL_COND(id == -1); // Not found
|
||||
if (default_server_priority < p_priority) {
|
||||
default_server_id = id;
|
||||
default_server_priority = p_priority;
|
||||
}
|
||||
}
|
||||
|
||||
int NavigationServerManager::find_server_id(const String &p_name) {
|
||||
for (int i = navigation_servers.size() - 1; 0 <= i; --i) {
|
||||
if (p_name == navigation_servers[i].name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NavigationServerManager::get_servers_count() {
|
||||
return navigation_servers.size();
|
||||
}
|
||||
|
||||
String NavigationServerManager::get_server_name(int p_id) {
|
||||
ERR_FAIL_INDEX_V(p_id, get_servers_count(), "");
|
||||
return navigation_servers[p_id].name;
|
||||
}
|
||||
|
||||
NavigationServer *NavigationServerManager::new_default_server() {
|
||||
ERR_FAIL_COND_V(default_server_id == -1, nullptr);
|
||||
return navigation_servers[default_server_id].create_callback();
|
||||
}
|
||||
|
||||
NavigationServer *NavigationServerManager::new_server(const String &p_name) {
|
||||
int id = find_server_id(p_name);
|
||||
if (id == -1) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return navigation_servers[id].create_callback();
|
||||
}
|
||||
}
|
@ -1,515 +0,0 @@
|
||||
#ifndef NAVIGATION_SERVER_H
|
||||
#define NAVIGATION_SERVER_H
|
||||
/*************************************************************************/
|
||||
/* navigation_server.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "core/containers/rid.h"
|
||||
#include "core/object/object.h"
|
||||
|
||||
#include "navigation/navigation_utilities.h"
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
class NavigationMesh;
|
||||
class NavigationPathQueryParameters3D;
|
||||
class NavigationPathQueryResult3D;
|
||||
|
||||
/// This server uses the concept of internal mutability.
|
||||
/// All the constant functions can be called in multithread because internally
|
||||
/// the server takes care to schedule the functions access.
|
||||
///
|
||||
/// Note: All the `set` functions are commands executed during the `sync` phase,
|
||||
/// don't expect that a change is immediately propagated.
|
||||
class NavigationServer : public Object {
|
||||
GDCLASS(NavigationServer, Object);
|
||||
|
||||
static NavigationServer *singleton;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
static NavigationServer *get_singleton();
|
||||
|
||||
virtual Array get_maps() const = 0;
|
||||
|
||||
/// Create a new map.
|
||||
virtual RID map_create() = 0;
|
||||
|
||||
/// Set map active.
|
||||
virtual void map_set_active(RID p_map, bool p_active) = 0;
|
||||
|
||||
/// Returns true if the map is active.
|
||||
virtual bool map_is_active(RID p_map) const = 0;
|
||||
|
||||
/// Set the map UP direction.
|
||||
virtual void map_set_up(RID p_map, Vector3 p_up) = 0;
|
||||
|
||||
/// Returns the map UP direction.
|
||||
virtual Vector3 map_get_up(RID p_map) const = 0;
|
||||
|
||||
/// Set the map cell size used to weld the navigation mesh polygons.
|
||||
virtual void map_set_cell_size(RID p_map, real_t p_cell_size) = 0;
|
||||
|
||||
/// Returns the map cell size.
|
||||
virtual real_t map_get_cell_size(RID p_map) const = 0;
|
||||
|
||||
virtual void map_set_use_edge_connections(RID p_map, bool p_enabled) = 0;
|
||||
virtual bool map_get_use_edge_connections(RID p_map) const = 0;
|
||||
|
||||
/// Set the map cell height used to weld the navigation mesh polygons.
|
||||
virtual void map_set_cell_height(RID p_map, real_t p_cell_height) = 0;
|
||||
|
||||
/// Returns the map cell height.
|
||||
virtual real_t map_get_cell_height(RID p_map) const = 0;
|
||||
|
||||
/// Set the map edge connection margin used to weld the compatible region edges.
|
||||
virtual void map_set_edge_connection_margin(RID p_map, real_t p_connection_margin) = 0;
|
||||
|
||||
/// Returns the edge connection margin of this map.
|
||||
virtual real_t map_get_edge_connection_margin(RID p_map) const = 0;
|
||||
|
||||
/// Set the map link connection radius used to attach links to the nav mesh.
|
||||
virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) = 0;
|
||||
|
||||
/// Returns the link connection radius of this map.
|
||||
virtual real_t map_get_link_connection_radius(RID p_map) const = 0;
|
||||
|
||||
/// Returns the navigation path to reach the destination from the origin.
|
||||
virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const = 0;
|
||||
|
||||
virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const = 0;
|
||||
virtual Vector3 map_get_closest_point(RID p_map, const Vector3 &p_point) const = 0;
|
||||
virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const = 0;
|
||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const = 0;
|
||||
|
||||
virtual Array map_get_links(RID p_map) const = 0;
|
||||
virtual Array map_get_regions(RID p_map) const = 0;
|
||||
virtual Array map_get_agents(RID p_map) const = 0;
|
||||
virtual Array map_get_obstacles(RID p_map) const = 0;
|
||||
|
||||
virtual void map_force_update(RID p_map) = 0;
|
||||
|
||||
/// Creates a new region.
|
||||
virtual RID region_create() = 0;
|
||||
|
||||
virtual void region_set_enabled(RID p_region, bool p_enabled) = 0;
|
||||
virtual bool region_get_enabled(RID p_region) const = 0;
|
||||
|
||||
virtual void region_set_use_edge_connections(RID p_region, bool p_enabled) = 0;
|
||||
virtual bool region_get_use_edge_connections(RID p_region) const = 0;
|
||||
|
||||
/// Set the enter_cost of a region
|
||||
virtual void region_set_enter_cost(RID p_region, real_t p_enter_cost) = 0;
|
||||
virtual real_t region_get_enter_cost(RID p_region) const = 0;
|
||||
|
||||
/// Set the travel_cost of a region
|
||||
virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) = 0;
|
||||
virtual real_t region_get_travel_cost(RID p_region) const = 0;
|
||||
|
||||
/// Set the node which manages this region.
|
||||
virtual void region_set_owner_id(RID p_region, ObjectID p_owner_id) = 0;
|
||||
virtual ObjectID region_get_owner_id(RID p_region) const = 0;
|
||||
|
||||
virtual bool region_owns_point(RID p_region, const Vector3 &p_point) const = 0;
|
||||
|
||||
/// Set the map of this region.
|
||||
virtual void region_set_map(RID p_region, RID p_map) = 0;
|
||||
virtual RID region_get_map(RID p_region) const = 0;
|
||||
|
||||
/// Set the region's layers
|
||||
virtual void region_set_navigation_layers(RID p_region, uint32_t p_navigation_layers) = 0;
|
||||
virtual uint32_t region_get_navigation_layers(RID p_region) const = 0;
|
||||
|
||||
/// Set the global transformation of this region.
|
||||
virtual void region_set_transform(RID p_region, Transform p_transform) = 0;
|
||||
|
||||
/// Set the navigation mesh of this region.
|
||||
virtual void region_set_navigation_mesh(RID p_region, Ref<NavigationMesh> p_navigation_mesh) = 0;
|
||||
|
||||
/// Get a list of a region's connection to other regions.
|
||||
virtual int region_get_connections_count(RID p_region) const = 0;
|
||||
virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const = 0;
|
||||
virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const = 0;
|
||||
|
||||
/// Creates a new link between positions in the nav map.
|
||||
virtual RID link_create() = 0;
|
||||
|
||||
/// Set the map of this link.
|
||||
virtual void link_set_map(RID p_link, RID p_map) = 0;
|
||||
virtual RID link_get_map(RID p_link) const = 0;
|
||||
|
||||
virtual void link_set_enabled(RID p_link, bool p_enabled) = 0;
|
||||
virtual bool link_get_enabled(RID p_link) const = 0;
|
||||
|
||||
/// Set whether this link travels in both directions.
|
||||
virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) = 0;
|
||||
virtual bool link_is_bidirectional(RID p_link) const = 0;
|
||||
|
||||
/// Set the link's layers.
|
||||
virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) = 0;
|
||||
virtual uint32_t link_get_navigation_layers(RID p_link) const = 0;
|
||||
|
||||
/// Set the start position of the link.
|
||||
virtual void link_set_start_position(RID p_link, Vector3 p_position) = 0;
|
||||
virtual Vector3 link_get_start_position(RID p_link) const = 0;
|
||||
|
||||
/// Set the end position of the link.
|
||||
virtual void link_set_end_position(RID p_link, Vector3 p_position) = 0;
|
||||
virtual Vector3 link_get_end_position(RID p_link) const = 0;
|
||||
|
||||
/// Set the enter cost of the link.
|
||||
virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) = 0;
|
||||
virtual real_t link_get_enter_cost(RID p_link) const = 0;
|
||||
|
||||
/// Set the travel cost of the link.
|
||||
virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) = 0;
|
||||
virtual real_t link_get_travel_cost(RID p_link) const = 0;
|
||||
|
||||
/// Set the node which manages this link.
|
||||
virtual void link_set_owner_id(RID p_link, ObjectID p_owner_id) = 0;
|
||||
virtual ObjectID link_get_owner_id(RID p_link) const = 0;
|
||||
|
||||
/// Creates the agent.
|
||||
virtual RID agent_create() = 0;
|
||||
|
||||
/// Put the agent in the map.
|
||||
virtual void agent_set_map(RID p_agent, RID p_map) = 0;
|
||||
virtual RID agent_get_map(RID p_agent) const = 0;
|
||||
|
||||
virtual void agent_set_paused(RID p_agent, bool p_paused) = 0;
|
||||
virtual bool agent_get_paused(RID p_agent) const = 0;
|
||||
|
||||
virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) = 0;
|
||||
virtual bool agent_get_avoidance_enabled(RID p_agent) const = 0;
|
||||
|
||||
virtual void agent_set_use_3d_avoidance(RID p_agent, bool p_enabled) = 0;
|
||||
virtual bool agent_get_use_3d_avoidance(RID p_agent) const = 0;
|
||||
|
||||
/// The maximum distance (center point to
|
||||
/// center point) to other agents this agent
|
||||
/// takes into account in the navigation. The
|
||||
/// larger this number, the longer the running
|
||||
/// time of the simulation. If the number is too
|
||||
/// low, the simulation will not be safe.
|
||||
/// Must be non-negative.
|
||||
virtual void agent_set_neighbor_distance(RID p_agent, real_t p_dist) = 0;
|
||||
|
||||
/// The maximum number of other agents this
|
||||
/// agent takes into account in the navigation.
|
||||
/// The larger this number, the longer the
|
||||
/// running time of the simulation. If the
|
||||
/// number is too low, the simulation will not
|
||||
/// be safe.
|
||||
virtual void agent_set_max_neighbors(RID p_agent, int p_count) = 0;
|
||||
|
||||
// Sets the minimum amount of time in seconds that an agent's
|
||||
// must be able to stay on the calculated velocity while still avoiding collisions with agent's
|
||||
// if this value is set to high an agent will often fall back to using a very low velocity just to be safe
|
||||
virtual void agent_set_time_horizon_agents(RID p_agent, real_t p_time_horizon) = 0;
|
||||
|
||||
/// Sets the minimum amount of time in seconds that an agent's
|
||||
// must be able to stay on the calculated velocity while still avoiding collisions with obstacle's
|
||||
// if this value is set to high an agent will often fall back to using a very low velocity just to be safe
|
||||
virtual void agent_set_time_horizon_obstacles(RID p_agent, real_t p_time_horizon) = 0;
|
||||
|
||||
/// The radius of this agent.
|
||||
/// Must be non-negative.
|
||||
virtual void agent_set_radius(RID p_agent, real_t p_radius) = 0;
|
||||
virtual void agent_set_height(RID p_agent, real_t p_height) = 0;
|
||||
|
||||
/// The maximum speed of this agent.
|
||||
/// Must be non-negative.
|
||||
virtual void agent_set_max_speed(RID p_agent, real_t p_max_speed) = 0;
|
||||
|
||||
/// forces and agent velocity change in the avoidance simulation, adds simulation instability if done recklessly
|
||||
virtual void agent_set_velocity_forced(RID p_agent, Vector3 p_velocity) = 0;
|
||||
|
||||
/// The wanted velocity for the agent as a "suggestion" to the avoidance simulation.
|
||||
/// The simulation will try to fulfil this velocity wish if possible but may change the velocity depending on other agent's and obstacles'.
|
||||
virtual void agent_set_velocity(RID p_agent, Vector3 p_velocity) = 0;
|
||||
|
||||
/// Position of the agent in world space.
|
||||
virtual void agent_set_position(RID p_agent, Vector3 p_position) = 0;
|
||||
|
||||
/// Returns true if the map got changed the previous frame.
|
||||
virtual bool agent_is_map_changed(RID p_agent) const = 0;
|
||||
|
||||
/// Callback called at the end of the RVO process
|
||||
virtual void agent_set_avoidance_callback(RID p_agent, ObjectID p_object_id, StringName p_method, Variant p_udata = Variant()) = 0;
|
||||
|
||||
virtual void agent_set_avoidance_layers(RID p_agent, uint32_t p_layers) = 0;
|
||||
virtual void agent_set_avoidance_mask(RID p_agent, uint32_t p_mask) = 0;
|
||||
virtual void agent_set_avoidance_priority(RID p_agent, real_t p_priority) = 0;
|
||||
|
||||
/// Creates the obstacle.
|
||||
virtual RID obstacle_create() = 0;
|
||||
virtual void obstacle_set_map(RID p_obstacle, RID p_map) = 0;
|
||||
virtual RID obstacle_get_map(RID p_obstacle) const = 0;
|
||||
virtual void obstacle_set_avoidance_enabled(RID p_obstacle, bool p_enabled) = 0;
|
||||
virtual bool obstacle_get_avoidance_enabled(RID p_obstacle) const = 0;
|
||||
virtual void obstacle_set_use_3d_avoidance(RID p_obstacle, bool p_enabled) = 0;
|
||||
virtual bool obstacle_get_use_3d_avoidance(RID p_obstacle) const = 0;
|
||||
virtual void obstacle_set_radius(RID p_obstacle, real_t p_radius) = 0;
|
||||
virtual void obstacle_set_paused(RID p_obstacle, bool p_paused) = 0;
|
||||
virtual bool obstacle_get_paused(RID p_obstacle) const = 0;
|
||||
virtual void obstacle_set_height(RID p_obstacle, real_t p_height) = 0;
|
||||
virtual void obstacle_set_velocity(RID p_obstacle, Vector3 p_velocity) = 0;
|
||||
virtual void obstacle_set_position(RID p_obstacle, Vector3 p_position) = 0;
|
||||
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices) = 0;
|
||||
virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers) = 0;
|
||||
|
||||
/// Destroy the `RID`
|
||||
virtual void free(RID p_object) = 0;
|
||||
|
||||
/// Control activation of this server.
|
||||
virtual void set_active(bool p_active) = 0;
|
||||
|
||||
/// Process the collision avoidance agents.
|
||||
/// The result of this process is needed by the physics server,
|
||||
/// so this must be called in the main thread.
|
||||
/// Note: This function is not thread safe.
|
||||
virtual void process(real_t delta_time) = 0;
|
||||
|
||||
/// Returns a customized navigation path using a query parameters object
|
||||
void query_path(const Ref<NavigationPathQueryParameters3D> &p_query_parameters, Ref<NavigationPathQueryResult3D> p_query_result) const;
|
||||
|
||||
virtual NavigationUtilities::PathQueryResult _query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const = 0;
|
||||
|
||||
virtual void init();
|
||||
virtual void finish();
|
||||
|
||||
enum ProcessInfo {
|
||||
INFO_ACTIVE_MAPS,
|
||||
INFO_REGION_COUNT,
|
||||
INFO_AGENT_COUNT,
|
||||
INFO_LINK_COUNT,
|
||||
INFO_POLYGON_COUNT,
|
||||
INFO_EDGE_COUNT,
|
||||
INFO_EDGE_MERGE_COUNT,
|
||||
INFO_EDGE_CONNECTION_COUNT,
|
||||
INFO_EDGE_FREE_COUNT,
|
||||
};
|
||||
|
||||
virtual int get_process_info(ProcessInfo p_info) const = 0;
|
||||
|
||||
NavigationServer();
|
||||
virtual ~NavigationServer();
|
||||
|
||||
void set_debug_enabled(bool p_enabled);
|
||||
bool get_debug_enabled() const;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void set_debug_navigation_enabled(bool p_enabled);
|
||||
bool get_debug_navigation_enabled() const;
|
||||
|
||||
void set_debug_avoidance_enabled(bool p_enabled);
|
||||
bool get_debug_avoidance_enabled() const;
|
||||
|
||||
void set_debug_navigation_edge_connection_color(const Color &p_color);
|
||||
Color get_debug_navigation_edge_connection_color() const;
|
||||
|
||||
void set_debug_navigation_geometry_edge_color(const Color &p_color);
|
||||
Color get_debug_navigation_geometry_edge_color() const;
|
||||
|
||||
void set_debug_navigation_geometry_face_color(const Color &p_color);
|
||||
Color get_debug_navigation_geometry_face_color() const;
|
||||
|
||||
void set_debug_navigation_geometry_edge_disabled_color(const Color &p_color);
|
||||
Color get_debug_navigation_geometry_edge_disabled_color() const;
|
||||
|
||||
void set_debug_navigation_geometry_face_disabled_color(const Color &p_color);
|
||||
Color get_debug_navigation_geometry_face_disabled_color() const;
|
||||
|
||||
void set_debug_navigation_link_connection_color(const Color &p_color);
|
||||
Color get_debug_navigation_link_connection_color() const;
|
||||
|
||||
void set_debug_navigation_link_connection_disabled_color(const Color &p_color);
|
||||
Color get_debug_navigation_link_connection_disabled_color() const;
|
||||
|
||||
void set_debug_navigation_agent_path_color(const Color &p_color);
|
||||
Color get_debug_navigation_agent_path_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_agents_radius_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_agents_radius_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_obstacles_radius_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_obstacles_radius_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_static_obstacle_pushin_face_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_static_obstacle_pushin_face_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_static_obstacle_pushout_face_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_static_obstacle_pushout_face_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_static_obstacle_pushin_edge_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_static_obstacle_pushin_edge_color() const;
|
||||
|
||||
void set_debug_navigation_avoidance_static_obstacle_pushout_edge_color(const Color &p_color);
|
||||
Color get_debug_navigation_avoidance_static_obstacle_pushout_edge_color() const;
|
||||
|
||||
void set_debug_navigation_enable_edge_connections(const bool p_value);
|
||||
bool get_debug_navigation_enable_edge_connections() const;
|
||||
|
||||
void set_debug_navigation_enable_edge_connections_xray(const bool p_value);
|
||||
bool get_debug_navigation_enable_edge_connections_xray() const;
|
||||
|
||||
void set_debug_navigation_enable_edge_lines(const bool p_value);
|
||||
bool get_debug_navigation_enable_edge_lines() const;
|
||||
|
||||
void set_debug_navigation_enable_edge_lines_xray(const bool p_value);
|
||||
bool get_debug_navigation_enable_edge_lines_xray() const;
|
||||
|
||||
void set_debug_navigation_enable_geometry_face_random_color(const bool p_value);
|
||||
bool get_debug_navigation_enable_geometry_face_random_color() const;
|
||||
|
||||
void set_debug_navigation_enable_link_connections(const bool p_value);
|
||||
bool get_debug_navigation_enable_link_connections() const;
|
||||
|
||||
void set_debug_navigation_enable_link_connections_xray(const bool p_value);
|
||||
bool get_debug_navigation_enable_link_connections_xray() const;
|
||||
|
||||
void set_debug_navigation_enable_agent_paths(const bool p_value);
|
||||
bool get_debug_navigation_enable_agent_paths() const;
|
||||
|
||||
void set_debug_navigation_enable_agent_paths_xray(const bool p_value);
|
||||
bool get_debug_navigation_enable_agent_paths_xray() const;
|
||||
|
||||
void set_debug_navigation_agent_path_point_size(float p_point_size);
|
||||
float get_debug_navigation_agent_path_point_size() const;
|
||||
|
||||
void set_debug_navigation_avoidance_enable_agents_radius(const bool p_value);
|
||||
bool get_debug_navigation_avoidance_enable_agents_radius() const;
|
||||
|
||||
void set_debug_navigation_avoidance_enable_obstacles_radius(const bool p_value);
|
||||
bool get_debug_navigation_avoidance_enable_obstacles_radius() const;
|
||||
|
||||
void set_debug_navigation_avoidance_enable_obstacles_static(const bool p_value);
|
||||
bool get_debug_navigation_avoidance_enable_obstacles_static() const;
|
||||
|
||||
protected:
|
||||
bool _debug_enabled;
|
||||
bool _debug_dirty;
|
||||
|
||||
bool _debug_navigation_enabled;
|
||||
bool _navigation_debug_dirty;
|
||||
void _emit_navigation_debug_changed_signal();
|
||||
|
||||
bool _debug_avoidance_enabled;
|
||||
bool _avoidance_debug_dirty;
|
||||
void _emit_avoidance_debug_changed_signal();
|
||||
|
||||
Color _debug_navigation_edge_connection_color;
|
||||
Color _debug_navigation_geometry_edge_color;
|
||||
Color _debug_navigation_geometry_face_color;
|
||||
Color _debug_navigation_geometry_edge_disabled_color;
|
||||
Color _debug_navigation_geometry_face_disabled_color;
|
||||
Color _debug_navigation_link_connection_color;
|
||||
Color _debug_navigation_link_connection_disabled_color;
|
||||
Color _debug_navigation_agent_path_color;
|
||||
|
||||
float _debug_navigation_agent_path_point_size;
|
||||
|
||||
Color _debug_navigation_avoidance_agents_radius_color;
|
||||
Color _debug_navigation_avoidance_obstacles_radius_color;
|
||||
|
||||
Color _debug_navigation_avoidance_static_obstacle_pushin_face_color;
|
||||
Color _debug_navigation_avoidance_static_obstacle_pushout_face_color;
|
||||
Color _debug_navigation_avoidance_static_obstacle_pushin_edge_color;
|
||||
Color _debug_navigation_avoidance_static_obstacle_pushout_edge_color;
|
||||
|
||||
bool _debug_navigation_enable_edge_connections;
|
||||
bool _debug_navigation_enable_edge_connections_xray;
|
||||
bool _debug_navigation_enable_edge_lines;
|
||||
bool _debug_navigation_enable_edge_lines_xray;
|
||||
bool _debug_navigation_enable_geometry_face_random_color;
|
||||
bool _debug_navigation_enable_link_connections;
|
||||
bool _debug_navigation_enable_link_connections_xray;
|
||||
bool _debug_navigation_enable_agent_paths;
|
||||
bool _debug_navigation_enable_agent_paths_xray;
|
||||
|
||||
bool _debug_navigation_avoidance_enable_agents_radius;
|
||||
bool _debug_navigation_avoidance_enable_obstacles_radius;
|
||||
bool _debug_navigation_avoidance_enable_obstacles_static;
|
||||
|
||||
#endif // DEBUG_ENABLED
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(NavigationServer::ProcessInfo);
|
||||
|
||||
typedef NavigationServer *(*CreateNavigationServerCallback)();
|
||||
|
||||
/// Manager used for the server singleton registration
|
||||
|
||||
class NavigationServerManager {
|
||||
struct ClassInfo {
|
||||
String name;
|
||||
CreateNavigationServerCallback create_callback;
|
||||
|
||||
ClassInfo() :
|
||||
name(""),
|
||||
create_callback(nullptr) {}
|
||||
|
||||
ClassInfo(String p_name, CreateNavigationServerCallback p_create_callback) :
|
||||
name(p_name),
|
||||
create_callback(p_create_callback) {}
|
||||
|
||||
ClassInfo(const ClassInfo &p_ci) :
|
||||
name(p_ci.name),
|
||||
create_callback(p_ci.create_callback) {}
|
||||
|
||||
ClassInfo operator=(const ClassInfo &p_ci) {
|
||||
name = p_ci.name;
|
||||
create_callback = p_ci.create_callback;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
static Vector<ClassInfo> navigation_servers;
|
||||
static int default_server_id;
|
||||
static int default_server_priority;
|
||||
|
||||
public:
|
||||
static const String setting_property_name;
|
||||
|
||||
private:
|
||||
static void on_servers_changed();
|
||||
|
||||
public:
|
||||
static void register_server(const String &p_name, CreateNavigationServerCallback p_create_callback);
|
||||
static void set_default_server(const String &p_name, int p_priority = 0);
|
||||
static int find_server_id(const String &p_name);
|
||||
static int get_servers_count();
|
||||
static String get_server_name(int p_id);
|
||||
static NavigationServer *new_default_server();
|
||||
static NavigationServer *new_server(const String &p_name);
|
||||
};
|
||||
|
||||
#endif
|
@ -52,13 +52,6 @@
|
||||
#include "audio/effects/audio_effect_stereo_enhance.h"
|
||||
#include "audio/effects/audio_stream_generator.h"
|
||||
#include "audio_server.h"
|
||||
#include "navigation/navigation_mesh_generator.h"
|
||||
#include "navigation/navigation_path_query_parameters_2d.h"
|
||||
#include "navigation/navigation_path_query_parameters_3d.h"
|
||||
#include "navigation/navigation_path_query_result_2d.h"
|
||||
#include "navigation/navigation_path_query_result_3d.h"
|
||||
#include "navigation_2d_server.h"
|
||||
#include "navigation_server.h"
|
||||
#include "physics_2d/physics_2d_server_sw.h"
|
||||
#include "physics_2d/physics_2d_server_wrap_mt.h"
|
||||
#include "rendering/shader_types.h"
|
||||
@ -110,16 +103,6 @@ void register_server_types() {
|
||||
|
||||
ClassDB::register_virtual_class<Physics2DServer>();
|
||||
|
||||
ClassDB::register_virtual_class<NavigationServer>();
|
||||
ClassDB::register_virtual_class<Navigation2DServer>();
|
||||
//ClassDB::register_class<NavigationMeshGeneratorManager>();
|
||||
ClassDB::register_virtual_class<NavigationMeshGenerator>();
|
||||
|
||||
ClassDB::register_class<NavigationPathQueryParameters2D>();
|
||||
ClassDB::register_class<NavigationPathQueryParameters3D>();
|
||||
ClassDB::register_class<NavigationPathQueryResult2D>();
|
||||
ClassDB::register_class<NavigationPathQueryResult3D>();
|
||||
|
||||
shader_types = memnew(ShaderTypes);
|
||||
|
||||
ClassDB::register_virtual_class<AudioStream>();
|
||||
@ -186,18 +169,6 @@ void register_server_types() {
|
||||
|
||||
Physics2DServerManager::register_server("PandemoniumPhysics", &_createPandemoniumPhysics2DCallback);
|
||||
Physics2DServerManager::set_default_server("PandemoniumPhysics");
|
||||
|
||||
// Navigation
|
||||
GLOBAL_DEF(NavigationMeshGeneratorManager::setting_property_name, "DEFAULT");
|
||||
ProjectSettings::get_singleton()->set_custom_property_info(NavigationMeshGeneratorManager::setting_property_name, PropertyInfo(Variant::STRING, NavigationMeshGeneratorManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT"));
|
||||
|
||||
// Navigation 2D
|
||||
GLOBAL_DEF(Navigation2DServerManager::setting_property_name, "DEFAULT");
|
||||
ProjectSettings::get_singleton()->set_custom_property_info(Navigation2DServerManager::setting_property_name, PropertyInfo(Variant::STRING, Navigation2DServerManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT"));
|
||||
|
||||
// Navigation 3D
|
||||
GLOBAL_DEF(NavigationServerManager::setting_property_name, "DEFAULT");
|
||||
ProjectSettings::get_singleton()->set_custom_property_info(NavigationServerManager::setting_property_name, PropertyInfo(Variant::STRING, NavigationServerManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT"));
|
||||
}
|
||||
|
||||
void unregister_server_types() {
|
||||
@ -208,6 +179,4 @@ void register_server_singletons() {
|
||||
Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingServer", RenderingServer::get_singleton()));
|
||||
Engine::get_singleton()->add_singleton(Engine::Singleton("Physics2DServer", Physics2DServer::get_singleton()));
|
||||
Engine::get_singleton()->add_singleton(Engine::Singleton("AudioServer", AudioServer::get_singleton()));
|
||||
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer", NavigationServer::get_singleton()));
|
||||
Engine::get_singleton()->add_singleton(Engine::Singleton("Navigation2DServer", Navigation2DServer::get_singleton()));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user