diff --git a/doc/classes/Navigation2D.xml b/doc/classes/Navigation2D.xml deleted file mode 100644 index abac29bdb7a..00000000000 --- a/doc/classes/Navigation2D.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - 2D navigation and pathfinding node. - - - Navigation2D provides navigation and pathfinding within a 2D area, specified as a collection of [NavigationPolygon] resources. These are automatically collected from child [NavigationRegion2D] nodes. - - - https://godotengine.org/asset-library/asset/117 - - - - - - - - - Returns the point closest to the provided [code]to_point[/code] on the navigation mesh surface. - - - - - - - - - Returns the owner region RID for the point returned by [method get_closest_point]. - - - - - - - - - - - - - - - - - - - Returns the path between two given points. Points are in local coordinate space. If [code]optimize[/code] is [code]true[/code] (the default), the path is smoothed by merging path segments where possible. - - - - - - - - - - - - diff --git a/doc/classes/Navigation3D.xml b/doc/classes/Navigation3D.xml deleted file mode 100644 index e7a4fe3c432..00000000000 --- a/doc/classes/Navigation3D.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - Mesh-based navigation and pathfinding node. - - - Provides navigation and pathfinding within a collection of [NavigationMesh]es. These will be automatically collected from child [NavigationRegion3D] nodes. In addition to basic pathfinding, this class also assists with aligning navigation agents with the meshes they are navigating on. - - - https://godotengine.org/asset-library/asset/124 - - - - - - - - - Returns the point closest to the provided [code]to_point[/code] on the navigation mesh surface. - - - - - - - - - Returns the normal for the point returned by [method get_closest_point]. - - - - - - - - - Returns the owner region RID for the point returned by [method get_closest_point]. - - - - - - - - - - - - - Returns the closest point between the navigation surface and the segment. - - - - - - - - - - - - - - - - - - - Returns the path between two given points. Points are in local coordinate space. If [code]optimize[/code] is [code]true[/code] (the default), the agent properties associated with each [NavigationMesh] (radius, height, etc.) are considered in the path calculation, otherwise they are ignored. - - - - - - - - - - Defines which direction is up. By default, this is [code](0, 1, 0)[/code], which is the world's "up" direction. - - - - - diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml index 5a9c31ef67a..59bf06eaf26 100644 --- a/doc/classes/NavigationAgent2D.xml +++ b/doc/classes/NavigationAgent2D.xml @@ -4,7 +4,7 @@ 2D Agent used in navigation for collision avoidance. - 2D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. This can be done by having the agent as a child of a [Navigation2D] node, or using [method set_navigation]. [NavigationAgent2D] is physics safe. + 2D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. [NavigationAgent2D] is physics safe. @@ -37,13 +37,6 @@ Returns which index the agent is currently on in the navigation path's [PackedVector2Array]. - - - - - Returns the [Navigation2D] node that the agent is using for its navigation system. - - @@ -79,15 +72,6 @@ Returns true if the target location is reached. The target location is set using [method set_target_location]. It may not always be possible to reach the target location. It should always be possible to reach the final location though. See [method get_final_location]. - - - - - - - Sets the [Navigation2D] node used by the agent. Useful when you don't want to make the agent a child of a [Navigation2D] node. - - diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml index f9df1d390b6..7a130e9591f 100644 --- a/doc/classes/NavigationAgent3D.xml +++ b/doc/classes/NavigationAgent3D.xml @@ -4,7 +4,7 @@ 3D Agent used in navigation for collision avoidance. - 3D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. This can be done by having the agent as a child of a [Navigation3D] node, or using [method set_navigation]. [NavigationAgent3D] is physics safe. + 3D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. [NavigationAgent3D] is physics safe. @@ -37,13 +37,6 @@ Returns which index the agent is currently on in the navigation path's [PackedVector3Array]. - - - - - Returns the [Navigation3D] node that the agent is using for its navigation system. - - @@ -79,15 +72,6 @@ Returns true if the target location is reached. The target location is set using [method set_target_location]. It may not always be possible to reach the target location. It should always be possible to reach the final location though. See [method get_final_location]. - - - - - - - Sets the [Navigation3D] node used by the agent. Useful when you don't want to make the agent a child of a [Navigation3D] node. - - diff --git a/doc/classes/NavigationObstacle2D.xml b/doc/classes/NavigationObstacle2D.xml index ddd96975f16..2e94eb0bbaa 100644 --- a/doc/classes/NavigationObstacle2D.xml +++ b/doc/classes/NavigationObstacle2D.xml @@ -4,27 +4,11 @@ 2D Obstacle used in navigation for collision avoidance. - 2D Obstacle used in navigation for collision avoidance. The obstacle needs navigation data to work correctly. This can be done by having the obstacle as a child of a [Navigation2D] node, or using [method set_navigation]. [NavigationObstacle2D] is physics safe. + 2D Obstacle used in navigation for collision avoidance. The obstacle needs navigation data to work correctly. [NavigationObstacle2D] is physics safe. - - - - - Returns the [Navigation2D] node that the obstacle is using for its navigation system. - - - - - - - - - Sets the [Navigation2D] node used by the obstacle. Useful when you don't want to make the obstacle a child of a [Navigation2D] node. - - diff --git a/doc/classes/NavigationObstacle3D.xml b/doc/classes/NavigationObstacle3D.xml index e01a40ed73a..d7454a7bea9 100644 --- a/doc/classes/NavigationObstacle3D.xml +++ b/doc/classes/NavigationObstacle3D.xml @@ -4,27 +4,11 @@ 3D Obstacle used in navigation for collision avoidance. - 3D Obstacle used in navigation for collision avoidance. The obstacle needs navigation data to work correctly. This can be done by having the obstacle as a child of a [Navigation3D] node, or using [method set_navigation]. [NavigationObstacle3D] is physics safe. + 3D Obstacle used in navigation for collision avoidance. The obstacle needs navigation data to work correctly. [NavigationObstacle3D] is physics safe. - - - - - Returns the [Navigation3D] node that the obstacle is using for its navigation system. - - - - - - - - - Sets the [Navigation3D] node used by the obstacle. Useful when you don't want to make the obstacle a child of a [Navigation3D] node. - - diff --git a/doc/classes/NavigationRegion3D.xml b/doc/classes/NavigationRegion3D.xml index b70bfb6596c..e48c326ad7c 100644 --- a/doc/classes/NavigationRegion3D.xml +++ b/doc/classes/NavigationRegion3D.xml @@ -4,7 +4,7 @@ A region of the navigation map. - A region of the navigation map. It tells the [Navigation3D] node what can be navigated and what cannot, based on the [NavigationMesh] resource. This should be a child of a [Navigation3D] node (even not a direct child). + A region of the navigation map. It tells the [NavigationServer3D] what can be navigated and what cannot, based on its [NavigationMesh] resource. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index bdf01a3dcf8..f551022437e 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1020,6 +1020,14 @@ + + + + + + + + Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection. diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index c0ee004ca63..7ed8ad6d4a2 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -272,6 +272,9 @@ + + If [code]true[/code], this TileMap bakes a navigation region. + If [code]true[/code], the cell's UVs will be clipped. diff --git a/doc/classes/World2D.xml b/doc/classes/World2D.xml index 25033cdb096..20b3afbd0b8 100644 --- a/doc/classes/World2D.xml +++ b/doc/classes/World2D.xml @@ -18,6 +18,9 @@ Direct access to the world's physics 2D space state. Used for querying current and potential collisions. When using multi-threaded physics, access is limited to [code]_physics_process(delta)[/code] in the main thread. + + The [RID] of this world's navigation map. Used by the [NavigationServer2D]. + The [RID] of this world's physics space resource. Used by the [PhysicsServer2D] for 2D physics, treating it as both a space and an area. diff --git a/doc/classes/World3D.xml b/doc/classes/World3D.xml index fe920774325..610ecacff42 100644 --- a/doc/classes/World3D.xml +++ b/doc/classes/World3D.xml @@ -23,6 +23,9 @@ The World3D's fallback_environment will be used if the World3D's [Environment] fails or is missing. + + The [RID] of this world's navigation map. Used by the [NavigationServer3D]. + The World3D's visual scenario. diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index d0e57980450..14ecccc13e6 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -35,7 +35,7 @@ #include "editor/import/scene_importer_mesh_node_3d.h" #include "scene/3d/collision_shape_3d.h" #include "scene/3d/mesh_instance_3d.h" -#include "scene/3d/navigation_3d.h" +#include "scene/3d/navigation_region_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/3d/vehicle_body_3d.h" #include "scene/animation/animation_player.h" diff --git a/modules/gdnavigation/nav_region.h b/modules/gdnavigation/nav_region.h index 954780033b3..3095435359e 100644 --- a/modules/gdnavigation/nav_region.h +++ b/modules/gdnavigation/nav_region.h @@ -31,10 +31,10 @@ #ifndef NAV_REGION_H #define NAV_REGION_H -#include "nav_rid.h" +#include "scene/resources/navigation_mesh.h" +#include "nav_rid.h" #include "nav_utils.h" -#include "scene/3d/navigation_3d.h" #include /** diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index e28cc57f9bf..6af371fbe4f 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -184,6 +184,9 @@ + + If [code]true[/code], this GridMap bakes a navigation region. + If [code]true[/code], grid items are centered on the X axis. diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index e7c252dc538..4c99c8f133b 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -179,6 +179,15 @@ bool GridMap::get_collision_layer_bit(int p_bit) const { return get_collision_layer() & (1 << p_bit); } +void GridMap::set_bake_navigation(bool p_bake_navigation) { + bake_navigation = p_bake_navigation; + _recreate_octant_data(); +} + +bool GridMap::is_baking_navigation() { + return bake_navigation; +} + void GridMap::set_mesh_library(const Ref &p_mesh_library) { if (!mesh_library.is_null()) { mesh_library->unregister_owner(this); @@ -474,13 +483,14 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Octant::NavMesh nm; nm.xform = xform * mesh_library->get_item_navmesh_transform(c.item); - if (navigation) { + if (bake_navigation) { RID region = NavigationServer3D::get_singleton()->region_create(); NavigationServer3D::get_singleton()->region_set_navmesh(region, navmesh); - NavigationServer3D::get_singleton()->region_set_transform(region, navigation->get_global_transform() * nm.xform); - NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid()); + NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * mesh_library->get_item_navmesh_transform(c.item)); + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); nm.region = region; } + g.navmesh_ids[E->get()] = nm; } } @@ -564,15 +574,16 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform()); } - if (navigation && mesh_library.is_valid()) { + if (bake_navigation && mesh_library.is_valid()) { for (Map::Element *F = g.navmesh_ids.front(); F; F = F->next()) { if (cell_map.has(F->key()) && F->get().region.is_valid() == false) { Ref nm = mesh_library->get_item_navmesh(cell_map[F->key()].item); if (nm.is_valid()) { RID region = NavigationServer3D::get_singleton()->region_create(); NavigationServer3D::get_singleton()->region_set_navmesh(region, nm); - NavigationServer3D::get_singleton()->region_set_transform(region, navigation->get_global_transform() * F->get().xform); - NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid()); + NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * F->get().xform); + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); + F->get().region = region; } } @@ -594,12 +605,10 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) { RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, RID()); } - if (navigation) { - for (Map::Element *F = g.navmesh_ids.front(); F; F = F->next()) { - if (F->get().region.is_valid()) { - NavigationServer3D::get_singleton()->free(F->get().region); - F->get().region = RID(); - } + for (Map::Element *F = g.navmesh_ids.front(); F; F = F->next()) { + if (F->get().region.is_valid()) { + NavigationServer3D::get_singleton()->free(F->get().region); + F->get().region = RID(); } } } @@ -635,16 +644,6 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) { void GridMap::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { - Node3D *c = this; - while (c) { - navigation = Object::cast_to(c); - if (navigation) { - break; - } - - c = Object::cast_to(c->get_parent()); - } - last_transform = get_global_transform(); for (Map::Element *E = octant_map.front(); E; E = E->next()) { @@ -679,8 +678,6 @@ void GridMap::_notification(int p_what) { _octant_exit_world(E->key()); } - navigation = nullptr; - //_queue_octants_dirty(MAP_DIRTY_INSTANCES|MAP_DIRTY_TRANSFORMS); //_update_octants_callback(); //_update_area_instances(); @@ -785,6 +782,9 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &GridMap::set_collision_layer_bit); ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &GridMap::get_collision_layer_bit); + ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &GridMap::set_bake_navigation); + ClassDB::bind_method(D_METHOD("is_baking_navigation"), &GridMap::is_baking_navigation); + ClassDB::bind_method(D_METHOD("set_mesh_library", "mesh_library"), &GridMap::set_mesh_library); ClassDB::bind_method(D_METHOD("get_mesh_library"), &GridMap::get_mesh_library); @@ -838,6 +838,8 @@ void GridMap::_bind_methods() { ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); + ADD_GROUP("Navigation", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation"); BIND_CONSTANT(INVALID_CELL_ITEM); diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index e5ec4bb602b..c485afd58ae 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -31,7 +31,6 @@ #ifndef GRID_MAP_H #define GRID_MAP_H -#include "scene/3d/navigation_3d.h" #include "scene/3d/node_3d.h" #include "scene/resources/mesh_library.h" #include "scene/resources/multimesh.h" @@ -135,6 +134,7 @@ class GridMap : public Node3D { uint32_t collision_layer = 1; uint32_t collision_mask = 1; + bool bake_navigation = false; Transform last_transform; @@ -145,7 +145,6 @@ class GridMap : public Node3D { bool center_y = true; bool center_z = true; float cell_scale = 1.0; - Navigation3D *navigation = nullptr; bool clip = false; bool clip_above = true; @@ -223,6 +222,9 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; + void set_bake_navigation(bool p_bake_navigation); + bool is_baking_navigation(); + void set_mesh_library(const Ref &p_mesh_library); Ref get_mesh_library() const; diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp deleted file mode 100644 index bec5ee7984d..00000000000 --- a/scene/2d/navigation_2d.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************/ -/* navigation_2d.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 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 "servers/navigation_server_2d.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); - - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin"); -} - -void Navigation2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_READY: { - NavigationServer2D::get_singleton()->map_set_active(map, true); - } break; - case NOTIFICATION_EXIT_TREE: { - NavigationServer2D::get_singleton()->map_set_active(map, false); - } break; - } -} - -void Navigation2D::set_cell_size(float p_cell_size) { - cell_size = p_cell_size; - NavigationServer2D::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; - NavigationServer2D::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin); -} - -Vector Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) const { - return NavigationServer2D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize); -} - -Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) const { - return NavigationServer2D::get_singleton()->map_get_closest_point(map, p_point); -} - -RID Navigation2D::get_closest_point_owner(const Vector2 &p_point) const { - return NavigationServer2D::get_singleton()->map_get_closest_point_owner(map, p_point); -} - -Navigation2D::Navigation2D() { - map = NavigationServer2D::get_singleton()->map_create(); - set_cell_size(10); // Ten pixels - set_edge_connection_margin(100); -} - -Navigation2D::~Navigation2D() { - NavigationServer2D::get_singleton()->free(map); -} diff --git a/scene/2d/navigation_2d.h b/scene/2d/navigation_2d.h deleted file mode 100644 index 12847e52acd..00000000000 --- a/scene/2d/navigation_2d.h +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************/ -/* navigation_2d.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 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. */ -/*************************************************************************/ - -#ifndef NAVIGATION_2D_H -#define NAVIGATION_2D_H - -#include "scene/2d/navigation_region_2d.h" -#include "scene/2d/node_2d.h" - -class Navigation2D : public Node2D { - GDCLASS(Navigation2D, Node2D); - - RID map; - real_t cell_size; - real_t edge_connection_margin; - -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_edge_connection_margin(float p_edge_connection_margin); - float get_edge_connection_margin() const { - return edge_connection_margin; - } - - Vector 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 diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 534e31b1f22..2319a1413c7 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -32,7 +32,6 @@ #include "core/config/engine.h" #include "core/math/geometry_2d.h" -#include "scene/2d/navigation_2d.h" #include "servers/navigation_server_2d.h" void NavigationAgent2D::_bind_methods() { @@ -42,9 +41,6 @@ void NavigationAgent2D::_bind_methods() { 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_dist", "neighbor_dist"), &NavigationAgent2D::set_neighbor_dist); ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent2D::get_neighbor_dist); @@ -95,27 +91,10 @@ void NavigationAgent2D::_notification(int p_what) { NavigationServer2D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done"); - // Search the navigation node and set it - { - Navigation2D *nav = nullptr; - Node *p = get_parent(); - while (p != nullptr) { - nav = Object::cast_to(p); - if (nav != nullptr) { - p = nullptr; - } else { - p = p->get_parent(); - } - } - - set_navigation(nav); - } - set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { agent_parent = nullptr; - set_navigation(nullptr); set_physics_process_internal(false); } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { @@ -146,25 +125,6 @@ NavigationAgent2D::~NavigationAgent2D() { agent = RID(); // Pointless } -void NavigationAgent2D::set_navigation(Navigation2D *p_nav) { - if (navigation == p_nav) { - return; // Pointless - } - - navigation = p_nav; - NavigationServer2D::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(p_nav); - ERR_FAIL_COND(nav == nullptr); - set_navigation(nav); -} - -Node *NavigationAgent2D::get_navigation_node() const { - return Object::cast_to(navigation); -} - void NavigationAgent2D::set_target_desired_distance(real_t p_dd) { target_desired_distance = p_dd; } @@ -287,7 +247,7 @@ void NavigationAgent2D::update_navigation() { if (agent_parent == nullptr) { return; } - if (navigation == nullptr) { + if (!agent_parent->is_inside_tree()) { return; } if (update_frame_id == Engine::get_singleton()->get_physics_frames()) { @@ -319,7 +279,7 @@ void NavigationAgent2D::update_navigation() { } if (reload_path) { - navigation_path = NavigationServer2D::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true); + navigation_path = NavigationServer2D::get_singleton()->map_get_path(agent_parent->get_world_2d()->get_navigation_map(), o, target_location, true); navigation_finished = false; nav_path_index = 0; emit_signal("path_changed"); diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 6b7da4a5f2b..2debed65a54 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -35,13 +35,11 @@ #include "scene/main/node.h" class Node2D; -class Navigation2D; class NavigationAgent2D : public Node { GDCLASS(NavigationAgent2D, Node); Node2D *agent_parent = nullptr; - Navigation2D *navigation = nullptr; RID agent; @@ -74,14 +72,6 @@ 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; } diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index 7e1aefe5e2e..965e2b6dc1e 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -31,48 +31,31 @@ #include "navigation_obstacle_2d.h" #include "scene/2d/collision_shape_2d.h" -#include "scene/2d/navigation_2d.h" #include "scene/2d/physics_body_2d.h" #include "servers/navigation_server_2d.h" void NavigationObstacle2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle2D::set_navigation_node); - ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle2D::get_navigation_node); } void NavigationObstacle2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { - update_agent_shape(); - - // Search the navigation node and set it - { - Navigation2D *nav = nullptr; - Node *p = get_parent(); - while (p != nullptr) { - nav = Object::cast_to(p); - if (nav != nullptr) { - p = nullptr; - } else { - p = p->get_parent(); - } - } - - set_navigation(nav); - } - set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { - set_navigation(nullptr); set_physics_process_internal(false); } break; + case NOTIFICATION_PARENTED: { + parent_node2d = Object::cast_to(get_parent()); + update_agent_shape(); + } break; + case NOTIFICATION_UNPARENTED: { + parent_node2d = nullptr; + } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - Node2D *node = Object::cast_to(get_parent()); - if (node) { - NavigationServer2D::get_singleton()->agent_set_position(agent, node->get_global_transform().get_origin()); + if (parent_node2d) { + NavigationServer2D::get_singleton()->agent_set_position(agent, parent_node2d->get_global_transform().get_origin()); } - } break; } } @@ -86,25 +69,6 @@ NavigationObstacle2D::~NavigationObstacle2D() { agent = RID(); // Pointless } -void NavigationObstacle2D::set_navigation(Navigation2D *p_nav) { - if (navigation == p_nav) { - return; // Pointless - } - - navigation = p_nav; - NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid()); -} - -void NavigationObstacle2D::set_navigation_node(Node *p_nav) { - Navigation2D *nav = Object::cast_to(p_nav); - ERR_FAIL_COND(nav == nullptr); - set_navigation(nav); -} - -Node *NavigationObstacle2D::get_navigation_node() const { - return Object::cast_to(navigation); -} - String NavigationObstacle2D::get_configuration_warning() const { String warning = Node::get_configuration_warning(); @@ -119,40 +83,37 @@ String NavigationObstacle2D::get_configuration_warning() const { } void NavigationObstacle2D::update_agent_shape() { - Node *node = get_parent(); - - // Estimate the radius of this physics body - real_t radius = 0.0; - for (int i(0); i < node->get_child_count(); i++) { - // For each collision shape - CollisionShape2D *cs = Object::cast_to(node->get_child(i)); - if (cs) { - // Take the distance between the Body center to the shape center - real_t r = cs->get_transform().get_origin().length(); - if (cs->get_shape().is_valid()) { - // and add the enclosing shape radius - r += cs->get_shape()->get_enclosing_radius(); + if (parent_node2d) { + // Estimate the radius of this physics body + real_t radius = 0.0; + for (int i(0); i < parent_node2d->get_child_count(); i++) { + // For each collision shape + CollisionShape2D *cs = Object::cast_to(parent_node2d->get_child(i)); + if (cs) { + // Take the distance between the Body center to the shape center + real_t r = cs->get_transform().get_origin().length(); + if (cs->get_shape().is_valid()) { + // and add the enclosing shape radius + r += cs->get_shape()->get_enclosing_radius(); + } + Size2 s = cs->get_global_transform().get_scale(); + r *= MAX(s.x, s.y); + // Takes the biggest radius + radius = MAX(radius, r); } - Size2 s = cs->get_global_transform().get_scale(); - r *= MAX(s.x, s.y); - // Takes the biggest radius - radius = MAX(radius, r); } - } - Node2D *node_2d = Object::cast_to(node); - if (node_2d) { - Vector2 s = node_2d->get_global_transform().get_scale(); + Vector2 s = parent_node2d->get_global_transform().get_scale(); radius *= MAX(s.x, s.y); - } - if (radius == 0.0) { - radius = 1.0; // Never a 0 radius - } + if (radius == 0.0) { + radius = 1.0; // Never a 0 radius + } - // Initialize the Agent as an object - NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0); - NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0); - NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0); - NavigationServer2D::get_singleton()->agent_set_radius(agent, radius); - NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0); + // Initialize the Agent as an object + NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0); + NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0); + NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0); + NavigationServer2D::get_singleton()->agent_set_radius(agent, radius); + NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0); + } } diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h index 421f8ca7cd5..135ca4651eb 100644 --- a/scene/2d/navigation_obstacle_2d.h +++ b/scene/2d/navigation_obstacle_2d.h @@ -31,15 +31,13 @@ #ifndef NAVIGATION_OBSTACLE_2D_H #define NAVIGATION_OBSTACLE_2D_H +#include "scene/2d/node_2d.h" #include "scene/main/node.h" -class Navigation2D; - class NavigationObstacle2D : public Node { GDCLASS(NavigationObstacle2D, Node); - Navigation2D *navigation = nullptr; - + Node2D *parent_node2d = nullptr; RID agent; protected: @@ -50,14 +48,6 @@ 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 agent; } diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index b02cdf12ad1..779dbe4b119 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -34,7 +34,6 @@ #include "core/core_string_names.h" #include "core/math/geometry_2d.h" #include "core/os/mutex.h" -#include "navigation_2d.h" #include "servers/navigation_server_2d.h" #include "thirdparty/misc/polypartition.h" @@ -366,9 +365,7 @@ void NavigationRegion2D::set_enabled(bool p_enabled) { if (!enabled) { NavigationServer2D::get_singleton()->region_set_map(region, RID()); } else { - if (navigation) { - NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid()); - } + NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map()); } if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) { @@ -394,29 +391,15 @@ bool NavigationRegion2D::_edit_is_selected_on_click(const Point2 &p_point, doubl void NavigationRegion2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - Node2D *c = this; - while (c) { - navigation = Object::cast_to(c); - if (navigation) { - if (enabled) { - NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid()); - } - break; - } - - c = Object::cast_to(c->get_parent()); + if (enabled) { + NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map()); } - } break; case NOTIFICATION_TRANSFORM_CHANGED: { NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform()); - } break; case NOTIFICATION_EXIT_TREE: { - if (navigation) { - NavigationServer2D::get_singleton()->region_set_map(region, RID()); - } - navigation = nullptr; + NavigationServer2D::get_singleton()->region_set_map(region, RID()); } break; case NOTIFICATION_DRAW: { if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) { @@ -507,18 +490,8 @@ String NavigationRegion2D::get_configuration_warning() const { } warning += TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon."); } - const Node2D *c = this; - while (c) { - if (Object::cast_to(c)) { - return warning; - } - c = Object::cast_to(c->get_parent()); - } - if (!warning.is_empty()) { - warning += "\n\n"; - } - return warning + TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data."); + return warning; } void NavigationRegion2D::_bind_methods() { diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index 0b9a258a25b..25a886b4461 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -91,14 +91,11 @@ public: ~NavigationPolygon() {} }; -class Navigation2D; - class NavigationRegion2D : public Node2D { GDCLASS(NavigationRegion2D, Node2D); bool enabled = true; RID region; - Navigation2D *navigation = nullptr; Ref navpoly; void _navpoly_changed(); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index d868ebae254..81a5b0b28c4 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -48,16 +48,6 @@ int TileMap::_get_quadrant_size() const { void TileMap::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - Node2D *c = this; - while (c) { - navigation = Object::cast_to(c); - if (navigation) { - break; - } - - c = Object::cast_to(c->get_parent()); - } - if (use_parent) { _clear_quadrants(); collision_parent = Object::cast_to(get_parent()); @@ -77,12 +67,10 @@ void TileMap::_notification(int p_what) { _update_quadrant_space(RID()); for (Map::Element *E = quadrant_map.front(); E; E = E->next()) { Quadrant &q = E->get(); - if (navigation) { - for (Map::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID()); - } - q.navpoly_ids.clear(); + for (Map::Element *F = q.navpoly_ids.front(); F; F = F->next()) { + NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID()); } + q.navpoly_ids.clear(); if (collision_parent) { collision_parent->remove_shape_owner(q.shape_owner_id); @@ -96,8 +84,6 @@ void TileMap::_notification(int p_what) { } collision_parent = nullptr; - navigation = nullptr; - } break; case NOTIFICATION_TRANSFORM_CHANGED: { @@ -135,11 +121,6 @@ void TileMap::_update_quadrant_transform() { local_transform = get_transform(); } - Transform2D nav_rel; - if (navigation) { - nav_rel = get_relative_transform_to_parent(navigation); - } - for (Map::Element *E = quadrant_map.front(); E; E = E->next()) { Quadrant &q = E->get(); Transform2D xform; @@ -150,9 +131,9 @@ void TileMap::_update_quadrant_transform() { PhysicsServer2D::get_singleton()->body_set_state(q.body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); } - if (navigation) { + if (bake_navigation) { for (Map::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - NavigationServer2D::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform); + NavigationServer2D::get_singleton()->region_set_transform(F->get().region, F->get().xform); } } @@ -315,11 +296,6 @@ void TileMap::update_dirty_quadrants() { RenderingServer *vs = RenderingServer::get_singleton(); PhysicsServer2D *ps = PhysicsServer2D::get_singleton(); Vector2 tofs = get_cell_draw_offset(); - Transform2D nav_rel; - if (navigation) { - nav_rel = get_relative_transform_to_parent(navigation); - } - Vector2 qofs; SceneTree *st = SceneTree::get_singleton(); @@ -352,12 +328,10 @@ void TileMap::update_dirty_quadrants() { } int shape_idx = 0; - if (navigation) { - for (Map::Element *E = q.navpoly_ids.front(); E; E = E->next()) { - NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID()); - } - q.navpoly_ids.clear(); + for (Map::Element *E = q.navpoly_ids.front(); E; E = E->next()) { + NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID()); } + q.navpoly_ids.clear(); for (Map::Element *E = q.occluder_instances.front(); E; E = E->next()) { RS::get_singleton()->free(E->get().id); @@ -579,7 +553,7 @@ void TileMap::update_dirty_quadrants() { vs->canvas_item_add_set_transform(debug_canvas_item, Transform2D()); } - if (navigation) { + if (bake_navigation) { Ref navpoly; Vector2 npoly_ofs; if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) { @@ -596,8 +570,8 @@ void TileMap::update_dirty_quadrants() { _fix_cell_transform(xform, c, npoly_ofs, s); RID region = NavigationServer2D::get_singleton()->region_create(); - NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid()); - NavigationServer2D::get_singleton()->region_set_transform(region, nav_rel * xform); + NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map()); + NavigationServer2D::get_singleton()->region_set_transform(region, xform); NavigationServer2D::get_singleton()->region_set_navpoly(region, navpoly); Quadrant::NavPoly np; @@ -787,12 +761,10 @@ void TileMap::_erase_quadrant(Map::Element *Q) { dirty_quadrant_list.remove(&q.dirty_list); } - if (navigation) { - for (Map::Element *E = q.navpoly_ids.front(); E; E = E->next()) { - NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID()); - } - q.navpoly_ids.clear(); + for (Map::Element *E = q.navpoly_ids.front(); E; E = E->next()) { + NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID()); } + q.navpoly_ids.clear(); for (Map::Element *E = q.occluder_instances.front(); E; E = E->next()) { RS::get_singleton()->free(E->get().id); @@ -1360,6 +1332,17 @@ float TileMap::get_collision_bounce() const { return bounce; } +void TileMap::set_bake_navigation(bool p_bake_navigation) { + bake_navigation = p_bake_navigation; + for (Map::Element *F = quadrant_map.front(); F; F = F->next()) { + _make_quadrant_dirty(F); + } +} + +bool TileMap::is_baking_navigation() { + return bake_navigation; +} + uint32_t TileMap::get_collision_layer() const { return collision_layer; } @@ -1784,6 +1767,9 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_bounce", "value"), &TileMap::set_collision_bounce); ClassDB::bind_method(D_METHOD("get_collision_bounce"), &TileMap::get_collision_bounce); + ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &TileMap::set_bake_navigation); + ClassDB::bind_method(D_METHOD("is_baking_navigation"), &TileMap::is_baking_navigation); + ClassDB::bind_method(D_METHOD("set_occluder_light_mask", "mask"), &TileMap::set_occluder_light_mask); ClassDB::bind_method(D_METHOD("get_occluder_light_mask"), &TileMap::get_occluder_light_mask); @@ -1842,6 +1828,9 @@ void TileMap::_bind_methods() { ADD_GROUP("Occluder", "occluder_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "occluder_light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask"); + ADD_GROUP("Navigation", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation"); + ADD_PROPERTY_DEFAULT("format", FORMAT_1); ADD_SIGNAL(MethodInfo("settings_changed")); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 3bf45879212..26c84a0bb9f 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -33,7 +33,6 @@ #include "core/templates/self_list.h" #include "core/templates/vset.h" -#include "scene/2d/navigation_2d.h" #include "scene/2d/node_2d.h" #include "scene/resources/tile_set.h" @@ -78,7 +77,7 @@ private: bool use_parent = false; CollisionObject2D *collision_parent = nullptr; bool use_kinematic = false; - Navigation2D *navigation = nullptr; + bool bake_navigation = false; union PosKey { struct { @@ -295,6 +294,9 @@ public: void set_collision_bounce(float p_bounce); float get_collision_bounce() const; + void set_bake_navigation(bool p_bake_navigation); + bool is_baking_navigation(); + void set_mode(Mode p_mode); Mode get_mode() const; diff --git a/scene/3d/navigation_3d.cpp b/scene/3d/navigation_3d.cpp deleted file mode 100644 index eaddec76012..00000000000 --- a/scene/3d/navigation_3d.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************/ -/* navigation_3d.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 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_3d.h" - -#include "servers/navigation_server_3d.h" - -Vector Navigation3D::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) const { - return NavigationServer3D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize); -} - -Vector3 Navigation3D::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision) const { - return NavigationServer3D::get_singleton()->map_get_closest_point_to_segment(map, p_from, p_to, p_use_collision); -} - -Vector3 Navigation3D::get_closest_point(const Vector3 &p_point) const { - return NavigationServer3D::get_singleton()->map_get_closest_point(map, p_point); -} - -Vector3 Navigation3D::get_closest_point_normal(const Vector3 &p_point) const { - return NavigationServer3D::get_singleton()->map_get_closest_point_normal(map, p_point); -} - -RID Navigation3D::get_closest_point_owner(const Vector3 &p_point) const { - return NavigationServer3D::get_singleton()->map_get_closest_point_owner(map, p_point); -} - -void Navigation3D::set_up_vector(const Vector3 &p_up) { - up = p_up; - NavigationServer3D::get_singleton()->map_set_up(map, up); -} - -Vector3 Navigation3D::get_up_vector() const { - return up; -} - -void Navigation3D::set_cell_size(float p_cell_size) { - cell_size = p_cell_size; - NavigationServer3D::get_singleton()->map_set_cell_size(map, cell_size); -} - -void Navigation3D::set_edge_connection_margin(float p_edge_connection_margin) { - edge_connection_margin = p_edge_connection_margin; - NavigationServer3D::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin); -} - -void Navigation3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_rid"), &Navigation3D::get_rid); - - ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation3D::get_simple_path, DEFVAL(true)); - ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "start", "end", "use_collision"), &Navigation3D::get_closest_point_to_segment, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation3D::get_closest_point); - ClassDB::bind_method(D_METHOD("get_closest_point_normal", "to_point"), &Navigation3D::get_closest_point_normal); - ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation3D::get_closest_point_owner); - - ClassDB::bind_method(D_METHOD("set_up_vector", "up"), &Navigation3D::set_up_vector); - ClassDB::bind_method(D_METHOD("get_up_vector"), &Navigation3D::get_up_vector); - - ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation3D::set_cell_size); - ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation3D::get_cell_size); - - ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation3D::set_edge_connection_margin); - ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation3D::get_edge_connection_margin); - - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_vector"), "set_up_vector", "get_up_vector"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin"); -} - -void Navigation3D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_READY: { - NavigationServer3D::get_singleton()->map_set_active(map, true); - } break; - case NOTIFICATION_EXIT_TREE: { - NavigationServer3D::get_singleton()->map_set_active(map, false); - } break; - } -} - -Navigation3D::Navigation3D() { - map = NavigationServer3D::get_singleton()->map_create(); - - set_cell_size(0.3); - set_edge_connection_margin(5.0); // Five meters, depends a lot on the agent's radius -} - -Navigation3D::~Navigation3D() { - NavigationServer3D::get_singleton()->free(map); -} diff --git a/scene/3d/navigation_3d.h b/scene/3d/navigation_3d.h deleted file mode 100644 index b89725a3f56..00000000000 --- a/scene/3d/navigation_3d.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************/ -/* navigation_3d.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 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. */ -/*************************************************************************/ - -#ifndef NAVIGATION_3D_H -#define NAVIGATION_3D_H - -#include "scene/3d/navigation_region_3d.h" -#include "scene/3d/node_3d.h" - -class Navigation3D : public Node3D { - GDCLASS(Navigation3D, Node3D); - - RID map; - - Vector3 up = Vector3(0, 1, 0); - real_t cell_size; - real_t edge_connection_margin; - -protected: - static void _bind_methods(); - void _notification(int p_what); - -public: - RID get_rid() const { - return map; - } - - void set_up_vector(const Vector3 &p_up); - Vector3 get_up_vector() const; - - void set_cell_size(float p_cell_size); - float get_cell_size() const { - return cell_size; - } - - void set_edge_connection_margin(float p_edge_connection_margin); - float get_edge_connection_margin() const { - return edge_connection_margin; - } - - Vector get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize = true) const; - Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision = false) const; - Vector3 get_closest_point(const Vector3 &p_point) const; - Vector3 get_closest_point_normal(const Vector3 &p_point) const; - RID get_closest_point_owner(const Vector3 &p_point) const; - - Navigation3D(); - ~Navigation3D(); -}; - -#endif // NAVIGATION_H diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 8917cc4664e..21ca3d70dd8 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -31,7 +31,6 @@ #include "navigation_agent_3d.h" #include "core/config/engine.h" -#include "scene/3d/navigation_3d.h" #include "servers/navigation_server_3d.h" void NavigationAgent3D::_bind_methods() { @@ -47,9 +46,6 @@ void NavigationAgent3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ignore_y", "ignore"), &NavigationAgent3D::set_ignore_y); ClassDB::bind_method(D_METHOD("get_ignore_y"), &NavigationAgent3D::get_ignore_y); - ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent3D::set_navigation_node); - ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent3D::get_navigation_node); - ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent3D::set_neighbor_dist); ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent3D::get_neighbor_dist); @@ -101,28 +97,10 @@ void NavigationAgent3D::_notification(int p_what) { agent_parent = Object::cast_to(get_parent()); NavigationServer3D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done"); - - // Search the navigation node and set it - { - Navigation3D *nav = nullptr; - Node *p = get_parent(); - while (p != nullptr) { - nav = Object::cast_to(p); - if (nav != nullptr) { - p = nullptr; - } else { - p = p->get_parent(); - } - } - - set_navigation(nav); - } - set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { agent_parent = nullptr; - set_navigation(nullptr); set_physics_process_internal(false); } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { @@ -154,25 +132,6 @@ NavigationAgent3D::~NavigationAgent3D() { agent = RID(); // Pointless } -void NavigationAgent3D::set_navigation(Navigation3D *p_nav) { - if (navigation == p_nav) { - return; // Pointless - } - - navigation = p_nav; - NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid()); -} - -void NavigationAgent3D::set_navigation_node(Node *p_nav) { - Navigation3D *nav = Object::cast_to(p_nav); - ERR_FAIL_COND(nav == nullptr); - set_navigation(nav); -} - -Node *NavigationAgent3D::get_navigation_node() const { - return Object::cast_to(navigation); -} - void NavigationAgent3D::set_target_desired_distance(real_t p_dd) { target_desired_distance = p_dd; } @@ -303,7 +262,7 @@ void NavigationAgent3D::update_navigation() { if (agent_parent == nullptr) { return; } - if (navigation == nullptr) { + if (!agent_parent->is_inside_tree()) { return; } if (update_frame_id == Engine::get_singleton()->get_physics_frames()) { @@ -337,7 +296,7 @@ void NavigationAgent3D::update_navigation() { } if (reload_path) { - navigation_path = NavigationServer3D::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true); + navigation_path = NavigationServer3D::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_location, true); navigation_finished = false; nav_path_index = 0; emit_signal("path_changed"); diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index bd890a051b3..22db889618a 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -35,13 +35,11 @@ #include "scene/main/node.h" class Node3D; -class Navigation3D; class NavigationAgent3D : public Node { GDCLASS(NavigationAgent3D, Node); Node3D *agent_parent = nullptr; - Navigation3D *navigation = nullptr; RID agent; @@ -76,14 +74,6 @@ public: NavigationAgent3D(); virtual ~NavigationAgent3D(); - void set_navigation(Navigation3D *p_nav); - const Navigation3D *get_navigation() const { - return navigation; - } - - void set_navigation_node(Node *p_nav); - Node *get_navigation_node() const; - RID get_rid() const { return agent; } diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp index 01bf7de9135..df03bca4fda 100644 --- a/scene/3d/navigation_obstacle_3d.cpp +++ b/scene/3d/navigation_obstacle_3d.cpp @@ -31,55 +31,38 @@ #include "navigation_obstacle_3d.h" #include "scene/3d/collision_shape_3d.h" -#include "scene/3d/navigation_3d.h" #include "scene/3d/physics_body_3d.h" #include "servers/navigation_server_3d.h" void NavigationObstacle3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle3D::set_navigation_node); - ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle3D::get_navigation_node); } void NavigationObstacle3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { - update_agent_shape(); - - // Search the navigation node and set it - { - Navigation3D *nav = nullptr; - Node *p = get_parent(); - while (p != nullptr) { - nav = Object::cast_to(p); - if (nav != nullptr) { - p = nullptr; - } else { - p = p->get_parent(); - } - } - - set_navigation(nav); - } - set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { - set_navigation(nullptr); set_physics_process_internal(false); } break; + case NOTIFICATION_PARENTED: { + parent_node3d = Object::cast_to(get_parent()); + update_agent_shape(); + } break; + case NOTIFICATION_UNPARENTED: { + parent_node3d = nullptr; + } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - Node3D *spatial = Object::cast_to(get_parent()); - if (spatial) { - NavigationServer3D::get_singleton()->agent_set_position(agent, spatial->get_global_transform().origin); - } + if (parent_node3d) { + NavigationServer3D::get_singleton()->agent_set_position(agent, parent_node3d->get_global_transform().origin); - PhysicsBody3D *rigid = Object::cast_to(get_parent()); - if (rigid) { - Vector3 v = rigid->get_linear_velocity(); - NavigationServer3D::get_singleton()->agent_set_velocity(agent, v); - NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v); + PhysicsBody3D *rigid = Object::cast_to(get_parent()); + if (rigid) { + Vector3 v = rigid->get_linear_velocity(); + NavigationServer3D::get_singleton()->agent_set_velocity(agent, v); + NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v); + } } - } break; } } @@ -93,29 +76,10 @@ NavigationObstacle3D::~NavigationObstacle3D() { agent = RID(); // Pointless } -void NavigationObstacle3D::set_navigation(Navigation3D *p_nav) { - if (navigation == p_nav) { - return; // Pointless - } - - navigation = p_nav; - NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid()); -} - -void NavigationObstacle3D::set_navigation_node(Node *p_nav) { - Navigation3D *nav = Object::cast_to(p_nav); - ERR_FAIL_COND(nav == nullptr); - set_navigation(nav); -} - -Node *NavigationObstacle3D::get_navigation_node() const { - return Object::cast_to(navigation); -} - String NavigationObstacle3D::get_configuration_warning() const { String warning = Node::get_configuration_warning(); - if (!Object::cast_to(get_parent())) { + if (!parent_node3d) { if (!warning.is_empty()) { warning += "\n\n"; } @@ -126,40 +90,38 @@ String NavigationObstacle3D::get_configuration_warning() const { } void NavigationObstacle3D::update_agent_shape() { - Node *node = get_parent(); - - // Estimate the radius of this physics body - real_t radius = 0.0; - for (int i(0); i < node->get_child_count(); i++) { - // For each collision shape - CollisionShape3D *cs = Object::cast_to(node->get_child(i)); - if (cs) { - // Take the distance between the Body center to the shape center - real_t r = cs->get_transform().origin.length(); - if (cs->get_shape().is_valid()) { - // and add the enclosing shape radius - r += cs->get_shape()->get_enclosing_radius(); + if (parent_node3d) { + // Estimate the radius of this physics body + real_t radius = 0.0; + for (int i(0); i < parent_node3d->get_child_count(); i++) { + // For each collision shape + CollisionShape3D *cs = Object::cast_to(parent_node3d->get_child(i)); + if (cs) { + // Take the distance between the Body center to the shape center + real_t r = cs->get_transform().origin.length(); + if (cs->get_shape().is_valid()) { + // and add the enclosing shape radius + r += cs->get_shape()->get_enclosing_radius(); + } + Vector3 s = cs->get_global_transform().basis.get_scale(); + r *= MAX(s.x, MAX(s.y, s.z)); + // Takes the biggest radius + radius = MAX(radius, r); } - Vector3 s = cs->get_global_transform().basis.get_scale(); - r *= MAX(s.x, MAX(s.y, s.z)); - // Takes the biggest radius - radius = MAX(radius, r); } - } - Node3D *spa = Object::cast_to(node); - if (spa) { - Vector3 s = spa->get_global_transform().basis.get_scale(); + + Vector3 s = parent_node3d->get_global_transform().basis.get_scale(); radius *= MAX(s.x, MAX(s.y, s.z)); - } - if (radius == 0.0) { - radius = 1.0; // Never a 0 radius - } + if (radius == 0.0) { + radius = 1.0; // Never a 0 radius + } - // Initialize the Agent as an object - NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0); - NavigationServer3D::get_singleton()->agent_set_max_neighbors(agent, 0); - NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0); - NavigationServer3D::get_singleton()->agent_set_radius(agent, radius); - NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0); + // Initialize the Agent as an object + NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0); + NavigationServer3D::get_singleton()->agent_set_max_neighbors(agent, 0); + NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0); + NavigationServer3D::get_singleton()->agent_set_radius(agent, radius); + NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0); + } } diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h index b8d05b8a87e..b1bb53724a7 100644 --- a/scene/3d/navigation_obstacle_3d.h +++ b/scene/3d/navigation_obstacle_3d.h @@ -31,15 +31,13 @@ #ifndef NAVIGATION_OBSTACLE_H #define NAVIGATION_OBSTACLE_H +#include "scene/3d/node_3d.h" #include "scene/main/node.h" -class Navigation3D; - class NavigationObstacle3D : public Node { GDCLASS(NavigationObstacle3D, Node); - Navigation3D *navigation = nullptr; - + Node3D *parent_node3d = nullptr; RID agent; protected: @@ -50,14 +48,6 @@ public: NavigationObstacle3D(); virtual ~NavigationObstacle3D(); - void set_navigation(Navigation3D *p_nav); - const Navigation3D *get_navigation() const { - return navigation; - } - - void set_navigation_node(Node *p_nav); - Node *get_navigation_node() const; - RID get_rid() const { return agent; } diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 19bde942222..8470a7d7253 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -32,7 +32,6 @@ #include "core/os/thread.h" #include "mesh_instance_3d.h" -#include "navigation_3d.h" #include "servers/navigation_server_3d.h" void NavigationRegion3D::set_enabled(bool p_enabled) { @@ -48,9 +47,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) { if (!enabled) { NavigationServer3D::get_singleton()->region_set_map(region, RID()); } else { - if (navigation) { - NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid()); - } + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); } if (debug_view) { @@ -74,17 +71,8 @@ bool NavigationRegion3D::is_enabled() const { void NavigationRegion3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - Node3D *c = this; - while (c) { - navigation = Object::cast_to(c); - if (navigation) { - if (enabled) { - NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid()); - } - break; - } - - c = c->get_parent_spatial(); + if (enabled) { + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); } if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) { @@ -105,15 +93,12 @@ void NavigationRegion3D::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - if (navigation) { - NavigationServer3D::get_singleton()->region_set_map(region, RID()); - } + NavigationServer3D::get_singleton()->region_set_map(region, RID()); if (debug_view) { debug_view->queue_delete(); debug_view = nullptr; } - navigation = nullptr; } break; } } @@ -198,19 +183,7 @@ String NavigationRegion3D::get_configuration_warning() const { warning += TTR("A NavigationMesh resource must be set or created for this node to work."); } - const Node3D *c = this; - while (c) { - if (Object::cast_to(c)) { - return warning; - } - - c = Object::cast_to(c->get_parent()); - } - - if (!warning.is_empty()) { - warning += "\n\n"; - } - return warning + TTR("NavigationRegion3D must be a child or grandchild to a Navigation3D node. It only provides navigation data."); + return warning; } void NavigationRegion3D::_bind_methods() { diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index 6ae15c93603..85bf4955717 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -35,8 +35,6 @@ #include "scene/resources/mesh.h" #include "scene/resources/navigation_mesh.h" -class Navigation3D; - class NavigationRegion3D : public Node3D { GDCLASS(NavigationRegion3D, Node3D); @@ -44,7 +42,6 @@ class NavigationRegion3D : public Node3D { RID region; Ref navmesh; - Navigation3D *navigation = nullptr; Node *debug_view = nullptr; Thread bake_thread; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 51d46438832..fcd8b8b4012 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -50,7 +50,6 @@ #include "scene/2d/line_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_obstacle_2d.h" #include "scene/2d/parallax_background.h" @@ -206,7 +205,6 @@ #include "scene/3d/listener_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/multimesh_instance_3d.h" -#include "scene/3d/navigation_3d.h" #include "scene/3d/navigation_agent_3d.h" #include "scene/3d/navigation_obstacle_3d.h" #include "scene/3d/navigation_region_3d.h" @@ -516,7 +514,6 @@ void register_scene_types() { ClassDB::register_class(); ClassDB::register_class(); - ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); @@ -793,7 +790,6 @@ void register_scene_types() { ClassDB::register_class(); ClassDB::register_class(); - ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); @@ -814,6 +810,8 @@ void register_scene_types() { ClassDB::add_compatibility_class("DynamicFont", "Font"); ClassDB::add_compatibility_class("DynamicFontData", "FontData"); ClassDB::add_compatibility_class("ToolButton", "Button"); + ClassDB::add_compatibility_class("Navigation3D", "Node3D"); + ClassDB::add_compatibility_class("Navigation2D", "Node2D"); // Renamed in 4.0. // Keep alphabetical ordering to easily locate classes and avoid duplicates. @@ -865,7 +863,6 @@ void register_scene_types() { ClassDB::add_compatibility_class("Listener", "Listener3D"); ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D"); ClassDB::add_compatibility_class("MultiMeshInstance", "MultiMeshInstance3D"); - ClassDB::add_compatibility_class("Navigation", "Navigation3D"); ClassDB::add_compatibility_class("NavigationAgent", "NavigationAgent3D"); ClassDB::add_compatibility_class("NavigationMeshInstance", "NavigationRegion3D"); ClassDB::add_compatibility_class("NavigationObstacle", "NavigationObstacle3D"); diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 156c7d05765..a064ade3627 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -34,6 +34,7 @@ #include "scene/2d/camera_2d.h" #include "scene/2d/visibility_notifier_2d.h" #include "scene/main/window.h" +#include "servers/navigation_server_2d.h" #include "servers/physics_server_2d.h" #include "servers/rendering_server.h" @@ -315,14 +316,18 @@ void World2D::_update() { indexer->_update(); } -RID World2D::get_canvas() { +RID World2D::get_canvas() const { return canvas; } -RID World2D::get_space() { +RID World2D::get_space() const { return space; } +RID World2D::get_navigation_map() const { + return navigation_map; +} + void World2D::get_viewport_list(List *r_viewports) { for (Map::Element *E = indexer->viewports.front(); E; E = E->next()) { r_viewports->push_back(E->key()); @@ -332,11 +337,13 @@ void World2D::get_viewport_list(List *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); ADD_PROPERTY(PropertyInfo(Variant::RID, "canvas", PROPERTY_HINT_NONE, "", 0), "", "get_canvas"); ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space"); + ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", 0), "", "get_navigation_map"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState2D", 0), "", "get_direct_space_state"); } @@ -346,9 +353,9 @@ PhysicsDirectSpaceState2D *World2D::get_direct_space_state() { World2D::World2D() { canvas = RenderingServer::get_singleton()->canvas_create(); - space = PhysicsServer2D::get_singleton()->space_create(); - //set space2D to be more friendly with pixels than meters, by adjusting some constants + // Create and configure space2D to be more friendly with pixels than meters + space = PhysicsServer2D::get_singleton()->space_create(); PhysicsServer2D::get_singleton()->space_set_active(space, true); PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98)); PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1))); @@ -356,11 +363,19 @@ World2D::World2D() { ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::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::FLOAT, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); + + // Create and configure the navigation_map to be more friendly with pixels than meters. + navigation_map = NavigationServer2D::get_singleton()->map_create(); + NavigationServer2D::get_singleton()->map_set_active(navigation_map, true); + NavigationServer2D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_size", 10)); + NavigationServer2D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/2d/default_edge_connection_margin", 100)); + indexer = memnew(SpatialIndexer2D); } World2D::~World2D() { RenderingServer::get_singleton()->free(canvas); PhysicsServer2D::get_singleton()->free(space); + NavigationServer2D::get_singleton()->free(navigation_map); memdelete(indexer); } diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index ae13367421d..38abf3d7adf 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -44,6 +44,7 @@ class World2D : public Resource { RID canvas; RID space; + RID navigation_map; SpatialIndexer2D *indexer; @@ -63,8 +64,9 @@ protected: void _update(); public: - RID get_canvas(); - RID get_space(); + RID get_canvas() const; + RID get_space() const; + RID get_navigation_map() const; PhysicsDirectSpaceState2D *get_direct_space_state(); diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp index 9c0317454bf..0e9f7a6cf2d 100644 --- a/scene/resources/world_3d.cpp +++ b/scene/resources/world_3d.cpp @@ -35,6 +35,7 @@ #include "scene/3d/camera_3d.h" #include "scene/3d/visibility_notifier_3d.h" #include "scene/scene_string_names.h" +#include "servers/navigation_server_3d.h" struct SpatialIndexer { Octree octree; @@ -243,6 +244,10 @@ RID World3D::get_space() const { return space; } +RID World3D::get_navigation_map() const { + return navigation_map; +} + RID World3D::get_scenario() const { return scenario; } @@ -310,6 +315,7 @@ void World3D::get_camera_list(List *r_cameras) { void World3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_space"), &World3D::get_space); + ClassDB::bind_method(D_METHOD("get_navigation_map"), &World3D::get_navigation_map); ClassDB::bind_method(D_METHOD("get_scenario"), &World3D::get_scenario); ClassDB::bind_method(D_METHOD("set_environment", "env"), &World3D::set_environment); ClassDB::bind_method(D_METHOD("get_environment"), &World3D::get_environment); @@ -322,6 +328,7 @@ void World3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects"); ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space"); + ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", 0), "", "get_navigation_map"); ADD_PROPERTY(PropertyInfo(Variant::RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState3D", 0), "", "get_direct_space_state"); } @@ -338,6 +345,11 @@ World3D::World3D() { PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/3d/default_angular_damp", 0.1)); ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); + navigation_map = NavigationServer3D::get_singleton()->map_create(); + NavigationServer3D::get_singleton()->map_set_active(navigation_map, true); + NavigationServer3D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/3d/default_cell_size", 0.3)); + NavigationServer3D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/3d/default_edge_connection_margin", 5.0)); // Five meters, depends a lot on the agent's radius + #ifdef _3D_DISABLED indexer = nullptr; #else @@ -348,6 +360,7 @@ World3D::World3D() { World3D::~World3D() { PhysicsServer3D::get_singleton()->free(space); RenderingServer::get_singleton()->free(scenario); + NavigationServer3D::get_singleton()->free(navigation_map); #ifndef _3D_DISABLED memdelete(indexer); diff --git a/scene/resources/world_3d.h b/scene/resources/world_3d.h index 3d6c33997e5..4e2717a2bbb 100644 --- a/scene/resources/world_3d.h +++ b/scene/resources/world_3d.h @@ -46,6 +46,7 @@ class World3D : public Resource { private: RID space; + RID navigation_map; RID scenario; SpatialIndexer *indexer; Ref environment; @@ -70,6 +71,7 @@ protected: public: RID get_space() const; + RID get_navigation_map() const; RID get_scenario() const; void set_environment(const Ref &p_environment);