summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2020-11-09 17:46:43 +0100
committerGitHub <noreply@github.com>2020-11-09 17:46:43 +0100
commited62876683a88294f6d3a93736f4c0a82a3d3288 (patch)
tree2398fc0ab26d84a93e0e54e97fcba883ccf7e109
parent827e5b8bf3ba84719fd98b9a50f6d744de3561e0 (diff)
parent8a3a4fa3a01d27f86a28160a10cf80523cba8fcb (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.cpp65
-rw-r--r--editor/plugins/node_3d_editor_plugin.h4
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;