From 72bd15299936a7b3b1f3cc633adc723156df7a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Sun, 10 Mar 2024 13:01:05 +0100 Subject: [PATCH] Refactor --- .../src/EditWindows/EntityHierarchyWindow.bf | 174 ++++++++++-------- GlitchyEngine/src/World/Scene.bf | 6 + GlitchyEngine/src/World/SceneRenderer.bf | 21 ++- 3 files changed, 122 insertions(+), 79 deletions(-) diff --git a/GlitchyEditor/src/EditWindows/EntityHierarchyWindow.bf b/GlitchyEditor/src/EditWindows/EntityHierarchyWindow.bf index c144528..c3af9b0 100644 --- a/GlitchyEditor/src/EditWindows/EntityHierarchyWindow.bf +++ b/GlitchyEditor/src/EditWindows/EntityHierarchyWindow.bf @@ -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 tree) + /// Shows the given entity and it's children as a tree. + private void ImGuiPrintEntityTree(TreeNode 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,90 +589,89 @@ 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 root = scope .(Entity(.InvalidEntity, _scene)); - if (_scene == null) + TreeNode InsertIntoTree(Entity entity) { - ImGui.TextUnformatted(""); - return; + var transform = entity.GetComponent(); + + 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 - - TreeNode root = scope .(Entity(.InvalidEntity, _scene)); + Entity entity = .(entityId, _scene); - TreeNode InsertIntoTree(Entity entity) + InsertIntoTree(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? payload = ImGui.AcceptDragDropPayload(.Entity); + + if(payload != null) { - var transform = entity.GetComponent(); - - 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? payload = ImGui.AcceptDragDropPayload(.Entity); - - if(payload != null) - { - UUID movedEntityId = payload->Data; - - Entity movedEntity = _editor.CurrentScene.GetEntityByID(movedEntityId); - var transformComponent = movedEntity.GetComponent(); 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 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 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(""); + 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 diff --git a/GlitchyEngine/src/World/Scene.bf b/GlitchyEngine/src/World/Scene.bf index 976ddab..98f5c79 100644 --- a/GlitchyEngine/src/World/Scene.bf +++ b/GlitchyEngine/src/World/Scene.bf @@ -9,6 +9,7 @@ using GlitchyEngine.Scripting; using GlitchyEngine.Math; using GlitchyEngine.Scripting.Classes; using GlitchyEngine.Serialization; +using GlitchyEngine.World.Components; namespace GlitchyEngine.World { @@ -800,6 +801,11 @@ namespace GlitchyEngine.World let nameComponent = entity.AddComponent(); nameComponent.Name = (name.IsEmpty ? "Entity" : name); + +#if GE_EDITOR + // Only add the editor flags if we are indeed in an editor + entity.AddComponent(); +#endif // If no id is given generate a random one. IDComponent idComponent = (id == default) ? IDComponent() : IDComponent(id); diff --git a/GlitchyEngine/src/World/SceneRenderer.bf b/GlitchyEngine/src/World/SceneRenderer.bf index eb5d7ea..c0347ae 100644 --- a/GlitchyEngine/src/World/SceneRenderer.bf +++ b/GlitchyEngine/src/World/SceneRenderer.bf @@ -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()) + for (var (entity, transform, mesh, meshRenderer, editorFlags) in Scene._ecsWorld.Enumerate()) { + 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()) + for (var (entity, transform, light, editorFlags) in Scene._ecsWorld.Enumerate()) { + 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()) + for (var (entity, transform, sprite, editorFlags) in Scene._ecsWorld.Enumerate()) { + if (editorFlags.Flags.HasFlag(.HideInScene)) + continue; + Renderer2D.DrawSprite(transform.WorldTransform, sprite, entity.Index); } - for (var (entity, transform, circle) in Scene._ecsWorld.Enumerate()) + for (var (entity, transform, circle, editorFlags) in Scene._ecsWorld.Enumerate()) { + if (editorFlags.Flags.HasFlag(.HideInScene)) + continue; + Renderer2D.DrawCircle(transform.WorldTransform, circle, entity.Index); }