diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index fbfb7914f0..44bba990ac 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -408,24 +408,12 @@ void PhysicsEngine::computeCollisionEvents() { } } - // 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; - } + const uint32_t CONTINUE_EVENT_FILTER_FREQUENCY = 10; - ++_numContactFrames; // scan known contacts and trigger events ContactMap::iterator contactItr = _contactMap.begin(); + + while (contactItr != _contactMap.end()) { ObjectMotionState* A = static_cast(contactItr->first._a); ObjectMotionState* B = static_cast(contactItr->first._b); @@ -433,21 +421,23 @@ void PhysicsEngine::computeCollisionEvents() { // TODO: make triggering these events clean and efficient. The code at this context shouldn't // have to figure out what kind of object (entity, avatar, etc) these are in order to properly // emit a collision event. - if (A && A->getType() == MOTION_STATE_TYPE_ENTITY) { - EntityItemID idA = static_cast(A)->getEntity()->getEntityItemID(); - EntityItemID idB; - if (B && B->getType() == MOTION_STATE_TYPE_ENTITY) { - idB = static_cast(B)->getEntity()->getEntityItemID(); - } - emit entityCollisionWithEntity(idA, idB, contactItr->second); - } else if (B && B->getType() == MOTION_STATE_TYPE_ENTITY) { - EntityItemID idA; - EntityItemID idB = static_cast(B)->getEntity()->getEntityItemID(); - emit entityCollisionWithEntity(idA, idB, contactItr->second); - } - // TODO: enable scripts to filter based on contact event type ContactEventType type = contactItr->second.computeType(_numContactFrames); + if(type != CONTACT_EVENT_TYPE_CONTINUE || _numSubsteps % CONTINUE_EVENT_FILTER_FREQUENCY == 0){ + if (A && A->getType() == MOTION_STATE_TYPE_ENTITY) { + EntityItemID idA = static_cast(A)->getEntity()->getEntityItemID(); + EntityItemID idB; + if (B && B->getType() == MOTION_STATE_TYPE_ENTITY) { + idB = static_cast(B)->getEntity()->getEntityItemID(); + } + emit entityCollisionWithEntity(idA, idB, contactItr->second); + } else if (B && B->getType() == MOTION_STATE_TYPE_ENTITY) { + EntityItemID idA; + EntityItemID idB = static_cast(B)->getEntity()->getEntityItemID(); + emit entityCollisionWithEntity(idA, idB, contactItr->second); + } + } + if (type == CONTACT_EVENT_TYPE_END) { ContactMap::iterator iterToDelete = contactItr; ++contactItr; @@ -456,6 +446,7 @@ void PhysicsEngine::computeCollisionEvents() { ++contactItr; } } + ++_numContactFrames; } void PhysicsEngine::dumpStatsIfNecessary() {