First pass for getting things ready for grid snap button (#1118)
* first pass of change to simplify snapping for snap-to-grid button and fix snapping bug caused by non-uniform scale
This commit is contained in:
committed by
GitHub
parent
f20ae8345a
commit
05e20803a8
@@ -10,52 +10,55 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AzManipulatorTestFrameworkTestFixtures.h"
|
||||
|
||||
#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 <AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h>
|
||||
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
|
||||
#include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
|
||||
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
|
||||
#include <AzToolsFramework/Manipulators/PlanarManipulator.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AZTestShared/Math/MathTestHelpers.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class GridSnappingFixture
|
||||
: public ToolsApplicationFixture
|
||||
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))
|
||||
{}
|
||||
, m_actionDispatcher(
|
||||
AZStd::make_unique<AzManipulatorTestFramework::ImmediateModeActionDispatcher>(*m_viewportManipulatorInteraction))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUpEditorFixtureImpl() override
|
||||
{
|
||||
m_cameraState = AzFramework::CreateIdentityDefaultCamera(
|
||||
AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
|
||||
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)
|
||||
{
|
||||
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> linearManipulator(AzManipulatorTestFramework::CreateLinearManipulator(
|
||||
m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
|
||||
/*position=*/AZ::Vector3(0.0f, 50.0f, 0.0f),
|
||||
/*radius=*/m_boundsRadius));
|
||||
|
||||
// the initial starting position of the manipulator (in front of the camera)
|
||||
const auto initialPositionWorld = m_linearManipulator->GetLocalPosition();
|
||||
const auto initialPositionWorld = 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
|
||||
@@ -66,21 +69,18 @@ namespace UnitTest
|
||||
// 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);
|
||||
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);
|
||||
});
|
||||
linearManipulator->InstallMouseMoveCallback(
|
||||
[this, linearManipulator](const AzToolsFramework::LinearManipulator::Action& action)
|
||||
{
|
||||
linearManipulator->SetLocalPosition(action.LocalPosition());
|
||||
});
|
||||
|
||||
m_actionDispatcher
|
||||
->EnableSnapToGrid()
|
||||
m_actionDispatcher->EnableSnapToGrid()
|
||||
->GridSize(5.0f)
|
||||
->CameraState(m_cameraState)
|
||||
->MousePosition(initialPositionScreen)
|
||||
@@ -89,7 +89,67 @@ namespace UnitTest
|
||||
->MousePosition(finalPositionScreen)
|
||||
->MouseLButtonUp()
|
||||
->ExpectManipulatorNotBeingInteracted()
|
||||
->ExpectTrue(m_linearManipulator->GetLocalPosition().IsClose(finalPositionWorld, 0.01f))
|
||||
;
|
||||
->ExpectTrue(linearManipulator->GetLocalPosition().IsClose(finalPositionWorld, 0.01f));
|
||||
}
|
||||
|
||||
template<typename Manipulator>
|
||||
void ValidateManipulatorSnappingBehavior(
|
||||
AZStd::shared_ptr<Manipulator> manipulator, AzManipulatorTestFramework::ImmediateModeActionDispatcher* actionDispatcher,
|
||||
const AzFramework::CameraState& cameraState)
|
||||
{
|
||||
manipulator->SetLocalOrientation(AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(180.0f, 0.0f, 135.0f)));
|
||||
|
||||
// the initial starting position of the manipulator (in front of the camera)
|
||||
const auto initialPositionWorld = manipulator->GetLocalPosition() + AZ::Vector3::CreateAxisX(0.15f);
|
||||
// where the manipulator should end up (unmoved)
|
||||
const auto finalPositionWorld = manipulator->GetLocalPosition();
|
||||
// where we should move the mouse to
|
||||
const auto attemptPositionWorld = manipulator->GetLocalPosition() + AZ::Vector3::CreateAxisX(0.35f);
|
||||
// calculate the position in screen space of the initial position of the manipulator
|
||||
const auto initialPositionScreen = AzFramework::WorldToScreen(initialPositionWorld, cameraState);
|
||||
// calculate the position in screen space of the final position of the manipulator
|
||||
const auto attemptPositionScreen = AzFramework::WorldToScreen(attemptPositionWorld, cameraState);
|
||||
|
||||
// callback to update the manipulator's current position
|
||||
manipulator->InstallMouseMoveCallback(
|
||||
[manipulator](const typename Manipulator::Action& action)
|
||||
{
|
||||
manipulator->SetLocalPosition(action.LocalPosition());
|
||||
});
|
||||
|
||||
actionDispatcher->EnableSnapToGrid()
|
||||
->GridSize(1.0f)
|
||||
->CameraState(cameraState)
|
||||
->MousePosition(initialPositionScreen)
|
||||
->MouseLButtonDown()
|
||||
->ExpectManipulatorBeingInteracted()
|
||||
->MousePosition(attemptPositionScreen)
|
||||
->MouseLButtonUp()
|
||||
->ExpectManipulatorNotBeingInteracted()
|
||||
->ExpectThat(manipulator->GetLocalPosition(), IsCloseTolerance(finalPositionWorld, 0.01f));
|
||||
}
|
||||
|
||||
TEST_F(GridSnappingFixture, MouseDownAndMoveLinearManipulatorDoesNotSnapWithMovementSmallerThanHalfGridSize)
|
||||
{
|
||||
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> linearManipulator(AzManipulatorTestFramework::CreateLinearManipulator(
|
||||
m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
|
||||
/*position=*/AZ::Vector3(0.0f, 10.0f, 0.0f),
|
||||
/*radius=*/m_boundsRadius));
|
||||
|
||||
linearManipulator->SetAxis(AZ::Vector3::CreateAxisY());
|
||||
|
||||
ValidateManipulatorSnappingBehavior(linearManipulator, m_actionDispatcher.get(), m_cameraState);
|
||||
}
|
||||
|
||||
TEST_F(GridSnappingFixture, MouseDownAndMovePlanarManipulatorDoesNotSnapWithMovementSmallerThanHalfGridSize)
|
||||
{
|
||||
AZStd::shared_ptr<AzToolsFramework::PlanarManipulator> planarManipulator(AzManipulatorTestFramework::CreatePlanarManipulator(
|
||||
m_viewportManipulatorInteraction->GetManipulatorManager().GetId(),
|
||||
/*position=*/AZ::Vector3(0.0f, 10.0f, 0.0f),
|
||||
/*radius=*/m_boundsRadius));
|
||||
|
||||
planarManipulator->SetAxes(AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
|
||||
|
||||
ValidateManipulatorSnappingBehavior(planarManipulator, m_actionDispatcher.get(), m_cameraState);
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
Reference in New Issue
Block a user