Преглед изворни кода

add support for translation offset with shape collider component and box shape component

Signed-off-by: greerdv <[email protected]>
greerdv пре 2 година
родитељ
комит
d80e269b9c

+ 24 - 0
Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp

@@ -91,6 +91,30 @@ namespace UnitTest
     {
     {
         return SuppressExpectedErrors(window, message);
         return SuppressExpectedErrors(window, message);
     }
     }
+
+    void RegistryTestHelper::SetUp(AZStd::string_view path, bool value)
+    {
+        m_oldSettingsRegistry = AZ::SettingsRegistry::Get();
+        if (m_oldSettingsRegistry)
+        {
+            AZ::SettingsRegistry::Unregister(m_oldSettingsRegistry);
+        }
+
+        m_settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
+        m_settingsRegistry->Set(path, value);
+        AZ::SettingsRegistry::Register(m_settingsRegistry.get());
+    }
+
+    void RegistryTestHelper::TearDown()
+    {
+        AZ::SettingsRegistry::Unregister(m_settingsRegistry.get());
+        if (m_oldSettingsRegistry)
+        {
+            AZ::SettingsRegistry::Register(m_oldSettingsRegistry);
+            m_oldSettingsRegistry = nullptr;
+        }
+        m_settingsRegistry.reset();
+    }
 }
 }
 
 
 namespace AZ
 namespace AZ

+ 13 - 0
Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.h

@@ -11,6 +11,7 @@
 #include <AzCore/Debug/TraceMessageBus.h>
 #include <AzCore/Debug/TraceMessageBus.h>
 #include <AzCore/IO/Path/Path.h>
 #include <AzCore/IO/Path/Path.h>
 #include <AzCore/Slice/SliceAsset.h>
 #include <AzCore/Slice/SliceAsset.h>
+#include <AzCore/Settings/SettingsRegistryImpl.h>
 
 
 namespace UnitTest
 namespace UnitTest
 {
 {
@@ -50,6 +51,18 @@ namespace UnitTest
         int m_expectedErrorCount;
         int m_expectedErrorCount;
         int m_expectedWarningCount;
         int m_expectedWarningCount;
     };
     };
+
+    //! Helper utility for setting a bool registry value in a test.
+    class RegistryTestHelper
+    {
+    public:
+        void SetUp(AZStd::string_view path, bool value);
+        void TearDown();
+
+    private:
+        AZStd::unique_ptr<AZ::SettingsRegistryInterface> m_settingsRegistry;
+        AZ::SettingsRegistryInterface* m_oldSettingsRegistry = nullptr;
+    };
 }
 }
 
 
 namespace AZ
 namespace AZ

+ 4 - 3
Gems/LmbrCentral/Code/Tests/AxisAlignedBoxShapeTest.cpp

@@ -7,6 +7,7 @@
  */
  */
 
 
 #include <AZTestShared/Math/MathTestHelpers.h>
 #include <AZTestShared/Math/MathTestHelpers.h>
+#include <AZTestShared/Utils/Utils.h>
 #include <AzCore/Component/ComponentApplication.h>
 #include <AzCore/Component/ComponentApplication.h>
 #include <AzCore/Math/Matrix3x3.h>
 #include <AzCore/Math/Matrix3x3.h>
 #include <AzCore/Math/Random.h>
 #include <AzCore/Math/Random.h>
