|
|
|
|
@ -7,6 +7,7 @@
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <AtomToolsFramework/Viewport/ModularViewportCameraController.h>
|
|
|
|
|
#include <AzCore/Settings/SettingsRegistryImpl.h>
|
|
|
|
|
#include <AzFramework/Viewport/ViewportControllerList.h>
|
|
|
|
|
#include <AzToolsFramework/Input/QtEventToAzInputManager.h>
|
|
|
|
|
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
|
|
|
|
|
@ -95,10 +96,16 @@ namespace UnitTest
|
|
|
|
|
m_controllerList->RegisterViewportContext(TestViewportId);
|
|
|
|
|
|
|
|
|
|
m_inputChannelMapper = AZStd::make_unique<AzToolsFramework::QtEventToAzInputMapper>(m_rootWidget.get(), TestViewportId);
|
|
|
|
|
|
|
|
|
|
m_settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
|
|
|
|
|
AZ::SettingsRegistry::Register(m_settingsRegistry.get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TearDown() override
|
|
|
|
|
{
|
|
|
|
|
AZ::SettingsRegistry::Unregister(m_settingsRegistry.get());
|
|
|
|
|
m_settingsRegistry.reset();
|
|
|
|
|
|
|
|
|
|
m_inputChannelMapper.reset();
|
|
|
|
|
|
|
|
|
|
m_controllerList->UnregisterViewportContext(TestViewportId);
|
|
|
|
|
@ -170,7 +177,7 @@ namespace UnitTest
|
|
|
|
|
void RepeatDiagonalMouseMovements(const AZStd::function<float()>& deltaTimeFn)
|
|
|
|
|
{
|
|
|
|
|
// move to the center of the screen
|
|
|
|
|
auto start = QPoint(WidgetSize.width() / 2, WidgetSize.height() / 2);
|
|
|
|
|
const auto start = QPoint(WidgetSize.width() / 2, WidgetSize.height() / 2);
|
|
|
|
|
MouseMove(m_rootWidget.get(), start, QPoint(0, 0));
|
|
|
|
|
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTimeFn()), AZ::ScriptTimePoint() });
|
|
|
|
|
|
|
|
|
|
@ -204,12 +211,15 @@ namespace UnitTest
|
|
|
|
|
::testing::NiceMock<MockWindowRequests> m_mockWindowRequests;
|
|
|
|
|
ViewportMouseCursorRequestImpl m_viewportMouseCursorRequests;
|
|
|
|
|
AtomToolsFramework::ModularCameraViewportContext* m_cameraViewportContextView = nullptr;
|
|
|
|
|
AZStd::unique_ptr<AZ::SettingsRegistryInterface> m_settingsRegistry;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const AzFramework::ViewportId ModularViewportCameraControllerFixture::TestViewportId = AzFramework::ViewportId(0);
|
|
|
|
|
|
|
|
|
|
TEST_F(ModularViewportCameraControllerFixture, MouseMovementDoesNotAccumulateExcessiveDriftInModularViewportCameraWithVaryingDeltaTime)
|
|
|
|
|
{
|
|
|
|
|
SandboxEditor::SetCameraCaptureCursorForLook(false);
|
|
|
|
|
|
|
|
|
|
// Given
|
|
|
|
|
PrepareCollaborators();
|
|
|
|
|
|
|
|
|
|
@ -242,6 +252,8 @@ namespace UnitTest
|
|
|
|
|
ModularViewportCameraControllerDeltaTimeParamFixture,
|
|
|
|
|
MouseMovementDoesNotAccumulateExcessiveDriftInModularViewportCameraWithFixedDeltaTime)
|
|
|
|
|
{
|
|
|
|
|
SandboxEditor::SetCameraCaptureCursorForLook(false);
|
|
|
|
|
|
|
|
|
|
// Given
|
|
|
|
|
PrepareCollaborators();
|
|
|
|
|
|
|
|
|
|
@ -263,4 +275,92 @@ namespace UnitTest
|
|
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_CASE_P(
|
|
|
|
|
All, ModularViewportCameraControllerDeltaTimeParamFixture, testing::Values(1.0f / 60.0f, 1.0f / 50.0f, 1.0f / 30.0f));
|
|
|
|
|
|
|
|
|
|
TEST_F(ModularViewportCameraControllerFixture, MouseMovementOrientatesCameraWhenCursorIsCaptured)
|
|
|
|
|
{
|
|
|
|
|
// Given
|
|
|
|
|
PrepareCollaborators();
|
|
|
|
|
// ensure cursor is captured
|
|
|
|
|
SandboxEditor::SetCameraCaptureCursorForLook(true);
|
|
|
|
|
|
|
|
|
|
const float deltaTime = 1.0f / 60.0f;
|
|
|
|
|
|
|
|
|
|
// When
|
|
|
|
|
// move to the center of the screen
|
|
|
|
|
auto start = QPoint(WidgetSize.width() / 2, WidgetSize.height() / 2);
|
|
|
|
|
MouseMove(m_rootWidget.get(), start, QPoint(0, 0));
|
|
|
|
|
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
|
|
|
|
|
|
|
|
|
|
const auto mouseDelta = QPoint(5, 0);
|
|
|
|
|
|
|
|
|
|
// initial movement to begin the camera behavior
|
|
|
|
|
MousePressAndMove(m_rootWidget.get(), start, mouseDelta, Qt::MouseButton::RightButton);
|
|
|
|
|
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
|
|
|
|
|
|
|
|
|
|
// move the cursor right
|
|
|
|
|
for (int i = 0; i < 50; ++i)
|
|
|
|
|
{
|
|
|
|
|
MousePressAndMove(m_rootWidget.get(), start + mouseDelta, mouseDelta, Qt::MouseButton::RightButton);
|
|
|
|
|
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// move the cursor left (do an extra iteration moving left to account for the initial dead-zone)
|
|
|
|
|
for (int i = 0; i < 51; ++i)
|
|
|
|
|
{
|
|
|
|
|
MousePressAndMove(m_rootWidget.get(), start + mouseDelta, -mouseDelta, Qt::MouseButton::RightButton);
|
|
|
|
|
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QTest::mouseRelease(m_rootWidget.get(), Qt::MouseButton::RightButton, Qt::KeyboardModifier::NoModifier, start + mouseDelta);
|
|
|
|
|
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
|
|
|
|
|
|
|
|
|
|
// Then
|
|
|
|
|
// retrieve the amount of yaw rotation
|
|
|
|
|
const AZ::Quaternion cameraRotation = m_cameraViewportContextView->GetCameraTransform().GetRotation();
|
|
|
|
|
const auto eulerAngles = AzFramework::EulerAngles(AZ::Matrix3x3::CreateFromQuaternion(cameraRotation));
|
|
|
|
|
|
|
|
|
|
// camera should be back at the center (no yaw)
|
|
|
|
|
using ::testing::FloatNear;
|
|
|
|
|
EXPECT_THAT(eulerAngles.GetZ(), FloatNear(0.0f, 0.001f));
|
|
|
|
|
|
|
|
|
|
// Clean-up
|
|
|
|
|
HaltCollaborators();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(ModularViewportCameraControllerFixture, CameraDoesNotContinueToRotateGivenNoInputWhenCaptured)
|
|
|
|
|
{
|
|
|
|
|
// Given
|
|
|
|
|
PrepareCollaborators();
|
|
|
|
|
SandboxEditor::SetCameraCaptureCursorForLook(true);
|
|
|
|
|
|
|
|
|
|
const float deltaTime = 1.0f / 60.0f;
|
|
|
|
|
|
|
|
|
|
// When
|
|
|
|
|
// move to the center of the screen
|
|
|
|
|
auto start = QPoint(WidgetSize.width() / 2, WidgetSize.height() / 2);
|
|
|
|
|
MouseMove(m_rootWidget.get(), start, QPoint(0, 0));
|
|
|
|
|
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
|
|
|
|
|
|
|
|
|
|
// will move a small amount initially
|
|
|
|
|
const auto mouseDelta = QPoint(5, 0);
|
|
|
|
|
MousePressAndMove(m_rootWidget.get(), start, mouseDelta, Qt::MouseButton::RightButton);
|
|
|
|
|
|
|
|
|
|
// ensure further updates to not continue to rotate
|
|
|
|
|
for (int i = 0; i < 50; ++i)
|
|
|
|
|
{
|
|
|
|
|
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Then
|
|
|
|
|
// ensure the camera rotation is no longer the identity
|
|
|
|
|
const AZ::Quaternion cameraRotation = m_cameraViewportContextView->GetCameraTransform().GetRotation();
|
|
|
|
|
const auto eulerAngles = AzFramework::EulerAngles(AZ::Matrix3x3::CreateFromQuaternion(cameraRotation));
|
|
|
|
|
|
|
|
|
|
// initial amount of rotation after first mouse move
|
|
|
|
|
using ::testing::FloatNear;
|
|
|
|
|
EXPECT_THAT(eulerAngles.GetZ(), FloatNear(-0.025f, 0.001f));
|
|
|
|
|
|
|
|
|
|
// Clean-up
|
|
|
|
|
HaltCollaborators();
|
|
|
|
|
}
|
|
|
|
|
} // namespace UnitTest
|
|
|
|
|
|