You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/PhysX/Code/Source/RigidBodyStatic.cpp

169 lines
5.2 KiB
C++

/*
* 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 <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzFramework/Physics/Configuration/StaticRigidBodyConfiguration.h>
#include <PxPhysicsAPI.h>
#include <Source/RigidBodyStatic.h>
#include <Source/Utils.h>
#include <PhysX/Utils.h>
#include <Source/Shape.h>
#include <Include/PhysX/NativeTypeIdentifiers.h>
#include <PhysX/PhysXLocks.h>
#include <Common/PhysXSceneQueryHelpers.h>
#include <PhysX/MathConversion.h>
namespace PhysX
{
AZ_CLASS_ALLOCATOR_IMPL(PhysX::StaticRigidBody, AZ::SystemAllocator, 0);
StaticRigidBody::StaticRigidBody(const AzPhysics::StaticRigidBodyConfiguration& configuration)
{
CreatePhysXActor(configuration);
}
StaticRigidBody::~StaticRigidBody()
{
//clean up the attached shapes
{
PHYSX_SCENE_WRITE_LOCK(m_pxStaticRigidBody->getScene());
for (auto shape : m_shapes)
{
m_pxStaticRigidBody->detachShape(*shape->GetPxShape());
shape->DetachedFromActor();
}
}
m_shapes.clear();
// Invalidate user data so it sets m_pxStaticRigidBody->userData to nullptr.
// It's appropriate to do this as m_pxStaticRigidBody is a shared pointer and
// technically it could survive m_actorUserData life's span.
m_actorUserData.Invalidate();
}
void StaticRigidBody::CreatePhysXActor(const AzPhysics::StaticRigidBodyConfiguration& configuration)
{
if (m_pxStaticRigidBody != nullptr)
{
AZ_Warning("PhysX Static Rigid Body", false, "Trying to create PhysX static rigid actor when it's already created");
return;
}
if (m_pxStaticRigidBody = PxActorFactories::CreatePxStaticRigidBody(configuration))
{
m_actorUserData = ActorData(m_pxStaticRigidBody.get());
m_actorUserData.SetRigidBodyStatic(this);
m_actorUserData.SetEntityId(configuration.m_entityId);
m_debugName = configuration.m_debugName;
m_pxStaticRigidBody->setName(m_debugName.c_str());
}
}
void StaticRigidBody::AddShape(const AZStd::shared_ptr<Physics::Shape>& shape)
{
auto pxShape = AZStd::rtti_pointer_cast<PhysX::Shape>(shape);
if (pxShape && pxShape->GetPxShape())
{
{
PHYSX_SCENE_WRITE_LOCK(m_pxStaticRigidBody->getScene());
m_pxStaticRigidBody->attachShape(*pxShape->GetPxShape());
}
pxShape->AttachedToActor(m_pxStaticRigidBody.get());
m_shapes.push_back(pxShape);
}
else
{
AZ_Error("PhysX Rigid Body Static", false, "Trying to add an invalid shape.");
}
}
AZStd::shared_ptr<Physics::Shape> StaticRigidBody::GetShape(AZ::u32 index)
{
if (index >= m_shapes.size())
{
return nullptr;
}
return m_shapes[index];
}
AZ::u32 StaticRigidBody::GetShapeCount()
{
return static_cast<AZ::u32>(m_shapes.size());
}
AZ::Transform StaticRigidBody::GetTransform() const
{
if (m_pxStaticRigidBody)
{
PHYSX_SCENE_READ_LOCK(m_pxStaticRigidBody->getScene());
return PxMathConvert(m_pxStaticRigidBody->getGlobalPose());
}
return AZ::Transform::CreateIdentity();
}
void StaticRigidBody::SetTransform(const AZ::Transform & transform)
{
if (m_pxStaticRigidBody)
{
PHYSX_SCENE_WRITE_LOCK(m_pxStaticRigidBody->getScene());
m_pxStaticRigidBody->setGlobalPose(PxMathConvert(transform));
}
}
AZ::Vector3 StaticRigidBody::GetPosition() const
{
if (m_pxStaticRigidBody)
{
PHYSX_SCENE_READ_LOCK(m_pxStaticRigidBody->getScene());
return PxMathConvert(m_pxStaticRigidBody->getGlobalPose().p);
}
return AZ::Vector3::CreateZero();
}
AZ::Quaternion StaticRigidBody::GetOrientation() const
{
if (m_pxStaticRigidBody)
{
PHYSX_SCENE_READ_LOCK(m_pxStaticRigidBody->getScene());
return PxMathConvert(m_pxStaticRigidBody->getGlobalPose().q);
}
return AZ::Quaternion::CreateZero();
}
AZ::Aabb StaticRigidBody::GetAabb() const
{
if (m_pxStaticRigidBody)
{
PHYSX_SCENE_READ_LOCK(m_pxStaticRigidBody->getScene());
return PxMathConvert(m_pxStaticRigidBody->getWorldBounds(1.0f));
}
return AZ::Aabb::CreateNull();
}
AzPhysics::SceneQueryHit StaticRigidBody::RayCast(const AzPhysics::RayCastRequest& request)
{
return PhysX::SceneQueryHelpers::ClosestRayHitAgainstShapes(request, m_shapes, GetTransform());
}
AZ::EntityId StaticRigidBody::GetEntityId() const
{
return m_actorUserData.GetEntityId();
}
AZ::Crc32 StaticRigidBody::GetNativeType() const
{
return PhysX::NativeTypeIdentifiers::RigidBodyStatic;
}
void* StaticRigidBody::GetNativePointer() const
{
return m_pxStaticRigidBody.get();
}
}