123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <AzFramework/Viewport/ViewportScreen.h>
- #include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
- #include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
- #include <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
- #include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
- #include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
- #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
- #include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
- namespace UnitTest
- {
- class AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture : public ToolsApplicationFixture<>
- {
- protected:
- struct State
- {
- State(AZStd::unique_ptr<AzManipulatorTestFramework::ManipulatorViewportInteraction> viewportManipulatorInteraction)
- : m_viewportManipulatorInteraction(viewportManipulatorInteraction.release())
- , m_actionDispatcher(
- AZStd::make_unique<AzManipulatorTestFramework::ImmediateModeActionDispatcher>(*m_viewportManipulatorInteraction))
- , m_linearManipulator(AzManipulatorTestFramework::CreateLinearManipulator(
- m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
- /*position=*/AZ::Vector3(0.0f, 50.0f, 0.0f),
- /*radius=*/m_boundsRadius))
- {
- // default sanity check call backs
- m_linearManipulator->InstallLeftMouseDownCallback(
- [this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action)
- {
- m_receivedLeftMouseDown = true;
- });
- m_linearManipulator->InstallMouseMoveCallback(
- [this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action)
- {
- m_receivedMouseMove = true;
- });
- m_linearManipulator->InstallLeftMouseUpCallback(
- [this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action)
- {
- m_receivedLeftMouseUp = true;
- });
- }
- ~State() = default;
- // sanity flags for manipulator mouse callbacks
- bool m_receivedLeftMouseDown = false;
- bool m_receivedMouseMove = false;
- bool m_receivedLeftMouseUp = false;
- private:
- AZStd::unique_ptr<AzManipulatorTestFramework::ManipulatorViewportInteraction> m_viewportManipulatorInteraction;
- public:
- AZStd::unique_ptr<AzManipulatorTestFramework::ImmediateModeActionDispatcher> m_actionDispatcher;
- AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_linearManipulator;
- };
- void ConsumeViewportLeftMouseClick(State& state);
- void ConsumeViewportMouseMoveHover(State& state);
- void ConsumeViewportMouseMoveActive(State& state);
- void MoveManipulatorAlongAxis(State& state);
- protected:
- void SetUpEditorFixtureImpl() override
- {
- m_directState =
- AZStd::make_unique<State>(AZStd::make_unique<AzManipulatorTestFramework::DirectCallManipulatorViewportInteraction>(
- AZStd::make_shared<NullDebugDisplayRequests>()));
- m_busState =
- AZStd::make_unique<State>(AZStd::make_unique<AzManipulatorTestFramework::IndirectCallManipulatorViewportInteraction>(
- AZStd::make_shared<NullDebugDisplayRequests>()));
- m_cameraState =
- AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
- }
- void TearDownEditorFixtureImpl() override
- {
- m_directState.reset();
- m_busState.reset();
- }
- public:
- AZStd::unique_ptr<State> m_directState;
- AZStd::unique_ptr<State> m_busState;
- AzFramework::CameraState m_cameraState;
- static constexpr float m_boundsRadius = 2.0f;
- };
- void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::ConsumeViewportLeftMouseClick(State& state)
- {
- // given a left mouse down ray in world space
- // consume the mouse down and up events
- state.m_actionDispatcher->CameraState(m_cameraState)
- ->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState))
- ->MouseLButtonDown()
- ->Trace("Expecting left mouse button down")
- ->ExpectTrue(state.m_receivedLeftMouseDown)
- ->Trace("Not expecting left mouse button up")
- ->ExpectFalse(state.m_receivedLeftMouseUp)
- ->Trace("Expecting mouse move")
- // note: a zero delta mouse move is generated after every mouse up event in the
- // editor application - the manipulator test framework simulates this event to
- // ensure the tests are representative of what actually happens in the editor
- // therefore we do expect m_receivedMouseMove to be true after MouseLButtonDown
- ->ExpectTrue(state.m_receivedMouseMove)
- ->ExpectManipulatorBeingInteracted()
- ->MouseLButtonUp()
- ->Trace("Expecting left mouse button up")
- ->ExpectTrue(state.m_receivedLeftMouseDown)
- ->ExpectTrue(state.m_receivedLeftMouseUp)
- ->ExpectTrue(state.m_receivedMouseMove)
- ->ExpectFalse(state.m_linearManipulator->PerformingAction())
- ->ExpectManipulatorNotBeingInteracted();
- }
- void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::ConsumeViewportMouseMoveHover(State& state)
- {
- // given a left mouse down ray in world space
- // consume the mouse move event
- state.m_actionDispatcher->CameraState(m_cameraState)
- ->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState))
- ->ExpectFalse(state.m_linearManipulator->PerformingAction())
- ->ExpectManipulatorNotBeingInteracted()
- ->ExpectFalse(state.m_receivedLeftMouseDown)
- ->ExpectFalse(state.m_receivedMouseMove)
- ->ExpectFalse(state.m_receivedLeftMouseUp);
- }
- void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::ConsumeViewportMouseMoveActive(State& state)
- {
- // given a left mouse down ray in world space
- // consume the mouse move event
- state.m_actionDispatcher->CameraState(m_cameraState)
- ->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState))
- ->MouseLButtonDown()
- ->ExpectTrue(state.m_linearManipulator->PerformingAction())
- ->ExpectManipulatorBeingInteracted()
- ->MouseLButtonUp()
- ->ExpectTrue(state.m_receivedLeftMouseDown)
- ->ExpectTrue(state.m_receivedMouseMove)
- ->ExpectTrue(state.m_receivedLeftMouseUp);
- }
- void AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture::MoveManipulatorAlongAxis(State& state)
- {
- // the initial starting position of the manipulator (in front of the camera)
- const auto initialPositionWorld = state.m_linearManipulator->GetLocalPosition();
- // where the manipulator should end up (in front and to the left of the camera)
- const auto finalPositionWorld = AZ::Vector3(-10.0f, 50.0f, 0.0f);
- // perspective scale factor for manipulator distance to camera
- const auto scaledRadiusBound =
- AzToolsFramework::CalculateScreenToWorldMultiplier(initialPositionWorld, m_cameraState) * m_boundsRadius;
- // vector from camera to manipulator
- const auto vectorToInitialPositionWorld = (initialPositionWorld - m_cameraState.m_position).GetNormalized();
- // adjusted final world position taking into account the manipulator position relative to the camera
- const auto finalPositionWorldAdjusted = finalPositionWorld - (vectorToInitialPositionWorld * scaledRadiusBound);
- // calculate the position in screen space of the initial position of the manipulator
- const auto initialPositionScreen = AzFramework::WorldToScreen(initialPositionWorld, m_cameraState);
- // calculate the position in screen space of the final position of the manipulator
- const auto finalPositionScreen = AzFramework::WorldToScreen(finalPositionWorldAdjusted, m_cameraState);
- AZ::Vector3 movementAlongAxis = AZ::Vector3::CreateZero();
- state.m_linearManipulator->InstallMouseMoveCallback(
- [&movementAlongAxis](const AzToolsFramework::LinearManipulator::Action& action)
- {
- movementAlongAxis = action.LocalPosition();
- });
- state.m_actionDispatcher->CameraState(m_cameraState)
- ->MousePosition(initialPositionScreen)
- ->MouseLButtonDown()
- ->ExpectTrue(state.m_linearManipulator->PerformingAction())
- ->ExpectManipulatorBeingInteracted()
- ->MousePosition(finalPositionScreen)
- ->MouseLButtonUp()
- ->ExpectTrue(state.m_receivedLeftMouseDown)
- ->ExpectTrue(state.m_receivedLeftMouseUp)
- ->ExpectTrue(movementAlongAxis.IsClose(finalPositionWorld, 0.01f));
- }
- TEST_F(AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture, ConsumeViewportLeftMouseClick)
- {
- ConsumeViewportLeftMouseClick(*m_directState);
- ConsumeViewportLeftMouseClick(*m_busState);
- }
- TEST_F(AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture, ConsumeViewportMouseMoveHover)
- {
- ConsumeViewportMouseMoveHover(*m_directState);
- ConsumeViewportMouseMoveHover(*m_busState);
- }
- TEST_F(AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture, ConsumeViewportMouseMoveActive)
- {
- ConsumeViewportMouseMoveActive(*m_directState);
- ConsumeViewportMouseMoveActive(*m_busState);
- }
- TEST_F(AzManipulatorTestFrameworkWorldSpaceBuilderTestFixture, MoveManipulatorAlongAxis)
- {
- MoveManipulatorAlongAxis(*m_directState);
- MoveManipulatorAlongAxis(*m_busState);
- }
- } // namespace UnitTest
|