Skip to content

Commit 5878b88

Browse files
committed
Add "active" state to one of the multiple selected Node3Ds to determine basis in Local mode
1 parent ee4acfb commit 5878b88

File tree

4 files changed

+70
-4
lines changed

4 files changed

+70
-4
lines changed

doc/classes/EditorSettings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@
288288
<member name="editors/2d/zoom_speed_factor" type="float" setter="" getter="">
289289
The factor to use when zooming in or out in the 2D editor. For example, [code]1.1[/code] will zoom in by 10% with every step. If set to [code]2.0[/code], zooming will only cycle through powers of two.
290290
</member>
291+
<member name="editors/3d/active_selection_box_color" type="Color" setter="" getter="">
292+
The color to use for the active selection box that surrounds selected nodes in the 3D editor viewport. The color's alpha channel influences the selection box's opacity.
293+
[b]Note:[/b] The term "active" indicates that this object is the primary selection used as the basis for certain operations. This is the last selected [Node3D], which can be reordered with [kbd]Shift + Left mouse button[/kbd].
294+
</member>
291295
<member name="editors/3d/default_fov" type="float" setter="" getter="">
292296
The default camera vertical field of view to use in the 3D editor (in degrees). The camera field of view can be adjusted on a per-scene basis using the [b]View[/b] menu at the top of the 3D editor. If a scene had its camera field of view adjusted using the [b]View[/b] menu, this setting is ignored in the scene in question. This setting is also ignored while a [Camera3D] node is being previewed in the editor.
293297
[b]Note:[/b] The editor camera always uses the [b]Keep Height[/b] aspect mode.

editor/editor_settings.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
771771

