diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 4b6d67ad..5e1b88b0 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -132,6 +132,8 @@ int main(int argc, char* argv[]) Nuake::Engine::Tick(); Nuake::Engine::Draw(); + Timestep ts = Nuake::Engine::GetTimestep(); + Nuake::Vector2 WindowSize = window->GetSize(); glViewport(0, 0, WindowSize.x, WindowSize.y); Nuake::Renderer2D::BeginDraw(WindowSize); @@ -153,6 +155,7 @@ int main(int argc, char* argv[]) } sceneFramebuffer->Unbind(); + editor.Update(ts); editor.Draw(); Nuake::Engine::EndDraw(); diff --git a/Editor/src/Windows/EditorInterface.cpp b/Editor/src/Windows/EditorInterface.cpp index e2ab9426..4d0769f5 100644 --- a/Editor/src/Windows/EditorInterface.cpp +++ b/Editor/src/Windows/EditorInterface.cpp @@ -96,6 +96,13 @@ namespace Nuake { Ref texture = framebuffer->GetTexture(); ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + const Vector2& mousePos = Input::GetMousePosition(); + const ImVec2& windowPos = ImGui::GetWindowPos(); + const ImVec2& windowSize = ImGui::GetWindowSize(); + const bool isInsideWidth = mousePos.x > windowPos.x && mousePos.x < windowPos.x + windowSize.x; + const bool isInsideHeight = mousePos.y > windowPos.y && mousePos.y < windowPos.y + windowSize.y; + m_IsHoveringViewport = isInsideWidth && isInsideHeight; + ImGuizmo::SetDrawlist(); ImGuizmo::AllowAxisFlip(false); ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, ImGui::GetWindowWidth(), ImGui::GetWindowHeight()); @@ -1091,10 +1098,11 @@ namespace Nuake { CurrentOperation = ImGuizmo::OPERATION::SCALE; } ImGui::PopStyleVar(); - } ImGui::PopStyleVar(); ImGui::End(); + + int corner2 = 1; window_flags |= ImGuiWindowFlags_NoMove; @@ -1107,10 +1115,23 @@ namespace Nuake { ImGui::SetNextWindowViewport(viewport->ID); ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 32.0f); + ImGui::SetNextWindowSize(ImVec2(25, ImGui::GetContentRegionAvail().y - DISTANCE * 2.0)); if (ImGui::Begin("Controls", &m_ShowOverlay, window_flags)) { + const auto& editorCam = Engine::GetCurrentScene()->m_EditorCamera; + const float camSpeed = editorCam->Speed; + + const float maxSpeed = 50.0f; + const float minSpeed = 0.1f; + const float normalizedSpeed = camSpeed / maxSpeed; + + ImVec2 start = ImGui::GetWindowPos(); + ImVec2 end = start + ImGui::GetWindowSize(); + + ImVec2 startOffset = ImVec2(start.x, end.y - (normalizedSpeed * ImGui::GetWindowHeight())); + + ImGui::GetWindowDrawList()->AddRectFilled(startOffset, end, IM_COL32(255, 255, 255, 180), 200.0f); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 100); - if (ImGui::Button("...")) {}; ImGui::PopStyleVar(); } @@ -1374,6 +1395,19 @@ namespace Nuake { ImGui::End(); } + void EditorInterface::Update(float ts) + { + auto& editorCam = Engine::GetCurrentScene()->m_EditorCamera; + editorCam->Update(ts, m_IsHoveringViewport); + + const bool entityIsSelected = Selection.Type == EditorSelectionType::Entity && Selection.Entity.IsValid(); + if (entityIsSelected && Input::IsKeyPressed(GLFW_KEY_F)) + { + editorCam->IsMoving = true; + editorCam->TargetPos = Vector3(0, 0, 0); + } + } + void EditorInterface::BuildFonts() { ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.5f, 0.5f)); diff --git a/Editor/src/Windows/EditorInterface.h b/Editor/src/Windows/EditorInterface.h index e7e51728..1e2a6cd4 100644 --- a/Editor/src/Windows/EditorInterface.h +++ b/Editor/src/Windows/EditorInterface.h @@ -17,6 +17,8 @@ namespace Nuake { bool m_ShowImGuiDemo = false; bool m_DebugCollisions = false; bool m_ShowOverlay = true; + bool m_IsHoveringViewport = false; + ImGuizmo::OPERATION CurrentOperation = ImGuizmo::TRANSLATE; ImGuizmo::MODE CurrentMode = ImGuizmo::WORLD; Ref m_SelectedMaterial; @@ -36,6 +38,7 @@ namespace Nuake { void BuildFonts(); void Init(); void Draw(); + void Update(float ts); void DrawMenuBar(); void DrawViewport(); void DrawEntityTree(Entity ent); diff --git a/Nuake/Engine.cpp b/Nuake/Engine.cpp index 20cef04b..d1caafb7 100644 --- a/Nuake/Engine.cpp +++ b/Nuake/Engine.cpp @@ -21,6 +21,7 @@ namespace Nuake float Engine::m_FixedUpdateRate = 1.0f / 90.0f; float Engine::m_FixedUpdateDifference = 0.f; float Engine::m_Time = 0.f; + Timestep Engine::m_TimeStep = 0.f; bool Engine::IsPlayMode = false; @@ -35,6 +36,8 @@ namespace Nuake CurrentWindow = Window::Get(); Logger::Log("Window initialized"); + Input::Init(); + Renderer2D::Init(); Logger::Log("2D renderer initialized"); @@ -44,18 +47,18 @@ namespace Nuake void Engine::Tick() { m_Time = (float)glfwGetTime(); - Timestep timestep = m_Time - m_LastFrameTime; + m_TimeStep = m_Time - m_LastFrameTime; m_LastFrameTime = m_Time; // Dont update if no scene is loaded. if (CurrentWindow->GetScene()) { - CurrentWindow->Update(timestep); + CurrentWindow->Update(m_TimeStep); // Play mode update all the entities, Editor does not. if (Engine::IsPlayMode) { - m_FixedUpdateDifference += timestep; + m_FixedUpdateDifference += m_TimeStep; // Fixed update if (m_FixedUpdateDifference >= m_FixedUpdateRate) @@ -67,7 +70,7 @@ namespace Nuake } else { - GetCurrentScene()->EditorUpdate(timestep); + GetCurrentScene()->EditorUpdate(m_TimeStep); } } diff --git a/Nuake/Engine.h b/Nuake/Engine.h index 6f635179..076b2c74 100644 --- a/Nuake/Engine.h +++ b/Nuake/Engine.h @@ -26,6 +26,7 @@ namespace Nuake static float m_FixedUpdateRate; static float m_FixedUpdateDifference; static float m_Time; + static Timestep m_TimeStep; public: static bool IsPlayMode; // Is currently in runtime.. @@ -40,6 +41,7 @@ namespace Nuake static void Draw(); // Start new frame static void EndDraw(); // Swap buffer static inline float GetTime() { return m_Time; } + static inline Timestep GetTimestep() { return m_TimeStep; } static Ref GetCurrentWindow(); static bool LoadScene(Ref scene); diff --git a/Nuake/src/Core/Input.cpp b/Nuake/src/Core/Input.cpp index b89076ca..b59d35fd 100644 --- a/Nuake/src/Core/Input.cpp +++ b/Nuake/src/Core/Input.cpp @@ -1,5 +1,7 @@ #include "Input.h" #include "../Window.h" + +#include #include namespace Nuake @@ -7,6 +9,16 @@ namespace Nuake Input* Input::s_Instance; std::map Input::m_Keys = std::map(); bool Input::m_MouseButtons[5] = { false, false, false, false, false }; + float Input::XScroll = 0.0f; + float Input::YScroll = 0.0f; + + void Input::ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) + { + XScroll = (float)xoffset; + YScroll = (float)yoffset; + + ImGui_ImplGlfw_ScrollCallback(window, xoffset, yoffset); + } #pragma region Keys // Only true if the key is currently being pressed @@ -82,7 +94,6 @@ namespace Nuake glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); } - // Action bool Input::IsMouseButtonDown(int button) { @@ -150,6 +161,7 @@ namespace Nuake { //auto window = Application::Get().GetWindow()->GetNative(); //glfwSetKeyCallback(window, Input::HandleInputCallback); + glfwSetScrollCallback(Window::Get()->GetHandle(), Input::ScrollCallback); return false; } diff --git a/Nuake/src/Core/Input.h b/Nuake/src/Core/Input.h index 35bd5897..6b47073f 100644 --- a/Nuake/src/Core/Input.h +++ b/Nuake/src/Core/Input.h @@ -3,6 +3,8 @@ #include "../Core/Maths.h" #include +struct GLFWwindow; + namespace Nuake { class Input @@ -15,6 +17,9 @@ namespace Nuake static bool IsKeyDown(int keycode); static bool IsKeyReleased(int keycode); + static float YScroll; + static float XScroll; + static void ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); static void HideMouse(); static void ShowMouse(); diff --git a/Nuake/src/Rendering/PostFX/SSAO.cpp b/Nuake/src/Rendering/PostFX/SSAO.cpp index df53923b..e3b6c027 100644 --- a/Nuake/src/Rendering/PostFX/SSAO.cpp +++ b/Nuake/src/Rendering/PostFX/SSAO.cpp @@ -56,7 +56,7 @@ namespace Nuake sample = glm::normalize(sample); sample *= randomFloats(generator); - float scale = (float)i / 64.0; + float scale = (float)i / 64.0f; scale = lerp(0.1f, 1.0f, scale * scale); sample *= scale; _ssaoKernel.push_back(sample); diff --git a/Nuake/src/Scene/EditorCamera.cpp b/Nuake/src/Scene/EditorCamera.cpp index 4d38dff1..175c91e5 100644 --- a/Nuake/src/Scene/EditorCamera.cpp +++ b/Nuake/src/Scene/EditorCamera.cpp @@ -6,100 +6,167 @@ namespace Nuake { - void EditorCamera::Update(Timestep ts) + void EditorCamera::Update(Timestep ts, const bool hover) { - float x = Input::GetMouseX(); - float y = Input::GetMouseY(); - - if (!controlled && Input::IsMouseButtonDown(1)) + if (IsMoving) { - mouseLastX = x; - mouseLastY = y; + Translation = glm::mix(Translation, TargetPos, 3.1f * ts); + Direction = glm::mix(Direction, TargetPos - Translation, 3.1f * ts); + if (glm::length(Translation - TargetPos) < 3.0f) + { + IsMoving = false; + Translation = Translation - TargetPos; + } } - controlled = Input::IsMouseButtonDown(1); + const float x = Input::GetMouseX(); + const float y = Input::GetMouseY(); - //if (!controlled) - // Input::ShowMouse(); - //else - // Input::HideMouse(); + const bool isFlying = Input::IsMouseButtonDown(1) || Input::IsMouseButtonDown(2); + const bool isPressingMouse = isFlying || Input::YScroll != 0.0f; + + if (hover) + { + controlled = isPressingMouse; + } + else + { + if (controlled && !isPressingMouse) + { + controlled = false; + } + } - // Should probably not have speed binding in here. - if (Input::IsKeyDown(GLFW_KEY_UP)) - Speed += 0.1f; - else if (Input::IsKeyDown(GLFW_KEY_DOWN)) - Speed -= 0.1f; - - if (Speed < 0) - Speed = 0; - - // Keyboard if (!controlled) - return; - - if (m_Type == CAMERA_TYPE::ORTHO) { - if (Input::IsKeyDown(GLFW_KEY_RIGHT)) - Translation.x += Speed * ts; - if (Input::IsKeyDown(GLFW_KEY_LEFT)) - Translation.x -= Speed * ts; - if (Input::IsKeyDown(GLFW_KEY_UP)) - Translation.y += Speed * ts; - if (Input::IsKeyDown(GLFW_KEY_DOWN)) - Translation.y -= Speed * ts; + Input::ShowMouse(); } - else + else if(hover) { - glm::vec3 movement = glm::vec3(0, 0, 0); - - if (Input::IsKeyDown(GLFW_KEY_D)) - movement -= Right * (Speed * ts); - if (Input::IsKeyDown(GLFW_KEY_A)) - movement += Right * (Speed * ts); - - if (Input::IsKeyDown(GLFW_KEY_W)) - movement += Direction * (Speed * ts); - if (Input::IsKeyDown(GLFW_KEY_S)) - movement -= Direction * (Speed * ts); - if (Input::IsKeyDown(GLFW_KEY_LEFT_SHIFT)) - movement -= Up * (Speed * ts); - if (Input::IsKeyDown(GLFW_KEY_SPACE)) - movement += Up * (Speed * ts); - - Translation += Vector3(movement); + Input::HideMouse(); } - if (firstMouse) + if (Input::IsKeyDown(GLFW_KEY_LEFT_ALT)) { - mouseLastX = x; - mouseLastY = y; - firstMouse = false; + if (Input::YScroll != 0.0f) + { + this->Fov += Input::YScroll; + + if (Fov < 5.0f) + { + Fov = 5.0f; + } + + Input::YScroll = 0.0f; + } } + else + { + // Keyboard + if (!controlled) + { + mouseLastX = x; + mouseLastY = y; + return; + } - // mouse - float diffx = x - mouseLastX; - float diffy = mouseLastY - y; - mouseLastX = x; - mouseLastY = y; + if (Input::IsMouseButtonDown(1)) + { + // Should probably not have speed binding in here. + if (Input::YScroll != 0) + { + Speed += Input::YScroll; + Input::YScroll = 0.0f; + } - const float sensitivity = 0.1f; - diffx *= sensitivity; - diffy *= sensitivity; + if (Speed < 0) + Speed = 0; - Yaw += diffx; - Pitch += diffy; - if (Pitch > 89.0f) - Pitch = 89.0f; - if (Pitch < -89.0f) - Pitch = -89.0f; + if (m_Type == CAMERA_TYPE::ORTHO) + { + if (Input::IsKeyDown(GLFW_KEY_RIGHT)) + Translation.x += Speed * ts; + if (Input::IsKeyDown(GLFW_KEY_LEFT)) + Translation.x -= Speed * ts; + if (Input::IsKeyDown(GLFW_KEY_UP)) + Translation.y += Speed * ts; + if (Input::IsKeyDown(GLFW_KEY_DOWN)) + Translation.y -= Speed * ts; + } + else + { + glm::vec3 movement = glm::vec3(0, 0, 0); - Direction.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch)); - Direction.y = sin(glm::radians(Pitch)); - Direction.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch)); - Direction = glm::normalize(Direction); - Right = glm::normalize(glm::cross(Up, Direction)); + if (Input::IsKeyDown(GLFW_KEY_D)) + movement -= Right * (Speed * ts); + if (Input::IsKeyDown(GLFW_KEY_A)) + movement += Right * (Speed * ts); + + if (Input::IsKeyDown(GLFW_KEY_W)) + movement += Direction * (Speed * ts); + if (Input::IsKeyDown(GLFW_KEY_S)) + movement -= Direction * (Speed * ts); + if (Input::IsKeyDown(GLFW_KEY_LEFT_SHIFT)) + movement -= Up * (Speed * ts); + if (Input::IsKeyDown(GLFW_KEY_SPACE)) + movement += Up * (Speed * ts); + + Translation += Vector3(movement); + } + + if (firstMouse) + { + mouseLastX = x; + mouseLastY = y; + firstMouse = false; + } + + // mouse + float diffx = x - mouseLastX; + float diffy = mouseLastY - y; + mouseLastX = x; + mouseLastY = y; + + const float sensitivity = 0.1f; + diffx *= sensitivity; + diffy *= sensitivity; + + Yaw += diffx; + Pitch += diffy; + + if (Pitch > 89.0f) + Pitch = 89.0f; + if (Pitch < -89.0f) + Pitch = -89.0f; + + Direction.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch)); + Direction.y = sin(glm::radians(Pitch)); + Direction.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch)); + Direction = glm::normalize(Direction); + Right = glm::normalize(glm::cross(Up, Direction)); + } + else if (Input::IsMouseButtonDown(2)) + { + Vector3 movement = Vector3(0); + const float deltaX = x - mouseLastX; + const float deltaY = y - mouseLastY; + movement += Right * (deltaX * ts); + movement += Up * (deltaY * ts); + Translation += Vector3(movement) * 0.5f; + + mouseLastX = x; + mouseLastY = y; + controlled = true; + } + else if (Input::YScroll != 0) + { + Translation += Vector3(Direction) * Input::YScroll; + Input::YScroll = 0.0f; + } + } } + Ref EditorCamera::Copy() { Ref copy = CreateRef(); diff --git a/Nuake/src/Scene/EditorCamera.h b/Nuake/src/Scene/EditorCamera.h index 44a797a9..28016309 100644 --- a/Nuake/src/Scene/EditorCamera.h +++ b/Nuake/src/Scene/EditorCamera.h @@ -14,9 +14,10 @@ namespace Nuake SetDirection(Vector3(-1, -1, -1)); } - void Update(Timestep ts); - + void Update(Timestep ts, const bool hover); + Vector3 TargetPos = Vector3(0, 0, 0); + bool IsMoving = false; Ref Copy(); private: bool controlled = false; diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 9e8e88d2..6ef7b7dd 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -126,7 +126,7 @@ namespace Nuake { void Scene::EditorUpdate(Timestep ts) { - m_EditorCamera->Update(ts); + } void Scene::Draw(FrameBuffer& framebuffer)