Răsfoiți Sursa

Added possibility to extract physics shape configuration without PhysX Gem bus (#18900)

* Added interface to obtain collider shape configuration

Signed-off-by: Norbert Prokopiuk <[email protected]>

* Fixed headers and restored original formating

Signed-off-by: Norbert Prokopiuk <[email protected]>

* Applied @michalpelka and @patrykantosz review suggestions

Signed-off-by: Norbert Prokopiuk <[email protected]>

* Added missing mocks for GetShapeConfiguration method

Signed-off-by: Norbert Prokopiuk <[email protected]>

---------

Signed-off-by: Norbert Prokopiuk <[email protected]>
Norbert Prokopiuk 1 lună în urmă
părinte
comite
8307686136

+ 3 - 0
Code/Framework/AzFramework/AzFramework/Physics/Shape.h

@@ -134,6 +134,9 @@ namespace Physics
         //! Retrieve this shape AABB using local coordinates
         virtual AZ::Aabb GetAabbLocal() const = 0;
 
+        //! Retrieve this shape configuration
+        virtual AZStd::shared_ptr<ShapeConfiguration> GetShapeConfiguration() const = 0;
+
         //! Fills in the vertices and indices buffers representing this shape.
         //! If vertices are returned but not indices you may assume the vertices are in triangle list format.
         //! @param vertices A buffer to be filled with vertices

+ 39 - 0
Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.h

@@ -13,6 +13,8 @@
 #include <AzCore/Math/Transform.h>
 #include <AzCore/Math/Vector2.h>
 #include <AzCore/Math/Vector3.h>
+#include <AzCore/std/smart_ptr/make_shared.h>
+#include <AzCore/std/smart_ptr/shared_ptr.h>
 #include <AzFramework/Physics/HeightfieldProviderBus.h>
 
 namespace AZ
@@ -61,6 +63,7 @@ namespace Physics
         explicit ShapeConfiguration(const AZ::Vector3& scale = ShapeConstants::DefaultScale);
         virtual ~ShapeConfiguration() = default;
         virtual ShapeType GetShapeType() const = 0;
+        virtual AZStd::shared_ptr<ShapeConfiguration> Clone() const = 0;
 
         AZ::Vector3 m_scale = ShapeConstants::DefaultScale;
     };
@@ -75,6 +78,10 @@ namespace Physics
             float radius = ShapeConstants::DefaultSphereRadius, const AZ::Vector3& scale = ShapeConstants::DefaultScale);
 
         ShapeType GetShapeType() const override { return ShapeType::Sphere; }
+        AZStd::shared_ptr<ShapeConfiguration> Clone() const override
+        {
+            return AZStd::make_shared<SphereShapeConfiguration>(*this);
+        }
         AZ::Sphere ToSphere(const AZ::Transform& transform = AZ::Transform::CreateIdentity()) const;
 
         float m_radius = ShapeConstants::DefaultSphereRadius;
@@ -91,6 +98,10 @@ namespace Physics
             const AZ::Vector3& scale = ShapeConstants::DefaultScale);
 
         ShapeType GetShapeType() const override { return ShapeType::Box; }
+        AZStd::shared_ptr<ShapeConfiguration> Clone() const override
+        {
+            return AZStd::make_shared<BoxShapeConfiguration>(*this);
+        }
         AZ::Obb ToObb(const AZ::Transform& transform = AZ::Transform::CreateIdentity()) const;
 
         AZ::Vector3 m_dimensions = ShapeConstants::DefaultBoxDimensions;
@@ -108,6 +119,10 @@ namespace Physics
             const AZ::Vector3& scale = ShapeConstants::DefaultScale);
 
         ShapeType GetShapeType() const override { return ShapeType::Capsule; }
+        AZStd::shared_ptr<ShapeConfiguration> Clone() const override
+        {
+            return AZStd::make_shared<CapsuleShapeConfiguration>(*this);
+        }
         AZ::Capsule ToCapsule(const AZ::Transform& transform = AZ::Transform::CreateIdentity()) const;
 
         float m_height = ShapeConstants::DefaultCapsuleHeight; //!< Total height, including hemispherical caps, oriented along z-axis.
@@ -124,6 +139,10 @@ namespace Physics
         AZ_CLASS_ALLOCATOR(ConvexHullShapeConfiguration, AZ::SystemAllocator);
 
         ShapeType GetShapeType() const override { return ShapeType::ConvexHull; }
