diff --git a/Source/Editor/Options/ViewportOptions.cs b/Source/Editor/Options/ViewportOptions.cs
index c934fc348..0fd018cbc 100644
--- a/Source/Editor/Options/ViewportOptions.cs
+++ b/Source/Editor/Options/ViewportOptions.cs
@@ -26,101 +26,108 @@ namespace FlaxEditor.Options
public float MouseWheelSensitivity { get; set; } = 1.0f;
///
- /// Gets or sets the default movement speed for the viewport camera (must be in range between minimum and maximum movement speed values).
+ /// Gets or sets the total amount of steps the camera needs to go from minimum to maximum speed.
///
- [DefaultValue(1.0f), Limit(0.05f, 64.0f)]
- [EditorDisplay("Defaults"), EditorOrder(110), Tooltip("The default movement speed for the viewport camera (must be in range between minimum and maximum movement speed values).")]
- public float MovementSpeed { get; set; } = 1.0f;
-
- ///
- /// Gets or sets the default minimum camera movement speed.
- ///
- [DefaultValue(0.05f), Limit(0.05f, 64.0f)]
- [EditorDisplay("Defaults"), EditorOrder(111), Tooltip("The default minimum movement speed for the viewport camera.")]
- public float MinMovementSpeed { get; set; } = 0.05f;
-
- ///
- /// Gets or sets the default maximum camera movement speed.
- ///
- [DefaultValue(64.0f), Limit(32.0f, 1000.0f)]
- [EditorDisplay("Defaults"), EditorOrder(112), Tooltip("The default maximum movement speed for the viewport camera.")]
- public float MaxMovementSpeed { get; set; } = 64f;
-
- ///
- /// Gets or sets the default camera easing mode.
- ///
- [DefaultValue(true)]
- [EditorDisplay("Defaults"), EditorOrder(120), Tooltip("The default camera easing mode.")]
- public bool UseCameraEasing { get; set; } = true;
+ [DefaultValue(64), Limit(1, 128)]
+ [EditorDisplay("Camera"), EditorOrder(110), Tooltip("The total amount of steps the camera needs to go from minimum to maximum speed.")]
+ public int TotalCameraSpeedSteps { get; set; } = 64;
///
/// Gets or sets the degree to which the camera will be eased when using camera flight in the editor window.
///
[DefaultValue(3.0f), Limit(1.0f, 8.0f)]
- [EditorDisplay("Defaults"), EditorOrder(121), Tooltip("The default degree to which the camera will be eased when using camera flight in the editor window (ignored if camera easing degree is enabled).")]
+ [EditorDisplay("Camera"), EditorOrder(111), Tooltip("The degree to which the camera will be eased when using camera flight in the editor window (ignored if camera easing degree is enabled).")]
public float CameraEasingDegree { get; set; } = 3.0f;
+ ///
+ /// Gets or sets the default movement speed for the viewport camera (must be in range between minimum and maximum movement speed values).
+ ///
+ [DefaultValue(1.0f), Limit(0.05f, 32.0f)]
+ [EditorDisplay("Defaults"), EditorOrder(120), Tooltip("The default movement speed for the viewport camera (must be in range between minimum and maximum movement speed values).")]
+ public float MovementSpeed { get; set; } = 1.0f;
+
+ ///
+ /// Gets or sets the default minimum camera movement speed.
+ ///
+ [DefaultValue(0.05f), Limit(0.05f, 32.0f)]
+ [EditorDisplay("Defaults"), EditorOrder(121), Tooltip("The default minimum movement speed for the viewport camera.")]
+ public float MinMovementSpeed { get; set; } = 0.05f;
+
+ ///
+ /// Gets or sets the default maximum camera movement speed.
+ ///
+ [DefaultValue(32.0f), Limit(16.0f, 1000.0f)]
+ [EditorDisplay("Defaults"), EditorOrder(122), Tooltip("The default maximum movement speed for the viewport camera.")]
+ public float MaxMovementSpeed { get; set; } = 32f;
+
+ ///
+ /// Gets or sets the default camera easing mode.
+ ///
+ [DefaultValue(true)]
+ [EditorDisplay("Defaults"), EditorOrder(130), Tooltip("The default camera easing mode.")]
+ public bool UseCameraEasing { get; set; } = true;
+
///
/// Gets or sets the default near clipping plane distance for the viewport camera.
///
[DefaultValue(10.0f), Limit(0.001f, 1000.0f)]
- [EditorDisplay("Defaults"), EditorOrder(130), Tooltip("The default near clipping plane distance for the viewport camera.")]
+ [EditorDisplay("Defaults"), EditorOrder(140), Tooltip("The default near clipping plane distance for the viewport camera.")]
public float NearPlane { get; set; } = 10.0f;
///
/// Gets or sets the default far clipping plane distance for the viewport camera.
///
[DefaultValue(40000.0f), Limit(10.0f)]
- [EditorDisplay("Defaults"), EditorOrder(140), Tooltip("The default far clipping plane distance for the viewport camera.")]
+ [EditorDisplay("Defaults"), EditorOrder(150), Tooltip("The default far clipping plane distance for the viewport camera.")]
public float FarPlane { get; set; } = 40000.0f;
///
/// Gets or sets the default field of view angle (in degrees) for the viewport camera.
///
[DefaultValue(60.0f), Limit(35.0f, 160.0f, 0.1f)]
- [EditorDisplay("Defaults"), EditorOrder(150), Tooltip("The default field of view angle (in degrees) for the viewport camera.")]
+ [EditorDisplay("Defaults"), EditorOrder(160), Tooltip("The default field of view angle (in degrees) for the viewport camera.")]
public float FieldOfView { get; set; } = 60.0f;
///
/// Gets or sets the default camera orthographic mode.
///
[DefaultValue(false)]
- [EditorDisplay("Defaults"), EditorOrder(160), Tooltip("The default camera orthographic mode.")]
+ [EditorDisplay("Defaults"), EditorOrder(170), Tooltip("The default camera orthographic mode.")]
public bool UseOrthographicProjection { get; set; } = false;
///
/// Gets or sets the default camera orthographic scale (if camera uses orthographic mode).
///
[DefaultValue(5.0f), Limit(0.001f, 100000.0f, 0.1f)]
- [EditorDisplay("Defaults"), EditorOrder(170), Tooltip("The default camera orthographic scale (if camera uses orthographic mode).")]
+ [EditorDisplay("Defaults"), EditorOrder(180), Tooltip("The default camera orthographic scale (if camera uses orthographic mode).")]
public float OrthographicScale { get; set; } = 5.0f;
///
/// Gets or sets the default panning direction for the viewport camera.
///
[DefaultValue(false)]
- [EditorDisplay("Defaults"), EditorOrder(180), Tooltip("The default panning direction for the viewport camera.")]
+ [EditorDisplay("Defaults"), EditorOrder(190), Tooltip("The default panning direction for the viewport camera.")]
public bool InvertPanning { get; set; } = false;
///
/// Gets or sets the default relative panning mode.
///
[DefaultValue(true)]
- [EditorDisplay("Defaults"), EditorOrder(190), Tooltip("The default relative panning mode. Uses distance between camera and target to determine panning speed.")]
+ [EditorDisplay("Defaults"), EditorOrder(200), Tooltip("The default relative panning mode. Uses distance between camera and target to determine panning speed.")]
public bool UseRelativePanning { get; set; } = true;
///
/// Gets or sets the default panning speed (ignored if relative panning is speed enabled).
///
[DefaultValue(0.8f), Limit(0.01f, 128.0f, 0.1f)]
- [EditorDisplay("Defaults"), EditorOrder(200), Tooltip("The default camera panning speed (ignored if relative panning is enabled).")]
+ [EditorDisplay("Defaults"), EditorOrder(210), Tooltip("The default camera panning speed (ignored if relative panning is enabled).")]
public float PanningSpeed { get; set; } = 0.8f;
///
/// Gets or sets the default editor viewport grid scale.
///
[DefaultValue(50.0f), Limit(25.0f, 500.0f, 5.0f)]
- [EditorDisplay("Defaults"), EditorOrder(210), Tooltip("The default editor viewport grid scale.")]
+ [EditorDisplay("Defaults"), EditorOrder(220), Tooltip("The default editor viewport grid scale.")]
public float ViewportGridScale { get; set; } = 50.0f;
}
}
diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs
index 399a71418..ba4087025 100644
--- a/Source/Editor/Viewport/EditorViewport.cs
+++ b/Source/Editor/Viewport/EditorViewport.cs
@@ -178,7 +178,6 @@ namespace FlaxEditor.Viewport
protected Float2 _mouseDelta;
// Camera
-
private ViewportCamera _camera;
private float _yaw;
private float _pitch;
@@ -193,8 +192,8 @@ namespace FlaxEditor.Viewport
private bool _relativePanning;
private bool _invertPanning;
- private float _linearMovementProgress;
- private float _easedMovementProgress = 0.0f;
+ private int _speedStep;
+ private int _maxSpeedSteps;
///
/// Speed of the mouse.
@@ -216,8 +215,9 @@ namespace FlaxEditor.Viewport
{
_movementSpeed = value;
+ var format = (_movementSpeed < 1.0f) ? "{0:0.##}" : "{0:#}";
if (_cameraButton != null)
- _cameraButton.Text = string.Format("{0:0.##}", _movementSpeed);
+ _cameraButton.Text = string.Format(format, _movementSpeed);
}
}
@@ -527,13 +527,14 @@ namespace FlaxEditor.Viewport
var largestText = "Relative Panning";
var textSize = Style.Current.FontMedium.MeasureText(largestText);
var xLocationForExtras = textSize.X + 5;
+ var format = (_movementSpeed < 1.0f) ? "{0:0.##}" : "{0:#}";
// Camera settings widget
_cameraWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
// Camera settings menu
var cameraCM = new ContextMenu();
- _cameraButton = new ViewportWidgetButton(string.Format("{0:0.##}", _movementSpeed), Editor.Instance.Icons.Camera64, cameraCM, false, Style.Current.FontMedium.MeasureText("000.00").X)
+ _cameraButton = new ViewportWidgetButton(string.Format(format, _movementSpeed), Editor.Instance.Icons.Camera64, cameraCM, false, Style.Current.FontMedium.MeasureText("0.00").X)
{
Tag = this,
TooltipText = "Camera Settings",
@@ -884,8 +885,8 @@ namespace FlaxEditor.Viewport
InputActions.Add(options => options.ViewpointRight, () => OrientViewport(Quaternion.Euler(EditorViewportCameraViewpointValues.First(vp => vp.Name == "Right").Orientation)));
InputActions.Add(options => options.ViewpointLeft, () => OrientViewport(Quaternion.Euler(EditorViewportCameraViewpointValues.First(vp => vp.Name == "Left").Orientation)));
InputActions.Add(options => options.CameraToggleRotation, () => _isVirtualMouseRightDown = !_isVirtualMouseRightDown);
- InputActions.Add(options => options.CameraIncreaseMoveSpeed, () => AdjustCameraMoveSpeed(Editor.Instance.Options.Options.Viewport.MouseWheelSensitivity * 0.01f));
- InputActions.Add(options => options.CameraDecreaseMoveSpeed, () => AdjustCameraMoveSpeed(Editor.Instance.Options.Options.Viewport.MouseWheelSensitivity * -0.01f));
+ InputActions.Add(options => options.CameraIncreaseMoveSpeed, () => AdjustCameraMoveSpeed(1));
+ InputActions.Add(options => options.CameraDecreaseMoveSpeed, () => AdjustCameraMoveSpeed(-1));
// Link for task event
task.Begin += OnRenderBegin;
@@ -1052,74 +1053,42 @@ namespace FlaxEditor.Viewport
}
}
- ///
- /// The inverse of .
- /// Interpolate between A and B, applying a reverse ease in function. Exponent controls the degree of the curve.
- ///
- private float InterpInverseEaseIn(float a, float b, float alpha, float exponent)
- {
- return 0.5f * Mathf.Pow((2.0f * (alpha - a) / (b - a)), 1.0f / exponent);
- }
-
- ///
- /// The inverse of .
- /// Interpolate between A and B, applying a reverse ease out function. Exponent controls the degree of the curve.
- ///
- private float InterpInverseEaseOut(float a, float b, float alpha, float exponent)
- {
- return 1.0f - InterpInverseEaseIn(a, b, 1.0f - alpha, exponent);
- }
-
- ///
- /// The inverse of .
- /// Interpolate between A and B, applying a reverse ease in/out function. Exponent controls the degree of the curve.
- ///
- private float InterpInverseEaseInOut(float a, float b, float alpha, float exponent)
- {
- if (alpha <= 0.0f)
- return a;
- if (alpha >= 1.0f)
- return b;
-
- return (alpha < 0.5f) ? InterpInverseEaseIn(a, b, alpha, exponent) : InterpInverseEaseOut(a, b, alpha, exponent);
- }
-
private void OnCameraMovementProgressChanged()
{
- _linearMovementProgress = Math.Abs(_minMovementSpeed - _maxMovementSpeed) < Mathf.Epsilon
- ? 0.0f
- : Mathf.Remap(_movementSpeed, _minMovementSpeed, _maxMovementSpeed, 0.0f, 1.0f);
-
- if (!_useCameraEasing)
+ // prevent NaN
+ if (Math.Abs(_minMovementSpeed - _maxMovementSpeed) < Mathf.Epsilon) {
+ _speedStep = 0;
return;
- _easedMovementProgress = InterpInverseEaseInOut(0.0f, 1.0f, _linearMovementProgress, _cameraEasingDegree);
+ }
+
+ // calculate current linear/eased progress
+ float progress = Mathf.Remap(_movementSpeed, _minMovementSpeed, _maxMovementSpeed, 0.0f, 1.0f);
+ if (_useCameraEasing)
+ progress = Mathf.Pow(progress, 1.0f / _cameraEasingDegree);
+
+ _speedStep = Mathf.RoundToInt(progress * _maxSpeedSteps);
}
///
/// Increases or decreases the camera movement speed.
///
- /// The difference in camera speed adjustment as a fraction of 1.
- protected void AdjustCameraMoveSpeed(float speedDelta)
+ /// The stepping direction for speed adjustment.
+ protected void AdjustCameraMoveSpeed(int step)
{
- float speed;
+ _speedStep = Mathf.Clamp(_speedStep + step, 0, _maxSpeedSteps);
- if (_useCameraEasing)
- {
- _easedMovementProgress = Mathf.Saturate(_easedMovementProgress + speedDelta);
- speed = Mathf.InterpEaseInOut(_minMovementSpeed, _maxMovementSpeed, _easedMovementProgress, _cameraEasingDegree);
- }
- else
- {
- _linearMovementProgress = Mathf.Saturate(_linearMovementProgress + speedDelta);
- speed = Mathf.Lerp(_minMovementSpeed, _maxMovementSpeed, _linearMovementProgress);
- }
+ // calculate new linear/eased progress
+ var progress = _useCameraEasing
+ ? Mathf.Pow((float)_speedStep / _maxSpeedSteps, _cameraEasingDegree)
+ : (float)_speedStep / _maxSpeedSteps;
- MovementSpeed = speed;
+ MovementSpeed = Mathf.Lerp(_minMovementSpeed, _maxMovementSpeed, progress);
}
private void OnEditorOptionsChanged(EditorOptions options)
{
_mouseSensitivity = options.Viewport.MouseSensitivity;
+ _maxSpeedSteps = options.Viewport.TotalCameraSpeedSteps;
_cameraEasingDegree = options.Viewport.CameraEasingDegree;
OnCameraMovementProgressChanged();
}
@@ -1507,10 +1476,8 @@ namespace FlaxEditor.Viewport
rmbWheel = useMovementSpeed && (_input.IsMouseRightDown || _isVirtualMouseRightDown) && wheelInUse;
if (rmbWheel)
{
- // speed delta can be adjusted through mouse wheel sensitivity in editor
- // with default sensitivity (1.0), it takes about ~100 scrolls from min to max
- var camSpeedDelta = _input.MouseWheelDelta * options.Viewport.MouseWheelSensitivity * 0.01f;
- AdjustCameraMoveSpeed(camSpeedDelta);
+ var step = _input.MouseWheelDelta * options.Viewport.MouseWheelSensitivity;
+ AdjustCameraMoveSpeed(step > 0.0f ? 1 : -1);
}
}