@@ -22,7 +23,7 @@ namespace UnitTest
 {
 {
     class AxisAlignedBoxShapeTest
     class AxisAlignedBoxShapeTest
         : public AllocatorsFixture
         : public AllocatorsFixture
-        , public ShapeOffsetTestsBase
+        , public RegistryTestHelper
     {
     {
         AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
         AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
         AZStd::unique_ptr<AZ::ComponentDescriptor> m_transformComponentDescriptor;
         AZStd::unique_ptr<AZ::ComponentDescriptor> m_transformComponentDescriptor;
@@ -33,7 +34,7 @@ namespace UnitTest
         void SetUp() override
         void SetUp() override
         {
         {
             AllocatorsFixture::SetUp();
             AllocatorsFixture::SetUp();
-            ShapeOffsetTestsBase::SetUp();
+            RegistryTestHelper::SetUp(LmbrCentral::ShapeComponentTranslationOffsetEnabled, true);
             m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
             m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
 
 
             m_transformComponentDescriptor =
             m_transformComponentDescriptor =
@@ -53,7 +54,7 @@ namespace UnitTest
             m_axisAlignedBoxShapeComponentDescriptor.reset();
             m_axisAlignedBoxShapeComponentDescriptor.reset();
             m_axisAlignedBoxShapeDebugDisplayComponentDescriptor.reset();
             m_axisAlignedBoxShapeDebugDisplayComponentDescriptor.reset();
             m_serializeContext.reset();
             m_serializeContext.reset();
-            ShapeOffsetTestsBase::TearDown();
+            RegistryTestHelper::TearDown();
             AllocatorsFixture::TearDown();
             AllocatorsFixture::TearDown();
         }
         }
     };
     };

+ 4 - 3
Gems/LmbrCentral/Code/Tests/BoxShapeTest.cpp

@@ -7,6 +7,7 @@
  */
  */
 
 
 #include <AZTestShared/Math/MathTestHelpers.h>
 #include <AZTestShared/Math/MathTestHelpers.h>
+#include <AZTestShared/Utils/Utils.h>
 #include <AzCore/Component/ComponentApplication.h>
 #include <AzCore/Component/ComponentApplication.h>
 #include <AzCore/Math/Matrix3x3.h>
 #include <AzCore/Math/Matrix3x3.h>
 #include <AzCore/Math/Random.h>
 #include <AzCore/Math/Random.h>
@@ -23,7 +24,7 @@ namespace UnitTest
 {
 {
     class BoxShapeTest
     class BoxShapeTest
         : public AllocatorsFixture
         : public AllocatorsFixture
-        , public ShapeOffsetTestsBase
+        , public RegistryTestHelper
     {
     {
         AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
         AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
         AZStd::unique_ptr<AZ::ComponentDescriptor> m_transformComponentDescriptor;
         AZStd::unique_ptr<AZ::ComponentDescriptor> m_transformComponentDescriptor;
@@ -35,7 +36,7 @@ namespace UnitTest
         void SetUp() override
         void SetUp() override
         {
         {
             AllocatorsFixture::SetUp();
             AllocatorsFixture::SetUp();
-            ShapeOffsetTestsBase::SetUp();
+            RegistryTestHelper::SetUp(LmbrCentral::ShapeComponentTranslationOffsetEnabled, true);
             m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
             m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
 
 
             m_transformComponentDescriptor = AZStd::unique_ptr<AZ::ComponentDescriptor>(AzFramework::TransformComponent::CreateDescriptor());
             m_transformComponentDescriptor = AZStd::unique_ptr<AZ::ComponentDescriptor>(AzFramework::TransformComponent::CreateDescriptor());
@@ -57,7 +58,7 @@ namespace UnitTest
             m_boxShapeDebugDisplayComponentDescriptor.reset();
             m_boxShapeDebugDisplayComponentDescriptor.reset();
             m_nonUniformScaleComponentDescriptor.reset();
             m_nonUniformScaleComponentDescriptor.reset();
             m_serializeContext.reset();
             m_serializeContext.reset();
-            ShapeOffsetTestsBase::TearDown();
+            RegistryTestHelper::TearDown();
             AllocatorsFixture::TearDown();
             AllocatorsFixture::TearDown();
         }
         }
     };
     };

+ 4 - 3
Gems/LmbrCentral/Code/Tests/CapsuleShapeTest.cpp

@@ -9,6 +9,7 @@
 #include <AzTest/AzTest.h>
 #include <AzTest/AzTest.h>
 
 
 #include <AZTestShared/Math/MathTestHelpers.h>
 #include <AZTestShared/Math/MathTestHelpers.h>
+#include <AZTestShared/Utils/Utils.h>
 #include <AzCore/Component/ComponentApplication.h>
 #include <AzCore/Component/ComponentApplication.h>
 #include <AzCore/UnitTest/TestTypes.h>
 #include <AzCore/UnitTest/TestTypes.h>
 #include <AzFramework/Components/TransformComponent.h>
 #include <AzFramework/Components/TransformComponent.h>
@@ -22,7 +23,7 @@ namespace UnitTest
 {
 {
     class CapsuleShapeTest
     class CapsuleShapeTest
         : public AllocatorsFixture
         : public AllocatorsFixture
-        , public ShapeOffsetTestsBase
+        , public RegistryTestHelper
     {
     {
         AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
         AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
         AZStd::unique_ptr<AZ::ComponentDescriptor> m_transformComponentDescriptor;
         AZStd::unique_ptr<AZ::ComponentDescriptor> m_transformComponentDescriptor;
@@ -34,7 +35,7 @@ namespace UnitTest
         void SetUp() override
         void SetUp() override
         {
         {
             AllocatorsFixture::SetUp();
             AllocatorsFixture::SetUp();
-            ShapeOffsetTestsBase::SetUp();
+            RegistryTestHelper::SetUp(LmbrCentral::ShapeComponentTranslationOffsetEnabled, true);
             m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
             m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
 
 
             m_transformComponentDescriptor = AZStd::unique_ptr<AZ::ComponentDescriptor>(AzFramework::TransformComponent::CreateDescriptor());
             m_transformComponentDescriptor = AZStd::unique_ptr<AZ::ComponentDescriptor>(AzFramework::TransformComponent::CreateDescriptor());
@@ -54,7 +55,7 @@ namespace UnitTest
             m_capsuleShapeComponentDescriptor.reset();
             m_capsuleShapeComponentDescriptor.reset();
             m_transformComponentDescriptor.reset();
             m_transformComponentDescriptor.reset();
             m_serializeContext.reset();
             m_serializeContext.reset();
-            ShapeOffsetTestsBase::TearDown();
+            RegistryTestHelper::TearDown();
             AllocatorsFixture::TearDown();
             AllocatorsFixture::TearDown();
         }
         }
     };
     };

+ 0 - 24
Gems/LmbrCentral/Code/Tests/ShapeTestUtils.cpp

@@ -12,30 +12,6 @@
 
 
 namespace UnitTest
 namespace UnitTest
 {
 {
-    void ShapeOffsetTestsBase::SetUp()
-    {
-        m_oldSettingsRegistry = AZ::SettingsRegistry::Get();
-        if (m_oldSettingsRegistry)
-        {
-            AZ::SettingsRegistry::Unregister(m_oldSettingsRegistry);
-        }
-
-        m_settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
-        m_settingsRegistry->Set(LmbrCentral::ShapeComponentTranslationOffsetEnabled, true);
-        AZ::SettingsRegistry::Register(m_settingsRegistry.get());
-    }
-
-    void ShapeOffsetTestsBase::TearDown()
-    {
-        AZ::SettingsRegistry::Unregister(m_settingsRegistry.get());
-        if (m_oldSettingsRegistry)
-        {
-            AZ::SettingsRegistry::Register(m_oldSettingsRegistry);
-            m_oldSettingsRegistry = nullptr;
-        }
-        m_settingsRegistry.reset();
-    }
-
     bool IsPointInside(const AZ::Entity& entity, const AZ::Vector3& point)
     bool IsPointInside(const AZ::Entity& entity, const AZ::Vector3& point)
     {
     {
         bool inside = false;
         bool inside = false;

+ 0 - 14
Gems/LmbrCentral/Code/Tests/ShapeTestUtils.h

@@ -8,9 +8,6 @@
 
 
 #pragma once
 #pragma once
 
 
-#include <AzCore/Settings/SettingsRegistryImpl.h>
-#include <AzCore/std/smart_ptr/unique_ptr.h>
-
 namespace AZ
 namespace AZ
 {
 {
     class Entity;
     class Entity;
@@ -19,16 +16,5 @@ namespace AZ
 
 
 namespace UnitTest
 namespace UnitTest
 {
 {
-    class ShapeOffsetTestsBase
-    {
-    public:
-        void SetUp();
-        void TearDown();
-
-    private:
-        AZStd::unique_ptr<AZ::SettingsRegistryInterface> m_settingsRegistry;
-        AZ::SettingsRegistryInterface* m_oldSettingsRegistry = nullptr;
-    };
-
     bool IsPointInside(const AZ::Entity& entity, const AZ::Vector3& point);
     bool IsPointInside(const AZ::Entity& entity, const AZ::Vector3& point);
 } // namespace UnitTest
 } // namespace UnitTest

+ 4 - 3
Gems/LmbrCentral/Code/Tests/SphereShapeTest.cpp

@@ -9,6 +9,7 @@
 #include <AzTest/AzTest.h>
 #include <AzTest/AzTest.h>
 
 
 #include <AZTestShared/Math/MathTestHelpers.h>
 #include <AZTestShared/Math/MathTestHelpers.h>
+#include <AZTestShared/Utils/Utils.h>
 #include <AzCore/Component/ComponentApplication.h>
 #include <AzCore/Component/ComponentApplication.h>
 #include <AzCore/UnitTest/TestTypes.h>
 #include <AzCore/UnitTest/TestTypes.h>
 #include <AzFramework/Components/TransformComponent.h>
 #include <AzFramework/Components/TransformComponent.h>
@@ -24,7 +25,7 @@ namespace UnitTest
 {
 {
     class SphereShapeTest
     class SphereShapeTest
         : public AllocatorsFixture
         : public AllocatorsFixture
-        , public ShapeOffsetTestsBase
+        , public RegistryTestHelper
     {
     {
         AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
         AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
         AZStd::unique_ptr<AZ::ComponentDescriptor> m_transformShapeComponentDescriptor;
         AZStd::unique_ptr<AZ::ComponentDescriptor> m_transformShapeComponentDescriptor;
@@ -34,7 +35,7 @@ namespace UnitTest
         void SetUp() override
         void SetUp() override
         {
         {
             AllocatorsFixture::SetUp();
             AllocatorsFixture::SetUp();
-            ShapeOffsetTestsBase::SetUp();
+            RegistryTestHelper::SetUp(LmbrCentral::ShapeComponentTranslationOffsetEnabled, true);
             m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
             m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
             m_transformShapeComponentDescriptor.reset(AzFramework::TransformComponent::CreateDescriptor());
             m_transformShapeComponentDescriptor.reset(AzFramework::TransformComponent::CreateDescriptor());
             m_transformShapeComponentDescriptor->Reflect(&(*m_serializeContext));
             m_transformShapeComponentDescriptor->Reflect(&(*m_serializeContext));
@@ -50,7 +51,7 @@ namespace UnitTest
             m_sphereShapeComponentDescriptor.reset();
             m_sphereShapeComponentDescriptor.reset();
             m_sphereShapeDebugDisplayComponentDescriptor.reset();
             m_sphereShapeDebugDisplayComponentDescriptor.reset();
             m_serializeContext.reset();
             m_serializeContext.reset();
-            ShapeOffsetTestsBase::TearDown();
+            RegistryTestHelper::TearDown();
             AllocatorsFixture::TearDown();
             AllocatorsFixture::TearDown();
         }
         }
     };
     };

+ 2 - 2
Gems/LmbrCentral/Code/include/LmbrCentral/Shape/ShapeComponentBus.h

@@ -194,14 +194,14 @@ namespace LmbrCentral
         /// Get the translation offset for the shape relative to its entity.
         /// Get the translation offset for the shape relative to its entity.
         virtual AZ::Vector3 GetTranslationOffset() const
         virtual AZ::Vector3 GetTranslationOffset() const
         {
         {
-            AZ_Warning("ShapeComponentRequests", !IsShapeComponentTranslationEnabled(), "GetTranslationOffset not implemented");
+            AZ_WarningOnce("ShapeComponentRequests", !IsShapeComponentTranslationEnabled(), "GetTranslationOffset not implemented");
             return AZ::Vector3::CreateZero();
             return AZ::Vector3::CreateZero();
         }
         }
 
 
         /// Set the translation offset for the shape relative to its entity.
         /// Set the translation offset for the shape relative to its entity.
         virtual void SetTranslationOffset([[maybe_unused]] const AZ::Vector3& translationOffset)
         virtual void SetTranslationOffset([[maybe_unused]] const AZ::Vector3& translationOffset)
         {
         {
-            AZ_Warning("ShapeComponentRequests", !IsShapeComponentTranslationEnabled(), "SetTranslationOffset not implemented");
+            AZ_WarningOnce("ShapeComponentRequests", !IsShapeComponentTranslationEnabled(), "SetTranslationOffset not implemented");
         }
         }
 
 
         virtual ~ShapeComponentRequests() = default;
         virtual ~ShapeComponentRequests() = default;

+ 4 - 0
Gems/PhysX/Code/Source/BaseColliderComponent.cpp

@@ -25,6 +25,8 @@
 #include <PhysX/PhysXLocks.h>
 #include <PhysX/PhysXLocks.h>
 #include <Scene/PhysXScene.h>
 #include <Scene/PhysXScene.h>
 
 
+#pragma optimize("", off)
+
 namespace PhysX
 namespace PhysX
 {
 {
     // ShapeInfoCache
     // ShapeInfoCache
@@ -329,3 +331,5 @@ namespace PhysX
     }
     }
 
 
 }
 }
+
+#pragma optimize("", on)

+ 0 - 1
Gems/PhysX/Code/Source/BaseColliderComponent.h

@@ -87,7 +87,6 @@ namespace PhysX
 
 
         static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
         static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
         {
         {
-            dependent.push_back(AZ_CRC_CE("ShapeService"));
             dependent.push_back(AZ_CRC_CE("NonUniformScaleService"));
             dependent.push_back(AZ_CRC_CE("NonUniformScaleService"));
         }
         }
 
 

+ 4 - 0
Gems/PhysX/Code/Source/EditorColliderComponent.cpp

@@ -38,6 +38,8 @@
 #include <Editor/ConfigurationWindowBus.h>
 #include <Editor/ConfigurationWindowBus.h>
 #include <Editor/ColliderComponentMode.h>
 #include <Editor/ColliderComponentMode.h>
 
 
+#pragma optimize("", off)
+
 namespace PhysX
 namespace PhysX
 {
 {
     void EditorProxyCylinderShapeConfig::Reflect(AZ::ReflectContext* context)
     void EditorProxyCylinderShapeConfig::Reflect(AZ::ReflectContext* context)
@@ -1597,3 +1599,5 @@ namespace PhysX
         }
         }
     }
     }
 } // namespace PhysX
 } // namespace PhysX
+
+#pragma optimize("", on)

+ 5 - 1
Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp

@@ -20,6 +20,8 @@
 #include <Source/NameConstants.h>
 #include <Source/NameConstants.h>
 #include <Source/Utils.h>
 #include <Source/Utils.h>
 
 
+#pragma optimize("", off)
+
 namespace PhysX
 namespace PhysX
 {
 {
     namespace Internal
     namespace Internal
@@ -88,7 +90,7 @@ namespace PhysX
             const AZStd::vector<EditorShapeColliderComponent*> shapeColliders = entity->FindComponents<EditorShapeColliderComponent>();
             const AZStd::vector<EditorShapeColliderComponent*> shapeColliders = entity->FindComponents<EditorShapeColliderComponent>();
             for (const EditorShapeColliderComponent* shapeCollider : shapeColliders)
             for (const EditorShapeColliderComponent* shapeCollider : shapeColliders)
             {
             {
-                const Physics::ColliderConfiguration& colliderConfig = shapeCollider->GetColliderConfiguration();
+                Physics::ColliderConfiguration colliderConfig = shapeCollider->GetColliderConfigurationScaled();
                 const AZStd::vector<AZStd::shared_ptr<Physics::ShapeConfiguration>>& shapeConfigs =
                 const AZStd::vector<AZStd::shared_ptr<Physics::ShapeConfiguration>>& shapeConfigs =
                     shapeCollider->GetShapeConfigurations();
                     shapeCollider->GetShapeConfigurations();
                 for (const auto& shapeConfig : shapeConfigs)
                 for (const auto& shapeConfig : shapeConfigs)
@@ -576,3 +578,5 @@ namespace PhysX
         }
         }
     }
     }
 } // namespace PhysX
 } // namespace PhysX
+
+#pragma optimize("", on)

+ 27 - 5
Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp

@@ -32,6 +32,8 @@
 #include <RigidBodyStatic.h>
 #include <RigidBodyStatic.h>
 #include <System/PhysXSystem.h>
 #include <System/PhysXSystem.h>
 
 
+#pragma optimize("", off)
+
 namespace PhysX
 namespace PhysX
 {
 {
     EditorShapeColliderComponent::EditorShapeColliderComponent()
     EditorShapeColliderComponent::EditorShapeColliderComponent()
@@ -151,7 +153,6 @@ namespace PhysX
     void EditorShapeColliderComponent::UpdateCachedSamplePoints() const
     void EditorShapeColliderComponent::UpdateCachedSamplePoints() const
     {
     {
         m_geometryCache.m_cachedSamplePoints.clear();
         m_geometryCache.m_cachedSamplePoints.clear();
-
         switch (m_shapeType)
         switch (m_shapeType)
         {
         {
         case ShapeType::Box:
         case ShapeType::Box:
@@ -223,8 +224,7 @@ namespace PhysX
             break;
             break;
         }
         }
 
 
-        AZ::Transform transform = GetWorldTM();
-        transform.ExtractUniformScale();
+        AZ::Transform transform = GetWorldTM() * AZ::Transform::CreateTranslation(m_colliderConfig.m_position);
         const size_t numPoints = m_geometryCache.m_cachedSamplePoints.size();
         const size_t numPoints = m_geometryCache.m_cachedSamplePoints.size();
         for (size_t pointIndex = 0; pointIndex < numPoints; ++pointIndex)
         for (size_t pointIndex = 0; pointIndex < numPoints; ++pointIndex)
         {
         {
@@ -237,6 +237,13 @@ namespace PhysX
         return m_colliderConfig;
         return m_colliderConfig;
     }
     }
 
 
+    Physics::ColliderConfiguration EditorShapeColliderComponent::GetColliderConfigurationScaled() const
+    {
+        Physics::ColliderConfiguration colliderConfigurationScaled = m_colliderConfig;
+        colliderConfigurationScaled.m_position *= m_cachedWorldTransform.GetUniformScale();
+        return colliderConfigurationScaled;
+    }
+
     const AZStd::vector<AZStd::shared_ptr<Physics::ShapeConfiguration>>& EditorShapeColliderComponent::GetShapeConfigurations() const
     const AZStd::vector<AZStd::shared_ptr<Physics::ShapeConfiguration>>& EditorShapeColliderComponent::GetShapeConfigurations() const
     {
     {
         return m_shapeConfigs;
         return m_shapeConfigs;
@@ -281,7 +288,7 @@ namespace PhysX
         for (const auto& shapeConfig : m_shapeConfigs)
         for (const auto& shapeConfig : m_shapeConfigs)
         {
         {
             colliderShapePairs.emplace_back(
             colliderShapePairs.emplace_back(
-                AZStd::make_shared<Physics::ColliderConfiguration>(m_colliderConfig), shapeConfig);
+                AZStd::make_shared<Physics::ColliderConfiguration>(GetColliderConfigurationScaled()), shapeConfig);
         }
         }
         configuration.m_colliderAndShapeData = colliderShapePairs;
         configuration.m_colliderAndShapeData = colliderShapePairs;
 
 
@@ -694,6 +701,7 @@ namespace PhysX
         UpdateSingleSidedSettings();
         UpdateSingleSidedSettings();
         UpdateShapeConfigs();
         UpdateShapeConfigs();
         UpdateTriggerSettings();
         UpdateTriggerSettings();
+        UpdateTranslationOffset();
 
 
         // Debug drawing
         // Debug drawing
         m_colliderDebugDraw.Connect(GetEntityId());
         m_colliderDebugDraw.Connect(GetEntityId());
@@ -841,6 +849,7 @@ namespace PhysX
         {
         {
             UpdateShapeConfigs();
             UpdateShapeConfigs();
             UpdateTriggerSettings();
             UpdateTriggerSettings();
+            UpdateTranslationOffset();
 
 
             CreateStaticEditorCollider();
             CreateStaticEditorCollider();
             Physics::ColliderComponentEventBus::Event(GetEntityId(), &Physics::ColliderComponentEvents::OnColliderChanged);
             Physics::ColliderComponentEventBus::Event(GetEntityId(), &Physics::ColliderComponentEvents::OnColliderChanged);
@@ -888,8 +897,10 @@ namespace PhysX
                 {
                 {
                 case Physics::ShapeType::Box:
                 case Physics::ShapeType::Box:
                 {
                 {
+                    Physics::ColliderConfiguration unscaledColliderConfig = m_colliderConfig;
+                    unscaledColliderConfig.m_position /= m_currentNonUniformScale;
                     const auto& boxConfig = static_cast<const Physics::BoxShapeConfiguration&>(*shapeConfig);
                     const auto& boxConfig = static_cast<const Physics::BoxShapeConfiguration&>(*shapeConfig);
-                    m_colliderDebugDraw.DrawBox(debugDisplay, m_colliderConfig, boxConfig, m_currentNonUniformScale, false);
+                    m_colliderDebugDraw.DrawBox(debugDisplay, unscaledColliderConfig, boxConfig, m_currentNonUniformScale, false);
                     break;
                     break;
                 }
                 }
                 case Physics::ShapeType::Capsule:
                 case Physics::ShapeType::Capsule:
@@ -947,6 +958,15 @@ namespace PhysX
         }
         }
     }
     }
 
 
+    void EditorShapeColliderComponent::UpdateTranslationOffset()
+    {
+        AZ::Vector3 translationOffset = AZ::Vector3::CreateZero();
+        LmbrCentral::ShapeComponentRequestsBus::EventResult(
+            translationOffset, GetEntityId(), &LmbrCentral::ShapeComponentRequests::GetTranslationOffset);
+
+        m_colliderConfig.m_position = m_currentNonUniformScale * translationOffset;
+    }
+
     void EditorShapeColliderComponent::UpdateSingleSidedSettings()
     void EditorShapeColliderComponent::UpdateSingleSidedSettings()
     {
     {
         if (GetEntity()->FindComponent<EditorRigidBodyComponent>())
         if (GetEntity()->FindComponent<EditorRigidBodyComponent>())
@@ -967,3 +987,5 @@ namespace PhysX
         }
         }
     }
     }
 } // namespace PhysX
 } // namespace PhysX
+
+#pragma optimize("", on)

+ 4 - 0
Gems/PhysX/Code/Source/EditorShapeColliderComponent.h

@@ -83,6 +83,9 @@ namespace PhysX
         virtual const Physics::ColliderConfiguration& GetColliderConfiguration() const;
         virtual const Physics::ColliderConfiguration& GetColliderConfiguration() const;
         virtual const AZStd::vector<AZStd::shared_ptr<Physics::ShapeConfiguration>>& GetShapeConfigurations() const;
         virtual const AZStd::vector<AZStd::shared_ptr<Physics::ShapeConfiguration>>& GetShapeConfigurations() const;
 
 
+        //! Returns a collider configuration with the entity scale and non-uniform scale applied to the collider position.
+        Physics::ColliderConfiguration GetColliderConfigurationScaled() const;
+
         // EditorComponentBase
         // EditorComponentBase
         void BuildGameEntity(AZ::Entity* gameEntity) override;
         void BuildGameEntity(AZ::Entity* gameEntity) override;
     private:
     private:
@@ -145,6 +148,7 @@ namespace PhysX
 
 
         void UpdateTriggerSettings();
         void UpdateTriggerSettings();
         void UpdateSingleSidedSettings();
         void UpdateSingleSidedSettings();
+        void UpdateTranslationOffset();
 
 
         Physics::ColliderConfiguration m_colliderConfig; //!< Stores collision layers, whether the collider is a trigger, etc.
         Physics::ColliderConfiguration m_colliderConfig; //!< Stores collision layers, whether the collider is a trigger, etc.
         DebugDraw::Collider m_colliderDebugDraw; //!< Handles drawing the collider based on global and local
         DebugDraw::Collider m_colliderDebugDraw; //!< Handles drawing the collider based on global and local

+ 28 - 0
Gems/PhysX/Code/Source/ShapeColliderComponent.cpp

@@ -13,6 +13,8 @@
 #include <LmbrCentral/Shape/CapsuleShapeComponentBus.h>
 #include <LmbrCentral/Shape/CapsuleShapeComponentBus.h>
 #include <Source/Utils.h>
 #include <Source/Utils.h>
 
 
+#pragma optimize("", off)
+
 namespace PhysX
 namespace PhysX
 {
 {
     namespace Utils
     namespace Utils
@@ -34,6 +36,29 @@ namespace PhysX
         }
         }
     }
     }
 
 
+    void ShapeColliderComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(AZ_CRC_CE("PhysicsColliderService"));
+        provided.push_back(AZ_CRC_CE("PhysicsTriggerService"));
+        provided.push_back(AZ_CRC_CE("PhysicsShapeColliderService"));
+    }
+
+    void ShapeColliderComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+        required.push_back(AZ_CRC_CE("TransformService"));
+        required.push_back(AZ_CRC_CE("ShapeService"));
+    }
+
+    void ShapeColliderComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        incompatible.push_back(AZ_CRC_CE("PhysicsShapeColliderService"));
+        incompatible.push_back(AZ_CRC_CE("AxisAlignedBoxShapeService"));
+        incompatible.push_back(AZ_CRC_CE("CompoundShapeService"));
+        incompatible.push_back(AZ_CRC_CE("DiskShapeService"));
+        incompatible.push_back(AZ_CRC_CE("TubeShapeService"));
+        incompatible.push_back(AZ_CRC_CE("ReferenceShapeService"));
+    }
+
     // BaseColliderComponent
     // BaseColliderComponent
     void ShapeColliderComponent::UpdateScaleForShapeConfigs()
     void ShapeColliderComponent::UpdateScaleForShapeConfigs()
     {
     {
@@ -48,3 +73,6 @@ namespace PhysX
         }
         }
     }
     }
 } // namespace PhysX
 } // namespace PhysX
