From 096f69961a695eb1dee16d82248fc1bb7055bc0a Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Thu, 16 Apr 2015 16:42:28 -0700 Subject: [PATCH 1/2] Filtering triggering of collisions with contact type of "continue" --- libraries/physics/src/PhysicsEngine.cpp | 44 ++++++++++--------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 50f52a7efc..68a71c59c3 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -395,24 +395,13 @@ 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(); + + // TODO: enable scripts to filter based on contact event type + ContactEventType type = contactItr->second.computeType(_numContactFrames); while (contactItr != _contactMap.end()) { ObjectMotionState* A = static_cast(contactItr->first._a); ObjectMotionState* B = static_cast(contactItr->first._b); @@ -420,21 +409,21 @@ 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(); + 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); } - 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_END) { ContactMap::iterator iterToDelete = contactItr; ++contactItr; @@ -443,6 +432,7 @@ void PhysicsEngine::computeCollisionEvents() { ++contactItr; } } + ++_numContactFrames; } // Bullet collision flags are as follows: From 2b4d894ab3b706d6ec7e07eebfede0c1038f3d88 Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Fri, 17 Apr 2015 08:17:58 -0700 Subject: [PATCH 2/2] moved the type computation inside the while loop so it is correctly computed each iteration --- libraries/physics/src/PhysicsEngine.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 68a71c59c3..e43fffb20a 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -400,8 +400,7 @@ void PhysicsEngine::computeCollisionEvents() { // scan known contacts and trigger events ContactMap::iterator contactItr = _contactMap.begin(); - // TODO: enable scripts to filter based on contact event type - ContactEventType type = contactItr->second.computeType(_numContactFrames); + while (contactItr != _contactMap.end()) { ObjectMotionState* A = static_cast(contactItr->first._a); ObjectMotionState* B = static_cast(contactItr->first._b); @@ -409,6 +408,8 @@ 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. + // 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();