Skip to content

Commit

Permalink
Implement Alt + Mouse wheel to adjust FOV in the 3D editor viewport
Browse files Browse the repository at this point in the history
This allows for quicker FOV adjustments compared to using the View menu.
  • Loading branch information
Calinou committed Oct 24, 2021
1 parent c3bdcb4 commit a094e5d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 10 deletions.
60 changes: 52 additions & 8 deletions editor/plugins/spatial_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ void ViewportRotationControl::_bind_methods() {
ClassDB::bind_method(D_METHOD("_on_mouse_exited"), &ViewportRotationControl::_on_mouse_exited);
}

void SpatialEditorViewport::_view_settings_confirmed(real_t p_interp_delta) {
// Set FOV override multiplier back to the default, so that the FOV
// setting specified in the View menu is correctly applied.
cursor.fov_scale = 1.0;

_update_camera(p_interp_delta);
}

void SpatialEditorViewport::_update_camera(float p_interp_delta) {
bool is_orthogonal = camera->get_projection() == Camera::PROJECTION_ORTHOGONAL;

Expand Down Expand Up @@ -317,6 +325,8 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) {
equal = false;
} else if (!Math::is_equal_approx(old_camera_cursor.distance, camera_cursor.distance, tolerance)) {
equal = false;
} else if (!Math::is_equal_approx(old_camera_cursor.fov_scale, camera_cursor.fov_scale, tolerance)) {
equal = false;
}

