void BroadPhase2DHashGrid::_check_motion(Element *p_elem) { for (Map<Element*,PairData*>::Element *E=p_elem->paired.front();E;E=E->next()) { bool pairing = p_elem->aabb.intersects( E->key()->aabb ); if (pairing!=E->get()->colliding) { if (pairing) { if (pair_callback) { E->get()->ud=pair_callback(p_elem->owner,p_elem->subindex,E->key()->owner,E->key()->subindex,pair_userdata); } } else { if (unpair_callback) { unpair_callback(p_elem->owner,p_elem->subindex,E->key()->owner,E->key()->subindex,E->get()->ud,unpair_userdata); } } E->get()->colliding=pairing; } } }
void BroadPhaseBasic::remove(ID p_id) { Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); List<PairKey> to_erase; //unpair must be done immediately on removal to avoid potential invalid pointers for (Map<PairKey, void *>::Element *F = pair_map.front(); F; F = F->next()) { if (F->key().a == p_id || F->key().b == p_id) { if (unpair_callback) { Element *elem_A = &element_map[F->key().a]; Element *elem_B = &element_map[F->key().b]; unpair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, F->get(), unpair_userdata); } to_erase.push_back(F->key()); } } while (to_erase.size()) { pair_map.erase(to_erase.front()->get()); to_erase.pop_front(); } element_map.erase(E); }
void BroadPhase2DHashGrid::_unpair_attempt(Element *p_elem, Element* p_with) { Map<Element*,PairData*>::Element *E=p_elem->paired.find(p_with); ERR_FAIL_COND(!E); //this should really be paired.. E->get()->rc--; if (E->get()->rc==0) { if (E->get()->colliding) { //uncollide if (unpair_callback) { unpair_callback(p_elem->owner,p_elem->subindex,p_with->owner,p_with->subindex,E->get()->ud,unpair_userdata); } } memdelete(E->get()); p_elem->paired.erase(E); p_with->paired.erase(p_elem); } }
void BroadPhaseBasic::update() { // recompute pairs for (Map<ID, Element>::Element *I = element_map.front(); I; I = I->next()) { for (Map<ID, Element>::Element *J = I->next(); J; J = J->next()) { Element *elem_A = &I->get(); Element *elem_B = &J->get(); if (elem_A->owner == elem_B->owner) continue; bool pair_ok = elem_A->aabb.intersects(elem_B->aabb) && (!elem_A->_static || !elem_B->_static); PairKey key(I->key(), J->key()); Map<PairKey, void *>::Element *E = pair_map.find(key); if (!pair_ok && E) { if (unpair_callback) unpair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, E->get(), unpair_userdata); pair_map.erase(key); } if (pair_ok && !E) { void *data = NULL; if (pair_callback) data = pair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, unpair_userdata); pair_map.insert(key, data); } } } }