+
+#pragma optimize("", on)
+

+ 4 - 0
Gems/PhysX/Code/Source/ShapeColliderComponent.h

@@ -43,6 +43,10 @@ namespace PhysX
 
 
         ShapeColliderComponent() = default;
         ShapeColliderComponent() = default;
 
 
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+
         // BaseColliderComponent
         // BaseColliderComponent
         void UpdateScaleForShapeConfigs() override;
         void UpdateScaleForShapeConfigs() override;
     };
     };

+ 41 - 0
Gems/PhysX/Code/Tests/DebugDrawTests.cpp

@@ -9,8 +9,14 @@
 #include <AzFramework/UnitTest/TestDebugDisplayRequests.h>
 #include <AzFramework/UnitTest/TestDebugDisplayRequests.h>
 #include <EditorTestUtilities.h>
 #include <EditorTestUtilities.h>
 #include <EditorColliderComponent.h>
 #include <EditorColliderComponent.h>
+#include <EditorShapeColliderComponent.h>
 #include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
 #include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
 #include <AZTestShared/Math/MathTestHelpers.h>
 #include <AZTestShared/Math/MathTestHelpers.h>
+#include <AZTestShared/Utils/Utils.h>
+#include <LmbrCentral/Shape/BoxShapeComponentBus.h>
+#include <LmbrCentral/Shape/EditorShapeComponentBus.h>
+
+#pragma optimize("", off)
 
 
 namespace PhysXEditorTests
 namespace PhysXEditorTests
 {
 {
@@ -230,4 +236,39 @@ namespace PhysXEditorTests
 
 
         EXPECT_TRUE(debugDrawAabb.IsClose(colliderAabb, 1e-3f));
         EXPECT_TRUE(debugDrawAabb.IsClose(colliderAabb, 1e-3f));
     }
     }
