Update navigation obstacle API
Updates navigation obstacle API.
This commit is contained in:
@ -802,9 +802,44 @@ RID GodotNavigationServer::obstacle_create() {
|
||||
RID rid = obstacle_owner.make_rid();
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(rid);
|
||||
obstacle->set_self(rid);
|
||||
|
||||
RID agent_rid = agent_owner.make_rid();
|
||||
NavAgent *agent = agent_owner.get_or_null(agent_rid);
|
||||
agent->set_self(agent_rid);
|
||||
|
||||
obstacle->set_agent(agent);
|
||||
|
||||
return rid;
|
||||
}
|
||||
|
||||
COMMAND_2(obstacle_set_avoidance_enabled, RID, p_obstacle, bool, p_enabled) {
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle);
|
||||
ERR_FAIL_COND(obstacle == nullptr);
|
||||
|
||||
obstacle->set_avoidance_enabled(p_enabled);
|
||||
}
|
||||
|
||||
bool GodotNavigationServer::obstacle_get_avoidance_enabled(RID p_obstacle) const {
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle);
|
||||
ERR_FAIL_COND_V(obstacle == nullptr, false);
|
||||
|
||||
return obstacle->is_avoidance_enabled();
|
||||
}
|
||||
|
||||
COMMAND_2(obstacle_set_use_3d_avoidance, RID, p_obstacle, bool, p_enabled) {
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle);
|
||||
ERR_FAIL_COND(obstacle == nullptr);
|
||||
|
||||
obstacle->set_use_3d_avoidance(p_enabled);
|
||||
}
|
||||
|
||||
bool GodotNavigationServer::obstacle_get_use_3d_avoidance(RID p_obstacle) const {
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle);
|
||||
ERR_FAIL_COND_V(obstacle == nullptr, false);
|
||||
|
||||
return obstacle->get_use_3d_avoidance();
|
||||
}
|
||||
|
||||
COMMAND_2(obstacle_set_map, RID, p_obstacle, RID, p_map) {
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle);
|
||||
ERR_FAIL_COND(obstacle == nullptr);
|
||||
@ -837,12 +872,27 @@ RID GodotNavigationServer::obstacle_get_map(RID p_obstacle) const {
|
||||
return RID();
|
||||
}
|
||||
|
||||
COMMAND_2(obstacle_set_radius, RID, p_obstacle, real_t, p_radius) {
|
||||
ERR_FAIL_COND_MSG(p_radius < 0.0, "Radius must be positive.");
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle);
|
||||
ERR_FAIL_COND(obstacle == nullptr);
|
||||
|
||||
obstacle->set_radius(p_radius);
|
||||
}
|
||||
|
||||
COMMAND_2(obstacle_set_height, RID, p_obstacle, real_t, p_height) {
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle);
|
||||
ERR_FAIL_COND(obstacle == nullptr);
|
||||
obstacle->set_height(p_height);
|
||||
}
|
||||
|
||||
COMMAND_2(obstacle_set_velocity, RID, p_obstacle, Vector3, p_velocity) {
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle);
|
||||
ERR_FAIL_COND(obstacle == nullptr);
|
||||
|
||||
obstacle->set_velocity(p_velocity);
|
||||
}
|
||||
|
||||
COMMAND_2(obstacle_set_position, RID, p_obstacle, Vector3, p_position) {
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle);
|
||||
ERR_FAIL_COND(obstacle == nullptr);
|
||||
@ -917,29 +967,42 @@ COMMAND_1(free, RID, p_object) {
|
||||
link_owner.free(p_object);
|
||||
|
||||
} else if (agent_owner.owns(p_object)) {
|
||||
NavAgent *agent = agent_owner.get_or_null(p_object);
|
||||
internal_free_agent(p_object);
|
||||
|
||||
// Removes this agent from the map if assigned
|
||||
} else if (obstacle_owner.owns(p_object)) {
|
||||
internal_free_obstacle(p_object);
|
||||
|
||||
} else {
|
||||
ERR_PRINT("Attempted to free a NavigationServer RID that did not exist (or was already freed).");
|
||||
}
|
||||
}
|
||||
|
||||
void GodotNavigationServer::internal_free_agent(RID p_object) {
|
||||
NavAgent *agent = agent_owner.get_or_null(p_object);
|
||||
if (agent) {
|
||||
if (agent->get_map() != nullptr) {
|
||||
agent->get_map()->remove_agent(agent);
|
||||
agent->set_map(nullptr);
|
||||
}
|
||||
|
||||
agent_owner.free(p_object);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (obstacle_owner.owns(p_object)) {
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_object);
|
||||
|
||||
// Removes this agent from the map if assigned
|
||||
void GodotNavigationServer::internal_free_obstacle(RID p_object) {
|
||||
NavObstacle *obstacle = obstacle_owner.get_or_null(p_object);
|
||||
if (obstacle) {
|
||||
if (obstacle->get_map() != nullptr) {
|
||||
obstacle->get_map()->remove_obstacle(obstacle);
|
||||
obstacle->set_map(nullptr);
|
||||
}
|
||||
|
||||
if (obstacle->get_agent()) {
|
||||
if (obstacle->get_agent()->get_self() != RID()) {
|
||||
RID _agent_rid = obstacle->get_agent()->get_self();
|
||||
obstacle->set_agent(nullptr);
|
||||
internal_free_agent(_agent_rid);
|
||||
}
|
||||
}
|
||||
obstacle_owner.free(p_object);
|
||||
|
||||
} else {
|
||||
ERR_PRINT("Attempted to free a NavigationServer RID that did not exist (or was already freed).");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -198,8 +198,14 @@ public:
|
||||
COMMAND_2(agent_set_avoidance_priority, RID, p_agent, real_t, p_priority);
|
||||
|
||||
virtual RID obstacle_create() override;
|
||||
COMMAND_2(obstacle_set_avoidance_enabled, RID, p_obstacle, bool, p_enabled);
|
||||
virtual bool obstacle_get_avoidance_enabled(RID p_obstacle) const override;
|
||||
COMMAND_2(obstacle_set_use_3d_avoidance, RID, p_obstacle, bool, p_enabled);
|
||||
virtual bool obstacle_get_use_3d_avoidance(RID p_obstacle) const override;
|
||||
COMMAND_2(obstacle_set_map, RID, p_obstacle, RID, p_map);
|
||||
virtual RID obstacle_get_map(RID p_obstacle) const override;
|
||||
COMMAND_2(obstacle_set_radius, RID, p_obstacle, real_t, p_radius);
|
||||
COMMAND_2(obstacle_set_velocity, RID, p_obstacle, Vector3, p_velocity);
|
||||
COMMAND_2(obstacle_set_position, RID, p_obstacle, Vector3, p_position);
|
||||
COMMAND_2(obstacle_set_height, RID, p_obstacle, real_t, p_height);
|
||||
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices) override;
|
||||
@ -215,6 +221,10 @@ public:
|
||||
virtual NavigationUtilities::PathQueryResult _query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const override;
|
||||
|
||||
int get_process_info(ProcessInfo p_info) const override;
|
||||
|
||||
private:
|
||||
void internal_free_agent(RID p_object);
|
||||
void internal_free_obstacle(RID p_object);
|
||||
};
|
||||
|
||||
#undef COMMAND_1
|
||||
|
||||
@ -30,38 +30,121 @@
|
||||
|
||||
#include "nav_obstacle.h"
|
||||
|
||||
#include "nav_agent.h"
|
||||
#include "nav_map.h"
|
||||
|
||||
NavObstacle::NavObstacle() {}
|
||||
|
||||
NavObstacle::~NavObstacle() {}
|
||||
|
||||
void NavObstacle::set_agent(NavAgent *p_agent) {
|
||||
if (agent == p_agent) {
|
||||
return;
|
||||
}
|
||||
|
||||
agent = p_agent;
|
||||
|
||||
internal_update_agent();
|
||||
}
|
||||
|
||||
void NavObstacle::set_avoidance_enabled(bool p_enabled) {
|
||||
if (avoidance_enabled == p_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
avoidance_enabled = p_enabled;
|
||||
obstacle_dirty = true;
|
||||
|
||||
internal_update_agent();
|
||||
}
|
||||
|
||||
void NavObstacle::set_use_3d_avoidance(bool p_enabled) {
|
||||
if (use_3d_avoidance == p_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
use_3d_avoidance = p_enabled;
|
||||
obstacle_dirty = true;
|
||||
|
||||
if (agent) {
|
||||
agent->set_use_3d_avoidance(use_3d_avoidance);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_map(NavMap *p_map) {
|
||||
if (map != p_map) {
|
||||
map = p_map;
|
||||
obstacle_dirty = true;
|
||||
if (map == p_map) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (map) {
|
||||
map->remove_obstacle(this);
|
||||
if (agent) {
|
||||
agent->set_map(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
map = p_map;
|
||||
obstacle_dirty = true;
|
||||
|
||||
if (map) {
|
||||
map->add_obstacle(this);
|
||||
internal_update_agent();
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_position(const Vector3 p_position) {
|
||||
if (position != p_position) {
|
||||
position = p_position;
|
||||
obstacle_dirty = true;
|
||||
if (position == p_position) {
|
||||
return;
|
||||
}
|
||||
|
||||
position = p_position;
|
||||
obstacle_dirty = true;
|
||||
|
||||
if (agent) {
|
||||
agent->set_position(position);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_radius(real_t p_radius) {
|
||||
if (radius == p_radius) {
|
||||
return;
|
||||
}
|
||||
|
||||
radius = p_radius;
|
||||
|
||||
if (agent) {
|
||||
agent->set_radius(radius);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_height(const real_t p_height) {
|
||||
if (height != p_height) {
|
||||
height = p_height;
|
||||
obstacle_dirty = true;
|
||||
if (height == p_height) {
|
||||
return;
|
||||
}
|
||||
|
||||
height = p_height;
|
||||
obstacle_dirty = true;
|
||||
|
||||
if (agent) {
|
||||
agent->set_height(height);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_velocity(const Vector3 p_velocity) {
|
||||
velocity = p_velocity;
|
||||
|
||||
if (agent) {
|
||||
agent->set_velocity(velocity);
|
||||
}
|
||||
}
|
||||
|
||||
void NavObstacle::set_vertices(const Vector<Vector3> &p_vertices) {
|
||||
if (vertices != p_vertices) {
|
||||
vertices = p_vertices;
|
||||
obstacle_dirty = true;
|
||||
if (vertices == p_vertices) {
|
||||
return;
|
||||
}
|
||||
|
||||
vertices = p_vertices;
|
||||
obstacle_dirty = true;
|
||||
}
|
||||
|
||||
bool NavObstacle::is_map_changed() {
|
||||
@ -75,8 +158,16 @@ bool NavObstacle::is_map_changed() {
|
||||
}
|
||||
|
||||
void NavObstacle::set_avoidance_layers(uint32_t p_layers) {
|
||||
if (avoidance_layers == p_layers) {
|
||||
return;
|
||||
}
|
||||
|
||||
avoidance_layers = p_layers;
|
||||
obstacle_dirty = true;
|
||||
|
||||
if (agent) {
|
||||
agent->set_avoidance_layers(avoidance_layers);
|
||||
}
|
||||
}
|
||||
|
||||
bool NavObstacle::check_dirty() {
|
||||
@ -84,3 +175,22 @@ bool NavObstacle::check_dirty() {
|
||||
obstacle_dirty = false;
|
||||
return was_dirty;
|
||||
}
|
||||
|
||||
void NavObstacle::internal_update_agent() {
|
||||
if (agent) {
|
||||
agent->set_neighbor_distance(0.0);
|
||||
agent->set_max_neighbors(0.0);
|
||||
agent->set_time_horizon_agents(0.0);
|
||||
agent->set_time_horizon_obstacles(0.0);
|
||||
agent->set_avoidance_mask(0.0);
|
||||
agent->set_neighbor_distance(0.0);
|
||||
agent->set_avoidance_priority(1.0);
|
||||
agent->set_map(map);
|
||||
agent->set_radius(radius);
|
||||
agent->set_height(height);
|
||||
agent->set_position(position);
|
||||
agent->set_avoidance_layers(avoidance_layers);
|
||||
agent->set_avoidance_enabled(avoidance_enabled);
|
||||
agent->set_use_3d_avoidance(use_3d_avoidance);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,18 +33,23 @@
|
||||
|
||||
#include "core/object/class_db.h"
|
||||
#include "core/templates/local_vector.h"
|
||||
#include "nav_agent.h"
|
||||
#include "nav_rid.h"
|
||||
|
||||
class NavAgent;
|
||||
class NavMap;
|
||||
|
||||
class NavObstacle : public NavRid {
|
||||
NavAgent *agent = nullptr;
|
||||
NavMap *map = nullptr;
|
||||
Vector3 velocity;
|
||||
Vector3 position;
|
||||
Vector<Vector3> vertices;
|
||||
|
||||
real_t radius = 0.0;
|
||||
real_t height = 0.0;
|
||||
|
||||
bool avoidance_enabled = false;
|
||||
bool use_3d_avoidance = false;
|
||||
uint32_t avoidance_layers = 1;
|
||||
|
||||
bool obstacle_dirty = true;
|
||||
@ -55,15 +60,30 @@ public:
|
||||
NavObstacle();
|
||||
~NavObstacle();
|
||||
|
||||
void set_avoidance_enabled(bool p_enabled);
|
||||
bool is_avoidance_enabled() { return avoidance_enabled; }
|
||||
|
||||
void set_use_3d_avoidance(bool p_enabled);
|
||||
bool get_use_3d_avoidance() { return use_3d_avoidance; }
|
||||
|
||||
void set_map(NavMap *p_map);
|
||||
NavMap *get_map() { return map; }
|
||||
|
||||
void set_agent(NavAgent *p_agent);
|
||||
NavAgent *get_agent() { return agent; }
|
||||
|
||||
void set_position(const Vector3 p_position);
|
||||
const Vector3 &get_position() const { return position; }
|
||||
|
||||
void set_radius(real_t p_radius);
|
||||
real_t get_radius() const { return radius; }
|
||||
|
||||
void set_height(const real_t p_height);
|
||||
real_t get_height() const { return height; }
|
||||
|
||||
void set_velocity(const Vector3 p_velocity);
|
||||
const Vector3 &get_velocity() const { return velocity; }
|
||||
|
||||
void set_vertices(const Vector<Vector3> &p_vertices);
|
||||
const Vector<Vector3> &get_vertices() const { return vertices; }
|
||||
|
||||
@ -73,6 +93,9 @@ public:
|
||||
uint32_t get_avoidance_layers() const { return avoidance_layers; };
|
||||
|
||||
bool check_dirty();
|
||||
|
||||
private:
|
||||
void internal_update_agent();
|
||||
};
|
||||
|
||||
#endif // NAV_OBSTACLE_H
|
||||
|
||||
Reference in New Issue
Block a user