osgEarth 2.1.1
|
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 #ifndef OSGEARTHUTIL_SPATIAL_DATA 00020 #define OSGEARTHUTIL_SPATIAL_DATA 00021 00022 #include <osgEarthUtil/Common> 00023 #include <osgEarth/GeoData> 00024 #include <osg/observer_ptr> 00025 #include <osg/Geode> 00026 #include <osg/Plane> 00027 #include <osg/LOD> 00028 #include <map> 00029 00030 namespace osgEarth { namespace Util 00031 { 00032 using namespace osgEarth; 00033 00034 class GeoObject; 00035 //typedef std::vector< osg::ref_ptr<GeoObject> > GeoObjectVector; 00036 typedef std::pair< float, osg::ref_ptr<GeoObject> > GeoObjectPair; 00037 typedef std::multimap< float, osg::ref_ptr<GeoObject> > GeoObjectCollection; 00038 00042 class OSGEARTHUTIL_EXPORT GeoCell : public osg::LOD 00043 { 00044 public: 00045 GeoCell( 00046 const GeoExtent& extent, 00047 float maxRange, 00048 unsigned maxOjbects, 00049 unsigned splitDim, 00050 float splitRangeFactor, 00051 unsigned depth ); 00052 00054 virtual bool insertObject( GeoObject* object ); 00055 00057 bool removeObject( GeoObject* object ); 00058 00060 bool reindexObject( GeoObject* object ); 00061 00063 unsigned getSplitDimension() const { return _splitDim; } 00064 00066 unsigned getMaxObjects() const { return _maxObjects; } 00067 00069 float getSplitRangeFactor() const { return _splitRangeFactor; } 00070 00072 const GeoExtent& getExtent() const { return _extent; } 00073 00075 unsigned getLastCullFrame() const { return _frameStamp; } 00076 00077 public: // osg::LOD overrides 00078 00079 virtual osg::BoundingSphere computeBound() const; 00080 00081 virtual void traverse( osg::NodeVisitor& nv ); 00082 00083 protected: 00084 GeoExtent _extent; 00085 unsigned _splitDim; 00086 unsigned _maxObjects; // maximum # of objects to render in this cell before splitting. 00087 unsigned _minObjects; // minimum # of objects to drop below before pulling up 00088 float _maxRange; // maximum visibility range of this cell. 00089 float _splitRangeFactor; // child range = cell range * factor 00090 unsigned _count; // # of objects in this cell (including all children) 00091 unsigned _depth; 00092 unsigned _frameStamp; // last fram this cell was visited by CULL 00093 00094 void split(); 00095 void merge(); 00096 void adjustCount( int delta ); 00097 bool intersects( const class osg::Polytope& tope ) const; 00098 void generateBoundaries(); 00099 void generateBoundaryGeometry(); 00100 00101 std::vector<osg::Vec3d> _boundaryPoints; 00102 00103 // priority-order collection of objects 00104 GeoObjectCollection _objects; 00105 00106 osg::ref_ptr<osg::Geode> _clusterGeode; 00107 osg::ref_ptr<osg::Geode> _boundaryGeode; 00108 osg::Vec4Array* _boundaryColor; 00109 00110 friend class GeoCellVisitor; 00111 }; 00112 00113 class OSGEARTHUTIL_EXPORT GeoGraph : public GeoCell 00114 { 00115 public: 00116 GeoGraph( 00117 const GeoExtent& extent, 00118 float maxRange, 00119 unsigned maxObjects =500, 00120 unsigned splitDim =2, 00121 float splitRangeFactor =0.5f, 00122 unsigned rootWidth =2, 00123 unsigned rootHeight =2 ); 00124 00125 00126 bool insertObject( GeoObject* object ); 00127 00128 private: 00129 unsigned _rootWidth, _rootHeight; 00130 }; 00131 00132 class GeoCellVisitor : public osg::NodeVisitor 00133 { 00134 public: 00135 GeoCellVisitor() : osg::NodeVisitor( osg::NodeVisitor::TRAVERSE_ALL_CHILDREN ) { } 00136 00137 virtual void operator()( const GeoCell* cell, const GeoObjectCollection& objects ) =0; 00138 00139 void apply( osg::LOD& node ) { 00140 const GeoCell* cell = static_cast<const GeoCell*>(&node); 00141 if ( cell->_depth > 0 ) 00142 this->operator()( cell, cell->_objects ); 00143 traverse( node ); 00144 } 00145 }; 00146 00150 class OSGEARTHUTIL_EXPORT GeoObject : public osg::Referenced 00151 { 00152 public: 00157 virtual bool getLocation( osg::Vec3d& output ) const =0; 00158 00160 virtual float getPriority() const { return 0.0; } 00161 00163 virtual osg::Node* getNode() const =0; 00164 00166 GeoCell* getGeoCell() const { return _cell.get(); } 00167 00168 protected: 00169 GeoObject(); 00170 osg::observer_ptr<GeoCell> _cell; 00171 float _priority; 00172 friend class GeoCell; 00173 }; 00174 00175 } } // namespace osgEarth::Util 00176 00177 #endif // OSGEARTHUTIL_SPATIAL_DATA