mirror of
https://github.com/bulletphysics/bullet3.git
synced 2026-09-19 00:34:28 +00:00
add collisionFilterMask to rayTestBatch and rayTest
This will allow to exclude (filter) certain bodies. By default, static bodies have collision group 2, and dynamic (mass=1) bodies have collision group 1. As long as mask & group != 0, a raytest will be performed.
This commit is contained in:
@@ -5934,6 +5934,53 @@ struct CastSyncInfo
|
||||
};
|
||||
#endif // __cplusplus >= 201103L
|
||||
|
||||
|
||||
|
||||
|
||||
struct FilteredClosestRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
|
||||
{
|
||||
FilteredClosestRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld, int collisionFilterMask)
|
||||
: btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld),
|
||||
m_collisionFilterMask(collisionFilterMask)
|
||||
{
|
||||
}
|
||||
|
||||
int m_collisionFilterMask;
|
||||
|
||||
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
|
||||
{
|
||||
if (m_collisionFilterMask >= 0)
|
||||
{
|
||||
bool collides = (rayResult.m_collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & m_collisionFilterMask) != 0;
|
||||
if (!collides)
|
||||
return m_closestHitFraction;
|
||||
}
|
||||
return btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
|
||||
}
|
||||
};
|
||||
|
||||
struct FilteredAllHitsRayResultCallback: public btCollisionWorld::AllHitsRayResultCallback
|
||||
{
|
||||
FilteredAllHitsRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld, int collisionFilterMask)
|
||||
: btCollisionWorld::AllHitsRayResultCallback(rayFromWorld, rayToWorld),
|
||||
m_collisionFilterMask(collisionFilterMask)
|
||||
{
|
||||
}
|
||||
|
||||
int m_collisionFilterMask;
|
||||
|
||||
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
|
||||
{
|
||||
if (m_collisionFilterMask >= 0)
|
||||
{
|
||||
bool collides = (rayResult.m_collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & m_collisionFilterMask) != 0;
|
||||
if (!collides)
|
||||
return m_closestHitFraction;
|
||||
}
|
||||
return btCollisionWorld::AllHitsRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
|
||||
}
|
||||
};
|
||||
|
||||
struct BatchRayCaster
|
||||
{
|
||||
b3ThreadPool* m_threadPool;
|
||||
@@ -5943,9 +5990,11 @@ struct BatchRayCaster
|
||||
b3RayHitInfo* m_hitInfoOutputBuffer;
|
||||
int m_numRays;
|
||||
int m_reportHitNumber;
|
||||
int m_collisionFilterMask;
|
||||
|
||||
BatchRayCaster(b3ThreadPool* threadPool, const btCollisionWorld* world, const b3RayData* rayInputBuffer, b3RayHitInfo* hitInfoOutputBuffer, int numRays, int reportHitNumber)
|
||||
: m_threadPool(threadPool), m_world(world), m_rayInputBuffer(rayInputBuffer), m_hitInfoOutputBuffer(hitInfoOutputBuffer), m_numRays(numRays), m_reportHitNumber(reportHitNumber)
|
||||
BatchRayCaster(b3ThreadPool* threadPool, const btCollisionWorld* world, const b3RayData* rayInputBuffer, b3RayHitInfo* hitInfoOutputBuffer, int numRays, int reportHitNumber, int collisionFilterMask)
|
||||
: m_threadPool(threadPool), m_world(world), m_rayInputBuffer(rayInputBuffer), m_hitInfoOutputBuffer(hitInfoOutputBuffer), m_numRays(numRays), m_reportHitNumber(reportHitNumber),
|
||||
m_collisionFilterMask(collisionFilterMask)
|
||||
{
|
||||
m_syncInfo = new CastSyncInfo;
|
||||
}
|
||||
@@ -6018,12 +6067,12 @@ struct BatchRayCaster
|
||||
btVector3 rayFromWorld(from[0], from[1], from[2]);
|
||||
btVector3 rayToWorld(to[0], to[1], to[2]);
|
||||
|
||||
btCollisionWorld::ClosestRayResultCallback rayResultCallback(rayFromWorld, rayToWorld);
|
||||
FilteredClosestRayResultCallback rayResultCallback(rayFromWorld, rayToWorld, m_collisionFilterMask);
|
||||
rayResultCallback.m_flags |= btTriangleRaycastCallback::kF_UseGjkConvexCastRaytest;
|
||||
if (m_reportHitNumber >= 0)
|
||||
{
|
||||
//compute all hits, and select the m_reportHitNumber, if available
|
||||
btCollisionWorld::AllHitsRayResultCallback allResultsCallback(rayFromWorld, rayToWorld);
|
||||
FilteredAllHitsRayResultCallback allResultsCallback(rayFromWorld, rayToWorld, m_collisionFilterMask);
|
||||
allResultsCallback.m_flags |= btTriangleRaycastCallback::kF_UseGjkConvexCastRaytest;
|
||||
m_world->rayTest(rayFromWorld, rayToWorld, allResultsCallback);
|
||||
if (allResultsCallback.m_collisionObjects.size() > m_reportHitNumber)
|
||||
@@ -6115,6 +6164,7 @@ bool PhysicsServerCommandProcessor::processRequestRaycastIntersectionsCommand(co
|
||||
const int totalRays = numCommandRays + numStreamingRays;
|
||||
int numThreads = clientCmd.m_requestRaycastIntersections.m_numThreads;
|
||||
int reportHitNumber = clientCmd.m_requestRaycastIntersections.m_reportHitNumber;
|
||||
int collisionFilterMask = clientCmd.m_requestRaycastIntersections.m_collisionFilterMask;
|
||||
if (numThreads == 0)
|
||||
{
|
||||
// When 0 is specified, Bullet can decide how many threads to use.
|
||||
@@ -6183,7 +6233,7 @@ bool PhysicsServerCommandProcessor::processRequestRaycastIntersectionsCommand(co
|
||||
}
|
||||
}
|
||||
|
||||
BatchRayCaster batchRayCaster(m_data->m_threadPool, m_data->m_dynamicsWorld, &rays[0], (b3RayHitInfo*)bufferServerToClient, totalRays, reportHitNumber);
|
||||
BatchRayCaster batchRayCaster(m_data->m_threadPool, m_data->m_dynamicsWorld, &rays[0], (b3RayHitInfo*)bufferServerToClient, totalRays, reportHitNumber, collisionFilterMask);
|
||||
batchRayCaster.castRays(numThreads);
|
||||
|
||||
serverStatusOut.m_numDataStreamBytes = totalRays * sizeof(b3RayData);
|
||||
|
||||
Reference in New Issue
Block a user