|
|
|
|
@ -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() }));
|
|
|
|
|
|
|
|
|
|
|