// Callback from the spatial hash. static void queryFunc(cpShape *a, cpShape *b, cpSpace *space) { // Reject any of the simple cases if(queryReject(a,b)) return; cpCollisionHandler *handler = lookupCollisionHandler(space, a->collision_type, b->collision_type); cpBool sensor = a->sensor || b->sensor; if(sensor && handler == &cpSpaceDefaultHandler) return; // Shape 'a' should have the lower shape type. (required by cpCollideShapes() ) if(a->klass->type > b->klass->type){ cpShape *temp = a; a = b; b = temp; } // Narrow-phase collision detection. cpContact *contacts = cpContactBufferGetArray(space); int numContacts = cpCollideShapes(a, b, contacts); if(!numContacts) return; // Shapes are not colliding. cpSpacePushContacts(space, numContacts); // Get an arbiter from space->contactSet for the two shapes. // This is where the persistant contact magic comes from. cpShape *shape_pair[] = {a, b}; cpHashValue arbHashID = CP_HASH_PAIR((size_t)a, (size_t)b); cpArbiter *arb = (cpArbiter *)cpHashSetInsert(space->contactSet, arbHashID, shape_pair, space); cpArbiterUpdate(arb, contacts, numContacts, handler, a, b); // Call the begin function first if it's the first step if(arb->state == cpArbiterStateFirstColl && !handler->begin(arb, space, handler->data)){ cpArbiterIgnore(arb); // permanently ignore the collision until separation } if( // Ignore the arbiter if it has been flagged (arb->state != cpArbiterStateIgnore) && // Call preSolve handler->preSolve(arb, space, handler->data) && // Process, but don't add collisions for sensors. !sensor ){ cpArrayPush(space->arbiters, arb); } else { cpSpacePopContacts(space, numContacts); arb->contacts = NULL; arb->numContacts = 0; // Normally arbiters are set as used after calling the post-step callback. // However, post-step callbacks are not called for sensors or arbiters rejected from pre-solve. if(arb->state != cpArbiterStateIgnore) arb->state = cpArbiterStateNormal; } // Time stamp the arbiter so we know it was used recently. arb->stamp = space->stamp; }
static mrb_value arbiter_ignore(mrb_state* mrb, mrb_value self) { cpArbiter* arbiter; cpFloat ignore; arbiter = mrb_cp_get_arbiter_ptr(mrb, self); ignore = cpArbiterIgnore(arbiter); return mrb_bool_value(ignore); }
static cpBool PreSolve(cpArbiter *arb, cpSpace *space, void *ignore) { CP_ARBITER_GET_SHAPES(arb, a, b); OneWayPlatform *platform = (OneWayPlatform *)cpShapeGetUserData(a); if(cpvdot(cpArbiterGetNormal(arb), platform->n) < 0){ return cpArbiterIgnore(arb); } return cpTrue; }
static cpBool preSolve(cpArbiter *arb, cpSpace *space, void *ignore) { CP_ARBITER_GET_SHAPES(arb, a, b); OneWayPlatform *platform = (OneWayPlatform *)a->data; if(cpvdot(cpArbiterGetNormal(arb, 0), platform->n) < 0){ cpArbiterIgnore(arb); return cpFalse; } return cpTrue; }
int PhysicsWorld::collisionPreSolveCallback(PhysicsContact& contact) { if (!contact.isNotificationEnabled()) { cpArbiterIgnore(static_cast<cpArbiter*>(contact._contactInfo)); return true; } contact.setEventCode(PhysicsContact::EventCode::PRESOLVE); contact.setWorld(this); _scene->getEventDispatcher()->dispatchEvent(&contact); return contact.resetResult(); }
int PhysicsWorld::collisionPreSolveCallback(PhysicsContact& contact) { if (!contact.isNotificationEnabled()) { cpArbiterIgnore(static_cast<cpArbiter*>(contact.m_pContactInfo)); return true; } contact.setEventCode(PhysicsContact::EventCode::PRESOLVE); contact.setWorld(this); EventCustom event(PHYSICSCONTACT_EVENT_NAME); event.setUserData(&contact); m_pScene->getEventDispatcher()->dispatchEvent(&event); return contact.resetResult(); }
void cArbiter::Ignore() { return cpArbiterIgnore( mArbiter ); }
// Callback from the spatial hash. static void queryFunc(cpShape *a, cpShape *b, cpSpace *space) { // Reject any of the simple cases if(queryReject(a,b)) return; // Find the collision pair function for the shapes. struct{cpCollisionType a, b;} ids = {a->collision_type, b->collision_type}; cpHashValue collHashID = CP_HASH_PAIR(a->collision_type, b->collision_type); cpCollisionHandler *handler = (cpCollisionHandler *)cpHashSetFind(space->collFuncSet, collHashID, &ids); int sensor = a->sensor || b->sensor; if(sensor && handler == &space->defaultHandler) return; // Shape 'a' should have the lower shape type. (required by cpCollideShapes() ) if(a->klass->type > b->klass->type){ cpShape *temp = a; a = b; b = temp; } if(space->contactBuffersHead->numContacts + CP_MAX_CONTACTS_PER_ARBITER > CP_CONTACTS_BUFFER_SIZE){ // contact buffer could overflow on the next collision, push a fresh one. cpSpacePushNewContactBuffer(space); } // Narrow-phase collision detection. cpContact *contacts = ((cpContactBuffer *)(space->contactBuffersHead))->contacts + space->contactBuffersHead->numContacts; int numContacts = cpCollideShapes(a, b, contacts); if(!numContacts) return; // Shapes are not colliding. space->contactBuffersHead->numContacts += numContacts; // Get an arbiter from space->contactSet for the two shapes. // This is where the persistant contact magic comes from. cpShape *shape_pair[] = {a, b}; cpHashValue arbHashID = CP_HASH_PAIR((size_t)a, (size_t)b); cpArbiter *arb = (cpArbiter *)cpHashSetInsert(space->contactSet, arbHashID, shape_pair, space); cpArbiterUpdate(arb, contacts, numContacts, handler, a, b); // retains the contacts array // Call the begin function first if it's the first step if(arb->stamp == -1 && !handler->begin(arb, space, handler->data)){ cpArbiterIgnore(arb); // permanently ignore the collision until separation } if( // Ignore the arbiter if it has been flagged (arb->state != cpArbiterStateIgnore) && // Call preSolve handler->preSolve(arb, space, handler->data) && // Process, but don't add collisions for sensors. !sensor ){ cpArrayPush(space->arbiters, arb); } else { // cpfree(arb->contacts); space->contactBuffersHead->numContacts -= numContacts; arb->contacts = NULL; arb->numContacts = 0; } // Time stamp the arbiter so we know it was used recently. arb->stamp = space->stamp; }
void PhysicsContactPreSolve::ignore() { cpArbiterIgnore(static_cast<cpArbiter*>(_contactInfo)); }