diff --git a/Content/Engine/DefaultRadialMenu.flax b/Content/Engine/DefaultRadialMenu.flax
new file mode 100644
index 000000000..1159e4719
--- /dev/null
+++ b/Content/Engine/DefaultRadialMenu.flax
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d7c517175501d1b41143a9d2d81950bf0d91d0556cfebca5784e7ef2c4ba94cf
+size 20340
diff --git a/Content/Shaders/Editor/Grid.flax b/Content/Shaders/Editor/Grid.flax
new file mode 100644
index 000000000..1c87a1332
--- /dev/null
+++ b/Content/Shaders/Editor/Grid.flax
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ce516159bb427e1c2cbd48f86be17b2b3c065d2ecd6943aace05451853d6b3e1
+size 4626
diff --git a/Source/Editor/CustomEditors/CustomEditor.cs b/Source/Editor/CustomEditors/CustomEditor.cs
index c6f62746e..ca9bbc390 100644
--- a/Source/Editor/CustomEditors/CustomEditor.cs
+++ b/Source/Editor/CustomEditors/CustomEditor.cs
@@ -111,6 +111,11 @@ namespace FlaxEditor.CustomEditors
///
public PropertyNameLabel LinkedLabel;
+ ///
+ /// Gets the layout for this editor. Used to calculate bounds.
+ ///
+ public LayoutElementsContainer Layout => _layout;
+
internal virtual void Initialize(CustomEditorPresenter presenter, LayoutElementsContainer layout, ValueContainer values)
{
_layout = layout;
diff --git a/Source/Editor/CustomEditors/Editors/ActorTransformEditor.cs b/Source/Editor/CustomEditors/Editors/ActorTransformEditor.cs
index 3794bffc8..e341d4d4f 100644
--- a/Source/Editor/CustomEditors/Editors/ActorTransformEditor.cs
+++ b/Source/Editor/CustomEditors/Editors/ActorTransformEditor.cs
@@ -41,6 +41,13 @@ 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);
+ }
// Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
@@ -66,6 +73,13 @@ 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);
+ }
// Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
@@ -122,6 +136,13 @@ 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);
+ }
// Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
diff --git a/Source/Editor/CustomEditors/Editors/CollectionEditor.cs b/Source/Editor/CustomEditors/Editors/CollectionEditor.cs
index b06e2d55d..7c0670010 100644
--- a/Source/Editor/CustomEditors/Editors/CollectionEditor.cs
+++ b/Source/Editor/CustomEditors/Editors/CollectionEditor.cs
@@ -38,6 +38,9 @@ namespace FlaxEditor.CustomEditors.Editors
///
public readonly int Index;
+ private Rectangle _arrangeButtonRect;
+ private bool _arrangeButtonInUse;
+
///
/// Initializes a new instance of the class.
///
@@ -50,6 +53,12 @@ namespace FlaxEditor.CustomEditors.Editors
Index = index;
SetupContextMenu += OnSetupContextMenu;
+ _arrangeButtonRect = new Rectangle(2, 3, 12, 12);
+
+ // Extend margin of the label to support a dragging handle.
+ Margin m = Margin;
+ m.Left += 16;
+ Margin = m;
}
private void OnSetupContextMenu(PropertyNameLabel label, ContextMenu menu, CustomEditor linkedEditor)
@@ -71,6 +80,107 @@ namespace FlaxEditor.CustomEditors.Editors
b.Enabled = !Editor._readOnly;
}
+ ///
+ public override void OnEndMouseCapture()
+ {
+ base.OnEndMouseCapture();
+
+ _arrangeButtonInUse = false;
+ }
+
+
+ ///
+ public override void Draw()
+ {
+ base.Draw();
+ var style = FlaxEngine.GUI.Style.Current;
+
+ var mousePosition = PointFromScreen(Input.MouseScreenPosition);
+ var dragBarColor = _arrangeButtonRect.Contains(mousePosition) ? style.Foreground : style.ForegroundGrey;
+ Render2D.DrawSprite(FlaxEditor.Editor.Instance.Icons.DragBar12, _arrangeButtonRect, _arrangeButtonInUse ? Color.Orange : dragBarColor);
+ if (_arrangeButtonInUse && ArrangeAreaCheck(out _, out var arrangeTargetRect))
+ {
+ Render2D.FillRectangle(arrangeTargetRect, style.Selection);
+ }
+ }
+
+ private bool ArrangeAreaCheck(out int index, out Rectangle rect)
+ {
+ var child = Editor.ChildrenEditors[0];
+ var container = child.Layout.ContainerControl;
+ var mousePosition = container.PointFromScreen(Input.MouseScreenPosition);
+ var barSidesExtend = 20.0f;
+ var barHeight = 5.0f;
+ var barCheckAreaHeight = 40.0f;
+ var pos = mousePosition.Y + barCheckAreaHeight * 0.5f;
+
+ for (int i = 0; i < container.Children.Count / 2; i++)
+ {
+ var containerChild = container.Children[i * 2]; // times 2 to skip the value editor
+ if (Mathf.IsInRange(pos, containerChild.Top, containerChild.Top + barCheckAreaHeight) || (i == 0 && pos < containerChild.Top))
+ {
+ index = i;
+ var p1 = containerChild.UpperLeft;
+ rect = new Rectangle(PointFromParent(p1) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
+ return true;
+ }
+ }
+
+ var p2 = container.Children[((container.Children.Count / 2) - 1) * 2].BottomLeft;
+ if (pos > p2.Y)
+ {
+ index = (container.Children.Count / 2) - 1;
+ rect = new Rectangle(PointFromParent(p2) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
+ return true;
+ }
+
+ index = -1;
+ rect = Rectangle.Empty;
+ return false;
+ }
+
+ ///
+ public override bool OnMouseDown(Float2 location, MouseButton button)
+ {
+ if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
+ {
+ _arrangeButtonInUse = true;
+ Focus();
+ StartMouseCapture();
+ return true;
+ }
+
+ return base.OnMouseDown(location, button);
+ }
+
+ ///
+ public override bool OnMouseUp(Float2 location, MouseButton button)
+ {
+ if (button == MouseButton.Left && _arrangeButtonInUse)
+ {
+ _arrangeButtonInUse = false;
+ EndMouseCapture();
+ if (ArrangeAreaCheck(out var index, out _))
+ {
+ Editor.Shift(Index, index);
+ }
+ }
+
+ return base.OnMouseUp(location, button);
+ }
+
+ ///
+ public override void OnLostFocus()
+ {
+ if (_arrangeButtonInUse)
+ {
+ _arrangeButtonInUse = false;
+ EndMouseCapture();
+ }
+
+ base.OnLostFocus();
+ }
+
private void OnMoveUpClicked()
{
Editor.Move(Index, Index - 1);
@@ -106,6 +216,9 @@ namespace FlaxEditor.CustomEditors.Editors
private bool _canReorder = true;
+ private Rectangle _arrangeButtonRect;
+ private bool _arrangeButtonInUse;
+
public void Setup(CollectionEditor editor, int index, bool canReorder = true)
{
HeaderHeight = 18;
@@ -123,10 +236,92 @@ namespace FlaxEditor.CustomEditors.Editors
MouseButtonRightClicked += OnMouseButtonRightClicked;
if (_canReorder)
{
- // TODO: Drag drop
+ HeaderTextMargin = new Margin(18, 0, 0, 0);
+ _arrangeButtonRect = new Rectangle(16, 3, 12, 12);
}
}
+ private bool ArrangeAreaCheck(out int index, out Rectangle rect)
+ {
+ var container = Parent;
+ var mousePosition = container.PointFromScreen(Input.MouseScreenPosition);
+ var barSidesExtend = 20.0f;
+ var barHeight = 5.0f;
+ var barCheckAreaHeight = 40.0f;
+ var pos = mousePosition.Y + barCheckAreaHeight * 0.5f;
+
+ for (int i = 0; i < (container.Children.Count + 1) / 2; i++) // Add 1 to pretend there is a spacer at the end.
+ {
+ var containerChild = container.Children[i * 2]; // times 2 to skip the value editor
+ if (Mathf.IsInRange(pos, containerChild.Top, containerChild.Top + barCheckAreaHeight) || (i == 0 && pos < containerChild.Top))
+ {
+ index = i;
+ var p1 = containerChild.UpperLeft;
+ rect = new Rectangle(PointFromParent(p1) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
+ return true;
+ }
+ }
+
+ var p2 = container.Children[container.Children.Count - 1].BottomLeft;
+ if (pos > p2.Y)
+ {
+ index = ((container.Children.Count + 1) / 2) - 1;
+ rect = new Rectangle(PointFromParent(p2) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
+ return true;
+ }
+
+ index = -1;
+ rect = Rectangle.Empty;
+ return false;
+ }
+
+ public override void Draw()
+ {
+ base.Draw();
+ if (_canReorder)
+ {
+ var style = FlaxEngine.GUI.Style.Current;
+
+ var mousePosition = PointFromScreen(Input.MouseScreenPosition);
+ var dragBarColor = _arrangeButtonRect.Contains(mousePosition) ? style.Foreground : style.ForegroundGrey;
+ Render2D.DrawSprite(FlaxEditor.Editor.Instance.Icons.DragBar12, _arrangeButtonRect, _arrangeButtonInUse ? Color.Orange : dragBarColor);
+ if (_arrangeButtonInUse && ArrangeAreaCheck(out _, out var arrangeTargetRect))
+ {
+ Render2D.FillRectangle(arrangeTargetRect, style.Selection);
+ }
+ }
+ }
+
+ ///
+ public override bool OnMouseDown(Float2 location, MouseButton button)
+ {
+ if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
+ {
+ _arrangeButtonInUse = true;
+ Focus();
+ StartMouseCapture();
+ return true;
+ }
+
+ return base.OnMouseDown(location, button);
+ }
+
+ ///
+ public override bool OnMouseUp(Float2 location, MouseButton button)
+ {
+ if (button == MouseButton.Left && _arrangeButtonInUse)
+ {
+ _arrangeButtonInUse = false;
+ EndMouseCapture();
+ if (ArrangeAreaCheck(out var index, out _))
+ {
+ Editor.Shift(Index, index);
+ }
+ }
+
+ return base.OnMouseUp(location, button);
+ }
+
private void OnMouseButtonRightClicked(DropPanel panel, Float2 location)
{
if (LinkedEditor == null)
@@ -324,7 +519,6 @@ namespace FlaxEditor.CustomEditors.Editors
(elementType.GetProperties().Length == 1 && elementType.GetFields().Length == 0) ||
elementType.Equals(new ScriptType(typeof(JsonAsset))) ||
elementType.Equals(new ScriptType(typeof(SettingsBase)));
-
for (int i = 0; i < size; i++)
{
// Apply spacing
@@ -440,6 +634,39 @@ namespace FlaxEditor.CustomEditors.Editors
SetValue(cloned);
}
+ ///
+ /// Shifts the specified item at the given index and moves it through the list to the other item. It supports undo.
+ ///
+ /// Index of the source item.
+ /// Index of the destination to move to.
+ private void Shift(int srcIndex, int dstIndex)
+ {
+ if (IsSetBlocked)
+ return;
+
+ var cloned = CloneValues();
+ if (dstIndex > srcIndex)
+ {
+ for (int i = srcIndex; i < dstIndex; i++)
+ {
+ var tmp = cloned[i + 1];
+ cloned[i + 1] = cloned[i];
+ cloned[i] = tmp;
+ }
+ }
+ else
+ {
+ for (int i = srcIndex; i > dstIndex; i--)
+ {
+ var tmp = cloned[i - 1];
+ cloned[i - 1] = cloned[i];
+ cloned[i] = tmp;
+ }
+ }
+
+ SetValue(cloned);
+ }
+
///
/// Removes the item at the specified index. It supports undo.
///
diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs
index 034cecebf..6a1e804b8 100644
--- a/Source/Editor/Editor.cs
+++ b/Source/Editor/Editor.cs
@@ -1378,6 +1378,7 @@ namespace FlaxEditor
public byte AutoReloadScriptsOnMainWindowFocus;
public byte ForceScriptCompilationOnStartup;
public byte UseAssetImportPathRelative;
+ public byte EnableParticlesPreview;
public byte AutoRebuildCSG;
public float AutoRebuildCSGTimeoutMs;
public byte AutoRebuildNavMesh;
diff --git a/Source/Editor/GUI/Input/ColorValueBox.cs b/Source/Editor/GUI/Input/ColorValueBox.cs
index ec437ad5a..1531266e3 100644
--- a/Source/Editor/GUI/Input/ColorValueBox.cs
+++ b/Source/Editor/GUI/Input/ColorValueBox.cs
@@ -130,7 +130,7 @@ namespace FlaxEditor.GUI.Input
base.Draw();
var style = Style.Current;
- var r = new Rectangle(2, 2, Width - 4, Height - 4);
+ var r = new Rectangle(0, 0, Width, Height);
Render2D.FillRectangle(r, _value);
Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);
diff --git a/Source/Editor/GUI/ItemsListContextMenu.cs b/Source/Editor/GUI/ItemsListContextMenu.cs
index 78fbcd779..4a1793982 100644
--- a/Source/Editor/GUI/ItemsListContextMenu.cs
+++ b/Source/Editor/GUI/ItemsListContextMenu.cs
@@ -23,6 +23,9 @@ namespace FlaxEditor.GUI
[HideInEditor]
public class Item : Control
{
+ private bool _isStartsWithMatch;
+ private bool _isFullMatch;
+
///
/// The is mouse down flag.
///
@@ -43,6 +46,11 @@ namespace FlaxEditor.GUI
///
public string Category;
+ ///
+ /// A computed score for the context menu order
+ ///
+ public float SortScore;
+
///
/// Occurs when items gets clicked by the user.
///
@@ -61,44 +69,69 @@ namespace FlaxEditor.GUI
{
}
+ ///
+ /// Updates the
+ ///
+ public void UpdateScore()
+ {
+ SortScore = 0;
+
+ if (!Visible)
+ return;
+
+ if (_highlights is { Count: > 0 })
+ SortScore += 1;
+ if (_isStartsWithMatch)
+ SortScore += 2;
+ if (_isFullMatch)
+ SortScore += 5;
+ }
+
///
/// Updates the filter.
///
/// The filter text.
public void UpdateFilter(string filterText)
{
+ _isStartsWithMatch = _isFullMatch = false;
+
if (string.IsNullOrWhiteSpace(filterText))
{
// Clear filter
_highlights?.Clear();
Visible = true;
+ return;
}
- else
+
+ if (QueryFilterHelper.Match(filterText, Name, out var ranges))
{
- if (QueryFilterHelper.Match(filterText, Name, out var ranges))
- {
- // Update highlights
- if (_highlights == null)
- _highlights = new List(ranges.Length);
- else
- _highlights.Clear();
- var style = Style.Current;
- var font = style.FontSmall;
- for (int i = 0; i < ranges.Length; i++)
- {
- var start = font.GetCharPosition(Name, ranges[i].StartIndex);
- var end = font.GetCharPosition(Name, ranges[i].EndIndex);
- _highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
- }
- Visible = true;
- }
+ // Update highlights
+ if (_highlights == null)
+ _highlights = new List(ranges.Length);
else
+ _highlights.Clear();
+ var style = Style.Current;
+ var font = style.FontSmall;
+ for (int i = 0; i < ranges.Length; i++)
{
- // Hide
- _highlights?.Clear();
- Visible = false;
+ var start = font.GetCharPosition(Name, ranges[i].StartIndex);
+ var end = font.GetCharPosition(Name, ranges[i].EndIndex);
+ _highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
+
+ if (ranges[i].StartIndex <= 0)
+ {
+ _isStartsWithMatch = true;
+ if (ranges[i].Length == Name.Length)
+ _isFullMatch = true;
+ }
}
+ Visible = true;
+ return;
}
+
+ // Hide
+ _highlights?.Clear();
+ Visible = false;
}
///
@@ -178,7 +211,14 @@ namespace FlaxEditor.GUI
public override int Compare(Control other)
{
if (other is Item otherItem)
- return string.Compare(Name, otherItem.Name, StringComparison.Ordinal);
+ {
+ int order = -1 * SortScore.CompareTo(otherItem.SortScore);
+ if (order == 0)
+ {
+ order = string.Compare(Name, otherItem.Name, StringComparison.Ordinal);
+ }
+ return order;
+ }
return base.Compare(other);
}
}
@@ -249,7 +289,10 @@ namespace FlaxEditor.GUI
for (int i = 0; i < items.Count; i++)
{
if (items[i] is Item item)
+ {
item.UpdateFilter(_searchBox.Text);
+ item.UpdateScore();
+ }
}
if (_categoryPanels != null)
{
@@ -262,6 +305,7 @@ namespace FlaxEditor.GUI
if (category.Children[j] is Item item2)
{
item2.UpdateFilter(_searchBox.Text);
+ item2.UpdateScore();
anyVisible |= item2.Visible;
}
}
@@ -273,6 +317,8 @@ namespace FlaxEditor.GUI
}
}
+ SortItems();
+
UnlockChildrenRecursive();
PerformLayout(true);
_searchBox.Focus();
diff --git a/Source/Editor/GUI/Timeline/Tracks/MemberTrack.cs b/Source/Editor/GUI/Timeline/Tracks/MemberTrack.cs
index 0361ffe6f..b280c5758 100644
--- a/Source/Editor/GUI/Timeline/Tracks/MemberTrack.cs
+++ b/Source/Editor/GUI/Timeline/Tracks/MemberTrack.cs
@@ -363,6 +363,8 @@ namespace FlaxEditor.GUI.Timeline.Tracks
///
public override void OnDestroy()
{
+ if (_previewValue != null)
+ Timeline.ShowPreviewValuesChanged -= OnTimelineShowPreviewValuesChanged;
_previewValue = null;
_rightKey = null;
_addKey = null;
diff --git a/Source/Editor/Gizmo/GridGizmo.cs b/Source/Editor/Gizmo/GridGizmo.cs
index 74a16449e..b5fcf9a31 100644
--- a/Source/Editor/Gizmo/GridGizmo.cs
+++ b/Source/Editor/Gizmo/GridGizmo.cs
@@ -2,6 +2,7 @@
using System;
using FlaxEngine;
+using System.Runtime.InteropServices;
namespace FlaxEditor.Gizmo
{
@@ -15,91 +16,120 @@ namespace FlaxEditor.Gizmo
[HideInEditor]
private sealed class Renderer : PostProcessEffect
{
- private IntPtr _debugDrawContext;
+ [StructLayout(LayoutKind.Sequential)]
+ private struct Data
+ {
+ public Matrix WorldMatrix;
+ public Matrix ViewProjectionMatrix;
+ public Float4 GridColor;
+ public Float3 ViewPos;
+ public float Far;
+ public Float3 Padding;
+ public float GridSize;
+ }
+
+ private static readonly uint[] _triangles =
+ {
+ 0, 2, 1, // Face front
+ 1, 3, 0,
+ };
+
+ private GPUBuffer[] _vbs = new GPUBuffer[1];
+ private GPUBuffer _vertexBuffer;
+ private GPUBuffer _indexBuffer;
+ private GPUPipelineState _psGrid;
+ private Shader _shader;
public Renderer()
{
- Order = -100;
UseSingleTarget = true;
- Location = PostProcessEffectLocation.BeforeForwardPass;
+ Location = PostProcessEffectLocation.Default;
+ _shader = FlaxEngine.Content.LoadAsyncInternal("Shaders/Editor/Grid");
}
~Renderer()
{
- if (_debugDrawContext != IntPtr.Zero)
- {
- DebugDraw.FreeContext(_debugDrawContext);
- _debugDrawContext = IntPtr.Zero;
- }
+ Destroy(ref _psGrid);
+ Destroy(ref _vertexBuffer);
+ Destroy(ref _indexBuffer);
+ _shader = null;
}
- public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
+ public override unsafe void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
{
+ if (_shader == null)
+ return;
Profiler.BeginEventGPU("Editor Grid");
- if (_debugDrawContext == IntPtr.Zero)
- _debugDrawContext = DebugDraw.AllocateContext();
- DebugDraw.SetContext(_debugDrawContext);
- DebugDraw.UpdateContext(_debugDrawContext, 1.0f / Mathf.Max(Engine.FramesPerSecond, 1));
-
- var viewPos = (Vector3)renderContext.View.Position;
- var plane = new Plane(Vector3.Zero, Vector3.UnitY);
- var dst = CollisionsHelper.DistancePlanePoint(ref plane, ref viewPos);
-
var options = Editor.Instance.Options.Options;
- float space = options.Viewport.ViewportGridScale, size;
- if (dst <= 500.0f)
+ Float3 camPos = renderContext.View.WorldPosition;
+ float gridSize = renderContext.View.Far + 20000;
+
+ // Lazy-init resources
+ if (_vertexBuffer == null)
{
- size = 8000;
+ _vertexBuffer = new GPUBuffer();
+ var desc = GPUBufferDescription.Vertex(sizeof(Float3), 4);
+ _vertexBuffer.Init(ref desc);
}
- else if (dst <= 2000.0f)
+ if (_indexBuffer == null)
{
- space *= 2;
- size = 8000;
+ _indexBuffer = new GPUBuffer();
+ fixed (uint* ptr = _triangles)
+ {
+ var desc = GPUBufferDescription.Index(sizeof(uint), _triangles.Length, new IntPtr(ptr));
+ _indexBuffer.Init(ref desc);
+ }
}
- else
+ if (_psGrid == null)
{
- space *= 20;
- size = 100000;
+ _psGrid = new GPUPipelineState();
+ var desc = GPUPipelineState.Description.Default;
+ desc.BlendMode = BlendingMode.AlphaBlend;
+ desc.CullMode = CullMode.TwoSided;
+ desc.VS = _shader.GPU.GetVS("VS_Grid");
+ desc.PS = _shader.GPU.GetPS("PS_Grid");
+ _psGrid.Init(ref desc);
}
- float bigLineIntensity = 0.8f;
- Color bigColor = Color.Gray * bigLineIntensity;
- Color color = bigColor * 0.8f;
- int count = (int)(size / space);
- int midLine = count / 2;
- int bigLinesMod = count / 8;
-
- Vector3 start = new Vector3(0, 0, size * -0.5f);
- Vector3 end = new Vector3(0, 0, size * 0.5f);
-
- for (int i = 0; i <= count; i++)
+ // Update vertices of the plane
+ // TODO: perf this operation in a Vertex Shader
+ float y = 1.5f; // Add small bias to reduce Z-fighting with geometry at scene origin
+ var vertices = new Float3[]
{
- start.X = end.X = i * space + start.Z;
- Color lineColor = color;
- if (i == midLine)
- lineColor = Color.Blue * bigLineIntensity;
- else if (i % bigLinesMod == 0)
- lineColor = bigColor;
- DebugDraw.DrawLine(start, end, lineColor);
+ new Float3(-gridSize + camPos.X, y, -gridSize + camPos.Z),
+ new Float3(gridSize + camPos.X, y, gridSize + camPos.Z),
+ new Float3(-gridSize + camPos.X, y, gridSize + camPos.Z),
+ new Float3(gridSize + camPos.X, y, -gridSize + camPos.Z),
+ };
+ fixed (Float3* ptr = vertices)
+ {
+ context.UpdateBuffer(_vertexBuffer, new IntPtr(ptr), (uint)(sizeof(Float3) * vertices.Length));
}
- start = new Vector3(size * -0.5f, 0, 0);
- end = new Vector3(size * 0.5f, 0, 0);
-
- for (int i = 0; i <= count; i++)
+ // Update constant buffer data
+ var cb = _shader.GPU.GetCB(0);
+ if (cb != IntPtr.Zero)
{
- start.Z = end.Z = i * space + start.X;
- Color lineColor = color;
- if (i == midLine)
- lineColor = Color.Red * bigLineIntensity;
- else if (i % bigLinesMod == 0)
- lineColor = bigColor;
- DebugDraw.DrawLine(start, end, lineColor);
+ var data = new Data();
+ Matrix.Multiply(ref renderContext.View.View, ref renderContext.View.Projection, out var viewProjection);
+ data.WorldMatrix = Matrix.Identity;
+ Matrix.Transpose(ref viewProjection, out data.ViewProjectionMatrix);
+ data.ViewPos = renderContext.View.WorldPosition;
+ data.GridColor = options.Viewport.ViewportGridColor;
+ data.Far = renderContext.View.Far;
+ data.GridSize = options.Viewport.ViewportGridViewDistance;
+ context.UpdateCB(cb, new IntPtr(&data));
}
- DebugDraw.Draw(ref renderContext, input.View(), null, true);
- DebugDraw.SetContext(IntPtr.Zero);
+ // Draw geometry using custom Pixel Shader and Vertex Shader
+ context.BindCB(0, cb);
+ context.BindIB(_indexBuffer);
+ _vbs[0] = _vertexBuffer;
+ context.BindVB(_vbs);
+ context.SetState(_psGrid);
+ context.SetRenderTarget(renderContext.Buffers.DepthBuffer.View(), input.View());
+ context.DrawIndexed((uint)_triangles.Length);
Profiler.EndEventGPU();
}
diff --git a/Source/Editor/Managed/ManagedEditor.cpp b/Source/Editor/Managed/ManagedEditor.cpp
index c4c71bdfd..d0b060ffe 100644
--- a/Source/Editor/Managed/ManagedEditor.cpp
+++ b/Source/Editor/Managed/ManagedEditor.cpp
@@ -223,6 +223,19 @@ void ManagedEditor::Init()
{
LOG(Info, "Loading managed assemblies (due to disabled compilation on startup)");
Scripting::Load();
+
+ const auto endInitMethod = mclass->GetMethod("EndInit");
+ if (endInitMethod == nullptr)
+ {
+ LOG(Fatal, "Invalid Editor assembly! Missing EndInit method.");
+ }
+ endInitMethod->Invoke(instance, nullptr, &exception);
+ if (exception)
+ {
+ MException ex(exception);
+ ex.Log(LogType::Warning, TEXT("ManagedEditor::EndInit"));
+ LOG_STR(Fatal, TEXT("Failed to initialize editor during EndInit! ") + ex.Message);
+ }
}
// Call building if need to (based on CL)
diff --git a/Source/Editor/Managed/ManagedEditor.h b/Source/Editor/Managed/ManagedEditor.h
index e51749e5f..5c7907d17 100644
--- a/Source/Editor/Managed/ManagedEditor.h
+++ b/Source/Editor/Managed/ManagedEditor.h
@@ -27,6 +27,7 @@ API_CLASS(Namespace="FlaxEditor", Name="Editor", NoSpawn, NoConstructor) class M
byte AutoReloadScriptsOnMainWindowFocus = 1;
byte ForceScriptCompilationOnStartup = 1;
byte UseAssetImportPathRelative = 1;
+ byte EnableParticlesPreview = 1;
byte AutoRebuildCSG = 1;
float AutoRebuildCSGTimeoutMs = 50;
byte AutoRebuildNavMesh = 1;
diff --git a/Source/Editor/Modules/ContentFindingModule.cs b/Source/Editor/Modules/ContentFindingModule.cs
index 480844ac4..73e22d769 100644
--- a/Source/Editor/Modules/ContentFindingModule.cs
+++ b/Source/Editor/Modules/ContentFindingModule.cs
@@ -228,7 +228,7 @@ namespace FlaxEditor.Modules
new SearchResult { Name = item.ShortName, Type = assetItem.TypeName, Item = item }
};
}
- var actor = FlaxEngine.Object.Find(ref id);
+ var actor = FlaxEngine.Object.Find(ref id, true);
if (actor != null)
{
return new List
@@ -236,6 +236,16 @@ namespace FlaxEditor.Modules
new SearchResult { Name = actor.Name, Type = actor.TypeName, Item = actor }
};
}
+ var script = FlaxEngine.Object.Find