/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commercial and non commercial applications, * as long as this copyright notice is maintained. * * This application is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static bool s_ExitApplication = false; struct Extents { Extents(): _maxLevel(0), _min(DBL_MAX,DBL_MAX), _max(-DBL_MAX,-DBL_MAX) {} Extents(unsigned int maxLevel, double minX, double minY, double maxX, double maxY): _maxLevel(maxLevel), _min(minX, minY), _max(maxX, maxY) {} Extents(const Extents& extents): _maxLevel(extents._maxLevel), _min(extents._min), _max(extents._max) {} Extents& operator = (const Extents& rhs) { if (&rhs == this) return *this; _maxLevel = rhs._maxLevel; _min = rhs._min; _max = rhs._max; return *this; } bool intersects(unsigned level, osg::Vec2d& in_min, osg::Vec2d& in_max) { osg::notify(osg::INFO)<<"intersects("<(&group); osgTerrain::Locator* locator = terrainTile ? terrainTile->getLocator() : 0; if (locator) { osg::Vec3d l00(0.0,0.0,0.0); osg::Vec3d l10(1.0,0.0,0.0); osg::Vec3d l11(1.0,1.0,0.0); osg::Vec3d l01(0.0,1.0,0.0); osg::Vec3d w00, w10, w11, w01; locator->convertLocalToModel(l00, w00); locator->convertLocalToModel(l10, w10); locator->convertLocalToModel(l11, w11); locator->convertLocalToModel(l01, w01); if (locator->getEllipsoidModel() && locator->getCoordinateSystemType()==osgTerrain::Locator::GEOCENTRIC) { convertXYZToLatLongHeight(locator->getEllipsoidModel(), w00); convertXYZToLatLongHeight(locator->getEllipsoidModel(), w10); convertXYZToLatLongHeight(locator->getEllipsoidModel(), w11); convertXYZToLatLongHeight(locator->getEllipsoidModel(), w01); } updateBound(w00); updateBound(w10); updateBound(w11); updateBound(w01); return; } traverse(group); } void apply(osg::Transform& transform) { osg::Matrix matrix; if (!_matrixStack.empty()) matrix = _matrixStack.back(); transform.computeLocalToWorldMatrix(matrix,this); pushMatrix(matrix); traverse(transform); popMatrix(); } void apply(osg::PagedLOD& plod) { if (s_ExitApplication) return; ++_currentLevel; initBound(); // first compute the bounds of this subgraph for(unsigned int i=0; i node = readNodeFileAndWriteToCache(filename); if (!s_ExitApplication && node.valid()) node->accept(*this); } } } --_currentLevel; } void apply(osg::Geode& geode) { for(unsigned int i=0; iasGeometry(); if (geom) { osg::Vec3Array* vertices = dynamic_cast(geom->getVertexArray()); if (vertices) updateBound(*vertices); } } } osg::Node* readNodeFileAndWriteToCache(const std::string& filename) { osg::Node* node = 0; if (_fileCache.valid() && osgDB::containsServerAddress(filename)) { if (_fileCache->existsInCache(filename)) { osg::notify(osg::NOTICE)<<"reading from FileCache: "<readNode(filename, osgDB::Registry::instance()->getOptions()).takeNode(); } else { osg::notify(osg::NOTICE)<<"reading : "<writeNode(*node, filename, osgDB::Registry::instance()->getOptions()); } } } else { osg::notify(osg::NOTICE)<<"reading : "<accept(cvv); if (!cvv.valid()) { OSG_NOTICE<<"Warning, errors in geometry found in file "<convertXYZToLatLongHeight(v.x(), v.y(), v.z(), v.y(), v.x(), v.z()); v.x() = osg::RadiansToDegrees(v.x()); v.y() = osg::RadiansToDegrees(v.y()); } void initBound() { _min.set(DBL_MAX, DBL_MAX); _max.set(-DBL_MAX, -DBL_MAX); } void updateBound(osg::Vec3d& v) { if (v.x() < _min.x()) _min.x() = v.x(); if (v.y() < _min.y()) _min.y() = v.y(); if (v.x() > _max.x()) _max.x() = v.x(); if (v.y() > _max.y()) _max.y() = v.y(); } void updateBound(osg::Vec3Array& vertices) { // set up matrix osg::Matrix matrix; if (!_matrixStack.empty()) matrix = _matrixStack.back(); // set up ellipsoid model osg::EllipsoidModel* em = !_csnStack.empty() ? _csnStack.back()->getEllipsoidModel() : 0; for(osg::Vec3Array::iterator itr = vertices.begin(); itr != vertices.end(); ++itr) { osg::Vec3d v = osg::Vec3d(*itr) * matrix; if (em) convertXYZToLatLongHeight(em, v); updateBound(v); } } bool intersects() { osg::notify(osg::INFO)<<"intersects() _min = "<<_min<<" _max = "<<_max<intersects(_currentLevel, _min, _max)) return true; } return false; } typedef std::vector ExtentsList; typedef std::vector MatrixStack; typedef std::vector CSNStack; osg::ref_ptr _fileCache; ExtentsList _extentsList; unsigned int _currentLevel; MatrixStack _matrixStack; CSNStack _csnStack; osg::Vec2d _min; osg::Vec2d _max; }; static void signalHandler(int sig) { printf("\nCaught signal %d, requesting exit...\n\n",sig); s_ExitApplication = true; } int main( int argc, char **argv ) { #ifndef _WIN32 signal(SIGHUP, signalHandler); signal(SIGQUIT, signalHandler); signal(SIGKILL, signalHandler); signal(SIGUSR1, signalHandler); signal(SIGUSR2, signalHandler); #endif signal(SIGABRT, signalHandler); signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); // set up the usage document, in case we need to print out how to use this program. arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is an application for collecting a set of separate files into a single archive file that can be later read in OSG applications.."); arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); arguments.getApplicationUsage()->addCommandLineOption("-l level","Read down to level across the whole database."); arguments.getApplicationUsage()->addCommandLineOption("-e level minX minY maxX maxY","Read down to across the extents minX, minY to maxY, maxY. Note, for geocentric datase X and Y are longitude and latitude respectively."); arguments.getApplicationUsage()->addCommandLineOption("-c directory","Shorthand for --file-cache directory."); arguments.getApplicationUsage()->addCommandLineOption("--file-cache directory","Set directory as to place cache download files."); // if user request help write it out to cout. if (arguments.read("-h") || arguments.read("--help")) { arguments.getApplicationUsage()->write(std::cout); return 1; } LoadDataVisitor ldv; std::string fileCachePath; while(arguments.read("--file-cache",fileCachePath) || arguments.read("-c",fileCachePath)) {} if (fileCachePath.empty()) { const char* env_fileCachePath = getenv("OSG_FILE_CACHE"); if (env_fileCachePath) { fileCachePath = env_fileCachePath; } } if (fileCachePath.empty()) { std::cout<<"No path to the file cache defined, please set OSG_FILE_PATH env var, or use --file-cache to set a suitable directory for the file cache."< loadedModel = ldv.readNodeFileAndWriteToCache(filename); if (!loadedModel) { std::cout<<"No data loaded, please specify a database to load"<accept(ldv); if (s_ExitApplication) { std::cout<<"osgfilecache cleanly exited in response to signal."<