+        AZStd::shared_ptr<ShapeConfiguration> Clone() const override
+        {
+            return AZStd::make_shared<ConvexHullShapeConfiguration>(*this);
+        }
 
         const void* m_vertexData = nullptr;
         AZ::u32 m_vertexCount = 0;
@@ -146,6 +165,10 @@ namespace Physics
         AZ_CLASS_ALLOCATOR(TriangleMeshShapeConfiguration, AZ::SystemAllocator);
 
         ShapeType GetShapeType() const override { return ShapeType::TriangleMesh; }
+        AZStd::shared_ptr<ShapeConfiguration> Clone() const override
+        {
+            return AZStd::make_shared<TriangleMeshShapeConfiguration>(*this);
+        }
 
         const void* m_vertexData = nullptr;
         AZ::u32 m_vertexCount = 0;
@@ -167,6 +190,10 @@ namespace Physics
         AZ_RTTI(PhysicsAssetShapeConfiguration, "{1C0046D9-BC9E-4F93-9F0E-D62654FB18EA}", ShapeConfiguration);
         static void Reflect(AZ::ReflectContext* context);
         ShapeType GetShapeType() const override;
+        AZStd::shared_ptr<ShapeConfiguration> Clone() const override
+        {
+            return AZStd::make_shared<PhysicsAssetShapeConfiguration>(*this);
+        }
 
         AZ::Data::Asset<AZ::Data::AssetData> m_asset{ AZ::Data::AssetLoadBehavior::PreLoad };
         AZ::Vector3 m_assetScale = AZ::Vector3::CreateOne();
@@ -182,6 +209,10 @@ namespace Physics
         static void Reflect(AZ::ReflectContext* context);
 
         ShapeType GetShapeType() const override { return ShapeType::Native; }
+        AZStd::shared_ptr<ShapeConfiguration> Clone() const override
+        {
+            return AZStd::make_shared<NativeShapeConfiguration>(*this);
+        }
 
         void* m_nativeShapePtr = nullptr; ///< Native shape ptr. This will not be serialised
         AZ::Vector3 m_nativeShapeScale = AZ::Vector3::CreateOne(); ///< Native shape scale. This will be serialised
@@ -207,6 +238,10 @@ namespace Physics
         ~CookedMeshShapeConfiguration();
 
         ShapeType GetShapeType() const override;
+        AZStd::shared_ptr<ShapeConfiguration> Clone() const override
+        {
+            return AZStd::make_shared<CookedMeshShapeConfiguration>(*this);
+        }
 
         //! Sets the cooked data. This will release the cached mesh.
         //! Input data has to be in the physics engine specific format.
@@ -246,6 +281,10 @@ namespace Physics
         {
             return ShapeType::Heightfield;
         }
+        AZStd::shared_ptr<ShapeConfiguration> Clone() const override
+        {
+            return AZStd::make_shared<HeightfieldShapeConfiguration>(*this);
+        }
 
         const void* GetCachedNativeHeightfield() const;
         void* GetCachedNativeHeightfield();

+ 1 - 0
Gems/PhysX/Common/Code/Mocks/PhysX/MockPhysicsShape.h

@@ -23,6 +23,7 @@ namespace UnitTest
         MOCK_CONST_METHOD0(GetCollisionGroup, AzPhysics::CollisionGroup ());
         MOCK_CONST_METHOD0(GetCollisionLayer, AzPhysics::CollisionLayer ());
         MOCK_CONST_METHOD0(GetContactOffset, float ());
+        MOCK_CONST_METHOD0(GetShapeConfiguration, AZStd::shared_ptr<Physics::ShapeConfiguration> ());
         MOCK_CONST_METHOD3(GetGeometry, void(AZStd::vector<AZ::Vector3>&, AZStd::vector<AZ::u32>&, const AZ::Aabb*));
         MOCK_CONST_METHOD0(GetLocalPose, AZStd::pair<AZ::Vector3, AZ::Quaternion> ());
         MOCK_CONST_METHOD0(GetMaterial, AZStd::shared_ptr<Physics::Material>());

+ 8 - 2
Gems/PhysX/Core/Code/Source/Shape.cpp

@@ -10,6 +10,7 @@
 
 #include <AzFramework/Physics/Common/PhysicsSceneQueries.h>
 #include <AzFramework/Physics/Material/PhysicsMaterial.h>
