Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,83 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzTest/AzTest.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
namespace UnitTest
{
class LinearManipulatorTestFixture
: public ToolsApplicationFixture
{
protected:
LinearManipulatorTestFixture(const AzToolsFramework::ManipulatorManagerId& manipulatorManagerId)
: m_manipulatorManagerId(manipulatorManagerId) {}
void SetUpEditorFixtureImpl() override
{
m_linearManipulator = AzManipulatorTestFramework::CreateLinearManipulator(
m_manipulatorManagerId,
/*position=*/AZ::Vector3::CreateZero(),
/*radius=*/1.0f);
// default sanity check call backs
m_linearManipulator->InstallLeftMouseDownCallback(
[this](const AzToolsFramework::LinearManipulator::Action& /*action*/)
{
m_receivedLeftMouseDown = true;
});
m_linearManipulator->InstallMouseMoveCallback(
[this](const AzToolsFramework::LinearManipulator::Action& /*action*/)
{
m_receivedMouseMove = true;
});
m_linearManipulator->InstallLeftMouseUpCallback(
[this](const AzToolsFramework::LinearManipulator::Action& /*action*/)
{
m_receivedLeftMouseUp = true;
});
}
void TearDownEditorFixtureImpl() override
{
m_linearManipulator->Unregister();
m_linearManipulator.reset();
}
const AzToolsFramework::ManipulatorManagerId m_manipulatorManagerId;
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_linearManipulator;
// sanity flags for manipulator mouse callbacks
bool m_receivedLeftMouseDown = false;
bool m_receivedMouseMove = false;
bool m_receivedLeftMouseUp = false;
// initial world space starting position for mouse interaction
const AzToolsFramework::ViewportInteraction::MousePick m_mouseStartingPositionRay =
AzManipulatorTestFramework::CreateMousePick(
AZ::Vector3(0.0f, -2.0f, 0.0f), AZ::Vector3(0.0f, 1.0f, 0.0f), AzFramework::ScreenPoint( 0,0 ));
// left mouse down ray in world space 2 units back from origin looking down +y axis with a null interaction
// id and no keyboard modifiers
AzToolsFramework::ViewportInteraction::MouseInteraction m_interaction =
AzManipulatorTestFramework::CreateMouseInteraction(
m_mouseStartingPositionRay,
AzManipulatorTestFramework::CreateMouseButtons(AzToolsFramework::ViewportInteraction::MouseButton::Left),
AzToolsFramework::ViewportInteraction::InteractionId(AZ::EntityId(0), 0),
AzToolsFramework::ViewportInteraction::KeyboardModifiers(0));
};
} // namespace UnitTest
@@ -0,0 +1,146 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AzManipulatorTestFrameworkTestFixtures.h"
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
#include <AzToolsFramework/ViewportSelection/EditorDefaultSelection.h>
namespace UnitTest
{
class AzManipulatorTestFrameworkBusCallTestFixture
: public LinearManipulatorTestFixture
{
protected:
AzManipulatorTestFrameworkBusCallTestFixture()
: LinearManipulatorTestFixture(AzToolsFramework::g_mainManipulatorManagerId) {}
bool IsManipulatorInteractingBusCall() const
{
bool manipulatorInteracting = false;
AzToolsFramework::ManipulatorManagerRequestBus::EventResult(
manipulatorInteracting, AzToolsFramework::g_mainManipulatorManagerId,
&AzToolsFramework::ManipulatorManagerRequestBus::Events::Interacting);
return manipulatorInteracting;
}
};
TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportLeftMouseClick)
{
// given a left mouse down ray in world space
auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent(
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
// consume the mouse down and up events
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
event.m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up;
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
// expect the left mouse down and mouse up sanity flags to be set
EXPECT_TRUE(m_receivedLeftMouseDown);
EXPECT_TRUE(m_receivedLeftMouseUp);
// do not expect the mouse move sanity flag to be set
EXPECT_FALSE(m_receivedMouseMove);
}
TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportMouseMoveHover)
{
// given a left mouse down ray in world space
const auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent(
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Move);
// consume the mouse move event
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
// do not expect the manipulator to be performing an action
EXPECT_FALSE(m_linearManipulator->PerformingAction());
EXPECT_FALSE(IsManipulatorInteractingBusCall());
// do not expect the left mouse down/up and mouse move sanity flags to be set
EXPECT_FALSE(m_receivedLeftMouseDown);
EXPECT_FALSE(m_receivedMouseMove);
EXPECT_FALSE(m_receivedLeftMouseUp);
}
TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportMouseMoveActive)
{
// given a left mouse down ray in world space
auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent(
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
// consume the mouse down event
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
// consume the mouse move event
event.m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Move;
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
// do not expect the mouse to be hovering over the manipulator
EXPECT_FALSE(m_linearManipulator->MouseOver());
// expect the manipulator to be performing an action
EXPECT_TRUE(m_linearManipulator->PerformingAction());
EXPECT_TRUE(IsManipulatorInteractingBusCall());
// consume the mouse up event
event.m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up;
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
// expect the left mouse down/up and mouse move sanity flags to be set
EXPECT_TRUE(m_receivedLeftMouseDown);
EXPECT_TRUE(m_receivedMouseMove);
EXPECT_TRUE(m_receivedLeftMouseUp);
}
TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, MoveManipulatorAlongAxis)
{
AZ::Vector3 movementAlongAxis = AZ::Vector3::CreateZero();
const AZ::Vector3 expectedMovementAlongAxis = AZ::Vector3(-5.0f, 0.0f, 0.0f);
const AZ::Vector3 initialManipulatorPosition = m_linearManipulator->GetPosition();
m_linearManipulator->InstallMouseMoveCallback(
[&movementAlongAxis, this](const AzToolsFramework::LinearManipulator::Action& action)
{
movementAlongAxis = action.LocalPositionOffset();
m_linearManipulator->SetLocalPosition(action.LocalPosition());
});
// given a left mouse down ray in world space
auto event = AzManipulatorTestFramework::CreateMouseInteractionEvent(
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
// consume the mouse down event
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
// move the mouse along the -x axis
event.m_mouseInteraction.m_mousePick.m_rayOrigin += expectedMovementAlongAxis;
event.m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Move;
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
// expect the manipulator to be performing an action
EXPECT_TRUE(m_linearManipulator->PerformingAction());
EXPECT_TRUE(IsManipulatorInteractingBusCall());
// consume the mouse up event
event.m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up;
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
// expect the left mouse down/up sanity flags to be set
EXPECT_TRUE(m_receivedLeftMouseDown);
EXPECT_TRUE(m_receivedLeftMouseUp);
// expect the manipulator movement along the axis to match the mouse movement along the axis
EXPECT_EQ(movementAlongAxis, expectedMovementAlongAxis);
EXPECT_EQ(m_linearManipulator->GetPosition(), initialManipulatorPosition + expectedMovementAlongAxis);
}
} // namespace UnitTest
@@ -0,0 +1,144 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AzManipulatorTestFrameworkTestFixtures.h"
namespace UnitTest
{
class CustomManipulatorManager
: public AzToolsFramework::ManipulatorManager
{
using ManagerBase = AzToolsFramework::ManipulatorManager;
public:
using ManagerBase::ManagerBase;
size_t RegisteredManipulatorCount() const
{
return m_manipulatorIdToPtrMap.size();
}
};
class AzManipulatorTestFrameworkCustomManagerTestFixture
: public LinearManipulatorTestFixture
{
protected:
AzManipulatorTestFrameworkCustomManagerTestFixture()
: LinearManipulatorTestFixture(AzToolsFramework::ManipulatorManagerId(AZ::Crc32("TestManipulatorManagerId"))) {}
void SetUpEditorFixtureImpl() override
{
m_manipulatorManager =
AZStd::make_shared<CustomManipulatorManager>(m_manipulatorManagerId);
LinearManipulatorTestFixture::SetUpEditorFixtureImpl();
}
void TearDownEditorFixtureImpl() override
{
LinearManipulatorTestFixture::TearDownEditorFixtureImpl();
m_manipulatorManager.reset();
}
AZStd::shared_ptr<CustomManipulatorManager> m_manipulatorManager;
};
TEST_F(AzManipulatorTestFrameworkCustomManagerTestFixture, RegisterManipulatorWithCustomManager)
{
// Expect the manager to contain one manipulator
EXPECT_EQ(m_manipulatorManager->RegisteredManipulatorCount(), 1);
}
TEST_F(AzManipulatorTestFrameworkCustomManagerTestFixture, ConsumeViewportLeftMouseClick)
{
// consume the mouse down and up events
m_manipulatorManager->ConsumeViewportMousePress(m_interaction);
m_manipulatorManager->ConsumeViewportMouseRelease(m_interaction);
// expect the left mouse down and mouse up sanity flags to be set
EXPECT_TRUE(m_receivedLeftMouseDown);
EXPECT_TRUE(m_receivedLeftMouseUp);
// do not expect the mouse move sanity flag to be set
EXPECT_FALSE(m_receivedMouseMove);
}
TEST_F(AzManipulatorTestFrameworkCustomManagerTestFixture, ConsumeViewportMouseMoveHover)
{
// consume the mouse move event
m_manipulatorManager->ConsumeViewportMouseMove(m_interaction);
// do not expect the manipulator to be performing an action
EXPECT_FALSE(m_linearManipulator->PerformingAction());
EXPECT_FALSE(m_manipulatorManager->Interacting());
// do not expect the left mouse down/up and mouse move sanity flags to be set
EXPECT_FALSE(m_receivedLeftMouseDown);
EXPECT_FALSE(m_receivedMouseMove);
EXPECT_FALSE(m_receivedLeftMouseUp);
}
TEST_F(AzManipulatorTestFrameworkCustomManagerTestFixture, ConsumeViewportMouseMoveActive)
{
// consume the mouse down and mouse move events
m_manipulatorManager->ConsumeViewportMousePress(m_interaction);
m_manipulatorManager->ConsumeViewportMouseMove(m_interaction);
// do not expect the mouse to be hovering over the manipulator
EXPECT_FALSE(m_linearManipulator->MouseOver());
// expect the manipulator to be performing an action
EXPECT_TRUE(m_linearManipulator->PerformingAction());
EXPECT_TRUE(m_manipulatorManager->Interacting());
// consume the mouse up event
m_manipulatorManager->ConsumeViewportMouseRelease(m_interaction);
// expect the left mouse down/up and mouse move sanity flags to be set
EXPECT_TRUE(m_receivedLeftMouseDown);
EXPECT_TRUE(m_receivedMouseMove);
EXPECT_TRUE(m_receivedLeftMouseUp);
}
TEST_F(AzManipulatorTestFrameworkCustomManagerTestFixture, MoveManipulatorAlongAxis)
{
AZ::Vector3 movementAlongAxis = AZ::Vector3::CreateZero();
const AZ::Vector3 expectedPositionAfterMovementAlongAxis = AZ::Vector3(-5.0f, 0.0f, 0.0f);
m_linearManipulator->InstallMouseMoveCallback(
[&movementAlongAxis](const AzToolsFramework::LinearManipulator::Action& action)
{
movementAlongAxis = action.m_current.m_localPositionOffset;
});
// consume the mouse down event
m_manipulatorManager->ConsumeViewportMousePress(m_interaction);
// move the mouse along the -x axis
m_interaction.m_mousePick.m_rayOrigin += expectedPositionAfterMovementAlongAxis;
m_manipulatorManager->ConsumeViewportMouseMove(m_interaction);
// expect the manipulator to be performing an action
EXPECT_TRUE(m_linearManipulator->PerformingAction());
EXPECT_TRUE(m_manipulatorManager->Interacting());
// consume the mouse up event
m_manipulatorManager->ConsumeViewportMouseRelease(m_interaction);
// expect the left mouse down/up sanity flags to be set
EXPECT_TRUE(m_receivedLeftMouseDown);
EXPECT_TRUE(m_receivedLeftMouseUp);
// expect the manipulator movement along the axis to match the mouse movement along the axis
EXPECT_EQ(movementAlongAxis, expectedPositionAfterMovementAlongAxis);
}
} // namespace UnitTest
@@ -0,0 +1,95 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzFramework/Viewport/ViewportScreen.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
#include "AzManipulatorTestFrameworkTestFixtures.h"
#include <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
#include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
namespace UnitTest
{
class GridSnappingFixture
: public ToolsApplicationFixture
{
public:
GridSnappingFixture()
: m_viewportManipulatorInteraction(AZStd::make_unique<AzManipulatorTestFramework::DirectCallManipulatorViewportInteraction>())
, 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))
{}
protected:
void SetUpEditorFixtureImpl() override
{
m_cameraState = AzFramework::CreateIdentityDefaultCamera(
AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
}
public:
const float m_boundsRadius = 1.0f;
AZStd::unique_ptr<AzManipulatorTestFramework::ManipulatorViewportInteraction> m_viewportManipulatorInteraction;
AZStd::unique_ptr<AzManipulatorTestFramework::ImmediateModeActionDispatcher> m_actionDispatcher;
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_linearManipulator;
AzFramework::CameraState m_cameraState;
};
TEST_F(GridSnappingFixture, MouseDownWithSnappingEnabledSnapsToClosestGridSize)
{
// the initial starting position of the manipulator (in front of the camera)
const auto initialPositionWorld = m_linearManipulator->GetPosition();
// 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);
// callback to update the manipulator's current position
m_linearManipulator->InstallMouseMoveCallback(
[this](const AzToolsFramework::LinearManipulator::Action& action)
{
auto pos = action.LocalPosition();
m_linearManipulator->SetLocalPosition(pos);
});
m_actionDispatcher
->EnableSnapToGrid()
->GridSize(5.0f)
->CameraState(m_cameraState)
->MousePosition(initialPositionScreen)
->MouseLButtonDown()
->ExpectManipulatorBeingInteracted()
->MousePosition(finalPositionScreen)
->MouseLButtonUp()
->ExpectManipulatorNotBeingInteracted()
->ExpectTrue(m_linearManipulator->GetPosition().IsClose(finalPositionWorld, 0.01f))
;
}
} // namespace UnitTest
@@ -0,0 +1,49 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzTest/AzTest.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzQtComponents/Utilities/QtPluginPaths.h>
#include <QApplication>
namespace UnitTest
{
// Handle asserts
class ToolsFrameworkHook
: public AZ::Test::ITestEnvironment
{
public:
void SetupEnvironment() override
{
AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
}
void TeardownEnvironment() override
{
AZ::AllocatorInstance<AZ::SystemAllocator>::Destroy();
}
};
} // namespace UnitTest
AZTEST_EXPORT int AZ_UNIT_TEST_HOOK_NAME(int argc, char** argv)
{
::testing::InitGoogleMock(&argc, argv);
AzQtComponents::PrepareQtPaths();
QApplication app(argc, argv);
AZ::Test::printUnusedParametersWarning(argc, argv);
AZ::Test::addTestEnvironments({ new UnitTest::ToolsFrameworkHook });
int result = RUN_ALL_TESTS();
return result;
}
IMPLEMENT_TEST_EXECUTABLE_MAIN();
@@ -0,0 +1,135 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "AzManipulatorTestFrameworkTestFixtures.h"
#include <AzManipulatorTestFramework/ViewportInteraction.h>
namespace UnitTest
{
class AValidViewportInteraction
: public ToolsApplicationFixture
{
public:
AValidViewportInteraction()
: m_viewportInteraction(AZStd::make_unique<AzManipulatorTestFramework::ViewportInteraction>())
{
}
protected:
void SetUpEditorFixtureImpl() override
{
m_cameraState =
AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AZ::Vector2(800.0f, 600.0f));
}
public:
AZStd::unique_ptr<AzManipulatorTestFramework::ViewportInteraction> m_viewportInteraction;
AzFramework::CameraState m_cameraState;
};
TEST_F(AValidViewportInteraction, HasViewportId1234)
{
EXPECT_EQ(m_viewportInteraction->GetViewportId(), 1234);
}
TEST_F(AValidViewportInteraction, CanSetAndGetCameraState)
{
m_viewportInteraction->SetCameraState(m_cameraState);
const auto cameraState = m_viewportInteraction->GetCameraState();
EXPECT_EQ(cameraState.m_position, m_cameraState.m_position);
EXPECT_EQ(cameraState.m_forward, m_cameraState.m_forward);
}
TEST_F(AValidViewportInteraction, CanEnableGridSnapping)
{
bool snapping = false;
m_viewportInteraction->EnableGridSnaping();
AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::EventResult(
snapping, m_viewportInteraction->GetViewportId(),
&AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Events::GridSnappingEnabled);
EXPECT_TRUE(snapping);
}
TEST_F(AValidViewportInteraction, CanDisableGridSnapping)
{
bool snapping = true;
m_viewportInteraction->DisableGridSnaping();
AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::EventResult(
snapping, m_viewportInteraction->GetViewportId(),
&AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Events::GridSnappingEnabled);
EXPECT_FALSE(snapping);
}
TEST_F(AValidViewportInteraction, CanGetAndSetGridSize)
{
float gridSize = 0.0f;
const float expectedGridSize = 50.0f;
m_viewportInteraction->SetGridSize(expectedGridSize);
m_viewportInteraction->DisableGridSnaping();
AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::EventResult(
gridSize, m_viewportInteraction->GetViewportId(),
&AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Events::GridSize);
EXPECT_EQ(gridSize, expectedGridSize);
}
TEST_F(AValidViewportInteraction, CanEnableAngularSnapping)
{
bool snapping = false;
m_viewportInteraction->EnableAngularSnaping();
AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::EventResult(
snapping, m_viewportInteraction->GetViewportId(),
&AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Events::AngleSnappingEnabled);
EXPECT_TRUE(snapping);
}
TEST_F(AValidViewportInteraction, CanDisableAngularSnapping)
{
bool snapping = true;
m_viewportInteraction->DisableAngularSnaping();
AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::EventResult(
snapping, m_viewportInteraction->GetViewportId(),
&AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Events::AngleSnappingEnabled);
EXPECT_FALSE(snapping);
}
TEST_F(AValidViewportInteraction, CanGetAndSetAngleStep)
{
float angularStep = 0.0f;
const float expectedAngularStep = 50.0f;
m_viewportInteraction->SetAngularStep(expectedAngularStep);
AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::EventResult(
angularStep, m_viewportInteraction->GetViewportId(),
&AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Events::AngleStep);
EXPECT_EQ(angularStep, expectedAngularStep);
}
TEST_F(AValidViewportInteraction, HasAValidGetDebugDisplay)
{
AzFramework::DebugDisplayRequests& debugDisplay = m_viewportInteraction->GetDebugDisplay();
EXPECT_NE(nullptr, &debugDisplay);
}
} // namespace UnitTest
@@ -0,0 +1,229 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzFramework/Viewport/ViewportScreen.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
#include <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
#include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.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>());
m_busState = AZStd::make_unique<State>(
AZStd::make_unique<AzManipulatorTestFramework::IndirectCallManipulatorViewportInteraction>());
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)
->MouseLButtonDown()
->MousePosition(AzManipulatorTestFramework::GetCameraStateViewportCenter(m_cameraState))
->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->GetPosition();
// 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