diff --git a/Nerfed.Editor/Components/SelectedInHierachy.cs b/Nerfed.Editor/Components/HierachyComponents.cs similarity index 64% rename from Nerfed.Editor/Components/SelectedInHierachy.cs rename to Nerfed.Editor/Components/HierachyComponents.cs index 8a46182..e858d3e 100644 --- a/Nerfed.Editor/Components/SelectedInHierachy.cs +++ b/Nerfed.Editor/Components/HierachyComponents.cs @@ -1,4 +1,4 @@ namespace Nerfed.Editor.Components; public readonly record struct SelectedInHierachy; -public readonly record struct ClickedInHierarchy; \ No newline at end of file +public readonly record struct ClickedInHierachy; \ No newline at end of file diff --git a/Nerfed.Editor/Nerfed.Editor.csproj b/Nerfed.Editor/Nerfed.Editor.csproj index 3e76714..ce46a3d 100644 --- a/Nerfed.Editor/Nerfed.Editor.csproj +++ b/Nerfed.Editor/Nerfed.Editor.csproj @@ -9,6 +9,7 @@ false Debug;Test;Release x64 + true diff --git a/Nerfed.Editor/Program.cs b/Nerfed.Editor/Program.cs index caefa0c..a5d46b0 100644 --- a/Nerfed.Editor/Program.cs +++ b/Nerfed.Editor/Program.cs @@ -31,6 +31,7 @@ private static void HandleOnInitialize() editorSystems.Add(new EditorHierarchyWindow(world)); Entity ent1 = world.CreateEntity("parent"); + world.Set(ent1, new Root()); world.Set(ent1, new LocalTransform(new Vector3(1, 0, 0), Quaternion.Identity, Vector3.One)); Entity ent2 = world.CreateEntity("child"); diff --git a/Nerfed.Editor/Systems/EditorHierarchyWindow.cs b/Nerfed.Editor/Systems/EditorHierarchyWindow.cs index 2dc52cc..28d3581 100644 --- a/Nerfed.Editor/Systems/EditorHierarchyWindow.cs +++ b/Nerfed.Editor/Systems/EditorHierarchyWindow.cs @@ -1,7 +1,9 @@ using ImGuiNET; using MoonTools.ECS; using Nerfed.Editor.Components; +using Nerfed.Runtime; using Nerfed.Runtime.Components; +using Nerfed.Runtime.Util; namespace Nerfed.Editor.Systems { @@ -10,7 +12,7 @@ internal class EditorHierarchyWindow : MoonTools.ECS.DebugSystem { private const ImGuiTreeNodeFlags baseFlags = ImGuiTreeNodeFlags.OpenOnArrow | ImGuiTreeNodeFlags.OpenOnDoubleClick | ImGuiTreeNodeFlags.SpanAvailWidth; - private readonly Filter rootEntitiesWithTransformFilter; + //private readonly Filter rootEntitiesWithTransformFilter; //private readonly Filter rootEntitiesFilterBroken; private readonly Filter rootEntitiesFilter; @@ -18,7 +20,7 @@ internal class EditorHierarchyWindow : MoonTools.ECS.DebugSystem public EditorHierarchyWindow(World world) : base(world) { - rootEntitiesWithTransformFilter = FilterBuilder.Include().Exclude().Build(); + //rootEntitiesWithTransformFilter = FilterBuilder.Include().Exclude().Build(); // TODO: this doesn't work. //rootEntitiesFilterBroken = FilterBuilder.Exclude().Build(); @@ -42,11 +44,29 @@ public override void Update(TimeSpan delta) if (ImGui.TreeNodeEx("World", flags)) { - foreach (Entity entity in rootEntitiesWithTransformFilter.Entities) + if (ImGui.BeginDragDropTarget()) { - DrawEntityAndChildren(entity); + unsafe + { + ImGuiPayloadPtr payload = ImGui.AcceptDragDropPayload($"{nameof(EditorHierarchyWindow)}"); + if (payload.NativePtr != null) + { + Entity* data = (Entity*)payload.Data; + Entity child = data[0]; + + Log.Info($"Dropped {child.ID}"); + + Transform.RemoveParent(World, child); + } + } + ImGui.EndDragDropTarget(); } + //foreach (Entity entity in rootEntitiesWithTransformFilter.Entities) + //{ + // DrawEntityAndChildren(entity); + //} + foreach (Entity entity in rootEntitiesFilter.Entities) { DrawEntityAndChildren(entity); @@ -76,9 +96,41 @@ private void DrawEntityAndChildren(in Entity entity) if (ImGui.TreeNodeEx($"{entity.ID} | {GetTag(entity)}", flags)) { + // Selection. if (ImGui.IsItemClicked() && !ImGui.IsItemToggledOpen()) { - World.Set(entity, new ClickedInHierarchy()); + World.Set(entity, new ClickedInHierachy()); + } + + // Drag and drop. + if (ImGui.BeginDragDropSource()) + { + unsafe + { + fixed (Entity* payload = &entity) + { + ImGui.SetDragDropPayload($"{nameof(EditorHierarchyWindow)}", (IntPtr)payload, (uint)sizeof(Entity)); + } + } + ImGui.EndDragDropSource(); + } + + if (ImGui.BeginDragDropTarget()) + { + unsafe + { + ImGuiPayloadPtr payload = ImGui.AcceptDragDropPayload($"{nameof(EditorHierarchyWindow)}"); + if (payload.NativePtr != null) + { + Entity* data = (Entity*)payload.Data; + Entity ent = data[0]; + + Log.Info($"Dropped {ent.ID}"); + + Transform.SetParent(World, ent, entity); + } + } + ImGui.EndDragDropTarget(); } ReverseSpanEnumerator childEntities = World.InRelations(entity); @@ -100,7 +152,7 @@ private class EditorHierachySelectionSystem : MoonTools.ECS.System public EditorHierachySelectionSystem(World world) : base(world) { selectedEntities = FilterBuilder.Include().Build(); - clickedEntities = FilterBuilder.Include().Build(); + clickedEntities = FilterBuilder.Include().Build(); } public override void Update(TimeSpan delta) @@ -128,9 +180,21 @@ public override void Update(TimeSpan delta) Set(entity, new SelectedInHierachy()); } - Remove(entity); + Remove(entity); } } } + + private class EditorHierachyDragAndDropSystem : MoonTools.ECS.System + { + public EditorHierachyDragAndDropSystem(World world) : base(world) + { + } + + public override void Update(TimeSpan delta) + { + + } + } } } diff --git a/Nerfed.Runtime/Systems/LocalToWorldSystem.cs b/Nerfed.Runtime/Systems/LocalToWorldSystem.cs index 97b31c0..33bf06c 100644 --- a/Nerfed.Runtime/Systems/LocalToWorldSystem.cs +++ b/Nerfed.Runtime/Systems/LocalToWorldSystem.cs @@ -45,7 +45,7 @@ private void UpdateWorldTransform(in Entity entity, Matrix4x4 localToWorldMatrix LocalToWorld localToWorld = new(localToWorldMatrix); Set(entity, localToWorld); - Log.Info($"Entity {entity} | local position {localTransform.position} | world position {localToWorldMatrix.Translation}"); + //Log.Info($"Entity {entity} | local position {localTransform.position} | world position {localToWorldMatrix.Translation}"); } ReverseSpanEnumerator childEntities = World.OutRelations(entity); diff --git a/Nerfed.Runtime/Util/Transform.cs b/Nerfed.Runtime/Util/Transform.cs index 2dc0764..2624c87 100644 --- a/Nerfed.Runtime/Util/Transform.cs +++ b/Nerfed.Runtime/Util/Transform.cs @@ -28,10 +28,7 @@ public static Matrix4x4 TRS(in this LocalTransform localTransform) // Relation goes from child to parent. public static void SetParent(in World world, in Entity child, in Entity parent) { - if (world.Related(parent, child)) - { - RemoveParent(world, parent); - } + RemoveParent(world, child); world.Relate(child, parent, new ChildParentRelation()); world.Set(child, new Child()); @@ -47,8 +44,10 @@ public static void RemoveParent(in World world, in Entity child) return; } + Entity parent = world.OutRelationSingleton(child); + // TODO: Check if Unrelate all also unrelates incomming relations..? - world.UnrelateAll(child); + world.Unrelate(child, parent); world.Remove(child); world.Set(child, new Root()); }