WorldSpaceBuilderTest.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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/Viewport/ViewportScreen.h>
  9. #include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
  10. #include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
  11. #include <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
  12. #include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
  13. #include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
  14. #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
  15. #include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
  16. namespace UnitTest
  17. {
  18. class AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture : public ToolsApplicationFixture<>
  19. {
  20. protected:
  21. struct State
  22. {
  23. State(AZStd::unique_ptr<AzManipulatorTestFramework::ManipulatorViewportInteraction> viewportManipulatorInteraction)
  24. : m_viewportManipulatorInteraction(viewportManipulatorInteraction.release())
  25. , m_actionDispatcher(
  26. AZStd::make_unique<AzManipulatorTestFramework::ImmediateModeActionDispatcher>(*m_viewportManipulatorInteraction))
  27. , m_linearManipulator(AzManipulatorTestFramework::CreateLinearManipulator(
  28. m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
  29. /*position=*/AZ::Vector3(0.0f, 50.0f, 0.0f),
  30. /*radius=*/m_boundsRadius))
  31. {
  32. // default sanity check call backs
  33. m_linearManipulator->InstallLeftMouseDownCallback(
  34. [this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action)
  35. {
  36. m_receivedLeftMouseDown = true;
  37. });
  38. m_linearManipulator->InstallMouseMoveCallback(
  39. [this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action)
  40. {
  41. m_receivedMouseMove = true;
  42. });
  43. m_linearManipulator->InstallLeftMouseUpCallback(
  44. [this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action)
  45. {
  46. m_receivedLeftMouseUp = true;
  47. });
  48. }
  49. ~State() = default;
  50. // sanity flags for manipulator mouse callbacks
  51. bool m_receivedLeftMouseDown = false;
  52. bool m_receivedMouseMove = false;
  53. bool m_receivedLeftMouseUp = false;
  54. private:
  55. AZStd::unique_ptr<AzManipulatorTestFramework::ManipulatorViewportInteraction> m_viewportManipulatorInteraction;
  56. public:
  57. AZStd::unique_ptr<AzManipulatorTestFramework::ImmediateModeActionDispatcher> m_actionDispatcher;
  58. AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_linearManipulator;
  59. };
  60. void ConsumeViewportLeftMouseClick(State& state);
  61. void ConsumeViewportMouseMoveHover(State& state);
  62. void ConsumeViewportMouseMoveActive(State& state);
  63. void MoveManipulatorAlongAxis(State& state);
  64. protected:
  65. void SetUpEditorFixtureImpl() override
  66. {
  67. m_directState =
  68. AZStd::make_unique<State>(AZStd::make_unique<AzManipulatorTestFramework::DirectCallManipulatorViewportInteraction>(
  69. AZStd::make_shared<NullDebugDisplayRequests>()));
  70. m_busState =
  71. AZStd::make_unique<State>(AZStd::make_unique<AzManipulatorTestFramework::IndirectCallManipulatorViewportInteraction>(
  72. AZStd::make_shared<NullDebugDisplayRequests>()));
  73. m_cameraState =
  74. AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
  75. }
  76. void TearDownEditorFixtureImpl() override
  77. {
  78. m_directState.reset();
  79. m_busState.reset();
  80. }
  81. public:
  82. AZStd::unique_ptr<State> m_directState;
  83. AZStd::unique_ptr<State> m_busState;
  84. AzFramework::CameraState m_cameraState;
  85. static constexpr float m_boundsRadius = 2.0f;
  86. };
  87. void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::ConsumeViewportLeftMouseClick(State& state)
  88. {
  89. // given a left mouse down ray in world space
  90. // consume the mouse down and up events
  91. state.m_actionDispatcher->CameraState(m_cameraState)
  92. ->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState))
  93. ->MouseLButtonDown()
  94. ->Trace("Expecting left mouse button down")
  95. ->ExpectTrue(state.m_receivedLeftMouseDown)
  96. ->Trace("Not expecting left mouse button up")
  97. ->ExpectFalse(state.m_receivedLeftMouseUp)
  98. ->Trace("Expecting mouse move")
  99. // note: a zero delta mouse move is generated after every mouse up event in the
  100. // editor application - the manipulator test framework simulates this event to
  101. // ensure the tests are representative of what actually happens in the editor
  102. // therefore we do expect m_receivedMouseMove to be true after MouseLButtonDown
  103. ->ExpectTrue(state.m_receivedMouseMove)
  104. ->ExpectManipulatorBeingInteracted()
  105. ->MouseLButtonUp()
  106. ->Trace("Expecting left mouse button up")
  107. ->ExpectTrue(state.m_receivedLeftMouseDown)
  108. ->ExpectTrue(state.m_receivedLeftMouseUp)
  109. ->ExpectTrue(state.m_receivedMouseMove)
  110. ->ExpectFalse(state.m_linearManipulator->PerformingAction())
  111. ->ExpectManipulatorNotBeingInteracted();
  112. }
  113. void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::ConsumeViewportMouseMoveHover(State& state)
  114. {
  115. // given a left mouse down ray in world space
  116. // consume the mouse move event
  117. state.m_actionDispatcher->CameraState(m_cameraState)
  118. ->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState))
  119. ->ExpectFalse(state.m_linearManipulator->PerformingAction())
  120. ->ExpectManipulatorNotBeingInteracted()
  121. ->ExpectFalse(state.m_receivedLeftMouseDown)
  122. ->ExpectFalse(state.m_receivedMouseMove)
  123. ->ExpectFalse(state.m_receivedLeftMouseUp);
  124. }
  125. void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::ConsumeViewportMouseMoveActive(State& state)
  126. {
  127. // given a left mouse down ray in world space
  128. // consume the mouse move event
  129. state.m_actionDispatcher->CameraState(m_cameraState)
  130. ->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState))
  131. ->MouseLButtonDown()
  132. ->ExpectTrue(state.m_linearManipulator->PerformingAction())
  133. ->ExpectManipulatorBeingInteracted()
  134. ->MouseLButtonUp()
  135. ->ExpectTrue(state.m_receivedLeftMouseDown)
  136. ->ExpectTrue(state.m_receivedMouseMove)
  137. ->ExpectTrue(state.m_receivedLeftMouseUp);
  138. }
  139. void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::MoveManipulatorAlongAxis(State& state)
  140. {
  141. // the initial starting position of the manipulator (in front of the camera)
  142. const auto initialPositionWorld = state.m_linearManipulator->GetLocalPosition();
  143. // where the manipulator should end up (in front and to the left of the camera)
  144. const auto finalPositionWorld = AZ::Vector3(-10.0f, 50.0f, 0.0f);
  145. // perspective scale factor for manipulator distance to camera
  146. const auto scaledRadiusBound =
  147. AzToolsFramework::CalculateScreenToWorldMultiplier(initialPositionWorld, m_cameraState) * m_boundsRadius;
  148. // vector from camera to manipulator
  149. const auto vectorToInitialPositionWorld = (initialPositionWorld - m_cameraState.m_position).GetNormalized();
  150. // adjusted final world position taking into account the manipulator position relative to the camera
  151. const auto finalPositionWorldAdjusted = finalPositionWorld - (vectorToInitialPositionWorld * scaledRadiusBound);
  152. // calculate the position in screen space of the initial position of the manipulator
  153. const auto initialPositionScreen = AzFramework::WorldToScreen(initialPositionWorld, m_cameraState);
  154. // calculate the position in screen space of the final position of the manipulator
  155. const auto finalPositionScreen = AzFramework::WorldToScreen(finalPositionWorldAdjusted, m_cameraState);
  156. AZ::Vector3 movementAlongAxis = AZ::Vector3::CreateZero();
  157. state.m_linearManipulator->InstallMouseMoveCallback(
  158. [&movementAlongAxis](const AzToolsFramework::LinearManipulator::Action& action)
  159. {
  160. movementAlongAxis = action.LocalPosition();
  161. });
  162. state.m_actionDispatcher->CameraState(m_cameraState)
  163. ->MousePosition(initialPositionScreen)
  164. ->MouseLButtonDown()
  165. ->ExpectTrue(state.m_linearManipulator->PerformingAction())
  166. ->ExpectManipulatorBeingInteracted()
  167. ->MousePosition(finalPositionScreen)
  168. ->MouseLButtonUp()
  169. ->ExpectTrue(state.m_receivedLeftMouseDown)
  170. ->ExpectTrue(state.m_receivedLeftMouseUp)
  171. ->ExpectTrue(movementAlongAxis.IsClose(finalPositionWorld, 0.01f));
  172. }
  173. TEST_F(AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture, ConsumeViewportLeftMouseClick)
  174. {
  175. ConsumeViewportLeftMouseClick(*m_directState);
  176. ConsumeViewportLeftMouseClick(*m_busState);
  177. }
  178. TEST_F(AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture, ConsumeViewportMouseMoveHover)
  179. {
  180. ConsumeViewportMouseMoveHover(*m_directState);
  181. ConsumeViewportMouseMoveHover(*m_busState);
  182. }
  183. TEST_F(AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture, ConsumeViewportMouseMoveActive)
  184. {
  185. ConsumeViewportMouseMoveActive(*m_directState);
  186. ConsumeViewportMouseMoveActive(*m_busState);
  187. }
  188. TEST_F(AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture, MoveManipulatorAlongAxis)
  189. {
  190. MoveManipulatorAlongAxis(*m_directState);
  191. MoveManipulatorAlongAxis(*m_busState);
  192. }
  193. } // namespace UnitTest