Merge remote-tracking branch 'origin/master' into sdl_platform
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
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
Flax Engine is a high quality modern 3D game engine written in C++ and C#.
|
||||
From stunning graphics to powerful scripts, it's designed for fast workflow with many ready-to-use features waiting for you right now. To learn more see the website ([www.flaxengine.com](https://flaxengine.com)).
|
||||
|
||||
This repository contains full source code of the Flax Engine (excluding NDA-protected platforms support). Anyone is welcome to contribute or use the modified source in Flax-based games.
|
||||
This repository contains full source code of the Flax Engine (excluding NDA-protected platforms support). Documentation source is also available in a separate repository. Anyone is welcome to contribute or use the modified source in Flax-based games.
|
||||
|
||||
# Development
|
||||
|
||||
@@ -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`)
|
||||
|
||||
@@ -13,6 +13,11 @@ namespace FlaxEditor.Content.Create
|
||||
/// <inheritdoc />
|
||||
public string ResultUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating wether a file can be created based on the current settings.
|
||||
/// </summary>
|
||||
public abstract bool CanBeCreated { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this entry has settings to modify.
|
||||
/// </summary>
|
||||
|
||||
@@ -60,7 +60,8 @@ namespace FlaxEditor.Content.Create
|
||||
Text = "Create",
|
||||
AnchorPreset = AnchorPresets.BottomRight,
|
||||
Offsets = new Margin(-ButtonsWidth - ButtonsMargin, ButtonsWidth, -ButtonsHeight - ButtonsMargin, ButtonsHeight),
|
||||
Parent = this
|
||||
Parent = this,
|
||||
Enabled = entry.CanBeCreated,
|
||||
};
|
||||
createButton.Clicked += OnSubmit;
|
||||
var cancelButton = new Button
|
||||
@@ -68,7 +69,7 @@ namespace FlaxEditor.Content.Create
|
||||
Text = "Cancel",
|
||||
AnchorPreset = AnchorPresets.BottomRight,
|
||||
Offsets = new Margin(-ButtonsWidth - ButtonsMargin - ButtonsWidth - ButtonsMargin, ButtonsWidth, -ButtonsHeight - ButtonsMargin, ButtonsHeight),
|
||||
Parent = this
|
||||
Parent = this,
|
||||
};
|
||||
cancelButton.Clicked += OnCancel;
|
||||
|
||||
@@ -77,7 +78,7 @@ namespace FlaxEditor.Content.Create
|
||||
{
|
||||
AnchorPreset = AnchorPresets.HorizontalStretchTop,
|
||||
Offsets = new Margin(2, 2, infoLabel.Bottom + 2, EditorHeight),
|
||||
Parent = this
|
||||
Parent = this,
|
||||
};
|
||||
|
||||
// Settings editor
|
||||
@@ -87,6 +88,7 @@ namespace FlaxEditor.Content.Create
|
||||
_dialogSize = new Float2(TotalWidth, panel.Bottom);
|
||||
|
||||
_settingsEditor.Select(_entry.Settings);
|
||||
_settingsEditor.Modified += () => createButton.Enabled = _entry.CanBeCreated;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -12,6 +12,9 @@ namespace FlaxEditor.Content.Create
|
||||
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
|
||||
public class ParticleEmitterCreateEntry : CreateFileEntry
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override bool CanBeCreated => true;
|
||||
|
||||
/// <summary>
|
||||
/// Types of the emitter templates that can be created.
|
||||
/// </summary>
|
||||
|
||||
@@ -14,6 +14,9 @@ namespace FlaxEditor.Content.Create
|
||||
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
|
||||
public class PrefabCreateEntry : CreateFileEntry
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override bool CanBeCreated => _options.RootActorType != null;
|
||||
|
||||
/// <summary>
|
||||
/// The create options.
|
||||
/// </summary>
|
||||
@@ -73,6 +76,9 @@ namespace FlaxEditor.Content.Create
|
||||
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
|
||||
public class WidgetCreateEntry : CreateFileEntry
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override bool CanBeCreated => _options.RootControlType != null;
|
||||
|
||||
/// <summary>
|
||||
/// The create options.
|
||||
/// </summary>
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace FlaxEditor.Content.Create
|
||||
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
|
||||
internal class SettingsCreateEntry : CreateFileEntry
|
||||
{
|
||||
public override bool CanBeCreated => _options.Type != null;
|
||||
|
||||
internal class Options
|
||||
{
|
||||
[Tooltip("The settings type.")]
|
||||
|
||||
@@ -11,6 +11,9 @@ namespace FlaxEditor.Content.Create
|
||||
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
|
||||
public class VisualScriptCreateEntry : CreateFileEntry
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override bool CanBeCreated => _options.BaseClass != null;
|
||||
|
||||
/// <summary>
|
||||
/// The create options.
|
||||
/// </summary>
|
||||
|
||||
@@ -65,6 +65,9 @@ namespace FlaxEditor.Content
|
||||
/// <seealso cref="FlaxEditor.Content.Create.CreateFileEntry" />
|
||||
public class GenericJsonCreateEntry : CreateFileEntry
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override bool CanBeCreated => _options.Type != null;
|
||||
|
||||
/// <summary>
|
||||
/// The create options.
|
||||
/// </summary>
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace FlaxEditor
|
||||
private void Set(CustomEditorWindow value)
|
||||
{
|
||||
_customEditor = value;
|
||||
_presenter.Select(value);
|
||||
_presenter.OverrideEditor = value;
|
||||
_presenter.Select(value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -132,6 +145,8 @@ namespace FlaxEditor.CustomEditors
|
||||
get => _overrideEditor;
|
||||
set
|
||||
{
|
||||
if (_overrideEditor == value)
|
||||
return;
|
||||
_overrideEditor = value;
|
||||
RebuildLayout();
|
||||
}
|
||||
@@ -200,7 +215,6 @@ namespace FlaxEditor.CustomEditors
|
||||
protected override void Deinitialize()
|
||||
{
|
||||
Editor = null;
|
||||
_overrideEditor = null;
|
||||
|
||||
base.Deinitialize();
|
||||
}
|
||||
|
||||
@@ -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,14 +70,14 @@ 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)
|
||||
{
|
||||
var targetPrefab = nestedPrefab ?? prefab;
|
||||
panel.CustomControl.SlotsHorizontally = 3;
|
||||
|
||||
|
||||
// Selecting actor prefab asset
|
||||
var selectPrefab = panel.Button("Select Prefab");
|
||||
selectPrefab.Button.Clicked += () =>
|
||||
@@ -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
|
||||
|
||||
@@ -54,7 +54,8 @@ public class ModelPrefabEditor : GenericEditor
|
||||
}
|
||||
|
||||
// Creates the import path UI
|
||||
Utilities.Utils.CreateImportPathUI(layout, modelPrefab.ImportPath, false);
|
||||
var group = layout.Group("Import Path");
|
||||
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;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Emit;
|
||||
using FlaxEditor.CustomEditors.GUI;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
@@ -93,8 +94,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
// Add info box
|
||||
if (IsSingleObject && Values[0] is RigidBody && Editor.IsPlayMode)
|
||||
{
|
||||
_infoLabel = layout.Label(string.Empty).Label;
|
||||
var group = layout.Group("Info");
|
||||
_infoLabel = group.Label(string.Empty).Label;
|
||||
_infoLabel.AutoHeight = true;
|
||||
_infoLabel.Margin = new Margin(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -41,13 +41,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
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;
|
||||
@@ -136,13 +128,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
menu.AddButton("Link", ToggleLink).LinkTooltip("Links scale components for uniform scaling");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -611,6 +611,16 @@ namespace FlaxEditor.GUI
|
||||
OnClickItem(focusedItem);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select first item if no item is focused (most likely to be the best result), saves the user from pressing arrow down first
|
||||
var visibleItems = GetVisibleItems();
|
||||
if (visibleItems.Count > 0)
|
||||
{
|
||||
OnClickItem(visibleItems[0]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -66,6 +67,11 @@ namespace FlaxEditor.GUI.Tree
|
||||
/// Gets the first selected node or null.
|
||||
/// </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.
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Actions;
|
||||
using FlaxEditor.SceneGraph;
|
||||
using FlaxEditor.SceneGraph.Actors;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.Modules
|
||||
@@ -561,7 +562,8 @@ namespace FlaxEditor.Modules
|
||||
public void CreateParentForSelectedActors()
|
||||
{
|
||||
List<SceneGraphNode> selection = Editor.SceneEditing.Selection;
|
||||
var actors = selection.Where(x => x is ActorNode).Select(x => ((ActorNode)x).Actor);
|
||||
// Get Actors but skip scene node
|
||||
var actors = selection.Where(x => x is ActorNode and not SceneNode).Select(x => ((ActorNode)x).Actor);
|
||||
var actorsCount = actors.Count();
|
||||
if (actorsCount == 0)
|
||||
return;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -621,19 +621,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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -573,11 +573,11 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
"Blend animation poses (with additive mode)" +
|
||||
"\n" +
|
||||
"\nNote: " +
|
||||
"\nOrder of nodes matters, because Additive animation is appplayed on top of curent frame." +
|
||||
"\nThe order of the nodes is important, because additive animation is applied on top of current frame." +
|
||||
"\n" +
|
||||
"\nTip for blender users:" +
|
||||
"\nInside NLA the the order is bottom (first node in flax) to the top (last node in flax)" +
|
||||
"\nu need to place it in this order to get correct resoults",
|
||||
"\nInside NLA the the order is bottom (first node in flax) to the top (last node in flax)." +
|
||||
"\nYou need to place animations in this order to get correct results.",
|
||||
Flags = NodeFlags.AnimGraph,
|
||||
Size = new Float2(170, 80),
|
||||
DefaultValues = new object[]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -20,5 +20,7 @@ namespace FlaxEditor.Utilities
|
||||
#else
|
||||
public const string ShowInExplorer = "Show in explorer";
|
||||
#endif
|
||||
|
||||
public const float UIMargin = 3.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,7 +402,7 @@ namespace FlaxEditor.Utilities
|
||||
/// <summary>
|
||||
/// Creates an Import path ui that show the asset import path and adds a button to show the folder in the file system.
|
||||
/// </summary>
|
||||
/// <param name="parentLayout">The parent layout container.</param>
|
||||
/// <param name="parentLayout">The parent layout element.</param>
|
||||
/// <param name="assetItem">The asset item to get the import path of.</param>
|
||||
public static void CreateImportPathUI(CustomEditors.LayoutElementsContainer parentLayout, Content.BinaryAssetItem assetItem)
|
||||
{
|
||||
@@ -413,21 +413,16 @@ namespace FlaxEditor.Utilities
|
||||
/// <summary>
|
||||
/// Creates an Import path ui that show the import path and adds a button to show the folder in the file system.
|
||||
/// </summary>
|
||||
/// <param name="parentLayout">The parent layout container.</param>
|
||||
/// <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(5);
|
||||
parentLayout.Label("Import Path:").Label.TooltipText = "Source asset path (can be relative or absolute to the project)";
|
||||
var textBox = parentLayout.TextBox().TextBox;
|
||||
textBox.TooltipText = "Path is not editable here.";
|
||||
textBox.TooltipText = "Source asset path. Can be relative or absolute to the project. Path is not editable here.";
|
||||
textBox.IsReadOnly = true;
|
||||
textBox.Text = path;
|
||||
parentLayout.Space(2);
|
||||
var button = parentLayout.Button(Constants.ShowInExplorer).Button;
|
||||
button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path));
|
||||
}
|
||||
@@ -1505,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, () =>
|
||||
{
|
||||
|
||||
@@ -916,7 +916,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;
|
||||
}
|
||||
@@ -965,7 +965,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;
|
||||
}
|
||||
@@ -1011,16 +1011,64 @@ namespace FlaxEditor.Viewport
|
||||
#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;
|
||||
@@ -1965,8 +2013,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;
|
||||
@@ -1984,13 +2041,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"),
|
||||
@@ -2004,16 +2061,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)
|
||||
@@ -2046,43 +2103,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);
|
||||
|
||||
@@ -231,7 +231,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
group.Object(importSettingsValues);
|
||||
|
||||
// Creates the import path UI
|
||||
Utilities.Utils.CreateImportPathUI(layout, proxy.Window.Item as BinaryAssetItem);
|
||||
group = layout.Group("Import Path");
|
||||
Utilities.Utils.CreateImportPathUI(group, proxy.Window.Item as BinaryAssetItem);
|
||||
|
||||
layout.Space(5);
|
||||
var reimportButton = layout.Button("Reimport");
|
||||
|
||||
@@ -6,6 +6,7 @@ using FlaxEditor.Content.Import;
|
||||
using FlaxEditor.CustomEditors;
|
||||
using FlaxEditor.CustomEditors.Editors;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Viewport.Previews;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
@@ -76,7 +77,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
{
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var window = ((PropertiesProxy)Values[0])._window;
|
||||
var proxy = ((PropertiesProxy)Values[0]);
|
||||
var window = proxy._window;
|
||||
if (window == null)
|
||||
{
|
||||
layout.Label("Loading...", TextAlignment.Center);
|
||||
@@ -101,7 +103,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
base.Initialize(layout);
|
||||
|
||||
// Creates the import path UI
|
||||
Utilities.Utils.CreateImportPathUI(layout, window.Item as BinaryAssetItem);
|
||||
var pathGroup = layout.Group("Import Path");
|
||||
Utilities.Utils.CreateImportPathUI(pathGroup, window.Item as BinaryAssetItem);
|
||||
|
||||
layout.Space(5);
|
||||
var reimportButton = layout.Button("Reimport");
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +102,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
|
||||
private class CookData : CreateFileEntry
|
||||
{
|
||||
public override bool CanBeCreated => true;
|
||||
|
||||
public PropertiesProxy Proxy;
|
||||
public CollisionDataType Type;
|
||||
public ModelBase Model;
|
||||
|
||||
@@ -55,10 +55,11 @@ namespace FlaxEditor.Windows.Assets
|
||||
base.Initialize(layout);
|
||||
|
||||
// Creates the import path UI
|
||||
Utilities.Utils.CreateImportPathUI(layout, window.Item as BinaryAssetItem);
|
||||
var pathGroup = layout.Group("Import Path");
|
||||
Utilities.Utils.CreateImportPathUI(pathGroup, window.Item as BinaryAssetItem);
|
||||
|
||||
layout.Space(5);
|
||||
var reimportButton = layout.Button("Reimport");
|
||||
pathGroup.Space(5);
|
||||
var reimportButton = pathGroup.Button("Reimport");
|
||||
reimportButton.Button.Clicked += () => ((PropertiesProxy)Values[0]).Reimport();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,17 +754,17 @@ namespace FlaxEditor.Windows.Assets
|
||||
if (Utilities.Utils.OnAssetProperties(layout, proxy.Asset))
|
||||
return;
|
||||
|
||||
var group = layout.Group("Import Settings");
|
||||
var importSettingsGroup = layout.Group("Import Settings");
|
||||
|
||||
var importSettingsField = typeof(ImportPropertiesProxyBase).GetField(nameof(ImportSettings), BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var importSettingsValues = new ValueContainer(new ScriptMemberInfo(importSettingsField)) { proxy.ImportSettings };
|
||||
group.Object(importSettingsValues);
|
||||
importSettingsGroup.Object(importSettingsValues);
|
||||
|
||||
// Creates the import path UI
|
||||
Utilities.Utils.CreateImportPathUI(layout, proxy.Window.Item as BinaryAssetItem);
|
||||
var group = layout.Group("Import Path");
|
||||
Utilities.Utils.CreateImportPathUI(group, proxy.Window.Item as BinaryAssetItem);
|
||||
|
||||
layout.Space(5);
|
||||
var reimportButton = group.Button("Reimport");
|
||||
var reimportButton = importSettingsGroup.Button("Reimport");
|
||||
reimportButton.Button.Clicked += () => ((ImportPropertiesProxyBase)Values[0]).Reimport();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -160,6 +160,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
AnchorPreset = AnchorPresets.HorizontalStretchMiddle,
|
||||
Parent = headerPanel,
|
||||
Bounds = new Rectangle(4, 4, headerPanel.Width - 8, 18),
|
||||
TooltipText = "Search the prefab.\n\nYou can prefix your search with different search operators:\ns: -> Actor with script of type\na: -> Actor type\nc: -> Control type",
|
||||
};
|
||||
_searchBox.TextChanged += OnSearchBoxTextChanged;
|
||||
|
||||
|
||||
@@ -119,9 +119,10 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
|
||||
base.Initialize(layout);
|
||||
|
||||
|
||||
// Creates the import path UI
|
||||
Utilities.Utils.CreateImportPathUI(layout, proxy._window.Item as BinaryAssetItem);
|
||||
var group = layout.Group("Import Path");
|
||||
Utilities.Utils.CreateImportPathUI(group, proxy._window.Item as BinaryAssetItem);
|
||||
|
||||
layout.Space(5);
|
||||
var reimportButton = layout.Button("Reimport");
|
||||
|
||||
@@ -143,7 +143,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
base.Initialize(layout);
|
||||
|
||||
// Creates the import path UI
|
||||
Utilities.Utils.CreateImportPathUI(layout, proxy._window.Item as BinaryAssetItem);
|
||||
var group = layout.Group("Import Path");
|
||||
Utilities.Utils.CreateImportPathUI(group, proxy._window.Item as BinaryAssetItem);
|
||||
|
||||
// Reimport
|
||||
layout.Space(5);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ namespace FlaxEditor.Windows
|
||||
private class GameRoot : UIEditorRoot
|
||||
{
|
||||
internal bool Editable = true;
|
||||
public override bool EnableInputs => !Time.GamePaused && Editor.IsPlayMode && Editable;
|
||||
public override bool EnableInputs => !Time.GamePaused && Editor.IsPlayMode;
|
||||
public override bool EnableSelecting => (!Editor.IsPlayMode || Time.GamePaused) && Editable;
|
||||
public override TransformGizmo TransformGizmo => Editor.Instance.MainTransformGizmo;
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -492,7 +492,7 @@ namespace FlaxEditor.Windows.Profiler
|
||||
{
|
||||
break;
|
||||
}
|
||||
subEventsMemoryTotal += sub.ManagedMemoryAllocation + e.NativeMemoryAllocation;
|
||||
subEventsMemoryTotal += sub.ManagedMemoryAllocation + sub.NativeMemoryAllocation;
|
||||
}
|
||||
|
||||
string name = e.Name.Replace("::", ".");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace FlaxEditor.Windows
|
||||
: base(editor, true, ScrollBars.None)
|
||||
{
|
||||
Title = "Scene";
|
||||
Icon = editor.Icons.Globe32;
|
||||
|
||||
// Scene searching query input box
|
||||
var headerPanel = new ContainerControl
|
||||
@@ -83,6 +84,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()
|
||||
@@ -467,11 +469,13 @@ void Asset::CancelStreaming()
|
||||
{
|
||||
// Cancel loading task but go over asset locker to prevent case if other load threads still loads asset while it's reimported on other thread
|
||||
Locker.Lock();
|
||||
auto loadTask = (ContentLoadTask*)Platform::AtomicRead(&_loadingTask);
|
||||
auto loadingTask = (ContentLoadTask*)Platform::AtomicRead(&_loadingTask);
|
||||
Locker.Unlock();
|
||||
if (loadTask)
|
||||
if (loadingTask)
|
||||
{
|
||||
loadTask->Cancel();
|
||||
Platform::AtomicStore(&_loadingTask, 0);
|
||||
LOG(Warning, "Cancel loading task for \'{0}\'", ToString());
|
||||
loadingTask->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,7 +594,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());
|
||||
@@ -632,18 +636,11 @@ void Asset::onUnload_MainThread()
|
||||
|
||||
ASSERT(IsInMainThread());
|
||||
|
||||
// Cancel any streaming before calling OnUnloaded event
|
||||
CancelStreaming();
|
||||
|
||||
// Send event
|
||||
OnUnloaded(this);
|
||||
|
||||
// Check if is during loading
|
||||
auto loadingTask = (ContentLoadTask*)Platform::AtomicRead(&_loadingTask);
|
||||
if (loadingTask != nullptr)
|
||||
{
|
||||
// Cancel loading
|
||||
Platform::AtomicStore(&_loadingTask, 0);
|
||||
LOG(Warning, "Cancel loading task for \'{0}\'", ToString());
|
||||
loadingTask->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
@@ -34,6 +34,10 @@ public:
|
||||
|
||||
public:
|
||||
// [ContentLoadTask]
|
||||
String ToString() const override
|
||||
{
|
||||
return String::Format(TEXT("Load Asset Data Task ({}, {}, {})"), (int32)GetState(), _chunks, _asset ? _asset->GetPath() : String::Empty);
|
||||
}
|
||||
bool HasReference(Object* obj) const override
|
||||
{
|
||||
return obj == _asset;
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
static CreateAssetResult Create(CreateAssetContext& context)
|
||||
{
|
||||
// Base
|
||||
IMPORT_SETUP(SkeletonMask, 1);
|
||||
IMPORT_SETUP(SkeletonMask, 2);
|
||||
|
||||
// Chunk 0
|
||||
if (context.AllocateChunk(0))
|
||||
|
||||
@@ -93,6 +93,9 @@ public:
|
||||
// Calculates the inverse of the specified matrix.
|
||||
static void Invert(const Double4x4& value, Double4x4& result);
|
||||
|
||||
// Creates a left-handed, look-at matrix.
|
||||
static void LookAt(const Double3& eye, const Double3& target, const Double3& up, Double4x4& result);
|
||||
|
||||
// Calculates the product of two matrices.
|
||||
static void Multiply(const Double4x4& left, const Double4x4& right, Double4x4& result);
|
||||
|
||||
|
||||
@@ -1001,6 +1001,37 @@ void Double4x4::Invert(const Double4x4& value, Double4x4& result)
|
||||
result.M44 = +d44 * det;
|
||||
}
|
||||
|
||||
void Double4x4::LookAt(const Double3& eye, const Double3& target, const Double3& up, Double4x4& result)
|
||||
{
|
||||
Double3 xaxis, yaxis, zaxis;
|
||||
Double3::Subtract(target, eye, zaxis);
|
||||
zaxis.Normalize();
|
||||
Double3::Cross(up, zaxis, xaxis);
|
||||
xaxis.Normalize();
|
||||
Double3::Cross(zaxis, xaxis, yaxis);
|
||||
|
||||
result.M11 = xaxis.X;
|
||||
result.M21 = xaxis.Y;
|
||||
result.M31 = xaxis.Z;
|
||||
|
||||
result.M12 = yaxis.X;
|
||||
result.M22 = yaxis.Y;
|
||||
result.M32 = yaxis.Z;
|
||||
|
||||
result.M13 = zaxis.X;
|
||||
result.M23 = zaxis.Y;
|
||||
result.M33 = zaxis.Z;
|
||||
|
||||
result.M14 = 0.0f;
|
||||
result.M24 = 0.0f;
|
||||
result.M34 = 0.0f;
|
||||
|
||||
result.M41 = -Double3::Dot(xaxis, eye);
|
||||
result.M42 = -Double3::Dot(yaxis, eye);
|
||||
result.M43 = -Double3::Dot(zaxis, eye);
|
||||
result.M44 = 1.0f;
|
||||
}
|
||||
|
||||
void Double4x4::Multiply(const Double4x4& left, const Double4x4& right, Double4x4& result)
|
||||
{
|
||||
result.M11 = left.M11 * right.M11 + left.M12 * right.M21 + left.M13 * right.M31 + left.M14 * right.M41;
|
||||
|
||||
@@ -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>
|
||||
|
||||
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() * [&]()
|
||||
@@ -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);
|
||||
@@ -810,6 +820,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);
|
||||
}
|
||||
}
|
||||
@@ -869,8 +880,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());
|
||||
@@ -918,8 +929,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());
|
||||
}
|
||||
@@ -1164,6 +1176,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);
|
||||
}
|
||||
|
||||
@@ -1520,6 +1533,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);
|
||||
|
||||
@@ -74,7 +74,7 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
API_FUNCTION() static bool CanClear(void* context = nullptr);
|
||||
#endif
|
||||
|
||||
// Gets the last view position when rendering the current context. Can be sued for custom culling or LODing when drawing more complex shapes.
|
||||
// Gets the last view position when rendering the current context. Can be used for custom culling or LODing when drawing more complex shapes.
|
||||
static Vector3 GetViewPos();
|
||||
|
||||
/// <summary>
|
||||
@@ -296,12 +296,21 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
/// Draws the triangles.
|
||||
/// </summary>
|
||||
/// <param name="vertices">The triangle vertices list (must have multiple of 3 elements).</param>
|
||||
/// <param name="transform">The custom matrix used to transform all line vertices.</param>
|
||||
/// <param name="transform">The custom matrix used to transform all triangle vertices.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
API_FUNCTION() static void DrawTriangles(const Span<Float3>& vertices, const Matrix& transform, const Color& color = Color::White, float duration = 0.0f, bool depthTest = true);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the triangles using the provided vertex buffer that contains groups of 3 Vertex elements per-triangle.
|
||||
/// </summary>
|
||||
/// <param name="triangles">The GPU buffer with vertices for triangles (must have multiple of 3 elements).</param>
|
||||
/// <param name="transform">The custom matrix used to transform all triangle vertices.</param>
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
API_FUNCTION() static void DrawTriangles(GPUBuffer* triangles, const Matrix& transform, float duration = 0.0f, bool depthTest = true);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the triangles.
|
||||
/// </summary>
|
||||
@@ -315,7 +324,7 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
/// Draws the triangles.
|
||||
/// </summary>
|
||||
/// <param name="vertices">The triangle vertices list (must have multiple of 3 elements).</param>
|
||||
/// <param name="transform">The custom matrix used to transform all line vertices.</param>
|
||||
/// <param name="transform">The custom matrix used to transform all triangle vertices.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
@@ -336,7 +345,7 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
/// </summary>
|
||||
/// <param name="vertices">The triangle vertices list.</param>
|
||||
/// <param name="indices">The triangle indices list (must have multiple of 3 elements).</param>
|
||||
/// <param name="transform">The custom matrix used to transform all line vertices.</param>
|
||||
/// <param name="transform">The custom matrix used to transform all triangle vertices.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
@@ -357,7 +366,7 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
/// </summary>
|
||||
/// <param name="vertices">The triangle vertices list.</param>
|
||||
/// <param name="indices">The triangle indices list (must have multiple of 3 elements).</param>
|
||||
/// <param name="transform">The custom matrix used to transform all line vertices.</param>
|
||||
/// <param name="transform">The custom matrix used to transform all triangle vertices.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
@@ -376,7 +385,7 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
/// Draws the triangles.
|
||||
/// </summary>
|
||||
/// <param name="vertices">The triangle vertices list (must have multiple of 3 elements).</param>
|
||||
/// <param name="transform">The custom matrix used to transform all line vertices.</param>
|
||||
/// <param name="transform">The custom matrix used to transform all triangle vertices.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
@@ -395,7 +404,7 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
/// Draws the triangles.
|
||||
/// </summary>
|
||||
/// <param name="vertices">The triangle vertices list (must have multiple of 3 elements).</param>
|
||||
/// <param name="transform">The custom matrix used to transform all line vertices.</param>
|
||||
/// <param name="transform">The custom matrix used to transform all triangle vertices.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
@@ -416,7 +425,7 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
/// </summary>
|
||||
/// <param name="vertices">The triangle vertices list.</param>
|
||||
/// <param name="indices">The triangle indices list (must have multiple of 3 elements).</param>
|
||||
/// <param name="transform">The custom matrix used to transform all line vertices.</param>
|
||||
/// <param name="transform">The custom matrix used to transform all triangle vertices.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
@@ -437,7 +446,7 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
/// </summary>
|
||||
/// <param name="vertices">The triangle vertices list.</param>
|
||||
/// <param name="indices">The triangle indices list (must have multiple of 3 elements).</param>
|
||||
/// <param name="transform">The custom matrix used to transform all line vertices.</param>
|
||||
/// <param name="transform">The custom matrix used to transform all triangle vertices.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
|
||||
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
|
||||
|
||||
@@ -443,6 +443,15 @@ bool Engine::IsEditor()
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Engine::IsPlayMode()
|
||||
{
|
||||
#if USE_EDITOR
|
||||
return Editor::IsPlayMode;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32 Engine::GetFramesPerSecond()
|
||||
{
|
||||
return EngineImpl::Fps;
|
||||
|
||||
@@ -178,6 +178,11 @@ public:
|
||||
/// </summary>
|
||||
API_PROPERTY() static bool IsEditor();
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the editor is in play mode or will always return true in a shipped applications.
|
||||
/// </summary>
|
||||
API_PROPERTY() static bool IsPlayMode();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of frames rendered during last second known as Frames Per Second. User scripts updates or fixed updates for physics may run at a different frequency than scene rendering. Use this property to get an accurate amount of frames rendered during the last second.
|
||||
/// </summary>
|
||||
|
||||
@@ -37,6 +37,21 @@ DEFINE_ENGINE_SERVICE_EVENT(LateFixedUpdate);
|
||||
DEFINE_ENGINE_SERVICE_EVENT(Draw);
|
||||
DEFINE_ENGINE_SERVICE_EVENT_INVERTED(BeforeExit);
|
||||
|
||||
#if TRACY_ENABLE
|
||||
|
||||
StringView FillEventNameBuffer(Char* buffer, StringView name, StringView postfix)
|
||||
{
|
||||
int32 size = 0;
|
||||
for (int32 j = 0; j < name.Length(); j++)
|
||||
if (name[j] != ' ')
|
||||
buffer[size++] = name[j];
|
||||
Platform::MemoryCopy(buffer + size, postfix.Get(), (postfix.Length() + 1) * sizeof(Char));
|
||||
size += postfix.Length();
|
||||
return StringView(buffer, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
EngineService::EngineServicesArray& EngineService::GetServices()
|
||||
{
|
||||
static EngineServicesArray Services;
|
||||
@@ -78,14 +93,9 @@ void EngineService::OnInit()
|
||||
const StringView name(service->Name);
|
||||
#if TRACY_ENABLE
|
||||
ZoneScoped;
|
||||
int32 nameBufferLength = 0;
|
||||
Char nameBuffer[100];
|
||||
for (int32 j = 0; j < name.Length(); j++)
|
||||
if (name[j] != ' ')
|
||||
nameBuffer[nameBufferLength++] = name[j];
|
||||
Platform::MemoryCopy(nameBuffer + nameBufferLength, TEXT("::Init"), 7 * sizeof(Char));
|
||||
nameBufferLength += 7;
|
||||
ZoneName(nameBuffer, nameBufferLength);
|
||||
StringView zoneName = FillEventNameBuffer(nameBuffer, name, StringView(TEXT("::Init"), 6));
|
||||
ZoneName(zoneName.Get(), zoneName.Length());
|
||||
#endif
|
||||
LOG(Info, "Initialize {0}...", name);
|
||||
service->IsInitialized = true;
|
||||
@@ -114,15 +124,10 @@ void EngineService::OnDispose()
|
||||
{
|
||||
#if TRACY_ENABLE
|
||||
ZoneScoped;
|
||||
const StringView name(service->Name);
|
||||
int32 nameBufferLength = 0;
|
||||
Char nameBuffer[100];
|
||||
for (int32 j = 0; j < name.Length(); j++)
|
||||
if (name[j] != ' ')
|
||||
nameBuffer[nameBufferLength++] = name[j];
|
||||
Platform::MemoryCopy(nameBuffer + nameBufferLength, TEXT("::Dispose"), 10 * sizeof(Char));
|
||||
nameBufferLength += 10;
|
||||
ZoneName(nameBuffer, nameBufferLength);
|
||||
const StringView name(service->Name);
|
||||
StringView zoneName = FillEventNameBuffer(nameBuffer, name, StringView(TEXT("::Dispose"), 9));
|
||||
ZoneName(zoneName.Get(), zoneName.Length());
|
||||
#endif
|
||||
service->IsInitialized = false;
|
||||
service->Dispose();
|
||||
|
||||
@@ -67,6 +67,14 @@ public:
|
||||
return _type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets work synchronization start point
|
||||
/// </summary>
|
||||
FORCE_INLINE GPUSyncPoint GetSyncStart() const
|
||||
{
|
||||
return _syncPoint;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets work finish synchronization point
|
||||
/// </summary>
|
||||
|
||||
@@ -36,7 +36,7 @@ GPUTasksContext::~GPUTasksContext()
|
||||
if (task->GetSyncPoint() <= _currentSyncPoint && task->GetState() != TaskState::Finished)
|
||||
{
|
||||
if (!Engine::IsRequestingExit)
|
||||
LOG(Warning, "{0} has been canceled before a sync", task->ToString());
|
||||
LOG(Warning, "'{0}' has been canceled before a sync", task->ToString());
|
||||
task->CancelSync();
|
||||
}
|
||||
}
|
||||
@@ -51,18 +51,15 @@ void GPUTasksContext::Run(GPUTask* task)
|
||||
ASSERT(task != nullptr);
|
||||
|
||||
task->Execute(this);
|
||||
if (task->IsSyncing())
|
||||
//if (task->GetSyncStart() != 0)
|
||||
_tasksSyncing.Add(task);
|
||||
}
|
||||
|
||||
void GPUTasksContext::OnCancelSync(GPUTask* task)
|
||||
{
|
||||
ASSERT(task != nullptr);
|
||||
|
||||
_tasksSyncing.Remove(task);
|
||||
|
||||
if (!Engine::IsRequestingExit)
|
||||
LOG(Warning, "{0} has been canceled before a sync", task->ToString());
|
||||
LOG(Warning, "'{0}' has been canceled before a sync", task->ToString());
|
||||
}
|
||||
|
||||
void GPUTasksContext::OnFrameBegin()
|
||||
|
||||
@@ -18,7 +18,7 @@ protected:
|
||||
CriticalSection _locker;
|
||||
GPUSyncPoint _currentSyncPoint;
|
||||
int32 _totalTasksDoneCount = 0;
|
||||
Array<GPUTask*, InlinedAllocation<64>> _tasksSyncing;
|
||||
Array<GPUTask*> _tasksSyncing;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
|
||||
@@ -54,9 +54,9 @@ void GPUTask::OnCancel()
|
||||
if (IsSyncing())
|
||||
{
|
||||
// Task has been performed but is waiting for a CPU/GPU sync so we have to cancel that
|
||||
ASSERT(_context != nullptr);
|
||||
_context->OnCancelSync(this);
|
||||
_context = nullptr;
|
||||
SetState(TaskState::Canceled);
|
||||
}
|
||||
|
||||
// Base
|
||||
|
||||
@@ -475,6 +475,12 @@ bool MeshBase::Init(uint32 vertices, uint32 triangles, const Array<const void*,
|
||||
_collisionProxy.Init<uint32>(vertices, triangles, (const Float3*)vbData[0], (const uint32*)ibData);
|
||||
#endif
|
||||
|
||||
// Free old buffers
|
||||
SAFE_DELETE_GPU_RESOURCE(_vertexBuffers[0]);
|
||||
SAFE_DELETE_GPU_RESOURCE(_vertexBuffers[1]);
|
||||
SAFE_DELETE_GPU_RESOURCE(_vertexBuffers[2]);
|
||||
SAFE_DELETE_GPU_RESOURCE(_indexBuffer);
|
||||
|
||||
// Initialize
|
||||
_vertexBuffers[0] = vertexBuffer0;
|
||||
_vertexBuffers[1] = vertexBuffer1;
|
||||
|
||||
@@ -322,15 +322,17 @@ class StreamTextureMipTask : public GPUUploadTextureMipTask
|
||||
{
|
||||
private:
|
||||
StreamingTexture* _streamingTexture;
|
||||
Task* _rootTask;
|
||||
FlaxStorage::LockData _dataLock;
|
||||
|
||||
public:
|
||||
StreamTextureMipTask(StreamingTexture* texture, int32 mipIndex)
|
||||
StreamTextureMipTask(StreamingTexture* texture, int32 mipIndex, Task* rootTask)
|
||||
: GPUUploadTextureMipTask(texture->GetTexture(), mipIndex, Span<byte>(nullptr, 0), 0, 0, false)
|
||||
, _streamingTexture(texture)
|
||||
, _rootTask(rootTask ? rootTask : this)
|
||||
, _dataLock(_streamingTexture->GetOwner()->LockData())
|
||||
{
|
||||
_streamingTexture->_streamingTasks.Add(this);
|
||||
_streamingTexture->_streamingTasks.Add(_rootTask);
|
||||
_texture.Released.Bind<StreamTextureMipTask, &StreamTextureMipTask::OnResourceReleased2>(this);
|
||||
}
|
||||
|
||||
@@ -341,7 +343,7 @@ private:
|
||||
if (_streamingTexture)
|
||||
{
|
||||
ScopeLock lock(_streamingTexture->GetOwner()->GetOwnerLocker());
|
||||
_streamingTexture->_streamingTasks.Remove(this);
|
||||
_streamingTexture->_streamingTasks.Remove(_rootTask);
|
||||
_streamingTexture = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -393,7 +395,7 @@ protected:
|
||||
if (_streamingTexture)
|
||||
{
|
||||
ScopeLock lock(_streamingTexture->GetOwner()->GetOwnerLocker());
|
||||
_streamingTexture->_streamingTasks.Remove(this);
|
||||
_streamingTexture->_streamingTasks.Remove(_rootTask);
|
||||
_streamingTexture = nullptr;
|
||||
}
|
||||
|
||||
@@ -443,7 +445,7 @@ Task* StreamingTexture::CreateStreamingTask(int32 residency)
|
||||
|
||||
// Add upload data task
|
||||
const int32 allocatedMipIndex = TotalIndexToTextureMipIndex(mipIndex);
|
||||
task = New<StreamTextureMipTask>(this, allocatedMipIndex);
|
||||
task = New<StreamTextureMipTask>(this, allocatedMipIndex, result);
|
||||
if (result)
|
||||
result->ContinueWith(task);
|
||||
else
|
||||
|
||||
@@ -766,7 +766,7 @@ void AnimatedModel::UpdateBounds()
|
||||
// Apply margin based on model dimensions
|
||||
const Vector3 modelBoxSize = modelBox.GetSize();
|
||||
const Vector3 center = box.GetCenter();
|
||||
const Vector3 sizeHalf = Vector3::Max(box.GetSize() + modelBoxSize * 0.2f, modelBoxSize) * 0.5f;
|
||||
const Vector3 sizeHalf = Vector3::Max(box.GetSize() + modelBoxSize * 0.2f, modelBoxSize) * (0.5f * BoundsScale);
|
||||
_box = BoundingBox(center - sizeHalf, center + sizeHalf);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
bool PerBoneMotionBlur = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true, animation speed will be affected by the global time scale parameter.
|
||||
/// If true, animation speed will be affected by the global timescale parameter.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(30), DefaultValue(true), EditorDisplay(\"Skinned Model\")")
|
||||
bool UseTimeScale = true;
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
bool UpdateWhenOffscreen = false;
|
||||
|
||||
/// <summary>
|
||||
/// The animation update delta time scale. Can be used to speed up animation playback or create slow motion effect.
|
||||
/// The animation update delta timescale. Can be used to speed up animation playback or create slow motion effect.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(45), EditorDisplay(\"Skinned Model\")")
|
||||
float UpdateSpeed = 1.0f;
|
||||
@@ -120,7 +120,7 @@ public:
|
||||
AnimationUpdateMode UpdateMode = AnimationUpdateMode::Auto;
|
||||
|
||||
/// <summary>
|
||||
/// The master scale parameter for the actor bounding box. Helps reducing mesh flickering effect on screen edges.
|
||||
/// The master scale parameter for the actor bounding box. Helps to reduce mesh flickering effect on screen edges.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(60), DefaultValue(1.5f), Limit(0), EditorDisplay(\"Skinned Model\")")
|
||||
float BoundsScale = 1.5f;
|
||||
@@ -388,7 +388,7 @@ public:
|
||||
API_FUNCTION() void PauseSlotAnimation(const StringView& slotName, Animation* anim);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the any animation playback is active on the any slot in Anim Graph (not paused).
|
||||
/// Checks if any animation playback is active on any slot in Anim Graph (not paused).
|
||||
/// </summary>
|
||||
API_FUNCTION() bool IsPlayingSlotAnimation();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Camera.h"
|
||||
#include "Engine/Level/SceneObjectsFactory.h"
|
||||
#include "Engine/Core/Math/Matrix.h"
|
||||
#include "Engine/Core/Math/Double4x4.h"
|
||||
#include "Engine/Core/Math/Viewport.h"
|
||||
#include "Engine/Content/Assets/Model.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
@@ -238,7 +239,7 @@ Ray Camera::ConvertMouseToRay(const Float2& mousePosition, const Viewport& viewp
|
||||
viewport.Unproject(farPoint, ivp, farPoint);
|
||||
|
||||
Vector3 dir = Vector3::Normalize(farPoint - nearPoint);
|
||||
if (dir.IsZero())
|
||||
if (dir.IsZero() || dir.IsNanOrInfinity())
|
||||
return Ray::Identity;
|
||||
return Ray(nearPoint, dir);
|
||||
}
|
||||
@@ -302,12 +303,15 @@ void Camera::GetMatrices(Matrix& view, Matrix& projection, const Viewport& viewp
|
||||
}
|
||||
|
||||
// Create view matrix
|
||||
const Float3 direction = GetDirection();
|
||||
const Float3 position = _transform.Translation - origin;
|
||||
const Float3 target = position + direction;
|
||||
Float3 up;
|
||||
Float3::Transform(Float3::Up, GetOrientation(), up);
|
||||
Matrix::LookAt(position, target, up, view);
|
||||
const Vector3 direction = Vector3::Transform(Vector3::Forward, GetOrientation());
|
||||
const Vector3 position = _transform.Translation - origin;
|
||||
const Vector3 target = position + direction;
|
||||
|
||||
Vector3 up;
|
||||
Vector3::Transform(Vector3::Up, GetOrientation(), up);
|
||||
Real4x4 viewResult;
|
||||
Real4x4::LookAt(position, target, up, viewResult);
|
||||
view = Matrix(viewResult);
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
22
Source/Engine/Level/MeshReference.cs
Normal file
22
Source/Engine/Level/MeshReference.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
|
||||
using FlaxEngine.Json;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
partial class ModelInstanceActor
|
||||
{
|
||||
partial struct MeshReference : ICustomValueEquals
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool ValueEquals(object other)
|
||||
{
|
||||
var o = (MeshReference)other;
|
||||
return JsonSerializer.ValueEquals(Actor, o.Actor) &&
|
||||
LODIndex == o.LODIndex &&
|
||||
MeshIndex == o.MeshIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1090,7 +1090,7 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr
|
||||
root = dynamic_cast<Actor*>(sceneObjects.Value->At(targetActorIdx));
|
||||
}
|
||||
|
||||
// Try using the first actor without a parent as a new ro0t
|
||||
// Try using the first actor without a parent as a new root
|
||||
for (int32 i = 1; i < sceneObjects->Count(); i++)
|
||||
{
|
||||
SceneObject* obj = sceneObjects.Value->At(i);
|
||||
|
||||
@@ -223,7 +223,7 @@ bool ParticleEmitterGraphCPUExecutor::ComputeBounds(ParticleEmitter* emitter, Pa
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
ASSERT(!isnan(sphere.Radius) && !isinf(sphere.Radius) && !sphere.Center.IsNanOrInfinity());
|
||||
CHECK_RETURN(!isnan(sphere.Radius) && !isinf(sphere.Radius) && !sphere.Center.IsNanOrInfinity(), false);
|
||||
|
||||
// Expand sphere based on the render modules rules (sprite or mesh size)
|
||||
for (int32 moduleIndex = 0; moduleIndex < emitter->Graph.RenderModules.Count(); moduleIndex++)
|
||||
@@ -244,7 +244,7 @@ bool ParticleEmitterGraphCPUExecutor::ComputeBounds(ParticleEmitter* emitter, Pa
|
||||
Vector2::Max(*((Vector2*)spriteSize), maxSpriteSize, maxSpriteSize);
|
||||
spriteSize += stride;
|
||||
}
|
||||
ASSERT(!maxSpriteSize.IsNanOrInfinity());
|
||||
CHECK_RETURN(!maxSpriteSize.IsNanOrInfinity(), false);
|
||||
|
||||
// Enlarge the emitter bounds sphere
|
||||
sphere.Radius += maxSpriteSize.MaxValue();
|
||||
@@ -267,7 +267,7 @@ bool ParticleEmitterGraphCPUExecutor::ComputeBounds(ParticleEmitter* emitter, Pa
|
||||
if (radius > maxRadius)
|
||||
maxRadius = radius;
|
||||
}
|
||||
ASSERT(!isnan(maxRadius) && !isinf(maxRadius));
|
||||
CHECK_RETURN(!isnan(maxRadius) && !isinf(maxRadius), false);
|
||||
|
||||
// Enlarge the emitter bounds sphere
|
||||
sphere.Radius += maxRadius;
|
||||
@@ -315,7 +315,7 @@ bool ParticleEmitterGraphCPUExecutor::ComputeBounds(ParticleEmitter* emitter, Pa
|
||||
maxRibbonWidth = Math::Max(*((float*)ribbonWidth), maxRibbonWidth);
|
||||
ribbonWidth += stride;
|
||||
}
|
||||
ASSERT(!isnan(maxRibbonWidth) && !isinf(maxRibbonWidth));
|
||||
CHECK_RETURN(!isnan(maxRibbonWidth) && !isinf(maxRibbonWidth), false);
|
||||
|
||||
// Enlarge the emitter bounds sphere
|
||||
sphere.Radius += maxRibbonWidth * 0.5f;
|
||||
@@ -335,7 +335,7 @@ bool ParticleEmitterGraphCPUExecutor::ComputeBounds(ParticleEmitter* emitter, Pa
|
||||
maxRadius = Math::Max(*((float*)radius), maxRadius);
|
||||
radius += stride;
|
||||
}
|
||||
ASSERT(!isnan(maxRadius) && !isinf(maxRadius));
|
||||
CHECK_RETURN(!isnan(maxRadius) && !isinf(maxRadius), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -335,6 +335,7 @@ void Cloth::DrawPhysicsDebug(RenderView& view)
|
||||
#if WITH_CLOTH && COMPILE_WITH_DEBUG_DRAW
|
||||
if (_cloth)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
const ModelInstanceActor::MeshReference mesh = GetMesh();
|
||||
if (mesh.Actor == nullptr)
|
||||
return;
|
||||
|
||||
@@ -59,7 +59,7 @@ API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings", NoConstructor) class
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The default gravity force value (in cm^2/s).
|
||||
/// The default gravity value (in cm/(s^2)).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(0), EditorDisplay(\"Simulation\")")
|
||||
Vector3 DefaultGravity = Vector3(0, -981.0f, 0);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user