Added support for automatic subdivision of the destination graph

This commit is contained in:
Robert Osfield
2004-01-12 22:03:29 +00:00
parent 4765c8744d
commit 87299f4fc0
2 changed files with 174 additions and 41 deletions

View File

@@ -147,7 +147,7 @@ osg::BoundingBox DataSet::SourceData::getExtents(const osgTerrain::CoordinateSys
if (_gdalDataSet)
{
std::cout<<"Projecting bounding volume for "<<_source->getFileName()<<std::endl;
//std::cout<<"Projecting bounding volume for "<<_source->getFileName()<<std::endl;
osg::BoundingBox bb;
@@ -205,7 +205,7 @@ DataSet::SpatialProperties DataSet::SourceData::computeSpatialProperties(osgTerr
if (_gdalDataSet)
{
std::cout<<"Projecting bounding volume for "<<_source->getFileName()<<std::endl;
//std::cout<<"Projecting bounding volume for "<<_source->getFileName()<<std::endl;
DataSet::SpatialProperties sp;
@@ -742,14 +742,26 @@ void DataSet::Source::consolodateRequiredResolutions()
double minResX = itr->_resX;
double minResY = itr->_resY;
double maxResX = itr->_resX;
double maxResY = itr->_resY;
++itr;
for(;itr!=_requiredResolutions.end();++itr)
{
minResX = osg::minimum(minResX,itr->_resX);
minResY = osg::minimum(minResY,itr->_resY);
maxResX = osg::minimum(maxResX,itr->_resX);
maxResY = osg::minimum(maxResY,itr->_resY);
}
double currResX = minResX;
double currResY = minResY;
while (currResX<=maxResX && currResY<=maxResY)
{
consolodated.push_back(ResolutionPair(currResX,currResY));
currResX *= 2.0f;
currResY *= 2.0f;
}
consolodated.push_back(ResolutionPair(minResX,minResY));
_requiredResolutions.swap(consolodated);
}
@@ -803,7 +815,7 @@ void DataSet::DestinationTile::computeMaximumSourceResolution(CompositeSource* s
if (!sp._extents.intersects(_extents))
{
std::cout<<"DataSet::DestinationTile::computeMaximumSourceResolution:: source does not overlap ignoring for this tile."<<std::endl;
// std::cout<<"DataSet::DestinationTile::computeMaximumSourceResolution:: source does not overlap ignoring for this tile."<<std::endl;
continue;
}
@@ -835,7 +847,7 @@ void DataSet::DestinationTile::computeMaximumSourceResolution(CompositeSource* s
}
}
bool DataSet::DestinationTile::computeImageResolution(double& resX, double& resY)
bool DataSet::DestinationTile::computeImageResolution(unsigned int& numColumns, unsigned int& numRows, double& resX, double& resY)
{
if (_imagery_maxSourceResolutionX!=0.0f && _imagery_maxSourceResolutionY!=0.0f &&
_imagery_maxNumColumns!=0 && _imagery_maxNumRows!=0)
@@ -843,50 +855,43 @@ bool DataSet::DestinationTile::computeImageResolution(double& resX, double& resY
unsigned int numColumnsAtFullRes = 1+(unsigned int)ceilf((_extents.xMax()-_extents.xMin())/_imagery_maxSourceResolutionX);
unsigned int numRowsAtFullRes = 1+(unsigned int)ceilf((_extents.yMax()-_extents.yMin())/_imagery_maxSourceResolutionY);
unsigned int texture_numColumns = osg::minimum(_imagery_maxNumColumns,numColumnsAtFullRes);
unsigned int texture_numRows = osg::minimum(_imagery_maxNumRows,numRowsAtFullRes);
numColumns = osg::minimum(_imagery_maxNumColumns,numColumnsAtFullRes);
numRows = osg::minimum(_imagery_maxNumRows,numRowsAtFullRes);
resX = (_extents.xMax()-_extents.xMin())/(double)(texture_numColumns-1);
resY = (_extents.yMax()-_extents.yMin())/(double)(texture_numRows-1);
resX = (_extents.xMax()-_extents.xMin())/(double)(numColumns-1);
resY = (_extents.yMax()-_extents.yMin())/(double)(numRows-1);
return true;
}
return false;
}
bool DataSet::DestinationTile::computeTerrainResolution(double& resX, double& resY)
bool DataSet::DestinationTile::computeTerrainResolution(unsigned int& numColumns, unsigned int& numRows, double& resX, double& resY)
{
if (_terrain_maxSourceResolutionX!=0.0f && _terrain_maxSourceResolutionY!=0.0f &&
_terrain_maxNumColumns!=0 && _terrain_maxNumRows!=0)
{
unsigned int numColumnsAtFullRes = 1+(unsigned int)ceilf((_extents.xMax()-_extents.xMin())/_terrain_maxSourceResolutionX);
unsigned int numRowsAtFullRes = 1+(unsigned int)ceilf((_extents.yMax()-_extents.yMin())/_terrain_maxSourceResolutionY);
unsigned int dem_numColumns = osg::minimum(_terrain_maxNumColumns,numColumnsAtFullRes);
unsigned int dem_numRows = osg::minimum(_terrain_maxNumRows,numRowsAtFullRes);
numColumns = osg::minimum(_terrain_maxNumColumns,numColumnsAtFullRes);
numRows = osg::minimum(_terrain_maxNumRows,numRowsAtFullRes);
resX = (_extents.xMax()-_extents.xMin())/(double)(dem_numColumns-1);
resY = (_extents.yMax()-_extents.yMin())/(double)(dem_numRows-1);
resX = (_extents.xMax()-_extents.xMin())/(double)(numColumns-1);
resY = (_extents.yMax()-_extents.yMin())/(double)(numRows-1);
return true;
}
return false;
}
void DataSet::DestinationTile::allocate()
{
if (_imagery_maxSourceResolutionX!=0.0f && _imagery_maxSourceResolutionY!=0.0f &&
_imagery_maxNumColumns!=0 && _imagery_maxNumRows!=0)
unsigned int texture_numColumns, texture_numRows;
double texture_dx, texture_dy;
if (computeImageResolution(texture_numColumns,texture_numRows,texture_dx,texture_dy))
{
unsigned int numColumnsAtFullRes = 1+(unsigned int)ceilf((_extents.xMax()-_extents.xMin())/_imagery_maxSourceResolutionX);
unsigned int numRowsAtFullRes = 1+(unsigned int)ceilf((_extents.yMax()-_extents.yMin())/_imagery_maxSourceResolutionY);
unsigned int texture_numColumns = osg::minimum(_imagery_maxNumColumns,numColumnsAtFullRes);
unsigned int texture_numRows = osg::minimum(_imagery_maxNumRows,numRowsAtFullRes);
double texture_dx = (_extents.xMax()-_extents.xMin())/(double)(texture_numColumns-1);
double texture_dy = (_extents.yMax()-_extents.yMin())/(double)(texture_numRows-1);
_imagery = new DestinationData;
_imagery->_cs = _cs;
_imagery->_extents = _extents;
@@ -898,17 +903,11 @@ void DataSet::DestinationTile::allocate()
_imagery->_image->allocateImage(texture_numColumns,texture_numRows,1,GL_RGB,GL_UNSIGNED_BYTE);
}
if (_terrain_maxSourceResolutionX!=0.0f && _terrain_maxSourceResolutionY!=0.0f &&
_terrain_maxNumColumns!=0 && _terrain_maxNumRows!=0)
unsigned int dem_numColumns, dem_numRows;
double dem_dx, dem_dy;
if (computeTerrainResolution(dem_numColumns,dem_numRows,dem_dx,dem_dy))
{
unsigned int numColumnsAtFullRes = 1+(unsigned int)ceilf((_extents.xMax()-_extents.xMin())/_terrain_maxSourceResolutionX);
unsigned int numRowsAtFullRes = 1+(unsigned int)ceilf((_extents.yMax()-_extents.yMin())/_terrain_maxSourceResolutionY);
unsigned int dem_numColumns = osg::minimum(_terrain_maxNumColumns,numColumnsAtFullRes);
unsigned int dem_numRows = osg::minimum(_terrain_maxNumRows,numRowsAtFullRes);
double dem_dx = (_extents.xMax()-_extents.xMin())/(double)(dem_numColumns-1);
double dem_dy = (_extents.yMax()-_extents.yMin())/(double)(dem_numRows-1);
_terrain = new DestinationData;
_terrain->_cs = _cs;
_terrain->_extents = _extents;
@@ -1363,8 +1362,9 @@ void DataSet::DestinationTile::addRequiredResolutions(CompositeSource* sourceGra
{
if (source->intersects(*_imagery))
{
unsigned int numCols,numRows;
double resX, resY;
if (computeImageResolution(resX,resY))
if (computeImageResolution(numCols,numRows,resX,resY))
{
source->addRequiredResolution(resX,resY);
}
@@ -1374,8 +1374,9 @@ void DataSet::DestinationTile::addRequiredResolutions(CompositeSource* sourceGra
{
if (source->intersects(*_terrain))
{
unsigned int numCols,numRows;
double resX, resY;
if (computeTerrainResolution(resX,resY))
if (computeTerrainResolution(numCols,numRows,resX,resY))
{
source->addRequiredResolution(resX,resY);
}
@@ -1528,6 +1529,116 @@ void DataSet::loadSources()
}
}
DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::CoordinateSystem* cs,
const osg::BoundingBox& extents,
unsigned int maxImageSize,
unsigned int maxTerrainSize,
unsigned int currentLevel,
unsigned int maxNumLevels)
{
DataSet::CompositeDestination* destinationGraph = new DataSet::CompositeDestination;
// first create the topmost tile
DestinationTile* tile = new DestinationTile;
tile->_name = _tileBasename;
tile->_cs = cs;
tile->_extents = extents;
tile->setMaximumImagerySize(maxImageSize,maxImageSize);
tile->setMaximumTerrainSize(maxTerrainSize,maxTerrainSize);
tile->computeMaximumSourceResolution(_sourceGraph.get());
if (currentLevel>=maxNumLevels-1)
{
// bottom level can't divide any further.
destinationGraph->_tiles.push_back(tile);
}
else
{
destinationGraph->_tiles.push_back(tile);
bool needToDivideX = false;
bool needToDivideY = false;
unsigned int texture_numColumns;
unsigned int texture_numRows;
double texture_dx;
double texture_dy;
if (tile->computeImageResolution(texture_numColumns,texture_numRows,texture_dx,texture_dy))
{
if (texture_dx>tile->_imagery_maxSourceResolutionX) needToDivideX = true;
if (texture_dy>tile->_imagery_maxSourceResolutionY) needToDivideY = true;
}
unsigned int dem_numColumns;
unsigned int dem_numRows;
double dem_dx;
double dem_dy;
if (tile->computeTerrainResolution(dem_numColumns,dem_numRows,dem_dx,dem_dy))
{
if (dem_dx>tile->_terrain_maxSourceResolutionX) needToDivideX = true;
if (dem_dy>tile->_terrain_maxSourceResolutionY) needToDivideY = true;
}
float xCenter = (extents.xMin()+extents.xMax())*0.5f;
float yCenter = (extents.yMin()+extents.yMax())*0.5f;
if (needToDivideX && needToDivideY)
{
std::cout<<"Need to Divide X + Y for level "<<currentLevel<<std::endl;
// create four tiles.
osg::BoundingBox bottom_left(extents.xMin(),extents.yMin(),extents.zMin(),xCenter,yCenter,extents.zMax());
osg::BoundingBox bottom_right(xCenter,extents.yMin(),extents.zMin(),extents.xMax(),yCenter,extents.zMax());
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,
bottom_left,
maxImageSize,
maxTerrainSize,
currentLevel+1,
maxNumLevels));
destinationGraph->_children.push_back(createDestinationGraph(cs,
bottom_left,
maxImageSize,
maxTerrainSize,
currentLevel+1,
maxNumLevels));
destinationGraph->_children.push_back(createDestinationGraph(cs,
bottom_left,
maxImageSize,
maxTerrainSize,
currentLevel+1,
maxNumLevels));
destinationGraph->_children.push_back(createDestinationGraph(cs,
bottom_left,
maxImageSize,
maxTerrainSize,
currentLevel+1,
maxNumLevels));
}
else if (needToDivideX)
{
std::cout<<"Need to Divide X only"<<std::endl;
}
else if (needToDivideY)
{
std::cout<<"Need to Divide Y only"<<std::endl;
}
else
{
std::cout<<"No Need to Divide"<<std::endl;
}
}
return destinationGraph;
}
void DataSet::computeDestinationGraphFromSources()
{
@@ -1561,7 +1672,20 @@ void DataSet::computeDestinationGraphFromSources()
}
// then create the destinate graph accordingly.
#if 1
unsigned int imageSize = 256;
unsigned int terrainSize = 256;
unsigned int numLevels = 5;
_destinationGraph = createDestinationGraph(_coordinateSystem.get(),
extents,
imageSize,
terrainSize,
0,
numLevels);
#else
_destinationGraph = new CompositeDestination;
_destinationGraph->_cs = _coordinateSystem;
_destinationGraph->_extents = extents;
@@ -1664,6 +1788,8 @@ void DataSet::computeDestinationGraphFromSources()
}
#endif
}
template<class T>

View File

@@ -644,9 +644,9 @@ class DataSet : public osg::Referenced
void computeMaximumSourceResolution(CompositeSource* sourceGraph);
bool computeImageResolution(double& resX, double& resY);
bool computeTerrainResolution(double& resX, double& resY);
bool computeImageResolution(unsigned int& numColumns, unsigned int& numRows, double& resX, double& resY);
bool computeTerrainResolution(unsigned int& numColumns, unsigned int& numRows, double& resX, double& resY);
void allocate();
void addRequiredResolutions(CompositeSource* sourceGraph);
@@ -721,6 +721,13 @@ class DataSet : public osg::Referenced
void setDestinationTileBaseName(const std::string& basename) { _tileBasename = basename; }
void setDestinationTileExtension(const std::string& extension) { _tileExtension = _tileExtension; }
CompositeDestination* createDestinationGraph(osgTerrain::CoordinateSystem* cs,
const osg::BoundingBox& extents,
unsigned int maxImageSize,
unsigned int maxTerrainSize,
unsigned int currentLevel,
unsigned int maxNumLevels);
void computeDestinationGraphFromSources();
void updateSourcesForDestinationGraphNeeds();