diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/gdnative/include/nativescript/godot_nativescript.h | 2 | ||||
-rw-r--r-- | modules/gdnavigation/gd_navigation_server.cpp | 18 | ||||
-rw-r--r-- | modules/gdnavigation/gd_navigation_server.h | 4 | ||||
-rw-r--r-- | modules/gdnavigation/nav_map.cpp | 14 | ||||
-rw-r--r-- | modules/gdnavigation/nav_map.h | 2 | ||||
-rw-r--r-- | modules/gdnavigation/nav_region.cpp | 8 | ||||
-rw-r--r-- | modules/gdnavigation/nav_region.h | 8 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 2 | ||||
-rw-r--r-- | modules/gridmap/doc_classes/GridMap.xml | 6 | ||||
-rw-r--r-- | modules/gridmap/grid_map.cpp | 65 | ||||
-rw-r--r-- | modules/gridmap/grid_map.h | 10 |
11 files changed, 105 insertions, 34 deletions
diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index 73b1738b03..c97f5f0389 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -58,8 +58,10 @@ typedef enum { GODOT_PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags) GODOT_PROPERTY_HINT_LAYERS_2D_RENDER, GODOT_PROPERTY_HINT_LAYERS_2D_PHYSICS, + GODOT_PROPERTY_HINT_LAYERS_2D_NAVIGATION, GODOT_PROPERTY_HINT_LAYERS_3D_RENDER, GODOT_PROPERTY_HINT_LAYERS_3D_PHYSICS, + GODOT_PROPERTY_HINT_LAYERS_3D_NAVIGATION, GODOT_PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," GODOT_PROPERTY_HINT_DIR, ///< a directory path must be passed GODOT_PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp index 4f61ad5040..af76d9a4cc 100644 --- a/modules/gdnavigation/gd_navigation_server.cpp +++ b/modules/gdnavigation/gd_navigation_server.cpp @@ -200,11 +200,11 @@ real_t GdNavigationServer::map_get_edge_connection_margin(RID p_map) const { return map->get_edge_connection_margin(); } -Vector<Vector3> GdNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize) const { +Vector<Vector3> GdNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers) const { const NavMap *map = map_owner.getornull(p_map); ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>()); - return map->get_path(p_origin, p_destination, p_optimize); + return map->get_path(p_origin, p_destination, p_optimize, p_layers); } Vector3 GdNavigationServer::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const { @@ -273,6 +273,20 @@ COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform) { region->set_transform(p_transform); } +COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers) { + NavRegion *region = region_owner.getornull(p_region); + ERR_FAIL_COND(region == nullptr); + + region->set_layers(p_layers); +} + +uint32_t GdNavigationServer::region_get_layers(RID p_region) const { + NavRegion *region = region_owner.getornull(p_region); + ERR_FAIL_COND_V(region == nullptr, 0); + + return region->get_layers(); +} + COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh) { NavRegion *region = region_owner.getornull(p_region); ERR_FAIL_COND(region == nullptr); diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/gdnavigation/gd_navigation_server.h index 92f4ccfdd5..8bc65eccab 100644 --- a/modules/gdnavigation/gd_navigation_server.h +++ b/modules/gdnavigation/gd_navigation_server.h @@ -100,7 +100,7 @@ public: 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; - virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize) 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; @@ -109,6 +109,8 @@ public: virtual RID region_create() const; COMMAND_2(region_set_map, RID, p_region, RID, p_map); + COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers); + virtual uint32_t region_get_layers(RID p_region) const; COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform); COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh); virtual void region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const; diff --git a/modules/gdnavigation/nav_map.cpp b/modules/gdnavigation/nav_map.cpp index 2646a4cc0c..5289975e4b 100644 --- a/modules/gdnavigation/nav_map.cpp +++ b/modules/gdnavigation/nav_map.cpp @@ -70,7 +70,7 @@ gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const { return p; } -Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize) const { +Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers) const { const gd::Polygon *begin_poly = nullptr; const gd::Polygon *end_poly = nullptr; Vector3 begin_point; @@ -82,6 +82,11 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p for (size_t i(0); i < polygons.size(); i++) { const gd::Polygon &p = polygons[i]; + // Only consider the polygon if it in a region with compatible layers. + if ((p_layers & p.owner->get_layers()) == 0) { + continue; + } + // For each point cast a face and check the distance between the origin/destination for (size_t point_id = 2; point_id < p.points.size(); point_id++) { Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos); @@ -144,6 +149,11 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p for (size_t i = 0; i < navigation_polys[least_cost_id].poly->edges.size(); i++) { gd::NavigationPoly *least_cost_poly = &navigation_polys[least_cost_id]; + // Only consider the polygon if it in a region with compatible layers. + if ((p_layers & least_cost_poly->poly->owner->get_layers()) == 0) { + continue; + } + const gd::Edge &edge = least_cost_poly->poly->edges[i]; if (!edge.other_polygon) { continue; @@ -629,7 +639,7 @@ void NavMap::sync() { connection->get().B->edges[connection->get().B_edge].other_edge = connection->get().A_edge; } else { // The edge is already connected with another edge, skip. - ERR_PRINT("Attempted to merge a navigation mesh triangle edge with another already-merged edge. This happens when the Navigation3D's `cell_size` is different from the one used to generate the navigation mesh. This will cause navigation problem."); + ERR_PRINT("Attempted to merge a navigation mesh triangle edge with another already-merged edge. This happens when the current `cell_size` is different from the one used to generate the navigation mesh. This will cause navigation problem."); } } } diff --git a/modules/gdnavigation/nav_map.h b/modules/gdnavigation/nav_map.h index bffc1fbc1a..6b7cfae324 100644 --- a/modules/gdnavigation/nav_map.h +++ b/modules/gdnavigation/nav_map.h @@ -102,7 +102,7 @@ public: gd::PointKey get_point_key(const Vector3 &p_pos) const; - Vector<Vector3> get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize) const; + Vector<Vector3> get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers = 1) 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; diff --git a/modules/gdnavigation/nav_region.cpp b/modules/gdnavigation/nav_region.cpp index 383b0f15a6..a07995bc11 100644 --- a/modules/gdnavigation/nav_region.cpp +++ b/modules/gdnavigation/nav_region.cpp @@ -41,6 +41,14 @@ void NavRegion::set_map(NavMap *p_map) { polygons_dirty = true; } +void NavRegion::set_layers(uint32_t p_layers) { + layers = p_layers; +} + +uint32_t NavRegion::get_layers() const { + return layers; +} + void NavRegion::set_transform(Transform p_transform) { transform = p_transform; polygons_dirty = true; diff --git a/modules/gdnavigation/nav_region.h b/modules/gdnavigation/nav_region.h index 954780033b..fff7843fde 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 <vector> /** @@ -48,6 +48,7 @@ class NavRegion : public NavRid { NavMap *map = nullptr; Transform transform; Ref<NavigationMesh> mesh; + uint32_t layers = 1; bool polygons_dirty = true; @@ -66,6 +67,9 @@ public: return map; } + void set_layers(uint32_t p_layers); + uint32_t get_layers() const; + void set_transform(Transform transform); const Transform &get_transform() const { return transform; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 08645d371c..15cb3146ee 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -130,8 +130,10 @@ GDScriptParser::GDScriptParser() { register_annotation(MethodInfo("@export_flags", { Variant::STRING, "names" }), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FLAGS, Variant::INT>, 0, true); register_annotation(MethodInfo("@export_flags_2d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_RENDER, Variant::INT>); register_annotation(MethodInfo("@export_flags_2d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_PHYSICS, Variant::INT>); + register_annotation(MethodInfo("@export_flags_2d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_NAVIGATION, Variant::INT>); register_annotation(MethodInfo("@export_flags_3d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_RENDER, Variant::INT>); register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>); + register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>); // Networking. register_annotation(MethodInfo("@remote"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_REMOTE>); register_annotation(MethodInfo("@master"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTER>); diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index e28cc57f9b..25776b1f6d 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -184,6 +184,9 @@ </method> </methods> <members> + <member name="bake_navigation" type="bool" setter="set_bake_navigation" getter="is_baking_navigation" default="false"> + If [code]true[/code], this GridMap bakes a navigation region. + </member> <member name="cell_center_x" type="bool" setter="set_center_x" getter="get_center_x" default="true"> If [code]true[/code], grid items are centered on the X axis. </member> @@ -211,6 +214,9 @@ <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1"> The physics layers this GridMap detects collisions in. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. </member> + <member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1"> + The navigation layers the GridMap generates its navigable regions in. + </member> <member name="mesh_library" type="MeshLibrary" setter="set_mesh_library" getter="get_mesh_library"> The assigned [MeshLibrary]. </member> diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index e7c252dc53..c1c230d104 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -179,6 +179,24 @@ 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_navigation_layers(uint32_t p_layers) { + navigation_layers = p_layers; + _recreate_octant_data(); +} + +uint32_t GridMap::get_navigation_layers() { + return navigation_layers; +} + void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) { if (!mesh_library.is_null()) { mesh_library->unregister_owner(this); @@ -474,13 +492,15 @@ 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_layers(region, navigation_layers); 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 +584,17 @@ 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<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) { if (cell_map.has(F->key()) && F->get().region.is_valid() == false) { Ref<NavigationMesh> 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_layers(region, navigation_layers); 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 +616,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<IndexKey, Octant::NavMesh>::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<IndexKey, Octant::NavMesh>::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 +655,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<Navigation3D>(c); - if (navigation) { - break; - } - - c = Object::cast_to<Node3D>(c->get_parent()); - } - last_transform = get_global_transform(); for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { @@ -679,8 +689,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 +793,12 @@ 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_navigation_layers", "layers"), &GridMap::set_navigation_layers); + ClassDB::bind_method(D_METHOD("get_navigation_layers"), &GridMap::get_navigation_layers); + 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 +852,9 @@ 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"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); BIND_CONSTANT(INVALID_CELL_ITEM); diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index e5ec4bb602..4c04d492f7 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,8 @@ class GridMap : public Node3D { uint32_t collision_layer = 1; uint32_t collision_mask = 1; + bool bake_navigation = false; + uint32_t navigation_layers = 1; Transform last_transform; @@ -145,7 +146,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 +223,12 @@ 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_navigation_layers(uint32_t p_layers); + uint32_t get_navigation_layers(); + void set_mesh_library(const Ref<MeshLibrary> &p_mesh_library); Ref<MeshLibrary> get_mesh_library() const; |