if (!equal || p_interp_delta == 0 || is_orthogonal != orthogonal) {
Expand Down Expand Up @@ -380,7 +390,7 @@ float SpatialEditorViewport::get_zfar() const {
return CLAMP(spatial_editor->get_zfar(), MIN_Z, MAX_Z);
}
float SpatialEditorViewport::get_fov() const {
return CLAMP(spatial_editor->get_fov(), MIN_FOV, MAX_FOV);
return CLAMP(spatial_editor->get_fov() * cursor.fov_scale, MIN_FOV, MAX_FOV);
}

Transform SpatialEditorViewport::_get_camera_transform() const {
Expand Down Expand Up @@ -1161,18 +1171,26 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
float zoom_factor = 1 + (ZOOM_FREELOOK_MULTIPLIER - 1) * b->get_factor();
switch (b->get_button_index()) {
case BUTTON_WHEEL_UP: {
if (is_freelook_active()) {
scale_freelook_speed(zoom_factor);
if (b->get_alt()) {
scale_fov(-0.05);
} else {
scale_cursor_distance(1.0 / zoom_factor);
if (is_freelook_active()) {
scale_freelook_speed(zoom_factor);
} else {
scale_cursor_distance(1.0 / zoom_factor);
}
}
} break;

case BUTTON_WHEEL_DOWN: {
if (is_freelook_active()) {
scale_freelook_speed(1.0 / zoom_factor);
if (b->get_alt()) {
scale_fov(0.05);
} else {
scale_cursor_distance(zoom_factor);
if (is_freelook_active()) {
scale_freelook_speed(1.0 / zoom_factor);
} else {
scale_cursor_distance(zoom_factor);
}
}
} break;

Expand Down Expand Up @@ -2120,6 +2138,18 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
emit_signal("toggle_maximize_view", this);
}
}

if (ED_IS_SHORTCUT("spatial_editor/decrease_fov", p_event)) {
scale_fov(-0.05);
}

if (ED_IS_SHORTCUT("spatial_editor/increase_fov", p_event)) {
scale_fov(0.05);
}

if (ED_IS_SHORTCUT("spatial_editor/reset_fov", p_event)) {
reset_fov();
}
}

// freelook uses most of the useful shortcuts, like save, so its ok
Expand Down Expand Up @@ -2287,6 +2317,16 @@ void SpatialEditorViewport::set_freelook_active(bool active_now) {
freelook_active = active_now;
}

void SpatialEditorViewport::scale_fov(real_t p_fov_offset) {
cursor.fov_scale = CLAMP(cursor.fov_scale + p_fov_offset, 0.1, 2.5);
surface->update();
}

void SpatialEditorViewport::reset_fov() {
cursor.fov_scale = 1.0;
surface->update();
}

void SpatialEditorViewport::scale_cursor_distance(real_t scale) {
real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN);
real_t max_distance = MIN(camera->get_zfar() / 2, ZOOM_FREELOOK_MAX);
Expand Down Expand Up @@ -3506,6 +3546,7 @@ void SpatialEditorViewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("_menu_option"), &SpatialEditorViewport::_menu_option);
ClassDB::bind_method(D_METHOD("_toggle_camera_preview"), &SpatialEditorViewport::_toggle_camera_preview);
ClassDB::bind_method(D_METHOD("_preview_exited_scene"), &SpatialEditorViewport::_preview_exited_scene);
ClassDB::bind_method(D_METHOD("_view_settings_confirmed"), &SpatialEditorViewport::_view_settings_confirmed);
ClassDB::bind_method(D_METHOD("_update_camera"), &SpatialEditorViewport::_update_camera);
ClassDB::bind_method(D_METHOD("update_transform_gizmo_view"), &SpatialEditorViewport::update_transform_gizmo_view);
ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &SpatialEditorViewport::_selection_result_pressed);
Expand Down Expand Up @@ -6497,6 +6538,9 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
ED_SHORTCUT("spatial_editor/align_transform_with_view", TTR("Align Transform with View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_M);
ED_SHORTCUT("spatial_editor/align_rotation_with_view", TTR("Align Rotation with View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_F);
ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KEY_MASK_SHIFT + KEY_F);
ED_SHORTCUT("spatial_editor/decrease_fov", TTR("Decrease Field of View"), KEY_MASK_CMD + KEY_EQUAL); // Usually direct access key for `KEY_PLUS`.
ED_SHORTCUT("spatial_editor/increase_fov", TTR("Increase Field of View"), KEY_MASK_CMD + KEY_MINUS);
ED_SHORTCUT("spatial_editor/reset_fov", TTR("Reset Field of View to Default"), KEY_MASK_CMD + KEY_0);

PopupMenu *p;

Expand Down Expand Up @@ -6645,7 +6689,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
settings_vbc->add_margin_child(TTR("View Z-Far:"), settings_zfar);

for (uint32_t i = 0; i < VIEWPORTS_COUNT; ++i) {
settings_dialog->connect("confirmed", viewports[i], "_update_camera", varray(0.0));
settings_dialog->connect("confirmed", viewports[i], "_view_settings_confirmed", varray(0.0));
}

/* XFORM DIALOG */
Expand Down
7 changes: 5 additions & 2 deletions editor/plugins/spatial_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ class SpatialEditorViewport : public Control {

struct Cursor {
Vector3 pos;
float x_rot, y_rot, distance;
float x_rot, y_rot, distance, fov_scale;
Vector3 eye_pos; // Used in freelook mode
bool region_select;
Point2 region_begin, region_end;
Expand All @@ -388,6 +388,7 @@ class SpatialEditorViewport : public Control {
x_rot = 0.5;
y_rot = -0.5;
distance = 4;
fov_scale = 1.0;
region_select = false;
}
};
Expand All @@ -396,6 +397,8 @@ class SpatialEditorViewport : public Control {
Cursor cursor; // Immediate cursor
Cursor camera_cursor; // That one may be interpolated (don't modify this one except for smoothing purposes)

void scale_fov(real_t p_fov_offset);
void reset_fov();
void scale_cursor_distance(real_t scale);

void set_freelook_active(bool active_now);
Expand All @@ -412,7 +415,7 @@ class SpatialEditorViewport : public Control {

void set_message(String p_message, float p_time = 5);

//
void _view_settings_confirmed(float p_interp_delta);
void _update_camera(float p_interp_delta);
Transform to_camera_transform(const Cursor &p_cursor) const;
void _draw();
Expand Down

0 comments on commit a094e5d

Please sign in to comment.