From 564c9ff0ca331f80bbe132ba02d3e08215961dc5 Mon Sep 17 00:00:00 2001 From: Saas Date: Fri, 19 Dec 2025 19:00:55 +0100 Subject: [PATCH 1/2] improve orthographic/ perspective viewport cam toggle --- Source/Editor/Viewport/EditorViewport.cs | 8 +- .../Viewport/Widgets/ViewportWidgetButton.cs | 91 +++++++++++++++++++ 2 files changed, 95 insertions(+), 4 deletions(-) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index c16d3d9f5..08e65f9d0 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -247,8 +247,8 @@ namespace FlaxEditor.Viewport { _movementSpeed = value; - if (_cameraButton != null) - _cameraButton.Text = string.Format(MovementSpeedTextFormat, _movementSpeed); + if (_orthographicModeButton != null) + _orthographicModeButton.Text = string.Format(MovementSpeedTextFormat, _movementSpeed); } } @@ -581,7 +581,7 @@ namespace FlaxEditor.Viewport // Camera Settings Menu var cameraCM = new ContextMenu(); - _cameraButton = new ViewportWidgetButton(string.Format(MovementSpeedTextFormat, _movementSpeed), _editor.Icons.Camera64, cameraCM, false, cameraSpeedTextWidth) + _cameraButton = new ViewportWidgetButton("", _editor.Icons.Camera64, cameraCM) { Tag = this, TooltipText = "Camera Settings", @@ -590,7 +590,7 @@ namespace FlaxEditor.Viewport _cameraWidget.Parent = this; // Orthographic/Perspective Mode Widget - _orthographicModeButton = new ViewportWidgetButton(string.Empty, _editor.Icons.CamSpeed32, null, true) + _orthographicModeButton = new OrthoCamToggleViewportWidgetButton(cameraSpeedTextWidth) { Checked = !_isOrtho, TooltipText = "Toggle Orthographic/Perspective Mode", diff --git a/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs b/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs index 55c3e9c71..545d71d9b 100644 --- a/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs +++ b/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs @@ -7,6 +7,97 @@ using FlaxEngine.GUI; namespace FlaxEditor.Viewport.Widgets { + /// + /// Otrhographic view toggle viewport Widget Button class. + /// Will draw a custom camera frustum to represent an orthographic or perspective camera. + /// + /// + [HideInEditor] + public class OrthoCamToggleViewportWidgetButton : ViewportWidgetButton + { + private const int iconPointCount = 4; + private const float iconRenderScale = 4.0f; + + private readonly Float2 iconDrawOffset = new Float2(3.0f, 3.0f); + + private readonly Float2[] iconPointsPerspective = new[] + { + new Float2(0.0f, 1.0f), // Top left + new Float2(4.0f, 0.0f), // Top right + new Float2(4.0f, 3.0f), // Bottom right + new Float2(0.0f, 2.0f), // Bottom left + }; + + private readonly Float2[] iconPointsOrtho = new[] + { + new Float2(0.0f, 0.0f), // Top left + new Float2(4.0f, 0.0f), // Top right + new Float2(4.0f, 3.0f), // Bottom right + new Float2(0.0f, 3.0f), // Bottom left + }; + + private bool wasChecked; + private float lerpWeight; + + /// + /// Initializes a new instance of the class. + /// + public OrthoCamToggleViewportWidgetButton(float speedTextWidth) + : base("00.0", SpriteHandle.Invalid, null, true, 20.0f + speedTextWidth) + { + wasChecked = Checked; + } + + /// + public override void Update(float deltaTime) + { + if (wasChecked != Checked) + { + lerpWeight = 0.0f; + wasChecked = Checked; + } + + if (lerpWeight <= 1.0f) + lerpWeight += deltaTime * 4.2f; + + base.Update(deltaTime); + } + + /// + public override void Draw() + { + // Cache data + var style = Style.Current; + var textRect = new Rectangle(0.0f, 0.0f, Width - 2.0f, Height); + var backgroundRect = textRect with { Width = Width - 1.0f }; + + // Check if is checked or mouse is over + if (Checked) + Render2D.FillRectangle(backgroundRect, style.BackgroundSelected * (IsMouseOver ? 0.9f : 0.6f)); + else if (IsMouseOver) + Render2D.FillRectangle(backgroundRect, style.BackgroundHighlighted); + + // Draw text + Render2D.DrawText(style.FontMedium, Text, textRect, style.ForegroundViewport * (IsMouseOver ? 1.0f : 0.9f), TextAlignment.Far, TextAlignment.Center); + + // Draw camera frustum icon + Float2[] currentStart = Checked ? iconPointsOrtho : iconPointsPerspective; + Float2[] currentTarget = Checked ? iconPointsPerspective : iconPointsOrtho; + + for (int i = 1; i < iconPointCount + 1; i++) + { + int endPointIndex = Mathf.Wrap(i, 0, iconPointCount - 1); + Float2 lineStart = Float2.Lerp(currentStart[i - 1], currentTarget[i - 1], lerpWeight); + Float2 lineEnd = Float2.Lerp(currentStart[endPointIndex], currentTarget[endPointIndex], lerpWeight); + + lineStart = lineStart * iconRenderScale + iconDrawOffset; + lineEnd = lineEnd * iconRenderScale + iconDrawOffset; + + Render2D.DrawLine(lineStart, lineEnd, Color.White); + } + } + } + /// /// Viewport Widget Button class. /// From 2a2f046f30a967049db2c2b1b279dd143de35f18 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 10 Mar 2026 21:13:36 +0100 Subject: [PATCH 2/2] Don't snap vertices in camera projection icon for better quality #3875 --- Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs b/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs index 545d71d9b..dd09dc24c 100644 --- a/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs +++ b/Source/Editor/Viewport/Widgets/ViewportWidgetButton.cs @@ -84,6 +84,8 @@ namespace FlaxEditor.Viewport.Widgets Float2[] currentStart = Checked ? iconPointsOrtho : iconPointsPerspective; Float2[] currentTarget = Checked ? iconPointsPerspective : iconPointsOrtho; + var features = Render2D.Features; + Render2D.Features = features & ~Render2D.RenderingFeatures.VertexSnapping; for (int i = 1; i < iconPointCount + 1; i++) { int endPointIndex = Mathf.Wrap(i, 0, iconPointCount - 1); @@ -95,6 +97,7 @@ namespace FlaxEditor.Viewport.Widgets Render2D.DrawLine(lineStart, lineEnd, Color.White); } + Render2D.Features = features; } }