Adds feature for creating multiple physics scenes
This commit is contained in:
657
Source/Engine/Physics/PhysicsScene.Queries.cpp
Normal file
657
Source/Engine/Physics/PhysicsScene.Queries.cpp
Normal file
@@ -0,0 +1,657 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Physics.h"
|
||||
#include "PhysicsScene.h"
|
||||
#include "Utilities.h"
|
||||
#include "CollisionData.h"
|
||||
#include "Actors/PhysicsColliderActor.h"
|
||||
#include <ThirdParty/PhysX/PxPhysicsAPI.h>
|
||||
#include <ThirdParty/PhysX/PxQueryFiltering.h>
|
||||
|
||||
// Temporary result buffer size
|
||||
#define HIT_BUFFER_SIZE 128
|
||||
|
||||
template<typename HitType>
|
||||
class DynamicHitBuffer : public PxHitCallback<HitType>
|
||||
{
|
||||
private:
|
||||
|
||||
uint32 _count;
|
||||
HitType _buffer[HIT_BUFFER_SIZE];
|
||||
|
||||
public:
|
||||
|
||||
DynamicHitBuffer()
|
||||
: PxHitCallback<HitType>(_buffer, HIT_BUFFER_SIZE)
|
||||
, _count(0)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Computes the number of any hits in this result, blocking or touching.
|
||||
PX_INLINE PxU32 getNbAnyHits() const
|
||||
{
|
||||
return getNbTouches();
|
||||
}
|
||||
|
||||
// Convenience iterator used to access any hits in this result, blocking or touching.
|
||||
PX_INLINE const HitType& getAnyHit(const PxU32 index) const
|
||||
{
|
||||
PX_ASSERT(index < getNbTouches() + PxU32(this->hasBlock));
|
||||
return index < getNbTouches() ? getTouches()[index] : this->block;
|
||||
}
|
||||
|
||||
PX_INLINE PxU32 getNbTouches() const
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
PX_INLINE const HitType* getTouches() const
|
||||
{
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
PX_INLINE const HitType& getTouch(const PxU32 index) const
|
||||
{
|
||||
PX_ASSERT(index < getNbTouches());
|
||||
return _buffer[index];
|
||||
}
|
||||
|
||||
PX_INLINE PxU32 getMaxNbTouches() const
|
||||
{
|
||||
return HIT_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
PxAgain processTouches(const HitType* buffer, PxU32 nbHits) override
|
||||
{
|
||||
nbHits = Math::Min(nbHits, HIT_BUFFER_SIZE - _count);
|
||||
for (PxU32 i = 0; i < nbHits; i++)
|
||||
{
|
||||
_buffer[_count + i] = buffer[i];
|
||||
}
|
||||
_count += nbHits;
|
||||
return true;
|
||||
}
|
||||
|
||||
void finalizeQuery() override
|
||||
{
|
||||
if (this->hasBlock)
|
||||
{
|
||||
// Blocking hits go to hits
|
||||
processTouches(&this->block, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define SCENE_QUERY_SETUP(blockSingle) if (GetScene() == nullptr) return false; \
|
||||
const PxHitFlags hitFlags = PxHitFlag::ePOSITION | PxHitFlag::eNORMAL | PxHitFlag::eUV; \
|
||||
PxQueryFilterData filterData = PxQueryFilterData(); \
|
||||
filterData.flags |= PxQueryFlag::ePREFILTER; \
|
||||
filterData.data.word0 = layerMask; \
|
||||
filterData.data.word1 = blockSingle ? 1 : 0; \
|
||||
filterData.data.word2 = hitTriggers ? 1 : 0
|
||||
|
||||
#define SCENE_QUERY_SETUP_SWEEP_1() SCENE_QUERY_SETUP(true); \
|
||||
PxSweepBufferN<1> buffer
|
||||
|
||||
#define SCENE_QUERY_SETUP_SWEEP() SCENE_QUERY_SETUP(false); \
|
||||
DynamicHitBuffer<PxSweepHit> buffer
|
||||
|
||||
#define SCENE_QUERY_SETUP_OVERLAP_1() SCENE_QUERY_SETUP(false); \
|
||||
PxOverlapBufferN<1> buffer
|
||||
|
||||
#define SCENE_QUERY_SETUP_OVERLAP() SCENE_QUERY_SETUP(false); \
|
||||
DynamicHitBuffer<PxOverlapHit> buffer
|
||||
|
||||
#define SCENE_QUERY_COLLECT_SINGLE() const auto& hit = buffer.getAnyHit(0); \
|
||||
hitInfo.Gather(hit)
|
||||
|
||||
#define SCENE_QUERY_COLLECT_ALL() results.Clear(); \
|
||||
results.Resize(buffer.getNbAnyHits(), false); \
|
||||
for (int32 i = 0; i < results.Count(); i++) \
|
||||
{ \
|
||||
const auto& hit = buffer.getAnyHit(i); \
|
||||
results[i].Gather(hit); \
|
||||
}
|
||||
|
||||
#define SCENE_QUERY_COLLECT_OVERLAP() results.Clear(); \
|
||||
results.Resize(buffer.getNbTouches(), false); \
|
||||
for (int32 i = 0; i < results.Count(); i++) \
|
||||
{ \
|
||||
auto& hitInfo = results[i]; \
|
||||
const auto& hit = buffer.getTouch(i); \
|
||||
hitInfo = hit.shape ? static_cast<::PhysicsColliderActor*>(hit.shape->userData) : nullptr; \
|
||||
}
|
||||
|
||||
#define SCENE_QUERY_COLLECT_OVERLAP_COLLIDER() results.Clear(); \
|
||||
results.Resize(buffer.getNbTouches(), false); \
|
||||
for (int32 i = 0; i < results.Count(); i++) \
|
||||
{ \
|
||||
auto& hitInfo = results[i]; \
|
||||
const auto& hit = buffer.getTouch(i); \
|
||||
hitInfo = hit.shape ? static_cast<::Collider*>(hit.shape->userData) : nullptr; \
|
||||
}
|
||||
|
||||
void RayCastHit::Gather(const PxRaycastHit& hit)
|
||||
{
|
||||
Point = P2C(hit.position);
|
||||
Normal = P2C(hit.normal);
|
||||
Distance = hit.distance;
|
||||
Collider = hit.shape ? static_cast<PhysicsColliderActor*>(hit.shape->userData) : nullptr;
|
||||
FaceIndex = hit.faceIndex;
|
||||
UV.X = hit.u;
|
||||
UV.Y = hit.v;
|
||||
}
|
||||
|
||||
void RayCastHit::Gather(const PxSweepHit& hit)
|
||||
{
|
||||
Point = P2C(hit.position);
|
||||
Normal = P2C(hit.normal);
|
||||
Distance = hit.distance;
|
||||
Collider = hit.shape ? static_cast<PhysicsColliderActor*>(hit.shape->userData) : nullptr;
|
||||
FaceIndex = hit.faceIndex;
|
||||
UV = Vector2::Zero;
|
||||
}
|
||||
|
||||
class QueryFilter : public PxQueryFilterCallback
|
||||
{
|
||||
public:
|
||||
|
||||
PxQueryHitType::Enum preFilter(const PxFilterData& filterData, const PxShape* shape, const PxRigidActor* actor, PxHitFlags& queryFlags) override
|
||||
{
|
||||
// Early out to avoid crashing
|
||||
if (!shape)
|
||||
return PxQueryHitType::eNONE;
|
||||
|
||||
// Check mask
|
||||
const PxFilterData shapeFilter = shape->getQueryFilterData();
|
||||
if ((filterData.word0 & shapeFilter.word0) == 0)
|
||||
{
|
||||
return PxQueryHitType::eNONE;
|
||||
}
|
||||
|
||||
// Check if skip triggers
|
||||
const bool hitTriggers = filterData.word2 != 0;
|
||||
if (!hitTriggers && shape->getFlags() & PxShapeFlag::eTRIGGER_SHAPE)
|
||||
return PxQueryHitType::eNONE;
|
||||
|
||||
const bool blockSingle = filterData.word1 != 0;
|
||||
return blockSingle ? PxQueryHitType::eBLOCK : PxQueryHitType::eTOUCH;
|
||||
}
|
||||
|
||||
PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit) override
|
||||
{
|
||||
// Not used
|
||||
return PxQueryHitType::eNONE;
|
||||
}
|
||||
};
|
||||
|
||||
class CharacterQueryFilter : public PxQueryFilterCallback
|
||||
{
|
||||
public:
|
||||
|
||||
PxQueryHitType::Enum preFilter(const PxFilterData& filterData, const PxShape* shape, const PxRigidActor* actor, PxHitFlags& queryFlags) override
|
||||
{
|
||||
// Early out to avoid crashing
|
||||
if (!shape)
|
||||
return PxQueryHitType::eNONE;
|
||||
|
||||
// Let triggers through
|
||||
if (PxFilterObjectIsTrigger(shape->getFlags()))
|
||||
return PxQueryHitType::eNONE;
|
||||
|
||||
// Trigger the contact callback for pairs (A,B) where the filtermask of A contains the ID of B and vice versa
|
||||
const PxFilterData shapeFilter = shape->getQueryFilterData();
|
||||
if (filterData.word0 & shapeFilter.word1)
|
||||
return PxQueryHitType::eBLOCK;
|
||||
|
||||
return PxQueryHitType::eNONE;
|
||||
}
|
||||
|
||||
PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit) override
|
||||
{
|
||||
// Not used
|
||||
return PxQueryHitType::eNONE;
|
||||
}
|
||||
};
|
||||
|
||||
PxQueryFilterCallback* PhysicsScene::GetQueryFilterCallback()
|
||||
{
|
||||
static QueryFilter Filter;
|
||||
return &Filter;
|
||||
}
|
||||
|
||||
PxQueryFilterCallback* PhysicsScene::GetCharacterQueryFilterCallback()
|
||||
{
|
||||
static CharacterQueryFilter Filter;
|
||||
return &Filter;
|
||||
}
|
||||
|
||||
bool PhysicsScene::RayCast(const Vector3& origin, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP(true);
|
||||
PxRaycastBuffer buffer;
|
||||
|
||||
// Perform raycast test
|
||||
return GetScene()->raycast(C2P(origin), C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback());
|
||||
}
|
||||
|
||||
bool PhysicsScene::RayCast(const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP(true);
|
||||
PxRaycastBuffer buffer;
|
||||
|
||||
// Perform raycast test
|
||||
if (!GetScene()->raycast(C2P(origin), C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_SINGLE();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::RayCastAll(const Vector3& origin, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP(false);
|
||||
DynamicHitBuffer<PxRaycastHit> buffer;
|
||||
|
||||
// Perform raycast test
|
||||
if (!GetScene()->raycast(C2P(origin), C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_ALL();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP_1();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||
|
||||
// Perform sweep test
|
||||
return GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback());
|
||||
}
|
||||
|
||||
bool PhysicsScene::BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP_1();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||
|
||||
// Perform sweep test
|
||||
if (!GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_SINGLE();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::BoxCastAll(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||
|
||||
// Perform sweep test
|
||||
if (!GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_ALL();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::SphereCast(const Vector3& center, const float radius, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP_1();
|
||||
const PxTransform pose(C2P(center));
|
||||
const PxSphereGeometry geometry(radius);
|
||||
|
||||
// Perform sweep test
|
||||
return GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback());
|
||||
}
|
||||
|
||||
bool PhysicsScene::SphereCast(const Vector3& center, const float radius, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP_1();
|
||||
const PxTransform pose(C2P(center));
|
||||
const PxSphereGeometry geometry(radius);
|
||||
|
||||
// Perform sweep test
|
||||
if (!GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_SINGLE();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::SphereCastAll(const Vector3& center, const float radius, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP();
|
||||
const PxTransform pose(C2P(center));
|
||||
const PxSphereGeometry geometry(radius);
|
||||
|
||||
// Perform sweep test
|
||||
if (!GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_ALL();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP_1();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||
|
||||
// Perform sweep test
|
||||
return GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback());
|
||||
}
|
||||
|
||||
bool PhysicsScene::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP_1();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||
|
||||
// Perform sweep test
|
||||
if (!GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_SINGLE();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::CapsuleCastAll(const Vector3& center, const float radius, const float height, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||
|
||||
// Perform sweep test
|
||||
if (!GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_ALL();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP_1();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||
|
||||
// Perform sweep test
|
||||
return GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback());
|
||||
}
|
||||
|
||||
bool PhysicsScene::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP_1();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||
|
||||
// Perform sweep test
|
||||
if (!GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_SINGLE();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::ConvexCastAll(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_SWEEP();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||
|
||||
// Perform sweep test
|
||||
if (!GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_ALL();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::CheckBox(const Vector3& center, const Vector3& halfExtents, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP_1();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||
|
||||
// Perform overlap test
|
||||
return GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback());
|
||||
}
|
||||
|
||||
bool PhysicsScene::CheckSphere(const Vector3& center, const float radius, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP_1();
|
||||
const PxTransform pose(C2P(center));
|
||||
const PxSphereGeometry geometry(radius);
|
||||
|
||||
// Perform overlap test
|
||||
return GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback());
|
||||
}
|
||||
|
||||
bool PhysicsScene::CheckCapsule(const Vector3& center, const float radius, const float height, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP_1();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||
|
||||
// Perform overlap test
|
||||
return GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback());
|
||||
}
|
||||
|
||||
bool PhysicsScene::CheckConvex(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP_1();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||
|
||||
// Perform overlap test
|
||||
return GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback());
|
||||
}
|
||||
|
||||
bool PhysicsScene::OverlapBox(const Vector3& center, const Vector3& halfExtents, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||
|
||||
// Perform overlap test
|
||||
if (!GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_OVERLAP_COLLIDER();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::OverlapSphere(const Vector3& center, const float radius, Array<Collider*>& results, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP();
|
||||
const PxTransform pose(C2P(center));
|
||||
const PxSphereGeometry geometry(radius);
|
||||
|
||||
// Perform overlap test
|
||||
if (!GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_OVERLAP_COLLIDER();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::OverlapCapsule(const Vector3& center, const float radius, const float height, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||
|
||||
// Perform overlap test
|
||||
if (!GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_OVERLAP_COLLIDER();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::OverlapConvex(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||
|
||||
// Perform overlap test
|
||||
if (!GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_OVERLAP_COLLIDER();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::OverlapBox(const Vector3& center, const Vector3& halfExtents, Array<PhysicsColliderActor*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxBoxGeometry geometry(C2P(halfExtents));
|
||||
|
||||
// Perform overlap test
|
||||
if (!GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_OVERLAP();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::OverlapSphere(const Vector3& center, const float radius, Array<PhysicsColliderActor*>& results, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP();
|
||||
const PxTransform pose(C2P(center));
|
||||
const PxSphereGeometry geometry(radius);
|
||||
|
||||
// Perform overlap test
|
||||
if (!GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_OVERLAP();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::OverlapCapsule(const Vector3& center, const float radius, const float height, Array<PhysicsColliderActor*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxCapsuleGeometry geometry(radius, height * 0.5f);
|
||||
|
||||
// Perform overlap test
|
||||
if (!GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_OVERLAP();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhysicsScene::OverlapConvex(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, Array<PhysicsColliderActor*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false)
|
||||
|
||||
// Prepare data
|
||||
SCENE_QUERY_SETUP_OVERLAP();
|
||||
const PxTransform pose(C2P(center), C2P(rotation));
|
||||
const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
|
||||
|
||||
// Perform overlap test
|
||||
if (!GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()))
|
||||
return false;
|
||||
|
||||
// Collect results
|
||||
SCENE_QUERY_COLLECT_OVERLAP();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if WITH_VEHICLE
|
||||
void PhysicsScene::AddWheeledVehicle(WheeledVehicle* vehicle)
|
||||
{
|
||||
mWheelVehicles.Add(vehicle);
|
||||
}
|
||||
|
||||
void PhysicsScene::RemoveWheeledVehicle(WheeledVehicle* vehicle)
|
||||
{
|
||||
mWheelVehicles.Remove(vehicle);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user