osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthDrivers/engine_osgterrain/SerialKeyNodeFactory.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003 * Copyright 2008-2010 Pelican Mapping
00004 * http://osgearth.org
00005 *
00006 * osgEarth is free software; you can redistribute it and/or modify
00007 * it under the terms of the GNU Lesser General Public License as published by
00008 * the Free Software Foundation; either version 2 of the License, or
00009 * (at your option) any later version.
00010 *
00011 * This program is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU Lesser General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU Lesser General Public License
00017 * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018 */
00019 #include "SerialKeyNodeFactory"
00020 #include "DynamicLODScaleCallback"
00021 #include "FileLocationCallback"
00022 #include "LODFactorCallback"
00023 #include <osgEarth/Registry>
00024 #include <osg/PagedLOD>
00025 #include <osg/CullStack>
00026 #include <osg/Uniform>
00027 
00028 #include <osgEarth/MapNode>
00029 
00030 using namespace osgEarth;
00031 using namespace OpenThreads;
00032 
00033 #define LC "[SerialKeyNodeFactory] "
00034 
00035 SerialKeyNodeFactory::SerialKeyNodeFactory(TileBuilder*             builder,
00036                                            const OSGTerrainOptions& options,
00037                                            const MapInfo&           mapInfo,
00038                                            Terrain*                 terrain,
00039                                            UID                      engineUID ) :
00040 _builder( builder ),
00041 _options( options ),
00042 _mapInfo( mapInfo ),
00043 _terrain( terrain ),
00044 _engineUID( engineUID )
00045 {
00046     //NOP
00047 }
00048 
00049 void
00050 SerialKeyNodeFactory::addTile(Tile* tile, bool tileHasRealData, bool tileHasLodBlending, osg::Group* parent )
00051 {
00052     // associate this tile with the terrain:
00053     tile->setTerrainTechnique( _terrain->cloneTechnique() );
00054     tile->attachToTerrain( _terrain );
00055 
00056     // assemble a URI for this tile's child group:
00057     std::stringstream buf;
00058     buf << tile->getKey().str() << "." << _engineUID << ".osgearth_osgterrain_tile";
00059     std::string uri; uri = buf.str();
00060 
00061     osg::Node* result = 0L;
00062 
00063     // Only add the next tile if it hasn't been blacklisted
00064     bool wrapInPagedLOD =
00065         tileHasRealData &&
00066         !osgEarth::Registry::instance()->isBlacklisted( uri ) &&
00067         tile->getKey().getLevelOfDetail() < (unsigned)*_options.maxLOD();
00068 
00069     if ( wrapInPagedLOD )
00070     {
00071         osg::BoundingSphere bs = tile->getBound();
00072         double maxRange = 1e10;
00073         double minRange = bs.radius() * _options.minTileRangeFactor().value();
00074 
00075         // create a PLOD so we can keep subdividing:
00076         osg::PagedLOD* plod = new osg::PagedLOD();
00077         plod->setCenter( bs.center() );
00078         plod->addChild( tile, minRange, maxRange );
00079 
00080         plod->setFileName( 1, uri );
00081         plod->setRange   ( 1, 0, minRange );
00082 
00083         plod->setUserData( new MapNode::TileRangeData(minRange, maxRange) );
00084 
00085 #if USE_FILELOCATIONCALLBACK
00086         osgDB::Options* options = new osgDB::Options;
00087         options->setFileLocationCallback( new FileLocationCallback() );
00088         plod->setDatabaseOptions( options );
00089 
00090 #endif
00091         result = plod;
00092         
00093         if ( tileHasLodBlending )
00094         {
00095             // Make the LOD transition distance, and a measure of how
00096             // close the tile is to an LOD change, to shaders.
00097             result->addCullCallback(new Drivers::LODFactorCallback);
00098         }
00099     }
00100     else
00101     {
00102         result = tile;
00103     }
00104 
00105     // this cull callback dynamically adjusts the LOD scale based on distance-to-camera:
00106     if ( _options.lodFallOff().isSet() && *_options.lodFallOff() > 0.0 )
00107     {
00108         result->addCullCallback( new DynamicLODScaleCallback(*_options.lodFallOff()) );
00109     }
00110 
00111     // this one rejects back-facing tiles:
00112     if ( _mapInfo.isGeocentric() )
00113     {
00114         result->addCullCallback( HeightFieldUtils::createClusterCullingCallback(
00115             static_cast<osgTerrain::HeightFieldLayer*>(tile->getElevationLayer())->getHeightField(),
00116             tile->getLocator()->getEllipsoidModel(),
00117             tile->getVerticalScale() ) );
00118     }
00119 
00120     parent->addChild( result );
00121 }
00122 
00123 osg::Node*
00124 SerialKeyNodeFactory::createNode( const TileKey& key )
00125 {
00126     osg::ref_ptr<Tile> tiles[4];
00127     bool               realData[4];
00128     bool               lodBlending[4];
00129     bool               tileHasAnyRealData = false;
00130 
00131     for( unsigned i = 0; i < 4; ++i )
00132     {
00133         TileKey child = key.createChildKey( i );
00134         _builder->createTile( child, false, tiles[i], realData[i], lodBlending[i] );
00135         if ( tiles[i].valid() && realData[i] )
00136             tileHasAnyRealData = true;
00137     }
00138 
00139     osg::Group* root = 0L;
00140 
00141     if ( tileHasAnyRealData )
00142     {
00143         // Now postprocess them and assemble into a tile group.
00144         root = new osg::Group();
00145 
00146         for( unsigned i = 0; i < 4; ++i )
00147         {
00148             if ( tiles[i].valid() )
00149             {
00150                 addTile( tiles[i].get(), realData[i], lodBlending[i], root );
00151             }
00152         }
00153     }
00154 
00155     return root;
00156 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines