diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index 4f2b40514..e0a51622b 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -60,6 +60,10 @@ namespace FlaxEditor.Options [EditorDisplay("Common"), EditorOrder(200)] public InputBinding FocusSelection = new InputBinding(KeyboardKeys.F); + [DefaultValue(typeof(InputBinding), "Shift+F")] + [EditorDisplay("Common"), EditorOrder(200)] + public InputBinding LockFocusSelection = new InputBinding(KeyboardKeys.F, KeyboardKeys.Shift); + [DefaultValue(typeof(InputBinding), "Ctrl+F")] [EditorDisplay("Common"), EditorOrder(210)] public InputBinding Search = new InputBinding(KeyboardKeys.F, KeyboardKeys.Control); diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs index 48cd4fd98..8d7039dc6 100644 --- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs +++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs @@ -133,6 +133,8 @@ namespace FlaxEditor.Viewport } } + private bool _lockedFocus; + private double _lockedFocusOffset; private readonly ViewportDebugDrawData _debugDrawData = new ViewportDebugDrawData(32); private StaticModel _previewStaticModel; private int _previewModelEntryIndex; @@ -386,11 +388,43 @@ namespace FlaxEditor.Viewport InputActions.Add(options => options.TranslateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate); InputActions.Add(options => options.RotateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate); InputActions.Add(options => options.ScaleMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale); + InputActions.Add(options => options.LockFocusSelection, LockFocusSelection); InputActions.Add(options => options.FocusSelection, FocusSelection); InputActions.Add(options => options.RotateSelection, RotateSelection); InputActions.Add(options => options.Delete, _editor.SceneEditing.Delete); } + /// + public override void Update(float deltaTime) + { + base.Update(deltaTime); + + var selection = TransformGizmo.SelectedParents; + var requestUnlockFocus = FlaxEngine.Input.Mouse.GetButtonDown(MouseButton.Right) || FlaxEngine.Input.Mouse.GetButtonDown(MouseButton.Left); + if (TransformGizmo.SelectedParents.Count == 0 || (requestUnlockFocus && ContainsFocus)) + { + UnlockFocusSelection(); + } + else if (_lockedFocus) + { + var selectionBounds = BoundingSphere.Empty; + for (int i = 0; i < selection.Count; i++) + { + selection[i].GetEditorSphere(out var sphere); + BoundingSphere.Merge(ref selectionBounds, ref sphere, out selectionBounds); + } + + if (ContainsFocus) + { + var viewportFocusDistance = Vector3.Distance(ViewPosition, selectionBounds.Center) / 10f; + _lockedFocusOffset -= FlaxEngine.Input.Mouse.ScrollDelta * viewportFocusDistance; + } + + var focusDistance = Mathf.Max(selectionBounds.Radius * 2d, 100d); + ViewPosition = selectionBounds.Center + (-ViewDirection * (focusDistance + _lockedFocusOffset)); + } + } + /// /// Overrides the selection outline effect or restored the default one. /// @@ -753,6 +787,23 @@ namespace FlaxEditor.Viewport FocusSelection(ref orientation); } + /// + /// Lock focus on the current selection gizmo. + /// + public void LockFocusSelection() + { + _lockedFocus = true; + } + + /// + /// Unlock focus on the current selection. + /// + public void UnlockFocusSelection() + { + _lockedFocus = false; + _lockedFocusOffset = 0f; + } + /// /// Focuses the viewport on the current selection of the gizmo. ///