Skip to content

Commit 7eac239

Browse files
committed
Add unbound shortcuts for blender-like transforms.
This adds shortcuts for "instant" transforms, where you can press the key and immediately be transforming an object without holding the mouse then click to commit the transformation (or ESC to abort). This is inspired by Blender's G(rab)/R(otate)/S(cale) shortcuts, but I decided not to add default bindings as `S` is already bound to the regular scale tool, and it might be confusing to only bind some of them. See godotengine/godot-proposals#1215.
1 parent 0a56752 commit 7eac239

File tree

2 files changed

+63
-43
lines changed

2 files changed

+63
-43
lines changed

editor/plugins/spatial_editor_plugin.cpp

+59-43
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,11 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
12271227

12281228
if (b->is_pressed()) {
12291229

1230+
if (_edit.mode != TRANSFORM_NONE && _edit.instant) {
1231+
commit_transform();
1232+
break; // just commit the edit, stop processing the event so we don't deselect the object
1233+
}
1234+
12301235
NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
12311236
if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->get_alt()) {
12321237
break;
@@ -1275,33 +1280,17 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
12751280
clicked_includes_current = false;
12761281

12771282
if ((spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT && b->get_control()) || spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_ROTATE) {
1278-
1279-
/* HANDLE ROTATION */
1280-
if (get_selected_count() == 0)
1281-
break; //bye
1282-
//handle rotate
1283-
_edit.mode = TRANSFORM_ROTATE;
1284-
_compute_edit(b->get_position());
1283+
begin_transform(TRANSFORM_ROTATE, false);
12851284
break;
12861285
}
12871286

12881287
if (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_MOVE) {
1289-
1290-
if (get_selected_count() == 0)
1291-
break; //bye
1292-
//handle translate
1293-
_edit.mode = TRANSFORM_TRANSLATE;
1294-
_compute_edit(b->get_position());
1288+
begin_transform(TRANSFORM_TRANSLATE, false);
12951289
break;
12961290
}
12971291

12981292
if (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SCALE) {
1299-
1300-
if (get_selected_count() == 0)
1301-
break; //bye
1302-
//handle scale
1303-
_edit.mode = TRANSFORM_SCALE;
1304-
_compute_edit(b->get_position());
1293+
begin_transform(TRANSFORM_SCALE, false);
13051294
break;
13061295
}
13071296

@@ -1367,29 +1356,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
13671356
}
13681357

13691358
if (_edit.mode != TRANSFORM_NONE) {
1370-
1371-
static const char *_transform_name[4] = { "None", "Rotate", "Translate", "Scale" };
1372-
undo_redo->create_action(_transform_name[_edit.mode]);
1373-
1374-
List<Node *> &selection = editor_selection->get_selected_node_list();
1375-
1376-
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
1377-
1378-
Spatial *sp = Object::cast_to<Spatial>(E->get());
1379-
if (!sp)
1380-
continue;
1381-
1382-
SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
1383-
if (!se)
1384-
continue;
1385-
1386-
undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_gizmo_transform());
1387-
undo_redo->add_undo_method(sp, "set_global_transform", se->original);
1388-
}
1389-
undo_redo->commit_action();
1390-
_edit.mode = TRANSFORM_NONE;
1391-
spatial_editor->set_local_coords_enabled(_edit.original_local);
1392-
set_message("");
1359+
commit_transform();
13931360
}
13941361

13951362
surface->update();
@@ -1445,7 +1412,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
14451412
String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle);
14461413
set_message(n + ": " + String(v));
14471414

