some rayTest improvements in btDbvt::rayTestInternal, it avoids/reduces memory allocations during stack allocation (by sharing a persistent m_stack)
and rayTestInternal re-uses precomputed invRayDirection/signs. also did some performance comparison with different ray-AABB test, from http://jgt.akpeters.com/papers/EisemannEtAl07/ In short: it is faster, but it is not clear how to cull ray segments using ray slopes: when rays starts inside the AABB, we get a negative t value, but negatives also get false t-values...
This commit is contained in:
@@ -414,6 +414,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
||||
{
|
||||
if (collisionShape->isConvex())
|
||||
{
|
||||
|
||||
btConvexCast::CastResult castResult;
|
||||
castResult.m_allowedPenetration = allowedPenetration;
|
||||
castResult.m_fraction = btScalar(1.);//??
|
||||
@@ -608,6 +609,10 @@ struct btSingleRayCallback : public btBroadphaseRayCallback
|
||||
|
||||
btVector3 m_rayFromWorld;
|
||||
btVector3 m_rayToWorld;
|
||||
btTransform m_rayFromTrans;
|
||||
btTransform m_rayToTrans;
|
||||
btVector3 m_hitNormal;
|
||||
|
||||
const btCollisionWorld* m_world;
|
||||
btCollisionWorld::RayResultCallback& m_resultCallback;
|
||||
|
||||
@@ -617,9 +622,32 @@ struct btSingleRayCallback : public btBroadphaseRayCallback
|
||||
m_world(world),
|
||||
m_resultCallback(resultCallback)
|
||||
{
|
||||
m_rayFromTrans.setIdentity();
|
||||
m_rayFromTrans.setOrigin(m_rayFromWorld);
|
||||
m_rayToTrans.setIdentity();
|
||||
m_rayToTrans.setOrigin(m_rayToWorld);
|
||||
|
||||
btVector3 rayDir = (rayToWorld-rayFromWorld);
|
||||
#ifdef TEST_RAY_SLOPES
|
||||
btMakeRaySlope(rayFromWorld.getX(),rayFromWorld.getY(),rayFromWorld.getZ(),rayDir.getX(),rayDir.getY(),rayDir.getZ(),&m_ray);
|
||||
#else
|
||||
|
||||
rayDir.normalize ();
|
||||
///what about division by zero? --> just set rayDirection[i] to INF/1e30
|
||||
m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
|
||||
m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
|
||||
m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
|
||||
m_signs[0] = m_rayDirectionInverse[0] < 0.0;
|
||||
m_signs[1] = m_rayDirectionInverse[1] < 0.0;
|
||||
m_signs[2] = m_rayDirectionInverse[2] < 0.0;
|
||||
#endif
|
||||
|
||||
m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual bool process(const btBroadphaseProxy* proxy)
|
||||
{
|
||||
///terminate further ray tests, once the closestHitFraction reached zero
|
||||
@@ -639,20 +667,14 @@ struct btSingleRayCallback : public btBroadphaseRayCallback
|
||||
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
|
||||
#else
|
||||
//getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
|
||||
btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
|
||||
btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
|
||||
const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
|
||||
const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
|
||||
#endif
|
||||
btScalar hitLambda = m_resultCallback.m_closestHitFraction;
|
||||
btVector3 hitNormal;
|
||||
if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
|
||||
//btScalar hitLambda = m_resultCallback.m_closestHitFraction;
|
||||
//culling already done by broadphase
|
||||
//if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
|
||||
{
|
||||
btTransform rayFromTrans,rayToTrans;
|
||||
rayFromTrans.setIdentity();
|
||||
rayFromTrans.setOrigin(m_rayFromWorld);
|
||||
rayToTrans.setIdentity();
|
||||
rayToTrans.setOrigin(m_rayToWorld);
|
||||
|
||||
m_world->rayTestSingle(rayFromTrans,rayToTrans,
|
||||
m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
|
||||
collisionObject,
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
|
||||
Reference in New Issue
Block a user