void World::buildQuadTree(QuadTreeNode *node, std::vector<QuadTreeNode*>& leafs) { float halfSize = node->getSize()/2.f; if (node->getSize() <= mMinBatchSize) { // We arrived at a leaf float minZ,maxZ; Ogre::Vector2 center = node->getCenter(); float cellWorldSize = getStorage()->getCellWorldSize(); if (mStorage->getMinMaxHeights(node->getSize(), center, minZ, maxZ)) { Ogre::AxisAlignedBox bounds(Ogre::Vector3(-halfSize*cellWorldSize, -halfSize*cellWorldSize, minZ), Ogre::Vector3(halfSize*cellWorldSize, halfSize*cellWorldSize, maxZ)); convertBounds(bounds); node->setBoundingBox(bounds); leafs.push_back(node); } else node->markAsDummy(); // no data available for this node, skip it return; } if (node->getCenter().x - halfSize > mMaxX || node->getCenter().x + halfSize < mMinX || node->getCenter().y - halfSize > mMaxY || node->getCenter().y + halfSize < mMinY ) // Out of bounds of the actual terrain - this will happen because // we rounded the size up to the next power of two { node->markAsDummy(); return; } // Not a leaf, create its children node->createChild(SW, halfSize, node->getCenter() - halfSize/2.f); node->createChild(SE, halfSize, node->getCenter() + Ogre::Vector2(halfSize/2.f, -halfSize/2.f)); node->createChild(NW, halfSize, node->getCenter() + Ogre::Vector2(-halfSize/2.f, halfSize/2.f)); node->createChild(NE, halfSize, node->getCenter() + halfSize/2.f); buildQuadTree(node->getChild(SW), leafs); buildQuadTree(node->getChild(SE), leafs); buildQuadTree(node->getChild(NW), leafs); buildQuadTree(node->getChild(NE), leafs); // if all children are dummy, we are also dummy for (int i=0; i<4; ++i) { if (!node->getChild((ChildDirection)i)->isDummy()) return; } node->markAsDummy(); }
Map* parseElements(xmlDocPtr doc, xmlNodePtr cur){ Map* map = initMap(); Node *node; Way* way; Relation *r; Avl* aNode = NULL; Avl* avlWay = NULL; ListNode* ln = NULL; ListWay* wO = NULL; ListWay* wW = NULL; ListWay* wG = NULL; ListWay* wH = NULL; ListWay* wB = NULL; ListWay* wC = NULL; ListRelation* lr= NULL; int flagN = 1; int flagW = 1; cur = cur->xmlChildrenNode; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { if (!xmlStrcmp(cur->name, (const xmlChar *)"bounds")){ map->bounds = parseBounds(cur); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"node"))){ node = parseNode (doc, cur, map->bounds); if(node->name!=NULL){ ln = addRefListNode(node->id,ln); } if(flagN == 1){ init(&aNode,node,NULL); flagN = 0; } else{ insert(&aNode,node,NULL); } } if ((!xmlStrcmp(cur->name, (const xmlChar *)"way"))){ way = parseWay (doc, cur, map->referenceTag); if(way != NULL){ if((way->tag->type) == 0){ wO = addRefListWay(way->id," ", wO); } else if(way->tag->type == 1){ wW = addRefListWay(way->id," ", wW); } else if(way->tag->type == 2){ wG = addRefListWay(way->id," ", wG); } else if(way->tag->type == 3){ wH = addRefListWay(way->id," ", wH); } else if(way->tag->type == 4){ wB = addRefListWay(way->id," ", wB); } else if(way->tag->type == 5){ wC = addRefListWay(way->id," ", wC); } if(flagW == 1){ init(&avlWay,NULL, way); flagW = 0; } else{ insert(&avlWay,NULL,way); } } } if ((!xmlStrcmp(cur->name, (const xmlChar *)"relation"))){ r = parseRelation(doc, cur); if(r != NULL){ lr = addRefListRelation(r,lr); } } } cur = cur->next; } map->avl = aNode; map->avlWay = avlWay; map->nodeOther = ln; map->wayWater = wW; map->wayOther = wO; map->wayGreen = wG; map->wayBuilding = wB; map->wayHighway = wH; map->wayCadastre = wC; map->listRelation = lr; Node* n0 = initNode(0, map->bounds->min->y, map->bounds->min->x, "true", map->bounds, NULL); Node* n1 = initNode(1, map->bounds->max->y, map->bounds->min->x, "true", map->bounds, NULL); Node* n2 = initNode(2, map->bounds->max->y, map->bounds->max->x, "true", map->bounds, NULL); Node* n3 = initNode(3, map->bounds->min->y, map->bounds->max->x, "true", map->bounds, NULL); insert(&aNode,n0,NULL); insert(&aNode,n1,NULL); insert(&aNode,n2,NULL); insert(&aNode,n3,NULL); map->bounds = convertBounds(map->bounds); return map; }