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());
}
Exemple #3
0
			inline Uint32 get_polygon_count() const noexcept
			{
				return m_polygons.size();
			}
Exemple #4
0
			inline void add_polygon(const Polygon &polygon) noexcept
			{
				m_polygons.push_back(polygon);
			}