+
+    TEST_F(PhysXEditorFixture, ShapeCollider_BoxWithTranslationOffset_DebugDrawCorrect)
+    {
+        EntityPtr boxShapeEntity = CreateInactiveEditorEntity("BoxShape");
+        AZ::EntityId boxShapeEntityId = boxShapeEntity->GetId();
+        boxShapeEntity->CreateComponent<AzToolsFramework::Components::EditorNonUniformScaleComponent>();
+        boxShapeEntity->CreateComponent(LmbrCentral::EditorBoxShapeComponentTypeId);
+        boxShapeEntity->CreateComponent<PhysX::EditorShapeColliderComponent>();
+        boxShapeEntity->Activate();
+
+        AZ::Transform transform(AZ::Vector3(1.0f, 2.0f, 3.0f), AZ::Quaternion(0.4f, -0.2f, -0.4f, 0.8f), 0.7f);
+        AZ::TransformBus::Event(boxShapeEntityId, &AZ::TransformBus::Events::SetWorldTM, transform);
+        AZ::NonUniformScaleRequestBus::Event(boxShapeEntityId, &AZ::NonUniformScaleRequests::SetScale, AZ::Vector3(1.0f, 1.5f, 2.0f));
+        LmbrCentral::BoxShapeComponentRequestsBus::Event(
+            boxShapeEntityId, &LmbrCentral::BoxShapeComponentRequests::SetBoxDimensions, AZ::Vector3(3.0f, 4.0f, 5.0f));
+        LmbrCentral::ShapeComponentRequestsBus::Event(
+            boxShapeEntityId, &LmbrCentral::ShapeComponentRequests::SetTranslationOffset, AZ::Vector3(2.0f, -5.0f, 3.0f));
+        // turn off the shape visibility, so that only the shape collider component debug draws
+        LmbrCentral::EditorShapeComponentRequestsBus::Event(
+            boxShapeEntityId, &LmbrCentral::EditorShapeComponentRequests::SetVisibleInEditor, false);
+
+        UnitTest::TestDebugDisplayRequests testDebugDisplayRequests;
+        AzFramework::EntityDebugDisplayEventBus::Event(
+            boxShapeEntityId,
+            &AzFramework::EntityDebugDisplayEvents::DisplayEntityViewport,
+            AzFramework::ViewportInfo{ 0 },
+            testDebugDisplayRequests);
+        const AZ::Aabb debugDrawAabb = testDebugDisplayRequests.GetAabb();
+
+        EXPECT_THAT(debugDrawAabb.GetMin(), UnitTest::IsClose(AZ::Vector3(-7.246f, -6.302f, -2.46f)));
+        EXPECT_THAT(debugDrawAabb.GetMax(), UnitTest::IsClose(AZ::Vector3(0.51f, 0.25f, 5.1f)));
+    }
+
 } // namespace PhysXEditorTests
 } // namespace PhysXEditorTests
