/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #if ENABLE_CRY_PHYSICS #pragma once #include <AzCore/Component/Component.h> #include <AzCore/Component/EntityBus.h> #include <AzCore/Component/TransformBus.h> #include <AzCore/Math/Transform.h> #include <AzFramework/Physics/RagdollPhysicsBus.h> #include <AzFramework/Physics/PhysicsComponentBus.h> #include <AzFramework/Physics/PhysicsSystemComponentBus.h> #include <LmbrCentral/Physics/CryPhysicsComponentRequestBus.h> #include <LmbrCentral/Rendering/MeshComponentBus.h> #include "PhysicsSystemComponent.h" #include <physinterface.h> struct SProximityElement; struct IPhysicalEntity; namespace LmbrCentral { /*! * Entity component which listens for Ragdoll requests, * and re-physicalizes with the ragdoll data */ class RagdollComponent : public AZ::Component , private AzFramework::RagdollPhysicsRequestBus::Handler , private CryPhysicsComponentRequestBus::Handler , private EntityPhysicsEventBus::Handler , private AzFramework::PhysicsComponentRequestBus::Handler , private MeshComponentNotificationBus::Handler { public: AZ_COMPONENT(RagdollComponent, "{80DF7994-5A4B-4B10-87B3-BE7BC541CFBB}"); ~RagdollComponent() override = default; ////////////////////////////////////////////////////////////////////////// // Component descriptor static void Reflect(AZ::ReflectContext* context); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC("RagdollService", 0xd416b0dc)); } static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("RagdollService", 0xd416b0dc)); } static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { required.push_back(AZ_CRC("SkinnedMeshService", 0xac7cea96)); } static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) { dependent.push_back(AZ_CRC("PhysicsService", 0xa7350d22)); } private: //////////////////////////////////////////////////////////////////////// // AZ::Component void Activate() override; void Deactivate() override; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // CryCharacterPhysicsRagdollRequestBus::Handler void EnterRagdoll() override; void ExitRagdoll() override; void EnableSimulation(const Physics::RagdollState& initialState) override; void EnableSimulationQueued(const Physics::RagdollState& initialState) override; void DisableSimulation() override; void DisableSimulationQueued() override; Physics::Ragdoll* GetRagdoll() override; void GetState(Physics::RagdollState& ragdollState) const override; void SetState(const Physics::RagdollState& ragdollState) override; void SetStateQueued(const Physics::RagdollState& ragdollState) override; void GetNodeState(size_t nodeIndex, Physics::RagdollNodeState& nodeState) const override; void SetNodeState(size_t nodeIndex, const Physics::RagdollNodeState& nodeState) override; Physics::RagdollNode* GetNode(size_t nodeIndex) const override; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // CryPhysicsComponentRequests IPhysicalEntity* GetPhysicalEntity() override; void GetPhysicsParameters(pe_params& outParameters) override; void SetPhysicsParameters(const pe_params& parameters) override; void GetPhysicsStatus(pe_status& outStatus) override; void ApplyPhysicsAction(const pe_action& action, bool threadSafe) override; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // EntityPhysicsEvents void OnPostStep(const EntityPhysicsEvents::PostStep& event) override; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // EntityPhysicsEvents virtual void EnablePhysics() override {} virtual void DisablePhysics() override {} virtual bool IsPhysicsEnabled() override { return m_physicalEntity != nullptr; } void AddImpulse(const AZ::Vector3& impulse) override; void AddImpulseAtPoint(const AZ::Vector3& impulse, const AZ::Vector3& worldSpacePoint) override; virtual void SetVelocity(const AZ::Vector3& velocity) override; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // MeshComponentNotificationBus::Handler virtual void OnMeshCreated(const AZ::Data::Asset<AZ::Data::AssetData>& asset) override; virtual void OnMeshDestroyed() override; //////////////////////////////////////////////////////////////////////// void CreateRagdollInternal(); void CreateRagdollEntity(); void AssignRagdollParameters(); void RetainJointVelocities(const AZ::Vector3& initialVelocity); ////////////////////////////////////////////////////////////////////////// // Reflected Data bool m_isActiveInitially = false; bool m_tryToUsePhysicsComponentMass = true; // Advanced float m_maxPhysicsTimeStep = 0.025f; float m_mass = 80.f; float m_stiffnessScale = 0.f; unsigned m_skeletalLevelOfDetail = 1; bool m_retainJointVelocity = false; bool m_collidesWithCharacters = true; // Damping float m_timeUntilAtRest = 0.025f; float m_damping = 0.3f; float m_dampingDuringFreefall = 0.1f; int m_groundedRequiredPointsOfContact = 4; float m_groundedTimeUntilAtRest = 0.065f; float m_groundedDamping = 1.5f; // Buoyancy float m_fluidDensity = 1000.f; float m_fluidDamping = 0; float m_fluidResistance = 1000.f; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // Non Reflected Data IPhysicalEntity* m_physicalEntity = nullptr; SProximityElement* m_proximityTriggerProxy = nullptr; ////////////////////////////////////////////////////////////////////////// }; } // namespace LmbrCentral #endif // ENABLE_CRY_PHYSICS