772772
// Use a similar color to the 2D editor selection.
773773
EDITOR_SETTING_USAGE(Variant::COLOR, PROPERTY_HINT_NONE, "editors/3d/selection_box_color", Color(1.0, 0.5, 0), "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
774+
EDITOR_SETTING_USAGE(Variant::COLOR, PROPERTY_HINT_NONE, "editors/3d/active_selection_box_color", Color(1.5, 0.75, 0, 1.0), "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
774775
EDITOR_SETTING_USAGE(Variant::COLOR, PROPERTY_HINT_NONE, "editors/3d_gizmos/gizmo_colors/instantiated", Color(0.7, 0.7, 0.7, 0.6), "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
775776
EDITOR_SETTING_USAGE(Variant::COLOR, PROPERTY_HINT_NONE, "editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1), "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
776777
EDITOR_SETTING_USAGE(Variant::COLOR, PROPERTY_HINT_NONE, "editors/3d_gizmos/gizmo_colors/aabb", Color(0.28, 0.8, 0.82), "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)

editor/plugins/node_3d_editor_plugin.cpp

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -791,8 +791,12 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) {
791791

792792
if (p_allow_locked || (selected != nullptr && !_is_node_locked(selected))) {
793793
if (clicked_wants_append) {
794+
Node *active_node = editor_selection->get_selected_node_list().is_empty() ? nullptr : editor_selection->get_selected_node_list().back()->get();
794795
if (editor_selection->is_selected(selected)) {
795796
editor_selection->remove_node(selected);
797+
if (selected != active_node) {
798+
editor_selection->add_node(selected);
799+
}
796800
} else {
797801
editor_selection->add_node(selected);
798802
}
@@ -6238,7 +6242,7 @@ void Node3DEditor::update_transform_gizmo() {
62386242
for (const KeyValue<int, Transform3D> &E : se->subgizmos) {
62396243
Transform3D xf = se->sp->get_global_transform() * se->gizmo->get_subgizmo_transform(E.key);
62406244
gizmo_center += xf.origin;
6241-
if (count == 0 && local_gizmo_coords) {
6245+
if ((unsigned int)count == se->subgizmos.size() - 1 && local_gizmo_coords) {
62426246
gizmo_basis = xf.basis;
62436247
}
62446248
count++;
@@ -6262,7 +6266,7 @@ void Node3DEditor::update_transform_gizmo() {
62626266

62636267
Transform3D xf = sel_item->sp->get_global_transform();
62646268
gizmo_center += xf.origin;
6265-
if (count == 0 && local_gizmo_coords) {
6269+
if (count == selection.size() - 1 && local_gizmo_coords) {
62666270
gizmo_basis = xf.basis;
62676271
}
62686272
count++;
@@ -6271,7 +6275,7 @@ void Node3DEditor::update_transform_gizmo() {
62716275

62726276
gizmo.visible = count > 0;
62736277
gizmo.transform.origin = (count > 0) ? gizmo_center / count : Vector3();
6274-
gizmo.transform.basis = (count == 1) ? gizmo_basis : Basis();
6278+
gizmo.transform.basis = gizmo_basis;
62756279

62766280
for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
62776281
viewports[i]->update_transform_gizmo_view();
@@ -6363,23 +6367,33 @@ void Node3DEditor::_generate_selection_boxes() {
63636367
// This lets the user see where the selection is while still having a sense of depth.
63646368
Ref<SurfaceTool> st = memnew(SurfaceTool);
63656369
Ref<SurfaceTool> st_xray = memnew(SurfaceTool);
6370+
Ref<SurfaceTool> active_st = memnew(SurfaceTool);
6371+
Ref<SurfaceTool> active_st_xray = memnew(SurfaceTool);
63666372

63676373
st->begin(Mesh::PRIMITIVE_LINES);
63686374
st_xray->begin(Mesh::PRIMITIVE_LINES);
6375+
active_st->begin(Mesh::PRIMITIVE_LINES);
6376+
active_st_xray->begin(Mesh::PRIMITIVE_LINES);
63696377
for (int i = 0; i < 12; i++) {
63706378
Vector3 a, b;
63716379
aabb.get_edge(i, a, b);
63726380

63736381
st->add_vertex(a);
63746382
st->add_vertex(b);
6383+
active_st->add_vertex(a);
6384+
active_st->add_vertex(b);
63756385
st_xray->add_vertex(a);
63766386
st_xray->add_vertex(b);
6387+
active_st_xray->add_vertex(a);
6388+
active_st_xray->add_vertex(b);
63776389
}
63786390

6391+
const Color selection_box_color = EDITOR_GET("editors/3d/selection_box_color");
6392+
const Color active_selection_box_color = EDITOR_GET("editors/3d/active_selection_box_color");
6393+
63796394
Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D);
63806395
mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
63816396
mat->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true);
6382-
const Color selection_box_color = EDITOR_GET("editors/3d/selection_box_color");
63836397
mat->set_albedo(selection_box_color);
63846398
mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
63856399
st->set_material(mat);
@@ -6393,6 +6407,23 @@ void Node3DEditor::_generate_selection_boxes() {
63936407
mat_xray->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
63946408
st_xray->set_material(mat_xray);
63956409
selection_box_xray = st_xray->commit();
6410+
6411+
Ref<StandardMaterial3D> active_mat = memnew(StandardMaterial3D);
6412+
active_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
6413+
active_mat->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true);
6414+
active_mat->set_albedo(active_selection_box_color);
6415+
active_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
6416+
active_st->set_material(active_mat);
6417+
active_selection_box = active_st->commit();
6418+
6419+
Ref<StandardMaterial3D> active_mat_xray = memnew(StandardMaterial3D);
6420+
active_mat_xray->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
6421+
active_mat_xray->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true);
6422+
active_mat_xray->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true);
6423+
active_mat_xray->set_albedo(active_selection_box_color * Color(1, 1, 1, 0.15));
6424+
active_mat_xray->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
6425+
active_st_xray->set_material(active_mat_xray);
6426+
active_selection_box_xray = active_st_xray->commit();
63966427
}
63976428

63986429
Dictionary Node3DEditor::get_state() const {
@@ -7827,6 +7858,33 @@ void Node3DEditor::update_grid() {
78277858

78287859
void Node3DEditor::_selection_changed() {
78297860
_refresh_menu_icons();
7861+
7862+
const HashMap<Node *, Object *> &selection = editor_selection->get_selection();
7863+
7864+
for (const KeyValue<Node *, Object *> &E : selection) {
7865+
Node3D *sp = Object::cast_to<Node3D>(E.key);
7866+
if (!sp) {
7867+
continue;
7868+
}
7869+
7870+
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
7871+
if (!se) {
7872+
continue;
7873+
}
7874+
7875+
if (sp == editor_selection->get_selected_node_list().back()->get()) {
7876+
RenderingServer::get_singleton()->instance_set_base(se->sbox_instance, active_selection_box->get_rid());
7877+
RenderingServer::get_singleton()->instance_set_base(se->sbox_instance_xray, active_selection_box_xray->get_rid());
7878+
RenderingServer::get_singleton()->instance_set_base(se->sbox_instance_offset, active_selection_box->get_rid());
7879+
RenderingServer::get_singleton()->instance_set_base(se->sbox_instance_xray_offset, active_selection_box_xray->get_rid());
7880+
} else {
7881+
RenderingServer::get_singleton()->instance_set_base(se->sbox_instance, selection_box->get_rid());
7882+
RenderingServer::get_singleton()->instance_set_base(se->sbox_instance_xray, selection_box_xray->get_rid());
7883+
RenderingServer::get_singleton()->instance_set_base(se->sbox_instance_offset, selection_box->get_rid());
7884+
RenderingServer::get_singleton()->instance_set_base(se->sbox_instance_xray_offset, selection_box_xray->get_rid());
7885+
}
7886+
}
7887+
78307888
if (selected && editor_selection->get_selected_node_list().size() != 1) {
78317889
Vector<Ref<Node3DGizmo>> gizmos = selected->get_gizmos();
78327890
for (int i = 0; i < gizmos.size(); i++) {

editor/plugins/node_3d_editor_plugin.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,8 +694,11 @@ class Node3DEditor : public VBoxContainer {
694694
real_t snap_rotate_value;
695695
real_t snap_scale_value;
696696

697+
Ref<ArrayMesh> active_selection_box_xray;
698+
Ref<ArrayMesh> active_selection_box;
697699
Ref<ArrayMesh> selection_box_xray;
698700
Ref<ArrayMesh> selection_box;
701+
699702
RID indicators;
700703
RID indicators_instance;
701704
RID cursor_mesh;

0 commit comments

Comments
 (0)