mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Overhauled component editors
This commit is contained in:
@@ -9,11 +9,11 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
public const String s_WindowTitle = "Components";
|
public const String s_WindowTitle = "Components";
|
||||||
|
|
||||||
public Editor Editor => _editor;
|
private EntityHierarchyWindow _entityHierarchyWindow;
|
||||||
|
|
||||||
public this(Editor editor)
|
public this(EntityHierarchyWindow entityHierarchyWindow)
|
||||||
{
|
{
|
||||||
_editor = editor;
|
_entityHierarchyWindow = entityHierarchyWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void InternalShow()
|
protected override void InternalShow()
|
||||||
@@ -24,9 +24,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_editor.SelectedEntities.Count == 1)
|
if(_entityHierarchyWindow.SelectedEntities.Count == 1)
|
||||||
{
|
{
|
||||||
EcsEntity entity = _editor.SelectedEntities.Front;
|
Entity entity = _entityHierarchyWindow.SelectedEntities.Front;
|
||||||
|
|
||||||
ShowComponents(entity);
|
ShowComponents(entity);
|
||||||
}
|
}
|
||||||
@@ -34,20 +34,21 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.End();
|
ImGui.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowComponents(EcsEntity entity)
|
private void ShowComponents(Entity entity)
|
||||||
{
|
{
|
||||||
NameComponentEditor.Show(_editor.World, entity);
|
ShowNameComponentEditor(entity);
|
||||||
TransformComponentEditor.Show(_editor.World, entity);
|
ShowTransformComponentEditor(entity);
|
||||||
}
|
ShowCameraComponentEditor(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class NameComponentEditor
|
private static void ShowNameComponentEditor(Entity entity)
|
||||||
{
|
{
|
||||||
public static void Show(EcsWorld world, EcsEntity entity)
|
if (!entity.HasComponent<DebugNameComponent>())
|
||||||
{
|
return;
|
||||||
char8[128] nameBuffer = default;
|
|
||||||
|
|
||||||
DebugNameComponent* component = world.GetComponent<DebugNameComponent>(entity);
|
char8[256] nameBuffer = default;
|
||||||
|
|
||||||
|
DebugNameComponent* component = entity.GetComponent<DebugNameComponent>();
|
||||||
|
|
||||||
String name = null;
|
String name = null;
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
name = scope:: $"Entity {entity.[Friend]Index}";
|
name = scope:: $"Entity {entity.Handle.[Friend]Index}";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy name to buffer
|
// Copy name to buffer
|
||||||
@@ -67,27 +68,75 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if(component == null)
|
if(component == null)
|
||||||
{
|
{
|
||||||
component = world.AssignComponent<DebugNameComponent>(entity);
|
component = entity.AddComponent<DebugNameComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
component.DebugName.Clear();
|
component.DebugName.Clear();
|
||||||
component.DebugName.Append(&nameBuffer);
|
component.DebugName.Append(&nameBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static class TransformComponentEditor
|
private static void ShowTransformComponentEditor(Entity entity)
|
||||||
{
|
{
|
||||||
public static void Show(EcsWorld world, EcsEntity entity)
|
if (!entity.HasComponent<SimpleTransformComponent>())
|
||||||
{
|
|
||||||
TransformComponent* component = world.GetComponent<TransformComponent>(entity);
|
|
||||||
|
|
||||||
if(component == null)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var transform = entity.GetComponent<SimpleTransformComponent>();
|
||||||
|
|
||||||
if(ImGui.TreeNodeEx("Transform", .DefaultOpen))
|
if(ImGui.TreeNodeEx("Transform", .DefaultOpen))
|
||||||
{
|
{
|
||||||
Vector3 position = component.Position;
|
bool ShowValue(String text, ref float value, String id)
|
||||||
|
{
|
||||||
|
ImGui.Text(text);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.PushID(id);
|
||||||
|
bool valueChanged = ImGui.DragFloat(String.Empty, &value, 0.1f);
|
||||||
|
ImGui.PopID();
|
||||||
|
|
||||||
|
return valueChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShowTableRow(String name, ref Vector3 value)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
ImGui.Text(name);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
changed |= ShowValue("X: ", ref value.X, scope $"{name}X");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
changed |= ShowValue("Y: ", ref value.Y, scope $"{name}Y");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
changed |= ShowValue("Z: ", ref value.Z, scope $"{name}Z");
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix.Decompose(transform.Transform, var position, var rotation, var scale);
|
||||||
|
|
||||||
|
ImGui.BeginTable("posRotScaleTable", 4);
|
||||||
|
|
||||||
|
if (ShowTableRow("Position", ref position))
|
||||||
|
{
|
||||||
|
transform.Transform.Translation = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldScale = scale;
|
||||||
|
if (ShowTableRow("Scale", ref scale))
|
||||||
|
{
|
||||||
|
Vector3 v = 1.0f / oldScale * scale;
|
||||||
|
|
||||||
|
transform.Transform.Scale = (Vector3)transform.Transform.Scale * v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImGui.EndTable();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Vector3 position = transform.Position;
|
||||||
bool positionChanged = false;
|
bool positionChanged = false;
|
||||||
|
|
||||||
Vector3 rotationEuler = MathHelper.ToDegrees(component.RotationEuler);
|
Vector3 rotationEuler = MathHelper.ToDegrees(component.RotationEuler);
|
||||||
@@ -137,6 +186,96 @@ namespace GlitchyEditor.EditWindows
|
|||||||
if(scaleChanged)
|
if(scaleChanged)
|
||||||
component.Scale = scale;
|
component.Scale = scale;
|
||||||
|
|
||||||
|
*/
|
||||||
|
ImGui.TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static String[] strings = new String[]("Orthographic", "Perspective", "Perspective (Infinite)") ~ delete _;
|
||||||
|
|
||||||
|
private static void ShowCameraComponentEditor(Entity entity)
|
||||||
|
{
|
||||||
|
if (!entity.HasComponent<CameraComponent>())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(ImGui.TreeNodeEx("Camera", .DefaultOpen))
|
||||||
|
{
|
||||||
|
var cameraComponent = entity.GetComponent<CameraComponent>();
|
||||||
|
|
||||||
|
ImGui.Checkbox("Primary", &cameraComponent.Primary);
|
||||||
|
|
||||||
|
var camera = ref cameraComponent.Camera;
|
||||||
|
|
||||||
|
String typeName = strings[camera.ProjectionType.Underlying];
|
||||||
|
|
||||||
|
if (ImGui.BeginCombo("Projection", typeName.CStr()))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
bool isSelected = (typeName == strings[i]);
|
||||||
|
|
||||||
|
if (ImGui.Selectable(strings[i], isSelected))
|
||||||
|
{
|
||||||
|
camera.ProjectionType = (.)i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSelected)
|
||||||
|
ImGui.SetItemDefaultFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (camera.ProjectionType == .Perspective)
|
||||||
|
{
|
||||||
|
float fovY = MathHelper.ToDegrees(camera.PerspectiveFovY);
|
||||||
|
if (ImGui.DragFloat("Fov Y", &fovY, 0.1f))
|
||||||
|
camera.PerspectiveFovY = MathHelper.ToRadians(fovY);
|
||||||
|
|
||||||
|
float near = camera.PerspectiveNearPlane;
|
||||||
|
if (ImGui.DragFloat("Near", &near, 0.1f))
|
||||||
|
camera.PerspectiveNearPlane = near;
|
||||||
|
|
||||||
|
float far = camera.PerspectiveFarPlane;
|
||||||
|
if (ImGui.DragFloat("Far", &far, 0.1f))
|
||||||
|
camera.PerspectiveFarPlane = far;
|
||||||
|
}
|
||||||
|
else if (camera.ProjectionType == .InfinitePerspective)
|
||||||
|
{
|
||||||
|
float fovY = MathHelper.ToDegrees(camera.PerspectiveFovY);
|
||||||
|
if (ImGui.DragFloat("Vertical FOV", &fovY, 0.1f))
|
||||||
|
camera.PerspectiveFovY = MathHelper.ToRadians(fovY);
|
||||||
|
|
||||||
|
float near = camera.PerspectiveNearPlane;
|
||||||
|
if (ImGui.DragFloat("Near", &near, 0.1f))
|
||||||
|
camera.PerspectiveNearPlane = near;
|
||||||
|
}
|
||||||
|
else if (camera.ProjectionType == .Orthographic)
|
||||||
|
{
|
||||||
|
float size = camera.OrthographicHeight;
|
||||||
|
if (ImGui.DragFloat("Size", &size, 0.1f))
|
||||||
|
camera.OrthographicHeight = size;
|
||||||
|
|
||||||
|
float near = camera.OrthographicNearPlane;
|
||||||
|
if (ImGui.DragFloat("Near", &near, 0.1f))
|
||||||
|
camera.OrthographicNearPlane = near;
|
||||||
|
|
||||||
|
float far = camera.OrthographicFarPlane;
|
||||||
|
if (ImGui.DragFloat("Far", &far, 0.1f))
|
||||||
|
camera.OrthographicFarPlane = far;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fixedAspectRatio = camera.FixedAspectRatio;
|
||||||
|
if (ImGui.Checkbox("Fixed Aspect Ratio", &fixedAspectRatio))
|
||||||
|
camera.FixedAspectRatio = fixedAspectRatio;
|
||||||
|
|
||||||
|
if (fixedAspectRatio)
|
||||||
|
{
|
||||||
|
float aspect = camera.AspectRatio;
|
||||||
|
if (ImGui.DragFloat("Aspect Ratio", &aspect, 0.1f))
|
||||||
|
camera.AspectRatio = aspect;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,20 @@ namespace GlitchyEditor.EditWindows
|
|||||||
/// Buffer for the entity search string.
|
/// Buffer for the entity search string.
|
||||||
private char8[64] _entitySearchChars;
|
private char8[64] _entitySearchChars;
|
||||||
|
|
||||||
public Editor Editor => _editor;
|
private Scene _scene;
|
||||||
|
|
||||||
public this(Editor editor)
|
private List<Entity> _selectedEntities = new .() ~ delete _;
|
||||||
|
|
||||||
|
public List<Entity> SelectedEntities => _selectedEntities;
|
||||||
|
|
||||||
|
public this(Scene scene)
|
||||||
{
|
{
|
||||||
_editor = editor;
|
SetContext(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetContext(Scene scene)
|
||||||
|
{
|
||||||
|
_scene = scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void InternalShow()
|
protected override void InternalShow()
|
||||||
@@ -39,6 +48,64 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.End();
|
ImGui.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether or not all selected entities have the same parent.
|
||||||
|
internal bool AllSelectionsOnSameLevel()
|
||||||
|
{
|
||||||
|
EcsEntity? parent = .InvalidEntity;
|
||||||
|
|
||||||
|
for(var selectedEntity in _selectedEntities)
|
||||||
|
{
|
||||||
|
var transformComponent = selectedEntity.GetComponent<SimpleTransformComponent>();
|
||||||
|
|
||||||
|
if(parent == .InvalidEntity)
|
||||||
|
{
|
||||||
|
parent = transformComponent.Parent;
|
||||||
|
}
|
||||||
|
else if(transformComponent.Parent != parent)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finds all children of the given entity and stores their IDs in the given list.
|
||||||
|
internal void FindChildren(EcsEntity entity, List<EcsEntity> entities)
|
||||||
|
{
|
||||||
|
for(var (child, childTransform) in _scene.[Friend]_ecsWorld.Enumerate<SimpleTransformComponent>())
|
||||||
|
{
|
||||||
|
if(childTransform.Parent == entity)
|
||||||
|
{
|
||||||
|
if(!entities.Contains(child))
|
||||||
|
entities.Add(child);
|
||||||
|
|
||||||
|
FindChildren(child, entities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deletes all selected entities and their children.
|
||||||
|
internal void DeleteSelectedEntities()
|
||||||
|
{
|
||||||
|
List<EcsEntity> entities = scope .();
|
||||||
|
|
||||||
|
for(var entity in _selectedEntities)
|
||||||
|
{
|
||||||
|
entities.Add(entity.Handle);
|
||||||
|
|
||||||
|
FindChildren(entity.Handle, entities);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var entityId in entities)
|
||||||
|
{
|
||||||
|
Entity entity = .(entityId, _scene);
|
||||||
|
_scene.DestroyEntity(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectedEntities.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
private void ShowEntityHierarchyMenuBar()
|
private void ShowEntityHierarchyMenuBar()
|
||||||
{
|
{
|
||||||
if(ImGui.BeginMenuBar())
|
if(ImGui.BeginMenuBar())
|
||||||
@@ -47,42 +114,43 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if(ImGui.MenuItem("Empty Entity"))
|
if(ImGui.MenuItem("Empty Entity"))
|
||||||
{
|
{
|
||||||
_editor.CreateEntityWithTransform();
|
_scene.CreateEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui.IsItemHovered())
|
if(ImGui.IsItemHovered())
|
||||||
ImGui.SetTooltip("Create a new Entity with a transform component.");
|
ImGui.SetTooltip("Create a new Entity.");
|
||||||
|
|
||||||
if(ImGui.MenuItem("Empty Child", null, false, !_editor.SelectedEntities.IsEmpty))
|
if(ImGui.MenuItem("Empty Child", null, false, !_selectedEntities.IsEmpty))
|
||||||
{
|
{
|
||||||
var newEntity = _editor.CreateEntityWithTransform();
|
var newEntity = _scene.CreateEntity();
|
||||||
var parent = _editor.World.AssignComponent<ParentComponent>(newEntity);
|
|
||||||
|
var transformCmp = newEntity.GetComponent<SimpleTransformComponent>();
|
||||||
// Last entity in list is the entity that has been selected last.
|
// Last entity in list is the entity that has been selected last.
|
||||||
parent.Entity = _editor.SelectedEntities.Back;
|
transformCmp.Parent = _selectedEntities.Back.Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui.IsItemHovered())
|
if(ImGui.IsItemHovered())
|
||||||
ImGui.SetTooltip("Create a new Entity that is a child of the currently selected entity.");
|
ImGui.SetTooltip("Create a new Entity that is a child of the currently selected entity.");
|
||||||
|
|
||||||
if(ImGui.MenuItem("Empty Parent", null, false, !_editor.SelectedEntities.IsEmpty && _editor.AllSelectionsOnSameLevel()))
|
if(ImGui.MenuItem("Empty Parent", null, false, !_selectedEntities.IsEmpty && AllSelectionsOnSameLevel()))
|
||||||
{
|
{
|
||||||
var commonParent = _editor.World.GetComponent<ParentComponent>(_editor.SelectedEntities.Front);
|
var commonParent = _selectedEntities.Front.GetComponent<SimpleTransformComponent>();
|
||||||
|
|
||||||
var newEntity = _editor.CreateEntityWithTransform();
|
var newEntity = _scene.CreateEntity();
|
||||||
|
|
||||||
if(commonParent != null)
|
if(commonParent != null)
|
||||||
{
|
{
|
||||||
// parent of selected entities is parent of the new entity.
|
// parent of selected entities is parent of the new entity.
|
||||||
// (which is why this doesn't work if the entities don't have the same parent)
|
// (which is why this doesn't work if the entities don't have the same parent)
|
||||||
var newEntityParent = _editor.World.AssignComponent<ParentComponent>(newEntity);
|
var newEntityTransform = newEntity.GetComponent<SimpleTransformComponent>();
|
||||||
newEntityParent.Entity = commonParent.Entity;
|
newEntityTransform.Parent = commonParent.Parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// new entity is parent of all selected entities.
|
// new entity is parent of all selected entities.
|
||||||
for(var selectedEntity in _editor.SelectedEntities)
|
for(var selectedEntity in _selectedEntities)
|
||||||
{
|
{
|
||||||
var selectedEntityParent = _editor.World.AssignComponent<ParentComponent>(selectedEntity);
|
var selectedTransform = selectedEntity.GetComponent<SimpleTransformComponent>();
|
||||||
selectedEntityParent.Entity = newEntity;
|
selectedTransform.Parent = newEntity.Handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,9 +163,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
if(ImGui.IsItemHovered())
|
if(ImGui.IsItemHovered())
|
||||||
ImGui.SetTooltip("Create a new Entity.");
|
ImGui.SetTooltip("Create a new Entity.");
|
||||||
|
|
||||||
if(ImGui.MenuItem("Delete", null, false, !_editor.SelectedEntities.IsEmpty) || Input.IsKeyPressed(.Delete))
|
if(ImGui.MenuItem("Delete", null, false, !_selectedEntities.IsEmpty) || Input.IsKeyPressed(.Delete))
|
||||||
{
|
{
|
||||||
_editor.DeleteSelectedEntities();
|
DeleteSelectedEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui.IsItemHovered())
|
if(ImGui.IsItemHovered())
|
||||||
@@ -111,11 +179,11 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ImGuiPrintEntityTree(TreeNode<EcsEntity> tree)
|
private void ImGuiPrintEntityTree(TreeNode<Entity> tree)
|
||||||
{
|
{
|
||||||
String name = null;
|
String name = null;
|
||||||
|
|
||||||
var nameComponent = _editor.World.GetComponent<DebugNameComponent>(tree.Value);
|
var nameComponent = tree.Value.GetComponent<DebugNameComponent>();
|
||||||
|
|
||||||
if(nameComponent != null)
|
if(nameComponent != null)
|
||||||
{
|
{
|
||||||
@@ -123,24 +191,24 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
name = scope:: $"Entity {(tree.Value.[Friend]Index)}";
|
name = scope:: $"Entity {(tree.Value.Handle.[Friend]Index)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.TreeNodeFlags flags = .OpenOnArrow;
|
ImGui.TreeNodeFlags flags = .OpenOnArrow | .DefaultOpen;
|
||||||
|
|
||||||
if(tree.Children.Count == 0)
|
if(tree.Children.Count == 0)
|
||||||
flags |= .Leaf;
|
flags |= .Leaf;
|
||||||
|
|
||||||
bool inSelectedList = _editor.SelectedEntities.Contains(tree.Value);
|
bool inSelectedList = _selectedEntities.Contains(tree.Value);
|
||||||
|
|
||||||
if(inSelectedList)
|
if(inSelectedList)
|
||||||
flags |= .Selected;
|
flags |= .Selected;
|
||||||
|
|
||||||
bool isOpen = ImGui.TreeNodeEx(name, flags);
|
bool isOpen = ImGui.TreeNodeEx((void*)(uint)tree.Value.Handle.[Friend]Index, flags, $"{name}");
|
||||||
|
|
||||||
if(ImGui.BeginDragDropSource())
|
if(ImGui.BeginDragDropSource())
|
||||||
{
|
{
|
||||||
ImGui.SetDragDropPayload("DND_Entity", &tree.Value, sizeof(EcsEntity));
|
ImGui.SetDragDropPayload("DND_Entity", &tree.Value, sizeof(Entity));
|
||||||
|
|
||||||
ImGui.Text(name);
|
ImGui.Text(name);
|
||||||
|
|
||||||
@@ -153,37 +221,37 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if(payload != null)
|
if(payload != null)
|
||||||
{
|
{
|
||||||
Log.ClientLogger.AssertDebug(payload.DataSize == sizeof(EcsEntity));
|
Log.ClientLogger.AssertDebug(payload.DataSize == sizeof(Entity));
|
||||||
|
|
||||||
EcsEntity movedEntity = *(EcsEntity*)payload.Data;
|
Entity movedEntity = *(Entity*)payload.Data;
|
||||||
|
|
||||||
bool dropLegal = true;
|
bool dropLegal = true;
|
||||||
|
|
||||||
EcsEntity walker = tree.Value;
|
Entity walker = tree.Value;
|
||||||
|
|
||||||
// make sure the dropped entity is not a parent of the entity we dropped it on.
|
// make sure the dropped entity is not a parent of the entity we dropped it on.
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
var walkerParent = _editor.World.GetComponent<ParentComponent>(walker);
|
var parentTransform = walker.GetComponent<SimpleTransformComponent>();
|
||||||
|
|
||||||
if(walkerParent == null)
|
if(parentTransform.Parent == .InvalidEntity)
|
||||||
{
|
{
|
||||||
dropLegal = true;
|
dropLegal = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if(walkerParent.Entity == movedEntity)
|
else if(parentTransform.Parent == movedEntity.Handle)
|
||||||
{
|
{
|
||||||
dropLegal = false;
|
dropLegal = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
walker = walkerParent.Entity;
|
walker = .(parentTransform.Parent, _scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dropLegal)
|
if(dropLegal)
|
||||||
{
|
{
|
||||||
var movedEntityParent = _editor.World.AssignComponent<ParentComponent>(movedEntity);
|
var movedEntityTransform = movedEntity.GetComponent<SimpleTransformComponent>();
|
||||||
movedEntityParent.Entity = tree.Value;
|
movedEntityTransform.Parent = tree.Value.Handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,16 +274,16 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if(inSelectedList)
|
if(inSelectedList)
|
||||||
{
|
{
|
||||||
_editor.SelectedEntities.Remove(tree.Value);
|
_selectedEntities.Remove(tree.Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!ImGui.GetIO().KeyCtrl)
|
if(!ImGui.GetIO().KeyCtrl)
|
||||||
{
|
{
|
||||||
_editor.SelectedEntities.Clear();
|
_selectedEntities.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
_editor.SelectedEntities.Add(tree.Value);
|
_selectedEntities.Add(tree.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
inSelectedList = !inSelectedList;
|
inSelectedList = !inSelectedList;
|
||||||
@@ -226,34 +294,39 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
StringView searchString = StringView(&_entitySearchChars);
|
StringView searchString = StringView(&_entitySearchChars);
|
||||||
|
|
||||||
if(searchString.Length == 0)
|
if(searchString.IsWhiteSpace)
|
||||||
{
|
{
|
||||||
// Show entity hierarchy as tree
|
// Show entity hierarchy as tree
|
||||||
|
|
||||||
TreeNode<EcsEntity> root = scope .(.InvalidEntity);
|
TreeNode<Entity> root = scope .(Entity(.InvalidEntity, _scene));
|
||||||
|
|
||||||
TreeNode<EcsEntity> AddEntity(EcsEntity entity)
|
TreeNode<Entity> InsertIntoTree(Entity entity)
|
||||||
{
|
{
|
||||||
var parent = _editor.World.GetComponent<ParentComponent>(entity);
|
var transform = entity.GetComponent<SimpleTransformComponent>();
|
||||||
|
|
||||||
if(parent == null)
|
if(transform == null)
|
||||||
{
|
{
|
||||||
return root.AddChild(entity);
|
return root.AddChild(entity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var parentNode = root.FindNode(parent.Entity);
|
var parentEntity = Entity(transform.Parent, _scene);
|
||||||
|
|
||||||
|
var parentNode = root.FindNode(parentEntity);
|
||||||
|
|
||||||
if(parentNode == null)
|
if(parentNode == null)
|
||||||
parentNode = AddEntity(parent.Entity);
|
parentNode = InsertIntoTree(parentEntity);
|
||||||
|
|
||||||
return parentNode.AddChild(entity);
|
return parentNode.AddChild(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var entity in _editor.World.Enumerate())
|
for(var entityId in _scene.[Friend]_ecsWorld.Enumerate())
|
||||||
{
|
{
|
||||||
AddEntity(entity);
|
Entity entity = .(entityId, _scene);
|
||||||
|
|
||||||
|
//if (!entity.HasComponent<EditorComponent>())
|
||||||
|
InsertIntoTree(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui.TreeNodeEx("Scene", .DefaultOpen))
|
if(ImGui.TreeNodeEx("Scene", .DefaultOpen))
|
||||||
@@ -264,15 +337,14 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if(payload != null)
|
if(payload != null)
|
||||||
{
|
{
|
||||||
Log.ClientLogger.AssertDebug(payload.DataSize == sizeof(EcsEntity));
|
Log.ClientLogger.AssertDebug(payload.DataSize == sizeof(Entity));
|
||||||
|
|
||||||
EcsEntity movedEntity = *(EcsEntity*)payload.Data;
|
Entity movedEntity = *(Entity*)payload.Data;
|
||||||
|
|
||||||
_editor.World.RemoveComponent<ParentComponent>(movedEntity);
|
|
||||||
|
|
||||||
// Also mark transform as dirty
|
// Also mark transform as dirty
|
||||||
var transformComponent = _editor.World.GetComponent<TransformComponent>(movedEntity);
|
var transformComponent = movedEntity.GetComponent<SimpleTransformComponent>();
|
||||||
transformComponent?.IsDirty = true;
|
transformComponent.Parent = .InvalidEntity;
|
||||||
|
//transformComponent?.IsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
ImGui.EndDragDropTarget();
|
||||||
@@ -294,11 +366,13 @@ namespace GlitchyEditor.EditWindows
|
|||||||
List<StringView> searchTokens = new:ScopedAlloc! .(searchString.Split(' ', .RemoveEmptyEntries));
|
List<StringView> searchTokens = new:ScopedAlloc! .(searchString.Split(' ', .RemoveEmptyEntries));
|
||||||
|
|
||||||
worldEnumeration:
|
worldEnumeration:
|
||||||
for(var entity in _editor.World.Enumerate())
|
for(var entityId in _scene.[Friend]_ecsWorld.Enumerate())
|
||||||
{
|
{
|
||||||
|
Entity entity = .(entityId, _scene);
|
||||||
|
|
||||||
String name = null;
|
String name = null;
|
||||||
|
|
||||||
var nameComponent = _editor.World.GetComponent<DebugNameComponent>(entity);
|
var nameComponent = entity.GetComponent<DebugNameComponent>();
|
||||||
|
|
||||||
if(nameComponent != null)
|
if(nameComponent != null)
|
||||||
{
|
{
|
||||||
@@ -306,7 +380,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
name = scope:worldEnumeration $"Entity {entity.[Friend]Index}";
|
name = scope:worldEnumeration $"Entity {entityId.[Friend]Index}";
|
||||||
}
|
}
|
||||||
|
|
||||||
StringView nameView = StringView(name);
|
StringView nameView = StringView(name);
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ namespace GlitchyEditor
|
|||||||
private EcsWorld _ecsWorld;
|
private EcsWorld _ecsWorld;
|
||||||
private Scene _scene;
|
private Scene _scene;
|
||||||
|
|
||||||
private EntityHierarchyWindow _entityHierarchyWindow = new .(this) ~ delete _;
|
private EntityHierarchyWindow _entityHierarchyWindow ~ delete _;
|
||||||
private ComponentEditWindow _componentEditWindow = new .(this) ~ delete _;
|
private ComponentEditWindow _componentEditWindow ~ delete _;
|
||||||
private SceneViewportWindow _sceneViewportWindow = new .(this) ~ delete _;
|
private SceneViewportWindow _sceneViewportWindow = new .(this) ~ delete _;
|
||||||
|
|
||||||
private List<EcsEntity> _selectedEntities = new .() ~ delete _;
|
private List<EcsEntity> _selectedEntities = new .() ~ delete _;
|
||||||
@@ -31,6 +31,9 @@ namespace GlitchyEditor
|
|||||||
{
|
{
|
||||||
_scene = scene;
|
_scene = scene;
|
||||||
_ecsWorld = _scene.[Friend]_ecsWorld;
|
_ecsWorld = _scene.[Friend]_ecsWorld;
|
||||||
|
|
||||||
|
_entityHierarchyWindow = new EntityHierarchyWindow(_scene);
|
||||||
|
_componentEditWindow = new ComponentEditWindow(_entityHierarchyWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
|
|||||||
@@ -77,25 +77,27 @@ namespace GlitchyEditor
|
|||||||
{
|
{
|
||||||
_cameraEntity = _scene.CreateEntity("Camera Entity");
|
_cameraEntity = _scene.CreateEntity("Camera Entity");
|
||||||
let camera = _cameraEntity.AddComponent<CameraComponent>();
|
let camera = _cameraEntity.AddComponent<CameraComponent>();
|
||||||
camera.Camera.SetPerspective(0.1f, 1000f, MathHelper.ToRadians(75));
|
camera.Camera.SetPerspective(MathHelper.ToRadians(75), 0.1f, 10000.0f);
|
||||||
camera.Primary = true;
|
camera.Primary = true;
|
||||||
camera.FixedAspectRatio = false;
|
camera.FixedAspectRatio = false;
|
||||||
let transform = _cameraEntity.GetComponent<SimpleTransformComponent>();
|
let transform = _cameraEntity.GetComponent<SimpleTransformComponent>();
|
||||||
transform.Transform = Matrix.Translation(0, 0, -5);
|
transform.Transform = Matrix.Translation(0, 0, -5);
|
||||||
|
|
||||||
_cameraEntity.AddComponent<NativeScriptComponent>().Bind<CameraController>();
|
_cameraEntity.AddComponent<NativeScriptComponent>().Bind<CameraController>();
|
||||||
|
_cameraEntity.AddComponent<EditorComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
_otherCameraEntity = _scene.CreateEntity("Other Camera Entity");
|
_otherCameraEntity = _scene.CreateEntity("Other Camera Entity");
|
||||||
let camera = _otherCameraEntity.AddComponent<CameraComponent>();
|
let camera = _otherCameraEntity.AddComponent<CameraComponent>();
|
||||||
camera.Camera.SetPerspective(0.1f, 1000f, MathHelper.ToRadians(45));
|
camera.Camera.SetPerspective(MathHelper.ToRadians(45), 0.1f, 1000.0f);
|
||||||
camera.Primary = false;
|
camera.Primary = false;
|
||||||
camera.FixedAspectRatio = false;
|
camera.FixedAspectRatio = false;
|
||||||
let transform = _otherCameraEntity.GetComponent<SimpleTransformComponent>();
|
let transform = _otherCameraEntity.GetComponent<SimpleTransformComponent>();
|
||||||
transform.Transform = Matrix.Translation(0, 0, -5);
|
transform.Transform = Matrix.Translation(0, 0, -5);
|
||||||
|
|
||||||
_otherCameraEntity.AddComponent<NativeScriptComponent>().Bind<CameraController>();
|
_otherCameraEntity.AddComponent<NativeScriptComponent>().Bind<CameraController>();
|
||||||
|
_otherCameraEntity.AddComponent<EditorComponent>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,19 @@ using System;
|
|||||||
|
|
||||||
namespace GlitchyEngine.World
|
namespace GlitchyEngine.World
|
||||||
{
|
{
|
||||||
|
/// If an entity has the EditorComponent it won't be displayed in the scene hierarchy.
|
||||||
|
struct EditorComponent
|
||||||
|
{
|
||||||
|
bool b = false;
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct SimpleTransformComponent
|
struct SimpleTransformComponent
|
||||||
{
|
{
|
||||||
|
public EcsEntity Parent = .InvalidEntity;
|
||||||
public Matrix Transform = Matrix.Identity;
|
public Matrix Transform = Matrix.Identity;
|
||||||
|
|
||||||
public this()
|
public this()
|
||||||
@@ -38,14 +49,24 @@ namespace GlitchyEngine.World
|
|||||||
{
|
{
|
||||||
public enum ProjectionType
|
public enum ProjectionType
|
||||||
{
|
{
|
||||||
case Perspective(float FovY, float NearPlane, float FarPlane);
|
case Orthographic = 0;//(float Height, float NearPlane, float FarPlane);
|
||||||
case InfinitePerspective(float FovY, float NearPlane);
|
case Perspective = 1;//(float FovY, float NearPlane, float FarPlane);
|
||||||
case Orthographic(float Height, float NearPlane, float FarPlane);
|
case InfinitePerspective = 2;//(float FovY, float NearPlane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private float _perspectiveFovY = MathHelper.ToRadians(75f);
|
||||||
|
private float _perspectiveNearPlane = 0.1f;
|
||||||
|
private float _perspectiveFarPlane = 10000.0f;
|
||||||
|
|
||||||
|
private float _orthographicHeight = 10.0f;
|
||||||
|
private float _orthographicNearPlane = 0.0f;
|
||||||
|
private float _orthographicFarPlane = 10.0f;
|
||||||
|
|
||||||
private float _aspectRatio = 16.0f / 9.0f;
|
private float _aspectRatio = 16.0f / 9.0f;
|
||||||
|
|
||||||
private ProjectionType _projectionType = .InfinitePerspective(MathHelper.ToRadians(75f), 0.1f);
|
private bool _fixedAspectRatio = false;
|
||||||
|
|
||||||
|
private ProjectionType _projectionType = .InfinitePerspective;//(MathHelper.ToRadians(75f), 0.1f);
|
||||||
|
|
||||||
public ProjectionType ProjectionType
|
public ProjectionType ProjectionType
|
||||||
{
|
{
|
||||||
@@ -57,6 +78,110 @@ namespace GlitchyEngine.World
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float PerspectiveFovY
|
||||||
|
{
|
||||||
|
get => _perspectiveFovY;
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
if (_perspectiveFovY == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_perspectiveFovY = value;
|
||||||
|
CalculateProjection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float PerspectiveNearPlane
|
||||||
|
{
|
||||||
|
get => _perspectiveNearPlane;
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
if (_perspectiveNearPlane == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_perspectiveNearPlane = value;
|
||||||
|
CalculateProjection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float PerspectiveFarPlane
|
||||||
|
{
|
||||||
|
get => _perspectiveFarPlane;
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
if (_perspectiveFarPlane == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_perspectiveFarPlane = value;
|
||||||
|
CalculateProjection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float OrthographicHeight
|
||||||
|
{
|
||||||
|
get => _orthographicHeight;
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
if (_orthographicHeight == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_orthographicHeight = value;
|
||||||
|
CalculateProjection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float OrthographicNearPlane
|
||||||
|
{
|
||||||
|
get => _orthographicNearPlane;
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
if (_orthographicNearPlane == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_orthographicNearPlane = value;
|
||||||
|
CalculateProjection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float OrthographicFarPlane
|
||||||
|
{
|
||||||
|
get => _orthographicFarPlane;
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
if (_orthographicFarPlane == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_orthographicFarPlane = value;
|
||||||
|
CalculateProjection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float AspectRatio
|
||||||
|
{
|
||||||
|
get => _aspectRatio;
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
if (_aspectRatio == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_aspectRatio = value;
|
||||||
|
CalculateProjection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FixedAspectRatio
|
||||||
|
{
|
||||||
|
get => _fixedAspectRatio;
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
if (_fixedAspectRatio == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_fixedAspectRatio = value;
|
||||||
|
CalculateProjection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private const Matrix mat = Matrix.InfinitePerspectiveProjection(MathHelper.ToRadians(75f), 1.0f, 0.1f);
|
private const Matrix mat = Matrix.InfinitePerspectiveProjection(MathHelper.ToRadians(75f), 1.0f, 0.1f);
|
||||||
|
|
||||||
public this()
|
public this()
|
||||||
@@ -66,21 +191,31 @@ namespace GlitchyEngine.World
|
|||||||
|
|
||||||
public void SetOrthographic(float height, float nearPlane, float farPlane) mut
|
public void SetOrthographic(float height, float nearPlane, float farPlane) mut
|
||||||
{
|
{
|
||||||
_projectionType = .Orthographic(height, nearPlane, farPlane);
|
_projectionType = .Orthographic;//(height, nearPlane, farPlane);
|
||||||
|
|
||||||
|
_orthographicHeight = height;
|
||||||
|
_orthographicNearPlane = nearPlane;
|
||||||
|
_orthographicFarPlane = farPlane;
|
||||||
|
|
||||||
CalculateProjection();
|
CalculateProjection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPerspective(float fovY, float nearPlane, float farPlane) mut
|
public void SetPerspective(float fovY, float nearPlane, float farPlane) mut
|
||||||
{
|
{
|
||||||
_projectionType = .Perspective(fovY, nearPlane, farPlane);
|
_projectionType = .Perspective;//(fovY, nearPlane, farPlane);
|
||||||
|
_perspectiveFovY = fovY;
|
||||||
|
_perspectiveNearPlane = nearPlane;
|
||||||
|
_perspectiveFarPlane = farPlane;
|
||||||
|
|
||||||
CalculateProjection();
|
CalculateProjection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetInfinitePerspective(float fovY, float nearPlane) mut
|
public void SetInfinitePerspective(float fovY, float nearPlane) mut
|
||||||
{
|
{
|
||||||
_projectionType = .InfinitePerspective(fovY, nearPlane);
|
_projectionType = .InfinitePerspective;//(fovY, nearPlane);
|
||||||
|
_perspectiveFovY = fovY;
|
||||||
|
_perspectiveNearPlane = nearPlane;
|
||||||
|
//_perspectiveFarPlane = farPlane;
|
||||||
|
|
||||||
CalculateProjection();
|
CalculateProjection();
|
||||||
}
|
}
|
||||||
@@ -94,20 +229,21 @@ namespace GlitchyEngine.World
|
|||||||
|
|
||||||
private void CalculateProjection() mut
|
private void CalculateProjection() mut
|
||||||
{
|
{
|
||||||
if (_projectionType case .Orthographic(let nearPlane, let farPlane, let projectionHeight))
|
if (_projectionType case .Orthographic)//(let nearPlane, let farPlane, let projectionHeight))
|
||||||
{
|
{
|
||||||
float halfHeight = projectionHeight / 2.0f;
|
float halfHeight = _orthographicHeight / 2.0f;
|
||||||
float halfWidth = halfHeight / _aspectRatio;
|
float halfWidth = halfHeight * _aspectRatio;
|
||||||
|
|
||||||
_projection = Matrix.OrthographicProjectionOffCenter(-halfWidth, halfWidth, halfHeight, -halfHeight, nearPlane, farPlane);
|
_projection = Matrix.OrthographicProjectionOffCenter(-halfWidth, halfWidth, halfHeight, -halfHeight,
|
||||||
|
_orthographicNearPlane, _orthographicFarPlane);
|
||||||
}
|
}
|
||||||
else if (_projectionType case .Perspective(let nearPlane, let farPlane, let fovY))
|
else if (_projectionType case .Perspective)//(let nearPlane, let farPlane, let fovY))
|
||||||
{
|
{
|
||||||
_projection = Matrix.PerspectiveProjection(fovY, _aspectRatio, nearPlane, farPlane);
|
_projection = Matrix.PerspectiveProjection(_perspectiveFovY, _aspectRatio, _perspectiveNearPlane, _perspectiveFarPlane);
|
||||||
}
|
}
|
||||||
else if (_projectionType case .InfinitePerspective(let nearPlane, let fovY))
|
else if (_projectionType case .InfinitePerspective)//(let nearPlane, let fovY))
|
||||||
{
|
{
|
||||||
_projection = Matrix.InfinitePerspectiveProjection(fovY, _aspectRatio, nearPlane);
|
_projection = Matrix.InfinitePerspectiveProjection(_perspectiveFovY, _aspectRatio, _perspectiveNearPlane);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user