Merge branch 'master' into 1.11
This commit is contained in:
@@ -438,7 +438,6 @@ VertexOutput VS(TerrainVertexInput input)
|
||||
// Apply world position offset per-vertex
|
||||
#if USE_POSITION_OFFSET
|
||||
output.Geometry.WorldPosition += material.PositionOffset;
|
||||
output.Geometry.PrevWorldPosition += material.PositionOffset;
|
||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -46,21 +46,26 @@ Follow the instructions below to compile and run the engine from source.
|
||||
* Install Visual Studio Code
|
||||
* Install .NET 8 or 9 SDK ([https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
|
||||
* Ubuntu: `sudo apt install dotnet-sdk-8.0`
|
||||
* Fedora: `sudo dnf install dotnet-sdk-8.0`
|
||||
* Arch: `sudo pacman -S dotnet-sdk-8.0 dotnet-runtime-8.0 dotnet-targeting-pack-8.0 dotnet-host`
|
||||
* Install Vulkan SDK ([https://vulkan.lunarg.com/](https://vulkan.lunarg.com/))
|
||||
* Ubuntu: `sudo apt install vulkan-sdk`
|
||||
* Arch: `sudo pacman -S spirv-tools vulkan-headers vulkan-tools vulkan-validation-layers`
|
||||
* Fedora: `sudo dnf install vulkan-headers vulkan-tools vulkan-validation-layers`
|
||||
* Arch: `sudo pacman -S vulkan-headers vulkan-tools vulkan-validation-layers`
|
||||
* Install Git with LFS
|
||||
* Ubuntu: `sudo apt-get install git git-lfs`
|
||||
* Arch: `sudo pacman -S git git-lfs`
|
||||
* `git-lfs install`
|
||||
* Install the required packages:
|
||||
* Ubuntu: `sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev zlib1g-dev`
|
||||
* Fedora: `sudo dnf install libX11-devel libXcursor-devel libXinerama-devel ghc-zlib-devel`
|
||||
* Arch: `sudo pacman -S base-devel libx11 libxcursor libxinerama zlib`
|
||||
* Install Clang compiler (version 6 or later):
|
||||
* Ubuntu: `sudo apt-get install clang lldb lld`
|
||||
* Fedora: `sudo dnf install clang llvm lldb lld`
|
||||
* Arch: `sudo pacman -S clang lldb lld`
|
||||
* Clone the repository (with LFS)
|
||||
* git-lfs clone https://github.com/FlaxEngine/FlaxEngine.git
|
||||
* Run `./GenerateProjectFiles.sh`
|
||||
* Open workspace with Visual Code
|
||||
* Build and run (configuration and task named `Flax|Editor.Linux.Development|x64`)
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace FlaxEditor.Content.Create
|
||||
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
|
||||
public class PrefabCreateEntry : CreateFileEntry
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override bool CanBeCreated => _options.RootActorType != null;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace FlaxEditor.Content.GUI
|
||||
set
|
||||
{
|
||||
value = Mathf.Clamp(value, 0.3f, 3.0f);
|
||||
if (!Mathf.NearEqual(value, _viewScale))
|
||||
if (value != _viewScale)
|
||||
{
|
||||
_viewScale = value;
|
||||
ViewScaleChanged?.Invoke();
|
||||
|
||||
@@ -10,11 +10,9 @@ using FlaxEngine;
|
||||
namespace FlaxEditor.Content
|
||||
{
|
||||
/// <summary>
|
||||
/// Context proxy object for shader source files (represented by <see cref="ShaderSourceItem"/>).
|
||||
/// Base class for shader source files.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.Content.ContentProxy" />
|
||||
[ContentContextMenu("New/Shader Source")]
|
||||
public class ShaderSourceProxy : ContentProxy
|
||||
public abstract class ShaderBaseProxy : ContentProxy
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override bool CanCreate(ContentFolder targetLocation)
|
||||
@@ -29,6 +27,21 @@ namespace FlaxEditor.Content
|
||||
return targetLocation.ShortName == "Source" && prevTargetLocation.ShortName == "Shaders";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override EditorWindow Open(Editor editor, ContentItem item)
|
||||
{
|
||||
Editor.Instance.CodeEditing.OpenFile(item.Path);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Context proxy object for shader source files (represented by <see cref="ShaderSourceItem"/>).
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.Content.ContentProxy" />
|
||||
[ContentContextMenu("New/Shader Source (.shader)")]
|
||||
public class ShaderSourceProxy : ShaderBaseProxy
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void Create(string outputPath, object arg)
|
||||
{
|
||||
@@ -44,13 +57,6 @@ namespace FlaxEditor.Content
|
||||
File.WriteAllText(outputPath, shaderTemplate, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override EditorWindow Open(Editor editor, ContentItem item)
|
||||
{
|
||||
Editor.Instance.CodeEditing.OpenFile(item.Path);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Color AccentColor => Color.FromRGB(0x7542f5);
|
||||
|
||||
@@ -66,4 +72,33 @@ namespace FlaxEditor.Content
|
||||
return item is ShaderSourceItem;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Context proxy object for shader header files.
|
||||
/// </summary>
|
||||
/// <seealso cref="FlaxEditor.Content.ContentProxy" />
|
||||
[ContentContextMenu("New/Shader Header (.hlsl)")]
|
||||
public class ShaderHeaderProxy : ShaderBaseProxy
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void Create(string outputPath, object arg)
|
||||
{
|
||||
File.WriteAllText(outputPath, "\n", Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Color AccentColor => Color.FromRGB(0x2545a5);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string FileExtension => "hlsl";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Shader Header";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsProxyFor(ContentItem item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.SceneGraph;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
@@ -52,6 +53,16 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
/// <param name="nodes">The nodes to select</param>
|
||||
public void Select(List<SceneGraph.SceneGraphNode> nodes);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current selection.
|
||||
/// </summary>
|
||||
public List<SceneGraphNode> Selection { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indication of if the properties window is locked on specific objects.
|
||||
/// </summary>
|
||||
public bool LockSelection { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -81,6 +92,8 @@ namespace FlaxEditor.CustomEditors
|
||||
Offsets = Margin.Zero;
|
||||
Pivot = Float2.Zero;
|
||||
IsScrollable = true;
|
||||
Spacing = Utilities.Constants.UIMargin;
|
||||
Margin = new Margin(Utilities.Constants.UIMargin);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -95,7 +108,7 @@ namespace FlaxEditor.CustomEditors
|
||||
{
|
||||
FlaxEditor.Editor.LogWarning(ex);
|
||||
|
||||
// Refresh layout on errors to reduce lgo spam
|
||||
// Refresh layout on errors to reduce log spam
|
||||
_presenter.BuildLayout();
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ using FlaxEditor.CustomEditors.Elements;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.GUI.Tree;
|
||||
using FlaxEditor.Modules;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEditor.Windows.Assets;
|
||||
@@ -71,7 +70,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
// Display prefab UI (when displaying object inside Prefab Window then display only nested prefabs)
|
||||
prefab.GetNestedObject(ref prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId);
|
||||
var nestedPrefab = FlaxEngine.Content.Load<Prefab>(nestedPrefabId);
|
||||
var panel = layout.CustomContainer<UniformGridPanel>();
|
||||
var panel = layout.UniformGrid();
|
||||
panel.CustomControl.Height = 20.0f;
|
||||
panel.CustomControl.SlotsVertically = 1;
|
||||
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter || nestedPrefab)
|
||||
@@ -133,35 +132,22 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
var actor = (Actor)Values[0];
|
||||
var scriptType = TypeUtils.GetType(actor.TypeName);
|
||||
var item = scriptType.ContentItem;
|
||||
if (Presenter.Owner is PropertiesWindow propertiesWindow)
|
||||
if (Presenter.Owner != null)
|
||||
{
|
||||
var lockButton = cm.AddButton(propertiesWindow.LockObjects ? "Unlock" : "Lock");
|
||||
var lockButton = cm.AddButton(Presenter.Owner.LockSelection ? "Unlock" : "Lock");
|
||||
lockButton.ButtonClicked += button =>
|
||||
{
|
||||
propertiesWindow.LockObjects = !propertiesWindow.LockObjects;
|
||||
var owner = Presenter?.Owner;
|
||||
if (owner == null)
|
||||
return;
|
||||
owner.LockSelection = !owner.LockSelection;
|
||||
|
||||
// Reselect current selection
|
||||
if (!propertiesWindow.LockObjects && Editor.Instance.SceneEditing.SelectionCount > 0)
|
||||
if (!owner.LockSelection && owner.Selection.Count > 0)
|
||||
{
|
||||
var cachedSelection = Editor.Instance.SceneEditing.Selection.ToArray();
|
||||
Editor.Instance.SceneEditing.Select(null);
|
||||
Editor.Instance.SceneEditing.Select(cachedSelection);
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (Presenter.Owner is PrefabWindow prefabWindow)
|
||||
{
|
||||
var lockButton = cm.AddButton(prefabWindow.LockSelectedObjects ? "Unlock" : "Lock");
|
||||
lockButton.ButtonClicked += button =>
|
||||
{
|
||||
prefabWindow.LockSelectedObjects = !prefabWindow.LockSelectedObjects;
|
||||
|
||||
// Reselect current selection
|
||||
if (!prefabWindow.LockSelectedObjects && prefabWindow.Selection.Count > 0)
|
||||
{
|
||||
var cachedSelection = prefabWindow.Selection.ToList();
|
||||
prefabWindow.Select(null);
|
||||
prefabWindow.Select(cachedSelection);
|
||||
var cachedSelection = owner.Selection.ToList();
|
||||
owner.Select(null);
|
||||
owner.Select(cachedSelection);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -258,7 +244,17 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
else if (editor.Values[0] is SceneObject sceneObject)
|
||||
{
|
||||
node.TextColor = sceneObject.HasPrefabLink ? FlaxEngine.GUI.Style.Current.ProgressNormal : FlaxEngine.GUI.Style.Current.BackgroundSelected;
|
||||
node.Text = Utilities.Utils.GetPropertyNameUI(sceneObject.GetType().Name);
|
||||
if (editor.Values.Info != ScriptMemberInfo.Null)
|
||||
{
|
||||
if (editor.Values.GetAttributes().FirstOrDefault(x => x is EditorDisplayAttribute) is EditorDisplayAttribute editorDisplayAttribute && !string.IsNullOrEmpty(editorDisplayAttribute.Name))
|
||||
node.Text = $"{Utilities.Utils.GetPropertyNameUI(editorDisplayAttribute.Name)} ({Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name)})";
|
||||
else
|
||||
node.Text = Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name);
|
||||
}
|
||||
else if (sceneObject is Actor actor)
|
||||
node.Text = $"{actor.Name} ({Utilities.Utils.GetPropertyNameUI(sceneObject.GetType().Name)})";
|
||||
else
|
||||
node.Text = Utilities.Utils.GetPropertyNameUI(sceneObject.GetType().Name);
|
||||
}
|
||||
// Array Item
|
||||
else if (editor.ParentEditor is CollectionEditor)
|
||||
@@ -268,7 +264,12 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
// Common type
|
||||
else if (editor.Values.Info != ScriptMemberInfo.Null)
|
||||
{
|
||||
node.Text = Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name);
|
||||
if (editor.Values.GetAttributes().FirstOrDefault(x => x is EditorDisplayAttribute) is EditorDisplayAttribute editorDisplayAttribute
|
||||
&& !string.IsNullOrEmpty(editorDisplayAttribute.Name)
|
||||
&& !editorDisplayAttribute.Name.Contains("_inline"))
|
||||
node.Text = $"{Utilities.Utils.GetPropertyNameUI(editorDisplayAttribute.Name)} ({Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name)})";
|
||||
else
|
||||
node.Text = Utilities.Utils.GetPropertyNameUI(editor.Values.Info.Name);
|
||||
}
|
||||
// Custom type
|
||||
else if (editor.Values[0] != null)
|
||||
@@ -316,7 +317,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
var childEditor = editor.ChildrenEditors[i];
|
||||
|
||||
// Special case for root actor transformation (can be applied only in Prefab editor, not in Level)
|
||||
if (isActorEditorInLevel && childEditor.Values.Info.Name is "LocalPosition" or "LocalOrientation" or "LocalScale")
|
||||
if (isActorEditorInLevel && childEditor.Values.Info.Name is "LocalPosition" or "LocalOrientation" or "LocalScale" or "Name")
|
||||
continue;
|
||||
|
||||
var child = ProcessDiff(childEditor, !isScriptEditorWithRefValue);
|
||||
@@ -361,13 +362,39 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
return result;
|
||||
}
|
||||
|
||||
private TreeNode CreateDiffTree(Actor actor, CustomEditorPresenter presenter, LayoutElementsContainer layout)
|
||||
{
|
||||
var actorNode = Editor.Instance.Scene.GetActorNode(actor);
|
||||
ValueContainer vc = new ValueContainer(ScriptMemberInfo.Null);
|
||||
vc.SetType(new ScriptType(actorNode.EditableObject.GetType()));
|
||||
vc.Add(actorNode.EditableObject);
|
||||
var editor = CustomEditorsUtil.CreateEditor(vc, null, false);
|
||||
editor.Initialize(presenter, layout, vc);
|
||||
var node = ProcessDiff(editor, false);
|
||||
layout.ClearLayout();
|
||||
foreach (var child in actor.Children)
|
||||
{
|
||||
var childNode = CreateDiffTree(child, presenter, layout);
|
||||
if (childNode == null)
|
||||
continue;
|
||||
if (node == null)
|
||||
node = CreateDiffNode(editor);
|
||||
node.AddChild(childNode);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
private void ViewChanges(Control target, Float2 targetLocation)
|
||||
{
|
||||
// Build a tree out of modified properties
|
||||
var rootNode = ProcessDiff(this, false);
|
||||
var thisActor = (Actor)Values[0];
|
||||
var rootActor = thisActor.IsPrefabRoot ? thisActor : thisActor.GetPrefabRoot();
|
||||
var presenter = new CustomEditorPresenter(null);
|
||||
var layout = new CustomElementsContainer<ContainerControl>();
|
||||
var rootNode = CreateDiffTree(rootActor, presenter, layout);
|
||||
|
||||
// Skip if no changes detected
|
||||
if (rootNode == null || rootNode.ChildrenCount == 0)
|
||||
if (rootNode == null)
|
||||
{
|
||||
var cm1 = new ContextMenu();
|
||||
cm1.AddButton("No changes detected");
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
_infoLabel = playbackGroup.Label(string.Empty).Label;
|
||||
_infoLabel.AutoHeight = true;
|
||||
|
||||
var grid = playbackGroup.CustomContainer<UniformGridPanel>();
|
||||
var grid = playbackGroup.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = Button.DefaultHeight;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
var paintValue = new ReadOnlyValueContainer(new ScriptType(typeof(ClothPaintingGizmoMode)), _gizmoMode);
|
||||
paintGroup.Object(paintValue);
|
||||
{
|
||||
var grid = paintGroup.CustomContainer<UniformGridPanel>();
|
||||
var grid = paintGroup.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = Button.DefaultHeight;
|
||||
|
||||
@@ -92,12 +92,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
|
||||
// Update add button
|
||||
var update = group.Button("Update").Button;
|
||||
group.Space(0);
|
||||
update.TooltipText = "Refreshes the dashboard statistics";
|
||||
update.Height = 16.0f;
|
||||
update.Clicked += RebuildLayout;
|
||||
|
||||
// New locale add button
|
||||
var addLocale = group.Button("Add Locale...").Button;
|
||||
group.Space(0);
|
||||
addLocale.TooltipText = "Shows a locale picker and creates new localization for it with not translated string tables";
|
||||
addLocale.Height = 16.0f;
|
||||
addLocale.ButtonClicked += delegate(Button button)
|
||||
@@ -167,12 +169,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
|
||||
// Export button
|
||||
var exportLocalization = group.Button("Export...").Button;
|
||||
group.Space(0);
|
||||
exportLocalization.TooltipText = "Exports the localization strings into .pot file for translation";
|
||||
exportLocalization.Height = 16.0f;
|
||||
exportLocalization.Clicked += () => Export(tableEntries, allKeys);
|
||||
|
||||
// Find localized strings in code button
|
||||
var findStringsCode = group.Button("Find localized strings in code").Button;
|
||||
group.Space(0);
|
||||
findStringsCode.TooltipText = "Searches for localized string usage in inside a project source files";
|
||||
findStringsCode.Height = 16.0f;
|
||||
findStringsCode.Clicked += delegate
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ModelPrefabEditor : GenericEditor
|
||||
|
||||
// Creates the import path UI
|
||||
var group = layout.Group("Import Path");
|
||||
Utilities.Utils.CreateImportPathUI(group, modelPrefab.ImportPath, false);
|
||||
Utilities.Utils.CreateImportPathUI(group, modelPrefab.ImportPath);
|
||||
|
||||
var button = layout.Button("Reimport", "Reimports the source asset as prefab.");
|
||||
_reimportButton = button.Button;
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
_infoLabel = playbackGroup.Label(string.Empty).Label;
|
||||
_infoLabel.AutoHeight = true;
|
||||
|
||||
var grid = playbackGroup.CustomContainer<UniformGridPanel>();
|
||||
var grid = playbackGroup.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = Button.DefaultHeight;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
if (ragdoll.Parent is AnimatedModel animatedModel && animatedModel.SkinnedModel)
|
||||
{
|
||||
// Builder
|
||||
var grid = editorGroup.CustomContainer<UniformGridPanel>();
|
||||
var grid = editorGroup.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = Button.DefaultHeight;
|
||||
@@ -53,7 +53,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
if (Presenter.Owner != null)
|
||||
{
|
||||
// Selection
|
||||
var grid = editorGroup.CustomContainer<UniformGridPanel>();
|
||||
var grid = editorGroup.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = Button.DefaultHeight;
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
_infoLabel = playbackGroup.Label(string.Empty).Label;
|
||||
_infoLabel.AutoHeight = true;
|
||||
|
||||
var grid = playbackGroup.CustomContainer<UniformGridPanel>();
|
||||
var grid = playbackGroup.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = Button.DefaultHeight;
|
||||
|
||||
@@ -682,7 +682,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
|
||||
private CustomElementsContainer<UniformGridPanel> UniformGridTwoByOne(LayoutElementsContainer cont)
|
||||
{
|
||||
var grid = cont.CustomContainer<UniformGridPanel>();
|
||||
var grid = cont.UniformGrid();
|
||||
grid.CustomControl.SlotsHorizontally = 2;
|
||||
grid.CustomControl.SlotsVertically = 1;
|
||||
grid.CustomControl.SlotPadding = Margin.Zero;
|
||||
|
||||
@@ -43,11 +43,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
base.Initialize(layout);
|
||||
|
||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||
{
|
||||
ug.Height += 2;
|
||||
ug.SlotSpacing = new Float2(4);
|
||||
ug.SlotPadding = new Margin(0, 0, 1, 1);
|
||||
}
|
||||
CheckLayout(ug);
|
||||
|
||||
// Override colors
|
||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||
@@ -75,11 +71,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
base.Initialize(layout);
|
||||
|
||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||
{
|
||||
ug.Height += 2;
|
||||
ug.SlotSpacing = new Float2(4);
|
||||
ug.SlotPadding = new Margin(0, 0, 1, 1);
|
||||
}
|
||||
CheckLayout(ug);
|
||||
|
||||
// Override colors
|
||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||
@@ -138,11 +130,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
|
||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||
{
|
||||
ug.Height += 2;
|
||||
ug.SlotSpacing = new Float2(4);
|
||||
ug.SlotPadding = new Margin(0, 0, 1, 1);
|
||||
}
|
||||
CheckLayout(ug);
|
||||
|
||||
// Override colors
|
||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||
@@ -203,5 +191,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
_linkButton.TooltipText = LinkValues ? "Unlinks scale components from uniform scaling" : "Links scale components for uniform scaling";
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckLayout(UniformGridPanel ug)
|
||||
{
|
||||
// Enlarge to fix border visibility
|
||||
ug.Height += 2;
|
||||
ug.SlotSpacing += new Float2(2);
|
||||
ug.SlotPadding += new Margin(0, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,10 +642,10 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (_canResize && !_readOnly)
|
||||
{
|
||||
var panel = dragArea.HorizontalPanel();
|
||||
panel.Panel.Size = new Float2(0, 20);
|
||||
panel.Panel.Margin = new Margin(2);
|
||||
panel.Panel.Size = new Float2(0, 18);
|
||||
panel.Panel.Margin = new Margin(0, 0, Utilities.Constants.UIMargin, 0);
|
||||
|
||||
var removeButton = panel.Button("-", "Remove last item");
|
||||
var removeButton = panel.Button("-", "Remove the last item");
|
||||
removeButton.Button.Size = new Float2(16, 16);
|
||||
removeButton.Button.Enabled = size > _minCount;
|
||||
removeButton.Button.AnchorPreset = AnchorPresets.TopRight;
|
||||
@@ -656,7 +656,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
Resize(Count - 1);
|
||||
};
|
||||
|
||||
var addButton = panel.Button("+", "Add new item");
|
||||
var addButton = panel.Button("+", "Add a new item");
|
||||
addButton.Button.Size = new Float2(16, 16);
|
||||
addButton.Button.Enabled = (!NotNullItems || size > 0) && size < _maxCount;
|
||||
addButton.Button.AnchorPreset = AnchorPresets.TopRight;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
float trackBallSize = 80.0f;
|
||||
float trackBallSize = 100f;
|
||||
float margin = 4.0f;
|
||||
|
||||
// Panel
|
||||
@@ -50,7 +50,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
// Scale editor
|
||||
{
|
||||
var grid = masterPanel.CustomContainer<UniformGridPanel>();
|
||||
var grid = masterPanel.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.SlotPadding = new Margin(4, 2, 2, 2);
|
||||
gridControl.ClipChildren = false;
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public sealed class LocalizedStringEditor : GenericEditor
|
||||
{
|
||||
private TextBoxElement _idElement, _valueElement;
|
||||
private Button _viewStringButton;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override DisplayStyle Style => DisplayStyle.Inline;
|
||||
@@ -70,6 +71,21 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
};
|
||||
addString.SetAnchorPreset(AnchorPresets.MiddleRight, false, true);
|
||||
addString.ButtonClicked += OnAddStringClicked;
|
||||
|
||||
var viewString = new Button
|
||||
{
|
||||
Visible = false,
|
||||
Width = 16.0f,
|
||||
BackgroundColor = Color.White,
|
||||
BackgroundColorHighlighted = Color.Gray,
|
||||
BackgroundBrush = new SpriteBrush(Editor.Instance.Icons.Search12),
|
||||
TooltipText = "Find localized text in Localized String Table asset for the current locale...",
|
||||
Parent = valueElement.TextBox,
|
||||
};
|
||||
viewString.SetAnchorPreset(AnchorPresets.MiddleRight, false, true);
|
||||
viewString.LocalX -= 16.0f;
|
||||
viewString.ButtonClicked += OnViewStringClicked;
|
||||
_viewStringButton = viewString;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -80,6 +96,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (_valueElement != null)
|
||||
{
|
||||
_valueElement.TextBox.WatermarkText = Localization.GetString(_idElement.Text);
|
||||
_viewStringButton.Visible = !string.IsNullOrEmpty(_valueElement.TextBox.WatermarkText);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,14 +109,21 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
_valueElement = null;
|
||||
}
|
||||
|
||||
private void OnSelectStringClicked(Button button)
|
||||
private bool GetSettings(out LocalizationSettings settings)
|
||||
{
|
||||
var settings = GameSettings.Load<LocalizationSettings>();
|
||||
settings = GameSettings.Load<LocalizationSettings>();
|
||||
if (settings?.LocalizedStringTables == null || settings.LocalizedStringTables.Length == 0)
|
||||
{
|
||||
MessageBox.Show("No valid localization settings setup.");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnSelectStringClicked(Button button)
|
||||
{
|
||||
if (GetSettings(out var settings))
|
||||
return;
|
||||
Profiler.BeginEvent("LocalizedStringEditor.OnSelectStringClicked");
|
||||
var allKeys = new HashSet<string>();
|
||||
for (int i = 0; i < settings.LocalizedStringTables.Length; i++)
|
||||
@@ -136,6 +160,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
menu.Hide();
|
||||
_idElement.TextBox.SetTextAsUser(after[0].Text);
|
||||
_valueElement.TextBox.SetTextAsUser(string.Empty);
|
||||
}
|
||||
};
|
||||
searchBox.TextChanged += delegate
|
||||
@@ -158,12 +183,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
private void OnAddStringClicked(Button button)
|
||||
{
|
||||
var settings = GameSettings.Load<LocalizationSettings>();
|
||||
if (settings?.LocalizedStringTables == null || settings.LocalizedStringTables.Length == 0)
|
||||
{
|
||||
MessageBox.Show("No valid localization settings setup.");
|
||||
if (GetSettings(out var settings))
|
||||
return;
|
||||
}
|
||||
Profiler.BeginEvent("LocalizedStringEditor.OnAddStringClicked");
|
||||
var allKeys = new HashSet<string>();
|
||||
for (int i = 0; i < settings.LocalizedStringTables.Length; i++)
|
||||
@@ -231,5 +252,30 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
_idElement.TextBox.SetTextAsUser(newKey);
|
||||
Profiler.EndEvent();
|
||||
}
|
||||
|
||||
private void OnViewStringClicked(Button button)
|
||||
{
|
||||
if (GetSettings(out var settings))
|
||||
return;
|
||||
var id = _idElement.TextBox.Text;
|
||||
var value = _valueElement.TextBox.WatermarkText;
|
||||
for (int i = 0; i < settings.LocalizedStringTables.Length; i++)
|
||||
{
|
||||
var table = settings.LocalizedStringTables[i];
|
||||
if (table && !table.WaitForLoaded())
|
||||
{
|
||||
var entries = table.Entries;
|
||||
if (entries.TryGetValue(id, out var messages))
|
||||
{
|
||||
if (messages.Length != 0 && messages[0] == value)
|
||||
{
|
||||
Editor.Instance.ContentEditing.Open(table);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MessageBox.Show("Unable to find localized string table.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
|
||||
_element = layout.TextBox(isMultiLine);
|
||||
_defaultWatermarkColor = _element.TextBox.WatermarkTextColor;
|
||||
_watermarkColor = _defaultWatermarkColor = _element.TextBox.WatermarkTextColor;
|
||||
if (watermarkAttribute is WatermarkAttribute watermark)
|
||||
{
|
||||
_watermarkText = watermark.WatermarkText;
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
@@ -131,7 +131,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
@@ -220,7 +220,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
@@ -469,7 +469,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
@@ -783,7 +783,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
@@ -163,7 +163,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
@@ -274,7 +274,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var grid = layout.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = TextBox.DefaultHeight;
|
||||
|
||||
@@ -22,7 +22,8 @@ namespace FlaxEditor.CustomEditors.Elements
|
||||
ArrowImageClosed = new SpriteBrush(Style.Current.ArrowRight),
|
||||
ArrowImageOpened = new SpriteBrush(Style.Current.ArrowDown),
|
||||
EnableDropDownIcon = true,
|
||||
ItemsMargin = new Margin(7, 7, 3, 3),
|
||||
ItemsMargin = new Margin(Utilities.Constants.UIMargin),
|
||||
ItemsSpacing = Utilities.Constants.UIMargin,
|
||||
HeaderHeight = 18.0f,
|
||||
EnableContainmentLines = true,
|
||||
};
|
||||
|
||||
@@ -20,13 +20,6 @@ namespace FlaxEditor.CustomEditors.GUI
|
||||
/// </summary>
|
||||
public const int SplitterSize = 2;
|
||||
|
||||
/// <summary>
|
||||
/// The splitter margin (in pixels).
|
||||
/// </summary>
|
||||
public const int SplitterMargin = 4;
|
||||
|
||||
private const int SplitterSizeHalf = SplitterSize / 2;
|
||||
|
||||
private PropertiesListElement _element;
|
||||
private float _splitterValue;
|
||||
private Rectangle _splitterRect;
|
||||
@@ -65,16 +58,18 @@ namespace FlaxEditor.CustomEditors.GUI
|
||||
/// <param name="element">The element.</param>
|
||||
public PropertiesList(PropertiesListElement element)
|
||||
{
|
||||
ClipChildren = false;
|
||||
_element = element;
|
||||
_splitterValue = 0.4f;
|
||||
BottomMargin = TopMargin = RightMargin = SplitterMargin;
|
||||
Margin = new Margin();
|
||||
Spacing = Utilities.Constants.UIMargin;
|
||||
UpdateSplitRect();
|
||||
}
|
||||
|
||||
private void UpdateSplitRect()
|
||||
{
|
||||
_splitterRect = new Rectangle(Mathf.Clamp(_splitterValue * Width - SplitterSizeHalf, 0.0f, Width), 0, SplitterSize, Height);
|
||||
LeftMargin = _splitterValue * Width + SplitterMargin;
|
||||
_splitterRect = new Rectangle(Mathf.Clamp(_splitterValue * Width - SplitterSize * 0.5f, 0.0f, Width), 0, SplitterSize, Height);
|
||||
LeftMargin = _splitterValue * Width + _spacing;
|
||||
}
|
||||
|
||||
private void StartTracking()
|
||||
@@ -222,23 +217,33 @@ namespace FlaxEditor.CustomEditors.GUI
|
||||
/// <inheritdoc />
|
||||
protected override void PerformLayoutAfterChildren()
|
||||
{
|
||||
// Sort controls from up to down into two columns: one for labels and one for the rest of the stuff
|
||||
|
||||
// Place non-label controls from top to down
|
||||
float y = _margin.Top;
|
||||
float w = Width - _margin.Width;
|
||||
bool firstItem = true;
|
||||
for (int i = 0; i < _children.Count; i++)
|
||||
{
|
||||
Control c = _children[i];
|
||||
if (!(c is PropertyNameLabel))
|
||||
{
|
||||
var h = c.Height;
|
||||
c.Bounds = new Rectangle(_margin.Left, y + _spacing, w, h);
|
||||
var rect = new Rectangle(_margin.Left, y, w, c.Height);
|
||||
if (c.Visible)
|
||||
{
|
||||
if (firstItem)
|
||||
firstItem = false;
|
||||
else
|
||||
rect.Y += _spacing;
|
||||
}
|
||||
else if (!firstItem)
|
||||
rect.Y += _spacing;
|
||||
c.Bounds = rect;
|
||||
if (c.Visible)
|
||||
y = c.Bottom;
|
||||
}
|
||||
}
|
||||
y += _margin.Bottom;
|
||||
|
||||
// Place labels accordingly to their respective controls placement
|
||||
float namesWidth = _splitterValue * Width;
|
||||
int count = _element.Labels.Count;
|
||||
float[] yStarts = new float[count + 1];
|
||||
@@ -271,7 +276,9 @@ namespace FlaxEditor.CustomEditors.GUI
|
||||
{
|
||||
var label = _element.Labels[i];
|
||||
|
||||
var rect = new Rectangle(0, yStarts[i] + 1, namesWidth, yStarts[i + 1] - yStarts[i] - 2);
|
||||
var rect = new Rectangle(0, yStarts[i], namesWidth, yStarts[i + 1] - yStarts[i]);
|
||||
if (i != count - 1)
|
||||
rect.Height -= _spacing;
|
||||
//label.Parent = this;
|
||||
label.Bounds = rect;
|
||||
}
|
||||
|
||||
@@ -202,6 +202,17 @@ namespace FlaxEditor.CustomEditors
|
||||
return element;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds new uniform grid control.
|
||||
/// </summary>
|
||||
/// <returns>The created element.</returns>
|
||||
public CustomElementsContainer<UniformGridPanel> UniformGrid()
|
||||
{
|
||||
var grid = CustomContainer<UniformGridPanel>();
|
||||
grid.CustomControl.SlotSpacing = new Float2(Utilities.Constants.UIMargin);
|
||||
return grid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds new custom element.
|
||||
/// </summary>
|
||||
|
||||
@@ -1031,6 +1031,8 @@ namespace FlaxEditor
|
||||
{
|
||||
Internal_GetEditorBoxWithChildren(FlaxEngine.Object.GetUnmanagedPtr(actor), out var box);
|
||||
BoundingSphere.FromBox(ref box, out sphere);
|
||||
if (sphere == BoundingSphere.Empty)
|
||||
sphere = new BoundingSphere(actor.Position, sphere.Radius);
|
||||
sphere.Radius = Math.Max(sphere.Radius, 15.0f);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -285,6 +285,17 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
}
|
||||
}
|
||||
|
||||
private static void ForceDefocus(ContainerControl c)
|
||||
{
|
||||
foreach (var cc in c.Children)
|
||||
{
|
||||
if (cc.ContainsFocus)
|
||||
cc.Defocus();
|
||||
if (cc is ContainerControl ccc)
|
||||
ForceDefocus(ccc);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hide popup menu and all child menus.
|
||||
/// </summary>
|
||||
@@ -299,6 +310,9 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
// Close child
|
||||
HideChild();
|
||||
|
||||
// Force defocus
|
||||
ForceDefocus(this);
|
||||
|
||||
// Unlink from window
|
||||
Parent = null;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace FlaxEditor.GUI.Input
|
||||
get => _min;
|
||||
set
|
||||
{
|
||||
if (!Mathd.NearEqual(_min, value))
|
||||
if (_min != value)
|
||||
{
|
||||
if (value > _max)
|
||||
throw new ArgumentException();
|
||||
@@ -58,7 +58,7 @@ namespace FlaxEditor.GUI.Input
|
||||
get => _max;
|
||||
set
|
||||
{
|
||||
if (!Mathd.NearEqual(_max, value))
|
||||
if (_max != value)
|
||||
{
|
||||
if (value < _min)
|
||||
throw new ArgumentException();
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace FlaxEditor.GUI.Input
|
||||
get => _min;
|
||||
set
|
||||
{
|
||||
if (!Mathf.NearEqual(_min, value))
|
||||
if (_min != value)
|
||||
{
|
||||
if (value > _max)
|
||||
throw new ArgumentException();
|
||||
@@ -54,7 +54,7 @@ namespace FlaxEditor.GUI.Input
|
||||
get => _max;
|
||||
set
|
||||
{
|
||||
if (!Mathf.NearEqual(_max, value))
|
||||
if (_max != value)
|
||||
{
|
||||
if (value < _min)
|
||||
throw new ArgumentException();
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace FlaxEditor.GUI.Input
|
||||
set
|
||||
{
|
||||
value = Mathf.Clamp(value, Minimum, Maximum);
|
||||
if (!Mathf.NearEqual(value, _value))
|
||||
if (value != _value)
|
||||
{
|
||||
_value = value;
|
||||
|
||||
@@ -311,7 +311,7 @@ namespace FlaxEditor.GUI.Input
|
||||
get => _min;
|
||||
set
|
||||
{
|
||||
if (!Mathf.NearEqual(_min, value))
|
||||
if (_min != value)
|
||||
{
|
||||
if (value > _max)
|
||||
throw new ArgumentException();
|
||||
@@ -330,7 +330,7 @@ namespace FlaxEditor.GUI.Input
|
||||
get => _max;
|
||||
set
|
||||
{
|
||||
if (!Mathf.NearEqual(_max, value))
|
||||
if (_max != value)
|
||||
{
|
||||
if (value < _min)
|
||||
throw new ArgumentException();
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace FlaxEditor.GUI.Tabs
|
||||
if (EnabledInHierarchy && Tab.Enabled)
|
||||
{
|
||||
Tabs.SelectedTab = Tab;
|
||||
Tab.PerformLayout(true);
|
||||
Tabs.Focus();
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace FlaxEditor.GUI.Tree
|
||||
private readonly bool _supportMultiSelect;
|
||||
private Margin _margin;
|
||||
private bool _autoSize = true;
|
||||
private bool _deferLayoutUpdate = false;
|
||||
|
||||
/// <summary>
|
||||
/// The TreeNode that is being dragged over. This could have a value when not dragging.
|
||||
@@ -67,6 +68,11 @@ namespace FlaxEditor.GUI.Tree
|
||||
/// </summary>
|
||||
public TreeNode SelectedNode => Selection.Count > 0 ? Selection[0] : null;
|
||||
|
||||
/// <summary>
|
||||
/// Allow nodes to Draw the root tree line.
|
||||
/// </summary>
|
||||
public bool DrawRootTreeLine = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the margin for the child tree nodes.
|
||||
/// </summary>
|
||||
@@ -353,9 +359,25 @@ namespace FlaxEditor.GUI.Tree
|
||||
BulkSelectUpdateExpanded(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void PerformLayout(bool force = false)
|
||||
{
|
||||
if (_isLayoutLocked && !force)
|
||||
return;
|
||||
|
||||
// In case the tree was fully expanded or collapsed along its children, avoid calculating the layout multiple times for each child
|
||||
_deferLayoutUpdate = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (_deferLayoutUpdate)
|
||||
{
|
||||
base.PerformLayout();
|
||||
_deferLayoutUpdate = false;
|
||||
}
|
||||
|
||||
var node = SelectedNode;
|
||||
|
||||
// Check if has focus and if any node is focused and it isn't a root
|
||||
|
||||
@@ -760,20 +760,21 @@ namespace FlaxEditor.GUI.Tree
|
||||
// Show tree guidelines
|
||||
if (Editor.Instance.Options.Options.Interface.ShowTreeLines)
|
||||
{
|
||||
TreeNode parentNode = Parent as TreeNode;
|
||||
ContainerControl parent = Parent;
|
||||
TreeNode parentNode = parent as TreeNode;
|
||||
bool thisNodeIsLast = false;
|
||||
while (parentNode != null && parentNode != ParentTree.Children[0])
|
||||
while (parentNode != null && (parentNode != tree.Children[0] || tree.DrawRootTreeLine))
|
||||
{
|
||||
float bottomOffset = 0;
|
||||
float topOffset = 0;
|
||||
|
||||
if (Parent == parentNode && this == Parent.Children[0])
|
||||
if (parent == parentNode && this == parent.Children[0])
|
||||
topOffset = 2;
|
||||
|
||||
if (thisNodeIsLast && parentNode.Children.Count == 1)
|
||||
bottomOffset = topOffset != 0 ? 4 : 2;
|
||||
|
||||
if (Parent == parentNode && this == Parent.Children[Parent.Children.Count - 1] && !_opened)
|
||||
if (parent == parentNode && this == parent.Children[^1] && !_opened)
|
||||
{
|
||||
thisNodeIsLast = true;
|
||||
bottomOffset = topOffset != 0 ? 4 : 2;
|
||||
@@ -784,6 +785,8 @@ namespace FlaxEditor.GUI.Tree
|
||||
if (_iconCollaped.IsValid)
|
||||
leftOffset += 18;
|
||||
var lineRect1 = new Rectangle(parentNode.TextRect.Left - leftOffset, parentNode.HeaderRect.Top + topOffset, 1, parentNode.HeaderRect.Height - bottomOffset);
|
||||
if (HasAnyVisibleChild && CustomArrowRect.HasValue && CustomArrowRect.Value.Intersects(lineRect1))
|
||||
lineRect1 = Rectangle.Empty; // Skip drawing line if it's overlapping the arrow rectangle
|
||||
Render2D.FillRectangle(lineRect1, isSelected ? style.ForegroundGrey : style.LightBackground);
|
||||
parentNode = parentNode.Parent as TreeNode;
|
||||
}
|
||||
|
||||
@@ -1135,6 +1135,7 @@ namespace FlaxEditor.Modules
|
||||
Proxy.Add(new FontProxy());
|
||||
Proxy.Add(new ShaderProxy());
|
||||
Proxy.Add(new ShaderSourceProxy());
|
||||
Proxy.Add(new ShaderHeaderProxy());
|
||||
Proxy.Add(new ParticleEmitterProxy());
|
||||
Proxy.Add(new ParticleEmitterFunctionProxy());
|
||||
Proxy.Add(new ParticleSystemProxy());
|
||||
|
||||
@@ -255,12 +255,17 @@ namespace FlaxEditor.Modules
|
||||
|
||||
// When applying changes to prefab from actor in level ignore it's root transformation (see ActorEditor.ProcessDiff)
|
||||
var originalTransform = instance.LocalTransform;
|
||||
var originalName = instance.Name;
|
||||
if (instance.IsPrefabRoot && instance.HasScene)
|
||||
{
|
||||
instance.LocalTransform = prefab.GetDefaultInstance().Transform;
|
||||
instance.Name = prefab.GetDefaultInstance().Name;
|
||||
}
|
||||
|
||||
// Call backend
|
||||
var failed = PrefabManager.Internal_ApplyAll(FlaxEngine.Object.GetUnmanagedPtr(instance));
|
||||
instance.LocalTransform = originalTransform;
|
||||
instance.Name = originalName;
|
||||
if (failed)
|
||||
throw new Exception("Failed to apply the prefab. See log to learn more.");
|
||||
|
||||
|
||||
@@ -306,19 +306,21 @@ namespace FlaxEditor.Modules
|
||||
public override void OnPlayEnd()
|
||||
{
|
||||
var gameWin = Editor.Windows.GameWin;
|
||||
|
||||
switch (gameWin.FocusOnPlayOption)
|
||||
if (gameWin != null)
|
||||
{
|
||||
case Options.InterfaceOptions.PlayModeFocus.None: break;
|
||||
case Options.InterfaceOptions.PlayModeFocus.GameWindow: break;
|
||||
case Options.InterfaceOptions.PlayModeFocus.GameWindowThenRestore:
|
||||
if (_previousWindow != null && !_previousWindow.IsDisposing)
|
||||
switch (gameWin.FocusOnPlayOption)
|
||||
{
|
||||
if (!Editor.Windows.GameWin.ParentDockPanel.ContainsTab(_previousWindow))
|
||||
break;
|
||||
_previousWindow.Focus();
|
||||
case Options.InterfaceOptions.PlayModeFocus.None: break;
|
||||
case Options.InterfaceOptions.PlayModeFocus.GameWindow: break;
|
||||
case Options.InterfaceOptions.PlayModeFocus.GameWindowThenRestore:
|
||||
if (_previousWindow != null && !_previousWindow.IsDisposing)
|
||||
{
|
||||
if (!Editor.Windows.GameWin.ParentDockPanel.ContainsTab(_previousWindow))
|
||||
break;
|
||||
_previousWindow.Focus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Editor.UI.UncheckPauseButton();
|
||||
|
||||
@@ -628,19 +628,19 @@ namespace FlaxEditor.Modules
|
||||
MenuWindow = MainMenu.AddButton("Window");
|
||||
cm = MenuWindow.ContextMenu;
|
||||
cm.VisibleChanged += OnMenuWindowVisibleChanged;
|
||||
cm.AddButton("Content", Editor.Windows.ContentWin.FocusOrShow);
|
||||
cm.AddButton("Scene", Editor.Windows.SceneWin.FocusOrShow);
|
||||
cm.AddButton("Toolbox", Editor.Windows.ToolboxWin.FocusOrShow);
|
||||
cm.AddButton("Properties", Editor.Windows.PropertiesWin.FocusOrShow);
|
||||
cm.AddButton("Game", Editor.Windows.GameWin.FocusOrShow);
|
||||
cm.AddButton("Editor", Editor.Windows.EditWin.FocusOrShow);
|
||||
cm.AddButton("Debug Log", Editor.Windows.DebugLogWin.FocusOrShow);
|
||||
cm.AddButton("Output Log", Editor.Windows.OutputLogWin.FocusOrShow);
|
||||
cm.AddButton("Graphics Quality", Editor.Windows.GraphicsQualityWin.FocusOrShow);
|
||||
cm.AddButton("Game Cooker", Editor.Windows.GameCookerWin.FocusOrShow);
|
||||
cm.AddButton("Content", inputOptions.ContentWindow,Editor.Windows.ContentWin.FocusOrShow);
|
||||
cm.AddButton("Scene", inputOptions.SceneWindow, Editor.Windows.SceneWin.FocusOrShow);
|
||||
cm.AddButton("Toolbox", inputOptions.ToolboxWindow, Editor.Windows.ToolboxWin.FocusOrShow);
|
||||
cm.AddButton("Properties", inputOptions.PropertiesWindow, Editor.Windows.PropertiesWin.FocusOrShow);
|
||||
cm.AddButton("Game", inputOptions.GameWindow, Editor.Windows.GameWin.FocusOrShow);
|
||||
cm.AddButton("Editor", inputOptions.EditorWindow, Editor.Windows.EditWin.FocusOrShow);
|
||||
cm.AddButton("Debug Log", inputOptions.DebugLogWindow, Editor.Windows.DebugLogWin.FocusOrShow);
|
||||
cm.AddButton("Output Log", inputOptions.OutputLogWindow, Editor.Windows.OutputLogWin.FocusOrShow);
|
||||
cm.AddButton("Graphics Quality", inputOptions.GraphicsQualityWindow, Editor.Windows.GraphicsQualityWin.FocusOrShow);
|
||||
cm.AddButton("Game Cooker", inputOptions.GameCookerWindow, Editor.Windows.GameCookerWin.FocusOrShow);
|
||||
cm.AddButton("Profiler", inputOptions.ProfilerWindow, Editor.Windows.ProfilerWin.FocusOrShow);
|
||||
cm.AddButton("Content Search", Editor.ContentFinding.ShowSearch);
|
||||
cm.AddButton("Visual Script Debugger", Editor.Windows.VisualScriptDebuggerWin.FocusOrShow);
|
||||
cm.AddButton("Content Search", inputOptions.ContentSearchWindow, Editor.ContentFinding.ShowSearch);
|
||||
cm.AddButton("Visual Script Debugger", inputOptions.VisualScriptDebuggerWindow, Editor.Windows.VisualScriptDebuggerWin.FocusOrShow);
|
||||
cm.AddSeparator();
|
||||
cm.AddButton("Save window layout", Editor.Windows.SaveLayout);
|
||||
_menuWindowApplyWindowLayout = cm.AddChildMenu("Window layouts");
|
||||
|
||||
@@ -33,6 +33,25 @@ namespace FlaxEditor.Options
|
||||
OpenPrefab,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shortcut availability in play mode.
|
||||
/// </summary>
|
||||
public enum PlayModeShortcutAvailability
|
||||
{
|
||||
/// <summary>
|
||||
/// None of the window shortcuts will be available in play mode.
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// Only the profiler window shortcut will be available in play mode.
|
||||
/// </summary>
|
||||
ProfilerOnly,
|
||||
/// <summary>
|
||||
/// All window shortcuts will be available in play mode.
|
||||
/// </summary>
|
||||
All,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Input editor options data container.
|
||||
/// </summary>
|
||||
@@ -40,6 +59,16 @@ namespace FlaxEditor.Options
|
||||
[HideInEditor]
|
||||
public sealed class InputOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value based on the current settings that indicates wether window shortcuts will be avaliable during play mode.
|
||||
/// </summary>
|
||||
public static bool WindowShortcutsAvaliable => !Editor.IsPlayMode || Editor.Instance.Options.Options.Input.PlayModeWindowShortcutAvaliability == PlayModeShortcutAvailability.All;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value based on the current settings that indicates wether the profiler window shortcut will be avaliable during play mode.
|
||||
/// </summary>
|
||||
public static bool ProfilerShortcutAvaliable => WindowShortcutsAvaliable || Editor.Instance.Options.Options.Input.PlayModeWindowShortcutAvaliability == PlayModeShortcutAvailability.ProfilerOnly;
|
||||
|
||||
#region Common
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Ctrl+S")]
|
||||
@@ -230,9 +259,9 @@ namespace FlaxEditor.Options
|
||||
|
||||
#region Profiler
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha7")]
|
||||
[EditorDisplay("Profiler", "Open Profiler Window"), EditorOrder(630)]
|
||||
public InputBinding ProfilerWindow = new InputBinding(KeyboardKeys.None);
|
||||
public InputBinding ProfilerWindow = new InputBinding(KeyboardKeys.Alpha7, KeyboardKeys.Control);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Profiler", "Start/Stop Profiler"), EditorOrder(631)]
|
||||
@@ -356,24 +385,267 @@ namespace FlaxEditor.Options
|
||||
|
||||
#endregion
|
||||
|
||||
#region Debug Views
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Alt+Alpha4")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2000)]
|
||||
public InputBinding Default = new InputBinding(KeyboardKeys.Alpha4, KeyboardKeys.Alt);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Alt+Alpha3")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2010)]
|
||||
public InputBinding Unlit = new InputBinding(KeyboardKeys.Alpha3, KeyboardKeys.Alt);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2020)]
|
||||
public InputBinding NoPostFX = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Alt+Alpha2")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2030)]
|
||||
public InputBinding Wireframe = new InputBinding(KeyboardKeys.Alpha2, KeyboardKeys.Alt);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Alt+Alpha5")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2040)]
|
||||
public InputBinding LightBuffer = new InputBinding(KeyboardKeys.Alpha5, KeyboardKeys.Alt);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2050)]
|
||||
public InputBinding ReflectionsBuffer = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2060)]
|
||||
public InputBinding DepthBuffer = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2070)]
|
||||
public InputBinding MotionVectors = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2080)]
|
||||
public InputBinding LightmapUVDensity = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2090)]
|
||||
public InputBinding VertexColors = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Alt+Alpha1")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2100)]
|
||||
public InputBinding PhysicsColliders = new InputBinding(KeyboardKeys.Alpha1, KeyboardKeys.Alt);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2110)]
|
||||
public InputBinding LODPreview = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2120)]
|
||||
public InputBinding MaterialComplexity = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2130)]
|
||||
public InputBinding QuadOverdraw = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2140)]
|
||||
public InputBinding GloablSDF = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2150)]
|
||||
public InputBinding GlobalSurfaceAtlas = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Debug Views"), EditorOrder(2160)]
|
||||
public InputBinding GlobalIllumination = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
#endregion
|
||||
|
||||
#region View Flags
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3000)]
|
||||
public InputBinding AntiAliasing = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3010)]
|
||||
public InputBinding Shadows = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha7")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3020)]
|
||||
public InputBinding EditorSprites = new InputBinding(KeyboardKeys.Alpha7, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3030)]
|
||||
public InputBinding Reflections = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3040)]
|
||||
public InputBinding ScreenSpaceReflections = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3050)]
|
||||
public InputBinding AmbientOcclusion = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha6")]
|
||||
[EditorDisplay("View Flags", "Global Illumination"), EditorOrder(3060)]
|
||||
public InputBinding GlobalIlluminationViewFlag = new InputBinding(KeyboardKeys.Alpha6, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3070)]
|
||||
public InputBinding DirectionalLights = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3080)]
|
||||
public InputBinding PointLights = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3090)]
|
||||
public InputBinding SpotLights = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3100)]
|
||||
public InputBinding SkyLights = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3110)]
|
||||
public InputBinding Sky = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3120)]
|
||||
public InputBinding Fog = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3130)]
|
||||
public InputBinding SpecularLight = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3140)]
|
||||
public InputBinding Decals = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha3")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3150)]
|
||||
public InputBinding CustomPostProcess = new InputBinding(KeyboardKeys.Alpha3, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3160)]
|
||||
public InputBinding Bloom = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3170)]
|
||||
public InputBinding ToneMapping = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha2")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3180)]
|
||||
public InputBinding EyeAdaptation = new InputBinding(KeyboardKeys.Alpha2, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3190)]
|
||||
public InputBinding CameraArtifacts = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3200)]
|
||||
public InputBinding LensFlares = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3210)]
|
||||
public InputBinding DepthOfField = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3220)]
|
||||
public InputBinding MotionBlur = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3230)]
|
||||
public InputBinding ContactShadows = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha1")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3240)]
|
||||
public InputBinding PhysicsDebug = new InputBinding(KeyboardKeys.Alpha1, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha5")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3250)]
|
||||
public InputBinding LightsDebug = new InputBinding(KeyboardKeys.Alpha5, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Alpha4")]
|
||||
[EditorDisplay("View Flags"), EditorOrder(3260)]
|
||||
public InputBinding DebugDraw = new InputBinding(KeyboardKeys.Alpha4, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Interface
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Ctrl+W")]
|
||||
[EditorDisplay("Interface"), EditorOrder(2000)]
|
||||
[EditorDisplay("Interface"), EditorOrder(3500)]
|
||||
public InputBinding CloseTab = new InputBinding(KeyboardKeys.W, KeyboardKeys.Control);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Ctrl+Tab")]
|
||||
[EditorDisplay("Interface"), EditorOrder(2010)]
|
||||
[EditorDisplay("Interface"), EditorOrder(3510)]
|
||||
public InputBinding NextTab = new InputBinding(KeyboardKeys.Tab, KeyboardKeys.Control);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Shift+Ctrl+Tab")]
|
||||
[EditorDisplay("Interface"), EditorOrder(2020)]
|
||||
[EditorDisplay("Interface"), EditorOrder(3520)]
|
||||
public InputBinding PreviousTab = new InputBinding(KeyboardKeys.Tab, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(SceneNodeDoubleClick.Expand)]
|
||||
[EditorDisplay("Interface"), EditorOrder(2030)]
|
||||
[EditorDisplay("Interface"), EditorOrder(3530)]
|
||||
public SceneNodeDoubleClick DoubleClickSceneNode = SceneNodeDoubleClick.Expand;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Windows
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating what window shortcuts will be available during play mode.
|
||||
/// </summary>
|
||||
[DefaultValue(PlayModeShortcutAvailability.ProfilerOnly)]
|
||||
[EditorDisplay("Windows", "Avaliability in Play Mode"), EditorOrder(3000)]
|
||||
public PlayModeShortcutAvailability PlayModeWindowShortcutAvaliability { get; set; } = PlayModeShortcutAvailability.ProfilerOnly;
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha5")]
|
||||
[EditorDisplay("Windows"), EditorOrder(3010)]
|
||||
public InputBinding ContentWindow = new InputBinding(KeyboardKeys.Alpha5, KeyboardKeys.Control);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha4")]
|
||||
[EditorDisplay("Windows"), EditorOrder(3020)]
|
||||
public InputBinding SceneWindow = new InputBinding(KeyboardKeys.Alpha4, KeyboardKeys.Control);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Windows"), EditorOrder(3030)]
|
||||
public InputBinding ToolboxWindow = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha3")]
|
||||
[EditorDisplay("Windows"), EditorOrder(3040)]
|
||||
public InputBinding PropertiesWindow = new InputBinding(KeyboardKeys.Alpha3, KeyboardKeys.Control);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha2")]
|
||||
[EditorDisplay("Windows"), EditorOrder(3050)]
|
||||
public InputBinding GameWindow = new InputBinding(KeyboardKeys.Alpha2, KeyboardKeys.Control);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Ctrl+Alpha1")]
|
||||
[EditorDisplay("Windows"), EditorOrder(3060)]
|
||||
public InputBinding EditorWindow = new InputBinding(KeyboardKeys.Alpha1, KeyboardKeys.Control);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Windows"), EditorOrder(3070)]
|
||||
public InputBinding DebugLogWindow = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Windows"), EditorOrder(3080)]
|
||||
public InputBinding OutputLogWindow = new InputBinding(KeyboardKeys.C, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Windows"), EditorOrder(3090)]
|
||||
public InputBinding GraphicsQualityWindow = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Windows"), EditorOrder(4000)]
|
||||
public InputBinding GameCookerWindow = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Windows"), EditorOrder(4010)]
|
||||
public InputBinding ContentSearchWindow = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "None")]
|
||||
[EditorDisplay("Windows"), EditorOrder(4020)]
|
||||
public InputBinding VisualScriptDebuggerWindow = new InputBinding(KeyboardKeys.None);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ namespace FlaxEditor.SceneGraph
|
||||
return false;
|
||||
}
|
||||
|
||||
BoundingSphere sphere = new BoundingSphere(Transform.Translation, 7.0f);
|
||||
var center = _actor.Transform.Translation;
|
||||
ViewportIconsRenderer.GetBounds(ref center, ref ray.Ray.Position, out var sphere);
|
||||
return CollisionsHelper.RayIntersectsSphere(ref ray.Ray, ref sphere, out distance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
_infoLabel = playbackGroup.Label(string.Empty).Label;
|
||||
_infoLabel.AutoHeight = true;
|
||||
|
||||
var grid = playbackGroup.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = Button.DefaultHeight;
|
||||
|
||||
@@ -320,7 +320,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
if (noFilter && actor != null)
|
||||
{
|
||||
// Pick the correct id when inside a prefab window.
|
||||
var id = actor.HasPrefabLink && actor.Scene.Scene == null ? actor.PrefabObjectID : actor.ID;
|
||||
var id = actor.HasPrefabLink && actor.Scene == null ? actor.PrefabObjectID : actor.ID;
|
||||
isExpanded = Editor.Instance.ProjectCache.IsExpandedActor(ref id);
|
||||
}
|
||||
|
||||
|
||||
@@ -534,7 +534,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
Title = "Tangent Vector",
|
||||
Description = "World space tangent vector",
|
||||
Flags = NodeFlags.MaterialGraph,
|
||||
Size = new Float2(160, 40),
|
||||
Size = new Float2(160, 30),
|
||||
Elements = new[]
|
||||
{
|
||||
NodeElementArchetype.Factory.Output(0, "Tangent", typeof(Float3), 0),
|
||||
@@ -546,7 +546,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
Title = "Bitangent Vector",
|
||||
Description = "World space bitangent vector",
|
||||
Flags = NodeFlags.MaterialGraph,
|
||||
Size = new Float2(160, 40),
|
||||
Size = new Float2(160, 30),
|
||||
Elements = new[]
|
||||
{
|
||||
NodeElementArchetype.Factory.Output(0, "Bitangent", typeof(Float3), 0),
|
||||
@@ -558,7 +558,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
Title = "Camera Position",
|
||||
Description = "World space camera location",
|
||||
Flags = NodeFlags.MaterialGraph,
|
||||
Size = new Float2(160, 40),
|
||||
Size = new Float2(160, 30),
|
||||
Elements = new[]
|
||||
{
|
||||
NodeElementArchetype.Factory.Output(0, "XYZ", typeof(Float3), 0),
|
||||
@@ -570,7 +570,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
Title = "Per Instance Random",
|
||||
Description = "Per object instance random value (normalized to range 0-1)",
|
||||
Flags = NodeFlags.MaterialGraph,
|
||||
Size = new Float2(200, 40),
|
||||
Size = new Float2(200, 30),
|
||||
Elements = new[]
|
||||
{
|
||||
NodeElementArchetype.Factory.Output(0, "", typeof(float), 0),
|
||||
@@ -607,14 +607,14 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
Title = "Terrain Layer Weight",
|
||||
Description = "Terrain layer weight mask used for blending terrain layers",
|
||||
Flags = NodeFlags.MaterialGraph,
|
||||
Size = new Float2(220, 30),
|
||||
Size = new Float2(200, 30),
|
||||
DefaultValues = new object[]
|
||||
{
|
||||
0,
|
||||
},
|
||||
Elements = new[]
|
||||
{
|
||||
NodeElementArchetype.Factory.ComboBox(0, 0, 70.0f, 0, LayersAndTagsSettings.GetCurrentTerrainLayers()),
|
||||
NodeElementArchetype.Factory.ComboBox(0, 0, 175.0f, 0, LayersAndTagsSettings.GetCurrentTerrainLayers()),
|
||||
NodeElementArchetype.Factory.Output(0, "", typeof(float), 0),
|
||||
}
|
||||
},
|
||||
|
||||
@@ -409,7 +409,7 @@ namespace FlaxEditor.Surface
|
||||
/// <summary>
|
||||
/// Called after adding the control to the surface after paste.
|
||||
/// </summary>
|
||||
/// <param name="idsMapping">The nodes IDs mapping (original node ID to pasted node ID). Can be sued to update internal node's data after paste operation from the original data.</param>
|
||||
/// <param name="idsMapping">The nodes IDs mapping (original node ID to pasted node ID). Can be used to update internal node's data after paste operation from the original data.</param>
|
||||
public virtual void OnPasted(System.Collections.Generic.Dictionary<uint, uint> idsMapping)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -369,24 +369,14 @@ namespace FlaxEditor.Surface
|
||||
}
|
||||
|
||||
// Change scale (disable scaling during selecting nodes)
|
||||
if (IsMouseOver && !_leftMouseDown && !IsPrimaryMenuOpened)
|
||||
if (IsMouseOver && !_leftMouseDown && !_rightMouseDown && !IsPrimaryMenuOpened)
|
||||
{
|
||||
var nextViewScale = ViewScale + delta * 0.1f;
|
||||
|
||||
if (delta > 0 && !_rightMouseDown)
|
||||
{
|
||||
// Scale towards mouse when zooming in
|
||||
var nextCenterPosition = ViewPosition + location / ViewScale;
|
||||
ViewScale = nextViewScale;
|
||||
ViewPosition = nextCenterPosition - (location / ViewScale);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scale while keeping center position when zooming out or when dragging view
|
||||
var viewCenter = ViewCenterPosition;
|
||||
ViewScale = nextViewScale;
|
||||
ViewCenterPosition = viewCenter;
|
||||
}
|
||||
// Scale towards/ away from mouse when zooming in/ out
|
||||
var nextCenterPosition = ViewPosition + location / ViewScale;
|
||||
ViewScale = nextViewScale;
|
||||
ViewPosition = nextCenterPosition - (location / ViewScale);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -498,11 +488,9 @@ namespace FlaxEditor.Surface
|
||||
// Check if user is pressing control
|
||||
if (Root.GetKey(KeyboardKeys.Control))
|
||||
{
|
||||
// Add to selection
|
||||
if (!controlUnderMouse.IsSelected)
|
||||
{
|
||||
AddToSelection(controlUnderMouse);
|
||||
}
|
||||
// Add/remove from selection
|
||||
controlUnderMouse.IsSelected = !controlUnderMouse.IsSelected;
|
||||
SelectionChanged?.Invoke();
|
||||
}
|
||||
// Check if node isn't selected
|
||||
else if (!controlUnderMouse.IsSelected)
|
||||
|
||||
@@ -20,5 +20,7 @@ namespace FlaxEditor.Utilities
|
||||
#else
|
||||
public const string ShowInExplorer = "Show in explorer";
|
||||
#endif
|
||||
|
||||
public const float UIMargin = 3.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,13 +415,10 @@ namespace FlaxEditor.Utilities
|
||||
/// </summary>
|
||||
/// <param name="parentLayout">The parent layout element.</param>
|
||||
/// <param name="path">The import path.</param>
|
||||
/// <param name="useInitialSpacing">Whether to use an initial layout space of 5 for separation.</param>
|
||||
public static void CreateImportPathUI(CustomEditors.LayoutElementsContainer parentLayout, string path, bool useInitialSpacing = true)
|
||||
public static void CreateImportPathUI(CustomEditors.LayoutElementsContainer parentLayout, string path)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
if (useInitialSpacing)
|
||||
parentLayout.Space(0);
|
||||
var textBox = parentLayout.TextBox().TextBox;
|
||||
textBox.TooltipText = "Source asset path. Can be relative or absolute to the project. Path is not editable here.";
|
||||
textBox.IsReadOnly = true;
|
||||
@@ -1503,7 +1500,6 @@ namespace FlaxEditor.Utilities
|
||||
inputActions.Add(options => options.BuildNav, Editor.Instance.BuildNavMesh);
|
||||
inputActions.Add(options => options.BuildSDF, Editor.Instance.BuildAllMeshesSDF);
|
||||
inputActions.Add(options => options.TakeScreenshot, Editor.Instance.Windows.TakeScreenshot);
|
||||
inputActions.Add(options => options.ProfilerWindow, () => Editor.Instance.Windows.ProfilerWin.FocusOrShow());
|
||||
#if USE_PROFILER
|
||||
inputActions.Add(options => options.ProfilerStartStop, () =>
|
||||
{
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
#include "Engine/Level/Actors/SpotLight.h"
|
||||
#include "Engine/Video/VideoPlayer.h"
|
||||
|
||||
#define ICON_RADIUS 7.0f
|
||||
|
||||
enum class IconTypes
|
||||
{
|
||||
PointLight,
|
||||
@@ -67,6 +65,16 @@ public:
|
||||
};
|
||||
|
||||
ViewportIconsRendererService ViewportIconsRendererServiceInstance;
|
||||
float ViewportIconsRenderer::Scale = 1.0f;
|
||||
|
||||
void ViewportIconsRenderer::GetBounds(const Vector3& position, const Vector3& viewPosition, BoundingSphere& bounds)
|
||||
{
|
||||
constexpr Real minSize = 7.0;
|
||||
constexpr Real maxSize = 30.0;
|
||||
Real scale = Math::Square(Vector3::Distance(position, viewPosition) / 1000.0f);
|
||||
Real radius = minSize + Math::Min<Real>(scale, 1.0f) * (maxSize - minSize);
|
||||
bounds = BoundingSphere(position, radius * Scale);
|
||||
}
|
||||
|
||||
void ViewportIconsRenderer::DrawIcons(RenderContext& renderContext, Actor* actor)
|
||||
{
|
||||
@@ -134,7 +142,8 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Scene
|
||||
AssetReference<Texture> texture;
|
||||
for (Actor* icon : icons)
|
||||
{
|
||||
BoundingSphere sphere(icon->GetPosition() - renderContext.View.Origin, ICON_RADIUS);
|
||||
BoundingSphere sphere;
|
||||
ViewportIconsRenderer::GetBounds(icon->GetPosition() - renderContext.View.Origin, renderContext.View.Position, sphere);
|
||||
if (!frustum.Intersects(sphere))
|
||||
continue;
|
||||
IconTypes iconType;
|
||||
@@ -174,7 +183,7 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Scene
|
||||
if (draw.Buffer)
|
||||
{
|
||||
// Create world matrix
|
||||
Matrix::Scaling(ICON_RADIUS * 2.0f, m2);
|
||||
Matrix::Scaling((float)sphere.Radius * 2.0f, m2);
|
||||
Matrix::RotationY(PI, world);
|
||||
Matrix::Multiply(m2, world, m1);
|
||||
Matrix::Billboard(sphere.Center, view.Position, Vector3::Up, view.Direction, m2);
|
||||
@@ -194,14 +203,15 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Actor
|
||||
auto& view = renderContext.View;
|
||||
const BoundingFrustum frustum = view.Frustum;
|
||||
Matrix m1, m2, world;
|
||||
BoundingSphere sphere(actor->GetPosition() - renderContext.View.Origin, ICON_RADIUS);
|
||||
BoundingSphere sphere;
|
||||
ViewportIconsRenderer::GetBounds(actor->GetPosition() - renderContext.View.Origin, renderContext.View.Position, sphere);
|
||||
IconTypes iconType;
|
||||
AssetReference<Texture> texture;
|
||||
|
||||
if (frustum.Intersects(sphere) && ActorTypeToIconType.TryGet(actor->GetTypeHandle(), iconType))
|
||||
{
|
||||
// Create world matrix
|
||||
Matrix::Scaling(ICON_RADIUS * 2.0f, m2);
|
||||
Matrix::Scaling((float)sphere.Radius * 2.0f, m2);
|
||||
Matrix::RotationY(PI, world);
|
||||
Matrix::Multiply(m2, world, m1);
|
||||
Matrix::Billboard(sphere.Center, view.Position, Vector3::Up, view.Direction, m2);
|
||||
|
||||
@@ -17,6 +17,19 @@ API_CLASS(Static, Namespace="FlaxEditor") class FLAXENGINE_API ViewportIconsRend
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(ViewportIconsRenderer);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Global scale of the icons.
|
||||
/// </summary>
|
||||
API_FIELD() static float Scale;
|
||||
|
||||
/// <summary>
|
||||
/// Draws the icons for the actors in the given scene (or actor tree).
|
||||
/// </summary>
|
||||
/// <param name="position">The icon position.</param>
|
||||
/// <param name="viewPosition">The viewer position.</param>
|
||||
/// <param name="bounds">The computed bounds for the icon.</param>
|
||||
API_FUNCTION() static void GetBounds(API_PARAM(Ref) const Vector3& position, API_PARAM(Ref) const Vector3& viewPosition, API_PARAM(Out) BoundingSphere& bounds);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the icons for the actors in the given scene (or actor tree).
|
||||
/// </summary>
|
||||
|
||||
@@ -910,7 +910,7 @@ namespace FlaxEditor.Viewport
|
||||
for (int i = 0; i < ViewFlagsValues.Length; i++)
|
||||
{
|
||||
var v = ViewFlagsValues[i];
|
||||
var button = viewFlags.AddButton(v.Name);
|
||||
var button = viewFlags.AddButton(v.Name, v.InputBinding.ToString());
|
||||
button.CloseMenuOnClick = false;
|
||||
button.Tag = v.Mode;
|
||||
}
|
||||
@@ -959,7 +959,7 @@ namespace FlaxEditor.Viewport
|
||||
}
|
||||
else
|
||||
{
|
||||
var button = debugView.AddButton(v.Name);
|
||||
var button = debugView.AddButton(v.Name, v.InputBinding.ToString());
|
||||
button.CloseMenuOnClick = false;
|
||||
button.Tag = v.Mode;
|
||||
}
|
||||
@@ -1002,19 +1002,79 @@ namespace FlaxEditor.Viewport
|
||||
ViewWidgetButtonMenu.VisibleChanged += control => resolutionValue.Value = ResolutionScale;
|
||||
}
|
||||
|
||||
// Icons Scale
|
||||
{
|
||||
var icons = ViewWidgetButtonMenu.AddButton("Icons");
|
||||
icons.CloseMenuOnClick = false;
|
||||
var iconsValue = new FloatValueBox(ViewportIconsRenderer.Scale, xLocationForExtras, 2, 70.0f, 0.01f, 100.0f, 0.001f)
|
||||
{
|
||||
Parent = icons
|
||||
};
|
||||
iconsValue.ValueChanged += () => ViewportIconsRenderer.Scale = iconsValue.Value;
|
||||
ViewWidgetButtonMenu.VisibleChanged += control => iconsValue.Value = ViewportIconsRenderer.Scale;
|
||||
}
|
||||
|
||||
#endregion View mode widget
|
||||
}
|
||||
|
||||
// Viewpoints
|
||||
InputActions.Add(options => options.ViewpointTop, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Top").Orientation)));
|
||||
InputActions.Add(options => options.ViewpointBottom, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Bottom").Orientation)));
|
||||
InputActions.Add(options => options.ViewpointFront, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Front").Orientation)));
|
||||
InputActions.Add(options => options.ViewpointBack, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Back").Orientation)));
|
||||
InputActions.Add(options => options.ViewpointRight, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Right").Orientation)));
|
||||
InputActions.Add(options => options.ViewpointLeft, () => OrientViewport(Quaternion.Euler(CameraViewpointValues.First(vp => vp.Name == "Left").Orientation)));
|
||||
// Editor camera
|
||||
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.ToggleOrthographic, () => OnOrthographicModeToggled(null));
|
||||
// Debug views
|
||||
InputActions.Add(options => options.Default, () => Task.ViewMode = ViewMode.Default);
|
||||
InputActions.Add(options => options.Unlit, () => Task.ViewMode = ViewMode.Unlit);
|
||||
InputActions.Add(options => options.NoPostFX, () => Task.ViewMode = ViewMode.NoPostFx);
|
||||
InputActions.Add(options => options.Wireframe, () => Task.ViewMode = ViewMode.Wireframe);
|
||||
InputActions.Add(options => options.LightBuffer, () => Task.ViewMode = ViewMode.LightBuffer);
|
||||
InputActions.Add(options => options.ReflectionsBuffer, () => Task.ViewMode = ViewMode.Reflections);
|
||||
InputActions.Add(options => options.DepthBuffer, () => Task.ViewMode = ViewMode.Depth);
|
||||
InputActions.Add(options => options.MotionVectors, () => Task.ViewMode = ViewMode.MotionVectors);
|
||||
InputActions.Add(options => options.LightmapUVDensity, () => Task.ViewMode = ViewMode.LightmapUVsDensity);
|
||||
InputActions.Add(options => options.VertexColors, () => Task.ViewMode = ViewMode.VertexColors);
|
||||
InputActions.Add(options => options.PhysicsColliders, () => Task.ViewMode = ViewMode.PhysicsColliders);
|
||||
InputActions.Add(options => options.LODPreview, () => Task.ViewMode = ViewMode.LODPreview);
|
||||
InputActions.Add(options => options.MaterialComplexity, () => Task.ViewMode = ViewMode.MaterialComplexity);
|
||||
InputActions.Add(options => options.QuadOverdraw, () => Task.ViewMode = ViewMode.QuadOverdraw);
|
||||
InputActions.Add(options => options.GloablSDF, () => Task.ViewMode = ViewMode.GlobalSDF);
|
||||
InputActions.Add(options => options.GlobalSurfaceAtlas, () => Task.ViewMode = ViewMode.GlobalSurfaceAtlas);
|
||||
InputActions.Add(options => options.GlobalIllumination, () => Task.ViewMode = ViewMode.GlobalIllumination);
|
||||
// View flags
|
||||
InputActions.Add(options => options.AntiAliasing, () => Task.ViewFlags ^= ViewFlags.AntiAliasing);
|
||||
InputActions.Add(options => options.Shadows, () => Task.ViewFlags ^= ViewFlags.Shadows);
|
||||
InputActions.Add(options => options.EditorSprites, () => Task.ViewFlags ^= ViewFlags.EditorSprites);
|
||||
InputActions.Add(options => options.Reflections, () => Task.ViewFlags ^= ViewFlags.Reflections);
|
||||
InputActions.Add(options => options.ScreenSpaceReflections, () => Task.ViewFlags ^= ViewFlags.SSR);
|
||||
InputActions.Add(options => options.AmbientOcclusion, () => Task.ViewFlags ^= ViewFlags.AO);
|
||||
InputActions.Add(options => options.GlobalIllumination, () => Task.ViewFlags ^= ViewFlags.GI);
|
||||
InputActions.Add(options => options.DirectionalLights, () => Task.ViewFlags ^= ViewFlags.DirectionalLights);
|
||||
InputActions.Add(options => options.PointLights, () => Task.ViewFlags ^= ViewFlags.PointLights);
|
||||
InputActions.Add(options => options.SpotLights, () => Task.ViewFlags ^= ViewFlags.SpotLights);
|
||||
InputActions.Add(options => options.SkyLights, () => Task.ViewFlags ^= ViewFlags.SkyLights);
|
||||
InputActions.Add(options => options.Sky, () => Task.ViewFlags ^= ViewFlags.Sky);
|
||||
InputActions.Add(options => options.Fog, () => Task.ViewFlags ^= ViewFlags.Fog);
|
||||
InputActions.Add(options => options.SpecularLight, () => Task.ViewFlags ^= ViewFlags.SpecularLight);
|
||||
InputActions.Add(options => options.Decals, () => Task.ViewFlags ^= ViewFlags.Decals);
|
||||
InputActions.Add(options => options.CustomPostProcess, () => Task.ViewFlags ^= ViewFlags.CustomPostProcess);
|
||||
InputActions.Add(options => options.Bloom, () => Task.ViewFlags ^= ViewFlags.Bloom);
|
||||
InputActions.Add(options => options.ToneMapping, () => Task.ViewFlags ^= ViewFlags.ToneMapping);
|
||||
InputActions.Add(options => options.EyeAdaptation, () => Task.ViewFlags ^= ViewFlags.EyeAdaptation);
|
||||
InputActions.Add(options => options.CameraArtifacts, () => Task.ViewFlags ^= ViewFlags.CameraArtifacts);
|
||||
InputActions.Add(options => options.LensFlares, () => Task.ViewFlags ^= ViewFlags.LensFlares);
|
||||
InputActions.Add(options => options.DepthOfField, () => Task.ViewFlags ^= ViewFlags.DepthOfField);
|
||||
InputActions.Add(options => options.MotionBlur, () => Task.ViewFlags ^= ViewFlags.MotionBlur);
|
||||
InputActions.Add(options => options.ContactShadows, () => Task.ViewFlags ^= ViewFlags.ContactShadows);
|
||||
InputActions.Add(options => options.PhysicsDebug, () => Task.ViewFlags ^= ViewFlags.PhysicsDebug);
|
||||
InputActions.Add(options => options.LightsDebug, () => Task.ViewFlags ^= ViewFlags.LightsDebug);
|
||||
InputActions.Add(options => options.DebugDraw, () => Task.ViewFlags ^= ViewFlags.DebugDraw);
|
||||
|
||||
// Link for task event
|
||||
task.Begin += OnRenderBegin;
|
||||
@@ -1933,8 +1993,17 @@ namespace FlaxEditor.Viewport
|
||||
{
|
||||
public readonly string Name;
|
||||
public readonly ViewMode Mode;
|
||||
public readonly InputBinding InputBinding;
|
||||
public readonly ViewModeOptions[] Options;
|
||||
|
||||
public ViewModeOptions(ViewMode mode, string name, InputBinding inputBinding)
|
||||
{
|
||||
Mode = mode;
|
||||
Name = name;
|
||||
InputBinding = inputBinding;
|
||||
Options = null;
|
||||
}
|
||||
|
||||
public ViewModeOptions(ViewMode mode, string name)
|
||||
{
|
||||
Mode = mode;
|
||||
@@ -1952,13 +2021,13 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
private static readonly ViewModeOptions[] ViewModeValues =
|
||||
{
|
||||
new ViewModeOptions(ViewMode.Default, "Default"),
|
||||
new ViewModeOptions(ViewMode.Unlit, "Unlit"),
|
||||
new ViewModeOptions(ViewMode.NoPostFx, "No PostFx"),
|
||||
new ViewModeOptions(ViewMode.Wireframe, "Wireframe"),
|
||||
new ViewModeOptions(ViewMode.LightBuffer, "Light Buffer"),
|
||||
new ViewModeOptions(ViewMode.Reflections, "Reflections Buffer"),
|
||||
new ViewModeOptions(ViewMode.Depth, "Depth Buffer"),
|
||||
new ViewModeOptions(ViewMode.Default, "Default", Editor.Instance.Options.Options.Input.Default),
|
||||
new ViewModeOptions(ViewMode.Unlit, "Unlit", Editor.Instance.Options.Options.Input.Unlit),
|
||||
new ViewModeOptions(ViewMode.NoPostFx, "No PostFx", Editor.Instance.Options.Options.Input.NoPostFX),
|
||||
new ViewModeOptions(ViewMode.Wireframe, "Wireframe", Editor.Instance.Options.Options.Input.Wireframe),
|
||||
new ViewModeOptions(ViewMode.LightBuffer, "Light Buffer", Editor.Instance.Options.Options.Input.LightBuffer),
|
||||
new ViewModeOptions(ViewMode.Reflections, "Reflections Buffer", Editor.Instance.Options.Options.Input.ReflectionsBuffer),
|
||||
new ViewModeOptions(ViewMode.Depth, "Depth Buffer", Editor.Instance.Options.Options.Input.DepthBuffer),
|
||||
new ViewModeOptions("GBuffer", new[]
|
||||
{
|
||||
new ViewModeOptions(ViewMode.Diffuse, "Diffuse"),
|
||||
@@ -1972,16 +2041,16 @@ namespace FlaxEditor.Viewport
|
||||
new ViewModeOptions(ViewMode.Normals, "Normals"),
|
||||
new ViewModeOptions(ViewMode.AmbientOcclusion, "Ambient Occlusion"),
|
||||
}),
|
||||
new ViewModeOptions(ViewMode.MotionVectors, "Motion Vectors"),
|
||||
new ViewModeOptions(ViewMode.LightmapUVsDensity, "Lightmap UVs Density"),
|
||||
new ViewModeOptions(ViewMode.VertexColors, "Vertex Colors"),
|
||||
new ViewModeOptions(ViewMode.PhysicsColliders, "Physics Colliders"),
|
||||
new ViewModeOptions(ViewMode.LODPreview, "LOD Preview"),
|
||||
new ViewModeOptions(ViewMode.MaterialComplexity, "Material Complexity"),
|
||||
new ViewModeOptions(ViewMode.QuadOverdraw, "Quad Overdraw"),
|
||||
new ViewModeOptions(ViewMode.GlobalSDF, "Global SDF"),
|
||||
new ViewModeOptions(ViewMode.GlobalSurfaceAtlas, "Global Surface Atlas"),
|
||||
new ViewModeOptions(ViewMode.GlobalIllumination, "Global Illumination"),
|
||||
new ViewModeOptions(ViewMode.MotionVectors, "Motion Vectors", Editor.Instance.Options.Options.Input.MotionVectors),
|
||||
new ViewModeOptions(ViewMode.LightmapUVsDensity, "Lightmap UVs Density", Editor.Instance.Options.Options.Input.LightmapUVDensity),
|
||||
new ViewModeOptions(ViewMode.VertexColors, "Vertex Colors", Editor.Instance.Options.Options.Input.VertexColors),
|
||||
new ViewModeOptions(ViewMode.PhysicsColliders, "Physics Colliders", Editor.Instance.Options.Options.Input.PhysicsColliders),
|
||||
new ViewModeOptions(ViewMode.LODPreview, "LOD Preview", Editor.Instance.Options.Options.Input.LODPreview),
|
||||
new ViewModeOptions(ViewMode.MaterialComplexity, "Material Complexity", Editor.Instance.Options.Options.Input.MaterialComplexity),
|
||||
new ViewModeOptions(ViewMode.QuadOverdraw, "Quad Overdraw", Editor.Instance.Options.Options.Input.QuadOverdraw),
|
||||
new ViewModeOptions(ViewMode.GlobalSDF, "Global SDF", Editor.Instance.Options.Options.Input.GloablSDF),
|
||||
new ViewModeOptions(ViewMode.GlobalSurfaceAtlas, "Global Surface Atlas", Editor.Instance.Options.Options.Input.GlobalSurfaceAtlas),
|
||||
new ViewModeOptions(ViewMode.GlobalIllumination, "Global Illumination", Editor.Instance.Options.Options.Input.GlobalIllumination),
|
||||
};
|
||||
|
||||
private void WidgetViewModeShowHideClicked(ContextMenuButton button)
|
||||
@@ -2014,43 +2083,45 @@ namespace FlaxEditor.Viewport
|
||||
{
|
||||
public readonly ViewFlags Mode;
|
||||
public readonly string Name;
|
||||
public readonly InputBinding InputBinding;
|
||||
|
||||
public ViewFlagOptions(ViewFlags mode, string name)
|
||||
public ViewFlagOptions(ViewFlags mode, string name, InputBinding inputBinding)
|
||||
{
|
||||
Mode = mode;
|
||||
Name = name;
|
||||
InputBinding = inputBinding;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly ViewFlagOptions[] ViewFlagsValues =
|
||||
{
|
||||
new ViewFlagOptions(ViewFlags.AntiAliasing, "Anti Aliasing"),
|
||||
new ViewFlagOptions(ViewFlags.Shadows, "Shadows"),
|
||||
new ViewFlagOptions(ViewFlags.EditorSprites, "Editor Sprites"),
|
||||
new ViewFlagOptions(ViewFlags.Reflections, "Reflections"),
|
||||
new ViewFlagOptions(ViewFlags.SSR, "Screen Space Reflections"),
|
||||
new ViewFlagOptions(ViewFlags.AO, "Ambient Occlusion"),
|
||||
new ViewFlagOptions(ViewFlags.GI, "Global Illumination"),
|
||||
new ViewFlagOptions(ViewFlags.DirectionalLights, "Directional Lights"),
|
||||
new ViewFlagOptions(ViewFlags.PointLights, "Point Lights"),
|
||||
new ViewFlagOptions(ViewFlags.SpotLights, "Spot Lights"),
|
||||
new ViewFlagOptions(ViewFlags.SkyLights, "Sky Lights"),
|
||||
new ViewFlagOptions(ViewFlags.Sky, "Sky"),
|
||||
new ViewFlagOptions(ViewFlags.Fog, "Fog"),
|
||||
new ViewFlagOptions(ViewFlags.SpecularLight, "Specular Light"),
|
||||
new ViewFlagOptions(ViewFlags.Decals, "Decals"),
|
||||
new ViewFlagOptions(ViewFlags.CustomPostProcess, "Custom Post Process"),
|
||||
new ViewFlagOptions(ViewFlags.Bloom, "Bloom"),
|
||||
new ViewFlagOptions(ViewFlags.ToneMapping, "Tone Mapping"),
|
||||
new ViewFlagOptions(ViewFlags.EyeAdaptation, "Eye Adaptation"),
|
||||
new ViewFlagOptions(ViewFlags.CameraArtifacts, "Camera Artifacts"),
|
||||
new ViewFlagOptions(ViewFlags.LensFlares, "Lens Flares"),
|
||||
new ViewFlagOptions(ViewFlags.DepthOfField, "Depth of Field"),
|
||||
new ViewFlagOptions(ViewFlags.MotionBlur, "Motion Blur"),
|
||||
new ViewFlagOptions(ViewFlags.ContactShadows, "Contact Shadows"),
|
||||
new ViewFlagOptions(ViewFlags.PhysicsDebug, "Physics Debug"),
|
||||
new ViewFlagOptions(ViewFlags.LightsDebug, "Lights Debug"),
|
||||
new ViewFlagOptions(ViewFlags.DebugDraw, "Debug Draw"),
|
||||
new ViewFlagOptions(ViewFlags.AntiAliasing, "Anti Aliasing", Editor.Instance.Options.Options.Input.AntiAliasing),
|
||||
new ViewFlagOptions(ViewFlags.Shadows, "Shadows", Editor.Instance.Options.Options.Input.Shadows),
|
||||
new ViewFlagOptions(ViewFlags.EditorSprites, "Editor Sprites", Editor.Instance.Options.Options.Input.EditorSprites),
|
||||
new ViewFlagOptions(ViewFlags.Reflections, "Reflections", Editor.Instance.Options.Options.Input.Reflections),
|
||||
new ViewFlagOptions(ViewFlags.SSR, "Screen Space Reflections", Editor.Instance.Options.Options.Input.ScreenSpaceReflections),
|
||||
new ViewFlagOptions(ViewFlags.AO, "Ambient Occlusion", Editor.Instance.Options.Options.Input.AmbientOcclusion),
|
||||
new ViewFlagOptions(ViewFlags.GI, "Global Illumination", Editor.Instance.Options.Options.Input.GlobalIlluminationViewFlag),
|
||||
new ViewFlagOptions(ViewFlags.DirectionalLights, "Directional Lights", Editor.Instance.Options.Options.Input.DirectionalLights),
|
||||
new ViewFlagOptions(ViewFlags.PointLights, "Point Lights", Editor.Instance.Options.Options.Input.PointLights),
|
||||
new ViewFlagOptions(ViewFlags.SpotLights, "Spot Lights", Editor.Instance.Options.Options.Input.SpotLights),
|
||||
new ViewFlagOptions(ViewFlags.SkyLights, "Sky Lights", Editor.Instance.Options.Options.Input.SkyLights),
|
||||
new ViewFlagOptions(ViewFlags.Sky, "Sky", Editor.Instance.Options.Options.Input.Sky),
|
||||
new ViewFlagOptions(ViewFlags.Fog, "Fog", Editor.Instance.Options.Options.Input.Fog),
|
||||
new ViewFlagOptions(ViewFlags.SpecularLight, "Specular Light", Editor.Instance.Options.Options.Input.SpecularLight),
|
||||
new ViewFlagOptions(ViewFlags.Decals, "Decals", Editor.Instance.Options.Options.Input.Decals),
|
||||
new ViewFlagOptions(ViewFlags.CustomPostProcess, "Custom Post Process", Editor.Instance.Options.Options.Input.CustomPostProcess),
|
||||
new ViewFlagOptions(ViewFlags.Bloom, "Bloom", Editor.Instance.Options.Options.Input.Bloom),
|
||||
new ViewFlagOptions(ViewFlags.ToneMapping, "Tone Mapping", Editor.Instance.Options.Options.Input.ToneMapping),
|
||||
new ViewFlagOptions(ViewFlags.EyeAdaptation, "Eye Adaptation", Editor.Instance.Options.Options.Input.EyeAdaptation),
|
||||
new ViewFlagOptions(ViewFlags.CameraArtifacts, "Camera Artifacts", Editor.Instance.Options.Options.Input.CameraArtifacts),
|
||||
new ViewFlagOptions(ViewFlags.LensFlares, "Lens Flares", Editor.Instance.Options.Options.Input.LensFlares),
|
||||
new ViewFlagOptions(ViewFlags.DepthOfField, "Depth of Field", Editor.Instance.Options.Options.Input.DepthOfField),
|
||||
new ViewFlagOptions(ViewFlags.MotionBlur, "Motion Blur", Editor.Instance.Options.Options.Input.MotionBlur),
|
||||
new ViewFlagOptions(ViewFlags.ContactShadows, "Contact Shadows", Editor.Instance.Options.Options.Input.ContactShadows),
|
||||
new ViewFlagOptions(ViewFlags.PhysicsDebug, "Physics Debug", Editor.Instance.Options.Options.Input.PhysicsDebug),
|
||||
new ViewFlagOptions(ViewFlags.LightsDebug, "Lights Debug", Editor.Instance.Options.Options.Input.LightsDebug),
|
||||
new ViewFlagOptions(ViewFlags.DebugDraw, "Debug Draw", Editor.Instance.Options.Options.Input.DebugDraw),
|
||||
};
|
||||
|
||||
private void WidgetViewFlagsShowHide(Control cm)
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
{
|
||||
UseTimeScale = false,
|
||||
UpdateWhenOffscreen = true,
|
||||
BoundsScale = 100.0f,
|
||||
BoundsScale = 1.0f,
|
||||
UpdateMode = AnimatedModel.AnimationUpdateMode.Manual,
|
||||
};
|
||||
Task.AddCustomActor(_previewModel);
|
||||
|
||||
@@ -635,5 +635,11 @@ namespace FlaxEditor.Windows.Assets
|
||||
public void Select(List<SceneGraphNode> nodes)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public List<SceneGraphNode> Selection => new List<SceneGraphNode>();
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool LockSelection { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,29 +76,29 @@ namespace FlaxEditor.Windows.Assets
|
||||
|
||||
// Transparency
|
||||
|
||||
[EditorOrder(200), DefaultValue(MaterialTransparentLightingMode.Surface), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Transparent material lighting mode.")]
|
||||
[EditorOrder(200), DefaultValue(MaterialTransparentLightingMode.Surface), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Transparent material lighting mode.")]
|
||||
public MaterialTransparentLightingMode TransparentLightingMode;
|
||||
|
||||
[EditorOrder(205), DefaultValue(true), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables reflections when rendering material.")]
|
||||
[EditorOrder(205), DefaultValue(true), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables reflections when rendering material.")]
|
||||
public bool EnableReflections;
|
||||
|
||||
[VisibleIf(nameof(EnableReflections))]
|
||||
[EditorOrder(210), DefaultValue(false), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables Screen Space Reflections when rendering material.")]
|
||||
[EditorOrder(210), DefaultValue(false), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables Screen Space Reflections when rendering material.")]
|
||||
public bool EnableScreenSpaceReflections;
|
||||
|
||||
[EditorOrder(210), DefaultValue(true), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables fog effects when rendering material.")]
|
||||
[EditorOrder(210), DefaultValue(true), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables fog effects when rendering material.")]
|
||||
public bool EnableFog;
|
||||
|
||||
[EditorOrder(220), DefaultValue(true), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables distortion effect when rendering.")]
|
||||
[EditorOrder(220), DefaultValue(true), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables distortion effect when rendering.")]
|
||||
public bool EnableDistortion;
|
||||
|
||||
[EditorOrder(224), DefaultValue(false), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables sampling Global Illumination in material (eg. light probes or volumetric lightmap).")]
|
||||
[EditorOrder(224), DefaultValue(false), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables sampling Global Illumination in material (eg. light probes or volumetric lightmap).")]
|
||||
public bool EnableGlobalIllumination;
|
||||
|
||||
[EditorOrder(225), DefaultValue(false), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Enables refraction offset based on the difference between the per-pixel normal and the per-vertex normal. Useful for large water-like surfaces.")]
|
||||
[EditorOrder(225), DefaultValue(false), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Enables refraction offset based on the difference between the per-pixel normal and the per-vertex normal. Useful for large water-like surfaces.")]
|
||||
public bool PixelNormalOffsetRefraction;
|
||||
|
||||
[EditorOrder(230), DefaultValue(0.12f), VisibleIf(nameof(IsStandard)), EditorDisplay("Transparency"), Tooltip("Controls opacity values clipping point."), Limit(0.0f, 1.0f, 0.01f)]
|
||||
[EditorOrder(230), DefaultValue(0.12f), VisibleIf(nameof(IsForward)), EditorDisplay("Transparency"), Tooltip("Controls opacity values clipping point."), Limit(0.0f, 1.0f, 0.01f)]
|
||||
public float OpacityThreshold;
|
||||
|
||||
// Tessellation
|
||||
@@ -146,6 +146,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
private bool IsDecal => Domain == MaterialDomain.Decal;
|
||||
private bool IsGUI => Domain == MaterialDomain.GUI;
|
||||
private bool IsStandard => Domain == MaterialDomain.Surface || Domain == MaterialDomain.Terrain || Domain == MaterialDomain.Particle || Domain == MaterialDomain.Deformable;
|
||||
private bool IsForward => Domain == MaterialDomain.Particle || ((Domain == MaterialDomain.Deformable || Domain == MaterialDomain.Surface) && BlendMode != MaterialBlendMode.Opaque);
|
||||
private bool IsStandardOrGUI => IsStandard || IsGUI;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -254,7 +254,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
if (lodIndex >= countLODs - loadedLODs)
|
||||
{
|
||||
var mesh = lod.GetMesh(0);
|
||||
vertexLayout = mesh.VertexLayout;
|
||||
if (mesh != null)
|
||||
vertexLayout = mesh.VertexLayout;
|
||||
if (vertexLayout != null && vertexLayout.Elements.Length != 0)
|
||||
break;
|
||||
vertexLayout = null;
|
||||
@@ -759,7 +760,6 @@ namespace FlaxEditor.Windows.Assets
|
||||
var importSettingsField = typeof(ImportPropertiesProxyBase).GetField(nameof(ImportSettings), BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var importSettingsValues = new ValueContainer(new ScriptMemberInfo(importSettingsField)) { proxy.ImportSettings };
|
||||
importSettingsGroup.Object(importSettingsValues);
|
||||
importSettingsGroup.Space(3);
|
||||
|
||||
// Creates the import path UI
|
||||
var group = layout.Group("Import Path");
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
lodIndex.IntValue.Value = sdf.Texture != null ? sdf.LOD : 6;
|
||||
_sdfModelLodIndex = lodIndex;
|
||||
|
||||
var buttons = group.CustomContainer<UniformGridPanel>();
|
||||
var buttons = layout.UniformGrid();
|
||||
var gridControl = buttons.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = Button.DefaultHeight;
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
public PrefabTree()
|
||||
: base(true)
|
||||
{
|
||||
DrawRootTreeLine = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
/// <param name="before">The selection before the change.</param>
|
||||
public void OnSelectionChanged(SceneGraphNode[] before)
|
||||
{
|
||||
if (LockSelectedObjects)
|
||||
if (LockSelection)
|
||||
return;
|
||||
|
||||
Undo.AddAction(new SelectionChangeAction(before, Selection.ToArray(), OnSelectionUndo));
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
/// <summary>
|
||||
/// Indication of if the prefab window selection is locked on specific objects.
|
||||
/// </summary>
|
||||
public bool LockSelectedObjects
|
||||
public bool LockSelection
|
||||
{
|
||||
get => _lockSelection;
|
||||
set
|
||||
|
||||
@@ -413,7 +413,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
var group = layout.Group("Functions");
|
||||
var nodes = window.VisjectSurface.Nodes;
|
||||
|
||||
var grid = group.CustomContainer<UniformGridPanel>();
|
||||
var grid = layout.UniformGrid();
|
||||
var gridControl = grid.CustomControl;
|
||||
gridControl.ClipChildren = false;
|
||||
gridControl.Height = Button.DefaultHeight;
|
||||
|
||||
@@ -204,6 +204,7 @@ namespace FlaxEditor.Windows
|
||||
// Content structure tree
|
||||
_tree = new Tree(false)
|
||||
{
|
||||
DrawRootTreeLine = false,
|
||||
Parent = _contentTreePanel,
|
||||
};
|
||||
_tree.SelectedChanged += OnTreeSelectionChanged;
|
||||
|
||||
@@ -140,6 +140,7 @@ namespace FlaxEditor.Windows
|
||||
: base(editor, true, ScrollBars.None)
|
||||
{
|
||||
Title = "Editor";
|
||||
Icon = editor.Icons.Grid32;
|
||||
|
||||
// Create viewport
|
||||
Viewport = new MainEditorGizmoViewport(editor)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.Options;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using DockWindow = FlaxEditor.GUI.Docking.DockWindow;
|
||||
@@ -49,6 +50,73 @@ namespace FlaxEditor.Windows
|
||||
}
|
||||
});
|
||||
|
||||
// Set up editor window shortcuts
|
||||
InputActions.Add(options => options.ContentWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.ContentWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.SceneWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.SceneWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.ToolboxWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.ToolboxWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.PropertiesWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.PropertiesWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.GameWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.GameWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.EditorWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.EditWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.DebugLogWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.DebugLogWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.OutputLogWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.OutputLogWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.GraphicsQualityWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.GraphicsQualityWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.GameCookerWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.GameCookerWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.ProfilerWindow, () =>
|
||||
{
|
||||
if (InputOptions.ProfilerShortcutAvaliable)
|
||||
Editor.Windows.ProfilerWin.FocusOrShow();
|
||||
});
|
||||
InputActions.Add(options => options.ContentFinder, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.ContentFinding.ShowSearch();
|
||||
});
|
||||
InputActions.Add(options => options.VisualScriptDebuggerWindow, () =>
|
||||
{
|
||||
if (InputOptions.WindowShortcutsAvaliable)
|
||||
Editor.Windows.VisualScriptDebuggerWin.FocusOrShow();
|
||||
});
|
||||
|
||||
// Register
|
||||
Editor.Windows.OnWindowAdd(this);
|
||||
}
|
||||
|
||||
@@ -305,6 +305,7 @@ namespace FlaxEditor.Windows
|
||||
: base(editor, true, ScrollBars.None)
|
||||
{
|
||||
Title = "Game";
|
||||
Icon = editor.Icons.Play64;
|
||||
AutoFocus = true;
|
||||
|
||||
var task = MainRenderTask.Instance;
|
||||
|
||||
@@ -482,6 +482,7 @@ namespace FlaxEditor.Windows
|
||||
: base(editor, true, ScrollBars.None)
|
||||
{
|
||||
Title = "Output Log";
|
||||
Icon = editor.Icons.Info64;
|
||||
ClipChildren = false;
|
||||
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
||||
|
||||
@@ -983,6 +984,10 @@ namespace FlaxEditor.Windows
|
||||
var cachedOutputTargetViewOffset = _output.TargetViewOffset;
|
||||
var isBottomScroll = _vScroll.Value >= _vScroll.Maximum - (_scrollSize * 2) || wasEmpty;
|
||||
_output.Text = _textBuffer.ToString();
|
||||
if (_hScroll.Maximum <= 0.0)
|
||||
cachedOutputTargetViewOffset.X = 0;
|
||||
if (_vScroll.Maximum <= 0.0)
|
||||
cachedOutputTargetViewOffset.Y = 0;
|
||||
_output.TargetViewOffset = cachedOutputTargetViewOffset;
|
||||
_textBufferCount = _entries.Count;
|
||||
if (!_vScroll.IsThumbClicked)
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace FlaxEditor.Windows
|
||||
/// <summary>
|
||||
/// Indication of if the properties window is locked on specific objects.
|
||||
/// </summary>
|
||||
public bool LockObjects
|
||||
public bool LockSelection
|
||||
{
|
||||
get => _lockObjects;
|
||||
set
|
||||
@@ -66,6 +66,7 @@ namespace FlaxEditor.Windows
|
||||
: base(editor, true, ScrollBars.Vertical)
|
||||
{
|
||||
Title = "Properties";
|
||||
Icon = editor.Icons.Build64;
|
||||
AutoFocus = true;
|
||||
|
||||
Presenter = new CustomEditorPresenter(editor.Undo, null, this);
|
||||
@@ -86,9 +87,9 @@ namespace FlaxEditor.Windows
|
||||
if (Level.ScenesCount > 1)
|
||||
return;
|
||||
_actorScrollValues.Clear();
|
||||
if (LockObjects)
|
||||
if (LockSelection)
|
||||
{
|
||||
LockObjects = false;
|
||||
LockSelection = false;
|
||||
Presenter.Deselect();
|
||||
}
|
||||
}
|
||||
@@ -121,7 +122,7 @@ namespace FlaxEditor.Windows
|
||||
|
||||
private void OnSelectionChanged()
|
||||
{
|
||||
if (LockObjects)
|
||||
if (LockSelection)
|
||||
return;
|
||||
|
||||
// Update selected objects
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace FlaxEditor.Windows
|
||||
: base(editor, true, ScrollBars.None)
|
||||
{
|
||||
Title = "Scene";
|
||||
Icon = editor.Icons.Globe32;
|
||||
|
||||
// Scene searching query input box
|
||||
var headerPanel = new ContainerControl
|
||||
@@ -84,6 +85,7 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
Margin = new Margin(0.0f, 0.0f, -16.0f, _sceneTreePanel.ScrollBarsSize), // Hide root node
|
||||
IsScrollable = true,
|
||||
DrawRootTreeLine = false,
|
||||
};
|
||||
_tree.AddChild(root.TreeNode);
|
||||
_tree.SelectedChanged += Tree_OnSelectedChanged;
|
||||
|
||||
@@ -455,6 +455,7 @@ namespace FlaxEditor.Windows
|
||||
: base(editor, true, ScrollBars.None)
|
||||
{
|
||||
Title = "Toolbox";
|
||||
Icon = editor.Icons.Toolbox96;
|
||||
|
||||
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
#include "Engine/Engine/Globals.h"
|
||||
|
||||
ThreadLocal<bool> ContentDeprecatedFlags;
|
||||
|
||||
void ContentDeprecated::Mark()
|
||||
@@ -593,7 +595,7 @@ bool Asset::onLoad(LoadAssetTask* task)
|
||||
|
||||
#if USE_EDITOR
|
||||
// Auto-save deprecated assets to get rid of data in an old format
|
||||
if (isDeprecated && isLoaded)
|
||||
if (isDeprecated && isLoaded && !IsVirtual() && !GetPath().StartsWith(StringUtils::GetDirectoryName(Globals::TemporaryFolder)))
|
||||
{
|
||||
PROFILE_CPU_NAMED("Asset.Save");
|
||||
LOG(Info, "Resaving asset '{}' that uses deprecated data format", ToString());
|
||||
|
||||
@@ -326,7 +326,7 @@ bool Model::Init(const Span<int32>& meshesCountPerLod)
|
||||
lod.Link(this, lodIndex);
|
||||
lod.ScreenSize = 1.0f;
|
||||
const int32 meshesCount = meshesCountPerLod[lodIndex];
|
||||
if (meshesCount <= 0 || meshesCount > MODEL_MAX_MESHES)
|
||||
if (meshesCount < 0 || meshesCount > MODEL_MAX_MESHES)
|
||||
return true;
|
||||
|
||||
lod.Meshes.Resize(meshesCount);
|
||||
@@ -365,7 +365,7 @@ bool Model::LoadHeader(ReadStream& stream, byte& headerVersion)
|
||||
// Meshes
|
||||
uint16 meshesCount;
|
||||
stream.ReadUint16(&meshesCount);
|
||||
if (meshesCount == 0 || meshesCount > MODEL_MAX_MESHES)
|
||||
if (meshesCount > MODEL_MAX_MESHES)
|
||||
return true;
|
||||
ASSERT(lodIndex == 0 || LODs[0].Meshes.Count() >= meshesCount);
|
||||
lod.Meshes.Resize(meshesCount, false);
|
||||
|
||||
@@ -669,6 +669,8 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
|
||||
Array<GPUVertexLayout::Elements, FixedAllocation<MODEL_MAX_VB>> vbElements;
|
||||
const bool useSeparatePositions = !isSkinned;
|
||||
const bool useSeparateColors = !isSkinned;
|
||||
PixelFormat positionsFormat = modelData.PositionFormat == ModelData::PositionFormats::Float32 ? PixelFormat::R32G32B32_Float : PixelFormat::R16G16B16A16_Float;
|
||||
PixelFormat texCoordsFormat = modelData.TexCoordFormat == ModelData::TexCoordFormats::Float16 ? PixelFormat::R16G16_Float : PixelFormat::R8G8_UNorm;
|
||||
PixelFormat blendIndicesFormat = PixelFormat::R8G8B8A8_UInt;
|
||||
PixelFormat blendWeightsFormat = PixelFormat::R8G8B8A8_UNorm;
|
||||
for (const Int4& indices : mesh.BlendIndices)
|
||||
@@ -681,14 +683,13 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
|
||||
}
|
||||
{
|
||||
byte vbIndex = 0;
|
||||
// TODO: add option to quantize vertex positions (eg. 16-bit)
|
||||
// TODO: add option to quantize vertex attributes (eg. 8-bit blend weights, 8-bit texcoords)
|
||||
|
||||
// Position
|
||||
if (useSeparatePositions)
|
||||
{
|
||||
auto& vb0 = vbElements.AddOne();
|
||||
vb0.Add({ VertexElement::Types::Position, vbIndex, 0, 0, PixelFormat::R32G32B32_Float });
|
||||
vb0.Add({ VertexElement::Types::Position, vbIndex, 0, 0, positionsFormat });
|
||||
vbIndex++;
|
||||
}
|
||||
|
||||
@@ -696,13 +697,13 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
|
||||
{
|
||||
auto& vb = vbElements.AddOne();
|
||||
if (!useSeparatePositions)
|
||||
vb.Add({ VertexElement::Types::Position, vbIndex, 0, 0, PixelFormat::R32G32B32_Float });
|
||||
vb.Add({ VertexElement::Types::Position, vbIndex, 0, 0, positionsFormat });
|
||||
for (int32 channelIdx = 0; channelIdx < mesh.UVs.Count(); channelIdx++)
|
||||
{
|
||||
auto& channel = mesh.UVs.Get()[channelIdx];
|
||||
if (channel.HasItems())
|
||||
{
|
||||
vb.Add({ (VertexElement::Types)((int32)VertexElement::Types::TexCoord0 + channelIdx), vbIndex, 0, 0, PixelFormat::R16G16_Float });
|
||||
vb.Add({ (VertexElement::Types)((int32)VertexElement::Types::TexCoord0 + channelIdx), vbIndex, 0, 0, texCoordsFormat });
|
||||
}
|
||||
}
|
||||
vb.Add({ VertexElement::Types::Normal, vbIndex, 0, 0, PixelFormat::R10G10B10A2_UNorm });
|
||||
@@ -737,7 +738,7 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
|
||||
// Write vertex buffers
|
||||
for (int32 vbIndex = 0; vbIndex < vbCount; vbIndex++)
|
||||
{
|
||||
if (useSeparatePositions && vbIndex == 0)
|
||||
if (useSeparatePositions && vbIndex == 0 && positionsFormat == PixelFormat::R32G32B32_Float)
|
||||
{
|
||||
// Fast path for vertex positions of static models using the first buffer
|
||||
stream.WriteBytes(mesh.Positions.Get(), sizeof(Float3) * vertices);
|
||||
@@ -755,7 +756,15 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
|
||||
case VertexElement::Types::Position:
|
||||
{
|
||||
const Float3 position = mesh.Positions.Get()[vertex];
|
||||
stream.Write(position);
|
||||
if (positionsFormat == PixelFormat::R16G16B16A16_Float)
|
||||
{
|
||||
const Half4 positionEnc(Float4(position, 0.0f));
|
||||
stream.Write(positionEnc);
|
||||
}
|
||||
else //if (positionsFormat == PixelFormat::R32G32B32_Float)
|
||||
{
|
||||
stream.Write(position);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VertexElement::Types::Color:
|
||||
@@ -821,8 +830,16 @@ bool ModelBase::SaveLOD(WriteStream& stream, const ModelData& modelData, int32 l
|
||||
{
|
||||
const int32 channelIdx = (int32)element.Type - (int32)VertexElement::Types::TexCoord0;
|
||||
const Float2 uv = mesh.UVs.Get()[channelIdx].Get()[vertex];
|
||||
const Half2 uvEnc(uv);
|
||||
stream.Write(uvEnc);
|
||||
if (texCoordsFormat == PixelFormat::R8G8_UNorm)
|
||||
{
|
||||
stream.Write((uint8)Math::Clamp<int32>((int32)(uv.X * 255), 0, 255));
|
||||
stream.Write((uint8)Math::Clamp<int32>((int32)(uv.Y * 255), 0, 255));
|
||||
}
|
||||
else //if (texCoordsFormat == PixelFormat::R16G16_Float)
|
||||
{
|
||||
const Half2 uvEnc(uv);
|
||||
stream.Write(uvEnc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -478,7 +478,7 @@ bool SkinnedModel::Init(const Span<int32>& meshesCountPerLod)
|
||||
lod._lodIndex = lodIndex;
|
||||
lod.ScreenSize = 1.0f;
|
||||
const int32 meshesCount = meshesCountPerLod[lodIndex];
|
||||
if (meshesCount <= 0 || meshesCount > MODEL_MAX_MESHES)
|
||||
if (meshesCount < 0 || meshesCount > MODEL_MAX_MESHES)
|
||||
return true;
|
||||
|
||||
lod.Meshes.Resize(meshesCount);
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
#include "Engine/Level/Types.h"
|
||||
#include "Engine/Debug/Exceptions/JsonParseException.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Core/Collections/HashSet.h"
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#endif
|
||||
#include <ThirdParty/rapidjson/document.h>
|
||||
|
||||
bool JsonStorageProxy::IsValidExtension(const StringView& extension)
|
||||
@@ -56,27 +60,31 @@ bool JsonStorageProxy::GetAssetInfo(const StringView& path, Guid& resultId, Stri
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
void ChangeIds(rapidjson_flax::Value& obj, rapidjson_flax::Document& document, const StringAnsi& srcId, const StringAnsi& dstId)
|
||||
void FindObjectIds(const rapidjson_flax::Value& obj, const rapidjson_flax::Document& document, HashSet<Guid>& ids, const char* parentName = nullptr)
|
||||
{
|
||||
if (obj.IsObject())
|
||||
{
|
||||
for (rapidjson_flax::Value::MemberIterator i = obj.MemberBegin(); i != obj.MemberEnd(); ++i)
|
||||
for (rapidjson_flax::Value::ConstMemberIterator i = obj.MemberBegin(); i != obj.MemberEnd(); ++i)
|
||||
{
|
||||
ChangeIds(i->value, document, srcId, dstId);
|
||||
FindObjectIds(i->value, document, ids, i->name.GetString());
|
||||
}
|
||||
}
|
||||
else if (obj.IsArray())
|
||||
{
|
||||
for (rapidjson::SizeType i = 0; i < obj.Size(); i++)
|
||||
{
|
||||
ChangeIds(obj[i], document, srcId, dstId);
|
||||
FindObjectIds(obj[i], document, ids, parentName);
|
||||
}
|
||||
}
|
||||
else if (obj.IsString())
|
||||
else if (obj.IsString() && obj.GetStringLength() == 32)
|
||||
{
|
||||
if (StringUtils::Compare(srcId.Get(), obj.GetString()) == 0)
|
||||
if (parentName && StringUtils::Compare(parentName, "ID") == 0)
|
||||
{
|
||||
obj.SetString(dstId.Get(), document.GetAllocator());
|
||||
auto value = JsonTools::GetGuid(obj);
|
||||
if (value.IsValid())
|
||||
{
|
||||
ids.Add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,9 +99,7 @@ bool JsonStorageProxy::ChangeId(const StringView& path, const Guid& newId)
|
||||
// Load file
|
||||
Array<byte> fileData;
|
||||
if (File::ReadAllBytes(path, fileData))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse data
|
||||
rapidjson_flax::Document document;
|
||||
@@ -107,33 +113,35 @@ bool JsonStorageProxy::ChangeId(const StringView& path, const Guid& newId)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try get asset metadata
|
||||
// Get all IDs inside the file
|
||||
HashSet<Guid> ids;
|
||||
FindObjectIds(document, document, ids);
|
||||
|
||||
// Remap into a unique IDs
|
||||
Dictionary<Guid, Guid> remap;
|
||||
remap.EnsureCapacity(ids.Count());
|
||||
for (const auto& id : ids)
|
||||
remap.Add(id.Item, Guid::New());
|
||||
|
||||
// Remap asset ID using the provided value
|
||||
auto idNode = document.FindMember("ID");
|
||||
if (idNode == document.MemberEnd())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
remap[JsonTools::GetGuid(idNode->value)] = newId;
|
||||
|
||||
// Change IDs
|
||||
auto oldIdStr = idNode->value.GetString();
|
||||
auto newIdStr = newId.ToString(Guid::FormatType::N).ToStringAnsi();
|
||||
ChangeIds(document, document, oldIdStr, newIdStr);
|
||||
// Change IDs of asset and objects inside asset
|
||||
JsonTools::ChangeIds(document, remap);
|
||||
|
||||
// Save to file
|
||||
rapidjson_flax::StringBuffer buffer;
|
||||
PrettyJsonWriter writer(buffer);
|
||||
document.Accept(writer.GetWriter());
|
||||
if (File::WriteAllBytes(path, (byte*)buffer.GetString(), (int32)buffer.GetSize()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
#else
|
||||
|
||||
LOG(Warning, "Editing cooked content is invalid.");
|
||||
return true;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -673,23 +673,23 @@ namespace FlaxEngine
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Vector4" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <param name="other">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="Vector4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref BoundingBox value)
|
||||
public bool Equals(ref BoundingBox other)
|
||||
{
|
||||
return Minimum == value.Minimum && Maximum == value.Maximum;
|
||||
return Minimum == other.Minimum && Maximum == other.Maximum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Vector4" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <param name="other">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="Vector4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(BoundingBox value)
|
||||
public bool Equals(BoundingBox other)
|
||||
{
|
||||
return Equals(ref value);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -487,23 +487,23 @@ namespace FlaxEngine
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Vector4" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <param name="other">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="Vector4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref BoundingSphere value)
|
||||
public bool Equals(ref BoundingSphere other)
|
||||
{
|
||||
return (Center == value.Center) && (Radius == value.Radius);
|
||||
return Center == other.Center && Radius == other.Radius;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Vector4" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <param name="other">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="Vector4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(BoundingSphere value)
|
||||
public bool Equals(BoundingSphere other)
|
||||
{
|
||||
return Equals(ref value);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -197,12 +197,9 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object other)
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (!(other is Color))
|
||||
return false;
|
||||
var color = (Color)other;
|
||||
return Equals(ref color);
|
||||
return value is Color other && Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -213,7 +210,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Color other)
|
||||
{
|
||||
return Mathf.NearEqual(other.R, R) && Mathf.NearEqual(other.G, G) && Mathf.NearEqual(other.B, B) && Mathf.NearEqual(other.A, A);
|
||||
return R == other.R && G == other.G && B == other.B && A == other.A;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -661,23 +658,23 @@ namespace FlaxEngine
|
||||
/// <summary>
|
||||
/// Compares two colors.
|
||||
/// </summary>
|
||||
/// <param name="lhs">The left.</param>
|
||||
/// <param name="rhs">The right.</param>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>True if colors are equal, otherwise false.</returns>
|
||||
public static bool operator ==(Color lhs, Color rhs)
|
||||
public static bool operator ==(Color left, Color right)
|
||||
{
|
||||
return lhs.Equals(ref rhs);
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two colors.
|
||||
/// </summary>
|
||||
/// <param name="lhs">The left.</param>
|
||||
/// <param name="rhs">The right.</param>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>True if colors are not equal, otherwise false.</returns>
|
||||
public static bool operator !=(Color lhs, Color rhs)
|
||||
public static bool operator !=(Color left, Color right)
|
||||
{
|
||||
return !lhs.Equals(ref rhs);
|
||||
return !left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1464,7 +1464,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Double2 left, Double2 right)
|
||||
{
|
||||
return Mathd.NearEqual(left.X, right.X) && Mathd.NearEqual(left.Y, right.Y);
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1476,7 +1476,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(Double2 left, Double2 right)
|
||||
{
|
||||
return !Mathd.NearEqual(left.X, right.X) || !Mathd.NearEqual(left.Y, right.Y);
|
||||
return !left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1582,7 +1582,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Double2 other)
|
||||
{
|
||||
return Mathd.NearEqual(other.X, X) && Mathd.NearEqual(other.Y, Y);
|
||||
return X == other.X && Y == other.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1590,7 +1590,7 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
public static bool Equals(ref Double2 a, ref Double2 b)
|
||||
{
|
||||
return Mathd.NearEqual(a.X, b.X) && Mathd.NearEqual(a.Y, b.Y);
|
||||
return a.Equals(ref b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1601,7 +1601,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Double2 other)
|
||||
{
|
||||
return Mathd.NearEqual(other.X, X) && Mathd.NearEqual(other.Y, Y);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1611,7 +1611,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
return value is Double2 other && Mathd.NearEqual(other.X, X) && Mathd.NearEqual(other.Y, Y);
|
||||
return value is Double2 other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1759,7 +1759,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Double3 left, Double3 right)
|
||||
{
|
||||
return Mathd.NearEqual(left.X, right.X) && Mathd.NearEqual(left.Y, right.Y) && Mathd.NearEqual(left.Z, right.Z);
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1771,7 +1771,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(Double3 left, Double3 right)
|
||||
{
|
||||
return !Mathd.NearEqual(left.X, right.X) || !Mathd.NearEqual(left.Y, right.Y) || !Mathd.NearEqual(left.Z, right.Z);
|
||||
return !left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1880,7 +1880,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Double3 other)
|
||||
{
|
||||
return Mathd.NearEqual(other.X, X) && Mathd.NearEqual(other.Y, Y) && Mathd.NearEqual(other.Z, Z);
|
||||
return X == other.X && Y == other.Y && Z == other.Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1891,7 +1891,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Double3 other)
|
||||
{
|
||||
return Mathd.NearEqual(other.X, X) && Mathd.NearEqual(other.Y, Y) && Mathd.NearEqual(other.Z, Z);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1901,7 +1901,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
return value is Double3 other && Mathd.NearEqual(other.X, X) && Mathd.NearEqual(other.Y, Y) && Mathd.NearEqual(other.Z, Z);
|
||||
return value is Double3 other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1258,7 +1258,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Double4 left, Double4 right)
|
||||
{
|
||||
return Mathd.NearEqual(left.X, right.X) && Mathd.NearEqual(left.Y, right.Y) && Mathd.NearEqual(left.Z, right.Z) && Mathd.NearEqual(left.W, right.W);
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1379,7 +1379,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Double4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(ref Double4 other)
|
||||
{
|
||||
return Mathd.NearEqual(other.X, X) && Mathd.NearEqual(other.Y, Y) && Mathd.NearEqual(other.Z, Z) && Mathd.NearEqual(other.W, W);
|
||||
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1390,7 +1390,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Double4 other)
|
||||
{
|
||||
return Mathd.NearEqual(other.X, X) && Mathd.NearEqual(other.Y, Y) && Mathd.NearEqual(other.Z, Z) && Mathd.NearEqual(other.W, W);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1400,7 +1400,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
return value is Double4 other && Mathd.NearEqual(other.X, X) && Mathd.NearEqual(other.Y, Y) && Mathd.NearEqual(other.Z, Z) && Mathd.NearEqual(other.W, W);
|
||||
return value is Double4 other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1540,7 +1540,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Float2 left, Float2 right)
|
||||
{
|
||||
return Mathf.NearEqual(left.X, right.X) && Mathf.NearEqual(left.Y, right.Y);
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1552,7 +1552,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(Float2 left, Float2 right)
|
||||
{
|
||||
return !Mathf.NearEqual(left.X, right.X) || !Mathf.NearEqual(left.Y, right.Y);
|
||||
return !left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1658,7 +1658,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Float2 other)
|
||||
{
|
||||
return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y);
|
||||
return X == other.X && Y == other.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1666,7 +1666,7 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
public static bool Equals(ref Float2 a, ref Float2 b)
|
||||
{
|
||||
return Mathf.NearEqual(a.X, b.X) && Mathf.NearEqual(a.Y, b.Y);
|
||||
return a.Equals(ref b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1677,7 +1677,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Float2 other)
|
||||
{
|
||||
return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1687,7 +1687,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
return value is Float2 other && Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y);
|
||||
return value is Float2 other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1791,7 +1791,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Float3 left, Float3 right)
|
||||
{
|
||||
return Mathf.NearEqual(left.X, right.X) && Mathf.NearEqual(left.Y, right.Y) && Mathf.NearEqual(left.Z, right.Z);
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1803,7 +1803,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(Float3 left, Float3 right)
|
||||
{
|
||||
return !Mathf.NearEqual(left.X, right.X) || !Mathf.NearEqual(left.Y, right.Y) || !Mathf.NearEqual(left.Z, right.Z);
|
||||
return !left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1912,7 +1912,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Float3 other)
|
||||
{
|
||||
return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z);
|
||||
return X == other.X && Y == other.Y && Z == other.Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1923,7 +1923,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Float3 other)
|
||||
{
|
||||
return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1933,7 +1933,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
return value is Float3 other && Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z);
|
||||
return value is Float3 other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1288,7 +1288,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Float4 left, Float4 right)
|
||||
{
|
||||
return Mathf.NearEqual(left.X, right.X) && Mathf.NearEqual(left.Y, right.Y) && Mathf.NearEqual(left.Z, right.Z) && Mathf.NearEqual(left.W, right.W);
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1419,7 +1419,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Float4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(ref Float4 other)
|
||||
{
|
||||
return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z) && Mathf.NearEqual(other.W, W);
|
||||
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1430,7 +1430,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Float4 other)
|
||||
{
|
||||
return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z) && Mathf.NearEqual(other.W, W);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1440,7 +1440,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
return value is Float4 other && Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z) && Mathf.NearEqual(other.W, W);
|
||||
return value is Float4 other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ bool Matrix::operator==(const Matrix& other) const
|
||||
{
|
||||
for (int32 i = 0; i < 16; i++)
|
||||
{
|
||||
if (Math::NotNearEqual(other.Raw[i], Raw[i]))
|
||||
if (other.Raw[i] != Raw[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -3236,22 +3236,22 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Matrix" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(ref Matrix other)
|
||||
{
|
||||
return Mathf.NearEqual(other.M11, M11) &&
|
||||
Mathf.NearEqual(other.M12, M12) &&
|
||||
Mathf.NearEqual(other.M13, M13) &&
|
||||
Mathf.NearEqual(other.M14, M14) &&
|
||||
Mathf.NearEqual(other.M21, M21) &&
|
||||
Mathf.NearEqual(other.M22, M22) &&
|
||||
Mathf.NearEqual(other.M23, M23) &&
|
||||
Mathf.NearEqual(other.M24, M24) &&
|
||||
Mathf.NearEqual(other.M31, M31) &&
|
||||
Mathf.NearEqual(other.M32, M32) &&
|
||||
Mathf.NearEqual(other.M33, M33) &&
|
||||
Mathf.NearEqual(other.M34, M34) &&
|
||||
Mathf.NearEqual(other.M41, M41) &&
|
||||
Mathf.NearEqual(other.M42, M42) &&
|
||||
Mathf.NearEqual(other.M43, M43) &&
|
||||
Mathf.NearEqual(other.M44, M44);
|
||||
return other.M11 == M11 &&
|
||||
other.M12 == M12 &&
|
||||
other.M13 == M13 &&
|
||||
other.M14 == M14 &&
|
||||
other.M21 == M21 &&
|
||||
other.M22 == M22 &&
|
||||
other.M23 == M23 &&
|
||||
other.M24 == M24 &&
|
||||
other.M31 == M31 &&
|
||||
other.M32 == M32 &&
|
||||
other.M33 == M33 &&
|
||||
other.M34 == M34 &&
|
||||
other.M41 == M41 &&
|
||||
other.M42 == M42 &&
|
||||
other.M43 == M43 &&
|
||||
other.M44 == M44;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -3272,10 +3272,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (!(value is Matrix))
|
||||
return false;
|
||||
var v = (Matrix)value;
|
||||
return Equals(ref v);
|
||||
return value is Matrix other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Matrix2x2"/> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(ref Matrix2x2 other)
|
||||
{
|
||||
return Mathf.NearEqual(other.M11, M11) && Mathf.NearEqual(other.M12, M12) && Mathf.NearEqual(other.M21, M21) && Mathf.NearEqual(other.M22, M22);
|
||||
return M11 == other.M11 && M12 == other.M12 && M21 == other.M21 && M22 == other.M22;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -502,7 +502,7 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
public static bool Equals(ref Matrix2x2 a, ref Matrix2x2 b)
|
||||
{
|
||||
return Mathf.NearEqual(a.M11, b.M11) && Mathf.NearEqual(a.M12, b.M12) && Mathf.NearEqual(a.M21, b.M21) && Mathf.NearEqual(a.M22, b.M22);
|
||||
return a.Equals(ref b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -242,14 +242,13 @@ void Matrix3x3::Decompose(Float3& scale, Quaternion& rotation) const
|
||||
|
||||
bool Matrix3x3::operator==(const Matrix3x3& other) const
|
||||
{
|
||||
return
|
||||
Math::NearEqual(M11, other.M11) &&
|
||||
Math::NearEqual(M12, other.M12) &&
|
||||
Math::NearEqual(M13, other.M13) &&
|
||||
Math::NearEqual(M21, other.M21) &&
|
||||
Math::NearEqual(M22, other.M22) &&
|
||||
Math::NearEqual(M23, other.M23) &&
|
||||
Math::NearEqual(M31, other.M31) &&
|
||||
Math::NearEqual(M32, other.M32) &&
|
||||
Math::NearEqual(M33, other.M33);
|
||||
return M11 == other.M11 &&
|
||||
M12 == other.M12 &&
|
||||
M13 == other.M13 &&
|
||||
M21 == other.M21 &&
|
||||
M22 == other.M22 &&
|
||||
M23 == other.M23 &&
|
||||
M31 == other.M31 &&
|
||||
M32 == other.M32 &&
|
||||
M33 == other.M33;
|
||||
}
|
||||
|
||||
@@ -2125,15 +2125,15 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Matrix3x3"/> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(ref Matrix3x3 other)
|
||||
{
|
||||
return (Mathf.NearEqual(other.M11, M11) &&
|
||||
Mathf.NearEqual(other.M12, M12) &&
|
||||
Mathf.NearEqual(other.M13, M13) &&
|
||||
Mathf.NearEqual(other.M21, M21) &&
|
||||
Mathf.NearEqual(other.M22, M22) &&
|
||||
Mathf.NearEqual(other.M23, M23) &&
|
||||
Mathf.NearEqual(other.M31, M31) &&
|
||||
Mathf.NearEqual(other.M32, M32) &&
|
||||
Mathf.NearEqual(other.M33, M33));
|
||||
return M11 == other.M11 &&
|
||||
M12 == other.M12 &&
|
||||
M13 == other.M13 &&
|
||||
M21 == other.M21 &&
|
||||
M22 == other.M22 &&
|
||||
M23 == other.M23 &&
|
||||
M31 == other.M31 &&
|
||||
M32 == other.M32 &&
|
||||
M33 == other.M33;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2152,17 +2152,7 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
public static bool Equals(ref Matrix3x3 a, ref Matrix3x3 b)
|
||||
{
|
||||
return
|
||||
Mathf.NearEqual(a.M11, b.M11) &&
|
||||
Mathf.NearEqual(a.M12, b.M12) &&
|
||||
Mathf.NearEqual(a.M13, b.M13) &&
|
||||
Mathf.NearEqual(a.M21, b.M21) &&
|
||||
Mathf.NearEqual(a.M22, b.M22) &&
|
||||
Mathf.NearEqual(a.M23, b.M23) &&
|
||||
Mathf.NearEqual(a.M31, b.M31) &&
|
||||
Mathf.NearEqual(a.M32, b.M32) &&
|
||||
Mathf.NearEqual(a.M33, b.M33)
|
||||
;
|
||||
return a.Equals(ref b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -397,7 +397,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref OrientedBoundingBox value)
|
||||
{
|
||||
return (Extents == value.Extents) && (Transformation == value.Transformation);
|
||||
return Extents == value.Extents && Transformation == value.Transformation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -582,23 +582,23 @@ namespace FlaxEngine
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Vector4" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <param name="other">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="Vector4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Plane value)
|
||||
public bool Equals(ref Plane other)
|
||||
{
|
||||
return Normal == value.Normal && D == value.D;
|
||||
return Normal == other.Normal && D == other.D;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Vector4" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <param name="other">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="Vector4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Plane value)
|
||||
public bool Equals(Plane other)
|
||||
{
|
||||
return Equals(ref value);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -608,10 +608,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (!(value is Plane))
|
||||
return false;
|
||||
var strongValue = (Plane)value;
|
||||
return Equals(ref strongValue);
|
||||
return value is Plane other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1149,7 +1149,7 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the quaternion that will rotate vector from into vector to, around their plan perpendicular axis.The input vectors don't need to be normalized.
|
||||
/// Gets the quaternion that will rotate vector from into vector to, around their plan perpendicular axis. The input vectors don't need to be normalized.
|
||||
/// </summary>
|
||||
/// <param name="from">The source vector.</param>
|
||||
/// <param name="to">The destination vector.</param>
|
||||
@@ -1179,7 +1179,7 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the quaternion that will rotate vector from into vector to, around their plan perpendicular axis.The input vectors don't need to be normalized.
|
||||
/// Gets the quaternion that will rotate the from into vector to, around their plan perpendicular axis. The input vectors don't need to be normalized.
|
||||
/// </summary>
|
||||
/// <param name="from">The source vector.</param>
|
||||
/// <param name="to">The destination vector.</param>
|
||||
@@ -1602,7 +1602,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Quaternion left, Quaternion right)
|
||||
{
|
||||
return Dot(ref left, ref right) > Tolerance;
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1614,7 +1614,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(Quaternion left, Quaternion right)
|
||||
{
|
||||
return Dot(ref left, ref right) <= Tolerance;
|
||||
return !left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1714,8 +1714,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Quaternion other)
|
||||
{
|
||||
//return Dot(ref this, ref other) > Tolerance;
|
||||
return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z) && Mathf.NearEqual(other.W, W);
|
||||
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1736,10 +1735,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (!(value is Quaternion))
|
||||
return false;
|
||||
var strongValue = (Quaternion)value;
|
||||
return Equals(ref strongValue);
|
||||
return value is Quaternion other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ public:
|
||||
/// <returns><c>true</c> if the specified <see cref="Quaternion" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
FORCE_INLINE bool operator==(const Quaternion& other) const
|
||||
{
|
||||
return Dot(*this, other) > Tolerance;
|
||||
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -358,7 +358,7 @@ public:
|
||||
/// <returns><c>true</c> if the specified <see cref="Quaternion" /> isn't equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
FORCE_INLINE bool operator!=(const Quaternion& other) const
|
||||
{
|
||||
return Dot(*this, other) < Tolerance;
|
||||
return X != other.X || Y != other.Y || Z != other.Z || W != other.W;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -428,23 +428,23 @@ namespace FlaxEngine
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Vector4" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <param name="other">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="Vector4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Ray value)
|
||||
public bool Equals(ref Ray other)
|
||||
{
|
||||
return (Position == value.Position) && (Direction == value.Direction);
|
||||
return Position == other.Position && Direction == other.Direction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Vector4" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <param name="other">The <see cref="Vector4" /> to compare with this instance.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="Vector4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Ray value)
|
||||
public bool Equals(Ray other)
|
||||
{
|
||||
return Equals(ref value);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -499,21 +499,19 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Rectangle other)
|
||||
{
|
||||
return Location.Equals(ref other.Location) && Size.Equals(ref other.Size);
|
||||
return Location == other.Location && Size == other.Size;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(Rectangle other)
|
||||
{
|
||||
return Location.Equals(ref other.Location) && Size.Equals(ref other.Size);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
return false;
|
||||
return obj is Rectangle && Equals((Rectangle)obj);
|
||||
return obj is Rectangle other && Equals(ref other);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -1654,7 +1654,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Vector2 left, Vector2 right)
|
||||
{
|
||||
return Mathr.NearEqual(left.X, right.X) && Mathr.NearEqual(left.Y, right.Y);
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1666,7 +1666,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(Vector2 left, Vector2 right)
|
||||
{
|
||||
return !Mathr.NearEqual(left.X, right.X) || !Mathr.NearEqual(left.Y, right.Y);
|
||||
return !left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1782,7 +1782,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Vector2 other)
|
||||
{
|
||||
return Mathr.NearEqual(other.X, X) && Mathr.NearEqual(other.Y, Y);
|
||||
return X == other.X && Y == other.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1790,7 +1790,7 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
public static bool Equals(ref Vector2 a, ref Vector2 b)
|
||||
{
|
||||
return Mathr.NearEqual(a.X, b.X) && Mathr.NearEqual(a.Y, b.Y);
|
||||
return a.Equals(ref b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1801,7 +1801,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Vector2 other)
|
||||
{
|
||||
return Mathr.NearEqual(other.X, X) && Mathr.NearEqual(other.Y, Y);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1811,7 +1811,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
return value is Vector2 other && Mathr.NearEqual(other.X, X) && Mathr.NearEqual(other.Y, Y);
|
||||
return value is Vector2 other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2010,7 +2010,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Vector3 left, Vector3 right)
|
||||
{
|
||||
return Mathr.NearEqual(left.X, right.X) && Mathr.NearEqual(left.Y, right.Y) && Mathr.NearEqual(left.Z, right.Z);
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2022,7 +2022,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(Vector3 left, Vector3 right)
|
||||
{
|
||||
return !Mathr.NearEqual(left.X, right.X) || !Mathr.NearEqual(left.Y, right.Y) || !Mathr.NearEqual(left.Z, right.Z);
|
||||
return !left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2141,7 +2141,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ref Vector3 other)
|
||||
{
|
||||
return Mathr.NearEqual(other.X, X) && Mathr.NearEqual(other.Y, Y) && Mathr.NearEqual(other.Z, Z);
|
||||
return X == other.X && Y == other.Y && Z == other.Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2152,7 +2152,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Vector3 other)
|
||||
{
|
||||
return Mathr.NearEqual(other.X, X) && Mathr.NearEqual(other.Y, Y) && Mathr.NearEqual(other.Z, Z);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2162,7 +2162,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
return value is Vector3 other && Mathr.NearEqual(other.X, X) && Mathr.NearEqual(other.Y, Y) && Mathr.NearEqual(other.Z, Z);
|
||||
return value is Vector3 other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1362,7 +1362,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Vector4 left, Vector4 right)
|
||||
{
|
||||
return Mathr.NearEqual(left.X, right.X) && Mathr.NearEqual(left.Y, right.Y) && Mathr.NearEqual(left.Z, right.Z) && Mathr.NearEqual(left.W, right.W);
|
||||
return left.Equals(ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1493,7 +1493,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="Vector4" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(ref Vector4 other)
|
||||
{
|
||||
return Mathr.NearEqual(other.X, X) && Mathr.NearEqual(other.Y, Y) && Mathr.NearEqual(other.Z, Z) && Mathr.NearEqual(other.W, W);
|
||||
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1504,7 +1504,7 @@ namespace FlaxEngine
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Vector4 other)
|
||||
{
|
||||
return Mathr.NearEqual(other.X, X) && Mathr.NearEqual(other.Y, Y) && Mathr.NearEqual(other.Z, Z) && Mathr.NearEqual(other.W, W);
|
||||
return Equals(ref other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1514,7 +1514,7 @@ namespace FlaxEngine
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
return value is Vector4 other && Mathr.NearEqual(other.X, X) && Mathr.NearEqual(other.Y, Y) && Mathr.NearEqual(other.Z, Z) && Mathr.NearEqual(other.W, W);
|
||||
return value is Vector4 other && Equals(ref other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
36
Source/Engine/Core/ScopeExit.h
Normal file
36
Source/Engine/Core/ScopeExit.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Core.h"
|
||||
|
||||
template<typename FuncType>
|
||||
struct ScopeExit
|
||||
{
|
||||
explicit ScopeExit(FuncType&& func)
|
||||
: _func((FuncType&&)func)
|
||||
{
|
||||
}
|
||||
|
||||
~ScopeExit()
|
||||
{
|
||||
_func();
|
||||
}
|
||||
|
||||
private:
|
||||
FuncType _func;
|
||||
};
|
||||
|
||||
namespace THelpers
|
||||
{
|
||||
struct ScopeExitInternal
|
||||
{
|
||||
template<typename FuncType>
|
||||
ScopeExit<FuncType> operator*(FuncType&& func)
|
||||
{
|
||||
return ScopeExit<FuncType>((FuncType&&)func);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define SCOPE_EXIT const auto CONCAT_MACROS(__scopeExit, __LINE__) = THelpers::ScopeExitInternal() * [&]()
|
||||
@@ -1162,9 +1162,9 @@ bool Variant::operator==(const Variant& other) const
|
||||
case VariantType::Enum:
|
||||
return AsEnum == other.AsEnum;
|
||||
case VariantType::Float:
|
||||
return Math::NearEqual(AsFloat, other.AsFloat);
|
||||
return AsFloat == other.AsFloat;
|
||||
case VariantType::Double:
|
||||
return Math::Abs(AsDouble - other.AsDouble) < ZeroTolerance;
|
||||
return AsDouble == other.AsDouble;
|
||||
case VariantType::Pointer:
|
||||
return AsPointer == other.AsPointer;
|
||||
case VariantType::String:
|
||||
|
||||
@@ -99,6 +99,7 @@ struct DebugGeometryBuffer
|
||||
{
|
||||
GPUBuffer* Buffer;
|
||||
float TimeLeft;
|
||||
bool Lines;
|
||||
Matrix Transform;
|
||||
};
|
||||
|
||||
@@ -234,6 +235,14 @@ void TeleportList(const Float3& delta, Array<DebugText3D>& list)
|
||||
}
|
||||
}
|
||||
|
||||
void TeleportList(const Float3& delta, Array<DebugGeometryBuffer>& list)
|
||||
{
|
||||
for (auto& v : list)
|
||||
{
|
||||
v.Transform.SetTranslation(v.Transform.GetTranslation() + delta);
|
||||
}
|
||||
}
|
||||
|
||||
struct DebugDrawData
|
||||
{
|
||||
Array<DebugGeometryBuffer> GeometryBuffers;
|
||||
@@ -302,6 +311,7 @@ struct DebugDrawData
|
||||
|
||||
void Teleport(const Float3& delta)
|
||||
{
|
||||
TeleportList(delta, GeometryBuffers);
|
||||
TeleportList(delta, DefaultLines);
|
||||
TeleportList(delta, OneFrameLines);
|
||||
TeleportList(delta, DefaultTriangles);
|
||||
@@ -812,6 +822,7 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
|
||||
defaultWireTriangles = WriteLists(vertexCounter, Context->DebugDrawDefault.DefaultWireTriangles, Context->DebugDrawDefault.OneFrameWireTriangles);
|
||||
{
|
||||
PROFILE_CPU_NAMED("Flush");
|
||||
ZoneValue(DebugDrawVB->Data.Count() / 1024); // Size in kB
|
||||
DebugDrawVB->Flush(context);
|
||||
}
|
||||
}
|
||||
@@ -871,8 +882,8 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
|
||||
Matrix mvp;
|
||||
Matrix::Multiply(geometry.Transform, vp, mvp);
|
||||
Matrix::Transpose(mvp, tmp.ViewProjection);
|
||||
auto state = data.EnableDepthTest ? (geometry.Lines ? &DebugDrawPsLinesDepthTest : &DebugDrawPsTrianglesDepthTest) : (geometry.Lines ? &DebugDrawPsLinesDefault : &DebugDrawPsTrianglesDefault);
|
||||
context->UpdateCB(cb, &tmp);
|
||||
auto state = data.EnableDepthTest ? &DebugDrawPsLinesDepthTest : &DebugDrawPsLinesDefault;
|
||||
context->SetState(state->Get(enableDepthWrite, true));
|
||||
context->BindVB(ToSpan(&geometry.Buffer, 1));
|
||||
context->Draw(0, geometry.Buffer->GetElementsCount());
|
||||
@@ -920,8 +931,9 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
|
||||
Matrix mvp;
|
||||
Matrix::Multiply(geometry.Transform, vp, mvp);
|
||||
Matrix::Transpose(mvp, tmp.ViewProjection);
|
||||
auto state = geometry.Lines ? &DebugDrawPsLinesDefault : &DebugDrawPsTrianglesDefault;
|
||||
context->UpdateCB(cb, &tmp);
|
||||
context->SetState(DebugDrawPsLinesDefault.Get(false, false));
|
||||
context->SetState(state->Get(false, false));
|
||||
context->BindVB(ToSpan(&geometry.Buffer, 1));
|
||||
context->Draw(0, geometry.Buffer->GetElementsCount());
|
||||
}
|
||||
@@ -1166,6 +1178,7 @@ void DebugDraw::DrawLines(GPUBuffer* lines, const Matrix& transform, float durat
|
||||
auto& geometry = debugDrawData.GeometryBuffers.AddOne();
|
||||
geometry.Buffer = lines;
|
||||
geometry.TimeLeft = duration;
|
||||
geometry.Lines = true;
|
||||
geometry.Transform = transform * Matrix::Translation(-Context->Origin);
|
||||
}
|
||||
|
||||
@@ -1522,6 +1535,23 @@ void DebugDraw::DrawTriangles(const Span<Float3>& vertices, const Matrix& transf
|
||||
}
|
||||
}
|
||||
|
||||
void DebugDraw::DrawTriangles(GPUBuffer* triangles, const Matrix& transform, float duration, bool depthTest)
|
||||
{
|
||||
if (triangles == nullptr || triangles->GetSize() == 0)
|
||||
return;
|
||||
if (triangles->GetSize() % (sizeof(Vertex) * 3) != 0)
|
||||
{
|
||||
DebugLog::ThrowException("Cannot draw debug lines with incorrect amount of items in array");
|
||||
return;
|
||||
}
|
||||
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
|
||||
auto& geometry = debugDrawData.GeometryBuffers.AddOne();
|
||||
geometry.Buffer = triangles;
|
||||
geometry.TimeLeft = duration;
|
||||
geometry.Lines = false;
|
||||
geometry.Transform = transform * Matrix::Translation(-Context->Origin);
|
||||
}
|
||||
|
||||
void DebugDraw::DrawTriangles(const Array<Float3>& vertices, const Color& color, float duration, bool depthTest)
|
||||
{
|
||||
DrawTriangles(Span<Float3>(vertices.Get(), vertices.Count()), color, duration, depthTest);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user