From 968399c72342f5e9834169fd84f8c61c1a43c41e Mon Sep 17 00:00:00 2001 From: VTui22 <106135221+VTui22@users.noreply.github.com> Date: Sat, 16 Sep 2023 18:43:37 +0800 Subject: [PATCH] improve mouse operations in scene view (#385) --- Engine/Source/Editor/EditorApp.cpp | 1 + Engine/Source/Editor/UILayers/SceneView.cpp | 52 +++++++++++++-------- Engine/Source/Editor/UILayers/SceneView.h | 13 ++++++ Engine/Source/Runtime/Window/Window.cpp | 14 ++++++ Engine/Source/Runtime/Window/Window.h | 6 ++- 5 files changed, 65 insertions(+), 21 deletions(-) diff --git a/Engine/Source/Editor/EditorApp.cpp b/Engine/Source/Editor/EditorApp.cpp index e0abcd8c..39cbb23b 100644 --- a/Engine/Source/Editor/EditorApp.cpp +++ b/Engine/Source/Editor/EditorApp.cpp @@ -561,6 +561,7 @@ bool EditorApp::Update(float deltaTime) if (m_pEngineImGuiContext) { + GetMainWindow()->SetMouseVisible(m_pSceneView->IsShowMouse(), m_pSceneView->GetMouseFixedPositionX(), m_pSceneView->GetMouseFixedPositionY()); if (m_pViewportCameraController) { m_pViewportCameraController->Update(deltaTime); diff --git a/Engine/Source/Editor/UILayers/SceneView.cpp b/Engine/Source/Editor/UILayers/SceneView.cpp index 9555e2c2..02af5e01 100644 --- a/Engine/Source/Editor/UILayers/SceneView.cpp +++ b/Engine/Source/Editor/UILayers/SceneView.cpp @@ -244,8 +244,8 @@ void SceneView::PickSceneMesh(float regionWidth, float regionHeight) return; } - float screenX = static_cast(engine::Input::Get().GetMousePositionX() - GetWindowPosX()); - float screenY = static_cast(engine::Input::Get().GetMousePositionY() - GetWindowPosY()); + float screenX = static_cast(m_mouseFixedPositionX - GetWindowPosX()); + float screenY = static_cast(m_mouseFixedPositionY - GetWindowPosY()); float screenWidth = static_cast(regionWidth); float screenHeight = static_cast(regionHeight); if (screenX < 0.0f || screenX > screenWidth || @@ -290,6 +290,7 @@ void SceneView::PickSceneMesh(float regionWidth, float regionHeight) } pSceneWorld->SetSelectedEntity(nearestEntity); + } void SceneView::Update() @@ -307,21 +308,6 @@ void SceneView::Update() ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); auto flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse; ImGui::Begin(GetName(), &m_isEnable, flags); - if (engine::Input::Get().IsMouseLBPressed()) - { - ImVec2 windowSize = ImGui::GetWindowSize(); - ImVec2 windowPos = ImGui::GetWindowPos(); - ImVec2 mousePos = ImGui::GetMousePos(); - cd::Vec2f rightDown(windowPos.x + windowSize.x, windowPos.y + windowSize.y); - if (mousePos.x > windowPos.x && mousePos.x < rightDown.x() && mousePos.y > windowPos.y && mousePos.y < rightDown.y() && !m_isTerrainEditMode) - { - m_pCameraController->SetIsInViewScene(true); - } - else - { - m_pCameraController->SetIsInViewScene(false); - } - } // Draw top menu buttons which include ImGuizmo operation modes, ViewCamera settings. UpdateToolMenuButtons(); @@ -341,6 +327,9 @@ void SceneView::Update() pCameraComponent->SetAspect(static_cast(regionWidth) / static_cast(regionHeight)); } } + ImVec2 windowPos = ImGui::GetWindowPos(); + ImVec2 mousePos = ImGui::GetMousePos(); + cd::Vec2f rightDown(windowPos.x + regionSize.x, windowPos.y + regionSize.y); // Check if mouse hover on the area of SceneView so it can control. ImVec2 cursorPosition = ImGui::GetCursorPos(); @@ -365,19 +354,44 @@ void SceneView::Update() ImGui::End(); - if (engine::Input::Get().IsMouseLBPressed()) + if (engine::Input::Get().IsMouseLBPressed() || engine::Input::Get().IsMouseMBPressed() || engine::Input::Get().IsMouseRBPressed()) { if (!m_isMouseDownFirstTime) { + if (0 != engine::Input::Get().GetMousePositionOffsetX() || 0 != engine::Input::Get().GetMousePositionOffsetY()) + { + m_isUsingCamera = true; + } + if (engine::Input::Get().IsMouseLBPressed()) + { + m_isLeftClick = true; + } return; } m_isMouseDownFirstTime = false; - PickSceneMesh(regionWidth, regionHeight); + if (mousePos.x > windowPos.x && mousePos.x < rightDown.x() && mousePos.y > windowPos.y && mousePos.y < rightDown.y() && !m_isTerrainEditMode) + { + m_pCameraController->SetIsInViewScene(true); + m_isMouseShow = false; + } + else + { + m_pCameraController->SetIsInViewScene(false); + } } else { + m_mouseFixedPositionX = engine::Input::Get().GetMousePositionX(); + m_mouseFixedPositionY = engine::Input::Get().GetMousePositionY(); + if (!m_isMouseShow && !m_isUsingCamera) + { + PickSceneMesh(regionWidth, regionHeight); + } m_isMouseDownFirstTime = true; + m_isMouseShow = true; + m_isUsingCamera = false; + m_isLeftClick = false; } } diff --git a/Engine/Source/Editor/UILayers/SceneView.h b/Engine/Source/Editor/UILayers/SceneView.h index 8067f55a..80c385b3 100644 --- a/Engine/Source/Editor/UILayers/SceneView.h +++ b/Engine/Source/Editor/UILayers/SceneView.h @@ -63,6 +63,10 @@ class SceneView : public engine::ImGuiBaseLayer void SetAABBRenderer(engine::Renderer* pAABBRenderer) { m_pAABBRenderer = pAABBRenderer; } bool IsTerrainEditMode() const { return m_isTerrainEditMode; } + bool IsFirstClick() const { return m_isMouseDownFirstTime; } + bool IsShowMouse() { return m_isMouseShow; } + uint32_t GetMouseFixedPositionX() const { return m_mouseFixedPositionX; } + uint32_t GetMouseFixedPositionY() const { return m_mouseFixedPositionY; } void SetCameraController(engine::CameraController* pCameraController) { m_pCameraController = pCameraController; } @@ -84,6 +88,9 @@ class SceneView : public engine::ImGuiBaseLayer bool m_is3DMode = true; bool m_isIBLActive = false; bool m_isTerrainEditMode = false; + bool m_isMouseShow = true; + bool m_isUsingCamera = false; + bool m_isLeftClick = false; RenderModeType m_renderMode = RenderModeType::Rendered; engine::Renderer* m_pSceneRenderer = nullptr; @@ -94,6 +101,12 @@ class SceneView : public engine::ImGuiBaseLayer engine::RenderTarget* m_pRenderTarget = nullptr; bool m_isMouseDownFirstTime = true; + int32_t m_mouseFixedPositionX = 0; + int32_t m_mouseFixedPositionY = 0; + + int32_t m_mouseMovementDuringPressedX; + int32_t m_mouseMovementDuringPressedY; + engine::CameraController* m_pCameraController = nullptr; }; diff --git a/Engine/Source/Runtime/Window/Window.cpp b/Engine/Source/Runtime/Window/Window.cpp index c40569a7..ad1cc71a 100644 --- a/Engine/Source/Runtime/Window/Window.cpp +++ b/Engine/Source/Runtime/Window/Window.cpp @@ -313,4 +313,18 @@ void Window::SetWindowIcon(const char* pFilePath) const stbi_image_free(pImageData); } +void Window::SetMouseVisible(bool isVisible, uint32_t x, uint32_t y) +{ + SDL_ShowCursor(isVisible); + if (!isVisible) + { + SDL_SetRelativeMouseMode(SDL_TRUE); + SDL_WarpMouseInWindow(m_pSDLWindow, x, y); + } + else + { + SDL_SetRelativeMouseMode(SDL_FALSE); + } +} + } \ No newline at end of file diff --git a/Engine/Source/Runtime/Window/Window.h b/Engine/Source/Runtime/Window/Window.h index c2477bf8..89d62fea 100644 --- a/Engine/Source/Runtime/Window/Window.h +++ b/Engine/Source/Runtime/Window/Window.h @@ -28,7 +28,7 @@ class Window uint16_t GetWidth() const { return m_width; } uint16_t GetHeight() const { return m_height; } - + const bool GetInputFocus() const; const bool GetMouseFocus() const; @@ -43,7 +43,9 @@ class Window bool ShouldClose() const { return m_isClosed; } void Close(bool bPushSdlEvent = true); - + + void SetMouseVisible(bool isVisible, uint32_t x, uint32_t y); + public: // Window Delegate OnDropFile;