Proximity Detection - Arbitrary Radius

Mjohnsonii
Posts: 7
Joined: Tue Dec 09, 2008 7:41 pm

Proximity Detection - Arbitrary Radius

Post by Mjohnsonii »

Greetings,

I recently attempted to use a btPairCachingGhostObject with a sphere collision primitive to detect when other objects enter the area within the sphere. I found that when the radius of the sphere is greater than about 50 units the performance suffers dramatically. I understand about the size limitations mentioned in the Manual but I guess I wasn't clear if those limitations applied to GhostObjects.

Is there a way to use Bullet so that objects can be detected when other collision primitives enter the area of a sphere with an arbitrary radius?

Best Regards.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Proximity Detection - Arbitrary Radius

Post by Erwin Coumans »

This way is rather expensive, because it will perform penetration calculations with all overlapping objects in that radius.

What kind of results do you want? Only a boolean (overlap yes/no) or detailed contact results (contact location, penetration depth, separating normal)?
Thanks,
Erwin
Mjohnsonii
Posts: 7
Joined: Tue Dec 09, 2008 7:41 pm

Re: Proximity Detection - Arbitrary Radius

Post by Mjohnsonii »

Erwin Coumans wrote:This way is rather expensive, because it will perform penetration calculations with all overlapping objects in that radius.

What kind of results do you want? Only a boolean (overlap yes/no) or detailed contact results (contact location, penetration depth, separating normal)?
Thanks,
Erwin
I'm looking for a boolean response (is the collision primitive overlapping the radius or not?), I don't need the details of the contact.

Best Regards.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Proximity Detection - Arbitrary Radius

Post by Erwin Coumans »

It is acceptable to use a bounding axis aligned bounding box (AABB) instead of a sphere radius?

If so, you can use the new Bullet 2.76 broadphase query with all objects that have AABB overlap. See btBroadphaseInterface::aabbTest.
Thanks,
Erwin
Mjohnsonii
Posts: 7
Joined: Tue Dec 09, 2008 7:41 pm

Re: Proximity Detection - Arbitrary Radius

Post by Mjohnsonii »

Erwin Coumans wrote:It is acceptable to use a bounding axis aligned bounding box (AABB) instead of a sphere radius?

If so, you can use the new Bullet 2.76 broadphase query with all objects that have AABB overlap. See btBroadphaseInterface::aabbTest.
Thanks,
Erwin
Thanks Erwin. I'll try the AABB approach and manually filter out the "false positives" that could occur in the corners of the box.

Best Regards.
Eliambow
Posts: 1
Joined: Sat Mar 20, 2010 8:11 pm

Re: Proximity Detection - Arbitrary Radius

Post by Eliambow »

Mjohnsonii wrote:
Erwin Coumans wrote:It is acceptable to use a bounding axis aligned bounding box (AABB) instead of a sphere radius?

If so, you can use the new Bullet 2.76 broadphase query with all objects that have AABB overlap. See btBroadphaseInterface::aabbTest.
Thanks,
Erwin
Thanks Erwin. I'll try the AABB approach and manually filter out the "false positives" that could occur in the corners of the box.

Best Regards.
Did you have any luck? I was wondering how you go about constructing the Callback, I'm a bit confused.

Never mind I did the following and it seems to work:

Code: Select all

struct AgentsWithinProximityNotMe : public btBroadphaseAabbCallback {
  btCollisionObject *m_collisionObject;
  std::vector<Agent *> *m_agents;
  short int m_collisionFilterGroup, m_collisionFilterMask;
 
  AgentsWithinProximityNotMe(btCollisionObject *me, std::vector<Agent *> &agents, short int collisionGroup, short int collisionMask) :
    m_collisionObject(me), m_agents(&agents), m_collisionFilterGroup(collisionGroup), m_collisionFilterMask(collisionMask) { }

  inline bool needsCollision(btBroadphaseProxy* proxy0) const {
    bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
    collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
    return collides;
  }

  virtual bool process (const btBroadphaseProxy *proxy) {
    btCollisionObject *collisionObject = (btCollisionObject *)proxy->m_clientObject;
    // don't add self to results
    if (collisionObject == m_collisionObject)
      return true;
    // check collision filters and masks
    if (needsCollision(collisionObject->getBroadphaseHandle())) {
      printf("%04u: Agent %04u within range \n", ((Agent *)m_collisionObject->getUserPointer())->id, ((Agent *)collisionObject->getUserPointer())->id);
      m_agents->push_back((Agent *)collisionObject->getUserPointer());
    }
    return true;
  }
};

void Agent::getAgentsWithin(float range, std::vector<Agent *> &agents) {
  // The idea here is to get a list of agents within a bounding box (range) of the current agent
  // using the broadphase method we can cut the time down dramatically (I think)
  btSphereShape rangeSphere(range);
  btVector3 min, max;
  rangeSphere.getAabb(getCollisionObject()->getWorldTransform(), min, max);
  AgentsWithinProximityNotMe callback(getCollisionObject(), agents, COL_AGENT, COL_AGENT); 
  world->getBroadphase()->aabbTest(min, max, callback);
}