Merge branch 'master' into 1.5

# Conflicts:
#	Source/Engine/Renderer/AmbientOcclusionPass.cpp
This commit is contained in:
2023-01-15 18:27:49 +01:00
10 changed files with 761 additions and 29 deletions
+12 -12
View File
@@ -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);
}
+6 -1
View File
@@ -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);
}
}
}
+53
View File
@@ -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();
+24
View File
@@ -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);
}
}
}
+424 -1
View File
@@ -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 />
+198
View File
@@ -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;
}
}
}
+25
View File
@@ -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;