diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 931c50fc44f..c5b47d0d8f2 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -5508,6 +5508,12 @@ void Node3DEditor::_init_indicators() { Vector origin_colors; Vector origin_points; + const int count_of_elements = 3 * 6; + origin_colors.resize(count_of_elements); + origin_points.resize(count_of_elements); + + int x = 0; + for (int i = 0; i < 3; i++) { Vector3 axis; axis[i] = 1; @@ -5530,21 +5536,22 @@ void Node3DEditor::_init_indicators() { grid_enable[i] = false; grid_visible[i] = false; - origin_colors.push_back(origin_color); - origin_colors.push_back(origin_color); - origin_colors.push_back(origin_color); - origin_colors.push_back(origin_color); - origin_colors.push_back(origin_color); - origin_colors.push_back(origin_color); + origin_colors.set(x, origin_color); + origin_colors.set(x + 1, origin_color); + origin_colors.set(x + 2, origin_color); + origin_colors.set(x + 3, origin_color); + origin_colors.set(x + 4, origin_color); + origin_colors.set(x + 5, origin_color); // To both allow having a large origin size and avoid jitter // at small scales, we should segment the line into pieces. // 3 pieces seems to do the trick, and let's use powers of 2. - origin_points.push_back(axis * 1048576); - origin_points.push_back(axis * 1024); - origin_points.push_back(axis * 1024); - origin_points.push_back(axis * -1024); - origin_points.push_back(axis * -1024); - origin_points.push_back(axis * -1048576); + origin_points.set(x, axis * 1048576); + origin_points.set(x + 1, axis * 1024); + origin_points.set(x + 2, axis * 1024); + origin_points.set(x + 3, axis * -1024); + origin_points.set(x + 4, axis * -1024); + origin_points.set(x + 5, axis * -1048576); + x += 6; } Ref grid_shader = memnew(Shader); @@ -6121,6 +6128,32 @@ void Node3DEditor::_init_grid() { grid_mat[c]->set_shader_param("grid_size", grid_fade_size); grid_mat[c]->set_shader_param("orthogonal", orthogonal); + // Cache these so we don't have to re-access memory. + Vector &ref_grid = grid_points[c]; + Vector &ref_grid_normals = grid_normals[c]; + Vector &ref_grid_colors = grid_colors[c]; + + // Count our elements same as code below it. + int expected_size = 0; + for (int i = -grid_size; i <= grid_size; i++) { + const real_t position_a = center_a + i * small_step_size; + const real_t position_b = center_b + i * small_step_size; + + // Don't draw lines over the origin if it's enabled. + if (!(origin_enabled && Math::is_zero_approx(position_a))) { + expected_size += 2; + } + + if (!(origin_enabled && Math::is_zero_approx(position_b))) { + expected_size += 2; + } + } + + int idx = 0; + ref_grid.resize(expected_size); + ref_grid_normals.resize(expected_size); + ref_grid_colors.resize(expected_size); + // In each iteration of this loop, draw one line in each direction (so two lines per loop, in each if statement). for (int i = -grid_size; i <= grid_size; i++) { Color line_color; @@ -6143,12 +6176,13 @@ void Node3DEditor::_init_grid() { line_end[a] = position_a; line_bgn[b] = bgn_b; line_end[b] = end_b; - grid_points[c].push_back(line_bgn); - grid_points[c].push_back(line_end); - grid_colors[c].push_back(line_color); - grid_colors[c].push_back(line_color); - grid_normals[c].push_back(normal); - grid_normals[c].push_back(normal); + ref_grid.set(idx, line_bgn); + ref_grid.set(idx + 1, line_end); + ref_grid_colors.set(idx, line_color); + ref_grid_colors.set(idx + 1, line_color); + ref_grid_normals.set(idx, normal); + ref_grid_normals.set(idx + 1, normal); + idx += 2; } if (!(origin_enabled && Math::is_zero_approx(position_b))) { @@ -6158,12 +6192,13 @@ void Node3DEditor::_init_grid() { line_end[b] = position_b; line_bgn[a] = bgn_a; line_end[a] = end_a; - grid_points[c].push_back(line_bgn); - grid_points[c].push_back(line_end); - grid_colors[c].push_back(line_color); - grid_colors[c].push_back(line_color); - grid_normals[c].push_back(normal); - grid_normals[c].push_back(normal); + ref_grid.set(idx, line_bgn); + ref_grid.set(idx + 1, line_end); + ref_grid_colors.set(idx, line_color); + ref_grid_colors.set(idx + 1, line_color); + ref_grid_normals.set(idx, normal); + ref_grid_normals.set(idx + 1, normal); + idx += 2; } } @@ -6201,8 +6236,22 @@ void Node3DEditor::_finish_grid() { } void Node3DEditor::update_grid() { - _finish_grid(); - _init_grid(); + const Camera3D::Projection current_projection = viewports[0]->camera->get_projection(); + + if (current_projection != grid_camera_last_update_perspective) { + grid_init_draw = false; // redraw + grid_camera_last_update_perspective = current_projection; + } + + // Gets a orthogonal or perspective position correctly (for the grid comparison) + const Vector3 camera_position = get_editor_viewport(0)->camera->get_position(); + + if (!grid_init_draw || (camera_position - grid_camera_last_update_position).length() >= 10.0f) { + _finish_grid(); + _init_grid(); + grid_init_draw = true; + grid_camera_last_update_position = camera_position; + } } void Node3DEditor::_selection_changed() { diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index cb2edbcbc16..1a3360ed595 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -35,6 +35,7 @@ #include "editor/editor_plugin.h" #include "editor/editor_scale.h" #include "editor/plugins/node_3d_editor_gizmos.h" +#include "scene/3d/camera_3d.h" #include "scene/3d/light_3d.h" #include "scene/3d/visual_instance_3d.h" #include "scene/3d/world_environment.h" @@ -42,7 +43,6 @@ #include "scene/resources/environment.h" #include "scene/resources/sky_material.h" -class Camera3D; class Node3DEditor; class Node3DEditorViewport; class SubViewportContainer; @@ -521,6 +521,9 @@ private: bool grid_visible[3]; //currently visible bool grid_enable[3]; //should be always visible if true bool grid_enabled; + bool grid_init_draw = false; + Camera3D::Projection grid_camera_last_update_perspective; + Vector3 grid_camera_last_update_position = Vector3(); Ref move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3]; Ref gizmo_color[3]; @@ -622,7 +625,6 @@ private: void _menu_gizmo_toggled(int p_option); void _update_camera_override_button(bool p_game_running); void _update_camera_override_viewport(Object *p_viewport); - HBoxContainer *hbc_menu; // Used for secondary menu items which are displayed depending on the currently selected node // (such as MeshInstance's "Mesh" menu).