From 3dcd1a5ffb9b6747870aa1fb866c04c1224ebec7 Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Wed, 4 Oct 2023 19:07:48 +0200 Subject: [PATCH 01/32] Improve viewport camera settings * remove fixed camera speed buttons from camera speed scale widget * change camera speed scale widget to general camera settings widget * move all camera-related settings from view mode widget to camera settings widget * fix some typo * add possibility to set camera speed manually * add min/max camera speed options --- Source/Editor/Viewport/EditorViewport.cs | 415 +++++++++++++++-------- 1 file changed, 279 insertions(+), 136 deletions(-) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index 8c71a8b02..83fce7a3d 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -125,12 +125,19 @@ namespace FlaxEditor.Viewport public const int FpsCameraFilteringFrames = 3; /// - /// The speed widget button. + /// The camera settings widget. /// - protected ViewportWidgetButton _speedWidget; + protected ViewportWidgetsContainer _cameraWidget; + + /// + /// The camera settings widget button. + /// + protected ViewportWidgetButton _cameraButton; private float _mouseSensitivity; private float _movementSpeed; + private float _minMovementSpeed; + private float _maxMovementSpeed; private float _mouseAccelerationScale; private bool _useMouseFiltering; private bool _useMouseAcceleration; @@ -171,8 +178,8 @@ namespace FlaxEditor.Viewport private float _fieldOfView; private float _nearPlane; private float _farPlane; - private float _orthoSize = 1.0f; - private bool _isOrtho = false; + private float _orthoSize; + private bool _isOrtho; private float _wheelMovementChangeDeltaSum = 0; private bool _invertPanning; @@ -194,19 +201,31 @@ namespace FlaxEditor.Viewport get => _movementSpeed; set { - for (int i = 0; i < EditorViewportCameraSpeedValues.Length; i++) - { - if (Math.Abs(value - EditorViewportCameraSpeedValues[i]) < 0.001f) - { - _movementSpeed = EditorViewportCameraSpeedValues[i]; - if (_speedWidget != null) - _speedWidget.Text = _movementSpeed.ToString(); - break; - } - } + _movementSpeed = value; + + if (_cameraButton != null) + _cameraButton.Text = _movementSpeed.ToString(); } } + /// + /// Gets or sets the minimum camera movement speed. + /// + public float MinMovementSpeed + { + get => _minMovementSpeed; + set => _minMovementSpeed = value; + } + + /// + /// Gets or sets the maximum camera movement speed. + /// + public float MaxMovementSpeed + { + get => _maxMovementSpeed; + set => _maxMovementSpeed = value; + } + /// /// Gets the mouse movement position delta (user press and move). /// @@ -441,30 +460,183 @@ namespace FlaxEditor.Viewport if (useWidgets) { - var largestText = "Invert Panning"; + #region Camera settings widget + var largestText = "Relative Panning"; var textSize = Style.Current.FontMedium.MeasureText(largestText); var xLocationForExtras = textSize.X + 5; - // Camera speed widget - var camSpeed = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight); - var camSpeedCM = new ContextMenu(); - var camSpeedButton = new ViewportWidgetButton(_movementSpeed.ToString(), Editor.Instance.Icons.CamSpeed32, camSpeedCM) + + // Camera settings widget + _cameraWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight); + + // Camera settings menu + var cameraCM = new ContextMenu(); + _cameraButton = new ViewportWidgetButton(_movementSpeed.ToString(), Editor.Instance.Icons.Camera64, cameraCM) { Tag = this, - TooltipText = "Camera speed scale" + TooltipText = "Camera Settings", + Parent = _cameraWidget }; - _speedWidget = camSpeedButton; - for (int i = 0; i < EditorViewportCameraSpeedValues.Length; i++) - { - var v = EditorViewportCameraSpeedValues[i]; - var button = camSpeedCM.AddButton(v.ToString()); - button.Tag = v; - } - camSpeedCM.ButtonClicked += button => MovementSpeed = (float)button.Tag; - camSpeedCM.VisibleChanged += WidgetCamSpeedShowHide; - camSpeedButton.Parent = camSpeed; - camSpeed.Parent = this; + _cameraWidget.Parent = this; + + // Camera speed + var camSpeedButton = cameraCM.AddButton("Camera Speed"); + camSpeedButton.CloseMenuOnClick = false; + var camSpeedValue = new FloatValueBox(_movementSpeed, xLocationForExtras, 2, 70.0f, _minMovementSpeed, _maxMovementSpeed, 0.5f) + { + Parent = camSpeedButton, + }; + + camSpeedValue.ValueChanged += () => OnMovementSpeedChanged(camSpeedValue); + cameraCM.VisibleChanged += control => camSpeedValue.Value = _movementSpeed; + + var minCamSpeedButton = cameraCM.AddButton("Min Cam Speed"); + minCamSpeedButton.CloseMenuOnClick = false; + var minCamSpeedValue = new FloatValueBox(_minMovementSpeed, xLocationForExtras, 2, 70.0f, 0.05f, _maxMovementSpeed, 0.5f) + { + Parent = minCamSpeedButton, + }; + var maxCamSpeedButton = cameraCM.AddButton("Max Cam Speed"); + maxCamSpeedButton.CloseMenuOnClick = false; + var maxCamSpeedValue = new FloatValueBox(_maxMovementSpeed, xLocationForExtras, 2, 70.0f, _minMovementSpeed, 64.0f, 0.5f) + { + Parent = maxCamSpeedButton, + }; + + minCamSpeedValue.ValueChanged += () => + { + OnMinMovementSpeedChanged(minCamSpeedValue); + + maxCamSpeedValue.MinValue = minCamSpeedValue.Value; + + if (camSpeedValue.MinValue != minCamSpeedValue.Value) + camSpeedValue.MinValue = minCamSpeedValue.Value; + }; + cameraCM.VisibleChanged += control => minCamSpeedValue.Value = _minMovementSpeed; + maxCamSpeedValue.ValueChanged += () => + { + OnMaxMovementSpeedChanged(maxCamSpeedValue); + + minCamSpeedValue.MaxValue = maxCamSpeedValue.Value; + + if (camSpeedValue.MaxValue != maxCamSpeedValue.Value) + camSpeedValue.MaxValue = maxCamSpeedValue.Value; + }; + cameraCM.VisibleChanged += control => maxCamSpeedValue.Value = _maxMovementSpeed; + + // Invert Panning + { + var invertPanning = cameraCM.AddButton("Invert Panning"); + invertPanning.CloseMenuOnClick = false; + var invertPanningValue = new CheckBox(xLocationForExtras, 2, _invertPanning) + { + Parent = invertPanning + }; + + invertPanningValue.StateChanged += OnInvertPanningToggled; + cameraCM.VisibleChanged += control => invertPanningValue.Checked = _invertPanning; + } + + cameraCM.AddSeparator(); + + // Camera Viewpoints + { + var cameraView = cameraCM.AddChildMenu("Viewpoints").ContextMenu; + for (int i = 0; i < EditorViewportCameraViewpointValues.Length; i++) + { + var co = EditorViewportCameraViewpointValues[i]; + var button = cameraView.AddButton(co.Name); + button.Tag = co.Orientation; + } + + cameraView.ButtonClicked += OnViewpointChanged; + } + + // Orthographic + { + var ortho = cameraCM.AddButton("Orthographic"); + ortho.CloseMenuOnClick = false; + var orthoValue = new CheckBox(xLocationForExtras, 2, _isOrtho) + { + Parent = ortho + }; + + orthoValue.StateChanged += checkBox => + { + if (checkBox.Checked != _isOrtho) + { + OnOrthographicModeToggled(checkBox); + cameraCM.Hide(); + } + }; + cameraCM.VisibleChanged += control => orthoValue.Checked = _isOrtho; + } + + // Field of View + { + var fov = cameraCM.AddButton("Field Of View"); + fov.CloseMenuOnClick = false; + var fovValue = new FloatValueBox(_fieldOfView, xLocationForExtras, 2, 70.0f, 35.0f, 160.0f, 0.1f) + { + Parent = fov + }; + + fovValue.ValueChanged += () => OnFieldOfViewChanged(fovValue); + cameraCM.VisibleChanged += control => + { + fov.Visible = !_isOrtho; + fovValue.Value = _fieldOfView; + }; + } + + // Ortho Scale + { + var orthoSize = cameraCM.AddButton("Ortho Scale"); + orthoSize.CloseMenuOnClick = false; + var orthoSizeValue = new FloatValueBox(_orthoSize, xLocationForExtras, 2, 70.0f, 0.001f, 100000.0f, 0.01f) + { + Parent = orthoSize + }; + + orthoSizeValue.ValueChanged += () => OnOrthographicSizeChanged(orthoSizeValue); + cameraCM.VisibleChanged += control => + { + orthoSize.Visible = _isOrtho; + orthoSizeValue.Value = _orthoSize; + }; + } + + // Near Plane + { + var nearPlane = cameraCM.AddButton("Near Plane"); + nearPlane.CloseMenuOnClick = false; + var nearPlaneValue = new FloatValueBox(_nearPlane, xLocationForExtras, 2, 70.0f, 0.001f, 1000.0f) + { + Parent = nearPlane + }; + + nearPlaneValue.ValueChanged += () => OnNearPlaneChanged(nearPlaneValue); + cameraCM.VisibleChanged += control => nearPlaneValue.Value = _nearPlane; + } + + // Far Plane + { + var farPlane = cameraCM.AddButton("Far Plane"); + farPlane.CloseMenuOnClick = false; + var farPlaneValue = new FloatValueBox(_farPlane, xLocationForExtras, 2, 70.0f, 10.0f) + { + Parent = farPlane + }; + + farPlaneValue.ValueChanged += () => OnFarPlaneChanged(farPlaneValue); + cameraCM.VisibleChanged += control => farPlaneValue.Value = _farPlane; + } + #endregion Camera settings widget + + #region View mode widget + largestText = "Brightness"; + textSize = Style.Current.FontMedium.MeasureText(largestText); + xLocationForExtras = textSize.X + 5; - // View mode widget var viewMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperLeft); ViewWidgetButtonMenu = new ContextMenu(); var viewModeButton = new ViewportWidgetButton("View", SpriteHandle.Invalid, ViewWidgetButtonMenu) @@ -481,8 +653,8 @@ namespace FlaxEditor.Viewport // Show FPS { InitFpsCounter(); - _showFpsButon = ViewWidgetShowMenu.AddButton("FPS Counter", () => ShowFpsCounter = !ShowFpsCounter); - _showFpsButon.CloseMenuOnClick = false; + _showFpsButton = ViewWidgetShowMenu.AddButton("FPS Counter", () => ShowFpsCounter = !ShowFpsCounter); + _showFpsButton.CloseMenuOnClick = false; } } @@ -540,104 +712,6 @@ namespace FlaxEditor.Viewport ViewWidgetButtonMenu.AddSeparator(); - // Orthographic - { - var ortho = ViewWidgetButtonMenu.AddButton("Orthographic"); - ortho.CloseMenuOnClick = false; - var orthoValue = new CheckBox(xLocationForExtras, 2, _isOrtho) - { - Parent = ortho - }; - orthoValue.StateChanged += checkBox => - { - if (checkBox.Checked != _isOrtho) - { - _isOrtho = checkBox.Checked; - ViewWidgetButtonMenu.Hide(); - if (_isOrtho) - { - var orient = ViewOrientation; - OrientViewport(ref orient); - } - } - }; - ViewWidgetButtonMenu.VisibleChanged += control => orthoValue.Checked = _isOrtho; - } - - // Camera Viewpoints - { - var cameraView = ViewWidgetButtonMenu.AddChildMenu("Viewpoints").ContextMenu; - for (int i = 0; i < EditorViewportCameraViewpointValues.Length; i++) - { - var co = EditorViewportCameraViewpointValues[i]; - var button = cameraView.AddButton(co.Name); - button.Tag = co.Orientation; - } - cameraView.ButtonClicked += button => - { - var orient = Quaternion.Euler((Float3)button.Tag); - OrientViewport(ref orient); - }; - } - - // Field of View - { - var fov = ViewWidgetButtonMenu.AddButton("Field Of View"); - fov.CloseMenuOnClick = false; - var fovValue = new FloatValueBox(1, xLocationForExtras, 2, 70.0f, 35.0f, 160.0f, 0.1f) - { - Parent = fov - }; - - fovValue.ValueChanged += () => _fieldOfView = fovValue.Value; - ViewWidgetButtonMenu.VisibleChanged += control => - { - fov.Visible = !_isOrtho; - fovValue.Value = _fieldOfView; - }; - } - - // Ortho Scale - { - var orthoSize = ViewWidgetButtonMenu.AddButton("Ortho Scale"); - orthoSize.CloseMenuOnClick = false; - var orthoSizeValue = new FloatValueBox(_orthoSize, xLocationForExtras, 2, 70.0f, 0.001f, 100000.0f, 0.01f) - { - Parent = orthoSize - }; - - orthoSizeValue.ValueChanged += () => _orthoSize = orthoSizeValue.Value; - ViewWidgetButtonMenu.VisibleChanged += control => - { - orthoSize.Visible = _isOrtho; - orthoSizeValue.Value = _orthoSize; - }; - } - - // Near Plane - { - var nearPlane = ViewWidgetButtonMenu.AddButton("Near Plane"); - nearPlane.CloseMenuOnClick = false; - var nearPlaneValue = new FloatValueBox(2.0f, xLocationForExtras, 2, 70.0f, 0.001f, 1000.0f) - { - Parent = nearPlane - }; - nearPlaneValue.ValueChanged += () => _nearPlane = nearPlaneValue.Value; - ViewWidgetButtonMenu.VisibleChanged += control => nearPlaneValue.Value = _nearPlane; - } - - // Far Plane - { - var farPlane = ViewWidgetButtonMenu.AddButton("Far Plane"); - farPlane.CloseMenuOnClick = false; - var farPlaneValue = new FloatValueBox(1000, xLocationForExtras, 2, 70.0f, 10.0f) - { - Parent = farPlane - }; - farPlaneValue.ValueChanged += () => _farPlane = farPlaneValue.Value; - ViewWidgetButtonMenu.VisibleChanged += control => farPlaneValue.Value = _farPlane; - } - // Brightness { var brightness = ViewWidgetButtonMenu.AddButton("Brightness"); @@ -661,6 +735,7 @@ namespace FlaxEditor.Viewport resolutionValue.ValueChanged += () => ResolutionScale = resolutionValue.Value; ViewWidgetButtonMenu.VisibleChanged += control => resolutionValue.Value = ResolutionScale; } + #endregion View mode widget // Invert Panning { @@ -695,6 +770,74 @@ namespace FlaxEditor.Viewport // Link for task event task.Begin += OnRenderBegin; } + + private void OnMovementSpeedChanged(FloatValueBox control) + { + var value = Mathf.Clamp(control.Value, _minMovementSpeed, _maxMovementSpeed); + MovementSpeed = value; + } + + private void OnMinMovementSpeedChanged(FloatValueBox control) + { + var value = Mathf.Clamp(control.Value, 0.05f, _maxMovementSpeed); + _minMovementSpeed = value; + + if (_movementSpeed < value) + _movementSpeed = value; + } + + private void OnMaxMovementSpeedChanged(FloatValueBox control) + { + var value = Mathf.Clamp(control.Value, _minMovementSpeed, 1000.0f); + _maxMovementSpeed = value; + + if (_movementSpeed > value) + _movementSpeed = value; + } + + + private void OnInvertPanningToggled(Control control) + { + _invertPanning = !_invertPanning; + } + + + private void OnViewpointChanged(ContextMenuButton button) + { + var orient = Quaternion.Euler((Float3)button.Tag); + OrientViewport(ref orient); + } + + private void OnFieldOfViewChanged(FloatValueBox control) + { + _fieldOfView = control.Value; + } + + private void OnOrthographicModeToggled(Control control) + { + _isOrtho = !_isOrtho; + + if (_isOrtho) + { + var orient = ViewOrientation; + OrientViewport(ref orient); + } + } + + private void OnOrthographicSizeChanged(FloatValueBox control) + { + _orthoSize = control.Value; + } + + private void OnNearPlaneChanged(FloatValueBox control) + { + _nearPlane = control.Value; + } + + private void OnFarPlaneChanged(FloatValueBox control) + { + _farPlane = control.Value; + } /// /// Gets a value indicating whether this viewport is using mouse currently (eg. user moving objects). @@ -793,7 +936,7 @@ namespace FlaxEditor.Viewport } private FpsCounter _fpsCounter; - private ContextMenuButton _showFpsButon; + private ContextMenuButton _showFpsButton; /// /// Gets or sets a value indicating whether show or hide FPS counter. @@ -805,7 +948,7 @@ namespace FlaxEditor.Viewport { _fpsCounter.Visible = value; _fpsCounter.Enabled = value; - _showFpsButon.Icon = value ? Style.Current.CheckBoxTick : SpriteHandle.Invalid; + _showFpsButton.Icon = value ? Style.Current.CheckBoxTick : SpriteHandle.Invalid; } } @@ -1043,8 +1186,8 @@ namespace FlaxEditor.Viewport _camera.Update(deltaTime); useMovementSpeed = _camera.UseMovementSpeed; - if (_speedWidget != null) - _speedWidget.Parent.Visible = useMovementSpeed; + if (_cameraButton != null) + _cameraButton.Parent.Visible = useMovementSpeed; } // Get parent window From 67536f04e9500cc9965343bf971825e87a8d5990 Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Wed, 4 Oct 2023 21:05:21 +0200 Subject: [PATCH 02/32] Improve camera panning * add camera panning speed option to camera settings context menu * add relative panning speed based on distance to camera target to camera settings context menu * add relative panning option to camera settings context menu * fix float comparisons * remove invert panning entry from view widget * remove unused show/hide method for camera widget --- Source/Editor/Viewport/Cameras/FPSCamera.cs | 5 +- Source/Editor/Viewport/EditorViewport.cs | 111 ++++++++++++-------- 2 files changed, 74 insertions(+), 42 deletions(-) diff --git a/Source/Editor/Viewport/Cameras/FPSCamera.cs b/Source/Editor/Viewport/Cameras/FPSCamera.cs index e578933cf..bf2e840ea 100644 --- a/Source/Editor/Viewport/Cameras/FPSCamera.cs +++ b/Source/Editor/Viewport/Cameras/FPSCamera.cs @@ -259,7 +259,10 @@ namespace FlaxEditor.Viewport.Cameras // Pan if (input.IsPanning) { - var panningSpeed = 0.8f; + var panningSpeed = (Viewport.RelativePanning) + ? Mathf.Abs((position - TargetPoint).Length) * 0.005f + : Viewport.PanningSpeed; + if (Viewport.InvertPanning) { position += up * (mouseDelta.Y * panningSpeed); diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index 83fce7a3d..28546d6df 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -181,6 +181,8 @@ namespace FlaxEditor.Viewport private float _orthoSize; private bool _isOrtho; private float _wheelMovementChangeDeltaSum = 0; + private float _panningSpeed; + private bool _relativePanning; private bool _invertPanning; /// @@ -412,6 +414,15 @@ namespace FlaxEditor.Viewport set => _isOrtho = value; } + /// + /// Gets or sets if the panning speed should be relative to the camera target. + /// + public bool RelativePanning + { + get => _relativePanning; + set => _relativePanning = value; + } + /// /// Gets or sets if the panning direction is inverted. /// @@ -421,6 +432,15 @@ namespace FlaxEditor.Viewport set => _invertPanning = value; } + /// + /// Gets or sets the camera panning speed. + /// + public float PanningSpeed + { + get => _panningSpeed; + set => _panningSpeed = value; + } + /// /// The input actions collection to processed during user input. /// @@ -508,7 +528,7 @@ namespace FlaxEditor.Viewport maxCamSpeedValue.MinValue = minCamSpeedValue.Value; - if (camSpeedValue.MinValue != minCamSpeedValue.Value) + if (Math.Abs(camSpeedValue.MinValue - minCamSpeedValue.Value) > Mathf.Epsilon) camSpeedValue.MinValue = minCamSpeedValue.Value; }; cameraCM.VisibleChanged += control => minCamSpeedValue.Value = _minMovementSpeed; @@ -518,11 +538,48 @@ namespace FlaxEditor.Viewport minCamSpeedValue.MaxValue = maxCamSpeedValue.Value; - if (camSpeedValue.MaxValue != maxCamSpeedValue.Value) + if (Math.Abs(camSpeedValue.MaxValue - maxCamSpeedValue.Value) > Mathf.Epsilon) camSpeedValue.MaxValue = maxCamSpeedValue.Value; }; cameraCM.VisibleChanged += control => maxCamSpeedValue.Value = _maxMovementSpeed; - + + // Panning Speed + { + var panningSpeed = cameraCM.AddButton("Panning Speed"); + panningSpeed.CloseMenuOnClick = false; + var panningSpeedValue = new FloatValueBox(_panningSpeed, xLocationForExtras, 2, 70.0f, 0.01f, 128.0f, 0.1f) + { + Parent = panningSpeed + }; + + panningSpeedValue.ValueChanged += () => OnPanningSpeedChanged(panningSpeedValue); + cameraCM.VisibleChanged += control => + { + panningSpeed.Visible = !_relativePanning; + panningSpeedValue.Value = _panningSpeed; + }; + } + + // Relative Panning + { + var relativePanning = cameraCM.AddButton("Relative Panning"); + relativePanning.CloseMenuOnClick = false; + var relativePanningValue = new CheckBox(xLocationForExtras, 2, _relativePanning) + { + Parent = relativePanning + }; + + relativePanningValue.StateChanged += checkBox => + { + if (checkBox.Checked != _relativePanning) + { + OnRelativePanningToggled(checkBox); + cameraCM.Hide(); + } + }; + cameraCM.VisibleChanged += control => relativePanningValue.Checked = _relativePanning; + } + // Invert Panning { var invertPanning = cameraCM.AddButton("Invert Panning"); @@ -736,25 +793,6 @@ namespace FlaxEditor.Viewport ViewWidgetButtonMenu.VisibleChanged += control => resolutionValue.Value = ResolutionScale; } #endregion View mode widget - - // Invert Panning - { - var invert = ViewWidgetButtonMenu.AddButton("Invert Panning"); - invert.CloseMenuOnClick = false; - var invertValue = new CheckBox(xLocationForExtras, 2, _invertPanning) - { - Parent = invert - }; - - invertValue.StateChanged += checkBox => - { - if (checkBox.Checked != _invertPanning) - { - _invertPanning = checkBox.Checked; - } - }; - ViewWidgetButtonMenu.VisibleChanged += control => invertValue.Checked = _invertPanning; - } } InputActions.Add(options => options.ViewpointTop, () => OrientViewport(Quaternion.Euler(EditorViewportCameraViewpointValues.First(vp => vp.Name == "Top").Orientation))); @@ -794,7 +832,16 @@ namespace FlaxEditor.Viewport if (_movementSpeed > value) _movementSpeed = value; } - + + private void OnPanningSpeedChanged(FloatValueBox control) + { + _panningSpeed = control.Value; + } + + private void OnRelativePanningToggled(Control control) + { + _relativePanning = !_relativePanning; + } private void OnInvertPanningToggled(Control control) { @@ -1636,24 +1683,6 @@ namespace FlaxEditor.Viewport new ViewModeOptions(ViewMode.GlobalIllumination, "Global Illumination"), }; - private void WidgetCamSpeedShowHide(Control cm) - { - if (cm.Visible == false) - return; - - var ccm = (ContextMenu)cm; - foreach (var e in ccm.Items) - { - if (e is ContextMenuButton b) - { - var v = (float)b.Tag; - b.Icon = Mathf.Abs(MovementSpeed - v) < 0.001f - ? Style.Current.CheckBoxTick - : SpriteHandle.Invalid; - } - } - } - private void WidgetViewModeShowHideClicked(ContextMenuButton button) { if (button.Tag is ViewMode v) From 4f93a0d9c9c326f9a7b0bcc0125e8dc4bae0999f Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Wed, 4 Oct 2023 22:07:30 +0200 Subject: [PATCH 03/32] Add default camera settings to editor options * update ViewportOptions to include new default camera settings * update existing default settings in ViewportOptions * extract viewport options setup into own method * initialize new camera settings with default settings in EditorViewport --- Source/Editor/Options/ViewportOptions.cs | 64 ++++++++++++++++++++---- Source/Editor/Viewport/EditorViewport.cs | 31 +++++++++--- 2 files changed, 76 insertions(+), 19 deletions(-) diff --git a/Source/Editor/Options/ViewportOptions.cs b/Source/Editor/Options/ViewportOptions.cs index cee63a562..c780ac06a 100644 --- a/Source/Editor/Options/ViewportOptions.cs +++ b/Source/Editor/Options/ViewportOptions.cs @@ -24,47 +24,89 @@ namespace FlaxEditor.Options [DefaultValue(1.0f), Limit(0.01f, 100.0f)] [EditorDisplay("General"), EditorOrder(101), Tooltip("The mouse wheel sensitivity applied to zoom in orthographic mode.")] public float MouseWheelSensitivity { get; set; } = 1.0f; - + /// - /// Gets or sets the default movement speed for the viewport camera (must match the dropdown menu values in the viewport). + /// 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.01f, 100.0f)] - [EditorDisplay("Defaults"), EditorOrder(110), Tooltip("The default movement speed for the viewport camera (must match the dropdown menu values in the viewport).")] + [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 DefaultMovementSpeed { 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 DefaultMinMovementSpeed { 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 DefaultMaxMovementSpeed { get; set; } = 64f; + /// /// Gets or sets the default near clipping plane distance for the viewport camera. /// [DefaultValue(10.0f), Limit(0.001f, 1000.0f)] - [EditorDisplay("Defaults"), EditorOrder(120), Tooltip("The default near clipping plane distance for the viewport camera.")] + [EditorDisplay("Defaults"), EditorOrder(130), Tooltip("The default near clipping plane distance for the viewport camera.")] public float DefaultNearPlane { 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(130), Tooltip("The default far clipping plane distance for the viewport camera.")] + [EditorDisplay("Defaults"), EditorOrder(140), Tooltip("The default far clipping plane distance for the viewport camera.")] public float DefaultFarPlane { 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", "Default Field Of View"), EditorOrder(140), Tooltip("The default field of view angle (in degrees) for the viewport camera.")] + [EditorDisplay("Defaults"), EditorOrder(150), Tooltip("The default field of view angle (in degrees) for the viewport camera.")] public float DefaultFieldOfView { get; set; } = 60.0f; /// - /// Gets or sets if the panning direction is inverted for the viewport camera. + /// Gets or sets the default camera orthographic mode. /// [DefaultValue(false)] - [EditorDisplay("Defaults"), EditorOrder(150), Tooltip("Invert the panning direction for the viewport camera.")] + [EditorDisplay("Defaults"), EditorOrder(160), Tooltip("The default camera orthographic mode.")] + public bool DefaultOrthographicProjection { 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).")] + public float DefaultOrthographicScale { 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.")] public bool DefaultInvertPanning { get; set; } = false; /// - /// Scales editor viewport grid. + /// 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.")] + public bool DefaultRelativePanning { 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).")] + public float DefaultPanningSpeed { 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(160), Tooltip("Scales editor viewport grid.")] + [EditorDisplay("Defaults"), EditorOrder(210), 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 28546d6df..a85319298 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -467,15 +467,8 @@ namespace FlaxEditor.Viewport // Setup options { - var options = Editor.Instance.Options.Options; - _movementSpeed = options.Viewport.DefaultMovementSpeed; - _nearPlane = options.Viewport.DefaultNearPlane; - _farPlane = options.Viewport.DefaultFarPlane; - _fieldOfView = options.Viewport.DefaultFieldOfView; - _invertPanning = options.Viewport.DefaultInvertPanning; - Editor.Instance.Options.OptionsChanged += OnEditorOptionsChanged; - OnEditorOptionsChanged(options); + SetupViewportOptions(); } if (useWidgets) @@ -808,6 +801,28 @@ namespace FlaxEditor.Viewport // Link for task event task.Begin += OnRenderBegin; } + + /// + /// Sets the viewport options to the default values. + /// + private void SetupViewportOptions() + { + var options = Editor.Instance.Options.Options; + _minMovementSpeed = options.Viewport.DefaultMinMovementSpeed; + _movementSpeed = options.Viewport.DefaultMovementSpeed; + _maxMovementSpeed = options.Viewport.DefaultMaxMovementSpeed; + _panningSpeed = options.Viewport.DefaultPanningSpeed; + _invertPanning = options.Viewport.DefaultInvertPanning; + _relativePanning = options.Viewport.DefaultRelativePanning; + + _isOrtho = options.Viewport.DefaultOrthographicProjection; + _orthoSize = options.Viewport.DefaultOrthographicScale; + _fieldOfView = options.Viewport.DefaultFieldOfView; + _nearPlane = options.Viewport.DefaultNearPlane; + _farPlane = options.Viewport.DefaultFarPlane; + + OnEditorOptionsChanged(options); + } private void OnMovementSpeedChanged(FloatValueBox control) { From a280ce3dc709875041bd8a5003226fe71145370d Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Wed, 4 Oct 2023 22:12:05 +0200 Subject: [PATCH 04/32] Add reset button to camera settings widget --- Source/Editor/Viewport/EditorViewport.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index a85319298..da327a665 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -680,6 +680,22 @@ namespace FlaxEditor.Viewport farPlaneValue.ValueChanged += () => OnFarPlaneChanged(farPlaneValue); cameraCM.VisibleChanged += control => farPlaneValue.Value = _farPlane; } + + cameraCM.AddSeparator(); + + //Reset Button + { + var reset = cameraCM.AddButton("Reset to default"); + reset.ButtonClicked += button => + { + SetupViewportOptions(); + + // trigger UI update + minCamSpeedValue.Value = _minMovementSpeed; + camSpeedValue.Value = _movementSpeed; + maxCamSpeedValue.Value = _maxMovementSpeed; + }; + } #endregion Camera settings widget #region View mode widget From ccf37e9d6861086f2e129832889484d73972f9ba Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Wed, 4 Oct 2023 22:19:48 +0200 Subject: [PATCH 05/32] Add saving and loading of cached values for camera settings * remove "Default" from all settings in ViewportOptions as they are shown in the "Defaults" group anyway --- Source/Editor/Options/ViewportOptions.cs | 26 ++++----- Source/Editor/Viewport/EditorViewport.cs | 69 +++++++++++++++++++----- 2 files changed, 69 insertions(+), 26 deletions(-) diff --git a/Source/Editor/Options/ViewportOptions.cs b/Source/Editor/Options/ViewportOptions.cs index c780ac06a..94e3ee1fc 100644 --- a/Source/Editor/Options/ViewportOptions.cs +++ b/Source/Editor/Options/ViewportOptions.cs @@ -24,83 +24,83 @@ namespace FlaxEditor.Options [DefaultValue(1.0f), Limit(0.01f, 100.0f)] [EditorDisplay("General"), EditorOrder(101), Tooltip("The mouse wheel sensitivity applied to zoom in orthographic mode.")] 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). /// [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 DefaultMovementSpeed { get; set; } = 1.0f; + 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 DefaultMinMovementSpeed { get; set; } = 0.05f; + 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 DefaultMaxMovementSpeed { get; set; } = 64f; - + public float MaxMovementSpeed { get; set; } = 64f; + /// /// 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.")] - public float DefaultNearPlane { get; set; } = 10.0f; + 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.")] - public float DefaultFarPlane { get; set; } = 40000.0f; + 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.")] - public float DefaultFieldOfView { get; set; } = 60.0f; + 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.")] - public bool DefaultOrthographicProjection { get; set; } = false; + public bool OrthographicProjection { 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).")] - public float DefaultOrthographicScale { get; set; } = 5.0f; + 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.")] - public bool DefaultInvertPanning { get; set; } = false; + 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.")] - public bool DefaultRelativePanning { get; set; } = true; + public bool RelativePanning { 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).")] - public float DefaultPanningSpeed { get; set; } = 0.8f; + public float PanningSpeed { get; set; } = 0.8f; /// /// Gets or sets the default editor viewport grid scale. diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index da327a665..a5abfd2b7 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -134,6 +134,8 @@ namespace FlaxEditor.Viewport /// protected ViewportWidgetButton _cameraButton; + private readonly Editor _editor; + private float _mouseSensitivity; private float _movementSpeed; private float _minMovementSpeed; @@ -455,6 +457,8 @@ namespace FlaxEditor.Viewport public EditorViewport(SceneRenderTask task, ViewportCamera camera, bool useWidgets) : base(task) { + _editor = Editor.Instance; + _mouseAccelerationScale = 0.1f; _useMouseFiltering = false; _useMouseAcceleration = false; @@ -471,6 +475,30 @@ namespace FlaxEditor.Viewport SetupViewportOptions(); } + // Initialize camera values from cache + if (_editor.ProjectCache.TryGetCustomData("CameraMovementSpeedValue", out var cachedState)) + _movementSpeed = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("CameraMinMovementSpeedValue", out cachedState)) + _minMovementSpeed = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("CameraMaxMovementSpeedValue", out cachedState)) + _maxMovementSpeed = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("CameraPanningSpeedValue", out cachedState)) + _panningSpeed = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("CameraInvertPanningState", out cachedState)) + _invertPanning = bool.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("CameraRelativePanningState", out cachedState)) + _relativePanning = bool.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("CameraOrthographicState", out cachedState)) + _isOrtho = bool.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("CameraOrthographicSizeValue", out cachedState)) + _orthoSize = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("CameraFieldOfViewValue", out cachedState)) + _fieldOfView = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("CameraNearPlaneValue", out cachedState)) + _nearPlane = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("CameraFarPlaneValue", out cachedState)) + _farPlane = float.Parse(cachedState); + if (useWidgets) { #region Camera settings widget @@ -510,7 +538,7 @@ namespace FlaxEditor.Viewport }; var maxCamSpeedButton = cameraCM.AddButton("Max Cam Speed"); maxCamSpeedButton.CloseMenuOnClick = false; - var maxCamSpeedValue = new FloatValueBox(_maxMovementSpeed, xLocationForExtras, 2, 70.0f, _minMovementSpeed, 64.0f, 0.5f) + var maxCamSpeedValue = new FloatValueBox(_maxMovementSpeed, xLocationForExtras, 2, 70.0f, _minMovementSpeed, 1000.0f, 0.5f) { Parent = maxCamSpeedButton, }; @@ -824,26 +852,28 @@ namespace FlaxEditor.Viewport private void SetupViewportOptions() { var options = Editor.Instance.Options.Options; - _minMovementSpeed = options.Viewport.DefaultMinMovementSpeed; - _movementSpeed = options.Viewport.DefaultMovementSpeed; - _maxMovementSpeed = options.Viewport.DefaultMaxMovementSpeed; - _panningSpeed = options.Viewport.DefaultPanningSpeed; - _invertPanning = options.Viewport.DefaultInvertPanning; - _relativePanning = options.Viewport.DefaultRelativePanning; + _minMovementSpeed = options.Viewport.MinMovementSpeed; + _movementSpeed = options.Viewport.MovementSpeed; + _maxMovementSpeed = options.Viewport.MaxMovementSpeed; + _panningSpeed = options.Viewport.PanningSpeed; + _invertPanning = options.Viewport.InvertPanning; + _relativePanning = options.Viewport.RelativePanning; - _isOrtho = options.Viewport.DefaultOrthographicProjection; - _orthoSize = options.Viewport.DefaultOrthographicScale; - _fieldOfView = options.Viewport.DefaultFieldOfView; - _nearPlane = options.Viewport.DefaultNearPlane; - _farPlane = options.Viewport.DefaultFarPlane; + _isOrtho = options.Viewport.OrthographicProjection; + _orthoSize = options.Viewport.OrthographicScale; + _fieldOfView = options.Viewport.FieldOfView; + _nearPlane = options.Viewport.NearPlane; + _farPlane = options.Viewport.FarPlane; OnEditorOptionsChanged(options); } - + private void OnMovementSpeedChanged(FloatValueBox control) { var value = Mathf.Clamp(control.Value, _minMovementSpeed, _maxMovementSpeed); MovementSpeed = value; + + _editor.ProjectCache.SetCustomData("CameraMovementSpeedValue", _movementSpeed.ToString()); } private void OnMinMovementSpeedChanged(FloatValueBox control) @@ -853,6 +883,8 @@ namespace FlaxEditor.Viewport if (_movementSpeed < value) _movementSpeed = value; + + _editor.ProjectCache.SetCustomData("CameraMinMovementSpeedValue", _minMovementSpeed.ToString()); } private void OnMaxMovementSpeedChanged(FloatValueBox control) @@ -862,21 +894,26 @@ namespace FlaxEditor.Viewport if (_movementSpeed > value) _movementSpeed = value; + + _editor.ProjectCache.SetCustomData("CameraMaxMovementSpeedValue", _maxMovementSpeed.ToString()); } private void OnPanningSpeedChanged(FloatValueBox control) { _panningSpeed = control.Value; + _editor.ProjectCache.SetCustomData("CameraPanningSpeedValue", _panningSpeed.ToString()); } private void OnRelativePanningToggled(Control control) { _relativePanning = !_relativePanning; + _editor.ProjectCache.SetCustomData("CameraRelativePanningState", _relativePanning.ToString()); } private void OnInvertPanningToggled(Control control) { _invertPanning = !_invertPanning; + _editor.ProjectCache.SetCustomData("CameraInvertPanningState", _invertPanning.ToString()); } @@ -889,6 +926,7 @@ namespace FlaxEditor.Viewport private void OnFieldOfViewChanged(FloatValueBox control) { _fieldOfView = control.Value; + _editor.ProjectCache.SetCustomData("CameraFieldOfViewValue", _fieldOfView.ToString()); } private void OnOrthographicModeToggled(Control control) @@ -900,21 +938,26 @@ namespace FlaxEditor.Viewport var orient = ViewOrientation; OrientViewport(ref orient); } + + _editor.ProjectCache.SetCustomData("CameraOrthographicState", _isOrtho.ToString()); } private void OnOrthographicSizeChanged(FloatValueBox control) { _orthoSize = control.Value; + _editor.ProjectCache.SetCustomData("CameraOrthographicSizeValue", _orthoSize.ToString()); } private void OnNearPlaneChanged(FloatValueBox control) { _nearPlane = control.Value; + _editor.ProjectCache.SetCustomData("CameraNearPlaneValue", _nearPlane.ToString()); } private void OnFarPlaneChanged(FloatValueBox control) { _farPlane = control.Value; + _editor.ProjectCache.SetCustomData("CameraNearPlaneValue", _farPlane.ToString()); } /// From 1f2d665654f74b1791a26d8ac17c7fdc2f99d299 Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Wed, 4 Oct 2023 23:06:27 +0200 Subject: [PATCH 06/32] Add camera speed easing based on Mathf.InterpEaseInOut * change camera move speed method to use easing curve * add methods for inversion of Mathf.InterpEaseInOut (might have better alternative) * add setting for easing curve degree in ViewportOptions * update camera speed adjustments to use easing curve * remove unused camera speed values array * update some comments and namings --- Source/Editor/Options/ViewportOptions.cs | 7 ++ Source/Editor/Viewport/EditorViewport.cs | 139 +++++++++++++---------- 2 files changed, 83 insertions(+), 63 deletions(-) diff --git a/Source/Editor/Options/ViewportOptions.cs b/Source/Editor/Options/ViewportOptions.cs index 94e3ee1fc..26caa2694 100644 --- a/Source/Editor/Options/ViewportOptions.cs +++ b/Source/Editor/Options/ViewportOptions.cs @@ -46,6 +46,13 @@ namespace FlaxEditor.Options [EditorDisplay("Defaults"), EditorOrder(112), Tooltip("The default maximum movement speed for the viewport camera.")] public float MaxMovementSpeed { get; set; } = 64f; + /// + /// 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(120), Tooltip("The default degree to which the camera will be eased when using camera flight in the editor window.")] + public float CameraEasingDegree { get; set; } = 3.0f; + /// /// Gets or sets the default near clipping plane distance for the viewport camera. /// diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index a5abfd2b7..51b3a2d78 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -182,11 +182,14 @@ namespace FlaxEditor.Viewport private float _farPlane; private float _orthoSize; private bool _isOrtho; - private float _wheelMovementChangeDeltaSum = 0; + private float _cameraEasingDegree; private float _panningSpeed; private bool _relativePanning; private bool _invertPanning; + private float _linearMovementProgress; + private float _easedMovementProgress; + /// /// Speed of the mouse. /// @@ -499,6 +502,8 @@ namespace FlaxEditor.Viewport if (_editor.ProjectCache.TryGetCustomData("CameraFarPlaneValue", out cachedState)) _farPlane = float.Parse(cachedState); + OnCameraMovementProgressChanged(); + if (useWidgets) { #region Camera settings widget @@ -530,6 +535,7 @@ namespace FlaxEditor.Viewport camSpeedValue.ValueChanged += () => OnMovementSpeedChanged(camSpeedValue); cameraCM.VisibleChanged += control => camSpeedValue.Value = _movementSpeed; + // Minimum & maximum camera speed var minCamSpeedButton = cameraCM.AddButton("Min Cam Speed"); minCamSpeedButton.CloseMenuOnClick = false; var minCamSpeedValue = new FloatValueBox(_minMovementSpeed, xLocationForExtras, 2, 70.0f, 0.05f, _maxMovementSpeed, 0.5f) @@ -564,7 +570,7 @@ namespace FlaxEditor.Viewport }; cameraCM.VisibleChanged += control => maxCamSpeedValue.Value = _maxMovementSpeed; - // Panning Speed + // Panning speed { var panningSpeed = cameraCM.AddButton("Panning Speed"); panningSpeed.CloseMenuOnClick = false; @@ -581,7 +587,7 @@ namespace FlaxEditor.Viewport }; } - // Relative Panning + // Relative panning { var relativePanning = cameraCM.AddButton("Relative Panning"); relativePanning.CloseMenuOnClick = false; @@ -601,7 +607,7 @@ namespace FlaxEditor.Viewport cameraCM.VisibleChanged += control => relativePanningValue.Checked = _relativePanning; } - // Invert Panning + // Invert panning { var invertPanning = cameraCM.AddButton("Invert Panning"); invertPanning.CloseMenuOnClick = false; @@ -616,7 +622,7 @@ namespace FlaxEditor.Viewport cameraCM.AddSeparator(); - // Camera Viewpoints + // Camera viewpoints { var cameraView = cameraCM.AddChildMenu("Viewpoints").ContextMenu; for (int i = 0; i < EditorViewportCameraViewpointValues.Length; i++) @@ -629,7 +635,7 @@ namespace FlaxEditor.Viewport cameraView.ButtonClicked += OnViewpointChanged; } - // Orthographic + // Orthographic mode { var ortho = cameraCM.AddButton("Orthographic"); ortho.CloseMenuOnClick = false; @@ -649,7 +655,7 @@ namespace FlaxEditor.Viewport cameraCM.VisibleChanged += control => orthoValue.Checked = _isOrtho; } - // Field of View + // Field of view { var fov = cameraCM.AddButton("Field Of View"); fov.CloseMenuOnClick = false; @@ -666,7 +672,7 @@ namespace FlaxEditor.Viewport }; } - // Ortho Scale + // Orthographic scale { var orthoSize = cameraCM.AddButton("Ortho Scale"); orthoSize.CloseMenuOnClick = false; @@ -683,7 +689,7 @@ namespace FlaxEditor.Viewport }; } - // Near Plane + // Near plane { var nearPlane = cameraCM.AddButton("Near Plane"); nearPlane.CloseMenuOnClick = false; @@ -696,7 +702,7 @@ namespace FlaxEditor.Viewport cameraCM.VisibleChanged += control => nearPlaneValue.Value = _nearPlane; } - // Far Plane + // Far plane { var farPlane = cameraCM.AddButton("Far Plane"); farPlane.CloseMenuOnClick = false; @@ -711,7 +717,7 @@ namespace FlaxEditor.Viewport cameraCM.AddSeparator(); - //Reset Button + // Reset button { var reset = cameraCM.AddButton("Reset to default"); reset.ButtonClicked += button => @@ -752,7 +758,7 @@ namespace FlaxEditor.Viewport } } - // View Flags + // View flags { var viewFlags = ViewWidgetButtonMenu.AddChildMenu("View Flags").ContextMenu; viewFlags.AddButton("Reset flags", () => Task.ViewFlags = ViewFlags.DefaultEditor).Icon = Editor.Instance.Icons.Rotate32; @@ -776,7 +782,7 @@ namespace FlaxEditor.Viewport viewFlags.VisibleChanged += WidgetViewFlagsShowHide; } - // Debug View + // Debug view { var debugView = ViewWidgetButtonMenu.AddChildMenu("Debug View").ContextMenu; for (int i = 0; i < EditorViewportViewModeValues.Length; i++) @@ -839,8 +845,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(1)); - InputActions.Add(options => options.CameraDecreaseMoveSpeed, () => AdjustCameraMoveSpeed(-1)); + 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)); // Link for task event task.Begin += OnRenderBegin; @@ -873,6 +879,7 @@ namespace FlaxEditor.Viewport var value = Mathf.Clamp(control.Value, _minMovementSpeed, _maxMovementSpeed); MovementSpeed = value; + OnCameraMovementProgressChanged(); _editor.ProjectCache.SetCustomData("CameraMovementSpeedValue", _movementSpeed.ToString()); } @@ -884,6 +891,7 @@ namespace FlaxEditor.Viewport if (_movementSpeed < value) _movementSpeed = value; + OnCameraMovementProgressChanged(); _editor.ProjectCache.SetCustomData("CameraMinMovementSpeedValue", _minMovementSpeed.ToString()); } @@ -895,6 +903,7 @@ namespace FlaxEditor.Viewport if (_movementSpeed > value) _movementSpeed = value; + OnCameraMovementProgressChanged(); _editor.ProjectCache.SetCustomData("CameraMaxMovementSpeedValue", _maxMovementSpeed.ToString()); } @@ -992,33 +1001,63 @@ 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); + + _easedMovementProgress = InterpInverseEaseInOut(0.0f, 1.0f, _linearMovementProgress, _cameraEasingDegree); + } + /// /// Increases or decreases the camera movement speed. /// - /// The stepping direction for speed adjustment. - protected void AdjustCameraMoveSpeed(int step) + /// The difference in camera speed adjustment as a fraction of 1. + protected void AdjustCameraMoveSpeed(float speedDelta) { - int camValueIndex = -1; - for (int i = 0; i < EditorViewportCameraSpeedValues.Length; i++) - { - if (Mathf.NearEqual(EditorViewportCameraSpeedValues[i], _movementSpeed)) - { - camValueIndex = i; - break; - } - } - if (camValueIndex == -1) - return; - - if (step > 0) - MovementSpeed = EditorViewportCameraSpeedValues[Mathf.Min(camValueIndex + 1, EditorViewportCameraSpeedValues.Length - 1)]; - else if (step < 0) - MovementSpeed = EditorViewportCameraSpeedValues[Mathf.Max(camValueIndex - 1, 0)]; + _easedMovementProgress = Mathf.Clamp(_easedMovementProgress + speedDelta, 0.0f, 1.0f); + var easedSpeed = Mathf.InterpEaseInOut(_minMovementSpeed, _maxMovementSpeed, _easedMovementProgress, _cameraEasingDegree); + MovementSpeed = Mathf.Round(easedSpeed * 100) / 100; } private void OnEditorOptionsChanged(EditorOptions options) { _mouseSensitivity = options.Viewport.MouseSensitivity; + _cameraEasingDegree = options.Viewport.CameraEasingDegree; + OnCameraMovementProgressChanged(); } private void OnRenderBegin(RenderTask task, GPUContext context) @@ -1210,8 +1249,6 @@ namespace FlaxEditor.Viewport /// The parent window. protected virtual void OnControlMouseBegin(Window win) { - _wheelMovementChangeDeltaSum = 0; - // Hide cursor and start tracking mouse movement win.StartTrackingMouse(false); win.Cursor = CursorType.Hidden; @@ -1406,18 +1443,10 @@ namespace FlaxEditor.Viewport rmbWheel = useMovementSpeed && (_input.IsMouseRightDown || _isVirtualMouseRightDown) && wheelInUse; if (rmbWheel) { - const float step = 4.0f; - _wheelMovementChangeDeltaSum += _input.MouseWheelDelta * options.Viewport.MouseWheelSensitivity; - if (_wheelMovementChangeDeltaSum >= step) - { - _wheelMovementChangeDeltaSum -= step; - AdjustCameraMoveSpeed(1); - } - else if (_wheelMovementChangeDeltaSum <= -step) - { - _wheelMovementChangeDeltaSum += step; - AdjustCameraMoveSpeed(-1); - } + // 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); } } @@ -1686,22 +1715,6 @@ namespace FlaxEditor.Viewport new CameraViewpoint("Bottom", new Float3(-90, 0, 0)) }; - private readonly float[] EditorViewportCameraSpeedValues = - { - 0.05f, - 0.1f, - 0.25f, - 0.5f, - 1.0f, - 2.0f, - 4.0f, - 6.0f, - 8.0f, - 16.0f, - 32.0f, - 64.0f, - }; - private struct ViewModeOptions { public readonly string Name; From 4b78d5e39e1be9b8cba2a4c857ce9ed7b831ec84 Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Wed, 4 Oct 2023 23:29:32 +0200 Subject: [PATCH 07/32] Orthographic/perspective mode toggle Note: missing dedicated icon! --- Source/Editor/Viewport/EditorViewport.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index 51b3a2d78..f83d9eb98 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -134,6 +134,11 @@ namespace FlaxEditor.Viewport ///
protected ViewportWidgetButton _cameraButton; + /// + /// The orthographic mode widget button. + /// + protected ViewportWidgetButton _orthographicModeButton; + private readonly Editor _editor; private float _mouseSensitivity; @@ -524,6 +529,15 @@ namespace FlaxEditor.Viewport }; _cameraWidget.Parent = this; + // Toggle orthographic mode widget + _orthographicModeButton = new ViewportWidgetButton(string.Empty, Editor.Instance.Icons.CamSpeed32, null, true) + { + Checked = !_isOrtho, + TooltipText = "Toggle Orthographic/Perspective Mode", + Parent = _cameraWidget, + }; + _orthographicModeButton.Toggled += OnOrthographicModeToggled; + // Camera speed var camSpeedButton = cameraCM.AddButton("Camera Speed"); camSpeedButton.CloseMenuOnClick = false; @@ -942,6 +956,9 @@ namespace FlaxEditor.Viewport { _isOrtho = !_isOrtho; + if (_orthographicModeButton != null) + _orthographicModeButton.Checked = !_isOrtho; + if (_isOrtho) { var orient = ViewOrientation; From 3a9fdd8b52dba06013b6a1fe0eee4887f898810b Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Thu, 5 Oct 2023 12:55:00 +0200 Subject: [PATCH 08/32] Add possibility to disable camera easing * add camera easing setting to camera settings widget * add camera easing default setting to ViewportOptions * update some settings in ViewportOptions --- Source/Editor/Options/ViewportOptions.cs | 13 ++++-- Source/Editor/Viewport/EditorViewport.cs | 59 +++++++++++++++++++++--- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Options/ViewportOptions.cs b/Source/Editor/Options/ViewportOptions.cs index 26caa2694..c934fc348 100644 --- a/Source/Editor/Options/ViewportOptions.cs +++ b/Source/Editor/Options/ViewportOptions.cs @@ -46,11 +46,18 @@ namespace FlaxEditor.Options [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; + /// /// 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(120), Tooltip("The default degree to which the camera will be eased when using camera flight in the editor window.")] + [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).")] public float CameraEasingDegree { get; set; } = 3.0f; /// @@ -79,7 +86,7 @@ namespace FlaxEditor.Options /// [DefaultValue(false)] [EditorDisplay("Defaults"), EditorOrder(160), Tooltip("The default camera orthographic mode.")] - public bool OrthographicProjection { get; set; } = false; + public bool UseOrthographicProjection { get; set; } = false; /// /// Gets or sets the default camera orthographic scale (if camera uses orthographic mode). @@ -100,7 +107,7 @@ namespace FlaxEditor.Options /// [DefaultValue(true)] [EditorDisplay("Defaults"), EditorOrder(190), Tooltip("The default relative panning mode. Uses distance between camera and target to determine panning speed.")] - public bool RelativePanning { get; set; } = true; + public bool UseRelativePanning { get; set; } = true; /// /// Gets or sets the default panning speed (ignored if relative panning is speed enabled). diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index f83d9eb98..de4311452 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -187,13 +187,14 @@ namespace FlaxEditor.Viewport private float _farPlane; private float _orthoSize; private bool _isOrtho; + private bool _useCameraEasing; private float _cameraEasingDegree; private float _panningSpeed; private bool _relativePanning; private bool _invertPanning; private float _linearMovementProgress; - private float _easedMovementProgress; + private float _easedMovementProgress = 0.0f; /// /// Speed of the mouse. @@ -238,6 +239,15 @@ namespace FlaxEditor.Viewport set => _maxMovementSpeed = value; } + /// + /// Gets or sets the camera easing mode. + /// + public bool UseCameraEasing + { + get => _useCameraEasing; + set => _useCameraEasing = value; + } + /// /// Gets the mouse movement position delta (user press and move). /// @@ -490,6 +500,8 @@ namespace FlaxEditor.Viewport _minMovementSpeed = float.Parse(cachedState); if (_editor.ProjectCache.TryGetCustomData("CameraMaxMovementSpeedValue", out cachedState)) _maxMovementSpeed = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("UseCameraEasingState", out cachedState)) + _useCameraEasing = bool.Parse(cachedState); if (_editor.ProjectCache.TryGetCustomData("CameraPanningSpeedValue", out cachedState)) _panningSpeed = float.Parse(cachedState); if (_editor.ProjectCache.TryGetCustomData("CameraInvertPanningState", out cachedState)) @@ -584,6 +596,19 @@ namespace FlaxEditor.Viewport }; cameraCM.VisibleChanged += control => maxCamSpeedValue.Value = _maxMovementSpeed; + // Camera easing + { + var useCameraEasing = cameraCM.AddButton("Camera Easing"); + useCameraEasing.CloseMenuOnClick = false; + var useCameraEasingValue = new CheckBox(xLocationForExtras, 2, _useCameraEasing) + { + Parent = useCameraEasing + }; + + useCameraEasingValue.StateChanged += OnCameraEasingToggled; + cameraCM.VisibleChanged += control => useCameraEasingValue.Checked = _useCameraEasing; + } + // Panning speed { var panningSpeed = cameraCM.AddButton("Panning Speed"); @@ -875,11 +900,12 @@ namespace FlaxEditor.Viewport _minMovementSpeed = options.Viewport.MinMovementSpeed; _movementSpeed = options.Viewport.MovementSpeed; _maxMovementSpeed = options.Viewport.MaxMovementSpeed; + _useCameraEasing = options.Viewport.UseCameraEasing; _panningSpeed = options.Viewport.PanningSpeed; _invertPanning = options.Viewport.InvertPanning; - _relativePanning = options.Viewport.RelativePanning; + _relativePanning = options.Viewport.UseRelativePanning; - _isOrtho = options.Viewport.OrthographicProjection; + _isOrtho = options.Viewport.UseOrthographicProjection; _orthoSize = options.Viewport.OrthographicScale; _fieldOfView = options.Viewport.FieldOfView; _nearPlane = options.Viewport.NearPlane; @@ -920,6 +946,14 @@ namespace FlaxEditor.Viewport OnCameraMovementProgressChanged(); _editor.ProjectCache.SetCustomData("CameraMaxMovementSpeedValue", _maxMovementSpeed.ToString()); } + + private void OnCameraEasingToggled(Control control) + { + _useCameraEasing = !_useCameraEasing; + + OnCameraMovementProgressChanged(); + _editor.ProjectCache.SetCustomData("UseCameraEasingState", _useCameraEasing.ToString()); + } private void OnPanningSpeedChanged(FloatValueBox control) { @@ -1056,6 +1090,8 @@ namespace FlaxEditor.Viewport ? 0.0f : Mathf.Remap(_movementSpeed, _minMovementSpeed, _maxMovementSpeed, 0.0f, 1.0f); + if (!_useCameraEasing) + return; _easedMovementProgress = InterpInverseEaseInOut(0.0f, 1.0f, _linearMovementProgress, _cameraEasingDegree); } @@ -1065,9 +1101,20 @@ namespace FlaxEditor.Viewport /// The difference in camera speed adjustment as a fraction of 1. protected void AdjustCameraMoveSpeed(float speedDelta) { - _easedMovementProgress = Mathf.Clamp(_easedMovementProgress + speedDelta, 0.0f, 1.0f); - var easedSpeed = Mathf.InterpEaseInOut(_minMovementSpeed, _maxMovementSpeed, _easedMovementProgress, _cameraEasingDegree); - MovementSpeed = Mathf.Round(easedSpeed * 100) / 100; + float speed; + + if (_useCameraEasing) + { + _easedMovementProgress = Mathf.Clamp(_easedMovementProgress + speedDelta, 0.0f, 1.0f); + speed = Mathf.InterpEaseInOut(_minMovementSpeed, _maxMovementSpeed, _easedMovementProgress, _cameraEasingDegree); + } + else + { + _linearMovementProgress = Mathf.Clamp(_linearMovementProgress + speedDelta, 0.0f, 1.0f); + speed = Mathf.Lerp(_minMovementSpeed, _maxMovementSpeed, _linearMovementProgress); + } + + MovementSpeed = Mathf.Round(speed * 100) / 100; } private void OnEditorOptionsChanged(EditorOptions options) From fd94cfb4690aea20cb0f0c4c0e5db139da451c4c Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Thu, 5 Oct 2023 20:04:09 +0200 Subject: [PATCH 09/32] Update how camera settings widget is displayed * add option to force a certain text width to ViewportWidgetButton * force camera settings widget to fit longest possible speed value * changed displayed camera speed using string.Format * changed some lines to always correctly display the camera speed * switched from Mathf.Clamp to Mathf.Saturate for values between 0 and 1 --- Source/Editor/Viewport/EditorViewport.cs | 26 +++++++++---------- .../Viewport/Widgets/ViewportWidgetButton.cs | 11 +++++--- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index de4311452..399a71418 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -217,7 +217,7 @@ namespace FlaxEditor.Viewport _movementSpeed = value; if (_cameraButton != null) - _cameraButton.Text = _movementSpeed.ToString(); + _cameraButton.Text = string.Format("{0:0.##}", _movementSpeed); } } @@ -495,7 +495,7 @@ namespace FlaxEditor.Viewport // Initialize camera values from cache if (_editor.ProjectCache.TryGetCustomData("CameraMovementSpeedValue", out var cachedState)) - _movementSpeed = float.Parse(cachedState); + MovementSpeed = float.Parse(cachedState); if (_editor.ProjectCache.TryGetCustomData("CameraMinMovementSpeedValue", out cachedState)) _minMovementSpeed = float.Parse(cachedState); if (_editor.ProjectCache.TryGetCustomData("CameraMaxMovementSpeedValue", out cachedState)) @@ -533,7 +533,7 @@ namespace FlaxEditor.Viewport // Camera settings menu var cameraCM = new ContextMenu(); - _cameraButton = new ViewportWidgetButton(_movementSpeed.ToString(), Editor.Instance.Icons.Camera64, cameraCM) + _cameraButton = new ViewportWidgetButton(string.Format("{0:0.##}", _movementSpeed), Editor.Instance.Icons.Camera64, cameraCM, false, Style.Current.FontMedium.MeasureText("000.00").X) { Tag = this, TooltipText = "Camera Settings", @@ -546,7 +546,7 @@ namespace FlaxEditor.Viewport { Checked = !_isOrtho, TooltipText = "Toggle Orthographic/Perspective Mode", - Parent = _cameraWidget, + Parent = _cameraWidget }; _orthographicModeButton.Toggled += OnOrthographicModeToggled; @@ -555,7 +555,7 @@ namespace FlaxEditor.Viewport camSpeedButton.CloseMenuOnClick = false; var camSpeedValue = new FloatValueBox(_movementSpeed, xLocationForExtras, 2, 70.0f, _minMovementSpeed, _maxMovementSpeed, 0.5f) { - Parent = camSpeedButton, + Parent = camSpeedButton }; camSpeedValue.ValueChanged += () => OnMovementSpeedChanged(camSpeedValue); @@ -566,13 +566,13 @@ namespace FlaxEditor.Viewport minCamSpeedButton.CloseMenuOnClick = false; var minCamSpeedValue = new FloatValueBox(_minMovementSpeed, xLocationForExtras, 2, 70.0f, 0.05f, _maxMovementSpeed, 0.5f) { - Parent = minCamSpeedButton, + Parent = minCamSpeedButton }; var maxCamSpeedButton = cameraCM.AddButton("Max Cam Speed"); maxCamSpeedButton.CloseMenuOnClick = false; var maxCamSpeedValue = new FloatValueBox(_maxMovementSpeed, xLocationForExtras, 2, 70.0f, _minMovementSpeed, 1000.0f, 0.5f) { - Parent = maxCamSpeedButton, + Parent = maxCamSpeedButton }; minCamSpeedValue.ValueChanged += () => @@ -898,7 +898,7 @@ namespace FlaxEditor.Viewport { var options = Editor.Instance.Options.Options; _minMovementSpeed = options.Viewport.MinMovementSpeed; - _movementSpeed = options.Viewport.MovementSpeed; + MovementSpeed = options.Viewport.MovementSpeed; _maxMovementSpeed = options.Viewport.MaxMovementSpeed; _useCameraEasing = options.Viewport.UseCameraEasing; _panningSpeed = options.Viewport.PanningSpeed; @@ -929,7 +929,7 @@ namespace FlaxEditor.Viewport _minMovementSpeed = value; if (_movementSpeed < value) - _movementSpeed = value; + MovementSpeed = value; OnCameraMovementProgressChanged(); _editor.ProjectCache.SetCustomData("CameraMinMovementSpeedValue", _minMovementSpeed.ToString()); @@ -941,7 +941,7 @@ namespace FlaxEditor.Viewport _maxMovementSpeed = value; if (_movementSpeed > value) - _movementSpeed = value; + MovementSpeed = value; OnCameraMovementProgressChanged(); _editor.ProjectCache.SetCustomData("CameraMaxMovementSpeedValue", _maxMovementSpeed.ToString()); @@ -1105,16 +1105,16 @@ namespace FlaxEditor.Viewport if (_useCameraEasing) { - _easedMovementProgress = Mathf.Clamp(_easedMovementProgress + speedDelta, 0.0f, 1.0f); + _easedMovementProgress = Mathf.Saturate(_easedMovementProgress + speedDelta); speed = Mathf.InterpEaseInOut(_minMovementSpeed, _maxMovementSpeed, _easedMovementProgress, _cameraEasingDegree); } else { - _linearMovementProgress = Mathf.Clamp(_linearMovementProgress + speedDelta, 0.0f, 1.0f); + _linearMovementProgress = Mathf.Saturate(_linearMovementProgress + speedDelta); speed = Mathf.Lerp(_minMovementSpeed, _maxMovementSpeed, _linearMovementProgress); } - MovementSpeed = Mathf.Round(speed * 100) / 100; + MovementSpeed = speed; } private void OnEditorOptionsChanged(EditorOptions options) diff --git a/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs b/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs index 481bc3f1b..5ff5cdb6d 100644 --- a/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs +++ b/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs @@ -19,6 +19,7 @@ namespace FlaxEditor.Viewport.Widgets private bool _checked; private bool _autoCheck; private bool _isMosueDown; + private float _forcedTextWidth; /// /// Event fired when user toggles checked state. @@ -63,14 +64,16 @@ namespace FlaxEditor.Viewport.Widgets /// The text. /// The icon. /// The context menu. - /// if set to true will be automatic checked on mouse click. - public ViewportWidgetButton(string text, SpriteHandle icon, ContextMenu contextMenu = null, bool autoCheck = false) - : base(0, 0, CalculateButtonWidth(0, icon.IsValid), ViewportWidgetsContainer.WidgetsHeight) + /// If set to true will be automatic checked on mouse click. + /// Forces the text to be drawn with the specified width. + public ViewportWidgetButton(string text, SpriteHandle icon, ContextMenu contextMenu = null, bool autoCheck = false, float textWidth = 0.0f) + : base(0, 0, CalculateButtonWidth(textWidth, icon.IsValid), ViewportWidgetsContainer.WidgetsHeight) { _text = text; Icon = icon; _cm = contextMenu; _autoCheck = autoCheck; + _forcedTextWidth = textWidth; if (_cm != null) _cm.VisibleChanged += CmOnVisibleChanged; @@ -160,7 +163,7 @@ namespace FlaxEditor.Viewport.Widgets var style = Style.Current; if (style != null && style.FontMedium) - Width = CalculateButtonWidth(style.FontMedium.MeasureText(_text).X, Icon.IsValid); + Width = CalculateButtonWidth(_forcedTextWidth > 0.0f ? _forcedTextWidth : style.FontMedium.MeasureText(_text).X, Icon.IsValid); } } } From 00aa54cde82da867b2a861cd1b6bf307dafc0a7f Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Sat, 7 Oct 2023 02:40:52 +0200 Subject: [PATCH 10/32] Update camera speed stepping and easing * remove complex curve function * update camera easing feature to use Mathf.Pow instead * add total camera speed steps to ViewportOptions * change default value for max camera speed from 64 to 32 * update ViewportOptions ordering and grouping * update string format for movement speed --- Source/Editor/Options/ViewportOptions.cs | 77 +++++++++++--------- Source/Editor/Viewport/EditorViewport.cs | 93 ++++++++---------------- 2 files changed, 72 insertions(+), 98 deletions(-) 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); } } From 997c442e69366cc1c5e4404368fd252a4d134bf7 Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Sun, 8 Oct 2023 01:07:36 +0200 Subject: [PATCH 11/32] Update movement speed formatting * add property for movement speed text format * add additional checks to camera speed progress calculation * round movement speed to make it visually more appealing in the context menu --- Source/Editor/Viewport/EditorViewport.cs | 45 ++++++++++++++++++++---- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index ba4087025..8ce99b115 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -178,6 +178,7 @@ namespace FlaxEditor.Viewport protected Float2 _mouseDelta; // Camera + private ViewportCamera _camera; private float _yaw; private float _pitch; @@ -205,6 +206,23 @@ namespace FlaxEditor.Viewport ///
public float MouseWheelZoomSpeedFactor = 1; + /// + /// Format of the text for the camera move speed. + /// + private string MovementSpeedTextFormat { + get { + if (Mathf.Abs(_movementSpeed - _maxMovementSpeed) < Mathf.Epsilon || Mathf.Abs(_movementSpeed - _minMovementSpeed) < Mathf.Epsilon) + return "{0:0.##}"; + + if (_movementSpeed < 10.0f) + return "{0:0.00}"; + else if (_movementSpeed < 100.0f) + return "{0:0.0}"; + else + return "{0:#}"; + } + } + /// /// Gets or sets the camera movement speed. /// @@ -215,9 +233,8 @@ namespace FlaxEditor.Viewport { _movementSpeed = value; - var format = (_movementSpeed < 1.0f) ? "{0:0.##}" : "{0:#}"; if (_cameraButton != null) - _cameraButton.Text = string.Format(format, _movementSpeed); + _cameraButton.Text = string.Format(MovementSpeedTextFormat, _movementSpeed); } } @@ -527,14 +544,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:#}"; + var cameraSpeedTextWidth = Style.Current.FontMedium.MeasureText("0.00").X; // Camera settings widget _cameraWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight); // Camera settings menu var cameraCM = new ContextMenu(); - _cameraButton = new ViewportWidgetButton(string.Format(format, _movementSpeed), Editor.Instance.Icons.Camera64, cameraCM, false, Style.Current.FontMedium.MeasureText("0.00").X) + _cameraButton = new ViewportWidgetButton(string.Format(MovementSpeedTextFormat, _movementSpeed), Editor.Instance.Icons.Camera64, cameraCM, false, cameraSpeedTextWidth) { Tag = this, TooltipText = "Camera Settings", @@ -1060,9 +1077,21 @@ namespace FlaxEditor.Viewport _speedStep = 0; return; } + + if (Math.Abs(_movementSpeed - _maxMovementSpeed) < Mathf.Epsilon) + { + _speedStep = _maxSpeedSteps; + return; + } + else if (Math.Abs(_movementSpeed - _minMovementSpeed) < Mathf.Epsilon) + { + _speedStep = 0; + return; + } // calculate current linear/eased progress - float progress = Mathf.Remap(_movementSpeed, _minMovementSpeed, _maxMovementSpeed, 0.0f, 1.0f); + var progress = Mathf.Remap(_movementSpeed, _minMovementSpeed, _maxMovementSpeed, 0.0f, 1.0f); + if (_useCameraEasing) progress = Mathf.Pow(progress, 1.0f / _cameraEasingDegree); @@ -1081,8 +1110,10 @@ namespace FlaxEditor.Viewport var progress = _useCameraEasing ? Mathf.Pow((float)_speedStep / _maxSpeedSteps, _cameraEasingDegree) : (float)_speedStep / _maxSpeedSteps; - - MovementSpeed = Mathf.Lerp(_minMovementSpeed, _maxMovementSpeed, progress); + + var speed = Mathf.Lerp(_minMovementSpeed, _maxMovementSpeed, progress); + MovementSpeed = (float)Math.Round(speed, 3); + _editor.ProjectCache.SetCustomData("CameraMovementSpeedValue", _movementSpeed.ToString()); } private void OnEditorOptionsChanged(EditorOptions options) From 966e5cdda27b209d2a775375b21379cb72b4fc3e Mon Sep 17 00:00:00 2001 From: Christopher Rothert Date: Sun, 8 Oct 2023 01:30:35 +0200 Subject: [PATCH 12/32] Update some comments --- Source/Editor/Viewport/EditorViewport.cs | 40 +++++++++++++----------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index 8ce99b115..8f733ce0c 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -546,10 +546,10 @@ namespace FlaxEditor.Viewport var xLocationForExtras = textSize.X + 5; var cameraSpeedTextWidth = Style.Current.FontMedium.MeasureText("0.00").X; - // Camera settings widget + // Camera Settings Widget _cameraWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight); - // Camera settings menu + // Camera Settings Menu var cameraCM = new ContextMenu(); _cameraButton = new ViewportWidgetButton(string.Format(MovementSpeedTextFormat, _movementSpeed), Editor.Instance.Icons.Camera64, cameraCM, false, cameraSpeedTextWidth) { @@ -559,7 +559,7 @@ namespace FlaxEditor.Viewport }; _cameraWidget.Parent = this; - // Toggle orthographic mode widget + // Orthographic/Perspective Mode Widget _orthographicModeButton = new ViewportWidgetButton(string.Empty, Editor.Instance.Icons.CamSpeed32, null, true) { Checked = !_isOrtho, @@ -568,7 +568,7 @@ namespace FlaxEditor.Viewport }; _orthographicModeButton.Toggled += OnOrthographicModeToggled; - // Camera speed + // Camera Speed var camSpeedButton = cameraCM.AddButton("Camera Speed"); camSpeedButton.CloseMenuOnClick = false; var camSpeedValue = new FloatValueBox(_movementSpeed, xLocationForExtras, 2, 70.0f, _minMovementSpeed, _maxMovementSpeed, 0.5f) @@ -579,7 +579,7 @@ namespace FlaxEditor.Viewport camSpeedValue.ValueChanged += () => OnMovementSpeedChanged(camSpeedValue); cameraCM.VisibleChanged += control => camSpeedValue.Value = _movementSpeed; - // Minimum & maximum camera speed + // Minimum & Maximum Camera Speed var minCamSpeedButton = cameraCM.AddButton("Min Cam Speed"); minCamSpeedButton.CloseMenuOnClick = false; var minCamSpeedValue = new FloatValueBox(_minMovementSpeed, xLocationForExtras, 2, 70.0f, 0.05f, _maxMovementSpeed, 0.5f) @@ -614,7 +614,7 @@ namespace FlaxEditor.Viewport }; cameraCM.VisibleChanged += control => maxCamSpeedValue.Value = _maxMovementSpeed; - // Camera easing + // Camera Easing { var useCameraEasing = cameraCM.AddButton("Camera Easing"); useCameraEasing.CloseMenuOnClick = false; @@ -627,7 +627,7 @@ namespace FlaxEditor.Viewport cameraCM.VisibleChanged += control => useCameraEasingValue.Checked = _useCameraEasing; } - // Panning speed + // Panning Speed { var panningSpeed = cameraCM.AddButton("Panning Speed"); panningSpeed.CloseMenuOnClick = false; @@ -644,7 +644,7 @@ namespace FlaxEditor.Viewport }; } - // Relative panning + // Relative Panning { var relativePanning = cameraCM.AddButton("Relative Panning"); relativePanning.CloseMenuOnClick = false; @@ -664,7 +664,7 @@ namespace FlaxEditor.Viewport cameraCM.VisibleChanged += control => relativePanningValue.Checked = _relativePanning; } - // Invert panning + // Invert Panning { var invertPanning = cameraCM.AddButton("Invert Panning"); invertPanning.CloseMenuOnClick = false; @@ -679,7 +679,7 @@ namespace FlaxEditor.Viewport cameraCM.AddSeparator(); - // Camera viewpoints + // Camera Viewpoints { var cameraView = cameraCM.AddChildMenu("Viewpoints").ContextMenu; for (int i = 0; i < EditorViewportCameraViewpointValues.Length; i++) @@ -692,7 +692,7 @@ namespace FlaxEditor.Viewport cameraView.ButtonClicked += OnViewpointChanged; } - // Orthographic mode + // Orthographic Mode { var ortho = cameraCM.AddButton("Orthographic"); ortho.CloseMenuOnClick = false; @@ -712,7 +712,7 @@ namespace FlaxEditor.Viewport cameraCM.VisibleChanged += control => orthoValue.Checked = _isOrtho; } - // Field of view + // Field of View { var fov = cameraCM.AddButton("Field Of View"); fov.CloseMenuOnClick = false; @@ -729,7 +729,7 @@ namespace FlaxEditor.Viewport }; } - // Orthographic scale + // Orthographic Scale { var orthoSize = cameraCM.AddButton("Ortho Scale"); orthoSize.CloseMenuOnClick = false; @@ -746,7 +746,7 @@ namespace FlaxEditor.Viewport }; } - // Near plane + // Near Plane { var nearPlane = cameraCM.AddButton("Near Plane"); nearPlane.CloseMenuOnClick = false; @@ -759,7 +759,7 @@ namespace FlaxEditor.Viewport cameraCM.VisibleChanged += control => nearPlaneValue.Value = _nearPlane; } - // Far plane + // Far Plane { var farPlane = cameraCM.AddButton("Far Plane"); farPlane.CloseMenuOnClick = false; @@ -774,14 +774,16 @@ namespace FlaxEditor.Viewport cameraCM.AddSeparator(); - // Reset button + // Reset Button { var reset = cameraCM.AddButton("Reset to default"); reset.ButtonClicked += button => { SetupViewportOptions(); - // trigger UI update + // if the context menu is opened without triggering the value changes beforehand, + // the movement speed will not be correctly reset to its default value in certain cases + // therefore, a UI update needs to be triggered here minCamSpeedValue.Value = _minMovementSpeed; camSpeedValue.Value = _movementSpeed; maxCamSpeedValue.Value = _maxMovementSpeed; @@ -815,7 +817,7 @@ namespace FlaxEditor.Viewport } } - // View flags + // View Flags { var viewFlags = ViewWidgetButtonMenu.AddChildMenu("View Flags").ContextMenu; viewFlags.AddButton("Reset flags", () => Task.ViewFlags = ViewFlags.DefaultEditor).Icon = Editor.Instance.Icons.Rotate32; @@ -839,7 +841,7 @@ namespace FlaxEditor.Viewport viewFlags.VisibleChanged += WidgetViewFlagsShowHide; } - // Debug view + // Debug View { var debugView = ViewWidgetButtonMenu.AddChildMenu("Debug View").ContextMenu; for (int i = 0; i < EditorViewportViewModeValues.Length; i++) From 6f773bd558a760eb0d347042181b29b8cf16dbb1 Mon Sep 17 00:00:00 2001 From: MineBill Date: Tue, 24 Oct 2023 18:03:07 +0300 Subject: [PATCH 13/32] Make the message box a TASKMODEL to prevent interation with the editor. --- Source/Engine/Platform/Windows/WindowsPlatform.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Engine/Platform/Windows/WindowsPlatform.cpp b/Source/Engine/Platform/Windows/WindowsPlatform.cpp index c5bc44ab9..474a92072 100644 --- a/Source/Engine/Platform/Windows/WindowsPlatform.cpp +++ b/Source/Engine/Platform/Windows/WindowsPlatform.cpp @@ -451,6 +451,7 @@ DialogResult MessageBox::Show(Window* parent, const StringView& text, const Stri default: break; } + flags |= MB_TASKMODAL; // Show dialog int result = MessageBoxW(parent ? static_cast(parent->GetNativePtr()) : nullptr, String(text).GetText(), String(caption).GetText(), flags); From daf31cfa4dc26f6c87dde163a43efab100a2ded9 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 25 Oct 2023 14:57:44 +0200 Subject: [PATCH 14/32] Format code #1611 --- Source/Editor/Viewport/EditorViewport.cs | 27 +++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index 8fd28ebfd..c49392d01 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -212,8 +212,10 @@ namespace FlaxEditor.Viewport /// /// Format of the text for the camera move speed. /// - private string MovementSpeedTextFormat { - get { + private string MovementSpeedTextFormat + { + get + { if (Mathf.Abs(_movementSpeed - _maxMovementSpeed) < Mathf.Epsilon || Mathf.Abs(_movementSpeed - _minMovementSpeed) < Mathf.Epsilon) return "{0:0.##}"; @@ -480,7 +482,7 @@ namespace FlaxEditor.Viewport get => _panningSpeed; set => _panningSpeed = value; } - + /// /// The input actions collection to processed during user input. /// @@ -544,6 +546,7 @@ namespace FlaxEditor.Viewport if (useWidgets) { #region Camera settings widget + var largestText = "Relative Panning"; var textSize = Style.Current.FontMedium.MeasureText(largestText); var xLocationForExtras = textSize.X + 5; @@ -609,7 +612,7 @@ namespace FlaxEditor.Viewport maxCamSpeedValue.ValueChanged += () => { OnMaxMovementSpeedChanged(maxCamSpeedValue); - + minCamSpeedValue.MaxValue = maxCamSpeedValue.Value; if (Math.Abs(camSpeedValue.MaxValue - maxCamSpeedValue.Value) > Mathf.Epsilon) @@ -792,9 +795,11 @@ namespace FlaxEditor.Viewport maxCamSpeedValue.Value = _maxMovementSpeed; }; } + #endregion Camera settings widget #region View mode widget + largestText = "Brightness"; textSize = Style.Current.FontMedium.MeasureText(largestText); xLocationForExtras = textSize.X + 5; @@ -964,6 +969,7 @@ namespace FlaxEditor.Viewport resolutionValue.ValueChanged += () => ResolutionScale = resolutionValue.Value; ViewWidgetButtonMenu.VisibleChanged += control => resolutionValue.Value = ResolutionScale; } + #endregion View mode widget } @@ -1036,7 +1042,7 @@ namespace FlaxEditor.Viewport OnCameraMovementProgressChanged(); _editor.ProjectCache.SetCustomData("CameraMaxMovementSpeedValue", _maxMovementSpeed.ToString()); } - + private void OnCameraEasingToggled(Control control) { _useCameraEasing = !_useCameraEasing; @@ -1145,11 +1151,12 @@ namespace FlaxEditor.Viewport private void OnCameraMovementProgressChanged() { // prevent NaN - if (Math.Abs(_minMovementSpeed - _maxMovementSpeed) < Mathf.Epsilon) { + if (Math.Abs(_minMovementSpeed - _maxMovementSpeed) < Mathf.Epsilon) + { _speedStep = 0; return; } - + if (Math.Abs(_movementSpeed - _maxMovementSpeed) < Mathf.Epsilon) { _speedStep = _maxSpeedSteps; @@ -1180,9 +1187,9 @@ namespace FlaxEditor.Viewport // calculate new linear/eased progress var progress = _useCameraEasing - ? Mathf.Pow((float)_speedStep / _maxSpeedSteps, _cameraEasingDegree) - : (float)_speedStep / _maxSpeedSteps; - + ? Mathf.Pow((float)_speedStep / _maxSpeedSteps, _cameraEasingDegree) + : (float)_speedStep / _maxSpeedSteps; + var speed = Mathf.Lerp(_minMovementSpeed, _maxMovementSpeed, progress); MovementSpeed = (float)Math.Round(speed, 3); _editor.ProjectCache.SetCustomData("CameraMovementSpeedValue", _movementSpeed.ToString()); From 966cd973c660e76feeac8547a8314960f389e967 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 25 Oct 2023 18:35:59 +0200 Subject: [PATCH 15/32] Add `GetHash` to various math/core types #1802 --- Source/Engine/Core/Math/Vector2.h | 6 ++++++ Source/Engine/Core/Math/Vector3.h | 6 ++++++ Source/Engine/Core/Math/Vector4.h | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/Source/Engine/Core/Math/Vector2.h b/Source/Engine/Core/Math/Vector2.h index 83deb009a..cea03ec10 100644 --- a/Source/Engine/Core/Math/Vector2.h +++ b/Source/Engine/Core/Math/Vector2.h @@ -646,6 +646,12 @@ inline Vector2Base operator/(typename TOtherFloat::Type a, const Vector2Ba return Vector2Base(a) / b; } +template +inline uint32 GetHash(const Vector2Base& key) +{ + return (*(uint32*)&key.X * 397) ^ *(uint32*)&key.Y; +} + namespace Math { template diff --git a/Source/Engine/Core/Math/Vector3.h b/Source/Engine/Core/Math/Vector3.h index c0ebdf01d..01b55e9bd 100644 --- a/Source/Engine/Core/Math/Vector3.h +++ b/Source/Engine/Core/Math/Vector3.h @@ -977,6 +977,12 @@ inline Vector3Base operator/(typename TOtherFloat::Type a, const Vector3Ba return Vector3Base(a) / b; } +template +inline uint32 GetHash(const Vector3Base& key) +{ + return (((*(uint32*)&key.X * 397) ^ *(uint32*)&key.Y) * 397) ^ *(uint32*)&key.Z; +} + namespace Math { template diff --git a/Source/Engine/Core/Math/Vector4.h b/Source/Engine/Core/Math/Vector4.h index 5c7b24c4a..1cc6d4db8 100644 --- a/Source/Engine/Core/Math/Vector4.h +++ b/Source/Engine/Core/Math/Vector4.h @@ -552,6 +552,12 @@ inline Vector4Base operator/(typename TOtherFloat::Type a, const Vector4Ba return Vector4Base(a) / b; } +template +inline uint32 GetHash(const Vector4Base& key) +{ + return (((((*(uint32*)&key.X * 397) ^ *(uint32*)&key.Y) * 397) ^ *(uint32*)&key.Z) * 397) ^*(uint32*)&key.W; +} + namespace Math { template From c27187bd0ab0a5c5065d1e05df0772264062588e Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 25 Oct 2023 19:17:04 +0200 Subject: [PATCH 16/32] Fix deserializing vector types in Editor from `ToString` FormatException #1802 --- Source/Editor/Options/InputBinding.cs | 7 ------ .../Math/TypeConverters/ColorConverter.cs | 4 ---- .../Math/TypeConverters/Double2Converter.cs | 24 ++----------------- .../Math/TypeConverters/Double3Converter.cs | 24 ++----------------- .../Math/TypeConverters/Double4Converter.cs | 24 ++----------------- .../Math/TypeConverters/Float2Converter.cs | 24 ++----------------- .../Math/TypeConverters/Float3Converter.cs | 24 ++----------------- .../Math/TypeConverters/Float4Converter.cs | 24 ++++++++++++++----- .../Core/Math/TypeConverters/Int2Converter.cs | 24 ++----------------- .../Core/Math/TypeConverters/Int3Converter.cs | 24 ++----------------- .../Core/Math/TypeConverters/Int4Converter.cs | 24 ++----------------- .../TypeConverters/QuaternionConverter.cs | 24 ++----------------- .../Math/TypeConverters/Vector2Converter.cs | 24 ++----------------- .../Math/TypeConverters/Vector3Converter.cs | 24 ++----------------- .../Math/TypeConverters/Vector4Converter.cs | 24 ++----------------- 15 files changed, 42 insertions(+), 281 deletions(-) diff --git a/Source/Editor/Options/InputBinding.cs b/Source/Editor/Options/InputBinding.cs index eb61c0f68..95c3c1d6f 100644 --- a/Source/Editor/Options/InputBinding.cs +++ b/Source/Editor/Options/InputBinding.cs @@ -259,10 +259,7 @@ namespace FlaxEditor.Options public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) - { return true; - } - return base.CanConvertFrom(context, sourceType); } @@ -270,9 +267,7 @@ namespace FlaxEditor.Options public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(string)) - { return false; - } return base.CanConvertTo(context, destinationType); } @@ -284,7 +279,6 @@ namespace FlaxEditor.Options InputBinding.TryParse(str, out var result); return result; } - return base.ConvertFrom(context, culture, value); } @@ -295,7 +289,6 @@ namespace FlaxEditor.Options { return ((InputBinding)value).ToString(); } - return base.ConvertTo(context, culture, value, destinationType); } } diff --git a/Source/Engine/Core/Math/TypeConverters/ColorConverter.cs b/Source/Engine/Core/Math/TypeConverters/ColorConverter.cs index afd34bbfd..65377acaa 100644 --- a/Source/Engine/Core/Math/TypeConverters/ColorConverter.cs +++ b/Source/Engine/Core/Math/TypeConverters/ColorConverter.cs @@ -13,9 +13,7 @@ namespace FlaxEngine.TypeConverters public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) - { return true; - } return base.CanConvertFrom(context, sourceType); } @@ -23,9 +21,7 @@ namespace FlaxEngine.TypeConverters public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(string)) - { return false; - } return base.CanConvertTo(context, destinationType); } diff --git a/Source/Engine/Core/Math/TypeConverters/Double2Converter.cs b/Source/Engine/Core/Math/TypeConverters/Double2Converter.cs index 4eebbfce4..e0670df05 100644 --- a/Source/Engine/Core/Math/TypeConverters/Double2Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Double2Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Double2Converter : TypeConverter + internal class Double2Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Double2(double.Parse(v[0], culture), double.Parse(v[1], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Double3Converter.cs b/Source/Engine/Core/Math/TypeConverters/Double3Converter.cs index 420e0016c..a66892ecb 100644 --- a/Source/Engine/Core/Math/TypeConverters/Double3Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Double3Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Double3Converter : TypeConverter + internal class Double3Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Double3(double.Parse(v[0], culture), double.Parse(v[1], culture), double.Parse(v[2], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Double4Converter.cs b/Source/Engine/Core/Math/TypeConverters/Double4Converter.cs index fc1d9a7fe..d085217ef 100644 --- a/Source/Engine/Core/Math/TypeConverters/Double4Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Double4Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Double4Converter : TypeConverter + internal class Double4Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Double4(double.Parse(v[0], culture), double.Parse(v[1], culture), double.Parse(v[2], culture), double.Parse(v[3], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Float2Converter.cs b/Source/Engine/Core/Math/TypeConverters/Float2Converter.cs index a41a0f4d5..4b2ffadf5 100644 --- a/Source/Engine/Core/Math/TypeConverters/Float2Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Float2Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Float2Converter : TypeConverter + internal class Float2Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Float2(float.Parse(v[0], culture), float.Parse(v[1], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Float3Converter.cs b/Source/Engine/Core/Math/TypeConverters/Float3Converter.cs index aded4117e..3739c44ef 100644 --- a/Source/Engine/Core/Math/TypeConverters/Float3Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Float3Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Float3Converter : TypeConverter + internal class Float3Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Float3(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Float4Converter.cs b/Source/Engine/Core/Math/TypeConverters/Float4Converter.cs index 58c76ac65..620f2c838 100644 --- a/Source/Engine/Core/Math/TypeConverters/Float4Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Float4Converter.cs @@ -7,15 +7,13 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Float4Converter : TypeConverter + internal class VectorConverter : TypeConverter { /// public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) - { return true; - } return base.CanConvertFrom(context, sourceType); } @@ -23,18 +21,32 @@ namespace FlaxEngine.TypeConverters public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(string)) - { return false; - } return base.CanConvertTo(context, destinationType); } + internal static string[] GetParts(string str) + { + string[] v = str.Split(','); + if (v.Length == 1) + { + // When converting from ToString() + v = str.Split(' '); + for (int i = 0; i < v.Length; i++) + v[i] = v[i].Substring(v[i].IndexOf(':') + 1); + } + return v; + } + } + + internal class Float4Converter : VectorConverter + { /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Float4(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Int2Converter.cs b/Source/Engine/Core/Math/TypeConverters/Int2Converter.cs index c4989c085..f528aa46b 100644 --- a/Source/Engine/Core/Math/TypeConverters/Int2Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Int2Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Int2Converter : TypeConverter + internal class Int2Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Int2(int.Parse(v[0], culture), int.Parse(v[1], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Int3Converter.cs b/Source/Engine/Core/Math/TypeConverters/Int3Converter.cs index fe01f91fd..520f806d0 100644 --- a/Source/Engine/Core/Math/TypeConverters/Int3Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Int3Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Int3Converter : TypeConverter + internal class Int3Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Int3(int.Parse(v[0], culture), int.Parse(v[1], culture), int.Parse(v[2], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Int4Converter.cs b/Source/Engine/Core/Math/TypeConverters/Int4Converter.cs index 2ce0fc202..e9a27dfda 100644 --- a/Source/Engine/Core/Math/TypeConverters/Int4Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Int4Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Int4Converter : TypeConverter + internal class Int4Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Int4(int.Parse(v[0], culture), int.Parse(v[1], culture), int.Parse(v[2], culture), int.Parse(v[3], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/QuaternionConverter.cs b/Source/Engine/Core/Math/TypeConverters/QuaternionConverter.cs index 23bb901be..5d9aa206b 100644 --- a/Source/Engine/Core/Math/TypeConverters/QuaternionConverter.cs +++ b/Source/Engine/Core/Math/TypeConverters/QuaternionConverter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class QuaternionConverter : TypeConverter + internal class QuaternionConverter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Quaternion(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Vector2Converter.cs b/Source/Engine/Core/Math/TypeConverters/Vector2Converter.cs index 96d6beadc..acb5b5817 100644 --- a/Source/Engine/Core/Math/TypeConverters/Vector2Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Vector2Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Vector2Converter : TypeConverter + internal class Vector2Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Vector2(float.Parse(v[0], culture), float.Parse(v[1], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Vector3Converter.cs b/Source/Engine/Core/Math/TypeConverters/Vector3Converter.cs index 23ee4df11..66ec831f0 100644 --- a/Source/Engine/Core/Math/TypeConverters/Vector3Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Vector3Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Vector3Converter : TypeConverter + internal class Vector3Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Vector3(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture)); } return base.ConvertFrom(context, culture, value); diff --git a/Source/Engine/Core/Math/TypeConverters/Vector4Converter.cs b/Source/Engine/Core/Math/TypeConverters/Vector4Converter.cs index c3b4d074b..f4781f45b 100644 --- a/Source/Engine/Core/Math/TypeConverters/Vector4Converter.cs +++ b/Source/Engine/Core/Math/TypeConverters/Vector4Converter.cs @@ -7,34 +7,14 @@ using System.Globalization; namespace FlaxEngine.TypeConverters { - internal class Vector4Converter : TypeConverter + internal class Vector4Converter : VectorConverter { - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - if (destinationType == typeof(string)) - { - return false; - } - return base.CanConvertTo(context, destinationType); - } - /// public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { - string[] v = str.Split(','); + string[] v = GetParts(str); return new Vector4(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture)); } return base.ConvertFrom(context, culture, value); From 2158fa7358aca67c2a5c9f90c89edd4a92a2b52d Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 25 Oct 2023 23:34:29 +0200 Subject: [PATCH 17/32] Remove not needed end line in script template --- Content/Editor/Scripting/ScriptTemplate.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Content/Editor/Scripting/ScriptTemplate.cs b/Content/Editor/Scripting/ScriptTemplate.cs index 663acf05f..30fbe9d86 100644 --- a/Content/Editor/Scripting/ScriptTemplate.cs +++ b/Content/Editor/Scripting/ScriptTemplate.cs @@ -33,4 +33,3 @@ public class %class% : Script // Here you can add code that needs to be called every frame } } - From f44421b7a76551415e12915599387c862f7ecbb2 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 26 Oct 2023 11:25:30 +0200 Subject: [PATCH 18/32] Optimize managed method invoke on NetCore to skip virtual call that is the same as default one --- Source/Engine/Scripting/BinaryModule.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Engine/Scripting/BinaryModule.cpp b/Source/Engine/Scripting/BinaryModule.cpp index efd147917..679ead4e3 100644 --- a/Source/Engine/Scripting/BinaryModule.cpp +++ b/Source/Engine/Scripting/BinaryModule.cpp @@ -1270,7 +1270,11 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp // Invoke the method MObject* exception = nullptr; +#if USE_NETCORE // NetCore uses the same path for both virtual and non-virtual calls + MObject* resultObject = mMethod->Invoke(mInstance, params, &exception); +#else MObject* resultObject = withInterfaces ? mMethod->InvokeVirtual((MObject*)mInstance, params, &exception) : mMethod->Invoke(mInstance, params, &exception); +#endif if (exception) { MException ex(exception); From bfaa292b04ae6c793a0d9ab4e4b161cdc52a8687 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 26 Oct 2023 11:37:37 +0200 Subject: [PATCH 19/32] Fix invoking managed method on value types (eg. `Transform`) to properly handle instance value #1801 --- Source/Engine/Engine/NativeInterop.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index 2f74e421c..fea1fadda 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -1302,7 +1302,8 @@ namespace FlaxEngine.Interop #if !USE_AOT internal bool TryGetDelegate(out Invoker.MarshalAndInvokeDelegate outDeleg, out object outDelegInvoke) { - if (invokeDelegate == null) + // Skip using in-built delegate for value types (eg. Transform) to properly handle instance value passing to method + if (invokeDelegate == null && !method.DeclaringType.IsValueType) { List methodTypes = new List(); if (!method.IsStatic) From 186e13b5e894d898db4ad8bf3fae70df5f3cbed1 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 26 Oct 2023 14:33:21 +0200 Subject: [PATCH 20/32] Add support for runtime running on GPU without Compute Shaders support --- Source/Engine/Graphics/GPUDevice.cpp | 2 ++ Source/Engine/Graphics/Shaders/GPUShader.cpp | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Graphics/GPUDevice.cpp b/Source/Engine/Graphics/GPUDevice.cpp index 34d8e7661..f0056e26c 100644 --- a/Source/Engine/Graphics/GPUDevice.cpp +++ b/Source/Engine/Graphics/GPUDevice.cpp @@ -313,6 +313,8 @@ bool GPUDevice::Init() _res->TasksManager.SetExecutor(CreateTasksExecutor()); LOG(Info, "Total graphics memory: {0}", Utilities::BytesToText(TotalGraphicsMemory)); + if (!Limits.HasCompute) + LOG(Warning, "Compute Shaders are not supported"); return false; } diff --git a/Source/Engine/Graphics/Shaders/GPUShader.cpp b/Source/Engine/Graphics/Shaders/GPUShader.cpp index e76ee9996..86d983fd8 100644 --- a/Source/Engine/Graphics/Shaders/GPUShader.cpp +++ b/Source/Engine/Graphics/Shaders/GPUShader.cpp @@ -87,7 +87,11 @@ bool GPUShader::Create(MemoryReadStream& stream) GPUShaderProgramInitializer initializer; #if !BUILD_RELEASE initializer.Owner = this; + const StringView name = GetName(); +#else + const StringView name; #endif + const bool hasCompute = GPUDevice::Instance->Limits.HasCompute; for (int32 i = 0; i < shadersCount; i++) { const ShaderStage type = static_cast(stream.ReadByte()); @@ -117,10 +121,15 @@ bool GPUShader::Create(MemoryReadStream& stream) stream.ReadBytes(&initializer.Bindings, sizeof(ShaderBindings)); // Create shader program + if (type == ShaderStage::Compute && !hasCompute) + { + LOG(Warning, "Failed to create {} Shader program '{}' ({}).", ::ToString(type), String(initializer.Name), name); + continue; + } GPUShaderProgram* shader = CreateGPUShaderProgram(type, initializer, cache, cacheSize, stream); if (shader == nullptr) { - LOG(Error, "Failed to create {} Shader program '{}'.", ::ToString(type), String(initializer.Name)); + LOG(Error, "Failed to create {} Shader program '{}' ({}).", ::ToString(type), String(initializer.Name), name); return true; } From 1d41aa01ce95d942148deb7b97132872bbc8db9d Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 26 Oct 2023 14:36:02 +0200 Subject: [PATCH 21/32] Refactor vertex shaders to use `GPUShaderProgramVS::InputElement` for input layout data --- .../Graphics/Shaders/GPUShaderProgram.h | 13 +++++++ .../DirectX/DX11/GPUShaderDX11.cpp | 35 ++++++----------- .../DirectX/DX12/GPUShaderDX12.cpp | 33 ++++++---------- .../GraphicsDevice/Vulkan/GPUShaderVulkan.cpp | 38 +++++++------------ .../ShadersCompilation/ShaderCompiler.cpp | 19 +++++----- 5 files changed, 59 insertions(+), 79 deletions(-) diff --git a/Source/Engine/Graphics/Shaders/GPUShaderProgram.h b/Source/Engine/Graphics/Shaders/GPUShaderProgram.h index 09c45506f..31f6638dc 100644 --- a/Source/Engine/Graphics/Shaders/GPUShaderProgram.h +++ b/Source/Engine/Graphics/Shaders/GPUShaderProgram.h @@ -122,6 +122,19 @@ public: ///
class GPUShaderProgramVS : public GPUShaderProgram { +public: + // Input element run-time data (see VertexShaderMeta::InputElement for compile-time data) + PACK_STRUCT(struct InputElement + { + byte Type; // VertexShaderMeta::InputType + byte Index; + byte Format; // PixelFormat + byte InputSlot; + uint32 AlignedByteOffset; // Fixed value or INPUT_LAYOUT_ELEMENT_ALIGN if auto + byte InputSlotClass; // INPUT_LAYOUT_ELEMENT_PER_VERTEX_DATA or INPUT_LAYOUT_ELEMENT_PER_INSTANCE_DATA + uint32 InstanceDataStepRate; // 0 if per-vertex + }); + public: /// /// Gets input layout description handle (platform dependent). diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderDX11.cpp index b58684a4e..52192c634 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderDX11.cpp @@ -15,32 +15,21 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const { case ShaderStage::Vertex: { - D3D11_INPUT_ELEMENT_DESC inputLayoutDesc[VERTEX_SHADER_MAX_INPUT_ELEMENTS]; - - // Temporary variables - byte Type, Format, Index, InputSlot, InputSlotClass; - uint32 AlignedByteOffset, InstanceDataStepRate; - - // Load Input Layout (it may be empty) + // Load Input Layout byte inputLayoutSize; stream.ReadByte(&inputLayoutSize); ASSERT(inputLayoutSize <= VERTEX_SHADER_MAX_INPUT_ELEMENTS); + D3D11_INPUT_ELEMENT_DESC inputLayoutDesc[VERTEX_SHADER_MAX_INPUT_ELEMENTS]; for (int32 a = 0; a < inputLayoutSize; a++) { // Read description - // TODO: maybe use struct and load at once? - stream.ReadByte(&Type); - stream.ReadByte(&Index); - stream.ReadByte(&Format); - stream.ReadByte(&InputSlot); - stream.ReadUint32(&AlignedByteOffset); - stream.ReadByte(&InputSlotClass); - stream.ReadUint32(&InstanceDataStepRate); + GPUShaderProgramVS::InputElement inputElement; + stream.Read(inputElement); // Get semantic name const char* semanticName = nullptr; // TODO: maybe use enum+mapping ? - switch (Type) + switch (inputElement.Type) { case 1: semanticName = "POSITION"; @@ -70,7 +59,7 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const semanticName = "BLENDWEIGHT"; break; default: - LOG(Fatal, "Invalid vertex shader element semantic type: {0}", Type); + LOG(Fatal, "Invalid vertex shader element semantic type: {0}", inputElement.Type); break; } @@ -78,12 +67,12 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const inputLayoutDesc[a] = { semanticName, - static_cast(Index), - static_cast(Format), - static_cast(InputSlot), - static_cast(AlignedByteOffset), - static_cast(InputSlotClass), - static_cast(InstanceDataStepRate) + static_cast(inputElement.Index), + static_cast(inputElement.Format), + static_cast(inputElement.InputSlot), + static_cast(inputElement.AlignedByteOffset), + static_cast(inputElement.InputSlotClass), + static_cast(inputElement.InstanceDataStepRate) }; } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderDX12.cpp index e1e716853..07352b674 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderDX12.cpp @@ -20,32 +20,21 @@ GPUShaderProgram* GPUShaderDX12::CreateGPUShaderProgram(ShaderStage type, const { case ShaderStage::Vertex: { - D3D12_INPUT_ELEMENT_DESC inputLayout[VERTEX_SHADER_MAX_INPUT_ELEMENTS]; - - // Temporary variables - byte Type, Format, Index, InputSlot, InputSlotClass; - uint32 AlignedByteOffset, InstanceDataStepRate; - // Load Input Layout (it may be empty) byte inputLayoutSize; stream.ReadByte(&inputLayoutSize); ASSERT(inputLayoutSize <= VERTEX_SHADER_MAX_INPUT_ELEMENTS); + D3D12_INPUT_ELEMENT_DESC inputLayout[VERTEX_SHADER_MAX_INPUT_ELEMENTS]; for (int32 a = 0; a < inputLayoutSize; a++) { // Read description - // TODO: maybe use struct and load at once? - stream.ReadByte(&Type); - stream.ReadByte(&Index); - stream.ReadByte(&Format); - stream.ReadByte(&InputSlot); - stream.ReadUint32(&AlignedByteOffset); - stream.ReadByte(&InputSlotClass); - stream.ReadUint32(&InstanceDataStepRate); + GPUShaderProgramVS::InputElement inputElement; + stream.Read(inputElement); // Get semantic name const char* semanticName = nullptr; // TODO: maybe use enum+mapping ? - switch (Type) + switch (inputElement.Type) { case 1: semanticName = "POSITION"; @@ -75,7 +64,7 @@ GPUShaderProgram* GPUShaderDX12::CreateGPUShaderProgram(ShaderStage type, const semanticName = "BLENDWEIGHT"; break; default: - LOG(Fatal, "Invalid vertex shader element semantic type: {0}", Type); + LOG(Fatal, "Invalid vertex shader element semantic type: {0}", inputElement.Type); break; } @@ -83,12 +72,12 @@ GPUShaderProgram* GPUShaderDX12::CreateGPUShaderProgram(ShaderStage type, const inputLayout[a] = { semanticName, - static_cast(Index), - static_cast(Format), - static_cast(InputSlot), - static_cast(AlignedByteOffset), - static_cast(InputSlotClass), - static_cast(InstanceDataStepRate) + static_cast(inputElement.Index), + static_cast(inputElement.Format), + static_cast(inputElement.InputSlot), + static_cast(inputElement.AlignedByteOffset), + static_cast(inputElement.InputSlotClass), + static_cast(inputElement.InstanceDataStepRate) }; } diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp index 5e583d713..852ce5bad 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp @@ -14,9 +14,9 @@ #include "Engine/Graphics/PixelFormatExtensions.h" #if PLATFORM_DESKTOP -#define VULKAN_UNIFORM_RING_BUFFER_SIZE 24 * 1024 * 1024 +#define VULKAN_UNIFORM_RING_BUFFER_SIZE (24 * 1024 * 1024) #else -#define VULKAN_UNIFORM_RING_BUFFER_SIZE 8 * 1024 * 1024 +#define VULKAN_UNIFORM_RING_BUFFER_SIZE (8 * 1024 * 1024) #endif UniformBufferUploaderVulkan::UniformBufferUploaderVulkan(GPUDeviceVulkan* device) @@ -153,10 +153,6 @@ GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, cons vertexBindingDescriptions[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; } - // Temporary variables - byte Type, Format, Index, InputSlot, InputSlotClass; - uint32 AlignedByteOffset, InstanceDataStepRate; - // Load Input Layout (it may be empty) byte inputLayoutSize; stream.ReadByte(&inputLayoutSize); @@ -167,32 +163,26 @@ GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, cons for (int32 a = 0; a < inputLayoutSize; a++) { // Read description - // TODO: maybe use struct and load at once? - stream.ReadByte(&Type); - stream.ReadByte(&Index); - stream.ReadByte(&Format); - stream.ReadByte(&InputSlot); - stream.ReadUint32(&AlignedByteOffset); - stream.ReadByte(&InputSlotClass); - stream.ReadUint32(&InstanceDataStepRate); + GPUShaderProgramVS::InputElement inputElement; + stream.Read(inputElement); - const auto size = PixelFormatExtensions::SizeInBytes((PixelFormat)Format); - if (AlignedByteOffset != INPUT_LAYOUT_ELEMENT_ALIGN) - offset = AlignedByteOffset; + const auto size = PixelFormatExtensions::SizeInBytes((PixelFormat)inputElement.Format); + if (inputElement.AlignedByteOffset != INPUT_LAYOUT_ELEMENT_ALIGN) + offset = inputElement.AlignedByteOffset; - auto& vertexBindingDescription = vertexBindingDescriptions[InputSlot]; - vertexBindingDescription.binding = InputSlot; + auto& vertexBindingDescription = vertexBindingDescriptions[inputElement.InputSlot]; + vertexBindingDescription.binding = inputElement.InputSlot; vertexBindingDescription.stride = Math::Max(vertexBindingDescription.stride, (uint32_t)(offset + size)); - vertexBindingDescription.inputRate = InputSlotClass == INPUT_LAYOUT_ELEMENT_PER_VERTEX_DATA ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE; - ASSERT(InstanceDataStepRate == 0 || InstanceDataStepRate == 1); + vertexBindingDescription.inputRate = inputElement.InputSlotClass == INPUT_LAYOUT_ELEMENT_PER_VERTEX_DATA ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE; + ASSERT(inputElement.InstanceDataStepRate == 0 || inputElement.InstanceDataStepRate == 1); auto& vertexAttributeDescription = vertexAttributeDescriptions[a]; vertexAttributeDescription.location = a; - vertexAttributeDescription.binding = InputSlot; - vertexAttributeDescription.format = RenderToolsVulkan::ToVulkanFormat((PixelFormat)Format); + vertexAttributeDescription.binding = inputElement.InputSlot; + vertexAttributeDescription.format = RenderToolsVulkan::ToVulkanFormat((PixelFormat)inputElement.Format); vertexAttributeDescription.offset = offset; - bindingsCount = Math::Max(bindingsCount, (uint32)InputSlot + 1); + bindingsCount = Math::Max(bindingsCount, (uint32)inputElement.InputSlot + 1); offset += size; } diff --git a/Source/Engine/ShadersCompilation/ShaderCompiler.cpp b/Source/Engine/ShadersCompilation/ShaderCompiler.cpp index 291910b11..c0fda4d6e 100644 --- a/Source/Engine/ShadersCompilation/ShaderCompiler.cpp +++ b/Source/Engine/ShadersCompilation/ShaderCompiler.cpp @@ -460,16 +460,15 @@ bool ShaderCompiler::WriteCustomDataVS(ShaderCompilationContext* context, Shader auto& element = layout[a]; if (!layoutVisible[a]) continue; - - // TODO: serialize whole struct? - - output->WriteByte(static_cast(element.Type)); - output->WriteByte(element.Index); - output->WriteByte(static_cast(element.Format)); - output->WriteByte(element.InputSlot); - output->WriteUint32(element.AlignedByteOffset); - output->WriteByte(element.InputSlotClass); - output->WriteUint32(element.InstanceDataStepRate); + GPUShaderProgramVS::InputElement data; + data.Type = static_cast(element.Type); + data.Index = element.Index; + data.Format = static_cast(element.Format); + data.InputSlot = element.InputSlot; + data.AlignedByteOffset = element.AlignedByteOffset; + data.InputSlotClass = element.InputSlotClass; + data.InstanceDataStepRate = element.InstanceDataStepRate; + output->Write(data); } return false; From d9b0e99b9c46e5370f79ad810beb21b709a40815 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 26 Oct 2023 15:20:35 +0200 Subject: [PATCH 22/32] Add support for using `Revision` number in projects version --- Source/Editor/ProjectInfo.cpp | 3 +- Source/Editor/ProjectInfo.cs | 85 ++++++++--------- Source/Engine/Core/Types/Version.cpp | 6 +- .../Bindings/BindingsGenerator.Cpp.cs | 7 +- Source/Tools/Flax.Build/ProjectInfo.cs | 93 +++++++++---------- 5 files changed, 91 insertions(+), 103 deletions(-) diff --git a/Source/Editor/ProjectInfo.cpp b/Source/Editor/ProjectInfo.cpp index 4e7ee4483..30c558b5d 100644 --- a/Source/Editor/ProjectInfo.cpp +++ b/Source/Editor/ProjectInfo.cpp @@ -154,7 +154,8 @@ bool ProjectInfo::LoadProject(const String& projectPath) Version = ::Version( JsonTools::GetInt(version, "Major", 0), JsonTools::GetInt(version, "Minor", 0), - JsonTools::GetInt(version, "Build", 0)); + JsonTools::GetInt(version, "Build", -1), + JsonTools::GetInt(version, "Revision", -1)); } } if (Version.Revision() == 0) diff --git a/Source/Editor/ProjectInfo.cs b/Source/Editor/ProjectInfo.cs index b00c4e042..083665f0f 100644 --- a/Source/Editor/ProjectInfo.cs +++ b/Source/Editor/ProjectInfo.cs @@ -23,17 +23,11 @@ namespace FlaxEditor public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value == null) - { writer.WriteNull(); - } else if (value is Version) - { writer.WriteValue(value.ToString()); - } else - { throw new JsonSerializationException("Expected Version object value"); - } } /// @@ -47,65 +41,60 @@ namespace FlaxEditor public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) - { return null; - } - else + + if (reader.TokenType == JsonToken.StartObject) { - if (reader.TokenType == JsonToken.StartObject) + try { - try + reader.Read(); + var values = new Dictionary(); + while (reader.TokenType == JsonToken.PropertyName) { + var key = reader.Value as string; reader.Read(); - Dictionary values = new Dictionary(); - while (reader.TokenType == JsonToken.PropertyName) - { - var key = reader.Value as string; - reader.Read(); - var val = (long)reader.Value; - reader.Read(); - values.Add(key, (int)val); - } + var val = (long)reader.Value; + reader.Read(); + values.Add(key, (int)val); + } - int major = 0, minor = 0, build = 0; - values.TryGetValue("Major", out major); - values.TryGetValue("Minor", out minor); - values.TryGetValue("Build", out build); + values.TryGetValue("Major", out var major); + values.TryGetValue("Minor", out var minor); + if (!values.TryGetValue("Build", out var build)) + build = -1; + if (!values.TryGetValue("Revision", out var revision)) + revision = -1; - Version v = new Version(major, minor, build); - return v; - } - catch (Exception ex) - { - throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex); - } + if (build <= 0) + return new Version(major, minor); + if (revision <= 0) + return new Version(major, minor, build); + return new Version(major, minor, build, revision); } - else if (reader.TokenType == JsonToken.String) + catch (Exception ex) { - try - { - Version v = new Version((string)reader.Value!); - return v; - } - catch (Exception ex) - { - throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex); - } - } - else - { - throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.Value)); + throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex); } } + if (reader.TokenType == JsonToken.String) + { + try + { + return new Version((string)reader.Value!); + } + catch (Exception ex) + { + throw new Exception(String.Format("Error parsing version string: {0}", reader.Value), ex); + } + } + throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.Value)); } /// /// Determines whether this instance can convert the specified object type. /// /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// + /// true if this instance can convert the specified object type; otherwise, false. public override bool CanConvert(Type objectType) { return objectType == typeof(Version); diff --git a/Source/Engine/Core/Types/Version.cpp b/Source/Engine/Core/Types/Version.cpp index 4a11a0af6..c0410d1cb 100644 --- a/Source/Engine/Core/Types/Version.cpp +++ b/Source/Engine/Core/Types/Version.cpp @@ -7,15 +7,15 @@ Version::Version(int32 major, int32 minor, int32 build, int32 revision) { _major = Math::Max(major, 0); _minor = Math::Max(minor, 0); - _build = Math::Max(build, 0); - _revision = Math::Max(revision, 0); + _build = Math::Max(build, -1); + _revision = Math::Max(revision, -1); } Version::Version(int32 major, int32 minor, int32 build) { _major = Math::Max(major, 0); _minor = Math::Max(minor, 0); - _build = Math::Max(build, 0); + _build = Math::Max(build, -1); _revision = -1; } diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 90e96d075..10e4d5846 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -3135,14 +3135,17 @@ namespace Flax.Build.Bindings contents.AppendLine("#pragma once"); contents.AppendLine(); contents.AppendLine($"#define {binaryModuleNameUpper}_NAME \"{binaryModuleName}\""); - if (version.Build == -1) + if (version.Build <= 0) contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION Version({version.Major}, {version.Minor})"); - else + else if (version.Revision <= 0) contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION Version({version.Major}, {version.Minor}, {version.Build})"); + else + contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION Version({version.Major}, {version.Minor}, {version.Build}, {version.Revision})"); contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION_TEXT \"{version}\""); contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION_MAJOR {version.Major}"); contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION_MINOR {version.Minor}"); contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION_BUILD {version.Build}"); + contents.AppendLine($"#define {binaryModuleNameUpper}_VERSION_REVISION {version.Revision}"); contents.AppendLine($"#define {binaryModuleNameUpper}_COMPANY \"{project.Company}\""); contents.AppendLine($"#define {binaryModuleNameUpper}_COPYRIGHT \"{project.Copyright}\""); contents.AppendLine(); diff --git a/Source/Tools/Flax.Build/ProjectInfo.cs b/Source/Tools/Flax.Build/ProjectInfo.cs index 7830f59c1..ec615fc49 100644 --- a/Source/Tools/Flax.Build/ProjectInfo.cs +++ b/Source/Tools/Flax.Build/ProjectInfo.cs @@ -14,9 +14,9 @@ namespace Flax.Build /// /// Writes the JSON representation of the object. /// - /// The to write to. + /// The to write to. /// The value. - /// The calling serializer. + /// The calling serializer. public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString()); @@ -25,73 +25,68 @@ namespace Flax.Build /// /// Reads the JSON representation of the object. /// - /// The to read from. - /// Type of the object. - /// The existing property value of the JSON that is being converted. - /// The calling serializer. + /// The to read from. + /// Type of the object. + /// The serializer options. /// The object value. public override Version? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.Null) - { return null; - } - else + + if (reader.TokenType == JsonTokenType.StartObject) { - if (reader.TokenType == JsonTokenType.StartObject) + try { - try + reader.Read(); + var values = new Dictionary(); + while (reader.TokenType == JsonTokenType.PropertyName) { + var key = reader.GetString(); reader.Read(); - Dictionary values = new Dictionary(); - while (reader.TokenType == JsonTokenType.PropertyName) - { - var key = reader.GetString(); - reader.Read(); - var val = reader.GetInt32(); - reader.Read(); - values.Add(key, val); - } + var val = reader.GetInt32(); + reader.Read(); + values.Add(key, val); + } - int major = 0, minor = 0, build = 0; - values.TryGetValue("Major", out major); - values.TryGetValue("Minor", out minor); - values.TryGetValue("Build", out build); + values.TryGetValue("Major", out var major); + values.TryGetValue("Minor", out var minor); + if (!values.TryGetValue("Build", out var build)) + build = -1; + if (!values.TryGetValue("Revision", out var revision)) + revision = -1; - Version v = new Version(major, minor, build); - return v; - } - catch (Exception ex) - { - throw new Exception(String.Format("Error parsing version string: {0}", reader.GetString()), ex); - } + if (build <= 0) + return new Version(major, minor); + if (revision <= 0) + return new Version(major, minor, build); + return new Version(major, minor, build, revision); } - else if (reader.TokenType == JsonTokenType.String) + catch (Exception ex) { - try - { - Version v = new Version((string)reader.GetString()!); - return v; - } - catch (Exception ex) - { - throw new Exception(String.Format("Error parsing version string: {0}", reader.GetString()), ex); - } - } - else - { - throw new Exception(String.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.GetString())); + throw new Exception(string.Format("Error parsing version string: {0}", reader.GetString()), ex); } } + + if (reader.TokenType == JsonTokenType.String) + { + try + { + return new Version((string)reader.GetString()!); + } + catch (Exception ex) + { + throw new Exception(string.Format("Error parsing version string: {0}", reader.GetString()), ex); + } + } + throw new Exception(string.Format("Unexpected token or value when parsing version. Token: {0}, Value: {1}", reader.TokenType, reader.GetString())); } /// /// Determines whether this instance can convert the specified object type. /// /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// + /// true if this instance can convert the specified object type; otherwise, false. public override bool CanConvert(Type objectType) { return objectType == typeof(Version); @@ -318,7 +313,7 @@ namespace Flax.Build Log.Verbose("Loading project file from \"" + path + "\"..."); var contents = File.ReadAllText(path); var project = JsonSerializer.Deserialize(contents.AsSpan(), - new JsonSerializerOptions() { Converters = { new FlaxVersionConverter() }, IncludeFields = true, TypeInfoResolver = ProjectInfoSourceGenerationContext.Default }); + new JsonSerializerOptions() { Converters = { new FlaxVersionConverter() }, IncludeFields = true, TypeInfoResolver = ProjectInfoSourceGenerationContext.Default }); project.ProjectPath = path; project.ProjectFolderPath = Path.GetDirectoryName(path); From 70a06c5db362624f51358d6e0afc8f76b0197ba5 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 26 Oct 2023 15:21:01 +0200 Subject: [PATCH 23/32] Update build number and add revision field for future patches --- Flax.flaxproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Flax.flaxproj b/Flax.flaxproj index 6b3014e94..78d9714f5 100644 --- a/Flax.flaxproj +++ b/Flax.flaxproj @@ -3,7 +3,8 @@ "Version": { "Major": 1, "Minor": 7, - "Build": 6402 + "Revision": 0, + "Build": 6403 }, "Company": "Flax", "Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.", From 615b6470e53a4643230fd51aee70454958544706 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 28 Oct 2023 11:44:11 +0200 Subject: [PATCH 24/32] Fix iOS project path if it contains whitespace chars --- .../iOS/Binaries/Project/FlaxGame.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Platforms/iOS/Binaries/Project/FlaxGame.xcodeproj/project.pbxproj b/Source/Platforms/iOS/Binaries/Project/FlaxGame.xcodeproj/project.pbxproj index 1dd5d4e01..3b8889487 100644 --- a/Source/Platforms/iOS/Binaries/Project/FlaxGame.xcodeproj/project.pbxproj +++ b/Source/Platforms/iOS/Binaries/Project/FlaxGame.xcodeproj/project.pbxproj @@ -222,7 +222,7 @@ ${PBXResourcesGroup} GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ${HeaderSearchPaths}; + HEADER_SEARCH_PATHS = "${HeaderSearchPaths}"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -275,7 +275,7 @@ ${PBXResourcesGroup} GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ${HeaderSearchPaths}; + HEADER_SEARCH_PATHS = "${HeaderSearchPaths}"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; From a95c9059aa09501503ea7e6f32b8b94bbf2663d9 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 27 Oct 2023 10:08:04 +0200 Subject: [PATCH 25/32] Update build number --- Flax.flaxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flax.flaxproj b/Flax.flaxproj index 78d9714f5..a3157a032 100644 --- a/Flax.flaxproj +++ b/Flax.flaxproj @@ -4,7 +4,7 @@ "Major": 1, "Minor": 7, "Revision": 0, - "Build": 6403 + "Build": 6404 }, "Company": "Flax", "Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.", From b028faf0ccdc35df62ce9d9f98e388eec9cf71b7 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 28 Oct 2023 13:52:23 +0200 Subject: [PATCH 26/32] Update assets --- Content/Editor/Particles/Smoke.flax | 4 ++-- Content/Editor/Particles/Sparks.flax | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Content/Editor/Particles/Smoke.flax b/Content/Editor/Particles/Smoke.flax index 1335a84f4..b42c2f325 100644 --- a/Content/Editor/Particles/Smoke.flax +++ b/Content/Editor/Particles/Smoke.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c3dc51e7805056006ca6cbb481ba202583a9b2287c152fc04e28e1d07747d6ce -size 14706 +oid sha256:334ac0d00495fc88b10839061ff0c3f45323d4f75ab6176b19005199a7324a19 +size 14569 diff --git a/Content/Editor/Particles/Sparks.flax b/Content/Editor/Particles/Sparks.flax index 7977e231b..7ee0ed6e9 100644 --- a/Content/Editor/Particles/Sparks.flax +++ b/Content/Editor/Particles/Sparks.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77d902ab5f79426cc66dc5f19a3b8280136a58aa3c6fd317554d1a032357c65a -size 15275 +oid sha256:87046a9bfe275cac290b4764de8a512c222ccc386d01af9026d57c3e4b7773b6 +size 13625 From 468c93949ece14505fcd643350112290198da936 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 28 Oct 2023 14:01:44 +0200 Subject: [PATCH 27/32] Fix crash when creating empty particle emitter --- Source/Engine/Particles/Particles.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Particles/Particles.cpp b/Source/Engine/Particles/Particles.cpp index 52845a0f8..784f28c98 100644 --- a/Source/Engine/Particles/Particles.cpp +++ b/Source/Engine/Particles/Particles.cpp @@ -1334,7 +1334,8 @@ void ParticlesSystem::Job(int32 index) auto emitter = particleSystem->Emitters[track.AsEmitter.Index].Get(); auto& data = instance.Emitters[track.AsEmitter.Index]; ASSERT(emitter && emitter->IsLoaded()); - ASSERT(emitter->Capacity != 0 && emitter->Graph.Layout.Size != 0); + if (emitter->Capacity == 0 || emitter->Graph.Layout.Size == 0) + continue; PROFILE_CPU_ASSET(emitter); // Calculate new time position From 9f3221c533cd75716b2fbe4b0ce9ab20f6f1e959 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 28 Oct 2023 14:02:25 +0200 Subject: [PATCH 28/32] Remove unused include --- Source/Engine/Physics/Actors/PhysicsColliderActor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Engine/Physics/Actors/PhysicsColliderActor.cpp b/Source/Engine/Physics/Actors/PhysicsColliderActor.cpp index 02645943c..f2ab5d8a2 100644 --- a/Source/Engine/Physics/Actors/PhysicsColliderActor.cpp +++ b/Source/Engine/Physics/Actors/PhysicsColliderActor.cpp @@ -1,7 +1,6 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "PhysicsColliderActor.h" -#include "Engine/Scripting/Script.h" #include "RigidBody.h" PhysicsColliderActor::PhysicsColliderActor(const SpawnParams& params) From d9c2decff50f8c5e2658a151624160505cb43d2c Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 28 Oct 2023 20:09:27 +0200 Subject: [PATCH 29/32] Fix crash when contact was not read properly --- Source/Engine/Physics/PhysX/SimulationEventCallbackPhysX.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Source/Engine/Physics/PhysX/SimulationEventCallbackPhysX.cpp b/Source/Engine/Physics/PhysX/SimulationEventCallbackPhysX.cpp index 684aeca19..5968bdd78 100644 --- a/Source/Engine/Physics/PhysX/SimulationEventCallbackPhysX.cpp +++ b/Source/Engine/Physics/PhysX/SimulationEventCallbackPhysX.cpp @@ -117,9 +117,7 @@ void SimulationEventCallback::onContact(const PxContactPairHeader& pairHeader, c { // Skip sending events to removed actors if (pairHeader.flags & (PxContactPairHeaderFlag::eREMOVED_ACTOR_0 | PxContactPairHeaderFlag::eREMOVED_ACTOR_1)) - { return; - } Collision c; PxContactPairExtraDataIterator j(pairHeader.extraDataStream, pairHeader.extraDataStreamSize); @@ -193,7 +191,7 @@ void SimulationEventCallback::onContact(const PxContactPairHeader& pairHeader, c RemovedCollisions.Add(c); } } - ASSERT(!j.nextItemSet()); + //ASSERT(!j.nextItemSet()); } void SimulationEventCallback::onTrigger(PxTriggerPair* pairs, PxU32 count) From 9c1a7a20d490ee3cf561dd4f9b6dab919595e045 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 28 Oct 2023 22:10:41 +0200 Subject: [PATCH 30/32] Add `volk.h` header to distributed build files --- Source/ThirdParty/volk/volk.Build.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Source/ThirdParty/volk/volk.Build.cs b/Source/ThirdParty/volk/volk.Build.cs index 2f4cfa0d6..67f7593d9 100644 --- a/Source/ThirdParty/volk/volk.Build.cs +++ b/Source/ThirdParty/volk/volk.Build.cs @@ -1,5 +1,6 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. +using System.Collections.Generic; using System.IO; using Flax.Build; using Flax.Build.NativeCpp; @@ -62,4 +63,12 @@ public class volk : ThirdPartyModule Log.ErrorOnce("Missing VulkanSDK.", ref _missingSDKError); } } + + /// + public override void GetFilesToDeploy(List files) + { + base.GetFilesToDeploy(files); + + files.Add(Path.Combine(FolderPath, "volk.h")); + } } From 83a931de7e21f1dfdc79461f3fc5214b225019da Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 29 Oct 2023 01:57:48 +0200 Subject: [PATCH 31/32] Fix typo bug in DOF --- Source/Engine/Renderer/DepthOfFieldPass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Renderer/DepthOfFieldPass.cpp b/Source/Engine/Renderer/DepthOfFieldPass.cpp index cd7930f5c..707a441e6 100644 --- a/Source/Engine/Renderer/DepthOfFieldPass.cpp +++ b/Source/Engine/Renderer/DepthOfFieldPass.cpp @@ -204,7 +204,7 @@ void DepthOfFieldPass::Render(RenderContext& renderContext, GPUTexture*& frame, { DepthOfFieldSettings& dofSettings = renderContext.List->Settings.DepthOfField; const bool useDoF = EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::DepthOfField) && dofSettings.Enabled; - if (!useDoF || _platformSupportsDoF || checkIfSkipPass()) + if (!useDoF || !_platformSupportsDoF || checkIfSkipPass()) return; auto device = GPUDevice::Instance; auto context = device->GetMainContext(); From 56c9429e253960e2dbb16b80462877d812dc1662 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 29 Oct 2023 02:57:59 +0200 Subject: [PATCH 32/32] Fix spawning prefab without transform provided #1831 --- Source/Engine/Level/Prefabs/PrefabManager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Level/Prefabs/PrefabManager.cpp b/Source/Engine/Level/Prefabs/PrefabManager.cpp index cd9d893ec..de164343b 100644 --- a/Source/Engine/Level/Prefabs/PrefabManager.cpp +++ b/Source/Engine/Level/Prefabs/PrefabManager.cpp @@ -39,7 +39,7 @@ PrefabManagerService PrefabManagerServiceInstance; Actor* PrefabManager::SpawnPrefab(Prefab* prefab) { Actor* parent = Level::Scenes.Count() != 0 ? Level::Scenes.Get()[0] : nullptr; - return SpawnPrefab(prefab, Transform::Identity, parent, nullptr); + return SpawnPrefab(prefab, Transform(Vector3::Minimum), parent, nullptr); } Actor* PrefabManager::SpawnPrefab(Prefab* prefab, const Vector3& position) @@ -73,12 +73,12 @@ Actor* PrefabManager::SpawnPrefab(Prefab* prefab, Actor* parent, const Transform Actor* PrefabManager::SpawnPrefab(Prefab* prefab, Actor* parent) { - return SpawnPrefab(prefab, Transform::Identity, parent, nullptr); + return SpawnPrefab(prefab, Transform(Vector3::Minimum), parent, nullptr); } Actor* PrefabManager::SpawnPrefab(Prefab* prefab, Actor* parent, Dictionary* objectsCache, bool withSynchronization) { - return SpawnPrefab(prefab, Transform::Identity, parent, objectsCache, withSynchronization); + return SpawnPrefab(prefab, Transform(Vector3::Minimum), parent, objectsCache, withSynchronization); } Actor* PrefabManager::SpawnPrefab(Prefab* prefab, const Transform& transform, Actor* parent, Dictionary* objectsCache, bool withSynchronization) @@ -191,7 +191,7 @@ Actor* PrefabManager::SpawnPrefab(Prefab* prefab, const Transform& transform, Ac parent->Children.Add(root); // Move root to the right location - if (transform != Transform::Identity) + if (transform.Translation != Vector3::Minimum) root->SetTransform(transform); // Link actors hierarchy