From fd07f907bc8fabfc6ef7b2a9ffd562c474bd36e9 Mon Sep 17 00:00:00 2001 From: ibtehajn <81370835+ibtehajn@users.noreply.github.com> Date: Wed, 28 Jul 2021 13:22:24 +0100 Subject: [PATCH 1/4] Implement axis locking options for rigid bodies Linear and angular motion of rigid bodies can now be restricted along specific world-space axes. Signed-off-by: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> --- .../Configuration/RigidBodyConfiguration.cpp | 6 +++ .../Configuration/RigidBodyConfiguration.h | 10 ++++ .../Code/Source/EditorRigidBodyComponent.cpp | 27 ++++++++++ Gems/PhysX/Code/Source/Utils.cpp | 8 +++ Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp | 54 +++++++++++++++++++ 5 files changed, 105 insertions(+) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp index a61f6a4845..cfea76f1d7 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp @@ -123,6 +123,12 @@ namespace AzPhysics ->Field("Kinematic", &RigidBodyConfiguration::m_kinematic) ->Field("CCD Enabled", &RigidBodyConfiguration::m_ccdEnabled) ->Field("Compute Mass", &RigidBodyConfiguration::m_computeMass) + ->Field("Lock Linear X", &RigidBodyConfiguration::m_lockLinearX) + ->Field("Lock Linear Y", &RigidBodyConfiguration::m_lockLinearY) + ->Field("Lock Linear Z", &RigidBodyConfiguration::m_lockLinearZ) + ->Field("Lock Angular X", &RigidBodyConfiguration::m_lockAngularX) + ->Field("Lock Angular Y", &RigidBodyConfiguration::m_lockAngularY) + ->Field("Lock Angular Z", &RigidBodyConfiguration::m_lockAngularZ) ->Field("Mass", &RigidBodyConfiguration::m_mass) ->Field("Compute COM", &RigidBodyConfiguration::m_computeCenterOfMass) ->Field("Centre of mass offset", &RigidBodyConfiguration::m_centerOfMassOffset) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h index 59829e740c..46f2620938 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h @@ -62,6 +62,16 @@ namespace AzPhysics bool m_computeInertiaTensor = true; bool m_computeMass = true; + //! Flags to restrict motion along specific world-space axes. + bool m_lockLinearX = false; + bool m_lockLinearY = false; + bool m_lockLinearZ = false; + + //! Flags to restrict rotation around specific world-space axes. + bool m_lockAngularX = false; + bool m_lockAngularY = false; + bool m_lockAngularZ = false; + //! If set, non-simulated shapes will also be included in the mass properties calculation. bool m_includeAllShapesInMassCalculation = false; diff --git a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp index d27874f030..c94cc46ba4 100644 --- a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp @@ -156,6 +156,33 @@ namespace PhysX ->DataElement(AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_kinematic, "Kinematic", "Rigid body is kinematic") ->Attribute(AZ::Edit::Attributes::Visibility, &AzPhysics::RigidBodyConfiguration::GetKinematicVisibility) + + // Linear axis locking properties + ->ClassElement(AZ::Edit::ClassElements::Group, "Linear Axis Locking") + ->Attribute(AZ::Edit::Attributes::AutoExpand, false) + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearX, "Lock X", + "Lock linear momentum in X direction") + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearY, "Lock Y", + "Lock linear momentum in Y direction") + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearZ, "Lock Z", + "Lock linear momentum in Z direction") + + // Angular axis locking properties + ->ClassElement(AZ::Edit::ClassElements::Group, "Angular Axis Locking") + ->Attribute(AZ::Edit::Attributes::AutoExpand, false) + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularX, "Lock X", + "Lock angular momentum in X direction") + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularY, "Lock Y", + "Lock angular momentum in Y direction") + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularZ, "Lock Z", + "Lock angular momentum in Z direction") + ->ClassElement(AZ::Edit::ClassElements::Group, "Continuous Collision Detection") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->Attribute(AZ::Edit::Attributes::Visibility, &AzPhysics::RigidBodyConfiguration::GetCCDVisibility) diff --git a/Gems/PhysX/Code/Source/Utils.cpp b/Gems/PhysX/Code/Source/Utils.cpp index 4e5695e3c6..0b7ab9436b 100644 --- a/Gems/PhysX/Code/Source/Utils.cpp +++ b/Gems/PhysX/Code/Source/Utils.cpp @@ -1466,6 +1466,14 @@ namespace PhysX rigidDynamic->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, configuration.m_kinematic); rigidDynamic->setMaxAngularVelocity(configuration.m_maxAngularVelocity); + // Set axis locks. + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X, configuration.m_lockLinearX); + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y, configuration.m_lockLinearY); + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Z, configuration.m_lockLinearZ); + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X, configuration.m_lockAngularX); + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, configuration.m_lockAngularY); + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, configuration.m_lockAngularZ); + return rigidDynamic; } diff --git a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp index 770e47d477..76ee035b70 100644 --- a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp +++ b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp @@ -1102,6 +1102,60 @@ namespace PhysX SanityCheckValidFrustumParams(points.value(), validHeight, validBottomRadius, validTopRadius, validSubdivisions); } + TEST_F(PhysXSpecificTest, RigidBody_RigidBodyWithAxisLockFlagsCreated_InternalPhysXFlagsSetAccordingly) + { + // Helper function wrapping creation logic + auto CreateRigidBody = [this](bool linearX, bool linearY, bool linearZ, bool angularX, bool angularY, bool angularZ) -> AzPhysics::RigidBody* + { + AzPhysics::RigidBodyConfiguration rigidBodyConfig; + + rigidBodyConfig.m_lockLinearX = linearX; + rigidBodyConfig.m_lockLinearY = linearY; + rigidBodyConfig.m_lockLinearZ = linearZ; + + rigidBodyConfig.m_lockAngularX = angularX; + rigidBodyConfig.m_lockAngularY = angularY; + rigidBodyConfig.m_lockAngularZ = angularZ; + + if (auto* sceneInterface = AZ::Interface::Get()) + { + AzPhysics::SimulatedBodyHandle simBodyHandle = sceneInterface->AddSimulatedBody(m_testSceneHandle, &rigidBodyConfig); + return azdynamic_cast(sceneInterface->GetSimulatedBodyFromHandle(m_testSceneHandle, simBodyHandle)); + } + + return nullptr; + }; + + auto RemoveRigidBody = [this](AzPhysics::RigidBody*& rigidBody) + { + auto* sceneInterface = AZ::Interface::Get(); + if (rigidBody && sceneInterface) + { + sceneInterface->RemoveSimulatedBody(rigidBody->m_sceneOwner, rigidBody->m_bodyHandle); + } + rigidBody = nullptr; + }; + + auto TestLockFlags = [&CreateRigidBody, &RemoveRigidBody](bool linearX, bool linearY, bool linearZ, + bool angularX, bool angularY, bool angularZ, + physx::PxRigidDynamicLockFlags expectedFlags) + { + auto* rigidBody = CreateRigidBody(linearX, linearY, linearZ, angularX, angularY, angularZ); + ASSERT_TRUE(rigidBody != nullptr); + + physx::PxRigidDynamic* pxRigidBody = static_cast(rigidBody->GetNativePointer()); + EXPECT_EQ(pxRigidBody->getRigidDynamicLockFlags(), expectedFlags); + + RemoveRigidBody(rigidBody); + }; + + TestLockFlags(false, false, false, false, false, false, physx::PxRigidDynamicLockFlags(0)); + TestLockFlags(true, false, false, false, false, false, physx::PxRigidDynamicLockFlags(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X)); + TestLockFlags(false, false, false, false, true, false, physx::PxRigidDynamicLockFlags(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y)); + TestLockFlags(false, true, false, false, false, true, + physx::PxRigidDynamicLockFlags(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y | physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z)); + } + TEST_F(PhysXSpecificTest, RigidBody_RigidBodyWithSimulatedFlagsHitsPlane_OnlySimulatedShapeCollidesWithPlane) { // Helper function wrapping creation logic From 16869d56f32316b8bdaa157e53de39fd68fcc6fa Mon Sep 17 00:00:00 2001 From: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> Date: Wed, 28 Jul 2021 14:09:26 +0100 Subject: [PATCH 2/4] Use regular comment The Doxygen comment would only apply to the first field in each group. Signed-off-by: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> --- .../Physics/Configuration/RigidBodyConfiguration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h index 46f2620938..51dcce842d 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h @@ -62,12 +62,12 @@ namespace AzPhysics bool m_computeInertiaTensor = true; bool m_computeMass = true; - //! Flags to restrict motion along specific world-space axes. + // Flags to restrict motion along specific world-space axes. bool m_lockLinearX = false; bool m_lockLinearY = false; bool m_lockLinearZ = false; - //! Flags to restrict rotation around specific world-space axes. + // Flags to restrict rotation around specific world-space axes. bool m_lockAngularX = false; bool m_lockAngularY = false; bool m_lockAngularZ = false; From 0824bb462a44cf017827d0628a4f4694f1bf68a7 Mon Sep 17 00:00:00 2001 From: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> Date: Wed, 28 Jul 2021 16:33:02 +0100 Subject: [PATCH 3/4] Improve tooltip text Signed-off-by: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> --- Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp index c94cc46ba4..bd7c49a0a7 100644 --- a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp @@ -162,26 +162,26 @@ namespace PhysX ->Attribute(AZ::Edit::Attributes::AutoExpand, false) ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearX, "Lock X", - "Lock linear momentum in X direction") + "Lock motion along X direction") ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearY, "Lock Y", - "Lock linear momentum in Y direction") + "Lock motion along Y direction") ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearZ, "Lock Z", - "Lock linear momentum in Z direction") + "Lock motion along Z direction") // Angular axis locking properties ->ClassElement(AZ::Edit::ClassElements::Group, "Angular Axis Locking") ->Attribute(AZ::Edit::Attributes::AutoExpand, false) ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularX, "Lock X", - "Lock angular momentum in X direction") + "Lock rotation around X direction") ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularY, "Lock Y", - "Lock angular momentum in Y direction") + "Lock rotation around Y direction") ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularZ, "Lock Z", - "Lock angular momentum in Z direction") + "Lock rotation around Z direction") ->ClassElement(AZ::Edit::ClassElements::Group, "Continuous Collision Detection") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) From a7e414fafeb18834d5c930ae2eb225d8bd889d1c Mon Sep 17 00:00:00 2001 From: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> Date: Wed, 28 Jul 2021 17:58:31 +0100 Subject: [PATCH 4/4] Fix Linux compilation error in test code Signed-off-by: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> --- Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp index 76ee035b70..6e96db4db2 100644 --- a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp +++ b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp @@ -1144,7 +1144,9 @@ namespace PhysX ASSERT_TRUE(rigidBody != nullptr); physx::PxRigidDynamic* pxRigidBody = static_cast(rigidBody->GetNativePointer()); - EXPECT_EQ(pxRigidBody->getRigidDynamicLockFlags(), expectedFlags); + + // These values need to be cast to integral types to prevent a compilation error on somme platforms. + EXPECT_EQ(static_cast(pxRigidBody->getRigidDynamicLockFlags()), static_cast((expectedFlags))); RemoveRigidBody(rigidBody); };