TerrainTile 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSGTERRAIN_TERRAINTILE
  14. #define OSGTERRAIN_TERRAINTILE 1
  15. #include <osg/Group>
  16. #include <osg/CoordinateSystemNode>
  17. #include <osgDB/ReaderWriter>
  18. #include <osgTerrain/TerrainTechnique>
  19. #include <osgTerrain/Layer>
  20. #include <osgTerrain/Locator>
  21. namespace osgTerrain {
  22. class Terrain;
  23. class OSGTERRAIN_EXPORT TileID
  24. {
  25. public:
  26. TileID();
  27. TileID(int in_level, int in_x, int in_y);
  28. bool operator == (const TileID& rhs) const
  29. {
  30. return (level==rhs.level) && (x==rhs.x) && (y==rhs.y);
  31. }
  32. bool operator != (const TileID& rhs) const
  33. {
  34. return (level!=rhs.level) || (x!=rhs.x) || (y!=rhs.y);
  35. }
  36. bool operator < (const TileID& rhs) const
  37. {
  38. if (level<rhs.level) return true;
  39. if (level>rhs.level) return false;
  40. if (x<rhs.x) return true;
  41. if (x>rhs.x) return false;
  42. return y<rhs.y;
  43. }
  44. bool valid() const { return level>=0; }
  45. int level;
  46. int x;
  47. int y;
  48. };
  49. /** Terrain provides a framework for loosely coupling height field data with height rendering algorithms.
  50. * This allows TerrainTechnique's to be plugged in at runtime.*/
  51. class OSGTERRAIN_EXPORT TerrainTile : public osg::Group
  52. {
  53. public:
  54. TerrainTile();
  55. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  56. TerrainTile(const TerrainTile&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
  57. META_Node(osgTerrain, TerrainTile);
  58. virtual void traverse(osg::NodeVisitor& nv);
  59. /** Call init on any attached TerrainTechnique.*/
  60. void init(int dirtyMask, bool assumeMultiThreaded);
  61. /** Set the Terrain that this Terrain tile is a member of.*/
  62. void setTerrain(Terrain* ts);
  63. /** Get the Terrain that this Terrain tile is a member of.*/
  64. Terrain* getTerrain() { return _terrain; }
  65. /** Get the const Terrain that this Terrain tile is a member of.*/
  66. const Terrain* getTerrain() const { return _terrain; }
  67. /** Set the TileID (layer, x,y) of the TerrainTile.
  68. * The TileID is used so it can be located by its neighbours
  69. * via the enclosing Terrain node that manages a map of TileID to TerraiTiles.*/
  70. void setTileID(const TileID& tileID);
  71. /** Get the TileID (layer, x,y) of the TerrainTile.*/
  72. const TileID& getTileID() const { return _tileID; }
  73. /** Set the TerrainTechnique*/
  74. void setTerrainTechnique(TerrainTechnique* terrainTechnique);
  75. template<class T> void setTerrainTechnique(const osg::ref_ptr<T>& terrainTechnique) { setTerrainTechnique(terrainTechnique.get()); }
  76. /** Get the TerrainTechnique*/
  77. TerrainTechnique* getTerrainTechnique() { return _terrainTechnique.get(); }
  78. /** Get the const TerrainTechnique*/
  79. const TerrainTechnique* getTerrainTechnique() const { return _terrainTechnique.get(); }
  80. /** Set the coordinate frame locator of the terrain node.
  81. * The locator takes non-dimensional s,t coordinates into the X,Y,Z world coords and back.*/
  82. void setLocator(Locator* locator) { _locator = locator; }
  83. template<class T> void setLocator(const osg::ref_ptr<T>& locator) { setLocator(locator.get()); }
  84. /** Get the coordinate frame locator of the terrain node.*/
  85. Locator* getLocator() { return _locator.get(); }
  86. /** Get the const coordinate frame locator of the terrain node.*/
  87. const Locator* getLocator() const { return _locator.get(); }
  88. /** Set the layer to use to define the elevations of the terrain.*/
  89. void setElevationLayer(Layer* layer);
  90. template<class T> void setElevationLayer(const osg::ref_ptr<T>& layer) { setElevationLayer(layer.get()); }
  91. /** Get the layer to use to define the elevations of the terrain.*/
  92. Layer* getElevationLayer() { return _elevationLayer.get(); }
  93. /** Get the const layer to use to define the elevations of the terrain.*/
  94. const Layer* getElevationLayer() const { return _elevationLayer.get(); }
  95. /** Set a color layer with specified layer number.*/
  96. void setColorLayer(unsigned int i, Layer* layer);
  97. template<class T> void setColorLayer(unsigned int i, const osg::ref_ptr<T>& layer) { setColorLayer(i, layer.get()); }
  98. /** Get color layer with specified layer number.*/
  99. Layer* getColorLayer(unsigned int i) { return i<_colorLayers.size() ? _colorLayers[i].get() : 0; }
  100. /** Set const color layer with specified layer number.*/
  101. const Layer* getColorLayer(unsigned int i) const { return i<_colorLayers.size() ? _colorLayers[i].get() : 0; }
  102. /** Get the number of colour layers.*/
  103. unsigned int getNumColorLayers() const { return _colorLayers.size(); }
  104. /** Set hint to whether the TerrainTechnique should create per vertex normals for lighting purposes.*/
  105. void setRequiresNormals(bool flag) { _requiresNormals = flag; }
  106. /** Get whether the TerrainTechnique should create per vertex normals for lighting purposes.*/
  107. bool getRequiresNormals() const { return _requiresNormals; }
  108. /** Set the hint to whether the TerrainTechnique should treat the invalid Layer entries that at are neighbours to valid entries with the default value.*/
  109. void setTreatBoundariesToValidDataAsDefaultValue(bool flag) { _treatBoundariesToValidDataAsDefaultValue = flag; }
  110. /** Get whether the TeatBoundariesToValidDataAsDefaultValue hint.*/
  111. bool getTreatBoundariesToValidDataAsDefaultValue() const { return _treatBoundariesToValidDataAsDefaultValue; }
  112. enum BlendingPolicy
  113. {
  114. INHERIT, /** Default - check for the any BlendingPolicy set on the enclosing osgTerrain::Terrain node, and if it's also INHERIT then assume ENABLE_BLENDING_WHEN_ALPHA_PRESENT. */
  115. DO_NOT_SET_BLENDING,
  116. ENABLE_BLENDING,
  117. ENABLE_BLENDING_WHEN_ALPHA_PRESENT /** check colour layers for alpha value and if present enable blending. */
  118. };
  119. /** Set the policy to use when deciding whether to enable/disable blending and use of transparent bin.*/
  120. void setBlendingPolicy(BlendingPolicy policy) { _blendingPolicy = policy; }
  121. /** Get the policy to use when deciding whether to enable/disable blending and use of transparent bin.*/
  122. BlendingPolicy getBlendingPolicy() const { return _blendingPolicy; }
  123. enum DirtyMask
  124. {
  125. NOT_DIRTY = 0,
  126. IMAGERY_DIRTY = 1<<0,
  127. ELEVATION_DIRTY = 1<<1,
  128. LEFT_EDGE_DIRTY = 1<<2,
  129. RIGHT_EDGE_DIRTY = 1<<3,
  130. TOP_EDGE_DIRTY = 1<<4,
  131. TOP_LEFT_CORNER_DIRTY = 1<<5,
  132. TOP_RIGHT_CORNER_DIRTY = 1<<6,
  133. BOTTOM_EDGE_DIRTY = 1<<7,
  134. BOTTOM_LEFT_CORNER_DIRTY = 1<<8,
  135. BOTTOM_RIGHT_CORNER_DIRTY = 1<<9,
  136. EDGES_DIRTY = LEFT_EDGE_DIRTY | RIGHT_EDGE_DIRTY | TOP_EDGE_DIRTY | BOTTOM_EDGE_DIRTY |
  137. TOP_LEFT_CORNER_DIRTY | TOP_RIGHT_CORNER_DIRTY | BOTTOM_LEFT_CORNER_DIRTY | BOTTOM_RIGHT_CORNER_DIRTY,
  138. ALL_DIRTY = IMAGERY_DIRTY | ELEVATION_DIRTY | EDGES_DIRTY
  139. };
  140. /** Set the dirty flag on/off.*/
  141. void setDirty(bool dirty) { setDirtyMask(dirty ? ALL_DIRTY : NOT_DIRTY); }
  142. /** return true if the any of the DirtyMask are set.*/
  143. int getDirty() const { return _dirtyMask!=NOT_DIRTY; }
  144. /** Set the dirty flag on/off.*/
  145. void setDirtyMask(int dirtyMask);
  146. /** return true if the tile is dirty and needs to be updated,*/
  147. int getDirtyMask() const { return _dirtyMask; }
  148. /** Compute the bounding volume of the terrain by computing the union of the bounding volumes of all layers.*/
  149. virtual osg::BoundingSphere computeBound() const;
  150. /** Callback for post processing loaded TerrainTile, and for filling in missing elements such as external external imagery.*/
  151. struct TileLoadedCallback : public osg::Referenced
  152. {
  153. virtual bool deferExternalLayerLoading() const = 0;
  154. virtual void loaded(osgTerrain::TerrainTile* tile, const osgDB::ReaderWriter::Options* options) const = 0;
  155. };
  156. static void setTileLoadedCallback(TileLoadedCallback* lc);
  157. static osg::ref_ptr<TileLoadedCallback>& getTileLoadedCallback();
  158. /** If State is non-zero, this function releases any associated OpenGL objects for
  159. * the specified graphics context. Otherwise, releases OpenGL objects
  160. * for all graphics contexts. */
  161. virtual void releaseGLObjects(osg::State* = 0) const;
  162. protected:
  163. virtual ~TerrainTile();
  164. typedef std::vector< osg::ref_ptr<Layer> > Layers;
  165. friend class Terrain;
  166. Terrain* _terrain;
  167. int _dirtyMask;
  168. bool _hasBeenTraversal;
  169. TileID _tileID;
  170. osg::ref_ptr<TerrainTechnique> _terrainTechnique;
  171. osg::ref_ptr<Locator> _locator;
  172. osg::ref_ptr<Layer> _elevationLayer;
  173. Layers _colorLayers;
  174. bool _requiresNormals;
  175. bool _treatBoundariesToValidDataAsDefaultValue;
  176. BlendingPolicy _blendingPolicy;
  177. };
  178. /** Helper callback for managing optional sets of layers, that loading of is deffered to this callback,
  179. * with this callback working out which layers to load, and how to create fallback versions of the layers.
  180. */
  181. class OSGTERRAIN_EXPORT WhiteListTileLoadedCallback : public TerrainTile::TileLoadedCallback
  182. {
  183. public:
  184. WhiteListTileLoadedCallback();
  185. void allow(const std::string& setname) { _setWhiteList.insert(setname); }
  186. void setMinimumNumOfLayers(unsigned int numLayers) { _minumumNumberOfLayers = numLayers; }
  187. unsigned int getMinimumNumOfLayers() const { return _minumumNumberOfLayers; }
  188. void setReplaceSwitchLayer(bool replaceSwitchLayer) { _replaceSwitchLayer = replaceSwitchLayer; }
  189. bool getReplaceSwitchLayer() const { return _replaceSwitchLayer; }
  190. void setAllowAll(bool allowAll) { _allowAll = allowAll; }
  191. bool getAllowAll() const { return _allowAll; }
  192. bool layerAcceptable(const std::string& setname) const;
  193. bool readImageLayer(osgTerrain::ImageLayer* imageLayer, const osgDB::ReaderWriter::Options* options) const;
  194. virtual bool deferExternalLayerLoading() const;
  195. virtual void loaded(osgTerrain::TerrainTile* tile, const osgDB::ReaderWriter::Options* options) const;
  196. protected:
  197. virtual ~WhiteListTileLoadedCallback();
  198. typedef std::set<std::string> SetWhiteList;
  199. SetWhiteList _setWhiteList;
  200. unsigned int _minumumNumberOfLayers;
  201. bool _replaceSwitchLayer;
  202. bool _allowAll;
  203. };
  204. }
  205. #endif