AnimViewportInputController.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
  9. #include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
  10. #include <AzToolsFramework/Viewport/ViewportMessages.h>
  11. #include <AzToolsFramework/Manipulators/ManipulatorManager.h>
  12. #include <AzToolsFramework/Viewport/ViewportInteractionHelpers.h>
  13. #include <EMStudio/AnimViewportInputController.h>
  14. namespace EMStudio
  15. {
  16. bool AnimViewportInputController::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
  17. {
  18. using AzFramework::InputChannel;
  19. using AzToolsFramework::ViewportInteraction::KeyboardModifier;
  20. using AzToolsFramework::ViewportInteraction::MouseButton;
  21. using AzToolsFramework::ViewportInteraction::MouseEvent;
  22. using AzToolsFramework::ViewportInteraction::MouseInteraction;
  23. using AzToolsFramework::ViewportInteraction::MouseInteractionEvent;
  24. using AzToolsFramework::ViewportInteraction::ProjectedViewportRay;
  25. using AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus;
  26. using AzToolsFramework::ViewportInteraction::Helpers;
  27. bool interactionHandled = false;
  28. float wheelDelta = 0.0f;
  29. AZStd::optional<MouseButton> overrideButton;
  30. AZStd::optional<MouseEvent> eventType;
  31. const auto state = event.m_inputChannel.GetState();
  32. if (Helpers::IsMouseMove(event.m_inputChannel))
  33. {
  34. const auto* position = event.m_inputChannel.GetCustomData<AzFramework::InputChannel::PositionData2D>();
  35. AZ_Assert(position, "Expected PositionData2D but found nullptr");
  36. AzFramework::WindowSize windowSize;
  37. AzFramework::WindowRequestBus::EventResult(
  38. windowSize, event.m_windowHandle, &AzFramework::WindowRequestBus::Events::GetRenderResolution);
  39. const auto screenPoint = AzFramework::ScreenPoint(
  40. aznumeric_cast<int>(position->m_normalizedPosition.GetX() * windowSize.m_width),
  41. aznumeric_cast<int>(position->m_normalizedPosition.GetY() * windowSize.m_height));
  42. ProjectedViewportRay ray{};
  43. ViewportInteractionRequestBus::EventResult(
  44. ray, GetViewportId(), &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint);
  45. m_mouseInteraction.m_mousePick.m_rayOrigin = ray.m_origin;
  46. m_mouseInteraction.m_mousePick.m_rayDirection = ray.m_direction;
  47. m_mouseInteraction.m_mousePick.m_screenCoordinates = screenPoint;
  48. eventType = MouseEvent::Move;
  49. }
  50. else if (auto mouseButton = Helpers::GetMouseButton(event.m_inputChannel); mouseButton != MouseButton::None)
  51. {
  52. const AZ::u32 mouseButtonValue = static_cast<AZ::u32>(mouseButton);
  53. overrideButton = mouseButton;
  54. if (state == InputChannel::State::Began)
  55. {
  56. m_mouseInteraction.m_mouseButtons.m_mouseButtons |= mouseButtonValue;
  57. eventType = MouseEvent::Down;
  58. }
  59. else if (state == InputChannel::State::Ended)
  60. {
  61. // If we've actually logged a mouse down event, forward a mouse up event.
  62. // This prevents corner cases like the context menu thinking it should be opened even though no one clicked in this
  63. // viewport, due to RenderViewportWidget ensuring all controllers get InputChannel::State::Ended events.
  64. if (m_mouseInteraction.m_mouseButtons.m_mouseButtons & mouseButtonValue)
  65. {
  66. eventType = MouseEvent::Up;
  67. }
  68. }
  69. }
  70. else if (auto keyboardModifier = Helpers::GetKeyboardModifier(event.m_inputChannel); keyboardModifier != KeyboardModifier::None)
  71. {
  72. if (state == InputChannel::State::Began || state == InputChannel::State::Updated)
  73. {
  74. m_mouseInteraction.m_keyboardModifiers.m_keyModifiers |= static_cast<AZ::u32>(keyboardModifier);
  75. }
  76. else if (state == InputChannel::State::Ended)
  77. {
  78. m_mouseInteraction.m_keyboardModifiers.m_keyModifiers &= ~static_cast<AZ::u32>(keyboardModifier);
  79. }
  80. }
  81. else if (event.m_inputChannel.GetInputChannelId() == AzFramework::InputDeviceMouse::Movement::Z)
  82. {
  83. if (state == InputChannel::State::Began || state == InputChannel::State::Updated)
  84. {
  85. eventType = MouseEvent::Wheel;
  86. wheelDelta = event.m_inputChannel.GetValue();
  87. }
  88. }
  89. if (eventType)
  90. {
  91. MouseInteraction mouseInteraction = m_mouseInteraction;
  92. if (overrideButton)
  93. {
  94. mouseInteraction.m_mouseButtons.m_mouseButtons = static_cast<AZ::u32>(overrideButton.value());
  95. }
  96. mouseInteraction.m_interactionId.m_viewportId = GetViewportId();
  97. auto currentCursorState = AzFramework::SystemCursorState::Unknown;
  98. AzFramework::InputSystemCursorRequestBus::EventResult(
  99. currentCursorState, event.m_inputChannel.GetInputDevice().GetInputDeviceId(),
  100. &AzFramework::InputSystemCursorRequestBus::Events::GetSystemCursorState);
  101. const auto mouseInteractionEvent = [mouseInteraction, event = eventType.value(), wheelDelta,
  102. cursorCaptured = currentCursorState == AzFramework::SystemCursorState::ConstrainedAndHidden]
  103. {
  104. switch (event)
  105. {
  106. case MouseEvent::Up:
  107. case MouseEvent::Down:
  108. case MouseEvent::Move:
  109. case MouseEvent::DoubleClick:
  110. return MouseInteractionEvent(AZStd::move(mouseInteraction), event, cursorCaptured);
  111. case MouseEvent::Wheel:
  112. return MouseInteractionEvent(AZStd::move(mouseInteraction), wheelDelta);
  113. }
  114. AZ_Assert(false, "Unhandled MouseEvent");
  115. return MouseInteractionEvent(MouseInteraction{}, MouseEvent::Up, false);
  116. }();
  117. AzToolsFramework::ViewportInteraction::ViewportMouseRequestBus::EventResult(interactionHandled,
  118. GetViewportId(), &AzToolsFramework::ViewportInteraction::ViewportMouseRequestBus::Handler::HandleMouseInteraction,
  119. mouseInteractionEvent);
  120. }
  121. return interactionHandled;
  122. }
  123. } // namespace EMStudio