|
@@ -187,6 +187,7 @@ NavigationObstacle2D::NavigationObstacle2D() {
|
|
|
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
debug_canvas_item = RenderingServer::get_singleton()->canvas_item_create();
|
|
|
+ debug_mesh_rid = RenderingServer::get_singleton()->mesh_create();
|
|
|
#endif // DEBUG_ENABLED
|
|
|
}
|
|
|
|
|
@@ -197,6 +198,10 @@ NavigationObstacle2D::~NavigationObstacle2D() {
|
|
|
obstacle = RID();
|
|
|
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
+ if (debug_mesh_rid.is_valid()) {
|
|
|
+ RenderingServer::get_singleton()->free(debug_mesh_rid);
|
|
|
+ debug_mesh_rid = RID();
|
|
|
+ }
|
|
|
if (debug_canvas_item.is_valid()) {
|
|
|
RenderingServer::get_singleton()->free(debug_canvas_item);
|
|
|
debug_canvas_item = RID();
|
|
@@ -206,6 +211,10 @@ NavigationObstacle2D::~NavigationObstacle2D() {
|
|
|
|
|
|
void NavigationObstacle2D::set_vertices(const Vector<Vector2> &p_vertices) {
|
|
|
vertices = p_vertices;
|
|
|
+
|
|
|
+ vertices_are_clockwise = !Geometry2D::is_polygon_clockwise(vertices); // Geometry2D is inverted.
|
|
|
+ vertices_are_valid = !Geometry2D::triangulate_polygon(vertices).is_empty();
|
|
|
+
|
|
|
const Transform2D node_transform = is_inside_tree() ? get_global_transform() : Transform2D();
|
|
|
NavigationServer2D::get_singleton()->obstacle_set_vertices(obstacle, node_transform.xform(vertices));
|
|
|
#ifdef DEBUG_ENABLED
|
|
@@ -370,43 +379,61 @@ void NavigationObstacle2D::_update_fake_agent_radius_debug() {
|
|
|
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
void NavigationObstacle2D::_update_static_obstacle_debug() {
|
|
|
- if (get_vertices().size() > 2 && NavigationServer2D::get_singleton()->get_debug_navigation_avoidance_enable_obstacles_static()) {
|
|
|
- bool obstacle_pushes_inward = Geometry2D::is_polygon_clockwise(get_vertices());
|
|
|
+ if (get_vertices().size() < 3) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- Color debug_static_obstacle_face_color;
|
|
|
+ if (!NavigationServer2D::get_singleton()->get_debug_navigation_avoidance_enable_obstacles_static()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- if (obstacle_pushes_inward) {
|
|
|
- debug_static_obstacle_face_color = NavigationServer2D::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushin_face_color();
|
|
|
- } else {
|
|
|
- debug_static_obstacle_face_color = NavigationServer2D::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushout_face_color();
|
|
|
- }
|
|
|
+ RenderingServer *rs = RenderingServer::get_singleton();
|
|
|
|
|
|
- Vector<Vector2> debug_obstacle_polygon_vertices = get_vertices();
|
|
|
+ rs->mesh_clear(debug_mesh_rid);
|
|
|
|
|
|
- Vector<Color> debug_obstacle_polygon_colors;
|
|
|
- debug_obstacle_polygon_colors.resize(debug_obstacle_polygon_vertices.size());
|
|
|
- debug_obstacle_polygon_colors.fill(debug_static_obstacle_face_color);
|
|
|
+ const int vertex_count = vertices.size();
|
|
|
|
|
|
- RS::get_singleton()->canvas_item_add_polygon(debug_canvas_item, get_global_transform().xform(debug_obstacle_polygon_vertices), debug_obstacle_polygon_colors);
|
|
|
+ Vector<Vector2> edge_vertex_array;
|
|
|
+ edge_vertex_array.resize(vertex_count * 4);
|
|
|
|
|
|
- Color debug_static_obstacle_edge_color;
|
|
|
+ Vector2 *edge_vertex_array_ptrw = edge_vertex_array.ptrw();
|
|
|
|
|
|
- if (obstacle_pushes_inward) {
|
|
|
- debug_static_obstacle_edge_color = NavigationServer2D::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushin_edge_color();
|
|
|
- } else {
|
|
|
- debug_static_obstacle_edge_color = NavigationServer2D::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushout_edge_color();
|
|
|
- }
|
|
|
+ int vertex_index = 0;
|
|
|
|
|
|
- Vector<Vector2> debug_obstacle_line_vertices = get_vertices();
|
|
|
- debug_obstacle_line_vertices.push_back(debug_obstacle_line_vertices[0]);
|
|
|
- debug_obstacle_line_vertices.resize(debug_obstacle_line_vertices.size());
|
|
|
+ for (int i = 0; i < vertex_count; i++) {
|
|
|
+ Vector2 point = vertices[i];
|
|
|
+ Vector2 next_point = vertices[(i + 1) % vertex_count];
|
|
|
|
|
|
- Vector<Color> debug_obstacle_line_colors;
|
|
|
- debug_obstacle_line_colors.resize(debug_obstacle_line_vertices.size());
|
|
|
- debug_obstacle_line_colors.fill(debug_static_obstacle_edge_color);
|
|
|
+ Vector2 direction = next_point.direction_to(point);
|
|
|
+ Vector2 arrow_dir = -direction.orthogonal();
|
|
|
+ Vector2 edge_middle = point + ((next_point - point) * 0.5);
|
|
|
|
|
|
- // Transforming the vertices directly instead of the canvas item in order to not affect the circle shape by non-uniform scales.
|
|
|
- RS::get_singleton()->canvas_item_add_polyline(debug_canvas_item, get_global_transform().xform(debug_obstacle_line_vertices), debug_obstacle_line_colors, 4.0);
|
|
|
+ edge_vertex_array_ptrw[vertex_index++] = edge_middle;
|
|
|
+ edge_vertex_array_ptrw[vertex_index++] = edge_middle + (arrow_dir * 10.0);
|
|
|
+
|
|
|
+ edge_vertex_array_ptrw[vertex_index++] = point;
|
|
|
+ edge_vertex_array_ptrw[vertex_index++] = next_point;
|
|
|
+ }
|
|
|
+
|
|
|
+ Color debug_static_obstacle_edge_color;
|
|
|
+
|
|
|
+ if (are_vertices_valid()) {
|
|
|
+ debug_static_obstacle_edge_color = NavigationServer2D::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushout_edge_color();
|
|
|
+ } else {
|
|
|
+ debug_static_obstacle_edge_color = NavigationServer2D::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushin_edge_color();
|
|
|
}
|
|
|
+
|
|
|
+ Vector<Color> line_color_array;
|
|
|
+ line_color_array.resize(edge_vertex_array.size());
|
|
|
+ line_color_array.fill(debug_static_obstacle_edge_color);
|
|
|
+
|
|
|
+ Array edge_mesh_array;
|
|
|
+ edge_mesh_array.resize(Mesh::ARRAY_MAX);
|
|
|
+ edge_mesh_array[Mesh::ARRAY_VERTEX] = edge_vertex_array;
|
|
|
+ edge_mesh_array[Mesh::ARRAY_COLOR] = line_color_array;
|
|
|
+
|
|
|
+ rs->mesh_add_surface_from_arrays(debug_mesh_rid, RS::PRIMITIVE_LINES, edge_mesh_array, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
|
|
|
+
|
|
|
+ rs->canvas_item_add_mesh(debug_canvas_item, debug_mesh_rid, get_global_transform());
|
|
|
}
|
|
|
#endif // DEBUG_ENABLED
|