update Ragdoll component to only uses Handles (#981)

This commit is contained in:
amzn-sean
2021-05-27 16:42:17 +01:00
committed by GitHub
parent 7ced53cf58
commit 529e29071c
7 changed files with 93 additions and 42 deletions
@@ -102,7 +102,7 @@ namespace Physics
/// Is the ragdoll currently simulated?
/// @result True in case the ragdoll is simulated, false if not.
virtual bool IsSimulated() = 0;
virtual bool IsSimulated() const = 0;
/// Writes the state for all of the bodies in the ragdoll to the provided output.
/// The caller owns the output state and can safely manipulate it without affecting the physics simulation.
@@ -26,7 +26,7 @@ namespace EMotionFX
MOCK_METHOD0(DisableSimulation, void());
MOCK_METHOD0(DisableSimulationQueued, void());
MOCK_METHOD0(IsSimulated, bool());
MOCK_CONST_METHOD0(IsSimulated, bool());
MOCK_CONST_METHOD1(GetState, void(Physics::RagdollState&));
MOCK_METHOD1(SetState, void(const Physics::RagdollState&));
@@ -274,7 +274,7 @@ namespace PhysX
m_queuedDisableSimulation = true;
}
bool Ragdoll::IsSimulated()
bool Ragdoll::IsSimulated() const
{
return m_simulating;
}
@@ -46,7 +46,7 @@ namespace PhysX
void EnableSimulationQueued(const Physics::RagdollState& initialState) override;
void DisableSimulation() override;
void DisableSimulationQueued() override;
bool IsSimulated() override;
bool IsSimulated() const override;
void GetState(Physics::RagdollState& ragdollState) const override;
void SetState(const Physics::RagdollState& ragdollState) override;
void SetStateQueued(const Physics::RagdollState& ragdollState) override;
@@ -465,7 +465,7 @@ namespace PhysX
PhysX::CharacterController* CharacterControllerComponent::GetController()
{
return const_cast<PhysX::CharacterController*>(GetControllerConst());
return const_cast<PhysX::CharacterController*>(static_cast<const CharacterControllerComponent&>(*this).GetControllerConst());
}
void CharacterControllerComponent::CreateController()
@@ -170,63 +170,88 @@ namespace PhysX
// RagdollPhysicsBus
void RagdollComponent::EnableSimulation(const Physics::RagdollState& initialState)
{
m_ragdoll->EnableSimulation(initialState);
if (auto* ragdoll = GetPhysXRagdoll())
{
ragdoll->EnableSimulation(initialState);
}
}
void RagdollComponent::EnableSimulationQueued(const Physics::RagdollState& initialState)
{
m_ragdoll->EnableSimulationQueued(initialState);
if (auto* ragdoll = GetPhysXRagdoll())
{
ragdoll->EnableSimulationQueued(initialState);
}
}
void RagdollComponent::DisableSimulation()
{
if (m_ragdoll)
if (auto* ragdoll = GetPhysXRagdoll())
{
m_ragdoll->DisableSimulation();
ragdoll->DisableSimulation();
}
}
void RagdollComponent::DisableSimulationQueued()
{
if (m_ragdoll)
if (auto* ragdoll = GetPhysXRagdoll())
{
m_ragdoll->DisableSimulationQueued();
ragdoll->DisableSimulationQueued();
}
}
Physics::Ragdoll* RagdollComponent::GetRagdoll()
{
return m_ragdoll;
return GetPhysXRagdoll();
}
void RagdollComponent::GetState(Physics::RagdollState& ragdollState) const
{
m_ragdoll->GetState(ragdollState);
if (const auto* ragdoll = GetPhysXRagdollConst())
{
ragdoll->GetState(ragdollState);
}
}
void RagdollComponent::SetState(const Physics::RagdollState& ragdollState)
{
m_ragdoll->SetState(ragdollState);
if (auto* ragdoll = GetPhysXRagdoll())
{
ragdoll->SetState(ragdollState);
}
}
void RagdollComponent::SetStateQueued(const Physics::RagdollState& ragdollState)
{
m_ragdoll->SetStateQueued(ragdollState);
if (auto* ragdoll = GetPhysXRagdoll())
{
ragdoll->SetStateQueued(ragdollState);
}
}
void RagdollComponent::GetNodeState(size_t nodeIndex, Physics::RagdollNodeState& nodeState) const
{
m_ragdoll->GetNodeState(nodeIndex, nodeState);
if (const auto* ragdoll = GetPhysXRagdollConst())
{
ragdoll->GetNodeState(nodeIndex, nodeState);
}
}
void RagdollComponent::SetNodeState(size_t nodeIndex, const Physics::RagdollNodeState& nodeState)
{
m_ragdoll->SetNodeState(nodeIndex, nodeState);
if (auto* ragdoll = GetPhysXRagdoll())
{
ragdoll->SetNodeState(nodeIndex, nodeState);
}
}
Physics::RagdollNode* RagdollComponent::GetNode(size_t nodeIndex) const
{
return m_ragdoll->GetNode(nodeIndex);
if (const auto* ragdoll = GetPhysXRagdollConst())
{
return ragdoll->GetNode(nodeIndex);
}
return nullptr;
}
void RagdollComponent::EnablePhysics()
@@ -245,14 +270,19 @@ namespace PhysX
bool RagdollComponent::IsPhysicsEnabled() const
{
return m_ragdoll && m_ragdoll->IsSimulated();
if (const auto* ragdoll = GetPhysXRagdollConst())
{
return ragdoll->IsSimulated();
}
return false;
}
AZ::Aabb RagdollComponent::GetAabb() const
{
if (m_ragdoll)
if (const auto* ragdoll = GetPhysXRagdollConst())
{
return m_ragdoll->GetAabb();
return ragdoll->GetAabb();
}
return AZ::Aabb::CreateNull();
}
@@ -264,18 +294,14 @@ namespace PhysX
AzPhysics::SimulatedBodyHandle RagdollComponent::GetSimulatedBodyHandle() const
{
if (m_ragdoll)
{
return m_ragdoll->m_bodyHandle;
}
return AzPhysics::InvalidSimulatedBodyHandle;
return m_ragdollHandle;
}
AzPhysics::SceneQueryHit RagdollComponent::RayCast(const AzPhysics::RayCastRequest& request)
{
if (m_ragdoll)
if (auto* ragdoll = GetPhysXRagdoll())
{
return m_ragdoll->RayCast(request);
return ragdoll->RayCast(request);
}
return AzPhysics::SceneQueryHit();
}
@@ -323,23 +349,24 @@ namespace PhysX
AZ::TransformBus::EventResult(entityTransform, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
ragdollConfiguration.m_initialState = GetBindPoseWorld(bindPose, entityTransform);
AzPhysics::SceneHandle defaultSceneHandle = AzPhysics::InvalidSceneHandle;
Physics::DefaultWorldBus::BroadcastResult(defaultSceneHandle, &Physics::DefaultWorldRequests::GetDefaultSceneHandle);
m_attachedSceneHandle = AzPhysics::InvalidSceneHandle;
Physics::DefaultWorldBus::BroadcastResult(m_attachedSceneHandle, &Physics::DefaultWorldRequests::GetDefaultSceneHandle);
if (auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get())
{
AzPhysics::SimulatedBodyHandle bodyHandle = sceneInterface->AddSimulatedBody(defaultSceneHandle, &ragdollConfiguration);
m_ragdoll = azdynamic_cast<PhysX::Ragdoll*>(sceneInterface->GetSimulatedBodyFromHandle(defaultSceneHandle, bodyHandle));
m_ragdollHandle = sceneInterface->AddSimulatedBody(m_attachedSceneHandle, &ragdollConfiguration);
}
if (m_ragdoll == nullptr)
auto* ragdoll = GetPhysXRagdoll();
if (ragdoll == nullptr ||
m_ragdollHandle == AzPhysics::InvalidSimulatedBodyHandle)
{
AZ_Error("PhysX Ragdoll Component", false, "Failed to create ragdoll.");
return;
}
for (size_t nodeIndex = 0; nodeIndex < numNodes; nodeIndex++)
{
if (physx::PxRigidDynamic* pxRigidBody = m_ragdoll->GetPxRigidDynamic(nodeIndex))
if (physx::PxRigidDynamic* pxRigidBody = ragdoll->GetPxRigidDynamic(nodeIndex))
{
pxRigidBody->setSolverIterationCounts(m_positionIterations, m_velocityIterations);
}
@@ -352,7 +379,7 @@ namespace PhysX
for (size_t nodeIndex = 0; nodeIndex < numNodes; nodeIndex++)
{
if (const AZStd::shared_ptr<Physics::Joint>& joint = m_ragdoll->GetNode(nodeIndex)->GetJoint())
if (const AZStd::shared_ptr<Physics::Joint>& joint = ragdoll->GetNode(nodeIndex)->GetJoint())
{
if (auto* pxJoint = static_cast<physx::PxD6Joint*>(joint->GetNativePointer()))
{
@@ -374,20 +401,41 @@ namespace PhysX
void RagdollComponent::DestroyRagdoll()
{
if (m_ragdoll)
if (m_ragdollHandle != AzPhysics::InvalidSimulatedBodyHandle &&
m_attachedSceneHandle != AzPhysics::InvalidSceneHandle)
{
AzFramework::RagdollPhysicsRequestBus::Handler::BusDisconnect();
AzFramework::RagdollPhysicsNotificationBus::Event(GetEntityId(),
&AzFramework::RagdollPhysicsNotifications::OnRagdollDeactivated);
AzFramework::RagdollPhysicsNotificationBus::Event(
GetEntityId(), &AzFramework::RagdollPhysicsNotifications::OnRagdollDeactivated);
if (auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get())
{
sceneInterface->RemoveSimulatedBody(m_ragdoll->m_sceneOwner, m_ragdoll->m_bodyHandle);
sceneInterface->RemoveSimulatedBody(m_attachedSceneHandle, m_ragdollHandle);
m_attachedSceneHandle = AzPhysics::InvalidSceneHandle;
}
m_ragdoll = nullptr;
}
}
Ragdoll* RagdollComponent::GetPhysXRagdoll()
{
return const_cast<Ragdoll*>(static_cast<const RagdollComponent&>(*this).GetPhysXRagdollConst());
}
const Ragdoll* RagdollComponent::GetPhysXRagdollConst() const
{
if (m_ragdollHandle == AzPhysics::InvalidSimulatedBodyHandle ||
m_attachedSceneHandle == AzPhysics::InvalidSceneHandle)
{
return nullptr;
}
if (auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get())
{
return azdynamic_cast<PhysX::Ragdoll*>(sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_ragdollHandle));
}
return nullptr;
}
// deprecated Cry functions
void RagdollComponent::EnterRagdoll()
{
@@ -104,10 +104,13 @@ namespace PhysX
private:
void CreateRagdoll(const Physics::RagdollConfiguration& ragdollConfiguration);
void DestroyRagdoll();
Ragdoll* GetPhysXRagdoll();
const Ragdoll* GetPhysXRagdollConst() const;
bool IsJointProjectionVisible();
Ragdoll* m_ragdoll;
AzPhysics::SimulatedBodyHandle m_ragdollHandle = AzPhysics::InvalidSimulatedBodyHandle;
AzPhysics::SceneHandle m_attachedSceneHandle = AzPhysics::InvalidSceneHandle;
/// Minimum number of position iterations to perform in the PhysX solver.
/// Lower iteration counts are less expensive but may behave less realistically.
AZ::u32 m_positionIterations = 16;