void WorldBuilder::addPolygonsToHeight(PolygonVector polygons) { PolygonVectorIterator polygonIt; int polygonNumber = 0; for (polygonIt = polygons.begin(); polygonIt != polygons.end(); ++polygonIt) { osg::notify(osg::DEBUG_INFO) << "\tProcessed polygon: " << ++polygonNumber << " of " << polygons.size() << std::endl; osg::ref_ptr<Polygon> polygon = (*polygonIt); bool foundMatchingTile = false; HeightTileVectorIterator heightIt; for (heightIt = m_heightTiles.begin(); heightIt != m_heightTiles.end(); ++heightIt) { osg::ref_ptr<HeightTile> heightTile = (*heightIt); if (heightTile->addPolygon(polygon)) { foundMatchingTile = true; break; } } if (!foundMatchingTile) { m_polygonsOutsideTiles.push_back(polygon); } } }
void WorldBuilder::buildWorld() { // Load height files osg::notify(osg::ALWAYS) << "Reading height file(s)..." << std::endl; std::vector<std::string>::iterator it; int filenumber = 0; for (it = m_heigthFilenames.begin(); it != m_heigthFilenames.end(); ++it) { osg::notify(osg::DEBUG_INFO) << "Reading height file: " << ++filenumber << " of " << m_heigthFilenames.size() << std::endl; std::string heightFilename = osgDB::findDataFile(*it); if (!heightFilename.empty()) { osg::ref_ptr<HeightTile> heightTile = new HeightTile(); heightTile->load(heightFilename); m_heightTiles.push_back(heightTile); } else { osg::notify(osg::WARN) << "Warning: Could not find height data file: " << (*it) << std::endl; } } // Load shape files and populate height files with polygons osg::notify(osg::ALWAYS) << "Reading shape file(s)..." << std::endl; filenumber = 0; for (it = m_shapeFilenames.begin(); it != m_shapeFilenames.end(); ++it) { osg::notify(osg::DEBUG_INFO) << "Reading shape file: " << ++filenumber << " of " << m_shapeFilenames.size() << std::endl; std::string shapeFilename = osgDB::findDataFile(*it); if (!shapeFilename.empty()) { osg::ref_ptr<ShapeTile> shapeWorld = new ShapeTile(); shapeWorld->load(shapeFilename); m_shapeTiles.push_back(shapeWorld); } else { osg::notify(osg::WARN) << "Warning: Could not find shape file: " << (*it) << std::endl; } } // Extract polygons from shape tiles osg::notify(osg::ALWAYS) << "Extracting polygons..." << std::endl; int tilenumber = 0; ShapeWorldVectorIterator shapeIt; for (shapeIt = m_shapeTiles.begin(); shapeIt != m_shapeTiles.end(); ++shapeIt) { osg::notify(osg::DEBUG_INFO) << "Processed shape tile: " << ++tilenumber << " of " << m_shapeTiles.size() << std::endl; osg::ref_ptr<ShapeTile> shapeWorld = (*shapeIt); addPolygonsToHeight(shapeWorld->polygons()); } // Update height values for polygons osg::notify(osg::ALWAYS) << "Update heights in polygons..." << std::endl; tilenumber = 0; HeightTileVectorIterator heightIt; for (heightIt = m_heightTiles.begin(); heightIt != m_heightTiles.end(); ++heightIt) { osg::notify(osg::DEBUG_INFO) << "Update height in tile: " << ++tilenumber << " of " << m_heightTiles.size() << std::endl; osg::ref_ptr<HeightTile> heightTile = (*heightIt); heightTile->updatePolygonHeight(); } // Use OSG binary format as default std::string fileExtension("osgb"); std::string path = osgDB::getCurrentWorkingDirectory(); std::string filename("buildings"); if (!m_outputFilename.empty()) { if (osgDB::getLowerCaseFileExtension(m_outputFilename) != "osgb") { osg::notify(osg::WARN) << "Warning: Unknown file extension specified. Reverting to .osgb file format." << std::endl; } filename = osgDB::getStrippedName(m_outputFilename); path = osgDB::getFilePath(m_outputFilename); } // Build complete filename std::stringstream completeFilename; completeFilename << path; completeFilename << osgDB::getNativePathSeparator(); completeFilename << filename; completeFilename << "."; completeFilename << fileExtension; // Build balanced tree for polygons osg::ref_ptr<PolygonTree> polygonTree = new PolygonTree(path, filename); polygonTree->setBucketSize(m_maxBuildingsPerFile); osg::notify(osg::ALWAYS) << "Build polygon tree..." << std::endl; for (heightIt = m_heightTiles.begin(); heightIt != m_heightTiles.end(); ++heightIt) { osg::notify(osg::DEBUG_INFO) << "Getting polygons from height tile: " << ++tilenumber << " of " << m_heightTiles.size() << std::endl; osg::ref_ptr<HeightTile> heightTile = (*heightIt); PolygonVector polygons = heightTile->polygons(); if (!polygons.empty()) { PolygonVectorIterator polygonIt; for (polygonIt = polygons.begin(); polygonIt != polygons.end(); ++polygonIt) { osg::ref_ptr<Polygon> polygon = (*polygonIt); polygonTree->addPolygon(polygon); } } } // Add polygons that are outside height tiles to tree if (!m_polygonsOutsideTiles.empty()) { osg::notify(osg::ALWAYS) << "Polygons outside height tiles: " << m_polygonsOutsideTiles.size() << std::endl; PolygonVectorIterator polygonIt; for (polygonIt = m_polygonsOutsideTiles.begin(); polygonIt != m_polygonsOutsideTiles.end(); ++polygonIt) { osg::ref_ptr<Polygon> polygon = (*polygonIt); polygonTree->addPolygon(polygon); } } // Balance polygon tree osg::notify(osg::ALWAYS) << "Balancing polygon tree..." << std::endl; polygonTree->balance(); // Create buildings from polygons osg::notify(osg::ALWAYS) << "Create buildings from polygon tree..." << std::endl; osg::ref_ptr<osg::Group> worldGroup = polygonTree->createBuildingTree(); // Write model output osg::notify(osg::ALWAYS) << "Write models as output..." << std::endl; osgDB::writeNodeFile(*worldGroup, completeFilename.str()); // Export all textures osg::notify(osg::ALWAYS) << "Exporting textures..." << std::endl; std::stringstream texturePath; texturePath << path; texturePath << osgDB::getNativePathSeparator(); texturePath << filename; texturePath << "_root"; TextureLibrary::instance().exportTextures(texturePath.str()); }
inline Uint32 get_polygon_count() const noexcept { return m_polygons.size(); }
inline void add_polygon(const Polygon &polygon) noexcept { m_polygons.push_back(polygon); }