- They need to be physically simulated in respect to gravity, terrain and certain select large objects (e.g. elevators)
- They should not collide with each other or any objects not above (e.g. players), or maybe more correctly, not react to the collision (e.g. block the btKinematicCharacterController from moving)
- I want to detect whenever a player starts to collide/overlap with them (so when the player runs over them the player picks them up)
Code: Select all
btDiscreteDynamicsWorld *bulletWorld;
//Player, uses btPairCachingGhostObject with btKinematicCharacterController
bulletWorld->addCollisionObject(&ghostObject, COL_PLAYER, COL_TERRAIN);
//Terrain, uses a btRigidBody with a custom btConcaveShape
bulletWorld->addRigidBody(&terrainBody, COL_TERRAIN, (short)(COL_ALL ^ COL_TERRAIN));
//ItemEntity, uses btRigidBody
bulletWorld->addRigidBody(&btObject, COL_ITEM, COL_TERRAIN);
Code: Select all
btManifoldArray manifoldArray;
auto bulletWorld = world->getPhysics().getBulletWorld();
auto &pairArray = ghostObject.getOverlappingPairCache()->getOverlappingPairArray();
for (int i = 0; i < pairArray.size(); ++i)
{
auto &pair = pairArray[i];
//TODO: Is it possible to look at pair directory for instances I
//only care that an overlapp happened between 2 objects?
btBroadphasePair* collisionPair = bulletWorld->getPairCache()->findPair(pair.m_pProxy0, pair.m_pProxy1);
if (collisionPair->m_algorithm)
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
for (int j = 0; j < manifoldArray.size(); j++)
{
btPersistentManifold* manifold = manifoldArray[j];
auto otherObject = manifold->getBody0() != &ghostObject ?
manifold->getBody0() : manifold->getBody1();
auto userData = (BulletUserData*)otherObject->getUserPointer();
if (userData && userData->isEntity() && userData->asEntity()->isAlive())
{
//TODO: Come up with a design to avoid the dynamic_cast...
ItemEntity *item = dynamic_cast<ItemStackEntity*>(userData->asEntity());
if (item)
{
item->addToInventory(inventory);
}
}
}
}