1/**************************************************************************/
2/* nav_obstacle.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "nav_obstacle.h"
32
33#include "nav_agent.h"
34#include "nav_map.h"
35
36NavObstacle::NavObstacle() {}
37
38NavObstacle::~NavObstacle() {}
39
40void NavObstacle::set_agent(NavAgent *p_agent) {
41 if (agent == p_agent) {
42 return;
43 }
44
45 agent = p_agent;
46
47 internal_update_agent();
48}
49
50void NavObstacle::set_avoidance_enabled(bool p_enabled) {
51 if (avoidance_enabled == p_enabled) {
52 return;
53 }
54
55 avoidance_enabled = p_enabled;
56 obstacle_dirty = true;
57
58 internal_update_agent();
59}
60
61void NavObstacle::set_use_3d_avoidance(bool p_enabled) {
62 if (use_3d_avoidance == p_enabled) {
63 return;
64 }
65
66 use_3d_avoidance = p_enabled;
67 obstacle_dirty = true;
68
69 if (agent) {
70 agent->set_use_3d_avoidance(use_3d_avoidance);
71 }
72}
73
74void NavObstacle::set_map(NavMap *p_map) {
75 if (map == p_map) {
76 return;
77 }
78
79 if (map) {
80 map->remove_obstacle(this);
81 if (agent) {
82 agent->set_map(nullptr);
83 }
84 }
85
86 map = p_map;
87 obstacle_dirty = true;
88
89 if (map) {
90 map->add_obstacle(this);
91 internal_update_agent();
92 }
93}
94
95void NavObstacle::set_position(const Vector3 p_position) {
96 if (position == p_position) {
97 return;
98 }
99
100 position = p_position;
101 obstacle_dirty = true;
102
103 if (agent) {
104 agent->set_position(position);
105 }
106}
107
108void NavObstacle::set_radius(real_t p_radius) {
109 if (radius == p_radius) {
110 return;
111 }
112
113 radius = p_radius;
114
115 if (agent) {
116 agent->set_radius(radius);
117 }
118}
119
120void NavObstacle::set_height(const real_t p_height) {
121 if (height == p_height) {
122 return;
123 }
124
125 height = p_height;
126 obstacle_dirty = true;
127
128 if (agent) {
129 agent->set_height(height);
130 }
131}
132
133void NavObstacle::set_velocity(const Vector3 p_velocity) {
134 velocity = p_velocity;
135
136 if (agent) {
137 agent->set_velocity(velocity);
138 }
139}
140
141void NavObstacle::set_vertices(const Vector<Vector3> &p_vertices) {
142 if (vertices == p_vertices) {
143 return;
144 }
145
146 vertices = p_vertices;
147 obstacle_dirty = true;
148}
149
150bool NavObstacle::is_map_changed() {
151 if (map) {
152 bool is_changed = map->get_map_update_id() != map_update_id;
153 map_update_id = map->get_map_update_id();
154 return is_changed;
155 } else {
156 return false;
157 }
158}
159
160void NavObstacle::set_avoidance_layers(uint32_t p_layers) {
161 if (avoidance_layers == p_layers) {
162 return;
163 }
164
165 avoidance_layers = p_layers;
166 obstacle_dirty = true;
167
168 if (agent) {
169 agent->set_avoidance_layers(avoidance_layers);
170 }
171}
172
173bool NavObstacle::check_dirty() {
174 const bool was_dirty = obstacle_dirty;
175 obstacle_dirty = false;
176 return was_dirty;
177}
178
179void NavObstacle::internal_update_agent() {
180 if (agent) {
181 agent->set_neighbor_distance(0.0);
182 agent->set_max_neighbors(0.0);
183 agent->set_time_horizon_agents(0.0);
184 agent->set_time_horizon_obstacles(0.0);
185 agent->set_avoidance_mask(0.0);
186 agent->set_neighbor_distance(0.0);
187 agent->set_avoidance_priority(1.0);
188 agent->set_map(map);
189 agent->set_paused(paused);
190 agent->set_radius(radius);
191 agent->set_height(height);
192 agent->set_position(position);
193 agent->set_avoidance_layers(avoidance_layers);
194 agent->set_avoidance_enabled(avoidance_enabled);
195 agent->set_use_3d_avoidance(use_3d_avoidance);
196 }
197}
198
199void NavObstacle::set_paused(bool p_paused) {
200 if (paused == p_paused) {
201 return;
202 }
203
204 paused = p_paused;
205
206 if (map) {
207 if (paused) {
208 map->remove_obstacle(this);
209 } else {
210 map->add_obstacle(this);
211 }
212 }
213 internal_update_agent();
214}
215
216bool NavObstacle::get_paused() const {
217 return paused;
218}
219