Update to how entity space is treated in the viewport (#4263)
* first pass fixes for how entity space is handled in the viewport interaction model Signed-off-by: hultonha <hultonha@amazon.co.uk> * small updates to simplify space handling Signed-off-by: hultonha <hultonha@amazon.co.uk> * fix for influence group with one entity selected Signed-off-by: hultonha <hultonha@amazon.co.uk> * some tidy-up and fix for scale manipulator snapping Signed-off-by: hultonha <hultonha@amazon.co.uk> * couple of small fixes for scale manipulator Signed-off-by: hultonha <hultonha@amazon.co.uk> * small comment update Signed-off-by: hultonha <hultonha@amazon.co.uk> * fixes for integration test failures Signed-off-by: hultonha <hultonha@amazon.co.uk> * add test for rotation manipulator Signed-off-by: hultonha <hultonha@amazon.co.uk> * add test coverage for rotation manipulators Signed-off-by: hultonha <hultonha@amazon.co.uk> * add tests for translation manipulators and some other tidy-up changes Signed-off-by: hultonha <hultonha@amazon.co.uk> * add tests for translating a group of entities Signed-off-by: hultonha <hultonha@amazon.co.uk> * add some tests for scale manipulators Signed-off-by: hultonha <hultonha@amazon.co.uk> * some updates and formatting changes (clang-format) to ViewportScreen Signed-off-by: hultonha <hultonha@amazon.co.uk> * simplify usage of lround code Signed-off-by: hultonha <hultonha@amazon.co.uk> * update missed name updates Signed-off-by: hultonha <hultonha@amazon.co.uk> * update usage of WorldToScreenNdc Signed-off-by: hultonha <hultonha@amazon.co.uk> * updates following review feedback Signed-off-by: hultonha <hultonha@amazon.co.uk> * some more small tidy-up changes Signed-off-by: hultonha <hultonha@amazon.co.uk> * move static variables to be marked inline Signed-off-by: hultonha <hultonha@amazon.co.uk> * small formatting fixes Signed-off-by: hultonha <hultonha@amazon.co.uk>
This commit is contained in:
@@ -242,11 +242,11 @@ namespace UnitTest
|
||||
{
|
||||
// the initial starting position of the entities
|
||||
AZ::TransformBus::Event(
|
||||
m_entityId1, &AZ::TransformBus::Events::SetWorldTM, AZ::Transform::CreateTranslation(m_entity1WorldTranslation));
|
||||
m_entityId1, &AZ::TransformBus::Events::SetWorldTM, AZ::Transform::CreateTranslation(Entity1WorldTranslation));
|
||||
AZ::TransformBus::Event(
|
||||
m_entityId2, &AZ::TransformBus::Events::SetWorldTM, AZ::Transform::CreateTranslation(m_entity2WorldTranslation));
|
||||
m_entityId2, &AZ::TransformBus::Events::SetWorldTM, AZ::Transform::CreateTranslation(Entity2WorldTranslation));
|
||||
AZ::TransformBus::Event(
|
||||
m_entityId3, &AZ::TransformBus::Events::SetWorldTM, AZ::Transform::CreateTranslation(m_entity3WorldTranslation));
|
||||
m_entityId3, &AZ::TransformBus::Events::SetWorldTM, AZ::Transform::CreateTranslation(Entity3WorldTranslation));
|
||||
}
|
||||
|
||||
static void PositionCamera(AzFramework::CameraState& cameraState)
|
||||
@@ -261,9 +261,10 @@ namespace UnitTest
|
||||
AZ::EntityId m_entityId1;
|
||||
AZ::EntityId m_entityId2;
|
||||
AZ::EntityId m_entityId3;
|
||||
AZ::Vector3 m_entity1WorldTranslation = AZ::Vector3(5.0f, 15.0f, 10.0f);
|
||||
AZ::Vector3 m_entity2WorldTranslation = AZ::Vector3(5.0f, 14.0f, 10.0f);
|
||||
AZ::Vector3 m_entity3WorldTranslation = AZ::Vector3(5.0f, 16.0f, 10.0f);
|
||||
|
||||
static inline const AZ::Vector3 Entity1WorldTranslation = AZ::Vector3(5.0f, 15.0f, 10.0f);
|
||||
static inline const AZ::Vector3 Entity2WorldTranslation = AZ::Vector3(5.0f, 14.0f, 10.0f);
|
||||
static inline const AZ::Vector3 Entity3WorldTranslation = AZ::Vector3(5.0f, 16.0f, 10.0f);
|
||||
};
|
||||
|
||||
void ArrangeIndividualRotatedEntitySelection(const AzToolsFramework::EntityIdList& entityIds, const AZ::Quaternion& orientation)
|
||||
@@ -371,16 +372,16 @@ namespace UnitTest
|
||||
// Given
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
ArrangeIndividualRotatedEntitySelection(m_entityIds, AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f)));
|
||||
const auto entityTransform = AZ::Transform::CreateFromQuaternion(AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f)));
|
||||
ArrangeIndividualRotatedEntitySelection(m_entityIds, entityTransform.GetRotation());
|
||||
RefreshManipulators(EditorTransformComponentSelectionRequestBus::Events::RefreshType::All);
|
||||
|
||||
SetTransformMode(EditorTransformComponentSelectionRequestBus::Events::Mode::Rotation);
|
||||
|
||||
const AZ::Transform manipulatorTransformBefore = GetManipulatorTransform().value_or(AZ::Transform::CreateIdentity());
|
||||
|
||||
// check preconditions - manipulator transform matches parent/world transform (identity)
|
||||
EXPECT_THAT(manipulatorTransformBefore.GetBasisY(), IsClose(AZ::Vector3::CreateAxisY()));
|
||||
EXPECT_THAT(manipulatorTransformBefore.GetBasisZ(), IsClose(AZ::Vector3::CreateAxisZ()));
|
||||
// check preconditions - manipulator transform matches the entity transform
|
||||
EXPECT_THAT(manipulatorTransformBefore, IsClose(entityTransform));
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -624,7 +625,7 @@ namespace UnitTest
|
||||
EXPECT_TRUE(selectedEntitiesBefore.empty());
|
||||
|
||||
// calculate the position in screen space of the initial entity position
|
||||
const auto entity1ScreenPosition = AzFramework::WorldToScreen(m_entity1WorldTranslation, m_cameraState);
|
||||
const auto entity1ScreenPosition = AzFramework::WorldToScreen(Entity1WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->SetStickySelect(true)
|
||||
@@ -649,7 +650,7 @@ namespace UnitTest
|
||||
EXPECT_TRUE(selectedEntitiesBefore.empty());
|
||||
|
||||
// calculate the position in screen space of the initial entity position
|
||||
const auto entity1ScreenPosition = AzFramework::WorldToScreen(m_entity1WorldTranslation, m_cameraState);
|
||||
const auto entity1ScreenPosition = AzFramework::WorldToScreen(Entity1WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->SetStickySelect(false)
|
||||
@@ -728,7 +729,7 @@ namespace UnitTest
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(Entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->SetStickySelect(true)
|
||||
@@ -754,7 +755,7 @@ namespace UnitTest
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(Entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->SetStickySelect(false)
|
||||
@@ -780,7 +781,7 @@ namespace UnitTest
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(Entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->SetStickySelect(true)
|
||||
@@ -806,7 +807,7 @@ namespace UnitTest
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(Entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->SetStickySelect(false)
|
||||
@@ -832,7 +833,7 @@ namespace UnitTest
|
||||
AzToolsFramework::SelectEntities({ m_entityId1, m_entityId2 });
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(Entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->SetStickySelect(true)
|
||||
@@ -858,7 +859,7 @@ namespace UnitTest
|
||||
AzToolsFramework::SelectEntities({ m_entityId1, m_entityId2 });
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(Entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->SetStickySelect(false)
|
||||
@@ -1001,7 +1002,7 @@ namespace UnitTest
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(Entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// single click select entity2
|
||||
m_actionDispatcher->SetStickySelect(false)
|
||||
@@ -1035,7 +1036,7 @@ namespace UnitTest
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(Entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// single click select entity2
|
||||
m_actionDispatcher->SetStickySelect(GetParam())
|
||||
@@ -1056,7 +1057,7 @@ namespace UnitTest
|
||||
manipulatorTransform, AzToolsFramework::GetEntityContextId(),
|
||||
&AzToolsFramework::EditorTransformComponentSelectionRequestBus::Events::GetManipulatorTransform);
|
||||
|
||||
EXPECT_THAT(manipulatorTransform->GetTranslation(), IsClose(m_entity2WorldTranslation));
|
||||
EXPECT_THAT(manipulatorTransform->GetTranslation(), IsClose(Entity2WorldTranslation));
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
@@ -1069,7 +1070,7 @@ namespace UnitTest
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(Entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// position in space above the entities
|
||||
const auto clickOffPositionWorld = AZ::Vector3(5.0f, 15.0f, 12.0f);
|
||||
@@ -1096,7 +1097,7 @@ namespace UnitTest
|
||||
manipulatorTransform, AzToolsFramework::GetEntityContextId(),
|
||||
&AzToolsFramework::EditorTransformComponentSelectionRequestBus::Events::GetManipulatorTransform);
|
||||
|
||||
EXPECT_THAT(manipulatorTransform->GetTranslation(), IsClose(m_entity2WorldTranslation));
|
||||
EXPECT_THAT(manipulatorTransform->GetTranslation(), IsClose(Entity2WorldTranslation));
|
||||
})
|
||||
->MousePosition(clickOffPositionScreen)
|
||||
->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Control)
|
||||
@@ -1113,11 +1114,560 @@ namespace UnitTest
|
||||
&AzToolsFramework::EditorTransformComponentSelectionRequestBus::Events::GetManipulatorTransform);
|
||||
|
||||
// manipulator transform is reset
|
||||
EXPECT_THAT(manipulatorTransform->GetTranslation(), IsClose(m_entity1WorldTranslation));
|
||||
EXPECT_THAT(manipulatorTransform->GetTranslation(), IsClose(Entity1WorldTranslation));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(All, EditorTransformComponentSelectionViewportPickingManipulatorTestFixtureParam, testing::Values(true, false));
|
||||
|
||||
// create alias for EditorTransformComponentSelectionViewportPickingManipulatorTestFixture to help group tests
|
||||
using EditorTransformComponentSelectionManipulatorInteractionTestFixture =
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture;
|
||||
|
||||
// type to group related inputs and outcomes for parameterized tests (single entity)
|
||||
struct ManipulatorOptionsSingle
|
||||
{
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifier m_keyboardModifier;
|
||||
AZ::Transform m_expectedManipulatorTransformAfter;
|
||||
AZ::Transform m_expectedEntityTransformAfter;
|
||||
};
|
||||
|
||||
class EditorTransformComponentSelectionRotationManipulatorSingleEntityTestFixtureParam
|
||||
: public EditorTransformComponentSelectionManipulatorInteractionTestFixture
|
||||
, public ::testing::WithParamInterface<ManipulatorOptionsSingle>
|
||||
{
|
||||
};
|
||||
|
||||
TEST_P(
|
||||
EditorTransformComponentSelectionRotationManipulatorSingleEntityTestFixtureParam,
|
||||
RotatingASingleEntityWithDifferentModifierCombinations)
|
||||
{
|
||||
using AzToolsFramework::EditorTransformComponentSelectionRequestBus;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
SetTransformMode(EditorTransformComponentSelectionRequestBus::Events::Mode::Rotation);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
const float screenToWorldMultiplier = AzToolsFramework::CalculateScreenToWorldMultiplier(Entity1WorldTranslation, m_cameraState);
|
||||
const float manipulatorRadius = 2.0f * screenToWorldMultiplier;
|
||||
|
||||
const auto rotationManipulatorStartHoldWorldPosition = Entity1WorldTranslation +
|
||||
AZ::Quaternion::CreateRotationX(AZ::DegToRad(-45.0f)).TransformVector(AZ::Vector3::CreateAxisY(-manipulatorRadius));
|
||||
const auto rotationManipulatorEndHoldWorldPosition = Entity1WorldTranslation +
|
||||
AZ::Quaternion::CreateRotationX(AZ::DegToRad(-135.0f)).TransformVector(AZ::Vector3::CreateAxisY(-manipulatorRadius));
|
||||
|
||||
// calculate screen space positions
|
||||
const auto rotationManipulatorHoldScreenPosition =
|
||||
AzFramework::WorldToScreen(rotationManipulatorStartHoldWorldPosition, m_cameraState);
|
||||
const auto rotationManipulatorEndHoldScreenPosition =
|
||||
AzFramework::WorldToScreen(rotationManipulatorEndHoldWorldPosition, m_cameraState);
|
||||
|
||||
m_actionDispatcher->CameraState(m_cameraState)
|
||||
->MousePosition(rotationManipulatorHoldScreenPosition)
|
||||
->KeyboardModifierDown(GetParam().m_keyboardModifier)
|
||||
->MouseLButtonDown()
|
||||
->MousePosition(rotationManipulatorEndHoldScreenPosition)
|
||||
->MouseLButtonUp();
|
||||
|
||||
const auto expectedEntityTransform = GetParam().m_expectedEntityTransformAfter;
|
||||
const auto expectedManipulatorTransform = GetParam().m_expectedManipulatorTransformAfter;
|
||||
|
||||
const auto manipulatorTransform = GetManipulatorTransform();
|
||||
const auto entityTransform = AzToolsFramework::GetWorldTransform(m_entityId1);
|
||||
|
||||
EXPECT_THAT(*manipulatorTransform, IsClose(expectedManipulatorTransform));
|
||||
EXPECT_THAT(entityTransform, IsClose(expectedEntityTransform));
|
||||
}
|
||||
|
||||
static const AZ::Transform ExpectedTransformAfterLocalRotationManipulatorMotion = AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion::CreateRotationX(AZ::DegToRad(-90.0f)),
|
||||
EditorTransformComponentSelectionViewportPickingFixture::Entity1WorldTranslation);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
All,
|
||||
EditorTransformComponentSelectionRotationManipulatorSingleEntityTestFixtureParam,
|
||||
testing::Values(
|
||||
// this replicates rotating an entity in local space with no modifiers held
|
||||
// manipulator and entity rotate
|
||||
ManipulatorOptionsSingle{ AzToolsFramework::ViewportInteraction::KeyboardModifier::None,
|
||||
ExpectedTransformAfterLocalRotationManipulatorMotion,
|
||||
ExpectedTransformAfterLocalRotationManipulatorMotion },
|
||||
// this replicates rotating an entity in local space with the alt modifier held
|
||||
// manipulator and entity rotate
|
||||
ManipulatorOptionsSingle{ AzToolsFramework::ViewportInteraction::KeyboardModifier::Alt,
|
||||
ExpectedTransformAfterLocalRotationManipulatorMotion,
|
||||
ExpectedTransformAfterLocalRotationManipulatorMotion },
|
||||
// this replicates rotating an entity in world space with the shift modifier held
|
||||
// entity rotates, manipulator remains aligned to world
|
||||
ManipulatorOptionsSingle{
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifier::Shift,
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity1WorldTranslation),
|
||||
ExpectedTransformAfterLocalRotationManipulatorMotion },
|
||||
// this replicates rotating the manipulator in local space with the ctrl modifier held (entity is unchanged)
|
||||
ManipulatorOptionsSingle{
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifier::Ctrl, ExpectedTransformAfterLocalRotationManipulatorMotion,
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity1WorldTranslation) }));
|
||||
|
||||
// type to group related inputs and outcomes for parameterized tests (two entities)
|
||||
struct ManipulatorOptionsMultiple
|
||||
{
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifier m_keyboardModifier;
|
||||
AZ::Transform m_expectedManipulatorTransformAfter;
|
||||
AZ::Transform m_firstExpectedEntityTransformAfter;
|
||||
AZ::Transform m_secondExpectedEntityTransformAfter;
|
||||
};
|
||||
|
||||
class EditorTransformComponentSelectionRotationManipulatorMultipleEntityTestFixtureParam
|
||||
: public EditorTransformComponentSelectionManipulatorInteractionTestFixture
|
||||
, public ::testing::WithParamInterface<ManipulatorOptionsMultiple>
|
||||
{
|
||||
};
|
||||
|
||||
TEST_P(
|
||||
EditorTransformComponentSelectionRotationManipulatorMultipleEntityTestFixtureParam,
|
||||
RotatingMultipleEntitiesWithDifferentModifierCombinations)
|
||||
{
|
||||
using AzToolsFramework::EditorTransformComponentSelectionRequestBus;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
SetTransformMode(EditorTransformComponentSelectionRequestBus::Events::Mode::Rotation);
|
||||
|
||||
AzToolsFramework::SelectEntities({ m_entityId2, m_entityId3 });
|
||||
|
||||
// manipulator should be centered between the two entities
|
||||
const auto initialManipulatorTransform = GetManipulatorTransform();
|
||||
|
||||
const float screenToWorldMultiplier =
|
||||
AzToolsFramework::CalculateScreenToWorldMultiplier(initialManipulatorTransform->GetTranslation(), m_cameraState);
|
||||
const float manipulatorRadius = 2.0f * screenToWorldMultiplier;
|
||||
|
||||
const auto rotationManipulatorStartHoldWorldPosition = initialManipulatorTransform->GetTranslation() +
|
||||
AZ::Quaternion::CreateRotationX(AZ::DegToRad(-45.0f)).TransformVector(AZ::Vector3::CreateAxisY(-manipulatorRadius));
|
||||
const auto rotationManipulatorEndHoldWorldPosition = initialManipulatorTransform->GetTranslation() +
|
||||
AZ::Quaternion::CreateRotationX(AZ::DegToRad(-135.0f)).TransformVector(AZ::Vector3::CreateAxisY(-manipulatorRadius));
|
||||
|
||||
// calculate screen space positions
|
||||
const auto rotationManipulatorHoldScreenPosition =
|
||||
AzFramework::WorldToScreen(rotationManipulatorStartHoldWorldPosition, m_cameraState);
|
||||
const auto rotationManipulatorEndHoldScreenPosition =
|
||||
AzFramework::WorldToScreen(rotationManipulatorEndHoldWorldPosition, m_cameraState);
|
||||
|
||||
m_actionDispatcher->CameraState(m_cameraState)
|
||||
->MousePosition(rotationManipulatorHoldScreenPosition)
|
||||
->KeyboardModifierDown(GetParam().m_keyboardModifier)
|
||||
->MouseLButtonDown()
|
||||
->MousePosition(rotationManipulatorEndHoldScreenPosition)
|
||||
->MouseLButtonUp();
|
||||
|
||||
const auto expectedEntity2Transform = GetParam().m_firstExpectedEntityTransformAfter;
|
||||
const auto expectedEntity3Transform = GetParam().m_secondExpectedEntityTransformAfter;
|
||||
const auto expectedManipulatorTransform = GetParam().m_expectedManipulatorTransformAfter;
|
||||
|
||||
const auto manipulatorTransformAfter = GetManipulatorTransform();
|
||||
const auto entity2Transform = AzToolsFramework::GetWorldTransform(m_entityId2);
|
||||
const auto entity3Transform = AzToolsFramework::GetWorldTransform(m_entityId3);
|
||||
|
||||
EXPECT_THAT(*manipulatorTransformAfter, IsClose(expectedManipulatorTransform));
|
||||
EXPECT_THAT(entity2Transform, IsClose(expectedEntity2Transform));
|
||||
EXPECT_THAT(entity3Transform, IsClose(expectedEntity3Transform));
|
||||
}
|
||||
|
||||
// note: The aggregate manipulator position will be the average of entity 2 and 3 combined which
|
||||
// winds up being the same as entity 1
|
||||
static const AZ::Vector3 AggregateManipulatorPositionWithEntity2and3Selected =
|
||||
EditorTransformComponentSelectionViewportPickingFixture::Entity1WorldTranslation;
|
||||
|
||||
static const AZ::Transform ExpectedEntity2TransformAfterLocalGroupRotationManipulatorMotion =
|
||||
AZ::Transform::CreateTranslation(AggregateManipulatorPositionWithEntity2and3Selected) *
|
||||
AZ::Transform::CreateFromQuaternion(AZ::Quaternion::CreateRotationX(AZ::DegToRad(-90.0f))) *
|
||||
AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisY(-1.0f));
|
||||
static const AZ::Transform ExpectedEntity3TransformAfterLocalGroupRotationManipulatorMotion =
|
||||
AZ::Transform::CreateTranslation(AggregateManipulatorPositionWithEntity2and3Selected) *
|
||||
AZ::Transform::CreateFromQuaternion(AZ::Quaternion::CreateRotationX(AZ::DegToRad(-90.0f))) *
|
||||
AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisY(1.0f));
|
||||
static const AZ::Transform ExpectedEntity2TransformAfterLocalIndividualRotationManipulatorMotion =
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity2WorldTranslation) *
|
||||
AZ::Transform::CreateFromQuaternion(AZ::Quaternion::CreateRotationX(AZ::DegToRad(-90.0f)));
|
||||
static const AZ::Transform ExpectedEntity3TransformAfterLocalIndividualRotationManipulatorMotion =
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity3WorldTranslation) *
|
||||
AZ::Transform::CreateFromQuaternion(AZ::Quaternion::CreateRotationX(AZ::DegToRad(-90.0f)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
All,
|
||||
EditorTransformComponentSelectionRotationManipulatorMultipleEntityTestFixtureParam,
|
||||
testing::Values(
|
||||
// this replicates rotating a group of entities in local space with no modifiers held
|
||||
// manipulator and entity rotate
|
||||
ManipulatorOptionsMultiple{ AzToolsFramework::ViewportInteraction::KeyboardModifier::None,
|
||||
ExpectedTransformAfterLocalRotationManipulatorMotion,
|
||||
ExpectedEntity2TransformAfterLocalGroupRotationManipulatorMotion,
|
||||
ExpectedEntity3TransformAfterLocalGroupRotationManipulatorMotion },
|
||||
// this replicates rotating a group of entities in local space with the alt modifier held
|
||||
// manipulator and entity rotate
|
||||
ManipulatorOptionsMultiple{ AzToolsFramework::ViewportInteraction::KeyboardModifier::Alt,
|
||||
ExpectedTransformAfterLocalRotationManipulatorMotion,
|
||||
ExpectedEntity2TransformAfterLocalIndividualRotationManipulatorMotion,
|
||||
ExpectedEntity3TransformAfterLocalIndividualRotationManipulatorMotion },
|
||||
// this replicates rotating a group of entities in world space with the shift modifier held
|
||||
// entity rotates, manipulator remains aligned to world
|
||||
ManipulatorOptionsMultiple{
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifier::Shift,
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity1WorldTranslation),
|
||||
ExpectedEntity2TransformAfterLocalGroupRotationManipulatorMotion,
|
||||
ExpectedEntity3TransformAfterLocalGroupRotationManipulatorMotion },
|
||||
// this replicates rotating the manipulator in local space with the ctrl modifier held (entity is unchanged)
|
||||
ManipulatorOptionsMultiple{
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifier::Ctrl, ExpectedTransformAfterLocalRotationManipulatorMotion,
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity2WorldTranslation),
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity3WorldTranslation) }));
|
||||
|
||||
class EditorTransformComponentSelectionTranslationManipulatorSingleEntityTestFixtureParam
|
||||
: public EditorTransformComponentSelectionManipulatorInteractionTestFixture
|
||||
, public ::testing::WithParamInterface<ManipulatorOptionsSingle>
|
||||
{
|
||||
};
|
||||
|
||||
static const float LinearManipulatorYAxisMovement = -3.0f;
|
||||
static const float LinearManipulatorZAxisMovement = 2.0f;
|
||||
|
||||
TEST_P(
|
||||
EditorTransformComponentSelectionTranslationManipulatorSingleEntityTestFixtureParam,
|
||||
TranslatingASingleEntityWithDifferentModifierCombinations)
|
||||
{
|
||||
using AzToolsFramework::EditorTransformComponentSelectionRequestBus;
|
||||
|
||||
PositionEntities();
|
||||
|
||||
// move camera up and to the left so it's just above the normal row of entities
|
||||
AzFramework::SetCameraTransform(
|
||||
m_cameraState,
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(0.0f, 0.0f, 90.0f)), AZ::Vector3(10.0f, 14.5, 11.0f)));
|
||||
|
||||
SetTransformMode(EditorTransformComponentSelectionRequestBus::Events::Mode::Translation);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
const auto entity1Transform = AzToolsFramework::GetWorldTransform(m_entityId1);
|
||||
|
||||
const float screenToWorldMultiplier = AzToolsFramework::CalculateScreenToWorldMultiplier(
|
||||
AzToolsFramework::GetWorldTransform(m_entityId1).GetTranslation(), m_cameraState);
|
||||
|
||||
// calculate positions for two click and drag motions (moving a linear manipulator)
|
||||
// begin each click in the center of the line of the linear manipulators
|
||||
const auto translationManipulatorStartHoldWorldPosition1 =
|
||||
AzToolsFramework::GetWorldTransform(m_entityId1).GetTranslation() + entity1Transform.GetBasisZ() * screenToWorldMultiplier;
|
||||
const auto translationManipulatorEndHoldWorldPosition1 =
|
||||
translationManipulatorStartHoldWorldPosition1 + AZ::Vector3::CreateAxisZ(LinearManipulatorZAxisMovement);
|
||||
const auto translationManipulatorStartHoldWorldPosition2 = AzToolsFramework::GetWorldTransform(m_entityId1).GetTranslation() +
|
||||
AZ::Vector3::CreateAxisZ(LinearManipulatorZAxisMovement) - entity1Transform.GetBasisY() * screenToWorldMultiplier;
|
||||
const auto translationManipulatorEndHoldWorldPosition2 =
|
||||
translationManipulatorStartHoldWorldPosition2 + AZ::Vector3::CreateAxisY(LinearManipulatorYAxisMovement);
|
||||
|
||||
// transform to screen space
|
||||
const auto translationManipulatorStartHoldScreenPosition1 =
|
||||
AzFramework::WorldToScreen(translationManipulatorStartHoldWorldPosition1, m_cameraState);
|
||||
const auto translationManipulatorEndHoldScreenPosition1 =
|
||||
AzFramework::WorldToScreen(translationManipulatorEndHoldWorldPosition1, m_cameraState);
|
||||
const auto translationManipulatorStartHoldScreenPosition2 =
|
||||
AzFramework::WorldToScreen(translationManipulatorStartHoldWorldPosition2, m_cameraState);
|
||||
const auto translationManipulatorEndHoldScreenPosition2 =
|
||||
AzFramework::WorldToScreen(translationManipulatorEndHoldWorldPosition2, m_cameraState);
|
||||
|
||||
m_actionDispatcher->CameraState(m_cameraState)
|
||||
->MousePosition(translationManipulatorStartHoldScreenPosition1)
|
||||
->KeyboardModifierDown(GetParam().m_keyboardModifier)
|
||||
->MouseLButtonDown()
|
||||
->MousePosition(translationManipulatorEndHoldScreenPosition1)
|
||||
->MouseLButtonUp()
|
||||
->MousePosition(translationManipulatorStartHoldScreenPosition2)
|
||||
->MouseLButtonDown()
|
||||
->MousePosition(translationManipulatorEndHoldScreenPosition2)
|
||||
->MouseLButtonUp();
|
||||
|
||||
const auto expectedEntityTransform = GetParam().m_expectedEntityTransformAfter;
|
||||
const auto expectedManipulatorTransform = GetParam().m_expectedManipulatorTransformAfter;
|
||||
|
||||
const auto manipulatorTransform = GetManipulatorTransform();
|
||||
const auto entityTransform = AzToolsFramework::GetWorldTransform(m_entityId1);
|
||||
|
||||
EXPECT_THAT(*manipulatorTransform, IsCloseTolerance(expectedManipulatorTransform, 0.01f));
|
||||
EXPECT_THAT(entityTransform, IsCloseTolerance(expectedEntityTransform, 0.01f));
|
||||
}
|
||||
|
||||
static const AZ::Transform ExpectedTransformAfterLocalTranslationManipulatorMotion = AZ::Transform::CreateTranslation(
|
||||
EditorTransformComponentSelectionViewportPickingFixture::Entity1WorldTranslation +
|
||||
AZ::Vector3(0.0f, LinearManipulatorYAxisMovement, LinearManipulatorZAxisMovement));
|
||||
|
||||
// where the manipulator should end up after the input from TranslatingMultipleEntitiesWithDifferentModifierCombinations
|
||||
static const AZ::Transform ExpectedManipulatorTransformAfterGroupTranslationManipulatorMotion = AZ::Transform::CreateTranslation(
|
||||
AggregateManipulatorPositionWithEntity2and3Selected +
|
||||
AZ::Vector3(0.0f, LinearManipulatorYAxisMovement, LinearManipulatorZAxisMovement));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
All,
|
||||
EditorTransformComponentSelectionTranslationManipulatorSingleEntityTestFixtureParam,
|
||||
testing::Values(
|
||||
// this replicates translating an entity in local space with no modifiers held
|
||||
// manipulator and entity translate
|
||||
ManipulatorOptionsSingle{ AzToolsFramework::ViewportInteraction::KeyboardModifier::None,
|
||||
ExpectedTransformAfterLocalTranslationManipulatorMotion,
|
||||
ExpectedTransformAfterLocalTranslationManipulatorMotion },
|
||||
// this replicates translating an entity in local space with the alt modifier held
|
||||
// manipulator and entity translate (to the user, equivalent to no modifiers with one entity selected)
|
||||
ManipulatorOptionsSingle{ AzToolsFramework::ViewportInteraction::KeyboardModifier::Alt,
|
||||
ExpectedTransformAfterLocalTranslationManipulatorMotion,
|
||||
ExpectedTransformAfterLocalTranslationManipulatorMotion },
|
||||
// this replicates translating an entity in world space with the shift modifier held
|
||||
// manipulator and entity translate
|
||||
ManipulatorOptionsSingle{ AzToolsFramework::ViewportInteraction::KeyboardModifier::Shift,
|
||||
ExpectedTransformAfterLocalTranslationManipulatorMotion,
|
||||
ExpectedTransformAfterLocalTranslationManipulatorMotion },
|
||||
// this replicates translating the manipulator in local space with the ctrl modifier held
|
||||
// entity is unchanged, manipulator moves
|
||||
ManipulatorOptionsSingle{
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifier::Ctrl, ExpectedTransformAfterLocalTranslationManipulatorMotion,
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity1WorldTranslation) }));
|
||||
|
||||
class EditorTransformComponentSelectionTranslationManipulatorMultipleEntityTestFixtureParam
|
||||
: public EditorTransformComponentSelectionManipulatorInteractionTestFixture
|
||||
, public ::testing::WithParamInterface<ManipulatorOptionsMultiple>
|
||||
{
|
||||
};
|
||||
|
||||
static const AZ::Transform Entity2RotationForLocalTranslation =
|
||||
AZ::Transform::CreateFromQuaternion(AZ::Quaternion::CreateRotationZ(AZ::DegToRad(90.0f)));
|
||||
|
||||
TEST_P(
|
||||
EditorTransformComponentSelectionTranslationManipulatorMultipleEntityTestFixtureParam,
|
||||
TranslatingMultipleEntitiesWithDifferentModifierCombinations)
|
||||
{
|
||||
using AzToolsFramework::EditorTransformComponentSelectionRequestBus;
|
||||
|
||||
PositionEntities();
|
||||
|
||||
// move camera up and to the left so it's just above the normal row of entities
|
||||
AzFramework::SetCameraTransform(
|
||||
m_cameraState,
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(0.0f, 0.0f, 90.0f)), AZ::Vector3(10.0f, 14.5, 11.0f)));
|
||||
|
||||
SetTransformMode(EditorTransformComponentSelectionRequestBus::Events::Mode::Translation);
|
||||
|
||||
// give entity 2 a different orientation to entity 3 so when moving in local space their translation vectors will be different
|
||||
AZ::TransformBus::Event(
|
||||
m_entityId2, &AZ::TransformBus::Events::SetWorldRotationQuaternion, Entity2RotationForLocalTranslation.GetRotation());
|
||||
|
||||
AzToolsFramework::SelectEntities({ m_entityId2, m_entityId3 });
|
||||
|
||||
const auto initialManipulatorTransform = GetManipulatorTransform();
|
||||
|
||||
const float screenToWorldMultiplier = AzToolsFramework::CalculateScreenToWorldMultiplier(
|
||||
AzToolsFramework::GetWorldTransform(m_entityId1).GetTranslation(), m_cameraState);
|
||||
|
||||
// calculate positions for two click and drag motions (moving a linear manipulator)
|
||||
// begin each click in the center of the line of the linear manipulators
|
||||
const auto translationManipulatorStartHoldWorldPosition1 = AzToolsFramework::GetWorldTransform(m_entityId1).GetTranslation() +
|
||||
initialManipulatorTransform->GetBasisZ() * screenToWorldMultiplier;
|
||||
const auto translationManipulatorEndHoldWorldPosition1 =
|
||||
translationManipulatorStartHoldWorldPosition1 + AZ::Vector3::CreateAxisZ(LinearManipulatorZAxisMovement);
|
||||
const auto translationManipulatorStartHoldWorldPosition2 = AzToolsFramework::GetWorldTransform(m_entityId1).GetTranslation() +
|
||||
AZ::Vector3::CreateAxisZ(LinearManipulatorZAxisMovement) - initialManipulatorTransform->GetBasisY() * screenToWorldMultiplier;
|
||||
const auto translationManipulatorEndHoldWorldPosition2 =
|
||||
translationManipulatorStartHoldWorldPosition2 + AZ::Vector3::CreateAxisY(LinearManipulatorYAxisMovement);
|
||||
|
||||
// transform to screen space
|
||||
const auto translationManipulatorStartHoldScreenPosition1 =
|
||||
AzFramework::WorldToScreen(translationManipulatorStartHoldWorldPosition1, m_cameraState);
|
||||
const auto translationManipulatorEndHoldScreenPosition1 =
|
||||
AzFramework::WorldToScreen(translationManipulatorEndHoldWorldPosition1, m_cameraState);
|
||||
const auto translationManipulatorStartHoldScreenPosition2 =
|
||||
AzFramework::WorldToScreen(translationManipulatorStartHoldWorldPosition2, m_cameraState);
|
||||
const auto translationManipulatorEndHoldScreenPosition2 =
|
||||
AzFramework::WorldToScreen(translationManipulatorEndHoldWorldPosition2, m_cameraState);
|
||||
|
||||
m_actionDispatcher->CameraState(m_cameraState)
|
||||
->MousePosition(translationManipulatorStartHoldScreenPosition1)
|
||||
->KeyboardModifierDown(GetParam().m_keyboardModifier)
|
||||
->MouseLButtonDown()
|
||||
->MousePosition(translationManipulatorEndHoldScreenPosition1)
|
||||
->MouseLButtonUp()
|
||||
->MousePosition(translationManipulatorStartHoldScreenPosition2)
|
||||
->MouseLButtonDown()
|
||||
->MousePosition(translationManipulatorEndHoldScreenPosition2)
|
||||
->MouseLButtonUp();
|
||||
|
||||
const auto expectedEntity2Transform = GetParam().m_firstExpectedEntityTransformAfter;
|
||||
const auto expectedEntity3Transform = GetParam().m_secondExpectedEntityTransformAfter;
|
||||
const auto expectedManipulatorTransform = GetParam().m_expectedManipulatorTransformAfter;
|
||||
|
||||
const auto manipulatorTransformAfter = GetManipulatorTransform();
|
||||
const auto entity2Transform = AzToolsFramework::GetWorldTransform(m_entityId2);
|
||||
const auto entity3Transform = AzToolsFramework::GetWorldTransform(m_entityId3);
|
||||
|
||||
EXPECT_THAT(*manipulatorTransformAfter, IsCloseTolerance(expectedManipulatorTransform, 0.01f));
|
||||
EXPECT_THAT(entity2Transform, IsCloseTolerance(expectedEntity2Transform, 0.01f));
|
||||
EXPECT_THAT(entity3Transform, IsCloseTolerance(expectedEntity3Transform, 0.01f));
|
||||
}
|
||||
|
||||
static const AZ::Transform ExpectedEntity2TransformAfterLocalGroupTranslationManipulatorMotion =
|
||||
AZ::Transform::CreateTranslation(
|
||||
EditorTransformComponentSelectionViewportPickingFixture::Entity2WorldTranslation +
|
||||
AZ::Vector3(0.0f, LinearManipulatorYAxisMovement, LinearManipulatorZAxisMovement)) *
|
||||
Entity2RotationForLocalTranslation;
|
||||
static const AZ::Transform ExpectedEntity3TransformAfterLocalGroupTranslationManipulatorMotion = AZ::Transform::CreateTranslation(
|
||||
EditorTransformComponentSelectionViewportPickingFixture::Entity3WorldTranslation +
|
||||
AZ::Vector3(0.0f, LinearManipulatorYAxisMovement, LinearManipulatorZAxisMovement));
|
||||
// note: as entity has been rotated by 90 degrees about Z in TranslatingMultipleEntitiesWithDifferentModifierCombinations then
|
||||
// LinearManipulatorYAxisMovement is now aligned to the world x-axis
|
||||
static const AZ::Transform ExpectedEntity2TransformAfterLocalIndividualTranslationManipulatorMotion =
|
||||
AZ::Transform::CreateTranslation(
|
||||
EditorTransformComponentSelectionViewportPickingFixture::Entity2WorldTranslation +
|
||||
AZ::Vector3(-LinearManipulatorYAxisMovement, 0.0f, LinearManipulatorZAxisMovement)) *
|
||||
Entity2RotationForLocalTranslation;
|
||||
static const AZ::Transform ExpectedEntity3TransformAfterLocalIndividualTranslationManipulatorMotion = AZ::Transform::CreateTranslation(
|
||||
EditorTransformComponentSelectionViewportPickingFixture::Entity3WorldTranslation +
|
||||
AZ::Vector3(0.0f, LinearManipulatorYAxisMovement, LinearManipulatorZAxisMovement));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
All,
|
||||
EditorTransformComponentSelectionTranslationManipulatorMultipleEntityTestFixtureParam,
|
||||
testing::Values(
|
||||
// this replicates translating a group of entities in local space with no modifiers held (group influence)
|
||||
// manipulator and entity translate
|
||||
ManipulatorOptionsMultiple{ AzToolsFramework::ViewportInteraction::KeyboardModifier::None,
|
||||
ExpectedManipulatorTransformAfterGroupTranslationManipulatorMotion,
|
||||
ExpectedEntity2TransformAfterLocalGroupTranslationManipulatorMotion,
|
||||
ExpectedEntity3TransformAfterLocalGroupTranslationManipulatorMotion },
|
||||
// this replicates translating a group of entities in local space with the alt modifier held
|
||||
// entities move in their own local space (individual influence)
|
||||
ManipulatorOptionsMultiple{ AzToolsFramework::ViewportInteraction::KeyboardModifier::Alt,
|
||||
ExpectedManipulatorTransformAfterGroupTranslationManipulatorMotion,
|
||||
ExpectedEntity2TransformAfterLocalIndividualTranslationManipulatorMotion,
|
||||
ExpectedEntity3TransformAfterLocalIndividualTranslationManipulatorMotion },
|
||||
// this replicates translating a group of entities in world space with the shift modifier held
|
||||
// entities and manipulator move in world space
|
||||
ManipulatorOptionsMultiple{ AzToolsFramework::ViewportInteraction::KeyboardModifier::Shift,
|
||||
ExpectedManipulatorTransformAfterGroupTranslationManipulatorMotion,
|
||||
ExpectedEntity2TransformAfterLocalGroupTranslationManipulatorMotion,
|
||||
ExpectedEntity3TransformAfterLocalGroupTranslationManipulatorMotion },
|
||||
// this replicates translating the manipulator in local space with the ctrl modifier held (entities are unchanged)
|
||||
ManipulatorOptionsMultiple{
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifier::Ctrl,
|
||||
ExpectedManipulatorTransformAfterGroupTranslationManipulatorMotion,
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity2WorldTranslation) *
|
||||
Entity2RotationForLocalTranslation,
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity3WorldTranslation) }));
|
||||
|
||||
class EditorTransformComponentSelectionScaleManipulatorMultipleEntityTestFixtureParam
|
||||
: public EditorTransformComponentSelectionManipulatorInteractionTestFixture
|
||||
, public ::testing::WithParamInterface<ManipulatorOptionsMultiple>
|
||||
{
|
||||
};
|
||||
|
||||
static const float LinearManipulatorZAxisMovementScale = 0.5f;
|
||||
|
||||
TEST_P(
|
||||
EditorTransformComponentSelectionScaleManipulatorMultipleEntityTestFixtureParam,
|
||||
ScalingMultipleEntitiesWithDifferentModifierCombinations)
|
||||
{
|
||||
using AzToolsFramework::EditorTransformComponentSelectionRequestBus;
|
||||
|
||||
PositionEntities();
|
||||
|
||||
// move camera up and to the left so it's just above the normal row of entities
|
||||
AzFramework::SetCameraTransform(
|
||||
m_cameraState,
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(0.0f, 0.0f, 90.0f)), AZ::Vector3(10.0f, 15.0f, 10.1f)));
|
||||
|
||||
SetTransformMode(EditorTransformComponentSelectionRequestBus::Events::Mode::Scale);
|
||||
|
||||
AzToolsFramework::SelectEntities({ m_entityId2, m_entityId3 });
|
||||
|
||||
// manipulator should be centered between the two entities
|
||||
const auto initialManipulatorTransform = GetManipulatorTransform();
|
||||
|
||||
const float screenToWorldMultiplier =
|
||||
AzToolsFramework::CalculateScreenToWorldMultiplier(initialManipulatorTransform->GetTranslation(), m_cameraState);
|
||||
|
||||
const auto translationManipulatorStartHoldWorldPosition1 = AzToolsFramework::GetWorldTransform(m_entityId1).GetTranslation() +
|
||||
initialManipulatorTransform->GetBasisZ() * screenToWorldMultiplier;
|
||||
const auto translationManipulatorEndHoldWorldPosition1 =
|
||||
translationManipulatorStartHoldWorldPosition1 + AZ::Vector3::CreateAxisZ(LinearManipulatorZAxisMovementScale);
|
||||
|
||||
// calculate screen space positions
|
||||
const auto scaleManipulatorHoldScreenPosition =
|
||||
AzFramework::WorldToScreen(translationManipulatorStartHoldWorldPosition1, m_cameraState);
|
||||
const auto scaleManipulatorEndHoldScreenPosition =
|
||||
AzFramework::WorldToScreen(translationManipulatorEndHoldWorldPosition1, m_cameraState);
|
||||
|
||||
m_actionDispatcher->CameraState(m_cameraState)
|
||||
->MousePosition(scaleManipulatorHoldScreenPosition)
|
||||
->KeyboardModifierDown(GetParam().m_keyboardModifier)
|
||||
->MouseLButtonDown()
|
||||
->MousePosition(scaleManipulatorEndHoldScreenPosition)
|
||||
->MouseLButtonUp();
|
||||
|
||||
const auto expectedEntity2Transform = GetParam().m_firstExpectedEntityTransformAfter;
|
||||
const auto expectedEntity3Transform = GetParam().m_secondExpectedEntityTransformAfter;
|
||||
const auto expectedManipulatorTransform = GetParam().m_expectedManipulatorTransformAfter;
|
||||
|
||||
const auto manipulatorTransformAfter = GetManipulatorTransform();
|
||||
const auto entity2Transform = AzToolsFramework::GetWorldTransform(m_entityId2);
|
||||
const auto entity3Transform = AzToolsFramework::GetWorldTransform(m_entityId3);
|
||||
|
||||
EXPECT_THAT(*manipulatorTransformAfter, IsCloseTolerance(expectedManipulatorTransform, 0.01f));
|
||||
EXPECT_THAT(entity2Transform, IsCloseTolerance(expectedEntity2Transform, 0.01f));
|
||||
EXPECT_THAT(entity3Transform, IsCloseTolerance(expectedEntity3Transform, 0.01f));
|
||||
}
|
||||
|
||||
static const AZ::Transform ExpectedEntity2TransformAfterLocalGroupScaleManipulatorMotion =
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity2WorldTranslation) *
|
||||
AZ::Transform::CreateTranslation(AZ::Vector3(0.0f, -1.0f, 0.0f)) *
|
||||
AZ::Transform::CreateUniformScale(LinearManipulatorZAxisMovement);
|
||||
static const AZ::Transform ExpectedEntity3TransformAfterLocalGroupScaleManipulatorMotion =
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity3WorldTranslation) *
|
||||
AZ::Transform::CreateTranslation(AZ::Vector3(0.0f, 1.0f, 0.0f)) * AZ::Transform::CreateUniformScale(LinearManipulatorZAxisMovement);
|
||||
static const AZ::Transform ExpectedEntity2TransformAfterLocalIndividualScaleManipulatorMotion =
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity2WorldTranslation) *
|
||||
AZ::Transform::CreateUniformScale(LinearManipulatorZAxisMovement);
|
||||
static const AZ::Transform ExpectedEntity3TransformAfterLocalIndividualScaleManipulatorMotion =
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity3WorldTranslation) *
|
||||
AZ::Transform::CreateUniformScale(LinearManipulatorZAxisMovement);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
All,
|
||||
EditorTransformComponentSelectionScaleManipulatorMultipleEntityTestFixtureParam,
|
||||
testing::Values(
|
||||
// this replicates scaling a group of entities in local space with no modifiers held
|
||||
// entities scale relative to manipulator pivot
|
||||
ManipulatorOptionsMultiple{ AzToolsFramework::ViewportInteraction::KeyboardModifier::None,
|
||||
AZ::Transform::CreateTranslation(AggregateManipulatorPositionWithEntity2and3Selected),
|
||||
ExpectedEntity2TransformAfterLocalGroupScaleManipulatorMotion,
|
||||
ExpectedEntity3TransformAfterLocalGroupScaleManipulatorMotion },
|
||||
// this replicates scaling a group of entities in local space with the alt modifier held
|
||||
// entities scale about their own pivot
|
||||
ManipulatorOptionsMultiple{ AzToolsFramework::ViewportInteraction::KeyboardModifier::Alt,
|
||||
AZ::Transform::CreateTranslation(AggregateManipulatorPositionWithEntity2and3Selected),
|
||||
ExpectedEntity2TransformAfterLocalIndividualScaleManipulatorMotion,
|
||||
ExpectedEntity3TransformAfterLocalIndividualScaleManipulatorMotion },
|
||||
// this replicates scaling a group of entities in world space with the shift modifier held
|
||||
// entities scale relative to manipulator pivot in world space
|
||||
ManipulatorOptionsMultiple{ AzToolsFramework::ViewportInteraction::KeyboardModifier::Shift,
|
||||
AZ::Transform::CreateTranslation(AggregateManipulatorPositionWithEntity2and3Selected),
|
||||
ExpectedEntity2TransformAfterLocalGroupScaleManipulatorMotion,
|
||||
ExpectedEntity3TransformAfterLocalGroupScaleManipulatorMotion },
|
||||
// this has no effect (entities and manipulator are unchanged)
|
||||
ManipulatorOptionsMultiple{
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifier::Ctrl,
|
||||
AZ::Transform::CreateTranslation(AggregateManipulatorPositionWithEntity2and3Selected),
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity2WorldTranslation),
|
||||
AZ::Transform::CreateTranslation(EditorTransformComponentSelectionViewportPickingFixture::Entity3WorldTranslation) }));
|
||||
|
||||
using EditorTransformComponentSelectionManipulatorTestFixture =
|
||||
IndirectCallManipulatorViewportInteractionFixtureMixin<EditorTransformComponentSelectionFixture>;
|
||||
|
||||
@@ -1661,7 +2211,7 @@ namespace UnitTest
|
||||
All,
|
||||
EditorTransformComponentSelectionSingleEntityPivotAndOverrideFixture,
|
||||
testing::Values(
|
||||
ReferenceFrameWithOrientation{ AzToolsFramework::ReferenceFrame::Local, ChildExpectedPivotLocalOrientationInWorldSpace },
|
||||
ReferenceFrameWithOrientation{ AzToolsFramework::ReferenceFrame::Local, PivotOverrideLocalOrientationInWorldSpace },
|
||||
ReferenceFrameWithOrientation{ AzToolsFramework::ReferenceFrame::Parent, PivotOverrideLocalOrientationInWorldSpace },
|
||||
ReferenceFrameWithOrientation{ AzToolsFramework::ReferenceFrame::World, AZ::Quaternion::CreateIdentity() }));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user