From e2e779bed7be25b2c9167c1b13de69b630e57d08 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 Mar 2004 16:54:08 +0000 Subject: [PATCH] Added support for generation of PagedLOD databases in osgTerrain::DataSet --- include/osgTerrain/DataSet | 80 ++++++-- src/osgTerrain/DataSet.cpp | 393 +++++++++++++++++++++++++++++++------ 2 files changed, 396 insertions(+), 77 deletions(-) diff --git a/include/osgTerrain/DataSet b/include/osgTerrain/DataSet index f45ef0e16..1a2c6177f 100644 --- a/include/osgTerrain/DataSet +++ b/include/osgTerrain/DataSet @@ -673,15 +673,22 @@ class DataSet : public osg::Referenced void equalizeEdge(Position position); void equalizeBoundaries(); + + void setTileComplete(bool complete) { _complete = complete; } + bool getTileComplete() const { return _complete; } void optimizeResolution(); osg::Node* createScene(); + + void empty(); - std::string _name; - DataSet* _dataSet; + std::string _name; + unsigned int _level; + unsigned int _tileX; + unsigned int _tileY; osg::ref_ptr _imagery; osg::ref_ptr _terrain; @@ -701,9 +708,7 @@ class DataSet : public osg::Referenced float _terrain_maxSourceResolutionX; float _terrain_maxSourceResolutionY; - unsigned int _level; - unsigned int _tileX; - unsigned int _tileY; + bool _complete; }; @@ -712,13 +717,25 @@ class DataSet : public osg::Referenced public: CompositeDestination(): + _dataSet(0), + _parent(0), + _level(0), + _tileX(0), + _tileY(0), _type(GROUP), - _maxVisibleDistance(FLT_MAX) {} + _maxVisibleDistance(FLT_MAX), + _subTileGenerated(false) {} CompositeDestination(osgTerrain::CoordinateSystem* cs, const osg::BoundingBox& extents): SpatialProperties(cs,extents), + _dataSet(0), + _parent(0), + _level(0), + _tileX(0), + _tileY(0), _type(GROUP), - _maxVisibleDistance(FLT_MAX) {} + _maxVisibleDistance(FLT_MAX), + _subTileGenerated(false) {} void computeNeighboursFromQuadMap(); @@ -729,28 +746,52 @@ class DataSet : public osg::Referenced void equalizeBoundaries(); osg::Node* createScene(); + + bool areSubTilesComplete(); + std::string getSubTileName(); + osg::Node* createPagedLODScene(); + osg::Node* createSubTileScene(); + + void setSubTilesGenerated(bool generated) { _subTileGenerated=generated; } + bool getSubTilesGenerated() const { return _subTileGenerated; } + typedef std::vector< osg::ref_ptr > TileList; typedef std::vector< osg::ref_ptr > ChildList; - CompositeType _type; - TileList _tiles; - ChildList _children; - float _maxVisibleDistance; + DataSet* _dataSet; + CompositeDestination* _parent; + std::string _name; + unsigned int _level; + unsigned int _tileX; + unsigned int _tileY; + CompositeType _type; + TileList _tiles; + ChildList _children; + float _maxVisibleDistance; + bool _subTileGenerated; }; - typedef std::map Row; + typedef std::map Row; typedef std::map Level; typedef std::map QuadMap; - void insertTileToQuadMap(DestinationTile* tile) + void insertTileToQuadMap(CompositeDestination* tile) { _quadMap[tile->_level][tile->_tileY][tile->_tileX] = tile; } DestinationTile* getTile(unsigned int level,unsigned int X, unsigned int Y) + { + CompositeDestination* cd = getComposite(level,X,Y); + if (!cd) return 0; + if (cd->_tiles.empty()) return 0; + return (cd->_tiles).front().get(); + } + + CompositeDestination* getComposite(unsigned int level,unsigned int X, unsigned int Y) { QuadMap::iterator levelItr = _quadMap.find(level); if (levelItr==_quadMap.end()) return 0; @@ -794,9 +835,13 @@ class DataSet : public osg::Referenced void setDestinationGeoTransform(const osg::Matrixd& geoTransform) { _geoTransform = geoTransform; } void setDestinationTileBaseName(const std::string& basename) { _tileBasename = basename; } - void setDestinationTileExtension(const std::string& extension) { _tileExtension = extension; } + const std::string& getDestinationTileBaseName() const { return _tileBasename; } - CompositeDestination* createDestinationGraph(osgTerrain::CoordinateSystem* cs, + void setDestinationTileExtension(const std::string& extension) { _tileExtension = extension; } + const std::string& getDestinationTileExtension() const { return _tileExtension; } + + CompositeDestination* createDestinationGraph(CompositeDestination* parent, + osgTerrain::CoordinateSystem* cs, const osg::BoundingBox& extents, unsigned int maxImageSize, unsigned int maxTerrainSize, @@ -830,6 +875,11 @@ class DataSet : public osg::Referenced virtual ~DataSet() {} + void _readRow(Row& row); + void _equalizeRow(Row& row); + void _writeRow(Row& row); + void _emptyRow(Row& row); + void init(); osg::ref_ptr _sourceGraph; diff --git a/src/osgTerrain/DataSet.cpp b/src/osgTerrain/DataSet.cpp index a9cf02772..ee0785d6b 100644 --- a/src/osgTerrain/DataSet.cpp +++ b/src/osgTerrain/DataSet.cpp @@ -1072,6 +1072,9 @@ void DataSet::Source::buildOverviews() DataSet::DestinationTile::DestinationTile(): _dataSet(0), + _level(0), + _tileX(0), + _tileY(0), _imagery_maxNumColumns(4096), _imagery_maxNumRows(4096), _imagery_maxSourceResolutionX(0.0f), @@ -1079,7 +1082,8 @@ DataSet::DestinationTile::DestinationTile(): _terrain_maxNumColumns(1024), _terrain_maxNumRows(1024), _terrain_maxSourceResolutionX(0.0f), - _terrain_maxSourceResolutionY(0.0f) + _terrain_maxSourceResolutionY(0.0f), + _complete(false) { for(int i=0;icreateScene(); if (_tiles.empty() && _children.size()==1) return _children.front()->createScene(); - if (_type==GROUP) { @@ -1916,8 +1926,7 @@ osg::Node* DataSet::CompositeDestination::createScene() if (node) rangeNodeListMap[(*citr)->_maxVisibleDistance].push_back(node); } - osg::PagedLOD* pagedLOD = (_type==PAGED_LOD) ? new osg::PagedLOD : 0; - osg::LOD* lod = (pagedLOD) ? pagedLOD : new osg::LOD; + osg::LOD* lod = new osg::LOD; unsigned int childNum = 0; for(RangeNodeListMap::reverse_iterator rnitr=rangeNodeListMap.rbegin(); @@ -1958,15 +1967,7 @@ osg::Node* DataSet::CompositeDestination::createScene() if (child) { - if (pagedLOD) - { - std::cout<<"Need to set name of PagedLOD child"<addChild(child,0,maxVisibleDistance); - } - else - { - lod->addChild(child,0,maxVisibleDistance); - } + lod->addChild(child,0,maxVisibleDistance); ++childNum; } @@ -1974,6 +1975,133 @@ osg::Node* DataSet::CompositeDestination::createScene() return lod; } +bool DataSet::CompositeDestination::areSubTilesComplete() +{ + for(TileList::iterator itr=_tiles.begin(); + itr!=_tiles.end(); + ++itr) + { + if (!(*itr)->getTileComplete()) return false; + } + return true; +} + +std::string DataSet::CompositeDestination::getSubTileName() +{ + return _name+"_subtile"+_dataSet->getDestinationTileExtension(); +} + +osg::Node* DataSet::CompositeDestination::createPagedLODScene() +{ + if (_children.empty() && _tiles.empty()) return 0; + + if (_children.empty() && _tiles.size()==1) return _tiles.front()->createScene(); + + if (_tiles.empty() && _children.size()==1) return _children.front()->createPagedLODScene(); + + + if (_type==GROUP) + { + osg::Group* group = new osg::Group; + for(TileList::iterator titr=_tiles.begin(); + titr!=_tiles.end(); + ++titr) + { + osg::Node* node = (*titr)->createScene(); + if (node) group->addChild(node); + } + + // handle chilren + for(ChildList::iterator citr=_children.begin(); + citr!=_children.end(); + ++citr) + { + osg::Node* node = (*citr)->createScene(); + if (node) group->addChild(node); + } + return group; + } + + // must be either a LOD or a PagedLOD + + typedef std::vector NodeList; + + // collect all the local tiles + NodeList tileNodes; + for(TileList::iterator titr=_tiles.begin(); + titr!=_tiles.end(); + ++titr) + { + osg::Node* node = (*titr)->createScene(); + if (node) tileNodes.push_back(node); + } + + osg::PagedLOD* pagedLOD = new osg::PagedLOD; + + float farDistance = 1e8; + if (tileNodes.size()==1) + { + pagedLOD->addChild(tileNodes.front(),_maxVisibleDistance,farDistance); + } + else if (tileNodes.size()>1) + { + osg::Group* group = new osg::Group; + for(NodeList::iterator itr=tileNodes.begin(); + itr != tileNodes.end(); + ++itr) + { + group->addChild(*itr); + } + pagedLOD->addChild(group,_maxVisibleDistance,farDistance); + } + + pagedLOD->setFileName(1,getSubTileName()); + pagedLOD->setRange(1,0,_maxVisibleDistance); + + if (pagedLOD->getNumChildren()>0) + pagedLOD->setCenter(pagedLOD->getBound().center()); + + return pagedLOD; +} + +osg::Node* DataSet::CompositeDestination::createSubTileScene() +{ + if (_type==GROUP || + _children.empty() || + _tiles.empty()) return 0; + + // handle chilren + typedef std::vector NodeList; + NodeList nodeList; + for(ChildList::iterator citr=_children.begin(); + citr!=_children.end(); + ++citr) + { + osg::Node* node = (*citr)->createPagedLODScene(); + if (node) nodeList.push_back(node); + } + + if (nodeList.size()==1) + { + return nodeList.front(); + } + else if (nodeList.size()>1) + { + osg::Group* group = new osg::Group; + for(NodeList::iterator itr=nodeList.begin(); + itr!=nodeList.end(); + ++itr) + { + group->addChild(*itr); + } + return group; + } + else + { + return 0; + } +} + /////////////////////////////////////////////////////////////////////////////// DataSet::DataSet() @@ -2021,7 +2149,8 @@ void DataSet::loadSources() } } -DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::CoordinateSystem* cs, +DataSet::CompositeDestination* DataSet::createDestinationGraph(CompositeDestination* parent, + osgTerrain::CoordinateSystem* cs, const osg::BoundingBox& extents, unsigned int maxImageSize, unsigned int maxTerrainSize, @@ -2041,23 +2170,27 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord std::ostringstream os; os << _tileBasename << "_L"<getProjectionRef()<_parent = parent; + destinationGraph->_name = os.str(); + destinationGraph->_level = currentLevel; + destinationGraph->_tileX = currentX; + destinationGraph->_tileY = currentY; + destinationGraph->_dataSet = this; + DestinationTile* tile = new DestinationTile; - tile->_name = os.str(); - tile->_dataSet = this; - tile->_cs = cs; - tile->_extents = extents; + tile->_name = destinationGraph->_name; tile->_level = currentLevel; tile->_tileX = currentX; tile->_tileY = currentY; + tile->_dataSet = this; + tile->_cs = cs; + tile->_extents = extents; tile->setMaximumImagerySize(maxImageSize,maxImageSize); tile->setMaximumTerrainSize(maxTerrainSize,maxTerrainSize); tile->computeMaximumSourceResolution(_sourceGraph.get()); - insertTileToQuadMap(tile); + insertTileToQuadMap(destinationGraph); if (currentLevel>=maxNumLevels-1) { @@ -2116,7 +2249,8 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord osg::BoundingBox top_left(extents.xMin(),yCenter,extents.zMin(),xCenter,extents.yMax(),extents.zMax()); osg::BoundingBox top_right(xCenter,yCenter,extents.zMin(),extents.xMax(),extents.yMax(),extents.zMax()); - destinationGraph->_children.push_back(createDestinationGraph(cs, + destinationGraph->_children.push_back(createDestinationGraph(destinationGraph, + cs, bottom_left, maxImageSize, maxTerrainSize, @@ -2125,7 +2259,8 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord newY, maxNumLevels)); - destinationGraph->_children.push_back(createDestinationGraph(cs, + destinationGraph->_children.push_back(createDestinationGraph(destinationGraph, + cs, bottom_right, maxImageSize, maxTerrainSize, @@ -2134,7 +2269,8 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord newY, maxNumLevels)); - destinationGraph->_children.push_back(createDestinationGraph(cs, + destinationGraph->_children.push_back(createDestinationGraph(destinationGraph, + cs, top_left, maxImageSize, maxTerrainSize, @@ -2143,7 +2279,8 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord newY+1, maxNumLevels)); - destinationGraph->_children.push_back(createDestinationGraph(cs, + destinationGraph->_children.push_back(createDestinationGraph(destinationGraph, + cs, top_right, maxImageSize, maxTerrainSize, @@ -2171,7 +2308,8 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord osg::BoundingBox left(extents.xMin(),extents.yMin(),extents.zMin(),xCenter,extents.yMax(),extents.zMax()); osg::BoundingBox right(xCenter,extents.yMin(),extents.zMin(),extents.xMax(),extents.yMax(),extents.zMax()); - destinationGraph->_children.push_back(createDestinationGraph(cs, + destinationGraph->_children.push_back(createDestinationGraph(destinationGraph, + cs, left, maxImageSize, maxTerrainSize, @@ -2180,7 +2318,8 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord newY, maxNumLevels)); - destinationGraph->_children.push_back(createDestinationGraph(cs, + destinationGraph->_children.push_back(createDestinationGraph(destinationGraph, + cs, right, maxImageSize, maxTerrainSize, @@ -2209,7 +2348,8 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord osg::BoundingBox top(extents.xMin(),yCenter,extents.zMin(),extents.xMax(),extents.yMax(),extents.zMax()); osg::BoundingBox bottom(extents.xMin(),extents.yMin(),extents.zMin(),extents.xMax(),yCenter,extents.zMax()); - destinationGraph->_children.push_back(createDestinationGraph(cs, + destinationGraph->_children.push_back(createDestinationGraph(destinationGraph, + cs, bottom, maxImageSize, maxTerrainSize, @@ -2218,7 +2358,8 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord newY, maxNumLevels)); - destinationGraph->_children.push_back(createDestinationGraph(cs, + destinationGraph->_children.push_back(createDestinationGraph(destinationGraph, + cs, top, maxImageSize, maxTerrainSize, @@ -2245,19 +2386,6 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord } return destinationGraph; - -#if 0 - // now get each tile to point to each other. - top_left_tile->setNeighbours(0,0,bottom_left_tile,bottom_right_tile,top_right_tile,0,0,0); - top_right_tile->setNeighbours(top_left_tile,bottom_left_tile,bottom_right_tile,0,0,0,0,0); - bottom_left_tile->setNeighbours(0,0,0,0,bottom_right_tile,top_right_tile,top_left_tile,0); - bottom_right_tile->setNeighbours(bottom_left_tile,0,0,0,0,0,top_right_tile,top_left_tile); - - top_left_tile->checkNeighbouringTiles(); - top_right_tile->checkNeighbouringTiles(); - bottom_left_tile->checkNeighbouringTiles(); - bottom_right_tile->checkNeighbouringTiles(); -#endif } void DataSet::computeDestinationGraphFromSources(unsigned int numLevels) @@ -2307,7 +2435,8 @@ void DataSet::computeDestinationGraphFromSources(unsigned int numLevels) unsigned int imageSize = 256; unsigned int terrainSize = 64; - _destinationGraph = createDestinationGraph(_coordinateSystem.get(), + _destinationGraph = createDestinationGraph(0, + _coordinateSystem.get(), extents, imageSize, terrainSize, @@ -2477,6 +2606,117 @@ void DataSet::populateDestinationGraphFromSources() } +void DataSet::_readRow(Row& row) +{ + std::cout<<"_readRow "<second; + for(CompositeDestination::TileList::iterator titr=cd->_tiles.begin(); + titr!=cd->_tiles.end(); + ++titr) + { + DestinationTile* tile = titr->get(); + std::cout<<" reading tile level="<_level<<" X="<_tileX<<" Y="<_tileY<readFrom(_sourceGraph.get()); + } + } +} + +void DataSet::_equalizeRow(Row& row) +{ + std::cout<<"_equalizeRow"<second; + for(CompositeDestination::TileList::iterator titr=cd->_tiles.begin(); + titr!=cd->_tiles.end(); + ++titr) + { + DestinationTile* tile = titr->get(); + std::cout<<" equalizing tile level="<_level<<" X="<_tileX<<" Y="<_tileY<equalizeBoundaries(); + tile->setTileComplete(true); + } + } +} + +void DataSet::_writeRow(Row& row) +{ + std::cout<<"_writeRow"<second; + CompositeDestination* parent = cd->_parent; + + if (parent) + { + if (!parent->getSubTilesGenerated() && parent->areSubTilesComplete()) + { + osg::ref_ptr node = parent->createSubTileScene(); + std::string filename = parent->getSubTileName(); + if (node.valid()) + { + std::cout<<" writeSubTile filename="<setSubTilesGenerated(true); + } + else + { + std::cout<<" failed to writeSubTile node for tile, filename="< node = cd->createPagedLODScene(); + + //std::string filename = cd->_name + _tileExtension; + std::string filename = _tileBasename+_tileExtension; + + if (node.valid()) + { + std::cout<<" writeNodeFile = "<_level<<" X="<_tileX<<" Y="<_tileY<<" filename="<second; + for(CompositeDestination::TileList::iterator titr=cd->_tiles.begin(); + titr!=cd->_tiles.end(); + ++titr) + { + DestinationTile* tile = titr->get(); + std::cout<<" empty tile level="<_level<<" X="<_tileX<<" Y="<_tileY<empty(); + } + } + + + +} + + void DataSet::createDestination(unsigned int numLevels) { @@ -2485,34 +2725,63 @@ void DataSet::createDestination(unsigned int numLevels) computeDestinationGraphFromSources(numLevels); updateSourcesForDestinationGraphNeeds(); - - populateDestinationGraphFromSources(); - if (_destinationGraph.valid()) - { - if (_databaseType==LOD_DATABASE) - { - _rootNode = _destinationGraph->createScene(); - } - else - { - // create top most level? - } - } } void DataSet::writeDestination() { - - std::string filename = _tileBasename+_tileExtension; - std::cout<<"DataSet::writeDestination("<createScene(); + osgDB::writeNodeFile(*_rootNode,filename); + } + else // _databaseType==PagedLOD_DATABASE + { + // for each level build read and write the rows. + for(QuadMap::iterator qitr=_quadMap.begin(); + qitr!=_quadMap.end(); + ++qitr) + { + Level& level = qitr->second; + + // skip is level is empty. + if (level.empty()) continue; + + std::cout<<"New level"<second); + Level::iterator curr_itr = prev_itr; + ++curr_itr; + for(; + curr_itr!=level.end(); + ++curr_itr) + { + _readRow(curr_itr->second); + + _equalizeRow(prev_itr->second); + _writeRow(prev_itr->second); + _emptyRow(prev_itr->second); + + prev_itr = curr_itr; + } + + _equalizeRow(prev_itr->second); + _writeRow(prev_itr->second); + _emptyRow(prev_itr->second); + } + } } else { std::cout<<"Error: no scene graph to output, no file written."<