5
\$\begingroup\$

I'd like to add non collidable objects (eg: power ups, items, ...) in a game world using Bullet Physics Engine and to know if there is collision between player and them.

Some info : there is a lot of items (> 1000), all are box shapes and they don't overlap.

Here is things i have tried :

btDbvt* bvtItems = new btDbvt(); //btDbvt is a hierachical AABB tree, used by Bullet
foreach(var item ...)
{    
    btDbvtVolume volume = ... //compute item AABB;
    bvtItems->insert(volume, (void*)someExtraData);
}

Then, to find collisions between items and player :

playerRigidBody->getAabb(min, max);
btDbvtVolume playervolume = ... //compute player AABB
bvtItems->collideTV(bvtItems->m_root, playervolume, *someCollisionHandler);

This works fairly well (and its very fast), however, there is a problem : it only check items AABB against player AABB. That loss of precision is acceptable for items but not for player which is not a box. It would actually need another check to make sure player really collide with item but i don't know how to do this in Bullet. It would have been nice to have a function like this :

playerRigidBody->checkCollisionWithAABB();


After doing trying that, I discovered that a btGhostObject exist and seems to have been made for that.

I changed my code like this :

foreach(var item...)
{
    btCollisionObject* ghostObject = new btGhostObject();
    ghostObject->setCollisionShape(boxShape);
    ghostObject->setCollisionFlags(ghostObject->getCollisionFlags() 
                                   | btCollisionObject::CF_NO_CONTACT_RESPONSE);
    startTransform.setOrigin(...); //item position
    ghostObject->setWorldTransform(startTransform);
    dynamicsWorld->addCollisionObject(ghostObject, btBroadphaseProxy::SensorTrigger,
                   btBroadphaseProxy:: CharacterFilter);
}

It also works ok, but there is a huge fps drop (almost ten times slower) which is not acceptable. Maybe there is something missing (forget set a flag) and Bullet is doing extra job for nothing or maybe all that ghostObjects are polluting broad phase and ghostObject is not the right thing for that.

Any help would be appreciated.

\$\endgroup\$
3
  • \$\begingroup\$ So items can collide, right? The title says the contrary. \$\endgroup\$ Commented Nov 10, 2012 at 12:04
  • \$\begingroup\$ Do the items move? \$\endgroup\$ Commented Nov 10, 2012 at 12:16
  • \$\begingroup\$ By "non-collidable" i mean that player can go trought (no collision response). These items don't move, they mainly act like "triggers". I only need to know if player is overlapping them or not. I edited title. \$\endgroup\$
    – tigrou
    Commented Nov 10, 2012 at 12:27

2 Answers 2

5
\$\begingroup\$

You could use world->contactTest(player, callback);

This will use the same dynamic aaabb tree (if you use btDbvtBroadphase) and uses an exact contact computation. It is probably fastest and easiest. World can be btCollisionWorld or btDiscreteDynamicsWorld.

If you use ghosts: You don't need to add a ghost for each item, just a single ghost around the player.

\$\endgroup\$
2
\$\begingroup\$

Create a normal static or kinematic rigid body and set collision flag NO_CONTACT_RESPONSE. This way the object participates in physics calculations and records collisions, but does not give any impulses to other objects.

You can then check for collisions with these instructions.

\$\endgroup\$
1
  • \$\begingroup\$ Your answer has much helpful as Erwin one, thanks. Adding normal rigid bodies instead of ghosts was the way to do. Unfortunatly i cannot flag both answers as accepted one. \$\endgroup\$
    – tigrou
    Commented Nov 12, 2012 at 13:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .