From 48b2c2a4f2cb9cbd86b31e674a7a19fab6f9a23d Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Mon, 11 Oct 2021 16:52:43 +0100 Subject: [PATCH 01/11] Surface Materials list unit tests Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com> --- .../Code/Tests/SurfaceMaterialsListTest.cpp | 73 +++++++++++++++++++ Gems/Terrain/Code/terrain_tests_files.cmake | 1 + 2 files changed, 74 insertions(+) create mode 100644 Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp diff --git a/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp b/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp new file mode 100644 index 0000000000..fb70b1366f --- /dev/null +++ b/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include + +using ::testing::NiceMock; +using ::testing::AtLeast; +using ::testing::_; + +namespace UnitTest +{ + class TerrainSurfaceMaterialsListTest : public ::testing::Test + { + protected: + AZ::ComponentApplication m_app; + + void SetUp() override + { + AZ::ComponentApplication::Descriptor appDesc; + appDesc.m_memoryBlocksByteSize = 20 * 1024 * 1024; + appDesc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_NO_RECORDS; + appDesc.m_stackRecordLevels = 20; + + m_app.Create(appDesc); + } + + AZStd::unique_ptr CreateEntityWithShapeComponents() + { + auto entity = AZStd::make_unique(); + entity->Init(); + + auto shapeComponent = entity->CreateComponent(); + m_app.RegisterComponentDescriptor(shapeComponent->CreateDescriptor()); + + return entity; + } + + Terrain::TerrainSurfaceMaterialsListComponent* AddSurfaceMaterialListComponent(AZ::Entity* entity) + { + auto surfaceMaterialsListComponent = entity->CreateComponent(); + m_app.RegisterComponentDescriptor(surfaceMaterialsListComponent->CreateDescriptor()); + + return surfaceMaterialsListComponent; + } + + void TearDown() override + { + m_app.Destroy(); + } + }; + + TEST_F(TerrainSurfaceMaterialsListTest, SurfaceGradientListActivatesSuccessfully) + { + auto entity = CreateEntityWithShapeComponents(); + + AddSurfaceMaterialListComponent(entity.get()); + + entity->Activate(); + + EXPECT_EQ(entity->GetState(), AZ::Entity::State::Active); + + entity.reset(); + } +} // namespace UnitTest diff --git a/Gems/Terrain/Code/terrain_tests_files.cmake b/Gems/Terrain/Code/terrain_tests_files.cmake index 3ce1d05003..793bc01ac5 100644 --- a/Gems/Terrain/Code/terrain_tests_files.cmake +++ b/Gems/Terrain/Code/terrain_tests_files.cmake @@ -10,5 +10,6 @@ set(FILES Tests/TerrainTest.cpp Tests/TerrainSystemTest.cpp Tests/LayerSpawnerTests.cpp + Tests/SurfaceMaterialsListTest.cpp Tests/MockAxisAlignedBoxShapeComponent.h ) From 68fe604dde986d31c0455813e1e12ca193d13026 Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Mon, 11 Oct 2021 17:18:41 +0100 Subject: [PATCH 02/11] Missing shape test Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com> --- .../Code/Tests/SurfaceMaterialsListTest.cpp | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp b/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp index fb70b1366f..cc1af8bf62 100644 --- a/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp +++ b/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp @@ -33,10 +33,16 @@ namespace UnitTest m_app.Create(appDesc); } - AZStd::unique_ptr CreateEntityWithShapeComponents() + AZStd::unique_ptr CreateEntity() { auto entity = AZStd::make_unique(); entity->Init(); + return entity; + } + + AZStd::unique_ptr CreateEntityWithShapeComponents() + { + auto entity = CreateEntity(); auto shapeComponent = entity->CreateComponent(); m_app.RegisterComponentDescriptor(shapeComponent->CreateDescriptor()); @@ -58,6 +64,19 @@ namespace UnitTest } }; + TEST_F(TerrainSurfaceMaterialsListTest, SurfaceGradientListRequiresShapeToActivate) + { + auto entity = CreateEntity(); + + AddSurfaceMaterialListComponent(entity.get()); + + entity->Activate(); + + EXPECT_EQ(entity->GetState(), AZ::Entity::State::Active); + + entity.reset(); + } + TEST_F(TerrainSurfaceMaterialsListTest, SurfaceGradientListActivatesSuccessfully) { auto entity = CreateEntityWithShapeComponents(); From a849008a4857d50ed109d03ad8c087889f44d401 Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Tue, 12 Oct 2021 09:33:36 +0100 Subject: [PATCH 03/11] compile fix and add activation failure test. Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com> --- Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp b/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp index cc1af8bf62..c2c24e300f 100644 --- a/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp +++ b/Gems/Terrain/Code/Tests/SurfaceMaterialsListTest.cpp @@ -10,7 +10,6 @@ #include #include #include -#include using ::testing::NiceMock; using ::testing::AtLeast; @@ -66,14 +65,16 @@ namespace UnitTest TEST_F(TerrainSurfaceMaterialsListTest, SurfaceGradientListRequiresShapeToActivate) { + // Check that the component requires a shape service to activate: trying to Activate the entity will cause the test to fail, so + // use the EvaluateDependenciesGetDetails function to check the dependencies are met. + auto entity = CreateEntity(); AddSurfaceMaterialListComponent(entity.get()); - entity->Activate(); - - EXPECT_EQ(entity->GetState(), AZ::Entity::State::Active); - + const AZ::Entity::DependencySortOutcome sortOutcome = entity->EvaluateDependenciesGetDetails(); + EXPECT_FALSE(sortOutcome.IsSuccess()); + entity.reset(); } From 161600a4123cd9ca4a1e52ddfa5704358f07817f Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Wed, 10 Nov 2021 16:24:55 -0800 Subject: [PATCH 04/11] Removing old cry code that would load client.cfg for server launcher. Client.cfg should not be loaded by default. If you want to load a cfg then you should provide it via commandline (--console-command-file). Signed-off-by: Gene Walters --- Code/Legacy/CrySystem/SystemInit.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Code/Legacy/CrySystem/SystemInit.cpp b/Code/Legacy/CrySystem/SystemInit.cpp index d9ba3bb4c9..eaebfbb956 100644 --- a/Code/Legacy/CrySystem/SystemInit.cpp +++ b/Code/Legacy/CrySystem/SystemInit.cpp @@ -1186,12 +1186,6 @@ AZ_POP_DISABLE_WARNING InlineInitializationProcessing("CSystem::Init End"); - if (gEnv->IsDedicated()) - { - SCVarsClientConfigSink CVarsClientConfigSink; - LoadConfiguration("client.cfg", &CVarsClientConfigSink); - } - // Send out EBus event EBUS_EVENT(CrySystemEventBus, OnCrySystemInitialized, *this, startupParams); From 2ced6011e907a42549b16b52c952582fcbf58f63 Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 29 Oct 2021 16:35:47 +0100 Subject: [PATCH 05/11] add python test for smoothness of interpolated rigid body motion Signed-off-by: greerdv --- .../Gem/PythonTests/Physics/TestSuite_Main.py | 6 ++ ...ick_InterpolatedRigidBodyMotionIsSmooth.py | 98 +++++++++++++++++++ pytest.ini | 1 + 3 files changed, 105 insertions(+) create mode 100644 AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py index b64fbb5656..2dc8e04b1e 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py @@ -91,4 +91,10 @@ class TestAutomation(TestAutomationBase): @revert_physics_config def test_C15425929_Undo_Redo(self, request, workspace, editor, launcher_platform): from .tests import Physics_UndoRedoWorksOnEntityWithPhysComponents as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.tick + @pytest.mark.xfail(reason="Test still under development.") + def test_Tick_InterpolatedRigidBodyMotionIsSmooth(self, request, workspace, editor, launcher_platform): + from .tests.tick import Tick_InterpolatedRigidBodyMotionIsSmooth as test_module self._run_test(request, workspace, editor, test_module) \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py new file mode 100644 index 0000000000..67cbdbd6cb --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py @@ -0,0 +1,98 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT + +Test Case Title : Verify that a rigid body with "Interpolate motion" option selected moves smoothly. +""" + + +# fmt: off +class Tests(): + create_entity = ("Created test entity", "Failed to create test entity") + rigid_body_added = ("Added PhysX Rigid Body component", "Failed to add PhysX Rigid Body component") + rigid_body_smooth = ("Rigid body motion passed smoothness threshold", "Failed to meet smoothness threshold for rigid body motion") +# fmt: on + + +def Tick_InterpolatedRigidBodyMotionIsSmooth(): + """ + Summary: + Create entity with Mesh and PhysX Collider components and assign a fbx file in both the components. + Verify that the fbx is properly fitting the mesh. + + Expected Behavior: + 1) The fbx is properly fitting the mesh. + 2) Multiple material slots show up under Materials section in the PhysX Collider component and that + they correspond to the number of surfaces as designed in the mesh. + + Test Steps: + 1) Load the empty level + 2) Create an entity + 3) Add rigid body component + 4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames + 5) Check if the motion of the rigid body was sufficiently smooth + + :return: None + """ + # imports + import os + import azlmbr.legacy.general as general + import azlmbr.math as math + from editor_python_test_tools.editor_entity_utils import EditorEntity as Entity + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + from editor_python_test_tools.asset_utils import Asset + import numpy as np + + # constants + COEFFICIENT_OF_DETERMINATION_THRESHOLD = 1 - 1e-4 # curves with values below this are not considered sufficiently smooth + + helper.init_idle() + # 1) Load the empty level + helper.open_level("Physics", "Base") + + # 2) Create an entity + test_entity = Entity.create_editor_entity("test_entity") + Report.result(Tests.create_entity, test_entity.id.IsValid()) + + azlmbr.components.TransformBus( + azlmbr.bus.Event, "SetWorldTranslation", test_entity.id, math.Vector3(0.0, 0.0, 0.0)) + + # 3) Add rigid body component + rigid_body_component = test_entity.add_component("PhysX Rigid Body") + rigid_body_component.set_component_property_value("Configuration|Interpolate motion", True) + azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetLinearDamping", test_entity.id, 0.0) + Report.result(Tests.rigid_body_added, test_entity.has_component("PhysX Rigid Body")) + + # 4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames + t = [] + z = [] + general.enter_game_mode() + general.idle_wait_frames(1) + game_entity_id = general.find_game_entity("test_entity") + for timestep in range(100): + t.append(azlmbr.components.TickRequestBus(azlmbr.bus.Broadcast, "GetTimeAtCurrentTick").GetSeconds()) + z.append(azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", game_entity_id)) + general.idle_wait_frames(1) + general.exit_game_mode() + + # 5) Test that the z vs t curve is sufficiently smooth (if the interpolation is not working well, the curve will be less smooth) + # normalize the t and z data + t = np.array(t) - np.mean(t) + z = np.array(z) - np.mean(z) + # fit a polynomial to the z vs t curve + fit = np.poly1d(np.polyfit(t, z, 4)) + residual = fit(t) - z + # calculate the coefficient of determination (a measure of how closely the polynomial curve fits the data) + # if the coefficient is very close to 1, then the curve fits the data very well, suggesting that the rigid body motion is smooth + # if the coefficient is significantly less than 1, then the z values vary more erratically relative to the smooth curve, + # indicating that the motion of the rigid body is not smooth + coefficient_of_determination = (1 - np.sum(residual * residual) / np.sum(z * z)) + Report.result(Tests.rigid_body_smooth, bool(coefficient_of_determination > COEFFICIENT_OF_DETERMINATION_THRESHOLD)) + + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(Tick_InterpolatedRigidBodyMotionIsSmooth) diff --git a/pytest.ini b/pytest.ini index 65c93e0eb2..a863f8ca96 100644 --- a/pytest.ini +++ b/pytest.ini @@ -22,4 +22,5 @@ markers = SUITE_smoke: Tiny, quick tests of fundamental operation (tests with no SUITE_awsi: Time consuming AWS integration end-to-end tests # secondary markers which may appear alongisde a suite marker: REQUIRES_gpu: Tests which require a physical GPU + tick: Tests which verify if systems update correctly with system ticks (for example, physics bodies should move smoothly) # custom markers not listed above will cause pytest to emit a typo warning From 128b3d7ec0e1c87553b21665e485736a00d51809 Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 29 Oct 2021 16:55:41 +0100 Subject: [PATCH 06/11] fix copy paste error in test description Signed-off-by: greerdv --- .../tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py index 67cbdbd6cb..c7cc3725c7 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py @@ -19,13 +19,11 @@ class Tests(): def Tick_InterpolatedRigidBodyMotionIsSmooth(): """ Summary: - Create entity with Mesh and PhysX Collider components and assign a fbx file in both the components. - Verify that the fbx is properly fitting the mesh. + Create entity with PhysX Rigid Body component and turn on the Interpolate motion setting. + Verify that the position of the rigid body varies smoothly with time. Expected Behavior: - 1) The fbx is properly fitting the mesh. - 2) Multiple material slots show up under Materials section in the PhysX Collider component and that - they correspond to the number of surfaces as designed in the mesh. + 1) The motion of the rigid body under the gravity is a smooth curve, rather than an erratic/jittery movement. Test Steps: 1) Load the empty level From 06ef0372781093dc5e8eb57e90d41237ddb4a1ca Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 29 Oct 2021 16:57:42 +0100 Subject: [PATCH 07/11] fix typo Signed-off-by: greerdv --- .../tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py index c7cc3725c7..1b9310910d 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py @@ -23,7 +23,7 @@ def Tick_InterpolatedRigidBodyMotionIsSmooth(): Verify that the position of the rigid body varies smoothly with time. Expected Behavior: - 1) The motion of the rigid body under the gravity is a smooth curve, rather than an erratic/jittery movement. + 1) The motion of the rigid body under gravity is a smooth curve, rather than an erratic/jittery movement. Test Steps: 1) Load the empty level From 53c6a22ac2cc618aa57d417d7aac4c05737568c0 Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 29 Oct 2021 17:21:21 +0100 Subject: [PATCH 08/11] add python test for smoothness of character gameplay component motion Signed-off-by: greerdv --- .../Gem/PythonTests/Physics/TestSuite_Main.py | 8 +- ...haracterGameplayComponentMotionIsSmooth.py | 97 +++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py index 2dc8e04b1e..3ef593612b 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py @@ -97,4 +97,10 @@ class TestAutomation(TestAutomationBase): @pytest.mark.xfail(reason="Test still under development.") def test_Tick_InterpolatedRigidBodyMotionIsSmooth(self, request, workspace, editor, launcher_platform): from .tests.tick import Tick_InterpolatedRigidBodyMotionIsSmooth as test_module - self._run_test(request, workspace, editor, test_module) \ No newline at end of file + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.tick + @pytest.mark.xfail(reason="Test still under development.") + def test_Tick_Tick_CharacterGameplayComponentMotionIsSmooth(self, request, workspace, editor, launcher_platform): + from .tests.tick import Tick_CharacterGameplayComponentMotionIsSmooth as test_module + self._run_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py new file mode 100644 index 0000000000..6425ece640 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py @@ -0,0 +1,97 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT + +Test Case Title : Verify that an entity with a character gameplay component moves smoothly. +""" + + +# fmt: off +class Tests(): + create_entity = ("Created test entity", "Failed to create test entity") + character_controller_added = ("Added PhysX Character Controller component", "Failed to add PhysX Character Controller component") + character_gameplay_added = ("Added PhysX Character Gameplay component", "Failed to add PhysX Character Gameplay component") + character_motion_smooth = ("Character motion passed smoothness threshold", "Failed to meet smoothness threshold for character motion") +# fmt: on + + +def Tick_CharacterGameplayComponentMotionIsSmooth(): + """ + Summary: + Create entity with PhysX Character Controller and PhysX Character Gameplay components. + Verify that the motion of the character controller under gravity is smooth. + + Expected Behavior: + 1) The motion of the character controller under gravity is a smooth curve, rather than an erratic/jittery movement. + + Test Steps: + 1) Load the empty level + 2) Create an entity + 3) Add a PhysX Character Controller Component and PhysX Character Gameplay component + 4) Enter game mode and collect data for the character controller's z co-ordinate and the time values for a series of frames + 5) Check if the motion of the character controller was sufficiently smooth + + :return: None + """ + # imports + import os + import azlmbr.legacy.general as general + import azlmbr.math as math + from editor_python_test_tools.editor_entity_utils import EditorEntity as Entity + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + from editor_python_test_tools.asset_utils import Asset + import numpy as np + + # constants + COEFFICIENT_OF_DETERMINATION_THRESHOLD = 1 - 1e-4 # curves with values below this are not considered sufficiently smooth + + helper.init_idle() + # 1) Load the empty level + helper.open_level("Physics", "Base") + + # 2) Create an entity + test_entity = Entity.create_editor_entity("test_entity") + Report.result(Tests.create_entity, test_entity.id.IsValid()) + + azlmbr.components.TransformBus( + azlmbr.bus.Event, "SetWorldTranslation", test_entity.id, math.Vector3(0.0, 0.0, 0.0)) + + # 3) Add character controller and character gameplay components + character_controller_component = test_entity.add_component("PhysX Character Controller") + Report.result(Tests.character_controller_added, test_entity.has_component("PhysX Character Controller")) + character_gameplay_component = test_entity.add_component("PhysX Character Gameplay") + Report.result(Tests.character_gameplay_added, test_entity.has_component("PhysX Character Gameplay")) + + # 4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames + t = [] + z = [] + general.enter_game_mode() + general.idle_wait_frames(1) + game_entity_id = general.find_game_entity("test_entity") + for timestep in range(100): + t.append(azlmbr.components.TickRequestBus(azlmbr.bus.Broadcast, "GetTimeAtCurrentTick").GetSeconds()) + z.append(azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", game_entity_id)) + general.idle_wait_frames(1) + general.exit_game_mode() + + # 5) Test that the z vs t curve is sufficiently smooth (if the interpolation is not working well, the curve will be less smooth) + # normalize the t and z data + t = np.array(t) - np.mean(t) + z = np.array(z) - np.mean(z) + # fit a polynomial to the z vs t curve + fit = np.poly1d(np.polyfit(t, z, 4)) + residual = fit(t) - z + # calculate the coefficient of determination (a measure of how closely the polynomial curve fits the data) + # if the coefficient is very close to 1, then the curve fits the data very well, suggesting that the rigid body motion is smooth + # if the coefficient is significantly less than 1, then the z values vary more erratically relative to the smooth curve, + # indicating that the motion of the rigid body is not smooth + coefficient_of_determination = (1 - np.sum(residual * residual) / np.sum(z * z)) + Report.result(Tests.character_motion_smooth, bool(coefficient_of_determination > COEFFICIENT_OF_DETERMINATION_THRESHOLD)) + + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(Tick_CharacterGameplayComponentMotionIsSmooth) From edefb57cfdaffc1b1b7e6c020ae5f50c46bf4200 Mon Sep 17 00:00:00 2001 From: AMZN-AlexOteiza <82234181+AMZN-AlexOteiza@users.noreply.github.com> Date: Thu, 11 Nov 2021 13:58:00 +0000 Subject: [PATCH 09/11] Fixed crash when typing asset name and clicking browse (#5495) --- .../AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp index 24b2c7466e..e97be57470 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.cpp @@ -1072,10 +1072,10 @@ namespace AzToolsFramework RefreshAutocompleter(); } - // When focus is lost, clear the field if necessary + // When focus is lost, revert to the selected asset if (!focus && m_incompleteFilename) { - HandleFieldClear(); + SetSelectedAssetID(GetCurrentAssetID()); } } From 9d05168cfceb8aae13a55f68133053afa9234203 Mon Sep 17 00:00:00 2001 From: greerdv Date: Thu, 11 Nov 2021 15:10:46 +0000 Subject: [PATCH 10/11] address feedback from PR Signed-off-by: greerdv --- .../Gem/PythonTests/Physics/TestSuite_Main.py | 6 +++--- .../Tick_CharacterGameplayComponentMotionIsSmooth.py | 10 ++++++---- .../tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py | 10 ++++++---- pytest.ini | 2 +- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py index 3ef593612b..fb2744deda 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Main.py @@ -93,14 +93,14 @@ class TestAutomation(TestAutomationBase): from .tests import Physics_UndoRedoWorksOnEntityWithPhysComponents as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.tick + @pytest.mark.GROUP_tick @pytest.mark.xfail(reason="Test still under development.") def test_Tick_InterpolatedRigidBodyMotionIsSmooth(self, request, workspace, editor, launcher_platform): from .tests.tick import Tick_InterpolatedRigidBodyMotionIsSmooth as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.tick + @pytest.mark.GROUP_tick @pytest.mark.xfail(reason="Test still under development.") - def test_Tick_Tick_CharacterGameplayComponentMotionIsSmooth(self, request, workspace, editor, launcher_platform): + def test_Tick_CharacterGameplayComponentMotionIsSmooth(self, request, workspace, editor, launcher_platform): from .tests.tick import Tick_CharacterGameplayComponentMotionIsSmooth as test_module self._run_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py index 6425ece640..fe718d7247 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_CharacterGameplayComponentMotionIsSmooth.py @@ -13,6 +13,8 @@ class Tests(): create_entity = ("Created test entity", "Failed to create test entity") character_controller_added = ("Added PhysX Character Controller component", "Failed to add PhysX Character Controller component") character_gameplay_added = ("Added PhysX Character Gameplay component", "Failed to add PhysX Character Gameplay component") + enter_game_mode = ("Entered game mode", "Failed to enter game mode") + exit_game_mode = ("Exited game mode", "Failed to exit game mode") character_motion_smooth = ("Character motion passed smoothness threshold", "Failed to meet smoothness threshold for character motion") # fmt: on @@ -50,7 +52,7 @@ def Tick_CharacterGameplayComponentMotionIsSmooth(): helper.init_idle() # 1) Load the empty level - helper.open_level("Physics", "Base") + helper.open_level("", "Base") # 2) Create an entity test_entity = Entity.create_editor_entity("test_entity") @@ -68,14 +70,14 @@ def Tick_CharacterGameplayComponentMotionIsSmooth(): # 4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames t = [] z = [] - general.enter_game_mode() + helper.enter_game_mode(Tests.enter_game_mode) general.idle_wait_frames(1) game_entity_id = general.find_game_entity("test_entity") - for timestep in range(100): + for frame in range(100): t.append(azlmbr.components.TickRequestBus(azlmbr.bus.Broadcast, "GetTimeAtCurrentTick").GetSeconds()) z.append(azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", game_entity_id)) general.idle_wait_frames(1) - general.exit_game_mode() + helper.exit_game_mode(Tests.exit_game_mode) # 5) Test that the z vs t curve is sufficiently smooth (if the interpolation is not working well, the curve will be less smooth) # normalize the t and z data diff --git a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py index 1b9310910d..19e79355d9 100644 --- a/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py +++ b/AutomatedTesting/Gem/PythonTests/Physics/tests/tick/Tick_InterpolatedRigidBodyMotionIsSmooth.py @@ -12,6 +12,8 @@ Test Case Title : Verify that a rigid body with "Interpolate motion" option sele class Tests(): create_entity = ("Created test entity", "Failed to create test entity") rigid_body_added = ("Added PhysX Rigid Body component", "Failed to add PhysX Rigid Body component") + enter_game_mode = ("Entered game mode", "Failed to enter game mode") + exit_game_mode = ("Exited game mode", "Failed to exit game mode") rigid_body_smooth = ("Rigid body motion passed smoothness threshold", "Failed to meet smoothness threshold for rigid body motion") # fmt: on @@ -49,7 +51,7 @@ def Tick_InterpolatedRigidBodyMotionIsSmooth(): helper.init_idle() # 1) Load the empty level - helper.open_level("Physics", "Base") + helper.open_level("", "Base") # 2) Create an entity test_entity = Entity.create_editor_entity("test_entity") @@ -67,14 +69,14 @@ def Tick_InterpolatedRigidBodyMotionIsSmooth(): # 4) Enter game mode and collect data for the rigid body's z co-ordinate and the time values for a series of frames t = [] z = [] - general.enter_game_mode() + helper.enter_game_mode(Tests.enter_game_mode) general.idle_wait_frames(1) game_entity_id = general.find_game_entity("test_entity") - for timestep in range(100): + for frame in range(100): t.append(azlmbr.components.TickRequestBus(azlmbr.bus.Broadcast, "GetTimeAtCurrentTick").GetSeconds()) z.append(azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", game_entity_id)) general.idle_wait_frames(1) - general.exit_game_mode() + helper.exit_game_mode(Tests.exit_game_mode) # 5) Test that the z vs t curve is sufficiently smooth (if the interpolation is not working well, the curve will be less smooth) # normalize the t and z data diff --git a/pytest.ini b/pytest.ini index a863f8ca96..a229b19a4d 100644 --- a/pytest.ini +++ b/pytest.ini @@ -22,5 +22,5 @@ markers = SUITE_smoke: Tiny, quick tests of fundamental operation (tests with no SUITE_awsi: Time consuming AWS integration end-to-end tests # secondary markers which may appear alongisde a suite marker: REQUIRES_gpu: Tests which require a physical GPU - tick: Tests which verify if systems update correctly with system ticks (for example, physics bodies should move smoothly) + GROUP_tick: Tests which verify if systems update correctly with system ticks (for example, physics bodies should move smoothly) # custom markers not listed above will cause pytest to emit a typo warning From 984ea571f4772b228ccd22d4da980897d388fb50 Mon Sep 17 00:00:00 2001 From: SWMasterson Date: Thu, 11 Nov 2021 08:32:33 -0800 Subject: [PATCH 11/11] Add P0 test for Entity Reference component. (#5456) Signed-off-by: Sean Masterson --- .../Gem/PythonTests/Atom/TestSuite_Main.py | 4 + ...omEditorComponents_EntityReferenceAdded.py | 158 ++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py index d183ca12be..c7565d5e4b 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py @@ -41,6 +41,10 @@ class TestAutomation(EditorTestSuite): class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest): from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module + @pytest.mark.test_case_id("C36525661") + class AtomEditorComponents_EntityReferenceAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_EntityReferenceAdded as test_module + @pytest.mark.test_case_id("C32078121") class AtomEditorComponents_ExposureControlAdded(EditorSharedTest): from Atom.tests import hydra_AtomEditorComponents_ExposureControlAdded as test_module diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py new file mode 100644 index 0000000000..dddcca64fa --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_EntityReferenceAdded.py @@ -0,0 +1,158 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + + +class Tests: + creation_undo = ( + "UNDO Entity creation success", + "UNDO Entity creation failed") + creation_redo = ( + "REDO Entity creation success", + "REDO Entity creation failed") + entity_reference_creation = ( + "Entity Reference Entity successfully created", + "Entity Reference Entity failed to be created") + entity_reference_component = ( + "Entity has an Entity Reference component", + "Entity failed to find Entity Reference component") + enter_game_mode = ( + "Entered game mode", + "Failed to enter game mode") + exit_game_mode = ( + "Exited game mode", + "Couldn't exit game mode") + is_visible = ( + "Entity is visible", + "Entity was not visible") + is_hidden = ( + "Entity is hidden", + "Entity was not hidden") + entity_deleted = ( + "Entity deleted", + "Entity was not deleted") + deletion_undo = ( + "UNDO deletion success", + "UNDO deletion failed") + deletion_redo = ( + "REDO deletion success", + "REDO deletion failed") + + +def AtomEditorComponents_EntityReference_AddedToEntity(): + """ + Summary: + Tests the Entity Reference component can be added to an entity and has the expected functionality. + + Test setup: + - Wait for Editor idle loop. + - Open the "Base" level. + + Expected Behavior: + The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components. + Creation and deletion undo/redo should also work. + + Test Steps: + 1) Create an Entity Reference entity with no components. + 2) Add Entity Reference component to Entity Reference entity. + 3) UNDO the entity creation and component addition. + 4) REDO the entity creation and component addition. + 5) Enter/Exit game mode. + 6) Test IsHidden. + 7) Test IsVisible. + 8) Delete Entity Reference entity. + 9) UNDO deletion. + 10) REDO deletion. + 11) Look for errors. + + :return: None + """ + + import azlmbr.legacy.general as general + + from editor_python_test_tools.editor_entity_utils import EditorEntity + from editor_python_test_tools.utils import Report, Tracer, TestHelper + from Atom.atom_utils.atom_constants import AtomComponentProperties + + with Tracer() as error_tracer: + # Test setup begins. + # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. + TestHelper.init_idle() + TestHelper.open_level("", "Base") + + # Test steps begin. + # 1. Create an Entity Reference entity with no components. + entity_reference_entity = EditorEntity.create_editor_entity(AtomComponentProperties.entity_reference()) + Report.critical_result(Tests.entity_reference_creation, entity_reference_entity.exists()) + + # 2. Add Entity Reference component to Entity Reference entity. + entity_reference_component = entity_reference_entity.add_component( + AtomComponentProperties.entity_reference()) + Report.critical_result( + Tests.entity_reference_component, + entity_reference_entity.has_component(AtomComponentProperties.entity_reference())) + + # 3. UNDO the entity creation and component addition. + # -> UNDO component addition. + general.undo() + # -> UNDO naming entity. + general.undo() + # -> UNDO selecting entity. + general.undo() + # -> UNDO entity creation. + general.undo() + general.idle_wait_frames(1) + Report.result(Tests.creation_undo, not entity_reference_entity.exists()) + + # 4. REDO the entity creation and component addition. + # -> REDO entity creation. + general.redo() + # -> REDO selecting entity. + general.redo() + # -> REDO naming entity. + general.redo() + # -> REDO component addition. + general.redo() + general.idle_wait_frames(1) + Report.result(Tests.creation_redo, entity_reference_entity.exists()) + + # 5. Enter/Exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + general.idle_wait_frames(1) + TestHelper.exit_game_mode(Tests.exit_game_mode) + + # 6. Test IsHidden. + entity_reference_entity.set_visibility_state(False) + Report.result(Tests.is_hidden, entity_reference_entity.is_hidden() is True) + + # 7. Test IsVisible. + entity_reference_entity.set_visibility_state(True) + general.idle_wait_frames(1) + Report.result(Tests.is_visible, entity_reference_entity.is_visible() is True) + + # 8. Delete Entity Reference entity. + entity_reference_entity.delete() + Report.result(Tests.entity_deleted, not entity_reference_entity.exists()) + + # 9. UNDO deletion. + general.undo() + Report.result(Tests.deletion_undo, entity_reference_entity.exists()) + + # 10. REDO deletion. + general.redo() + Report.result(Tests.deletion_redo, not entity_reference_entity.exists()) + + # 11. Look for errors and asserts. + TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) + for error_info in error_tracer.errors: + Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") + for assert_info in error_tracer.asserts: + Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}") + + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(AtomEditorComponents_EntityReference_AddedToEntity)