From 90e52d69bc465519707c89d22c0568882fcc6637 Mon Sep 17 00:00:00 2001 From: greerdv Date: Tue, 13 Apr 2021 10:50:07 +0100 Subject: [PATCH] fixing bug with subdivision level for runtime asset colliders and adding caching for collider aabbs --- .../Physics/ShapeConfiguration.cpp | 1 + .../AzFramework/Physics/ShapeConfiguration.h | 1 + .../Code/Source/BaseColliderComponent.cpp | 7 +++---- .../Code/Source/EditorColliderComponent.cpp | 20 ++++++++++++++----- .../Code/Source/EditorColliderComponent.h | 2 ++ 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp b/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp index 44c24758f3..f01e42a443 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp @@ -142,6 +142,7 @@ namespace Physics ->Field("PhysicsAsset", &PhysicsAssetShapeConfiguration::m_asset) ->Field("AssetScale", &PhysicsAssetShapeConfiguration::m_assetScale) ->Field("UseMaterialsFromAsset", &PhysicsAssetShapeConfiguration::m_useMaterialsFromAsset) + ->Field("SubdivisionLevel", &PhysicsAssetShapeConfiguration::m_subdivisionLevel) ; if (auto editContext = serializeContext->GetEditContext()) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.h index 8afe6851b7..b3d04a10c9 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.h @@ -141,6 +141,7 @@ namespace Physics AZ::Data::Asset m_asset{ AZ::Data::AssetLoadBehavior::PreLoad }; AZ::Vector3 m_assetScale = AZ::Vector3::CreateOne(); bool m_useMaterialsFromAsset = true; + AZ::u8 m_subdivisionLevel = 4; ///< The level of subdivision if a primitive shape is replaced with a convex mesh due to scaling. }; class NativeShapeConfiguration : public ShapeConfiguration diff --git a/Gems/PhysX/Code/Source/BaseColliderComponent.cpp b/Gems/PhysX/Code/Source/BaseColliderComponent.cpp index f4bc86ef93..c67cc105d8 100644 --- a/Gems/PhysX/Code/Source/BaseColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/BaseColliderComponent.cpp @@ -330,10 +330,9 @@ namespace PhysX } const bool hasNonUniformScale = (AZ::NonUniformScaleRequestBus::FindFirstHandler(GetEntityId()) != nullptr); - // the value for the subdivision level doesn't matter in the runtime, because any approximation of primitives will already have - // happened in the editor, so can pass an arbitrary value here - AZ::u8 subdivisionLevel = 0; - Utils::GetShapesFromAsset(physicsAssetConfiguration, componentColliderConfiguration, hasNonUniformScale, subdivisionLevel, m_shapes); + AZ::u8 subdivisionLevel = physicsAssetConfiguration.m_subdivisionLevel; + Utils::GetShapesFromAsset(physicsAssetConfiguration, componentColliderConfiguration, hasNonUniformScale, + physicsAssetConfiguration.m_subdivisionLevel, m_shapes); return true; } diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp index 974ce23810..8c31746931 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp @@ -513,6 +513,8 @@ namespace PhysX break; case Physics::ShapeType::PhysicsAsset: colliderComponent = gameEntity->CreateComponent(); + + m_shapeConfiguration.m_physicsAsset.m_configuration.m_subdivisionLevel = m_shapeConfiguration.m_subdivisionLevel; colliderComponent->SetShapeConfigurationList({ AZStd::make_pair(sharedColliderConfig, AZStd::make_shared(m_shapeConfiguration.m_physicsAsset.m_configuration)) }); @@ -560,6 +562,8 @@ namespace PhysX void EditorColliderComponent::CreateStaticEditorCollider() { + m_cachedAabbDirty = true; + // Don't create static rigid body in the editor if current entity components // don't allow creation of runtime static rigid body component if (!StaticRigidBodyUtils::CanCreateRuntimeComponent(*GetEntity())) @@ -1014,11 +1018,17 @@ namespace PhysX // PhysX::ColliderShapeBus AZ::Aabb EditorColliderComponent::GetColliderShapeAabb() { - return PhysX::Utils::GetColliderAabb(GetWorldTM() - , m_hasNonUniformScale - , m_shapeConfiguration.m_subdivisionLevel - , m_shapeConfiguration.GetCurrent() - , m_configuration); + if (m_cachedAabbDirty) + { + m_cachedAabb = PhysX::Utils::GetColliderAabb(GetWorldTM() + , m_hasNonUniformScale + , m_shapeConfiguration.m_subdivisionLevel + , m_shapeConfiguration.GetCurrent() + , m_configuration); + m_cachedAabbDirty = false; + } + + return m_cachedAabb; } void EditorColliderComponent::UpdateShapeConfigurationScale() diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.h b/Gems/PhysX/Code/Source/EditorColliderComponent.h index 65c7a9c67f..f179525802 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.h +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.h @@ -261,6 +261,8 @@ namespace PhysX bool m_hasNonUniformScale = false; //!< Whether there is a non-uniform scale component on this entity. AZ::Vector3 m_cachedNonUniformScale = AZ::Vector3::CreateOne(); //!< Caches the current non-uniform scale. mutable AZStd::optional m_scaledPrimitive; //!< Approximation for non-uniformly scaled primitive. + AZ::Aabb m_cachedAabb = AZ::Aabb::CreateNull(); //!< Cache the Aabb to avoid recalculating it. + bool m_cachedAabbDirty = true; //!< Track whether the cached Aabb needs to be recomputed. AZ::ComponentDescriptor::StringWarningArray m_componentWarnings; };