From 62bb5baac9c6605769c5fa2bf7f6e0f5192b2fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Sun, 15 May 2022 14:36:07 +0200 Subject: [PATCH] Gizmo improvements --- .../src/EditWindows/SceneViewportWindow.bf | 90 +++++++++++++++---- GlitchyEditor/src/Editor.bf | 23 ++--- GlitchyEditor/src/EditorLayer.bf | 8 +- GlitchyEngine/src/World/Entity.bf | 2 +- GlitchyEngine/src/World/Scene.bf | 14 +++ GlitchyEngine/src/World/TransformComponent.bf | 5 +- GlitchyEngine/vendor/bon | 2 +- GlitchyEngine/vendor/imgui | 2 +- 8 files changed, 108 insertions(+), 38 deletions(-) diff --git a/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf b/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf index 2e6e816..69fa248 100644 --- a/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf +++ b/GlitchyEditor/src/EditWindows/SceneViewportWindow.bf @@ -41,12 +41,14 @@ namespace GlitchyEditor.EditWindows ImGui.PushStyleVar(.WindowPadding, ImGui.Vec2(1, 1)); defer ImGui.PopStyleVar(); - if(!ImGui.Begin(s_WindowTitle, &_open, .NoScrollbar)) + if(!ImGui.Begin(s_WindowTitle, &_open, .NoScrollbar | .MenuBar)) { ImGui.End(); return; } + ShowMenuBar(); + if(ImGui.IsWindowHovered() && Input.IsMouseButtonPressing(.RightButton)) { var currentWindow = ImGui.GetCurrentWindow(); @@ -74,8 +76,60 @@ namespace GlitchyEditor.EditWindows } } + private ImGuizmo.OPERATION _gizmoType = .TRANSLATE; + + private ImGuizmo.MODE _gizmoMode = .LOCAL; + + private void ShowMenuBar() + { + if(ImGui.BeginMenuBar()) + { + if (ImGui.RadioButton("Position", _gizmoType.HasFlag(.TRANSLATE))) + { + if (Input.IsKeyPressed(Key.Control)) + _gizmoType ^= .TRANSLATE; + else + _gizmoType = .TRANSLATE; + } + + if (ImGui.RadioButton("Rotation", _gizmoType.HasFlag(.ROTATE))) + { + if (Input.IsKeyPressed(Key.Control)) + _gizmoType ^= .ROTATE; + else + _gizmoType = .ROTATE; + } + + if (ImGui.RadioButton("Scale", _gizmoType.HasFlag(.SCALE))) + { + if (Input.IsKeyPressed(Key.Control)) + _gizmoType ^= .SCALE; + else + _gizmoType = .SCALE; + } + + if (ImGui.RadioButton("All", _gizmoType == .TRANSLATE | .ROTATE | .SCALE)) + _gizmoType = .TRANSLATE | .ROTATE | .SCALE; + + // If we scale, the mode must be local otherwise we could skew the matrix. + if (_gizmoType.HasFlag(.SCALE)) + _gizmoMode = .LOCAL; + + if (ImGui.MenuItem(_gizmoMode == .WORLD ? "Global" : "Local", null, true, !_gizmoType.HasFlag(.SCALE))) + { + if (_gizmoMode == .WORLD) + _gizmoMode = .LOCAL; + else + _gizmoMode = .WORLD; + } + + ImGui.EndMenuBar(); + } + } + private void DrawImGuizmo(ImGui.Vec2 viewportSize) { + ImGuizmo.SetOrthographic(false); ImGuizmo.SetDrawlist(); var topLeft = ImGui.GetWindowPos(); @@ -85,28 +139,34 @@ namespace GlitchyEditor.EditWindows topLeft.y += cntMin.y; ImGuizmo.SetRect(topLeft.x, topLeft.y, viewportSize.x, viewportSize.y); - var cameraTransformCmp = _editor.CurrentCamera.GetComponent(); + var cameraTransformCmp = _editor.CurrentScene.ActiveCamera.GetComponent(); var view = cameraTransformCmp.WorldTransform.Invert(); var cameraCmp = _editor.CurrentCamera.GetComponent(); var projection = cameraCmp.Camera.Projection; - Matrix mat = .Identity; - ImGuizmo.DrawGrid((.)&view, (.)&projection, (.)&mat, 10); + if(_editor.EntityHierarchyWindow.SelectedEntities.Count == 0) + return; - if(_editor.EntityHierarchyWindow.SelectedEntities.Count > 0) + var entity = _editor.EntityHierarchyWindow.SelectedEntities.Back; + + var transformCmp = entity.GetComponent(); + + var worldTransform = transformCmp.WorldTransform; + + Matrix parentView = .Identity; + if (transformCmp.Parent != .InvalidEntity) { - var entity = _editor.EntityHierarchyWindow.SelectedEntities.Front; + var parentTransformCmp = Entity(transformCmp.Parent, entity.Scene).GetComponent(); + parentView = parentTransformCmp.WorldTransform.Invert(); + } - var transformCmp = entity.GetComponent(); - - var transform = transformCmp.LocalTransform; - - ImGuizmo.SetRect(topLeft.x, topLeft.y, viewportSize.x, viewportSize.y); - - ImGuizmo.Manipulate((.)&view, (.)&projection, .TRANSLATE, .LOCAL, (.)&transform); - - transformCmp.LocalTransform = transform; + if (ImGuizmo.Manipulate((.)&view, (.)&projection, _gizmoType, _gizmoMode, (.)&worldTransform)) + { + // TODO: Fix when parent is scaled + // Seems to work fine for parent rotation and translation but scaled parent ruins everything + // (probably because scaling a rotated matrix results in a skewed matrix, but unity can do it, so should we) + transformCmp.LocalTransform = parentView * worldTransform; } } } diff --git a/GlitchyEditor/src/Editor.bf b/GlitchyEditor/src/Editor.bf index 17e1832..3c43398 100644 --- a/GlitchyEditor/src/Editor.bf +++ b/GlitchyEditor/src/Editor.bf @@ -28,7 +28,6 @@ namespace GlitchyEditor { _scene = value; _entityHierarchyWindow.SetContext(_scene); - FindCurrentEditorCamera(); } } @@ -45,26 +44,20 @@ namespace GlitchyEditor public void Update() { - var scriptComponent = CurrentCamera.GetComponent(); - - if (var camController = scriptComponent?.Instance as EditorCameraController) + _currentCamera = _scene.ActiveCamera; + if (_currentCamera.IsValid) { - camController.IsEnabled = (SceneViewportWindow.HasFocus && Input.IsMouseButtonPressed(.RightButton)); + var scriptComponent = _currentCamera.GetComponent(); + + if (var camController = scriptComponent?.Instance as EditorCameraController) + { + camController.IsEnabled = (SceneViewportWindow.HasFocus && Input.IsMouseButtonPressed(.RightButton)); + } } _entityHierarchyWindow.Show(); _componentEditWindow.Show(); _sceneViewportWindow.Show(); } - - private void FindCurrentEditorCamera() - { - _currentCamera = .(.InvalidEntity, _scene); - // TODO: a bit sketchy - for (var (entity, editComp, cam) in _scene.[Friend]_ecsWorld.Enumerate()) - { - _currentCamera = .(entity, CurrentScene); - } - } } } diff --git a/GlitchyEditor/src/EditorLayer.bf b/GlitchyEditor/src/EditorLayer.bf index d573c01..cc1c11e 100644 --- a/GlitchyEditor/src/EditorLayer.bf +++ b/GlitchyEditor/src/EditorLayer.bf @@ -226,14 +226,14 @@ namespace GlitchyEditor var fxLib = Application.Get().EffectLibrary; using (Effect myEffect = fxLib.Load("content/Shaders/myEffect.hlsl")) - using (Texture2D albedo = new Texture2D("Textures/White.png", true)) + /*using (Texture2D albedo = new Texture2D("Textures/White.png", true)) using (Texture2D normal = new Texture2D("Textures/White.png")) using (Texture2D rough = new Texture2D("Textures/White.png")) - using (Texture2D metal = new Texture2D("Textures/White.png")) - /*using (Texture2D albedo = new Texture2D("Textures/TestMat/rustediron2_albedo.png", true)) + using (Texture2D metal = new Texture2D("Textures/White.png"))*/ + using (Texture2D albedo = new Texture2D("Textures/TestMat/rustediron2_albedo.png", true)) using (Texture2D normal = new Texture2D("Textures/TestMat/rustediron2_normal.png")) using (Texture2D rough = new Texture2D("Textures/TestMat/rustediron2_roughness.png")) - using (Texture2D metal = new Texture2D("Textures/TestMat/rustediron2_metallic.png"))*/ + using (Texture2D metal = new Texture2D("Textures/TestMat/rustediron2_metallic.png")) { albedo.SamplerState = SamplerStateManager.AnisotropicWrap; normal.SamplerState = SamplerStateManager.AnisotropicWrap; diff --git a/GlitchyEngine/src/World/Entity.bf b/GlitchyEngine/src/World/Entity.bf index a29d108..43ad148 100644 --- a/GlitchyEngine/src/World/Entity.bf +++ b/GlitchyEngine/src/World/Entity.bf @@ -27,7 +27,7 @@ namespace GlitchyEngine.World public ChildEnumerator EnumerateChildren => .(this); - public bool IsValid => _entity.IsValid; + public bool IsValid => _entity.IsValid && _scene != null; public Entity? Parent { diff --git a/GlitchyEngine/src/World/Scene.bf b/GlitchyEngine/src/World/Scene.bf index eb338a4..90b428e 100644 --- a/GlitchyEngine/src/World/Scene.bf +++ b/GlitchyEngine/src/World/Scene.bf @@ -12,6 +12,20 @@ namespace GlitchyEngine.World internal EcsWorld _ecsWorld = new .() ~ delete _; private Dictionary _onComponentAddedHandlers = new .() ~ delete _; + + public Entity ActiveCamera => { + Entity cameraEntity = .(); + + for (var (entity, camera) in _ecsWorld.Enumerate()) + { + if (camera.Primary && camera.RenderTarget != null) + { + cameraEntity = .(entity, this); + } + } + + cameraEntity + }; public this() { diff --git a/GlitchyEngine/src/World/TransformComponent.bf b/GlitchyEngine/src/World/TransformComponent.bf index 747de1e..808287d 100644 --- a/GlitchyEngine/src/World/TransformComponent.bf +++ b/GlitchyEngine/src/World/TransformComponent.bf @@ -43,7 +43,10 @@ namespace GlitchyEngine.World _localTransform = value; - Matrix.Decompose(_localTransform, out _position, out _rotation, out _scale); + Matrix.Decompose(_localTransform, out _position, let rotation, out _scale); + + Rotation = rotation; + IsDirty = true; } } diff --git a/GlitchyEngine/vendor/bon b/GlitchyEngine/vendor/bon index 515b606..c35a5d7 160000 --- a/GlitchyEngine/vendor/bon +++ b/GlitchyEngine/vendor/bon @@ -1 +1 @@ -Subproject commit 515b606cf3048179b19d51e55a503b3007ae94e4 +Subproject commit c35a5d7c1451b503822730857eb8639cec54bbc2 diff --git a/GlitchyEngine/vendor/imgui b/GlitchyEngine/vendor/imgui index b1d8913..e74dac8 160000 --- a/GlitchyEngine/vendor/imgui +++ b/GlitchyEngine/vendor/imgui @@ -1 +1 @@ -Subproject commit b1d891368e640f5a24b2af0385b95a58683a3095 +Subproject commit e74dac8a0cea29548943fb1a47a558c616c8a7a7