/**\brief Retrieves nearby QuadTrees * \param c Coordinate * \param r Radius * \return std::list of QuadTree pointers. */ list<QuadTree*> SpriteManager::GetQuadrantsNear( Coordinate c, float r) { // The possibleQuadrants are those trees adjacent and within a radius r // Gather more trees when r is greater than the size of a quadrant map<Coordinate,QuadTree*>::iterator iter; list<QuadTree*> nearbyQuadrants; set<Coordinate> possibleQuadrants; Coordinate center = GetQuadrantCenter(c); possibleQuadrants.insert( center ); float R = r; do{ possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(-R,-0))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(-0,+R))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(+0,-R))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(+R,+0))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(-R,-R))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(-R,+R))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(+R,-R))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(+R,+R))); R/=2; } while(R>QUADRANTSIZE); set<Coordinate>::iterator it; for(it = possibleQuadrants.begin(); it != possibleQuadrants.end(); ++it) { //here we're checking to see if this possible quadrant is one of the existing quadrants // and if it is then we add its QuadTree to the vector we're returning //how about we try creating the quadrant if it does not already exist iter = trees.find(*it); if(iter != trees.end() && iter->second->PossiblyNear(c,r)){ nearbyQuadrants.push_back(iter->second); } } return nearbyQuadrants; }
/**\brief Retrieves nearby QuadTrees * \param c Coordinate * \param r Radius * \return std::list of QuadTree pointers. */ list<QuadTree*> SpriteManager::GetQuadrantsNear( Coordinate c, float r) { // The possibleQuadrants are those trees adjacent and within a radius r // Gather more trees when r is greater than the size of a quadrant map<Coordinate,QuadTree*>::iterator iter; list<QuadTree*> nearbyQuadrants; set<Coordinate> possibleQuadrants; possibleQuadrants.insert( GetQuadrantCenter(c)); float R = r; do{ possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(-R,-0))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(-0,+R))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(+0,-R))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(+R,+0))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(-R,-R))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(-R,+R))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(+R,-R))); possibleQuadrants.insert( GetQuadrantCenter(c + Coordinate(+R,+R))); R/=2; } while(R>QUADRANTSIZE); set<Coordinate>::iterator it; for(it = possibleQuadrants.begin(); it != possibleQuadrants.end(); ++it) { iter = trees.find(*it); if(iter != trees.end() && iter->second->PossiblyNear(c,r)){ nearbyQuadrants.push_back(iter->second); } } return nearbyQuadrants; }
/**\brief Draws the current sprites */ void SpriteManager::Draw() { if( OPTION(int,"options/development/debug-quadtree") ) GetQuadrant( Camera::Instance()->GetFocusCoordinate() )->Draw( GetQuadrantCenter( Camera::Instance()->GetFocusCoordinate() ) ); list<Sprite *>::iterator i; list<Sprite*> *onscreen; float r = (Video::GetHalfHeight() < Video::GetHalfWidth() ? Video::GetHalfWidth() : Video::GetHalfHeight()) *V_SQRT2; onscreen = GetSpritesNear( Camera::Instance()->GetFocusCoordinate(), r, DRAW_ORDER_ALL); onscreen->sort(compareSpritePtrs); for( i = onscreen->begin(); i != onscreen->end(); ++i ) { (*i)->Draw(); } delete onscreen; }
/**\brief Returns QuadTree at Coordinate * \param point Coordinate */ QuadTree* SpriteManager::GetQuadrant( Coordinate point ) { Coordinate treeCenter = GetQuadrantCenter(point); // Check in the known Quadrant map<Coordinate,QuadTree*>::iterator iter; iter = trees.find( treeCenter ); if( iter != trees.end() ) { return iter->second; } // Create the new Tree and attach it to the universe QuadTree *newTree = new QuadTree(treeCenter, QUADRANTSIZE); assert(treeCenter == newTree->GetCenter() ); assert(newTree->Contains(point)); trees.insert(make_pair(treeCenter, newTree)); AdjustBoundaries(); // Debug //cout<<"A Tree at "<<treeCenter<<" was created to contain "<<point<<". "<<trees.size()<<" Quadrants exist now."<<endl; return newTree; }
/**\brief Retrieves nearby QuadTrees in a square band at <bandIndex> quadrants distant from the coordinate * \param c Coordinate * \param bandIndex number of quadrants distant from c * \return std::list of QuadTree pointers. */ list<QuadTree*> SpriteManager::GetQuadrantsInBand ( Coordinate c, int bandIndex) { // The possibleQuadrants here are the quadrants that are in the square band // at distance bandIndex from the coordinate // After we get the possible quadrants we prune them by making sure they exist // (ie that something is in them) list<QuadTree*> nearbyQuadrants; set<Coordinate> possibleQuadrants; //note that the QUADRANTSIZE define is the // distance from the middle to the edge of a quadrant //to get the square band of co-ordinates we have to // - start at bottom left // loop over increasing Y (to get 'west' line) // loop over increasing X (to get 'south' line) // - start at top right // loop over decreasing Y (to get 'east' line) // loop over decreasing X (to get 'north' line) int edgeDistance = bandIndex * QUADRANTSIZE * 2; //number of pixels from middle to the band Coordinate bottomLeft (c - Coordinate (edgeDistance, edgeDistance)); Coordinate topLeft (c + Coordinate (-edgeDistance, edgeDistance)); Coordinate topRight (c + Coordinate (edgeDistance, edgeDistance)); Coordinate bottomRight (c + Coordinate (edgeDistance, -edgeDistance)); //the 'full' length of one of the lines is (bandindex * 2) + 1 //we don't need the +1 as we deal with the corners individually, separately int bandLength = (bandIndex * 2); //deal with the un-included corners first //we're using bottomLeft and topRight as the anchors, // so topLeft and bottomRight are added here possibleQuadrants.insert (GetQuadrantCenter (topLeft)); possibleQuadrants.insert (GetQuadrantCenter (bottomRight)); for (int i = 0; i < bandLength; i ++) { int offset = ((QUADRANTSIZE * 2) * i); Coordinate west, south, north, east; west = GetQuadrantCenter (bottomLeft + Coordinate (0, offset)); south = GetQuadrantCenter (bottomLeft + Coordinate (offset, 0)); north = GetQuadrantCenter (topRight - Coordinate (offset, 0)); east = GetQuadrantCenter (topRight - Coordinate (0, offset)); possibleQuadrants.insert (west); //west possibleQuadrants.insert (south); //south possibleQuadrants.insert (north); //north possibleQuadrants.insert (east); //east } //here we're checking to see if this possible quadrant is one of the existing quadrants // and if it is then we add its QuadTree to the vector we're returning // if it's not then there's nothing in it anyway so we don't care about it set<Coordinate>::iterator it; map<Coordinate,QuadTree*>::iterator iter; for(it = possibleQuadrants.begin(); it != possibleQuadrants.end(); ++it) { iter = trees.find(*it); if(iter != trees.end()) { nearbyQuadrants.push_back(iter->second); } } return nearbyQuadrants; }
/**\brief Draws the current sprites */ void SpriteManager::DrawQuadrantMap( Coordinate focus ) { GetQuadrant( focus )->Draw( GetQuadrantCenter( focus ) ); }
/**\brief Draws the current sprites */ void SpriteManager::DrawQuadrantMap() { GetQuadrant( Camera::Instance()->GetFocusCoordinate() )->Draw( GetQuadrantCenter( Camera::Instance()->GetFocusCoordinate() ) ); }