Merge pull request #4659 from ericrius1/collision

Filtering triggering of collisions with contact type of "continue"
This commit is contained in:
Andrew Meadows 2015-04-22 09:33:40 -07:00
commit 65825a4501

View file

@ -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<ObjectMotionState*>(contactItr->first._a);
ObjectMotionState* B = static_cast<ObjectMotionState*>(contactItr->first._b);
@ -433,6 +421,9 @@ 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<EntityMotionState*>(A)->getEntity()->getEntityItemID();
EntityItemID idB;
@ -445,9 +436,8 @@ void PhysicsEngine::computeCollisionEvents() {
EntityItemID idB = static_cast<EntityMotionState*>(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;
@ -456,6 +446,7 @@ void PhysicsEngine::computeCollisionEvents() {
++contactItr;
}
}
++_numContactFrames;
}
void PhysicsEngine::dumpStatsIfNecessary() {