//Returns false if the point could not be removed (it doesn't exist) //data is used to make sure it is the point requested //NOTE: X and Y are not used when comparing the point, just for walking the tree, //so if you have two of the same data, it might not remove the one //at the position specified (the system assumes you are using pointers) bool remove(T searchData, float x, float y) { //Point will not be in this node's bounds if(!isPointInRange(x, y, bounds)) return false; //Search through points for the data for (typename std::list<QuadPoint<T> >::iterator it = data.begin(); it!= data.end(); ++it) { //Found the data point; erase it (inefficient only in large vectors) //TODO: Replace vector with list or something? if ((*it).data==searchData) { data.erase(it); return true; } } //Search children (if any) if (!tL) return false; if (tL->remove(searchData, x, y) || tR->remove(searchData, x, y) || bL->remove(searchData, x, y) || bR->remove(searchData, x, y)) { //All children are empty; delete them if (isEmpty()) { //TODO: Should this be a pool? delete tL; delete tR; delete bL; delete bR; tL = NULL; } return true; } //Data point not in quadtree return false; }
bool ZoneContainerComponent::removeActiveArea(Zone* zone, ActiveArea* activeArea) { if (zone == NULL) return false; ManagedReference<SceneObject*> thisLocker = activeArea; Locker zoneLocker(zone); QuadTree* regionTree = zone->getRegionTree(); regionTree->remove(activeArea); // lets remove the in range active areas of players SortedVector<QuadTreeEntry*> objects; float range = activeArea->getRadius() + 64; zone->getInRangeObjects(activeArea->getPositionX(), activeArea->getPositionY(), range, &objects, false); zone->dropSceneObject(activeArea); zoneLocker.release(); for (int i = 0; i < objects.size(); ++i) { SceneObject* object = cast<SceneObject*>(objects.get(i)); // Locker olocker(object); if (!object->isTangibleObject()) { continue; } TangibleObject* tano = cast<TangibleObject*>(object); if (tano->hasActiveArea(activeArea)) { tano->dropActiveArea(activeArea); activeArea->enqueueExitEvent(object); } } activeArea->notifyObservers(ObserverEventType::OBJECTREMOVEDFROMZONE, NULL, 0); activeArea->setZone(NULL); return true; }