1448-
} else if (m->get_button_mask() & BUTTON_MASK_LEFT) {
1415+
} else if (m->get_button_mask() & BUTTON_MASK_LEFT || _edit.instant) {
14491416

14501417
if (nav_scheme == NAVIGATION_MAYA && m->get_alt()) {
14511418
nav_mode = NAVIGATION_ORBIT;
@@ -2090,6 +2057,15 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
20902057
if (ED_IS_SHORTCUT("spatial_editor/cancel_transform", p_event) && _edit.mode != TRANSFORM_NONE) {
20912058
cancel_transform();
20922059
}
2060+
if (ED_IS_SHORTCUT("spatial_editor/instant_translate", p_event)) {
2061+
begin_transform(TRANSFORM_TRANSLATE, true);
2062+
}
2063+
if (ED_IS_SHORTCUT("spatial_editor/instant_rotate", p_event)) {
2064+
begin_transform(TRANSFORM_ROTATE, true);
2065+
}
2066+
if (ED_IS_SHORTCUT("spatial_editor/instant_scale", p_event)) {
2067+
begin_transform(TRANSFORM_SCALE, true);
2068+
}
20932069

20942070
// Freelook doesn't work in orthogonal mode.
20952071
if (!orthogonal && ED_IS_SHORTCUT("spatial_editor/freelook_toggle", p_event)) {
@@ -3844,12 +3820,49 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p
38443820
_perform_drop_data();
38453821
}
38463822

3823+
void SpatialEditorViewport::begin_transform(TransformMode p_mode, bool instant) {
3824+
if (get_selected_count() == 0)
3825+
return;
3826+
_edit.mode = p_mode;
3827+
_compute_edit(_edit.mouse_pos);
3828+
_edit.instant = instant;
3829+
_edit.snap = spatial_editor->is_snap_enabled();
3830+
}
3831+
3832+
void SpatialEditorViewport::commit_transform() {
3833+
ERR_FAIL_COND(_edit.mode == TRANSFORM_NONE);
3834+
static const char *_transform_name[4] = { "None", "Rotate", "Translate", "Scale" };
3835+
undo_redo->create_action(_transform_name[_edit.mode]);
3836+
3837+
List<Node *> &selection = editor_selection->get_selected_node_list();
3838+
3839+
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
3840+
3841+
Spatial *sp = Object::cast_to<Spatial>(E->get());
3842+
if (!sp)
3843+
continue;
3844+
3845+
SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
3846+
if (!se)
3847+
continue;
3848+
3849+
undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_gizmo_transform());
3850+
undo_redo->add_undo_method(sp, "set_global_transform", se->original);
3851+
}
3852+
undo_redo->commit_action();
3853+
_edit.mode = TRANSFORM_NONE;
3854+
_edit.instant = 0;
3855+
spatial_editor->set_local_coords_enabled(_edit.original_local);
3856+
set_message("");
3857+
}
3858+
38473859
SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) {
38483860

38493861
_edit.mode = TRANSFORM_NONE;
38503862
_edit.plane = TRANSFORM_VIEW;
38513863
_edit.edited_gizmo = 0;
38523864
_edit.snap = 1;
3865+
_edit.instant = 0;
38533866
_edit.gizmo_handle = 0;
38543867

38553868
index = p_index;
@@ -3974,6 +3987,9 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
39743987
ED_SHORTCUT("spatial_editor/lock_transform_xz", TTR("Lock Transformation to XZ plane"), KEY_MASK_SHIFT | KEY_Y);
39753988
ED_SHORTCUT("spatial_editor/lock_transform_xy", TTR("Lock Transformation to XY plane"), KEY_MASK_SHIFT | KEY_Z);
39763989
ED_SHORTCUT("spatial_editor/cancel_transform", TTR("Cancel Transformation"), KEY_ESCAPE);
3990+
ED_SHORTCUT("spatial_editor/instant_translate", TTR("Begin Translate Transformation"));
3991+
ED_SHORTCUT("spatial_editor/instant_rotate", TTR("Begin Rotate Transformation"));
3992+
ED_SHORTCUT("spatial_editor/instant_scale", TTR("Begin Scale Transformation"));
39773993

39783994
preview_camera = memnew(CheckBox);
39793995
preview_camera->set_text(TTR("Preview"));

editor/plugins/spatial_editor_plugin.h

+4
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ class SpatialEditorViewport : public Control {
366366
Variant gizmo_initial_value;
367367
Vector3 gizmo_initial_pos;
368368
bool original_local;
369+
bool instant;
369370
} _edit;
370371

371372
struct Cursor {
@@ -444,6 +445,9 @@ class SpatialEditorViewport : public Control {
444445
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
445446
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
446447

448+
void begin_transform(TransformMode p_mode, bool instant);
449+
void commit_transform();
450+
447451
protected:
448452
void _notification(int p_what);
449453
static void _bind_methods();

0 commit comments

Comments
 (0)