+
+#pragma optimize("", on)

+ 4 - 0
Gems/PhysX/Code/Tests/EditorTestUtilities.cpp

@@ -43,6 +43,8 @@ namespace PhysXEditorTests
 
 
     void PhysXEditorFixture::SetUp()
     void PhysXEditorFixture::SetUp()
     {
     {
+        UnitTest::RegistryTestHelper::SetUp(LmbrCentral::ShapeComponentTranslationOffsetEnabled, true);
+
         if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
         if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
         {
         {
             //in case a test modifies the default world config setup a config without getting the default(eg. SetWorldConfiguration_ForwardsConfigChangesToWorldRequestBus)
             //in case a test modifies the default world config setup a config without getting the default(eg. SetWorldConfiguration_ForwardsConfigChangesToWorldRequestBus)
@@ -68,6 +70,8 @@ namespace PhysXEditorTests
         {
         {
             physicsSystem->RemoveScene(m_defaultSceneHandle);
             physicsSystem->RemoveScene(m_defaultSceneHandle);
         }
         }
+
+        UnitTest::RegistryTestHelper::TearDown();
     }
     }
 
 
     void PhysXEditorFixture::ConnectToPVD()
     void PhysXEditorFixture::ConnectToPVD()

+ 2 - 0
Gems/PhysX/Code/Tests/EditorTestUtilities.h

@@ -12,6 +12,7 @@
 #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
 #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
 #include <AzFramework/Physics/SystemBus.h>
 #include <AzFramework/Physics/SystemBus.h>
 #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
 #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
+#include <AZTestShared/Utils/Utils.h>
 
 
 #include <System/PhysXSystem.h>
 #include <System/PhysXSystem.h>
 
 
@@ -43,6 +44,7 @@ namespace PhysXEditorTests
     class PhysXEditorFixture
     class PhysXEditorFixture
         : public UnitTest::AllocatorsTestFixture
         : public UnitTest::AllocatorsTestFixture
         , public Physics::DefaultWorldBus::Handler
         , public Physics::DefaultWorldBus::Handler
+        , public UnitTest::RegistryTestHelper
     {
     {
     public:
     public:
         void SetUp() override;
         void SetUp() override;

+ 128 - 10
Gems/PhysX/Code/Tests/ShapeColliderComponentTests.cpp

@@ -7,26 +7,27 @@
  */
  */
 
 
 #include <AzCore/UnitTest/TestTypes.h>
 #include <AzCore/UnitTest/TestTypes.h>
-#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
 #include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
 #include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
-#include <Tests/EditorTestUtilities.h>
+#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
 #include <EditorColliderComponent.h>
 #include <EditorColliderComponent.h>
-#include <EditorShapeColliderComponent.h>
-#include <EditorRigidBodyComponent.h>
 #include <EditorForceRegionComponent.h>
 #include <EditorForceRegionComponent.h>
-#include <ShapeColliderComponent.h>
-#include <RigidBodyComponent.h>
-#include <StaticRigidBodyComponent.h>
-#include <RigidBodyStatic.h>
+#include <EditorRigidBodyComponent.h>
+#include <EditorShapeColliderComponent.h>
 #include <LmbrCentral/Shape/BoxShapeComponentBus.h>
 #include <LmbrCentral/Shape/BoxShapeComponentBus.h>
+#include <LmbrCentral/Shape/CompoundShapeComponentBus.h>
 #include <LmbrCentral/Shape/CylinderShapeComponentBus.h>
 #include <LmbrCentral/Shape/CylinderShapeComponentBus.h>
 #include <LmbrCentral/Shape/PolygonPrismShapeComponentBus.h>
 #include <LmbrCentral/Shape/PolygonPrismShapeComponentBus.h>
-#include <LmbrCentral/Shape/SphereShapeComponentBus.h>
-#include <LmbrCentral/Shape/CompoundShapeComponentBus.h>
 #include <LmbrCentral/Shape/QuadShapeComponentBus.h>
 #include <LmbrCentral/Shape/QuadShapeComponentBus.h>
+#include <LmbrCentral/Shape/SphereShapeComponentBus.h>
 #include <PhysX/ForceRegionComponentBus.h>
 #include <PhysX/ForceRegionComponentBus.h>
+#include <PhysX/MathConversion.h>
 #include <PhysX/PhysXLocks.h>
 #include <PhysX/PhysXLocks.h>
 #include <PhysX/SystemComponentBus.h>
 #include <PhysX/SystemComponentBus.h>
+#include <RigidBodyComponent.h>
+#include <RigidBodyStatic.h>
+#include <ShapeColliderComponent.h>
+#include <StaticRigidBodyComponent.h>
+#include <Tests/EditorTestUtilities.h>
 #include <Tests/PhysXTestCommon.h>
 #include <Tests/PhysXTestCommon.h>
 
 
 namespace PhysXEditorTests
 namespace PhysXEditorTests
@@ -151,6 +152,123 @@ namespace PhysXEditorTests
         EXPECT_TRUE(aabb.GetMin().IsClose(-0.5f * boxDimensions));
         EXPECT_TRUE(aabb.GetMin().IsClose(-0.5f * boxDimensions));
     }
     }
 
 
+    TEST_F(PhysXEditorFixture, EditorShapeColliderComponent_ShapeColliderWithBoxAndTranslationOffset_CorrectEditorStaticBodyGeometry)
+    {
+        // create an editor entity with a shape collider component, a non-uniform scale component and a box shape component
+        EntityPtr editorEntity = CreateInactiveEditorEntity("ShapeColliderComponentEditorEntity");
+        editorEntity->CreateComponent(LmbrCentral::EditorBoxShapeComponentTypeId);
+        editorEntity->CreateComponent<PhysX::EditorShapeColliderComponent>();
+        editorEntity->CreateComponent<AzToolsFramework::Components::EditorNonUniformScaleComponent>();
+        editorEntity->Activate();
+        AZ::EntityId editorEntityId = editorEntity->GetId();
+
+        AZ::Transform transform(AZ::Vector3(2.0f, -6.0f, 5.0f), AZ::Quaternion(0.3f, -0.3f, 0.1f, 0.9f), 1.6f);
+        AZ::TransformBus::Event(editorEntityId, &AZ::TransformBus::Events::SetWorldTM, transform);
+        AZ::NonUniformScaleRequestBus::Event(editorEntityId, &AZ::NonUniformScaleRequests::SetScale, AZ::Vector3(2.0f, 2.5f, 0.5f));
+        LmbrCentral::BoxShapeComponentRequestsBus::Event(
+            editorEntityId, &LmbrCentral::BoxShapeComponentRequests::SetBoxDimensions, AZ::Vector3(5.0f, 8.0f, 6.0f));
+        LmbrCentral::ShapeComponentRequestsBus::Event(
+            editorEntityId, &LmbrCentral::ShapeComponentRequests::SetTranslationOffset, AZ::Vector3(-4.0f, 3.0f, -1.0f));
+
+        AzPhysics::SimulatedBody* simulatedBody = nullptr;
+        AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(simulatedBody, editorEntity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetSimulatedBody);
+        const auto* pxRigidStatic = static_cast<const physx::PxRigidStatic*>(simulatedBody->GetNativePointer());
+
+        AZ::Aabb aabb = PxMathConvert(pxRigidStatic->getWorldBounds(1.0f));
+        EXPECT_THAT(aabb.GetMin(), UnitTest::IsClose(AZ::Vector3(-25.488f, -10.16f, -11.448f)));
+        EXPECT_THAT(aabb.GetMax(), UnitTest::IsClose(AZ::Vector3(1.136f, 18.32f, 16.584f)));
+    }
+
+    TEST_F(PhysXEditorFixture, EditorShapeColliderComponent_ShapeColliderWithBoxAndTranslationOffset_CorrectEditorDynamicBodyGeometry)
+    {
+        // create an editor entity with a shape collider component, a non-uniform scale component and a box shape component
+        EntityPtr editorEntity = CreateInactiveEditorEntity("ShapeColliderComponentEditorEntity");
+        editorEntity->CreateComponent(LmbrCentral::EditorBoxShapeComponentTypeId);
+        editorEntity->CreateComponent<PhysX::EditorShapeColliderComponent>();
+        editorEntity->CreateComponent<PhysX::EditorRigidBodyComponent>();
+        editorEntity->CreateComponent<AzToolsFramework::Components::EditorNonUniformScaleComponent>();
+        editorEntity->Activate();
+        AZ::EntityId editorEntityId = editorEntity->GetId();
+
+        AZ::Transform transform(AZ::Vector3(-5.0f, -1.0f, 3.0f), AZ::Quaternion(0.7f, 0.5f, -0.1f, 0.5f), 1.2f);
+        AZ::TransformBus::Event(editorEntityId, &AZ::TransformBus::Events::SetWorldTM, transform);
+        AZ::NonUniformScaleRequestBus::Event(editorEntityId, &AZ::NonUniformScaleRequests::SetScale, AZ::Vector3(1.5f, 1.5f, 4.0f));
+        LmbrCentral::BoxShapeComponentRequestsBus::Event(
+            editorEntityId, &LmbrCentral::BoxShapeComponentRequests::SetBoxDimensions, AZ::Vector3(6.0f, 4.0f, 1.0f));
+        LmbrCentral::ShapeComponentRequestsBus::Event(
+            editorEntityId, &LmbrCentral::ShapeComponentRequests::SetTranslationOffset, AZ::Vector3(6.0f, -5.0f, -4.0f));
+
+        editorEntity->Deactivate();
+        editorEntity->Activate();
+
+        AzPhysics::SimulatedBody* simulatedBody = nullptr;
+        AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(simulatedBody, editorEntity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetSimulatedBody);
+        const auto* pxRigidDynamic = static_cast<const physx::PxRigidDynamic*>(simulatedBody->GetNativePointer());
+
+        AZ::Aabb aabb = PxMathConvert(pxRigidDynamic->getWorldBounds(1.0f));
+        EXPECT_THAT(aabb.GetMin(), UnitTest::IsClose(AZ::Vector3(-20.264f, 15.68f, -6.864f)));
+        EXPECT_THAT(aabb.GetMax(), UnitTest::IsClose(AZ::Vector3(-7.592f, 26.0f, 6.672f)));
+    }
+
+    TEST_F(PhysXEditorFixture, EditorShapeColliderComponent_ShapeColliderWithBoxAndTranslationOffset_CorrectRuntimeStaticBodyGeometry)
+    {
+        // create an editor entity with a shape collider component, a non-uniform scale component and a box shape component
+        EntityPtr editorEntity = CreateInactiveEditorEntity("ShapeColliderComponentEditorEntity");
+        editorEntity->CreateComponent(LmbrCentral::EditorBoxShapeComponentTypeId);
+        editorEntity->CreateComponent<PhysX::EditorShapeColliderComponent>();
+        editorEntity->CreateComponent<AzToolsFramework::Components::EditorNonUniformScaleComponent>();
+        editorEntity->Activate();
+        AZ::EntityId editorEntityId = editorEntity->GetId();
+
+        AZ::Transform transform(AZ::Vector3(7.0f, 2.0f, 4.0f), AZ::Quaternion(0.4f, -0.8f, 0.4f, 0.2f), 2.5f);
+        AZ::TransformBus::Event(editorEntityId, &AZ::TransformBus::Events::SetWorldTM, transform);
+        AZ::NonUniformScaleRequestBus::Event(editorEntityId, &AZ::NonUniformScaleRequests::SetScale, AZ::Vector3(0.8f, 2.0f, 1.5f));
+        LmbrCentral::BoxShapeComponentRequestsBus::Event(
+            editorEntityId, &LmbrCentral::BoxShapeComponentRequests::SetBoxDimensions, AZ::Vector3(1.0f, 4.0f, 7.0f));
+        LmbrCentral::ShapeComponentRequestsBus::Event(
+            editorEntityId, &LmbrCentral::ShapeComponentRequests::SetTranslationOffset, AZ::Vector3(6.0f, -1.0f, -2.0f));
+
+        EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
+
+        AzPhysics::SimulatedBody* simulatedBody = nullptr;
+        AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(simulatedBody, gameEntity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetSimulatedBody);
+        const auto* pxRigidStatic = static_cast<const physx::PxRigidStatic*>(simulatedBody->GetNativePointer());
+
+        AZ::Aabb aabb = PxMathConvert(pxRigidStatic->getWorldBounds(1.0f));
+        EXPECT_THAT(aabb.GetMin(), UnitTest::IsClose(AZ::Vector3(-4.8f, -14.14f, 5.265f)));
+        EXPECT_THAT(aabb.GetMax(), UnitTest::IsClose(AZ::Vector3(12.4f, 15.02f, 31.895f)));
+    }
+
+    TEST_F(PhysXEditorFixture, EditorShapeColliderComponent_ShapeColliderWithBoxAndTranslationOffset_CorrectRuntimeDynamicBodyGeometry)
+    {
+        // create an editor entity with a shape collider component, a non-uniform scale component and a box shape component
+        EntityPtr editorEntity = CreateInactiveEditorEntity("ShapeColliderComponentEditorEntity");
+        editorEntity->CreateComponent(LmbrCentral::EditorBoxShapeComponentTypeId);
+        editorEntity->CreateComponent<PhysX::EditorShapeColliderComponent>();
+        editorEntity->CreateComponent<PhysX::EditorRigidBodyComponent>();
+        editorEntity->CreateComponent<AzToolsFramework::Components::EditorNonUniformScaleComponent>();
+        editorEntity->Activate();
+        AZ::EntityId editorEntityId = editorEntity->GetId();
+
+        AZ::Transform transform(AZ::Vector3(4.0f, 4.0f, 2.0f), AZ::Quaternion(0.1f, 0.3f, 0.9f, 0.3f), 0.8f);
+        AZ::TransformBus::Event(editorEntityId, &AZ::TransformBus::Events::SetWorldTM, transform);
+        AZ::NonUniformScaleRequestBus::Event(editorEntityId, &AZ::NonUniformScaleRequests::SetScale, AZ::Vector3(2.5f, 1.0f, 2.0f));
+        LmbrCentral::BoxShapeComponentRequestsBus::Event(
+            editorEntityId, &LmbrCentral::BoxShapeComponentRequests::SetBoxDimensions, AZ::Vector3(4.0f, 2.0f, 7.0f));
+        LmbrCentral::ShapeComponentRequestsBus::Event(
+            editorEntityId, &LmbrCentral::ShapeComponentRequests::SetTranslationOffset, AZ::Vector3(-2.0f, 7.0f, -1.0f));
+
+        EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
+
+        AzPhysics::SimulatedBody* simulatedBody = nullptr;
+        AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(simulatedBody, gameEntity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetSimulatedBody);
+        const auto* pxRigidDynamic = static_cast<const physx::PxRigidDynamic*>(simulatedBody->GetNativePointer());
+
+        AZ::Aabb aabb = PxMathConvert(pxRigidDynamic->getWorldBounds(1.0f));
+        EXPECT_THAT(aabb.GetMin(), UnitTest::IsClose(AZ::Vector3(-1.664f, -8.352f, -0.88f)));
+        EXPECT_THAT(aabb.GetMax(), UnitTest::IsClose(AZ::Vector3(9.536f, 2.848f, 9.04f)));
+    }
+
     void SetPolygonPrismVertices(AZ::EntityId entityId, const AZStd::vector<AZ::Vector2>& vertices)
     void SetPolygonPrismVertices(AZ::EntityId entityId, const AZStd::vector<AZ::Vector2>& vertices)
     {
     {
         AZ::PolygonPrismPtr polygonPrism;
         AZ::PolygonPrismPtr polygonPrism;