/* -*-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 commericial and non commericial 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 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("< node = osgDB::readNodeFile(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); } } } protected: inline void pushMatrix(osg::Matrix& matrix) { _matrixStack.push_back(matrix); } inline void popMatrix() { _matrixStack.pop_back(); } void convertXYZToLatLongHeight(osg::EllipsoidModel* em, osg::Vec3d& v) { em->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; 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 seperate 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; unsigned int maxLevels = 0; while(arguments.read("-l",maxLevels)) { ldv.addExtents(maxLevels); } double minX, maxX, minY, maxY; while(arguments.read("-e",maxLevels, minX, minY, maxX, maxY)) { ldv.addExtents(maxLevels, minX, minY, maxX, maxY); } std::string fileCache; while(arguments.read("--file-cache",fileCache) || arguments.read("-c",fileCache)) {} if (!fileCache.empty()) { std::string str("OSG_FILE_CACHE="); str += fileCache; putenv(strdup((char*)str.c_str())); } osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); 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."<