character controller component now uses simulated body handles (#929)

This commit is contained in:
amzn-sean
2021-05-26 18:24:13 +01:00
committed by GitHub
parent 9a0b93c9ff
commit 63ce0c1a62
2 changed files with 156 additions and 82 deletions
@@ -105,39 +105,55 @@ namespace PhysX
AZ::Vector3 CharacterControllerComponent::GetBasePosition() const
{
return IsPhysicsEnabled() ? m_controller->GetBasePosition() : AZ::Vector3::CreateZero();
if (auto* controller = GetControllerConst())
{
return controller->GetBasePosition();
}
return AZ::Vector3::CreateZero();
}
void CharacterControllerComponent::SetBasePosition(const AZ::Vector3& position)
{
if (IsPhysicsEnabled())
if (auto* controller = GetController())
{
m_controller->SetBasePosition(position);
controller->SetBasePosition(position);
AZ::TransformBus::Event(GetEntityId(), &AZ::TransformBus::Events::SetWorldTranslation, position);
}
}
AZ::Vector3 CharacterControllerComponent::GetCenterPosition() const
{
return IsPhysicsEnabled() ? m_controller->GetCenterPosition() : AZ::Vector3::CreateZero();
if (auto* controller = GetControllerConst())
{
return controller->GetCenterPosition();
}
return AZ::Vector3::CreateZero();
}
float CharacterControllerComponent::GetStepHeight() const
{
return IsPhysicsEnabled() ? m_controller->GetStepHeight() : 0.0f;
if (auto* controller = GetControllerConst())
{
return controller->GetStepHeight();
}
return 0.0f;
}
void CharacterControllerComponent::SetStepHeight(float stepHeight)
{
if (IsPhysicsEnabled())
if (auto* controller = GetController())
{
m_controller->SetStepHeight(stepHeight);
controller->SetStepHeight(stepHeight);
}
}
AZ::Vector3 CharacterControllerComponent::GetUpDirection() const
{
return IsPhysicsEnabled() ? m_controller->GetUpDirection() : AZ::Vector3::CreateZero();
if (auto* controller = GetControllerConst())
{
return controller->GetUpDirection();
}
return AZ::Vector3::CreateZero();
}
void CharacterControllerComponent::SetUpDirection([[maybe_unused]] const AZ::Vector3& upDirection)
@@ -147,51 +163,58 @@ namespace PhysX
float CharacterControllerComponent::GetSlopeLimitDegrees() const
{
return IsPhysicsEnabled() ? m_controller->GetSlopeLimitDegrees() : 0.0f;
if (auto* controller = GetControllerConst())
{
return controller->GetSlopeLimitDegrees();
}
return 0.0f;
}
void CharacterControllerComponent::SetSlopeLimitDegrees(float slopeLimitDegrees)
{
if (IsPhysicsEnabled())
if (auto* controller = GetController())
{
m_controller->SetSlopeLimitDegrees(slopeLimitDegrees);
controller->SetSlopeLimitDegrees(slopeLimitDegrees);
}
}
float CharacterControllerComponent::GetMaximumSpeed() const
{
if (IsPhysicsEnabled())
if (auto* controller = GetControllerConst())
{
return m_controller->GetMaximumSpeed();
return controller->GetMaximumSpeed();
}
return 0.0f;
}
void CharacterControllerComponent::SetMaximumSpeed(float maximumSpeed)
{
if (IsPhysicsEnabled())
if (auto* controller = GetController())
{
m_controller->SetMaximumSpeed(maximumSpeed);
controller->SetMaximumSpeed(maximumSpeed);
}
}
AZ::Vector3 CharacterControllerComponent::GetVelocity() const
{
return IsPhysicsEnabled() ? m_controller->GetVelocity() : AZ::Vector3::CreateZero();
if (auto* controller = GetControllerConst())
{
return controller->GetVelocity();
}
return AZ::Vector3::CreateZero();
}
void CharacterControllerComponent::AddVelocity(const AZ::Vector3& velocity)
{
if (IsPhysicsEnabled())
if (auto* controller = GetController())
{
m_controller->AddVelocity(velocity);
controller->AddVelocity(velocity);
}
}
Physics::Character* CharacterControllerComponent::GetCharacter()
{
return m_controller;
return GetController();
}
void CharacterControllerComponent::EnablePhysics()
@@ -206,14 +229,14 @@ namespace PhysX
bool CharacterControllerComponent::IsPhysicsEnabled() const
{
return m_controller != nullptr;
return GetControllerConst() != nullptr;
}
AZ::Aabb CharacterControllerComponent::GetAabb() const
{
if (m_controller)
if (auto* controller = GetControllerConst())
{
return m_controller->GetAabb();
return controller->GetAabb();
}
return AZ::Aabb::CreateNull();
}
@@ -225,94 +248,121 @@ namespace PhysX
AzPhysics::SimulatedBodyHandle CharacterControllerComponent::GetSimulatedBodyHandle() const
{
if (m_controller)
{
return m_controller->m_bodyHandle;
}
return AzPhysics::InvalidSimulatedBodyHandle;
return m_controllerBodyHandle;
}
AzPhysics::SceneQueryHit CharacterControllerComponent::RayCast(const AzPhysics::RayCastRequest& request)
{
if (m_controller)
if (auto* controller = GetController())
{
return m_controller->RayCast(request);
return controller->RayCast(request);
}
return AzPhysics::SceneQueryHit();
}
// CharacterControllerRequestBus
void CharacterControllerComponent::Resize(float height)
{
return m_controller->Resize(height);
if (auto* controller = GetController())
{
controller->Resize(height);
}
}
float CharacterControllerComponent::GetHeight()
{
return m_controller->GetHeight();
if (auto* controller = GetController())
{
return controller->GetHeight();
}
return 0.0f;
}
void CharacterControllerComponent::SetHeight(float height)
{
return m_controller->SetHeight(height);
if (auto* controller = GetController())
{
controller->SetHeight(height);
}
}
float CharacterControllerComponent::GetRadius()
{
return m_controller->GetRadius();
if (auto* controller = GetController())
{
return controller->GetRadius();
}
return 0.0f;
}
void CharacterControllerComponent::SetRadius(float radius)
{
return m_controller->SetRadius(radius);
if (auto* controller = GetController())
{
controller->SetRadius(radius);
}
}
float CharacterControllerComponent::GetHalfSideExtent()
{
return m_controller->GetHalfSideExtent();
if (auto* controller = GetController())
{
return controller->GetHalfSideExtent();
}
return 0.0f;
}
void CharacterControllerComponent::SetHalfSideExtent(float halfSideExtent)
{
return m_controller->SetHalfSideExtent(halfSideExtent);
if (auto* controller = GetController())
{
controller->SetHalfSideExtent(halfSideExtent);
}
}
float CharacterControllerComponent::GetHalfForwardExtent()
{
return m_controller->GetHalfForwardExtent();
if (auto* controller = GetController())
{
return controller->GetHalfForwardExtent();
}
return 0.0f;
}
void CharacterControllerComponent::SetHalfForwardExtent(float halfForwardExtent)
{
return m_controller->SetHalfForwardExtent(halfForwardExtent);
if (auto* controller = GetController())
{
controller->SetHalfForwardExtent(halfForwardExtent);
}
}
// TransformNotificationBus
void CharacterControllerComponent::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world)
{
if (!IsPhysicsEnabled())
if (auto* controller = GetController())
{
return;
controller->SetBasePosition(world.GetTranslation());
}
m_controller->SetBasePosition(world.GetTranslation());
}
void CharacterControllerComponent::SetCollisionLayer(const AZStd::string& layerName, AZ::Crc32 colliderTag)
{
if (!IsPhysicsEnabled())
auto* controller = GetController();
if (controller == nullptr)
{
return;
}
if (Physics::Utils::FilterTag(m_controller->GetColliderTag(), colliderTag))
if (Physics::Utils::FilterTag(controller->GetColliderTag(), colliderTag))
{
bool success = false;
AzPhysics::CollisionLayer collisionLayer;
Physics::CollisionRequestBus::BroadcastResult(success, &Physics::CollisionRequests::TryGetCollisionLayerByName, layerName, collisionLayer);
if (success)
{
m_controller->SetCollisionLayer(collisionLayer);
controller->SetCollisionLayer(collisionLayer);
}
}
}
@@ -320,30 +370,33 @@ namespace PhysX
AZStd::string CharacterControllerComponent::GetCollisionLayerName()
{
AZStd::string layerName;
if (!IsPhysicsEnabled())
auto* controller = GetControllerConst();
if (controller == nullptr)
{
return layerName;
}
Physics::CollisionRequestBus::BroadcastResult(layerName, &Physics::CollisionRequests::GetCollisionLayerName, m_controller->GetCollisionLayer());
Physics::CollisionRequestBus::BroadcastResult(
layerName, &Physics::CollisionRequests::GetCollisionLayerName, controller->GetCollisionLayer());
return layerName;
}
void CharacterControllerComponent::SetCollisionGroup(const AZStd::string& groupName, AZ::Crc32 colliderTag)
{
if (!IsPhysicsEnabled())
auto* controller = GetController();
if (controller == nullptr)
{
return;
}
if (Physics::Utils::FilterTag(m_controller->GetColliderTag(), colliderTag))
if (Physics::Utils::FilterTag(controller->GetColliderTag(), colliderTag))
{
bool success = false;
AzPhysics::CollisionGroup collisionGroup;
Physics::CollisionRequestBus::BroadcastResult(success, &Physics::CollisionRequests::TryGetCollisionGroupByName, groupName, collisionGroup);
if (success)
{
m_controller->SetCollisionGroup(collisionGroup);
controller->SetCollisionGroup(collisionGroup);
}
}
}
@@ -351,23 +404,26 @@ namespace PhysX
AZStd::string CharacterControllerComponent::GetCollisionGroupName()
{
AZStd::string groupName;
if (!IsPhysicsEnabled())
auto* controller = GetControllerConst();
if (controller == nullptr)
{
return groupName;
}
Physics::CollisionRequestBus::BroadcastResult(groupName, &Physics::CollisionRequests::GetCollisionGroupName, m_controller->GetCollisionGroup());
Physics::CollisionRequestBus::BroadcastResult(
groupName, &Physics::CollisionRequests::GetCollisionGroupName, controller->GetCollisionGroup());
return groupName;
}
void CharacterControllerComponent::ToggleCollisionLayer(const AZStd::string& layerName, AZ::Crc32 colliderTag, bool enabled)
{
if (!IsPhysicsEnabled())
auto* controller = GetController();
if (controller == nullptr)
{
return;
}
if (Physics::Utils::FilterTag(m_controller->GetColliderTag(), colliderTag))
if (Physics::Utils::FilterTag(controller->GetColliderTag(), colliderTag))
{
bool success = false;
AzPhysics::CollisionLayer collisionLayer;
@@ -375,23 +431,43 @@ namespace PhysX
if (success)
{
AzPhysics::CollisionLayer layer(layerName);
AzPhysics::CollisionGroup group = m_controller->GetCollisionGroup();
AzPhysics::CollisionGroup group = controller->GetCollisionGroup();
group.SetLayer(layer, enabled);
m_controller->SetCollisionGroup(group);
controller->SetCollisionGroup(group);
}
}
}
void CharacterControllerComponent::OnPreSimulate(float deltaTime)
{
if (m_controller)
if (auto* controller = GetController())
{
m_controller->ApplyRequestedVelocity(deltaTime);
const AZ::Vector3 newPosition = GetBasePosition();
controller->ApplyRequestedVelocity(deltaTime);
const AZ::Vector3 newPosition = controller->GetBasePosition();
AZ::TransformBus::Event(GetEntityId(), &AZ::TransformBus::Events::SetWorldTranslation, newPosition);
}
}
const PhysX::CharacterController* CharacterControllerComponent::GetControllerConst() const
{
if (m_controllerBodyHandle == AzPhysics::InvalidSimulatedBodyHandle || m_attachedSceneHandle == AzPhysics::InvalidSceneHandle)
{
return nullptr;
}
if (auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get())
{
return azdynamic_cast<PhysX::CharacterController*>(
sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_controllerBodyHandle));
}
return nullptr;
}
PhysX::CharacterController* CharacterControllerComponent::GetController()
{
return const_cast<PhysX::CharacterController*>(GetControllerConst());
}
void CharacterControllerComponent::CreateController()
{
if (IsPhysicsEnabled())
@@ -399,9 +475,8 @@ namespace PhysX
return;
}
AzPhysics::SceneHandle defaultSceneHandle = AzPhysics::InvalidSceneHandle;
Physics::DefaultWorldBus::BroadcastResult(defaultSceneHandle, &Physics::DefaultWorldRequests::GetDefaultSceneHandle);
if (defaultSceneHandle == AzPhysics::InvalidSceneHandle)
Physics::DefaultWorldBus::BroadcastResult(m_attachedSceneHandle, &Physics::DefaultWorldRequests::GetDefaultSceneHandle);
if (m_attachedSceneHandle == AzPhysics::InvalidSceneHandle)
{
AZ_Error("PhysX Character Controller Component", false, "Failed to retrieve default scene.");
return;
@@ -427,11 +502,9 @@ namespace PhysX
auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get();
if (sceneInterface != nullptr)
{
m_controllerBodyHandle = sceneInterface->AddSimulatedBody(defaultSceneHandle, m_characterConfig.get());
m_controller = azdynamic_cast<PhysX::CharacterController*>(
sceneInterface->GetSimulatedBodyFromHandle(defaultSceneHandle, m_controllerBodyHandle));
m_controllerBodyHandle = sceneInterface->AddSimulatedBody(m_attachedSceneHandle, m_characterConfig.get());
}
if (m_controller == nullptr)
if (m_controllerBodyHandle == AzPhysics::InvalidSimulatedBodyHandle)
{
AZ_Error("PhysX Character Controller Component", false, "Failed to create character controller.");
return;
@@ -447,7 +520,7 @@ namespace PhysX
DestroyController();
}
});
sceneInterface->RegisterSimulationBodyRemovedHandler(defaultSceneHandle, m_onSimulatedBodyRemovedHandler);
sceneInterface->RegisterSimulationBodyRemovedHandler(m_attachedSceneHandle, m_onSimulatedBodyRemovedHandler);
}
CharacterControllerRequestBus::Handler::BusConnect(GetEntityId());
@@ -467,24 +540,23 @@ namespace PhysX
void CharacterControllerComponent::DisableController()
{
if (!IsPhysicsEnabled())
if (auto* controller = GetController())
{
return;
controller->DisablePhysics();
if (auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get())
{
sceneInterface->RemoveSimulatedBody(m_attachedSceneHandle, controller->m_bodyHandle);
}
DestroyController();
}
m_controller->DisablePhysics();
if (auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get())
{
sceneInterface->RemoveSimulatedBody(m_controller->m_sceneOwner, m_controller->m_bodyHandle);
}
DestroyController();
}
void CharacterControllerComponent::DestroyController()
{
m_controller = nullptr;
m_controllerBodyHandle = AzPhysics::InvalidSimulatedBodyHandle;
m_attachedSceneHandle = AzPhysics::InvalidSceneHandle;
m_preSimulateHandler.Disconnect();
m_onSimulatedBodyRemovedHandler.Disconnect();
CharacterControllerRequestBus::Handler::BusDisconnect();
@@ -131,6 +131,8 @@ namespace PhysX
void ToggleCollisionLayer(const AZStd::string& layerName, AZ::Crc32 colliderTag, bool enabled) override;
private:
const PhysX::CharacterController* GetControllerConst() const;
PhysX::CharacterController* GetController();
// Creates the physics character controller in the current default physics scene.
// This will do nothing if the controller is already created.
void CreateController();
@@ -143,8 +145,8 @@ namespace PhysX
AZStd::unique_ptr<Physics::CharacterConfiguration> m_characterConfig;
AZStd::shared_ptr<Physics::ShapeConfiguration> m_shapeConfig;
PhysX::CharacterController* m_controller = nullptr;
AzPhysics::SimulatedBodyHandle m_controllerBodyHandle = AzPhysics::InvalidSimulatedBodyHandle;
AzPhysics::SceneHandle m_attachedSceneHandle = AzPhysics::InvalidSceneHandle;
AzPhysics::SystemEvents::OnPresimulateEvent::Handler m_preSimulateHandler;
AzPhysics::SceneEvents::OnSimulationBodyRemoved::Handler m_onSimulatedBodyRemovedHandler;
};