Added optional (and more powerful) collision filtering algorithm.

This commit is contained in:
enn0x 2011-11-12 23:26:53 +00:00
parent 7fc41e9cb8
commit 65885e5069
5 changed files with 157 additions and 13 deletions

View File

@ -47,9 +47,6 @@ INLINE BulletWorld::
_info.m_sparsesdf.Reset();
delete _ghost_cb;
delete _filter_cb;
delete _world;
delete _solver;
delete _configuration;

View File

@ -37,9 +37,11 @@ PStatCollector BulletWorld::_pstat_b2p("App:Bullet:DoPhysics:SyncB2P");
BulletWorld::
BulletWorld() {
// Callbacks
_ghost_cb = new btGhostPairCallback();
_filter_cb = new btFilterCallback();
// Init groups filter matrix
for (int i=0; i<32; i++) {
_filter_cb2._collide[i].clear();
_filter_cb2._collide[i].set_bit(i);
}
// Broadphase
btScalar dx(bullet_sap_extents);
@ -67,10 +69,23 @@ BulletWorld() {
// World
_world = new btSoftRigidDynamicsWorld(_dispatcher, _broadphase, _solver, _configuration);
_world->getPairCache()->setInternalGhostPairCallback(_ghost_cb);
_world->getPairCache()->setOverlapFilterCallback(_filter_cb);
_world->setGravity(btVector3(0.0f, 0.0f, 0.0f));
// Ghost-pair callback
_world->getPairCache()->setInternalGhostPairCallback(&_ghost_cb);
// Filter callback
switch (bullet_filter_algorithm) {
case FA_mask:
_world->getPairCache()->setOverlapFilterCallback(&_filter_cb1);
break;
case FA_groups_mask:
_world->getPairCache()->setOverlapFilterCallback(&_filter_cb2);
break;
default:
bullet_cat.error() << "no proper filter algorithm!" << endl;
}
// SoftBodyWorldInfo
_info.m_dispatcher = _dispatcher;
_info.m_broadphase = _broadphase;
@ -711,11 +726,38 @@ get_collision_object(PandaNode *node) {
}
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::FilterCallback::needBroadphaseCollision
// Function: BulletWorld::get_collision_object
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletWorld::
set_group_collision_flag(unsigned int group1, unsigned int group2, bool enable) {
if (bullet_filter_algorithm != FA_groups_mask) {
bullet_cat.warning() << "filter algorithm is not 'groups-mask'" << endl;
}
_filter_cb2._collide[group1].set_bit_to(group2, enable);
_filter_cb2._collide[group2].set_bit_to(group1, enable);
}
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::get_collision_object
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool BulletWorld::
get_group_collision_flag(unsigned int group1, unsigned int group2) const {
return _filter_cb2._collide[group1].get_bit(group2);
}
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::FilterCallback1::needBroadphaseCollision
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
bool BulletWorld::btFilterCallback::
bool BulletWorld::btFilterCallback1::
needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const {
btCollisionObject *obj0 = (btCollisionObject *) proxy0->m_clientObject;
@ -736,6 +778,39 @@ needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) co
return (mask0 & mask1) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::FilterCallback2::needBroadphaseCollision
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
bool BulletWorld::btFilterCallback2::
needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const {
btCollisionObject *obj0 = (btCollisionObject *) proxy0->m_clientObject;
btCollisionObject *obj1 = (btCollisionObject *) proxy1->m_clientObject;
nassertr(obj0, false);
nassertr(obj1, false);
PandaNode *node0 = (PandaNode *) obj0->getUserPointer();
PandaNode *node1 = (PandaNode *) obj1->getUserPointer();
nassertr(node0, false);
nassertr(node1, false);
CollideMask mask0 = node0->get_into_collide_mask();
CollideMask mask1 = node1->get_into_collide_mask();
for (int i=0; i<32; i++) {
if (mask0.get_bit(i)) {
if ((_collide[i] & mask1) != 0)
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::BroadphaseAlgorithm ostream operator
// Description:
@ -778,3 +853,45 @@ operator >> (istream &in, BulletWorld::BroadphaseAlgorithm &algorithm) {
return in;
}
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::FilterAlgorithm ostream operator
// Description:
////////////////////////////////////////////////////////////////////
ostream &
operator << (ostream &out, BulletWorld::FilterAlgorithm algorithm) {
switch (algorithm) {
case BulletWorld::FA_mask:
return out << "mask";
case BulletWorld::FA_groups_mask:
return out << "groups-mask";
};
return out << "**invalid BulletWorld::FilterAlgorithm(" << (int)algorithm << ")**";
}
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::FilterAlgorithm istream operator
// Description:
////////////////////////////////////////////////////////////////////
istream &
operator >> (istream &in, BulletWorld::FilterAlgorithm &algorithm) {
string word;
in >> word;
if (word == "mask") {
algorithm = BulletWorld::FA_mask;
}
else if (word == "groups-mask") {
algorithm = BulletWorld::FA_groups_mask;
}
else {
bullet_cat.error()
<< "Invalid BulletWorld::FilterAlgorithm: " << word << "\n";
algorithm = BulletWorld::FA_mask;
}
return in;
}

View File

@ -137,12 +137,21 @@ PUBLISHED:
BulletPersistentManifold *get_manifold(int idx) const;
MAKE_SEQ(get_manifolds, get_num_manifolds, get_manifold);
// Collision filtering
void set_group_collision_flag(unsigned int group1, unsigned int group2, bool enable);
bool get_group_collision_flag(unsigned int group1, unsigned int group2) const;
// Configuration
enum BroadphaseAlgorithm {
BA_sweep_and_prune,
BA_dynamic_aabb_tree,
};
enum FilterAlgorithm {
FA_mask,
FA_groups_mask,
};
public:
static btCollisionObject *get_collision_object(PandaNode *node);
@ -167,20 +176,30 @@ private:
static PStatCollector _pstat_p2b;
static PStatCollector _pstat_b2p;
struct btFilterCallback : public btOverlapFilterCallback {
struct btFilterCallback1 : public btOverlapFilterCallback {
virtual bool needBroadphaseCollision(
btBroadphaseProxy* proxy0,
btBroadphaseProxy* proxy1) const;
};
struct btFilterCallback2 : public btOverlapFilterCallback {
virtual bool needBroadphaseCollision(
btBroadphaseProxy* proxy0,
btBroadphaseProxy* proxy1) const;
CollideMask _collide[32];
};
btBroadphaseInterface *_broadphase;
btCollisionConfiguration *_configuration;
btCollisionDispatcher *_dispatcher;
btConstraintSolver *_solver;
btSoftRigidDynamicsWorld *_world;
btGhostPairCallback *_ghost_cb;
btFilterCallback *_filter_cb;
btGhostPairCallback _ghost_cb;
btFilterCallback1 _filter_cb1;
btFilterCallback2 _filter_cb2;
btSoftBodyWorldInfo _info;
@ -220,6 +239,11 @@ operator << (ostream &out, BulletWorld::BroadphaseAlgorithm algorithm);
EXPCL_PANDABULLET istream &
operator >> (istream &in, BulletWorld::BroadphaseAlgorithm &algorithm);
EXPCL_PANDABULLET ostream &
operator << (ostream &out, BulletWorld::FilterAlgorithm algorithm);
EXPCL_PANDABULLET istream &
operator >> (istream &in, BulletWorld::FilterAlgorithm &algorithm);
#include "bulletWorld.I"
#endif // __BULLET_WORLD_H__

View File

@ -73,6 +73,11 @@ ConfigVariableEnum<BulletWorld::BroadphaseAlgorithm> bullet_broadphase_algorithm
PRC_DESC("Specifies the broadphase algorithm to be used by the physics "
"engine. Default value is 'aabb' (dynamic aabb tree)."));
ConfigVariableEnum<BulletWorld::FilterAlgorithm> bullet_filter_algorithm
("bullet-filter-algorithm", BulletWorld::FA_mask,
PRC_DESC("Specifies the algorithm to be used by the physics engine for "
"collision filtering. Default value is 'mask'."));
ConfigVariableDouble bullet_sap_extents
("bullet-sap-extents", 1000.0,
PRC_DESC("Specifies the world extent in all directions. The config variable "

View File

@ -31,6 +31,7 @@ NotifyCategoryDecl(bullet, EXPCL_PANDABULLET, EXPTP_PANDABULLET);
extern ConfigVariableInt bullet_max_objects;
extern ConfigVariableInt bullet_gc_lifetime;
extern ConfigVariableEnum<BulletWorld::BroadphaseAlgorithm> bullet_broadphase_algorithm;
extern ConfigVariableEnum<BulletWorld::FilterAlgorithm> bullet_filter_algorithm;
extern ConfigVariableDouble bullet_sap_extents;
extern ConfigVariableBool bullet_enable_contact_events;
extern ConfigVariableInt bullet_solver_iterations;