+#include <AzFramework/Physics/ShapeConfiguration.h>
 #include <Common/PhysXSceneQueryHelpers.h>
 #include <PhysX/PhysXLocks.h>
 #include <PhysX/Utils.h>
@@ -68,6 +69,7 @@ namespace PhysX
     Shape::Shape(const Physics::ColliderConfiguration& colliderConfiguration, const Physics::ShapeConfiguration& shapeConfiguration)
         : m_collisionLayer(colliderConfiguration.m_collisionLayer)
     {
+        m_shapeConfiguration = shapeConfiguration.Clone();
         if (physx::PxShape* newShape = Utils::CreatePxShapeFromConfig(colliderConfiguration, shapeConfiguration, m_collisionGroup))
         {
             m_pxShape = PxShapeUniquePtr(newShape, AZStd::bind(&Shape::ReleasePxShape, this, newShape));
@@ -440,8 +442,12 @@ namespace PhysX
         return nullptr;
     }
 
-    void Shape::GetGeometry(AZStd::vector<AZ::Vector3>& vertices, AZStd::vector<AZ::u32>& indices,
-        const AZ::Aabb* optionalBounds) const
+    AZStd::shared_ptr<Physics::ShapeConfiguration> Shape::GetShapeConfiguration() const
+    {
+        return m_shapeConfiguration;
+    }
+
+    void Shape::GetGeometry(AZStd::vector<AZ::Vector3>& vertices, AZStd::vector<AZ::u32>& indices, const AZ::Aabb* optionalBounds) const
     {
         if (!m_pxShape)
         {

+ 3 - 0
Gems/PhysX/Core/Code/Source/Shape.h

@@ -12,6 +12,7 @@
 #include <AzFramework/Physics/Shape.h>
 #include <AzFramework/Physics/ShapeConfiguration.h>
 #include <AzCore/std/smart_ptr/enable_shared_from_this.h>
+#include <AzCore/std/smart_ptr/shared_ptr.h>
 
 #include <AzFramework/Physics/Collision/CollisionGroups.h>
 #include <AzFramework/Physics/Collision/CollisionLayers.h>
@@ -66,6 +67,7 @@ namespace PhysX
         AzPhysics::SceneQueryHit RayCastLocal(const AzPhysics::RayCastRequest& localSpaceRequest) override;
         AZ::Aabb GetAabb(const AZ::Transform& worldTransform) const override;
         AZ::Aabb GetAabbLocal() const override;
+        AZStd::shared_ptr<Physics::ShapeConfiguration> GetShapeConfiguration() const override;
         void GetGeometry(AZStd::vector<AZ::Vector3>& vertices, AZStd::vector<AZ::u32>& indices,
             const AZ::Aabb* optionalBounds = nullptr) const override;
 
@@ -90,6 +92,7 @@ namespace PhysX
         AZStd::vector<AZStd::shared_ptr<PhysX::Material>> m_materials;
         AzPhysics::CollisionLayer m_collisionLayer;
         AzPhysics::CollisionGroup m_collisionGroup;
+        AZStd::shared_ptr<Physics::ShapeConfiguration> m_shapeConfiguration;
         AZ::Crc32 m_tag;
         physx::PxActor* m_attachedActor = nullptr;
     };

+ 1 - 0
Gems/ScriptCanvasPhysics/Code/Tests/ScriptCanvasPhysicsTest.cpp

@@ -186,6 +186,7 @@ namespace ScriptCanvasPhysicsTests
         MOCK_METHOD0(DetachedFromActor, void());
         MOCK_METHOD2(RayCast, AzPhysics::SceneQueryHit(const AzPhysics::RayCastRequest& worldSpaceRequest, const AZ::Transform& worldTransform));
         MOCK_METHOD1(RayCastLocal, AzPhysics::SceneQueryHit(const AzPhysics::RayCastRequest& localSpaceRequest));
+        MOCK_CONST_METHOD0(GetShapeConfiguration, AZStd::shared_ptr<Physics::ShapeConfiguration> ());
         MOCK_CONST_METHOD3(GetGeometry, void(AZStd::vector<AZ::Vector3>&, AZStd::vector<AZ::u32>&, const AZ::Aabb*));
         MOCK_CONST_METHOD1(GetAabb, AZ::Aabb(const AZ::Transform& worldTransform));
         MOCK_CONST_METHOD0(GetAabbLocal, AZ::Aabb());