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