Improve NavigationRegion2D debug performance
Improves NavigationRegion2D debug performance by replacing the canvas polygon and line commands with a static mesh.
This commit is contained in:
parent
1e6b11dcd4
commit
5f5fe737d2
|
@ -162,8 +162,19 @@ void NavigationRegion2D::_notification(int p_what) {
|
||||||
set_physics_process_internal(true);
|
set_physics_process_internal(true);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_VISIBILITY_CHANGED: {
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (debug_instance_rid.is_valid()) {
|
||||||
|
RS::get_singleton()->canvas_item_set_visible(debug_instance_rid, is_visible_in_tree());
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
_region_exit_navigation_map();
|
_region_exit_navigation_map();
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
_free_debug();
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||||
|
@ -189,6 +200,9 @@ void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_
|
||||||
}
|
}
|
||||||
|
|
||||||
navigation_polygon = p_navigation_polygon;
|
navigation_polygon = p_navigation_polygon;
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
debug_mesh_dirty = true;
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
NavigationServer2D::get_singleton()->region_set_navigation_polygon(region, p_navigation_polygon);
|
NavigationServer2D::get_singleton()->region_set_navigation_polygon(region, p_navigation_polygon);
|
||||||
|
|
||||||
if (navigation_polygon.is_valid()) {
|
if (navigation_polygon.is_valid()) {
|
||||||
|
@ -420,12 +434,42 @@ void NavigationRegion2D::_region_update_transform() {
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
void NavigationRegion2D::_update_debug_mesh() {
|
void NavigationRegion2D::_update_debug_mesh() {
|
||||||
Vector<Vector2> navigation_polygon_vertices = navigation_polygon->get_vertices();
|
if (!is_inside_tree()) {
|
||||||
if (navigation_polygon_vertices.size() < 3) {
|
_free_debug();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NavigationServer2D *ns2d = NavigationServer2D::get_singleton();
|
const NavigationServer2D *ns2d = NavigationServer2D::get_singleton();
|
||||||
|
RenderingServer *rs = RenderingServer::get_singleton();
|
||||||
|
|
||||||
|
if (!debug_instance_rid.is_valid()) {
|
||||||
|
debug_instance_rid = rs->canvas_item_create();
|
||||||
|
}
|
||||||
|
if (!debug_mesh_rid.is_valid()) {
|
||||||
|
debug_mesh_rid = rs->mesh_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Transform2D region_gt = get_global_transform();
|
||||||
|
|
||||||
|
rs->canvas_item_set_parent(debug_instance_rid, get_world_2d()->get_canvas());
|
||||||
|
rs->canvas_item_set_transform(debug_instance_rid, region_gt);
|
||||||
|
|
||||||
|
if (!debug_mesh_dirty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs->mesh_clear(debug_mesh_rid);
|
||||||
|
debug_mesh_dirty = false;
|
||||||
|
|
||||||
|
const Vector<Vector2> &vertices = navigation_polygon->get_vertices();
|
||||||
|
if (vertices.size() < 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int polygon_count = navigation_polygon->get_polygon_count();
|
||||||
|
if (polygon_count == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool enabled_geometry_face_random_color = ns2d->get_debug_navigation_enable_geometry_face_random_color();
|
bool enabled_geometry_face_random_color = ns2d->get_debug_navigation_enable_geometry_face_random_color();
|
||||||
bool enabled_edge_lines = ns2d->get_debug_navigation_enable_edge_lines();
|
bool enabled_edge_lines = ns2d->get_debug_navigation_enable_edge_lines();
|
||||||
|
@ -438,39 +482,109 @@ void NavigationRegion2D::_update_debug_mesh() {
|
||||||
debug_edge_color = ns2d->get_debug_navigation_geometry_edge_disabled_color();
|
debug_edge_color = ns2d->get_debug_navigation_geometry_edge_disabled_color();
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomPCG rand;
|
int vertex_count = 0;
|
||||||
|
int line_count = 0;
|
||||||
|
|
||||||
for (int i = 0; i < navigation_polygon->get_polygon_count(); i++) {
|
for (int i = 0; i < polygon_count; i++) {
|
||||||
// An array of vertices for this polygon.
|
const Vector<int> &polygon = navigation_polygon->get_polygon(i);
|
||||||
Vector<int> polygon = navigation_polygon->get_polygon(i);
|
int polygon_size = polygon.size();
|
||||||
Vector<Vector2> debug_polygon_vertices;
|
if (polygon_size < 3) {
|
||||||
debug_polygon_vertices.resize(polygon.size());
|
continue;
|
||||||
for (int j = 0; j < polygon.size(); j++) {
|
}
|
||||||
ERR_FAIL_INDEX(polygon[j], navigation_polygon_vertices.size());
|
line_count += polygon_size * 2;
|
||||||
debug_polygon_vertices.write[j] = navigation_polygon_vertices[polygon[j]];
|
vertex_count += (polygon_size - 2) * 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the polygon color, slightly randomly modified from the settings one.
|
Vector<Vector2> face_vertex_array;
|
||||||
Color random_variation_color = debug_face_color;
|
face_vertex_array.resize(vertex_count);
|
||||||
|
|
||||||
|
Vector<Color> face_color_array;
|
||||||
if (enabled_geometry_face_random_color) {
|
if (enabled_geometry_face_random_color) {
|
||||||
random_variation_color.set_hsv(
|
face_color_array.resize(vertex_count);
|
||||||
debug_face_color.get_h() + rand.random(-1.0, 1.0) * 0.1,
|
|
||||||
debug_face_color.get_s(),
|
|
||||||
debug_face_color.get_v() + rand.random(-1.0, 1.0) * 0.2);
|
|
||||||
}
|
}
|
||||||
random_variation_color.a = debug_face_color.a;
|
|
||||||
|
|
||||||
Vector<Color> debug_face_colors;
|
Vector<Vector2> line_vertex_array;
|
||||||
debug_face_colors.push_back(random_variation_color);
|
if (enabled_edge_lines) {
|
||||||
RS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), debug_polygon_vertices, debug_face_colors);
|
line_vertex_array.resize(line_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
RandomPCG rand;
|
||||||
|
Color polygon_color = debug_face_color;
|
||||||
|
|
||||||
|
int face_vertex_index = 0;
|
||||||
|
int line_vertex_index = 0;
|
||||||
|
|
||||||
|
Vector2 *face_vertex_array_ptrw = face_vertex_array.ptrw();
|
||||||
|
Color *face_color_array_ptrw = face_color_array.ptrw();
|
||||||
|
Vector2 *line_vertex_array_ptrw = line_vertex_array.ptrw();
|
||||||
|
|
||||||
|
for (int polygon_index = 0; polygon_index < polygon_count; polygon_index++) {
|
||||||
|
const Vector<int> &polygon_indices = navigation_polygon->get_polygon(polygon_index);
|
||||||
|
int polygon_indices_size = polygon_indices.size();
|
||||||
|
if (polygon_indices_size < 3) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled_geometry_face_random_color) {
|
||||||
|
// Generate the polygon color, slightly randomly modified from the settings one.
|
||||||
|
polygon_color.set_hsv(debug_face_color.get_h() + rand.random(-1.0, 1.0) * 0.1, debug_face_color.get_s(), debug_face_color.get_v() + rand.random(-1.0, 1.0) * 0.2);
|
||||||
|
polygon_color.a = debug_face_color.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int polygon_indices_index = 0; polygon_indices_index < polygon_indices_size - 2; polygon_indices_index++) {
|
||||||
|
face_vertex_array_ptrw[face_vertex_index] = vertices[polygon_indices[0]];
|
||||||
|
face_vertex_array_ptrw[face_vertex_index + 1] = vertices[polygon_indices[polygon_indices_index + 1]];
|
||||||
|
face_vertex_array_ptrw[face_vertex_index + 2] = vertices[polygon_indices[polygon_indices_index + 2]];
|
||||||
|
if (enabled_geometry_face_random_color) {
|
||||||
|
face_color_array_ptrw[face_vertex_index] = polygon_color;
|
||||||
|
face_color_array_ptrw[face_vertex_index + 1] = polygon_color;
|
||||||
|
face_color_array_ptrw[face_vertex_index + 2] = polygon_color;
|
||||||
|
}
|
||||||
|
face_vertex_index += 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (enabled_edge_lines) {
|
if (enabled_edge_lines) {
|
||||||
Vector<Color> debug_edge_colors;
|
for (int polygon_indices_index = 0; polygon_indices_index < polygon_indices_size; polygon_indices_index++) {
|
||||||
debug_edge_colors.push_back(debug_edge_color);
|
line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[polygon_indices_index]];
|
||||||
debug_polygon_vertices.push_back(debug_polygon_vertices[0]); // Add first again for closing polyline.
|
line_vertex_index += 1;
|
||||||
RS::get_singleton()->canvas_item_add_polyline(get_canvas_item(), debug_polygon_vertices, debug_edge_colors);
|
if (polygon_indices_index + 1 == polygon_indices_size) {
|
||||||
|
line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[0]];
|
||||||
|
line_vertex_index += 1;
|
||||||
|
} else {
|
||||||
|
line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[polygon_indices_index + 1]];
|
||||||
|
line_vertex_index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enabled_geometry_face_random_color) {
|
||||||
|
face_color_array.resize(face_vertex_array.size());
|
||||||
|
face_color_array.fill(debug_face_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array face_mesh_array;
|
||||||
|
face_mesh_array.resize(Mesh::ARRAY_MAX);
|
||||||
|
face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array;
|
||||||
|
face_mesh_array[Mesh::ARRAY_COLOR] = face_color_array;
|
||||||
|
|
||||||
|
rs->mesh_add_surface_from_arrays(debug_mesh_rid, RS::PRIMITIVE_TRIANGLES, face_mesh_array, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
|
||||||
|
|
||||||
|
if (enabled_edge_lines) {
|
||||||
|
Vector<Color> line_color_array;
|
||||||
|
line_color_array.resize(line_vertex_array.size());
|
||||||
|
line_color_array.fill(debug_edge_color);
|
||||||
|
|
||||||
|
Array line_mesh_array;
|
||||||
|
line_mesh_array.resize(Mesh::ARRAY_MAX);
|
||||||
|
line_mesh_array[Mesh::ARRAY_VERTEX] = line_vertex_array;
|
||||||
|
line_mesh_array[Mesh::ARRAY_COLOR] = line_color_array;
|
||||||
|
|
||||||
|
rs->mesh_add_surface_from_arrays(debug_mesh_rid, RS::PRIMITIVE_LINES, line_mesh_array, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
|
||||||
|
}
|
||||||
|
|
||||||
|
rs->canvas_item_add_mesh(debug_instance_rid, debug_mesh_rid, Transform2D());
|
||||||
|
rs->canvas_item_set_visible(debug_instance_rid, is_visible_in_tree());
|
||||||
}
|
}
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
|
|
||||||
|
@ -512,3 +626,19 @@ void NavigationRegion2D::_update_debug_baking_rect() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
void NavigationRegion2D::_free_debug() {
|
||||||
|
RenderingServer *rs = RenderingServer::get_singleton();
|
||||||
|
ERR_FAIL_NULL(rs);
|
||||||
|
if (debug_instance_rid.is_valid()) {
|
||||||
|
rs->canvas_item_clear(debug_instance_rid);
|
||||||
|
rs->free(debug_instance_rid);
|
||||||
|
debug_instance_rid = RID();
|
||||||
|
}
|
||||||
|
if (debug_mesh_rid.is_valid()) {
|
||||||
|
rs->free(debug_mesh_rid);
|
||||||
|
debug_mesh_rid = RID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
|
|
@ -52,6 +52,12 @@ class NavigationRegion2D : public Node2D {
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
private:
|
private:
|
||||||
|
RID debug_mesh_rid;
|
||||||
|
RID debug_instance_rid;
|
||||||
|
|
||||||
|
bool debug_mesh_dirty = true;
|
||||||
|
|
||||||
|
void _free_debug();
|
||||||
void _update_debug_mesh();
|
void _update_debug_mesh();
|
||||||
void _update_debug_edge_connections_mesh();
|
void _update_debug_edge_connections_mesh();
|
||||||
void _update_debug_baking_rect();
|
void _update_debug_baking_rect();
|
||||||
|
|
Loading…
Reference in New Issue