osg::Node* SingleKeyNodeFactory::createTile(TileModel* model, bool setupChildrenIfNecessary) { // compile the model into a node: TileNode* tileNode = _modelCompiler->compile( model, _frame ); // see if this tile might have children. bool prepareForChildren = setupChildrenIfNecessary && model->_tileKey.getLOD() < *_options.maxLOD(); osg::Node* result = 0L; if ( prepareForChildren ) { //Compute the min range based on the 2D size of the tile osg::BoundingSphere bs = tileNode->getBound(); GeoExtent extent = model->_tileKey.getExtent(); GeoPoint lowerLeft(extent.getSRS(), extent.xMin(), extent.yMin(), 0.0, ALTMODE_ABSOLUTE); GeoPoint upperRight(extent.getSRS(), extent.xMax(), extent.yMax(), 0.0, ALTMODE_ABSOLUTE); osg::Vec3d ll, ur; lowerLeft.toWorld( ll ); upperRight.toWorld( ur ); double radius = (ur - ll).length() / 2.0; float minRange = (float)(radius * _options.minTileRangeFactor().value()); TilePagedLOD* plod = new TilePagedLOD( _engineUID, _liveTiles, _deadTiles ); plod->setCenter ( bs.center() ); plod->addChild ( tileNode ); plod->setRange ( 0, minRange, FLT_MAX ); plod->setFileName( 1, Stringify() << tileNode->getKey().str() << "." << _engineUID << ".osgearth_engine_mp_tile" ); plod->setRange ( 1, 0, minRange ); #if USE_FILELOCATIONCALLBACK osgDB::Options* options = Registry::instance()->cloneOrCreateOptions(); options->setFileLocationCallback( new FileLocationCallback() ); plod->setDatabaseOptions( options ); #endif result = plod; // this one rejects back-facing tiles: if ( _frame.getMapInfo().isGeocentric() && _options.clusterCulling() == true ) { osg::HeightField* hf = model->_elevationData.getHeightField(); result->addCullCallback( HeightFieldUtils::createClusterCullingCallback( hf, tileNode->getKey().getProfile()->getSRS()->getEllipsoid(), *_options.verticalScale() ) ); } } else { result = tileNode; } return result; }
TileGroup::TileGroup(TileNode* tilenode, const UID& engineUID, TileNodeRegistry* live, TileNodeRegistry* dead, osgDB::Options* dbOptions) { _numSubtilesUpsampling = 0; _numSubtilesLoaded = 0; _traverseSubtiles = true; this->addChild( tilenode ); _tilenode = tilenode; for(unsigned q=0; q<4; ++q) { TileKey subkey = tilenode->getKey().createChildKey(q); TilePagedLOD* lod = new TilePagedLOD(this, subkey, engineUID, live, dead); lod->setDatabaseOptions( dbOptions ); lod->setCenter( tilenode->getBound().center() ); lod->setRadius( tilenode->getBound().radius() ); this->addChild( lod ); } }