EditorCapsuleShapeComponentTests.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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 <AzToolsFramework/Viewport/ViewportSettings.h>
  9. #include <EditorShapeTestUtils.h>
  10. #include <LmbrCentralReflectionTest.h>
  11. #include <Shape/EditorCapsuleShapeComponent.h>
  12. #include <Shape/EditorSphereShapeComponent.h>
  13. namespace LmbrCentral
  14. {
  15. // Serialized legacy EditorCapsuleShapeComponent v1.
  16. const char kEditorCapsuleComponentVersion1[] =
  17. R"DELIMITER(<ObjectStream version="1">
  18. <Class name="EditorCapsuleShapeComponent" field="element" version="1" type="{06B6C9BE-3648-4DA2-9892-755636EF6E19}">
  19. <Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
  20. <Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
  21. <Class name="AZ::u64" field="Id" value="10467239283436660413" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
  22. </Class>
  23. </Class>
  24. <Class name="CapsuleShapeConfig" field="Configuration" version="1" type="{00931AEB-2AD8-42CE-B1DC-FA4332F51501}">
  25. <Class name="float" field="Height" value="0.5700000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  26. <Class name="float" field="Radius" value="1.5700000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  27. </Class>
  28. </Class>
  29. </ObjectStream>)DELIMITER";
  30. class LoadEditorCapsuleShapeComponentFromVersion1
  31. : public LoadEditorComponentTest<EditorCapsuleShapeComponent>
  32. {
  33. protected:
  34. const char* GetSourceDataBuffer() const override { return kEditorCapsuleComponentVersion1; }
  35. };
  36. TEST_F(LoadEditorCapsuleShapeComponentFromVersion1, Application_IsRunning)
  37. {
  38. ASSERT_NE(GetApplication(), nullptr);
  39. }
  40. TEST_F(LoadEditorCapsuleShapeComponentFromVersion1, Components_Load)
  41. {
  42. EXPECT_NE(m_object.get(), nullptr);
  43. }
  44. TEST_F(LoadEditorCapsuleShapeComponentFromVersion1, EditorComponent_Found)
  45. {
  46. EXPECT_EQ(m_entity->GetComponents().size(), 2);
  47. EXPECT_NE(m_entity->FindComponent(m_object->GetId()), nullptr);
  48. }
  49. TEST_F(LoadEditorCapsuleShapeComponentFromVersion1, Height_MatchesSourceData)
  50. {
  51. float height = 0.0f;
  52. CapsuleShapeComponentRequestsBus::EventResult(
  53. height, m_entity->GetId(), &CapsuleShapeComponentRequests::GetHeight);
  54. EXPECT_FLOAT_EQ(height, 0.57f);
  55. }
  56. TEST_F(LoadEditorCapsuleShapeComponentFromVersion1, Radius_MatchesSourceData)
  57. {
  58. float radius = 0.0f;
  59. CapsuleShapeComponentRequestsBus::EventResult(
  60. radius, m_entity->GetId(), &CapsuleShapeComponentRequests::GetRadius);
  61. EXPECT_FLOAT_EQ(radius, 1.57f);
  62. }
  63. class EditorCapsuleShapeComponentFixture
  64. : public UnitTest::ToolsApplicationFixture<>
  65. {
  66. public:
  67. void SetUpEditorFixtureImpl() override;
  68. void TearDownEditorFixtureImpl() override;
  69. AZStd::unique_ptr<AZ::ComponentDescriptor> m_editorCapsuleShapeComponentDescriptor;
  70. AZStd::unique_ptr<AZ::ComponentDescriptor> m_editorSphereShapeComponentDescriptor;
  71. AZ::Entity* m_entity = nullptr;
  72. AZ::EntityId m_entityId;
  73. AZ::EntityComponentIdPair m_entityComponentIdPair;
  74. };
  75. void EditorCapsuleShapeComponentFixture::SetUpEditorFixtureImpl()
  76. {
  77. AZ::SerializeContext* serializeContext = nullptr;
  78. AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
  79. // need to reflect EditorSphereShapeComponent in order for EditorBaseShapeComponent to be reflected
  80. m_editorSphereShapeComponentDescriptor = AZStd::unique_ptr<AZ::ComponentDescriptor>(EditorSphereShapeComponent::CreateDescriptor());
  81. m_editorCapsuleShapeComponentDescriptor =
  82. AZStd::unique_ptr<AZ::ComponentDescriptor>(EditorCapsuleShapeComponent::CreateDescriptor());
  83. ShapeComponentConfig::Reflect(serializeContext);
  84. CapsuleShape::Reflect(serializeContext);
  85. m_editorSphereShapeComponentDescriptor->Reflect(serializeContext);
  86. m_editorCapsuleShapeComponentDescriptor->Reflect(serializeContext);
  87. UnitTest::CreateDefaultEditorEntity("CapsuleShapeComponentEntity", &m_entity);
  88. m_entityId = m_entity->GetId();
  89. m_entity->Deactivate();
  90. m_entityComponentIdPair =
  91. AZ::EntityComponentIdPair(m_entityId, m_entity->CreateComponent(EditorCapsuleShapeComponentTypeId)->GetId());
  92. m_entity->Activate();
  93. }
  94. void EditorCapsuleShapeComponentFixture::TearDownEditorFixtureImpl()
  95. {
  96. AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
  97. &AzToolsFramework::EditorEntityContextRequestBus::Events::DestroyEditorEntity, m_entityId);
  98. m_entity = nullptr;
  99. m_entityId.SetInvalid();
  100. m_editorCapsuleShapeComponentDescriptor.reset();
  101. m_editorSphereShapeComponentDescriptor.reset();
  102. }
  103. using EditorCapsuleShapeComponentManipulatorFixture =
  104. UnitTest::IndirectCallManipulatorViewportInteractionFixtureMixin<EditorCapsuleShapeComponentFixture>;
  105. void SetUpCapsuleShapeComponent(
  106. AZ::EntityId entityId,
  107. const AZ::Transform& transform,
  108. const AZ::Vector3& translationOffset,
  109. float radius,
  110. float height)
  111. {
  112. AZ::TransformBus::Event(entityId, &AZ::TransformBus::Events::SetWorldTM, transform);
  113. ShapeComponentRequestsBus::Event(entityId, &ShapeComponentRequests::SetTranslationOffset, translationOffset);
  114. CapsuleShapeComponentRequestsBus::Event(entityId, &CapsuleShapeComponentRequests::SetRadius, radius);
  115. CapsuleShapeComponentRequestsBus::Event(entityId, &CapsuleShapeComponentRequests::SetHeight, height);
  116. }
  117. TEST_F(EditorCapsuleShapeComponentManipulatorFixture, CapsuleShapeSymmetricalHeightManipulatorsScaleCorrectly)
  118. {
  119. AZ::Transform capsuleTransform(AZ::Vector3(6.0f, -3.0f, 4.0f), AZ::Quaternion(0.3f, 0.1f, -0.3f, 0.9f), 2.0f);
  120. const float radius = 0.5f;
  121. const float height = 2.0f;
  122. const AZ::Vector3 translationOffset(-5.0f, 3.0f, -2.0f);
  123. SetUpCapsuleShapeComponent(m_entity->GetId(), capsuleTransform, translationOffset, radius, height);
  124. EnterComponentMode(m_entityId, EditorCapsuleShapeComponentTypeId);
  125. // position the camera so it is looking at the capsule
  126. AzFramework::SetCameraTransform(m_cameraState, AZ::Transform::CreateTranslation(AZ::Vector3(0.0f, -5.0f, 10.0f)));
  127. const AZ::Vector3 worldStart(1.6f, 6.84f, 8.88f);
  128. const AZ::Vector3 worldEnd(1.6f, 6.6f, 9.2f);
  129. DragMouse(m_cameraState, m_actionDispatcher.get(), worldStart, worldEnd, AzToolsFramework::DefaultSymmetricalEditingModifier);
  130. ExpectCapsuleHeight(m_entity->GetId(), 2.4f);
  131. }
  132. TEST_F(EditorCapsuleShapeComponentManipulatorFixture, CapsuleShapeAsymmetricalHeightManipulatorsScaleCorrectly)
  133. {
  134. AZ::Transform capsuleTransform(AZ::Vector3(2.0f, -6.0f, 5.0f), AZ::Quaternion(0.7f, -0.1f, -0.1f, 0.7f), 0.5f);
  135. const float radius = 2.0f;
  136. const float height = 7.0f;
  137. const AZ::Vector3 translationOffset(2.0f, 5.0f, -3.0f);
  138. SetUpCapsuleShapeComponent(m_entity->GetId(), capsuleTransform, translationOffset, radius, height);
  139. EnterComponentMode(m_entityId, EditorCapsuleShapeComponentTypeId);
  140. // position the camera so it is looking at the capsule
  141. AzFramework::SetCameraTransform(m_cameraState, AZ::Transform::CreateTranslation(AZ::Vector3(5.0f, -10.0f, 7.5f)));
  142. const AZ::Vector3 worldStart(3.87f, -3.16f, 7.5f);
  143. const AZ::Vector3 worldEnd(3.73f, -3.64f, 7.5f);
  144. DragMouse(m_cameraState, m_actionDispatcher.get(), worldStart, worldEnd);
  145. ExpectCapsuleHeight(m_entity->GetId(), 6.0f);
  146. }
  147. TEST_F(EditorCapsuleShapeComponentManipulatorFixture, CapsuleShapeRadiusManipulatorScalesCorrectly)
  148. {
  149. AZ::Transform capsuleTransform(AZ::Vector3(-4.0f, -5.0f, 1.0f), AZ::Quaternion::CreateIdentity(), 2.5f);
  150. const float radius = 1.0f;
  151. const float height = 5.0f;
  152. const AZ::Vector3 translationOffset(6.0f, 3.0f, -2.0f);
  153. SetUpCapsuleShapeComponent(m_entity->GetId(), capsuleTransform, translationOffset, radius, height);
  154. EnterComponentMode(m_entityId, EditorCapsuleShapeComponentTypeId);
  155. // position the camera so it is looking at the capsule
  156. AzFramework::SetCameraTransform(m_cameraState, AZ::Transform::CreateTranslation(AZ::Vector3(15.0f, -5.0f, -5.0f)));
  157. const AZ::Vector3 worldStart(13.5f, 2.5f, -4.0f);
  158. const AZ::Vector3 worldEnd(14.75f, 2.5f, -4.0f);
  159. DragMouse(m_cameraState, m_actionDispatcher.get(), worldStart, worldEnd);
  160. ExpectCapsuleRadius(m_entity->GetId(), 1.5f);
  161. }
  162. }