I've made some quick experiments yesterday ( so I didn't test them too much, and if the code I'm about to post doesn't work please forgive me ). Anyway by extending a bit the collision filter groups I've managed to get more control on the collisions logic.
I don't know if this solution is reliable for a more robust "collision group system"; anyway if somebody is interested what I did is:
1) Define at the global scope a (backward compatible) more complete set of collision flags:
Code: Select all
enum MyCollisionFilterGroups
{
CFG_DEFAULT = 1,
CFG_STATIC = 2,
CFG_KINEMATIC = 4,
CFG_DEBRIS = 8,
CFG_SENSORTRIGGER = 16,
CFG_NOCOLLISION = 32,
CFG_GROUP0 = 64,
CFG_GROUP1 = 128,
CFG_GROUP2 = 256,
CFG_GROUP3 = 512,
CFG_GROUP4 = 1024,
CFG_GROUP5 = 2048,
CFG_GROUP6 = 4096,
CFG_GROUP7 = 8192,
CFG_ALLFILTER = CFG_DEFAULT | CFG_STATIC | CFG_KINEMATIC | CFG_DEBRIS | CFG_SENSORTRIGGER |
CFG_GROUP0 | CFG_GROUP1 | CFG_GROUP2 | CFG_GROUP3 | CFG_GROUP4 | CFG_GROUP5 | CFG_GROUP6 | CFG_GROUP7
};
2) Subclass btDiscreteDynamicsWorld to change the "plain" addRigidBody(...) method:
Code: Select all
class MyBtDiscreteDynamicsWorld : public btDiscreteDynamicsWorld
{
public:
[...] // Constructor Here And Other Stuff
inline virtual void addRigidBody(btRigidBody* body) {
if (!body->isStaticOrKinematicObject()) {
body->setGravity(m_gravity);
}
if (body->getCollisionShape()) {
/*
bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
short collisionFilterGroup = isDynamic? short(CFG_DEFAULT) : short(CFG_STATIC);
short collisionFilterMask = isDynamic? short(CFG_ALLFILTER) : short(CFG_ALLFILTER ^ CFG_STATIC);
*/
bool isKinematic = body->isKinematicObject();
bool isStatic = body->isStaticObject();
//bool isDynamic = !(isStatic || isKinematic);
short collisionFilterGroup = CFG_DEFAULT;//isDynamic? short(CFG_DEFAULT) : short(CFG_STATIC);
short collisionFilterMask = CFG_ALLFILTER;//isDynamic? short(CFG_ALLFILTER) : short(CFG_ALLFILTER ^ CFG_STATIC);
if (isKinematic) {collisionFilterGroup = CFG_KINEMATIC;collisionFilterMask = CFG_ALLFILTER^(CFG_STATIC | CFG_KINEMATIC);}
else if (isStatic) {collisionFilterGroup = CFG_STATIC;collisionFilterMask = CFG_ALLFILTER^(CFG_STATIC | CFG_KINEMATIC);}
addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
}
}
};
3) Now the rigid bodies can be added to the subclassed world like this ( code pasted in a hurry, hope it works ):
Code: Select all
btWorld->addRigidBody(body,CFG_NOCOLLISION); // CFG_NOCOLLISION means that this object cannot collide with anything (use it with static or kinematic bodies, or set gravity to zero). Good stuff for spacial triggers probably here...
btWorld->addRigidBody(body,CFG_GROUP0,CFG_ALLFILTER^CFG_GROUP0); // this object is put in group0 and can collide with everything except objects belonging to group0 (by default objects are put in CFG_DEFAULT if dynamics)
btWorld->addRigidBody(body,CFG_GROUP0,CFG_ALLFILTER^(CFG_GROUP0 | CFG_GROUP1)); // this object is put in group0 and can collide with everything except objects belonging to group0 and group1
Hope it works in cases when one needs just a few collision groups...
Note that in the Bullet code kinematic objects were given the "static" group by default, I've changed it so that it's possible to create bodies that can collide with static objects but not with kinematic ones.
Hope it helps...