Merge branch 'master' into 1.5
# Conflicts: # Source/Engine/Renderer/AmbientOcclusionPass.cpp
This commit is contained in:
@@ -101,18 +101,6 @@ namespace FlaxEditor.GUI
|
||||
_timeRemaining = Mathf.CeilToInt(time);
|
||||
if (_timeLabel != null)
|
||||
_timeLabel.Text = "Auto Save in: " + _timeRemaining;
|
||||
|
||||
// Move on text update if the progress bar is visible - removes this call from update
|
||||
if (Editor.Instance.UI.ProgressVisible && !_isMoved)
|
||||
{
|
||||
_isMoved = true;
|
||||
LocalX -= 250;
|
||||
}
|
||||
else if (!Editor.Instance.UI.ProgressVisible && _isMoved)
|
||||
{
|
||||
LocalX += 250;
|
||||
_isMoved = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -123,6 +111,18 @@ namespace FlaxEditor.GUI
|
||||
_saveNowButton.TextColor = _saveNowButton.IsMouseOver ? Style.Current.BackgroundHighlighted : _defaultTextColor;
|
||||
_cancelSaveButton.TextColor = _cancelSaveButton.IsMouseOver ? Style.Current.BackgroundHighlighted : _defaultTextColor;
|
||||
}
|
||||
|
||||
// Move if the progress bar is visible
|
||||
if (Editor.Instance.UI.ProgressVisible && !_isMoved)
|
||||
{
|
||||
_isMoved = true;
|
||||
LocalX -= 280;
|
||||
}
|
||||
else if (!Editor.Instance.UI.ProgressVisible && _isMoved)
|
||||
{
|
||||
LocalX += 280;
|
||||
_isMoved = false;
|
||||
}
|
||||
base.Update(deltaTime);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,11 @@ namespace FlaxEditor.GUI
|
||||
/// </summary>
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the status text color
|
||||
/// </summary>
|
||||
public Color TextColor { get; set; } = Style.Current.Foreground;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StatusBar"/> class.
|
||||
/// </summary>
|
||||
@@ -51,7 +56,7 @@ namespace FlaxEditor.GUI
|
||||
Render2D.DrawSprite(style.StatusBarSizeGrip, new Rectangle(Width - 12, 10, 12, 12), style.Foreground);
|
||||
|
||||
// Draw status text
|
||||
Render2D.DrawText(style.FontSmall, Text, new Rectangle(4, 0, Width - 20, Height), style.Foreground, TextAlignment.Near, TextAlignment.Center);
|
||||
Render2D.DrawText(style.FontSmall, Text, new Rectangle(4, 0, Width - 20, Height), TextColor, TextAlignment.Near, TextAlignment.Center);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ namespace FlaxEditor.Modules
|
||||
handler.ProgressStart += HandlerOnProgressStart;
|
||||
handler.ProgressChanged += HandlerOnProgressChanged;
|
||||
handler.ProgressEnd += HandlerOnProgressEnd;
|
||||
handler.ProgressFailed += HandlerOnProgressFail;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -113,6 +114,7 @@ namespace FlaxEditor.Modules
|
||||
handler.ProgressStart -= HandlerOnProgressStart;
|
||||
handler.ProgressChanged -= HandlerOnProgressChanged;
|
||||
handler.ProgressEnd -= HandlerOnProgressEnd;
|
||||
handler.ProgressFailed -= HandlerOnProgressFail;
|
||||
}
|
||||
|
||||
private void UpdateProgress()
|
||||
@@ -150,5 +152,11 @@ namespace FlaxEditor.Modules
|
||||
Editor.Windows.FlashMainWindow();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandlerOnProgressFail(ProgressHandler handler, string message)
|
||||
{
|
||||
UpdateProgress();
|
||||
Editor.UI.ProgressFailed(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,10 @@ namespace FlaxEditor.Modules
|
||||
{
|
||||
private Label _progressLabel;
|
||||
private ProgressBar _progressBar;
|
||||
private Button _outputLogButton;
|
||||
private List<KeyValuePair<string, DateTime>> _statusMessages;
|
||||
private ContentStats _contentStats;
|
||||
private bool _progressFailed;
|
||||
|
||||
private ContextMenuButton _menuFileSaveScenes;
|
||||
private ContextMenuButton _menuFileCloseScenes;
|
||||
@@ -252,6 +254,12 @@ namespace FlaxEditor.Modules
|
||||
{
|
||||
if (StatusBar == null)
|
||||
return;
|
||||
|
||||
if (ScriptsBuilder.LastCompilationFailed)
|
||||
{
|
||||
ProgressFailed("Scripts Compilation Failed");
|
||||
return;
|
||||
}
|
||||
var contentStats = FlaxEngine.Content.Stats;
|
||||
|
||||
Color color;
|
||||
@@ -303,7 +311,28 @@ namespace FlaxEditor.Modules
|
||||
if (_progressLabel != null)
|
||||
_progressLabel.Text = text;
|
||||
if (_progressBar != null)
|
||||
{
|
||||
if (_progressFailed)
|
||||
{
|
||||
ResetProgressFailure();
|
||||
}
|
||||
_progressBar.Value = progress * 100.0f;
|
||||
}
|
||||
}
|
||||
|
||||
internal void ProgressFailed(string message)
|
||||
{
|
||||
_progressFailed = true;
|
||||
StatusBar.StatusColor = Color.Red;
|
||||
StatusBar.Text = message;
|
||||
_outputLogButton.Visible = true;
|
||||
}
|
||||
|
||||
internal void ResetProgressFailure()
|
||||
{
|
||||
_outputLogButton.Visible = false;
|
||||
_progressFailed = false;
|
||||
UpdateStatusBar();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -584,6 +613,30 @@ namespace FlaxEditor.Modules
|
||||
Parent = mainWindow,
|
||||
Offsets = new Margin(0, 0, -StatusBar.DefaultHeight, StatusBar.DefaultHeight),
|
||||
};
|
||||
// Output log button
|
||||
_outputLogButton = new Button()
|
||||
{
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
Parent = StatusBar,
|
||||
Visible = false,
|
||||
Text = "",
|
||||
Width = 200,
|
||||
TooltipText = "Opens or shows the output log window.",
|
||||
BackgroundColor = Color.Transparent,
|
||||
BorderColor = Color.Transparent,
|
||||
BackgroundColorHighlighted = Color.Transparent,
|
||||
BackgroundColorSelected = Color.Transparent,
|
||||
BorderColorHighlighted = Color.Transparent,
|
||||
BorderColorSelected = Color.Transparent,
|
||||
};
|
||||
_outputLogButton.LocalY -= 2;
|
||||
var defaultTextColor = StatusBar.TextColor;
|
||||
_outputLogButton.HoverBegin += () => StatusBar.TextColor = Style.Current.BackgroundSelected;
|
||||
_outputLogButton.HoverEnd += () => StatusBar.TextColor = defaultTextColor;
|
||||
_outputLogButton.Clicked += () =>
|
||||
{
|
||||
Editor.Windows.OutputLogWin.FocusOrShow();
|
||||
};
|
||||
|
||||
// Progress bar with label
|
||||
const float progressBarWidth = 120.0f;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using FlaxEngine;
|
||||
using FlaxEditor.Utilities;
|
||||
|
||||
namespace FlaxEditor.Progress.Handlers
|
||||
@@ -21,7 +20,7 @@ namespace FlaxEditor.Progress.Handlers
|
||||
// Link for events
|
||||
ScriptsBuilder.CompilationBegin += OnStart;
|
||||
ScriptsBuilder.CompilationSuccess += OnEnd;
|
||||
ScriptsBuilder.CompilationFailed += OnEnd;
|
||||
ScriptsBuilder.CompilationFailed += OnCompilationFailed;
|
||||
ScriptsBuilder.CompilationStarted += () => OnUpdate(0.2f, "Compiling scripts...");
|
||||
ScriptsBuilder.ScriptsReloadCalled += () => OnUpdate(0.8f, "Reloading scripts...");
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
@@ -45,6 +44,11 @@ namespace FlaxEditor.Progress.Handlers
|
||||
Newtonsoft.Json.JsonSerializer.ClearCache();
|
||||
}
|
||||
|
||||
private void OnCompilationFailed()
|
||||
{
|
||||
OnFail("Scripts compilation failed");
|
||||
}
|
||||
|
||||
private void OnScriptsReloadEnd()
|
||||
{
|
||||
_selectionCache.Restore();
|
||||
|
||||
@@ -16,6 +16,11 @@ namespace FlaxEditor.Progress
|
||||
/// </summary>
|
||||
/// <param name="handler">The calling handler.</param>
|
||||
public delegate void ProgressDelegate(ProgressHandler handler);
|
||||
|
||||
/// <summary>
|
||||
/// Progress failed handler event delegate
|
||||
/// </summary>
|
||||
public delegate void ProgressFailedDelegate(ProgressHandler handler, string message);
|
||||
|
||||
private float _progress;
|
||||
private bool _isActive;
|
||||
@@ -51,6 +56,11 @@ namespace FlaxEditor.Progress
|
||||
/// </summary>
|
||||
public event ProgressDelegate ProgressEnd;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the progress fails
|
||||
/// </summary>
|
||||
public event ProgressFailedDelegate ProgressFailed;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this handler action can be cancelled.
|
||||
/// </summary>
|
||||
@@ -109,5 +119,19 @@ namespace FlaxEditor.Progress
|
||||
ProgressChanged?.Invoke(this);
|
||||
ProgressEnd?.Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when progress action fails
|
||||
/// </summary>
|
||||
protected virtual void OnFail(string message)
|
||||
{
|
||||
if (!_isActive)
|
||||
throw new InvalidOperationException("Already ended.");
|
||||
|
||||
_isActive = false;
|
||||
_progress = 0;
|
||||
_infoText = string.Empty;
|
||||
ProgressFailed?.Invoke(this, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using FlaxEditor.GUI.Input;
|
||||
using FlaxEditor.Options;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Json;
|
||||
|
||||
namespace FlaxEditor.Windows
|
||||
{
|
||||
@@ -28,6 +29,14 @@ namespace FlaxEditor.Windows
|
||||
private GUI.Docking.DockPanel _maximizeRestoreDockTo;
|
||||
private CursorLockMode _cursorLockMode = CursorLockMode.None;
|
||||
|
||||
// Viewport scaling variables
|
||||
private List<ViewportScaleOptions> _defaultViewportScaling = new List<ViewportScaleOptions>();
|
||||
private List<ViewportScaleOptions> _customViewportScaling = new List<ViewportScaleOptions>();
|
||||
private float _viewportAspectRatio = 1;
|
||||
private float _windowAspectRatio = 1;
|
||||
private bool _useAspect = false;
|
||||
private bool _freeAspect = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the viewport.
|
||||
/// </summary>
|
||||
@@ -106,6 +115,35 @@ namespace FlaxEditor.Windows
|
||||
/// </summary>
|
||||
public bool FocusOnPlay { get; set; }
|
||||
|
||||
private enum ViewportScaleType
|
||||
{
|
||||
Resolution = 0,
|
||||
Aspect = 1,
|
||||
}
|
||||
|
||||
private class ViewportScaleOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// The name.
|
||||
/// </summary>
|
||||
public string Label;
|
||||
|
||||
/// <summary>
|
||||
/// The Type of scaling to do.
|
||||
/// </summary>
|
||||
public ViewportScaleType ScaleType;
|
||||
|
||||
/// <summary>
|
||||
/// The width and height to scale by.
|
||||
/// </summary>
|
||||
public Int2 Size;
|
||||
|
||||
/// <summary>
|
||||
/// If the scaling is active.
|
||||
/// </summary>
|
||||
public bool Active;
|
||||
}
|
||||
|
||||
private class GameRoot : ContainerControl
|
||||
{
|
||||
public bool EnableEvents => !Time.GamePaused;
|
||||
@@ -255,6 +293,9 @@ namespace FlaxEditor.Windows
|
||||
Parent = _viewport
|
||||
};
|
||||
RootControl.GameRoot = _guiRoot;
|
||||
|
||||
SizeChanged += control => { ResizeViewport(); };
|
||||
|
||||
Editor.StateMachine.PlayingState.SceneDuplicating += PlayingStateOnSceneDuplicating;
|
||||
Editor.StateMachine.PlayingState.SceneRestored += PlayingStateOnSceneRestored;
|
||||
|
||||
@@ -267,6 +308,85 @@ namespace FlaxEditor.Windows
|
||||
InputActions.Add(options => options.StepFrame, Editor.Simulation.RequestPlayOneFrame);
|
||||
}
|
||||
|
||||
private void ChangeViewportRatio(ViewportScaleOptions v)
|
||||
{
|
||||
if (v == null)
|
||||
return;
|
||||
|
||||
if (v.Size.Y <= 0 || v.Size.X <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.Equals(v.Label, "Free Aspect") && v.Size == new Int2(1, 1))
|
||||
{
|
||||
_freeAspect = true;
|
||||
_useAspect = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (v.ScaleType)
|
||||
{
|
||||
case ViewportScaleType.Aspect:
|
||||
_useAspect = true;
|
||||
_freeAspect = false;
|
||||
break;
|
||||
case ViewportScaleType.Resolution:
|
||||
_useAspect = false;
|
||||
_freeAspect = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_viewportAspectRatio = (float)v.Size.X / v.Size.Y;
|
||||
|
||||
if (!_freeAspect)
|
||||
{
|
||||
if (!_useAspect)
|
||||
{
|
||||
_viewport.KeepAspectRatio = true;
|
||||
_viewport.CustomResolution = new Int2(v.Size.X, v.Size.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
_viewport.CustomResolution = new Int2?();
|
||||
_viewport.KeepAspectRatio = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_viewport.CustomResolution = new Int2?();
|
||||
_viewport.KeepAspectRatio = false;
|
||||
}
|
||||
|
||||
ResizeViewport();
|
||||
}
|
||||
|
||||
private void ResizeViewport()
|
||||
{
|
||||
if (!_freeAspect)
|
||||
{
|
||||
_windowAspectRatio = Width / Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
_windowAspectRatio = 1;
|
||||
}
|
||||
|
||||
var scaleWidth = _viewportAspectRatio / _windowAspectRatio;
|
||||
var scaleHeight = _windowAspectRatio / _viewportAspectRatio;
|
||||
|
||||
if (scaleHeight < 1)
|
||||
{
|
||||
_viewport.Bounds = new Rectangle(0, Height * (1 - scaleHeight) / 2, Width, Height * scaleHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
_viewport.Bounds = new Rectangle(Width * (1 - scaleWidth) / 2, 0, Width * scaleWidth, Height);
|
||||
}
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
private void OnPostRender(GPUContext context, ref RenderContext renderContext)
|
||||
{
|
||||
// Debug Draw shapes
|
||||
@@ -372,6 +492,53 @@ namespace FlaxEditor.Windows
|
||||
resolutionValue.ValueChanged += () => _viewport.ResolutionScale = resolutionValue.Value;
|
||||
}
|
||||
|
||||
// Viewport aspect ratio
|
||||
{
|
||||
// Create default scaling options if they dont exist from deserialization.
|
||||
if (_defaultViewportScaling.Count == 0)
|
||||
{
|
||||
_defaultViewportScaling.Add(new ViewportScaleOptions
|
||||
{
|
||||
Label = "Free Aspect",
|
||||
ScaleType = ViewportScaleType.Aspect,
|
||||
Size = new Int2(1, 1),
|
||||
Active = true,
|
||||
});
|
||||
_defaultViewportScaling.Add(new ViewportScaleOptions
|
||||
{
|
||||
Label = "16:9 Aspect",
|
||||
ScaleType = ViewportScaleType.Aspect,
|
||||
Size = new Int2(16, 9),
|
||||
Active = false,
|
||||
});
|
||||
_defaultViewportScaling.Add(new ViewportScaleOptions
|
||||
{
|
||||
Label = "16:10 Aspect",
|
||||
ScaleType = ViewportScaleType.Aspect,
|
||||
Size = new Int2(16, 10),
|
||||
Active = false,
|
||||
});
|
||||
_defaultViewportScaling.Add(new ViewportScaleOptions
|
||||
{
|
||||
Label = "1920x1080 Resolution",
|
||||
ScaleType = ViewportScaleType.Resolution,
|
||||
Size = new Int2(1920, 1080),
|
||||
Active = false,
|
||||
});
|
||||
_defaultViewportScaling.Add(new ViewportScaleOptions
|
||||
{
|
||||
Label = "2560x1440 Resolution",
|
||||
ScaleType = ViewportScaleType.Resolution,
|
||||
Size = new Int2(2560, 1440),
|
||||
Active = false,
|
||||
});
|
||||
}
|
||||
|
||||
var vsMenu = menu.AddChildMenu("Viewport Size").ContextMenu;
|
||||
|
||||
CreateViewportSizingContextMenu(vsMenu);
|
||||
}
|
||||
|
||||
// Take Screenshot
|
||||
{
|
||||
var takeScreenshot = menu.AddButton("Take Screenshot");
|
||||
@@ -400,6 +567,243 @@ namespace FlaxEditor.Windows
|
||||
menu.AddSeparator();
|
||||
}
|
||||
|
||||
private void CreateViewportSizingContextMenu(ContextMenu vsMenu)
|
||||
{
|
||||
// Add default viewport sizing options
|
||||
for (int i = 0; i < _defaultViewportScaling.Count; i++)
|
||||
{
|
||||
var viewportScale = _defaultViewportScaling[i];
|
||||
var button = vsMenu.AddButton(viewportScale.Label);
|
||||
button.CloseMenuOnClick = false;
|
||||
button.Icon = viewportScale.Active ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
|
||||
button.Tag = viewportScale;
|
||||
if (viewportScale.Active)
|
||||
ChangeViewportRatio(viewportScale);
|
||||
|
||||
button.Clicked += () =>
|
||||
{
|
||||
if (button.Tag == null)
|
||||
return;
|
||||
|
||||
// Reset selected icon on all buttons
|
||||
foreach (var child in vsMenu.Items)
|
||||
{
|
||||
if (child is ContextMenuButton cmb && cmb.Tag is ViewportScaleOptions v)
|
||||
{
|
||||
if (cmb == button)
|
||||
{
|
||||
v.Active = true;
|
||||
button.Icon = Style.Current.CheckBoxTick;
|
||||
ChangeViewportRatio(v);
|
||||
}
|
||||
else if (v.Active)
|
||||
{
|
||||
cmb.Icon = SpriteHandle.Invalid;
|
||||
v.Active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
if (_defaultViewportScaling.Count != 0)
|
||||
vsMenu.AddSeparator();
|
||||
|
||||
// Add custom viewport options
|
||||
for (int i = 0; i < _customViewportScaling.Count; i++)
|
||||
{
|
||||
var viewportScale = _customViewportScaling[i];
|
||||
var childCM = vsMenu.AddChildMenu(viewportScale.Label);
|
||||
childCM.CloseMenuOnClick = false;
|
||||
childCM.Icon = viewportScale.Active ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
|
||||
childCM.Tag = viewportScale;
|
||||
if (viewportScale.Active)
|
||||
ChangeViewportRatio(viewportScale);
|
||||
|
||||
var applyButton = childCM.ContextMenu.AddButton("Apply");
|
||||
applyButton.Tag = childCM.Tag = viewportScale;
|
||||
applyButton.CloseMenuOnClick = false;
|
||||
applyButton.Clicked += () =>
|
||||
{
|
||||
if (childCM.Tag == null)
|
||||
return;
|
||||
|
||||
// Reset selected icon on all buttons
|
||||
foreach (var child in vsMenu.Items)
|
||||
{
|
||||
if (child is ContextMenuButton cmb && cmb.Tag is ViewportScaleOptions v)
|
||||
{
|
||||
if (child == childCM)
|
||||
{
|
||||
v.Active = true;
|
||||
childCM.Icon = Style.Current.CheckBoxTick;
|
||||
ChangeViewportRatio(v);
|
||||
}
|
||||
else if (v.Active)
|
||||
{
|
||||
cmb.Icon = SpriteHandle.Invalid;
|
||||
v.Active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var deleteButton = childCM.ContextMenu.AddButton("Delete");
|
||||
deleteButton.CloseMenuOnClick = false;
|
||||
deleteButton.Clicked += () =>
|
||||
{
|
||||
if (childCM.Tag == null)
|
||||
return;
|
||||
|
||||
var v = (ViewportScaleOptions)childCM.Tag;
|
||||
if (v.Active)
|
||||
{
|
||||
v.Active = false;
|
||||
_defaultViewportScaling[0].Active = true;
|
||||
ChangeViewportRatio(_defaultViewportScaling[0]);
|
||||
}
|
||||
_customViewportScaling.Remove(v);
|
||||
vsMenu.DisposeAllItems();
|
||||
CreateViewportSizingContextMenu(vsMenu);
|
||||
vsMenu.PerformLayout();
|
||||
};
|
||||
}
|
||||
if (_customViewportScaling.Count != 0)
|
||||
vsMenu.AddSeparator();
|
||||
|
||||
// Add button
|
||||
var add = vsMenu.AddButton("Add...");
|
||||
add.CloseMenuOnClick = false;
|
||||
add.Clicked += () =>
|
||||
{
|
||||
var popup = new ContextMenuBase
|
||||
{
|
||||
Size = new Float2(230, 125),
|
||||
ClipChildren = false,
|
||||
CullChildren = false,
|
||||
};
|
||||
popup.Show(add, new Float2(add.Width, 0));
|
||||
|
||||
var nameLabel = new Label
|
||||
{
|
||||
Parent = popup,
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
Text = "Name",
|
||||
HorizontalAlignment = TextAlignment.Near,
|
||||
};
|
||||
nameLabel.LocalX += 10;
|
||||
nameLabel.LocalY += 10;
|
||||
|
||||
var nameTextBox = new TextBox
|
||||
{
|
||||
Parent = popup,
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
IsMultiline = false,
|
||||
};
|
||||
nameTextBox.LocalX += 100;
|
||||
nameTextBox.LocalY += 10;
|
||||
|
||||
var typeLabel = new Label
|
||||
{
|
||||
Parent = popup,
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
Text = "Type",
|
||||
HorizontalAlignment = TextAlignment.Near,
|
||||
};
|
||||
typeLabel.LocalX += 10;
|
||||
typeLabel.LocalY += 35;
|
||||
|
||||
var typeDropdown = new Dropdown
|
||||
{
|
||||
Parent = popup,
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
Items = { "Aspect", "Resolution" },
|
||||
SelectedItem = "Aspect",
|
||||
Width = nameTextBox.Width
|
||||
};
|
||||
typeDropdown.LocalY += 35;
|
||||
typeDropdown.LocalX += 100;
|
||||
|
||||
var whLabel = new Label
|
||||
{
|
||||
Parent = popup,
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
Text = "Width & Height",
|
||||
HorizontalAlignment = TextAlignment.Near,
|
||||
};
|
||||
whLabel.LocalX += 10;
|
||||
whLabel.LocalY += 60;
|
||||
|
||||
var wValue = new IntValueBox(16)
|
||||
{
|
||||
Parent = popup,
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
MinValue = 1,
|
||||
Width = 55,
|
||||
};
|
||||
wValue.LocalY += 60;
|
||||
wValue.LocalX += 100;
|
||||
|
||||
var hValue = new IntValueBox(9)
|
||||
{
|
||||
Parent = popup,
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
MinValue = 1,
|
||||
Width = 55,
|
||||
};
|
||||
hValue.LocalY += 60;
|
||||
hValue.LocalX += 165;
|
||||
|
||||
var submitButton = new Button
|
||||
{
|
||||
Parent = popup,
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
Text = "Submit",
|
||||
Width = 70,
|
||||
};
|
||||
submitButton.LocalX += 40;
|
||||
submitButton.LocalY += 90;
|
||||
|
||||
submitButton.Clicked += () =>
|
||||
{
|
||||
Enum.TryParse(typeDropdown.SelectedItem, out ViewportScaleType type);
|
||||
|
||||
var combineString = type == ViewportScaleType.Aspect ? ":" : "x";
|
||||
var name = nameTextBox.Text + " (" + wValue.Value + combineString + hValue.Value + ") " + typeDropdown.SelectedItem;
|
||||
|
||||
var newViewportOption = new ViewportScaleOptions
|
||||
{
|
||||
ScaleType = type,
|
||||
Label = name,
|
||||
Size = new Int2(wValue.Value, hValue.Value),
|
||||
};
|
||||
|
||||
_customViewportScaling.Add(newViewportOption);
|
||||
vsMenu.DisposeAllItems();
|
||||
CreateViewportSizingContextMenu(vsMenu);
|
||||
vsMenu.PerformLayout();
|
||||
};
|
||||
|
||||
var cancelButton = new Button
|
||||
{
|
||||
Parent = popup,
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
Text = "Cancel",
|
||||
Width = 70,
|
||||
};
|
||||
cancelButton.LocalX += 120;
|
||||
cancelButton.LocalY += 90;
|
||||
|
||||
cancelButton.Clicked += () =>
|
||||
{
|
||||
nameTextBox.Clear();
|
||||
typeDropdown.SelectedItem = "Aspect";
|
||||
hValue.Value = 9;
|
||||
wValue.Value = 16;
|
||||
popup.Hide();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw()
|
||||
{
|
||||
@@ -471,7 +875,7 @@ namespace FlaxEditor.Windows
|
||||
Screen.CursorVisible = true;
|
||||
if (Screen.CursorLock == CursorLockMode.Clipped)
|
||||
Screen.CursorLock = CursorLockMode.None;
|
||||
|
||||
|
||||
// Defocus
|
||||
_isUnlockingMouse = true;
|
||||
Focus(null);
|
||||
@@ -624,6 +1028,8 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
writer.WriteAttributeString("ShowGUI", ShowGUI.ToString());
|
||||
writer.WriteAttributeString("ShowDebugDraw", ShowDebugDraw.ToString());
|
||||
writer.WriteAttributeString("DefaultViewportScaling", JsonSerializer.Serialize(_defaultViewportScaling));
|
||||
writer.WriteAttributeString("CustomViewportScaling", JsonSerializer.Serialize(_customViewportScaling));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -633,6 +1039,23 @@ namespace FlaxEditor.Windows
|
||||
ShowGUI = value1;
|
||||
if (bool.TryParse(node.GetAttribute("ShowDebugDraw"), out value1))
|
||||
ShowDebugDraw = value1;
|
||||
if (node.HasAttribute("CustomViewportScaling"))
|
||||
_customViewportScaling = JsonSerializer.Deserialize<List<ViewportScaleOptions>>(node.GetAttribute("CustomViewportScaling"));
|
||||
|
||||
for (int i = 0; i < _customViewportScaling.Count; i++)
|
||||
{
|
||||
if (_customViewportScaling[i].Active)
|
||||
ChangeViewportRatio(_customViewportScaling[i]);
|
||||
}
|
||||
|
||||
if (node.HasAttribute("DefaultViewportScaling"))
|
||||
_defaultViewportScaling = JsonSerializer.Deserialize<List<ViewportScaleOptions>>(node.GetAttribute("DefaultViewportScaling"));
|
||||
|
||||
for (int i = 0; i < _defaultViewportScaling.Count; i++)
|
||||
{
|
||||
if (_defaultViewportScaling[i].Active)
|
||||
ChangeViewportRatio(_defaultViewportScaling[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#pragma warning disable 675
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Very basic pseudo numbers generator.
|
||||
/// </summary>
|
||||
[HideInEditor]
|
||||
public class RandomStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the initial seed.
|
||||
/// </summary>
|
||||
private int _initialSeed;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the current seed.
|
||||
/// </summary>
|
||||
private int _seed;
|
||||
|
||||
/// <summary>
|
||||
/// Init
|
||||
/// </summary>
|
||||
public RandomStream()
|
||||
{
|
||||
_initialSeed = 0;
|
||||
_seed = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and initializes a new random stream from the specified seed value.
|
||||
/// </summary>
|
||||
/// <param name="seed">The seed value.</param>
|
||||
public RandomStream(int seed)
|
||||
{
|
||||
_initialSeed = seed;
|
||||
_seed = seed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets initial seed value
|
||||
/// </summary>
|
||||
public int GetInitialSeed()
|
||||
{
|
||||
return _initialSeed;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current seed.
|
||||
/// </summary>
|
||||
public int GetCurrentSeed()
|
||||
{
|
||||
return _seed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this random stream with the specified seed value.
|
||||
/// </summary>
|
||||
/// <param name="seed">The seed value.</param>
|
||||
public void Initialize(int seed)
|
||||
{
|
||||
_initialSeed = seed;
|
||||
_seed = seed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this random stream to the initial seed value.
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
_seed = _initialSeed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a new random seed.
|
||||
/// </summary>
|
||||
public void GenerateNewSeed()
|
||||
{
|
||||
Initialize(new System.Random().Next());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a random boolean.
|
||||
/// </summary>
|
||||
public unsafe bool GetBool()
|
||||
{
|
||||
MutateSeed();
|
||||
fixed (int* seedPtr = &_seed)
|
||||
return *seedPtr < (uint.MaxValue / 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a random number between 0 and uint.MaxValue.
|
||||
/// </summary>
|
||||
public unsafe uint GetUnsignedInt()
|
||||
{
|
||||
MutateSeed();
|
||||
fixed (int* seedPtr = &_seed)
|
||||
return (uint)*seedPtr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a random number between 0 and 1.
|
||||
/// </summary>
|
||||
public unsafe float GetFraction()
|
||||
{
|
||||
MutateSeed();
|
||||
float temp = 1.0f;
|
||||
float result = 0.0f;
|
||||
*(int*)&result = (int)((*(int*)&temp & 0xff800000) | (_seed & 0x007fffff));
|
||||
return Mathf.Frac(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a random number between 0 and 1.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public float Rand()
|
||||
{
|
||||
return GetFraction();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a random vector of unit size.
|
||||
/// </summary>
|
||||
public Float3 GetUnitVector()
|
||||
{
|
||||
Float3 result;
|
||||
float l;
|
||||
do
|
||||
{
|
||||
result.X = GetFraction() * 2.0f - 1.0f;
|
||||
result.Y = GetFraction() * 2.0f - 1.0f;
|
||||
result.Z = GetFraction() * 2.0f - 1.0f;
|
||||
l = result.LengthSquared;
|
||||
} while (l > 1.0f || l < Mathf.Epsilon);
|
||||
return Float3.Normalize(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random <see cref="Vector3"/> with components in a range between [0;1].
|
||||
/// </summary>
|
||||
public Vector3 GetVector3()
|
||||
{
|
||||
return new Vector3(GetFraction(), GetFraction(), GetFraction());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function for rand implementations.
|
||||
/// </summary>
|
||||
/// <param name="a">Top border</param>
|
||||
/// <returns>A random number in [0..A)</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int RandHelper(int a)
|
||||
{
|
||||
return a > 0 ? Mathf.FloorToInt(GetFraction() * ((float)a - Mathf.Epsilon)) : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function for rand implementations
|
||||
/// </summary>
|
||||
/// <param name="min">Minimum value</param>
|
||||
/// <param name="max">Maximum value</param>
|
||||
/// <returns>A random number in [min; max] range</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int RandRange(int min, int max)
|
||||
{
|
||||
int range = max - min + 1;
|
||||
return min + RandHelper(range);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function for rand implementations
|
||||
/// </summary>
|
||||
/// <param name="min">Minimum value</param>
|
||||
/// <param name="max">Maximum value</param>
|
||||
/// <returns>A random number in [min; max] range</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public float RandRange(float min, float max)
|
||||
{
|
||||
return min + (max - min) * Rand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mutates the current seed into the next seed.
|
||||
/// </summary>
|
||||
protected void MutateSeed()
|
||||
{
|
||||
// This can be modified to provide better randomization
|
||||
_seed = _seed * 196314165 + 907633515;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Basic pseudo numbers generator utility.
|
||||
/// </summary>
|
||||
public static class RandomUtil
|
||||
{
|
||||
private static readonly Random _random = new Random();
|
||||
|
||||
/// <summary>
|
||||
/// Generates a pseudo-random number from normalized range [0;1].
|
||||
/// </summary>
|
||||
/// <returns>The random number.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float Rand()
|
||||
{
|
||||
return _random.Next(0, int.MaxValue) / (float)int.MaxValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -206,20 +206,12 @@ void AmbientOcclusionPass::Render(RenderContext& renderContext)
|
||||
if (renderContext.List == nullptr)
|
||||
return;
|
||||
auto& aoSettings = renderContext.List->Settings.AmbientOcclusion;
|
||||
if (aoSettings.Enabled == false || (renderContext.View.Flags & ViewFlags::AO) == ViewFlags::None)
|
||||
if (aoSettings.Enabled == false ||
|
||||
(renderContext.View.Flags & ViewFlags::AO) == ViewFlags::None ||
|
||||
renderContext.View.IsOrthographicProjection() || // TODO: add support for SSAO in ortho projection
|
||||
Math::Min(renderContext.Buffers->GetWidth(), renderContext.Buffers->GetHeight()) < 16 ||
|
||||
checkIfSkipPass())
|
||||
return;
|
||||
|
||||
// TODO: add support for SSAO in ortho projection
|
||||
if (renderContext.View.IsOrthographicProjection())
|
||||
return;
|
||||
|
||||
// Ensure to have valid data
|
||||
if (checkIfSkipPass())
|
||||
{
|
||||
// Resources are missing. Do not perform rendering.
|
||||
return;
|
||||
}
|
||||
|
||||
PROFILE_GPU_CPU("Ambient Occlusion");
|
||||
|
||||
settings.Radius = aoSettings.Radius * 0.006f;
|
||||
|
||||
Reference in New Issue
Block a user