From 24a5a4fbbe26f4cca68714d64cd0d528bf78e9b5 Mon Sep 17 00:00:00 2001 From: OusmBlueNinja <89956790+OusmBlueNinja@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:43:18 -0600 Subject: [PATCH] Updated Input Handler --- imgui.ini | 27 +++--- src/Components/Transform.h | 4 + src/Engine/InputManager.cpp | 89 +++++++++++++++--- src/Engine/InputManager.h | 48 ++++++++-- src/Engine/KeyCode.h | 13 +++ src/Windows/RenderWindow.cpp | 175 +++++++++++++++++++++++++---------- src/Windows/RenderWindow.h | 6 +- 7 files changed, 277 insertions(+), 85 deletions(-) diff --git a/imgui.ini b/imgui.ini index e3d8c6c..1dbd6bd 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,10 +1,11 @@ [Window][DockSpace] Pos=0,0 -Size=1920,1177 +Size=1280,720 Collapsed=0 [Window][Debug##Default] -Pos=926,701 +ViewportPos=1168,966 +ViewportId=0x16723995 Size=400,400 Collapsed=0 @@ -79,8 +80,8 @@ Collapsed=0 DockId=0x0000001F,0 [Window][Performance##performance] -Pos=8,581 -Size=335,588 +Pos=8,360 +Size=335,352 Collapsed=0 DockId=0x0000001C,0 @@ -104,7 +105,7 @@ DockId=0x0000000F,0 [Window][Scene Window##SceneWindow] Pos=8,28 -Size=335,551 +Size=335,330 Collapsed=0 DockId=0x0000001B,0 @@ -133,26 +134,26 @@ Collapsed=0 DockId=0x0000001E,0 [Window][ Logger##logger] -Pos=345,739 -Size=586,430 +Pos=345,282 +Size=265,430 Collapsed=0 DockId=0x00000021,0 [Window][ Editor##EditorWindow] Pos=345,28 -Size=1170,709 +Size=530,252 Collapsed=0 DockId=0x0000001F,0 [Window][ Inspector##InspectorWindow] -Pos=1517,28 -Size=395,1141 +Pos=877,28 +Size=395,684 Collapsed=0 DockId=0x00000022,0 [Window][ Profiler] -Pos=933,739 -Size=582,430 +Pos=612,282 +Size=263,430 Collapsed=0 DockId=0x00000023,0 @@ -180,7 +181,7 @@ Column 0 Width=30 Column 1 Weight=1.0000 [Docking][Data] -DockSpace ID=0x14621557 Window=0x3DA2F1DE Pos=8,28 Size=1904,1141 Split=X Selected=0xF7365A5A +DockSpace ID=0x14621557 Window=0x3DA2F1DE Pos=250,293 Size=1264,684 Split=X Selected=0xF7365A5A DockNode ID=0x00000020 Parent=0x14621557 SizeRef=884,684 Split=X DockNode ID=0x00000013 Parent=0x00000020 SizeRef=335,1142 Split=Y Selected=0x818D04BB DockNode ID=0x0000001B Parent=0x00000013 SizeRef=264,551 HiddenTabBar=1 Selected=0x1D5D92B6 diff --git a/src/Components/Transform.h b/src/Components/Transform.h index f8a1eac..34459e3 100644 --- a/src/Components/Transform.h +++ b/src/Components/Transform.h @@ -32,6 +32,10 @@ public: rotation = {x, y, z}; } + void LookAt(const glm::vec3& target, const glm::vec3& up) { + viewMatrix = glm::lookAt(position, target, up); + } + TransformComponent(); virtual const std::string &GetName() const override; static const std::string &GetStaticName(); diff --git a/src/Engine/InputManager.cpp b/src/Engine/InputManager.cpp index 96df075..4931559 100644 --- a/src/Engine/InputManager.cpp +++ b/src/Engine/InputManager.cpp @@ -1,29 +1,92 @@ // InputManager.cpp #include "InputManager.h" -#include +#include // For std::clamp - - -void InputManager::Update(GLFWwindow* window) +// Constructor +InputManager::InputManager() + : m_MouseDeltaX(0.0f), m_MouseDeltaY(0.0f), m_ScrollDelta(0.0f) { - if (!window) - { + Initialize(); +} + +// Initialize method to set up state vectors +void InputManager::Initialize() { + // Initialize key states + m_KeyStates.resize(GLFW_KEY_LAST + 1, false); + m_PreviousKeyStates.resize(GLFW_KEY_LAST + 1, false); + + // Initialize mouse button states + m_MouseButtonStates.resize(GLFW_MOUSE_BUTTON_LAST + 1, false); + m_PreviousMouseButtonStates.resize(GLFW_MOUSE_BUTTON_LAST + 1, false); +} + +// Update method to poll input states +void InputManager::Update(GLFWwindow* window) { + if (!window) { return; } - // Update the state of each key - for (int key = 0; key <= GLFW_KEY_LAST; ++key) - { + // Update previous key states + m_PreviousKeyStates = m_KeyStates; + + // Update current key states + for (int key = 0; key <= GLFW_KEY_LAST; ++key) { m_KeyStates[key] = glfwGetKey(window, key) == GLFW_PRESS; } + + // Update previous mouse button states + m_PreviousMouseButtonStates = m_MouseButtonStates; + + // Update current mouse button states + for (int button = 0; button <= GLFW_MOUSE_BUTTON_LAST; ++button) { + m_MouseButtonStates[button] = glfwGetMouseButton(window, button) == GLFW_PRESS; + } + + // Reset mouse deltas and scroll delta for this frame + m_MouseDeltaX = 0.0f; + m_MouseDeltaY = 0.0f; + m_ScrollDelta = 0.0f; } -bool InputManager::IsKeyPressed(KeyCode key) const -{ +// Keyboard input query +bool InputManager::IsKeyPressed(KeyCode key) const { int keyInt = static_cast(key); - if (keyInt >= 0 && keyInt <= GLFW_KEY_LAST) - { + if (keyInt >= 0 && keyInt <= GLFW_KEY_LAST) { return m_KeyStates[keyInt]; } return false; } + +// Mouse button input query +bool InputManager::IsMouseButtonPressed(MouseButton button) const { + int buttonInt = static_cast(button); + if (buttonInt >= 0 && buttonInt <= GLFW_MOUSE_BUTTON_LAST) { + return m_MouseButtonStates[buttonInt]; + } + return false; +} + +// Mouse button just pressed (edge detection) +bool InputManager::IsMouseButtonJustPressed(MouseButton button) const { + int buttonInt = static_cast(button); + if (buttonInt >= 0 && buttonInt <= GLFW_MOUSE_BUTTON_LAST) { + return m_MouseButtonStates[buttonInt] && !m_PreviousMouseButtonStates[buttonInt]; + } + return false; +} + +// Mouse button just released (edge detection) +bool InputManager::IsMouseButtonJustReleased(MouseButton button) const { + int buttonInt = static_cast(button); + if (buttonInt >= 0 && buttonInt <= GLFW_MOUSE_BUTTON_LAST) { + return !m_MouseButtonStates[buttonInt] && m_PreviousMouseButtonStates[buttonInt]; + } + return false; +} + +// Reset deltas after handling input +void InputManager::ResetDeltas() { + m_MouseDeltaX = 0.0f; + m_MouseDeltaY = 0.0f; + m_ScrollDelta = 0.0f; +} diff --git a/src/Engine/InputManager.h b/src/Engine/InputManager.h index 6dae226..c584b5e 100644 --- a/src/Engine/InputManager.h +++ b/src/Engine/InputManager.h @@ -3,18 +3,50 @@ #include "KeyCode.h" #include +#include - -class InputManager -{ +class InputManager { public: - // Update key states (to be called every frame) + // Constructor + InputManager(); + + // Update method to poll input states void Update(GLFWwindow* window); - // Check if a key is pressed + // Keyboard input query bool IsKeyPressed(KeyCode key) const; + // Mouse button input queries + bool IsMouseButtonPressed(MouseButton button) const; + bool IsMouseButtonJustPressed(MouseButton button) const; + bool IsMouseButtonJustReleased(MouseButton button) const; + + // Mouse movement deltas + float GetMouseDeltaX() const { return m_MouseDeltaX; } + float GetMouseDeltaY() const { return m_MouseDeltaY; } + + // Scroll delta + float GetScrollDelta() const { return m_ScrollDelta; } + + // Call this after handling input to reset deltas + void ResetDeltas(); + private: - // Array or map storing key states - bool m_KeyStates[GLFW_KEY_LAST + 1] = { false }; -}; + // Storage for key states + std::vector m_KeyStates; + std::vector m_PreviousKeyStates; + + // Storage for mouse button states + std::vector m_MouseButtonStates; + std::vector m_PreviousMouseButtonStates; + + // Mouse movement deltas + float m_MouseDeltaX; + float m_MouseDeltaY; + + // Scroll delta + float m_ScrollDelta; + + // Initialization helper + void Initialize(); +}; \ No newline at end of file diff --git a/src/Engine/KeyCode.h b/src/Engine/KeyCode.h index 9373f96..998344e 100644 --- a/src/Engine/KeyCode.h +++ b/src/Engine/KeyCode.h @@ -126,3 +126,16 @@ enum class KeyCode RightSuper = GLFW_KEY_RIGHT_SUPER, Menu = GLFW_KEY_MENU }; + +// Enum for mouse buttons +enum class MouseButton { + LEFT = GLFW_MOUSE_BUTTON_LEFT, + RIGHT = GLFW_MOUSE_BUTTON_RIGHT, + MIDDLE = GLFW_MOUSE_BUTTON_MIDDLE, + BUTTON4 = GLFW_MOUSE_BUTTON_4, + BUTTON5 = GLFW_MOUSE_BUTTON_5, + BUTTON6 = GLFW_MOUSE_BUTTON_6, + BUTTON7 = GLFW_MOUSE_BUTTON_7, + BUTTON8 = GLFW_MOUSE_BUTTON_8, + LAST = GLFW_MOUSE_BUTTON_LAST +}; diff --git a/src/Windows/RenderWindow.cpp b/src/Windows/RenderWindow.cpp index 35c56c1..6cdfec8 100644 --- a/src/Windows/RenderWindow.cpp +++ b/src/Windows/RenderWindow.cpp @@ -1,30 +1,51 @@ #include "RenderWindow.h" -#include "imgui.h" -#include #include +#include + #include #include #include "Components/GameObject.h" #include "Components/mesh.h" #include "Components/transform.h" +#include "Components/CameraComponent.h" + #include "Engine/AssetManager.h" #include "Engine/Settings.h" +#include "Engine/InputManager.h" +#include "Engine/KeyCode.h" + #include "Rendering/Shader.h" #include "ImGuizmo.h" #include "gcml.h" #include "Icons.h" +#include "imgui.h" + #define CAM_FOV 45.0f #define CAM_NEAR_PLAIN 0.1f #define CAM_FAR_PLAIN 2048.0f +float editorYaw = -90.0f; // Horizontal angle, initialized to face along negative Z-axis +float editorPitch = 0.0f; // Vertical angle +float editorDistance = 5.0f; // Distance from the target +glm::vec3 editorTarget(0.0f, 0.0f, 0.0f); // The point the camera orbits around + +// Configuration Parameters +const float rotationSpeed = 0.1f; // Sensitivity for mouse rotation +const float zoomSpeed = 2.0f; // Sensitivity for zooming +const float movementSpeed = 5.0f; // Speed for panning +const float minZoom = 2.0f; // Minimum zoom distance +const float maxZoom = 20.0f; // Maximum zoom distance + // Managers extern AssetManager g_AssetManager; extern Settings g_SettingsManager; +extern InputManager g_InputManager; + // Settings extern bool DrawBBBO; @@ -222,7 +243,7 @@ enum GizmoOperation // Initialize with a default operation GizmoOperation currentOperation = GIZMO_TRANSLATE; -void RenderWindow::Show(bool *GameRunning) +void RenderWindow::Show(bool *GameRunning, double deltaTime) { // Begin the ImGui window with an icon and label ImGui::Begin(ICON_FA_GAMEPAD " Editor##EditorWindow"); @@ -300,70 +321,120 @@ void RenderWindow::Show(bool *GameRunning) // Obtain view and projection matrices from the active camera glm::mat4 viewMatrix; glm::mat4 projectionMatrix; + // Camera Selection and Setup Logic (e.g., within your rendering or update function) - if (m_ActiveCamera) // Ensure m_ActiveCamera is correctly initialized + if (m_ActiveCamera) { + // Use the existing active camera viewMatrix = m_ActiveCamera->GetViewMatrix(); projectionMatrix = m_ActiveCamera->GetProjectionMatrix(); } else { - // Fallback view matrix - viewMatrix = glm::lookAt(glm::vec3(0.0f, 0.0f, 5.0f), - glm::vec3(0.0f, 0.0f, 0.0f), - glm::vec3(0.0f, 1.0f, 0.0f)); + m_ActiveCamera = m_EditorCamera.GetComponent(); - // Fallback projection matrix - float aspect = (h != 0) ? static_cast(w) / static_cast(h) : 1.0f; - projectionMatrix = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 100.0f); - } - - static ImGuizmo::OPERATION currentOperation = ImGuizmo::TRANSLATE; - - if (ImGui::IsWindowFocused() && ImGui::IsWindowHovered()) - { - - if (ImGui::IsKeyPressed(ImGuiKey_T)) + // 1. Mouse Input for Rotation + if (g_InputManager.IsMouseButtonPressed(MouseButton::RIGHT)) { - currentOperation = ImGuizmo::TRANSLATE; - } - if (ImGui::IsKeyPressed(ImGuiKey_R)) - { - currentOperation = ImGuizmo::ROTATE; + float deltaX = g_InputManager.GetMouseDeltaX(); + float deltaY = g_InputManager.GetMouseDeltaY(); + + editorYaw += deltaX * rotationSpeed; + editorPitch += deltaY * rotationSpeed; + + // Clamp the pitch to prevent flipping + if (editorPitch > 89.0f) + editorPitch = 89.0f; + if (editorPitch < -89.0f) + editorPitch = -89.0f; } - if (ImGui::IsKeyPressed(ImGuiKey_S)) + // 2. Scroll Input for Zooming + float scrollDelta = g_InputManager.GetScrollDelta(); + editorDistance -= scrollDelta * zoomSpeed; + editorDistance = glm::clamp(editorDistance, minZoom, maxZoom); + + // 3. Keyboard Input for Panning (WASD) + glm::vec3 forward = glm::normalize(editorTarget - m_EditorCamera.GetComponent()->GetPosition()); + glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0f, 1.0f, 0.0f))); + glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f); + + deltaTime = static_cast(deltaTime); + + if (g_InputManager.IsKeyPressed(KeyCode::W)) + editorTarget += up * movementSpeed * deltaTime; + if (g_InputManager.IsKeyPressed(KeyCode::S)) + editorTarget -= up * movementSpeed * deltaTime; + if (g_InputManager.IsKeyPressed(KeyCode::A)) + editorTarget -= right * movementSpeed * deltaTime; + if (g_InputManager.IsKeyPressed(KeyCode::D)) + editorTarget += right * movementSpeed * deltaTime; + + // 4. Calculate the New Camera Position + glm::vec3 direction; + direction.x = cos(glm::radians(editorYaw)) * cos(glm::radians(editorPitch)); + direction.y = sin(glm::radians(editorPitch)); + direction.z = sin(glm::radians(editorYaw)) * cos(glm::radians(editorPitch)); + direction = glm::normalize(direction); + + glm::vec3 newPosition = editorTarget - direction * editorDistance; + + // 5. Update the Editor Camera's Transform + auto editorTransform = m_EditorCamera.GetComponent(); + editorTransform->SetPosition(newPosition); + editorTransform->LookAt(editorTarget, up); + + // 6. Retrieve Updated Matrices + viewMatrix = m_ActiveCamera->GetViewMatrix(); + projectionMatrix = m_ActiveCamera->GetProjectionMatrix(); + + static ImGuizmo::OPERATION currentOperation = ImGuizmo::TRANSLATE; + + if (ImGui::IsWindowFocused() && ImGui::IsWindowHovered()) { - currentOperation = ImGuizmo::SCALE; + + if (ImGui::IsKeyPressed(ImGuiKey_T)) + { + currentOperation = ImGuizmo::TRANSLATE; + } + if (ImGui::IsKeyPressed(ImGuiKey_R)) + { + currentOperation = ImGuizmo::ROTATE; + } + + if (ImGui::IsKeyPressed(ImGuiKey_S)) + { + currentOperation = ImGuizmo::SCALE; + } } - } - // Define snap settings - bool snap = false; // Enable snapping if needed - float snapValue = 0.1f; // Snap increment + // Define snap settings + bool snap = false; // Enable snapping if needed + float snapValue = 0.1f; // Snap increment - // Set the ImGuizmo rectangle to the window's position and size - ImVec2 windowPos = ImGui::GetWindowPos(); - ImVec2 windowSize = ImGui::GetWindowSize(); - ImGuizmo::SetRect(windowPos.x, windowPos.y, windowSize.x, windowSize.y); + // Set the ImGuizmo rectangle to the window's position and size + ImVec2 windowPos = ImGui::GetWindowPos(); + ImVec2 windowSize = ImGui::GetWindowSize(); + ImGuizmo::SetRect(windowPos.x, windowPos.y, windowSize.x, windowSize.y); - // Render the gizmo and handle user interaction - projectionMatrix[1][1] *= -1.0f; // Flip Image Internaly - ImGuizmo::Manipulate( - glm::value_ptr(viewMatrix), - glm::value_ptr(projectionMatrix), - currentOperation, - ImGuizmo::LOCAL, - glm::value_ptr(modelMatrix), - nullptr, // Optional delta matrix - snap ? &snapValue : nullptr // Optional snap values - ); + // Render the gizmo and handle user interaction + projectionMatrix[1][1] *= -1.0f; // Flip Image Internaly + ImGuizmo::Manipulate( + glm::value_ptr(viewMatrix), + glm::value_ptr(projectionMatrix), + currentOperation, + ImGuizmo::LOCAL, + glm::value_ptr(modelMatrix), + nullptr, // Optional delta matrix + snap ? &snapValue : nullptr // Optional snap values + ); - // Check if the gizmo is being used (i.e., if the user is interacting with it) - if (ImGuizmo::IsUsing()) - { - // Update the TransformComponent with the modified matrix - transform->SetTransformMatrix(modelMatrix); + // Check if the gizmo is being used (i.e., if the user is interacting with it) + if (ImGuizmo::IsUsing()) + { + // Update the TransformComponent with the modified matrix + transform->SetTransformMatrix(modelMatrix); + } } } } @@ -387,6 +458,10 @@ void RenderWindow::InitGLResources() // throw this in here cus we dont have a constructor m_ActiveCamera = nullptr; + // Setup the editor camera + m_EditorCamera.AddComponent(std::make_shared()); + m_EditorCamera.AddComponent(std::make_shared()); + { std::shared_ptr shaderAsset = g_AssetManager.loadAsset(AssetType::SHADER, "assets/shaders/UnlitMaterial"); if (!shaderAsset) diff --git a/src/Windows/RenderWindow.h b/src/Windows/RenderWindow.h index 1553cb0..9805ba6 100644 --- a/src/Windows/RenderWindow.h +++ b/src/Windows/RenderWindow.h @@ -5,11 +5,13 @@ #include #include "Rendering/Shader.h" // #include "Components/CameraComponent.h" +#include "Components/GameObject.h" +#include "Engine/InputManager.h" class RenderWindow { public: - void Show(bool *GameRunning); + void Show(bool *GameRunning, double deltaTime); private: void InitGLResources(); @@ -39,6 +41,8 @@ private: // The loaded shader program (via AssetManager) Shader* m_ShaderPtr = nullptr; Shader* m_LineShaderPtr = nullptr; + + GameObject m_EditorCamera; };