Skip to content

Commit

Permalink
Add NavigationRegion function to change navigation map
Browse files Browse the repository at this point in the history
Adds NavigationRegion function to change navigation map.
  • Loading branch information
smix8 committed Jun 15, 2023
1 parent 7734146 commit 84647ab
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 69 deletions.
13 changes: 13 additions & 0 deletions doc/classes/NavigationRegion2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [param layer_number] between 1 and 32.
</description>
</method>
<method name="get_navigation_map" qualifiers="const">
<return type="RID" />
<description>
Returns the current navigation map [RID] used by this region.
</description>
</method>
<method name="get_region_rid" qualifiers="const">
<return type="RID" />
<description>
Expand All @@ -52,6 +58,13 @@
Based on [param value], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [param layer_number] between 1 and 32.
</description>
</method>
<method name="set_navigation_map">
<return type="void" />
<param index="0" name="navigation_map" type="RID" />
<description>
Sets the [RID] of the navigation map this region should use. By default the region will automatically join the [World2D] default navigation map so this function is only required to override the default map.
</description>
</method>
</methods>
<members>
<member name="avoidance_layers" type="int" setter="set_avoidance_layers" getter="get_avoidance_layers" default="1">
Expand Down
13 changes: 13 additions & 0 deletions doc/classes/NavigationRegion3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [param layer_number] between 1 and 32.
</description>
</method>
<method name="get_navigation_map" qualifiers="const">
<return type="RID" />
<description>
Returns the current navigation map [RID] used by this region.
</description>
</method>
<method name="get_region_rid" qualifiers="const">
<return type="RID" />
<description>
Expand All @@ -44,6 +50,13 @@
Based on [param value], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [param layer_number] between 1 and 32.
</description>
</method>
<method name="set_navigation_map">
<return type="void" />
<param index="0" name="navigation_map" type="RID" />
<description>
Sets the [RID] of the navigation map this region should use. By default the region will automatically join the [World3D] default navigation map so this function is only required to override the default map.
</description>
</method>
</methods>
<members>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
Expand Down
132 changes: 98 additions & 34 deletions scene/2d/navigation_region_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ void NavigationRegion2D::set_enabled(bool p_enabled) {
}

if (!enabled) {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
_region_enter_navigation_map();
} else {
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
_region_exit_navigation_map();
}

#ifdef DEBUG_ENABLED
Expand Down Expand Up @@ -161,48 +161,19 @@ 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: {
if (enabled) {
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
if (constrain_avoidance_obstacles[i].is_valid()) {
NavigationServer2D::get_singleton()->obstacle_set_map(constrain_avoidance_obstacles[i], get_world_2d()->get_navigation_map());
NavigationServer2D::get_singleton()->obstacle_set_position(constrain_avoidance_obstacles[i], get_global_position());
}
}
}
current_global_transform = get_global_transform();
NavigationServer2D::get_singleton()->region_set_transform(region, current_global_transform);
_region_enter_navigation_map();
} break;

case NOTIFICATION_TRANSFORM_CHANGED: {
set_physics_process_internal(true);
} break;

case NOTIFICATION_EXIT_TREE: {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
if (constrain_avoidance_obstacles[i].is_valid()) {
NavigationServer2D::get_singleton()->obstacle_set_map(constrain_avoidance_obstacles[i], RID());
}
}
_region_exit_navigation_map();
} break;

case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
set_physics_process_internal(false);
if (is_inside_tree()) {
Transform2D new_global_transform = get_global_transform();
if (current_global_transform != new_global_transform) {
current_global_transform = new_global_transform;
NavigationServer2D::get_singleton()->region_set_transform(region, current_global_transform);
queue_redraw();

for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
if (constrain_avoidance_obstacles[i].is_valid()) {
NavigationServer2D::get_singleton()->obstacle_set_position(constrain_avoidance_obstacles[i], get_global_position());
}
}
}
}
} break;

case NOTIFICATION_DRAW: {
Expand Down Expand Up @@ -240,6 +211,30 @@ Ref<NavigationPolygon> NavigationRegion2D::get_navigation_polygon() const {
return navigation_polygon;
}

void NavigationRegion2D::set_navigation_map(RID p_navigation_map) {
if (map_override == p_navigation_map) {
return;
}

map_override = p_navigation_map;

NavigationServer2D::get_singleton()->region_set_map(region, map_override);
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
if (constrain_avoidance_obstacles[i].is_valid()) {
NavigationServer2D::get_singleton()->obstacle_set_map(constrain_avoidance_obstacles[i], map_override);
}
}
}

RID NavigationRegion2D::get_navigation_map() const {
if (map_override.is_valid()) {
return map_override;
} else if (is_inside_tree()) {
return get_world_2d()->get_navigation_map();
}
return RID();
}

