Fix crash when using physics overlap tests with Collider outputs that catch Terrain

#3221
This commit is contained in:
Wojtek Figat
2025-02-21 15:07:44 +01:00
parent 44e894f406
commit 9d5d80bf4a
3 changed files with 49 additions and 62 deletions

View File

@@ -536,15 +536,6 @@ protected:
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; \
}
namespace
{
PxFoundation* Foundation = nullptr;
@@ -2266,51 +2257,6 @@ bool PhysicsBackend::CheckConvex(void* scene, const Vector3& center, const Colli
return scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter);
}
bool PhysicsBackend::OverlapBox(void* scene, const Vector3& center, const Vector3& halfExtents, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
{
SCENE_QUERY_SETUP_OVERLAP();
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
const PxBoxGeometry geometry(C2P(halfExtents));
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
return false;
SCENE_QUERY_COLLECT_OVERLAP_COLLIDER();
return true;
}
bool PhysicsBackend::OverlapSphere(void* scene, const Vector3& center, const float radius, Array<Collider*>& results, uint32 layerMask, bool hitTriggers)
{
SCENE_QUERY_SETUP_OVERLAP();
const PxTransform pose(C2P(center - scenePhysX->Origin));
const PxSphereGeometry geometry(radius);
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
return false;
SCENE_QUERY_COLLECT_OVERLAP_COLLIDER();
return true;
}
bool PhysicsBackend::OverlapCapsule(void* scene, const Vector3& center, const float radius, const float height, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
{
SCENE_QUERY_SETUP_OVERLAP();
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
const PxCapsuleGeometry geometry(radius, height * 0.5f);
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
return false;
SCENE_QUERY_COLLECT_OVERLAP_COLLIDER();
return true;
}
bool PhysicsBackend::OverlapConvex(void* scene, 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)
SCENE_QUERY_SETUP_OVERLAP();
const PxTransform pose(C2P(center - scenePhysX->Origin), C2P(rotation));
const PxConvexMeshGeometry geometry((PxConvexMesh*)convexMesh->GetConvex(), PxMeshScale(C2P(scale)));
if (!scenePhysX->Scene->overlap(geometry, pose, buffer, filterData, &QueryFilter))
return false;
SCENE_QUERY_COLLECT_OVERLAP_COLLIDER();
return true;
}
bool PhysicsBackend::OverlapBox(void* scene, const Vector3& center, const Vector3& halfExtents, Array<PhysicsColliderActor*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
{
SCENE_QUERY_SETUP_OVERLAP();

View File

@@ -6,6 +6,7 @@
#include "PhysicalMaterial.h"
#include "PhysicsSettings.h"
#include "PhysicsStatistics.h"
#include "Colliders/Collider.h"
#include "Engine/Engine/Time.h"
#include "Engine/Engine/EngineService.h"
#include "Engine/Profiler/ProfilerCPU.h"
@@ -630,22 +631,66 @@ bool PhysicsScene::CheckConvex(const Vector3& center, const CollisionData* conve
bool PhysicsScene::OverlapBox(const Vector3& center, const Vector3& halfExtents, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
{
return PhysicsBackend::OverlapBox(_scene, center, halfExtents, results, rotation, layerMask, hitTriggers);
Array<PhysicsColliderActor*> tmp;
if (PhysicsBackend::OverlapBox(_scene, center, halfExtents, tmp, rotation, layerMask, hitTriggers))
{
results.EnsureCapacity(tmp.Count());
for (PhysicsColliderActor* e : tmp)
{
if (e && e->Is<Collider>())
results.Add((Collider*)e);
}
return true;
}
return false;
}
bool PhysicsScene::OverlapSphere(const Vector3& center, const float radius, Array<Collider*>& results, uint32 layerMask, bool hitTriggers)
{
return PhysicsBackend::OverlapSphere(_scene, center, radius, results, layerMask, hitTriggers);
Array<PhysicsColliderActor*> tmp;
if (PhysicsBackend::OverlapSphere(_scene, center, radius, tmp, layerMask, hitTriggers))
{
results.EnsureCapacity(tmp.Count());
for (PhysicsColliderActor* e : tmp)
{
if (e && e->Is<Collider>())
results.Add((Collider*)e);
}
return true;
}
return false;
}
bool PhysicsScene::OverlapCapsule(const Vector3& center, const float radius, const float height, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
{
return PhysicsBackend::OverlapCapsule(_scene, center, radius, height, results, rotation, layerMask, hitTriggers);
Array<PhysicsColliderActor*> tmp;
if (PhysicsBackend::OverlapCapsule(_scene, center, radius, height, tmp, rotation, layerMask, hitTriggers))
{
results.EnsureCapacity(tmp.Count());
for (PhysicsColliderActor* e : tmp)
{
if (e && e->Is<Collider>())
results.Add((Collider*)e);
}
return true;
}
return false;
}
bool PhysicsScene::OverlapConvex(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, Array<Collider*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)
{
return PhysicsBackend::OverlapConvex(_scene, center, convexMesh, scale, results, rotation, layerMask, hitTriggers);
Array<PhysicsColliderActor*> tmp;
if (PhysicsBackend::OverlapConvex(_scene, center, convexMesh, scale, tmp, rotation, layerMask, hitTriggers))
{
results.EnsureCapacity(tmp.Count());
for (PhysicsColliderActor* e : tmp)
{
if (e && e->Is<Collider>())
results.Add((Collider*)e);
}
return true;
}
return false;
}
bool PhysicsScene::OverlapBox(const Vector3& center, const Vector3& halfExtents, Array<PhysicsColliderActor*>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers)

View File

@@ -139,10 +139,6 @@ public:
static bool CheckSphere(void* scene, const Vector3& center, float radius, uint32 layerMask, bool hitTriggers);
static bool CheckCapsule(void* scene, const Vector3& center, float radius, float height, const Quaternion& rotation, uint32 layerMask, bool hitTriggers);
static bool CheckConvex(void* scene, const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Quaternion& rotation, uint32 layerMask, bool hitTriggers);
static bool OverlapBox(void* scene, const Vector3& center, const Vector3& halfExtents, Array<Collider*, HeapAllocation>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers);
static bool OverlapSphere(void* scene, const Vector3& center, float radius, Array<Collider*, HeapAllocation>& results, uint32 layerMask, bool hitTriggers);
static bool OverlapCapsule(void* scene, const Vector3& center, float radius, float height, Array<Collider*, HeapAllocation>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers);
static bool OverlapConvex(void* scene, const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, Array<Collider*, HeapAllocation>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers);
static bool OverlapBox(void* scene, const Vector3& center, const Vector3& halfExtents, Array<PhysicsColliderActor*, HeapAllocation>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers);
static bool OverlapSphere(void* scene, const Vector3& center, float radius, Array<PhysicsColliderActor*, HeapAllocation>& results, uint32 layerMask, bool hitTriggers);
static bool OverlapCapsule(void* scene, const Vector3& center, float radius, float height, Array<PhysicsColliderActor*, HeapAllocation>& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers);