Added optional (and more powerful) collision filtering algorithm.
This commit is contained in:
parent
7fc41e9cb8
commit
65885e5069
|
|
@ -47,9 +47,6 @@ INLINE BulletWorld::
|
|||
|
||||
_info.m_sparsesdf.Reset();
|
||||
|
||||
delete _ghost_cb;
|
||||
delete _filter_cb;
|
||||
|
||||
delete _world;
|
||||
delete _solver;
|
||||
delete _configuration;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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__
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue