1/* -*-c++-*- */ 2/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph 3* Copyright 2008-2013 Pelican Mapping 4* http://osgearth.org 5* 6* osgEarth is free software; you can redistribute it and/or modify 7* it under the terms of the GNU Lesser General Public License as published by 8* the Free Software Foundation; either version 2 of the License, or 9* (at your option) any later version. 10* 11* This program is distributed in the hope that it will be useful, 12* but WITHOUT ANY WARRANTY; without even the implied warranty of 13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14* GNU Lesser General Public License for more details. 15* 16* You should have received a copy of the GNU Lesser General Public License 17* along with this program. If not, see <http://www.gnu.org/licenses/> 18*/ 19#ifndef OSGEARTH_ENGINE_QUADTREE_TILE_MODEL_FACTORY 20#define OSGEARTH_ENGINE_QUADTREE_TILE_MODEL_FACTORY 1 21 22#include "Common" 23#include "TileNode" 24#include "TileNodeRegistry" 25#include "QuadTreeTerrainEngineOptions" 26#include <osgEarth/Map> 27#include <osgEarth/ThreadingUtils> 28#include <osgEarth/Containers> 29#include <osgEarth/HeightFieldUtils> 30#include <osgEarth/MapFrame> 31#include <osgEarth/MapInfo> 32#include <osg/Group> 33 34namespace osgEarth_engine_quadtree 35{ 36 using namespace osgEarth; 37 38 struct HFKey { 39 TileKey _key; 40 bool _fallback; 41 bool _convertToHAE; 42 ElevationSamplePolicy _samplePolicy; 43 bool operator < (const HFKey& rhs) const { 44 if ( _key < rhs._key ) return true; 45 if ( rhs._key < _key ) return false; 46 if ( _fallback != rhs._fallback ) return true; 47 if ( _convertToHAE != rhs._convertToHAE ) return true; 48 return _samplePolicy < rhs._samplePolicy; 49 } 50 }; 51 52 struct HFValue { 53 osg::ref_ptr<osg::HeightField> _hf; 54 bool _isFallback; 55 }; 56 57 class HeightFieldCache : public osg::Referenced, public Revisioned 58 { 59 public: 60 HeightFieldCache(): 61 _cache ( true, 128 ) 62 { 63 64 } 65 66 bool getOrCreateHeightField( 67 const MapFrame& frame, 68 const TileKey& key, 69 bool fallback, 70 osg::ref_ptr<osg::HeightField>& out_hf, 71 bool* out_isFallback =0L, 72 bool convertToHAE =true, 73 ElevationSamplePolicy samplePolicy =SAMPLE_FIRST_VALID, 74 ProgressCallback* progress =0L ) const 75 { 76 // check the quick cache. 77 HFKey cachekey; 78 cachekey._key = key; 79 cachekey._fallback = fallback; 80 cachekey._convertToHAE = convertToHAE; 81 cachekey._samplePolicy = samplePolicy; 82 83 bool hit = false; 84 LRUCache<HFKey,HFValue>::Record rec; 85 if ( _cache.get(cachekey, rec) ) 86 { 87 out_hf = rec.value()._hf.get(); 88 if ( out_isFallback ) 89 *out_isFallback = rec.value()._isFallback; 90 return true; 91 } 92 93 bool isFallback; 94 95 bool ok = frame.getHeightField( key, fallback, out_hf, &isFallback, convertToHAE, samplePolicy, progress ); 96 97 if ( ok ) 98 { 99 // Treat Plate Carre specially by scaling the height values. (There is no need 100 // to do this with an empty heightfield) 101 const MapInfo& mapInfo = frame.getMapInfo(); 102 if ( mapInfo.isPlateCarre() ) 103 { 104 HeightFieldUtils::scaleHeightFieldToDegrees( out_hf.get() ); 105 } 106 107 if ( out_isFallback ) 108 *out_isFallback = isFallback; 109 110 // cache me 111 HFValue cacheval; 112 cacheval._hf = out_hf.get(); 113 cacheval._isFallback = isFallback; 114 _cache.insert( cachekey, cacheval ); 115 } 116 117 return ok; 118 } 119 120 void clear() 121 { 122 _cache.clear(); 123 } 124 125 private: 126 mutable LRUCache<HFKey,HFValue> _cache; 127 }; 128 129 /** 130 * For a given TileKey, this class builds a a corresponding TileNode from 131 * the map's data model. 132 * 133 * TODO: This should probably change to TileModelFactory or something since 134 * the creation of the TileNode itself is trivial and can be done outside of 135 * this class. 136 */ 137 class TileModelFactory : public osg::Referenced 138 { 139 public: 140 TileModelFactory( 141 const Map* map, 142 TileNodeRegistry* liveTiles, 143 const Drivers::QuadTreeTerrainEngineOptions& terrainOptions ); 144 145 HeightFieldCache* getHeightFieldCache() const; 146 147 /** dtor */ 148 virtual ~TileModelFactory() { } 149 150 void createTileModel( 151 const TileKey& key, 152 osg::ref_ptr<TileModel>& out_model, 153 bool& out_hasRealData, 154 bool& out_hasLodBlendedLayers ); 155 156 private: 157 158 const Map* _map; 159 osg::ref_ptr<TileNodeRegistry> _liveTiles; 160 const Drivers::QuadTreeTerrainEngineOptions& _terrainOptions; 161 osg::ref_ptr< HeightFieldCache > _hfCache; 162 }; 163 164} // namespace osgEarth_engine_quadtree 165 166#endif // OSGEARTH_ENGINE_QUADTREE_TILE_MODEL_FACTORY 167