You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-09 12:50:35 +00:00
Improve the 3D editor selection box appearance
- Draw two boxes slightly offset from each other to give the illustion of a thicker outline. - Decrease the offset compared to the 3D node's AABB to give a more accurate representation of its size. - Make the box fully visible instead of only displaying the corners. - Draw a x-ray version of the box that's more translucent, but visible through walls. This helps make the box more visible while still having a sense of depth. - Use an orange color similar to the 2D editor.
This commit is contained in:
@@ -2426,6 +2426,7 @@ void Node3DEditorViewport::_notification(int p_what) {
|
|||||||
t.basis = t.basis * aabb_s;
|
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, t);
|
||||||
|
RenderingServer::get_singleton()->instance_set_transform(se->sbox_instance_xray, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed || (spatial_editor->is_gizmo_visible() && !exist)) {
|
if (changed || (spatial_editor->is_gizmo_visible() && !exist)) {
|
||||||
@@ -4417,6 +4418,9 @@ Node3DEditorSelectedItem::~Node3DEditorSelectedItem() {
|
|||||||
if (sbox_instance.is_valid()) {
|
if (sbox_instance.is_valid()) {
|
||||||
RenderingServer::get_singleton()->free(sbox_instance);
|
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) {
|
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);
|
Node3DEditorSelectedItem *si = memnew(Node3DEditorSelectedItem);
|
||||||
|
|
||||||
si->sp = sp;
|
si->sp = sp;
|
||||||
si->sbox_instance = RenderingServer::get_singleton()->instance_create2(selection_box->get_rid(), sp->get_world_3d()->get_scenario());
|
si->sbox_instance = RenderingServer::get_singleton()->instance_create2(
|
||||||
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(si->sbox_instance, RS::SHADOW_CASTING_SETTING_OFF);
|
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;
|
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 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 = memnew(SurfaceTool);
|
||||||
|
Ref<SurfaceTool> st_xray = memnew(SurfaceTool);
|
||||||
|
|
||||||
st->begin(Mesh::PRIMITIVE_LINES);
|
st->begin(Mesh::PRIMITIVE_LINES);
|
||||||
|
st_xray->begin(Mesh::PRIMITIVE_LINES);
|
||||||
for (int i = 0; i < 12; i++) {
|
for (int i = 0; i < 12; i++) {
|
||||||
Vector3 a, b;
|
Vector3 a, b;
|
||||||
aabb.get_edge(i, 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_vertex(a);
|
||||||
st->add_color(Color(1.0, 1.0, 0.8, 0.4));
|
|
||||||
st->add_vertex(a.lerp(b, 0.2));
|
|
||||||
|
|
||||||
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));
|
|
||||||
st->add_vertex(b);
|
st->add_vertex(b);
|
||||||
|
st_xray->add_vertex(a);
|
||||||
|
st_xray->add_vertex(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D);
|
||||||
mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
|
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_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);
|
st->set_material(mat);
|
||||||
selection_box = st->commit();
|
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 {
|
Dictionary Node3DEditor::get_state() const {
|
||||||
@@ -5514,7 +5549,7 @@ void Node3DEditor::_init_indicators() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_generate_selection_box();
|
_generate_selection_boxes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node3DEditor::_update_gizmos_menu() {
|
void Node3DEditor::_update_gizmos_menu() {
|
||||||
|
|||||||
@@ -498,6 +498,7 @@ public:
|
|||||||
bool last_xform_dirty;
|
bool last_xform_dirty;
|
||||||
Node3D *sp;
|
Node3D *sp;
|
||||||
RID sbox_instance;
|
RID sbox_instance;
|
||||||
|
RID sbox_instance_xray;
|
||||||
|
|
||||||
Node3DEditorSelectedItem() {
|
Node3DEditorSelectedItem() {
|
||||||
sp = nullptr;
|
sp = nullptr;
|
||||||
@@ -613,6 +614,7 @@ private:
|
|||||||
float snap_rotate_value;
|
float snap_rotate_value;
|
||||||
float snap_scale_value;
|
float snap_scale_value;
|
||||||
|
|
||||||
|
Ref<ArrayMesh> selection_box_xray;
|
||||||
Ref<ArrayMesh> selection_box;
|
Ref<ArrayMesh> selection_box;
|
||||||
RID indicators;
|
RID indicators;
|
||||||
RID indicators_instance;
|
RID indicators_instance;
|
||||||
@@ -701,7 +703,7 @@ private:
|
|||||||
|
|
||||||
HBoxContainer *hbc_menu;
|
HBoxContainer *hbc_menu;
|
||||||
|
|
||||||
void _generate_selection_box();
|
void _generate_selection_boxes();
|
||||||
UndoRedo *undo_redo;
|
UndoRedo *undo_redo;
|
||||||
|
|
||||||
int camera_override_viewport_id;
|
int camera_override_viewport_id;
|
||||||
|
|||||||
Reference in New Issue
Block a user