This commit is contained in:
Simon Lübeß
2024-03-10 13:01:05 +01:00
parent 8d92822845
commit 72bd152999
3 changed files with 122 additions and 79 deletions
@@ -365,9 +365,8 @@ namespace GlitchyEditor.EditWindows
return deleted;
}
private void ShowVisibilityButton(Entity entity)
private void ShowVisibilityToggleButton(Entity entity)
{
ImGui.PushStyleVar(.WindowPadding, ImGui.Vec2(0, 2));
ImGui.PushStyleVar(.ItemInnerSpacing, ImGui.Vec2(0, 0));
ImGui.PushStyleColor(.Button, ImGui.Vec4(0, 0, 0, 0));
@@ -413,10 +412,11 @@ namespace GlitchyEditor.EditWindows
}
ImGui.PopStyleColor(3);
ImGui.PopStyleVar(2);
ImGui.PopStyleVar(1);
}
private void ImGuiPrintEntityTree(TreeNode<Entity> tree)
/// Shows the given entity and it's children as a tree.
private void ImGuiPrintEntityTree(TreeNode<Entity> tree, bool flat = false)
{
Entity entity = tree.Value;
@@ -428,7 +428,7 @@ namespace GlitchyEditor.EditWindows
ImGui.TableNextRow();
ImGui.TableNextColumn();
ShowVisibilityButton(entity);
ShowVisibilityToggleButton(entity);
ImGui.TableNextColumn();
@@ -507,7 +507,8 @@ namespace GlitchyEditor.EditWindows
ImGui.EndDragDropSource();
}
EntityDropTarget(entity);
if (!flat)
EntityDropTarget(entity);
bool clicked = ImGui.IsItemClicked() && !ImGui.IsItemToggledOpen();
bool clickedRight = ImGui.IsItemClicked(.Right);
@@ -588,89 +589,88 @@ namespace GlitchyEditor.EditWindows
private static Entity lastClickedEntity;
private void ShowEntityHierarchy()
/// Shows the entity hierarchy as a tree.
private void ShowUnfilteredEntityHierarchy()
{
StringView searchString = StringView(&_entitySearchChars);
TreeNode<Entity> root = scope .(Entity(.InvalidEntity, _scene));
if (_scene == null)
TreeNode<Entity> InsertIntoTree(Entity entity)
{
ImGui.TextUnformatted("<No scene open>");
return;
var transform = entity.GetComponent<TransformComponent>();
if(transform == null)
{
return root.AddChild(entity);
}
else
{
var parentEntity = Entity(transform.Parent, _scene);
var parentNode = root.FindNode(parentEntity);
if(parentNode == null)
parentNode = InsertIntoTree(parentEntity);
return parentNode.AddChild(entity);
}
}
if(searchString.IsWhiteSpace)
for(var entityId in _scene.[Friend]_ecsWorld.Enumerate())
{
// Show entity hierarchy as tree
Entity entity = .(entityId, _scene);
TreeNode<Entity> root = scope .(Entity(.InvalidEntity, _scene));
InsertIntoTree(entity);
}
TreeNode<Entity> InsertIntoTree(Entity entity)
// Rectangle over the entire window space
ImGui.Rect rect = .();
rect.Min = (ImGui.Vec2)((float2)ImGui.GetWindowContentRegionMin() + (float2)ImGui.GetWindowPos());
rect.Max = (ImGui.Vec2)((float2)rect.Min + (float2)ImGui.GetContentRegionAvail());
// Use window background as drop target to drop entities into scene root
if(ImGui.BeginDragDropTargetCustom(rect, ImGui.GetID("sceneDropTarget")))
{
Payload<UUID>? payload = ImGui.AcceptDragDropPayload<UUID>(.Entity);
if(payload != null)
{
var transform = entity.GetComponent<TransformComponent>();
if(transform == null)
if (_editor.CurrentScene.GetEntityByID(payload->Data) case .Ok(let movedEntity))
{
return root.AddChild(entity);
}
else
{
var parentEntity = Entity(transform.Parent, _scene);
var parentNode = root.FindNode(parentEntity);
if(parentNode == null)
parentNode = InsertIntoTree(parentEntity);
return parentNode.AddChild(entity);
}
}
for(var entityId in _scene.[Friend]_ecsWorld.Enumerate())
{
Entity entity = .(entityId, _scene);
InsertIntoTree(entity);
}
ImGui.Rect rect = .();
rect.Min = (ImGui.Vec2)((float2)ImGui.GetWindowContentRegionMin() + (float2)ImGui.GetWindowPos());
rect.Max = (ImGui.Vec2)((float2)rect.Min + (float2)ImGui.GetContentRegionAvail());
if(ImGui.BeginDragDropTargetCustom(rect, ImGui.GetID("sceneDropTarget")))
{
Payload<UUID>? payload = ImGui.AcceptDragDropPayload<UUID>(.Entity);
if(payload != null)
{
UUID movedEntityId = payload->Data;
Entity movedEntity = _editor.CurrentScene.GetEntityByID(movedEntityId);
var transformComponent = movedEntity.GetComponent<TransformComponent>();
transformComponent.Parent = .InvalidEntity;
}
ImGui.EndDragDropTarget();
}
if (ImGui.BeginTable("entityTable", 2, .RowBg | .NoBordersInBody | .SizingFixedFit))
{
ImGui.TableSetupColumn("Visibility", .IndentDisable | .NoResize);
ImGui.TableSetupColumn("Entities", .IndentEnable | .WidthStretch);
for(var child in root.Children)
else
{
ImGuiPrintEntityTree(child);
Log.EngineLogger.Error($"Tried to move entity with id {payload->Data} into scene root, but the entity doesn't exist.");
}
ImGui.EndTable();
}
}
else
{
// Show search results as flat list
List<StringView> searchTokens = new:ScopedAlloc! .(searchString.Split(' ', .RemoveEmptyEntries));
ImGui.EndDragDropTarget();
}
if (ImGui.BeginTable("entityTable", 2, .RowBg | .NoBordersInBody | .SizingFixedFit))
{
ImGui.TableSetupColumn("", .IndentDisable | .NoResize);
ImGui.TableSetupColumn("Entities", .IndentEnable | .WidthStretch);
for(var child in root.Children)
{
ImGuiPrintEntityTree(child);
}
ImGui.EndTable();
}
}
/// Shows a list of entities that match the search query.
private void ShowFilteredEntityList(StringView searchString)
{
List<StringView> searchTokens = scope .(searchString.Split(' ', .RemoveEmptyEntries));
if (ImGui.BeginTable("entityTable", 2, .RowBg | .NoBordersInBody | .SizingFixedFit))
{
ImGui.TableSetupColumn("Visibility", .IndentDisable | .NoResize);
ImGui.TableSetupColumn("Entities", .IndentEnable | .WidthStretch);
worldEnumeration:
for(var entityId in _scene.[Friend]_ecsWorld.Enumerate())
@@ -700,8 +700,32 @@ namespace GlitchyEditor.EditWindows
}
}
ImGuiPrintEntityTree(scope .(entity));
ImGuiPrintEntityTree(scope .(entity), true);
}
ImGui.EndTable();
}
}
/// Shows the entity hierarchy either as tree or as filtered list.
private void ShowEntityHierarchy()
{
StringView searchString = StringView(&_entitySearchChars);
if (_scene == null)
{
ImGui.TextUnformatted("<No scene open>");
return;
}
if(searchString.IsWhiteSpace)
{
ShowUnfilteredEntityHierarchy();
}
else
{
ShowFilteredEntityList(searchString);
}
// If the mouse was released and no entity took the chance to become selected we probably hovered the background while releasing -> select no entity
+6
View File
@@ -9,6 +9,7 @@ using GlitchyEngine.Scripting;
using GlitchyEngine.Math;
using GlitchyEngine.Scripting.Classes;
using GlitchyEngine.Serialization;
using GlitchyEngine.World.Components;
namespace GlitchyEngine.World
{
@@ -801,6 +802,11 @@ namespace GlitchyEngine.World
let nameComponent = entity.AddComponent<NameComponent>();
nameComponent.Name = (name.IsEmpty ? "Entity" : name);
#if GE_EDITOR
// Only add the editor flags if we are indeed in an editor
entity.AddComponent<EditorFlagsComponent>();
#endif
// If no id is given generate a random one.
IDComponent idComponent = (id == default) ? IDComponent() : IDComponent(id);
+17 -4
View File
@@ -2,6 +2,7 @@ using GlitchyEngine.Renderer;
using GlitchyEngine.Content;
using GlitchyEngine.Math;
using System;
using GlitchyEngine.World.Components;
namespace GlitchyEngine.World;
@@ -156,16 +157,22 @@ class SceneRenderer
// 3D render
Renderer.BeginScene(camera, _compositeTarget);
for (var (entity, transform, mesh, meshRenderer) in Scene._ecsWorld.Enumerate<TransformComponent, MeshComponent, MeshRendererComponent>())
for (var (entity, transform, mesh, meshRenderer, editorFlags) in Scene._ecsWorld.Enumerate<TransformComponent, MeshComponent, MeshRendererComponent, EditorFlagsComponent>())
{
if (editorFlags.Flags.HasFlag(.HideInScene))
continue;
if (mesh.Mesh == .Invalid || meshRenderer.Material == .Invalid)
continue;
Renderer.Submit(mesh.Mesh, meshRenderer.Material, entity, transform.WorldTransform);
}
for (var (entity, transform, light) in Scene._ecsWorld.Enumerate<TransformComponent, LightComponent>())
for (var (entity, transform, light, editorFlags) in Scene._ecsWorld.Enumerate<TransformComponent, LightComponent, EditorFlagsComponent>())
{
if (editorFlags.Flags.HasFlag(.HideInScene))
continue;
Renderer.Submit(light.SceneLight, transform.WorldTransform);
}
@@ -182,13 +189,19 @@ class SceneRenderer
// Sprite renderer
Renderer2D.BeginScene(camera, .BackToFront);
for (var (entity, transform, sprite) in Scene._ecsWorld.Enumerate<TransformComponent, SpriteRendererComponent>())
for (var (entity, transform, sprite, editorFlags) in Scene._ecsWorld.Enumerate<TransformComponent, SpriteRendererComponent, EditorFlagsComponent>())
{
if (editorFlags.Flags.HasFlag(.HideInScene))
continue;
Renderer2D.DrawSprite(transform.WorldTransform, sprite, entity.Index);
}
for (var (entity, transform, circle) in Scene._ecsWorld.Enumerate<TransformComponent, CircleRendererComponent>())
for (var (entity, transform, circle, editorFlags) in Scene._ecsWorld.Enumerate<TransformComponent, CircleRendererComponent, EditorFlagsComponent>())
{
if (editorFlags.Flags.HasFlag(.HideInScene))
continue;
Renderer2D.DrawCircle(transform.WorldTransform, circle, entity.Index);
}