123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- /*
- * 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 <Actor/BlastActorImpl.h>
- #include <Actor/ShapesProvider.h>
- #include <AzCore/Component/TransformBus.h>
- #include <AzCore/Math/Transform.h>
- #include <AzFramework/Physics/PhysicsSystem.h>
- #include <AzFramework/Physics/RigidBodyBus.h>
- #include <AzFramework/Physics/Shape.h>
- #include <AzFramework/Physics/SystemBus.h>
- #include <AzFramework/Physics/Utils.h>
- #include <AzFramework/Physics/Material/PhysicsMaterialManager.h>
- #include <AzFramework/Physics/Components/SimulatedBodyComponentBus.h>
- #include <Blast/BlastActor.h>
- #include <Family/BlastFamily.h>
- #include <NvBlastExtPxAsset.h>
- #include <NvBlastTkActor.h>
- #include <NvBlastTkAsset.h>
- #include <NvBlastTypes.h>
- #include <PhysX/ColliderComponentBus.h>
- #include <PhysX/ComponentTypeIds.h>
- #include <PhysX/MathConversion.h>
- #include <PhysX/SystemComponentBus.h>
- namespace Blast
- {
- BlastActorImpl::BlastActorImpl(const BlastActorDesc& desc)
- : m_family(*desc.m_family)
- , m_tkActor(*desc.m_tkActor)
- , m_entity(desc.m_entity)
- , m_chunkIndices(desc.m_chunkIndices)
- , m_isLeafChunk(desc.m_isLeafChunk)
- , m_isStatic(desc.m_isStatic)
- , m_physicsMaterialId(desc.m_physicsMaterialId)
- , m_parentLinearVelocity(desc.m_parentLinearVelocity)
- , m_parentCenterOfMass(desc.m_parentCenterOfMass)
- , m_bodyConfiguration(desc.m_bodyConfiguration)
- , m_scale(desc.m_scale)
- {
- // Store pointer to ourselves in the blast toolkit actor's userData
- m_tkActor.userData = this;
- m_shapesProvider = AZStd::make_unique<ShapesProvider>(m_entity->GetId(), desc.m_bodyConfiguration);
- }
- BlastActorImpl::~BlastActorImpl()
- {
- m_tkActor.userData = nullptr;
- }
- void BlastActorImpl::Spawn()
- {
- // Get physics material from id
- AZStd::shared_ptr<Physics::Material> physicsMaterial = AZ::Interface<Physics::MaterialManager>::Get()->GetMaterial(m_physicsMaterialId);
- if (!physicsMaterial)
- {
- physicsMaterial = AZ::Interface<Physics::MaterialManager>::Get()->GetDefaultMaterial();
- }
- // Add shapes for each of the visible chunks
- AddShapes(m_chunkIndices, m_family.GetPxAsset(), physicsMaterial->GetMaterialAsset());
- m_entity->Init();
- m_entity->Activate();
- auto transform = AZ::Transform::CreateFromQuaternionAndTranslation(
- m_bodyConfiguration.m_orientation, m_bodyConfiguration.m_position);
- transform.MultiplyByUniformScale(m_scale);
- AZ::TransformBus::Event(m_entity->GetId(), &AZ::TransformInterface::SetWorldTM, transform);
- // Set initial velocities if we're not static
- if (!m_isStatic)
- {
- AzPhysics::RigidBody* rigidBody = nullptr;
- Physics::RigidBodyRequestBus::EventResult(
- rigidBody, m_entity->GetId(), &Physics::RigidBodyRequests::GetRigidBody);
- rigidBody->SetTransform(transform);
- const AZ::Vector3 com = rigidBody->GetTransform().TransformPoint(rigidBody->GetCenterOfMassLocal());
- const AZ::Vector3 linearVelocity =
- m_parentLinearVelocity + m_bodyConfiguration.m_initialAngularVelocity.Cross(com - m_parentCenterOfMass);
- Physics::RigidBodyRequestBus::Event(
- m_entity->GetId(), &Physics::RigidBodyRequests::SetLinearVelocity, linearVelocity);
- Physics::RigidBodyRequestBus::Event(
- m_entity->GetId(), &Physics::RigidBodyRequests::SetAngularVelocity,
- m_bodyConfiguration.m_initialAngularVelocity);
- }
- }
- void BlastActorImpl::AddShapes(
- const AZStd::vector<uint32_t>& chunkIndices, const Nv::Blast::ExtPxAsset& asset,
- const AZ::Data::Asset<Physics::MaterialAsset>& physicsMaterialAsset)
- {
- const Nv::Blast::ExtPxChunk* pxChunks = asset.getChunks();
- const Nv::Blast::ExtPxSubchunk* pxSubchunks = asset.getSubchunks();
- const uint32_t chunkCount = asset.getChunkCount();
- const uint32_t subchunkCount = asset.getSubchunkCount();
- AZ_Assert(pxChunks, "Received asset with a null chunk array.");
- AZ_Assert(pxSubchunks, "Received asset with a null subchunk array.");
- if (!pxChunks || !pxSubchunks)
- {
- return;
- }
- for (uint32_t chunkId : chunkIndices)
- {
- AZ_Assert(chunkId < chunkCount, "Out of bounds access to the BlastPxActor's PxChunks.");
- if (chunkId >= chunkCount)
- {
- continue;
- }
- const Nv::Blast::ExtPxChunk& chunk = pxChunks[chunkId];
- for (uint32_t i = 0; i < chunk.subchunkCount; i++)
- {
- const uint32_t subchunkIndex = chunk.firstSubchunkIndex + i;
- AZ_Assert(subchunkIndex < subchunkCount, "Out of bounds access to the BlastPxActor's PxSubchunks.");
- if (subchunkIndex >= subchunkCount)
- {
- continue;
- }
- auto& subchunk = pxSubchunks[subchunkIndex];
- AZ::Transform transform = PxMathConvert(subchunk.transform);
- auto colliderConfiguration = CalculateColliderConfiguration(transform, physicsMaterialAsset);
- Physics::NativeShapeConfiguration shapeConfiguration;
- shapeConfiguration.m_nativeShapePtr =
- reinterpret_cast<void*>(const_cast<physx::PxConvexMeshGeometry*>(&subchunk.geometry)->convexMesh);
- shapeConfiguration.m_nativeShapeScale = AZ::Vector3(m_scale);
- AZStd::shared_ptr<Physics::Shape> shape = AZ::Interface<Physics::SystemRequests>::Get()->CreateShape(
- colliderConfiguration, shapeConfiguration);
- AZ_Assert(shape, "Failed to create Shape for BlastActor");
- m_shapesProvider->AddShape(shape);
- }
- }
- }
- Physics::ColliderConfiguration BlastActorImpl::CalculateColliderConfiguration(
- const AZ::Transform& transform, const AZ::Data::Asset<Physics::MaterialAsset>& physicsMaterialAsset)
- {
- auto& actorConfiguration = m_family.GetActorConfiguration();
- Physics::ColliderConfiguration colliderConfiguration;
- colliderConfiguration.m_position = transform.GetTranslation();
- colliderConfiguration.m_rotation = transform.GetRotation();
- colliderConfiguration.m_isExclusive = true;
- colliderConfiguration.m_materialSlots.SetMaterialAsset(0, physicsMaterialAsset);
- colliderConfiguration.m_collisionGroupId = actorConfiguration.m_collisionGroupId;
- colliderConfiguration.m_collisionLayer = actorConfiguration.m_collisionLayer;
- colliderConfiguration.m_isInSceneQueries = actorConfiguration.m_isInSceneQueries;
- colliderConfiguration.m_isSimulated = actorConfiguration.m_isSimulated;
- colliderConfiguration.m_tag = actorConfiguration.m_tag;
- return colliderConfiguration;
- }
- AZ::Transform BlastActorImpl::GetTransform() const
- {
- return GetSimulatedBody()->GetTransform();
- }
- const BlastFamily& BlastActorImpl::GetFamily() const
- {
- return m_family;
- }
- const Nv::Blast::TkActor& BlastActorImpl::GetTkActor() const
- {
- return m_tkActor;
- }
- AzPhysics::SimulatedBody* BlastActorImpl::GetSimulatedBody()
- {
- AzPhysics::SimulatedBody* worldBody = nullptr;
- AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(
- worldBody, m_entity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetSimulatedBody);
- return worldBody;
- }
- const AzPhysics::SimulatedBody* BlastActorImpl::GetSimulatedBody() const
- {
- AzPhysics::SimulatedBody* worldBody = nullptr;
- AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(
- worldBody, m_entity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetSimulatedBody);
- return worldBody;
- }
- const AZStd::vector<uint32_t>& BlastActorImpl::GetChunkIndices() const
- {
- return m_chunkIndices;
- }
- bool BlastActorImpl::IsStatic() const
- {
- return m_isStatic;
- }
- const AZ::Entity* BlastActorImpl::GetEntity() const
- {
- return m_entity.get();
- }
- void BlastActorImpl::Damage(const NvBlastDamageProgram& program, NvBlastExtProgramParams* programParams)
- {
- m_tkActor.damage(program, programParams);
- }
- } // namespace Blast
|