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>
This commit is contained in:
+6
@@ -123,6 +123,12 @@ namespace AzPhysics
|
|||||||
->Field("Kinematic", &RigidBodyConfiguration::m_kinematic)
|
->Field("Kinematic", &RigidBodyConfiguration::m_kinematic)
|
||||||
->Field("CCD Enabled", &RigidBodyConfiguration::m_ccdEnabled)
|
->Field("CCD Enabled", &RigidBodyConfiguration::m_ccdEnabled)
|
||||||
->Field("Compute Mass", &RigidBodyConfiguration::m_computeMass)
|
->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("Mass", &RigidBodyConfiguration::m_mass)
|
||||||
->Field("Compute COM", &RigidBodyConfiguration::m_computeCenterOfMass)
|
->Field("Compute COM", &RigidBodyConfiguration::m_computeCenterOfMass)
|
||||||
->Field("Centre of mass offset", &RigidBodyConfiguration::m_centerOfMassOffset)
|
->Field("Centre of mass offset", &RigidBodyConfiguration::m_centerOfMassOffset)
|
||||||
|
|||||||
@@ -62,6 +62,16 @@ namespace AzPhysics
|
|||||||
bool m_computeInertiaTensor = true;
|
bool m_computeInertiaTensor = true;
|
||||||
bool m_computeMass = 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.
|
//! If set, non-simulated shapes will also be included in the mass properties calculation.
|
||||||
bool m_includeAllShapesInMassCalculation = false;
|
bool m_includeAllShapesInMassCalculation = false;
|
||||||
|
|
||||||
|
|||||||
@@ -156,6 +156,33 @@ namespace PhysX
|
|||||||
->DataElement(AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_kinematic,
|
->DataElement(AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_kinematic,
|
||||||
"Kinematic", "Rigid body is kinematic")
|
"Kinematic", "Rigid body is kinematic")
|
||||||
->Attribute(AZ::Edit::Attributes::Visibility, &AzPhysics::RigidBodyConfiguration::GetKinematicVisibility)
|
->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")
|
->ClassElement(AZ::Edit::ClassElements::Group, "Continuous Collision Detection")
|
||||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||||
->Attribute(AZ::Edit::Attributes::Visibility, &AzPhysics::RigidBodyConfiguration::GetCCDVisibility)
|
->Attribute(AZ::Edit::Attributes::Visibility, &AzPhysics::RigidBodyConfiguration::GetCCDVisibility)
|
||||||
|
|||||||
@@ -1466,6 +1466,14 @@ namespace PhysX
|
|||||||
rigidDynamic->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, configuration.m_kinematic);
|
rigidDynamic->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, configuration.m_kinematic);
|
||||||
rigidDynamic->setMaxAngularVelocity(configuration.m_maxAngularVelocity);
|
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;
|
return rigidDynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1102,6 +1102,60 @@ namespace PhysX
|
|||||||
SanityCheckValidFrustumParams(points.value(), validHeight, validBottomRadius, validTopRadius, validSubdivisions);
|
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<AzPhysics::SceneInterface>::Get())
|
||||||
|
{
|
||||||
|
AzPhysics::SimulatedBodyHandle simBodyHandle = sceneInterface->AddSimulatedBody(m_testSceneHandle, &rigidBodyConfig);
|
||||||
|
return azdynamic_cast<AzPhysics::RigidBody*>(sceneInterface->GetSimulatedBodyFromHandle(m_testSceneHandle, simBodyHandle));
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto RemoveRigidBody = [this](AzPhysics::RigidBody*& rigidBody)
|
||||||
|
{
|
||||||
|
auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::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<physx::PxRigidDynamic*>(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)
|
TEST_F(PhysXSpecificTest, RigidBody_RigidBodyWithSimulatedFlagsHitsPlane_OnlySimulatedShapeCollidesWithPlane)
|
||||||
{
|
{
|
||||||
// Helper function wrapping creation logic
|
// Helper function wrapping creation logic
|
||||||
|
|||||||
Reference in New Issue
Block a user