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.
Proximity Detection - Arbitrary Radius
-
Erwin Coumans
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Proximity Detection - Arbitrary Radius
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
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
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.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
Best Regards.
-
Erwin Coumans
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Proximity Detection - Arbitrary Radius
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
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
Thanks Erwin. I'll try the AABB approach and manually filter out the "false positives" that could occur in the corners of the box.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
Best Regards.
-
Eliambow
- Posts: 1
- Joined: Sat Mar 20, 2010 8:11 pm
Re: Proximity Detection - Arbitrary Radius
Did you have any luck? I was wondering how you go about constructing the Callback, I'm a bit confused.Mjohnsonii wrote:Thanks Erwin. I'll try the AABB approach and manually filter out the "false positives" that could occur in the corners of the box.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
Best Regards.
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);
}