/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include #include #include #include #include #include #include #include #include #include namespace PhysX { // Definitions are put in .cpp so we can have AZStd::unique_ptr member with forward declared T in the header // This causes AZStd::unique_ptr ctor/dtor to be generated when full type info is available StaticRigidBodyComponent::StaticRigidBodyComponent() = default; StaticRigidBodyComponent::~StaticRigidBodyComponent() = default; StaticRigidBodyComponent::StaticRigidBodyComponent(AzPhysics::SceneHandle sceneHandle) : m_attachedSceneHandle(sceneHandle) { } void StaticRigidBodyComponent::Reflect(AZ::ReflectContext* context) { if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() ->Version(1) ; } } void StaticRigidBodyComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC("PhysicsWorldBodyService", 0x944da0cc)); provided.push_back(AZ_CRC("PhysXStaticRigidBodyService", 0xaae8973b)); } void StaticRigidBodyComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); } void StaticRigidBodyComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { // There can be only one StaticRigidBodyComponent per entity incompatible.push_back(AZ_CRC("PhysXStaticRigidBodyService", 0xaae8973b)); // Cannot have both StaticRigidBodyComponent and RigidBodyComponent incompatible.push_back(AZ_CRC("PhysXRigidBodyService", 0x1d4c64a8)); } void StaticRigidBodyComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) { dependent.push_back(AZ_CRC("PhysXColliderService", 0x4ff43f7c)); } void StaticRigidBodyComponent::InitStaticRigidBody() { AZ::Transform transform = AZ::Transform::CreateIdentity(); AZ::TransformBus::EventResult(transform, GetEntityId(), &AZ::TransformInterface::GetWorldTM); AzPhysics::StaticRigidBodyConfiguration configuration; configuration.m_orientation = transform.GetRotation(); configuration.m_position = transform.GetTranslation(); configuration.m_entityId = GetEntityId(); configuration.m_debugName = GetEntity()->GetName(); AZStd::vector> allshapes; ColliderComponentRequestBus::EnumerateHandlersId(GetEntityId(), [&allshapes](ColliderComponentRequests* handler) { const AZStd::vector>& shapes = handler->GetShapes(); allshapes.insert(allshapes.end(), shapes.begin(), shapes.end()); return true; }); configuration.m_colliderAndShapeData = allshapes; if (m_attachedSceneHandle == AzPhysics::InvalidSceneHandle) { Physics::DefaultWorldBus::BroadcastResult(m_attachedSceneHandle, &Physics::DefaultWorldRequests::GetDefaultSceneHandle); } if (auto* sceneInterface = AZ::Interface::Get()) { m_staticRigidBodyHandle = sceneInterface->AddSimulatedBody(m_attachedSceneHandle, &configuration); } } void StaticRigidBodyComponent::Activate() { AZ::TransformNotificationBus::Handler::BusConnect(GetEntityId()); InitStaticRigidBody(); AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusConnect(GetEntityId()); } void StaticRigidBodyComponent::Deactivate() { if (auto* sceneInterface = AZ::Interface::Get()) { sceneInterface->RemoveSimulatedBody(m_attachedSceneHandle, m_staticRigidBodyHandle); } AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); AZ::TransformNotificationBus::Handler::BusDisconnect(); } void StaticRigidBodyComponent::OnTransformChanged([[maybe_unused]] const AZ::Transform& local, const AZ::Transform& world) { if (AzPhysics::SimulatedBody* body = GetSimulatedBody()) { body->SetTransform(world); } } void StaticRigidBodyComponent::EnablePhysics() { if (IsPhysicsEnabled()) { return; } if (auto* sceneInterface = AZ::Interface::Get()) { sceneInterface->EnableSimulationOfBody(m_attachedSceneHandle, m_staticRigidBodyHandle); } } void StaticRigidBodyComponent::DisablePhysics() { if (auto* sceneInterface = AZ::Interface::Get()) { sceneInterface->DisableSimulationOfBody(m_attachedSceneHandle, m_staticRigidBodyHandle); } } bool StaticRigidBodyComponent::IsPhysicsEnabled() const { if (m_staticRigidBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) { if (auto* sceneInterface = AZ::Interface::Get(); sceneInterface != nullptr && sceneInterface->IsEnabled(m_attachedSceneHandle))//check if the scene is enabled { if (AzPhysics::SimulatedBody* body = sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_staticRigidBodyHandle)) { return body->m_simulating; } } } return false; } AZ::Aabb StaticRigidBodyComponent::GetAabb() const { if (auto* sceneInterface = AZ::Interface::Get()) { if (AzPhysics::SimulatedBody* body = sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_staticRigidBodyHandle)) { return body->GetAabb(); } } return AZ::Aabb::CreateNull(); } AzPhysics::SimulatedBodyHandle StaticRigidBodyComponent::GetSimulatedBodyHandle() const { return m_staticRigidBodyHandle; } AzPhysics::SimulatedBody* StaticRigidBodyComponent::GetSimulatedBody() { if (auto* sceneInterface = AZ::Interface::Get()) { return sceneInterface->GetSimulatedBodyFromHandle(m_attachedSceneHandle, m_staticRigidBodyHandle); } return nullptr; } AzPhysics::SceneQueryHit StaticRigidBodyComponent::RayCast(const AzPhysics::RayCastRequest& request) { if (auto* body = azdynamic_cast(GetSimulatedBody())) { return body->RayCast(request); } return AzPhysics::SceneQueryHit(); } } // namespace PhysX