Browse Source

Merge pull request #16854 from aws-lumberyard-dev/cgalvan/gitflow_231005_o3de

Merged `stabilization/2310` to `main`
Chris Galvan 1 năm trước cách đây
mục cha
commit
0d490a2b4b
100 tập tin đã thay đổi với 793 bổ sung9986 xóa
  1. 0 5
      .automatedtesting.json
  2. 1 0
      .github/CODEOWNERS
  3. 26 0
      .github/workflows/stabilization-pr-checklist.yaml
  4. 2 1
      .gitignore
  5. 284 236
      Assets/Engine/SeedAssetList.seed
  6. 0 0
      AutomatedTesting/Assets/Objects/PxMesh/test.fbx
  7. 0 0
      AutomatedTesting/Assets/Objects/PxMesh/test.fbx.assetinfo
  8. 0 0
      AutomatedTesting/Assets/Objects/PxMesh/test.mtl
  9. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/linux/vulkan/Atom_AreaLights/disk_screenshot.png
  10. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/linux/vulkan/Atom_AreaLights/sphere_screenshot.png
  11. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/linux/vulkan/Atom_DepthOfField/depth_of_field_screenshot1.png
  12. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/dx12/Atom_AreaLights/disk_screenshot.png
  13. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/dx12/Atom_AreaLights/sphere_screenshot.png
  14. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/dx12/Atom_DepthOfField/depth_of_field_screenshot1.png
  15. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/vulkan/Atom_AreaLights/disk_screenshot.png
  16. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/vulkan/Atom_AreaLights/sphere_screenshot.png
  17. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/vulkan/Atom_DepthOfField/depth_of_field_screenshot1.png
  18. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/linux/vulkan/Atom_AreaLights/disk_screenshot.png
  19. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/linux/vulkan/Atom_AreaLights/sphere_screenshot.png
  20. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/linux/vulkan/Atom_DepthOfField/depth_of_field_screenshot1.png
  21. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/dx12/Atom_AreaLights/disk_screenshot.png
  22. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/dx12/Atom_AreaLights/sphere_screenshot.png
  23. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/dx12/Atom_DepthOfField/depth_of_field_screenshot1.png
  24. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/vulkan/Atom_AreaLights/disk_screenshot.png
  25. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/vulkan/Atom_AreaLights/sphere_screenshot.png
  26. 3 0
      AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/vulkan/Atom_DepthOfField/depth_of_field_screenshot1.png
  27. 17 0
      AutomatedTesting/AutomationScripts/RunAtomScreenshotTests.bat
  28. 14 0
      AutomatedTesting/AutomationScripts/RunAtomScreenshotTests.sh
  29. 11 0
      AutomatedTesting/CMakePresets.json
  30. 2 2
      AutomatedTesting/Editor/Scripts/auto_lod.py
  31. 3 3
      AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py
  32. 14 0
      AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt
  33. 145 0
      AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Periodic_GPU.py
  34. 1 1
      AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Smoke_GPU.py
  35. 2 2
      AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py
  36. 18 1
      AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py
  37. 120 94
      AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_canvas_utils.py
  38. 55 76
      AutomatedTesting/Gem/PythonTests/Atom/tests/MaterialCanvas_Atom_BasicTests.py
  39. 1 1
      AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HairAdded.py
  40. 3 3
      AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py
  41. 7 7
      AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py
  42. 2 2
      AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py
  43. 1 1
      AutomatedTesting/Gem/PythonTests/EditorPythonBindings/tests/Editor_ComponentAssetCommands_Works.py
  44. 1 1
      AutomatedTesting/Gem/PythonTests/EditorPythonBindings/tests/Editor_PySide_Example_Works.py
  45. 1 248
      AutomatedTesting/Gem/PythonTests/Physics/TestSuite_InDevelopment.py
  46. 0 79
      AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py
  47. 0 205
      AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Sandbox.py
  48. 0 14
      AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Utils.py
  49. 1 1
      AutomatedTesting/Gem/PythonTests/Physics/tests/EntityComponentTests/PhysX_Mesh_Collider_Component_CRUD.py
  50. 0 95
      AutomatedTesting/Gem/PythonTests/Physics/tests/Physics_UndoRedoWorksOnEntityWithPhysComponents.py
  51. 0 105
      AutomatedTesting/Gem/PythonTests/Physics/tests/Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether.py
  52. 0 83
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_AddingNewGroupWorks.py
  53. 0 107
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_BoxShapeEditing.py
  54. 0 107
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_CapsuleShapeEditing.py
  55. 0 334
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_ColliderPositionOffset.py
  56. 0 302
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_ColliderRotationOffset.py
  57. 0 361
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_CollisionGroupsWorkflow.py
  58. 0 230
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_DiffCollisionGroupDiffCollidingLayersNotCollide.py
  59. 2 2
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_MultipleSurfaceSlots.py
  60. 0 222
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_NoneCollisionGroupSameLayerNotCollide.py
  61. 2 2
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_PxMeshAutoAssignedWhenAddingRenderMeshComponent.py
  62. 1 1
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_PxMeshAutoAssignedWhenModifyingRenderMeshComponent.py
  63. 1 1
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_PxMeshConvexMeshCollides.py
  64. 0 84
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_PxMeshErrorIfNoMesh.py
  65. 1 1
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx.py
  66. 0 126
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SameCollisionGroupDiffLayersCollide.py
  67. 0 184
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SameCollisionGroupSameCustomLayerCollide.py
  68. 0 187
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SameCollisionGroupSameLayerCollide.py
  69. 0 233
      AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_TriggerPassThrough.py
  70. 0 222
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_CapsuleShapedForce.py
  71. 0 282
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_DirectionHasNoAffectOnTotalForce.py
  72. 0 246
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_HighValuesDirectionAxesWorkWithNoError.py
  73. 0 165
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ImpulsesBoxShapedRigidBody.py
  74. 0 169
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ImpulsesCapsuleShapedRigidBody.py
  75. 0 171
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ImpulsesPxMeshShapedRigidBody.py
  76. 0 296
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_LinearDampingForceOnRigidBodies.py
  77. 0 160
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_LocalSpaceForceOnRigidBodies.py
  78. 0 162
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_MovingForceRegionChangesNetForce.py
  79. 0 177
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_MultipleComponentsCombineForces.py
  80. 0 233
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_MultipleForcesInSameComponentCombineForces.py
  81. 0 168
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_NoQuiverOnHighLinearDampingForce.py
  82. 0 198
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ParentChildForcesCombineForces.py
  83. 0 188
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_PointForceOnRigidBodies.py
  84. 0 404
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_PositionOffset.py
  85. 0 138
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_PxMeshShapedForce.py
  86. 0 404
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_RotationalOffset.py
  87. 0 141
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SimpleDragForceOnRigidBodies.py
  88. 0 142
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SmallMagnitudeDeviationOnLargeForces.py
  89. 0 149
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SphereShapedForce.py
  90. 0 161
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SplineForceOnRigidBodies.py
  91. 0 166
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SplineRegionWithModifiedTransform.py
  92. 0 84
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_WithNonTriggerColliderWarning.py
  93. 0 182
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_WorldSpaceForceOnRigidBodies.py
  94. 0 241
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroLinearDampingDoesNothing.py
  95. 0 242
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroLocalSpaceForceDoesNothing.py
  96. 0 242
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroPointForceDoesNothing.py
  97. 0 173
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroSimpleDragForceDoesNothing.py
  98. 0 175
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroSplineForceDoesNothing.py
  99. 0 242
      AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroWorldSpaceForceDoesNothing.py
  100. 0 113
      AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_Ball2BodiesConstrained.py

+ 0 - 5
.automatedtesting.json

@@ -12,10 +12,5 @@
     "ENABLE_GEMS": [
     ],
     "REPOS": [
-        {
-            "NAME": "o3de-extras",
-            "URL": "https://github.com/o3de/o3de-extras.git",
-            "BRANCH": "development"
-        }
     ]
 }

+ 1 - 0
.github/CODEOWNERS

@@ -18,6 +18,7 @@
 /Code/Framework/AzGameFramework/ @o3de/sig-core-reviewers @o3de/sig-core-maintainers
 /Code/LauncherUnified/ @o3de/sig-core-reviewers @o3de/sig-core-maintainers
 /engine.json @o3de/sig-core-reviewers @o3de/sig-core-maintainers
+/Gems/Archive/ @o3de/sig-core-reviewers @o3de/sig-core-maintainers
 /Gems/Compression/ @o3de/sig-core-reviewers @o3de/sig-core-maintainers
 /Gems/CrashReporting/ @o3de/sig-core-reviewers @o3de/sig-core-maintainers
 /Gems/ImGui/ @o3de/sig-core-reviewers @o3de/sig-core-maintainers

+ 26 - 0
.github/workflows/stabilization-pr-checklist.yaml

@@ -0,0 +1,26 @@
+name: Add stabilization PR checklist
+
+on:
+  pull_request_target:
+    types: [opened, reopened]
+    branches:
+    - stabilization/**
+    
+jobs:
+  comment-on-PR:
+    runs-on: ubuntu-latest
+    permissions:
+      pull-requests: write
+    steps:
+      - name: Pull sig-release repo
+        uses: actions/checkout@v4
+        with:
+          repository: o3de/sig-release
+          ref: main
+          fetch-depth: 0
+          path: sig-release
+          
+      - uses: mshick/add-pr-comment@v2
+        with:
+          message-path: |
+            sig-release/releases/Process/O3DE Exception Checklist.md

+ 2 - 1
.gitignore

@@ -1,4 +1,5 @@
 .idea/
+.venv/
 .vs/
 .vscode/
 __pycache__
@@ -13,6 +14,7 @@ CMakeUserPresets.json
 [Uu]ser/
 FrameCapture/**
 .DS_Store
+.automatedtesting.json
 user*.cfg
 client*.cfg
 server*.cfg
@@ -20,4 +22,3 @@ server*.cfg
 _savebackup/
 *.swatches
 /imgui.ini
-

+ 284 - 236
Assets/Engine/SeedAssetList.seed

@@ -1,236 +1,284 @@
-<ObjectStream version="3">
-  <Class name="AZStd::vector" type="{82FC5264-88D0-57CD-9307-FC52E4DAD550}">
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{2FB1A7EF-557C-577E-94E6-DC1F331E374F}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/config.dat" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{1103CB60-BE8D-56C0-AE9D-98EF531C7106}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/gpu/android_gpus.xml" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{AD7E02A2-5658-5138-95F2-47347A9C1BE1}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/gpu/android_models.xml" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{7646BFFB-B94B-5593-8669-9B387B4669D6}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/gpu/ios_models.xml" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{F408D747-032E-5409-BBDF-2C4AAA5FD385}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/perfhud_pc.xml" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{34B60E74-28FA-57C4-9A2E-77515A083AC5}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="1000" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="engineassets/icons/averagememoryusage.tif.streamingimage" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{D84DBC88-3637-5876-B249-E92EA9BCD0F5}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="1000" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="engineassets/icons/highmemoryusage.tif.streamingimage" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{98BA37F2-74C0-54CD-8109-F71276E834FE}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="1000" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="engineassets/icons/livepreview.tif.streamingimage" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{DAC6670C-4A48-5661-B0DC-030071B2F2AB}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="1000" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="engineassets/icons/lowmemoryusage.tif.streamingimage" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{9AF56C8A-4B9F-5B20-A77D-E30114E032D6}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="1000" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="engineassets/icons/navigationprocessing.tif.streamingimage" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{B6A22033-75B8-5580-80D7-0568C08AAFF3}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="1000" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="engineassets/icons/nullsoundsystem.tif.streamingimage" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{8AE41B60-4004-5749-8B50-5EF6E5151342}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="1000" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="engineassets/icons/shadercompiling.tif.streamingimage" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{B150AA1E-B38A-5827-AABE-A072E7C2477F}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="1000" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="engineassets/icons/streaming.tif.streamingimage" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{F43241FB-ECDE-55A9-BA59-AE19AF495F62}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="1000" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="engineassets/icons/streamingterrain.tif.streamingimage" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{E03A8D59-7F4C-5C84-9D05-339A65C65E2C}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="fonts/default-ui.font" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{D4279574-B13F-5B71-B5D2-BE04FA3A0C81}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="127" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="fonts/default.font" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{368A249D-7AC3-5B44-A6FC-8FDDF7C2AA62}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/cvargroups/sys_spec_full.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{FD38C182-1AFC-514C-99E5-BB1AB60C4A31}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/spec/android_high.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{A81A509B-C473-583A-9675-AC159B274231}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/spec/android_high_nogmem.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{08D52EFB-D7FB-5266-905F-1599F8D29C77}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/spec/android_low.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{78605B06-1772-5B60-AEF4-4F5DD3AAA665}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/spec/android_malit760.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{9452506B-6F3D-5907-B631-78AD00C7A555}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/spec/android_medium.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{E68C7CB3-DE0B-5A2C-914B-F2E50F48D4F3}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/spec/android_veryhigh.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{6971FAB8-2ABE-5830-AE34-081B35970662}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/spec/ios_high.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{ECFC3EF0-4B9D-504B-8DC6-231CA22E2EDB}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/spec/ios_low.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{3B603071-F68A-515F-BE93-7592E08EA56B}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/spec/ios_medium.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{7DC7B81A-6E95-567E-8BBA-30957B97312A}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="config/spec/ios_veryhigh.cfg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{2DEEC017-D5F2-585D-A729-F68D51AF6E07}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="engine_dependencies.xml" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-    <Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
-      <Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
-        <Class name="AZ::Uuid" field="guid" value="{3B28A661-E723-5EBE-AB52-EC5829D88C31}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
-        <Class name="unsigned int" field="subId" value="-2010443522" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      </Class>
-      <Class name="unsigned int" field="platformFlags" value="255" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
-      <Class name="AZStd::string" field="pathHint" value="bootstrap.game.release.setreg" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
-    </Class>
-  </Class>
-</ObjectStream>
+{
+    "Type": "JsonSerialization",
+    "Version": 1,
+    "ClassName": "AZStd::vector<SeedInfo, allocator>",
+    "ClassData": [
+        {
+            "assetId": {
+                "guid": "{2FB1A7EF-557C-577E-94E6-DC1F331E374F}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/config.dat"
+        },
+        {
+            "assetId": {
+                "guid": "{1103CB60-BE8D-56C0-AE9D-98EF531C7106}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/gpu/android_gpus.xml"
+        },
+        {
+            "assetId": {
+                "guid": "{AD7E02A2-5658-5138-95F2-47347A9C1BE1}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/gpu/android_models.xml"
+        },
+        {
+            "assetId": {
+                "guid": "{7646BFFB-B94B-5593-8669-9B387B4669D6}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/gpu/ios_models.xml"
+        },
+        {
+            "assetId": {
+                "guid": "{F408D747-032E-5409-BBDF-2C4AAA5FD385}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/perfhud_pc.xml"
+        },
+        {
+            "assetId": {
+                "guid": "{34B60E74-28FA-57C4-9A2E-77515A083AC5}",
+                "subId": 1000
+            },
+            "platformFlags": 127,
+            "pathHint": "engineassets/icons/averagememoryusage.tif.streamingimage"
+        },
+        {
+            "assetId": {
+                "guid": "{D84DBC88-3637-5876-B249-E92EA9BCD0F5}",
+                "subId": 1000
+            },
+            "platformFlags": 127,
+            "pathHint": "engineassets/icons/highmemoryusage.tif.streamingimage"
+        },
+        {
+            "assetId": {
+                "guid": "{98BA37F2-74C0-54CD-8109-F71276E834FE}",
+                "subId": 1000
+            },
+            "platformFlags": 127,
+            "pathHint": "engineassets/icons/livepreview.tif.streamingimage"
+        },
+        {
+            "assetId": {
+                "guid": "{DAC6670C-4A48-5661-B0DC-030071B2F2AB}",
+                "subId": 1000
+            },
+            "platformFlags": 127,
+            "pathHint": "engineassets/icons/lowmemoryusage.tif.streamingimage"
+        },
+        {
+            "assetId": {
+                "guid": "{9AF56C8A-4B9F-5B20-A77D-E30114E032D6}",
+                "subId": 1000
+            },
+            "platformFlags": 127,
+            "pathHint": "engineassets/icons/navigationprocessing.tif.streamingimage"
+        },
+        {
+            "assetId": {
+                "guid": "{B6A22033-75B8-5580-80D7-0568C08AAFF3}",
+                "subId": 1000
+            },
+            "platformFlags": 127,
+            "pathHint": "engineassets/icons/nullsoundsystem.tif.streamingimage"
+        },
+        {
+            "assetId": {
+                "guid": "{8AE41B60-4004-5749-8B50-5EF6E5151342}",
+                "subId": 1000
+            },
+            "platformFlags": 127,
+            "pathHint": "engineassets/icons/shadercompiling.tif.streamingimage"
+        },
+        {
+            "assetId": {
+                "guid": "{B150AA1E-B38A-5827-AABE-A072E7C2477F}",
+                "subId": 1000
+            },
+            "platformFlags": 127,
+            "pathHint": "engineassets/icons/streaming.tif.streamingimage"
+        },
+        {
+            "assetId": {
+                "guid": "{F43241FB-ECDE-55A9-BA59-AE19AF495F62}",
+                "subId": 1000
+            },
+            "platformFlags": 127,
+            "pathHint": "engineassets/icons/streamingterrain.tif.streamingimage"
+        },
+        {
+            "assetId": {
+                "guid": "{E03A8D59-7F4C-5C84-9D05-339A65C65E2C}"
+            },
+            "platformFlags": 127,
+            "pathHint": "fonts/default-ui.font"
+        },
+        {
+            "assetId": {
+                "guid": "{D4279574-B13F-5B71-B5D2-BE04FA3A0C81}"
+            },
+            "platformFlags": 127,
+            "pathHint": "fonts/default.font"
+        },
+        {
+            "assetId": {
+                "guid": "{368A249D-7AC3-5B44-A6FC-8FDDF7C2AA62}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/cvargroups/sys_spec_full.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{FD38C182-1AFC-514C-99E5-BB1AB60C4A31}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/spec/android_high.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{A81A509B-C473-583A-9675-AC159B274231}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/spec/android_high_nogmem.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{08D52EFB-D7FB-5266-905F-1599F8D29C77}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/spec/android_low.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{78605B06-1772-5B60-AEF4-4F5DD3AAA665}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/spec/android_malit760.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{9452506B-6F3D-5907-B631-78AD00C7A555}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/spec/android_medium.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{E68C7CB3-DE0B-5A2C-914B-F2E50F48D4F3}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/spec/android_veryhigh.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{6971FAB8-2ABE-5830-AE34-081B35970662}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/spec/ios_high.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{ECFC3EF0-4B9D-504B-8DC6-231CA22E2EDB}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/spec/ios_low.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{3B603071-F68A-515F-BE93-7592E08EA56B}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/spec/ios_medium.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{7DC7B81A-6E95-567E-8BBA-30957B97312A}"
+            },
+            "platformFlags": 255,
+            "pathHint": "config/spec/ios_veryhigh.cfg"
+        },
+        {
+            "assetId": {
+                "guid": "{2DEEC017-D5F2-585D-A729-F68D51AF6E07}"
+            },
+            "platformFlags": 255,
+            "pathHint": "engine_dependencies.xml"
+        },
+        {
+            "assetId": {
+                "guid": "{3B28A661-E723-5EBE-AB52-EC5829D88C31}",
+                "subId": 3428050507
+            },
+            "platformFlags": 255,
+            "pathHint": "bootstrap.client.release.setreg"
+        },
+        {
+            "assetId": {
+                "guid": "{3B28A661-E723-5EBE-AB52-EC5829D88C31}",
+                "subId": 2733667963
+            },
+            "platformFlags": 255,
+            "pathHint": "bootstrap.client.profile.setreg"
+        },
+        {
+            "assetId": {
+                "guid": "{3B28A661-E723-5EBE-AB52-EC5829D88C31}",
+                "subId": 3945067969
+            },
+            "platformFlags": 255,
+            "pathHint": "bootstrap.client.debug.setreg"
+        },
+        {
+            "assetId": {
+                "guid": "{3B28A661-E723-5EBE-AB52-EC5829D88C31}",
+                "subId": 3877526290
+            },
+            "platformFlags": 255,
+            "pathHint": "bootstrap.server.release.setreg"
+        },
+        {
+            "assetId": {
+                "guid": "{3B28A661-E723-5EBE-AB52-EC5829D88C31}",
+                "subId": 3451833122
+            },
+            "platformFlags": 255,
+            "pathHint": "bootstrap.server.profile.setreg"
+        },
+        {
+            "assetId": {
+                "guid": "{3B28A661-E723-5EBE-AB52-EC5829D88C31}",
+                "subId": 2263697560
+            },
+            "platformFlags": 255,
+            "pathHint": "bootstrap.server.debug.setreg"
+        },
+        {
+            "assetId": {
+                "guid": "{3B28A661-E723-5EBE-AB52-EC5829D88C31}",
+                "subId": 3208209838
+            },
+            "platformFlags": 255,
+            "pathHint": "bootstrap.unified.release.setreg"
+        },
+        {
+            "assetId": {
+                "guid": "{3B28A661-E723-5EBE-AB52-EC5829D88C31}",
+                "subId": 3520632254
+            },
+            "platformFlags": 255,
+            "pathHint": "bootstrap.unified.profile.setreg"
+        },
+        {
+            "assetId": {
+                "guid": "{3B28A661-E723-5EBE-AB52-EC5829D88C31}",
+                "subId": 2660526372
+            },
+            "platformFlags": 255,
+            "pathHint": "bootstrap.unified.debug.setreg"
+        }
+    ]
+}

+ 0 - 0
AutomatedTesting/Levels/Physics/Material_PerFaceMaterialGetsCorrectMaterial/test.fbx → AutomatedTesting/Assets/Objects/PxMesh/test.fbx


+ 0 - 0
AutomatedTesting/Levels/Physics/Material_PerFaceMaterialGetsCorrectMaterial/test.fbx.assetinfo → AutomatedTesting/Assets/Objects/PxMesh/test.fbx.assetinfo


+ 0 - 0
AutomatedTesting/Levels/Physics/Material_PerFaceMaterialGetsCorrectMaterial/test.mtl → AutomatedTesting/Assets/Objects/PxMesh/test.mtl


+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/linux/vulkan/Atom_AreaLights/disk_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:041eef9a1950138e989d3c5ece4fa81d9697a4db57a0a668ac90e24c73e0672b
+size 118766

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/linux/vulkan/Atom_AreaLights/sphere_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7ec6274ab1ec266126e9e273e1f45c809b72b4c21465613048a4e1615d151269
+size 159561

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/linux/vulkan/Atom_DepthOfField/depth_of_field_screenshot1.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:57de2192a3621f7b63062d82c128f2bfd2b44e49f5c45af6ce6f53853cff9db8
+size 1364886

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/dx12/Atom_AreaLights/disk_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1beeed5946f41dceb33a401f7ffb7ff4c66b56023e8fa1a46c9ac9a063128cf7
+size 118796

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/dx12/Atom_AreaLights/sphere_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8b198f4792a62c4f5f2903402c23e6ffff6cc44e3078f574af6361f386a17f2e
+size 159656

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/dx12/Atom_DepthOfField/depth_of_field_screenshot1.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:afde855f891dd6b7b8e7db7bdabeea82fc5fe133596c14e28919b8127de233fe
+size 1401375

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/vulkan/Atom_AreaLights/disk_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:041eef9a1950138e989d3c5ece4fa81d9697a4db57a0a668ac90e24c73e0672b
+size 118766

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/vulkan/Atom_AreaLights/sphere_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7ec6274ab1ec266126e9e273e1f45c809b72b4c21465613048a4e1615d151269
+size 159561

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/LowEndRenderPipeline/windows/vulkan/Atom_DepthOfField/depth_of_field_screenshot1.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e66ad6ae9af991db25518e9da7a790d5ff0e25b3be5b19665017267a8bca511f
+size 1364401

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/linux/vulkan/Atom_AreaLights/disk_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6c8aa7646dd0aea1f6030ce66d60949da32e5e87e5af164429dc2a22e9bd3964
+size 118845

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/linux/vulkan/Atom_AreaLights/sphere_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0f3b3a03199ddb9e038862348be9827c9345b6eff5f2149a573f66f9d1d6861e
+size 159392

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/linux/vulkan/Atom_DepthOfField/depth_of_field_screenshot1.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cec0b8ee74a3c4826d1f83bfb10cc16a4e25dd799098900f1867e04ef061c36b
+size 842112

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/dx12/Atom_AreaLights/disk_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7fc983b42ae767b5a11e2ed0189dd6b080c32fbe21126d5cfeb8273ee01f1d0e
+size 118955

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/dx12/Atom_AreaLights/sphere_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d81a755121f64a7058940e257e041882685638b512129290c644c8e74e0361ee
+size 159581

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/dx12/Atom_DepthOfField/depth_of_field_screenshot1.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0418a6ede0fb2fc1653486e3f29b913c9cbc7fa1539973482db126e5d268a01b
+size 843526

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/vulkan/Atom_AreaLights/disk_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6c8aa7646dd0aea1f6030ce66d60949da32e5e87e5af164429dc2a22e9bd3964
+size 118845

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/vulkan/Atom_AreaLights/sphere_screenshot.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0f3b3a03199ddb9e038862348be9827c9345b6eff5f2149a573f66f9d1d6861e
+size 159392

+ 3 - 0
AutomatedTesting/AutomationScripts/ExpectedScreenshots/MainRenderPipeline/windows/vulkan/Atom_DepthOfField/depth_of_field_screenshot1.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cec0b8ee74a3c4826d1f83bfb10cc16a4e25dd799098900f1867e04ef061c36b
+size 842112

+ 17 - 0
AutomatedTesting/AutomationScripts/RunAtomScreenshotTests.bat

@@ -0,0 +1,17 @@
+REM --------------------------------------------------------------------------------------------------
+REM 
+REM Copyright (c) Contributors to the Open 3D Engine Project.
+REM For complete copyright and license terms please see the LICENSE at the root of this distribution.
+REM 
+REM SPDX-License-Identifier: Apache-2.0 OR MIT
+REM 
+REM --------------------------------------------------------------------------------------------------
+
+REM record current dir
+pushd .
+REM cd to o3de root dir, %~dp0 is the path to the folder that contains this script
+cd %~dp0/../..
+setlocal
+call python/python.cmd -s -B -m pytest -v --tb=short --show-capture=stdout -c pytest.ini --build-directory AutomatedTesting/build/bin/profile AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Periodic_GPU.py --output-path AutomatedTesting/build/Testing/LyTestTools/AutomatedTesting_Atom_TestSuite_Periodic_GPU --junitxml=AutomatedTesting/build/Testing/Pytest/AutomatedTesting_Atom_TestSuite_Periodic_GPU.xml
+endlocal
+popd

+ 14 - 0
AutomatedTesting/AutomationScripts/RunAtomScreenshotTests.sh

@@ -0,0 +1,14 @@
+#
+# 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
+#
+#
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+pushd $SCRIPT_DIR > /dev/null
+
+../../python/python.sh -s -B -m pytest -v --tb=short --show-capture=stdout -c ../../pytest.ini --build-directory ../../AutomatedTesting/build/bin/profile ../../AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Periodic_GPU.py --output-path ../../AutomatedTesting/build/Testing/LyTestTools/AutomatedTesting_Atom_TestSuite_Periodic_GPU --junitxml=../../AutomatedTesting/build/Testing/Pytest/AutomatedTesting_Atom_TestSuite_Periodic_GPU.xml
+
+popd > /dev/null

+ 11 - 0
AutomatedTesting/CMakePresets.json

@@ -0,0 +1,11 @@
+{
+    "version": 4,
+    "cmakeMinimumRequired": {
+        "major": 3,
+        "minor": 23,
+        "patch": 0
+    },
+    "include": [
+        "../CMakePresets.json"
+    ]
+}

+ 2 - 2
AutomatedTesting/Editor/Scripts/auto_lod.py

@@ -79,11 +79,11 @@ def update_manifest(scene):
     # Add an EditorMeshComponent to the entity
     editor_mesh_component = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "GetOrAddComponentByTypeName", entity_id, "AZ::Render::EditorMeshComponent")
     # Set the ModelAsset assetHint to the relative path of the input asset + the name of the MeshGroup we just created + the azmodel extension
-    # The MeshGroup we created will be output as a product in the asset's path named mesh_group_name.azmodel
+    # The MeshGroup we created will be output as a product in the asset's path named mesh_group_name.fbx.azmodel
     # The assetHint will be converted to an AssetId later during prefab loading
     json_update = json.dumps({
         "Controller": { "Configuration": { "ModelAsset": {
-            "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel" }}}
+            "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".fbx.azmodel" }}}
         });
     # Apply the JSON above to the component we created
     result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id, editor_mesh_component, json_update)

+ 3 - 3
AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py

@@ -151,10 +151,10 @@ def update_manifest(scene):
                                                                entity_id, "AZ::Render::EditorMeshComponent")
         # Set the ModelAsset assetHint to the relative path of the input asset + the name of the MeshGroup we just
         # created + the azmodel extension The MeshGroup we created will be output as a product in the asset's path
-        # named mesh_group_name.azmodel The assetHint will be converted to an AssetId later during prefab loading
+        # named mesh_group_name.fbx.azmodel The assetHint will be converted to an AssetId later during prefab loading
         json_update = json.dumps({
             "Controller": {"Configuration": {"ModelAsset": {
-                "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".azmodel"}}}
+                "assetHint": os.path.join(source_relative_path, mesh_group_name) + ".fbx.azmodel"}}}
         })
         # Apply the JSON above to the component we created
         result = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "UpdateComponentForEntity", entity_id,
@@ -172,7 +172,7 @@ def update_manifest(scene):
                 "ShapeConfiguration": {
                     "PhysicsAsset": {
                         "Asset": {
-                            "assetHint": os.path.join(source_relative_path, source_filename_only + "_triangle.pxmesh")
+                            "assetHint": os.path.join(source_relative_path, source_filename_only + "_triangle.fbx.pxmesh")
                         }
                     }
                 }

+ 14 - 0
AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt

@@ -7,6 +7,20 @@
 #
 
 if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED)
+    ly_add_pytest(
+        NAME AutomatedTesting::Atom_TestSuite_Periodic_GPU
+        TEST_SUITE periodic
+        TEST_REQUIRES gpu
+        TEST_SERIAL
+        TIMEOUT 1200
+        PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic_GPU.py
+        RUNTIME_DEPENDENCIES
+            AssetProcessor
+            AutomatedTesting.Assets
+            Editor
+        COMPONENT
+            Atom
+    )
     ly_add_pytest(
         NAME AutomatedTesting::Atom_Main_Null_Render_Level_Loads
         TEST_SUITE main

+ 145 - 0
AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Periodic_GPU.py

@@ -0,0 +1,145 @@
+"""
+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
+"""
+import logging
+import os
+import sys
+import tempfile
+import json
+
+import pytest
+
+from ly_test_tools.environment import process_utils
+from ly_test_tools.launchers import launcher_helper
+from ly_test_tools.log.log_monitor import LogMonitor
+
+import ly_test_tools.environment.waiter as waiter
+
+logger = logging.getLogger(__name__)
+
+expected_lines = [
+    "screenshot compare passed. Diff score is"
+]
+
+unexpected_lines = [
+    "screenshot compare failed. Diff score",
+    "screenshot compare error. Error",
+    "Level not found",
+    "Failed to load level"
+]
+
+atom_feature_test_list = [
+    pytest.param(
+        "Atom_DepthOfField", # test name
+        "depth_of_field_screenshot1.png", # names to capture the screenshots to, also the names of the comparison images. Comma separated list
+        "@gemroot:ScriptAutomation@/Assets/AutomationScripts/GenericRenderScreenshotTest.lua", # test control script
+        "levels/atomscreenshottests/feature/depthoffield/depthoffield.spawnable", # level to load
+        "Level D", # image comparison tolerance level. Comma separated list
+        "Camera" # camera names for the screenshots. Comma separated list
+    ),
+    pytest.param(
+        "Atom_AreaLights", # test name
+        "sphere_screenshot.png,disk_screenshot.png", # names to capture the screenshots to, also the names of the comparison images. Comma separated list
+        "@gemroot:ScriptAutomation@/Assets/AutomationScripts/GenericRenderScreenshotTest.lua", # test control script
+        "levels/atomscreenshottests/feature/arealight/arealight.spawnable", # level to load
+        "Level E,Level E", # image comparison tolerance level. Comma separated list
+        "TestCameraPointLights,TestCameraDiskLights" # camera names for the screenshots. Comma separated list
+    )
+]
+
+atom_render_pipeline_list = [
+     pytest.param("passes/MainRenderPipeline.azasset"),
+     pytest.param("passes/LowEndRenderPipeline.azasset")
+]
+
+# default names are windows
+launcher_name = "AutomatedTesting.GameLauncher.exe"
+ap_name = "AssetProcessor.exe"
+WINDOWS = sys.platform.startswith('win')
+LINUX = sys.platform == "linux"
+#MAC = sys.platform == "darwin"
+
+if LINUX:
+    launcher_name = "AutomatedTesting.GameLauncher"
+    ap_name = "AssetProcessor"
+
+
+def run_test(workspace, rhi, test_name, screenshot_name, test_script, level_path, compare_tolerance, camera_name, render_pipeline):
+        # build SettingRegistry patch for the test
+        run_settings= {
+             "O3DE" : {
+                  "ScriptAutomation" : {
+                       "ImageCapture" : {
+                            "LevelPath" : level_path,
+                            "TestGroupName" : test_name,
+                            "ImageName" : screenshot_name,
+                            "ImageComparisonLevel" : compare_tolerance,
+                            "CaptureCameraName" : camera_name
+                       }
+                  }
+             }
+        }
+        run_json = json.dumps(run_settings, indent=4)
+
+        # Generate a temp file
+        setreg_file = tempfile.NamedTemporaryFile('w+t', delete=False, suffix='.setreg')
+
+        # write the json to the settings registry patch file
+        setreg_file.write(run_json)
+        setreg_file.flush()
+        setreg_file.close()
+
+        # launch the test
+        game_launcher = launcher_helper.create_game_launcher(workspace)
+        game_launcher.args.extend([ f'--rhi={rhi} ',
+                                    f'--run-automation-suite={test_script} ',
+                                    '--exit-on-automation-end ',
+                                    f'--r_renderPipelinePath={render_pipeline}',
+                                    f'--regset-file={setreg_file.name}'])
+        game_launcher.start()
+        waiter.wait_for(lambda: process_utils.process_exists(launcher_name, ignore_extensions=True))
+
+        game_launcher_log_file = os.path.join(game_launcher.workspace.paths.project_log(), 'Game.log')
+        game_launcher_log_monitor = LogMonitor(game_launcher, game_launcher_log_file)
+         # test may do multiple image capture & compare so don't halt on unexpected
+        try:
+            game_launcher_log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected=False, timeout=400)
+        finally:
+            process_utils.kill_processes_named(ap_name, ignore_extensions=True)
+
+
+
[email protected]_smoke
[email protected]_gpu
[email protected](not WINDOWS, reason="DX12 is only supported on windows")
[email protected]("project", ["AutomatedTesting"])
[email protected]("launcher_platform", ["windows"])
[email protected]("render_pipeline", atom_render_pipeline_list)
+class TestPeriodicSuite_DX12_GPU(object):
+
+    @pytest.mark.parametrize("test_name, screenshot_name, test_script, level_path, compare_tolerance, camera_name", atom_feature_test_list)
+    def test_Atom_FeatureTests_DX12(
+            self, workspace, launcher_platform, test_name, screenshot_name, test_script, level_path, compare_tolerance, camera_name, render_pipeline):
+        """
+        Run Atom on DX12 and screen capture tests on parameterised levels
+        """
+        run_test(workspace, "dx12", test_name, screenshot_name, test_script, level_path, compare_tolerance, camera_name, render_pipeline)
+
[email protected]_smoke
[email protected]_gpu
[email protected](not WINDOWS and not LINUX, reason="Vulkan is only supported on windows, linux, & android")
[email protected]("project", ["AutomatedTesting"])
[email protected]("launcher_platform", ["windows, linux"])
[email protected]("render_pipeline", atom_render_pipeline_list)
+class TestPeriodicSuite_Vulkan_GPU(object):
+
+    @pytest.mark.parametrize("test_name, screenshot_name, test_script, level_path, compare_tolerance, camera_name", atom_feature_test_list)
+    def test_Atom_FeatureTests_Vulkan(
+            self, workspace, launcher_platform, test_name, screenshot_name, test_script, level_path, compare_tolerance, camera_name, render_pipeline):
+        """
+        Run Atom on Vulkan and screen capture tests on parameterised levels
+        """
+        run_test(workspace, "vulkan", test_name, screenshot_name, test_script, level_path, compare_tolerance, camera_name, render_pipeline)

+ 1 - 1
AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Smoke_GPU.py

@@ -38,7 +38,7 @@ class TestAutomation_RHIValidation_Vulkan_LowEndPipeline(EditorTestSuite):
         "-autotest_mode",
         "-rhi=vulkan",
         "-rhi-device-validation=enable",
-        "--r_default_pipeline_name=passes/LowEndRenderPipeline.azasset"
+        "--r_renderPipelinePath=passes/LowEndRenderPipeline.azasset"
         ]  # Default is ["-BatchMode", "-autotest_mode"]
     use_null_renderer = False  # Default is True
 

+ 2 - 2
AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_component_helper.py

@@ -184,7 +184,7 @@ def create_basic_atom_rendering_scene():
     ground_plane_material_component = ground_plane_entity.add_component(AtomComponentProperties.material())
     ground_plane_entity.set_local_uniform_scale(32.0)
     ground_plane_mesh_component = ground_plane_entity.add_component(AtomComponentProperties.mesh())
-    ground_plane_mesh_asset_path = os.path.join("testdata", "objects", "plane.azmodel")
+    ground_plane_mesh_asset_path = os.path.join("testdata", "objects", "plane.fbx.azmodel")
     ground_plane_mesh_asset = Asset.find_asset_by_path(ground_plane_mesh_asset_path, False)
     ground_plane_mesh_component.set_component_property_value(
         AtomComponentProperties.mesh('Model Asset'), ground_plane_mesh_asset.id)
@@ -204,7 +204,7 @@ def create_basic_atom_rendering_scene():
     sphere_entity = EditorEntity.create_editor_entity_at(
         math.Vector3(0.0, 0.0, 1.0), "Sphere", default_level_entity.id)
     sphere_mesh_component = sphere_entity.add_component(AtomComponentProperties.mesh())
-    sphere_mesh_asset_path = os.path.join("models", "sphere.azmodel")
+    sphere_mesh_asset_path = os.path.join("models", "sphere.fbx.azmodel")
     sphere_mesh_asset = Asset.find_asset_by_path(sphere_mesh_asset_path, False)
     sphere_mesh_component.set_component_property_value(
         AtomComponentProperties.mesh('Model Asset'), sphere_mesh_asset.id)

+ 18 - 1
AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py

@@ -452,7 +452,7 @@ class AtomComponentProperties:
         :return: Full property path OR component name if no property specified.
         """
         properties = {
-            'name': 'DepthOfField',
+            'name': 'Depth Of Field',
             'requires': [AtomComponentProperties.postfx_layer()],
             'Camera Entity': 'Controller|Configuration|Camera Entity',
             'CameraEntityId Override': 'Controller|Configuration|Overrides|CameraEntityId Override',
@@ -1585,9 +1585,26 @@ class GraphControllerRequestBusEvents(object):
     """
     ADD_NODE = "AddNode"
     REMOVE_NODE = "RemoveNode"
+    GET_POSITION = "GetPosition"
     WRAP_NODE = "WrapNode"
+    WRAP_NODE_ORDERED = "WrapNodeOrdered"
+    UNWRAP_NODE = "UnwrapNode"
+    IS_NODE_WRAPPED = "IsNodeWrapped"
+    SET_WRAPPER_NODE_ACTION_STRING = "SetWrapperNodeActionString"
     ADD_CONNECTION = "AddConnection"
     ADD_CONNECTION_BY_SLOT_ID = "AddConnectionBySlotId"
     ARE_SLOTS_CONNECTED = "AreSlotsConnected"
     REMOVE_CONNECTION = "RemoveConnection"
     EXTEND_SLOT = "ExtendSlot"
+    GET_NODE_BY_ID = "GetNodeById"
+    GET_NODES_FROM_GRAPH_NODE_IDS = "GetNodesFromGraphNodeIds"
+    GET_NODE_IDS_BY_NODE = "GetNodeIdByNode"
+    GET_SLOT_ID_BY_SLOT = "GetSlotIdBySlot"
+    GET_NODES = "GetNodes"
+    GET_SELECTED_NODES = "GetSelectedNodes"
+    SET_SELECTED = "SetSelected"
+    CLEAR_SELECTION = "ClearSelection"
+    ENABLE_NODE = "EnableNode"
+    DISABLE_NODE = "DisableNode"
+    CENTER_ON_NODES = "CenterOnNodes"
+    GET_MAJOR_PITCH = "GetMajorPitch"

+ 120 - 94
AutomatedTesting/Gem/PythonTests/Atom/atom_utils/material_canvas_utils.py

@@ -8,103 +8,129 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
 import azlmbr.atomtools as atomtools
 import azlmbr.editor.graph as graph
 import azlmbr.math as math
+import azlmbr.object
 import azlmbr.bus as bus
 
 from Atom.atom_utils.atom_constants import (
     DynamicNodeManagerRequestBusEvents, GraphControllerRequestBusEvents, GraphDocumentRequestBusEvents)
 
 
-def get_graph_name(document_id: math.Uuid) -> str:
-    """
-    Gets the graph name of the given document_id and returns it as a string.
-    :param document_id: The UUID of a given graph document file.
-    :return: str representing the graph name contained in document_id
-    """
-    return atomtools.GraphDocumentRequestBus(bus.Event, GraphDocumentRequestBusEvents.GET_GRAPH_NAME, document_id)
-
-
-def get_graph_id(document_id: math.Uuid) -> int:
-    """
-    Gets the graph ID of the given document_id and returns it as an int.
-    :param document_id: The UUID of a given graph document file.
-    :return: int representing the graph ID of the graph contained in document_id
-    """
-    return atomtools.GraphDocumentRequestBus(bus.Event, GraphDocumentRequestBusEvents.GET_GRAPH_ID, document_id)
-
-
-def get_graph(document_id: math.Uuid) -> object:
-    """
-    Gets the graph object of the given document_id and returns it.
-    :param document_id: The UUID of a given graph document file.
-    :return: azlmbr.object.PythonProxyObject representing a C++ AZStd::shared_ptr<Graph> object.
-    """
-    return atomtools.GraphDocumentRequestBus(bus.Event, GraphDocumentRequestBusEvents.GET_GRAPH, document_id)
-
-
-def create_node_by_name(graph: object, node_name: str) -> object:
-    """
-    Creates a new node in memory matching the node_name string on the specified graph object.
-    i.e. "World Position" for node_name would create a World Position node.
-    :param graph: An AZStd::shared_ptr<Graph> graph object to create the new node on.
-    :param node_name: String representing the type of node to add to the graph.
-    :return: azlmbr.object.PythonProxyObject representing a C++ AZStd::shared_ptr<Node> object.
-    """
-    return atomtools.DynamicNodeManagerRequestBus(
-        bus.Broadcast, DynamicNodeManagerRequestBusEvents.CREATE_NODE_BY_NAME, graph, node_name)
-
-
-def add_node(graph_id: math.Uuid, node: object, position: math.Vector2) -> int:
-    """
-    Adds a node saved in memory to the current graph document at a specific position on the graph grid.
-    :param graph_id: int representing the ID value of a given graph AZStd::shared_ptr<Graph> object.
-    :param node: An AZStd::shared_ptr<Node> object.
-    :param position: math.Vector2(x,y) value that determines where to place the node on the graph grid.
-    :return: int representing the node ID of the newly placed node.
-    """
-    return graph.GraphControllerRequestBus(
-        bus.Event, GraphControllerRequestBusEvents.ADD_NODE, graph_id, node, position)
-
-
-def get_graph_model_slot_id(slot_name: str) -> object:
-    """
-    Given a slot_name string, return a GraphModelSlotId object representing a node slot.
-    :param slot_name: String representing the name of the slot to target on the node.
-    :return: An GraphModelSlotId object.
-    """
-    return graph.GraphModelSlotId(slot_name)
-
-
-def add_connection_by_slot_id(
-        graph_id: math.Uuid,
-        source_node: object, source_slot: object,
-        target_node: object, target_slot: object) -> object:
-    """
-    Adds a new connection between a source node slot and a target node slot.
-    :param graph_id: int representing the ID value of a given graph AZStd::shared_ptr<Graph> object.
-    :param source_node: A proxy AZStd::shared_ptr<Node> object for the source node to start the connection from.
-    :param source_slot: A proxy GraphModelSlotId object for the slot on the source node to use for the connection.
-    :param target_node: A proxy AZStd::shared_ptr<Node> object for the target node to end the connection to.
-    :param target_slot: A proxy GraphModelSlotId object for the slot on the target node to use for the connection.
-    :return: azlmbr.object.PythonProxyObject representing a C++ AZStd::shared_ptr<Connection> object.
-    """
-    return graph.GraphControllerRequestBus(
-        bus.Event, GraphControllerRequestBusEvents.ADD_CONNECTION_BY_SLOT_ID, graph_id,
-        source_node, source_slot, target_node, target_slot)
-
-
-def are_slots_connected(
-        graph_id: math.Uuid,
-        source_node: object, source_slot: object,
-        target_node: object, target_slot: object) -> bool:
-    """
-    Determines if 2 nodes have a connection formed between them and returns a boolean for success/failure.
-    :param graph_id: int representing the ID value of a given graph AZStd::shared_ptr<Graph> object.
-    :param source_node: An AZStd::shared_ptr<Node> object representing the source node for the connection.
-    :param source_slot: An GraphModelSlotId object representing the slot on the source node the connection uses.
-    :param target_node: An AZStd::shared_ptr<Node> object representing the target node for the connection.
-    :param target_slot: An GraphModelSlotId object representing the slot on the target node the connection uses.
-    :return: bool representing success (True) or failure (False).
-    """
-    return graph.GraphControllerRequestBus(
-        bus.Event, GraphControllerRequestBusEvents.ARE_SLOTS_CONNECTED, graph_id,
-        source_node, source_slot, target_node, target_slot)
+class Node(object):
+    """
+    Represents a node inside of a graph and contains node related functions.
+    """
+
+    def __init__(self, node_python_proxy: azlmbr.object.PythonProxyObject):
+        """
+        :param node_python_proxy: azlmbr.object.PythonProxyObject representing a node object.
+        """
+        self.node_python_proxy = node_python_proxy
+
+    def get_slots(self) -> dict:
+        """
+        Returns a dictionary mapping of all slots on this Node.
+        :return: a dict containing slot name keys with graph.GraphModelSlotId slot values.
+        """
+        mapped_node_slots = {}
+        raw_node_slots_dict = self.node_python_proxy.invoke('GetSlots')
+
+        for k, v in raw_node_slots_dict.items():
+            mapped_node_slots[k.name] = graph.GraphModelSlotId(k.name)
+
+        return mapped_node_slots
+
+
+class Graph(object):
+    """
+    Binds this Graph object to the opened graph matching the document_id passed to construct this object.
+    """
+
+    def __init__(self, document_id: math.Uuid):
+        self.document_id = document_id
+
+    def get_graph_id(self) -> math.Uuid:
+        """
+        Returns the graph ID value for this Graph object.
+        :return: math.Uuid which represents the graph ID value.
+        """
+        return atomtools.GraphDocumentRequestBus(
+            bus.Event, GraphDocumentRequestBusEvents.GET_GRAPH_ID, self.document_id)
+
+    def get_graph_name(self) -> str:
+        """
+        Returns the graph name for this Graph object.
+        :return: string representing the name of this Graph object.
+        """
+        return atomtools.GraphDocumentRequestBus(
+            bus.Event, GraphDocumentRequestBusEvents.GET_GRAPH_NAME, self.document_id)
+
+    def get_graph(self) -> azlmbr.object.PythonProxyObject:
+        """
+        Returns the AZStd::shared_ptr<Graph> object for this Graph object.
+        :return: azlmbr.object.PythonProxyObject containing a AZStd::shared_ptr<Graph> object.
+        """
+        return atomtools.GraphDocumentRequestBus(bus.Event, GraphDocumentRequestBusEvents.GET_GRAPH, self.document_id)
+
+    def get_nodes(self) -> list[azlmbr.object.PythonProxyObject]:
+        """
+        Gets the current Nodes in this Graph and returns them as a list of azlmbr.object.PythonProxyObject objects.
+        :return: list of azlmbr.object.PythonProxyObject objects each representing a Node in this Graph.
+        """
+        return graph.GraphControllerRequestBus(
+            bus.Event, GraphControllerRequestBusEvents.GET_NODES, self.get_graph_id())
+
+    def create_node_by_name(self, node_name: str) -> azlmbr.object.PythonProxyObject:
+        """
+        Creates a new node in memory matching the node_name string on the specified graph object.
+        i.e. "World Position" for node_name would create a World Position node.
+        We create them in memory for use with the GraphControllerRequestBusEvents.ADD_NODE bus call on this Graph.
+        :param node_name: String representing the type of node to add to the graph.
+        :return: azlmbr.object.PythonProxyObject representing a C++ AZStd::shared_ptr<Node> object.
+        """
+        return atomtools.DynamicNodeManagerRequestBus(
+            bus.Broadcast, DynamicNodeManagerRequestBusEvents.CREATE_NODE_BY_NAME, self.get_graph(), node_name)
+
+    def add_node(self, node: azlmbr.object.PythonProxyObject, position: math.Vector2) -> Node:
+        """
+        Adds a node generated from the NodeManager to this Graph, then returns a Node object for that node.
+        :param node: A azlmbr.object.PythonProxyObject containing the node we wish to add to the graph.
+        :param position: math.Vector2(x,y) value that determines where to place the node on the Graph's grid.
+        :return: A Node object containing node object and node id via azlmbr.object.PythonProxyObject objects.
+        """
+        graph.GraphControllerRequestBus(
+            bus.Event, GraphControllerRequestBusEvents.ADD_NODE, self.get_graph_id(), node, position)
+        return Node(node)
+
+    def add_connection_by_slot_id(self,
+                                  source_node: Node,
+                                  source_slot: graph.GraphModelSlotId,
+                                  target_node: Node,
+                                  target_slot: graph.GraphModelSlotId) -> azlmbr.object.PythonProxyObject:
+        """
+        Connects a starting source_slot to a destination target_slot.
+        :param source_node: A Node() object for the source node we are connecting from.
+        :param source_slot: A graph.GraphModelSlotId representing a slot on the source_node.
+        :param target_node: A Node() object for the target node we are connecting to.
+        :param target_slot: A graph.GraphModelSlotId representing a slot on the target_node.
+        :return: azlmbr.object.PythonProxyObject representing a C++ AZStd::shared_ptr<Connection> object.
+        """
+        return graph.GraphControllerRequestBus(
+            bus.Event, GraphControllerRequestBusEvents.ADD_CONNECTION_BY_SLOT_ID, self.get_graph_id(),
+            source_node.node_python_proxy, source_slot, target_node.node_python_proxy, target_slot)
+
+    def are_slots_connected(self,
+                            source_node: Node,
+                            source_slot: graph.GraphModelSlotId,
+                            target_node: Node,
+                            target_slot: graph.GraphModelSlotId) -> bool:
+        """
+        Determines if the source_slot is connected to the target_slot on the target_node.
+        :param source_node: A Node() object for the source node that should be connected to the target node.
+        :param source_slot: A graph.GraphModelSlotId representing a slot on the source_node.
+        :param target_node: A Node() object for the target node that should be connected to the source node.
+        :param target_slot: A graph.GraphModelSlotId representing a slot on the target_node..
+        :return: True if the source_slot and target_slot are connected, False otherwise.
+        """
+        return graph.GraphControllerRequestBus(
+            bus.Event, GraphControllerRequestBusEvents.ARE_SLOTS_CONNECTED, self.get_graph_id(),
+            source_node.node_python_proxy, source_slot, target_node.node_python_proxy, target_slot)

+ 55 - 76
AutomatedTesting/Gem/PythonTests/Atom/tests/MaterialCanvas_Atom_BasicTests.py

@@ -25,9 +25,6 @@ class Tests:
     node_palette_pane_visible = (
         "Node Palette pane is visible.",
         "P0: Failed to verify Node Palette pane is visible.")
-    material_graph_created = (
-        "New AZStd::shared_ptr<Graph> object created.",
-        "P0: Failed to create new AZStd::shared_ptr<Graph> object.")
     material_graph_name_is_test1 = (
         "Verified material graph name is 'test1'",
         "P0: Failed to verify material graph name is 'test1'")
@@ -55,17 +52,13 @@ def MaterialCanvas_BasicFunctionalityChecks_AllChecksPass():
     2) Close the selected material graph document.
     3) Open multiple material graph documents then use the CloseAllDocuments bus call to close them all.
     4) Open multiple material graph documents then verify all material documents are opened.
-    5) Use the CloseAllDocumentsExcept bus call to close all but one.
+    5) Use the CloseAllDocumentsExcept bus call to close all but test_1_material_graph.
     6) Verify Node Palette pane visibility.
-    7) Verify material graph name is 'test1'.
-    8) Create a new material_graph from material_graph_document_ids[0].
-    9) Create a new world_position_node in memory.
-    10) Add the world_position_node to the material_graph.
-    11) Create a new standard_pbr_node in memory.
-    12) Add the standard_pbr_node to the material_graph
-    13) Create outbound_slot for our world_position_node and inbound_slot for our standard_pbr_node.
-    14) Create a node connection between world_position_node and standard_pbr_node successfully.
-    15) Look for errors and asserts.
+    7) Verify test_1_material_graph.name is 'test1'.
+    8) Create a new world_position_node inside test_1_material_graph.
+    9) Create a new standard_pbr_node inside test_1_material_graph.
+    10) Create a node connection between world_position_node outbound slot and standard_pbr_node inbound slot.
+    11) Look for errors and asserts.
 
     :return: None
     """
@@ -75,7 +68,7 @@ def MaterialCanvas_BasicFunctionalityChecks_AllChecksPass():
     import azlmbr.math as math
 
     import Atom.atom_utils.atom_tools_utils as atom_tools_utils
-    import Atom.atom_utils.material_canvas_utils as material_canvas_utils
+    from Atom.atom_utils.material_canvas_utils import Graph
     from editor_python_test_tools.utils import Report, Tracer, TestHelper
 
     with Tracer() as error_tracer:
@@ -86,51 +79,52 @@ def MaterialCanvas_BasicFunctionalityChecks_AllChecksPass():
         atom_tools_utils.disable_graph_compiler_settings()
 
         # Set constants before starting test steps.
-        test_1_material_graph = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test1.materialgraph")
-        test_2_material_graph = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test2.materialgraph")
-        test_3_material_graph = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test3.materialgraph")
-        test_4_material_graph = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test4.materialgraph")
-        test_5_material_graph = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test5.materialgraph")
+        test_1_material_graph_file = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test1.materialgraph")
+        test_2_material_graph_file = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test2.materialgraph")
+        test_3_material_graph_file = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test3.materialgraph")
+        test_4_material_graph_file = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test4.materialgraph")
+        test_5_material_graph_file = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test5.materialgraph")
 
         # 1. Open an existing material graph document.
-        material_graph_document_id = atom_tools_utils.open_document(test_1_material_graph)
+        test_1_material_graph = Graph(atom_tools_utils.open_document(test_1_material_graph_file))
         Report.result(
             Tests.open_existing_material_graph,
-            atom_tools_utils.is_document_open(material_graph_document_id) is True)
+            atom_tools_utils.is_document_open(test_1_material_graph.document_id) is True)
 
         # 2. Close the selected material graph document.
-        atom_tools_utils.close_document(material_graph_document_id)
+        atom_tools_utils.close_document(test_1_material_graph.document_id)
         Report.result(
             Tests.close_opened_material_graph,
-            atom_tools_utils.is_document_open(material_graph_document_id) is False)
+            atom_tools_utils.is_document_open(test_1_material_graph.document_id) is False)
 
         # 3. Open multiple material graph documents then use the CloseAllDocuments bus call to close them all.
-        for material_graph_document in [test_1_material_graph, test_2_material_graph, test_3_material_graph,
-                                        test_4_material_graph, test_5_material_graph]:
-            atom_tools_utils.open_document(os.path.join(material_graph_document))
+        material_graph_document_files = [
+            test_1_material_graph_file, test_2_material_graph_file, test_3_material_graph_file,
+            test_4_material_graph_file, test_5_material_graph_file]
+        for material_graph_document_file in material_graph_document_files:
+            Graph(atom_tools_utils.open_document(material_graph_document_file))
         Report.result(
             Tests.close_all_opened_material_graphs,
             atom_tools_utils.close_all_documents() is True)
 
         # 4. Open multiple material graph documents then verify all material documents are opened.
-        material_graph_document_ids = []
-        test_material_graphs = [test_1_material_graph, test_2_material_graph, test_3_material_graph,
-                                test_4_material_graph, test_5_material_graph]
-        for test_material_graph in test_material_graphs:
-            material_graph_document_id = atom_tools_utils.open_document(test_material_graph)
+        test_material_graphs = []
+        for material_graph_document_file in material_graph_document_files:
+            test_material_graph = Graph(atom_tools_utils.open_document(material_graph_document_file))
             Report.result(Tests.verify_all_material_graphs_are_opened,
-                          atom_tools_utils.is_document_open(material_graph_document_id) is True)
-            material_graph_document_ids.append(material_graph_document_id)
+                          atom_tools_utils.is_document_open(test_material_graph.document_id) is True)
+            test_material_graphs.append(test_material_graph)
 
-        # 5. Use the CloseAllDocumentsExcept bus call to close all but one.
-        atom_tools_utils.close_all_except_selected(material_graph_document_ids[0])
+        # 5. Use the CloseAllDocumentsExcept bus call to close all but test_1_material_graph.
+        test_1_material_graph = test_material_graphs[0]
+        atom_tools_utils.close_all_except_selected(test_1_material_graph.document_id)
         Report.result(
             Tests.close_all_opened_material_graphs_except_one,
-            atom_tools_utils.is_document_open(material_graph_document_ids[0]) is True and
-            atom_tools_utils.is_document_open(material_graph_document_ids[1]) is False and
-            atom_tools_utils.is_document_open(material_graph_document_ids[2]) is False and
-            atom_tools_utils.is_document_open(material_graph_document_ids[3]) is False and
-            atom_tools_utils.is_document_open(material_graph_document_ids[4]) is False)
+            atom_tools_utils.is_document_open(test_1_material_graph.document_id) is True and
+            atom_tools_utils.is_document_open(test_material_graphs[1].document_id) is False and
+            atom_tools_utils.is_document_open(test_material_graphs[2].document_id) is False and
+            atom_tools_utils.is_document_open(test_material_graphs[3].document_id) is False and
+            atom_tools_utils.is_document_open(test_material_graphs[4].document_id) is False)
 
         # 6. Verify Node Palette pane visibility.
         atom_tools_utils.set_pane_visibility("Node Palette", True)
@@ -138,52 +132,37 @@ def MaterialCanvas_BasicFunctionalityChecks_AllChecksPass():
             Tests.node_palette_pane_visible,
             atom_tools_utils.is_pane_visible("Node Palette") is True)
 
-        # 7. Verify material graph name is 'test1'.
-        material_graph_name = material_canvas_utils.get_graph_name(material_graph_document_ids[0])
+        # 7. Verify test_1_material_graph.name is 'test1'.
         Report.result(
             Tests.material_graph_name_is_test1,
-            material_graph_name == "test1")
+            test_1_material_graph.get_graph_name() == "test1")
 
-        # 8. Create a new material_graph from material_graph_document_ids[0].
-        material_graph = material_canvas_utils.get_graph(material_graph_document_ids[0])
-        material_graph_id = material_canvas_utils.get_graph_id(material_graph_document_ids[0])
-        Report.result(
-            Tests.material_graph_created,
-            material_graph.typename == "AZStd::shared_ptr<Graph>")
-
-        # 9. Create a new world_position_node in memory.
-        world_position_node = material_canvas_utils.create_node_by_name(material_graph, "World Position")
+        # 8. Create a new world_position_node inside test_1_material_graph.
+        created_world_position_node = test_1_material_graph.create_node_by_name('World Position')
+        world_position_node = test_1_material_graph.add_node(created_world_position_node, math.Vector2(-200.0, 10.0))
         Report.result(
             Tests.world_position_node_created,
-            world_position_node.typename == "AZStd::shared_ptr<Node>")
-
-        # 10. Add the world_position_node to the material_graph.
-        # This test will be verified when the nodes are connected as if it doesn't exist the connection won't be made.
-        material_canvas_utils.add_node(material_graph_id, world_position_node, math.Vector2(-200.0, 10.0))
+            world_position_node.node_python_proxy.typename == "AZStd::shared_ptr<Node>")
 
-        # 11. Create a new standard_pbr_node in memory.
-        standard_pbr_node = material_canvas_utils.create_node_by_name(material_graph, "Standard PBR")
+        # 9. Create a new standard_pbr_node inside test_1_material_graph.
+        created_standard_pbr_node = test_1_material_graph.create_node_by_name('Standard PBR')
+        standard_pbr_node = test_1_material_graph.add_node(created_standard_pbr_node, math.Vector2(10.0, 220.0))
         Report.result(
             Tests.standard_pbr_node_created,
-            standard_pbr_node.typename == "AZStd::shared_ptr<Node>")
-
-        # 12. Add the standard_pbr_node to the material_graph.
-        # This test will be verified when the nodes are connected as if it doesn't exist the connection won't be made.
-        material_canvas_utils.add_node(material_graph_id, standard_pbr_node, math.Vector2(10.0, 220.0))
-
-        # 13. Create outbound_slot for our world_position_node and inbound_slot for our standard_pbr_node.
-        # This test will be verified when the nodes are connected as if it doesn't exist the connection won't be made.
-        outbound_slot = material_canvas_utils.get_graph_model_slot_id('outPosition')
-        inbound_slot = material_canvas_utils.get_graph_model_slot_id('inPositionOffset')
-
-        # 14. Create a node connection between world_position_node and standard_pbr_node successfully.
-        material_canvas_utils.add_connection_by_slot_id(
-            material_graph_id, world_position_node, outbound_slot, standard_pbr_node, inbound_slot)
-        are_slots_connected = material_canvas_utils.are_slots_connected(
-                material_graph_id, world_position_node, outbound_slot, standard_pbr_node, inbound_slot)
+            standard_pbr_node.node_python_proxy.typename == "AZStd::shared_ptr<Node>")
+
+        # 10. Create a node connection between world_position_node outbound slot and standard_pbr_node inbound slot.
+        world_position_node_slots = world_position_node.get_slots()
+        standard_pbr_node_slots = standard_pbr_node.get_slots()
+        test_1_material_graph.add_connection_by_slot_id(
+            world_position_node, world_position_node_slots['outPosition'],
+            standard_pbr_node, standard_pbr_node_slots['inPositionOffset'])
+        are_slots_connected = test_1_material_graph.are_slots_connected(
+            world_position_node, world_position_node_slots['outPosition'],
+            standard_pbr_node, standard_pbr_node_slots['inPositionOffset'])
         Report.result(Tests.nodes_connected, are_slots_connected is True)
 
-        # 15. Look for errors and asserts.
+        # 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}")

+ 1 - 1
AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_HairAdded.py

@@ -354,7 +354,7 @@ def AtomEditorComponents_Hair_AddedToEntity():
         Report.result(Tests.hair_enabled, hair_component.is_enabled())
 
         # 8. Set assets for Actor and Hair
-        head_path = os.path.join('testdata', 'headbonechainhairstyle', 'test_hair_bone_chain_head_style.azmodel')
+        head_path = os.path.join('testdata', 'headbonechainhairstyle', 'test_hair_bone_chain_head_style.fbx.azmodel')
         head_asset = Asset.find_asset_by_path(head_path)
         hair_path = os.path.join('testdata', 'headbonechainhairstyle', 'test_hair_bone_chain_head_style.tfxhair')
         hair_asset = Asset.find_asset_by_path(hair_path)

+ 3 - 3
AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MaterialAdded.py

@@ -218,12 +218,12 @@ def AtomEditorComponents_Material_AddedToEntity():
 
         # 12. Set a model asset to Mesh component
         # Set a simple model to ensure that the more complex model will load cleanly
-        model_path = os.path.join('objects', 'cube.azmodel')
+        model_path = os.path.join('objects', 'cube.fbx.azmodel')
         model = Asset.find_asset_by_path(model_path)
         mesh_component.set_component_property_value(AtomComponentProperties.mesh('Model Asset'), model.id)
         general.idle_wait_frames(1)
         # Update model asset to a model with 5 LOD materials
-        model_path = os.path.join('testdata', 'objects', 'modelhotreload', 'sphere_5lods.azmodel')
+        model_path = os.path.join('testdata', 'objects', 'modelhotreload', 'sphere_5lods.fbx.azmodel')
         model = Asset.find_asset_by_path(model_path)
         mesh_component.set_component_property_value(AtomComponentProperties.mesh('Model Asset'), model.id)
         general.idle_wait_frames(1)
@@ -242,7 +242,7 @@ def AtomEditorComponents_Material_AddedToEntity():
         # .\o3de\Gems\AtomLyIntegration\CommonFeatures\Code\Source\Material\EditorMaterialComponentSlot.cpp
         label = item.GetLabel()
         Report.result(Tests.model_material_label, label == 'lambert0')
-        # Asset path for lambert0 is 'objects/sphere_5lods_lambert0_11781189446760285338.azmaterial'; numbers may vary
+        # Asset path for lambert0 is 'objects/sphere_5lods_lambert0_11781189446760285338.fbx.azmaterial'; numbers may vary
         default_asset = Asset(item.GetDefaultAssetId())
         default_asset_path = default_asset.get_path()
         Report.result(

+ 7 - 7
AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_MeshAdded.py

@@ -79,10 +79,10 @@ class Tests:
         "Mesh component removed successfully",
         "P1: Mesh component was not correctly removed from the entity")
     model_asset_is_optimized = (
-        "tube.azmodel has <= 66 vertices",
+        "tube.fbx.azmodel has <= 66 vertices",
         "P0: Model has not been fully optimized")
     model_different_bone_ids_same_position_should_weld_vertices = (
-        "sameposition_differentboneIds_shouldnotweldvertices.azmodel has 48 vertices",
+        "sameposition_differentboneIds_shouldnotweldvertices.fbx.azmodel has 48 vertices",
         "P0: Vertices were welded when they shouldnt be")
 
 
@@ -215,7 +215,7 @@ def AtomEditorComponents_Mesh_AddedToEntity():
         Report.result(Tests.creation_redo, mesh_entity.exists())
 
         # 5. Set Mesh component asset property
-        model_path = os.path.join('testdata', 'objects', 'modelhotreload', 'sphere_5lods.azmodel')
+        model_path = os.path.join('testdata', 'objects', 'modelhotreload', 'sphere_5lods.fbx.azmodel')
         model = Asset.find_asset_by_path(model_path)
         mesh_component.set_component_property_value(AtomComponentProperties.mesh('Model Asset'), model.id)
         Report.result(Tests.model_asset_specified,
@@ -296,9 +296,9 @@ def AtomEditorComponents_Mesh_AddedToEntity():
 
         # 16. Set Mesh component Add Material Component and confirm a Material component added
         # Make sure the Entity Inspector is open and trigger the "Add Material Component" button
-        general.open_pane("Entity Inspector")
+        general.open_pane("Inspector")
         editor_window = pyside_utils.get_editor_main_window()
-        entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Entity Inspector")
+        entity_inspector = editor_window.findChild(QtWidgets.QDockWidget, "Inspector")
         add_material_component_button = pyside_utils.find_child_by_pattern(entity_inspector, "Add Material Component")
         add_material_component_button.click()
         Report.result(Tests.has_material, mesh_entity.has_component(AtomComponentProperties.material()))
@@ -326,7 +326,7 @@ def AtomEditorComponents_Mesh_AddedToEntity():
         Report.result(Tests.is_visible, mesh_entity.is_visible() is True)
         
         # 21. Test that vertex welding is functioning
-        model_path = os.path.join('testdata', 'objects', 'tube.azmodel')
+        model_path = os.path.join('testdata', 'objects', 'tube.fbx.azmodel')
         model = Asset.find_asset_by_path(model_path)
         onModelReadyHelper = OnModelReadyHelper()
         onModelReadyHelper.wait_for_on_model_ready(mesh_entity.id, mesh_component, model.id)
@@ -339,7 +339,7 @@ def AtomEditorComponents_Mesh_AddedToEntity():
                           AtomComponentProperties.mesh('Vertex Count LOD0')) <= 66)
 
         # 22. Test that vertices with the same position but different boneId's aren't unintentionally welded
-        model_path = os.path.join('testdata', 'objects', 'skinnedmesh', 'meshoptimization', 'sameposition_differentjointids_shouldnotweldvertices.azmodel')
+        model_path = os.path.join('testdata', 'objects', 'skinnedmesh', 'meshoptimization', 'sameposition_differentjointids_shouldnotweldvertices.fbx.azmodel')
         model = Asset.find_asset_by_path(model_path)
         onModelReadyHelper = OnModelReadyHelper()
         onModelReadyHelper.wait_for_on_model_ready(mesh_entity.id, mesh_component, model.id)

+ 2 - 2
AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomGPU_BasicLevelSetup.py

@@ -245,7 +245,7 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel():
         # 13. Add the Mesh component to the Ground Plane Entity and set the Mesh component Model Asset property.
         ground_plane_mesh_component = ground_plane_entity.add_component(AtomComponentProperties.mesh())
         Report.result(Tests.mesh_component_added, ground_plane_entity.has_component(AtomComponentProperties.mesh()))
-        ground_plane_model_asset_path = os.path.join("testdata", "objects", "plane.azmodel")
+        ground_plane_model_asset_path = os.path.join("testdata", "objects", "plane.fbx.azmodel")
         ground_plane_model_asset = Asset.find_asset_by_path(ground_plane_model_asset_path, False)
         ground_plane_mesh_component.set_component_property_value(
             AtomComponentProperties.mesh('Model Asset'), ground_plane_model_asset.id)
@@ -283,7 +283,7 @@ def AtomGPU_BasicLevelSetup_SetsUpLevel():
 
         # 18. Add Mesh component to Sphere Entity and set the Model Asset property for the Mesh component.
         sphere_mesh_component = sphere_entity.add_component(AtomComponentProperties.mesh())
-        sphere_model_asset_path = os.path.join("models", "sphere.azmodel")
+        sphere_model_asset_path = os.path.join("models", "sphere.fbx.azmodel")
         sphere_model_asset = Asset.find_asset_by_path(sphere_model_asset_path, False)
         sphere_mesh_component.set_component_property_value(
             AtomComponentProperties.mesh('Model Asset'), sphere_model_asset.id)

+ 1 - 1
AutomatedTesting/Gem/PythonTests/EditorPythonBindings/tests/Editor_ComponentAssetCommands_Works.py

@@ -113,7 +113,7 @@ class Editor_ComponentAssetCommands_Works(BaseClass):
         pte = pteObj.GetValue()
 
         # Tests for the Asset<> case
-        testAssetId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'assets/objects/foliage/cedar.azmodel', math.Uuid(), False)
+        testAssetId = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetIdByPath', 'assets/objects/foliage/cedar.fbx.azmodel', math.Uuid(), False)
         Editor_ComponentAssetCommands_Works.GetSetCompareTest(component, "Controller|Configuration|Model Asset", testAssetId)
         Editor_ComponentAssetCommands_Works.PteTest(pte, "Controller|Configuration|Model Asset", testAssetId)
 

+ 1 - 1
AutomatedTesting/Gem/PythonTests/EditorPythonBindings/tests/Editor_PySide_Example_Works.py

@@ -33,7 +33,7 @@ class Editor_PySide_Example_Works(BaseClass):
 
         # Waiting for one frame so that the widgets in the UI are updated with the new component information
         general.idle_enable(True)
-        general.open_pane("Entity Inspector")
+        general.open_pane("Inspector")
         general.idle_wait_frames(1)
 
         values = pyside_component_utils.get_component_combobox_values(typenameList[0], 'Intensity mode', print)

+ 1 - 248
AutomatedTesting/Gem/PythonTests/Physics/TestSuite_InDevelopment.py

@@ -24,57 +24,6 @@ revert_physics_config = fm.file_revert_list(['physxdebugconfiguration.setreg', '
 @pytest.mark.parametrize("project", ["AutomatedTesting"])
 @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
 class TestAutomation(TestAutomationBase):
-    # Marking the test as an expected failure due to sporadic failure on Automated Review: LYN-2580
-    # The test still runs, but a failure of the test doesn't result in the test run failing
-    @revert_physics_config
-    @fm.file_override('physxsystemconfiguration.setreg', 'Material_PerFaceMaterialGetsCorrectMaterial.setreg_override',
-                      'AutomatedTesting/Registry', search_subdirs=True)
-    def test_Material_PerFaceMaterialGetsCorrectMaterial(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_PerFaceMaterialGetsCorrectMaterial as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @revert_physics_config
-    @fm.file_override('physxsystemconfiguration.setreg','Collider_NoneCollisionGroupSameLayerNotCollide.setreg_override',
-                      'AutomatedTesting/Registry', search_subdirs=True)
-    def test_Collider_NoneCollisionGroupSameLayerNotCollide(self, request, workspace, editor, launcher_platform):
-        from .tests.collider import Collider_NoneCollisionGroupSameLayerNotCollide as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @revert_physics_config
-    @fm.file_override('physxsystemconfiguration.setreg','Collider_SameCollisionGroupSameCustomLayerCollide.setreg_override',
-                      'AutomatedTesting/Registry', search_subdirs=True)
-    def test_Collider_SameCollisionGroupSameCustomLayerCollide(self, request, workspace, editor, launcher_platform):
-        from .tests.collider import Collider_SameCollisionGroupSameCustomLayerCollide as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @revert_physics_config
-    @fm.file_override('physxsystemconfiguration.setreg','Material_RestitutionCombine.setreg_override',
-                      'AutomatedTesting/Registry', search_subdirs=True)
-    def test_Material_RestitutionCombine(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_RestitutionCombine as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @revert_physics_config
-    @fm.file_override('physxsystemconfiguration.setreg','Material_FrictionCombine.setreg_override',
-                      'AutomatedTesting/Registry', search_subdirs=True)
-    def test_Material_FrictionCombine(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_FrictionCombine as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @revert_physics_config
-    @fm.file_override('physxsystemconfiguration.setreg','Material_RestitutionCombinePriorityOrder.setreg_override',
-                      'AutomatedTesting/Registry', search_subdirs=True)
-    def test_Material_RestitutionCombinePriorityOrder(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_RestitutionCombinePriorityOrder as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @revert_physics_config
-    @fm.file_override('physxsystemconfiguration.setreg','Material_FrictionCombinePriorityOrder.setreg_override',
-                      'AutomatedTesting/Registry', search_subdirs=True)
-    def test_Material_FrictionCombinePriorityOrder(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_FrictionCombinePriorityOrder as test_module
-        self._run_test(request, workspace, editor, test_module)
-
     @revert_physics_config
     @fm.file_override('physxsystemconfiguration.setreg','Material_Restitution.setreg_override',
                       'AutomatedTesting/Registry', search_subdirs=True)
@@ -82,140 +31,10 @@ class TestAutomation(TestAutomationBase):
         from .tests.material import Material_Restitution as test_module
         self._run_test(request, workspace, editor, test_module)
 
-    @fm.file_revert("ragdollbones.physmaterial",
-                    r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnRagdollBones")
-    def test_Material_LibraryCrudOperationsReflectOnRagdollBones(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_LibraryCrudOperationsReflectOnRagdollBones as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Material_RagdollBones(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_RagdollBones as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @fm.file_revert("c15308221_material_componentsinsyncwithlibrary.physmaterial",
-                    r"AutomatedTesting\Levels\Physics\Material_ComponentsInSyncWithLibrary")
-    def test_Material_ComponentsInSyncWithLibrary(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_ComponentsInSyncWithLibrary as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    # BUG: LY-107723")
-    def test_ScriptCanvas_SetKinematicTargetTransform(self, request, workspace, editor, launcher_platform):
-        from .tests.script_canvas import ScriptCanvas_SetKinematicTargetTransform as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    # Failing, PhysXTerrain
-    @fm.file_revert("c4925579_material_addmodifydeleteonterrain.physmaterial",
-                    r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnTerrain")
-    def test_Material_LibraryCrudOperationsReflectOnTerrain(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_LibraryCrudOperationsReflectOnTerrain as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    # Failing, PhysXTerrain
-    def test_Terrain_TerrainTexturePainterWorks(self, request, workspace, editor, launcher_platform):
-        from .tests.terrain import Terrain_TerrainTexturePainterWorks as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    # Failing, PhysXTerrain
-    def test_Material_CanBeAssignedToTerrain(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_CanBeAssignedToTerrain as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    # Failing, PhysXTerrain
-    def test_Material_DefaultLibraryConsistentOnAllFeatures(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_DefaultLibraryConsistentOnAllFeatures as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    # Failing, PhysXTerrain
-    @fm.file_revert("all_ones_1.physmaterial", r"AutomatedTesting\Levels\Physics\Material_DefaultMaterialLibraryChangesWork")
-    @fm.file_override("default.physxconfiguration", "Material_DefaultMaterialLibraryChangesWork.physxconfiguration", "AutomatedTesting")
-    def test_Material_DefaultMaterialLibraryChangesWork(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_DefaultMaterialLibraryChangesWork as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Collider_SameCollisionGroupSameLayerCollide(self, request, workspace, editor, launcher_platform):
-        from .tests.collider import Collider_SameCollisionGroupSameLayerCollide as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Ragdoll_OldRagdollSerializationNoErrors(self, request, workspace, editor, launcher_platform):
-        from .tests.ragdoll import Ragdoll_OldRagdollSerializationNoErrors as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @fm.file_override("default.physxconfiguration", "ScriptCanvas_OverlapNode.physxconfiguration")
-    def test_ScriptCanvas_OverlapNode(self, request, workspace, editor, launcher_platform):
-        from .tests.script_canvas import ScriptCanvas_OverlapNode as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Material_StaticFriction(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_StaticFriction as test_module
-        self._run_test(request, workspace, editor, test_module)
-        
-    @fm.file_revert("c4888315_material_addmodifydeleteoncollider.physmaterial",
-                    r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnCollider")
-    def test_Material_LibraryCrudOperationsReflectOnCollider(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_LibraryCrudOperationsReflectOnCollider as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @fm.file_revert("c15563573_material_addmodifydeleteoncharactercontroller.physmaterial",
-                    r"AutomatedTesting\Levels\Physics\Material_LibraryCrudOperationsReflectOnCharacterController")
-    def test_Material_LibraryCrudOperationsReflectOnCharacterController(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_LibraryCrudOperationsReflectOnCharacterController as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @fm.file_revert("c4044455_material_librarychangesinstantly.physmaterial",
-                    r"AutomatedTesting\Levels\Physics\C4044455_Material_LibraryChangesInstantly")
-    def test_Material_LibraryChangesReflectInstantly(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_LibraryChangesReflectInstantly as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @fm.file_revert("Material_LibraryUpdatedAcrossLevels.physmaterial",
-                    r"AutomatedTesting\Levels\Physics\Material_LibraryUpdatedAcrossLevels")
-    def test_Material_LibraryUpdatedAcrossLevels(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_LibraryUpdatedAcrossLevels as test_module
-        self._run_test(request, workspace, editor, test_module)
-    
-    def test_RigidBody_LinearDampingAffectsMotion(self, request, workspace, editor, launcher_platform):
-        from .tests.rigid_body import RigidBody_LinearDampingAffectsMotion as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Terrain_CollisionAgainstRigidBody(self, request, workspace, editor, launcher_platform):
-        from .tests.terrain import Terrain_CollisionAgainstRigidBody as test_module
-        self._run_test(request, workspace, editor, test_module)
-
     def test_Physics_WorldBodyBusWorksOnEditorComponents(self, request, workspace, editor, launcher_platform):
         from .tests import Physics_WorldBodyBusWorksOnEditorComponents as test_module
         self._run_test(request, workspace, editor, test_module)
 
-    def test_Collider_PxMeshErrorIfNoMesh(self, request, workspace, editor, launcher_platform):
-        from .tests.collider import Collider_PxMeshErrorIfNoMesh as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_ForceRegion_ImpulsesBoxShapedRigidBody(self, request, workspace, editor, launcher_platform):
-        from .tests.force_region import ForceRegion_ImpulsesBoxShapedRigidBody as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Terrain_AddPhysTerrainComponent(self, request, workspace, editor, launcher_platform):
-        from .tests.terrain import Terrain_AddPhysTerrainComponent as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Terrain_CanAddMultipleTerrainComponents(self, request, workspace, editor, launcher_platform):
-        from .tests.terrain import Terrain_CanAddMultipleTerrainComponents as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Terrain_MultipleTerrainComponentsWarning(self, request, workspace, editor, launcher_platform):
-        from .tests.terrain import Terrain_MultipleTerrainComponentsWarning as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_ForceRegion_HighValuesDirectionAxesWorkWithNoError(self, request, workspace, editor, launcher_platform):
-        from .tests.force_region import ForceRegion_HighValuesDirectionAxesWorkWithNoError as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Terrain_MultipleResolutionsValid(self, request, workspace, editor, launcher_platform):
-        from .tests.terrain import Terrain_MultipleResolutionsValid as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_ForceRegion_SmallMagnitudeDeviationOnLargeForces(self, request, workspace, editor, launcher_platform):
-        from .tests.force_region import ForceRegion_SmallMagnitudeDeviationOnLargeForces as test_module
-        self._run_test(request, workspace, editor, test_module)
 
 # Custom test spec, it provides functionality to override files
 class EditorSingleTest_WithFileOverrides(EditorSingleTest):
@@ -265,35 +84,9 @@ class EditorTestAutomation(EditorTestSuite):
     def get_number_parallel_editors():
         return 16
 
-    #########################################
-    # Non-atomic tests: These need to be run in a single editor because they have custom setup and teardown
-    class Material_DynamicFriction(EditorSingleTest_WithFileOverrides):
-        from .tests.material import Material_DynamicFriction as test_module
-        files_to_override = [
-            ('physxsystemconfiguration.setreg', 'Material_DynamicFriction.setreg_override')
-        ]
-        base_dir = "AutomatedTesting/Registry"
-
-    @pytest.mark.skip(reason="GHI #9422: Test Periodically Fails")
-    class Collider_DiffCollisionGroupDiffCollidingLayersNotCollide(EditorSingleTest_WithFileOverrides):
-        from .tests.collider import Collider_DiffCollisionGroupDiffCollidingLayersNotCollide as test_module
-        files_to_override = [
-            ('physxsystemconfiguration.setreg',
-             'Collider_DiffCollisionGroupDiffCollidingLayersNotCollide.setreg_override')
-        ]
-        base_dir = "AutomatedTesting/Registry"
-
-    #########################################
-
     class Collider_MultipleSurfaceSlots(EditorBatchedTest):
         from .tests.collider import Collider_MultipleSurfaceSlots as test_module
 
-    class Material_LibraryClearingAssignsDefault(EditorBatchedTest):
-        from .tests.material import Material_LibraryClearingAssignsDefault as test_module
-
-    class Physics_UndoRedoWorksOnEntityWithPhysComponents(EditorBatchedTest):
-        from .tests import Physics_UndoRedoWorksOnEntityWithPhysComponents as test_module
-
     @pytest.mark.GROUP_tick
     @pytest.mark.xfail(reason="Test still under development.")
     class Tick_InterpolatedRigidBodyMotionIsSmooth(EditorBatchedTest):
@@ -304,50 +97,10 @@ class EditorTestAutomation(EditorTestSuite):
     class Tick_CharacterGameplayComponentMotionIsSmooth(EditorBatchedTest):
         from .tests.tick import Tick_CharacterGameplayComponentMotionIsSmooth as test_module
 
-    @pytest.mark.xfail(reason="AssertionError: Couldn't find Asset with path: Objects/SphereBot/r0-b_body.azmodel")
+    @pytest.mark.xfail(reason="AssertionError: Couldn't find Asset with path: Objects/SphereBot/r0-b_body.fbx.azmodel")
     class Collider_PxMeshAutoAssignedWhenModifyingRenderMeshComponent(EditorBatchedTest):
         from .tests.collider import Collider_PxMeshAutoAssignedWhenModifyingRenderMeshComponent as test_module
 
     @pytest.mark.skip(reason="GHI #9301: Test Periodically Fails")
     class Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx(EditorBatchedTest):
         from .tests.collider import Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx as test_module
-
-    @pytest.mark.skip(reason="GHI #9364: Test Periodically Fails")
-    class ForceRegion_LinearDampingForceOnRigidBodies(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_LinearDampingForceOnRigidBodies as test_module
-
-    @pytest.mark.xfail(
-        reason="This test will sometimes fail as the ball will continue to roll before the timeout is reached.")
-    class RigidBody_SleepWhenBelowKineticThreshold(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_SleepWhenBelowKineticThreshold as test_module
-
-    @pytest.mark.xfail(reason="GHI #9579: Test periodically fails")
-    class Collider_TriggerPassThrough(EditorBatchedTest):
-        from .tests.collider import Collider_TriggerPassThrough as test_module
-
-    @pytest.mark.skip(reason="GHI #9365: Test periodically fails")
-    class ForceRegion_NoQuiverOnHighLinearDampingForce(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_NoQuiverOnHighLinearDampingForce as test_module
-
-    @pytest.mark.xfail(reason="GHI #9565: Test periodically fails")
-    class RigidBody_ComputeInertiaWorks(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_ComputeInertiaWorks as test_module
-
-    # Marking the Test as expected to fail using the xfail decorator due to sporadic failure on Automated Review: SPEC-3146
-    # The test still runs, but a failure of the test doesn't result in the test run failing
-    @pytest.mark.xfail(
-        reason="Test Sporadically fails with message [ NOT FOUND ] Success: Bar1 : Expected angular velocity")
-    class RigidBody_MaxAngularVelocityWorks(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_MaxAngularVelocityWorks as test_module
-
-    @pytest.mark.xfail(reason="GHI #9582: Test periodically fails")
-    class ForceRegion_WorldSpaceForceOnRigidBodies(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_WorldSpaceForceOnRigidBodies as test_module
-
-    @pytest.mark.xfail(reason="GHI #9566: Test periodically fails")
-    class ForceRegion_PointForceOnRigidBodies(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_PointForceOnRigidBodies as test_module
-
-    @pytest.mark.xfail(reason="GHI #9368: Test Sporadically Fails")
-    class Collider_ColliderRotationOffset(EditorBatchedTest):
-        from .tests.collider import Collider_ColliderRotationOffset as test_module

+ 0 - 79
AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Periodic.py

@@ -26,13 +26,6 @@ revert_physics_config = fm.file_revert_list(['physxdebugconfiguration.setreg', '
 @pytest.mark.parametrize("project", ["AutomatedTesting"])
 class TestAutomation(TestAutomationBase):
 
-    @revert_physics_config
-    @fm.file_override('physxsystemconfiguration.setreg','Material_CharacterController.setreg_override',
-                      'AutomatedTesting/Registry', search_subdirs=True)
-    def test_Material_CharacterController(self, request, workspace, editor, launcher_platform):
-        from .tests.material import Material_CharacterController as test_module
-        self._run_test(request, workspace, editor, test_module)
-
     @revert_physics_config
     @fm.file_override('physxdefaultsceneconfiguration.setreg','ScriptCanvas_PostUpdateEvent.setreg_override',
                       'AutomatedTesting/Registry', search_subdirs=True)
@@ -47,78 +40,6 @@ class TestAutomation(TestAutomationBase):
         from .tests.script_canvas import ScriptCanvas_PreUpdateEvent as test_module
         self._run_test(request, workspace, editor, test_module)
 
-    @revert_physics_config
-    @fm.file_override('physxsystemconfiguration.setreg','Collider_AddingNewGroupWorks.setreg_override',
-                      'AutomatedTesting/Registry', search_subdirs=True)
-    def test_Collider_AddingNewGroupWorks(self, request, workspace, editor, launcher_platform):
-        from .tests.collider import Collider_AddingNewGroupWorks as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    @revert_physics_config
-    @fm.file_override('physxsystemconfiguration.setreg','Collider_CollisionGroupsWorkflow.setreg_override',
-                      'AutomatedTesting/Registry', search_subdirs=True)
-    def test_Collider_CollisionGroupsWorkflow(self, request, workspace, editor, launcher_platform):
-        from .tests.collider import Collider_CollisionGroupsWorkflow as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Joints_Fixed2BodiesConstrained(self, request, workspace, editor, launcher_platform):
-        from .tests.joints import Joints_Fixed2BodiesConstrained as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Joints_Hinge2BodiesConstrained(self, request, workspace, editor, launcher_platform):
-        from .tests.joints import Joints_Hinge2BodiesConstrained as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Joints_Ball2BodiesConstrained(self, request, workspace, editor, launcher_platform):
-        from .tests.joints import Joints_Ball2BodiesConstrained as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Joints_FixedBreakable(self, request, workspace, editor, launcher_platform):
-        from .tests.joints import Joints_FixedBreakable as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Joints_HingeBreakable(self, request, workspace, editor, launcher_platform):
-        from .tests.joints import Joints_HingeBreakable as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Joints_BallBreakable(self, request, workspace, editor, launcher_platform):
-        from .tests.joints import Joints_BallBreakable as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Joints_HingeNoLimitsConstrained(self, request, workspace, editor, launcher_platform):
-        from .tests.joints import Joints_HingeNoLimitsConstrained as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Joints_BallNoLimitsConstrained(self, request, workspace, editor, launcher_platform):
-        from .tests.joints import Joints_BallNoLimitsConstrained as test_module
-        self._run_test(request, workspace, editor, test_module)
-
-    def test_Joints_GlobalFrameConstrained(self, request, workspace, editor, launcher_platform):
-        from .tests.joints import Joints_GlobalFrameConstrained as test_module
-        self._run_test(request, workspace, editor, test_module)
-
     def test_ScriptCanvas_SpawnEntityWithPhysComponents(self, request, workspace, editor, launcher_platform):
         from .tests.script_canvas import ScriptCanvas_SpawnEntityWithPhysComponents as test_module
         self._run_test(request, workspace, editor, test_module)
-    
-    @revert_physics_config
-    def test_Material_DefaultLibraryUpdatedAcrossLevels(self, request, workspace, editor, launcher_platform):
-        @fm.file_override("physxsystemconfiguration.setreg",
-                          "Material_DefaultLibraryUpdatedAcrossLevels_before.setreg",
-                          "AutomatedTesting",
-                          search_subdirs=True)
-        def levels_before(self, request, workspace, editor, launcher_platform):
-            from .tests.material import Material_DefaultLibraryUpdatedAcrossLevels_before as test_module_0
-            self._run_test(request, workspace, editor, test_module_0)
-
-        # File override replaces the previous physxconfiguration file with another where the only difference is the default material library
-        @fm.file_override("physxsystemconfiguration.setreg",
-                          "Material_DefaultLibraryUpdatedAcrossLevels_after.setreg",
-                          "AutomatedTesting",
-                          search_subdirs=True)
-        def levels_after(self, request, workspace, editor, launcher_platform):
-            from .tests.material import Material_DefaultLibraryUpdatedAcrossLevels_after as test_module_1
-            self._run_test(request, workspace, editor, test_module_1)
-
-        levels_before(self, request, workspace, editor, launcher_platform)
-        levels_after(self, request, workspace, editor, launcher_platform)

+ 0 - 205
AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Sandbox.py

@@ -15,31 +15,8 @@ from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorBatchedTest,
 
 sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
 
-from base import TestAutomationBase
-
 revert_physics_config = fm.file_revert_list(['physxdebugconfiguration.setreg', 'physxdefaultsceneconfiguration.setreg', 'physxsystemconfiguration.setreg'], 'AutomatedTesting/Registry')
 
[email protected]_sandbox
[email protected]("launcher_platform", ['windows_editor'])
[email protected]("project", ["AutomatedTesting"])
-class TestAutomation(TestAutomationBase):
-
-    ## Seems to be flaky, need to investigate
-    def test_ScriptCanvas_GetCollisionNameReturnsName(self, request, workspace, editor, launcher_platform):
-        from .tests.script_canvas import ScriptCanvas_GetCollisionNameReturnsName as test_module
-        # Fixme: expected_lines=["Layer Name: Right"]
-        self._run_test(request, workspace, editor, test_module)
-
-    ## Seems to be flaky, need to investigate
-    def test_ScriptCanvas_GetCollisionNameReturnsNothingWhenHasToggledLayer(self, request, workspace, editor, launcher_platform):
-        from .tests.script_canvas import ScriptCanvas_GetCollisionNameReturnsNothingWhenHasToggledLayer as test_module
-        # All groups present in the PhysX Collider that could show up in test
-        # Fixme: collision_groups = ["All", "None", "All_NoTouchBend", "All_3", "None_1", "All_NoTouchBend_1", "All_2", "None_1_1", "All_NoTouchBend_1_1", "All_1", "None_1_1_1", "All_NoTouchBend_1_1_1", "All_4", "None_1_1_1_1", "All_NoTouchBend_1_1_1_1", "GroupLeft", "GroupRight"]
-        # Fixme: for group in collision_groups:
-        # Fixme:    unexpected_lines.append(f"GroupName: {group}")
-        # Fixme: expected_lines=["GroupName: "]
-        self._run_test(request, workspace, editor, test_module)
-
 @pytest.mark.SUITE_main
 @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
 @pytest.mark.parametrize("project", ["AutomatedTesting"])
@@ -50,42 +27,12 @@ class EditorTestAutomation(EditorTestSuite):
     def get_number_parallel_editors():
         return 16
 
-    class RigidBody_EnablingGravityWorksUsingNotificationsPoC(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_EnablingGravityWorksUsingNotificationsPoC as test_module
-
-    class ForceRegion_LocalSpaceForceOnRigidBodies(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_LocalSpaceForceOnRigidBodies as test_module
-
-    class Collider_SameCollisionGroupDiffLayersCollide(EditorBatchedTest):
-        from .tests.collider import Collider_SameCollisionGroupDiffLayersCollide as test_module
-
-    class CharacterController_SwitchLevels(EditorBatchedTest):
-        from .tests.character_controller import CharacterController_SwitchLevels as test_module
-
-    class Ragdoll_AddPhysxRagdollComponentWorks(EditorBatchedTest):
-        from .tests.ragdoll import Ragdoll_AddPhysxRagdollComponentWorks as test_module
-
-    class ScriptCanvas_MultipleRaycastNode(EditorBatchedTest):
-        # Fixme: This test previously relied on unexpected lines log reading with is now not supported.
-        # Now the log reading must be done inside the test, preferably with the Tracer() utility
-        #  unexpected_lines = ["Assert"] + test_module.Lines.unexpected
-        from .tests.script_canvas import ScriptCanvas_MultipleRaycastNode as test_module
-
-    class Joints_HingeLeadFollowerCollide(EditorBatchedTest):
-        from .tests.joints import Joints_HingeLeadFollowerCollide as test_module
-
     class ShapeCollider_CylinderShapeCollides(EditorBatchedTest):
         from .tests.shape_collider import ShapeCollider_CylinderShapeCollides as test_module
 
-    class Collider_BoxShapeEditing(EditorBatchedTest):
-        from .tests.collider import Collider_BoxShapeEditing as test_module
-
     class Collider_SphereShapeEditing(EditorBatchedTest):
         from .tests.collider import Collider_SphereShapeEditing as test_module
 
-    class Collider_CapsuleShapeEditing(EditorBatchedTest):
-        from .tests.collider import Collider_CapsuleShapeEditing as test_module
-
     class Collider_PxMeshAutoAssignedWhenAddingRenderMeshComponent(EditorBatchedTest):
         from .tests.collider import Collider_PxMeshAutoAssignedWhenAddingRenderMeshComponent as test_module
 
@@ -100,155 +47,3 @@ class EditorTestAutomation(EditorTestSuite):
 
     class ShapeCollider_LargeNumberOfShapeCollidersWontCrashEditor(EditorBatchedTest):
         from .tests.shape_collider import ShapeCollider_LargeNumberOfShapeCollidersWontCrashEditor as test_module
-
-    class ForceRegion_WithNonTriggerColliderWarning(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_WithNonTriggerColliderWarning as test_module
-        # Fixme: expected_lines = ["[Warning] (PhysX Force Region) - Please ensure collider component marked as trigger exists in entity"]
-
-    class Terrain_NoPhysTerrainComponentNoCollision(EditorBatchedTest):
-        from .tests.terrain import Terrain_NoPhysTerrainComponentNoCollision as test_module
-
-    class RigidBody_InitialLinearVelocity(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_InitialLinearVelocity as test_module
-
-    class RigidBody_StartGravityEnabledWorks(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_StartGravityEnabledWorks as test_module
-
-    class RigidBody_KinematicModeWorks(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_KinematicModeWorks as test_module
-
-    class ForceRegion_SimpleDragForceOnRigidBodies(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_SimpleDragForceOnRigidBodies as test_module
-
-    class ForceRegion_CapsuleShapedForce(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_CapsuleShapedForce as test_module
-
-    class ForceRegion_ImpulsesCapsuleShapedRigidBody(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_ImpulsesCapsuleShapedRigidBody as test_module
-
-    class RigidBody_MomentOfInertiaManualSetting(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_MomentOfInertiaManualSetting as test_module
-
-    class RigidBody_COM_ManualSettingWorks(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_COM_ManualSettingWorks as test_module
-
-    class RigidBody_AddRigidBodyComponent(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_AddRigidBodyComponent as test_module
-
-    class ForceRegion_SplineForceOnRigidBodies(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_SplineForceOnRigidBodies as test_module
-
-    class Collider_ColliderPositionOffset(EditorBatchedTest):
-        from .tests.collider import Collider_ColliderPositionOffset as test_module
-
-    class RigidBody_AngularDampingAffectsRotation(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_AngularDampingAffectsRotation as test_module
-
-    class Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether(EditorBatchedTest):
-        from .tests import Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether as test_module
-
-    class ForceRegion_MultipleForcesInSameComponentCombineForces(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_MultipleForcesInSameComponentCombineForces as test_module
-
-    class ForceRegion_ImpulsesPxMeshShapedRigidBody(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_ImpulsesPxMeshShapedRigidBody as test_module
-
-    class ScriptCanvas_TriggerEvents(EditorBatchedTest):
-        from .tests.script_canvas import ScriptCanvas_TriggerEvents as test_module
-        # needs to be updated to log for unexpected lines
-        # expected_lines = test_module.LogLines.expected_lines
-
-    class ForceRegion_ZeroPointForceDoesNothing(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_ZeroPointForceDoesNothing as test_module
-
-    class ForceRegion_ZeroWorldSpaceForceDoesNothing(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_ZeroWorldSpaceForceDoesNothing as test_module
-
-    class ForceRegion_ZeroLinearDampingDoesNothing(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_ZeroLinearDampingDoesNothing as test_module
-
-    class ForceRegion_MovingForceRegionChangesNetForce(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_MovingForceRegionChangesNetForce as test_module
-
-    class ScriptCanvas_CollisionEvents(EditorBatchedTest):
-        from .tests.script_canvas import ScriptCanvas_CollisionEvents as test_module
-
-    class ForceRegion_DirectionHasNoAffectOnTotalForce(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_DirectionHasNoAffectOnTotalForce as test_module
-
-    class RigidBody_StartAsleepWorks(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_StartAsleepWorks as test_module
-
-    class ForceRegion_ZeroLocalSpaceForceDoesNothing(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_ZeroLocalSpaceForceDoesNothing as test_module
-
-    class ForceRegion_ZeroSimpleDragForceDoesNothing(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_ZeroSimpleDragForceDoesNothing as test_module
-
-    class RigidBody_COM_ComputingWorks(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_COM_ComputingWorks as test_module
-
-    class RigidBody_MassDifferentValuesWorks(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_MassDifferentValuesWorks as test_module
-
-    class ForceRegion_SplineRegionWithModifiedTransform(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_SplineRegionWithModifiedTransform as test_module
-
-    class RigidBody_InitialAngularVelocity(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_InitialAngularVelocity as test_module
-
-    class ForceRegion_ZeroSplineForceDoesNothing(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_ZeroSplineForceDoesNothing as test_module
-
-    class ForceRegion_PositionOffset(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_PositionOffset as test_module
-
-    class Ragdoll_LevelSwitchDoesNotCrash(EditorBatchedTest):
-        from .tests.ragdoll import Ragdoll_LevelSwitchDoesNotCrash as test_module
-
-    class ForceRegion_MultipleComponentsCombineForces(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_MultipleComponentsCombineForces as test_module
-
-    class RigidBody_COM_NotIncludesTriggerShapes(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_COM_NotIncludesTriggerShapes as test_module
-
-    class Material_NoEffectIfNoColliderShape(EditorBatchedTest):
-        from .tests.material import Material_NoEffectIfNoColliderShape as test_module
-
-    class RigidBody_SetGravityWorks(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_SetGravityWorks as test_module
-
-    class Material_EmptyLibraryUsesDefault(EditorBatchedTest):
-        from .tests.material import Material_EmptyLibraryUsesDefault as test_module
-
-    class ScriptCanvas_PostPhysicsUpdate(EditorBatchedTest):
-        from .tests.script_canvas import ScriptCanvas_PostPhysicsUpdate as test_module
-        # Note: Test needs to be updated to log for unexpected lines
-        # unexpected_lines = ["Assert"] + test_module.Lines.unexpected
-
-    class ForceRegion_PxMeshShapedForce(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_PxMeshShapedForce as test_module
-
-    class Joints_HingeSoftLimitsConstrained(EditorBatchedTest):
-        from .tests.joints import Joints_HingeSoftLimitsConstrained as test_module
-
-    class Joints_BallLeadFollowerCollide(EditorBatchedTest):
-        from .tests.joints import Joints_BallLeadFollowerCollide as test_module
-
-    class ForceRegion_SphereShapedForce(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_SphereShapedForce as test_module
-
-    class ForceRegion_RotationalOffset(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_RotationalOffset as test_module
-
-    class RigidBody_EnablingGravityWorksPoC(EditorBatchedTest):
-        from .tests.rigid_body import RigidBody_EnablingGravityWorksPoC as test_module
-
-    class ForceRegion_ParentChildForcesCombineForces(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_ParentChildForcesCombineForces as test_module
-
-    class ScriptCanvas_ShapeCast(EditorBatchedTest):
-        from .tests.script_canvas import ScriptCanvas_ShapeCast as test_module
-
-    class ForceRegion_PrefabFileInstantiates(EditorBatchedTest):
-        from .tests.force_region import ForceRegion_PrefabFileInstantiates as test_module

+ 0 - 14
AutomatedTesting/Gem/PythonTests/Physics/TestSuite_Utils.py

@@ -18,20 +18,6 @@ from base import TestAutomationBase
 @pytest.mark.parametrize("launcher_platform", ['windows_editor'])
 @pytest.mark.parametrize("project", ["AutomatedTesting"])
 class TestUtils(TestAutomationBase):
-    @fm.file_revert("UtilTest_Physmaterial_Editor_TestLibrary.physmaterial", r"AutomatedTesting\Levels\Physics\Physmaterial_Editor_Test")
-    def test_physmaterial_editor(self, request, workspace, launcher_platform, editor):
-        """
-        Tests functionality of physmaterial editing utility
-        :param workspace: Fixture containing platform and project detail
-        :param request: Built in pytest object, and is needed to call the pytest "addfinalizer" teardown command.
-        :editor: Fixture containing editor details
-        """
-        from .utils import UtilTest_Physmaterial_Editor as physmaterial_editor_test_module
-
-        expected_lines = []
-        unexpected_lines = ["Assert"]
-        self._run_test(request, workspace, editor, physmaterial_editor_test_module, expected_lines, unexpected_lines)
-
     def test_UtilTest_Tracer_PicksErrorsAndWarnings(self, request, workspace, launcher_platform, editor):
         from .utils import UtilTest_Tracer_PicksErrorsAndWarnings as testcase_module
         self._run_test(request, workspace, editor, testcase_module, [], [])

+ 1 - 1
AutomatedTesting/Gem/PythonTests/Physics/tests/EntityComponentTests/PhysX_Mesh_Collider_Component_CRUD.py

@@ -44,7 +44,7 @@ def PhysX_Mesh_Collider_Component_CRUD():
     from consts.physics import PHYSX_MESH_COLLIDER
 
     # 0) Pre-conditions
-    physx_mesh = os.path.join("objects", "_primitives", "_box_1x1.pxmesh")
+    physx_mesh = os.path.join("objects", "_primitives", "_box_1x1.fbx.pxmesh")
     physx_material = os.path.join("physx", "glass.physxmaterial")
 
     TestHelper.init_idle()

+ 0 - 95
AutomatedTesting/Gem/PythonTests/Physics/tests/Physics_UndoRedoWorksOnEntityWithPhysComponents.py

@@ -1,95 +0,0 @@
-"""
-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 ID : C15425929
-# Test Case Title : Verify that undo - redo operations do not create any error
-
-
-
-# fmt: off
-class Tests:
-    entity_found      = ("Entity was initially found",         "Entity COULD NOT be found initially")
-    entity_deleted    = ("Entity was deleted",                 "Entity WAS NOT deleted")
-    deletion_undone   = ("Undo worked",                        "Undo DID NOT work")
-    deletion_redone   = ("Redo worked",                        "Redo DID NOT work")
-    no_error_occurred = ("Undo/redo completed without errors", "An error occurred during undo/redo")
-# fmt: off
-
-
-def Physics_UndoRedoWorksOnEntityWithPhysComponents():
-    """
-    Summary:
-    Tests that no error messages arise when using the undo and redo functions in the editor.
-
-    Level Description:
-    DeleteMe - an entity that just exists above the terrain with a sphere shape component on it.
-
-    Steps:
-    1) Load level
-    2) Initially find the entity
-    3) Delete the entity
-    4) Undo the deletion
-    5) Redo the deletion
-    6) Look for errors
-    7) Close the editor
-
-    Expected Behavior:
-    The entity should be deleted, un-deleted, and re-deleted.
-
-    :return: None
-    """
-    import os
-    import sys
-
-    from editor_python_test_tools.wait_utils import PrefabWaiter
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    from editor_python_test_tools.utils import Tracer
-
-    import azlmbr.legacy.general as general
-
-    helper.init_idle()
-
-    # 1) Load the level
-    helper.open_level("Physics", "Physics_UndoRedoWorksOnEntityWithPhysComponents")
-
-    with Tracer() as error_tracer:
-        # Entity to delete and undo and re-delete
-        entity_name = "DeleteMe"
-
-        # 2) Find entity initially
-        entity_id = general.find_editor_entity(entity_name)
-        Report.critical_result(Tests.entity_found, entity_id.IsValid())
-
-        # 3) Delete entity
-        general.select_objects([entity_name])
-        general.delete_selected()
-        PrefabWaiter.wait_for_propagation()
-        entity_id = general.find_editor_entity(entity_name)
-        Report.result(Tests.entity_deleted, not entity_id.IsValid())
-
-        # 4) Undo deletion
-        general.undo()
-        PrefabWaiter.wait_for_propagation()
-        entity_id = general.find_editor_entity(entity_name)
-        Report.result(Tests.deletion_undone, entity_id.IsValid())
-
-        # 5) Redo deletion
-        general.redo()
-        PrefabWaiter.wait_for_propagation()
-        entity_id = general.find_editor_entity(entity_name)
-        Report.result(Tests.deletion_redone, not entity_id.IsValid())
-
-        # 6) Look for errors
-        helper.wait_for_condition(lambda: error_tracer.has_errors, 1.0)
-        Report.result(Tests.no_error_occurred, not error_tracer.has_errors)
-        
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Physics_UndoRedoWorksOnEntityWithPhysComponents)

+ 0 - 105
AutomatedTesting/Gem/PythonTests/Physics/tests/Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether.py

@@ -1,105 +0,0 @@
-"""
-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 ID : C5689529
-# Test Case Title : Create an entity with PhysX Terrain component and add
-#                   PhysX Rigid Body PhysX, PhysX Collider and Rendering Mesh to it and
-#                   verify that it works in game mode
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode = ("Entered game mode",                             "Failed to enter game mode")
-    find_entity     = ("Entity found",                                  "Entity not found")
-    gravity_enabled = ("Gravity is enabled",                            "Gravity is disabled") 
-    mass_equal      = ("Mass of rigid body equal to the expected mass", "Mass of rigid body not equal to the expected mass")
-    exit_game_mode  = ("Exited game mode",                              "Couldn't exit game mode")
-# fmt: on
-
-
-def Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether():
-
-    """
-    Summary:
-    Create an entity with PhysX Terrain component and add PhysX Rigid Body PhysX,
-    PhysX Collider and Rendering Mesh to it and verify that it works in game mode
-
-    Level Description:
-    PhysXRigidBody (entity) - Entity with components PhysX Rigid Body, PhysX Collider, Terrain and Rendering Mesh
-
-    Expected Behavior:
-    The rigid body entity should be working in the game mode.
-    We are checking if entity id is valid and extracting some properties of rigid body.
-    Also we are waiting for few frames to ensure that the editor did not crash.
-
-    Test Steps:
-     1) Open level
-     2) Enter game mode
-     3) Retrieve and validate entities
-     4) Waiting for WAIT_FRAMES to ensure that the editor did not crash in the game mode
-     5) Check the properties of rigid body like Gravity(enabled) and Mass(1.0kg)
-     6) Exit game mode
-     7) Close the editor
-
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Constants
-    WAIT_FRAMES = 2
-    EXPECTED_MASS = 1.0  # Default mass of a rigid body component
-
-    helper.init_idle()
-
-    # 1) Open level
-    helper.open_level("Physics", "Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve and validate entities
-    rigid_body_id = general.find_game_entity("PhysXRigidBody")
-    Report.critical_result(Tests.find_entity, rigid_body_id.IsValid())
-
-    class RigidBody:
-        gravity_enabled = False
-        collison_occued = False
-        mass = 0.0
-
-    # 4) Waiting for WAIT_FRAMES to ensure that the editor did not crash in the game mode
-    general.idle_wait_frames(WAIT_FRAMES)
-    Report.info("Editor did not crash after waiting for " + str(WAIT_FRAMES) + " frames")
-
-    # 5) Check the properties of rigid body like Gravity(enabled) and Mass(1.0kg)
-    RigidBody.gravity_enabled = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", rigid_body_id)
-    Report.critical_result(Tests.gravity_enabled, RigidBody.gravity_enabled)
-    RigidBody.mass = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetMass", rigid_body_id)
-    Report.critical_result(Tests.mass_equal, RigidBody.mass == EXPECTED_MASS)
-
-    # 6) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Physics_VerifyColliderRigidBodyMeshAndTerrainWorkTogether)

+ 0 - 83
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_AddingNewGroupWorks.py

@@ -1,83 +0,0 @@
-"""
-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 ID : C4976227
-# Test Case Title : Validate that a Collision Group can be added
-
-# Level has entity with custom collision group added.
-# If level enters game mode, collision group addition is validated.
-
-# fmt: off
-class Tests:
-    enter_game_mode = ("Entered game mode",                  "Failed to enter game mode")
-    find_sphere     = ("Sphere entity found",                "Sphere entity not found")
-    collision_group = ("Collision group addition validated", "Collision group addition not valid")
-    exit_game_mode  = ("Exited game mode",                   "Couldn't exit game mode")
-# fmt: on
-
-
-def Collider_AddingNewGroupWorks():
-    """
-    Summary:
-    Runs an automated test to ensure that a collision group can be added.
-
-    Level Description:
-    Sphere (Entity)  - PhysX Collider(shape:sphere): Collision Layer (Default), Collides With (Test_Group)
-
-    Test_Group (Collision Group) - Collision Group that is custom made for this test. 
-        Requires a custom ".physxconfiguration" file in addition to the level file
-
-    Expected Behavior:
-    When game mode is entered the entity id should be valid and position should be found
-
-    Test Steps:
-    1) Open Level
-    2) Enter game mode
-    3) Validate entities
-    4) Exit game mode
-    5) Close Editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    helper.init_idle()
-    # 1) Open Level
-    helper.open_level("Physics", "Collider_AddingNewGroupWorks")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Validate entities
-    sphere_id = general.find_game_entity("Sphere")
-
-    Report.result(Tests.find_sphere, sphere_id.IsValid())
-
-    sphere_position = None
-    sphere_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", sphere_id)
-
-    Report.result(Tests.collision_group, sphere_id.isValid() and sphere_position != None)
-
-    # 4) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_AddingNewGroupWorks)

+ 0 - 107
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_BoxShapeEditing.py

@@ -1,107 +0,0 @@
-"""
-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 ID : C4982801
-Test Case Title : Verify that the shape Box can be selected from drop downlist and the value for its dimensions in x,y,z can be set after that
-
-"""
-
-
-# fmt: off
-class Tests():
-    entity_created           = ("Test Entity created successfully",          "Failed to create Test Entity")
-    collider_added           = ("PhysX Primitive Collider added successfully",         "Failed to add PhysX Primitive Collider")
-    collider_shape_changed   = ("PhysX Primitive Collider shape changed successfully", "Failed change PhysX Primitive Collider shape")
-    shape_dimensions_changed = ("Shape dimensions modified successfully",    "Failed to modify Shape dimensions")
-# fmt: on
-
-
-def Collider_BoxShapeEditing():
-    """
-    Summary:
-     Adding PhysX Primitive Collider and Shape components to test entity, then attempting to modify the shape's dimensions
-
-    Expected Behavior:
-     Box shape can be selected for the Shape Component and the value for X, Y, and Z dimensions can be changed
-
-    Test Steps:
-     1) Load the empty level
-     2) Create the test entity
-     3) Add PhysX Primitive Collider component to test entity
-     4) Change the PhysX Primitive Collider shape and store the original dimensions
-     5) Modify the dimensions
-     6) Verify they have been changed
-
-    Note:
-     - This test file must be called from the Open 3D Engine Editor command terminal
-     - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    # Helper Files
-
-    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 consts.physics import PHYSX_PRIMITIVE_COLLIDER
-
-    # Open 3D Engine Imports
-    import azlmbr.math as math
-
-    BOX_SHAPETYPE_ENUM = 1
-    SET_SIZE = 2.5
-    SIZE_TOLERANCE = 0.5
-
-    def check_dimensions_changed(set_dimension_value, modified_dimensions, tolerance):
-        def compare_values(value_name, set_value, grabbed_value, tolerance):
-            within_tolerance = math.Math_IsClose(set_value, grabbed_value, tolerance)
-            if not within_tolerance:
-                assert (
-                    False
-                ), f"The modified value for {value_name} was not within the allowed tolerance\nExpected:{set_value}\nActual: {grabbed_value}"
-            return within_tolerance
-
-        # Check for X, Y, & Z values
-        x_value = compare_values("x_value", set_dimension_value, modified_dimensions.x, tolerance)
-        y_value = compare_values("y_value", set_dimension_value, modified_dimensions.y, tolerance)
-        z_value = compare_values("z_value", set_dimension_value, modified_dimensions.z, tolerance)
-
-        return x_value and y_value and z_value
-
-    helper.init_idle()
-    # 1) Load the empty level
-    helper.open_level("", "Base")
-
-    # 2) Create the test entity
-    test_entity = Entity.create_editor_entity("Test Entity")
-    test_entity.add_component("PhysX Static Rigid Body")
-    Report.result(Tests.entity_created, test_entity.id.IsValid())
-
-    # 3) Add PhysX Primitive Collider component to test entity
-    test_component = test_entity.add_component(PHYSX_PRIMITIVE_COLLIDER)
-    Report.result(Tests.collider_added, test_entity.has_component(PHYSX_PRIMITIVE_COLLIDER))
-
-    # 4) Change the PhysX Primitive Collider shape and store the original dimensions
-    test_component.set_component_property_value("Shape Configuration|Shape", BOX_SHAPETYPE_ENUM)
-    add_check = test_component.get_component_property_value("Shape Configuration|Shape") == BOX_SHAPETYPE_ENUM
-    Report.result(Tests.collider_shape_changed, add_check)
-
-    # 5) Modify the dimensions
-    Report.info(f"Attempting to set XYZ values to {SET_SIZE}")
-    test_component.set_component_property_value(
-        "Shape Configuration|Box|Dimensions", math.Vector3(SET_SIZE, SET_SIZE, SET_SIZE)
-    )
-    mod_dimensions = test_component.get_component_property_value("Shape Configuration|Box|Dimensions")
-
-    # 6) Verify they have been changed
-    dimensions_successfully_changed = check_dimensions_changed(SET_SIZE, mod_dimensions, SIZE_TOLERANCE)
-    Report.result(Tests.shape_dimensions_changed, dimensions_successfully_changed)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_BoxShapeEditing)

+ 0 - 107
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_CapsuleShapeEditing.py

@@ -1,107 +0,0 @@
-"""
-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 ID : C4982802
-Test Case Title : Verify that the shape capsule can be selected from drop downlist and the value for its height and radius can be set after that
-
-"""
-
-
-# fmt: off
-class Tests():
-    entity_created           = ("Test Entity created successfully",          "Failed to create Test Entity")
-    collider_added           = ("PhysX Primitive Collider added successfully",         "Failed to add PhysX Primitive Collider")
-    collider_shape_changed   = ("PhysX Primitive Collider shape changed successfully", "Failed change PhysX Primitive Collider shape")
-    shape_dimensions_changed = ("Shape dimensions modified successfully",    "Failed to modify Shape dimensions")
-# fmt: on
-
-
-def Collider_CapsuleShapeEditing():
-    """
-    Summary:
-     Adding PhysX Primitive Collider and Shape components to test entity, then attempting to modify the shape's dimensions
-
-    Expected Behavior:
-     Capsule shape can be selected for the Shape Component and the value for Height and Radius can be changed
-
-    Test Steps:
-     1) Load the empty level
-     2) Create the test entity
-     3) Add PhysX Primitive Collider component to test entity
-     4) Change the PhysX Primitive Collider shape
-     5) Modify the dimensions
-     6) Verify they have been changed
-
-    Note:
-     - This test file must be called from the Open 3D Engine Editor command terminal
-     - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    # Helper Files
-
-    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 consts.physics import PHYSX_PRIMITIVE_COLLIDER
-
-    # Open 3D Engine Imports
-    import azlmbr.math as math
-
-    CAPSULE_SHAPETYPE_ENUM = 2
-    # Note from Editor Console: Height must exceed twice the radius in capsule configuration
-    SIZE_RADIUS = 4.0
-    SIZE_HEIGHT = SIZE_RADIUS * 2 + 1.0
-    SIZE_TOLERANCE = 0.5
-
-    def change_dimension_value(component, component_property_path, value):
-        Report.info(f"Attempting to set value for {component_property_path} to {value}")
-        component.set_component_property_value(component_property_path, value)
-        returning_value = component.get_component_property_value(component_property_path)
-        Report.info(f"Value for {component_property_path} is currently {returning_value}")
-        return returning_value
-
-    def check_dimension_change(value_name, value_set, grabbed_value, tolerance):
-        within_tolerance = math.Math_IsClose(value_set, grabbed_value, tolerance)
-        if not within_tolerance:
-            assert (
-                False
-            ), f"The modified value for {value_name} was not within the allowed tolerance\nExpected:{value_set}\nActual: {grabbed_value}"
-        return within_tolerance
-
-    helper.init_idle()
-    # 1) Load the empty level
-    helper.open_level("", "Base")
-
-    # 2) Create the test entity
-    test_entity = Entity.create_editor_entity("Test Entity")
-    test_entity.add_component("PhysX Static Rigid Body")
-    Report.result(Tests.entity_created, test_entity.id.IsValid())
-
-    # 3) Add PhysX Primitive Collider component to test entity
-    test_component = test_entity.add_component(PHYSX_PRIMITIVE_COLLIDER)
-    Report.result(Tests.collider_added, test_entity.has_component(PHYSX_PRIMITIVE_COLLIDER))
-
-    # 4) Change the PhysX Primitive Collider shape
-    test_component.set_component_property_value("Shape Configuration|Shape", CAPSULE_SHAPETYPE_ENUM)
-    add_check = test_component.get_component_property_value("Shape Configuration|Shape") == CAPSULE_SHAPETYPE_ENUM
-    Report.result(Tests.collider_shape_changed, add_check)
-
-    # 5) Modify the dimensions
-    mod_height = change_dimension_value(test_component, "Shape Configuration|Capsule|Height", SIZE_HEIGHT)
-    mod_radius = change_dimension_value(test_component, "Shape Configuration|Capsule|Radius", SIZE_RADIUS)
-
-    # 6) Verify they have been changed
-    resulting_check = check_dimension_change(
-        "Height", SIZE_HEIGHT, mod_height, SIZE_TOLERANCE
-    ) and check_dimension_change("Radius", SIZE_RADIUS, mod_radius, SIZE_TOLERANCE)
-    Report.result(Tests.shape_dimensions_changed, resulting_check)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_CapsuleShapeEditing)

+ 0 - 334
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_ColliderPositionOffset.py

@@ -1,334 +0,0 @@
-"""
-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 ID : C4982797
-# Test Case Title : Check that collision offsets trigger collision events,
-#                   not entity transform locations
-
-
-
-# fmt: off
-class Tests:
-    enter_game_mode       = ("Entered game mode",                                     "Failed to enter game mode")
-    boxes_found           = ("All boxes were validated",                              "Couldn't validate at least one box")
-    spheres_found         = ("All spheres were validated",                            "Not all the spheres could be validated")
-    test_completed        = ("The test completed",                                    "The test timed out")
-    target_spheres_passed = ("All spheres intended to collide with Target Boxes DID", "At least one sphere intended to collide with a Target Box DID NOT")
-    pass_spheres_passed   = ("All spheres intended to pass through Target Boxes DID", "At least one sphere intended to pass through a Target Box DID NOT")
-    exit_game_mode        = ("Exited game mode",                                      "Couldn't exit game mode")
-
-# fmt: on
-
-
-def Collider_ColliderPositionOffset():
-    # type: () -> None
-    """
-    Summary:
-    Runs an automated test to ensure that PhysXCollider offsets work properly. Collisions should be
-    calculated based on the location of the colliders, not the geometry of the entity's Transform
-
-    Level Description:
-    There are five classes of entities in the level: Target Spheres, Pass Spheres, Target Boxes, Pass Boxes
-    and Fail Boxes. All entities have gravity disabled, are positioned above the terrain, and have the same
-    collision group/layer (Default/All).
-
-    Target Boxes: These are the actual boxes that have their colliders offset. There are three of these
-        boxes, one for each offset axis (rightly labeled Box_[X, Y, or Z]_Target).
-
-    Target Spheres: These spheres are positioned near the Target Boxes' collision offset areas. These entities are
-        initialized with a velocity that will send them on course to collide with the collision geometry for the
-        Target Boxes. They are appropriately labeled for which Target box they are to collide with
-        Sphere_[X, Y, or Z]_Target
-
-    Pass Spheres: The spheres are positioned near the Target Boxes as well, and are also initialized with a velocity
-        that will will send them towards their Target Box. The difference here is that they aligned to "collide"
-        with their Target Box's actual transform (not their collider offset). They too are appropriately named
-        Sphere_[X, Y, or Z]_Pass
-
-    Pass Boxes: Pass Boxes are positioned on the other side of the Pass Spheres from their target Box. They serve
-        as a trigger to register that the Pass Sphere successfully passed through the respective Target Box's
-        transform geometry. They are rightfully named Box_[X, Y, or Z]_Pass
-
-    Fail Boxes: Fail boxes (like Pass Boxes) are positioned on the other side of their respective Target Box,
-        but they are arranged opposite the Target Sphere (rather than the Pass Sphere). They act as a fail safe
-        if the Target Sphere happens the pass through the Target Box's collider offset. They are named following the
-        same convention: Box_[X, Y, or Z]_Fail
-
-    Note: All boxes are set to "kinematic" so they do not move when a collision happens.
-
-    Expected Behavior:
-    Upon entering game mode, the spheres should follow their initial velocities. The Target Spheres should collide and
-    bounce off of the Target Boxes' collision offsets, and the Pass Spheres should pass through the visible transforms
-    of their Target Boxes and collide with their respective Pass Boxes.
-
-    Test Steps:
-    1) Loads the level
-    2) Enters game mode
-    3) Retrieve and validate entities
-    4) Ensures that the test objects are located
-    5) Wait for test to complete or time out
-    6) Log the results
-    7) Exit game mode and editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    # System imports
-    import os
-    import sys
-
-    # Internal editor imports
-
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-    import azlmbr
-
-    # ******** Global Variables ********
-
-    # Entity data organization class
-    class EntityData:
-        def __init__(self, name):
-            self.name = name
-            self.id = None
-            self.init_pos = None
-            self.current_pos = None
-            self.result = None
-
-    # fmt: off
-    # Establish entity sets
-    target_spheres = [EntityData("Sphere_X_Target"), EntityData("Sphere_Y_Target"), EntityData("Sphere_Z_Target")]
-    pass_spheres   = [EntityData("Sphere_X_Pass"),   EntityData("Sphere_Y_Pass"),   EntityData("Sphere_Z_Pass")]
-    target_boxes   = [EntityData("Box_X_Target"),    EntityData("Box_Y_Target"),    EntityData("Box_Z_Target")]
-    pass_boxes     = [EntityData("Box_X_Pass"),      EntityData("Box_Y_Pass"),      EntityData("Box_Z_Pass")]
-    fail_boxes     = [EntityData("Box_X_Fail"),      EntityData("Box_Y_Fail"),      EntityData("Box_Z_Fail")]
-
-    all_spheres = target_spheres + pass_spheres
-    all_boxes = pass_boxes + fail_boxes + target_boxes
-    all_entities = all_spheres + all_boxes
-
-    # Maps a Sphere to its last anticipated collision/position (by name)
-    final_expected_collisions = {
-        "Sphere_X_Target": "Box_X_Fail",
-        "Sphere_Y_Target": "Box_Y_Fail",
-        "Sphere_Z_Target": "Box_Z_Fail",
-        "Sphere_X_Pass":   "Box_X_Pass",
-        "Sphere_Y_Pass":   "Box_Y_Pass",
-        "Sphere_Z_Pass":   "Box_Z_Pass",
-    }
-
-    # Possible results
-    PASS   = "pass"
-    FAIL   = "fail"
-    TARGET = "target"
-    # fmt: on
-
-    # ******** Helper Functions ********
-
-    # Validate entities' IDs and initial positions.
-    #   Fast Fails if there are any problems retrieving vital information
-    def validate_entities(entity_list, test_tuple):
-        # type: ([EntityData], (str, str)) -> None
-        passed = True
-        for entity in entity_list:
-            valid = True
-            entity.id = general.find_game_entity(entity.name)
-            if not entity.id.IsValid():
-                valid = False
-                Report.info("Entity: {} could not be validated".format(entity.name))
-            entity.init_pos = entity.current_pos = azlmbr.components.TransformBus(
-                azlmbr.bus.Event, "GetWorldTranslation", entity.id
-            )
-
-            if entity.init_pos is None or entity.init_pos.IsZero():
-                valid = False
-                Report.info("Entity: {}'s initial position could not be found".format(entity.name))
-
-            if not valid:
-                passed = False
-                break
-        Report.critical_result(test_tuple, passed)
-
-    # Updates entities' current position
-    def update_positions(entity_list):
-        # type: ([EntityData]) -> None
-        for entity in entity_list:
-            entity.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", entity.id)
-
-    # Looks for implicit failure cases for moving spheres
-    #   by checking if they have moved through their "final expected collision" object
-    def check_for_failure(sphere_entities):
-        # type: ([EntityData]) -> None
-        for sphere in sphere_entities:
-            expected_name = final_expected_collisions[sphere.name]
-            expected_entity_list = [entity for entity in all_entities if entity.name == expected_name]
-            if len(expected_entity_list) == 0:
-                # Just in case we can't find the entity's "final expected collision" entity
-                Report.info("Failed finding {} in expected entities list:".format(expected_name))
-                Report.info("  {}".format(expected_entity_list))
-                helper.fail_fast()
-            expected_entity = expected_entity_list[0]
-            if sphere.result != FAIL and has_passed_through(sphere, expected_entity):
-                sphere.result = FAIL
-                Report.info("{} has unexpectedly passed through {}".format(sphere.name, expected_name))
-
-    # Checks for unexpected movement in stationary objects
-    #   Fast Fails and writes to the log if there is a difference between initial position and current position
-    def check_for_unexpected_movement(entity_list):
-        # type: ([EntityData]) -> None
-        for entity in entity_list:
-            if not entity.init_pos.IsClose(entity.current_pos, CLOSE_ENOUGH_THRESHOLD):
-                helper.fail_fast("{} has unexpectedly moved".format(entity.name))
-
-    # Verifies the results for the entities passed in.
-    #   Returns a count of the verified results
-    def verify_results(entity_list, expected_result):
-        # type: ([EntityData], str) -> int
-        results_verified = 0
-        for entity in entity_list:
-            if entity.result == expected_result:
-                results_verified += 1
-            else:
-                Report.info("{} had unexpected result: {}".format(entity.name, entity.result))
-        return results_verified
-
-    # Batch assign event handlers
-    def set_handlers(entity_list, callback, event="OnCollisionBegin"):
-        # type: ([EntityData], function, str) -> [handler]
-        handlers = []
-        for entity in entity_list:
-            handler = azlmbr.physics.CollisionNotificationBusHandler()
-            handler.connect(entity.id)
-            handler.add_callback(event, callback)
-            handlers.append(handler)
-        return handlers
-
-    # Checks to see if we are done collecting results for the test
-    def done_collecting_results(entity_list, num_results):
-        # type: ([EntityData], int) -> bool
-        result_count = 0
-        for entity in entity_list:
-            if entity.result is not None:
-                result_count += 1
-
-        # When all spheres have a result we are done
-        return result_count == num_results
-
-    # Checks if a moving entity has passed through a stationary entity.
-    #   There is an assumption that the stationary entity should not have substantial movement
-    def has_passed_through(moving_entity, stationary_entity):
-        # type: (EntityData, EntityData) -> bool
-        init_diff = stationary_entity.init_pos.Subtract(moving_entity.init_pos).Unary()
-        current_diff = stationary_entity.current_pos.Subtract(moving_entity.current_pos).Unary()
-        angle = init_diff.AngleSafeDeg(current_diff)
-        # Angle > 90 degrees represents a change of sides
-        result = angle > 90.0
-        return result
-
-    def test_completed():
-        update_positions(all_entities)
-        check_for_failure(all_spheres)
-        check_for_unexpected_movement(all_boxes)
-        return done_collecting_results(all_spheres, TOTAL_SPHERES)
-
-    # ******** Event Handlers ********
-
-    # General collision handler
-    def on_collision_begin(collider_id, result):
-        # type: (EntityId, str) -> None
-        for sphere in all_spheres:
-            if sphere.id.Equal(collider_id):
-                Report.info("Entity: {} collided with a {} box".format(sphere.name, result))
-                if result is FAIL or sphere.result is None:
-                    # Set result if not set yet OR the result is a failure (failure overrides success)
-                    sphere.result = result
-                return
-        # It wasn't a sphere that collided, something went wrong
-        if collider_id.IsValid():
-            entity_name = azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "GetEntityName", collider_id)
-            Report.info("{} box collided with unexpected entity: {}".format(result, entity_name))
-
-    # Fail Box collision event handler
-    def on_collision_begin_fail_box(args):
-        # type: ([EntityId, ...]) -> None
-        on_collision_begin(args[0], FAIL)
-
-    # Success Box Collision Event Handler
-    def on_collision_begin_pass_box(args):
-        # type: ([EntityId, ...]) -> None
-        on_collision_begin(args[0], PASS)
-
-    # Target box collision event handler
-    def on_collision_begin_target_box(args):
-        # type: ([EntityId, ...]) -> None
-        on_collision_begin(args[0], TARGET)
-
-    # ******** Execution Code *********
-
-    # Local Constants
-    TIME_OUT = 2.0
-    CLOSE_ENOUGH_THRESHOLD = 0.1
-
-    TOTAL_TARGET_SPHERES = 3
-    TOTAL_PASS_SPHERES = 3
-    TOTAL_SPHERES = TOTAL_TARGET_SPHERES + TOTAL_PASS_SPHERES
-
-    helper.init_idle()
-
-    # 1) Open level
-    helper.open_level("Physics", "Collider_ColliderPositionOffset")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve and validate entities
-    validate_entities(all_boxes, Tests.boxes_found)
-    validate_entities(all_spheres, Tests.spheres_found)
-
-    # Assign handlers
-    handlers = []
-    handlers = handlers + set_handlers(fail_boxes, on_collision_begin_fail_box)
-    handlers = handlers + set_handlers(pass_boxes, on_collision_begin_pass_box)
-    handlers = handlers + set_handlers(target_boxes, on_collision_begin_target_box)
-
-    # 4) Wait for either time out or for the test to complete
-    Report.result(Tests.test_completed, helper.wait_for_condition(test_completed, TIME_OUT))
-
-    # 5) Log results
-    # Verify entities results
-    pass_spheres_passed = verify_results(pass_spheres, PASS)
-    target_spheres_passed = verify_results(target_spheres, TARGET)
-
-    # Report results
-    Report.result(Tests.target_spheres_passed, target_spheres_passed == TOTAL_TARGET_SPHERES)
-    Report.result(Tests.pass_spheres_passed, pass_spheres_passed == TOTAL_PASS_SPHERES)
-
-    # Data dump at bottom of log
-    Report.info("******** Collected Data *********")
-    for entity in all_entities:
-        Report.info("Entity: {}".format(entity.name))
-        Report.info_vector3(entity.init_pos, " Initial position:")
-        Report.info_vector3(entity.current_pos, " Final position:")
-        Report.info(" Result: {}".format(entity.result))
-        Report.info("********************************")
-
-    # 6) Exit Game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-    Report.info("*** FINISHED TEST ***")
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_ColliderPositionOffset)

+ 0 - 302
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_ColliderRotationOffset.py

@@ -1,302 +0,0 @@
-"""
-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 ID : C4982798
-# Test Case Title : Verify that when the x,y,z values are defined in the offset, the collider frame
-#                   rotates from its original orientation in the direction defined by the x,y,z units
-
-
-
-import os
-import sys
-
-
-# fmt: off
-class Tests:
-    enter_game_mode       = ("Entered game mode",                                     "Failed to enter game mode")
-    boxes_found           = ("All boxes were found",                                  "Couldn't find at least one box")
-    spheres_found         = ("All spheres were found",                                "Not all the spheres could be found")
-    test_completed        = ("The test completed",                                    "The test timed out")
-    target_spheres_passed = ("All spheres intended to collide with Target Boxes DID", "At least one sphere intended to collide with a Target Box DID NOT")
-    pass_thru_spheres_passed   = ("All spheres intended to pass through Target Boxes DID", "At least one sphere intended to pass through a Target Box DID NOT")
-    exit_game_mode        = ("Exited game mode",                                      "Couldn't exit game mode")
-
-# fmt: on
-
-
-def Collider_ColliderRotationOffset():
-    # type: () -> None
-    """
-    Summary:
-    Runs an automated test to ensure that PhysXCollider rotational offsets work properly. Collisions should be
-    calculated based on the location of the colliders, including their rotational offsets in x, y, and/or z
-
-    Level Description:
-    There are five classes of entities in the level: Target Spheres, Pass Spheres, Target Boxes, Pass Boxes
-    and Fail Boxes. All entities have gravity disabled, are positioned above the terrain, and have the same
-    collision group/layer (Default/All).
-
-    Target Boxes: These are the actual boxes that have their collider offsets rotated by 90 degrees.
-        There are three of these boxes, one for each rotation axis (rightly labeled Box_[X, Y, or Z]_Target).
-
-    Target Spheres: These spheres are positioned near the Target Boxes' rotated collision areas. These entities are
-        initialized with a velocity that will send them on course to collide with the collision geometry for the
-        Target Boxes. They are appropriately labeled for which Target box they are to collide with
-        Sphere_[X, Y, or Z]_Target
-
-    Pass Thru Spheres: These spheres are positioned near the Target Boxes as well, and are also initialized with a
-        velocity that will will send them towards their Target Box. The difference here is that they are aligned to
-        "collide" with their Target Box's actual transform (not their rotated collider). They too are appropriately
-        named Sphere_[X, Y, or Z]_Pass
-
-    Pass Thru Boxes: Pass Boxes are positioned on the other side of the Pass Spheres from their target Box. They serve
-        as a trigger to register that the Pass Sphere successfully passed through the respective Target Box's
-        transform geometry. They are rightfully named Box_[X, Y, or Z]_Pass
-
-    Fail Boxes: Fail boxes (like Pass Boxes) are positioned on the other side of their respective Target Box,
-        but they are arranged opposite the Target Sphere (rather than the Pass Sphere). They act as a fail condition
-        if the Target Sphere happens the pass through the Target Box's rotated collider. They are named following the
-        same convention: Box_[X, Y, or Z]_Fail
-
-    Note: All boxes are set to "kinematic" so they do not move when a collision happens.
-
-    Expected Behavior:
-    Upon entering game mode, the spheres should follow their initial velocities. The Target Spheres should collide and
-    bounce off of the Target Boxes' rotated colliders, and the Pass Spheres should pass through the visible transforms
-    of their Target Boxes and collide with their respective Pass Boxes.
-
-    Test Steps:
-    1) Loads the level
-    2) Enters game mode
-    3) Retrieve and validate entities and starting locations
-    4) Wait for test to complete or time out
-    5) Log the results
-    6) Exit game mode and editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-
-
-
-    # Internal editor imports
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-    import azlmbr
-
-    # ******** Global Variables ********
-
-    # Entity data organization class
-    class EntityData:
-        def __init__(self, name):
-            self.name = name
-            self.id = None
-            self.init_pos = None
-            self.current_pos = None
-            self.result = None
-
-    # fmt: off
-    # Establish entity sets
-    target_spheres    = [EntityData("Sphere_X_Target"),    EntityData("Sphere_Y_Target"),    EntityData("Sphere_Z_Target")]
-    pass_thru_spheres = [EntityData("Sphere_X_Pass_Thru"), EntityData("Sphere_Y_Pass_Thru"), EntityData("Sphere_Z_Pass_Thru")]
-    target_boxes      = [EntityData("Box_X_Target"),       EntityData("Box_Y_Target"),       EntityData("Box_Z_Target")]
-    pass_thru_boxes   = [EntityData("Box_X_Pass_Thru"),    EntityData("Box_Y_Pass_Thru"),    EntityData("Box_Z_Pass_Thru")]
-    fail_boxes        = [EntityData("Box_X_Fail"),         EntityData("Box_Y_Fail"),         EntityData("Box_Z_Fail")]
-
-    all_spheres = target_spheres + pass_thru_spheres
-    all_boxes = pass_thru_boxes + fail_boxes + target_boxes
-    all_entities = all_spheres + all_boxes
-
-    # Possible results
-    PASS_THRU =   "pass thru"
-    FAIL =        "fail"
-    TARGET =      "target"
-    # fmt: on
-
-    # ******** Helper Functions ********
-
-    # Retrieve entities' IDs and initial positions.
-    #   Fast Fails if there are any problems retrieving vital information
-    def retrieve_entities(entity_list, test_tuple):
-        # type: ([EntityData], (str, str)) -> None
-        passed = True
-        for entity in entity_list:
-            valid = True
-            entity.id = general.find_game_entity(entity.name)
-            if not entity.id.IsValid():
-                valid = False
-                Report.info("Entity: {} could not be found".format(entity.name))
-            entity.init_pos = entity.current_pos = azlmbr.components.TransformBus(
-                azlmbr.bus.Event, "GetWorldTranslation", entity.id
-            )
-
-            if entity.init_pos is None or entity.init_pos.IsZero():
-                valid = False
-                Report.info("Entity: {}'s initial position could not be found".format(entity.name))
-
-            if not valid:
-                passed = False
-                break
-        Report.critical_result(test_tuple, passed)
-
-    # Updates entities' current position
-    def refresh_positions(entity_list):
-        # type: ([EntityData]) -> None
-        for entity in entity_list:
-            entity.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", entity.id)
-
-    # Checks for unexpected movement in stationary objects
-    #   Fast Fails and writes to the log if there is a difference between initial position and current position
-    def check_for_unexpected_movement(entity_list):
-        # type: ([EntityData]) -> None
-        for entity in entity_list:
-            if not entity.init_pos.IsClose(entity.current_pos, CLOSE_ENOUGH_THRESHOLD):
-                helper.fail_fast("{} has unexpectedly moved".format(entity.name))
-
-    # Verifies the results for the entities passed in.
-    #   Returns a count of the verified results
-    def verify_results(entity_list, expected_result):
-        # type: ([EntityData], str) -> int
-        results_verified = 0
-        for entity in entity_list:
-            if entity.result == expected_result:
-                results_verified += 1
-            else:
-                Report.info("{} had unexpected result:".format(entity.name))
-                Report.info("  expected: {}".format(expected_result))
-                Report.info("  found: {}".format(entity.result))
-        return results_verified
-
-    # Batch assign event handlers
-    def set_handlers(entity_list, callback, event="OnCollisionBegin"):
-        # type: ([EntityData], function, str) -> [handler]
-        handlers = []
-        for entity in entity_list:
-            handler = azlmbr.physics.CollisionNotificationBusHandler()
-            handler.connect(entity.id)
-            handler.add_callback(event, callback)
-            handlers.append(handler)
-        return handlers
-
-    # Checks to see if we are done collecting results for the test
-    def done_collecting_results(entity_list, num_results):
-        # type: ([EntityData], int) -> bool
-        result_count = 0
-        for entity in entity_list:
-            if entity.result is not None:
-                result_count += 1
-
-        # When all spheres have a result we are done
-        return result_count == num_results
-
-    # Callback function to be passed to wait_for_condition
-    # Updates game entities' data, checks for failures and unexpected results,
-    # then returns True if we are done observing the test.
-    def test_completed():
-        refresh_positions(all_entities)
-        # check_for_failure(all_spheres)
-        check_for_unexpected_movement(all_boxes)
-        return done_collecting_results(all_spheres, TOTAL_SPHERES)
-
-    # ******** Event Handlers ********
-
-    # General collision handler
-    def on_collision_begin(collider_id, result):
-        # type: (EntityId, str) -> None
-        for sphere in all_spheres:
-            if sphere.id.Equal(collider_id):
-                Report.info("Entity: {} collided with a {} box".format(sphere.name, result))
-                if result is FAIL or sphere.result is None:
-                    # Set result if not set yet OR the result is a failure (failure overrides success)
-                    sphere.result = result
-                return
-        # It wasn't a sphere that collided, something went wrong
-        if collider_id.IsValid():
-            entity_name = azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "GetEntityName", collider_id)
-            Report.info("{} box collided with unexpected entity: {}".format(result, entity_name))
-
-    # Fail Box collision event handler
-    def on_collision_begin_fail_box(args):
-        # type: ([EntityId, ...]) -> None
-        on_collision_begin(args[0], FAIL)
-
-    # Success Box Collision Event Handler
-    def on_collision_begin_pass_thru_box(args):
-        # type: ([EntityId, ...]) -> None
-        on_collision_begin(args[0], PASS_THRU)
-
-    # Target box collision event handler
-    def on_collision_begin_target_box(args):
-        # type: ([EntityId, ...]) -> None
-        on_collision_begin(args[0], TARGET)
-
-    # ******** Execution Code *********
-
-    # Local Constants
-    TIME_OUT = 2.0
-    CLOSE_ENOUGH_THRESHOLD = 0.0001
-
-    TOTAL_TARGET_SPHERES = 3
-    TOTAL_PASS_THRU_SPHERES = 3
-    TOTAL_SPHERES = TOTAL_TARGET_SPHERES + TOTAL_PASS_THRU_SPHERES
-
-    helper.init_idle()
-
-    # 1) Open level
-    helper.open_level("Physics", "Collider_ColliderRotationOffset")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve and validate entities
-    retrieve_entities(all_boxes, Tests.boxes_found)
-    retrieve_entities(all_spheres, Tests.spheres_found)
-
-    # Assign handlers
-    handlers = []
-    handlers.extend(set_handlers(fail_boxes, on_collision_begin_fail_box))
-    handlers.extend(set_handlers(pass_thru_boxes, on_collision_begin_pass_thru_box))
-    handlers.extend(set_handlers(target_boxes, on_collision_begin_target_box))
-
-    # 4) Wait for either time out or for the test to complete
-    Report.result(Tests.test_completed, helper.wait_for_condition(test_completed, TIME_OUT))
-
-    # 5) Log results
-    # Verify entities results
-    pass_thru_spheres_passed = verify_results(pass_thru_spheres, PASS_THRU)
-    target_spheres_passed = verify_results(target_spheres, TARGET)
-
-    # Report results
-    Report.result(Tests.target_spheres_passed, target_spheres_passed == TOTAL_TARGET_SPHERES)
-    Report.result(Tests.pass_thru_spheres_passed, pass_thru_spheres_passed == TOTAL_PASS_THRU_SPHERES)
-
-    # Data dump at bottom of log
-    Report.info("******** Collected Data *********")
-    for entity in all_entities:
-        Report.info("Entity: {}".format(entity.name))
-        Report.info_vector3(entity.init_pos, " Initial position:")
-        Report.info_vector3(entity.current_pos, " Final position:")
-        Report.info(" Result: {}".format(entity.result))
-        Report.info("********************************")
-
-    # 6) Exit Game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-    Report.info("*** FINISHED TEST ***")
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_ColliderRotationOffset)

+ 0 - 361
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_CollisionGroupsWorkflow.py

@@ -1,361 +0,0 @@
-"""
-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 ID : C3510644
-# Test Case Title : Check that the collision layer and collision group of the terrain can be changed
-#     and the collision behavior of the terrain changes accordingly
-
-
-# fmt: off
-class Tests:
-    enter_game_mode                       = ("Entered game mode",                     "Failed to enter game mode")
-    box_1_a_valid                         = ("Box 1 A has been validated",            "Box 1 A COULD NOT be validated")
-    box_2_a_valid                         = ("Box 2 A has been validated",            "Box 2 A COULD NOT be validated")
-    terrain_a_valid                       = ("Terrain A has been validated",          "Terrain A COULD NOT be validated")
-    box_1_b_valid                         = ("Box 1 B has been validated",            "Box 1 B COULD NOT be validated")
-    box_2_b_valid                         = ("Box 2 B has been validated",            "Box 2 B COULD NOT be validated")
-    terrain_b_valid                       = ("Terrain B has been validated",          "Terrain B COULD NOT be validated")
-    box_1_a_pos_found                     = ("Box 1 A position found",                "Box 1 A position NOT found")
-    box_2_a_pos_found                     = ("Box 2 A position found",                "Box 2 A position NOT found")
-    terrain_a_pos_found                   = ("Terrain A position found",              "Terrain A position NOT found")
-    box_1_b_pos_found                     = ("Box 1 B position found",                "Box 1 B position NOT found")
-    box_2_b_pos_found                     = ("Box 2 B position found",                "Box 2 B position NOT found")
-    terrain_b_pos_found                   = ("Terrain B position found",              "Terrain B position NOT found")
-    box_1_a_did_collide_with_terrain      = ("Box 1 A did collide with terrain",      "Box 1 A DID NOT collide with terrain")
-    box_1_a_did_not_pass_through_terrain  = ("Box 1 A did not fall past the terrain", "Box 1 A DID fall past the terrain")
-    box_2_a_did_not_collide_with_terrain  = ("Box 2 A did not collide with terrain", "Box 2 A DID collide with terrain")
-    box_2_a_did_pass_through_terrain      = ("Box 2 A did fall past the terrain",     "Box 2 A DID NOT fall past the terrain")
-    box_1_b_did_not_collide_with_terrain  = ("Box 1 B did not collide with terrain",  "Box 1 B DID collide with terrain")
-    box_1_b_did_pass_through_terrain      = ("Box 1 B did fall past the terrain",     "Box 1 B DID NOT fall past the terrain")
-    box_2_b_did_collide_with_terrain      = ("Box 2 B did collide with terrain",      "Box 2 B DID NOT collide with terrain")
-    box_2_b_did_not_pass_through_terrain  = ("Box 2 B did not fall past the terrain", "Box 2 B DID fall past the terrain")
-    exit_game_mode                        = ("Exited game mode",                      "Couldn't exit game mode")
-# fmt: on
-
-
-def Collider_CollisionGroupsWorkflow():
-    # type: () -> None
-    """
-    Summary:
-    Runs an automated test to ensure PhysX collision groups dictate whether collisions happen or not.
-    The test has two phases (A and B) for testing collision groups under different circumstances. Phase A
-    is run first and upon success Phase B starts.
-
-    Level Description:
-    Entities can be divided into 2 groups for the two phases, A and B. Each phase has identical entities with exception
-    to Terrain, where Terrain_A has a collision group/layer set for demo_group1/demo1 and Terrain_B has a collision
-    group/layer set for demo_group2/demo2.
-
-    Each Phase has two boxes, Box_1 and Box_2, where each box has it's collision group/layer set to it's number
-    (1 or 2). Each box is positioned just above the Terrain with gravity enabled.
-
-    All entities for Phase B are deactivated by default. If Phase A is setup and executed successfully it's
-    entities are deactivated and Phase B's entities are activated and validated before running the Phase B test.
-
-    Expected behavior:
-    When Phase A starts, it's two boxes should fall toward the terrain. Once the boxes' behavior is validated the
-    entities from Phase A are deactivated and Phase B's entities are activated. Like in Phase A, the boxes in Phase B
-    should fall towards the terrain. If all goes as expected Box_1_A and Box_2_B should collide with teh terrain, and
-    Box_2A and Box_1_B should fall through the terrain.
-
-    Test Steps:
-    0) [Define helper classes and functions]
-    1) Load the level
-    2) Enter game mode
-    3) Retrieve and validate entities
-    4) Phase A
-        a) set up
-        b) execute test
-        c) log results (deactivate Phase A entities)
-    5) Phase B
-        a) set up (activate Phase B entities)
-        b) execute test
-        c) log results
-    6) close editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-    - The level for this test uses two PhysX Terrains and must be run with cmdline argument "-autotest_mode"
-            to suppress the warning for having multiple terrains.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-    import azlmbr
-
-    # ******* Helper Classes ********
-
-    # Phase A's test results
-    class PhaseATestData:
-        total_results = 2
-        box_1_collided = False
-        box_1_fell_through = True
-        box_2_collided = False
-        box_2_fell_through = False
-        box_1 = None
-        box_2 = None
-        terrain = None
-        box_1_pos = None
-        box_2_pos = None
-        terrain_pos = None
-
-        @staticmethod
-        # Quick check for validating results for Phase A
-        def valid():
-            return (
-                PhaseATestData.box_1_collided
-                and PhaseATestData.box_2_fell_through
-                and not PhaseATestData.box_1_fell_through
-                and not PhaseATestData.box_2_collided
-            )
-
-    # Phase B's test results
-    class PhaseBTestData:
-        total_results = 2
-        box_1_collided = False
-        box_1_fell_through = False
-        box_2_collided = False
-        box_2_fell_through = True
-        box_1 = None
-        box_2 = None
-        terrain = None
-        box_1_pos = None
-        box_2_pos = None
-        terrain_pos = None
-
-        @staticmethod
-        # Quick check for validating results for Phase B
-        def valid():
-            return (
-                not PhaseBTestData.box_1_collided
-                and not PhaseBTestData.box_2_fell_through
-                and PhaseBTestData.box_1_fell_through
-                and PhaseBTestData.box_2_collided
-            )
-
-    # **** Helper Functions ****
-
-    # ** Validation helpers **
-
-    # Attempts to validate an entity based on the name parameter
-    def validate_entity(entity_name, msg_tuple):
-        # type: (str, (str, str)) -> EntityId
-        entity_id = general.find_game_entity(entity_name)
-        Report.critical_result(msg_tuple, entity_id.IsValid())
-        return entity_id
-
-    # Attempts to retrieve an entity's initial position and logs result
-    def validate_initial_position(entity_id, msg_tuple):
-        # type: (EntityId, (str, str)) -> azlmbr.math.Vector3
-        # Attempts to validate and return the entity's initial position.
-        # logs the result to Report.result() using the tuple parameter
-
-        pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", entity_id)
-        valid = not (pos is None or pos.IsZero())
-        entity_name = azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "GetEntityName", entity_id)
-        Report.critical_result(msg_tuple, valid)
-        Report.info_vector3(pos, "{} initial position:".format(entity_name))
-        return pos
-
-    # ** Phase completion checks checks **
-
-    # Checks if we are done collecting data for phase A
-    def done_collecting_results_a():
-        # type: () -> bool
-
-        # Update positions
-        PhaseATestData.box_1_pos = azlmbr.components.TransformBus(
-            azlmbr.bus.Event, "GetWorldTranslation", PhaseATestData.box_1
-        )
-        PhaseATestData.box_2_pos = azlmbr.components.TransformBus(
-            azlmbr.bus.Event, "GetWorldTranslation", PhaseATestData.box_2
-        )
-
-        # Check for boxes to fall through terrain
-        if PhaseATestData.box_1_pos.z < PhaseATestData.terrain_pos.z:
-            PhaseATestData.box_1_fell_through = True
-        else:
-            PhaseATestData.box_1_fell_through = False
-
-        if PhaseATestData.box_2_pos.z < PhaseATestData.terrain_pos.z:
-            PhaseATestData.box_2_fell_through = True
-        else:
-            PhaseATestData.box_2_fell_through = False
-
-        results = 0
-        if PhaseATestData.box_1_collided or PhaseATestData.box_1_fell_through:
-            results += 1
-        if PhaseATestData.box_2_collided or PhaseATestData.box_2_fell_through:
-            results += 1
-        return results == PhaseATestData.total_results
-
-    # Checks if we are done collecting data for phase B
-    def done_collecting_results_b():
-        # type: () -> bool
-
-        # Update positions
-        PhaseBTestData.box_1_pos = azlmbr.components.TransformBus(
-            azlmbr.bus.Event, "GetWorldTranslation", PhaseBTestData.box_1
-        )
-        PhaseBTestData.box_2_pos = azlmbr.components.TransformBus(
-            azlmbr.bus.Event, "GetWorldTranslation", PhaseBTestData.box_2
-        )
-
-        # Check for boxes to fall through terrain
-        if PhaseBTestData.box_1_pos.z < PhaseBTestData.terrain_pos.z:
-            PhaseBTestData.box_1_fell_through = True
-        else:
-            PhaseBTestData.box_1_fell_through = False
-
-        if PhaseBTestData.box_2_pos.z < PhaseBTestData.terrain_pos.z:
-            PhaseBTestData.box_2_fell_through = True
-        else:
-            PhaseBTestData.box_2_fell_through = False
-
-        results = 0
-        if PhaseBTestData.box_1_collided or PhaseBTestData.box_1_fell_through:
-            results += 1
-        if PhaseBTestData.box_2_collided or PhaseBTestData.box_2_fell_through:
-            results += 1
-        return results == PhaseBTestData.total_results
-
-    # **** Event Handlers ****
-
-    # Collision even handler for Phase A
-    def on_collision_begin_a(args):
-        # type: ([EntityId]) -> None
-        collider_id = args[0]
-        if (not PhaseATestData.box_1_collided) and PhaseATestData.box_1.Equal(collider_id):
-            Report.info("Box_1_A / Terrain_A collision detected")
-            PhaseATestData.box_1_collided = True
-        if (not PhaseATestData.box_2_collided) and PhaseATestData.box_2.Equal(collider_id):
-            Report.info("Box_2_A / Terrain_A collision detected")
-            PhaseATestData.box_2_collided = True
-
-    # Collision event handler for Phase B
-    def on_collision_begin_b(args):
-        # type: ([EntityId]) -> None
-        collider_id = args[0]
-        if (not PhaseBTestData.box_1_collided) and PhaseBTestData.box_1.Equal(collider_id):
-            Report.info("Box_1_B / Terrain_B collision detected")
-            PhaseBTestData.box_1_collided = True
-        if (not PhaseBTestData.box_2_collided) and PhaseBTestData.box_2.Equal(collider_id):
-            Report.info("Box_2_B / Terrain_B collision detected")
-            PhaseBTestData.box_2_collided = True
-
-    TIME_OUT = 1.5
-
-    # 1) Open level
-    helper.init_idle()
-    helper.open_level("Physics", "Collider_CollisionGroupsWorkflow")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve and validate entities
-    PhaseATestData.box_1 = validate_entity("Box_1_A", Tests.box_1_a_valid)
-    PhaseATestData.box_2 = validate_entity("Box_2_A", Tests.box_2_a_valid)
-    PhaseATestData.terrain = validate_entity("Terrain_Entity_A", Tests.terrain_a_valid)
-    PhaseBTestData.box_1 = validate_entity("Box_1_B", Tests.box_1_b_valid)
-    PhaseBTestData.box_2 = validate_entity("Box_2_B", Tests.box_2_b_valid)
-    PhaseBTestData.terrain = validate_entity("Terrain_Entity_B", Tests.terrain_b_valid)
-
-    # Make sure Phase B objects are disabled
-    azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "DeactivateGameEntity", PhaseBTestData.box_1)
-    azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "DeactivateGameEntity", PhaseBTestData.box_2)
-    azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "DeactivateGameEntity", PhaseBTestData.terrain)
-
-    # 4) *********** Phase A *****************
-
-    # 4.a) ** Set Up **
-
-    Report.info(" **** Beginning Phase A **** ")
-
-    # Locate Phase A entities
-    PhaseATestData.box_1_pos = validate_initial_position(PhaseATestData.box_1, Tests.box_1_a_pos_found)
-    PhaseATestData.box_2_pos = validate_initial_position(PhaseATestData.box_2, Tests.box_2_a_pos_found)
-    PhaseATestData.terrain_pos = validate_initial_position(PhaseATestData.terrain, Tests.terrain_a_pos_found)
-
-    # Assign Phase A event handler
-    handler_a = azlmbr.physics.CollisionNotificationBusHandler()
-    handler_a.connect(PhaseATestData.terrain)
-    handler_a.add_callback("OnCollisionBegin", on_collision_begin_a)
-
-    # 4.b) Execute Phase A
-    if not helper.wait_for_condition(done_collecting_results_a, TIME_OUT):
-        Report.info("Phase A timed out: make sure the level is set up properly or adjust time out threshold")
-
-    # 4.c) Log results for Phase A
-    Report.result(Tests.box_1_a_did_collide_with_terrain, PhaseATestData.box_1_collided)
-    Report.result(Tests.box_1_a_did_not_pass_through_terrain, not PhaseATestData.box_1_fell_through)
-    Report.info_vector3(PhaseATestData.box_1_pos, "Box_1_A's final position:")
-
-    Report.result(Tests.box_2_a_did_pass_through_terrain, PhaseATestData.box_2_fell_through)
-    Report.result(Tests.box_2_a_did_not_collide_with_terrain, not PhaseATestData.box_2_collided)
-    Report.info_vector3(PhaseATestData.box_2_pos, "Box_2_A's final position:")
-
-    if not PhaseATestData.valid():
-        Report.info("Phase A failed test")
-
-    # Deactivate entities for Phase A
-    azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "DeactivateGameEntity", PhaseATestData.box_1)
-    azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "DeactivateGameEntity", PhaseATestData.box_2)
-    azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "DeactivateGameEntity", PhaseATestData.terrain)
-
-    # 5) *********** Phase B *****************
-
-    # 5.a) ** Set Up **
-    Report.info(" *** Beginning Phase B *** ")
-    # Activate entities for Phase B
-    azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "ActivateGameEntity", PhaseBTestData.box_1)
-    azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "ActivateGameEntity", PhaseBTestData.box_2)
-    azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "ActivateGameEntity", PhaseBTestData.terrain)
-
-    # Initialize positions for Phase B
-    PhaseBTestData.box_1_pos = validate_initial_position(PhaseBTestData.box_1, Tests.box_1_b_pos_found)
-    PhaseBTestData.box_2_pos = validate_initial_position(PhaseBTestData.box_2, Tests.box_2_b_pos_found)
-    PhaseBTestData.terrain_pos = validate_initial_position(PhaseBTestData.terrain, Tests.terrain_b_pos_found)
-
-    # Assign Phase B event handler
-    handler_b = azlmbr.physics.CollisionNotificationBusHandler()
-    handler_b.connect(PhaseBTestData.terrain)
-    handler_b.add_callback("OnCollisionBegin", on_collision_begin_b)
-
-    # 5.b) Execute Phase B
-    if not helper.wait_for_condition(done_collecting_results_b, TIME_OUT):
-        Report.info("Phase B timed out: make sure the level is set up properly or adjust time out threshold")
-
-    # 5.c) Log results for Phase B
-    Report.result(Tests.box_1_b_did_not_collide_with_terrain, not PhaseBTestData.box_1_collided)
-    Report.result(Tests.box_1_b_did_pass_through_terrain, PhaseBTestData.box_1_fell_through)
-    Report.info_vector3(PhaseBTestData.box_1_pos, "Box_1_B's final position:")
-
-    Report.result(Tests.box_2_b_did_not_pass_through_terrain, not PhaseBTestData.box_2_fell_through)
-    Report.result(Tests.box_2_b_did_collide_with_terrain, PhaseBTestData.box_2_collided)
-    Report.info_vector3(PhaseBTestData.box_2_pos, "Box_2_B's final position:")
-
-    if not PhaseBTestData.valid():
-        Report.info("Phase B failed test")
-
-    # 6) Exit Game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-    Report.info(" **** TEST FINISHED ****")
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_CollisionGroupsWorkflow)

+ 0 - 230
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_DiffCollisionGroupDiffCollidingLayersNotCollide.py

@@ -1,230 +0,0 @@
-"""
-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 ID : C4982593
-# Test Case Title : Check that two entities with different collision groups and layers do not collide.
-
-
-
-# fmt: off
-class Tests:
-    enter_game_mode         = ("Entered game mode",                             "Failed to enter game mode")
-    moving_entity_found     = ("Moving entity found",                           "Moving entity not found")
-    stationary_entity_found = ("Stationary entity found",                       "Stationary entity not found")
-    moving_pos_found        = ("Moving sphere position found",                  "Moving sphere position not found")
-    stationary_pos_found    = ("Stationary sphere position found",              "Stationary sphere position not found")
-    spheres_share_x_axis    = ("Both spheres are aligned properly",             "Spheres are not aligned properly")
-    spheres_not_collided    = ("No collision was detected",                     "A collision was detected")
-    spheres_switched_sides  = ("The moving sphere passed through the other",    "Moving sphere did not pass through")
-    no_y_movement           = ("There was no Y movement",                       "Some Y movement was detected")
-    no_z_movement           = ("There was no Z movement",                       "Some Z movement was detected")
-    timed_out               = ("Test did not time out",                         "Test TIMED OUT")
-    stationary_didnt_move   = ("Stationary sphere did not move",                "Stationary sphere moved")
-    exit_game_mode          = ("Exited game mode",                              "Couldn't exit game mode")
-
-# fmt: on
-
-
-def Collider_DiffCollisionGroupDiffCollidingLayersNotCollide():
-    # type: () -> None
-    """
-    Summary:
-    Runs an automated test to ensure to rigid bodies on the different collision group and collision layer
-    DO NOT collide.
-
-    Level Description:
-    Moving (entity) - a spherical entity (colored yellow) that is set up with a collision layer of "demo1"
-        collision group of "demo_group1" gravity as disabled and an initial velocity of (3, 0, 0).
-    Stationary (entity) - a spherical entity (colored purple) that is set up with a collision layer of "demo2"
-        collision group of "demo_group2" gravity disabled, and is positioned at location (+2, 0, 0) relative to
-        Moving's starting position.
-
-    Expected Behavior:
-    When game mode is entered, Moving will begin moving in the positive X direction. The entity should pass through
-    Stationary with no collision detection triggered.
-
-    Test Steps:
-    1) Loads the level / Enter game mode
-    2) Retrieve test entities
-    3) Ensures that the test objects (Moving and Stationary) are located
-        3.5) set up variables and handlers
-    4) Wait for Moving to pass through Stationary
-    5) Logs results
-    6) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # **** Helper class ****
-
-    class Sphere:
-        def __init__(self, name):
-            self.id = None
-            self.name = name
-            self.initial_pos = None
-            self.current_position = None
-
-    # Tests for significant change between a set of float pairs
-    #   returns a list of booleans where the i-th index hold the result for the i-th float pair
-    def detect_significant_change(float_pairs):
-        # type: ([(float, float)]) -> [bool]
-        return [abs(p[0] - p[1]) >= CLOSE_ENOUGH_THRESHOLD for p in float_pairs]
-
-    # *** Executable Code ***
-
-    # Constants
-    TIME_OUT = 1.5
-    CLOSE_ENOUGH_THRESHOLD = 0.0001
-    SPHERE_RADIUS = 0.5  # Radius of both sphere entities
-
-    # 1) Open level / Enter game mode
-    helper.init_idle()
-    helper.open_level("Physics", "Collider_DiffCollisionGroupDiffCollidingLayersNotCollide")
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 2) Retrieve/validate entities
-    moving = Sphere("Moving")
-    moving.id = general.find_game_entity(moving.name)
-    Report.critical_result(Tests.moving_entity_found, moving.id.IsValid())
-
-    stationary = Sphere("Stationary")
-    stationary.id = general.find_game_entity(stationary.name)
-    Report.critical_result(Tests.stationary_entity_found, stationary.id.IsValid())
-
-    # 3) Log starting positions
-    moving.initial_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", moving.id)
-    stationary.initial_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", stationary.id)
-
-    # Ensure that spheres are aligned properly along the y and z axises (so x axis movement will cause collision)
-    spheres_aligned = (abs(moving.initial_pos.y - stationary.initial_pos.y) < SPHERE_RADIUS) and (
-        abs(moving.initial_pos.z - stationary.initial_pos.z) < SPHERE_RADIUS
-    )
-
-    # Report critical level integrity results
-    Report.critical_result(Tests.moving_pos_found, moving.initial_pos is not None and not moving.initial_pos.IsZero())
-    Report.critical_result(
-        Tests.stationary_pos_found, stationary.initial_pos is not None and not moving.initial_pos.IsZero()
-    )
-    Report.critical_result(
-        Tests.spheres_share_x_axis,
-        spheres_aligned,
-        "Please check the level to make sure Moving Sphere and Stationary Sphere share y and z positions",
-    )
-
-    # 3.5) Set up variables and handler for observing force region interaction
-
-    class TestData:
-        collision_occurred = False
-        spheres_switched = False
-
-    # Force Region Event Handler
-    def on_collision_begin(args):
-        collider_id = args[0]
-        if collider_id.Equal(moving.id):
-            if not TestData.collision_occurred:
-                TestData.collision_occurred = True
-                Report.info("Collision detected")
-
-    # Assign the handler
-    handler = azlmbr.physics.CollisionNotificationBusHandler()
-    handler.connect(stationary.id)
-    handler.add_callback("OnCollisionBegin", on_collision_begin)
-
-    moving.current_pos = moving.initial_pos
-    stationary.current_pos = stationary.initial_pos
-
-    # Tests if we are done collecting results and can exit the test
-    def done_collecting_results():
-
-        COMPARISON_BUFFER = 0.2
-
-        if not TestData.collision_occurred:
-
-            moving.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", moving.id)
-            stationary.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", stationary.id)
-
-            if moving.current_pos.x > stationary.current_pos.x + COMPARISON_BUFFER:
-                # Moving sphere passed the stationary sphere's x coordinate
-                TestData.spheres_switched = True
-                return True
-        else:
-            # A collision was detected
-            Report.info("A collision was detected unfortunately")
-            return True
-
-        return False
-
-    # 4) Wait for results to be collected or for time out
-    Report.result(Tests.timed_out, helper.wait_for_condition(done_collecting_results, TIME_OUT))
-
-    # 5) Log results
-    Report.result(Tests.spheres_switched_sides, TestData.spheres_switched)
-    Report.result(Tests.spheres_not_collided, not TestData.collision_occurred)
-
-    # Look for movement in Y direction. Report results
-    y_movement = detect_significant_change(
-        [(moving.initial_pos.y, moving.current_pos.y), (stationary.initial_pos.y, stationary.current_pos.y)]
-    )
-
-    if not any(y_movement):
-        Report.success(Tests.no_y_movement)
-    else:
-        Report.failure(Tests.no_y_movement)
-        if y_movement[0]:
-            Report.info("Moving entity Y movement detected. This should not happen")
-        if y_movement[1]:
-            Report.info("Stationary entity Y movement detected. This should not happen")
-
-    # Look for movement in Z direction. Report Results
-    z_movement = detect_significant_change(
-        [(moving.initial_pos.z, moving.current_pos.z), (stationary.initial_pos.z, stationary.current_pos.z)]
-    )
-
-    if not any(z_movement):
-        Report.success(Tests.no_z_movement)
-    else:
-        Report.failure(Tests.no_z_movement)
-        if z_movement[0]:
-            Report.info("Moving entity Z movement detected. This should not happen")
-        if z_movement[1]:
-            Report.info("Stationary entity Z movement detected. This should not happen")
-
-    Report.result(Tests.stationary_didnt_move, stationary.current_pos.Equal(stationary.initial_pos))
-
-    # Collected data dump
-    Report.info(" ********** Collected Data ***************")
-    Report.info("Moving sphere's positions:")
-    Report.info_vector3(moving.initial_pos, "  initial:")
-    Report.info_vector3(moving.current_pos, "  final:")
-    Report.info("*****************************")
-    Report.info("Stationary sphere's positions:")
-    Report.info_vector3(stationary.initial_pos, "  initial:")
-    Report.info_vector3(stationary.current_pos, "  final:")
-    Report.info("*****************************")
-
-    # 6) Exit Game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-    Report.info("*** FINISHED TEST ***")
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_DiffCollisionGroupDiffCollidingLayersNotCollide)

+ 2 - 2
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_MultipleSurfaceSlots.py

@@ -59,8 +59,8 @@ def Collider_MultipleSurfaceSlots():
     SURFACE_TAG_COUNT = 4  # Number of surface tags included in used asset
 
     # Asset paths
-    STATIC_MESH = os.path.join("assets", "Physics", "Collider_MultipleSurfaceSlots", "test.azmodel")
-    PHYSX_MESH = os.path.join("assets", "Physics","Collider_MultipleSurfaceSlots", "test.pxmesh")
+    STATIC_MESH = os.path.join("assets", "Physics", "Collider_MultipleSurfaceSlots", "test.fbx.azmodel")
+    PHYSX_MESH = os.path.join("assets", "Physics","Collider_MultipleSurfaceSlots", "test.fbx.pxmesh")
 
     # 1) Load the empty level
     hydra.open_base_level()

+ 0 - 222
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_NoneCollisionGroupSameLayerNotCollide.py

@@ -1,222 +0,0 @@
-"""
-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 ID : C4976245
-# Test Case Title : Check that two entities of collision group "None" do not collide,
-#       even though they have the same collision layer
-
-
-
-# fmt: off
-class Tests:
-    enter_game_mode         = ("Entered game mode",                             "Failed to enter game mode")
-    moving_entity_found     = ("Moving entity found",                           "Moving entity not found")
-    stationary_entity_found = ("Stationary entity found",                       "Stationary entity not found")
-    moving_pos_found        = ("Moving sphere position found",                  "Moving sphere position not found")
-    stationary_pos_found    = ("Stationary sphere position found",              "Stationary sphere position not found")
-    spheres_share_x_axis    = ("Both spheres are aligned properly",             "Spheres are not aligned properly")
-    spheres_not_collided    = ("No collision was detected",                     "A collision was detected")
-    spheres_switched_sides  = ("The moving sphere passed through the other",    "Moving sphere did not pass through")
-    no_y_movement           = ("There was no Y movement",                       "Some Y movement was detected")
-    no_z_movement           = ("There was no Z movement",                       "Some Z movement was detected")
-    timed_out               = ("Test did not time out",                         "Test TIMED OUT")
-    stationary_didnt_move   = ("Stationary sphere did not move",                "Stationary sphere moved")
-    exit_game_mode          = ("Exited game mode",                              "Couldn't exit game mode")
-# fmt: on
-
-
-def Collider_NoneCollisionGroupSameLayerNotCollide():
-    # type: () -> None
-    """
-    Summary:
-    Runs an automated test to ensure to rigid bodies on the same collision layer, but no collision group
-    DO NOT collide.
-
-    Level Description:
-    Moving (entity) - a spherical entity (colored yellow) that is set up with a collision layer of "demo1"
-        collision group of "None" gravity as disabled and an initial velocity of (3, 0, 0).
-    Stationary (entity) - a spherical entity (colored purple) that is set up with a collision layer of "demo1"
-        collision group of "None" gravity disabled, and is positioned at location (+2, 0, 0) relative to
-        Moving's starting position with no initial velocity.
-
-    Expected Behavior:
-    When game mode is entered, Moving will begin moving in the positive X direction. The entity should pass through
-    Stationary with no collision detection triggered.
-
-    Test Steps:
-    1) Loads the level / Enter game mode
-    2) Retrieve test entities
-    3) Ensures that the test objects (Moving and Stationary) are located
-    4) set up variables and handlers
-    5) Wait for Moving to pass through Stationary
-    6) Logs results
-    7) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # **** Helper class ****
-
-    class Sphere:
-        def __init__(self, name):
-            self.id = None
-            self.name = name
-            self.initial_pos = None
-            self.current_position = None
-
-    # Tests the deltas for for significant change. Prints a message to log if change is detected.
-    #   returns True if no change detected between both deltas-- False otherwise
-    def no_movement(delta_moving, delta_stationary, axis):
-        result = True
-        if delta_moving > CLOSE_ENOUGH_THRESHOLD:
-            Report.info("Moving entity {} movement detected. This should not happen".format(axis))
-            result = False
-
-        if delta_stationary > CLOSE_ENOUGH_THRESHOLD:
-            Report.info("Stationary entity {} movement detected. This should not happen".format(axis))
-            result = False
-
-        return result
-
-    # *** Executable Code ***
-
-    # Constants
-    TIME_OUT = 1.5
-    CLOSE_ENOUGH_THRESHOLD = 0.0001
-    SPHERE_RADIUS = 0.5  # Radius of both sphere entities
-    COMPARISON_BUFFER = 0.2  # used for position comparisons to offset game physics anomalies
-
-    # 1) Open level / Enter game mode
-    helper.init_idle()
-    helper.open_level("Physics", "Collider_NoneCollisionGroupSameLayerNotCollide")
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 2) Retrieve/validate entities
-    moving = Sphere("Moving")
-    moving.id = general.find_game_entity(moving.name)
-    Report.critical_result(Tests.moving_entity_found, moving.id.IsValid())
-
-    stationary = Sphere("Stationary")
-    stationary.id = general.find_game_entity(stationary.name)
-    Report.critical_result(Tests.stationary_entity_found, stationary.id.IsValid())
-
-    # 3) Log starting positions
-    moving.initial_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", moving.id)
-    stationary.initial_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", stationary.id)
-
-    # Ensure that spheres are aligned properly along the y and z axises (so x axis movement will cause collision)
-    spheres_aligned = (abs(moving.initial_pos.y - stationary.initial_pos.y) < SPHERE_RADIUS) and (
-        abs(moving.initial_pos.z - stationary.initial_pos.z) < SPHERE_RADIUS
-    )
-
-    # Report critical level integrity results
-    Report.critical_result(Tests.moving_pos_found, moving.initial_pos is not None and not moving.initial_pos.IsZero())
-    Report.critical_result(
-        Tests.stationary_pos_found, stationary.initial_pos is not None and not moving.initial_pos.IsZero()
-    )
-    Report.critical_result(
-        Tests.spheres_share_x_axis,
-        spheres_aligned,
-        "Please check the level to make sure Moving Sphere and Stationary Sphere share y and z positions",
-    )
-
-    # 4) Set up variables and handler for observing force region interaction
-
-    class TestData:
-        collision_occurred = False
-        spheres_switched = False
-
-    # Force Region Event Handler
-    def on_collision_begin(args):
-        collider_id = args[0]
-        if collider_id.Equal(moving.id):
-            if not TestData.collision_occurred:
-                TestData.collision_occurred = True
-                Report.info("Collision detected")
-
-    # Assign the handler
-    handler = azlmbr.physics.CollisionNotificationBusHandler()
-    handler.connect(stationary.id)
-    handler.add_callback("OnCollisionBegin", on_collision_begin)
-
-    moving.current_pos = moving.initial_pos
-    stationary.current_pos = stationary.initial_pos
-
-    # Tests if we are done collecting results and can exit the test
-    def done_collecting_results():
-
-        if not TestData.collision_occurred:
-
-            moving.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", moving.id)
-            stationary.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", stationary.id)
-
-            if moving.current_pos.x > (stationary.current_pos.x + COMPARISON_BUFFER):
-                # Moving sphere passed the stationary sphere's x coordinate
-                TestData.spheres_switched = True
-                return True
-        else:
-            # A collision was detected
-            Report.info("A collision was detected unfortunately")
-            return True
-
-        return False
-
-    # 5) Wait for results to be collected or for time out
-    Report.result(Tests.timed_out, helper.wait_for_condition(done_collecting_results, TIME_OUT))
-
-    # 6) Log results
-    Report.result(Tests.spheres_switched_sides, TestData.spheres_switched)
-    Report.result(Tests.spheres_not_collided, not TestData.collision_occurred)
-
-    # Look for movement in Y direction. Report results
-    no_movement_y = no_movement(
-        abs(moving.initial_pos.y - moving.current_pos.y), abs(stationary.initial_pos.y - stationary.current_pos.y), "Y"
-    )
-
-    Report.result(Tests.no_y_movement, no_movement_y)
-
-    # Look for movement in Z direction. Report results
-    no_movement_z = no_movement(
-        abs(moving.initial_pos.z - moving.current_pos.z), abs(stationary.initial_pos.z - stationary.current_pos.z), "Z"
-    )
-    Report.result(Tests.no_z_movement, no_movement_z)
-
-    Report.result(Tests.stationary_didnt_move, stationary.current_pos.Equal(stationary.initial_pos))
-
-    # Collected data dump
-    Report.info(" ********** Collected Data ***************")
-    Report.info("Moving sphere's positions:")
-    Report.info_vector3(moving.initial_pos, "  initial:")
-    Report.info_vector3(moving.current_pos, "  final:")
-    Report.info("*****************************")
-    Report.info("Stationary sphere's positions:")
-    Report.info_vector3(stationary.initial_pos, "  initial:")
-    Report.info_vector3(stationary.current_pos, "  final:")
-    Report.info("*****************************")
-
-    # 7) Exit Game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-    Report.info("*** FINISHED TEST ***")
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_NoneCollisionGroupSameLayerNotCollide)

+ 2 - 2
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_PxMeshAutoAssignedWhenAddingRenderMeshComponent.py

@@ -58,9 +58,9 @@ def Collider_PxMeshAutoAssignedWhenAddingRenderMeshComponent():
     import editor_python_test_tools.hydra_editor_utils as hydra
 
     # Asset paths
-    STATIC_MESH = os.path.join("assets", "Physics", "Collider_PxMeshAutoAssigned", "spherebot", "r0-b_body.azmodel")
+    STATIC_MESH = os.path.join("assets", "Physics", "Collider_PxMeshAutoAssigned", "spherebot", "r0-b_body.fbx.azmodel")
     PHYSX_MESH = os.path.join(
-        "assets", "Physics", "Collider_PxMeshAutoAssigned", "spherebot", "r0-b_body.pxmesh"
+        "assets", "Physics", "Collider_PxMeshAutoAssigned", "spherebot", "r0-b_body.fbx.pxmesh"
     )
 
     # 1) Load the empty level

+ 1 - 1
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_PxMeshAutoAssignedWhenModifyingRenderMeshComponent.py

@@ -59,7 +59,7 @@ def Collider_PxMeshAutoAssignedWhenModifyingRenderMeshComponent():
     # Open 3D Engine Imports
     import azlmbr.legacy.general as general
 
-    MESH_ASSET_PATH = os.path.join("Objects", "SphereBot", "r0-b_body.azmodel")
+    MESH_ASSET_PATH = os.path.join("Objects", "SphereBot", "r0-b_body.fbx.azmodel")
     MESH_PROPERTY_PATH = "Controller|Configuration|Model Asset"
     TESTED_PROPERTY_PATH = "Shape Configuration|Asset|PhysX Mesh"
 

+ 1 - 1
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_PxMeshConvexMeshCollides.py

@@ -72,7 +72,7 @@ def Collider_PxMeshConvexMeshCollides():
     import azlmbr.legacy.general as general
 
     # Constants
-    MESH_ASSET_PATH = os.path.join("assets", "Physics", "Collider_PxMeshConvexMeshCollides", "spherebot", "r0-b_body.pxmesh")
+    MESH_ASSET_PATH = os.path.join("assets", "Physics", "Collider_PxMeshConvexMeshCollides", "spherebot", "r0-b_body.fbx.pxmesh")
     TIMEOUT = 2.0
 
     # 1) Load the level

+ 0 - 84
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_PxMeshErrorIfNoMesh.py

@@ -1,84 +0,0 @@
-"""
-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 ID : C14861498
-# Test Case Title : Confirm that when a PhysXMeshCollider has no physics asset, the physics asset collider \
-#   shape throw an error
-
-
-
-# fmt:off
-class Tests():
-    enter_game_mode        = ("Entered game mode",               "Failed to enter game mode")
-    found_entity           = ("Entity was found",                "Entity WAS NOT found")
-    warning_message_logged = ("The expected warning was logged", "The expected message was not logged")
-    exit_game_mode         = ("Exited game mode",                "Couldn't exit game mode")
-# fmt:on
-
-
-def Collider_PxMeshErrorIfNoMesh():
-    """
-    Summary:
-    This test looks for the presence of an error when an entity with a PhysXMeshCollider has no physics mesh, but has its
-    collider shape set to a physics mesh.
-
-    Level Description:
-    One entity with a PhysXMeshCollider with the collider shape set to "physics asset" and no actual physics mesh.
-    That's it!
-
-    Steps:
-    1) Load the level / enter game mode
-    2) Find the entity
-    3) Look for warning
-    4) Exit game mode
-    5) Close the editor
-
-    [Log Monitor] make sure error lines are present in the log
-
-    Expected Behavior:
-    The editor should open, load the level and (seemingly) instantly close. The two error lines specified should
-    print to the log.
-
-    :return: None
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    from editor_python_test_tools.utils import Tracer
-
-    import azlmbr.legacy.general as general
-
-    helper.init_idle()
-
-    with Tracer() as warning_tracer:
-        def has_physx_warning():
-            return warning_tracer.has_warnings and any(
-                'PhysX' in warningInfo.window and
-                'EditorMeshColliderComponent' in warningInfo.message for warningInfo in warning_tracer.warnings)
-
-        # 1) Load level / enter game mode
-        helper.open_level("Physics", "Collider_PxMeshErrorIfNoMesh")
-        helper.enter_game_mode(Tests.enter_game_mode)
-
-        # 2) Find game entity
-        id = general.find_game_entity("test_entity")
-        Report.result(Tests.found_entity, id.IsValid())
-
-        # 3) Look for warning
-        helper.wait_for_condition(has_physx_warning, 1.0)
-        Report.result(Tests.warning_message_logged, has_physx_warning())
-
-        # 4) Exit game mode
-        helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_PxMeshErrorIfNoMesh)

+ 1 - 1
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx.py

@@ -66,7 +66,7 @@ def Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx():
     import azlmbr.asset as azasset
 
     # Asset paths
-    STATIC_MESH = os.path.join("assets", "Physics", "Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx", "test_asset.azmodel")
+    STATIC_MESH = os.path.join("assets", "Physics", "Collider_PxMeshNotAutoAssignedWhenNoPhysicsFbx", "test_asset.fbx.azmodel")
 
     # 1) Load the empty level
     hydra.open_base_level()

+ 0 - 126
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SameCollisionGroupDiffLayersCollide.py

@@ -1,126 +0,0 @@
-"""
-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 ID : C4976243
-# Test Case Title : Assign different collision layers and same collision group
-# (such that this group has both these collision layers enabled) to two entities and verify that they collide
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode     = ("Entered game mode",            "Failed to enter game mode")
-    find_terrain        = ("Terrain found",                "Terrain not found")
-    find_entity1        = ("Entity1 found",                "Entity1 not found")
-    find_entity2        = ("Entity2 found",                "Entity2 not found")
-    gravity_enabled     = ("Gravity is enabled",           "Gravity is disabled")
-    gravity_disabled    = ("Gravity is disabled",          "Gravity is enabled")
-    collision_occurance = ("Entity1 and Entity2 collided", "Entity1 and Entity2 did not collide")
-    exit_game_mode      = ("Exited game mode",             "Couldn't exit game mode")
-# fmt: on
-
-
-def Collider_SameCollisionGroupDiffLayersCollide():
-
-    """
-    Summary:
-    Assign different collision layers and same collision group (such that this group has both these
-    collision layers enabled) to two entities and verify that they collide
-
-    Level Description:
-    Entity1 (entity) - Entity with components PhysX Rigid Body, PhysX Collider, Terrain and Rendering Mesh
-                       "Collision Layer" as "A" and "Collides with" as "B" with gravity enabled.
-                       Entity1 is placed exactly above Terrain and Entity2 along z axis
-    Entity2 (entity) - Entity with components PhysX Rigid Body, PhysX Collider, Terrain and Rendering Mesh
-                       "Collision Layer" as "Default" and "Collides with" as "B" with gravity disabled
-                       Entity2 is placed exactly in between the Terrain and Entity1 along z axis
-    Terrain (entity) - Entity with Terrain component.
-                       "Collision Layer" as "Default" and "Collides with" as "All"
-
-    Expected Behavior:
-    Created entities should collide with each other.
-    We are checking created entities collided (Entity1 and Entity2)
-
-    Test Steps:
-     1) Open level
-     2) Enter game mode
-     3) Retrieve and validate entities
-     4) Check if gravity is enabled for entity1 and disabled for entity2
-     5) Create collision event handlers
-     6) Check for collisions between entities
-     7) Exit game mode
-     8) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Constants
-    TIMEOUT = 2  # waits for 2 secs to verify if the collision occured
-
-    helper.init_idle()
-
-    # 1) Open level
-    helper.open_level("Physics", "Collider_SameCollisionGroupDiffLayersCollide")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve and validate entities
-    terrain_id = general.find_game_entity("Terrain")
-    Report.info(dir(terrain_id))
-    entity1_id = general.find_game_entity("Entity1")
-    entity2_id = general.find_game_entity("Entity2")
-    Report.critical_result(Tests.find_terrain, terrain_id.IsValid())
-    Report.critical_result(Tests.find_entity1, entity1_id.IsValid())
-    Report.critical_result(Tests.find_entity2, entity2_id.IsValid())
-
-    # 4) Check if gravity is enabled for entity1 and disabled for entity2
-    is_gravity_enabled = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", entity1_id)
-    Report.info("Gravity check for entity1")
-    Report.result(Tests.gravity_enabled, is_gravity_enabled)
-    is_gravity_enabled = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", entity2_id)
-    Report.info("Gravity check for entity2")
-    Report.result(Tests.gravity_disabled, not is_gravity_enabled)
-
-    class Collision:
-        entity_collision = False
-
-    # 5) Create collision event handler
-    def on_collision_begin(args):
-        if args[0].Equal(entity1_id):
-            Report.info("Collision occurred")
-            Collision.entity_collision = True
-
-    handler = azlmbr.physics.CollisionNotificationBusHandler()
-    handler.connect(entity2_id)
-    handler.add_callback("OnCollisionBegin", on_collision_begin)
-
-    # 6) Check for collisions between entities
-    helper.wait_for_condition(lambda: Collision.entity_collision, TIMEOUT)
-    Report.critical_result(Tests.collision_occurance, Collision.entity_collision)
-
-    # 7) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_SameCollisionGroupDiffLayersCollide)

+ 0 - 184
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SameCollisionGroupSameCustomLayerCollide.py

@@ -1,184 +0,0 @@
-"""
-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 ID : C4976244
-# Test Case Title : Checks that two entities of similar custom layer collide
-
-
-
-# fmt: off
-class Tests:
-    enter_game_mode                   = ("Entered game mode",                 "Failed to enter game mode")
-    moving_sphere_found               = ("Moving sphere found",               "Moving sphere not found")
-    stationary_sphere_found           = ("Stationary sphere found",           "Stationary sphere not found")
-    velocities_before_collision_valid = ("Sphere velocities are valid",       "Sphere velocities are not valid")
-    orientation_before_collision      = ("Both spheres are aligned properly", "Spheres are not aligned properly")
-    spheres_collided                  = ("Collision was detected",            "A collision was not detected")
-    orientation_after_collision       = ("Spheres are aligned properly",      "Spheres are not aligned properly")
-    velocities_after_collision_valid  = ("Velocity after collision valid",    "Velocity after collision not valid")
-    exit_game_mode                    = ("Exited game mode",                  "Couldn't exit game mode")
-
-# fmt: on
-
-
-def Collider_SameCollisionGroupSameCustomLayerCollide():
-    # type: () -> None
-    """
-    Summary:
-    Runs an automated test to ensure to rigid bodies on similar collision layer and group collide.
-
-    Level Description:
-    Moving Sphere (Entity) - On the same x axis as the Stationary Sphere, moving in the positive x direction;
-        has sphere shaped PhysX Collider, PhysX Rigid Body, Sphere Shape. Collision Group All, layer A
-    Stationary Sphere (Entity) - On the same x axis as the Moving Sphere;
-        has sphere shaped PhysX Collider, PhysX Rigid Body, Sphere Shape Collision Group All, layer A
-
-    Expected Behavior: The moving sphere will move torward the stationary sphere in the positive x direction
-        and collide with it. Both spheres will then separate and move in opposite directions.
-
-    Test Steps:
-    1) Load the level
-    2) Enter Game Mode
-    3) Validate entities
-    4) Validate positions and velocities
-    5) Start handlers
-    6) Wait for collision
-    7) Validated and logs results
-    8) Exit Game Mode
-    9) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Constants
-    TIMEOUT = 1
-    FLOAT_THRESHOLD = sys.float_info.epsilon
-
-    # Helper functions
-    # Callback function for the collision handler
-    def on_collision_begin(args):
-        #  type (list) -> None
-        Report.info("Collision Occurred")
-        other_id = args[0]
-        if other_id.Equal(moving_sphere.id):
-            stationary_sphere.collision_happened = True
-
-    class Entity:
-        def __init__(self, name):
-            self.id = general.find_game_entity(name)
-            self.name = name
-            self.initial_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
-            self.final_velocity = None
-            self.initial_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-            self.final_position = None
-            self.collision_happened = False
-            Report.info_vector3(self.initial_position, "{} initial position: ".format(self.name))
-            Report.info_vector3(self.initial_velocity, "{} initial velocity: ".format(self.name))
-
-        def get_final_position_and_velocity(self):
-            # type () -> None
-            self.final_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
-            self.final_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-
-        def report_final_values(self):
-            # type () -> None
-            Report.info_vector3(self.final_position, "{} final position: ".format(self.name))
-            Report.info_vector3(self.final_velocity, "{} final velocity: ".format(self.name))
-
-        def moving_in_x_direction(self, positive_x_direction):
-            # type (bool) -> bool
-            velocity_vector = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
-            
-            if positive_x_direction:
-                correct_direction = velocity_vector.x > 0
-            else:
-                correct_direction = velocity_vector.x < 0
-            return (
-                correct_direction and abs(velocity_vector.y) < FLOAT_THRESHOLD and abs(velocity_vector.z) < FLOAT_THRESHOLD
-            )
-    
-    # Checks if spheres are in the correct orientation
-    def validate_positions(moving_entity_position, stationary_entity_position):
-        # type (Vector3, Vector3) -> bool
-        return (
-            abs(moving_entity_position.z - stationary_entity_position.z) < FLOAT_THRESHOLD
-            and abs(moving_entity_position.y - stationary_entity_position.y) < FLOAT_THRESHOLD
-            and moving_entity_position.x < stationary_entity_position.x
-        )
-
-    # Main Script
-    # 1) Load the level
-    helper.init_idle()
-    helper.open_level("Physics", "Collider_SameCollisionGroupSameCustomLayerCollide")
-
-    # 2) Enter Game Mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Validate entities
-    moving_sphere = Entity("Moving_Sphere")
-    stationary_sphere = Entity("Stationary_Sphere")
-
-    Report.critical_result(Tests.moving_sphere_found, moving_sphere.id.isValid())
-    Report.critical_result(Tests.stationary_sphere_found, stationary_sphere.id.isValid())
-
-    # 4) Validate positions and velocities
-    Report.critical_result(
-        Tests.orientation_before_collision,
-        validate_positions(moving_sphere.initial_position, stationary_sphere.initial_position),
-    )
-    Report.critical_result(
-        Tests.velocities_before_collision_valid,
-        moving_sphere.moving_in_x_direction(positive_x_direction = True)
-        and stationary_sphere.initial_velocity.IsZero(FLOAT_THRESHOLD),
-    )
-
-    # 5) Start handler
-    handler = azlmbr.physics.CollisionNotificationBusHandler()
-    handler.connect(stationary_sphere.id)
-    handler.add_callback("OnCollisionBegin", on_collision_begin)
-
-    # 6) Wait for collision
-    helper.wait_for_condition(lambda: stationary_sphere.collision_happened, TIMEOUT)
-
-    # 7) Validated and logs results
-    Report.result(Tests.spheres_collided, stationary_sphere.collision_happened)
-    moving_sphere.get_final_position_and_velocity()
-    stationary_sphere.get_final_position_and_velocity()
-
-    Report.result(
-        Tests.orientation_after_collision,
-        validate_positions(moving_sphere.final_position, stationary_sphere.final_position),
-    )
-    Report.result(
-        Tests.velocities_after_collision_valid,
-        moving_sphere.moving_in_x_direction(positive_x_direction = False) and stationary_sphere.moving_in_x_direction(positive_x_direction = True)
-    )
-
-    moving_sphere.report_final_values()
-    stationary_sphere.report_final_values()
-
-    # 8) Exit Game Mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_SameCollisionGroupSameCustomLayerCollide)

+ 0 - 187
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_SameCollisionGroupSameLayerCollide.py

@@ -1,187 +0,0 @@
-"""
-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 ID : C4976242
-# Test Case Title : Assign same collision layer and same collision group to two entities and
-# verify that they collide or not
-
-
-# fmt: off
-class Tests():
-    enter_game_mode            = ("Entered game mode",                      "Failed to enter game mode")
-    find_moving                = ("Moving entity found",                    "Moving entity not found")
-    find_stationary            = ("Stationary entity found",                "Stationary entity not found")
-    find_terrain               = ("Terrain entity found",                   "Terrain entity not found")
-    stationary_above_terrain   = ("Stationary is above terrain",            "Stationary is not above terrain")
-    moving_above_stationary    = ("Moving is above stationary",             "Moving is not above stationary")
-    gravity_works              = ("Moving Sphere fell down",                "Moving Sphere did not fall")
-    collisions                 = ("Collision occurred in between entities", "Collision did not occur between entities")
-    falls_below_terrain_height = ("Moving is below terrain",                "Moving did not fall below terrain before timeout")
-    exit_game_mode             = ("Exited game mode",                       "Couldn't exit game mode")
-# fmt: on
-
-
-def Collider_SameCollisionGroupSameLayerCollide():
-
-    """
-    Summary:
-    Open a Project that already has two entities with same collision layer and same collision group and verify collision
-
-    Level Description:
-    Moving and Stationary entities are created in level with same collision layer and same collision group.
-    Moving entity is placed above the Stationary entity.Terrain is placed below the Stationary entity.
-    So Moving and Stationary entities collide with each other and they go through terrain after collision.
-
-    Expected Behavior:
-    The Moving and Stationary entities should collide with each other.After Collision,they go through terrain.
-
-    Test Steps:
-     1) Open level and Enter game mode
-     2) Retrieve and validate Entities
-     3) Get the starting z position of the Moving entity,Stationary entity and Terrain
-     4) Check and report that the entities are at the correct heights before collision
-     5) Check that the gravity works and the Moving entity falls down
-     6) Check Spheres collide only with each other, but not with terrain
-     7) Check Moving Entity should be below terrain after collision
-     8) Exit game mode
-     9) Close the editor
-
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Constants
-    TIMEOUT = 2.0
-    TERRAIN_HEIGHT = 32.0  # Default height of the terrain
-    MIN_BELOW_TERRAIN = 0.5  # Minimum height below terrain the sphere must be in order to be 'under' it
-    CLOSE_ENOUGH_THRESHOLD = 0.0001
-
-    helper.init_idle()
-
-    # 1) Open level and Enter game mode
-    helper.open_level("Physics", "Collider_SameCollisionGroupSameLayerCollide")
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 2) Retrieve and validate Entities
-    moving_id = general.find_game_entity("Sphere_Moving")
-    Report.critical_result(Tests.find_moving, moving_id.IsValid())
-
-    stationary_id = general.find_game_entity("Sphere_Stationary")
-    Report.critical_result(Tests.find_stationary, stationary_id.IsValid())
-
-    terrain_id = general.find_game_entity("Terrain")
-    Report.critical_result(Tests.find_terrain, terrain_id.IsValid())
-
-    # 3) Get the starting z position of the Moving entity,Stationary entity and Terrain
-    class Sphere:
-        """
-        Class to hold values for test checks.
-        Attributes:
-            start_position_z: The initial z position of the sphere
-            position_z      : The z position of the sphere
-            fell            : When the sphere falls any distance below its original position, the value should be set True
-            below_terrain   : When the box falls below the specified terrain height, the value should be set True
-        """
-
-        start_position_z = None
-        position_z = None
-        fell = False
-        below_terrain = False
-
-    Sphere.start_position_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", moving_id)
-    stationary_start_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", stationary_id)
-
-    # 4)Check and report that the entities are at the correct heights before collision
-    Report.info(
-        "Terrain Height: {} \n Stationary Sphere height: {} \n Moving Sphere height: {}".format(
-            TERRAIN_HEIGHT, stationary_start_z, Sphere.start_position_z
-        )
-    )
-    Report.result(Tests.stationary_above_terrain, TERRAIN_HEIGHT < (stationary_start_z - CLOSE_ENOUGH_THRESHOLD))
-    Report.result(
-        Tests.moving_above_stationary, stationary_start_z < (Sphere.start_position_z - CLOSE_ENOUGH_THRESHOLD)
-    )
-
-    # 5)Check that the gravity works and the Moving entity falls down
-    def sphere_fell():
-        if not Sphere.fell:
-            Sphere.position_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", moving_id)
-            if Sphere.position_z < (Sphere.start_position_z - CLOSE_ENOUGH_THRESHOLD):
-                Report.info("Sphere position is now lower than the starting position")
-                Sphere.fell = True
-        return Sphere.fell
-
-    helper.wait_for_condition(sphere_fell, TIMEOUT)
-    Report.result(Tests.gravity_works, Sphere.fell)
-
-    # 6) Check Spheres collide only with each other, but not with terrain
-    class Collision:
-        entity_collision = False
-        terrain_collision = False
-
-    class CollisionHandler:
-        def __init__(self, id, func):
-            self.id = id
-            self.func = func
-            self.create_collision_handler()
-
-        def on_collision_begin(self, args):
-            self.func(args[0])
-
-        def create_collision_handler(self):
-            self.handler = azlmbr.physics.CollisionNotificationBusHandler()
-            self.handler.connect(self.id)
-            self.handler.add_callback("OnCollisionBegin", self.on_collision_begin)
-
-    def on_collision_terrain(other_id):
-        Collision.terrain_collision = True
-        Report.info("Collision occured in between Moving or Stationary entity with Terrain")
-
-    def on_moving_entity_collision(other_id):
-        if other_id.Equal(stationary_id):
-            Collision.entity_collision = True
-
-    # collision handler for entities
-    CollisionHandler(terrain_id, on_collision_terrain)
-    CollisionHandler(moving_id, on_moving_entity_collision)
-    # wait till timeout to check for any collisions happening in the level
-    helper.wait_for_condition(lambda: Collision.entity_collision, TIMEOUT)
-    Report.result(Tests.collisions, Collision.entity_collision and not Collision.terrain_collision)
-
-    # 7)Check Moving Entity should be below terrain after collision
-    def sphere_below_terrain():
-        if not Sphere.below_terrain:
-            Sphere.position_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", moving_id)
-            if Sphere.position_z < (TERRAIN_HEIGHT - MIN_BELOW_TERRAIN):
-                Sphere.below_terrain = True
-        return Sphere.below_terrain
-
-    sphere_under_terrain = helper.wait_for_condition(sphere_below_terrain, TIMEOUT)
-    Report.result(Tests.falls_below_terrain_height, sphere_under_terrain)
-
-    # 8) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_SameCollisionGroupSameLayerCollide)

+ 0 - 233
AutomatedTesting/Gem/PythonTests/Physics/tests/collider/Collider_TriggerPassThrough.py

@@ -1,233 +0,0 @@
-"""
-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 ID    : C4982595
-# Test Case Title : Verify that when the Trigger Checkbox is ticked, the object no longer collides with another object
-#                   but simply passes through it
-
-
-
-# fmt: off
-class Tests:
-    enter_game_mode                          = ("Entered game mode",                        "Failed to enter game mode")
-    sphere_found_valid                       = ("Sphere found and validated",               "Failed to find and validate Sphere")
-    trigger_box_found_valid                  = ("Trigger Box found and validated",          "Failed to find and validate Trigger Box")
-    physical_box_found_valid                 = ("Physical Box found and validated",         "Failed to find and validate Physical Box")
-    sphere_gravity_disabled                  = ("Gravity is disabled on Sphere",            "Gravity is enabled on Sphere")
-    sphere_positive_initial_x_velocity       = ("Sphere has positive initial x-velocity",   "Sphere does not have positive initial x-velocity")
-    sphere_entered_trigger_box               = ("Sphere entered Trigger Box",               "Sphere did not enter Trigger Box")
-    sphere_exited_trigger_box                = ("Sphere exited Trigger Box",                "Sphere did not exit Trigger Box")
-    sphere_passed_through_trigger_box        = ("Sphere passed through Trigger Box",        "Sphere did not pass through Trigger Box")
-    sphere_collided_with_physical_box        = ("Sphere collided with Physical Box",        "Sphere did not collide with Physical Box")
-    sphere_bounced_back                      = ("Sphere bounced back from Physical Box",    "Sphere did not bounce back from Physical Box")
-    sphere_did_not_pass_through_physical_box = ("Sphere did not pass through Physical Box", "Sphere passed through Physical Box")
-    exit_game_mode                           = ("Exited game mode",                         "Failed to exit game mode")
-# fmt: on
-
-
-def Collider_TriggerPassThrough():
-    """
-    Summary:
-    This script runs an automated test to verify that when an entity's PhysX collider is set as a trigger, the entity no
-    longer collides with another entity.
-
-    Level Description:
-    Entity: Sphere:       PhysX Rigid Body, PhysX Collider with sphere shape, and Mesh with sphere asset
-                          Gravity disabled, Radius 1.0, Initial linear x-velocity +30 m/s, Position (36.0, 36.0, 36.0)
-    Entity: Trigger Box:  PhysX Collider with box shape, and Mesh with cube asset
-                          Trigger enabled, Dimensions (2.0, 2.0, 2.0), Z-offset 1.0, Position (42.0, 36.0, 35.0)
-    Entity: Physical Box: PhysX Collider with box shape, and Mesh with cube asset
-                          Dimensions (2.0, 2.0, 2.0), Z-offset 1.0, Position (48.0, 36.0, 35.0)
-    The entities are aligned along the x-axis as follows:
-                      _              _
-       O   --->      !_!            |_|
-    Sphere       Trigger Box    Physical Box
-
-    Expected behavior:
-    The sphere will pass through the trigger box, collide with the physical box, and bounce back without passing through
-    the physical box.
-
-    Test Steps:
-     1) Open level and enter game mode
-     2) Retrieve and validate entities
-     3) Check that gravity is disabled on the sphere
-     4) Check that the sphere has positive initial x-velocity
-     5) Wait for the sphere to enter the trigger box
-     6) Wait for the sphere to exit the trigger box
-     7) Check that the sphere passed through the trigger box
-     8) Wait for the sphere to collide with the physical box
-     9) Wait for the sphere to stop colliding with the physical box and check that the sphere bounced back
-    10) Check that the sphere did not pass through the physical box
-    11) Exit game mode and close editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    # Setup path
-    import os
-    import sys
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-    import azlmbr.components
-    import azlmbr.physics
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    TIME_OUT_SECONDS = 3.0
-    SPHERE_RADIUS = 1.0
-    BOX_X_DIMENSION = 2.0
-    BOX_X_RADIUS = BOX_X_DIMENSION / 2
-    CLOSE_ENOUGH_BUFFER = 0.1
-
-    class Entity:
-        def __init__(self, name, found_valid_test):
-            self.name = name
-            self.id = general.find_game_entity(name)
-            self.found_valid_test = found_valid_test
-
-        def get_x_position(self):
-            position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-            Report.info_vector3(position, "{}'s position:".format(self.name))
-            return position.x
-
-    class Sphere(Entity):
-        def __init__(self, name, found_valid_test):
-            Entity.__init__(self, name, found_valid_test)
-            self.initial_x_velocity = self.get_x_velocity()
-
-            # Trigger state values
-            self.entered_trigger_target = False
-            self.trigger_enter_position = None
-            self.exited_trigger_target = False
-            self.trigger_exit_position = None
-            self.passed_through_trigger_target = False
-
-            # Collision state values
-            self.began_collision_with_collision_target = False
-            self.ended_collision_with_collision_target = False
-            self.bounced_back = False
-            self.did_not_pass_through_collision_target = None
-
-        def is_gravity_disabled(self):
-            return not azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
-
-        def get_x_velocity(self):
-            velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
-            Report.info_vector3(velocity, "{}'s velocity:".format(self.name))
-            return velocity.x
-
-    class TriggerBox(Entity):
-        def __init__(self, name, found_valid_test, trigger_target):
-            Entity.__init__(self, name, found_valid_test)
-            self.trigger_target = trigger_target
-
-            # Set up trigger notification handler
-            self.handler = azlmbr.physics.TriggerNotificationBusHandler()
-            self.handler.connect(self.id)
-            self.handler.add_callback("OnTriggerEnter", self.on_trigger_enter)
-            self.handler.add_callback("OnTriggerExit", self.on_trigger_exit)
-
-        def on_trigger_enter(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.trigger_target.id) and not self.trigger_target.entered_trigger_target:
-                self.trigger_target.trigger_enter_position = self.trigger_target.get_x_position()
-                self.trigger_target.entered_trigger_target = True
-
-        def on_trigger_exit(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.trigger_target.id) and not self.trigger_target.exited_trigger_target:
-                self.trigger_target.trigger_exit_position = self.trigger_target.get_x_position()
-                self.trigger_target.exited_trigger_target = True
-                # Check that the sphere's position traveled at least the approximate x-length of the box measured from
-                # the point on the sphere where it entered the trigger to the point on the sphere where it exited
-                if (
-                    self.trigger_target.trigger_exit_position - SPHERE_RADIUS + CLOSE_ENOUGH_BUFFER
-                    >= self.trigger_target.trigger_enter_position + BOX_X_DIMENSION + SPHERE_RADIUS
-                ):
-                    self.trigger_target.passed_through_trigger_target = True
-
-    class PhysicalBox(Entity):
-        def __init__(self, name, found_valid_test, collision_target):
-            Entity.__init__(self, name, found_valid_test)
-            self.collision_target = collision_target
-
-            # Set up collision notification handler
-            self.collision_handler = azlmbr.physics.CollisionNotificationBusHandler()
-            self.collision_handler.connect(self.id)
-            self.collision_handler.add_callback("OnCollisionBegin", self.on_collision_begin)
-            self.collision_handler.add_callback("OnCollisionEnd", self.on_collision_end)
-
-        def on_collision_begin(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.collision_target.id):
-                self.collision_target.began_collision_with_collision_target = True
-
-        def on_collision_end(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.collision_target.id):
-                self.collision_target.ended_collision_with_collision_target = True
-                # Check that the sphere reversed its x-direction
-                if self.collision_target.get_x_velocity() < 0:
-                    self.collision_target.bounced_back = True
-                # Check that the whole sphere is to the negative x-direction of the box
-                if sphere.get_x_position() + SPHERE_RADIUS <= physical_box.get_x_position() - BOX_X_RADIUS:
-                    self.collision_target.did_not_pass_through_collision_target = True
-
-    # 1) Open level and enter game mode
-    helper.init_idle()
-    helper.open_level("Physics", "Collider_TriggerPassThrough")
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 2) Retrieve and validate entities
-    sphere = Sphere("Sphere", Tests.sphere_found_valid)
-    trigger_box = TriggerBox("Trigger Box", Tests.trigger_box_found_valid, trigger_target=sphere)
-    physical_box = PhysicalBox("Physical Box", Tests.physical_box_found_valid, collision_target=sphere)
-
-    entities = (sphere, trigger_box, physical_box)
-    for entity in entities:
-        Report.critical_result(entity.found_valid_test, entity.id.IsValid())
-
-    # 3) Check that gravity is disabled on the sphere
-    Report.critical_result(Tests.sphere_gravity_disabled, sphere.is_gravity_disabled())
-
-    # 4) Check that the sphere has positive initial x-velocity
-    Report.critical_result(Tests.sphere_positive_initial_x_velocity, sphere.initial_x_velocity > 0)
-
-    # 5) Wait for the sphere to enter the trigger box
-    helper.wait_for_condition(lambda: sphere.entered_trigger_target, TIME_OUT_SECONDS)
-    Report.critical_result(Tests.sphere_entered_trigger_box, sphere.entered_trigger_target)
-
-    # 6) Wait for the sphere to exit the trigger box
-    helper.wait_for_condition(lambda: sphere.exited_trigger_target, TIME_OUT_SECONDS)
-    Report.critical_result(Tests.sphere_exited_trigger_box, sphere.exited_trigger_target)
-
-    # 7) Check that the sphere passed through the trigger box
-    Report.critical_result(Tests.sphere_passed_through_trigger_box, sphere.passed_through_trigger_target)
-
-    # 8) Wait for the sphere to collide with the physical box
-    helper.wait_for_condition(lambda: sphere.began_collision_with_collision_target, TIME_OUT_SECONDS)
-    Report.critical_result(Tests.sphere_collided_with_physical_box, sphere.began_collision_with_collision_target)
-
-    # 9) Wait for the sphere to stop colliding with the physical box and check that the sphere bounced back
-    helper.wait_for_condition(lambda: sphere.ended_collision_with_collision_target, TIME_OUT_SECONDS)
-    Report.result(Tests.sphere_bounced_back, sphere.bounced_back)
-
-    # 10) Check that the sphere did not pass through the physical box
-    Report.result(Tests.sphere_did_not_pass_through_physical_box, sphere.did_not_pass_through_collision_target)
-
-    # 11) Exit game mode and close editor
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Collider_TriggerPassThrough)

+ 0 - 222
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_CapsuleShapedForce.py

@@ -1,222 +0,0 @@
-"""
-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 ID : C5959760
-# Test Case Title : Check that force region (capsule) exerts point force
-
-
-
-# fmt: off
-class Tests:
-    enter_game_mode         = ("Entered game mode",                 "Failed to enter game mode")
-    box_entity_found        = ("Box was found in game",             "Box COULD NOT be found in game")
-    capsule_entity_found    = ("Capsule was found in game",         "Capsule COULD NOT be found in game")
-    box_pos_found           = ("Box position found",                "Box position not found")
-    capsule_pos_found       = ("Capsule position found",            "Capsule position not found")
-    force_region_entered    = ("Force region entered",              "Force region never entered")
-    force_exertion_predicted = ("Force exerted was predictable",    "The force exerted WAS NOT predicted")
-    box_fell                = ("Box fell",                          "The box did not fall")
-    box_was_pushed_x_z      = ("Box moved positive X, Z",           "Box DID NOT move in positive X, Z direction")
-    box_no_y_movement       = ("Box had no substantial Y movement", "Box HAD substantial Y movement")
-    capsule_no_move         = ("Capsule did not move",              "Capsule DID move")
-    exit_game_mode          = ("Exited game mode",                  "Couldn't exit game mode")
-    time_out                = ("Test did not time out",             "Test DID time out")
-
-# fmt: on
-
-
-def ForceRegion_CapsuleShapedForce():
-    # type: () -> None
-    """
-    Summary:
-    Runs an automated test to ensure point force from a capsule force region is exerted on rigid body objects.
-
-    Level Description:
-    A cube (entity: Box) set above a capsule force region (entity: Capsule). The Capsule was assigned point force
-    with magnitude set to 1000. The Box has been set for "gravity enabled"
-
-    Expected behavior:
-    The Box will fall (due to gravity) into the Capsule's force region. The force region should exert the point
-    force on the Box, applying a positive X and Z force of substantial magnitude.
-
-    Test Steps:
-    1) Loads the level / Enters game mode
-    2) Retrieve entities
-    3) Ensures that the test objects (Box and Capsule) are located
-        3.5) set up variables and handlers for monitoring results
-    4) Waits for the box to fall into the force region
-            or for time out if something unexpected happens
-    5) Logs results
-    6) Closes the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Global constants
-    CLOSE_ENOUGH = 0.001
-    TIME_OUT = 1.5
-
-    # Base class
-    class EntityBase:
-        def __init__(self, name):
-            self.name = name
-            self.id = None
-            self.initial_pos = None
-            self.current_pos = None
-
-    # Box child class of EntityBase
-    class Box(EntityBase):
-        def __init__(self, name):
-            EntityBase.__init__(self, name)
-            self.triggered_pos = None
-            self.fell = False
-            self.force_observed = False
-
-        def check_for_fall(self):
-            FALL_BUFFER = 0.2
-            if not self.fell:
-                self.fell = (
-                    self.initial_pos.z > self.current_pos.z + FALL_BUFFER
-                    and abs(self.initial_pos.x - self.current_pos.x) < CLOSE_ENOUGH
-                    and abs(self.initial_pos.y - self.current_pos.y) < CLOSE_ENOUGH
-                )
-            return self.fell
-
-        def check_for_force(self):
-            FORCE_BUFFER = 0.2
-            if not self.force_observed:
-                self.force_observed = (
-                    self.current_pos.z > self.triggered_pos.z + FORCE_BUFFER
-                    and self.current_pos.x > self.triggered_pos.x
-                    and abs(self.triggered_pos.y - self.current_pos.y) < CLOSE_ENOUGH
-                )
-            return self.force_observed
-
-    # Force Region child class of EntityBase
-    class ForceRegion(EntityBase):
-        def __init__(self, name):
-            EntityBase.__init__(self, name)
-            self.expected_force_magnitude = None
-            self.actual_force_vector = None
-            self.actual_force_magnitude = None
-            self.forced_entity = None
-            self.triggered = False
-
-    # 1) Open level / Enter game mode
-    helper.init_idle()
-    helper.open_level("Physics", "ForceRegion_CapsuleShapedForce")
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 2) Retrieve entities
-    box = Box("Box")
-    box.id = general.find_game_entity(box.name)
-    capsule = ForceRegion("Capsule")
-    capsule.id = general.find_game_entity(capsule.name)
-
-    Report.critical_result(Tests.box_entity_found, box.id.IsValid())
-    Report.critical_result(Tests.capsule_entity_found, capsule.id.IsValid())
-
-    # 3) Log positions for Box and Capsule
-    box.initial_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", box.id)
-    capsule.initial_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", capsule.id)
-    box.current_pos = box.initial_pos
-    capsule.current_pos = capsule.initial_pos
-
-    # validate and print positions to confirm objects were found
-    Report.critical_result(Tests.box_pos_found, box.initial_pos is not None and not box.initial_pos.IsZero())
-    Report.critical_result(
-        Tests.capsule_pos_found, capsule.initial_pos is not None and not capsule.initial_pos.IsZero()
-    )
-    capsule.expected_force_magnitude = azlmbr.physics.ForcePointRequestBus(azlmbr.bus.Event, "GetMagnitude", capsule.id)
-
-    # 3.5) set up handler
-
-    # Force Region Event Handler
-    def on_force_calculated(args):
-
-        # Only store data for first force region calculation
-        if not capsule.triggered and capsule.id.Equal(args[0]):
-            capsule.triggered = True
-            capsule.forced_entity = args[1]
-            capsule.actual_force_vector = args[2]
-            capsule.actual_force_magnitude = args[3]
-            if capsule.forced_entity.Equal(box.id):
-                box.triggered_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", box.id)
-                Report.info("Force Region exerted force on {}".format(box.name))
-
-    # Assign the handler
-    handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    handler.connect(None)
-    handler.add_callback("OnCalculateNetForce", on_force_calculated)
-
-    def done_collecting_results():
-        # Update entity positions
-        capsule.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", capsule.id)
-        box.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", box.id)
-        # Check for three "test complete" conditions
-        # ! Careful ordering for logic short circuiting. DO NOT SWAP ORDER !
-        return box.check_for_fall() and capsule.triggered and box.check_for_force()
-
-    # 4) wait for force region entry or time out
-    test_completed = helper.wait_for_condition(done_collecting_results, TIME_OUT)
-    Report.critical_result(Tests.time_out, test_completed)
-
-    # 5) Report findings
-    Report.result(Tests.box_fell, box.fell)
-    Report.result(Tests.force_region_entered, capsule.triggered)
-    Report.result(
-        Tests.force_exertion_predicted,
-        abs(capsule.expected_force_magnitude - capsule.actual_force_magnitude) < CLOSE_ENOUGH,
-    )
-    Report.result(Tests.box_was_pushed_x_z, box.force_observed)
-    Report.result(Tests.box_no_y_movement, abs(box.initial_pos.y - box.current_pos.y) < CLOSE_ENOUGH)
-    Report.result(Tests.capsule_no_move, capsule.initial_pos.IsClose(capsule.current_pos))
-
-    # Collected Data Dump
-    Report.info("******* Collected Data *******")
-    Report.info("Entity: {}".format(box.name))
-    Report.info_vector3(box.initial_pos, " Initial Position:")
-    Report.info_vector3(box.triggered_pos, " Trigger Position:")
-    Report.info_vector3(box.current_pos, " Final Position:")
-    Report.info(" Fell: {}".format(box.fell))
-    Report.info(" Force Observed: {}".format(box.force_observed))
-    Report.info("******************************")
-    Report.info("Entity: {}".format(capsule.name))
-    Report.info_vector3(capsule.initial_pos, " Initial Position:")
-    Report.info_vector3(capsule.current_pos, " Final Position:")
-    Report.info(" Expected Force Magnitude: {:.2f}".format(capsule.expected_force_magnitude))
-    Report.info_vector3(capsule.actual_force_vector, " Actual Force Vector:", capsule.actual_force_magnitude)
-    Report.info(" Triggered: {}".format(capsule.triggered))
-    Report.info(
-        " Triggered Entity: {}".format(
-            azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "GetEntityName", capsule.forced_entity)
-        )
-    )
-
-    Report.info("******************************")
-
-    # 6) Exit Game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-    Report.info("*** FINISHED TEST ***")
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_CapsuleShapedForce)

+ 0 - 282
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_DirectionHasNoAffectOnTotalForce.py

@@ -1,282 +0,0 @@
-"""
-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 ID : C12868578
-# Test Case Title : Check that World space and local space force direction doesn't affect magnitude of force exerted
-
-
-# fmt: off
-class Tests:
-    enter_game_mode      = ("Entered game mode",                        "Failed to enter game mode")
-    exit_game_mode       = ("Exited game mode",                         "Couldn't exit game mode")
-    entity_position      = ("All entities in good relative position",   "Not all entities in correct position")
-    sphere_collisions    = ("All spheres collided with Force Regions",  "Not All spheres collided")
-    initial_velocity     = ("Spheres started moving correctly",         "Spheres not moving correctly")
-    velocity_updated     = ("Sphere velocities updated",                "Sphere velocities didn't update")
-
-    # Z Direction
-    sphere_0_found       = ("sphere_0 is found",                        "sphere_0 is not found")
-    sphere_1_found       = ("sphere_1 is found",                        "sphere_1 is not found")
-    force_region_0_found = ("force_region_0 is found",                  "force_region_0 is not found")
-    force_region_1_found = ("force_region_1 is found",                  "force_region_1 is not found")
-    local_force_mag_z    = ("z-axis Local Space force magnitude valid", "z-axis Local Space force magnitude invalid")
-    local_force_dir_z    = ("z-axis Local Space force direction valid", "z-axis Local Space force direction invalid")
-    world_force_mag_z    = ("z-axis World Space force magnitude valid", "z-axis World Space force magnitude invalid")
-    world_force_dir_z    = ("z-axis World Space force direction valid", "z-axis World Space force direction invalid")
-
-    # X Direction
-    sphere_2_found       = ("sphere_2 is found",                        "sphere_2 is not found")
-    sphere_3_found       = ("sphere_3 is found",                        "sphere_3 is not found")
-    force_region_2_found = ("force_region_2 is found",                  "force_region_2 is not found")
-    force_region_3_found = ("force_region_3 is found",                  "force_region_3 is not found")
-    local_force_mag_x    = ("x-axis Local Space force magnitude valid", "x-axis Local Space force magnitude invalid")
-    local_force_dir_x    = ("x-axis Local Space force direction valid", "x-axis Local Space force direction invalid")
-    world_force_mag_x    = ("x-axis World Space force magnitude valid", "x-axis World Space force magnitude invalid")
-    world_force_dir_x    = ("x-axis World Space force direction valid", "x-axis World Space force direction invalid")
-
-    # Y Direction
-    sphere_4_found       = ("sphere_4 is found",                        "sphere_4 is not found")
-    sphere_5_found       = ("sphere_5 is found",                        "sphere_5 is not found")
-    force_region_4_found = ("force_region_4 is found",                  "force_region_4 is not found")
-    force_region_5_found = ("force_region_5 is found",                  "force_region_5 is not found")
-    local_force_mag_y    = ("y-axis Local Space force magnitude valid", "y-axis Local Space force magnitude invalid")
-    local_force_dir_y    = ("y-axis Local Space force direction valid", "y-axis Local Space force direction invalid")
-    world_force_mag_y    = ("y-axis World Space force magnitude valid", "y-axis World Space force magnitude invalid")
-    world_force_dir_y    = ("y-axis World Space force direction valid", "y-axis World Space force direction invalid")
-# fmt: on
-
-
-def ForceRegion_DirectionHasNoAffectOnTotalForce():
-    """
-    Summary: Check that world and local space force direction should not affect magnitude of force exerted on entity.
-
-    Level Description:
-    sphere_0 - Directly above force_region_0 with velocity of 10.0 in the negative z direction; has sphere shape
-        collider, rigid body, and sphere shape
-    sphere_1 - Directly above force_region_1 with velocity of 10.0 in the negative z direction; has sphere shape
-        collider, rigid body, and sphere shape
-    force_region_0 - Directly below sphere_0 with world space force of magnitude 100.0 and direction vector of
-        <0.0,0.0,999.0>; has box shape collider and force region
-    force_region_1 - Directly below sphere_1 with local space force of magnitude 100.0 and direction vector of
-        <0.0,0.0,999.0>; has box shape collider and force region
-
-    Expected Behavior: Both spheres bounce off of there respective force regions with a force of magnitude that is close
-        to 100.0 in positive z direction. The direction is normalized from the manual entered direction input.
-
-    Test Steps:
-    1) Open Level
-    2) Enter Game Mode
-    3) Set up and validate entities
-    4) Wait for collision
-    5) Wait for velocities to become positive
-    6) Log and validate results
-    7) Exit Game Mode
-    8) Close Editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Constants
-    FLOAT_THRESHOLD = sys.float_info.epsilon
-    TIMEOUT = 1
-    MAGNITUDE_THRESHOLD = 0.1
-    FORCE_VECTOR_THRESHOLD = 0.001
-
-    # Helper Functions
-    class Entity:
-        def __init__(self, name):
-            # type (str, hex) -> None
-            self.id = general.find_game_entity(name)
-            self.name = name
-            self.collision_happened = False
-            # ID validation
-            self.found = Tests.__dict__[self.name + "_found"]
-            Report.critical_result(self.found, self.id.isValid())
-
-        @property
-        def position(self):
-            # type () -> Vector3
-            return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-
-    class Sphere(Entity):
-        def __init__(self, name, axis, force_region):
-            Entity.__init__(self, name)
-            self.paired_force_region = force_region
-            self.axis = axis
-            self.force_vector = None
-            self.force_magnitude = None
-            # Set Handler
-            self.handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-            self.handler.connect(None)
-            self.handler.add_callback("OnCalculateNetForce", self.on_calculate_net_force)
-            # Report initial values
-            Report.info_vector3(self.position, "{} initial position: ".format(self.name))
-            Report.info_vector3(self.velocity, "{} initial velocity: ".format(self.name))
-
-        @property
-        def velocity(self):
-            # type () -> Vector3
-            return azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
-
-        @property
-        def is_moving_in_positive_direction(self):
-            # type () -> bool
-            # A List of the attribute names for the velocity (Vector3)
-            axis = ["x", "y", "z"]
-            # Finds the index in the list of the attribute in which the sphere is moving in
-            index = axis.index(self.axis)
-            # Checking that we are moving along that axis
-            moving_component = getattr(self.velocity, axis[index]) > 0.0
-            # Getting rid of moving axis from list
-            axis.pop(index)
-            # Checking that the sphere is not moving along either of the remaining two axis.
-            stationary_components = (
-                abs(getattr(self.velocity, axis[0])) < FLOAT_THRESHOLD
-                and abs(getattr(self.velocity, axis[1])) < FLOAT_THRESHOLD
-            )
-            return moving_component and stationary_components
-
-        def report_values(self):
-            # type () -> None
-            # Reports final position and velocity information
-            Report.info_vector3(self.position, "{} final position: ".format(self.name))
-            Report.info_vector3(self.velocity, "{} final velocity: ".format(self.name))
-
-        def on_calculate_net_force(self, args):
-            # type (list) -> None
-            # Flips the collision happened boolean for the sphere object and prints the force values.
-            if self.paired_force_region.id.Equal(args[0]) and self.id.equal(args[1]) and not self.collision_happened:
-                self.collision_happened = True
-                self.force_vector = args[2]
-                self.force_magnitude = args[3]
-                # Report force vector information
-                Report.info_vector3(self.force_vector, "{} had following force vector applied".format(self.name))
-                Report.info("{} is the applied force magnitude".format(self.force_magnitude))
-
-    def validate_local_force_results(sphere):
-        # type (Sphere) -> None
-        local_force_direction = Tests.__dict__["local_force_dir_{}".format(sphere.axis)]
-        local_force_magnitude = Tests.__dict__["local_force_mag_{}".format(sphere.axis)]
-
-        Report.result(local_force_direction, check_applied_force_vector(sphere.force_vector))
-        force_region_magnitude = azlmbr.physics.ForceLocalSpaceRequestBus(azlmbr.bus.Event,"GetMagnitude", sphere.paired_force_region.id)
-        print(force_region_magnitude)
-        print("LOOKKKK ABOVE!")
-        Report.result(local_force_magnitude, abs(sphere.force_magnitude - force_region_magnitude) < MAGNITUDE_THRESHOLD)
-
-    def validate_world_force_results(sphere):
-        # type (Sphere) -> None
-        world_force_direction = Tests.__dict__["world_force_dir_{}".format(sphere.axis)]
-        world_force_magnitude = Tests.__dict__["world_force_mag_{}".format(sphere.axis)]
-
-        Report.result(world_force_direction, check_applied_force_vector(sphere.force_vector))
-        force_region_magnitude = azlmbr.physics.ForceWorldSpaceRequestBus(azlmbr.bus.Event,"GetMagnitude", sphere.paired_force_region.id)
-        Report.result(world_force_magnitude, abs(sphere.force_magnitude - force_region_magnitude) < MAGNITUDE_THRESHOLD)
-
-    def check_pair_position(sphere):
-        # type (Sphere) -> bool
-        # Ensures sphere lines up with its associated force region
-        force_region_position = sphere.paired_force_region.position
-        axis = ["x", "y", "z"]
-        index = axis.index(sphere.axis)
-        offset_component = getattr(force_region_position, axis[index]) < getattr(sphere.position, axis[index])
-        axis.pop(index)
-        zero_components = (
-            abs(getattr(force_region_position, axis[0]) - getattr(sphere.position, axis[0])) < FLOAT_THRESHOLD
-            and abs(getattr(force_region_position, axis[1]) - getattr(sphere.position, axis[1])) < FLOAT_THRESHOLD
-        )
-        return offset_component and zero_components
-
-    def check_applied_force_vector(vector):
-        # type (Sphere) -> bool
-        # Ensures the force vector is within expected threshold. The components of the vector can either be 0 or 1
-        axis = ["x", "y", "z"]
-        return all(
-            [
-                True
-                for component in axis
-                if abs(getattr(vector, component) - 1.00) < FORCE_VECTOR_THRESHOLD
-                or abs(getattr(vector, component)) < FORCE_VECTOR_THRESHOLD
-            ]
-        )
-
-    # Main Script
-    helper.init_idle()
-    # 1) Open Level
-    helper.open_level("Physics", "ForceRegion_DirectionHasNoAffectOnTotalForce")
-
-    # 2) Enter Game Mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Set up and validate entities
-    force_region_0 = Entity("force_region_0")
-    force_region_1 = Entity("force_region_1")
-    force_region_2 = Entity("force_region_2")
-    force_region_3 = Entity("force_region_3")
-    force_region_4 = Entity("force_region_4")
-    force_region_5 = Entity("force_region_5")
-
-    sphere_0 = Sphere("sphere_0", "z", force_region_0)
-    sphere_1 = Sphere("sphere_1", "z", force_region_1)
-    sphere_2 = Sphere("sphere_2", "x", force_region_2)
-    sphere_3 = Sphere("sphere_3", "x", force_region_3)
-    sphere_4 = Sphere("sphere_4", "y", force_region_4)
-    sphere_5 = Sphere("sphere_5", "y", force_region_5)
-    sphere_list = [sphere_0, sphere_1, sphere_2, sphere_3, sphere_4, sphere_5]
-    local_force_list = [sphere_1, sphere_3, sphere_5]
-    world_force_list = [sphere_0, sphere_2, sphere_4]
-
-    Report.critical_result(
-        Tests.entity_position, all([check_pair_position(sphere) for sphere in sphere_list])
-    )
-
-    Report.critical_result(
-        Tests.initial_velocity,
-        all([not sphere.is_moving_in_positive_direction for sphere in sphere_list]),
-    )
-
-    # 4) Wait for collision
-    Report.critical_result(
-        Tests.sphere_collisions,
-        helper.wait_for_condition(
-            lambda: all([sphere.collision_happened for sphere in sphere_list]), TIMEOUT
-        ),
-    )
-
-    # 5) Wait for velocities to become positive
-    Report.critical_result(
-        Tests.velocity_updated,
-        helper.wait_for_condition(
-            lambda: all([sphere.is_moving_in_positive_direction for sphere in sphere_list]), TIMEOUT
-        ),
-    )
-
-    # 6) Log and validate results
-    [validate_local_force_results(sphere) for sphere in local_force_list]
-    [validate_world_force_results(sphere) for sphere in world_force_list]
-
-    [sphere.report_values() for sphere in sphere_list]
-
-    # 7) Exit Game Mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_DirectionHasNoAffectOnTotalForce)

+ 0 - 246
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_HighValuesDirectionAxesWorkWithNoError.py

@@ -1,246 +0,0 @@
-"""
-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 ID : C6321601
-# Test Case Title : Check that very high values of direction axes of forces do not throw error
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode              = ("Entered game mode",                                    "Failed to enter game mode")
-    find_terrain                 = ("Terrain found",                                        "Terrain not found")
-    find_sphere_world_space      = ("Sphere above world force region found",                "Sphere above world force region not found")
-    find_sphere_local_space      = ("Sphere above local force region found",                "Sphere above local force region not found")
-    find_sphere_point            = ("Sphere above point force region found",                "Sphere above point force region not found")
-    find_sphere_simple_drag      = ("Sphere above simple drag force region found",          "Sphere above simple drag force region not found")
-    find_sphere_linear_damping   = ("Sphere above linear damping force region found",       "Sphere above linear damping force region not found")
-    find_forcevol_world_space    = ("World force region found",                             "World force region not found")
-    find_forcevol_local_space    = ("Local force region found",                             "Local force region not found")
-    find_forcevol_point          = ("Point force region found",                             "Point force region not found")
-    find_forcevol_simple_drag    = ("Simple drag force region found",                       "Simple drag force region not found")
-    find_forcevol_linear_damping = ("Linear damping force region found",                    "Linear damping force region not found")
-    world_force_magnitude        = ("World force magnitude equal to expected magnitude",    "World force magnitude not equal to expected magnitude")
-    world_force_direction        = ("World force direction equal to expected direction",    "World force direction not equal to expected direction")
-    local_force_magnitude        = ("Local force magnitude equal to expected magnitude",    "Local force magnitude not equal to expected magnitude")
-    local_force_direction        = ("Local force direction equal to expected direction",    "Local force direction not equal to expected direction")
-    point_force_magnitude        = ("Point force magnitude equal to expected magnitude",    "Point force magnitude not equal to expected magnitude")
-    simp_drag_density            = ("Simple Drag force density equal to expected value",    "Simple Drag force density not equal to expected value")
-    lin_damp_damping             = ("Linear Damping force damping equal to expected value", "Linear Damping force damping not equal to expected value")
-    error_not_found              = ("Error not found",                                      "Error found")
-    exit_game_mode               = ("Exited game mode",                                     "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_HighValuesDirectionAxesWorkWithNoError():
-
-    """
-    Summary:
-    Check that very high values of direction axes of forces do not throw error.
-
-    Level Description:
-    Sphere_World_Space, Sphere_Local_Space, Sphere_Point, Sphere_Simple_Drag, Sphere_Linear_Damping
-    (Entities) Entities with components:
-      - Physx Collider (Sphere shaped with radius 1.0)
-      - Mesh(Prmitive sphere mesh)
-      - PhysX Rigid Body Physics
-
-    Below are the entities with common components
-      - PhysX Collider (Trigger enabled)
-      - PhysX Force Region(Visible and Debug Forces enabled)
-    They differ in Force Region Force Type with the following properties:
-      1) ForceVol_World_Space
-            Type - World Space - Direction(0.0, 0.0, 999999.0) - Magnitude(999999.0)
-      2) ForceVol_Local_Space
-            Type - Local Space - Direction(0.0, 0.0, 999999.0) - Magnitude(999999.0)
-      3) ForceVol_Point
-            Type - Point - Magnitude(999999.0)
-      4) ForceVol_Simple_Drag
-            Type - Simple Drag - Region Density(999.0)
-      5) ForceVol_Linear_Damping
-            Type - Linear Damping - Damping(99.0)
-    Each sphere is placed above its corresponding force regions.
-    Each of the force regions are seperated by some distance
-
-    Expected Behavior:
-    The given force should be applied as it is without any error on the Sphere.
-    We are verifying if the force being applied on each sphere is equal to the expected value
-
-    Test Steps:
-     1) Open level
-     2) Enter game mode
-     3) Retrieve and validate entities
-     4) Add force region handler and validate the forces
-     5) Exit game mode
-     6) Close the editor
-
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Aed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    from editor_python_test_tools.utils import Tracer
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-    import azlmbr.math as lymath
-
-    # Constants
-    TOLERANCE_PERCENT = 0.001
-    EXPECTED_DIRECTION = lymath.Vector3(0.0, 0.0, 1.0)
-    EXPECTED_DAMPING = 99.0
-    EXPECTED_DENSITY = 400.0
-    CLOSE_THRESHOLD = 0.0001
-
-    class SphereForceRegion:
-        def __init__(self, force_name):
-            self.force_name = force_name
-            self.sphere_name = "Sphere_{}".format(force_name)
-            self.force_region_name = "ForceVol_{}".format(force_name)
-            self.sphere_id = general.find_game_entity(self.sphere_name)
-            self.force_region_id = general.find_game_entity(self.force_region_name)
-            self.in_force_region = False
-            self.validate_entities()
-
-        def validate_entities(self):
-            Report.result(Tests.__dict__["find_{}".format(self.sphere_name.lower())], self.sphere_id.IsValid())
-            Report.result(
-                Tests.__dict__["find_{}".format(self.force_region_name.lower())], self.force_region_id.IsValid()
-            )
-
-    def validate_world_space_force(args):
-        Report.info("Validating world space force...")
-        world_expected_magnitude = azlmbr.physics.ForceWorldSpaceRequestBus(
-            azlmbr.bus.Event, "GetMagnitude", regions[0].force_region_id
-        )
-        world_actual_magnitude = args[3]
-        Report.info(
-            "Actual Magnitude: {}\t Expected Magnitude: {}".format(world_actual_magnitude, world_expected_magnitude)
-        )
-        Report.result(
-            Tests.world_force_magnitude,
-            abs(world_actual_magnitude - world_expected_magnitude) < TOLERANCE_PERCENT * world_expected_magnitude,
-        )
-        world_actual_direction = args[2]
-        Report.result(Tests.world_force_direction, world_actual_direction.IsClose(EXPECTED_DIRECTION, CLOSE_THRESHOLD))
-
-    def validate_local_space_force(args):
-        Report.info("Validating local space force...")
-        local_expected_magnitude = azlmbr.physics.ForceLocalSpaceRequestBus(
-            azlmbr.bus.Event, "GetMagnitude", regions[1].force_region_id
-        )
-        local_actual_magnitude = args[3]
-        Report.info(
-            "Actual Magnitude: {}\t Expected Magnitude: {}".format(local_actual_magnitude, local_expected_magnitude)
-        )
-        Report.result(
-            Tests.local_force_magnitude,
-            abs(local_actual_magnitude - local_expected_magnitude) < TOLERANCE_PERCENT * local_expected_magnitude,
-        )
-        local_actual_direction = args[2]
-        Report.result(Tests.local_force_direction, local_actual_direction.IsClose(EXPECTED_DIRECTION, CLOSE_THRESHOLD))
-
-    def validate_point_force(args):
-        Report.info("Validating Point space force...")
-        point_expected_magnitude = azlmbr.physics.ForcePointRequestBus(
-            azlmbr.bus.Event, "GetMagnitude", regions[2].force_region_id
-        )
-        point_actual_magnitude = args[3]
-        Report.info(
-            "Actual Magnitude: {}\t Expected Magnitude: {}".format(point_actual_magnitude, point_expected_magnitude)
-        )
-        Report.result(
-            Tests.point_force_magnitude,
-            abs(point_actual_magnitude - point_expected_magnitude) < TOLERANCE_PERCENT * point_expected_magnitude,
-        )
-
-    def validate_simple_drag_force(args):
-        Report.info("Validating Simple Drag force...")
-        simp_drag_density = azlmbr.physics.ForceSimpleDragRequestBus(
-            azlmbr.bus.Event, "GetDensity", regions[3].force_region_id
-        )
-        Report.info("Density: {}\t Expected Density: {}".format(simp_drag_density, EXPECTED_DENSITY))
-        Report.result(Tests.simp_drag_density, simp_drag_density == EXPECTED_DENSITY)
-
-    def validate_linear_damping_force(args):
-        Report.info("Validating Linear Damping force...")
-        lin_damp_damping = azlmbr.physics.ForceLinearDampingRequestBus(
-            azlmbr.bus.Event, "GetDamping", regions[4].force_region_id
-        )
-        Report.info("Damping: {}\t Expected Damping: {}".format(lin_damp_damping, EXPECTED_DAMPING))
-        Report.result(Tests.lin_damp_damping, lin_damp_damping == EXPECTED_DAMPING)
-
-    def on_calc_net_force(args):
-        """
-        Args:
-            args[0] - force region entity
-            args[1] - entity entering
-            args[2] - vector
-            args[3] - magnitude
-        """
-        for index, region in enumerate(regions):
-            if args[0].Equal(region.force_region_id) and args[1].Equal(region.sphere_id) and not region.in_force_region:
-                region.in_force_region = True
-                force_validations[index][1](args)
-
-    helper.init_idle()
-
-    with Tracer() as entity_error_tracer:
-
-        def has_physx_error():
-            return entity_error_tracer.has_errors
-
-        # 1) Open level
-        helper.open_level("Physics", "ForceRegion_HighValuesDirectionAxesWorkWithNoError")
-
-        # 2) Enter game mode
-        helper.enter_game_mode(Tests.enter_game_mode)
-
-        # 3) Retrieve and validate entities
-        # Terrain
-        terrain_id = general.find_game_entity("Terrain")
-        Report.result(Tests.find_terrain, terrain_id.IsValid())
-        force_validations = (
-            ("World_Space", validate_world_space_force),
-            ("Local_Space", validate_local_space_force),
-            ("Point", validate_point_force),
-            ("Simple_Drag", validate_simple_drag_force),
-            ("Linear_Damping", validate_linear_damping_force),
-        )
-        regions = []
-        for item in force_validations:
-            regions.append(SphereForceRegion(item[0]))
-
-        # 4) Add force region handler and validate the forces
-        force_notification_handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-        force_notification_handler.connect(None)
-        force_notification_handler.add_callback("OnCalculateNetForce", on_calc_net_force)
-
-        # Wait for 3 secs, because there is a known bug identified and filed in
-        # JIRA LY-107677
-        # The error "[Error] Huge object being added to a COctreeNode, name: 'MeshComponentRenderNode', objBox:"
-        # will show (if occured) in about 3 sec into the game mode.
-        helper.wait_for_condition(has_physx_error, 3.0)
-
-        # 5) Exit game mode
-        helper.exit_game_mode(Tests.exit_game_mode)
-
-    Report.result(Tests.error_not_found, not has_physx_error())
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_HighValuesDirectionAxesWorkWithNoError)

+ 0 - 165
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ImpulsesBoxShapedRigidBody.py

@@ -1,165 +0,0 @@
-# coding=utf-8
-"""
-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 ID : C5959764
-# Test Case Title : Check that rigid body (Cube) gets impulse from force region
-
-
-# fmt: off
-class Tests:
-    enter_game_mode       = ("Entered game mode",          "Failed to enter game mode")
-    find_cube             = ("Entity Cube found",          "Cube not found")
-    find_force_region     = ("Force Region found",         "Force Region not found")
-    cube_gained_height    = ("Cube went up",               "Cube didn't go up")
-    force_region_success  = ("Force Region impulsed Cube", "Force Region didn't impulse Cube")
-    exit_game_mode        = ("Exited game mode",           "Couldn't exit game mode")
-    tests_completed       = ("Tests completed",            "Tests did not complete")
-
-# fmt: on
-
-
-def ForceRegion_ImpulsesBoxShapedRigidBody():
-    """
-    This run() function will open a a level and validate that a Cube gets impulsed by a force region.
-    It does this by:
-      1) Open level
-      2) Enters Game mode
-      3) Finds the entities in the scene
-      4) Gets the position of the Cube
-      5) Listens for Cube to enter the force region
-      6) Gets the vector and magnitude when Cube is in force region
-      7) Lets the Cube travel up
-      8) Gets new position of Cube
-      9) Validate the results
-      10) Exits game mode and editor
-    """
-    # Setup path
-    import os, sys
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    class Cube:
-        id = None
-        gained_height = False  # Did the Cube gain height
-        z_end_position = 0
-        z_start_position = 0
-
-    # Listen for Force Region events
-    class RegionData:
-        def __init__(self, ID):
-            self.force_region_id = ID
-            self.force_region_entered = False
-            self.force_vector = None
-            self.force_magnitude_on_cube = 0  # Magnitude applied on cube
-            self.force_region_magnitude = 0  # Magnitude value for the force region set in the editor
-            self.force_region_magnitude_range = (
-                0.01
-            )  # Delta value allowed between magnitude force_magnitude_on_cube and force_region_magnitude
-
-        def force_region_in_range(self):
-            return abs(self.force_magnitude_on_cube - self.force_region_magnitude) < 0.01  # 0.01 for buffer room
-
-    def ifVectorClose(vec1, vec2):
-        return abs(vec1 - vec2) < 0.01  # 0.01 For buffer room for dif in the two vectors.
-
-    helper.init_idle()
-
-    # *****Variables*****
-    TIME_OUT = 4.0  # Seconds
-    UPWARD_Z_VECTOR = 1.0
-
-    # Open level
-    helper.open_level("Physics", "ForceRegion_ImpulsesBoxShapedRigidBody")
-
-    # Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # Get Entities
-    Cube.id = general.find_game_entity("Cube")
-    Report.critical_result(Tests.find_cube, Cube.id.IsValid())
-
-    RegionObject = RegionData(general.find_game_entity("Force Region"))
-    Report.critical_result(Tests.find_force_region, RegionObject.force_region_id.IsValid())
-
-    # Set values for cube and force region
-    Cube.z_start_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Cube.id)
-    RegionObject.force_region_magnitude = azlmbr.physics.ForcePointRequestBus(
-        azlmbr.bus.Event, "GetMagnitude", RegionObject.force_region_id
-    )
-    Report.info("Cube start z position = {}".format(Cube.z_start_position))
-
-    # Force Region Event Handler
-    def on_calculate_net_force(args):
-        """
-        Called when there is a collision in the level
-        Args:
-            args[0] - force region entity
-            args[1] - entity entering
-            args[2] - vector
-            args[3] - magnitude
-        """
-        assert RegionObject.force_region_id.Equal(args[0])
-
-        vect = args[2]
-        mag = args[3]
-        if not RegionObject.force_region_entered:
-            RegionObject.force_region_entered = True
-            RegionObject.force_vector = vect
-            RegionObject.force_magnitude_on_cube = mag
-            Report.info("Force Region entered")
-
-    # Assign the handler
-    handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    handler.connect(None)
-    handler.add_callback("OnCalculateNetForce", on_calculate_net_force)
-
-    # Give cube time to travel. Exit when cube is done moving or time runs out.
-    def test_completed():
-        Cube.z_end_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Cube.id)
-        Cube.gained_height = Cube.z_end_position > (Cube.z_start_position + 0.5)  # 0.5 for buffer
-
-        # Validate if cube gained height and entered force region
-        if Cube.gained_height and RegionObject.force_region_entered:
-            Report.success(Tests.cube_gained_height)
-            return True
-        return False
-
-    # Wait for test to complete
-    test_is_completed = helper.wait_for_condition(test_completed, TIME_OUT)
-
-    if not test_is_completed:
-        Report.info("The test timed out, check log for possible solutions or adjust the time out time")
-        Report.failure(Tests.tests_completed)
-
-    else:
-        # Did Force Region succeed. True if vector z is close to 1 and force region magnitude is close to magnitude applied on cube
-        force_region_result = (
-            ifVectorClose(RegionObject.force_vector.z, UPWARD_Z_VECTOR) and RegionObject.force_region_in_range()
-        )
-        Report.result(Tests.force_region_success, force_region_result)
-        Report.success(Tests.tests_completed)
-
-    # Report test info to log
-    Report.info("******* FINAL ENTITY INFORMATION *********")
-    Report.info("Cube Entered force region = {}".format(RegionObject.force_region_entered))
-    Report.info("Start Z Position = {}  End Z Position = {}".format(Cube.z_start_position, Cube.z_end_position))
-    Report.info("Cube Gained height = {}".format(Cube.gained_height))
-    Report.info("Vector = {}  Magnitude = {}".format(RegionObject.force_vector.z, RegionObject.force_magnitude_on_cube))
-
-    # Exit game mode and close the editor
-    Report.result(Tests.tests_completed, test_is_completed)
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_ImpulsesBoxShapedRigidBody)

+ 0 - 169
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ImpulsesCapsuleShapedRigidBody.py

@@ -1,169 +0,0 @@
-# coding=utf-8
-"""
-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 ID : C5959764
-# Test Case Title : Check that rigid body (Capsule) gets impulse from force region
-
-
-# fmt: off
-class Tests:
-    enter_game_mode       = ("Entered game mode",             "Failed to enter game mode")
-    find_capsule          = ("Entity Capsule found",          "Capsule not found")
-    find_force_region     = ("Force Region found",            "Force Region not found")
-    capsule_gained_height = ("Capsule went up",               "Capsule didn't go up")
-    force_region_success  = ("Force Region impulsed Capsule", "Force Region didn't impulse Capsule")
-    exit_game_mode        = ("Exited game mode",              "Couldn't exit game mode")
-    tests_completed       = ("Tests completed",               "Tests did not complete")
-
-# fmt: on
-
-
-def ForceRegion_ImpulsesCapsuleShapedRigidBody():
-    """
-    This run() function will open a a level and validate that a Capsule gets impulsed by a force region.
-    It does this by:
-      1) Open level
-      2) Enters Game mode
-      3) Finds the entities in the scene
-      4) Gets the position of the Capsule
-      5) Listens for Capsule to enter the force region
-      6) Gets the vector and magnitude when Capsule is in force region
-      7) Lets the Capsule travel up
-      8) Gets new position of Capsule
-      9) Validate the results
-      10) Exits game mode and editor
-    """
-    # Setup path
-    import os, sys
-
-
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    class Capsule:
-        id = None
-        gained_height = False  # Did the Capsule gain height
-        z_end_position = 0
-        z_start_position = 0
-
-    # Listen for Force Region events
-    class RegionData:
-        def __init__(self, ID):
-            self.force_region_id = ID
-            self.force_region_entered = False
-            self.force_vector = None
-            self.force_magnitude_on_capsule = 0  # Magnitude applied on Capsule
-            self.force_region_magnitude = 0  # Magnitude value for the force region set in the editor
-            self.force_region_magnitude_range = (
-                0.01
-            )  # Delta value allowed between magnitude force_magnitude_on_capsule and force_region_magnitude
-
-        def force_region_in_range(self):
-            return abs(self.force_magnitude_on_capsule - self.force_region_magnitude) < 0.01  # 0.01 for buffer room
-
-    def ifVectorClose(vec1, vec2):
-        return abs(vec1 - vec2) < 0.01  # 0.01 For buffer room for dif in the two vectors.
-
-    helper.init_idle()
-
-    # *****Variables*****
-    TIME_OUT = 4.0  # Seconds
-    UPWARD_Z_VECTOR = 1.0
-
-    # Open level
-    helper.open_level("Physics", "ForceRegion_ImpulsesCapsuleShapedRigidBody")
-
-    # Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # Get Entities
-    Capsule.id = general.find_game_entity("Capsule")
-    Report.critical_result(Tests.find_capsule, Capsule.id.IsValid())
-
-    RegionObject = RegionData(general.find_game_entity("Force Region"))
-    Report.critical_result(Tests.find_force_region, RegionObject.force_region_id.IsValid())
-
-    # Set values for Capsule and force region
-    Capsule.z_start_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Capsule.id)
-    RegionObject.force_region_magnitude = azlmbr.physics.ForcePointRequestBus(
-        azlmbr.bus.Event, "GetMagnitude", RegionObject.force_region_id
-    )
-    Report.info("Capsule start z position = {}".format(Capsule.z_start_position))
-
-    # Force Region Event Handler
-    def on_calculate_net_force(args):
-        """
-        Called when there is a collision in the level
-        Args:
-            args[0] - force region entity
-            args[1] - entity entering
-            args[2] - vector
-            args[3] - magnitude
-        """
-        assert RegionObject.force_region_id.Equal(args[0])
-
-        vect = args[2]
-        mag = args[3]
-        if not RegionObject.force_region_entered:
-            RegionObject.force_region_entered = True
-            RegionObject.force_vector = vect
-            RegionObject.force_magnitude_on_capsule = mag
-            Report.info("Force Region entered")
-
-    # Assign the handler
-    handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    handler.connect(None)
-    handler.add_callback("OnCalculateNetForce", on_calculate_net_force)
-
-    # Give Capsule time to travel. Exit when Capsule is done moving or time runs out.
-    def test_completed():
-        Capsule.z_end_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Capsule.id)
-        Capsule.gained_height = Capsule.z_end_position > (Capsule.z_start_position + 0.5)  # 0.5 for buffer
-
-        # Validate if Capsule gained height and entered force region
-        if Capsule.gained_height and RegionObject.force_region_entered:
-            Report.success(Tests.capsule_gained_height)
-            return True
-        return False
-
-    # Wait for test to complete
-    test_is_completed = helper.wait_for_condition(test_completed, TIME_OUT)
-
-    if not test_is_completed:
-        Report.info("The test timed out, check log for possible solutions or adjust the time out time")
-        Report.failure(Tests.tests_completed)
-
-    else:
-        # Did Force Region succeed. True if vector z is close to 1 and force region magnitude is close to magnitude applied on Capsule
-        force_region_result = (
-            ifVectorClose(RegionObject.force_vector.z, UPWARD_Z_VECTOR) and RegionObject.force_region_in_range()
-        )
-        Report.result(Tests.force_region_success, force_region_result)
-        Report.success(Tests.tests_completed)
-
-    # Report test info to logSS
-    Report.info("******* FINAL ENTITY INFORMATION *********")
-    Report.info("Capsule Entered force region = {}".format(RegionObject.force_region_entered))
-    Report.info("Start Z Position = {}  End Z Position = {}".format(Capsule.z_start_position, Capsule.z_end_position))
-    Report.info("Capsule Gained height = {}".format(Capsule.gained_height))
-    Report.info(
-        "Vector = {}  Magnitude = {}".format(RegionObject.force_vector.z, RegionObject.force_magnitude_on_capsule)
-    )
-
-    # Exit game mode and close the editor
-    Report.result(Tests.tests_completed, test_is_completed)
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_ImpulsesCapsuleShapedRigidBody)

+ 0 - 171
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ImpulsesPxMeshShapedRigidBody.py

@@ -1,171 +0,0 @@
-# coding=utf-8
-"""
-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 ID : C5959765
-# Test Case Title : Check that rigid body (asset) gets impulse from force region
-
-
-# fmt: off
-
-class Tests:
-    enter_game_mode      = ("Entered game mode",           "Failed to enter game mode")
-    find_asset           = ("Entity asset found",          "Asset not found")
-    find_force_region    = ("Force Region found",          "Force Region not found")
-    asset_gained_height  = ("Asset went up",               "Asset didn't go up")
-    force_region_success = ("Force Region impulsed asset", "Force Region didn't impulse asset")
-    exit_game_mode       = ("Exited game mode",            "Couldn't exit game mode")
-    tests_completed      = ("Tests completed",             "Tests did not complete")
-# fmt: on
-
-def ForceRegion_ImpulsesPxMeshShapedRigidBody():
-    """
-    # This run() function will open a a level and validate that a asset gets impulsed by a force region.
-    # It does this by:
-    #   1) Open level
-    #   2) Enters Game mode
-    #   3) Finds the entities in the scene
-    #   4) Set values for Asset and force region
-    #   5) Listens for asset to enter the force region
-    #   6) Gets the vector and magnitude when asset is in force region
-    #   7) Lets the asset travel up
-    #   8) Validate if Asset gained height and entered force region
-    #   9) Checks if test completed
-    #   10) Exits game mode and editor
-
-    # Level setup: Sedan asset above force region
-    # First Asset: Name = "Sedan"  This entity should drop vertically, collide with force region, and be shot up
-    # First force region: Name = "Force Region"  Should shoot Sedan entity up upon entry
-    """
-    # Setup path
-    import os, sys
-
-
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    class Asset:
-        id = None
-        gained_height = False  # Did the Asset gain height
-        z_end_position = 0
-        z_start_position = 0
-
-    # Listen for Force Region events
-    class RegionData:
-        def __init__(self, ID):
-            self.force_region_id = ID
-            self.force_region_entered = False
-            self.force_vector = None
-            self.force_magnitude_on_asset = 0  # Magnitude applied on Asset
-            self.force_region_magnitude = 0  # Magnitude value for the force region set in the editor
-            self.force_region_magnitude_range = (
-                0.01
-            )  # Delta value allowed between magnitude force_magnitude_on_asset and force_region_magnitude
-
-        def force_region_in_range(self):
-            return abs(self.force_magnitude_on_asset - self.force_region_magnitude) < 0.01  # 0.01 for buffer room
-
-    def ifVectorAxisClose(vec1, vec2):
-        return abs(vec1 - vec2) < 0.01  # 0.01 For buffer room for dif in the two vectors.
-
-    helper.init_idle()
-
-    # *****Variables*****
-    TIME_OUT = 4.0  # Seconds
-    UPWARD_Z_VECTOR = 1.0
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_ImpulsesPxMeshShapedRigidBody")
-
-    #  2) Enters Game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    #  3) Finds the entities in the scene
-    Asset.id = general.find_game_entity("Sedan")
-    Report.critical_result(Tests.find_asset, Asset.id.IsValid())
-
-    RegionObject = RegionData(general.find_game_entity("Force Region"))
-    Report.critical_result(Tests.find_force_region, RegionObject.force_region_id.IsValid())
-
-    #  4) Set values for Asset and force region
-    Asset.z_start_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Asset.id)
-    RegionObject.force_region_magnitude = azlmbr.physics.ForcePointRequestBus(
-        azlmbr.bus.Event, "GetMagnitude", RegionObject.force_region_id
-    )
-    Report.info("Asset start z position = {}".format(Asset.z_start_position))
-
-    #  5) Listens for asset to enter the force region
-    def on_calculate_net_force(args):
-        """
-        Called when there is a collision in the level
-        Args:
-            args[0] - force region entity
-            args[1] - entity entering
-            args[2] - vector
-            args[3] - magnitude
-        """
-
-        # 6) Gets the vector and magnitude when asset is in force region
-        vect = args[2]
-        mag = args[3]
-        if RegionObject.force_region_id.Equal(args[0]) and not RegionObject.force_region_entered:
-            RegionObject.force_region_entered = True
-            RegionObject.force_vector = vect
-            RegionObject.force_magnitude_on_asset = mag
-            Report.info("Force Region entered")
-
-    # Assign the handler
-    handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    handler.connect(None)
-    handler.add_callback("OnCalculateNetForce", on_calculate_net_force)
-
-    def test_completed():
-        # test_completed() will return a bool saying if all the Necessary actions in the test have been completed.
-        #   Necessary Actions: 1) Asset entered Force Region   2) Asset end_height > start_height
-        Asset.z_end_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Asset.id)
-        Asset.gained_height = Asset.z_end_position > (Asset.z_start_position + 0.5)  # 0.5 for buffer
-
-        # 8) Validate if Asset gained height and entered force region
-        if Asset.gained_height and RegionObject.force_region_entered:
-            Report.success(Tests.asset_gained_height)
-            return True
-        return False
-
-    #  7) Lets the asset travel up
-    test_is_completed = helper.wait_for_condition(test_completed, TIME_OUT)
-
-    # 9) Checks if test completed
-    if not test_is_completed:
-        Report.info("The test timed out, check log for possible solutions or adjust the time out time")
-        Report.failure(Tests.tests_completed)
-
-    else:
-        # Did Force Region succeed. True if vector z is close to 1 and force region magnitude is close to magnitude applied on Asset
-        force_region_result = (
-            ifVectorAxisClose(RegionObject.force_vector.z, UPWARD_Z_VECTOR) and RegionObject.force_region_in_range()
-        )
-        Report.result(Tests.force_region_success, force_region_result)
-        Report.success(Tests.tests_completed)
-
-    # Report test info to log
-    Report.info("******* FINAL ENTITY INFORMATION *********")
-    Report.info("Asset Entered force region = {}".format(RegionObject.force_region_entered))
-    Report.info("Start Z Position = {}  End Z Position = {}".format(Asset.z_start_position, Asset.z_end_position))
-    Report.info("Asset Gained height = {}".format(Asset.gained_height))
-    Report.info("Vector = {} Magnitude = {}".format(RegionObject.force_vector.z, RegionObject.force_magnitude_on_asset))
-
-    # 10) Exit game mode and close the editor
-    Report.result(Tests.tests_completed, test_is_completed)
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_ImpulsesPxMeshShapedRigidBody)

+ 0 - 296
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_LinearDampingForceOnRigidBodies.py

@@ -1,296 +0,0 @@
-"""
-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 ID : C5932042
-# Test Case Title : Check that force region exerts linear damping force on rigid bodies
-
-
-
-# fmt: off
-class Tests:
-    enter_game_mode         = ("Entered game mode",                         "Failed to enter game mode")
-    sphere_validated        = ("Sphere entity validated",                   "Sphere entity NOT validated")
-    force_region_validated  = ("Force Region validated",                    "Force Region NOT validated")
-    trigger_validated       = ("Trigger entity validated",                  "Trigger entity NOT validated")
-    sphere_pos_found        = ("Sphere position found",                     "Sphere position NOT found")
-    force_region_pos_found  = ("Force Region position found",               "Force Region position NOT found")
-    trigger_pos_found       = ("Trigger position found",                    "Trigger position NOT found")
-    level_setup             = ("Level looks set up right",                  "Level NOT set up right")
-    damping_force_entered   = ("Sphere entered linear damping region",      "Linear damping region never entered")
-    damping_force_expected  = ("Damping force was as expected",             "Damping force differed from expected")
-    sphere_slowed           = ("Sphere slowed down",                        "Sphere DID NOT slow down")
-    sphere_stopped          = ("Sphere entity stopped",                     "Sphere entity DID NOT stop")
-    force_region_no_move    = ("Force Region did not move",                 "Fore Region DID move")
-    trigger_no_move         = ("Trigger did not move",                      "Trigger DID move")
-    timed_out               = ("The test did not time out",                 "The test TIMED OUT")
-    trigger_not_triggered   = ("The Trigger was not triggered",             "The Trigger WAS triggered")
-    exit_game_mode          = ("Exited game mode",                          "Couldn't exit game mode")
-
-# fmt: on
-
-
-def ForceRegion_LinearDampingForceOnRigidBodies():
-    # type: () -> None
-    """
-    Summary:
-    Runs an automated test to ensure linear damping is exerted on rigid body objects from force regions.
-
-    Level Description:
-    A sphere (entity: Sphere) in positioned above a large cube force region (entity: force_region_entity) who is
-    assigned a linear damping force with damping of 10.0. The Sphere has gravity enabled, and is positioned high
-    enough for gravity to accelerate it faster than the maximum velocity inside the linear damping force region.
-
-    Expected Behavior:
-    When game mode is entered, gravity should accelerate the Sphere downward. The velocity of the Sphere should peak
-    right before it enters force_region_entity. Upon entering the force region, the Sphere should noticeably slow
-    down. The slower velocity should have a substantially larger (less negative) velocity.
-
-    Test Steps:
-    0) Define useful classes and constants
-    1) Loads the level / Enters game mode
-    2) Retrieve and validate entities
-    3) Ensures that the test object (Sphere) is located
-        3.5) Set up event handlers
-    4) Execute test until exit condition met
-    5) Logs results
-        5.5) Dump all collected data to log
-    6) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-    import azlmbr.math as azmath
-
-    # Entity base class: Handles basic entity data
-    class EntityBase:
-        def __init__(self, name):
-            self.name = name
-            self.id = None
-            self.initial_pos = None
-            self.current_pos = None
-
-    # Specific Sphere class
-    class Sphere(EntityBase):
-        def __init__(self, name):
-            EntityBase.__init__(self, name)
-            self.initial_velocity = None
-            self.initial_velocity_magnitude = None
-            self.current_velocity = None
-            self.slowed = False
-            self.stopped = False
-
-        def check_for_stop(self):
-            if not self.stopped:
-                self.current_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
-                self.slowed = self.initial_velocity_magnitude > self.current_velocity.GetLength() + (
-                    0.5 * self.initial_velocity_magnitude
-                )
-                self.stopped = self.current_velocity.IsZero()
-            return self.stopped
-
-    # Specific Force Region class
-    class ForceRegion(EntityBase):
-        def __init__(self, name):
-            EntityBase.__init__(self, name)
-            self.entered = False
-            self.object_entered = None
-            self.expected_force_direction = None
-            self.actual_force_vector = None
-            self.actual_force_magnitude = None
-            self.handler = None
-
-    # Specific Trigger class
-    class Trigger(EntityBase):
-        def __init__(self, name):
-            EntityBase.__init__(self, name)
-            self.triggered = False
-            self.triggering_obj = None
-            self.handler = None
-
-    # Constants
-    CLOSE_ENOUGH = 0.001
-    TIME_OUT = 10.0
-    INITIAL_VELOCITY = azmath.Vector3(0.0, 0.0, -10.0)
-
-    # 1) Open level / Enter game mode
-    helper.init_idle()
-    helper.open_level("Physics", "ForceRegion_LinearDampingForceOnRigidBodies")
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 2) Retrieve and validate entities
-    sphere = Sphere("Sphere")
-    sphere.id = general.find_game_entity(sphere.name)
-    force_region = ForceRegion("ForceRegion")
-    force_region.id = general.find_game_entity(force_region.name)
-    trigger = Trigger("Trigger")
-    trigger.id = general.find_game_entity(trigger.name)
-
-    Report.critical_result(Tests.sphere_validated, sphere.id.IsValid())
-    Report.critical_result(Tests.force_region_validated, force_region.id.IsValid())
-    Report.critical_result(Tests.trigger_validated, trigger.id.IsValid())
-
-    # 3) Log Entities' positions and initial data
-    sphere.initial_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", sphere.id)
-    force_region.initial_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", force_region.id)
-    trigger.initial_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", trigger.id)
-
-    Report.critical_result(Tests.sphere_pos_found, sphere.initial_pos is not None and not sphere.initial_pos.IsZero())
-    Report.critical_result(
-        Tests.force_region_pos_found, force_region.initial_pos is not None and not force_region.initial_pos.IsZero()
-    )
-    Report.critical_result(
-        Tests.trigger_pos_found, trigger.initial_pos is not None and not trigger.initial_pos.IsZero()
-    )
-
-    sphere.initial_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", sphere.id)
-
-    # Perform Calculations
-    sphere_acceleration_y = abs(sphere.initial_pos.y - force_region.initial_pos.y)
-    sphere_damping_y = abs(sphere.initial_pos.y - trigger.initial_pos.y)
-    sphere_acceleration_x = abs(sphere.initial_pos.x - force_region.initial_pos.x)
-    sphere_damping_x = abs(sphere.initial_pos.x - trigger.initial_pos.x)
-
-    # Perform Checks
-    sphere_acceleration_y_valid = sphere_acceleration_y < CLOSE_ENOUGH
-    sphere_damping_y_valid = sphere_damping_y < CLOSE_ENOUGH
-    sphere_acceleration_x_valid = sphere_acceleration_x < CLOSE_ENOUGH
-    sphere_damping_x_valid = sphere_damping_x < CLOSE_ENOUGH
-    setup_entity_priority_valid = sphere.initial_pos.z > force_region.initial_pos.z > trigger.initial_pos.z
-    sphere_is_close = sphere.initial_velocity.IsClose(INITIAL_VELOCITY, CLOSE_ENOUGH)
-    level_correct = (sphere_acceleration_y_valid and sphere_damping_y_valid and sphere_acceleration_x_valid
-                     and sphere_damping_x_valid and setup_entity_priority_valid and sphere_is_close)
-
-    # Report
-    if not sphere_acceleration_y_valid:
-        Report.info(f"Sphere initial Y position {sphere.initial_pos.y} "
-                    f"is not close enough to force region initial Y position {force_region.initial_pos.y}.")
-    if not sphere_damping_y_valid:
-        Report.info(f"Sphere initial Y position {sphere.initial_pos.y} "
-                    f"is not close enough to trigger initial Y position {trigger.initial_pos.y}.")
-    if not sphere_acceleration_x_valid:
-        Report.info(f"Sphere initial X position {sphere.initial_pos.x} "
-                    f"is not close enough to force region initial X position {force_region.initial_pos.x}.")
-    if not sphere_damping_x_valid:
-        Report.info(f"Sphere initial X position {sphere.initial_pos.x} "
-                    f"is not close enough to trigger initial X position {trigger.initial_pos.x}.")
-    if not setup_entity_priority_valid:
-        Report.info(f"Initial level entity expects "
-                    f"Initial Sphere Z Pos:{sphere.initial_pos.z} "
-                    f"> Force Region Initial Z Pos: {force_region.initial_pos.z} "
-                    f"> Trigger Initial Z Pos: {trigger.initial_pos.z} ")
-    if not sphere_is_close:
-        Report.info(f"Sphere initial velocity of {sphere.initial_velocity} was not close enough to {INITIAL_VELOCITY}")
-
-    Report.critical_result(Tests.level_setup, level_correct)
-
-    sphere.current_pos = sphere.initial_pos
-    force_region.current_pos = force_region.initial_pos
-    trigger.current_pos = trigger.initial_pos
-    force_region.expected_force_direction = sphere.initial_velocity.MultiplyFloat(-1.0)
-    force_region.expected_force_direction.Normalize()
-    sphere.current_velocity = sphere.initial_velocity
-    sphere.initial_velocity_magnitude = sphere.initial_velocity.GetLength()
-
-    # 3.5) Set up variables and handler for observing force region interaction
-
-    def done_collecting_results():
-
-        # Update current positions
-        sphere.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", sphere.id)
-        force_region.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", force_region.id)
-        trigger.current_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", trigger.id)
-
-        return force_region.entered and sphere.check_for_stop()
-
-    # Force Region Event Handler
-    def on_calc_net_force(args):
-        if args[0].Equal(force_region.id):
-            if args[1].Equal(sphere.id):
-                if not force_region.entered:
-                    force_region.entered = True
-                    force_region.object_entered = sphere
-                    force_region.actual_force_vector = args[2]
-                    force_region.actual_force_magnitude = args[3]
-                    Report.info("Entity: {} entered entity: {}'s volume".format(sphere.name, force_region.name))
-
-    def on_trigger_entered(args):
-        if args[0].Equal(sphere.id):
-            trigger.triggered = True
-            trigger.triggering_obj = sphere
-
-    # Assign event handlers
-    force_region.handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    force_region.handler.connect(None)
-    force_region.handler.add_callback("OnCalculateNetForce", on_calc_net_force)
-
-    trigger.handler = azlmbr.physics.TriggerNotificationBusHandler()
-    trigger.handler.connect(trigger.id)
-    trigger.handler.add_callback("OnTriggerEnter", on_trigger_entered)
-
-    # 4) Execute test until exit condition is met
-    Report.critical_result(Tests.timed_out, helper.wait_for_condition(done_collecting_results, TIME_OUT))
-
-    # 5) Log results
-    Report.result(Tests.damping_force_entered, force_region.entered)
-    Report.result(
-        Tests.damping_force_expected,
-        force_region.actual_force_vector.IsClose(force_region.expected_force_direction, CLOSE_ENOUGH),
-    )
-    Report.result(Tests.sphere_slowed, sphere.slowed)
-    Report.result(Tests.sphere_stopped, sphere.stopped)
-    Report.result(Tests.trigger_not_triggered, not trigger.triggered)
-    Report.result(Tests.force_region_no_move, force_region.initial_pos.IsClose(force_region.current_pos, CLOSE_ENOUGH))
-    Report.result(Tests.trigger_no_move, trigger.initial_pos.IsClose(trigger.current_pos, CLOSE_ENOUGH))
-
-    # 5.5) Collected Data Dump
-    Report.info(" ********** Collected Data ***************")
-    Report.info("{}:".format(sphere.name))
-    Report.info_vector3(sphere.initial_pos, " Initial position:")
-    Report.info_vector3(sphere.current_pos, " Final position:")
-    Report.info_vector3(sphere.initial_velocity, " Initial velocity:")
-    Report.info_vector3(sphere.current_velocity, " Final velocity:")
-    Report.info(" Slowed: {}".format(sphere.slowed))
-    Report.info(" Stopped: {}".format(sphere.stopped))
-    Report.info("***********************************")
-    Report.info("{}:".format(force_region.name))
-    Report.info_vector3(force_region.initial_pos, " Initial position:")
-    Report.info_vector3(force_region.current_pos, " Final position:")
-    Report.info_vector3(force_region.expected_force_direction, " Expected Force Direction:")
-    Report.info_vector3(
-        force_region.actual_force_vector, " Actual Force Direction:", force_region.actual_force_magnitude
-    )
-    Report.info(" Entered: {}".format(force_region.entered))
-    Report.info(" Object Entered: {}".format(force_region.object_entered.name))
-    Report.info("***********************************")
-    Report.info("{}:".format(trigger.name))
-    Report.info_vector3(trigger.initial_pos, " Initial position:")
-    Report.info_vector3(trigger.current_pos, " Final position:")
-    Report.info(" Triggered: {}".format(trigger.triggered))
-    Report.info(" Triggering Object: {}".format(trigger.triggering_obj))
-    Report.info("***********************************")
-
-    # 6) Exit Game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-    Report.info("*** FINISHED TEST ***")
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_LinearDampingForceOnRigidBodies)

+ 0 - 160
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_LocalSpaceForceOnRigidBodies.py

@@ -1,160 +0,0 @@
-"""
-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 ID : C5932041
-# Test Case Title : Check that force region exerts local space force on rigid bodies
-
-# Sphere drops and is acted upon in an upward and positive x-ward direction by a force
-# with a magnitude close to the assigned force region magnitude when it reaches the force region.
-
-
-# fmt: off
-class Tests:
-    enter_game_mode                 = ("Entered game mode",                             "Failed to enter game mode")
-    find_sphere                     = ("Sphere entity found",                           "Sphere entity not found")
-    find_box                        = ("Box entity found",                              "Box entity not found")
-    sphere_pos_found                = ("Sphere position found",                         "Sphere position not found")
-    sphere_velocity_found           = ("Sphere has downward velocity",                  "Sphere does not have downward velocity")
-    box_pos_found                   = ("Box position found",                            "Box position not found")
-    force_region_entered            = ("Force region entered",                          "Force region never entered")
-    force_x_component_detected      = ("Force x-component detected on the Sphere",      "Force x-component was not detected on the Sphere")
-    force_z_component_detected      = ("Force z-component detected on the Sphere",      "Force z-component was not detected on the Sphere")
-    force_y_component_not_detected  = ("Force y-component not detected on the Sphere",  "Force y-component was detected on the Sphere")
-    force_magnitude_detected        = ("Force magnitude detected on the Sphere",        "Force magnitude was not detected on the Sphere")
-    exit_game_mode                  = ("Exited game mode",                              "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_LocalSpaceForceOnRigidBodies():
-    """
-    Summary:
-    Runs an automated test to ensure that when a rigid body enters a force region a local space force is exerted.
-
-    Level Description:
-    Box (entity) - suspended above terrain at 45 degree angle with Direction Z = 1.0, magnitude = 1000, 
-        and gravity disabled; contains box mesh, PhysX Collider, and PhysX Force Region
-    Sphere (entity) - suspended above Box with slight x-axis offset, initial velocity in negative z direction, 
-        gravity disabled; contains sphere mesh, PhysX Rigid Body, PhysX Collider
-
-    Expected Behavior:
-    When game mode is entered, the Sphere entity will travel torward the terrain.
-    It will reach the force region of the Box entity and be imbued with a net force in the x and z directions.
-
-    Test Steps:
-     1) Open level
-     2) Enter game mode
-     3) Retrieve entities
-     4) Log Sphere velocity and positions for Sphere and Box
-     5) Set up handler and variables
-     6) Wait for force region entry or time out
-     7) Look for positive x, zero y, positive z force with a valid magnitude, and report findings
-     8) Exit game mode
-     9) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Constants
-    TIMEOUT = 2.0
-    TOLERANCE = 1
-    MAGNITUDE = 1000 # Magnitude assigned to the force region
-    FORCE_Y_TOLERANCE = sys.float_info.epsilon
-
-    helper.init_idle()
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_LocalSpaceForceOnRigidBodies")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve entities
-    sphere_id = general.find_game_entity("Sphere")
-    box_id = general.find_game_entity("Box")
-
-    Report.critical_result(Tests.find_sphere, sphere_id.isValid())
-    Report.critical_result(Tests.find_box, box_id.isValid())
-
-    # 4) Log Sphere velocity and positions for Sphere and Box
-    sphere_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", sphere_id)
-
-    box_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", sphere_id)
-
-    # Validate and print positions and sphere velocity
-    sphere_pos_found = sphere_pos is not None and sphere_pos.x != 0 and sphere_pos.y != 0 and sphere_pos.z != 0
-    Report.critical_result(Tests.sphere_pos_found, sphere_pos_found)
-    Report.info_vector3(sphere_pos, "Sphere Position:")
-
-    sphere_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", sphere_id)
-    Report.critical_result(Tests.sphere_velocity_found, sphere_velocity.z < 0)
-    Report.info_vector3(sphere_velocity, "Sphere Initial Velocity:")
-
-    box_pos_found = box_pos is not None and box_pos.x != 0 and box_pos.y != 0 and box_pos.z != 0
-    Report.critical_result(Tests.box_pos_found, box_pos_found)
-    Report.info_vector3(box_pos, "Box Position:")
-
-    # 5) Set up handler and variables
-    class RegionData:
-        force_region_entered = False
-        force_vector = None
-        force_magnitude = 0
-
-    # Force Region Event Handler
-    def on_force_region_entered(args):
-        region_id = args[0]
-        object_id = args[1]
-        force_vector = args[2]
-        force_magnitude = args[3]
-        if region_id.Equal(box_id) and object_id.Equal(sphere_id):
-            if not RegionData.force_region_entered:
-                RegionData.force_region_entered = True
-                RegionData.force_vector = force_vector
-                RegionData.force_magnitude = force_magnitude
-                Report.info("Force Region entered")
-
-    # Assign the handler
-    handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    handler.connect(None)
-    handler.add_callback("OnCalculateNetForce", on_force_region_entered)
-
-    # 6) Wait for force region entry or time out
-    helper.wait_for_condition(lambda: RegionData.force_region_entered, TIMEOUT)
-
-    # 7) Look for positive x, positive z force with a valid magnitude, and report findings
-    force_x_component_detected = RegionData.force_vector.x > 0
-    force_z_component_detected = RegionData.force_vector.z > 0
-    force_y_component_detected = abs(RegionData.force_vector.y) > FORCE_Y_TOLERANCE
-    force_magnitude_detected = abs(RegionData.force_magnitude - MAGNITUDE) < TOLERANCE
-
-    Report.result(Tests.force_region_entered, RegionData.force_region_entered)
-    Report.info_vector3(RegionData.force_vector, "Force vector detected", RegionData.force_magnitude)
-    Report.result(Tests.force_x_component_detected, force_x_component_detected)
-    Report.result(Tests.force_z_component_detected, force_z_component_detected)
-    Report.result(Tests.force_y_component_not_detected, not force_y_component_detected)
-    Report.result(Tests.force_magnitude_detected, force_magnitude_detected)
-
-    # 8) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_LocalSpaceForceOnRigidBodies)

+ 0 - 162
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_MovingForceRegionChangesNetForce.py

@@ -1,162 +0,0 @@
-"""
-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 ID : C5968760
-# Test Case Title : Check moving force region changes net force
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode   = ("Entered game mode",          "Failed to enter game mode")
-    find_sphere       = ("SphereRigidBody found",      "SphereRigidBody not found")
-    find_force_region = ("ForceRegionBox is found",    "ForceRegionBox is not found")
-    sphere_dropped    = ("Sphere dropped down",        "Sphere did not drop down") 
-    sphere_bounced    = ("Sphere bounced to its left", "Sphere did not bounce to its left")
-    exit_game_mode    = ("Exited game mode",           "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_MovingForceRegionChangesNetForce():
-
-    """
-    Summary:
-    Check moving force region changes net force.
-
-    Level Description:
-    The SphereRigidBody entity is placed above the ForceRegionBox entity.
-    ForceRegionBox (entity) - Entity with PhysX Force Region, Mesh, PhysX Collider
-    SphereRigidBody (entity) - Entity with PhysX Rigid body, Mesh and collider components
-
-    Expected Behavior:
-    We are checking if the ball falls down initially and then moving the force region to the right to verify if the
-    ball bounces off to the left when it collides with the force region.
-
-    Test Steps:
-     1)  Open level
-     2)  Enter game mode
-     3)  Retrieve and validate entities
-     4)  Get the initial position of the Sphere (rigid body)
-     5)  Move the object to right (X - direction) and rotate in Y - direction
-     6)  Check if the ball is falling down
-     7)  Add force region notification handler
-     8)  Wait till the ball enters the force region
-     9)  Check if the ball has bounced and moved left
-     10) Exit game mode
-     11) Close the editor
-
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Constants
-    TIMEOUT = 3.0  # wait a maximum of 3 seconds
-    SPHERE_RADIUS = 0.5
-    TRANSLATION_OFFSET = 0.2
-    ROTATION_OFFSET = -0.005
-
-    class Sphere:
-        id = None
-        initial_position = None
-        current_position = None
-        z_at_collision = None
-        in_force_region = False
-        bounced = False
-
-    class ForceRegion:
-        id = None
-        translation_position = None
-        rotation_position = None
-
-    def sphere_bounced():
-        Sphere.current_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", Sphere.id)
-        bounced_up = Sphere.current_position.z > Sphere.z_at_collision + SPHERE_RADIUS
-        bounced_left = Sphere.current_position.x < Sphere.initial_position.x
-        Sphere.bounced = bounced_left and bounced_up
-        return Sphere.bounced
-
-    helper.init_idle()
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_MovingForceRegionChangesNetForce")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve and validate entities
-    Sphere.id = general.find_game_entity("SphereRigidBody")
-    Report.critical_result(Tests.find_sphere, Sphere.id.IsValid())
-    ForceRegion.id = general.find_game_entity("ForceRegionBox")
-    Report.critical_result(Tests.find_force_region, ForceRegion.id.IsValid())
-
-    # 4) Get the initial position of the Sphere (rigid body)
-    Sphere.initial_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", Sphere.id)
-
-    # 5) Move the object to right (X - direction) and rotate in Y - direction
-    ForceRegion.translation_position = azlmbr.components.TransformBus(
-        azlmbr.bus.Event, "GetWorldTranslation", ForceRegion.id
-    )
-    azlmbr.components.TransformBus(
-        azlmbr.bus.Event, "SetWorldX", ForceRegion.id, (ForceRegion.translation_position.x + TRANSLATION_OFFSET)
-    )
-    # Rotation in y direction anti clockwise
-    ForceRegion.rotation_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldRotation", ForceRegion.id)
-    azlmbr.components.TransformBus(
-        azlmbr.bus.Event, "RotateAroundLocalY", ForceRegion.id, (ForceRegion.rotation_position.y + ROTATION_OFFSET)
-    )
-    Report.info("The force region has been repositioned")
-
-    # 6) Check if the ball is falling down
-    Sphere.current_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", Sphere.id)
-    sphere_dropped = Sphere.current_position.z < (Sphere.initial_position.z + SPHERE_RADIUS)
-    Report.critical_result(Tests.sphere_dropped, sphere_dropped)
-
-    # 7) Add force region notification handler
-    def on_force_region_entered(args):
-        region_id = args[0]
-        object_id = args[1]
-        if region_id.Equal(ForceRegion.id) and object_id.Equal(Sphere.id):
-            if not Sphere.in_force_region:
-                Sphere.in_force_region = True
-                Report.info("Force Region entered")
-
-    force_notification_handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    force_notification_handler.connect(None)
-    force_notification_handler.add_callback("OnCalculateNetForce", on_force_region_entered)
-
-    # 8) Wait till the ball enters the force region
-    helper.wait_for_condition(lambda: Sphere.in_force_region, TIMEOUT)
-    # sphere z position when it entered force region
-    Sphere.z_at_collision = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", Sphere.id).z
-
-    # 9) Check if the ball has bounced and moved left
-    # wait frames till the ball bounces
-    helper.wait_for_condition(sphere_bounced, TIMEOUT)
-    Report.result(Tests.sphere_bounced, Sphere.bounced)
-    
-    # 10) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_MovingForceRegionChangesNetForce)

+ 0 - 177
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_MultipleComponentsCombineForces.py

@@ -1,177 +0,0 @@
-"""
-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 ID : C5968759
-# Test Case Title : Check nested force regions exert forces simultaneously on rigid body
-
-
-# fmt: off
-class Tests:
-    enter_game_mode                  = ("Entered game mode",                  "Failed to enter game mode")
-    find_vertical_sphere             = ("Vertical sphere found",              "Vertical sphere not found")
-    find_angled_sphere               = ("Angled sphere found",                "Angled sphere not found")
-    find_point_force_region          = ("Point force region found",           "Force Region not found")
-    find_angled_force_region         = ("Angled force region found",          "Angled force region not found")
-    vertical_entered_force_region    = ("Vertical Sphere actions completed",  "Vertical Sphere actions not completed")
-    timed_out                        = ("Test did not time out",              "Test TIMED OUT")
-    angled_sphere_enter_force_region = ("Angled Sphere Entered Force Region", "Angled Sphere didn't enter Force Region")
-    vertical_sphere_fell_vertically  = ("Vertical Sphere fell vertically",    "Vertical Sphere didn't fall vertically")
-    angled_sphere_fell_at_angle      = ("Angled Sphere fell at an angle",     "Angled Sphere didn't fall at an angle")
-    vertical_sphere_slowed           = ("Vertical Sphere slowed",             "Vertical Sphere not slowed")
-    angled_sphere_slowed             = ("Angled Sphere slowed",               "Angled Sphere not slowed")
-    exit_game_mode                   = ("Exited game mode",                   "Couldn't exit game mode")
-
-
-# fmt: on
-
-import os, sys
-
-
-def ForceRegion_MultipleComponentsCombineForces():
-    """
-    Run() will open a a level and validate that the spheres are affected by the force regions as expected.
-
-    Expected Results: Both spheres fall into the force regions and are slowed. One of the spheres also falls at an angle
-
-    It does this by:
-      --> Opens level and enter game mode
-      --> Finds the entities in the scene
-      --> Listens for spheres to enter the force regions
-      --> Set Spheres start position and velocity
-      --> Listen for spheres to exit force regions
-      --> Set Spheres end position and velocity
-      --> Validate the results
-      --> Exits game mode and editor
-
-    Level Description: Two spheres floating above 2 force regions.
-    Sphere: 1 Name = "Sphere_vertical_drop"  This sphere should fall vertically
-    Sphere: 2 Name =  "Sphere_angled_drop"  This sphere should fall at an angle
-    First force region: Name = "Force Region Point"  Applies point force along the X axis to only the second sphere
-    Second force region: Name = "Force Region Simple Drag"  Applies a drag force on both spheres
-    Setup path
-    """
-
-
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus as bus
-    import azlmbr.physics
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    # Constants
-    TIME_OUT = 6.0  # Second to wait before timing out
-    POSITION_TOLERANCE = 0.1
-
-    def is_close_XY_position(vec1, vec2):
-        return abs(vec1.x - vec2.x) < POSITION_TOLERANCE and abs(vec1.y - vec2.y) < POSITION_TOLERANCE
-
-    # Holds details about the sphere
-    class Sphere:
-        def __init__(self, sphere_id, sphere_name):
-            self.name = sphere_name
-            self.id = sphere_id
-            self.start_position = None
-            self.end_position = None
-            self.start_velocity = None
-            self.end_velocity = None
-            self.entered_force_region = False
-            self.exited_force_region = False
-
-        def get_position(self):
-            return azlmbr.components.TransformBus(bus.Event, "GetWorldTranslation", self.id)
-
-        def get_velocity(self):
-            return azlmbr.physics.RigidBodyRequestBus(bus.Event, "GetLinearVelocity", self.id)
-
-
-    #   1) Opens level with spheres above a force region
-    helper.init_idle()
-    helper.open_level("Physics", "ForceRegion_MultipleComponentsCombineForces")
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    #   2) Finds the entities in the scene
-    sphere_vertical = Sphere(general.find_game_entity("Sphere_vertical_drop"), "Sphere Vertical")
-    Report.critical_result(Tests.find_vertical_sphere, sphere_vertical.id.IsValid())
-
-    sphere_angled = Sphere(general.find_game_entity("Sphere_angled_drop"), "Sphere Angled")
-    Report.critical_result(Tests.find_angled_sphere, sphere_angled.id.IsValid())
-
-    point_force_region_id = general.find_game_entity("Force Region Point")
-    Report.critical_result(Tests.find_point_force_region, point_force_region_id.IsValid())
-
-    simple_drag_force_region_id = general.find_game_entity("Force Region Simple Drag")
-    Report.critical_result(Tests.find_angled_force_region, simple_drag_force_region_id.IsValid())
-
-    # ******** Handler Functions ********
-
-    # Called if Sphere enters force region
-    def on_trigger_begin(args):
-        other_id = args[0]
-        #  4) Gets start position and velocity of spheres
-        if other_id.Equal(sphere_vertical.id) and sphere_vertical.entered_force_region is False:
-            Report.info("Trigger Entered")
-            sphere_vertical.entered_force_region = True
-            sphere_vertical.start_position = sphere_vertical.get_position()
-            sphere_vertical.start_velocity = sphere_vertical.get_velocity()
-            Report.result(Tests.vertical_entered_force_region, sphere_vertical.entered_force_region)
-        elif other_id.Equal(sphere_angled.id) and sphere_angled.entered_force_region is False:
-            sphere_angled.entered_force_region = True
-            sphere_angled.start_position = sphere_angled.get_position()
-            sphere_angled.start_velocity = sphere_angled.get_velocity()
-            Report.result(Tests.angled_sphere_enter_force_region, sphere_angled.entered_force_region)
-
-    def on_trigger_exit(args):
-        #  4) Gets end position and velocity of spheres
-        other_id = args[0]
-        if other_id.Equal(sphere_vertical.id):
-            Report.info("Trigger exited")
-            sphere_vertical.end_position = sphere_vertical.get_position()
-            sphere_vertical.end_velocity = sphere_vertical.get_velocity()
-            sphere_vertical.exited_force_region = True
-
-        elif other_id.Equal(sphere_angled.id):
-            Report.info("Trigger exited")
-            sphere_angled.end_position = sphere_angled.get_position()
-            sphere_angled.end_velocity = sphere_angled.get_velocity()
-
-            sphere_angled.exited_force_region = True
-
-    #  3) Listens for spheres to enter the force regions
-    # Create a handler for each force region
-    point_force_region_handler = azlmbr.physics.TriggerNotificationBusHandler()
-    point_force_region_handler.connect(point_force_region_id)
-    point_force_region_handler.add_callback("OnTriggerEnter", on_trigger_begin)
-    point_force_region_handler.add_callback("OnTriggerExit", on_trigger_exit)
-
-    simple_drag_force_region_handler = azlmbr.physics.TriggerNotificationBusHandler()
-    simple_drag_force_region_handler.connect(simple_drag_force_region_id)
-    simple_drag_force_region_handler.add_callback("OnTriggerEnter", on_trigger_begin)
-    simple_drag_force_region_handler.add_callback("OnTriggerExit", on_trigger_exit)
-
-    Report.result(Tests.timed_out, helper.wait_for_condition(lambda: sphere_angled.exited_force_region and
-                                                                     sphere_vertical.exited_force_region, TIME_OUT))
-
-    sphere_vertical_slowed_by_force_region = sphere_vertical.end_velocity.z > sphere_vertical.start_velocity.z
-    sphere_angled_slowed_by_force_region = sphere_angled.end_velocity.z > sphere_angled.start_velocity.z
-
-    sphere_angled_fell_at_expected_angle = sphere_angled.end_position.x > sphere_angled.start_position.x + POSITION_TOLERANCE
-    sphere_vertical_fell_at_expected_angle = is_close_XY_position(sphere_vertical.end_position, sphere_vertical.start_position)
-
-    Report.result(Tests.angled_sphere_fell_at_angle, sphere_angled_fell_at_expected_angle)
-    Report.result(Tests.vertical_sphere_fell_vertically, sphere_vertical_fell_at_expected_angle)
-    Report.result(Tests.angled_sphere_slowed, sphere_angled_slowed_by_force_region)
-    Report.result(Tests.vertical_sphere_slowed, sphere_vertical_slowed_by_force_region)
-
-    # 8) Exit Game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_MultipleComponentsCombineForces)

+ 0 - 233
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_MultipleForcesInSameComponentCombineForces.py

@@ -1,233 +0,0 @@
-"""
-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 ID : C5959810
-# Test Case Title : Check that multiple forces in single force region create correct net force
-
-
-
-# fmt: off
-class Tests:
-    enter_game_mode                  = ("Entered game mode",                    "Failed to enter game mode")
-    sphere_exists                    = ("Sphere has been found",                "Sphere has not been found")
-    force_region_exists              = ("Force Region has been found",          "Force Region has not been found")
-    sphere_position_found            = ("Sphere position found",                "Sphere position not found")
-    force_region_position_found      = ("Force Region position found",          "Force Region position not found")
-    orientation_before_collision     = ("Sphere is above Force Region",         "Sphere is not above Force Region")
-    sphere_velocity_found            = ("Sphere velocity found",                "Sphere velocity not found")
-    sphere_velocity_before_collision = ("Sphere has valid initial velocity",    "Sphere initial velocity not valid")
-    collision                        = ("Collision has occurred",               "No collision has occurred")
-    force_applied                    = ("Forces were combined correctly",       "Forces were not applied correctly")
-    new_velocity_applied             = ("Sphere velocity has been updated",     "Sphere velocity was never updated")
-    orientation_after_collision      = ("Sphere is above and to the left",      "Entity orientation is not valid")
-    sphere_velocity_post_collision   = ("Sphere velocity valid post-collision", "Sphere velocity no longer valid")
-    force_region_has_not_moved       = ("Force Region has not moved",           "Force Region has somehow moved")
-    exit_game_mode                   = ("Exited game mode",                     "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_MultipleForcesInSameComponentCombineForces():
-    # type: () -> None
-    """
-    Summary: Runs an automated test to ensure that separate forces in a force region add correctly
-
-    Level Description:
-    Sphere - Placed directly above the force region with an initial velocity in the -z direction;
-        has PhysX Rigid Body, sphere shaped PhysX Collider, Sphere Shape
-    Force Region - Placed directly under the sphere, has a point, and world space force in the
-        z and negative x direction respectively; has PhysX Force Region, box shaped PhysX Collider
-
-    Expected Behavior: Sphere collides with force region and is sent in the negative x and positive z direction
-
-    Test Steps:
-    1) Load Level
-    2) Enter Game Mode
-    3) Find Entities
-    4) Validate initial positions and velocity
-    5) Set up handler
-    6) Wait for Sphere collision with Force Region
-    7) Validate and Log Results
-    8) Exit Game Mode
-    9) Close Editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Constants
-    TIMEOUT = 1
-    FLOAT_THRESHOLD = sys.float_info.epsilon
-
-    # Helper Functions
-    class Collision:
-        happened = False
-        force_vector = None
-        force_magnitude = None
-        velocity_now_updated = False
-
-    class Entity:
-        def __init__(self, name):
-            self.id = general.find_game_entity(name)
-            self.name = name
-            self.initial_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
-            self.final_velocity = None
-            self.initial_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-            self.final_position = None
-
-        def get_final_position_and_velocity(self):
-            self.final_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
-            self.final_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-
-        def report_sphere_values(self):
-            Report.info_vector3(self.initial_position, "{} initial position: ".format(self.name))
-            Report.info_vector3(self.initial_velocity, "{} initial velocity: ".format(self.name))
-
-            Report.info_vector3(self.final_position, "{} final position: ".format(self.name))
-            Report.info_vector3(self.final_velocity, "{} final velocity: ".format(self.name))
-
-        def report_force_region_values(self):
-            Report.info_vector3(self.initial_position, "{} initial position: ".format(self.name))
-            Report.info_vector3(self.final_position, "{} final position: ".format(self.name))
-
-    def validate_positions(collision_happened, sphere_position, force_region_position):
-        if collision_happened:
-            result = sphere_position.x < force_region_position.x
-        else:
-            result = abs(sphere_position.x - force_region_position.x) < FLOAT_THRESHOLD
-
-        return (
-            result
-            and sphere_position.z > force_region_position.z
-            and abs(sphere_position.y - force_region_position.y) < FLOAT_THRESHOLD
-        )
-
-    def validate_sphere_velocity(collision_happened, sphere_velocity_vector):
-        if collision_happened:
-            x_result = sphere_velocity_vector.x < 0
-            z_result = sphere_velocity_vector.z > 0
-        else:
-            x_result = abs(sphere_velocity_vector.x) < FLOAT_THRESHOLD
-            z_result = sphere_velocity_vector.z < 0
-
-        return x_result and z_result and abs(sphere_velocity_vector.y) < FLOAT_THRESHOLD
-
-    def vector_valid(vector, can_be_zero):
-        if can_be_zero:
-            return vector != None
-        else:
-            return vector != None and not vector.IsZero()
-
-    def on_collision_begin(args):
-        assert force_region.id.Equal(args[0])
-
-        if sphere.id.equal(args[1]):
-            Collision.happened = True
-            Report.info("Collision has begun")
-            if vector_valid(args[2], False):
-                Collision.force_vector = args[2]
-                Collision.force_magnitude = args[3]
-
-    def force_valid(vector, magnitude):
-        return magnitude > 0 and vector.x < 0 and vector.z > 0 and abs(vector.y) < FLOAT_THRESHOLD
-
-    def velocity_update_check():
-        current_velocity_vector = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", sphere.id)
-        velocity_updated = (
-            current_velocity_vector.x < sphere.initial_velocity.x
-            and current_velocity_vector.z > sphere.initial_velocity.z
-        )
-        if velocity_updated:
-            Collision.velocity_now_updated = True
-
-        return velocity_updated
-
-    # Main Script
-    helper.init_idle()
-
-    # 1) Load Level
-    helper.open_level("Physics", "ForceRegion_MultipleForcesInSameComponentCombineForces")
-
-    # 2) Enter Game Mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Find Entities
-    sphere = Entity("Sphere")
-    force_region = Entity("Force_Region")
-
-    Report.critical_result(Tests.sphere_exists, sphere.id.isValid())
-    Report.critical_result(Tests.force_region_exists, force_region.id.isValid())
-
-    # 4) Validate initial positions and velocity
-    # Position validation
-    Report.critical_result(Tests.sphere_position_found, vector_valid(sphere.initial_position, False))
-    Report.critical_result(Tests.force_region_position_found, vector_valid(force_region.initial_position, False))
-    # Velocity validation
-    Report.critical_result(Tests.sphere_velocity_found, vector_valid(sphere.initial_velocity, False))
-
-    # Value validation
-    Report.critical_result(
-        Tests.orientation_before_collision,
-        validate_positions(Collision.happened, sphere.initial_position, force_region.initial_position),
-    )
-    Report.critical_result(
-        Tests.sphere_velocity_before_collision, validate_sphere_velocity(Collision.happened, sphere.initial_velocity)
-    )
-
-    # 5) Set up handler
-    handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    handler.connect(None)
-    handler.add_callback("OnCalculateNetForce", on_collision_begin)
-
-    # 6) Wait for Sphere collision with Force Region and Velocity application
-    helper.wait_for_condition(lambda: Collision.happened, TIMEOUT)
-    helper.wait_for_condition(velocity_update_check, TIMEOUT)
-
-    # 7) Validate and Log Results
-    sphere.get_final_position_and_velocity()
-    force_region.get_final_position_and_velocity()
-
-    # Value validation
-    Report.result(Tests.new_velocity_applied, Collision.velocity_now_updated)
-    Report.result(Tests.collision, Collision.happened)
-    Report.result(Tests.force_applied, force_valid(Collision.force_vector, Collision.force_magnitude))
-    Report.result(
-        Tests.orientation_after_collision,
-        validate_positions(Collision.happened, sphere.final_position, force_region.final_position),
-    )
-    Report.result(
-        Tests.sphere_velocity_post_collision, validate_sphere_velocity(Collision.happened, sphere.final_velocity)
-    )
-    Report.result(
-        Tests.force_region_has_not_moved,
-        force_region.final_position.Subtract(force_region.initial_position).IsZero(FLOAT_THRESHOLD),
-    )
-    # Value logging
-    sphere.report_sphere_values()
-    force_region.report_force_region_values()
-    Report.info_vector3(Collision.force_vector, "Applied Force: ", Collision.force_magnitude)
-
-    # 8) Exit Game Mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_MultipleForcesInSameComponentCombineForces)

+ 0 - 168
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_NoQuiverOnHighLinearDampingForce.py

@@ -1,168 +0,0 @@
-"""
-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 ID : C15845879
-# Test Case Title : Check that linear damping with high values do not make the object to quiver
-
-
-# fmt: off
-class Tests:
-    enter_game_mode                 = ("Entered game mode",               "Failed to enter game mode")
-    exit_game_mode                  = ("Exited game mode",                "Couldn't exit game mode")
-    sphere_found                    = ("Found sphere",                    "Did not find sphere")
-    force_region_found              = ("Found force region",              "Did not find force region")
-    check_relative_position         = ("Sphere is above force region",    "Sphere isn't above force region")
-    sphere_moving_down              = ("Sphere heading to force region",  "Sphere has invalid initial velocity")
-    sphere_entered_force_region     = ("Sphere has entered force region", "Sphere never entered force region")
-    sphere_stopped_moving           = ("Sphere final velocity is zero",   "Sphere final velocity invalid")
-    sphere_still_above_force_region = ("Sphere still above force region", "Sphere not above force region")
-    no_quiver                       = ("Sphere is not quivering",         "Sphere quivering in force region")
-# fmt: on
-
-
-def ForceRegion_NoQuiverOnHighLinearDampingForce():
-    """
-    Summary: Check that linear damping with high values do not make the object to quiver
-
-    Level Description:
-    sphere - Starts above the force_region entity with initial velocity in the negative z direction and
-    gravity disabbled; has physx collider in sphere shape, physx rigid body, and sphere shape
-    force_region - Sits below sphere entity, has linear damping force set at 100 and region has scaling
-        (5,5,5); has physx collider in box shape and physx force region
-
-    Expected Behavior: Sphere falls into force region and is stuck by the damping force. It specifically should
-        not quiver up and down.
-
-    Test Steps:
-    1) Open Level
-    2) Enter Game Mode
-    3) Create and Validate Entities
-    4) Setup handler and wait for sphere to enter force region
-    5) Validate the Sphere remains in Force Region
-    6) Check to see if the sphere is quivering
-    7) Exit Game Mode
-    8) Close Editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Constants
-    FLOAT_THRESHOLD = sys.float_info.epsilon
-    TIMEOUT = 1
-    VELOCITY_THRESHOLD = 0.01
-    QUIVER_THRESHOLD = 0.01
-    SLOWDOWN_FRAMES = 30
-    SPHERE_STOP_OFFSET = 3.5
-
-    # Helper Functions
-    class Entity:
-        def __init__(self, name):
-            self.id = general.find_game_entity(name)
-            self.name = name
-            self.force_region_id = None
-            self.entered_force_region = False
-            self.quiver_reference = None
-            Report.critical_result(Tests.__dict__[self.name + "_found"], self.id.isValid())
-
-        @property
-        def position(self):
-            # type () -> Vector3
-            return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-
-        @property
-        def velocity(self):
-            # type () -> Vector3
-            return azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", self.id)
-
-        @property
-        def is_moving_up(self):
-            # type () -> bool
-            return (
-                abs(self.velocity.x) < FLOAT_THRESHOLD
-                and abs(self.velocity.y) < FLOAT_THRESHOLD
-                and self.velocity.z > 0.0
-            )
-
-        def set_handler(self):
-            self.handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-            self.handler.connect(None)
-            self.handler.add_callback("OnCalculateNetForce", self.on_calculate_net_force)
-
-        def on_calculate_net_force(self, args):
-            # type (list) -> None
-            # Flips the collision happened boolean for the sphere object and prints the force values.
-            if self.force_region_id.Equal(args[0]) and self.id.Equal(args[1]) and not self.entered_force_region:
-                self.entered_force_region = True
-
-    def sphere_not_quivering():
-        # type () -> bool
-        # Returns False if sphere "quivers" from its initial position, True if it stays close to it's original position
-        return abs(sphere.position.z - sphere.quiver_reference) > QUIVER_THRESHOLD
-
-    def sphere_above_force_region(sphere_position, force_region_position):
-        # type () -> bool
-        return (
-            abs(sphere_position.x - force_region_position.x) < FLOAT_THRESHOLD
-            and abs(sphere_position.y - force_region_position.y) < FLOAT_THRESHOLD
-            and sphere_position.z > force_region_position.z
-        )
-
-    # Main Script
-    helper.init_idle()
-    # 1) Open Level
-    helper.open_level("Physics", "ForceRegion_NoQuiverOnHighLinearDampingForce")
-
-    # 2) Enter Game Mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Create and Validate Entities
-    sphere = Entity("sphere")
-    force_region = Entity("force_region")
-
-    sphere.force_region_id = force_region.id
-    Report.critical_result(Tests.sphere_moving_down, not sphere.is_moving_up)
-    Report.critical_result(
-        Tests.check_relative_position, sphere_above_force_region(sphere.position, force_region.position)
-    )
-
-    # 4) Setup handler and wait for sphere to enter force region
-    sphere.set_handler()
-    Report.critical_result(
-        Tests.sphere_entered_force_region, helper.wait_for_condition(lambda: sphere.entered_force_region, TIMEOUT)
-    )
-
-    # 5) Validate the Sphere remains in Force Region
-    # Must wait for the sphere to slow down
-    Report.result(Tests.sphere_stopped_moving, helper.wait_for_condition(lambda: sphere.velocity.IsZero(VELOCITY_THRESHOLD), TIMEOUT))
-    # Force region has scaling (5,5,5). Thus the upper edge of the force region is 2.5m above the transform. With proper offset we can
-    # see that sphere is stuck on top of the force region and did not bounce off. 
-    Report.result(Tests.sphere_still_above_force_region, (sphere.position.z - force_region.position.z) < SPHERE_STOP_OFFSET)
-
-    # 6) Check to see if the sphere is quivering
-    sphere.quiver_reference = sphere.position.z
-    Report.result(Tests.no_quiver, not helper.wait_for_condition(sphere_not_quivering, TIMEOUT))
-
-    # 7) Exit Game Mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_NoQuiverOnHighLinearDampingForce)

+ 0 - 198
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ParentChildForcesCombineForces.py

@@ -1,198 +0,0 @@
-"""
-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 ID : C6090547
-# Test Case Title : Check that force regions in parent and child entities work together.
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode               = ("Entered game mode",                                 "Failed to enter game mode")
-    find_sphere                   = ("Sphere found",                                      "Sphere not found")
-    find_parent_force_region      = ("Parent Force Region found",                         "Parent Force Region not found")
-    find_child_force_region       = ("Child Force Region found",                          "Child Force Region not found")
-    find_trigger_box              = ("Trigger Box found",                                 "Trigger Box not found")
-    sphere_gravity_disabled       = ("Sphere gravity disabled",                           "Sphere gravity not disabled")
-    parent_force_region_direction = ("Parent Force Region is in positive x direction",    "Parent Force Region is not in positive x direction")
-    child_force_region_direction  = ("Child Force Region is in positive y direction",     "Child Force Region is not in positive y direction")
-    parent_force_on_sphere        = ("Parent Force Region applied total force on sphere", "Parent Force Region did not apply total force on sphere")
-    child_force_on_sphere         = ("Child Force Region applied total force on sphere",  "Child Force Region did not apply total force on sphere")
-    sphere_enters_trigger         = ("Sphere entered Trigger",                            "Sphere did not enter Trigger before Timeout")
-    sphere_exits_trigger          = ("Sphere exited Trigger",                             "Sphere did not exit Trigger before Timeout")
-    exit_game_mode                = ("Exited game mode",                                  "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_ParentChildForcesCombineForces():
-    """
-    Summary:
-    Runs an automated test to ensure that force regions in parent and child entities work together.
-
-    Level Description:
-    Parent Force Region (entity) - contains PhysX Force Region with world space force which has positive X force
-                                   Magnitude with Direction (1, 0, 0) and PhysX Collider (box shape).
-    Child Force Region (entity)  - contains PhysX Force Region with world space force which has positive Y force
-                                   Magnitude with Direction (0, 1, 0) and PhysX Collider (box shape).
-    Sphere (entity)              - contains a Sphere mesh, PhysX Collider (sphere shape) and PhysX Rigid Body.
-                                   Sphere located at the low (x, y) corner of where the force regions overlap.
-    Trigger Box (entity)         - contains PhysX Collider (box shape)
-                                   trigger box placed in the (1, 1, 0) direction from the sphere at the opposite end of
-                                   the force region overlap.
-    Parent and Child force regions are placed above the terrain as two overlapping sheets.
-
-    Expected Behavior:
-    When game mode is entered, the Sphere should accelerate evenly in the positive (x, y) direction and it should move
-    as much in x as it does in y. Sphere should pass through Trigger Box.
-
-    Test Steps:
-     1)  Open level
-     2)  Enter game mode
-     3)  Retrieve and validate entities
-     4)  Make sure gravity is off from the start
-     5)  Make sure the parent entity is set as the parent of the child entity in level
-     6)  Make sure parent and child force regions are in correct directions
-     7)  Check parent and child force regions each exert its force on sphere
-     8)  Verify sphere passes through trigger box
-     9)  Exit game mode
-     10) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-    import azlmbr.math as lymath
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    # Constants
-    TIMEOUT = 3.0
-    X_DIRECTION = lymath.Vector3(1.0, 0.0, 0.0)
-    Y_DIRECTION = lymath.Vector3(0.0, 1.0, 0.0)
-    EXPECTED_MAGNITUDE = 100.0
-    TOLERANCE = 0.1
-
-    helper.init_idle()
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_ParentChildForcesCombineForces")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve and validate entities
-    sphere_id = general.find_game_entity("Sphere")
-    Report.critical_result(Tests.find_sphere, sphere_id.IsValid())
-
-    parent_id = general.find_game_entity("Parent Force Region")
-    Report.critical_result(Tests.find_parent_force_region, parent_id.IsValid())
-
-    child_id = general.find_game_entity("Child Force Region")
-    Report.critical_result(Tests.find_child_force_region, child_id.IsValid())
-
-    trigger_box_id = general.find_game_entity("Trigger Box")
-    Report.critical_result(Tests.find_trigger_box, trigger_box_id.IsValid())
-
-    # 4) Make sure gravity is off from the start
-    is_gravity_enabled = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", sphere_id)
-    Report.critical_result(Tests.sphere_gravity_disabled, not is_gravity_enabled)
-
-    # 5) Make sure the parent entity is set as the parent of the child entity in level
-    id = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetParentId", child_id)
-    if id.Equal(parent_id):
-        Report.info("parent and child force regions are in correct position")
-
-    # 6) Make sure parent and child force regions are in correct directions
-    dir_parent = azlmbr.physics.ForceWorldSpaceRequestBus(azlmbr.bus.Event, "GetDirection", parent_id)
-    dir_child = azlmbr.physics.ForceWorldSpaceRequestBus(azlmbr.bus.Event, "GetDirection", child_id)
-    Report.info_vector3(dir_parent, "Parent force region direction : ")
-    Report.info_vector3(dir_child, "Child force region direction : ")
-    Report.critical_result(Tests.parent_force_region_direction, dir_parent.IsClose(X_DIRECTION, TOLERANCE))
-    Report.critical_result(Tests.child_force_region_direction, dir_child.IsClose(Y_DIRECTION, TOLERANCE))
-
-    # 7) Check parent and child force regions each exert its force on sphere
-    class NetForceMagnitude:
-        parent_force_region_magnitude = 0
-        child_force_region_magnitude = 0
-
-    def on_calc_net_force(args):
-        """
-        args[0] - force region entity
-        args[1] - entity entering
-        args[2] - vector
-        args[3] - magnitude
-        """
-        force_region_id = args[0]
-        entering_entity = args[1]
-        if entering_entity.Equal(sphere_id):
-            if force_region_id.Equal(parent_id):
-                NetForceMagnitude.parent_force_region_magnitude = args[3]
-            elif force_region_id.Equal(child_id):
-                NetForceMagnitude.child_force_region_magnitude = args[3]
-
-    force_notification_handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    force_notification_handler.connect(None)
-    force_notification_handler.add_callback("OnCalculateNetForce", on_calc_net_force)
-    helper.wait_for_condition(lambda : NetForceMagnitude.parent_force_region_magnitude != 0 and NetForceMagnitude.child_force_region_magnitude != 0, 1.0)
-
-    Report.info("Parent Force Region Magnitude on Sphere : {}".format(NetForceMagnitude.parent_force_region_magnitude))
-    Report.info("Child Force Region Magnitude on Sphere : {}".format(NetForceMagnitude.child_force_region_magnitude))
-    Report.critical_result(
-        Tests.parent_force_on_sphere,
-        abs(EXPECTED_MAGNITUDE - NetForceMagnitude.parent_force_region_magnitude) < TOLERANCE,
-    )
-    Report.critical_result(
-        Tests.child_force_on_sphere,
-        abs(EXPECTED_MAGNITUDE - NetForceMagnitude.child_force_region_magnitude) < TOLERANCE,
-    )
-
-    # 8) Verify sphere passes through trigger box
-    class Trigger:
-        on_entered = False
-        on_exited = False
-
-    def on_trigger_enter(args):
-        other_id = args[0]
-        if other_id.Equal(sphere_id):
-            Trigger.on_entered = True
-
-    def on_trigger_exit(args):
-        other_id = args[0]
-        if other_id.Equal(sphere_id):
-            Trigger.on_exited = True
-
-    handler = azlmbr.physics.TriggerNotificationBusHandler()
-    handler.connect(trigger_box_id)
-    handler.add_callback("OnTriggerEnter", on_trigger_enter)
-    handler.add_callback("OnTriggerExit", on_trigger_exit)
-
-    # Check sphere enters trigger box
-    helper.wait_for_condition(lambda: Trigger.on_entered, TIMEOUT)
-    Report.critical_result(Tests.sphere_enters_trigger, Trigger.on_entered)
-
-    # Check sphere exits trigger box
-    helper.wait_for_condition(lambda: Trigger.on_exited, TIMEOUT)
-    Report.result(Tests.sphere_exits_trigger, Trigger.on_exited)
-
-    # 9) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_ParentChildForcesCombineForces)

+ 0 - 188
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_PointForceOnRigidBodies.py

@@ -1,188 +0,0 @@
-"""
-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 ID : C5932044
-# Test Case Title : Check that force region exerts point force on rigid bodies
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode             = ("Entered game mode",                                           "Failed to enter game mode"                                     )
-    find_ball                   = ("Ball entity found",                                           "Ball entity not found"                                         )
-    find_box                    = ("Box entity found",                                            "Box entity not found"                                          )
-    gravity_works               = ("Ball fell",                                                   "Ball did not fall"                                             )
-    ball_entered_force_region   = ("Ball entered force region",                                   "Ball did not enter force region before timeout"                )
-    ball_exited_force_region    = ("Ball exited force region",                                    "Ball did not exit force region before timeout"                 )
-    net_force_magnitude         = ("The net force magnitude on ball is close to expected value",  "The net force magnitude on ball is not close to expected value")
-    ball_moved_up               = ("Ball moved up",                                               "Ball did not move up"                                          )
-    ball_moved_right            = ("Ball moved right",                                            "Ball did not move right"                                       )
-    ball_not_moved_y            = ("Ball did not move in the y direction",                        "Ball moved in the y direction"                                 )
-    exit_game_mode              = ("Exited game mode",                                            "Couldn't exit game mode"                                       )
-# fmt: on
-
-
-def ForceRegion_PointForceOnRigidBodies():
-    """
-    Summary:
-    Runs an automated test to ensure that that a force region exerts point force on rigid bodies
-
-    Level Description:
-    RigidBody (entity) - a sphere suspended above and to the right the a force region with gravity enabled;
-        contains a sphere mesh, PhysX Collider (sphere shape), and PhysX RigidBody
-    ForceRegion (entity) - contains box mesh, PhysX Collider (Box shape), and PhysX RigidBody
-
-    Expected Behavior:
-    When game mode is entered, the ball entity will experience gravity and fall toward the upper right edge (+z, +x) of
-    the force region. The force region applies a point force to the ball, sending it upwards (+z) and to the right (+x)
-
-    Test Steps:
-     1) Open level
-     2) Enter game mode
-     3) Retrieve entities
-     4) Get the starting x & z position of the ball
-     5) Check that the ball falls (gravity check)
-     6) Check that the ball enters the trigger area
-     7) Get the magnitude of the collision
-     8) Check that the ball exits the trigger area
-     9) Verify that the magnitude of the collision is as expected
-    10) Check that the ball is moving up and to the right
-    11) Exit game mode
-    12) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    class Ball:
-        start_position_x = None
-        start_position_z = None
-        fell = False
-
-    # Constants
-    TIMEOUT = 2.0
-    MAGNITUDE_TOLERANCE = 0.2                      # Magnitudes must be within this amount in order to be valid
-    NO_MOTION_Y_TOLERANCE = sys.float_info.epsilon # Motion in the y axis must be below this in order to be valid
-
-    helper.init_idle()
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_PointForceOnRigidBodies")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve entities
-    ball_id = general.find_game_entity("RigidBody")
-    Report.critical_result(Tests.find_ball, ball_id.IsValid())
-
-    box_id = general.find_game_entity("ForceRegion")
-    Report.critical_result(Tests.find_box, box_id.IsValid())
-
-    # 4) Get the starting x & z position of the ball
-    Ball.start_position_x = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldX", ball_id)
-    Ball.start_position_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", ball_id)
-    Report.info("Ball start X: {}".format(Ball.start_position_x))
-    Report.info("Ball start Z: {}".format(Ball.start_position_z))
-
-    # 5) Check that the ball falls (gravity check)
-    def ball_falls():
-        if not Ball.fell:
-            ball_position_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", ball_id)
-            if (ball_position_z - Ball.start_position_z) < 0.0:
-                Report.info("Ball position is now lower than the starting position")
-                Ball.fell = True
-        return Ball.fell
-
-    helper.wait_for_condition(ball_falls, TIMEOUT)
-    Report.result(Tests.gravity_works, Ball.fell)
-
-    # 6) Check that the ball enters the trigger area
-    class ForceRegionTrigger:
-        entered = False
-        exited = False
-
-    def on_enter(args):
-        other_id = args[0]
-        if other_id.Equal(ball_id):
-            Report.info("Trigger entered")
-            ForceRegionTrigger.entered = True
-
-    def on_exit(args):
-        other_id = args[0]
-        if other_id.Equal(ball_id):
-            Report.info("Trigger exited")
-            ForceRegionTrigger.exited = True
-
-    handler = azlmbr.physics.TriggerNotificationBusHandler()
-    handler.connect(box_id)
-    handler.add_callback("OnTriggerEnter", on_enter)
-    handler.add_callback("OnTriggerExit", on_exit)
-
-    helper.wait_for_condition(lambda: ForceRegionTrigger.entered, TIMEOUT)
-    Report.result(Tests.ball_entered_force_region, ForceRegionTrigger.entered)
-
-    # 7) Get the magnitude of the collision
-    class NetForceMagnitude:
-        value = 0
-
-    def on_calc_net_force(args):
-        """
-        args[0] - force region entity
-        args[1] - entity entering
-        args[2] - vector
-        args[3] - magnitude
-        """
-        force_magnitude = args[3]
-        NetForceMagnitude.value = force_magnitude
-
-    force_notification_handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    force_notification_handler.connect(None)
-    force_notification_handler.add_callback("OnCalculateNetForce", on_calc_net_force)
-
-    # 8) Check that the ball exits the trigger area
-    helper.wait_for_condition(lambda: ForceRegionTrigger.exited, TIMEOUT)
-    Report.result(Tests.ball_exited_force_region, ForceRegionTrigger.exited)
-
-    # 9) Verify that the magnitude of the collision is as expected
-    def is_close_float(a, b, tolerance):
-        return abs(b - a) < tolerance
-
-    force_region_magnitude = azlmbr.physics.ForcePointRequestBus(azlmbr.bus.Event, "GetMagnitude", box_id)
-    Report.info(
-        "NetForce magnitude is {}, Force Region magnitude is {}".format(NetForceMagnitude.value, force_region_magnitude)
-    )
-    Report.result(
-        Tests.net_force_magnitude, is_close_float(NetForceMagnitude.value, force_region_magnitude, MAGNITUDE_TOLERANCE)
-    )
-
-    # 10) Check that the ball is moving up and to the right
-    linear_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", ball_id)
-    Report.info_vector3(linear_velocity, "Ball linear velocity")
-    Report.result(Tests.ball_moved_up, linear_velocity.z > 0)
-    Report.result(Tests.ball_moved_right, linear_velocity.x > 0)
-    Report.result(Tests.ball_not_moved_y, abs(linear_velocity.y) < NO_MOTION_Y_TOLERANCE)
-
-    # 11) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_PointForceOnRigidBodies)

+ 0 - 404
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_PositionOffset.py

@@ -1,404 +0,0 @@
-"""
-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 ID : C5959808
-# Test Case Title : Verify Force Region Position Offset
-
-
-
-# fmt:off
-class Tests:
-    # General tests
-    enter_game_mode = ("Entered game mode",               "Failed to enter game mode")
-    exit_game_mode  = ("Exited game mode",                "Couldn't exit game mode")
-    test_completed  = ("The test successfully completed", "The test timed out")
-    # ***** Entities found *****
-    # Force Regions
-    force_region_x_found          = ("Force Region for X axis test was found",          "Force Region for X axis test was NOT found")
-    force_region_y_found          = ("Force Region for Y axis test was found",          "Force Region for Y axis test was NOT found")
-    force_region_z_found          = ("Force Region for Z axis test was found",          "Force Region for Z axis test was NOT found")
-    # Force Region Pass Boxes
-    force_region_pass_box_x_found = ("Force Region Pass Box for X axis test was found", "Force Region Pass Box for X axis test was NOT found")
-    force_region_pass_box_y_found = ("Force Region Pass Box for Y axis test was found", "Force Region Pass Box for Y axis test was NOT found")
-    force_region_pass_box_z_found = ("Force Region Pass Box for Z axis test was found", "Force Region Pass Box for Z axis test was NOT found")
-    # External Pass Boxes
-    external_pass_box_x_found     = ("External Pass Box for X axis test was found",     "External Pass Box for X axis test was NOT found")
-    external_pass_box_y_found     = ("External Pass Box for Y axis test was found",     "External Pass Box for Y axis test was NOT found")
-    external_pass_box_z_found     = ("External Pass Box for Z axis test was found",     "External Pass Box for Z axis test was NOT found")
-    # Force Region Fail Boxes
-    force_region_fail_box_x_found = ("Force Region Fail Box for X axis test was found", "Force Region Fail Box for X axis test was NOT found")
-    force_region_fail_box_y_found = ("Force Region Fail Box for Y axis test was found", "Force Region Fail Box for Y axis test was NOT found")
-    force_region_fail_box_z_found = ("Force Region Fail Box for Z axis test was found", "Force Region Fail Box for Z axis test was NOT found")
-    # External Fail Boxes
-    external_fail_box_x_found     = ("External Fail Box for X axis test was found",     "External Fail Box for X axis test was NOT found")
-    external_fail_box_y_found     = ("External Fail Box for Y axis test was found",     "External Fail Box for Y axis test was NOT found")
-    external_fail_box_z_found     = ("External Fail Box for Z axis test was found",     "External Fail Box for Z axis test was NOT found")
-    # Pass spheres
-    sphere_pass_x_found           = ("Pass Sphere for X axis test was found",           "Pass Sphere for X axis test was NOT found")
-    sphere_pass_y_found           = ("Pass Sphere for Y axis test was found",           "Pass Sphere for Y axis test was NOT found")
-    sphere_pass_z_found           = ("Pass Sphere for Z axis test was found",           "Pass Sphere for Z axis test was NOT found")
-    # Bounce Spheres
-    sphere_bounce_x_found         = ("Bounce Sphere for X axis test was found",         "Bounce Sphere for X axis test was NOT found")
-    sphere_bounce_y_found         = ("Bounce Sphere for Y axis test was found",         "Bounce Sphere for Y axis test was NOT found")
-    sphere_bounce_z_found         = ("Bounce Sphere for Z axis test was found",         "Bounce Sphere for Z axis test was NOT found")
-
-    # ****** Entities' results ******
-    # Force Regions
-    force_region_x_mag_result      = ("Force Region for X axis magnitude exerted was as expected",         "Force Region for X axis magnitude exerted was NOT as expected")
-    force_region_y_mag_result      = ("Force Region for Y axis magnitude exerted was as expected",         "Force Region for Y axis magnitude exerted was NOT as expected")
-    force_region_z_mag_result      = ("Force Region for Z axis magnitude exerted was as expected",         "Force Region for Z axis magnitude exerted was NOT as expected")
-    force_region_x_norm_result     = ("Force Region for X axis normal exerted was as expected",            "Force Region for X axis normal exerted was NOT as expected")
-    force_region_y_norm_result     = ("Force Region for Y axis normal exerted was as expected",            "Force Region for Y axis normal exerted was NOT as expected")
-    force_region_z_norm_result     = ("Force Region for Z axis normal exerted was as expected",            "Force Region for Z axis normal exerted was NOT as expected")
-    # Force Region Pass Boxes
-    force_region_pass_box_x_result = ("Force Region Pass Box for X axis collided with exactly one sphere", "Force Region Pass Box for X axis DID NOT collide with exactly one sphere")
-    force_region_pass_box_y_result = ("Force Region Pass Box for Y axis collided with exactly one sphere", "Force Region Pass Box for Y axis DID NOT collide with exactly one sphere")
-    force_region_pass_box_z_result = ("Force Region Pass Box for Z axis collided with exactly one sphere", "Force Region Pass Box for Z axis DID NOT collide with exactly one sphere")
-    # External Pass Boxes
-    external_pass_box_x_result     = ("External Pass Box for X axis collided with exactly one sphere",     "External Pass Box for X axis DID NOT collide with exactly one sphere")
-    external_pass_box_y_result     = ("External Pass Box for Y axis collided with exactly one sphere",     "External Pass Box for Y axis DID NOT collide with exactly one sphere")
-    external_pass_box_z_result     = ("External Pass Box for Z axis collided with exactly one sphere",     "External Pass Box for Z axis DID NOT collide with exactly one sphere")
-    # Force Region Fail Boxes
-    force_region_fail_box_x_result = ("Force Region Fail Box for X axis collided with no spheres",         "Force Region Fail Box for X axis DID collide with a sphere")
-    force_region_fail_box_y_result = ("Force Region Fail Box for Y axis collided with no spheres",         "Force Region Fail Box for Y axis DID collide with a sphere")
-    force_region_fail_box_z_result = ("Force Region Fail Box for Z axis collided with no spheres",         "Force Region Fail Box for Z axis DID collide with a sphere")
-    # External Fail Boxes
-    external_fail_box_x_result     = ("External Fail Box for X axis collided with no spheres",             "External Fail Box for X axis DID collide with a sphere")
-    external_fail_box_y_result     = ("External Fail Box for Y axis collided with no spheres",             "External Fail Box for Y axis DID collide with a sphere")
-    external_fail_box_z_result     = ("External Fail Box for Z axis collided with no spheres",             "External Fail Box for Z axis DID collide with a sphere")
-    # Pass spheres
-    sphere_pass_x_result           = ("Pass Sphere for X axis collided with expected Box",                 "Pass Sphere for X axis DID NOT collide with expected Box")
-    sphere_pass_y_result           = ("Pass Sphere for Y axis collided with expected Box",                 "Pass Sphere for Y axis DID NOT collide with expected Box")
-    sphere_pass_z_result           = ("Pass Sphere for Z axis collided with expected Box",                 "Pass Sphere for Z axis DID NOT collide with expected Box")
-    # Bounce Spheres
-    sphere_bounce_x_result         = ("Bounce Sphere for X axis collided with expected Box",               "Bounce Sphere for X axis DID NOT collide with expected Box")
-    sphere_bounce_y_result         = ("Bounce Sphere for Y axis collided with expected Box",               "Bounce Sphere for Y axis DID NOT collide with expected Box")
-    sphere_bounce_z_result         = ("Bounce Sphere for Z axis collided with expected Box",               "Bounce Sphere for Z axis DID NOT collide with expected Box")
-    # fmt:on
-
-    @staticmethod
-    # Test tuple accessor via string
-    def get_test(test_name):
-        if test_name in Tests.__dict__:
-            return Tests.__dict__[test_name]
-        else:
-            return None
-
-def ForceRegion_PositionOffset():
-    """
-    Summary:
-    Force Region positional offset is tested for each of the 3 axises (X, Y, and Z). Each axis's test has one
-    ForceRegion, two spheres and four boxes. By monitoring which box each sphere collides with we can validate the
-    integrity of the ForceRegions positional offset.
-
-    Level Description:
-    Each axis's test has the following entities:
-    one force region - set for point force and with it's collider set offset (on the axis in test).
-    two spheres - one positioned near the transform of the force region, one positioned near the [offset] collider for
-        the force region
-    four boxes - One box is positioned inside the force region's transform, one inside the force region's [offset]
-        collider. The other two boxes are positioned behind the two spheres (relative to the direction they will be
-        initially traveling)
-
-    Expected Behavior:
-    All three axises' tests run in parallel. when the tests begin, the spheres should move toward their expected
-    force regions. The spheres positioned to collide with their region's [offset] collider should be forced backwards
-    before entering the force region and collide with the box behind it. The spheres positioned by their force region's
-    transforms should pass straight into the transform and collide with the box inside the transform.
-    The boxes inside the Force Regions' [offset] colliders and the boxes behind the spheres set to move into the Force
-    Regions' transforms should not register any collisions.
-
-    Steps:
-    1) Open level and enter game mode
-    2) Set up tests and variables
-    3) Wait for test results (or time out)
-        (Report results)
-    4) Exit game mode and close the editor
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.math as azmath
-    import azlmbr.bus
-    import azlmbr
-
-    # Constants
-    CLOSE_ENOUGH = 0.01  # Close enough threshold for comparing floats
-    TIME_OUT = 2.0  # Time out (in seconds) until test is aborted
-    FORCE_MAGNITUDE = 1000.0  # Point force magnitude for Force Regions
-    SPEED = 3.0  # Initial speed (in m/s) of the moving spheres.
-
-    # Full list for all spheres. Used for EntityId look up in event handlers
-    all_spheres = []
-
-    # Entity base class handles very general entity initialization
-    # Should be treated as a "virtual" class and all implementing child
-    # classes should implement a "self.result()" function referenced in EntityBase::report(self)
-    class EntityBase:
-        def __init__(self, name):
-            # type: (str) -> None
-            self.name = name
-            self.print_list = []
-            self.id = general.find_game_entity(name)
-            found_test = Tests.get_test(name + "_found")
-            Report.critical_result(found_test, self.id.IsValid())
-
-        # Reports this entity's result. Implicitly calls "get" on result.
-        # Subclasses implement their own definition of a successful result
-        def report(self):
-            # type: () -> None
-            result_test = Tests.get_test(self.name + "_result")
-            Report.result(result_test, self.result())
-
-        # Prints the print queue (with decorated header) if not empty
-        def print_log(self):
-            # type: () -> None
-            if self.print_list:
-                Report.info("*********** {} **********".format(self))
-                for line in self.print_list:
-                    Report.info(line)
-                Report.info("")
-
-        # Quick string cast, returns entity name
-        def __str__(self):
-            # type: () -> str
-            return self.name
-
-    # ForceRegion handles all the data and behavior associated with a ForceRegion (for this test)
-    # They simply wait for a Sphere to collide with them. On collision they store the calculated force
-    # magnitude for verification.
-    class ForceRegion(EntityBase):
-        def __init__(self, name, magnitude):
-            # type: (str, float) -> None
-            EntityBase.__init__(self, name)
-            self.expected_magnitude = magnitude
-            self.actual_magnitude = None
-            self.expected_normal = None
-            self.actual_normal = None
-            # Set point force Magnitude
-            azlmbr.physics.ForcePointRequestBus(azlmbr.bus.Event, "SetMagnitude", self.id, magnitude)
-            # Set up handler
-            self.handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-            self.handler.connect(None)
-            self.handler.add_callback("OnCalculateNetForce", self.on_calc_force)
-
-        # Callback function for OnCalculateNetForce event
-        def on_calc_force(self, args):
-            # type: ([EntityId, EntityId, azmath.Vector3, float]) -> None
-            if self.id.Equal(args[0]) and self.actual_magnitude is None:
-                for sphere in all_spheres:
-                    if sphere.id.Equal(args[1]):
-                        # Log event in print queue (for me and for the sphere)
-                        self.print_list.append("Exerting force on {}:".format(sphere))
-                        sphere.print_list.append("Force exerted by {}".format(self))
-                        # Save calculated data to be compared later
-                        self.actual_normal = args[2]
-                        self.actual_magnitude = args[3]
-                        self.expected_normal = sphere.initial_velocity.GetNormalizedSafe().Unary()
-                        # Add expected/actual to print queue
-                        self.print_list.append("Force Vector: ")
-                        self.print_list.append(
-                            "  Expected: ({:.2f}, {:.2f}, {:.2f})".format(
-                                self.expected_normal.x, self.expected_normal.y, self.expected_normal.z
-                            )
-                        )
-                        self.print_list.append(
-                            "  Actual: ({:.2f}, {:.2f}, {:.2f})".format(
-                                self.actual_normal.x, self.actual_normal.y, self.actual_normal.z
-                            )
-                        )
-                        self.print_list.append("Force Magnitude: ")
-                        self.print_list.append("  Expected: {}".format(self.expected_magnitude))
-                        self.print_list.append("  Actual: {:.2f}".format(self.actual_magnitude))
-
-        # EntityBase::report() overload.
-        # Force regions have 2 test tuples to report on
-        def report(self):
-            magnitude_test = Tests.get_test(self.name + "_mag_result")
-            normal_test = Tests.get_test(self.name + "_norm_result")
-            Report.result(magnitude_test, self.magnitude_result())
-            Report.result(normal_test, self.normal_result())
-
-        # Test result calculations
-        # Used in EntityBase for reporting results
-        def result(self):
-            # type: () -> bool
-            return self.magnitude_result() and self.normal_result()
-
-        def magnitude_result(self):
-            # type: () -> bool
-            return (
-                self.actual_magnitude is not None
-                and abs(self.actual_magnitude - self.expected_magnitude) < CLOSE_ENOUGH
-            )
-
-        def normal_result(self):
-            # type: () -> bool
-            return (
-                self.actual_normal is not None
-                and self.expected_normal is not None
-                and self.expected_normal.IsClose(self.actual_normal, CLOSE_ENOUGH)
-            )
-
-    # Spheres are the objects that test the force regions. They store an expected collision entity and an
-    # actual collision entity
-    class Sphere(EntityBase):
-        def __init__(self, name, initial_velocity, expected_collision):
-            # type: (str, azmath.Vector3, EntityBase, bool) -> None
-            EntityBase.__init__(self, name)
-            self.initial_velocity = initial_velocity
-            azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetLinearVelocity", self.id, initial_velocity)
-            self.print_list.append(
-                "Initial velocity: ({:.2f}, {:.2f}, {:.2f})".format(
-                    initial_velocity.x, initial_velocity.y, initial_velocity.z
-                )
-            )
-            self.expected_collision = expected_collision
-            self.print_list.append("Expected Collision: {}".format(expected_collision))
-            self.actual_collision = None
-            self.active = True
-            self.force_normal = None
-
-        # Registers a collision with this sphere. Saves a reference to the colliding entity for processing later.
-        # Deactivate self after collision is registered.
-        def collide(self, collision_entity):
-            # type: (EntityBase) -> None
-            # Log the event
-            self.print_list.append("Collided with {}".format(collision_entity))
-            self.actual_collision = collision_entity
-            # Deactivate self
-            azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "DeactivateGameEntity", self.id)
-            self.active = False
-
-        # Calculates result
-        # Used in EntityBase for reporting results
-        def result(self):
-            if self.actual_collision is None:
-                return False
-            else:
-                return self.expected_collision.id.Equal(self.actual_collision.id)
-
-    # Box entities wait for a collision with a sphere as a means of validation the force region's offset
-    # worked according to plan.
-    class Box(EntityBase):
-        def __init__(self, name, expected_sphere_collisions):
-            # type: (str, int) -> None
-            EntityBase.__init__(self, name)
-            self.spheres_collided = 0
-            self.expected_sphere_collisions = expected_sphere_collisions
-            # Set up handler
-            self.handler = azlmbr.physics.CollisionNotificationBusHandler()
-            self.handler.connect(self.id)
-            self.handler.add_callback("OnCollisionBegin", self.on_collision_begin)
-
-        # Callback function for OnCollisionBegin event
-        def on_collision_begin(self, args):
-            for sphere in all_spheres:
-                if sphere.id.Equal(args[0]):
-                    # Log event
-                    self.print_list.append("Collided with {}".format(sphere))
-                    # Register collision with sphere
-                    sphere.collide(self)
-                    self.spheres_collided += 1  # Count collisions for validation later
-                    break
-
-        # Calculates test result
-        # Used in EntityBase for reporting results
-        def result(self):
-            return self.spheres_collided == self.expected_sphere_collisions
-
-    # Manages the entities required to run the test for one axis (X, Y, or Z)
-    class AxisTest:
-        def __init__(self, axis, init_velocity):
-            # type: (str, azmath.Vector3) -> None
-            self.name = axis + " axis test"
-            self.force_region = ForceRegion("force_region_" + axis, FORCE_MAGNITUDE)
-            self.spheres = [
-                Sphere("sphere_pass_" + axis, init_velocity, Box("force_region_pass_box_" + axis, 1)),
-                Sphere("sphere_bounce_" + axis, init_velocity, Box("external_pass_box_" + axis, 1)),
-            ]
-            self.boxes = [
-                Box("external_fail_box_" + axis, 0),
-                Box("force_region_fail_box_" + axis, 0)
-            ] + [
-                # Gets the Boxes passed to spheres on init
-                sphere.expected_collision for sphere in self.spheres
-            ]
-            # Full list for all entities this test is responsible for
-            self.all_entities = self.boxes + self.spheres + [self.force_region]
-            # Add spheres to global "lookup" list
-            all_spheres.extend(self.spheres)
-
-        # Checks for all entities' test passing conditions
-        def passed(self):
-            return all([e.result() for e in self.all_entities])
-
-        # Returns true when this test has completed (i.e. when the spheres have collided and are deactivated)
-        def completed(self):
-            return all([not sphere.active for sphere in self.spheres])
-
-        # Reports results for all entities in this test
-        def report(self):
-            Report.info("::::::::::::::::::::::::::::: {} Results :::::::::::::::::::::::::::::".format(self.name))
-            for entity in self.all_entities:
-                entity.report()
-
-        # Prints the logs for all entities in this test
-        def print_log(self):
-            Report.info("::::::::::::::::::::::::::::: {} Log :::::::::::::::::::::::::::::".format(self.name))
-            for entity in self.all_entities:
-                entity.print_log()
-
-    # *********** Execution Code ***********
-
-    # 1) Open level
-    helper.init_idle()
-    helper.open_level("Physics", "ForceRegion_PositionOffset")
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 2) Variable set up
-    # Initial velocities for the three different directions spheres will be moving
-    x_vel = azmath.Vector3(SPEED, 0.0, 0.0)
-    y_vel = azmath.Vector3(0.0, SPEED, 0.0)
-    z_vel = azmath.Vector3(0.0, 0.0, SPEED)
-
-    # The three tests, one for each axis
-    axis_tests = [
-        AxisTest("x", z_vel),  # Spheres move in Z direction when testing X axis offset
-        AxisTest("y", x_vel),  # Spheres move in X direction when testing Y axis offset
-        AxisTest("z", y_vel),  # Spheres move in Y direction when testing Z axis offset
-    ]
-
-    # 3) Wait for test results or time out
-    Report.result(
-        Tests.test_completed, helper.wait_for_condition(
-            lambda: all([test.completed() for test in axis_tests]), TIME_OUT
-        )
-    )
-
-    # Report results
-    for test in axis_tests:
-        test.report()
-
-    # Print entity print queues for each failed test
-    for test in axis_tests:
-        if not test.passed():
-            test.print_log()
-
-    # 4) Exit game mode and close editor
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_PositionOffset)

+ 0 - 138
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_PxMeshShapedForce.py

@@ -1,138 +0,0 @@
-"""
-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 ID : C5959761
-# Test Case Title : Check that force region (physics asset) exerts point force
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode          = ("Entered game mode",         "Failed to enter game mode")
-    find_ball                = ("Ball entity found",         "Ball entity not found")
-    find_sedan               = ("Sedan entity found",        "Sedan entity not found")
-    ball_fell                = ("The ball fell",             "The ball did not fall")
-    ball_enters_force_region = ("Ball entered force region", "Ball did not enter force region")
-    ball_exits_force_region  = ("Ball exited force region",  "Ball did not exit force region")
-    ball_moved_up            = ("Ball moved up",             "Ball did not move up")
-    ball_moved_forward       = ("Ball moved forward",        "Ball did not move forward")
-    exit_game_mode           = ("Exited game mode",          "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_PxMeshShapedForce():
-    """
-    Summary:
-    Runs an automated test to ensure that PhysX force regions with physics assets exert point force on rigid bodies
-
-    Level Description:
-    A ball is suspended over a force region with a physics asset mesh (sedan). The ball is offset 1 unit towards the
-    hood of the sedan (In the Y direction)
-
-    Ball (entity) - Sphere shaped PhysX Collider; PhysX Rigid body with gravity enabled
-    Sedan (entity) - Sedan shaped PhysX Collider; PhysX Force Region with a point force (magnitude 1000.0)
-
-    Expected Behavior:
-    The ball should fall once game mode is entered and bounce off the force region down and to the right.
-
-    Test Steps:
-    1) Open level
-    2) Enter game mode
-    3) Validate entities
-    4) Wait for ball to fall
-    5) Wait for ball to enter force region
-    6) Wait for ball to exit force region
-    7) Validate velocity vector
-    8) Exit game mode
-    9) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-        Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    import azlmbr
-    import azlmbr.legacy.general as general
-    import azlmbr.bus as bus
-    import azlmbr.math
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    TIMEOUT = 2.0
-
-    class Ball:
-        def __init__(self, name):
-            self.id = general.find_game_entity(name)
-            self.entered_force_region = False
-            self.exited_force_region = False
-
-        def get_velocity(self):
-            return azlmbr.physics.RigidBodyRequestBus(bus.Event, "GetLinearVelocity", self.id)
-
-        def is_falling(self):
-            return self.get_velocity().z < 0.0
-
-    helper.init_idle()
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_PxMeshShapedForce")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Validate entities
-    ball = Ball("Ball")
-    Report.critical_result(Tests.find_ball, ball.id.IsValid())
-
-    sedan_id = general.find_game_entity("Sedan")
-    Report.critical_result(Tests.find_sedan, sedan_id.IsValid())
-
-    # 4) Wait for ball to fall
-    def on_trigger_enter(args):
-        other_id = args[0]
-        if other_id.Equal(ball.id):
-            ball.entered_force_region = True
-
-    def on_trigger_exit(args):
-        other_id = args[0]
-        if other_id.Equal(ball.id):
-            ball.exited_force_region = True
-
-    handler = azlmbr.physics.TriggerNotificationBusHandler()
-    handler.connect(sedan_id)
-    handler.add_callback("OnTriggerEnter", on_trigger_enter)
-    handler.add_callback("OnTriggerExit", on_trigger_exit)
-
-    Report.critical_result(Tests.ball_fell, helper.wait_for_condition(ball.is_falling, TIMEOUT))
-
-    # 5) Wait for ball to enter force region
-    helper.wait_for_condition(lambda: ball.entered_force_region, TIMEOUT)
-    Report.critical_result(Tests.ball_enters_force_region, ball.entered_force_region)
-
-    # 6) Wait for ball to exit force region
-    helper.wait_for_condition(lambda: ball.exited_force_region, TIMEOUT)
-    Report.critical_result(Tests.ball_exits_force_region, ball.exited_force_region)
-
-    # 7) Validate velocity vector
-    velocity = ball.get_velocity()
-    Report.result(Tests.ball_moved_up, velocity.z > 0.0)
-    Report.result(Tests.ball_moved_forward, velocity.y > 0.0)
-
-    # 8) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_PxMeshShapedForce)

+ 0 - 404
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_RotationalOffset.py

@@ -1,404 +0,0 @@
-"""
-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 ID : C5959809
-# Test Case Title : Verify Force Region Rotational Offset
-
-
-
-# fmt:off
-class Tests:
-    # General tests
-    enter_game_mode = ("Entered game mode",               "Failed to enter game mode")
-    exit_game_mode  = ("Exited game mode",                "Couldn't exit game mode")
-    test_completed  = ("The test successfully completed", "The test timed out")
-    # ***** Entities found *****
-    # Force Regions
-    force_region_x_found          = ("Force Region for X axis test was found",          "Force Region for X axis test was NOT found")
-    force_region_y_found          = ("Force Region for Y axis test was found",          "Force Region for Y axis test was NOT found")
-    force_region_z_found          = ("Force Region for Z axis test was found",          "Force Region for Z axis test was NOT found")
-    # Force Region Pass Boxes
-    force_region_pass_box_x_found = ("Force Region Pass Box for X axis test was found", "Force Region Pass Box for X axis test was NOT found")
-    force_region_pass_box_y_found = ("Force Region Pass Box for Y axis test was found", "Force Region Pass Box for Y axis test was NOT found")
-    force_region_pass_box_z_found = ("Force Region Pass Box for Z axis test was found", "Force Region Pass Box for Z axis test was NOT found")
-    # External Pass Boxes
-    external_pass_box_x_found     = ("External Pass Box for X axis test was found",     "External Pass Box for X axis test was NOT found")
-    external_pass_box_y_found     = ("External Pass Box for Y axis test was found",     "External Pass Box for Y axis test was NOT found")
-    external_pass_box_z_found     = ("External Pass Box for Z axis test was found",     "External Pass Box for Z axis test was NOT found")
-    # Force Region Fail Boxes
-    force_region_fail_box_x_found = ("Force Region Fail Box for X axis test was found", "Force Region Fail Box for X axis test was NOT found")
-    force_region_fail_box_y_found = ("Force Region Fail Box for Y axis test was found", "Force Region Fail Box for Y axis test was NOT found")
-    force_region_fail_box_z_found = ("Force Region Fail Box for Z axis test was found", "Force Region Fail Box for Z axis test was NOT found")
-    # External Fail Boxes
-    external_fail_box_x_found     = ("External Fail Box for X axis test was found",     "External Fail Box for X axis test was NOT found")
-    external_fail_box_y_found     = ("External Fail Box for Y axis test was found",     "External Fail Box for Y axis test was NOT found")
-    external_fail_box_z_found     = ("External Fail Box for Z axis test was found",     "External Fail Box for Z axis test was NOT found")
-    # Pass spheres
-    sphere_pass_x_found           = ("Pass Sphere for X axis test was found",           "Pass Sphere for X axis test was NOT found")
-    sphere_pass_y_found           = ("Pass Sphere for Y axis test was found",           "Pass Sphere for Y axis test was NOT found")
-    sphere_pass_z_found           = ("Pass Sphere for Z axis test was found",           "Pass Sphere for Z axis test was NOT found")
-    # Bounce Spheres
-    sphere_bounce_x_found         = ("Bounce Sphere for X axis test was found",         "Bounce Sphere for X axis test was NOT found")
-    sphere_bounce_y_found         = ("Bounce Sphere for Y axis test was found",         "Bounce Sphere for Y axis test was NOT found")
-    sphere_bounce_z_found         = ("Bounce Sphere for Z axis test was found",         "Bounce Sphere for Z axis test was NOT found")
-
-    # ****** Entities' results ******
-    # Force Regions
-    force_region_x_mag_result      = ("Force Region for X axis magnitude exerted was as expected",         "Force Region for X axis magnitude exerted was NOT as expected")
-    force_region_y_mag_result      = ("Force Region for Y axis magnitude exerted was as expected",         "Force Region for Y axis magnitude exerted was NOT as expected")
-    force_region_z_mag_result      = ("Force Region for Z axis magnitude exerted was as expected",         "Force Region for Z axis magnitude exerted was NOT as expected")
-    force_region_x_norm_result     = ("Force Region for X axis normal exerted was as expected",            "Force Region for X axis normal exerted was NOT as expected")
-    force_region_y_norm_result     = ("Force Region for Y axis normal exerted was as expected",            "Force Region for Y axis normal exerted was NOT as expected")
-    force_region_z_norm_result     = ("Force Region for Z axis normal exerted was as expected",            "Force Region for Z axis normal exerted was NOT as expected")
-    # Force Region Pass Boxes
-    force_region_pass_box_x_result = ("Force Region Pass Box for X axis collided with exactly one sphere", "Force Region Pass Box for X axis DID NOT collide with exactly one sphere")
-    force_region_pass_box_y_result = ("Force Region Pass Box for Y axis collided with exactly one sphere", "Force Region Pass Box for Y axis DID NOT collide with exactly one sphere")
-    force_region_pass_box_z_result = ("Force Region Pass Box for Z axis collided with exactly one sphere", "Force Region Pass Box for Z axis DID NOT collide with exactly one sphere")
-    # External Pass Boxes
-    external_pass_box_x_result     = ("External Pass Box for X axis collided with exactly one sphere",     "External Pass Box for X axis DID NOT collide with exactly one sphere")
-    external_pass_box_y_result     = ("External Pass Box for Y axis collided with exactly one sphere",     "External Pass Box for Y axis DID NOT collide with exactly one sphere")
-    external_pass_box_z_result     = ("External Pass Box for Z axis collided with exactly one sphere",     "External Pass Box for Z axis DID NOT collide with exactly one sphere")
-    # Force Region Fail Boxes
-    force_region_fail_box_x_result = ("Force Region Fail Box for X axis collided with no spheres",         "Force Region Fail Box for X axis DID collide with a sphere")
-    force_region_fail_box_y_result = ("Force Region Fail Box for Y axis collided with no spheres",         "Force Region Fail Box for Y axis DID collide with a sphere")
-    force_region_fail_box_z_result = ("Force Region Fail Box for Z axis collided with no spheres",         "Force Region Fail Box for Z axis DID collide with a sphere")
-    # External Fail Boxes
-    external_fail_box_x_result     = ("External Fail Box for X axis collided with no spheres",             "External Fail Box for X axis DID collide with a sphere")
-    external_fail_box_y_result     = ("External Fail Box for Y axis collided with no spheres",             "External Fail Box for Y axis DID collide with a sphere")
-    external_fail_box_z_result     = ("External Fail Box for Z axis collided with no spheres",             "External Fail Box for Z axis DID collide with a sphere")
-    # Pass spheres
-    sphere_pass_x_result           = ("Pass Sphere for X axis collided with expected Box",                 "Pass Sphere for X axis DID NOT collide with expected Box")
-    sphere_pass_y_result           = ("Pass Sphere for Y axis collided with expected Box",                 "Pass Sphere for Y axis DID NOT collide with expected Box")
-    sphere_pass_z_result           = ("Pass Sphere for Z axis collided with expected Box",                 "Pass Sphere for Z axis DID NOT collide with expected Box")
-    # Bounce Spheres
-    sphere_bounce_x_result         = ("Bounce Sphere for X axis collided with expected Box",               "Bounce Sphere for X axis DID NOT collide with expected Box")
-    sphere_bounce_y_result         = ("Bounce Sphere for Y axis collided with expected Box",               "Bounce Sphere for Y axis DID NOT collide with expected Box")
-    sphere_bounce_z_result         = ("Bounce Sphere for Z axis collided with expected Box",               "Bounce Sphere for Z axis DID NOT collide with expected Box")
-# fmt:on
-
-    @staticmethod
-    # Test tuple accessor via string
-    def get_test(test_name):
-        if test_name in Tests.__dict__:
-            return Tests.__dict__[test_name]
-        else:
-            return None
-
-
-def ForceRegion_RotationalOffset():
-    """
-    Summary:
-    Force Region rotational offset is tested for each of the 3 axises (X, Y, and Z). Each axis's test has one
-    ForceRegion, two spheres and four boxes. By monitoring which box each sphere collides with we can validate the
-    integrity of the ForceRegions rotational offset.
-
-    Level Description:
-    Each axis's test has the following entities:
-    one force region - set for point force and with it's collider rotationally offset (on the axis in test).
-    two spheres - one positioned near the transform of the force region, one positioned near the [offset] collider for
-        the force region
-    four boxes - One box is positioned inside the force region's transform, one inside the force region's [offset]
-        collider. The other two boxes are positioned behind the two spheres (relative to the direction they will be
-        initially traveling)
-
-    Expected Behavior:
-    All three axises' tests run in parallel. when the tests begin, the spheres should move toward their expected
-    force regions. The spheres positioned to collide with their region's [offset] collider should be forced backwards
-    before entering the force region and collide with the box behind it. The spheres positioned by their force region's
-    transforms should pass straight into the transform and collide with the box inside the transform.
-    The boxes inside the Force Regions' [offset] colliders and the boxes behind the spheres set to move into the Force
-    Regions' transforms should not register any collisions.
-
-    Steps:
-    1) Open level and enter game mode
-    2) Set up tests and variables
-    3) Wait for test results (or time out)
-        (Report results)
-    4) Exit game mode and close the editor
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.math as azmath
-    import azlmbr.bus
-    import azlmbr
-
-    # Constants
-    CLOSE_ENOUGH = 0.01  # Close enough threshold for comparing floats
-    TIME_OUT = 2.0  # Time out (in seconds) until test is aborted
-    FORCE_MAGNITUDE = 1000.0  # Point force magnitude for Force Regions
-    SPEED = 3.0  # Initial speed (in m/s) of the moving spheres.
-
-    # Full list for all spheres. Used for EntityId look up in event handlers
-    all_spheres = []
-
-    # Entity base class handles very general entity initialization
-    # Should be treated as a "virtual" class and all implementing child
-    # classes should implement a "self.result()" function referenced in EntityBase::report(self)
-    class EntityBase:
-        def __init__(self, name):
-            # type: (str) -> None
-            self.name = name
-            self.print_list = []
-            self.id = general.find_game_entity(name)
-            found_test = Tests.get_test(name + "_found")
-            Report.critical_result(found_test, self.id.IsValid())
-
-        # Reports this entity's result. Implicitly calls "get" on result.
-        # Subclasses implement their own definition of a successful result
-        def report(self):
-            # type: () -> None
-            result_test = Tests.get_test(self.name + "_result")
-            Report.result(result_test, self.result())
-
-        # Prints the print queue (with decorated header) if not empty
-        def print_log(self):
-            # type: () -> None
-            if self.print_list:
-                Report.info("*********** {} **********".format(self))
-                for line in self.print_list:
-                    Report.info(line)
-                Report.info("")
-
-        # Quick string cast, returns entity name
-        def __str__(self):
-            # type: () -> str
-            return self.name
-
-    # ForceRegion handles all the data and behavior associated with a ForceRegion (for this test)
-    # They simply wait for a Sphere to collide with them. On collision they store the calculated force
-    # magnitude for verification.
-    class ForceRegion(EntityBase):
-        def __init__(self, name, magnitude):
-            # type: (str, float) -> None
-            EntityBase.__init__(self, name)
-            self.expected_magnitude = magnitude
-            self.actual_magnitude = None
-            self.expected_normal = None
-            self.actual_normal = None
-            # Set point force Magnitude
-            azlmbr.physics.ForcePointRequestBus(azlmbr.bus.Event, "SetMagnitude", self.id, magnitude)
-            # Set up handler
-            self.handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-            self.handler.connect(None)
-            self.handler.add_callback("OnCalculateNetForce", self.on_calc_force)
-
-        # Callback function for OnCalculateNetForce event
-        def on_calc_force(self, args):
-            # type: ([EntityId, EntityId, azmath.Vector3, float]) -> None
-            if self.id.Equal(args[0]) and self.actual_magnitude is None:
-                for sphere in all_spheres:
-                    if sphere.id.Equal(args[1]):
-                        # Log event in print queue (for me and for the sphere)
-                        self.print_list.append("Exerting force on {}:".format(sphere))
-                        sphere.print_list.append("Force exerted by {}".format(self))
-                        # Save calculated data to be compared later
-                        self.actual_normal = args[2]
-                        self.actual_magnitude = args[3]
-                        pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-                        sphere_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", sphere.id)
-                        self.expected_normal = sphere_pos.Subtract(pos).GetNormalizedSafe()
-                        # Add expected/actual to print queue
-                        self.print_list.append("Force Vector: ")
-                        self.print_list.append(
-                            "  Expected: ({:.2f}, {:.2f}, {:.2f})".format(
-                                self.expected_normal.x, self.expected_normal.y, self.expected_normal.z
-                            )
-                        )
-                        self.print_list.append(
-                            "  Actual: ({:.2f}, {:.2f}, {:.2f})".format(
-                                self.actual_normal.x, self.actual_normal.y, self.actual_normal.z
-                            )
-                        )
-                        self.print_list.append("Force Magnitude: ")
-                        self.print_list.append("  Expected: {}".format(self.expected_magnitude))
-                        self.print_list.append("  Actual: {:.2f}".format(self.actual_magnitude))
-
-        # EntityBase::report() overload.
-        # Force regions have 2 test tuples to report on
-        def report(self):
-            magnitude_test = Tests.get_test(self.name + "_mag_result")
-            normal_test = Tests.get_test(self.name + "_norm_result")
-            Report.result(magnitude_test, self.magnitude_result())
-            Report.result(normal_test, self.normal_result())
-
-        # Test result calculations
-        # Used in EntityBase for reporting results
-        def result(self):
-            # type: () -> bool
-            return self.magnitude_result() and self.normal_result()
-
-        def magnitude_result(self):
-            # type: () -> bool
-            return (
-                    self.actual_magnitude is not None
-                    and abs(self.actual_magnitude - self.expected_magnitude) < CLOSE_ENOUGH
-            )
-
-        def normal_result(self):
-            # type: () -> bool
-            return (
-                    self.actual_normal is not None
-                    and self.expected_normal is not None
-                    and self.expected_normal.IsClose(self.actual_normal, CLOSE_ENOUGH)
-            )
-
-    # Spheres are the objects that test the force regions. They store an expected collision entity and an
-    # actual collision entity
-    class Sphere(EntityBase):
-        def __init__(self, name, initial_velocity, expected_collision):
-            # type: (str, azmath.Vector3, EntityBase) -> None
-            EntityBase.__init__(self, name)
-            self.initial_velocity = initial_velocity
-            azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetLinearVelocity", self.id, initial_velocity)
-            self.print_list.append(
-                "Initial velocity: ({:.2f}, {:.2f}, {:.2f})".format(
-                    initial_velocity.x, initial_velocity.y, initial_velocity.z
-                )
-            )
-            self.expected_collision = expected_collision
-            self.print_list.append("Expected Collision: {}".format(expected_collision))
-            self.actual_collision = None
-            self.active = True
-            self.force_normal = None
-
-        # Registers a collision with this sphere. Saves a reference to the colliding entity for processing later.
-        # Deactivate self after collision is registered.
-        def collide(self, collision_entity):
-            # type: (EntityBase) -> None
-            # Log the event
-            self.print_list.append("Collided with {}".format(collision_entity))
-            self.actual_collision = collision_entity
-            # Deactivate self
-            azlmbr.entity.GameEntityContextRequestBus(azlmbr.bus.Broadcast, "DeactivateGameEntity",
-                                                      self.id)
-            self.active = False
-
-        # Calculates result
-        # Used in EntityBase for reporting results
-        def result(self):
-            if self.actual_collision is None:
-                return False
-            else:
-                return self.expected_collision.id.Equal(self.actual_collision.id)
-
-    # Box entities wait for a collision with a sphere as a means of validation the force region's offset
-    # worked according to plan.
-    class Box(EntityBase):
-        def __init__(self, name, expected_sphere_collisions):
-            # type: (str, int) -> None
-            EntityBase.__init__(self, name)
-            self.spheres_collided = 0
-            self.expected_sphere_collisions = expected_sphere_collisions
-            # Set up handler
-            self.handler = azlmbr.physics.CollisionNotificationBusHandler()
-            self.handler.connect(self.id)
-            self.handler.add_callback("OnCollisionBegin", self.on_collision_begin)
-
-        # Callback function for OnCollisionBegin event
-        def on_collision_begin(self, args):
-            for sphere in all_spheres:
-                if sphere.id.Equal(args[0]):
-                    # Log event
-                    self.print_list.append("Collided with {}".format(sphere))
-                    # Register collision with sphere
-                    sphere.collide(self)
-                    self.spheres_collided += 1  # Count collisions for validation later
-                    break
-
-        # Calculates test result
-        # Used in EntityBase for reporting results
-        def result(self):
-            return self.spheres_collided == self.expected_sphere_collisions
-
-    # Manages the entities required to run the test for one axis (X, Y, or Z)
-    class AxisTest:
-        def __init__(self, axis, init_velocity):
-            # type: (str, azmath.Vector3) -> None
-            self.name = axis + " axis test"
-            self.force_region = ForceRegion("force_region_" + axis, FORCE_MAGNITUDE)
-            self.spheres = [
-                Sphere("sphere_pass_" + axis, init_velocity, Box("force_region_pass_box_" + axis, 1)),
-                Sphere("sphere_bounce_" + axis, init_velocity, Box("external_pass_box_" + axis, 1)),
-            ]
-            self.boxes = [
-                 Box("external_fail_box_" + axis, 0),
-                 Box("force_region_fail_box_" + axis, 0)
-            ] + [
-                 sphere.expected_collision for sphere in self.spheres
-                 # Gets the Boxes passed to spheres on init
-            ]
-            # Full list for all entities this test is responsible for
-            self.all_entities = self.boxes + self.spheres + [self.force_region]
-            # Add spheres to global "lookup" list
-            all_spheres.extend(self.spheres)
-
-        # Checks for all entities' test passing conditions
-        def passed(self):
-            return all([e.result() for e in self.all_entities])
-
-        # Returns true when this test has completed (i.e. when the spheres have collided and are deactivated)
-        def completed(self):
-            return all([not sphere.active for sphere in self.spheres])
-
-        # Reports results for all entities in this test
-        def report(self):
-            Report.info("::::::::::::::::::::::::::::: {} Results :::::::::::::::::::::::::::::".format(self.name))
-            for entity in self.all_entities:
-                entity.report()
-
-        # Prints the logs for all entities in this test
-        def print_log(self):
-            Report.info("::::::::::::::::::::::::::::: {} Log :::::::::::::::::::::::::::::".format(self.name))
-            for entity in self.all_entities:
-                entity.print_log()
-
-    # *********** Execution Code ***********
-
-    # 1) Open level
-    helper.init_idle()
-    helper.open_level("Physics", "ForceRegion_RotationalOffset")
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 2) Variable set up
-    # Initial velocities for the three different directions spheres will be moving
-    x_vel = azmath.Vector3(SPEED, 0.0, 0.0)
-    y_vel = azmath.Vector3(0.0, SPEED, 0.0)
-    z_vel = azmath.Vector3(0.0, 0.0, SPEED)
-
-    # The three tests, one for each axis
-    axis_tests = [AxisTest("x", x_vel), AxisTest("y", y_vel), AxisTest("z", z_vel)]
-
-    # 3) Wait for test results or time out
-    Report.result(
-        Tests.test_completed, helper.wait_for_condition(
-            lambda: all([test.completed() for test in axis_tests]), TIME_OUT
-        )
-    )
-
-    # Report results
-    for test in axis_tests:
-        test.report()
-
-    # Print entity print queues for each failed test
-    for test in axis_tests:
-        if not test.passed():
-            test.print_log()
-
-    # 4) Exit game mode and close editor
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_RotationalOffset)

+ 0 - 141
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SimpleDragForceOnRigidBodies.py

@@ -1,141 +0,0 @@
-# coding=utf-8
-"""
-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 ID : C5932043
-# Test Case Title : Check that force region exerts simple drag force on rigid bodies
-
-
-# fmt: off
-class Tests:
-    enter_game_mode        = ("Entered game mode",          "Failed to enter game mode")
-    find_sphere            = ("Sphere found",        "Sphere not found")
-    find_force_region      = ("Force Region found",         "Force Region not found")
-
-    # entity_actions_success refers to if the entity completed all expected actions in the test. For this test, this
-    # will be, did the Sphere enter and exit the force region
-    entity_actions_success = ("Entity actions completed",   "Entity actions not completed")
-    sphere_lost_height     = ("Sphere went down",           "Sphere didn't go down")
-    force_region_slows   = ("Force Region slowed Sphere", "Force Region didn't slow Sphere")
-    exit_game_mode         = ("Exited game mode",           "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_SimpleDragForceOnRigidBodies():
-    # This run() function will open a a level and validate that the force region slows down a spheres fall.
-    # It does this by:
-    #   1) Opens level with sphere above a force region
-    #   2) Enters Game mode
-    #   3) Finds the entities in the scene
-    #   4) Listens for sphere to enter the force region
-    #   5) Gets z velocity and position of sphere
-    #   6) Listens for sphere to exit force region
-    #   7) Gets new velocity and position of sphere
-    #   8) Validate the results
-    #   9) Exits game mode and editor
-
-    # Setup path
-    import os, sys
-
-
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Holds details about the sphere
-    class Sphere:
-        id = None
-        start_velocity_z = 0.0
-        end_velocity_z = 0.0
-        sphere_start_z_position = 0.0
-        sphere_end_z_position = 0.0
-        entered_force_region = False
-        exited_force_region = False
-
-    TIME_OUT = 4.0  # Time given to test to complete.
-
-    helper.init_idle()
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_SimpleDragForceOnRigidBodies")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Get Entities
-    Sphere.id = general.find_game_entity("Sphere")
-    Report.result(Tests.find_sphere, Sphere.id.IsValid())
-
-    force_region_id = general.find_game_entity("Force Region")
-    Report.result(Tests.find_force_region, force_region_id.IsValid())
-
-    # Called if Sphere enters force region
-    def on_trigger_begin(args):
-        other_id = args[0]
-        if other_id.Equal(Sphere.id):
-            Report.info("Entered force region")
-            Sphere.entered_force_region = True
-            #  5) Gets z velocity and position of sphere
-            Sphere.start_velocity_z = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", Sphere.id).z
-            Sphere.sphere_start_z_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Sphere.id)
-            Report.info(
-                "Sphere Start Z position = {}  Z Start Velocity = {}".format(
-                    Sphere.sphere_start_z_position, Sphere.start_velocity_z
-                )
-            )
-
-    # Called when sphere exits force region
-    def on_trigger_end(args):
-        other_id = args[0]
-        if other_id.Equal(Sphere.id):
-            Report.info("Exited force region")
-            Sphere.exited_force_region = True
-            #  7) Gets new velocity and position of sphere
-            Sphere.end_velocity_z = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", Sphere.id).z
-            Sphere.sphere_end_z_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Sphere.id)
-            Report.info(
-                "Sphere End Z position = {}  Sphere End Z Velocity = {}".format(
-                    Sphere.sphere_end_z_position, Sphere.end_velocity_z
-                )
-            )
-
-
-    handler = azlmbr.physics.TriggerNotificationBusHandler()
-    handler.connect(force_region_id)
-    # 4) Listens for sphere to enter the force region
-    handler.add_callback("OnTriggerEnter", on_trigger_begin)
-    # 6) Listens for sphere to exit force region
-    handler.add_callback("OnTriggerExit", on_trigger_end)
-
-    # Wait until all entities in scene are done performing their actions or test times out.
-    def done_with_entity_actions():
-        return Sphere.entered_force_region and Sphere.exited_force_region
-
-    test_completed = helper.wait_for_condition(done_with_entity_actions, TIME_OUT)
-    Report.result(Tests.entity_actions_success, test_completed)
-
-    #   8) Validate the results
-    if test_completed:
-        # Did Sphere fall
-        sphere_descended = Sphere.sphere_end_z_position + 0.5 < Sphere.sphere_start_z_position  # 0.5 for buffer
-        Report.result(Tests.sphere_lost_height, sphere_descended)
-
-        # Did Force Region slow down sphere's falling
-        # Note: The faster a sphere falls, the greater its negative/downward velocity will be. Adding 1.0 for buffer.
-        force_region_result = round(Sphere.end_velocity_z, 2) > round(Sphere.start_velocity_z, 2) + 1.0
-        Report.result(Tests.force_region_slows, force_region_result)
-
-    #  9) Exits game mode and editor
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_SimpleDragForceOnRigidBodies)

+ 0 - 142
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SmallMagnitudeDeviationOnLargeForces.py

@@ -1,142 +0,0 @@
-"""
-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 ID : C12905527
-# Test Case Title : Check that deviation occurring in Force Magnitude due to Values in Force direction is not large
-
-
-# fmt: off
-class Tests():
-    enter_game_mode       = ("Entered game mode",                                       "Failed to enter game mode")
-    find_force_region     = ("Force region was found",                                  "Force region was not found")
-    find_sphere           = ("Sphere was found",                                        "Sphere was not found")
-    sphere_entered_region = ("Sphere entered force region",                             "Sphere did not enter force region")
-    sphere_exited_region  = ("Sphere exited force region",                              "Sphere did not exit force region")
-    force_magnitude_close = ("The net force magnitude was close to the expected value", "The net force magnitude was not close to the expected value")
-    exit_game_mode        = ("Exited game mode",                                        "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_SmallMagnitudeDeviationOnLargeForces():
-    """
-    Summary:
-    Runs an automated test to ensure that the calculated net force magnitude is close to the configured value
-
-    Level Description:
-    A sphere (Sphere) is positioned above a force region (ForceRegion)
-        Sphere has a sphere PhysX collider and PhysX Rigid Body. Gravity is disabled, and it has an initial velocity of
-        2 m/s in the Z direction.
-
-        ForceRegion has a box PhysX collider and PhysX Force Region. Magnitude on the force region is set to 1,000,000.0
-
-    Expected Behavior:
-    The sphere enters and exits the force region. on_calc_net_force returns a value close to 1,000,000.0
-
-    Test Steps:
-    1) Open level
-    2) Enter game mode
-    3) Validate entities
-    4) Wait for the sphere to enter and exit the force region
-    5) Check the calculated net force against what we expect
-    6) Exit game mode
-    7) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr
-    import azlmbr.legacy.general as general
-
-    EXPECTED_MAGNITUDE = 1000000.0
-    PERMISSIBLE_ERROR = 0.001  # +/- 0.1%
-    TIMEOUT = 1.0
-
-    class Sphere:
-        def __init__(self, name):
-            self.name = name
-            self.id = general.find_game_entity(name)
-            self.entered_force_region = False
-            self.exited_force_region = False
-            self.net_force_magnitude = 0
-
-    def on_trigger_enter(args):
-        Report.info("triggered")
-        other_id = args[0]
-        if other_id.Equal(sphere.id):
-            sphere.entered_force_region = True
-
-    def on_trigger_exit(args):
-        other_id = args[0]
-        if other_id.Equal(sphere.id):
-            sphere.exited_force_region = True
-
-    def on_calc_net_force(args):
-        other_id = args[1]
-        force_magnitude = args[3]
-
-        if other_id.Equal(sphere.id):
-            sphere.net_force_magnitude = force_magnitude
-
-    helper.init_idle()
-    # 1) Open level
-    Report.info(general.get_current_level_name())
-    helper.open_level("Physics", "ForceRegion_SmallMagnitudeDeviationOnLargeForces")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Validate entities
-    sphere = Sphere("Sphere")
-    force_region_id = general.find_game_entity("ForceRegion")
-
-    Report.critical_result(Tests.find_sphere, sphere.id.IsValid())
-    Report.critical_result(Tests.find_force_region, force_region_id.IsValid())
-
-    # Create handlers
-    trigger_handler = azlmbr.physics.TriggerNotificationBusHandler()
-    trigger_handler.connect(force_region_id)
-    trigger_handler.add_callback("OnTriggerEnter", on_trigger_enter)
-    trigger_handler.add_callback("OnTriggerExit", on_trigger_exit)
-
-    net_force_handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    net_force_handler.connect(None)
-    net_force_handler.add_callback("OnCalculateNetForce", on_calc_net_force)
-
-    # 4) Wait for the sphere to enter and exit the force region
-    Report.result(Tests.sphere_entered_region, helper.wait_for_condition(lambda: sphere.entered_force_region, TIMEOUT))
-    Report.result(Tests.sphere_exited_region, helper.wait_for_condition(lambda: sphere.exited_force_region, TIMEOUT))
-
-    # 5) Check the calculated net force against what we expect
-    absolute_difference = abs(sphere.net_force_magnitude - EXPECTED_MAGNITUDE)
-    error = absolute_difference / EXPECTED_MAGNITUDE
-    net_force_was_close = error < PERMISSIBLE_ERROR
-
-    Report.result(Tests.force_magnitude_close, net_force_was_close)
-    if not net_force_was_close:
-        Report.info(
-            "\nExpected Magnitude: {}"
-            "\nActual Magnitude: {}"
-            "\nPermissible Error: {}"
-            "\nMeasured Error: {}".format(EXPECTED_MAGNITUDE, sphere.net_force_magnitude, PERMISSIBLE_ERROR, error)
-        )
-
-    # 6) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_SmallMagnitudeDeviationOnLargeForces)

+ 0 - 149
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SphereShapedForce.py

@@ -1,149 +0,0 @@
-"""
-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 ID : C5959759
-# Test Case Title : Check that force region (sphere) exerts point force
-
-
-
-# fmt: off
-class Tests:
-    enter_game_mode             = ("Entered game mode",                                  "Failed to enter game mode")
-    find_cube                   = ("Entity Cube found",                                  "Cube not found")
-    find_force_region           = ("Entity force region found",                          "Force region not found")
-    gravity_works               = ("Cube falls",                                         "Cube did not fall")
-    sphere_gravity_enabled      = ("Gravity is enabled on the cube",                     "Gravity is not enabled on the cube")
-    force_region_trigger        = ("Cube entered and exited force region",               "Cube did not enter adn exit force region")
-    force_calculated            = ("OnCalculateNetForce calculated",                     "OnCalculateNetForce did not get calculated")
-    force_x_vector              = ("Force x vector is positive",                         "Force x vector is not positive")
-    force_y_vector              = ("Force y vector is positive",                         "Force y vector is not positive")
-    point_force_magnitude_value = ("Magnitude is set to 1000",                           "Magnitude is not set to 1000")
-    point_force_magnitude       = ("Calculated magnitude is greater than set magnitude", "Calculated magnitude is not greater than set magnitude")
-    exit_game_mode              = ("Exited game mode",                                   "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_SphereShapedForce():
-    """
-    Level Setup
-    The level consists of a sherical force region with a point force of 1000.
-    A RigidBody cube with mass 1kg is positioned above the force region at an offset.
-    On entering game mode the cube will fall into the spherical point force region.
-    This should cause the cube to bounce off at considerable velocity.
-    We validate the point force observed is as expected
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    EXPECTED_MAGNITUDE = 1000.0
-    NEGATIVE_VELOCITY = -0.001
-    TOLERANCE = 0.001
-
-    # 1) Open level and enter game mode
-    helper.init_idle()
-    helper.open_level("Physics", "ForceRegion_SphereShapedForce")
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 2) Retrieve entities
-    cube_id = general.find_game_entity("CubeRigidBody")
-    Report.critical_result(Tests.find_cube, cube_id.IsValid())
-
-    sphere_force_region = general.find_game_entity("SphereForceRegion")
-    Report.critical_result(Tests.find_force_region, sphere_force_region.IsValid())
-
-    # 3) Gravity works
-    gravity_enabled = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", cube_id)
-    Report.result(Tests.sphere_gravity_enabled, gravity_enabled)
-    
-    def is_going_down():
-        vel = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", cube_id)
-        return vel.z < NEGATIVE_VELOCITY
-        
-    helper.wait_for_condition(is_going_down, 1.0)
-    cube_linear_velocity = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", cube_id)
-    Report.info("Cube z velocity from gravity: {}".format(cube_linear_velocity.z))
-    Report.result(Tests.gravity_works, cube_linear_velocity.z < NEGATIVE_VELOCITY)
-
-    # 4) Listen to trigger events and OnCalculateNetForce notification
-    class SphereForceRegion:
-        enter = False
-        exit = False
-
-    def on_enter(args):
-        other_id = args[0]
-        if other_id.Equal(cube_id):
-            Report.info("Cube touched spherical force region")
-            SphereForceRegion.enter = True
-
-    def on_exit(args):
-        other_id = args[0]
-        if other_id.Equal(cube_id):
-            Report.info("Cube touched spherical force region")
-            SphereForceRegion.exit = True
-
-    handler = azlmbr.physics.TriggerNotificationBusHandler()
-    handler.connect(sphere_force_region)
-    handler.add_callback("OnTriggerEnter", on_enter)
-    handler.add_callback("OnTriggerExit", on_exit)
-
-    class NetForce:
-        vector = None
-        magnitude = 0
-
-    def on_calc_net_force(args):
-        """
-        args[0] - force region entity
-        args[1] - entity entering
-        args[2] - vector
-        args[3] - magnitude
-        """
-        entering_entity = args[1]
-        if entering_entity.Equal(cube_id):
-            vector = args[2]
-            magnitude = args[3]
-            Report.info_vector3(vector, "Net Force vector", magnitude)
-            NetForce.vector = vector
-            NetForce.magnitude = magnitude
-
-    force_notification_handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    force_notification_handler.connect(None)
-    force_notification_handler.add_callback("OnCalculateNetForce", on_calc_net_force)
-
-    def force_region_enter_and_exit():
-        return SphereForceRegion.enter and SphereForceRegion.exit
-
-    helper.wait_for_condition(force_region_enter_and_exit, 3.0)
-
-    # 5) Report results
-    Report.result(Tests.force_region_trigger, force_region_enter_and_exit())
-    force_region_magnitude = azlmbr.physics.ForcePointRequestBus(azlmbr.bus.Event, "GetMagnitude", sphere_force_region)
-    Report.info("Force region magnitude = {}".format(force_region_magnitude))
-    # explicit check that the value is as expected
-    # set at level creation
-    Report.result(Tests.point_force_magnitude_value, force_region_magnitude == EXPECTED_MAGNITUDE)
-    # prevent the test from hanging if the force vector is not set
-    if NetForce.vector:
-        Report.success(Tests.force_calculated)
-        Report.result(Tests.force_x_vector, NetForce.vector.x > 0)
-        Report.result(Tests.force_y_vector, NetForce.vector.z > 0)
-    else:
-        Report.failure(Tests.force_calculated)
-    outcome = abs(NetForce.magnitude - force_region_magnitude) < TOLERANCE
-    Report.result(Tests.point_force_magnitude, outcome)
-
-    # 6) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_SphereShapedForce)

+ 0 - 161
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SplineForceOnRigidBodies.py

@@ -1,161 +0,0 @@
-"""
-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 ID : C5932045
-# Test Case Title : Check that force region exerts spline follow force on rigid bodies
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode             = ("Entered game mode",                   "Failed to enter game mode")
-    find_sphere                 = ("Sphere entity found",                 "Sphere entity not found")
-    find_force_region           = ("Force region found",                  "Force region not found")
-    find_trigger_0              = ("Trigger0 entity found",               "Trigger0 entity not found")
-    find_trigger_1              = ("Trigger1 entity found",               "Trigger1 entity not found")
-    find_trigger_2              = ("Trigger2 entity found",               "Trigger2 entity not found")
-    find_trigger_3              = ("Trigger3 entity found",               "Trigger3 entity not found")
-    triggers_positioned_apart   = ("All triggers were positioned apart",  "All triggers were not positioned apart")
-    sphere_fell                 = ("The sphere fell",                     "The sphere did not fall")
-    sphere_entered_force_region = ("The sphere entered the force region", "The sphere did not enter the force region before timeout")
-    sphere_reached_trigger0     = ("The sphere reached Trigger0",         "The sphere did not reach Trigger0 before timeout")
-    sphere_reached_trigger1     = ("The sphere reached Trigger1",         "The sphere did not reach Trigger1 before timeout")
-    sphere_reached_trigger2     = ("The sphere reached Trigger2",         "The sphere did not reach Trigger2 before timeout")
-    sphere_reached_trigger3     = ("The sphere reached Trigger3",         "The sphere did not reach Trigger3 before timeout")
-    exit_game_mode              = ("Exited game mode",                    "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_SplineForceOnRigidBodies():
-    """
-    Summary:
-    Runs an automated test to ensure that a PhysX force region exerts spline follow force on rigid bodies
-
-    Level Description:
-    A sphere entity is positioned above a force region entity
-    The sphere has a PhysX collider (sphere) and rigidbody component with default values
-
-    The force region entity has a PhysX collider (Box) and force region with a 'spline follow' force.
-    It also has a spline component with 4 nodes. Each node is connected linearly in the following pattern:
-        [0]___
-          ___[1]
-        [2]___
-             [3]
-
-    There are 4 trigger entities, each with a PhysX collider (sphere). They are positioned at each node.
-
-    Expected Behavior:
-    The sphere will fall into the force region and begin to follow the spline. It will visit each node in order.
-
-    Test Steps:
-    1) Open level
-    2) Enter game mode
-    3) Find entities
-    4) Verify triggers are apart
-    5) Drop the sphere
-    6) Wait for sphere to complete path
-    7) Exit game mode
-    8) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import itertools
-    import azlmbr
-    import azlmbr.legacy.general as general
-    import azlmbr.bus as bus
-
-    TIMEOUT = 5
-    MIN_TRIGGER_DISTANCE = 2
-
-    class Sphere:
-        def __init__(self, name):
-            self.name = name
-            self.id = general.find_game_entity(name)
-
-        def get_velocity(self):
-            return azlmbr.physics.RigidBodyRequestBus(bus.Event, "GetLinearVelocity", self.id)
-
-        def is_falling(self):
-            return self.get_velocity().z < 0.0
-
-    class Trigger:
-        def __init__(self, name, valid_test, triggered_test):
-            self.name = name
-            self.id = general.find_game_entity(name)
-            self.valid_test = valid_test
-            self.triggered_test = triggered_test
-            self.triggered = False
-            self.create_handler()
-
-        def get_position(self):
-            return azlmbr.components.TransformBus(bus.Event, "GetWorldTranslation", self.id)
-
-        def on_trigger_enter(self, args):
-            self.triggered = True
-
-        def create_handler(self):
-            self.handler = azlmbr.physics.TriggerNotificationBusHandler()
-            self.handler.connect(self.id)
-            self.handler.add_callback("OnTriggerEnter", self.on_trigger_enter)
-
-    def are_apart(position1, position2, distance):
-        return position1.GetDistance(position2) >= distance
-
-    helper.init_idle()
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_SplineForceOnRigidBodies")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Find entities
-    sphere = Sphere("Sphere")
-    Report.critical_result(Tests.find_sphere, sphere.id.IsValid())
-
-    force_region = Trigger("ForceRegion", Tests.find_force_region, Tests.sphere_entered_force_region)
-    trigger0 = Trigger("Trigger0", Tests.find_trigger_0, Tests.sphere_reached_trigger0)
-    trigger1 = Trigger("Trigger1", Tests.find_trigger_1, Tests.sphere_reached_trigger1)
-    trigger2 = Trigger("Trigger2", Tests.find_trigger_2, Tests.sphere_reached_trigger2)
-    trigger3 = Trigger("Trigger3", Tests.find_trigger_3, Tests.sphere_reached_trigger3)
-    all_triggers = (force_region, trigger0, trigger1, trigger2, trigger3)
-
-    for trigger in all_triggers:
-        Report.critical_result(trigger.valid_test, trigger.id.IsValid())
-
-    # 4) Verify triggers are apart
-    all_triggers_apart = True
-    for combination in itertools.combinations(all_triggers, 2):
-        if not are_apart(combination[0].get_position(), combination[1].get_position(), MIN_TRIGGER_DISTANCE):
-            all_triggers_apart = False
-
-    Report.critical_result(Tests.triggers_positioned_apart, all_triggers_apart)
-
-    # 5) Drop the sphere
-    Report.result(Tests.sphere_fell, helper.wait_for_condition(sphere.is_falling, TIMEOUT))
-
-    # 6) Wait for sphere to complete path
-    for trigger in all_triggers:
-        Report.result(trigger.triggered_test, helper.wait_for_condition(lambda: trigger.triggered, TIMEOUT))
-
-    # 7) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_SplineForceOnRigidBodies)

+ 0 - 166
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_SplineRegionWithModifiedTransform.py

@@ -1,166 +0,0 @@
-"""
-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 ID : C12868580
-# Test Case Title : Check that spline follow force works if transform components of entity are altered
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode             = ("Entered game mode",                   "Failed to enter game mode")
-    find_sphere                 = ("Sphere entity found",                 "Sphere entity not found")
-    find_force_region           = ("Force region found",                  "Force region not found")
-    find_trigger_0              = ("Trigger0 entity found",               "Trigger0 entity not found")
-    find_trigger_1              = ("Trigger1 entity found",               "Trigger1 entity not found")
-    find_trigger_2              = ("Trigger2 entity found",               "Trigger2 entity not found")
-    find_trigger_3              = ("Trigger3 entity found",               "Trigger3 entity not found")
-    triggers_positioned_apart   = ("All triggers were positioned apart",  "All triggers were not positioned apart")
-    sphere_entered_force_region = ("The sphere entered the force region", "The sphere did not enter the force region before timeout")
-    sphere_reached_trigger0     = ("The sphere reached Trigger0",         "The sphere did not reach Trigger0 before timeout")
-    sphere_reached_trigger1     = ("The sphere reached Trigger1",         "The sphere did not reach Trigger1 before timeout")
-    sphere_reached_trigger2     = ("The sphere reached Trigger2",         "The sphere did not reach Trigger2 before timeout")
-    sphere_reached_trigger3     = ("The sphere reached Trigger3",         "The sphere did not reach Trigger3 before timeout")
-    exit_game_mode              = ("Exited game mode",                    "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_SplineRegionWithModifiedTransform():
-    """
-    Summary:
-    Runs an automated test to ensure that a PhysX force region correctly exerts spline follow force on rigid bodies when
-    its transform component has been modified
-
-    Level Description:
-    A sphere entity is positioned outside (in the +x direction) a force region entity.
-    The sphere has a PhysX collider (sphere) and rigidbody component with gravity disabled, and an initial velocity of
-    -3 m/s (in the x direction)
-
-    The force region entity has a PhysX collider (Box) and force region with a 'spline follow' force.
-    It also has a bezier spline component with 4 nodes. Each node is connected in a meandering path through the region.
-
-             [3]~~~[2]
-                    )
-        O -> [0]~~~[1]
-    (sphere)
-
-    The force region is transformed 45 degrees around the Z axis, and scaled by 2 units in the X, Y, and Z directions.
-
-    There are also 4 trigger entities, each with a PhysX collider (sphere). They are positioned at each node.
-
-    Expected Behavior:
-    The sphere will enter into the force region and begin to follow the spline. It will visit each node in order.
-
-    Test Steps:
-    1) Open level
-    2) Enter game mode
-    3) Find entities
-    4) Verify triggers are apart
-    5) Wait for sphere to complete path
-    6) Exit game mode
-    7) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import itertools
-    import azlmbr
-    import azlmbr.legacy.general as general
-    import azlmbr.bus as bus
-
-    # region Constants
-    TIMEOUT = 10.0
-    MIN_TRIGGER_DISTANCE = 2.0
-    # endregion
-
-    # region Entity Classes
-    class Sphere:
-        def __init__(self, name):
-            self.name = name
-            self.id = general.find_game_entity(name)
-
-        def get_velocity(self):
-            return azlmbr.physics.RigidBodyRequestBus(bus.Event, "GetLinearVelocity", self.id)
-
-    class Trigger:
-        def __init__(self, name, valid_test, triggered_test):
-            self.name = name
-            self.id = general.find_game_entity(name)
-            self.valid_test = valid_test
-            self.triggered_test = triggered_test
-            self.triggered = False
-            self.create_handler()
-
-        def get_position(self):
-            return azlmbr.components.TransformBus(bus.Event, "GetWorldTranslation", self.id)
-
-        def on_trigger_enter(self, args):
-            self.triggered = True
-
-        def create_handler(self):
-            self.handler = azlmbr.physics.TriggerNotificationBusHandler()
-            self.handler.connect(self.id)
-            self.handler.add_callback("OnTriggerEnter", self.on_trigger_enter)
-
-    # endregion
-
-    # region Helper Functions
-    def are_apart(position1, position2, distance):
-        return position1.GetDistance(position2) >= distance
-
-    # endregion
-
-    helper.init_idle()
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_SplineRegionWithModifiedTransform")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Find Entities
-    sphere = Sphere("Sphere")
-    Report.critical_result(Tests.find_sphere, sphere.id.IsValid())
-
-    force_region = Trigger("ForceRegion", Tests.find_force_region, Tests.sphere_entered_force_region)
-    trigger0 = Trigger("Trigger0", Tests.find_trigger_0, Tests.sphere_reached_trigger0)
-    trigger1 = Trigger("Trigger1", Tests.find_trigger_1, Tests.sphere_reached_trigger1)
-    trigger2 = Trigger("Trigger2", Tests.find_trigger_2, Tests.sphere_reached_trigger2)
-    trigger3 = Trigger("Trigger3", Tests.find_trigger_3, Tests.sphere_reached_trigger3)
-    all_triggers = (force_region, trigger0, trigger1, trigger2, trigger3)
-
-    for trigger in all_triggers:
-        Report.critical_result(trigger.valid_test, trigger.id.IsValid())
-
-    # 4) Verify triggers are apart
-    all_triggers_apart = True
-    for trigger_a, trigger_b in itertools.combinations(all_triggers, 2):
-        if not are_apart(trigger_a.get_position(), trigger_b.get_position(), MIN_TRIGGER_DISTANCE):
-            Report.info("{} was not far enough away from {}".format(trigger_a.name, trigger_b.name))
-            all_triggers_apart = False
-
-    Report.critical_result(Tests.triggers_positioned_apart, all_triggers_apart)
-
-    # 5) Wait for sphere to complete path
-    for trigger in all_triggers:
-        Report.result(trigger.triggered_test, helper.wait_for_condition(lambda: trigger.triggered, TIMEOUT))
-
-    # 6) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_SplineRegionWithModifiedTransform)

+ 0 - 84
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_WithNonTriggerColliderWarning.py

@@ -1,84 +0,0 @@
-"""
-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 ID : C12905528
-Test Case Title : Check that user is warned if non-trigger collider component is used with force region
-
-"""
-
-
-# fmt: off
-class Tests():
-    create_test_entity     = ("Entity created successfully",        "Failed to create Entity")
-    add_physx_force_region = ("PhysX Force Region component added", "Failed to add PhysX Force Region component")
-    add_physx_collider     = ("PhysX Primitive Collider component added", "Failed to add PhysX Primitive Collider component")
-    warnings_found         = ("Warnings found in logs",             "No warnings found in logs")
-# fmt: on
-
-
-def ForceRegion_WithNonTriggerColliderWarning():
-    """
-    Summary:
-     Create entity with PhysX Force Region component. Check that user is warned if new PhysX Primitive Collider component is
-     added to Entity.
-
-    Expected Behavior:
-     User is warned by message in the console that the PhysX Primitive Collider component was not marked as a trigger
-
-    Test Steps:
-     1) Load the empty level
-     2) Create test entity
-     3) Add PhysX Force Region component
-     4) Start the Tracer to catch any errors and warnings
-     5) Add PhysX Primitive Collider component to the Entity
-     6) Verify there is warning in the logs
-
-    Note:
-     - This test file must be called from the Open 3D Engine Editor command terminal
-     - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import azlmbr.legacy.general as general
-    import editor_python_test_tools.hydra_editor_utils as hydra
-    
-    from editor_python_test_tools.editor_entity_utils import EditorEntity
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-    from editor_python_test_tools.utils import Tracer
-    from consts.physics import PHYSX_PRIMITIVE_COLLIDER
-
-    # 1) Load the empty level
-    hydra.open_base_level()
-
-    # 2) Create test entity
-    test_entity = EditorEntity.create_editor_entity("TestEntity")
-    Report.result(Tests.create_test_entity, test_entity.id.IsValid())
-
-    # 3) Add PhysX Force Region component
-    test_entity.add_component("PhysX Force Region")
-    test_entity.add_component("PhysX Static Rigid Body")
-    Report.result(Tests.add_physx_force_region, test_entity.has_component("PhysX Force Region"))
-
-    # 4) Start the Tracer to catch any errors and warnings
-    Report.info("Starting warning monitoring")
-    with Tracer() as section_tracer:
-        # 5) Add the PhysX Primitive Collider component
-        test_entity.add_component(PHYSX_PRIMITIVE_COLLIDER)
-        Report.result(Tests.add_physx_collider, test_entity.has_component(PHYSX_PRIMITIVE_COLLIDER))
-        general.idle_wait_frames(1)
-    Report.info("Ending warning monitoring")
-    
-    # 6) Verify there is warning in the logs
-    success_condition = section_tracer.has_warnings
-    # Checking if warning exist and the exact warning is caught in the expected lines in Test file
-    Report.result(Tests.warnings_found, success_condition)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_WithNonTriggerColliderWarning)

+ 0 - 182
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_WorldSpaceForceOnRigidBodies.py

@@ -1,182 +0,0 @@
-"""
-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 ID : C5932040
-# Test Case Title : Check that force region exerts world space force on rigid bodies
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode             = ("Entered game mode",                                              "Failed to enter game mode")
-    find_ball                   = ("Ball entity found",                                              "Ball entity not found")
-    find_box                    = ("Box entity found",                                               "Box entity not found")
-    gravity_works               = ("Ball fell",                                                      "Ball did not fall")
-    ball_triggers_force_region  = ("Ball triggered force region",                                    "Ball did not trigger force region")
-    net_force_magnitude         = ("The net force magnitude on the ball is close to expected value", "The net force magnitude on the ball is not close to expected value")
-    ball_moved_up               = ("Ball moved up",                                                  "Ball did not move up before timeout occurred")
-    exit_game_mode              = ("Exited game mode",                                               "Couldn't exit game mode")
-# fmt: on
-
-
-def is_close_float(a, b, factor):
-    return abs(b - a) < factor
-
-
-def ForceRegion_WorldSpaceForceOnRigidBodies():
-    """
-    Summary:
-    A ball is suspended over a box shaped force region.
-    The ball drops and is forced upward by the world space force of the force region
-
-    Level Description:
-    Ball (entity) - Sphere shaped Mesh; Sphere shaped PhysX Collider; PhysX Rigid Body
-    ForceRegion (entity) - Cube shaped Mesh; Cube shaped PhysX Collider; PhysX Force Region with world space force
-
-    Expected Behavior:
-    The level opens and enters game mode. At this time the ball will fall towards the force region.
-    When it collides, it will be launched upwards. Then the game mode will exit and the editor will close.
-
-    Test Steps:
-     1) Open level
-     2) Enter game mode
-     3) Find the entities
-     4) Get starting position of the ball
-     5) Check that gravity works and ball falls
-     6) Check that the ball enters the trigger area of force region
-     7) Get the magnitude of the collision
-     8) Check that the ball moved up
-     9) Verify that the magnitude of the collision is as expected
-    10) Exit game mode
-    11) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    class Ball:
-        start_position_z = None
-        fell = False
-
-    # Constants
-    TIMEOUT = 2.0
-    BALL_MIN_MOVED_UP = 5  # Minimum amount to indicate Z movement
-    MAGNITUDE_TOLERANCE = 0.26  # Force region magnitude tolerance
-
-    helper.init_idle()
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_WorldSpaceForceOnRigidBodies")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve entities
-    ball_id = general.find_game_entity("Ball")
-    Report.critical_result(Tests.find_ball, ball_id.IsValid())
-
-    box_id = general.find_game_entity("ForceRegion")
-    Report.critical_result(Tests.find_box, box_id.IsValid())
-
-    # 4) Get the starting z position of the ball
-    Ball.start_position_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", ball_id)
-    Report.info("Starting Height of the ball: {}".format(Ball.start_position_z))
-
-    # 5) Check that gravity works and the ball falls
-    def ball_falls():
-        if not Ball.fell:
-            ball_after_frame_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", ball_id)
-            if (ball_after_frame_z - Ball.start_position_z) < 0.0:
-                Report.info("Ball position is now lower than the starting position")
-                Ball.fell = True
-        return Ball.fell
-
-    helper.wait_for_condition(ball_falls, TIMEOUT)
-    Report.result(Tests.gravity_works, Ball.fell)
-
-    # 6) Check that the ball enters the trigger area
-    class ForceRegionTrigger:
-        entered = False
-        exited = False
-
-    def on_enter(args):
-        other_id = args[0]
-        if other_id.Equal(ball_id):
-            Report.info("Trigger entered")
-            ForceRegionTrigger.entered = True
-
-    def on_exit(args):
-        other_id = args[0]
-        if other_id.Equal(ball_id):
-            Report.info("Trigger exited")
-            ForceRegionTrigger.exited = True
-
-    handler = azlmbr.physics.TriggerNotificationBusHandler()
-    handler.connect(box_id)
-    handler.add_callback("OnTriggerEnter", on_enter)
-    handler.add_callback("OnTriggerExit", on_exit)
-
-    helper.wait_for_condition(lambda: ForceRegionTrigger.entered, TIMEOUT)
-    Report.result(Tests.ball_triggers_force_region, ForceRegionTrigger.entered)
-
-    # 7) Get the magnitude of the collision
-    class NetForceMagnitude:
-        value = 0
-
-    def on_calc_net_force(args):
-        """
-        args[0] - force region entity
-        args[1] - entity entering
-        args[2] - vector
-        args[3] - magnitude
-        """
-        force_magnitude = args[3]
-        NetForceMagnitude.value = force_magnitude
-
-    force_notification_handler = azlmbr.physics.ForceRegionNotificationBusHandler()
-    force_notification_handler.connect(None)
-    force_notification_handler.add_callback("OnCalculateNetForce", on_calc_net_force)
-
-    def ball_moved_up():
-        ball_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", ball_id)
-        return ball_z > Ball.start_position_z + BALL_MIN_MOVED_UP
-
-    # 8) Check that the ball moved up
-    if helper.wait_for_condition(lambda: ball_moved_up and ForceRegionTrigger.exited, TIMEOUT):
-        Report.success(Tests.ball_moved_up)
-    else:
-        Report.failure(Tests.ball_moved_up)
-
-    # 9) Verify that the magnitude of the collision is as expected
-    force_region_magnitude = azlmbr.physics.ForceWorldSpaceRequestBus(azlmbr.bus.Event, "GetMagnitude", box_id)
-    Report.info(
-        "NetForce magnitude is {}, Force Region magnitude is {}".format(NetForceMagnitude.value, force_region_magnitude)
-    )
-    Report.result(
-        Tests.net_force_magnitude, is_close_float(NetForceMagnitude.value, force_region_magnitude, MAGNITUDE_TOLERANCE)
-    )
-
-    # 10) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_WorldSpaceForceOnRigidBodies)

+ 0 - 241
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroLinearDampingDoesNothing.py

@@ -1,241 +0,0 @@
-"""
-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 ID : C6090552
-Test Case Title : Check that force region exerts linear damping force on rigid bodies (negative test)
-
-"""
-
-
-# fmt: off
-class Tests:
-    enter_game_mode           = ("Entered game mode",                                   "Failed to enter game mode")
-    ball_exists               = ("The Ball entity was found",                           "The Ball entity was not found")
-    forceregion_exists        = ("The ForceRegion entity was found",                    "The ForceRegion entity was not found")
-    terrain_exists            = ("The Terrain entity was found",                        "The Terrain entity was not found")
-    ball_over_force_region    = ("The ball is over the force region",                   "The ball is not over the force region")
-    gravity_enabled_on_ball   = ("The ball has gravity enabled",                        "The ball gravity failed to enable")
-    ball_entered_force_region = ("The ball entered the force region",                   "The ball did not enter the force region before timeout")
-    ball_fell_through_region  = ("The ball fell through the force region",              "The ball did not exit force region below enter location")
-    enter_exit_distance_close = ("The ball has passed through the entire force region", "Ball did not move the height of the force region")
-    ball_hit_ground           = ("The ball collided with the PhysX Terrain",            "The ball did not collide with the PhysX Terrain before timeout")
-    exit_game_mode            = ("Exited game mode",                                    "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_ZeroLinearDampingDoesNothing():
-    """
-    Summary:
-    A ball is suspended over a force region with a linear damping value of zero and a PhysX Terrain.
-
-    Level Description:
-        Ball - (entity): Mesh: Sphere shaped
-                         PhysX Rigid Body: Gravity is enabled; Default settings
-                         PhysX Collider: Sphere shape; offset (0.0, 0.0, 0.5); draw collider checked
-
-        ForceRegion - (entity): Box Shape: Game view checked; Shape dimensions (3.0, 3.0, 3.0)
-                                PhysX Force Region: Linear damping force: 0.0
-                                PhysX Collider: Box shape; Box dimensions (3.0, 3.0, 3.0); Trigger checked;
-                                                Draw collider checked
-
-        Terrain - (entity): PhysX Terrain: Default settings
-
-    Expected Behavior:
-        When game mode is entered, the ball will fall down toward the force region. It will enter the region and fall
-        straight through as if the region did not exist because the linear damping is set to zero. It will then
-        collide with the PhysX Terrain.
-
-    Test Steps
-        1) Open level
-        2) Enter game mode
-        3) Find/setup entities and handlers
-        4) Check that the ball is over the force region
-        5) Wait for ball to hit the ground
-        6) Report if the ball entered the force region, fell through it, and collided with terrain in the alloted time
-        7) Exit game mode and close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-        Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    helper.init_idle()
-
-    TIMEOUT_SECONDS = 3.0
-    X_Y_Z_TOLERANCE = 1.5
-    REGION_HEIGHT = 3.0
-    TERRAIN_HEIGHT = 32.0
-
-    def is_close(value1, value2, tolerance):
-        """
-        () -> bool
-        Absolute value of difference of values being less than or equal to the tolerance
-        """
-        return abs(value1 - value2) <= tolerance
-
-    def is_at_least(value1, value2, minimum):
-        """
-        () -> bool
-        Subtraction of value2 from value1 being greater than or equal to the minimum
-        """
-        return (value1 - value2) >= minimum
-
-    class Entity(object):
-        def __init__(self, name):
-            self.name = name
-            self.id = general.find_game_entity(self.name)
-            Report.critical_result(Tests.__dict__[self.name.lower() + "_exists"], self.id.IsValid())
-
-        def get_location(self):
-            # () -> Vector3
-            return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-
-    class Ball(Entity):
-        def __init__(self):
-            super(Ball, self).__init__("Ball")
-            self.location = self.get_location()
-            self.enter_region_location = None
-            self.exit_region_location = None
-            self.enable_gravity()
-            self.check_gravity_is_on()
-
-        def enable_gravity(self):
-            azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetGravityEnabled", self.id)
-
-        def check_gravity_is_on(self):
-            gravity_status = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
-            Report.critical_result(Tests.__dict__["gravity_enabled_on_" + self.name.lower()], gravity_status)
-
-        def check_alignment(self, region):
-            # () -> bool
-            Report.info_vector3(self.location, "Location of Ball: ")
-            Report.info_vector3(region.location, "Location of ForceRegion: ")
-
-            aligned = True
-            if not is_close(self.location.x, region.location.x, X_Y_Z_TOLERANCE):
-                aligned = False
-                Report.info("The ball is not aligned in the X axis.")
-            if not is_close(self.location.y, region.location.y, X_Y_Z_TOLERANCE):
-                aligned = False
-                Report.info("The ball is not aligned in the Y axis.")
-            if (self.location.z - region.location.z) < X_Y_Z_TOLERANCE:
-                aligned = False
-                Report.info("The ball is not high enough to enter the force region.")
-            if self.location.z < TERRAIN_HEIGHT:
-                aligned = False
-                Report.info("The ball is below the terrain.")
-            return aligned
-
-        def did_ball_fall_in_region_as_expected(self):
-            # () -> bool
-            if not self.exit_region_location:
-                Report.info("The ball did not exit the force region in time.")
-                return False
-            return (self.enter_region_location.z - self.exit_region_location.z) > X_Y_Z_TOLERANCE
-
-        def check_enter_vs_exit_locations(self):
-            """
-            Check that the ball enter location is above the exit location (ball successfully fell through the force
-            region) and check that the distance between the enter/exit locations is at least the height of the region
-
-            NOTE: The ball will "enter" the force region when the bottom edge of its collision box enters the region and
-                  will "exit" when it is completely outside the force region (top edge leaves region)
-            """
-            Report.info_vector3(self.enter_region_location, "Ball entering location: ")
-            Report.info_vector3(self.exit_region_location, "Ball exiting location: ")
-
-            Report.result(Tests.ball_fell_through_region, self.did_ball_fall_in_region_as_expected())
-            Report.result(
-                Tests.enter_exit_distance_close,
-                is_at_least(self.enter_region_location.z, self.exit_region_location.z, REGION_HEIGHT),
-            )
-
-    class ForceRegion(Entity):
-        def __init__(self, ball):
-            super(ForceRegion, self).__init__("ForceRegion")
-            self.ball = ball  # This creates a reference point to access the ball without looking in global scope
-            self.location = self.get_location()
-            self.ball_entered_trigger_area = False
-            self.trigger_handler = azlmbr.physics.TriggerNotificationBusHandler()
-            self.connect_trigger_handler()
-
-        def on_trigger_enter(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball has entered the force region trigger area.")
-                self.ball_entered_trigger_area = True
-                self.ball.enter_region_location = self.ball.get_location()
-
-        def on_trigger_exit(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball has exited the force region trigger area.")
-                self.ball.exit_region_location = self.ball.get_location()
-
-        def connect_trigger_handler(self):
-            self.trigger_handler.connect(self.id)
-            self.trigger_handler.add_callback("OnTriggerEnter", self.on_trigger_enter)
-            self.trigger_handler.add_callback("OnTriggerExit", self.on_trigger_exit)
-
-    class Terrain(Entity):
-        def __init__(self, ball):
-            super(Terrain, self).__init__("Terrain")
-            self.ball = ball  # This creates a reference point to access the ball without looking in global scope
-            self.ball_collided = False
-            self.collision_handler = azlmbr.physics.CollisionNotificationBusHandler()
-            self.connect_collision_handler()
-
-        def on_collision_begin(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball struck PhysX Terrain")
-                self.ball_collided = True
-
-        def connect_collision_handler(self):
-            self.collision_handler.connect(self.id)
-            self.collision_handler.add_callback("OnCollisionBegin", self.on_collision_begin)
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_ZeroLinearDampingDoesNothing")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Find/setup entities and handlers
-    ball = Ball()
-    region = ForceRegion(ball)
-    terrain = Terrain(ball)
-
-    # 4) Check that the ball is over the force region
-    Report.critical_result(Tests.ball_over_force_region, ball.check_alignment(region))
-
-    # 5) Wait for ball to hit the ground
-    helper.wait_for_condition(lambda: terrain.ball_collided, TIMEOUT_SECONDS)
-
-    # 6) Report if the ball entered the force region, fell through it, and collided with terrain in the alloted time
-    Report.result(Tests.ball_entered_force_region, region.ball_entered_trigger_area)
-    ball.check_enter_vs_exit_locations()
-    Report.result(Tests.ball_hit_ground, terrain.ball_collided)
-
-    # 7) Exit game mode and close the editor
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_ZeroLinearDampingDoesNothing)

+ 0 - 242
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroLocalSpaceForceDoesNothing.py

@@ -1,242 +0,0 @@
-"""
-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 ID : C6090551
-Test Case Title : Check that force region exerts local space force on rigid bodies (negative test)
-
-"""
-
-
-# fmt: off
-class Tests:
-    enter_game_mode           = ("Entered game mode",                                   "Failed to enter game mode")
-    ball_exists               = ("The Ball entity was found",                           "The Ball entity was not found")
-    forceregion_exists        = ("The ForceRegion entity was found",                    "The ForceRegion entity was not found")
-    terrain_exists            = ("The Terrain entity was found",                        "The Terrain entity was not found")
-    ball_over_force_region    = ("The ball is over the force region",                   "The ball is not over the force region")
-    gravity_enabled_on_ball   = ("The ball has gravity enabled",                        "The ball gravity failed to enable")
-    ball_entered_force_region = ("The ball entered the force region",                   "The ball did not enter the force region before timeout")
-    ball_fell_through_region  = ("The ball fell through the force region",              "The ball did not exit force region below enter location")
-    enter_exit_distance_close = ("The ball has passed through the entire force region", "Ball did not move the height of the force region")
-    ball_hit_ground           = ("The ball collided with the PhysX Terrain",            "The ball did not collide with the PhysX Terrain before timeout")
-    exit_game_mode            = ("Exited game mode",                                    "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_ZeroLocalSpaceForceDoesNothing():
-    """
-    Summary:
-        A ball is suspended over a box shaped force region and a PhysX Terrain. The force is a local space force
-        pointed in the positive Z direction with a magnitude of 10.
-
-    Level Description:
-        Ball - (entity): Mesh: Sphere shaped
-                        PhysX Rigid Body: Gravity is enabled; Default settings
-                        PhysX Collider: Sphere shape; offset (0.0, 0.0, 0.5); draw collider checked
-
-        ForceRegion - (entity): Box Shape: Game view checked; Shape dimensions (3.0, 3.0, 3.0)
-                            PhysX Force Region: Local Space force; direction (0.0, 0.0, 1.0); magnitude 10.0
-                            PhysX Collider: Box shape; Box dimensions (3.0, 3.0, 3.0); Trigger checked;
-                                            Draw collider checked
-
-        Terrain - (entity): PhysX Terrain: Default settings
-
-    Expected Behavior:
-        When game mode is entered, the ball entity will fall due to gravity and enter the force region.
-        The region has a very weak force and therefore the ball will fall through the force region,
-        where it will then collide with the PhysX Terrain.
-
-    Test Steps:
-        1) Open level
-        2) Enter game mode
-        3) Find/setup entities and handlers
-        4) Check that the ball is over the force region
-        5) Wait for ball to hit the ground
-        6) Report if the ball entered the force region, fell through it, and collided with terrain in the alloted time
-        7) Exit game mode and close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-        Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    helper.init_idle()
-
-    TIMEOUT_SECONDS = 3.0
-    X_Y_Z_TOLERANCE = 1.5
-    REGION_HEIGHT = 3.0
-    TERRAIN_HEIGHT = 32.0
-
-    def is_close(value1, value2, tolerance):
-        """
-        () -> bool
-        Absolute value of difference of values being less than or equal to the tolerance
-        """
-        return abs(value1 - value2) <= tolerance
-
-    def is_at_least(value1, value2, minimum):
-        """
-        () -> bool
-        Subtraction of value2 from value1 being greater than or equal to the minimum
-        """
-        return (value1 - value2) >= minimum
-
-    class Entity(object):
-        def __init__(self, name):
-            self.name = name
-            self.id = general.find_game_entity(self.name)
-            Report.critical_result(Tests.__dict__[self.name.lower() + "_exists"], self.id.IsValid())
-
-        def get_location(self):
-            # () -> Vector3
-            return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-
-    class Ball(Entity):
-        def __init__(self):
-            super(Ball, self).__init__("Ball")
-            self.location = self.get_location()
-            self.enter_region_location = None
-            self.exit_region_location = None
-            self.enable_gravity()
-            self.check_gravity_is_on()
-
-        def enable_gravity(self):
-            azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetGravityEnabled", self.id)
-
-        def check_gravity_is_on(self):
-            gravity_status = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
-            Report.critical_result(Tests.__dict__["gravity_enabled_on_" + self.name.lower()], gravity_status)
-
-        def check_alignment(self, region):
-            # () -> bool
-            Report.info_vector3(self.location, "Location of Ball: ")
-            Report.info_vector3(region.location, "Location of ForceRegion: ")
-
-            aligned = True
-            if not is_close(self.location.x, region.location.x, X_Y_Z_TOLERANCE):
-                aligned = False
-                Report.info("The ball is not aligned in the X axis.")
-            if not is_close(self.location.y, region.location.y, X_Y_Z_TOLERANCE):
-                aligned = False
-                Report.info("The ball is not aligned in the Y axis.")
-            if (self.location.z - region.location.z) < X_Y_Z_TOLERANCE:
-                aligned = False
-                Report.info("The ball is not high enough to enter the force region.")
-            if self.location.z < TERRAIN_HEIGHT:
-                aligned = False
-                Report.info("The ball is below the terrain.")
-            return aligned
-
-        def did_ball_fall_in_region_as_expected(self):
-            # () -> bool
-            if not self.exit_region_location:
-                Report.info("The ball did not exit the force region in time.")
-                return False
-            return (self.enter_region_location.z - self.exit_region_location.z) > X_Y_Z_TOLERANCE
-
-        def check_enter_vs_exit_locations(self):
-            """
-            Check that the ball enter location is above the exit location (ball successfully fell through the force
-            region) and check that the distance between the enter/exit locations is at least the height of the region
-
-            NOTE: The ball will "enter" the force region when the bottom edge of its collision box enters the region and
-                  will "exit" when it is completely outside the force region (top edge leaves region)
-            """
-            Report.info_vector3(self.enter_region_location, "Ball entering location: ")
-            Report.info_vector3(self.exit_region_location, "Ball exiting location: ")
-
-            Report.result(Tests.ball_fell_through_region, self.did_ball_fall_in_region_as_expected())
-            Report.result(
-                Tests.enter_exit_distance_close,
-                is_at_least(self.enter_region_location.z, self.exit_region_location.z, REGION_HEIGHT),
-            )
-
-    class ForceRegion(Entity):
-        def __init__(self, ball):
-            super(ForceRegion, self).__init__("ForceRegion")
-            self.ball = ball  # This creates a reference point to access the ball without looking in global scope
-            self.location = self.get_location()
-            self.ball_entered_trigger_area = False
-            self.trigger_handler = azlmbr.physics.TriggerNotificationBusHandler()
-            self.connect_trigger_handler()
-
-        def on_trigger_enter(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball has entered the force region trigger area.")
-                self.ball_entered_trigger_area = True
-                self.ball.enter_region_location = self.ball.get_location()
-
-        def on_trigger_exit(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball has exited the force region trigger area.")
-                self.ball.exit_region_location = self.ball.get_location()
-
-        def connect_trigger_handler(self):
-            self.trigger_handler.connect(self.id)
-            self.trigger_handler.add_callback("OnTriggerEnter", self.on_trigger_enter)
-            self.trigger_handler.add_callback("OnTriggerExit", self.on_trigger_exit)
-
-    class Terrain(Entity):
-        def __init__(self, ball):
-            super(Terrain, self).__init__("Terrain")
-            self.ball = ball  # This creates a reference point to access the ball without looking in global scope
-            self.ball_collided = False
-            self.collision_handler = azlmbr.physics.CollisionNotificationBusHandler()
-            self.connect_collision_handler()
-
-        def on_collision_begin(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball struck PhysX Terrain")
-                self.ball_collided = True
-
-        def connect_collision_handler(self):
-            self.collision_handler.connect(self.id)
-            self.collision_handler.add_callback("OnCollisionBegin", self.on_collision_begin)
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_ZeroLocalSpaceForceDoesNothing")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Find/setup entities and handlers
-    ball = Ball()
-    region = ForceRegion(ball)
-    terrain = Terrain(ball)
-
-    # 4) Check that the ball is over the force region
-    Report.critical_result(Tests.ball_over_force_region, ball.check_alignment(region))
-
-    # 5) Wait for ball to hit the ground
-    helper.wait_for_condition(lambda: terrain.ball_collided, TIMEOUT_SECONDS)
-
-    # 6) Report if the ball entered the force region, fell through it, and collided with terrain in the alloted time
-    Report.result(Tests.ball_entered_force_region, region.ball_entered_trigger_area)
-    ball.check_enter_vs_exit_locations()
-    Report.result(Tests.ball_hit_ground, terrain.ball_collided)
-
-    # 7) Exit game mode and close the editor
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_ZeroLocalSpaceForceDoesNothing)

+ 0 - 242
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroPointForceDoesNothing.py

@@ -1,242 +0,0 @@
-"""
-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 ID : C6090554
-Test Case Title : Check that force region exerts point force on rigid bodies (negative test)
-
-"""
-
-
-# fmt: off
-class Tests:
-    enter_game_mode           = ("Entered game mode",                                   "Failed to enter game mode")
-    ball_exists               = ("The Ball entity was found",                           "The Ball entity was not found")
-    forceregion_exists        = ("The ForceRegion entity was found",                    "The ForceRegion entity was not found")
-    terrain_exists            = ("The Terrain entity was found",                        "The Terrain entity was not found")
-    ball_over_force_region    = ("The ball is over the force region",                   "The ball is not over the force region")
-    gravity_enabled_on_ball   = ("The ball has gravity enabled",                        "The ball gravity failed to enable")
-    ball_entered_force_region = ("The ball entered the force region",                   "The ball did not enter the force region before timeout")
-    ball_fell_through_region  = ("The ball fell through the force region",              "The ball did not exit force region below enter location")
-    enter_exit_distance_close = ("The ball has passed through the entire force region", "Ball did not move the height of the force region")
-    ball_hit_ground           = ("The ball collided with the PhysX Terrain",            "The ball did not collide with the PhysX Terrain before timeout")
-    exit_game_mode            = ("Exited game mode",                                    "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_ZeroPointForceDoesNothing():
-    """
-    Summary:
-        A ball is suspended over a box shaped force region and a PhysX Terrain. The force is a point force
-        pointed outward from center with a magnitude of 10.
-
-    Level Description:
-        Ball - (entity): Mesh: Sphere shaped
-                        PhysX Rigid Body: Gravity is enabled; Default settings
-                        PhysX Collider: Sphere shape; offset (0.0, 0.0, 0.5); draw collider checked
-
-        ForceRegion - (entity): Box Shape: Game view checked; Shape dimensions (3.0, 3.0, 3.0)
-                            PhysX Force Region: Point force; magnitude 10.0
-                            PhysX Collider: Box shape; Box dimensions (3.0, 3.0, 3.0); Trigger checked;
-                                            Draw collider checked
-
-        Terrain - (entity): PhysX Terrain: Default settings
-
-    Expected Behavior:
-        When game mode is entered, the ball entity will fall due to gravity and enter the force region.
-        The region has a very weak force and therefore the ball will fall through the force region,
-        where it will then collide with the PhysX Terrain.
-
-    Test Steps:
-        1) Open level
-        2) Enter game mode
-        3) Find/setup entities and handlers
-        4) Check that the ball is over the force region
-        5) Wait for ball to hit the ground
-        6) Report if the ball entered the force region, fell through it, and collided with terrain in the alloted time
-        7) Exit game mode and close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-        Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    helper.init_idle()
-
-    TIMEOUT_SECONDS = 5.0
-    X_Y_Z_TOLERANCE = 1.5
-    REGION_HEIGHT = 3.0
-    TERRAIN_HEIGHT = 32.0
-
-    def is_close(value1, value2, tolerance):
-        """
-        () -> bool
-        Absolute value of difference of values being less than or equal to the tolerance
-        """
-        return abs(value1 - value2) <= tolerance
-
-    def is_at_least(value1, value2, minimum):
-        """
-        () -> bool
-        Subtraction of value2 from value1 being greater than or equal to the minimum
-        """
-        return (value1 - value2) >= minimum
-
-    class Entity(object):
-        def __init__(self, name):
-            self.name = name
-            self.id = general.find_game_entity(self.name)
-            Report.critical_result(Tests.__dict__[self.name.lower() + "_exists"], self.id.IsValid())
-
-        def get_location(self):
-            # () -> Vector3
-            return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-
-    class Ball(Entity):
-        def __init__(self):
-            super(Ball, self).__init__("Ball")
-            self.location = self.get_location()
-            self.enter_region_location = None
-            self.exit_region_location = None
-            self.enable_gravity()
-            self.check_gravity_is_on()
-
-        def enable_gravity(self):
-            azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetGravityEnabled", self.id)
-
-        def check_gravity_is_on(self):
-            gravity_status = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
-            Report.critical_result(Tests.__dict__["gravity_enabled_on_" + self.name.lower()], gravity_status)
-
-        def check_alignment(self, region):
-            # () -> bool
-            Report.info_vector3(self.location, "Location of Ball: ")
-            Report.info_vector3(region.location, "Location of ForceRegion: ")
-
-            aligned = True
-            if not is_close(self.location.x, region.location.x, X_Y_Z_TOLERANCE):
-                aligned = False
-                Report.info("The ball is not aligned in the X axis.")
-            if not is_close(self.location.y, region.location.y, X_Y_Z_TOLERANCE):
-                aligned = False
-                Report.info("The ball is not aligned in the Y axis.")
-            if (self.location.z - region.location.z) < X_Y_Z_TOLERANCE:
-                aligned = False
-                Report.info("The ball is not high enough to enter the force region.")
-            if self.location.z < TERRAIN_HEIGHT:
-                aligned = False
-                Report.info("The ball is below the terrain.")
-            return aligned
-
-        def did_ball_fall_in_region_as_expected(self):
-            # () -> bool
-            if not self.exit_region_location:
-                Report.info("The ball did not exit the force region in time.")
-                return False
-            return (self.enter_region_location.z - self.exit_region_location.z) > X_Y_Z_TOLERANCE
-
-        def check_enter_vs_exit_locations(self):
-            """
-            Check that the ball enter location is above the exit location (ball successfully fell through the force
-            region) and check that the distance between the enter/exit locations is at least the height of the region
-
-            NOTE: The ball will "enter" the force region when the bottom edge of its collision box enters the region and
-                  will "exit" when it is completely outside the force region (top edge leaves region)
-            """
-            Report.info_vector3(self.enter_region_location, "Ball entering location: ")
-            Report.info_vector3(self.exit_region_location, "Ball exiting location: ")
-
-            Report.result(Tests.ball_fell_through_region, self.did_ball_fall_in_region_as_expected())
-            Report.result(
-                Tests.enter_exit_distance_close,
-                is_at_least(self.enter_region_location.z, self.exit_region_location.z, REGION_HEIGHT),
-            )
-
-    class ForceRegion(Entity):
-        def __init__(self, ball):
-            super(ForceRegion, self).__init__("ForceRegion")
-            self.ball = ball  # This creates a reference point to access the ball without looking in global scope
-            self.location = self.get_location()
-            self.ball_entered_trigger_area = False
-            self.trigger_handler = azlmbr.physics.TriggerNotificationBusHandler()
-            self.connect_trigger_handler()
-
-        def on_trigger_enter(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball has entered the force region trigger area.")
-                self.ball_entered_trigger_area = True
-                self.ball.enter_region_location = self.ball.get_location()
-
-        def on_trigger_exit(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball has exited the force region trigger area.")
-                self.ball.exit_region_location = self.ball.get_location()
-
-        def connect_trigger_handler(self):
-            self.trigger_handler.connect(self.id)
-            self.trigger_handler.add_callback("OnTriggerEnter", self.on_trigger_enter)
-            self.trigger_handler.add_callback("OnTriggerExit", self.on_trigger_exit)
-
-    class Terrain(Entity):
-        def __init__(self, ball):
-            super(Terrain, self).__init__("Terrain")
-            self.ball = ball  # This creates a reference point to access the ball without looking in global scope
-            self.ball_collided = False
-            self.collision_handler = azlmbr.physics.CollisionNotificationBusHandler()
-            self.connect_collision_handler()
-
-        def on_collision_begin(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball struck PhysX Terrain")
-                self.ball_collided = True
-
-        def connect_collision_handler(self):
-            self.collision_handler.connect(self.id)
-            self.collision_handler.add_callback("OnCollisionBegin", self.on_collision_begin)
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_ZeroPointForceDoesNothing")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Find/setup entities and handlers
-    ball = Ball()
-    region = ForceRegion(ball)
-    terrain = Terrain(ball)
-
-    # 4) Check that the ball is over the force region
-    Report.critical_result(Tests.ball_over_force_region, ball.check_alignment(region))
-
-    # 5) Wait for ball to hit the ground
-    helper.wait_for_condition(lambda: terrain.ball_collided, TIMEOUT_SECONDS)
-
-    # 6) Report if the ball entered the force region, fell through it, and collided with terrain in the alloted time
-    Report.result(Tests.ball_entered_force_region, region.ball_entered_trigger_area)
-    ball.check_enter_vs_exit_locations()
-    Report.result(Tests.ball_hit_ground, terrain.ball_collided)
-
-    # 7) Exit game mode and close the editor
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_ZeroPointForceDoesNothing)

+ 0 - 173
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroSimpleDragForceDoesNothing.py

@@ -1,173 +0,0 @@
-"""
-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 ID : C6090553
-# Test Case Title : Check that force region exerts simple drag force on rigid bodies (negative test)
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode          = ("Entered game mode",              "Failed to enter game mode")
-    find_ball                = ("Ball found",                     "Ball not found")
-    find_force_region        = ("Force Region found",             "Force Region not found")
-    ball_gravity_disabled    = ("Ball gravity disabled",          "Ball gravity not disabled")
-    ball_fell                = ("The ball fell",                  "The ball did not fall")
-    ball_enters_force_region = ("Ball entered force region",      "Ball did not enter force region")
-    ball_exits_force_region  = ("Ball exited force region",       "Ball did not exit force region")
-    force_region_slows_ball  = ("Force Region did not slow ball", "Force Region slows ball")
-    exit_game_mode           = ("Exited game mode",               "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_ZeroSimpleDragForceDoesNothing():
-    """
-    Summary:
-    Runs an automated test to ensure that force region exerts simple drag force on rigid bodies(negative test).
-
-    Level Description:
-    Ball (entity)         -  contains a sphere mesh, PhysX Collider (sphere shape) and PhysX RigidBody. Ball is
-                             placed above force region
-    Force Region (entity) -  contains Physx Force Region with Simple Drag force with Region Density as 0 and
-                             PhysX Collider (box shape)
-
-    Expected Behavior:
-    When game mode is entered, Sphere falls through force region as though force region doesn't exist because
-    region density for the simple drag force is zero and has no effect on the dropping sphere.
-
-    Test Steps:
-      1)  Open level
-      2)  Enter Game mode
-      3)  Validate the entities in the scene
-      4)  Check ball gravity is disabled or not
-      5)  Get initial velocity of ball
-      6)  Wait for ball to enter force region
-      7)  Gets z velocity and position of ball
-      8)  Wait for ball to exit force region
-      9)  Gets new velocity and position of ball
-      10) Check that the ball does not slow due to the force region
-      11) Exits game mode and editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-
-    import os
-    import sys
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    # Holds details about the ball
-    class Ball:
-        id = None
-        initial_velocity_z = 0.0
-        start_velocity_z = 0.0
-        end_velocity_z = 0.0
-        ball_start_z_position = 0.0
-        ball_end_z_position = 0.0
-        entered_force_region = False
-        exited_force_region = False
-        ball_fell_down = False
-        ball_slows = False
-
-    def on_trigger_enter(args):
-        other_id = args[0]
-        if other_id.Equal(Ball.id):
-            Ball.entered_force_region = True
-
-    def on_trigger_exit(args):
-        other_id = args[0]
-        if other_id.Equal(Ball.id):
-            Ball.exited_force_region = True
-
-    # Constants
-    TIMEOUT = 2.0
-    CLOSE_ENOUGH_THRESHOLD = 0.01
-
-    helper.init_idle()
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_ZeroSimpleDragForceDoesNothing")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Validate the entities in the scene
-    Ball.id = general.find_game_entity("Sphere")
-    Report.critical_result(Tests.find_ball, Ball.id.IsValid())
-
-    force_region_id = general.find_game_entity("Force Region")
-    Report.critical_result(Tests.find_force_region, force_region_id.IsValid())
-
-    # 4) Check ball gravity is disabled or not
-    gravity_enabled = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", Ball.id)
-    Report.critical_result(Tests.ball_gravity_disabled, not gravity_enabled)
-
-    # 5) Get initial velocity of ball
-    # Ball linear velocity is set at (0, 0, -5) in the level
-    Ball.initial_velocity_z = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", Ball.id).z
-    Report.info("Ball initial velocity = {}".format(Ball.initial_velocity_z))
-
-    # 6) Wait for ball to enter force region
-    handler = azlmbr.physics.TriggerNotificationBusHandler()
-    handler.connect(force_region_id)
-    handler.add_callback("OnTriggerEnter", on_trigger_enter)
-    handler.add_callback("OnTriggerExit", on_trigger_exit)
-
-    helper.wait_for_condition(lambda: Ball.entered_force_region, TIMEOUT)
-    Report.critical_result(Tests.ball_enters_force_region, Ball.entered_force_region)
-
-    # 7) Gets z velocity and position of ball
-    Ball.start_velocity_z = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", Ball.id).z
-    Ball.ball_start_z_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Ball.id)
-    Report.info(
-        "Ball Start Z position = {}  Ball Start Z Velocity = {}".format(
-            Ball.ball_start_z_position, Ball.start_velocity_z
-        )
-    )
-
-    # 8) Wait for ball to exit force region
-    helper.wait_for_condition(lambda: Ball.exited_force_region, TIMEOUT)
-    Report.critical_result(Tests.ball_exits_force_region, Ball.exited_force_region)
-
-    # 9) Gets new velocity and position of ball
-    Ball.end_velocity_z = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "GetLinearVelocity", Ball.id).z
-    Ball.ball_end_z_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Ball.id)
-    Report.info(
-        "Ball End Z position = {}  Ball End Z Velocity = {}".format(Ball.ball_end_z_position, Ball.end_velocity_z)
-    )
-
-    # 10) Check that the ball does not slow due to the force region
-    # Check ball fell down or not
-    if (Ball.ball_end_z_position - CLOSE_ENOUGH_THRESHOLD) < Ball.ball_start_z_position:
-        Ball.ball_fell_down = True
-
-    Report.critical_result(Tests.ball_fell, Ball.ball_fell_down)
-
-    # Ball initial velocity is -5.0. Check that the ball does not slow down in force region
-    if ((Ball.end_velocity_z - Ball.initial_velocity_z) < CLOSE_ENOUGH_THRESHOLD) and (
-        (Ball.start_velocity_z - Ball.initial_velocity_z) < CLOSE_ENOUGH_THRESHOLD
-    ):
-        Ball.ball_slows = True
-
-    Report.critical_result(Tests.force_region_slows_ball, Ball.ball_slows)
-
-    # 11) Exits game mode and editor
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_ZeroSimpleDragForceDoesNothing)

+ 0 - 175
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroSplineForceDoesNothing.py

@@ -1,175 +0,0 @@
-"""
-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 ID : C6090555
-# Test Case Title : Check that force region exerts spline follow force on rigid bodies(negative test)
-
-
-
-# fmt: off
-class Tests():
-    enter_game_mode             = ("Entered game mode",                     "Failed to enter game mode")
-    find_sphere                 = ("Sphere entity found",                   "Sphere entity not found")
-    find_force_region           = ("Force region found",                    "Force region not found")
-    find_triggers               = ("All triggers are found",                "All triggers are not found")
-    sphere_fell                 = ("The sphere fell",                       "The sphere did not fall")
-    sphere_entered_force_region = ("The sphere entered the force region",   "The sphere did not enter the force region before timeout")
-    sphere_exited_force_region  = ("The sphere exited the force region",    "The sphere did not exit the force region before timeout")
-    sphere_drops_force_region   = ("Sphere drops through the force region", "Sphere did not drop through the force region due to spline force")
-    exit_game_mode              = ("Exited game mode",                      "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_ZeroSplineForceDoesNothing():
-    """
-    Summary:
-    Runs an automated test to ensure that a PhysX force region exerts spline follow force on rigid bodies(negative test)
-
-    Level Description:
-    A sphere entity is positioned above a force region entity
-    The sphere has a PhysX collider (sphere) and rigidbody component with default values
-
-    The force region entity has a PhysX collider (Box) and force region with a 'spline follow' force.
-    It also has a spline component with 4 nodes. Each node is connected linearly in the following pattern:
-            ___[0]
-        [1] ___
-            ___ [2]
-        [3]
-
-    There are 4 trigger entities, each with a PhysX collider (sphere). They are positioned at each node.
-
-    Expected Behavior:
-    The Sphere drops through the force region as though spline follow force does not exist.
-
-    Test Steps:
-    1) Open level
-    2) Enter game mode
-    3) Retrieve and Validate entities
-    4) Get position of spline and sphere
-    5) Wait till the sphere drops
-    6) Get z position of sphere when it enters and exits from trigger area
-    7) Verify sphere drops through force region without spline force effect
-    8) Exit game mode
-    9) Close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    # Constants
-    TIMEOUT = 3
-    CLOSE_ENOUGH = 0.001
-
-    class Sphere:
-        id = None
-        start_position_z = None
-        fell = False
-        entered_force_region = False
-        exited_force_region = False
-
-    def on_trigger_enter(args):
-        other_id = args[0]
-        if other_id.Equal(Sphere.id):
-            Sphere.entered_force_region = True
-
-    def on_trigger_exit(args):
-        other_id = args[0]
-        if other_id.Equal(Sphere.id):
-            Sphere.exited_force_region = True
-
-    helper.init_idle()
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_ZeroSplineForceDoesNothing")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Retrieve and Validate entities
-    Sphere.id = general.find_game_entity("Sphere")
-    Report.critical_result(Tests.find_sphere, Sphere.id.IsValid())
-
-    force_region_id = general.find_game_entity("Force Region")
-    Report.critical_result(Tests.find_force_region, force_region_id.IsValid())
-
-    all_triggers = ("Trigger0", "Trigger1", "Trigger2", "Trigger3")
-    all_triggers_found = True
-    for trigger in all_triggers:
-        trigger_id = general.find_game_entity(trigger)
-        if not trigger_id.IsValid():
-            all_triggers_found = False
-    Report.critical_result(Tests.find_triggers, all_triggers_found)
-
-    # 4) Get z position of spline and sphere
-    # All triggers are arranged at each node in spline. Getting z position of Trigger3 is same as z position of spline
-    spline_z_position = azlmbr.components.TransformBus(
-        azlmbr.bus.Event, "GetWorldZ", general.find_game_entity("Trigger3")
-    )
-    Report.info("Spline z position is : {}".format(spline_z_position))
-    Sphere.start_position_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Sphere.id)
-    Report.info("Sphere z position is : {}".format(Sphere.start_position_z))
-
-    # 5) Wait till the sphere drops
-    def sphere_fell():
-        if not Sphere.fell:
-            sphere_position_z = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldZ", Sphere.id)
-            if sphere_position_z < (Sphere.start_position_z - CLOSE_ENOUGH):
-                Report.info("Sphere position is lower than the starting position now")
-                Sphere.fell = True
-        return Sphere.fell
-
-    helper.wait_for_condition(sphere_fell, TIMEOUT)
-    Report.critical_result(Tests.sphere_fell, Sphere.fell)
-
-    # 6) Get position of sphere when it enters and exits from trigger area
-    # Wait for ball to enter force region
-    handler = azlmbr.physics.TriggerNotificationBusHandler()
-    handler.connect(force_region_id)
-    handler.add_callback("OnTriggerEnter", on_trigger_enter)
-
-    helper.wait_for_condition(lambda: Sphere.entered_force_region, TIMEOUT)
-    Report.critical_result(Tests.sphere_entered_force_region, Sphere.entered_force_region)
-    sphere_start_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", Sphere.id)
-    Report.info_vector3(sphere_start_position, "Sphere start position in Force Region")
-
-    # Wait for ball to exit force region
-    handler.add_callback("OnTriggerExit", on_trigger_exit)
-    helper.wait_for_condition(lambda: Sphere.exited_force_region, TIMEOUT)
-    Report.critical_result(Tests.sphere_exited_force_region, Sphere.exited_force_region)
-    sphere_end_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", Sphere.id)
-    Report.info_vector3(sphere_end_position, "Sphere end position in Force Region")
-
-    # 7) Verify sphere drops through force region without spline force effect
-    if (
-        ((sphere_start_position.x - sphere_end_position.x) < CLOSE_ENOUGH) and
-        ((sphere_start_position.y - sphere_end_position.y) < CLOSE_ENOUGH) and
-        (sphere_end_position.z < (spline_z_position - CLOSE_ENOUGH))
-    ):
-        Sphere.sphere_drops = True
-
-    Report.critical_result(Tests.sphere_drops_force_region, Sphere.sphere_drops)
-
-    # 8) Exit game mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_ZeroSplineForceDoesNothing)

+ 0 - 242
AutomatedTesting/Gem/PythonTests/Physics/tests/force_region/ForceRegion_ZeroWorldSpaceForceDoesNothing.py

@@ -1,242 +0,0 @@
-"""
-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 ID : C6090550
-Test Case Title : Check that force region exerts world space force on rigid bodies (negative test)
-
-"""
-
-
-# fmt: off
-class Tests:
-    enter_game_mode           = ("Entered game mode",                                   "Failed to enter game mode")
-    ball_exists               = ("The Ball entity was found",                           "The Ball entity was not found")
-    forceregion_exists        = ("The ForceRegion entity was found",                    "The ForceRegion entity was not found")
-    terrain_exists            = ("The Terrain entity was found",                        "The Terrain entity was not found")
-    ball_over_force_region    = ("The ball is over the force region",                   "The ball is not over the force region")
-    gravity_enabled_on_ball   = ("The ball has gravity enabled",                        "The ball gravity failed to enable")
-    ball_entered_force_region = ("The ball entered the force region",                   "The ball did not enter the force region before timeout")
-    ball_fell_through_region  = ("The ball fell through the force region",              "The ball did not exit force region below enter location")
-    enter_exit_distance_close = ("The ball has passed through the entire force region", "Ball did not move the height of the force region")
-    ball_hit_ground           = ("The ball collided with the PhysX Terrain",            "The ball did not collide with the PhysX Terrain before timeout")
-    exit_game_mode            = ("Exited game mode",                                    "Couldn't exit game mode")
-# fmt: on
-
-
-def ForceRegion_ZeroWorldSpaceForceDoesNothing():
-    """
-    Summary:
-        A ball is suspended above a cube shaped force region and a PhysX Terrain. The force is a world space force
-        pointed in the positive Z direction with a magnitude of 10.
-
-    Level Description:
-        Ball - (entity): Mesh: Sphere shaped
-                         PhysX Rigid Body: Gravity is enabled; Default settings
-                         PhysX Collider: Sphere shape; offset (0.0, 0.0, 0.5); draw collider checked
-
-        ForceRegion - (entity): Box Shape: Game view checked; Shape dimensions (3.0, 3.0, 3.0)
-                                PhysX Force Region: World Space force; direction (0.0, 0.0, 1.0); magnitude 10.0
-                                PhysX Collider: Box shape; Box dimensions (3.0, 3.0, 3.0); Trigger checked;
-                                                Draw collider checked
-
-        Terrain - (entity): PhysX Terrain: Default settings
-
-    Expected Behavior:
-        When game mode is entered, the ball entity will fall due to gravity and enter the force region.
-        The region has a very weak force and therefore the ball will fall through the force region,
-        where it will then collide with the PhysX Terrain.
-
-    Test Steps:
-        1) Open level
-        2) Enter game mode
-        3) Find/setup entities and handlers
-        4) Check that the ball is over the force region
-        5) Wait for ball to hit the ground
-        6) Report if the ball entered the force region, fell through it, and collided with terrain in the alloted time
-        7) Exit game mode and close the editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-        Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    helper.init_idle()
-
-    TIMEOUT_SECONDS = 3.0
-    X_Y_Z_TOLERANCE = 1.5
-    REGION_HEIGHT = 3.0
-    TERRAIN_HEIGHT = 32.0
-
-    def is_close(value1, value2, tolerance):
-        """
-        () -> bool
-        Absolute value of difference of values being less than or equal to the tolerance
-        """
-        return abs(value1 - value2) <= tolerance
-
-    def is_at_least(value1, value2, minimum):
-        """
-        () -> bool
-        Subtraction of value2 from value1 being greater than or equal to the minimum
-        """
-        return (value1 - value2) >= minimum
-
-    class Entity(object):
-        def __init__(self, name):
-            self.name = name
-            self.id = general.find_game_entity(self.name)
-            Report.critical_result(Tests.__dict__[self.name.lower() + "_exists"], self.id.IsValid())
-
-        def get_location(self):
-            # () -> Vector3
-            return azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", self.id)
-
-    class Ball(Entity):
-        def __init__(self):
-            super(Ball, self).__init__("Ball")
-            self.location = self.get_location()
-            self.enter_region_location = None
-            self.exit_region_location = None
-            self.enable_gravity()
-            self.check_gravity_is_on()
-
-        def enable_gravity(self):
-            azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "SetGravityEnabled", self.id)
-
-        def check_gravity_is_on(self):
-            gravity_status = azlmbr.physics.RigidBodyRequestBus(azlmbr.bus.Event, "IsGravityEnabled", self.id)
-            Report.critical_result(Tests.__dict__["gravity_enabled_on_" + self.name.lower()], gravity_status)
-
-        def check_alignment(self, region):
-            # () -> bool
-            Report.info_vector3(self.location, "Location of Ball: ")
-            Report.info_vector3(region.location, "Location of ForceRegion: ")
-
-            aligned = True
-            if not is_close(self.location.x, region.location.x, X_Y_Z_TOLERANCE):
-                aligned = False
-                Report.info("The ball is not aligned in the X axis.")
-            if not is_close(self.location.y, region.location.y, X_Y_Z_TOLERANCE):
-                aligned = False
-                Report.info("The ball is not aligned in the Y axis.")
-            if (self.location.z - region.location.z) < X_Y_Z_TOLERANCE:
-                aligned = False
-                Report.info("The ball is not high enough to enter the force region.")
-            if self.location.z < TERRAIN_HEIGHT:
-                aligned = False
-                Report.info("The ball is below the terrain.")
-            return aligned
-
-        def did_ball_fall_in_region_as_expected(self):
-            # () -> bool
-            if not self.exit_region_location:
-                Report.info("The ball did not exit the force region in time.")
-                return False
-            return (self.enter_region_location.z - self.exit_region_location.z) > X_Y_Z_TOLERANCE
-
-        def check_enter_vs_exit_locations(self):
-            """
-            Check that the ball enter location is above the exit location (ball successfully fell through the force
-            region) and check that the distance between the enter/exit locations is at least the height of the region
-
-            NOTE: The ball will "enter" the force region when the bottom edge of its collision box enters the region and
-                  will "exit" when it is completely outside the force region (top edge leaves region)
-            """
-            Report.info_vector3(self.enter_region_location, "Ball entering location: ")
-            Report.info_vector3(self.exit_region_location, "Ball exiting location: ")
-
-            Report.result(Tests.ball_fell_through_region, self.did_ball_fall_in_region_as_expected())
-            Report.result(
-                Tests.enter_exit_distance_close,
-                is_at_least(self.enter_region_location.z, self.exit_region_location.z, REGION_HEIGHT),
-            )
-
-    class ForceRegion(Entity):
-        def __init__(self, ball):
-            super(ForceRegion, self).__init__("ForceRegion")
-            self.ball = ball  # This creates a reference point to access the ball without looking in global scope
-            self.location = self.get_location()
-            self.ball_entered_trigger_area = False
-            self.trigger_handler = azlmbr.physics.TriggerNotificationBusHandler()
-            self.connect_trigger_handler()
-
-        def on_trigger_enter(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball has entered the force region trigger area.")
-                self.ball_entered_trigger_area = True
-                self.ball.enter_region_location = self.ball.get_location()
-
-        def on_trigger_exit(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball has exited the force region trigger area.")
-                self.ball.exit_region_location = self.ball.get_location()
-
-        def connect_trigger_handler(self):
-            self.trigger_handler.connect(self.id)
-            self.trigger_handler.add_callback("OnTriggerEnter", self.on_trigger_enter)
-            self.trigger_handler.add_callback("OnTriggerExit", self.on_trigger_exit)
-
-    class Terrain(Entity):
-        def __init__(self, ball):
-            super(Terrain, self).__init__("Terrain")
-            self.ball = ball  # This creates a reference point to access the ball without looking in global scope
-            self.ball_collided = False
-            self.collision_handler = azlmbr.physics.CollisionNotificationBusHandler()
-            self.connect_collision_handler()
-
-        def on_collision_begin(self, args):
-            other_id = args[0]
-            if other_id.Equal(self.ball.id):
-                Report.info("Ball struck PhysX Terrain")
-                self.ball_collided = True
-
-        def connect_collision_handler(self):
-            self.collision_handler.connect(self.id)
-            self.collision_handler.add_callback("OnCollisionBegin", self.on_collision_begin)
-
-    # 1) Open level
-    helper.open_level("Physics", "ForceRegion_ZeroWorldSpaceForceDoesNothing")
-
-    # 2) Enter game mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Find/setup entities and handlers
-    ball = Ball()
-    region = ForceRegion(ball)
-    terrain = Terrain(ball)
-
-    # 4) Check that the ball is over the force region
-    Report.critical_result(Tests.ball_over_force_region, ball.check_alignment(region))
-
-    # 5) Wait for ball to hit the ground
-    helper.wait_for_condition(lambda: terrain.ball_collided, TIMEOUT_SECONDS)
-
-    # 6) Report if the ball entered the force region, fell through it, and collided with terrain in the alloted time
-    Report.result(Tests.ball_entered_force_region, region.ball_entered_trigger_area)
-    ball.check_enter_vs_exit_locations()
-    Report.result(Tests.ball_hit_ground, terrain.ball_collided)
-
-    # 7) Exit game mode and close the editor
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(ForceRegion_ZeroWorldSpaceForceDoesNothing)

+ 0 - 113
AutomatedTesting/Gem/PythonTests/Physics/tests/joints/Joints_Ball2BodiesConstrained.py

@@ -1,113 +0,0 @@
-"""
-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 ID : C18243588
-# Test Case Title : Check that ball joint constrains 2 bodies within cone limits
-
-# fmt: off
-class Tests:
-    enter_game_mode                 = ("Entered game mode",                         "Failed to enter game mode")
-    exit_game_mode                  = ("Exited game mode",                          "Couldn't exit game mode")
-    lead_found                      = ("Found lead",                                "Did not find lead")
-    follower_found                  = ("Found follower",                            "Did not find follower")
-    check_lead_position             = ("Lead stays still",                          "Lead moved")
-    check_follower_position         = ("Follower moved in X, Y and Z directions",   "Follower did not move in X, Y and Z directions")
-    check_follower_below_lead       = ("Follower remains below lead",               "Follower moved above lead")
-# fmt: on
-
-
-def Joints_Ball2BodiesConstrained():
-    """
-    Summary: Check that ball joint constrains 2 bodies within cone limits
-
-    Level Description:
-    lead - Starts above follower entity
-    follower - Starts below lead entity. Constrained to lead entity with ball joint. Starts with initial velocity of (5, 2, 0).
-
-    Expected Behavior: 
-    The follower entity moved in the positive X, Y and Z directions.
-    The position of the lead entity does not change much.
-    The follower entity did not move above the lead entity.
-
-    Test Steps:
-    1) Open Level
-    2) Enter Game Mode
-    3) Create and Validate Entities
-    4) Wait for several seconds
-    5) Check to see if lead and follower behaved as expected
-    6) Exit Game Mode
-    7) Close Editor
-
-    Note:
-    - This test file must be called from the Open 3D Engine Editor command terminal
-    - Any passed and failed tests are written to the Editor.log file.
-            Parsing the file or running a log_monitor are required to observe the test results.
-
-    :return: None
-    """
-    import os
-    import sys
-    from editor_python_test_tools.utils import Report
-    from editor_python_test_tools.utils import TestHelper as helper
-
-    import azlmbr.legacy.general as general
-    import azlmbr.bus
-
-    import JointsHelper
-    from JointsHelper import JointEntity
-
-    # Constants
-    FLOAT_EPSILON = 0.1 # Negligible float value for comparing with translation vectors. Values smaller than this are considered zero.
-
-    # Helper Entity class
-    class Entity(JointEntity):
-        def criticalEntityFound(self): # Override function to use local Test dictionary
-            Report.critical_result(Tests.__dict__[self.name + "_found"], self.id.isValid())
-
-    # Main Script
-    helper.init_idle()
-
-    # 1) Open Level
-    helper.open_level("Physics", "Joints_Ball2BodiesConstrained")
-
-    # 2) Enter Game Mode
-    helper.enter_game_mode(Tests.enter_game_mode)
-
-    # 3) Create and Validate Entities
-    lead = Entity("lead")
-    follower = Entity("follower")
-    Report.info_vector3(lead.position, "lead initial position:")
-    Report.info_vector3(follower.position, "follower initial position:")
-    leadInitialPosition = lead.position
-    followerInitialPosition = follower.position
-
-    # 4) Wait for several seconds
-    general.idle_wait(1.0) # wait for lead and follower to move
-
-    # 5) Check to see if lead and follower behaved as expected
-    Report.info_vector3(lead.position, "lead position after 1 second:")
-    Report.info_vector3(follower.position, "follower position after 1 second:")
-
-    leadPositionDelta = lead.position.Subtract(leadInitialPosition)
-    leadRemainedStill = JointsHelper.vector3SmallerThanScalar(leadPositionDelta, FLOAT_EPSILON)
-    Report.critical_result(Tests.check_lead_position, leadRemainedStill)
-
-    followerPositionDelta = follower.position.Subtract(followerInitialPosition)
-    followerMovedInXAndZOnly = JointsHelper.vector3LargerThanScalar(followerPositionDelta, FLOAT_EPSILON)
-    Report.critical_result(Tests.check_follower_position, followerMovedInXAndZOnly)
-
-    followerBelowLead = follower.position.z < lead.position.z
-    Report.critical_result(Tests.check_follower_below_lead, followerBelowLead)
-
-    # 6) Exit Game Mode
-    helper.exit_game_mode(Tests.exit_game_mode)
-
-
-
-if __name__ == "__main__":
-    from editor_python_test_tools.utils import Report
-    Report.start_test(Joints_Ball2BodiesConstrained)

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác