You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-15 13:51:40 +00:00
Make NavMap objects request sync only on demand
Replaces brute-force sync check loop with a self-listing system where each object is responsible for its own dirty sync, requesting it on demand only.
This commit is contained in:
@@ -32,9 +32,6 @@
|
|||||||
|
|
||||||
#include "nav_map.h"
|
#include "nav_map.h"
|
||||||
|
|
||||||
NavAgent::NavAgent() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void NavAgent::set_avoidance_enabled(bool p_enabled) {
|
void NavAgent::set_avoidance_enabled(bool p_enabled) {
|
||||||
avoidance_enabled = p_enabled;
|
avoidance_enabled = p_enabled;
|
||||||
_update_rvo_agent_properties();
|
_update_rvo_agent_properties();
|
||||||
@@ -87,6 +84,8 @@ void NavAgent::_update_rvo_agent_properties() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_map(NavMap *p_map) {
|
void NavAgent::set_map(NavMap *p_map) {
|
||||||
@@ -94,6 +93,8 @@ void NavAgent::set_map(NavMap *p_map) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancel_sync_request();
|
||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
map->remove_agent(this);
|
map->remove_agent(this);
|
||||||
}
|
}
|
||||||
@@ -106,6 +107,8 @@ void NavAgent::set_map(NavMap *p_map) {
|
|||||||
if (avoidance_enabled) {
|
if (avoidance_enabled) {
|
||||||
map->set_agent_as_controlled(this);
|
map->set_agent_as_controlled(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +159,8 @@ void NavAgent::set_neighbor_distance(real_t p_neighbor_distance) {
|
|||||||
rvo_agent_2d.neighborDist_ = neighbor_distance;
|
rvo_agent_2d.neighborDist_ = neighbor_distance;
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_max_neighbors(int p_max_neighbors) {
|
void NavAgent::set_max_neighbors(int p_max_neighbors) {
|
||||||
@@ -166,6 +171,8 @@ void NavAgent::set_max_neighbors(int p_max_neighbors) {
|
|||||||
rvo_agent_2d.maxNeighbors_ = max_neighbors;
|
rvo_agent_2d.maxNeighbors_ = max_neighbors;
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_time_horizon_agents(real_t p_time_horizon) {
|
void NavAgent::set_time_horizon_agents(real_t p_time_horizon) {
|
||||||
@@ -176,6 +183,8 @@ void NavAgent::set_time_horizon_agents(real_t p_time_horizon) {
|
|||||||
rvo_agent_2d.timeHorizon_ = time_horizon_agents;
|
rvo_agent_2d.timeHorizon_ = time_horizon_agents;
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_time_horizon_obstacles(real_t p_time_horizon) {
|
void NavAgent::set_time_horizon_obstacles(real_t p_time_horizon) {
|
||||||
@@ -186,6 +195,8 @@ void NavAgent::set_time_horizon_obstacles(real_t p_time_horizon) {
|
|||||||
rvo_agent_2d.timeHorizonObst_ = time_horizon_obstacles;
|
rvo_agent_2d.timeHorizonObst_ = time_horizon_obstacles;
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_radius(real_t p_radius) {
|
void NavAgent::set_radius(real_t p_radius) {
|
||||||
@@ -196,6 +207,8 @@ void NavAgent::set_radius(real_t p_radius) {
|
|||||||
rvo_agent_2d.radius_ = radius;
|
rvo_agent_2d.radius_ = radius;
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_height(real_t p_height) {
|
void NavAgent::set_height(real_t p_height) {
|
||||||
@@ -206,6 +219,8 @@ void NavAgent::set_height(real_t p_height) {
|
|||||||
rvo_agent_2d.height_ = height;
|
rvo_agent_2d.height_ = height;
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_max_speed(real_t p_max_speed) {
|
void NavAgent::set_max_speed(real_t p_max_speed) {
|
||||||
@@ -218,6 +233,8 @@ void NavAgent::set_max_speed(real_t p_max_speed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_position(const Vector3 p_position) {
|
void NavAgent::set_position(const Vector3 p_position) {
|
||||||
@@ -231,6 +248,8 @@ void NavAgent::set_position(const Vector3 p_position) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_target_position(const Vector3 p_target_position) {
|
void NavAgent::set_target_position(const Vector3 p_target_position) {
|
||||||
@@ -249,6 +268,8 @@ void NavAgent::set_velocity(const Vector3 p_velocity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_velocity_forced(const Vector3 p_velocity) {
|
void NavAgent::set_velocity_forced(const Vector3 p_velocity) {
|
||||||
@@ -265,6 +286,8 @@ void NavAgent::set_velocity_forced(const Vector3 p_velocity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::update() {
|
void NavAgent::update() {
|
||||||
@@ -286,6 +309,8 @@ void NavAgent::set_avoidance_mask(uint32_t p_mask) {
|
|||||||
rvo_agent_2d.avoidance_mask_ = avoidance_mask;
|
rvo_agent_2d.avoidance_mask_ = avoidance_mask;
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_avoidance_layers(uint32_t p_layers) {
|
void NavAgent::set_avoidance_layers(uint32_t p_layers) {
|
||||||
@@ -296,6 +321,8 @@ void NavAgent::set_avoidance_layers(uint32_t p_layers) {
|
|||||||
rvo_agent_2d.avoidance_layers_ = avoidance_layers;
|
rvo_agent_2d.avoidance_layers_ = avoidance_layers;
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavAgent::set_avoidance_priority(real_t p_priority) {
|
void NavAgent::set_avoidance_priority(real_t p_priority) {
|
||||||
@@ -308,12 +335,16 @@ void NavAgent::set_avoidance_priority(real_t p_priority) {
|
|||||||
rvo_agent_2d.avoidance_priority_ = avoidance_priority;
|
rvo_agent_2d.avoidance_priority_ = avoidance_priority;
|
||||||
}
|
}
|
||||||
agent_dirty = true;
|
agent_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NavAgent::check_dirty() {
|
bool NavAgent::is_dirty() const {
|
||||||
const bool was_dirty = agent_dirty;
|
return agent_dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavAgent::sync() {
|
||||||
agent_dirty = false;
|
agent_dirty = false;
|
||||||
return was_dirty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Dictionary NavAgent::get_avoidance_data() const {
|
const Dictionary NavAgent::get_avoidance_data() const {
|
||||||
@@ -372,3 +403,23 @@ void NavAgent::set_paused(bool p_paused) {
|
|||||||
bool NavAgent::get_paused() const {
|
bool NavAgent::get_paused() const {
|
||||||
return paused;
|
return paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavAgent::request_sync() {
|
||||||
|
if (map && !sync_dirty_request_list_element.in_list()) {
|
||||||
|
map->add_agent_sync_dirty_request(&sync_dirty_request_list_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavAgent::cancel_sync_request() {
|
||||||
|
if (map && sync_dirty_request_list_element.in_list()) {
|
||||||
|
map->remove_agent_sync_dirty_request(&sync_dirty_request_list_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NavAgent::NavAgent() :
|
||||||
|
sync_dirty_request_list_element(this) {
|
||||||
|
}
|
||||||
|
|
||||||
|
NavAgent::~NavAgent() {
|
||||||
|
cancel_sync_request();
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include "core/object/class_db.h"
|
#include "core/object/class_db.h"
|
||||||
#include "core/templates/local_vector.h"
|
#include "core/templates/local_vector.h"
|
||||||
|
#include "core/templates/self_list.h"
|
||||||
|
|
||||||
#include <Agent2d.h>
|
#include <Agent2d.h>
|
||||||
#include <Agent3d.h>
|
#include <Agent3d.h>
|
||||||
@@ -74,8 +75,11 @@ class NavAgent : public NavRid {
|
|||||||
uint32_t last_map_iteration_id = 0;
|
uint32_t last_map_iteration_id = 0;
|
||||||
bool paused = false;
|
bool paused = false;
|
||||||
|
|
||||||
|
SelfList<NavAgent> sync_dirty_request_list_element;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NavAgent();
|
NavAgent();
|
||||||
|
~NavAgent();
|
||||||
|
|
||||||
void set_avoidance_enabled(bool p_enabled);
|
void set_avoidance_enabled(bool p_enabled);
|
||||||
bool is_avoidance_enabled() { return avoidance_enabled; }
|
bool is_avoidance_enabled() { return avoidance_enabled; }
|
||||||
@@ -141,7 +145,10 @@ public:
|
|||||||
void set_paused(bool p_paused);
|
void set_paused(bool p_paused);
|
||||||
bool get_paused() const;
|
bool get_paused() const;
|
||||||
|
|
||||||
bool check_dirty();
|
bool is_dirty() const;
|
||||||
|
void sync();
|
||||||
|
void request_sync();
|
||||||
|
void cancel_sync_request();
|
||||||
|
|
||||||
// Updates this agent with rvo data after the rvo simulation avoidance step.
|
// Updates this agent with rvo data after the rvo simulation avoidance step.
|
||||||
void update();
|
void update();
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ void NavLink::set_map(NavMap *p_map) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancel_sync_request();
|
||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
map->remove_link(this);
|
map->remove_link(this);
|
||||||
}
|
}
|
||||||
@@ -46,6 +48,7 @@ void NavLink::set_map(NavMap *p_map) {
|
|||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
map->add_link(this);
|
map->add_link(this);
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +60,8 @@ void NavLink::set_enabled(bool p_enabled) {
|
|||||||
|
|
||||||
// TODO: This should not require a full rebuild as the link has not really changed.
|
// TODO: This should not require a full rebuild as the link has not really changed.
|
||||||
link_dirty = true;
|
link_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavLink::set_bidirectional(bool p_bidirectional) {
|
void NavLink::set_bidirectional(bool p_bidirectional) {
|
||||||
@@ -65,6 +70,8 @@ void NavLink::set_bidirectional(bool p_bidirectional) {
|
|||||||
}
|
}
|
||||||
bidirectional = p_bidirectional;
|
bidirectional = p_bidirectional;
|
||||||
link_dirty = true;
|
link_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavLink::set_start_position(const Vector3 p_position) {
|
void NavLink::set_start_position(const Vector3 p_position) {
|
||||||
@@ -73,6 +80,8 @@ void NavLink::set_start_position(const Vector3 p_position) {
|
|||||||
}
|
}
|
||||||
start_position = p_position;
|
start_position = p_position;
|
||||||
link_dirty = true;
|
link_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavLink::set_end_position(const Vector3 p_position) {
|
void NavLink::set_end_position(const Vector3 p_position) {
|
||||||
@@ -81,11 +90,35 @@ void NavLink::set_end_position(const Vector3 p_position) {
|
|||||||
}
|
}
|
||||||
end_position = p_position;
|
end_position = p_position;
|
||||||
link_dirty = true;
|
link_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NavLink::check_dirty() {
|
bool NavLink::is_dirty() const {
|
||||||
const bool was_dirty = link_dirty;
|
return link_dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavLink::sync() {
|
||||||
link_dirty = false;
|
link_dirty = false;
|
||||||
return was_dirty;
|
}
|
||||||
|
|
||||||
|
void NavLink::request_sync() {
|
||||||
|
if (map && !sync_dirty_request_list_element.in_list()) {
|
||||||
|
map->add_link_sync_dirty_request(&sync_dirty_request_list_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavLink::cancel_sync_request() {
|
||||||
|
if (map && sync_dirty_request_list_element.in_list()) {
|
||||||
|
map->remove_link_sync_dirty_request(&sync_dirty_request_list_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NavLink::NavLink() :
|
||||||
|
sync_dirty_request_list_element(this) {
|
||||||
|
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_LINK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NavLink::~NavLink() {
|
||||||
|
cancel_sync_request();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
#include "nav_base.h"
|
#include "nav_base.h"
|
||||||
#include "nav_utils.h"
|
#include "nav_utils.h"
|
||||||
|
|
||||||
|
#include "core/templates/self_list.h"
|
||||||
|
|
||||||
class NavLink : public NavBase {
|
class NavLink : public NavBase {
|
||||||
NavMap *map = nullptr;
|
NavMap *map = nullptr;
|
||||||
bool bidirectional = true;
|
bool bidirectional = true;
|
||||||
@@ -43,10 +45,11 @@ class NavLink : public NavBase {
|
|||||||
|
|
||||||
bool link_dirty = true;
|
bool link_dirty = true;
|
||||||
|
|
||||||
|
SelfList<NavLink> sync_dirty_request_list_element;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NavLink() {
|
NavLink();
|
||||||
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_LINK;
|
~NavLink();
|
||||||
}
|
|
||||||
|
|
||||||
void set_map(NavMap *p_map);
|
void set_map(NavMap *p_map);
|
||||||
NavMap *get_map() const {
|
NavMap *get_map() const {
|
||||||
@@ -71,7 +74,10 @@ public:
|
|||||||
return end_position;
|
return end_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_dirty();
|
bool is_dirty() const;
|
||||||
|
void sync();
|
||||||
|
void request_sync();
|
||||||
|
void cancel_sync_request();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NAV_LINK_H
|
#endif // NAV_LINK_H
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ void NavMap::set_up(Vector3 p_up) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
up = p_up;
|
up = p_up;
|
||||||
regenerate_polygons = true;
|
map_settings_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMap::set_cell_size(real_t p_cell_size) {
|
void NavMap::set_cell_size(real_t p_cell_size) {
|
||||||
@@ -65,7 +65,7 @@ void NavMap::set_cell_size(real_t p_cell_size) {
|
|||||||
}
|
}
|
||||||
cell_size = p_cell_size;
|
cell_size = p_cell_size;
|
||||||
_update_merge_rasterizer_cell_dimensions();
|
_update_merge_rasterizer_cell_dimensions();
|
||||||
regenerate_polygons = true;
|
map_settings_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMap::set_cell_height(real_t p_cell_height) {
|
void NavMap::set_cell_height(real_t p_cell_height) {
|
||||||
@@ -74,7 +74,7 @@ void NavMap::set_cell_height(real_t p_cell_height) {
|
|||||||
}
|
}
|
||||||
cell_height = p_cell_height;
|
cell_height = p_cell_height;
|
||||||
_update_merge_rasterizer_cell_dimensions();
|
_update_merge_rasterizer_cell_dimensions();
|
||||||
regenerate_polygons = true;
|
map_settings_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMap::set_merge_rasterizer_cell_scale(float p_value) {
|
void NavMap::set_merge_rasterizer_cell_scale(float p_value) {
|
||||||
@@ -83,7 +83,7 @@ void NavMap::set_merge_rasterizer_cell_scale(float p_value) {
|
|||||||
}
|
}
|
||||||
merge_rasterizer_cell_scale = p_value;
|
merge_rasterizer_cell_scale = p_value;
|
||||||
_update_merge_rasterizer_cell_dimensions();
|
_update_merge_rasterizer_cell_dimensions();
|
||||||
regenerate_polygons = true;
|
map_settings_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMap::set_use_edge_connections(bool p_enabled) {
|
void NavMap::set_use_edge_connections(bool p_enabled) {
|
||||||
@@ -91,7 +91,7 @@ void NavMap::set_use_edge_connections(bool p_enabled) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
use_edge_connections = p_enabled;
|
use_edge_connections = p_enabled;
|
||||||
regenerate_links = true;
|
iteration_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMap::set_edge_connection_margin(real_t p_edge_connection_margin) {
|
void NavMap::set_edge_connection_margin(real_t p_edge_connection_margin) {
|
||||||
@@ -99,7 +99,7 @@ void NavMap::set_edge_connection_margin(real_t p_edge_connection_margin) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
edge_connection_margin = p_edge_connection_margin;
|
edge_connection_margin = p_edge_connection_margin;
|
||||||
regenerate_links = true;
|
iteration_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMap::set_link_connection_radius(real_t p_link_connection_radius) {
|
void NavMap::set_link_connection_radius(real_t p_link_connection_radius) {
|
||||||
@@ -107,7 +107,7 @@ void NavMap::set_link_connection_radius(real_t p_link_connection_radius) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
link_connection_radius = p_link_connection_radius;
|
link_connection_radius = p_link_connection_radius;
|
||||||
regenerate_links = true;
|
iteration_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const {
|
gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const {
|
||||||
@@ -183,27 +183,27 @@ gd::ClosestPointQueryResult NavMap::get_closest_point_info(const Vector3 &p_poin
|
|||||||
|
|
||||||
void NavMap::add_region(NavRegion *p_region) {
|
void NavMap::add_region(NavRegion *p_region) {
|
||||||
regions.push_back(p_region);
|
regions.push_back(p_region);
|
||||||
regenerate_links = true;
|
iteration_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMap::remove_region(NavRegion *p_region) {
|
void NavMap::remove_region(NavRegion *p_region) {
|
||||||
int64_t region_index = regions.find(p_region);
|
int64_t region_index = regions.find(p_region);
|
||||||
if (region_index >= 0) {
|
if (region_index >= 0) {
|
||||||
regions.remove_at_unordered(region_index);
|
regions.remove_at_unordered(region_index);
|
||||||
regenerate_links = true;
|
iteration_dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMap::add_link(NavLink *p_link) {
|
void NavMap::add_link(NavLink *p_link) {
|
||||||
links.push_back(p_link);
|
links.push_back(p_link);
|
||||||
regenerate_links = true;
|
iteration_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMap::remove_link(NavLink *p_link) {
|
void NavMap::remove_link(NavLink *p_link) {
|
||||||
int64_t link_index = links.find(p_link);
|
int64_t link_index = links.find(p_link);
|
||||||
if (link_index >= 0) {
|
if (link_index >= 0) {
|
||||||
links.remove_at_unordered(link_index);
|
links.remove_at_unordered(link_index);
|
||||||
regenerate_links = true;
|
iteration_dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,27 +361,9 @@ void NavMap::sync() {
|
|||||||
performance_data.pm_link_count = links.size();
|
performance_data.pm_link_count = links.size();
|
||||||
performance_data.pm_obstacle_count = obstacles.size();
|
performance_data.pm_obstacle_count = obstacles.size();
|
||||||
|
|
||||||
// Check if we need to update the links.
|
_sync_dirty_map_update_requests();
|
||||||
if (regenerate_polygons) {
|
|
||||||
for (NavRegion *region : regions) {
|
|
||||||
region->scratch_polygons();
|
|
||||||
}
|
|
||||||
regenerate_links = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (NavRegion *region : regions) {
|
if (iteration_dirty) {
|
||||||
if (region->sync()) {
|
|
||||||
regenerate_links = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (NavLink *link : links) {
|
|
||||||
if (link->check_dirty()) {
|
|
||||||
regenerate_links = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (regenerate_links) {
|
|
||||||
performance_data.pm_polygon_count = 0;
|
performance_data.pm_polygon_count = 0;
|
||||||
performance_data.pm_edge_count = 0;
|
performance_data.pm_edge_count = 0;
|
||||||
performance_data.pm_edge_merge_count = 0;
|
performance_data.pm_edge_merge_count = 0;
|
||||||
@@ -659,26 +641,19 @@ void NavMap::sync() {
|
|||||||
iteration_id = iteration_id % UINT32_MAX + 1;
|
iteration_id = iteration_id % UINT32_MAX + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we have modified obstacle positions?
|
map_settings_dirty = false;
|
||||||
for (NavObstacle *obstacle : obstacles) {
|
iteration_dirty = false;
|
||||||
if (obstacle->check_dirty()) {
|
|
||||||
obstacles_dirty = true;
|
_sync_avoidance();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Do we have modified agent arrays?
|
void NavMap::_sync_avoidance() {
|
||||||
for (NavAgent *agent : agents) {
|
_sync_dirty_avoidance_update_requests();
|
||||||
if (agent->check_dirty()) {
|
|
||||||
agents_dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update avoidance worlds.
|
|
||||||
if (obstacles_dirty || agents_dirty) {
|
if (obstacles_dirty || agents_dirty) {
|
||||||
_update_rvo_simulation();
|
_update_rvo_simulation();
|
||||||
}
|
}
|
||||||
|
|
||||||
regenerate_polygons = false;
|
|
||||||
regenerate_links = false;
|
|
||||||
obstacles_dirty = false;
|
obstacles_dirty = false;
|
||||||
agents_dirty = false;
|
agents_dirty = false;
|
||||||
}
|
}
|
||||||
@@ -889,6 +864,104 @@ Vector3 NavMap::get_region_connection_pathway_end(NavRegion *p_region, int p_con
|
|||||||
return Vector3();
|
return Vector3();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavMap::add_region_sync_dirty_request(SelfList<NavRegion> *p_sync_request) {
|
||||||
|
if (p_sync_request->in_list()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sync_dirty_requests.regions.add(p_sync_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMap::add_link_sync_dirty_request(SelfList<NavLink> *p_sync_request) {
|
||||||
|
if (p_sync_request->in_list()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sync_dirty_requests.links.add(p_sync_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMap::add_agent_sync_dirty_request(SelfList<NavAgent> *p_sync_request) {
|
||||||
|
if (p_sync_request->in_list()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sync_dirty_requests.agents.add(p_sync_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMap::add_obstacle_sync_dirty_request(SelfList<NavObstacle> *p_sync_request) {
|
||||||
|
if (p_sync_request->in_list()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sync_dirty_requests.obstacles.add(p_sync_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMap::remove_region_sync_dirty_request(SelfList<NavRegion> *p_sync_request) {
|
||||||
|
if (!p_sync_request->in_list()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sync_dirty_requests.regions.remove(p_sync_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMap::remove_link_sync_dirty_request(SelfList<NavLink> *p_sync_request) {
|
||||||
|
if (!p_sync_request->in_list()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sync_dirty_requests.links.remove(p_sync_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMap::remove_agent_sync_dirty_request(SelfList<NavAgent> *p_sync_request) {
|
||||||
|
if (!p_sync_request->in_list()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sync_dirty_requests.agents.remove(p_sync_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMap::remove_obstacle_sync_dirty_request(SelfList<NavObstacle> *p_sync_request) {
|
||||||
|
if (!p_sync_request->in_list()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sync_dirty_requests.obstacles.remove(p_sync_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMap::_sync_dirty_map_update_requests() {
|
||||||
|
// If entire map settings changed make all regions dirty.
|
||||||
|
if (map_settings_dirty) {
|
||||||
|
for (NavRegion *region : regions) {
|
||||||
|
region->scratch_polygons();
|
||||||
|
}
|
||||||
|
iteration_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iteration_dirty) {
|
||||||
|
iteration_dirty = sync_dirty_requests.regions.first() || sync_dirty_requests.links.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync NavRegions.
|
||||||
|
for (SelfList<NavRegion> *element = sync_dirty_requests.regions.first(); element; element = element->next()) {
|
||||||
|
element->self()->sync();
|
||||||
|
}
|
||||||
|
sync_dirty_requests.regions.clear();
|
||||||
|
|
||||||
|
// Sync NavLinks.
|
||||||
|
for (SelfList<NavLink> *element = sync_dirty_requests.links.first(); element; element = element->next()) {
|
||||||
|
element->self()->sync();
|
||||||
|
}
|
||||||
|
sync_dirty_requests.links.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMap::_sync_dirty_avoidance_update_requests() {
|
||||||
|
// Sync NavAgents.
|
||||||
|
agents_dirty = sync_dirty_requests.agents.first();
|
||||||
|
for (SelfList<NavAgent> *element = sync_dirty_requests.agents.first(); element; element = element->next()) {
|
||||||
|
element->self()->sync();
|
||||||
|
}
|
||||||
|
sync_dirty_requests.agents.clear();
|
||||||
|
|
||||||
|
// Sync NavObstacles.
|
||||||
|
obstacles_dirty = sync_dirty_requests.obstacles.first();
|
||||||
|
for (SelfList<NavObstacle> *element = sync_dirty_requests.obstacles.first(); element; element = element->next()) {
|
||||||
|
element->self()->sync();
|
||||||
|
}
|
||||||
|
sync_dirty_requests.obstacles.clear();
|
||||||
|
}
|
||||||
|
|
||||||
NavMap::NavMap() {
|
NavMap::NavMap() {
|
||||||
avoidance_use_multiple_threads = GLOBAL_GET("navigation/avoidance/thread_model/avoidance_use_multiple_threads");
|
avoidance_use_multiple_threads = GLOBAL_GET("navigation/avoidance/thread_model/avoidance_use_multiple_threads");
|
||||||
avoidance_use_high_priority_threads = GLOBAL_GET("navigation/avoidance/thread_model/avoidance_use_high_priority_threads");
|
avoidance_use_high_priority_threads = GLOBAL_GET("navigation/avoidance/thread_model/avoidance_use_high_priority_threads");
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ class NavMap : public NavRid {
|
|||||||
/// This value is used to limit how far links search to find polygons to connect to.
|
/// This value is used to limit how far links search to find polygons to connect to.
|
||||||
real_t link_connection_radius = NavigationDefaults3D::link_connection_radius;
|
real_t link_connection_radius = NavigationDefaults3D::link_connection_radius;
|
||||||
|
|
||||||
bool regenerate_polygons = true;
|
bool map_settings_dirty = true;
|
||||||
bool regenerate_links = true;
|
bool iteration_dirty = true;
|
||||||
|
|
||||||
/// Map regions
|
/// Map regions
|
||||||
LocalVector<NavRegion *> regions;
|
LocalVector<NavRegion *> regions;
|
||||||
@@ -128,6 +128,13 @@ class NavMap : public NavRid {
|
|||||||
HashMap<gd::EdgeKey, ConnectionPair, gd::EdgeKey> connection_pairs_map;
|
HashMap<gd::EdgeKey, ConnectionPair, gd::EdgeKey> connection_pairs_map;
|
||||||
LocalVector<gd::Edge::Connection> free_edges;
|
LocalVector<gd::Edge::Connection> free_edges;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
SelfList<NavRegion>::List regions;
|
||||||
|
SelfList<NavLink>::List links;
|
||||||
|
SelfList<NavAgent>::List agents;
|
||||||
|
SelfList<NavObstacle>::List obstacles;
|
||||||
|
} sync_dirty_requests;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NavMap();
|
NavMap();
|
||||||
~NavMap();
|
~NavMap();
|
||||||
@@ -226,12 +233,26 @@ public:
|
|||||||
Vector3 get_region_connection_pathway_start(NavRegion *p_region, int p_connection_id) const;
|
Vector3 get_region_connection_pathway_start(NavRegion *p_region, int p_connection_id) const;
|
||||||
Vector3 get_region_connection_pathway_end(NavRegion *p_region, int p_connection_id) const;
|
Vector3 get_region_connection_pathway_end(NavRegion *p_region, int p_connection_id) const;
|
||||||
|
|
||||||
|
void add_region_sync_dirty_request(SelfList<NavRegion> *p_sync_request);
|
||||||
|
void add_link_sync_dirty_request(SelfList<NavLink> *p_sync_request);
|
||||||
|
void add_agent_sync_dirty_request(SelfList<NavAgent> *p_sync_request);
|
||||||
|
void add_obstacle_sync_dirty_request(SelfList<NavObstacle> *p_sync_request);
|
||||||
|
|
||||||
|
void remove_region_sync_dirty_request(SelfList<NavRegion> *p_sync_request);
|
||||||
|
void remove_link_sync_dirty_request(SelfList<NavLink> *p_sync_request);
|
||||||
|
void remove_agent_sync_dirty_request(SelfList<NavAgent> *p_sync_request);
|
||||||
|
void remove_obstacle_sync_dirty_request(SelfList<NavObstacle> *p_sync_request);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _sync_dirty_map_update_requests();
|
||||||
|
void _sync_dirty_avoidance_update_requests();
|
||||||
|
|
||||||
void compute_single_step(uint32_t index, NavAgent **agent);
|
void compute_single_step(uint32_t index, NavAgent **agent);
|
||||||
|
|
||||||
void compute_single_avoidance_step_2d(uint32_t index, NavAgent **agent);
|
void compute_single_avoidance_step_2d(uint32_t index, NavAgent **agent);
|
||||||
void compute_single_avoidance_step_3d(uint32_t index, NavAgent **agent);
|
void compute_single_avoidance_step_3d(uint32_t index, NavAgent **agent);
|
||||||
|
|
||||||
|
void _sync_avoidance();
|
||||||
void _update_rvo_simulation();
|
void _update_rvo_simulation();
|
||||||
void _update_rvo_obstacles_tree_2d();
|
void _update_rvo_obstacles_tree_2d();
|
||||||
void _update_rvo_agents_tree_2d();
|
void _update_rvo_agents_tree_2d();
|
||||||
|
|||||||
@@ -33,10 +33,6 @@
|
|||||||
#include "nav_agent.h"
|
#include "nav_agent.h"
|
||||||
#include "nav_map.h"
|
#include "nav_map.h"
|
||||||
|
|
||||||
NavObstacle::NavObstacle() {}
|
|
||||||
|
|
||||||
NavObstacle::~NavObstacle() {}
|
|
||||||
|
|
||||||
void NavObstacle::set_agent(NavAgent *p_agent) {
|
void NavObstacle::set_agent(NavAgent *p_agent) {
|
||||||
if (agent == p_agent) {
|
if (agent == p_agent) {
|
||||||
return;
|
return;
|
||||||
@@ -45,6 +41,8 @@ void NavObstacle::set_agent(NavAgent *p_agent) {
|
|||||||
agent = p_agent;
|
agent = p_agent;
|
||||||
|
|
||||||
internal_update_agent();
|
internal_update_agent();
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavObstacle::set_avoidance_enabled(bool p_enabled) {
|
void NavObstacle::set_avoidance_enabled(bool p_enabled) {
|
||||||
@@ -56,6 +54,8 @@ void NavObstacle::set_avoidance_enabled(bool p_enabled) {
|
|||||||
obstacle_dirty = true;
|
obstacle_dirty = true;
|
||||||
|
|
||||||
internal_update_agent();
|
internal_update_agent();
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavObstacle::set_use_3d_avoidance(bool p_enabled) {
|
void NavObstacle::set_use_3d_avoidance(bool p_enabled) {
|
||||||
@@ -69,6 +69,8 @@ void NavObstacle::set_use_3d_avoidance(bool p_enabled) {
|
|||||||
if (agent) {
|
if (agent) {
|
||||||
agent->set_use_3d_avoidance(use_3d_avoidance);
|
agent->set_use_3d_avoidance(use_3d_avoidance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavObstacle::set_map(NavMap *p_map) {
|
void NavObstacle::set_map(NavMap *p_map) {
|
||||||
@@ -76,6 +78,8 @@ void NavObstacle::set_map(NavMap *p_map) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancel_sync_request();
|
||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
map->remove_obstacle(this);
|
map->remove_obstacle(this);
|
||||||
if (agent) {
|
if (agent) {
|
||||||
@@ -89,6 +93,8 @@ void NavObstacle::set_map(NavMap *p_map) {
|
|||||||
if (map) {
|
if (map) {
|
||||||
map->add_obstacle(this);
|
map->add_obstacle(this);
|
||||||
internal_update_agent();
|
internal_update_agent();
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +109,8 @@ void NavObstacle::set_position(const Vector3 p_position) {
|
|||||||
if (agent) {
|
if (agent) {
|
||||||
agent->set_position(position);
|
agent->set_position(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavObstacle::set_radius(real_t p_radius) {
|
void NavObstacle::set_radius(real_t p_radius) {
|
||||||
@@ -128,6 +136,8 @@ void NavObstacle::set_height(const real_t p_height) {
|
|||||||
if (agent) {
|
if (agent) {
|
||||||
agent->set_height(height);
|
agent->set_height(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavObstacle::set_velocity(const Vector3 p_velocity) {
|
void NavObstacle::set_velocity(const Vector3 p_velocity) {
|
||||||
@@ -145,6 +155,8 @@ void NavObstacle::set_vertices(const Vector<Vector3> &p_vertices) {
|
|||||||
|
|
||||||
vertices = p_vertices;
|
vertices = p_vertices;
|
||||||
obstacle_dirty = true;
|
obstacle_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NavObstacle::is_map_changed() {
|
bool NavObstacle::is_map_changed() {
|
||||||
@@ -168,12 +180,16 @@ void NavObstacle::set_avoidance_layers(uint32_t p_layers) {
|
|||||||
if (agent) {
|
if (agent) {
|
||||||
agent->set_avoidance_layers(avoidance_layers);
|
agent->set_avoidance_layers(avoidance_layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NavObstacle::check_dirty() {
|
bool NavObstacle::is_dirty() const {
|
||||||
const bool was_dirty = obstacle_dirty;
|
return obstacle_dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavObstacle::sync() {
|
||||||
obstacle_dirty = false;
|
obstacle_dirty = false;
|
||||||
return was_dirty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavObstacle::internal_update_agent() {
|
void NavObstacle::internal_update_agent() {
|
||||||
@@ -216,3 +232,23 @@ void NavObstacle::set_paused(bool p_paused) {
|
|||||||
bool NavObstacle::get_paused() const {
|
bool NavObstacle::get_paused() const {
|
||||||
return paused;
|
return paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavObstacle::request_sync() {
|
||||||
|
if (map && !sync_dirty_request_list_element.in_list()) {
|
||||||
|
map->add_obstacle_sync_dirty_request(&sync_dirty_request_list_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavObstacle::cancel_sync_request() {
|
||||||
|
if (map && sync_dirty_request_list_element.in_list()) {
|
||||||
|
map->remove_obstacle_sync_dirty_request(&sync_dirty_request_list_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NavObstacle::NavObstacle() :
|
||||||
|
sync_dirty_request_list_element(this) {
|
||||||
|
}
|
||||||
|
|
||||||
|
NavObstacle::~NavObstacle() {
|
||||||
|
cancel_sync_request();
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include "core/object/class_db.h"
|
#include "core/object/class_db.h"
|
||||||
#include "core/templates/local_vector.h"
|
#include "core/templates/local_vector.h"
|
||||||
|
#include "core/templates/self_list.h"
|
||||||
|
|
||||||
class NavAgent;
|
class NavAgent;
|
||||||
class NavMap;
|
class NavMap;
|
||||||
@@ -58,6 +59,8 @@ class NavObstacle : public NavRid {
|
|||||||
uint32_t last_map_iteration_id = 0;
|
uint32_t last_map_iteration_id = 0;
|
||||||
bool paused = false;
|
bool paused = false;
|
||||||
|
|
||||||
|
SelfList<NavObstacle> sync_dirty_request_list_element;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NavObstacle();
|
NavObstacle();
|
||||||
~NavObstacle();
|
~NavObstacle();
|
||||||
@@ -97,7 +100,10 @@ public:
|
|||||||
void set_paused(bool p_paused);
|
void set_paused(bool p_paused);
|
||||||
bool get_paused() const;
|
bool get_paused() const;
|
||||||
|
|
||||||
bool check_dirty();
|
bool is_dirty() const;
|
||||||
|
void sync();
|
||||||
|
void request_sync();
|
||||||
|
void cancel_sync_request();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void internal_update_agent();
|
void internal_update_agent();
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ void NavRegion::set_map(NavMap *p_map) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancel_sync_request();
|
||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
map->remove_region(this);
|
map->remove_region(this);
|
||||||
}
|
}
|
||||||
@@ -48,6 +50,7 @@ void NavRegion::set_map(NavMap *p_map) {
|
|||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
map->add_region(this);
|
map->add_region(this);
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +62,8 @@ void NavRegion::set_enabled(bool p_enabled) {
|
|||||||
|
|
||||||
// TODO: This should not require a full rebuild as the region has not really changed.
|
// TODO: This should not require a full rebuild as the region has not really changed.
|
||||||
polygons_dirty = true;
|
polygons_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavRegion::set_use_edge_connections(bool p_enabled) {
|
void NavRegion::set_use_edge_connections(bool p_enabled) {
|
||||||
@@ -66,6 +71,8 @@ void NavRegion::set_use_edge_connections(bool p_enabled) {
|
|||||||
use_edge_connections = p_enabled;
|
use_edge_connections = p_enabled;
|
||||||
polygons_dirty = true;
|
polygons_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavRegion::set_transform(Transform3D p_transform) {
|
void NavRegion::set_transform(Transform3D p_transform) {
|
||||||
@@ -75,6 +82,8 @@ void NavRegion::set_transform(Transform3D p_transform) {
|
|||||||
transform = p_transform;
|
transform = p_transform;
|
||||||
polygons_dirty = true;
|
polygons_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (map && Math::rad_to_deg(map->get_up().angle_to(transform.basis.get_column(1))) >= 90.0f) {
|
if (map && Math::rad_to_deg(map->get_up().angle_to(transform.basis.get_column(1))) >= 90.0f) {
|
||||||
ERR_PRINT_ONCE("Attempted to update a navigation region transform rotated 90 degrees or more away from the current navigation map UP orientation.");
|
ERR_PRINT_ONCE("Attempted to update a navigation region transform rotated 90 degrees or more away from the current navigation map UP orientation.");
|
||||||
@@ -103,6 +112,8 @@ void NavRegion::set_navigation_mesh(Ref<NavigationMesh> p_navigation_mesh) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
polygons_dirty = true;
|
polygons_dirty = true;
|
||||||
|
|
||||||
|
request_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 NavRegion::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision) const {
|
Vector3 NavRegion::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision) const {
|
||||||
@@ -220,3 +231,24 @@ void NavRegion::update_polygons() {
|
|||||||
|
|
||||||
surface_area = _new_region_surface_area;
|
surface_area = _new_region_surface_area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavRegion::request_sync() {
|
||||||
|
if (map && !sync_dirty_request_list_element.in_list()) {
|
||||||
|
map->add_region_sync_dirty_request(&sync_dirty_request_list_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavRegion::cancel_sync_request() {
|
||||||
|
if (map && sync_dirty_request_list_element.in_list()) {
|
||||||
|
map->remove_region_sync_dirty_request(&sync_dirty_request_list_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NavRegion::NavRegion() :
|
||||||
|
sync_dirty_request_list_element(this) {
|
||||||
|
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_REGION;
|
||||||
|
}
|
||||||
|
|
||||||
|
NavRegion::~NavRegion() {
|
||||||
|
cancel_sync_request();
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,10 +57,11 @@ class NavRegion : public NavBase {
|
|||||||
Vector<Vector3> pending_navmesh_vertices;
|
Vector<Vector3> pending_navmesh_vertices;
|
||||||
Vector<Vector<int>> pending_navmesh_polygons;
|
Vector<Vector<int>> pending_navmesh_polygons;
|
||||||
|
|
||||||
|
SelfList<NavRegion> sync_dirty_request_list_element;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NavRegion() {
|
NavRegion();
|
||||||
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_REGION;
|
~NavRegion();
|
||||||
}
|
|
||||||
|
|
||||||
void scratch_polygons() {
|
void scratch_polygons() {
|
||||||
polygons_dirty = true;
|
polygons_dirty = true;
|
||||||
@@ -97,6 +98,8 @@ public:
|
|||||||
real_t get_surface_area() const { return surface_area; }
|
real_t get_surface_area() const { return surface_area; }
|
||||||
|
|
||||||
bool sync();
|
bool sync();
|
||||||
|
void request_sync();
|
||||||
|
void cancel_sync_request();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update_polygons();
|
void update_polygons();
|
||||||
|
|||||||
Reference in New Issue
Block a user