Overhauled component editors

This commit is contained in:
Simon Lübeß
2022-04-01 23:29:35 +02:00
parent e82f70ba02
commit c13b0a26d1
5 changed files with 456 additions and 102 deletions
@@ -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)
{ {
char8[128] nameBuffer = default; if (!entity.HasComponent<DebugNameComponent>())
return;
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)
{ {
TransformComponent* component = world.GetComponent<TransformComponent>(entity); if (!entity.HasComponent<SimpleTransformComponent>())
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);
+5 -2
View File
@@ -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()
+4 -2
View File
@@ -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>();
} }
} }
+151 -15
View File
@@ -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);
} }
} }
} }