From cec8dd54edda409d1e72811c3dfb2a9547907532 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 1 Feb 2004 10:27:19 +0000 Subject: [PATCH] Improvements to the merging of source image datasets into the destination tiles which ensure that gaps don't appear. Made the elevation properly scaled relative to the having the x & y in degrees. --- examples/osgdem/DataSet.cpp | 300 +++++++++++++++++++++--------------- examples/osgdem/osgdem.cpp | 4 +- 2 files changed, 180 insertions(+), 124 deletions(-) diff --git a/examples/osgdem/DataSet.cpp b/examples/osgdem/DataSet.cpp index c8f66aa80..72d91935e 100644 --- a/examples/osgdem/DataSet.cpp +++ b/examples/osgdem/DataSet.cpp @@ -29,6 +29,53 @@ #include +#include + +bool areCoordinateSystemEquivilant(const osgTerrain::CoordinateSystem* lhs,const osgTerrain::CoordinateSystem* rhs) +{ + // if ptr's equal the return true + if (lhs == rhs) return true; + + // if one CS is NULL then true false + if (!lhs || !rhs) + { + //std::cout<<"areCoordinateSystemEquivilant lhs="<RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); - bandGreen->RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); - bandBlue->RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,(void*)(imageData+2),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); + bool directCopy = false; + if (directCopy) + { + bandRed->RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); + bandGreen->RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); + bandBlue->RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,(void*)(imageData+2),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace); + } + else + { + unsigned char* imageCache = new unsigned char[destWidth*destHeight*3]; + bandRed->RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,(void*)(imageCache+0),destWidth,destHeight,targetGDALType,pixelSpace,pixelSpace*destWidth); + bandGreen->RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,(void*)(imageCache+1),destWidth,destHeight,targetGDALType,pixelSpace,pixelSpace*destWidth); + bandBlue->RasterIO(GF_Read,windowX,_numValuesY-(windowY+windowHeight),windowWidth,windowHeight,(void*)(imageCache+2),destWidth,destHeight,targetGDALType,pixelSpace,pixelSpace*destWidth); + + // now copy into destination image + unsigned char* sourceRowPtr = imageCache; + unsigned int sourceRowDelta = pixelSpace*destWidth; + unsigned char* destinationRowPtr = imageData; + unsigned int destinationRowDelta = lineSpace; + + for(int row=0; + rowdestinationTotal) + { + // copy pixel across + destinationColumnPtr[0] = sourceColumnPtr[0]; + destinationColumnPtr[1] = sourceColumnPtr[1]; + destinationColumnPtr[2] = sourceColumnPtr[2]; + } +#else + if (sourceColumnPtr[0]!=0 || sourceColumnPtr[1]!=0 || sourceColumnPtr[2]!=0) + { + // copy pixel across + destinationColumnPtr[0] = sourceColumnPtr[0]; + destinationColumnPtr[1] = sourceColumnPtr[1]; + destinationColumnPtr[2] = sourceColumnPtr[2]; + } +#endif + } + } + + delete [] imageCache; + + } } @@ -374,9 +475,9 @@ void DataSet::SourceData::readHeightField(DestinationData& destination) else if (!bandSelected && bandRed) bandSelected = bandRed; else if (!bandSelected && bandGreen) bandSelected = bandGreen; else if (!bandSelected && bandBlue) bandSelected = bandBlue; - - //float heightRatio = 1.0/65536; - float heightRatio = 1.0; + + bool xyInDegrees = true; + float heightRatio = xyInDegrees ? 1.0f/111319.0f : 1.0f; if (bandSelected) { @@ -431,6 +532,7 @@ void DataSet::Source::loadSourceData() std::cout<<"DataSet::Source::loadSourceData() "<<_filename<_cs; } bool DataSet::Source::needReproject(const osgTerrain::CoordinateSystem* cs) const @@ -446,14 +548,19 @@ bool DataSet::Source::needReproject(const osgTerrain::CoordinateSystem* cs, doub if (_type==MODEL) return false; // always need to reproject imagery with GCP's. - if (_sourceData->_hasGCPs) return true; + if (_sourceData->_hasGCPs) + { + std::cout<<"Need to to reproject due to presence of GCP's"<_cs == cs) || - (_sourceData->_cs.valid() && cs && (*(_sourceData->_cs) == *cs)); - - - if (!csTheSame) return true; + if (!areCoordinateSystemEquivilant(_cs.get(),cs)) + { + std::cout<<"Need to do reproject !areCoordinateSystemEquivilant(_cs.get(),cs)"<_image = new osg::Image; _imagery->_image->allocateImage(texture_numColumns,texture_numRows,1,GL_RGB,GL_UNSIGNED_BYTE); + unsigned char* data = _imagery->_image->data(); + unsigned int totalSize = _imagery->_image->getTotalSizeInBytesIncludingMipmaps(); + for(unsigned int i=0;i_heightField.valid()) + + bool heightFieldPresent = _terrain.valid() && _terrain->_heightField.valid(); + bool imagePresent = _imagery.valid() && _imagery->_image.valid(); + + if (!heightFieldPresent && !imagePresent) { + std::cout<<"**** No terrain or imagery to build tile from, will need to create some fallback ****"<_heightField.get(); - - osg::Geode* geode = new osg::Geode; + geode = new osg::Geode; geode->addDrawable(new osg::ShapeDrawable(hf)); hf->setSkirtHeight(geode->getBound().radius()*0.01f); - if (_imagery.valid() && _imagery->_image.valid()) - { - std::string imageName(_name+".rgb"); - std::cout<<"Writing out imagery to "<_image->setFileName(imageName.c_str()); - osgDB::writeImageFile(*_imagery->_image,_imagery->_image->getFileName().c_str()); - - osg::StateSet* stateset = geode->getOrCreateStateSet(); - osg::Texture2D* texture = new osg::Texture2D(_imagery->_image.get()); - texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP); - texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP); - stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON); - } - - // create the skirt. - if (false) - { - - osg::Vec3 skirtVector(0.0f,0.0f,-0.003f); - - int numColumns = hf->getNumColumns(); - int numRows = hf->getNumRows(); - - int numVerticesInSkirt = 2*(numColumns*2 + numRows*2 - 3); - - osg::Geometry* skirt = new osg::Geometry; - osg::Vec3Array& v = *(new osg::Vec3Array(numVerticesInSkirt)); - osg::Vec3Array& n = *(new osg::Vec3Array(numVerticesInSkirt)); - osg::Vec2Array& t = *(new osg::Vec2Array(numVerticesInSkirt)); - - osg::DrawArrays& skirtDrawArrays = *(new osg::DrawArrays(GL_QUAD_STRIP,0,numVerticesInSkirt)); - int vi=0; - int r,c; - // create bottom skirt vertices - r=0; - float dt_dx = 1.0f/(float)(numColumns-1); - float dt_dy = 1.0f/(float)(numRows-1); - for(c=0;cgetVertex(c,r); - n[vi] = hf->getNormal(c,r); - t[vi++] = osg::Vec2(c*dt_dx,r*dt_dy); - - v[vi] = hf->getVertex(c,r)+skirtVector; - n[vi] = hf->getNormal(c,r); - t[vi++] = osg::Vec2(c*dt_dx,r*dt_dy); - - } - // create right skirt vertices - c=numColumns-1; - for(r=0;rgetVertex(c,r); - n[vi] = hf->getNormal(c,r); - t[vi++] = osg::Vec2(c*dt_dx,r*dt_dy); - - v[vi] = hf->getVertex(c,r)+skirtVector; - n[vi] = hf->getNormal(c,r); - t[vi++] = osg::Vec2(c*dt_dx,r*dt_dy); - } - // create top skirt vertices - r=numRows-1; - for(c=numColumns-1;c>0;--c) - { - v[vi] = hf->getVertex(c,r); - n[vi] = hf->getNormal(c,r); - t[vi++] = osg::Vec2(c*dt_dx,r*dt_dy); - - v[vi] = hf->getVertex(c,r)+skirtVector; - n[vi] = hf->getNormal(c,r); - t[vi++] = osg::Vec2(c*dt_dx,r*dt_dy); - } - // create left skirt vertices - c=0; - for(r=numRows-1;r>=0;--r) - { - v[vi] = hf->getVertex(c,r); - n[vi] = hf->getNormal(c,r); - t[vi++] = osg::Vec2(c*dt_dx,r*dt_dy); - - v[vi] = hf->getVertex(c,r)+skirtVector; - n[vi] = hf->getNormal(c,r); - t[vi++] = osg::Vec2(c*dt_dx,r*dt_dy); - } - - // pass arrays to Geometry - skirt->setVertexArray(&v); - skirt->setNormalArray(&n); - skirt->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); - skirt->setTexCoordArray(0,&t); - - skirt->addPrimitiveSet(&skirtDrawArrays); - - geode->addDrawable(skirt); - - } - - return geode; } else { - std::cout<<"**** No terrain to build tile from, will need to create some fallback ****"<allocate(2,2); + hf->setOrigin(osg::Vec3(_extents.xMin(),_extents.yMin(),0.0f)); + hf->setXInterval(_extents.xMax()-_extents.xMin()); + hf->setYInterval(_extents.yMax()-_extents.yMin()); + + geode = new osg::Geode; + + geode->addDrawable(new osg::ShapeDrawable(hf)); + + hf->setSkirtHeight(geode->getBound().radius()*0.01f); } + + if (imagePresent) + { + std::string imageName(_name+".rgb"); + std::cout<<"Writing out imagery to "<_image->setFileName(imageName.c_str()); + osgDB::writeImageFile(*_imagery->_image,_imagery->_image->getFileName().c_str()); + + osg::StateSet* stateset = geode->getOrCreateStateSet(); + osg::Texture2D* texture = new osg::Texture2D(_imagery->_image.get()); + texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP); + texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP); + stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON); + } + + return geode; + + } void DataSet::DestinationTile::readFrom(CompositeSource* sourceGraph) @@ -1675,7 +1731,7 @@ DataSet::CompositeDestination* DataSet::createDestinationGraph(osgTerrain::Coord DataSet::CompositeDestination* destinationGraph = new DataSet::CompositeDestination(cs,extents); - destinationGraph->_maxVisibleDistance = extents.radius()*5.0f; + destinationGraph->_maxVisibleDistance = extents.radius()*10.0f; // first create the topmost tile diff --git a/examples/osgdem/osgdem.cpp b/examples/osgdem/osgdem.cpp index 99ab89422..13f2c2e27 100644 --- a/examples/osgdem/osgdem.cpp +++ b/examples/osgdem/osgdem.cpp @@ -115,12 +115,12 @@ int main( int argc, char **argv ) } - if (false) + if (false) { // set up the coordinate system OGRSpatialReference oSRS; - oSRS.SetProjCS( "UTM 47 (WGS84) in southern hemisphere." ); + oSRS.SetProjCS( "WGS 84 / UTM zone 47S" ); oSRS.SetWellKnownGeogCS( "WGS84" ); oSRS.SetUTM( 47, FALSE );