void NavigationRegion2D::_navigation_polygon_changed() {
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) {
queue_redraw();
Expand Down Expand Up @@ -277,6 +272,9 @@ void NavigationRegion2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion2D::is_enabled);

ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationRegion2D::set_navigation_map);
ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationRegion2D::get_navigation_map);

ClassDB::bind_method(D_METHOD("set_use_edge_connections", "enabled"), &NavigationRegion2D::set_use_edge_connections);
ClassDB::bind_method(D_METHOD("get_use_edge_connections"), &NavigationRegion2D::get_use_edge_connections);

Expand Down Expand Up @@ -416,7 +414,11 @@ void NavigationRegion2D::_update_avoidance_constrain() {
NavigationServer2D::get_singleton()->obstacle_set_vertices(obstacle_rid, new_obstacle_outline);
NavigationServer2D::get_singleton()->obstacle_set_avoidance_layers(obstacle_rid, avoidance_layers);
if (is_inside_tree()) {
NavigationServer2D::get_singleton()->obstacle_set_map(obstacle_rid, get_world_2d()->get_navigation_map());
if (map_override.is_valid()) {
NavigationServer2D::get_singleton()->obstacle_set_map(obstacle_rid, map_override);
} else {
NavigationServer2D::get_singleton()->obstacle_set_map(obstacle_rid, get_world_2d()->get_navigation_map());
}
NavigationServer2D::get_singleton()->obstacle_set_position(obstacle_rid, get_global_position());
}
}
Expand Down Expand Up @@ -472,6 +474,68 @@ bool NavigationRegion2D::get_avoidance_layer_value(int p_layer_number) const {
return get_avoidance_layers() & (1 << (p_layer_number - 1));
}

void NavigationRegion2D::_region_enter_navigation_map() {
if (!is_inside_tree()) {
return;
}

if (enabled) {
if (map_override.is_valid()) {
NavigationServer2D::get_singleton()->region_set_map(region, map_override);
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
if (constrain_avoidance_obstacles[i].is_valid()) {
NavigationServer2D::get_singleton()->obstacle_set_map(constrain_avoidance_obstacles[i], map_override);
}
}
} else {
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
if (constrain_avoidance_obstacles[i].is_valid()) {
NavigationServer2D::get_singleton()->obstacle_set_map(constrain_avoidance_obstacles[i], get_world_2d()->get_navigation_map());
}
}
}
}

current_global_transform = get_global_transform();
NavigationServer2D::get_singleton()->region_set_transform(region, current_global_transform);
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
if (constrain_avoidance_obstacles[i].is_valid()) {
NavigationServer2D::get_singleton()->obstacle_set_position(constrain_avoidance_obstacles[i], get_global_position());
}
}

queue_redraw();
}

void NavigationRegion2D::_region_exit_navigation_map() {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
if (constrain_avoidance_obstacles[i].is_valid()) {
NavigationServer2D::get_singleton()->obstacle_set_map(constrain_avoidance_obstacles[i], RID());
}
}
}

void NavigationRegion2D::_region_update_transform() {
if (!is_inside_tree()) {
return;
}

Transform2D new_global_transform = get_global_transform();
if (current_global_transform != new_global_transform) {
current_global_transform = new_global_transform;
NavigationServer2D::get_singleton()->region_set_transform(region, current_global_transform);
for (uint32_t i = 0; i < constrain_avoidance_obstacles.size(); i++) {
if (constrain_avoidance_obstacles[i].is_valid()) {
NavigationServer2D::get_singleton()->obstacle_set_position(constrain_avoidance_obstacles[i], get_global_position());
}
}
}

queue_redraw();
}

#ifdef DEBUG_ENABLED
void NavigationRegion2D::_update_debug_mesh() {
Vector<Vector2> navigation_polygon_vertices = navigation_polygon->get_vertices();
Expand Down
7 changes: 7 additions & 0 deletions scene/2d/navigation_region_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class NavigationRegion2D : public Node2D {
bool use_edge_connections = true;

RID region;
RID map_override;
uint32_t navigation_layers = 1;
real_t enter_cost = 0.0;
real_t travel_cost = 1.0;
Expand Down Expand Up @@ -79,6 +80,9 @@ class NavigationRegion2D : public Node2D {
void set_enabled(bool p_enabled);
bool is_enabled() const;

void set_navigation_map(RID p_navigation_map);
RID get_navigation_map() const;

void set_use_edge_connections(bool p_enabled);
bool get_use_edge_connections() const;

Expand Down Expand Up @@ -115,6 +119,9 @@ class NavigationRegion2D : public Node2D {

private:
void _update_avoidance_constrain();
void _region_enter_navigation_map();
void _region_exit_navigation_map();
void _region_update_transform();
};

#endif // NAVIGATION_REGION_2D_H
Loading

0 comments on commit 84647ab

Please sign in to comment.