EditorPolygonPrismShapeComponentTests.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "LmbrCentralReflectionTest.h"
  9. #include "Shape/EditorPolygonPrismShapeComponent.h"
  10. #include "Shape/EditorSphereShapeComponent.h"
  11. #include <AZTestShared/Math/MathTestHelpers.h>
  12. #include <AzCore/Component/NonUniformScaleBus.h>
  13. #include <AzFramework/Viewport/ViewportScreen.h>
  14. #include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
  15. #include <AzManipulatorTestFramework/AzManipulatorTestFrameworkTestHelpers.h>
  16. #include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
  17. #include <AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h>
  18. #include <AzManipulatorTestFramework/ViewportInteraction.h>
  19. #include <AzToolsFramework/Entity/EditorEntityHelpers.h>
  20. #include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
  21. #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
  22. namespace LmbrCentral
  23. {
  24. // Serialized legacy EditorPolygonPrismShapeComponent v1.
  25. const char kEditorPolygonPrismComponentVersion1[] =
  26. R"DELIMITER(<ObjectStream version="1">
  27. <Class name="EditorPolygonPrismShapeComponent" field="element" version="1" type="{5368F204-FE6D-45C0-9A4F-0F933D90A785}">
  28. <Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
  29. <Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
  30. <Class name="AZ::u64" field="Id" value="2508877310741125152" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
  31. </Class>
  32. </Class>
  33. <Class name="PolygonPrismCommon" field="Configuration" version="1" type="{BDB453DE-8A51-42D0-9237-13A9193BE724}">
  34. <Class name="AZStd::shared_ptr" field="PolygonPrism" type="{2E879A16-9143-5862-A5B3-EDED931C60BC}">
  35. <Class name="PolygonPrism" field="element" version="1" type="{F01C8BDD-6F24-4344-8945-521A8750B30B}">
  36. <Class name="float" field="Height" value="1.5700000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  37. <Class name="VertexContainer&lt;Vector2 &gt;" field="VertexContainer" type="{EBE98B36-0783-5226-9739-064BD41EBB52}">
  38. <Class name="AZStd::vector" field="Vertices" type="{82AC1A71-2EA7-5FBC-9B3B-72B1CCFDD292}">
  39. <Class name="Vector2" field="element" value="-0.5700000 -0.5700000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
  40. <Class name="Vector2" field="element" value="0.5700000 -0.5700000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
  41. <Class name="Vector2" field="element" value="0.5700000 0.5700000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
  42. <Class name="Vector2" field="element" value="-0.5700000 0.5700000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
  43. </Class>
  44. </Class>
  45. </Class>
  46. </Class>
  47. </Class>
  48. </Class>
  49. </ObjectStream>)DELIMITER";
  50. class LoadEditorPolygonPrismShapeComponentFromVersion1 : public LoadEditorComponentTest<EditorPolygonPrismShapeComponent>
  51. {
  52. protected:
  53. const char* GetSourceDataBuffer() const override
  54. {
  55. return kEditorPolygonPrismComponentVersion1;
  56. }
  57. };
  58. TEST_F(LoadEditorPolygonPrismShapeComponentFromVersion1, Application_IsRunning)
  59. {
  60. ASSERT_NE(GetApplication(), nullptr);
  61. }
  62. TEST_F(LoadEditorPolygonPrismShapeComponentFromVersion1, Components_Load)
  63. {
  64. EXPECT_NE(m_object.get(), nullptr);
  65. }
  66. TEST_F(LoadEditorPolygonPrismShapeComponentFromVersion1, EditorComponent_Found)
  67. {
  68. EXPECT_EQ(m_entity->GetComponents().size(), 2);
  69. EXPECT_NE(m_entity->FindComponent(m_object->GetId()), nullptr);
  70. }
  71. TEST_F(LoadEditorPolygonPrismShapeComponentFromVersion1, Height_MatchesSourceData)
  72. {
  73. AZ::ConstPolygonPrismPtr polygonPrism;
  74. PolygonPrismShapeComponentRequestBus::EventResult(
  75. polygonPrism, m_entity->GetId(), &PolygonPrismShapeComponentRequestBus::Events::GetPolygonPrism);
  76. EXPECT_FLOAT_EQ(polygonPrism->GetHeight(), 1.57f);
  77. }
  78. TEST_F(LoadEditorPolygonPrismShapeComponentFromVersion1, Vertices_MatchesSourceData)
  79. {
  80. AZ::ConstPolygonPrismPtr polygonPrism;
  81. PolygonPrismShapeComponentRequestBus::EventResult(
  82. polygonPrism, m_entity->GetId(), &PolygonPrismShapeComponentRequestBus::Events::GetPolygonPrism);
  83. AZStd::vector<AZ::Vector2> sourceVertices = { AZ::Vector2(-0.57f, -0.57f), AZ::Vector2(0.57f, -0.57f), AZ::Vector2(0.57f, 0.57f),
  84. AZ::Vector2(-0.57f, 0.57f) };
  85. EXPECT_EQ(polygonPrism->m_vertexContainer.GetVertices(), sourceVertices);
  86. }
  87. class EditorPolygonPrismShapeComponentFixture : public UnitTest::ToolsApplicationFixture<>
  88. {
  89. public:
  90. void SetUpEditorFixtureImpl() override;
  91. void TearDownEditorFixtureImpl() override;
  92. AZStd::unique_ptr<AZ::ComponentDescriptor> m_editorPolygonPrismShapeComponentDescriptor;
  93. AZStd::unique_ptr<AZ::ComponentDescriptor> m_editorSphereShapeComponentDescriptor;
  94. AZ::Entity* m_entity = nullptr;
  95. };
  96. void EditorPolygonPrismShapeComponentFixture::SetUpEditorFixtureImpl()
  97. {
  98. AZ::SerializeContext* serializeContext = nullptr;
  99. AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
  100. // need to reflect EditorSphereShapeComponent in order for EditorBaseShapeComponent to be reflected
  101. m_editorSphereShapeComponentDescriptor = AZStd::unique_ptr<AZ::ComponentDescriptor>(EditorSphereShapeComponent::CreateDescriptor());
  102. m_editorPolygonPrismShapeComponentDescriptor =
  103. AZStd::unique_ptr<AZ::ComponentDescriptor>(EditorPolygonPrismShapeComponent::CreateDescriptor());
  104. ShapeComponentConfig::Reflect(serializeContext);
  105. PolygonPrismShape::Reflect(serializeContext);
  106. m_editorSphereShapeComponentDescriptor->Reflect(serializeContext);
  107. m_editorPolygonPrismShapeComponentDescriptor->Reflect(serializeContext);
  108. UnitTest::CreateDefaultEditorEntity("PolygonPrismShapeComponentEntity", &m_entity);
  109. m_entity->Deactivate();
  110. m_entity->CreateComponent(AzToolsFramework::Components::EditorNonUniformScaleComponent::RTTI_Type());
  111. m_entity->CreateComponent(EditorPolygonPrismShapeComponentTypeId);
  112. m_entity->Activate();
  113. }
  114. void EditorPolygonPrismShapeComponentFixture::TearDownEditorFixtureImpl()
  115. {
  116. AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
  117. &AzToolsFramework::EditorEntityContextRequestBus::Events::DestroyEditorEntity, m_entity->GetId());
  118. m_entity = nullptr;
  119. m_editorPolygonPrismShapeComponentDescriptor.reset();
  120. m_editorSphereShapeComponentDescriptor.reset();
  121. }
  122. using EditorPolygonPrismShapeComponentManipulatorFixture =
  123. UnitTest::IndirectCallManipulatorViewportInteractionFixtureMixin<EditorPolygonPrismShapeComponentFixture>;
  124. TEST_F(EditorPolygonPrismShapeComponentManipulatorFixture, PolygonPrismNonUniformScaleManipulatorsScaleCorrectly)
  125. {
  126. // set the non-uniform scale and enter the polygon prism shape component's component mode
  127. const AZ::Vector3 nonUniformScale(2.0f, 3.0f, 4.0f);
  128. AZ::NonUniformScaleRequestBus::Event(m_entity->GetId(), &AZ::NonUniformScaleRequests::SetScale, nonUniformScale);
  129. AzToolsFramework::SelectEntity(m_entity->GetId());
  130. AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
  131. &AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Events::AddSelectedComponentModesOfType,
  132. EditorPolygonPrismShapeComponentTypeId);
  133. // position the camera so it is looking down at the polygon prism
  134. AzFramework::SetCameraTransform(
  135. m_cameraState,
  136. AZ::Transform::CreateFromQuaternionAndTranslation(
  137. AZ::Quaternion::CreateRotationX(-AZ::Constants::HalfPi), AZ::Vector3(0.0f, 0.0f, 20.0f)));
  138. // the first vertex of the polygon prism should be at (-2, -2, 0) in its local space
  139. // because of the non-uniform scale, that should be (-4, -6, 0) in world space
  140. const AZ::Vector3 worldStart(-4.0f, -6.0f, 0.0f);
  141. // position in world space to drag the vertex to
  142. const AZ::Vector3 worldEnd(-8.0f, -9.0f, 0.0f);
  143. const auto screenStart = AzFramework::WorldToScreen(worldStart, m_cameraState);
  144. const auto screenEnd = AzFramework::WorldToScreen(worldEnd, m_cameraState);
  145. // diagonal offset to ensure we interact with the planar manipulator and not one of the linear manipulators
  146. const AzFramework::ScreenVector offset(50, -50);
  147. m_actionDispatcher
  148. ->CameraState(m_cameraState)
  149. // move the mouse to the first vertex of the polygon prism
  150. ->MousePosition(screenStart)
  151. // click to activate the manipulator
  152. ->MouseLButtonDown()
  153. ->MouseLButtonUp()
  154. // offset the mouse position slightly to ensure we get the planar manipulator and not one of the linear manipulators
  155. ->MousePosition(screenStart + offset)
  156. // drag to move the manipulator
  157. ->MouseLButtonDown()
  158. ->MousePosition(screenEnd + offset)
  159. ->MouseLButtonUp();
  160. AZ::PolygonPrismPtr polygonPrism = nullptr;
  161. PolygonPrismShapeComponentRequestBus::EventResult(
  162. polygonPrism, m_entity->GetId(), &PolygonPrismShapeComponentRequests::GetPolygonPrism);
  163. AZ::Vector2 vertex;
  164. polygonPrism->m_vertexContainer.GetVertex(0, vertex);
  165. // dragging the vertex to (-8, -9, 0) in world space should move its local translation to (-4, -3, 0)
  166. AZ::Vector2 expectedVertex(-4.0f, -3.0f);
  167. EXPECT_THAT(vertex, UnitTest::IsCloseTolerance(expectedVertex, 1e-2f));
  168. // now check the manipulator is still in the correct position relative to the vertex
  169. // by starting a drag from the new vertex world position
  170. m_actionDispatcher->CameraState(m_cameraState)
  171. ->MousePosition(screenEnd + offset)
  172. ->MouseLButtonDown()
  173. ->MousePosition(screenStart + offset)
  174. ->MouseLButtonUp();
  175. polygonPrism->m_vertexContainer.GetVertex(0, vertex);
  176. expectedVertex = AZ::Vector2(-2.0f, -2.0f);
  177. EXPECT_THAT(vertex, UnitTest::IsCloseTolerance(expectedVertex, 1e-2f));
  178. }
  179. } // namespace LmbrCentral