3
0
Fork 0
mirror of https://github.com/JulianGro/overte.git synced 2025-05-01 00:43:38 +02:00

don't send collision events for inactive pairs

also throttle collision events to 30/sec
This commit is contained in:
Andrew Meadows 2015-01-21 18:02:13 -08:00
parent 5a7912de17
commit 2751fab2c3
2 changed files with 28 additions and 3 deletions

View file

@ -249,23 +249,47 @@ void PhysicsEngine::stepSimulation() {
}
void PhysicsEngine::computeCollisionEvents() {
// update all contacts
// update all contacts every frame
int numManifolds = _collisionDispatcher->getNumManifolds();
for (int i = 0; i < numManifolds; ++i) {
btPersistentManifold* contactManifold = _collisionDispatcher->getManifoldByIndexInternal(i);
if (contactManifold->getNumContacts() > 0) {
// TODO: require scripts to register interest in callbacks for specific objects
// so we can filter out most collision events right here.
const btCollisionObject* objectA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
const btCollisionObject* objectB = static_cast<const btCollisionObject*>(contactManifold->getBody1());
if (!(objectA->isActive() || objectB->isActive())) {
// both objects are inactive so stop tracking this contact,
// which will eventually trigger a CONTACT_EVENT_TYPE_END
continue;
}
void* a = objectA->getUserPointer();
void* b = objectB->getUserPointer();
if (a || b) {
// the manifold has up to 4 distinct points, but only extract info from the first
_contactMap[ContactKey(a, b)].update(_numSubsteps, contactManifold->getContactPoint(0), _originOffset);
_contactMap[ContactKey(a, b)].update(_numContactFrames, contactManifold->getContactPoint(0), _originOffset);
}
}
}
// We harvest collision callbacks every few frames, which contributes the following effects:
//
// (1) There is a maximum collision callback rate per pair: substep_rate / SUBSTEPS_PER_COLLIION_FRAME
// (2) END/START cycles shorter than SUBSTEPS_PER_COLLIION_FRAME will be filtered out
// (3) There is variable lag between when the contact actually starts and when it is reported,
// up to SUBSTEPS_PER_COLLIION_FRAME * time_per_substep
//
const uint32_t SUBSTEPS_PER_COLLISION_FRAME = 2;
if (_numSubsteps - _numContactFrames * SUBSTEPS_PER_COLLISION_FRAME < SUBSTEPS_PER_COLLISION_FRAME) {
// we don't harvest collision callbacks every frame
// this sets a maximum callback-per-contact rate
// and also filters out END/START events that happen on shorter timescales
return;
}
++_numContactFrames;
// scan known contacts and trigger events
ContactMap::iterator contactItr = _contactMap.begin();
while (contactItr != _contactMap.end()) {
@ -289,7 +313,7 @@ void PhysicsEngine::computeCollisionEvents() {
}
// TODO: enable scripts to filter based on contact event type
ContactEventType type = contactItr->second.computeType(_numSubsteps);
ContactEventType type = contactItr->second.computeType(_numContactFrames);
if (type == CONTACT_EVENT_TYPE_END) {
ContactMap::iterator iterToDelete = contactItr;
++contactItr;

View file

@ -110,6 +110,7 @@ private:
EntityEditPacketSender* _entityPacketSender = NULL;
ContactMap _contactMap;
uint32_t _numContactFrames = 0;
};
#endif // hifi_PhysicsEngine_h