diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2020-11-09 17:46:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-09 17:46:43 +0100 |
commit | ed62876683a88294f6d3a93736f4c0a82a3d3288 (patch) | |
tree | 2398fc0ab26d84a93e0e54e97fcba883ccf7e109 | |
parent | 827e5b8bf3ba84719fd98b9a50f6d744de3561e0 (diff) | |
parent | 8a3a4fa3a01d27f86a28160a10cf80523cba8fcb (diff) |
Merge pull request #40106 from Calinou/improve-3d-selection-box
Improve the 3D editor selection box appearance
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 65 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.h | 4 |
2 files changed, 53 insertions, 16 deletions
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index cc26caa5a3..fdbf3415db 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2426,6 +2426,7 @@ void Node3DEditorViewport::_notification(int p_what) { t.basis = t.basis * aabb_s; RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance, t); + RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray, t); } if (changed || (spatial_editor->is_gizmo_visible() && !exist)) { @@ -4417,6 +4418,9 @@ Node3DEditorSelectedItem::~Node3DEditorSelectedItem() { if (sbox_instance.is_valid()) { RenderingServer::get_singleton()->free(sbox_instance); } + if (sbox_instance_xray.is_valid()) { + RenderingServer::get_singleton()->free(sbox_instance_xray); + } } void Node3DEditor::select_gizmo_highlight_axis(int p_axis) { @@ -4500,42 +4504,73 @@ Object *Node3DEditor::_get_editor_data(Object *p_what) { Node3DEditorSelectedItem *si = memnew(Node3DEditorSelectedItem); si->sp = sp; - si->sbox_instance = RenderingServer::get_singleton()->instance_create2(selection_box->get_rid(), sp->get_world_3d()->get_scenario()); - RS::get_singleton()->instance_geometry_set_cast_shadows_setting(si->sbox_instance, RS::SHADOW_CASTING_SETTING_OFF); + si->sbox_instance = RenderingServer::get_singleton()->instance_create2( + selection_box->get_rid(), + sp->get_world_3d()->get_scenario()); + RS::get_singleton()->instance_geometry_set_cast_shadows_setting( + si->sbox_instance, + RS::SHADOW_CASTING_SETTING_OFF); + si->sbox_instance_xray = RenderingServer::get_singleton()->instance_create2( + selection_box_xray->get_rid(), + sp->get_world_3d()->get_scenario()); + RS::get_singleton()->instance_geometry_set_cast_shadows_setting( + si->sbox_instance_xray, + RS::SHADOW_CASTING_SETTING_OFF); return si; } -void Node3DEditor::_generate_selection_box() { +void Node3DEditor::_generate_selection_boxes() { + // Use two AABBs to create the illusion of a slightly thicker line. AABB aabb(Vector3(), Vector3(1, 1, 1)); - aabb.grow_by(aabb.get_longest_axis_size() / 20.0); - + AABB aabb_offset(Vector3(), Vector3(1, 1, 1)); + // Grow the bounding boxes slightly to avoid Z-fighting with the mesh's edges. + aabb.grow_by(0.005); + aabb_offset.grow_by(0.01); + + // Create a x-ray (visible through solid surfaces) and standard version of the selection box. + // Both will be drawn at the same position, but with different opacity. + // This lets the user see where the selection is while still having a sense of depth. Ref<SurfaceTool> st = memnew(SurfaceTool); + Ref<SurfaceTool> st_xray = memnew(SurfaceTool); st->begin(Mesh::PRIMITIVE_LINES); + st_xray->begin(Mesh::PRIMITIVE_LINES); for (int i = 0; i < 12; i++) { Vector3 a, b; aabb.get_edge(i, a, b); - st->add_color(Color(1.0, 1.0, 0.8, 0.8)); st->add_vertex(a); - st->add_color(Color(1.0, 1.0, 0.8, 0.4)); - st->add_vertex(a.lerp(b, 0.2)); + st->add_vertex(b); + st_xray->add_vertex(a); + st_xray->add_vertex(b); + } - st->add_color(Color(1.0, 1.0, 0.8, 0.4)); - st->add_vertex(a.lerp(b, 0.8)); - st->add_color(Color(1.0, 1.0, 0.8, 0.8)); + for (int i = 0; i < 12; i++) { + Vector3 a, b; + aabb_offset.get_edge(i, a, b); + + st->add_vertex(a); st->add_vertex(b); + st_xray->add_vertex(a); + st_xray->add_vertex(b); } Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - mat->set_albedo(Color(1, 1, 1)); + // Use a similar color to the 2D editor selection. + mat->set_albedo(Color(1, 0.5, 0)); mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); st->set_material(mat); selection_box = st->commit(); + + Ref<StandardMaterial3D> mat_xray = memnew(StandardMaterial3D); + mat_xray->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + mat_xray->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); + mat_xray->set_albedo(Color(1, 0.5, 0, 0.15)); + mat_xray->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + st_xray->set_material(mat_xray); + selection_box_xray = st_xray->commit(); } Dictionary Node3DEditor::get_state() const { @@ -5514,7 +5549,7 @@ void Node3DEditor::_init_indicators() { } } - _generate_selection_box(); + _generate_selection_boxes(); } void Node3DEditor::_update_gizmos_menu() { diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index e4a384449b..4c4faef07f 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -498,6 +498,7 @@ public: bool last_xform_dirty; Node3D *sp; RID sbox_instance; + RID sbox_instance_xray; Node3DEditorSelectedItem() { sp = nullptr; @@ -613,6 +614,7 @@ private: float snap_rotate_value; float snap_scale_value; + Ref<ArrayMesh> selection_box_xray; Ref<ArrayMesh> selection_box; RID indicators; RID indicators_instance; @@ -701,7 +703,7 @@ private: HBoxContainer *hbc_menu; - void _generate_selection_box(); + void _generate_selection_boxes(); UndoRedo *undo_redo; int camera_override_viewport_id; |