From 4268376587af6dd9d23d2746f701bb2525dfa974 Mon Sep 17 00:00:00 2001 From: hultonha <82228511+hultonha@users.noreply.github.com> Date: Fri, 23 Jul 2021 07:52:44 +0100 Subject: [PATCH] Ensure camera system correctly consumes events when it is active (#2346) * add typename for struct initializer Signed-off-by: hultonha * fix for ensuring while the camera is 'active', events are consumed and not propagated Signed-off-by: hultonha * refactor how we decide which priority to repsond to events to Signed-off-by: hultonha * also -> only Signed-off-by: hultonha --- .../AzFramework/Viewport/CameraInput.cpp | 4 +++- .../AzFramework/Viewport/CameraInput.h | 2 ++ .../ModularViewportCameraController.cpp | 21 ++++++++++++------- .../Source/Viewport/RenderViewportWidget.cpp | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp index 1e324a4919..c5b6a2ff96 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp @@ -147,7 +147,9 @@ namespace AzFramework m_scrollDelta = scroll->m_delta; } - return m_cameras.HandleEvents(event, m_motionDelta, m_scrollDelta); + m_handlingEvents = m_cameras.HandleEvents(event, m_motionDelta, m_scrollDelta); + + return m_handlingEvents; } Camera CameraSystem::StepCamera(const Camera& targetCamera, const float deltaTime) diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h index 7c97bc7f89..bb0df4853a 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h @@ -262,12 +262,14 @@ namespace AzFramework public: bool HandleEvents(const InputEvent& event); Camera StepCamera(const Camera& targetCamera, float deltaTime); + bool HandlingEvents() const { return m_handlingEvents; } Cameras m_cameras; //!< Represents a collection of camera inputs that together provide a camera controller. private: ScreenVector m_motionDelta; //!< The delta used for look/orbit/pan (rotation + translation) - two dimensional. float m_scrollDelta = 0.0f; //!< The delta used for dolly/movement (translation) - one dimensional. + bool m_handlingEvents = false; //!< Is the camera system currently handling events (events are consumed and not propagated). }; //! A camera input to handle motion deltas that can rotate or orbit the camera. diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp index 9e2945fe31..10cfa059aa 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/ModularViewportCameraController.cpp @@ -117,19 +117,24 @@ namespace AtomToolsFramework AzFramework::ViewportDebugDisplayEventBus::Handler::BusDisconnect(); } - // should the camera system respond to this particular event - static bool ShouldHandle(const AzFramework::ViewportControllerPriority priority, const bool exclusive) + // what priority should the camera system respond to + static AzFramework::ViewportControllerPriority GetPriority(const AzFramework::CameraSystem& cameraSystem) { - // ModernViewportCameraControllerInstance receives events at all priorities, it should only respond - // to normal priority events if it is not in 'exclusive' mode and when in 'exclusive' mode it should - // only respond to the highest priority events - return !exclusive && priority == AzFramework::ViewportControllerPriority::Normal || - exclusive && priority == AzFramework::ViewportControllerPriority::Highest; + // ModernViewportCameraControllerInstance receives events at all priorities, when it is in 'exclusive' mode + // or it is actively handling events (essentially when the camera system is 'active' and responding to inputs) + // it should only respond to the highest priority + if (cameraSystem.m_cameras.Exclusive() || cameraSystem.HandlingEvents()) + { + return AzFramework::ViewportControllerPriority::Highest; + } + + // otherwise it should only respond to normal priority events + return AzFramework::ViewportControllerPriority::Normal; } bool ModernViewportCameraControllerInstance::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) { - if (ShouldHandle(event.m_priority, m_cameraSystem.m_cameras.Exclusive())) + if (event.m_priority == GetPriority(m_cameraSystem)) { return m_cameraSystem.HandleEvents(AzFramework::BuildInputEvent(event.m_inputChannel)); } diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp index 0ea59fcf9e..5167e3d3f6 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp @@ -88,7 +88,7 @@ namespace AtomToolsFramework [this](const AzFramework::InputChannel* inputChannel, QEvent* event) { AzFramework::NativeWindowHandle windowId = reinterpret_cast(winId()); - if (m_controllerList->HandleInputChannelEvent({GetId(), windowId, *inputChannel})) + if (m_controllerList->HandleInputChannelEvent(AzFramework::ViewportControllerInputEvent{GetId(), windowId, *inputChannel})) { // If the controller handled the input event, mark the event as accepted so it doesn't continue to propagate. if (event)