void QuadTreeNode::update(QuadTreeOccupant* pOc) { // Remove, may be re-added to this node later m_pOccupants.erase(pOc); // Propogate upwards, looking for a node that has room (the current one may still have room) QuadTreeNode* pNode = this; //auto tempQuadTree = m_pQuadTree; while(pNode != NULL) { pNode->m_numOccupantsBelow--; // If has room for 1 more, found a spot if(pNode->m_region.contains(pOc->m_aabb)) break; pNode = pNode->m_pParent; } // If no node that could contain the occupant was found, add to outside root set if(pNode == NULL) { pOc->m_pQuadTreeNode = NULL; //f*****g 5 characters is what i spent my saturday and sunday morning writing, 5 f*****g characters //guess what? no checks for this->m_pQuadTree being null, and no initialization either, so i get a shit ton of segmention fault //(well 1 but that's a shit ton) pOc->m_pQuadTree->m_outsideRoot.insert(pOc); } else // Add to the selected node pNode->add(pOc); }
void QuadTreeNode::update(QuadTreeOccupant* occupant) { // Remove, may be re-added to this node later occupants.erase(occupant); // Propogate upwards, looking for a node that has room (the current one may still have room) QuadTreeNode* n = this; while(n) { n->numOccupantsBelow--; // If has room for 1 more, found a spot if(n->region.contains(occupant->aabb)) break; n = n->parent; } // If no node that could contain the occupant was found, add to outside root set if(!n) { tree->outsideRoot.insert(occupant); occupant->node = NULL; } else // Add to the selected node n->add(occupant); }
void QuadTree::update_object(GameObject *object) { QuadTreeNode *node = m_object_node_map[object->getID()]; node->remove_object(object); add_object(object); }
Ogre::WorkQueue::Response* World::handleRequest(const Ogre::WorkQueue::Request *req, const Ogre::WorkQueue *srcQ) { if (req->getType() == REQ_ID_CHUNK) { const LoadRequestData data = Ogre::any_cast<LoadRequestData>(req->getData()); QuadTreeNode* node = data.mNode; LoadResponseData* responseData = new LoadResponseData(); getStorage()->fillVertexBuffers(node->getNativeLodLevel(), node->getSize(), node->getCenter(), getAlign(), responseData->mPositions, responseData->mNormals, responseData->mColours); return OGRE_NEW Ogre::WorkQueue::Response(req, true, Ogre::Any(responseData)); } else // REQ_ID_LAYERS { const LayersRequestData data = Ogre::any_cast<LayersRequestData>(req->getData()); LayersResponseData* responseData = new LayersResponseData(); getStorage()->getBlendmaps(data.mNodes, responseData->mLayerCollections, data.mPack); return OGRE_NEW Ogre::WorkQueue::Response(req, true, Ogre::Any(responseData)); } }
void QuadTreeNode::Update(QuadTreeOccupant* pOc) { // Remove, may be re-added to this node later m_pOccupants.erase(pOc); // Propogate upwards, looking for a node that has room (the current one may still have room) QuadTreeNode* pNode = this; while(pNode != NULL) { pNode->m_numOccupantsBelow--; // If has room for 1 more, found a spot if(pNode->m_region.Contains(pOc->m_aabb)) break; pNode = pNode->m_pParent; } // If no node that could contain the occupant was found, add to outside root set if(pNode == NULL) { m_pQuadTree->m_outsideRoot.insert(pOc); pOc->m_pQuadTreeNode = NULL; } else // Add to the selected node pNode->Add(pOc); }
Ogre::AxisAlignedBox World::getWorldBoundingBox (const Ogre::Vector2& center) { if (center.x > mMaxX || center.x < mMinX || center.y > mMaxY || center.y < mMinY) return Ogre::AxisAlignedBox::BOX_NULL; QuadTreeNode* node = findNode(center, mRootNode); return node->getWorldBoundingBox(); }
QuadTreeNode* QuadTreeNode::create(double xMin, double yMin, double xMax, double yMax, QuadTree* belongTree, QuadTreeNode* parentNode) { QuadTreeNode* quadTreeNode = new QuadTreeNode(); if(quadTreeNode->init(xMin, yMin, xMax, yMax, belongTree, parentNode)) { return quadTreeNode; } delete quadTreeNode; return NULL; }
void printQTNode( const QuadTreeNode<TestElement> & node, const char * prefix ) { QuadTreeNode<TestElement>::Elements::const_iterator iter = node.elements().begin(); while (iter != node.elements().end()) { dprintf( "%s(%d, %d) 0x%08x\n", prefix, (*iter)->x_, (*iter)->y_, *iter ); iter++; } }
int main(){ int N; cin >> N; for(int i=0; i<N; ++i){ string streeA, streeB; cin >> streeA >> streeB; QuadTreeNode* treeA = build(streeA); QuadTreeNode* treeB = build(streeB); QuadTreeNode* treeC = sumar(treeA, treeB); cout << "There are " << treeC->blackPixels() << " black pixels." << endl; } }
void QuadTreeNode::GetTreeDwellersAboveAndUnder(GrowingArray<QuadTreeDweller*>& anOutArray, int someTreeDwellerFlags) { GetTreeDwellers(anOutArray,someTreeDwellerFlags); GetTreeDwellersUnder(anOutArray,someTreeDwellerFlags); QuadTreeNode* treeNodeIterator = myParentNode; while(treeNodeIterator != NULL) { treeNodeIterator->GetTreeDwellers(anOutArray,someTreeDwellerFlags); treeNodeIterator = treeNodeIterator->myParentNode; } }
QuadTreeNode* QuadTreeNode::west_nbr(QuadTreeNode *node) { if(node->GetParent() == nullptr) //We arrived at the root. return nullptr; if((node->GetNodeType() & 0x1) == 1) //(NORTH/SOUTH)-EAST node return (node->GetNodeType() == NE ? node->GetParent()->GetChild(NW) : node->GetParent()->GetChild(SW)); QuadTreeNode* tmp = west_nbr(node->GetParent()); if(tmp == nullptr || tmp->IsLeaf()) return tmp; return (node->GetNodeType() == NW ? tmp->GetChild(NE) : tmp->GetChild(SE)); }
QuadTreeNode* QuadTreeNode::south_nbr(QuadTreeNode *node) { if(node->GetParent() == nullptr) //We arrived at the root. return nullptr; if(node->GetNodeType() >> 1 == 1) //NORTH-(WEST/EAST) node return (node->GetNodeType() == NE ? node->GetParent()->GetChild(SE) : node->GetParent()->GetChild(SW)); QuadTreeNode* tmp = south_nbr(node->GetParent()); if(tmp == nullptr || tmp->IsLeaf()) return tmp; return (node->GetNodeType() == SW ? tmp->GetChild(NW) : tmp->GetChild(NE)); }
void QuadTreeNode::MoveUnitsToChildren() { map<int, struct UnitInformationContainer>::iterator iter; for ( iter = UnitsContained.begin() ; iter != UnitsContained.end() ; iter++ ) { int unitID = iter->first; SAIFloat3 pos = iter->second.pos; UnitDef* def = iter->second.def; if ( !IsLeaf ) { QuadTreeNode* node = GetContainingNode( pos ); node->InsertUnit( unitID, pos, def ); } } UnitsContained.clear(); }
void insertContent( Content * c ) { #ifdef QUADDEBUG log() << "QUADTREE Insert of " << c << std::endl; #endif rootNode_.insertContent( c ); #ifdef QUADDEBUG log() << "QUADTREE Completed insert of " << c << std::endl; #endif };
bool QuadTreeNode::addToChildren(QuadTreeOccupant* occupant) { assert(hasChildren); Point2i position; getPossibleOccupantPosition(occupant, position); QuadTreeNode* c = getChild(position); // See if the occupant fits in the child at the selected position if(c->region.contains(occupant->aabb)) { // Fits, so can add to the child and finish c->add(occupant); return true; } return false; }
void QuadTreeNode::updateIndexBuffers() { if (hasChunk()) { // Fetch a suitable index buffer (which may be shared) size_t ourLod = getActualLodLevel(); int flags = 0; for (int i=0; i<4; ++i) { QuadTreeNode* neighbour = getNeighbour((Direction)i); // If the neighbour isn't currently rendering itself, // go up until we find one. NOTE: We don't need to go down, // because in that case neighbour's detail would be higher than // our detail and the neighbour would handle stitching by itself. while (neighbour && !neighbour->hasChunk()) neighbour = neighbour->getParent(); size_t lod = 0; if (neighbour) lod = neighbour->getActualLodLevel(); if (lod <= ourLod) // We only need to worry about neighbours less detailed than we are - lod = 0; // neighbours with more detail will do the stitching themselves // Use 4 bits for each LOD delta if (lod > 0) { assert (lod - ourLod < (1 << 4)); flags |= int(lod - ourLod) << (4*i); } } flags |= 0 /*((int)mAdditionalLod)*/ << (4*4); mChunk->setIndexBuffer(mTerrain->getBufferCache().getIndexBuffer(flags)); } else if (hasChildren()) { for (int i=0; i<4; ++i) mChildren[i]->updateIndexBuffers(); } }
bool QuadTreeNode::AddToChildren(QuadTreeOccupant* pOc) { assert(m_hasChildren); Point2i position; GetPossibleOccupantPosition(pOc, position); QuadTreeNode* pChild = GetChild(position); // See if the occupant fits in the child at the selected position if(pChild->m_region.Contains(pOc->m_aabb)) { // Fits, so can add to the child and finish pChild->Add(pOc); return true; } return false; }
void QuadTreeNode::get_objects_by_frustum(const Frustum &frustum, std::vector<GameObject*> &objects) { for (GameObject *object : m_objects) { const Aabb &aabb = object->get_bounding_box(); if (frustum.intersects_aabb(aabb)) objects.push_back(object); } if (is_leaf()) return; for (size_t i = 0; i < 4; i++) { QuadTreeNode *child = m_children[i]; const Vector3 radius_vec(child->m_radius, 1000.0f, child->m_radius); const Vector3 center_vec(child->m_center.x, 0.0f, child->m_center.y); const Aabb node_aabb(center_vec - radius_vec, center_vec + radius_vec); if (frustum.intersects_aabb(node_aabb)) child->get_objects_by_frustum(frustum, objects); } }
void QuadTreeNode::get_objects_by_radius(const Vector3 &position, float radius, std::vector<GameObject*> &objects) { for (GameObject *object : m_objects) { if (object->get_bounding_box().intersects_sphere(position, radius)) objects.push_back(object); } if (is_leaf()) return; for (size_t i = 0; i < 4; i++) { QuadTreeNode *child = m_children[i]; const Vector3 radius_vec(child->m_radius, 0.0f, child->m_radius); const Vector3 center_vec(child->m_center.x, 0.0f, child->m_center.y); const Aabb node_aabb(center_vec - radius_vec, center_vec + radius_vec); if (node_aabb.intersects_sphere(position, radius)) child->get_objects_by_radius(position, radius, objects); } }
void QuadTreeOccupant::TreeUpdate() { if(m_pQuadTree == NULL) return; if(m_pQuadTreeNode == NULL) { // If fits in the root now, add it QuadTreeNode* pRootNode = m_pQuadTree->m_pRootNode.get(); if(pRootNode->m_region.Contains(m_aabb)) { // Remove from outside root and add to tree m_pQuadTree->m_outsideRoot.erase(this); pRootNode->Add(this); } } else m_pQuadTreeNode->Update(this); }
int main(int argc, char **argv) { Image *img = new Image("./data/black.png"); std::vector<int> data = img->get_rgba(0, 0); printf("rgba: %d/%d/%d/%d\n", data.at(0), data.at(1), data.at(2), data.at(3)); QuadTree *tree = new QuadTree(); tree->initialize(img); printf("Root node heightmap: \n"); tree->root->printHeightmap(); printf("top leftmost leaf: \n"); QuadTreeNode *cursor = tree->root; while(cursor->tlNode){ cursor = cursor->tlNode; } cursor->printHeightmap(); return 0; }
void QuadTreeNode::remove(QuadTreeOccupant* occupant) { assert(!occupants.empty()); // Remove from node occupants.erase(occupant); // Propogate upwards, merging if there are enough occupants in the node QuadTreeNode* n = this; while(n) { n->numOccupantsBelow--; if(n->numOccupantsBelow >= minNumOccupants) { n->merge(); break; } n = n->parent; } }
void QuadTreeNode::Remove(QuadTreeOccupant* pOc) { assert(!m_pOccupants.empty()); // Remove from node m_pOccupants.erase(pOc); // Propogate upwards, merging if there are enough occupants in the node QuadTreeNode* pNode = this; while(pNode != NULL) { pNode->m_numOccupantsBelow--; if(pNode->m_numOccupantsBelow >= minNumOccupants) { pNode->Merge(); break; } pNode = pNode->m_pParent; } }
void TerrainRenderer::drawNode(GLdouble offsetX, GLdouble offsetY, GLdouble size, QuadTreeNode *node){ size = size/2; for(int i=0; i<2; i++){ for(int j=0; j<2; j++){ QuadTreeNode *child; if(i==0 && j==0) child = node->tlNode; if(i==1 && j==0) child = node->trNode; if(i==0 && j==1) child = node->blNode; if(i==1 && j==1) child = node->brNode; GLfloat tile_x = size*i+offsetX; GLfloat tile_y = size*i+offsetY; GLfloat d = getTileDistance(tile_x, tile_y, transformHeight(child->min), transformHeight(child->max), size); if(tile_x == 0.0 && tile_y == 0.0 && size == 0.5) printf("Distance from %i, %i: %f\n", i, j, d); if(d < size*2 && !child->isLeaf()){ drawNode(size*i+offsetX, size*j+offsetY, size, child); }else{ drawHeightmap(size*i+offsetX, size*j+offsetY, size, child); } } } }
bool checkForCollision( const Content & c ) const { #ifdef QUADDEBUG log() << "QuadTree checkForCollision called" << std::endl; #endif return rootNode_.checkForCollision( c ); }
void clear() { rootNode_.clear(); }
void debug() { rootNode_.debug(); }
void QuadTree::remove_object(GameObject *object) { QuadTreeNode *node = m_object_node_map[object->getID()]; node->remove_object(object); m_object_node_map.erase(object->getID()); }
// Test using the circle range void testCircleRange(string directoryName) { // Create a schema Schema *schema = Schema::create(LocationIndex); schema->setPrimaryKey("list_id"); // integer, by default not searchable schema->setSearchableAttribute("title", 2); // searchable text schema->setSearchableAttribute("address", 7); // searchable text // Create an analyzer Analyzer *analyzer = new Analyzer(NULL, NULL, NULL, NULL, ""); unsigned mergeEveryNSeconds = 3; unsigned mergeEveryMWrites = 5; unsigned updateHistogramEveryPMerges = 1; unsigned updateHistogramEveryQWrites = 5; CacheManager *cache = new CacheManager(134217728); IndexMetaData *indexMetaData = new IndexMetaData( cache, mergeEveryNSeconds, mergeEveryMWrites, updateHistogramEveryPMerges, updateHistogramEveryQWrites, directoryName); Indexer *indexer = Indexer::create(indexMetaData, analyzer, schema); // Create five records of 8 attributes and add them to the index addGeoRecord(indexer, schema, analyzer, 0, "Tom Smith and Jack Lennon", "Yesterday Once More", 100.0, 100.0); addGeoRecord(indexer, schema, analyzer, 1, "George Harris", "Here comes the sun", 110.0, 110.0); addGeoRecord(indexer, schema, analyzer, 2, "George Harris", "Here comes the sun", 10.0, 10.0); addGeoRecord(indexer, schema, analyzer, 3, "George Harris", "Here comes the sun", -100.0, -100.0); addGeoRecord(indexer, schema, analyzer, 4, "George Harris", "Here comes the sun", -110.0, -110.0); addGeoRecord(indexer, schema, analyzer, 5, "George Harris", "Here comes the sun", -100.0, 100.0); addGeoRecord(indexer, schema, analyzer, 6, "George Harris", "Here comes the sun", 100.0, -100.0); addGeoRecord(indexer, schema, analyzer, 7, "George Harris", "Here comes the sun", 101.0, -101.0); // commit the index bool retval = indexer->commit(); ASSERT( retval == 1 ); (void)retval; // Storing results of the query and expected results vector<vector<unsigned>*> expectedResults; vector<vector<GeoElement*>*> results; QueryEvaluatorRuntimeParametersContainer runTimeParameters; QueryEvaluator * queryEvaluator = new QueryEvaluator(indexer,&runTimeParameters ); //Rectangle queryRange(pair(pair(-20,-20),pair(20,20))); Point point; point.x = 100; point.y = 100; Circle circle(point,30); boost::shared_ptr<QuadTreeRootNodeAndFreeLists> quadtree_ReadView; quadtree_ReadView = dynamic_cast<IndexReaderWriter *>(indexer)->getQuadTree_ReadView(); QuadTreeNode *qt = quadtree_ReadView->root; qt->rangeQuery(results,circle); vector<unsigned> res; res.push_back(getExternalId(queryEvaluator,0)); res.push_back(getExternalId(queryEvaluator,1)); res.push_back(getExternalId(queryEvaluator,2)); expectedResults.push_back(&res); verifyResults(results,expectedResults); delete indexer; delete indexMetaData; delete analyzer; delete schema; }