Make raycast benchmark default, to show improved raycasting performance.

Add rayTest to btBroadphaseInterface, and implement efficient version for btDbvtBroadphase to accelerate raycasting.
btAxisSweep3, btSimpleBroadphase and btMultiSapBroadphase implement brute-force method (as before). For now, it is recommended to use btDbvtBroadphase for fastest world raycast.
This commit is contained in:
erwin.coumans
2008-10-14 06:23:45 +00:00
parent 780350a9e1
commit fffca75e9f
11 changed files with 123 additions and 25 deletions

View File

@@ -599,52 +599,70 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
}
}
void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
struct btSingleRayCallback : public btBroadphaseRayCallback
{
BT_PROFILE("rayTest");
btVector3 m_rayFromWorld;
btVector3 m_rayToWorld;
const btCollisionWorld* m_world;
btCollisionWorld::RayResultCallback& m_resultCallback;
btTransform rayFromTrans,rayToTrans;
rayFromTrans.setIdentity();
rayFromTrans.setOrigin(rayFromWorld);
rayToTrans.setIdentity();
btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
:m_rayFromWorld(rayFromWorld),
m_rayToWorld(rayToWorld),
m_world(world),
m_resultCallback(resultCallback)
{
rayToTrans.setOrigin(rayToWorld);
}
/// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD)
int i;
for (i=0;i<m_collisionObjects.size();i++)
virtual bool process(const btBroadphaseProxy* proxy)
{
///terminate further ray tests, once the closestHitFraction reached zero
if (resultCallback.m_closestHitFraction == btScalar(0.f))
break;
if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
return false;
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
btCollisionObject* collisionObject= m_collisionObjects[i];
//only perform raycast if filterMask matches
if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
{
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
//btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
//collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
//getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
btScalar hitLambda = resultCallback.m_closestHitFraction;
btScalar hitLambda = m_resultCallback.m_closestHitFraction;
btVector3 hitNormal;
{
if (btRayAabb(rayFromWorld,rayToWorld,collisionObject->getBroadphaseHandle()->m_aabbMin,collisionObject->getBroadphaseHandle()->m_aabbMax,hitLambda,hitNormal))
if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObject->getBroadphaseHandle()->m_aabbMin,collisionObject->getBroadphaseHandle()->m_aabbMax,hitLambda,hitNormal))
{
rayTestSingle(rayFromTrans,rayToTrans,
btTransform rayFromTrans,rayToTrans;
rayFromTrans.setIdentity();
rayFromTrans.setOrigin(m_rayFromWorld);
rayToTrans.setIdentity();
rayToTrans.setOrigin(m_rayToWorld);
m_world->rayTestSingle(rayFromTrans,rayToTrans,
collisionObject,
collisionObject->getCollisionShape(),
collisionObject->getWorldTransform(),
resultCallback);
m_resultCallback);
}
}
}
return true;
}
};
void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
{
BT_PROFILE("rayTest");
/// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD)
btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
}