diff --git a/Source/Editor/Tools/Foliage/EditFoliageGizmoMode.cs b/Source/Editor/Tools/Foliage/EditFoliageGizmoMode.cs
index 181bc1d17..e9102fb12 100644
--- a/Source/Editor/Tools/Foliage/EditFoliageGizmoMode.cs
+++ b/Source/Editor/Tools/Foliage/EditFoliageGizmoMode.cs
@@ -17,7 +17,7 @@ namespace FlaxEditor.Tools.Foliage
private int _selectedInstanceIndex = -1;
///
- /// The foliage painting gizmo.
+ /// The foliage editing gizmo.
///
public EditFoliageGizmo Gizmo;
@@ -66,8 +66,6 @@ namespace FlaxEditor.Tools.Foliage
base.Init(owner);
Gizmo = new EditFoliageGizmo(owner, this);
- SelectionOutline = FlaxEngine.Object.New();
- SelectionOutline.GizmoMode = this;
}
///
@@ -84,6 +82,11 @@ namespace FlaxEditor.Tools.Foliage
base.OnActivated();
Owner.Gizmos.Active = Gizmo;
+ if (SelectionOutline == null)
+ {
+ SelectionOutline = FlaxEngine.Object.New();
+ SelectionOutline.GizmoMode = this;
+ }
((MainEditorGizmoViewport)Owner).OverrideSelectionOutline(SelectionOutline);
SelectedInstanceIndex = -1;
}
diff --git a/Source/Editor/Tools/Foliage/EditFoliageSelectionOutline.cs b/Source/Editor/Tools/Foliage/EditFoliageSelectionOutline.cs
index 309b62ed3..ee078ea4e 100644
--- a/Source/Editor/Tools/Foliage/EditFoliageSelectionOutline.cs
+++ b/Source/Editor/Tools/Foliage/EditFoliageSelectionOutline.cs
@@ -6,7 +6,7 @@ using FlaxEngine;
namespace FlaxEditor.Tools.Foliage
{
///
- /// The custom outline for drawing the selected foliage instances outlines.
+ /// The custom outline for drawing the selected foliage instance.
///
///
[HideInEditor]
diff --git a/Source/Editor/Tools/Foliage/FoliageTab.cs b/Source/Editor/Tools/Foliage/FoliageTab.cs
index f893049ae..da5142070 100644
--- a/Source/Editor/Tools/Foliage/FoliageTab.cs
+++ b/Source/Editor/Tools/Foliage/FoliageTab.cs
@@ -5,7 +5,6 @@ using System.Collections.Generic;
using FlaxEditor.GUI.Tabs;
using FlaxEditor.Modules;
using FlaxEditor.SceneGraph.Actors;
-using FlaxEditor.Viewport.Modes;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -214,7 +213,7 @@ namespace FlaxEditor.Tools.Foliage
private void InitSculptMode()
{
- var tab = _modes.AddTab(FoliageTypes = new FoliageTypesTab(this));
+ var tab = _modes.AddTab(FoliageTypes = new FoliageTypesTab(this, Editor.Windows.EditWin.Viewport.EditFoliageTypesGizmo));
tab.Selected += OnTabSelected;
}
@@ -251,7 +250,7 @@ namespace FlaxEditor.Tools.Foliage
switch (_modes.SelectedTabIndex)
{
case 0:
- Editor.Windows.EditWin.Viewport.Gizmos.SetActiveMode();
+ Editor.Windows.EditWin.Viewport.Gizmos.SetActiveMode();
break;
case 1:
Editor.Windows.EditWin.Viewport.Gizmos.SetActiveMode();
diff --git a/Source/Editor/Tools/Foliage/FoliageTypesGizmo.cs b/Source/Editor/Tools/Foliage/FoliageTypesGizmo.cs
new file mode 100644
index 000000000..a4d95e388
--- /dev/null
+++ b/Source/Editor/Tools/Foliage/FoliageTypesGizmo.cs
@@ -0,0 +1,44 @@
+// Copyright (c) Wojciech Figat. All rights reserved.
+
+using FlaxEditor.Gizmo;
+
+namespace FlaxEditor.Tools.Foliage
+{
+ ///
+ /// Gizmo for editing foliage types.
+ ///
+ public sealed class FoliageTypesGizmo : GizmoBase
+ {
+ ///
+ /// The parent mode.
+ ///
+ public readonly FoliageTypesGizmoMode GizmoMode;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The owner.
+ /// The mode.
+ public FoliageTypesGizmo(IGizmoOwner owner, FoliageTypesGizmoMode mode)
+ : base(owner)
+ {
+ GizmoMode = mode;
+ }
+
+ ///
+ public override void Pick()
+ {
+ // Get mouse ray and try to hit foliage instance
+ var foliage = GizmoMode.SelectedFoliage;
+ if (!foliage)
+ return;
+ var ray = Owner.MouseRay;
+ if (foliage.Intersects(ref ray, out _, out _, out var instanceIndex))
+ {
+ // Select hit instance type
+ var instance = foliage.GetInstance(instanceIndex);
+ GizmoMode.SelectedTypeIndex = instance.Type;
+ }
+ }
+ }
+}
diff --git a/Source/Editor/Tools/Foliage/FoliageTypesGizmoMode.cs b/Source/Editor/Tools/Foliage/FoliageTypesGizmoMode.cs
new file mode 100644
index 000000000..0fed59181
--- /dev/null
+++ b/Source/Editor/Tools/Foliage/FoliageTypesGizmoMode.cs
@@ -0,0 +1,86 @@
+// Copyright (c) Wojciech Figat. All rights reserved.
+
+using FlaxEditor.Gizmo;
+using FlaxEditor.SceneGraph.Actors;
+using FlaxEditor.Viewport;
+using FlaxEditor.Viewport.Modes;
+
+namespace FlaxEditor.Tools.Foliage
+{
+ ///
+ /// Foliage types editing mode.
+ ///
+ ///
+ public class FoliageTypesGizmoMode : EditorGizmoMode
+ {
+ ///
+ /// The foliage types gizmo.
+ ///
+ public FoliageTypesGizmo Gizmo;
+
+ ///
+ /// The foliage type editing selection outline.
+ ///
+ public FoliageTypesOutline SelectionOutline;
+
+ ///
+ /// The selected foliage type index.
+ ///
+ public int SelectedTypeIndex
+ {
+ get => Editor.Instance.Windows.ToolboxWin.Foliage.SelectedFoliageTypeIndex;
+ set => Editor.Instance.Windows.ToolboxWin.Foliage.SelectedFoliageTypeIndex = value;
+ }
+
+ ///
+ /// Gets the selected foliage actor (see ).
+ ///
+ public FlaxEngine.Foliage SelectedFoliage
+ {
+ get
+ {
+ var sceneEditing = Editor.Instance.SceneEditing;
+ var foliageNode = sceneEditing.SelectionCount == 1 ? sceneEditing.Selection[0] as FoliageNode : null;
+ return (FlaxEngine.Foliage)foliageNode?.Actor;
+ }
+ }
+
+ ///
+ public override void Init(IGizmoOwner owner)
+ {
+ base.Init(owner);
+
+ Gizmo = new FoliageTypesGizmo(owner, this);
+ }
+
+ ///
+ public override void Dispose()
+ {
+ FlaxEngine.Object.Destroy(ref SelectionOutline);
+
+ base.Dispose();
+ }
+
+ ///
+ public override void OnActivated()
+ {
+ base.OnActivated();
+
+ Owner.Gizmos.Active = Gizmo;
+ if (SelectionOutline == null)
+ {
+ SelectionOutline = FlaxEngine.Object.New();
+ SelectionOutline.GizmoMode = this;
+ }
+ ((MainEditorGizmoViewport)Owner).OverrideSelectionOutline(SelectionOutline);
+ }
+
+ ///
+ public override void OnDeactivated()
+ {
+ ((MainEditorGizmoViewport)Owner).OverrideSelectionOutline(null);
+
+ base.OnDeactivated();
+ }
+ }
+}
diff --git a/Source/Editor/Tools/Foliage/FoliageTypesOutline.cs b/Source/Editor/Tools/Foliage/FoliageTypesOutline.cs
new file mode 100644
index 000000000..dfd773e58
--- /dev/null
+++ b/Source/Editor/Tools/Foliage/FoliageTypesOutline.cs
@@ -0,0 +1,62 @@
+// Copyright (c) Wojciech Figat. All rights reserved.
+
+using FlaxEditor.Gizmo;
+using FlaxEngine;
+
+namespace FlaxEditor.Tools.Foliage
+{
+ ///
+ /// The custom outline for drawing the selected foliage type.
+ ///
+ ///
+ [HideInEditor]
+ public class FoliageTypesOutline : SelectionOutline
+ {
+ ///
+ /// The parent mode.
+ ///
+ public FoliageTypesGizmoMode GizmoMode;
+
+ ///
+ public override bool CanRender()
+ {
+ if (!HasDataReady)
+ return false;
+
+ var foliage = GizmoMode.SelectedFoliage;
+ if (!foliage)
+ return false;
+ var typeIndex = GizmoMode.SelectedTypeIndex;
+ if (typeIndex < 0 || typeIndex >= foliage.FoliageTypesCount)
+ return false;
+ return true;
+ }
+
+ ///
+ public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
+ {
+ base.Render(context, ref renderContext, input, output);
+
+ // Restore debug option
+ var foliage = GizmoMode.SelectedFoliage;
+ if (foliage)
+ foliage._drawFoliageType = -1;
+ }
+
+ ///
+ protected override void DrawSelectionDepth(GPUContext context, SceneRenderTask task, GPUTexture customDepth)
+ {
+ var foliage = GizmoMode.SelectedFoliage;
+ if (!foliage)
+ return;
+ var typeIndex = GizmoMode.SelectedTypeIndex;
+ if (typeIndex < 0 || typeIndex >= foliage.FoliageTypesCount)
+ return;
+
+ // Draw instances of the given type
+ foliage._drawFoliageType = typeIndex;
+ _actors.Add(foliage);
+ Renderer.DrawSceneDepth(context, task, customDepth, _actors);
+ }
+ }
+}
diff --git a/Source/Editor/Tools/Foliage/FoliageTypesTab.cs b/Source/Editor/Tools/Foliage/FoliageTypesTab.cs
index 33c3c1fb5..18dc948cd 100644
--- a/Source/Editor/Tools/Foliage/FoliageTypesTab.cs
+++ b/Source/Editor/Tools/Foliage/FoliageTypesTab.cs
@@ -334,7 +334,8 @@ namespace FlaxEditor.Tools.Foliage
/// Initializes a new instance of the class.
///
/// The parent tab.
- public FoliageTypesTab(FoliageTab tab)
+ /// The gizmo mode.
+ public FoliageTypesTab(FoliageTab tab, FoliageTypesGizmoMode mode)
: base("Foliage Types")
{
Tab = tab;
diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs
index a9eab5ceb..debec1a14 100644
--- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs
+++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs
@@ -179,12 +179,17 @@ namespace FlaxEditor.Viewport
public Tools.Terrain.EditTerrainGizmoMode EditTerrainGizmo;
///
- /// The paint foliage gizmo.
+ /// The edit foliage types gizmo.
+ ///
+ public Tools.Foliage.FoliageTypesGizmoMode EditFoliageTypesGizmo;
+
+ ///
+ /// The paint foliage instances gizmo.
///
public Tools.Foliage.PaintFoliageGizmoMode PaintFoliageGizmo;
///
- /// The edit foliage gizmo.
+ /// The edit foliage instances gizmo.
///
public Tools.Foliage.EditFoliageGizmoMode EditFoliageGizmo;
@@ -276,6 +281,7 @@ namespace FlaxEditor.Viewport
Gizmos.AddMode(SculptTerrainGizmo = new Tools.Terrain.SculptTerrainGizmoMode());
Gizmos.AddMode(PaintTerrainGizmo = new Tools.Terrain.PaintTerrainGizmoMode());
Gizmos.AddMode(EditTerrainGizmo = new Tools.Terrain.EditTerrainGizmoMode());
+ Gizmos.AddMode(EditFoliageTypesGizmo = new Tools.Foliage.FoliageTypesGizmoMode());
Gizmos.AddMode(PaintFoliageGizmo = new Tools.Foliage.PaintFoliageGizmoMode());
Gizmos.AddMode(EditFoliageGizmo = new Tools.Foliage.EditFoliageGizmoMode());
@@ -343,10 +349,12 @@ namespace FlaxEditor.Viewport
/// The custom selection outline or null if use default one.
public void OverrideSelectionOutline(SelectionOutline customSelectionOutline)
{
+ if (Task == null)
+ return;
+
if (_customSelectionOutline != null)
{
Task.RemoveCustomPostFx(_customSelectionOutline);
- Object.Destroy(ref _customSelectionOutline);
Task.AddCustomPostFx(customSelectionOutline ? customSelectionOutline : SelectionOutline);
}
else if (customSelectionOutline != null)
@@ -857,8 +865,8 @@ namespace FlaxEditor.Viewport
if (_task != null)
{
// Release if task is not used to save screenshot for project icon
+ ReleaseTaskResources();
Object.Destroy(ref _task);
- ReleaseResources();
}
base.OnDestroy();
@@ -874,6 +882,7 @@ namespace FlaxEditor.Viewport
_savedTask = _task;
_savedBackBuffer = _backBuffer;
+ ReleaseTaskResources();
_task = null;
_backBuffer = null;
}
@@ -884,20 +893,20 @@ namespace FlaxEditor.Viewport
{
_savedTask.Enabled = false;
Object.Destroy(_savedTask);
- ReleaseResources();
+ ReleaseTaskResources();
_savedTask = null;
}
Object.Destroy(ref _savedBackBuffer);
}
- private void ReleaseResources()
+ private void ReleaseTaskResources()
{
- if (Task)
+ if (_task)
{
- Task.RemoveCustomPostFx(SelectionOutline);
- Task.RemoveCustomPostFx(EditorPrimitives);
- Task.RemoveCustomPostFx(_editorSpritesRenderer);
- Task.RemoveCustomPostFx(_customSelectionOutline);
+ _task.RemoveCustomPostFx(SelectionOutline);
+ _task.RemoveCustomPostFx(EditorPrimitives);
+ _task.RemoveCustomPostFx(_editorSpritesRenderer);
+ _task.RemoveCustomPostFx(_customSelectionOutline);
}
Object.Destroy(ref SelectionOutline);
Object.Destroy(ref EditorPrimitives);
diff --git a/Source/Engine/Foliage/Foliage.cpp b/Source/Engine/Foliage/Foliage.cpp
index c9e18ac9f..9b97e0e95 100644
--- a/Source/Engine/Foliage/Foliage.cpp
+++ b/Source/Engine/Foliage/Foliage.cpp
@@ -29,7 +29,7 @@
#include
#define FOLIAGE_GET_DRAW_MODES(renderContext, type) (type._drawModes & renderContext.View.Pass & renderContext.View.GetShadowsDrawPassMask(type.ShadowsMode))
-#define FOLIAGE_CAN_DRAW(renderContext, type) (type.IsReady() && FOLIAGE_GET_DRAW_MODES(renderContext, type) != DrawPass::None && type.Model->CanBeRendered())
+#define FOLIAGE_CAN_DRAW(renderContext, type) (type.IsReady() && type._canDraw && FOLIAGE_GET_DRAW_MODES(renderContext, type) != DrawPass::None && type.Model->CanBeRendered())
Foliage::Foliage(const SpawnParams& params)
: Actor(params)
@@ -620,14 +620,18 @@ void Foliage::PreDraw(const RenderView& view)
}
// Cache data per foliage instance type
- for (FoliageType& type : FoliageTypes)
- InitType(view, type);
+ for (int32 i = 0; i < FoliageTypes.Count(); i++)
+ InitType(view, i);
}
-void Foliage::InitType(const RenderView& view, FoliageType& type)
+void Foliage::InitType(const RenderView& view, int32 typeIndex)
{
+ FoliageType& type = FoliageTypes[typeIndex];
const DrawPass drawModes = type._drawModes & view.Pass & view.GetShadowsDrawPassMask(type.ShadowsMode);
type._canDraw = type.IsReady() && drawModes != DrawPass::None && type.Model && type.Model->CanBeRendered();
+#if USE_EDITOR
+ type._canDraw &= _drawFoliageType == -1 || _drawFoliageType == typeIndex;
+#endif
bool drawModesDirty = false;
for (int32 j = 0; j < type.Entries.Count(); j++)
{
@@ -1286,7 +1290,7 @@ void Foliage::Draw(RenderContext& renderContext)
// Draw single foliage instance projection into Global Surface Atlas
auto& instance = *(FoliageInstance*)GlobalSurfaceAtlasPass::Instance()->GetCurrentActorObject();
auto& type = FoliageTypes[instance.Type];
- InitType(renderContext.View, type);
+ InitType(renderContext.View, instance.Type);
Matrix world;
const Transform transform = _transform.LocalToWorld(instance.Transform);
renderContext.View.GetWorldMatrix(transform, world);
diff --git a/Source/Engine/Foliage/Foliage.h b/Source/Engine/Foliage/Foliage.h
index 948504736..b428ad356 100644
--- a/Source/Engine/Foliage/Foliage.h
+++ b/Source/Engine/Foliage/Foliage.h
@@ -217,7 +217,7 @@ private:
#endif
void PreDraw(const RenderView& view);
- void InitType(const RenderView& view, FoliageType& type);
+ void InitType(const RenderView& view, int32 typeIndex);
void UpdateBounds();
public:
@@ -231,6 +231,12 @@ public:
/// True whether the two objects intersected, otherwise false.
API_FUNCTION() bool Intersects(API_PARAM(Ref) const Ray& ray, API_PARAM(Out) Real& distance, API_PARAM(Out) Vector3& normal, API_PARAM(Out) int32& instanceIndex);
+private:
+#if USE_EDITOR
+ // Debug filter to draw only specific foliage type (in editor).
+ API_FIELD(Internal) int32 _drawFoliageType = -1;
+#endif
+
public:
// [Actor]
void Draw(RenderContext& renderContext) override;