diff --git a/NEWS.txt b/NEWS.txt index e72acc0bf..f3bbe1548 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -10,9 +10,11 @@ OSG News (most significant items from ChangeLog) Improved pager support with better multi-processor stability and constant frame rate peformance. - STL plugin. + new STL plugin. - NET plugin + new NET plugin + + OBJ plugin rewrite. Spelling and typo correction blitz on osg, osgDB and osgUtil libraries. diff --git a/examples/osgcallback/osgcallback.cpp b/examples/osgcallback/osgcallback.cpp index 5fc703087..8d56f7cd4 100644 --- a/examples/osgcallback/osgcallback.cpp +++ b/examples/osgcallback/osgcallback.cpp @@ -107,12 +107,12 @@ class InsertCallbacksVisitor : public osg::NodeVisitor class MyReadFileCallback : public osgDB::Registry::ReadFileCallback { public: - virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& fileName, osgDB::Registry::CacheHintOptions useObjectCache) + virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& fileName, osgDB::ReaderWriter::Options* options) { std::cout<<"before readNode"<readNodeImplementation(fileName,useObjectCache); + osgDB::ReaderWriter::ReadResult result = osgDB::Registry::instance()->readNodeImplementation(fileName,options); std::cout<<"after readNode"<getDataFilePathList(); } +/** Search for specified file in file system, checking the DataFilePathList for possible paths, + * returning the full path of the first valid file found, return an empty string if no string is found. + */ extern OSGDB_EXPORT std::string findDataFile(const std::string& filename,CaseSensitivity caseSensitivity=CASE_SENSITIVE); +/** Search for specified file in file system, checking first the database path set in the Options structure, then the DataFilePathList for possible paths, + * returning the full path of the first valid file found, return an empty string if no string is found. + */ +extern OSGDB_EXPORT std::string findDataFile(const std::string& filename,ReaderWriter::Options* options, CaseSensitivity caseSensitivity=CASE_SENSITIVE); + /** Convinience class for pushing a path on construction, and popping the path * and destruction. This helps keep the addition of a path local to a block * of code, even in the presence of exceptions.*/ + class PushAndPopDataPath { public: diff --git a/include/osgDB/ReadFile b/include/osgDB/ReadFile index a061ea2ee..90cea44a3 100644 --- a/include/osgDB/ReadFile +++ b/include/osgDB/ReadFile @@ -29,11 +29,11 @@ namespace osgDB { /** Read an osg::Object from file. * Return valid osg::Object on success, * return NULL on failure. - * Use the useObjectCache flag to override the osgDB::Regisytr::getUseObjectCacheHint(). + * Use the Options object to control cache operations and file search paths in osgDB::Registry. * The osgDB::Registry is used to load the appropriate ReaderWriter plugin * for the filename extension, and this plugin then handles the request * to read the specified file.*/ -extern OSGDB_EXPORT osg::Object* readObjectFile(const std::string& filename,Registry::CacheHintOptions useObjectCache); +extern OSGDB_EXPORT osg::Object* readObjectFile(const std::string& filename,const ReaderWriter::Options* options); /** Read an osg::Object from file. * Return valid osg::Object on success, @@ -43,18 +43,18 @@ extern OSGDB_EXPORT osg::Object* readObjectFile(const std::string& filename,Regi * to read the specified file.*/ inline osg::Object* readObjectFile(const std::string& filename) { - return readObjectFile(filename,Registry::instance()->getUseObjectCacheHint()); + return readObjectFile(filename,Registry::instance()->getOptions()); } /** Read an osg::Image from file. * Return valid osg::Image on success, * return NULL on failure. - * Use the useObjectCache flag to override the osgDB::Regisytr::getUseObjectCacheHint(). + * Use the Options object to control cache operations and file search paths in osgDB::Registry. * The osgDB::Registry is used to load the appropriate ReaderWriter plugin * for the filename extension, and this plugin then handles the request * to read the specified file.*/ -extern OSGDB_EXPORT osg::Image* readImageFile(const std::string& filename,Registry::CacheHintOptions useObjectCache); +extern OSGDB_EXPORT osg::Image* readImageFile(const std::string& filename,const ReaderWriter::Options* options); /** Read an osg::Image from file. * Return valid osg::Image on success, @@ -64,17 +64,17 @@ extern OSGDB_EXPORT osg::Image* readImageFile(const std::string& filename,Regis * to read the specified file.*/ inline osg::Image* readImageFile(const std::string& filename) { - return readImageFile(filename,Registry::instance()->getUseObjectCacheHint()); + return readImageFile(filename,Registry::instance()->getOptions()); } /** Read an osg::HeightField from file. * Return valid osg::HeightField on success, * return NULL on failure. - * Use the useObjectCache flag to override the osgDB::Regisytr::getUseObjectCacheHint(). + * Use the Options object to control cache operations and file search paths in osgDB::Registry. * The osgDB::Registry is used to load the appropriate ReaderWriter plugin * for the filename extension, and this plugin then handles the request * to read the specified file.*/ -extern OSGDB_EXPORT osg::HeightField* readHeightFieldFile(const std::string& filename,Registry::CacheHintOptions useObjectCache); +extern OSGDB_EXPORT osg::HeightField* readHeightFieldFile(const std::string& filename,const ReaderWriter::Options* options); /** Read an osg::HeightField from file. * Return valid osg::HeightField on success, @@ -84,17 +84,17 @@ extern OSGDB_EXPORT osg::HeightField* readHeightFieldFile(const std::string& fi * to read the specified file.*/ inline osg::HeightField* readHeightFieldFile(const std::string& filename) { - return readHeightFieldFile(filename,Registry::instance()->getUseObjectCacheHint()); + return readHeightFieldFile(filename,Registry::instance()->getOptions()); } /** Read an osg::Node from file. * Return valid osg::Node on success, * return NULL on failure. - * Use the useObjectCache flag to override the osgDB::Regisytr::getUseObjectCacheHint(). + * Use the Options object to control cache operations and file search paths in osgDB::Registry. * The osgDB::Registry is used to load the appropriate ReaderWriter plugin * for the filename extension, and this plugin then handles the request * to read the specified file.*/ -extern OSGDB_EXPORT osg::Node* readNodeFile(const std::string& filename,Registry::CacheHintOptions useObjectCache); +extern OSGDB_EXPORT osg::Node* readNodeFile(const std::string& filename,const ReaderWriter::Options* options); /** Read an osg::Node from file. * Return valid osg::Node on success, @@ -104,33 +104,33 @@ extern OSGDB_EXPORT osg::Node* readNodeFile(const std::string& filename,Registr * to read the specified file.*/ inline osg::Node* readNodeFile(const std::string& filename) { - return readNodeFile(filename,Registry::instance()->getUseObjectCacheHint()); + return readNodeFile(filename,Registry::instance()->getOptions()); } /** Read an osg::Node subgraph from files, creating a osg::Group to contain the nodes if more * than one subgraph has been loaded. - * Use the useObjectCache flag to override the osgDB::Regisytr::getUseObjectCacheHint().*/ -extern OSGDB_EXPORT osg::Node* readNodeFiles(std::vector& commandLine,Registry::CacheHintOptions useObjectCache); + * Use the Options object to control cache operations and file search paths in osgDB::Registry.*/ +extern OSGDB_EXPORT osg::Node* readNodeFiles(std::vector& commandLine,const ReaderWriter::Options* options); /** Read an osg::Node subgraph from files, creating a osg::Group to contain the nodes if more * than one subgraph has been loaded.*/ inline osg::Node* readNodeFiles(std::vector& commandLine) { - return readNodeFiles(commandLine,Registry::instance()->getUseObjectCacheHint()); + return readNodeFiles(commandLine,Registry::instance()->getOptions()); } /** Read an osg::Node subgraph from files, creating a osg::Group to contain the nodes if more * than one subgraph has been loaded. - * Use the useObjectCache flag to override the osgDB::Regisytr::getUseObjectCacheHint().*/ -extern OSGDB_EXPORT osg::Node* readNodeFiles(osg::ArgumentParser& parser,Registry::CacheHintOptions useObjectCache); + * Use the Options object to control cache operations and file search paths in osgDB::Registry.*/ +extern OSGDB_EXPORT osg::Node* readNodeFiles(osg::ArgumentParser& parser,const ReaderWriter::Options* options); /** Read an osg::Node subgraph from files, creating a osg::Group to contain the nodes if more * than one subgraph has been loaded.*/ inline osg::Node* readNodeFiles(osg::ArgumentParser& parser) { - return readNodeFiles(parser,Registry::instance()->getUseObjectCacheHint()); + return readNodeFiles(parser,Registry::instance()->getOptions()); } } diff --git a/include/osgDB/ReaderWriter b/include/osgDB/ReaderWriter index 146f33632..383c0c2d3 100644 --- a/include/osgDB/ReaderWriter +++ b/include/osgDB/ReaderWriter @@ -24,10 +24,15 @@ #include #include +#include + namespace osgDB { class Archive; +/** list of directories to search through which searching for files. */ +typedef std::deque FilePathList; + /** pure virtual base class for reading and writing of non native formats. */ class OSGDB_EXPORT ReaderWriter : public osg::Object { @@ -47,14 +52,45 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object class Options : public osg::Object { public: + + + /// bit mask for setting up which object types get cached by readObject/Image/HeightField/Node(filename) calls + enum CacheHintOptions + { /// do not cache objects of any type + CACHE_NONE = 0, - Options() {} + /// cache nodes loaded via readNode(filename) + CACHE_NODES = 1, + + /// cache images loaded via readImage(filename) + CACHE_IMAGES = 2, + + /// cache heightfield loaded via readHeightField(filename) + CACHE_HEIGHTFIELDS = 4, + + /// cache heightfield loaded via readHeightField(filename) + CACHE_ARCHIVES = 8, + + /// cache objects loaded via readObject(filename) + CACHE_OBJECTS = 16, + + /// cache on all read*(filename) calls + CACHE_ALL = CACHE_NODES | + CACHE_IMAGES | + CACHE_HEIGHTFIELDS | + CACHE_ARCHIVES | + CACHE_OBJECTS + }; + + + Options():_useObjectCacheHint(CACHE_NONE) {} Options(const std::string& str):_str(str) {} Options(const Options& options,const osg::CopyOp copyop=osg::CopyOp::SHALLOW_COPY): Object(options,copyop), _str(options._str), - _databasePath(options._databasePath) {} + _databasePaths(options._databasePaths), + _useObjectCacheHint(options._useObjectCacheHint) {} META_Object(osgDB,Options); @@ -65,17 +101,28 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object const std::string& getOptionString() const { return _str; } /** Set the database path to use a hint of where to look when loading models.*/ - void setDatabasePath(const std::string& str) { _databasePath = str; } + void setDatabasePath(const std::string& str) { _databasePaths.clear(); _databasePaths.push_back(str); } /** Get the database path which is used a hint of where to look when loading models.*/ - const std::string& getDatabasePath() const { return _databasePath; } + FilePathList& getDatabasePathList() { return _databasePaths; } + + /** Get the const database path which is used a hint of where to look when loading models.*/ + const FilePathList& getDatabasePathList() const { return _databasePaths; } + + /** Set whether the Registry::ObjectCache should be used by default.*/ + void setUseObjectCacheHint(CacheHintOptions useObjectCache) { _useObjectCacheHint = useObjectCache; } + + /** Get whether the Registry::ObjectCache should be used by default.*/ + CacheHintOptions getUseObjectCacheHint() const { return _useObjectCacheHint; } + protected: virtual ~Options() {} - std::string _str; - std::string _databasePath; + std::string _str; + FilePathList _databasePaths; + CacheHintOptions _useObjectCacheHint; }; diff --git a/include/osgDB/Registry b/include/osgDB/Registry index c6134b4ed..c1f4c37d5 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -25,7 +25,6 @@ #include #include #include -#include namespace osgDB { @@ -49,8 +48,6 @@ struct type_wrapper: basic_type_wrapper { } }; -/** list of directories to search through which searching for files. */ -typedef std::deque FilePathList; /** Registry is a singleton factory which stores @@ -68,33 +65,6 @@ class OSGDB_EXPORT Registry : public osg::Referenced { public: - /// bit mask for setting up which object types get cached by readObject/Image/HeightField/Node(filename) calls - enum CacheHintOptions - { /// do not cache objects of any type - CACHE_NONE = 0, - - /// cache nodes loaded via readNode(filename) - CACHE_NODES = 1, - - /// cache images loaded via readImage(filename) - CACHE_IMAGES = 2, - - /// cache heightfield loaded via readHeightField(filename) - CACHE_HEIGHTFIELDS = 4, - - /// cache heightfield loaded via readHeightField(filename) - CACHE_ARCHIVES = 8, - - /// cache objects loaded via readObject(filename) - CACHE_OBJECTS = 16, - - /// cache on all read*(filename) calls - CACHE_ALL = CACHE_NODES | - CACHE_IMAGES | - CACHE_HEIGHTFIELDS | - CACHE_ARCHIVES | - CACHE_OBJECTS - }; @@ -151,27 +121,27 @@ class OSGDB_EXPORT Registry : public osg::Referenced { public: - virtual ReaderWriter::ReadResult openArchive(const std::string& filename,ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint, CacheHintOptions useObjectCache) + virtual ReaderWriter::ReadResult openArchive(const std::string& filename,ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint, const ReaderWriter::Options* useObjectCache) { return osgDB::Registry::instance()->openArchiveImplementation(filename, status, indexBlockSizeHint, useObjectCache); } - virtual ReaderWriter::ReadResult readObject(const std::string& filename, CacheHintOptions options) + virtual ReaderWriter::ReadResult readObject(const std::string& filename, const ReaderWriter::Options* options) { return osgDB::Registry::instance()->readObjectImplementation(filename,options); } - virtual ReaderWriter::ReadResult readImage(const std::string& filename, CacheHintOptions options) + virtual ReaderWriter::ReadResult readImage(const std::string& filename, const ReaderWriter::Options* options) { return osgDB::Registry::instance()->readImageImplementation(filename,options); } - virtual ReaderWriter::ReadResult readHeightField(const std::string& filename, CacheHintOptions options) + virtual ReaderWriter::ReadResult readHeightField(const std::string& filename, const ReaderWriter::Options* options) { return osgDB::Registry::instance()->readHeightFieldImplementation(filename,options); } - virtual ReaderWriter::ReadResult readNode(const std::string& filename, CacheHintOptions options) + virtual ReaderWriter::ReadResult readNode(const std::string& filename, const ReaderWriter::Options* options) { return osgDB::Registry::instance()->readNodeImplementation(filename,options); } @@ -190,40 +160,40 @@ class OSGDB_EXPORT Registry : public osg::Referenced const ReadFileCallback* getReadFileCallback() const { return _readFileCallback.get(); } - ReaderWriter::ReadResult openArchive(const std::string& fileName,ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint, CacheHintOptions useObjectCache) + ReaderWriter::ReadResult openArchive(const std::string& fileName,ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint, const ReaderWriter::Options* options) { - if (_readFileCallback.valid()) return _readFileCallback->openArchive(fileName, status, indexBlockSizeHint, useObjectCache); - else return openArchiveImplementation(fileName, status, indexBlockSizeHint, useObjectCache); + if (_readFileCallback.valid()) return _readFileCallback->openArchive(fileName, status, indexBlockSizeHint, options); + else return openArchiveImplementation(fileName, status, indexBlockSizeHint, options); } - ReaderWriter::ReadResult openArchiveImplementation(const std::string& fileName, ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint, CacheHintOptions useObjectCache); + ReaderWriter::ReadResult openArchiveImplementation(const std::string& fileName, ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint, const ReaderWriter::Options* options); - ReaderWriter::ReadResult readObject(const std::string& fileName,CacheHintOptions useObjectCache) + ReaderWriter::ReadResult readObject(const std::string& fileName,const ReaderWriter::Options* options) { - if (_readFileCallback.valid()) return _readFileCallback->readObject(fileName,useObjectCache); - else return readObjectImplementation(fileName,useObjectCache); + if (_readFileCallback.valid()) return _readFileCallback->readObject(fileName,options); + else return readObjectImplementation(fileName,options); } - ReaderWriter::ReadResult readObjectImplementation(const std::string& fileName,CacheHintOptions useObjectCache); + ReaderWriter::ReadResult readObjectImplementation(const std::string& fileName,const ReaderWriter::Options* options); - ReaderWriter::ReadResult readImage(const std::string& fileName,CacheHintOptions useObjectCache) + ReaderWriter::ReadResult readImage(const std::string& fileName,const ReaderWriter::Options* options) { - if (_readFileCallback.valid()) return _readFileCallback->readImage(fileName,useObjectCache); - else return readImageImplementation(fileName,useObjectCache); + if (_readFileCallback.valid()) return _readFileCallback->readImage(fileName,options); + else return readImageImplementation(fileName,options); } - ReaderWriter::ReadResult readImageImplementation(const std::string& fileName,CacheHintOptions useObjectCache); + ReaderWriter::ReadResult readImageImplementation(const std::string& fileName,const ReaderWriter::Options* options); - ReaderWriter::ReadResult readHeightField(const std::string& fileName,CacheHintOptions useObjectCache) + ReaderWriter::ReadResult readHeightField(const std::string& fileName,const ReaderWriter::Options* options) { - if (_readFileCallback.valid()) return _readFileCallback->readHeightField(fileName,useObjectCache); - else return readHeightFieldImplementation(fileName,useObjectCache); + if (_readFileCallback.valid()) return _readFileCallback->readHeightField(fileName,options); + else return readHeightFieldImplementation(fileName,options); } - ReaderWriter::ReadResult readHeightFieldImplementation(const std::string& fileName,CacheHintOptions useObjectCache); + ReaderWriter::ReadResult readHeightFieldImplementation(const std::string& fileName,const ReaderWriter::Options* options); - ReaderWriter::ReadResult readNode(const std::string& fileName,CacheHintOptions useObjectCache) + ReaderWriter::ReadResult readNode(const std::string& fileName,const ReaderWriter::Options* options) { - if (_readFileCallback.valid()) return _readFileCallback->readNode(fileName,useObjectCache); - else return readNodeImplementation(fileName,useObjectCache); + if (_readFileCallback.valid()) return _readFileCallback->readNode(fileName,options); + else return readNodeImplementation(fileName,options); } - ReaderWriter::ReadResult readNodeImplementation(const std::string& fileName,CacheHintOptions useObjectCache); + ReaderWriter::ReadResult readNodeImplementation(const std::string& fileName,const ReaderWriter::Options* options); @@ -365,10 +335,10 @@ class OSGDB_EXPORT Registry : public osg::Referenced void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0); /** Set whether the Registry::ObjectCache should be used by default.*/ - void setUseObjectCacheHint(CacheHintOptions useObjectCache) { _useObjectCacheHint = useObjectCache; } + void setUseObjectCacheHint(ReaderWriter::Options::CacheHintOptions useObjectCache) { _useObjectCacheHint = useObjectCache; } /** Get whether the Registry::ObjectCache should be used by default.*/ - CacheHintOptions getUseObjectCacheHint() const { return _useObjectCacheHint; } + ReaderWriter::Options::CacheHintOptions getUseObjectCacheHint() const { return _useObjectCacheHint; } /** Add archive to archive cache so that future calls reference this archive.*/ @@ -494,21 +464,21 @@ class OSGDB_EXPORT Registry : public osg::Referenced ExtensionAliasMap _extAliasMap; // options to pass to reader writers. - osg::ref_ptr _options; + osg::ref_ptr _options; - FilePathList _dataFilePath; - FilePathList _libraryFilePath; + FilePathList _dataFilePath; + FilePathList _libraryFilePath; - CacheHintOptions _useObjectCacheHint; - ObjectCache _objectCache; - OpenThreads::Mutex _objectCacheMutex; + ReaderWriter::Options::CacheHintOptions _useObjectCacheHint; + ObjectCache _objectCache; + OpenThreads::Mutex _objectCacheMutex; - ArchiveCache _archiveCache; - OpenThreads::Mutex _archiveCacheMutex; + ArchiveCache _archiveCache; + OpenThreads::Mutex _archiveCacheMutex; - osg::ref_ptr _databasePager; - osg::ref_ptr _sharedStateManager; + osg::ref_ptr _databasePager; + osg::ref_ptr _sharedStateManager; }; diff --git a/src/osgDB/Archive.cpp b/src/osgDB/Archive.cpp index e5d9fe305..c7b71e9b7 100644 --- a/src/osgDB/Archive.cpp +++ b/src/osgDB/Archive.cpp @@ -24,12 +24,12 @@ using namespace osgDB; osgDB::Archive* osgDB::openArchive(const std::string& filename, Archive::ArchiveStatus status, unsigned int indexBlockSizeHint) { - return openArchive(filename, status, indexBlockSizeHint, Registry::instance()->getUseObjectCacheHint()); + return openArchive(filename, status, indexBlockSizeHint, Registry::instance()->getOptions()); } -osgDB::Archive* osgDB::openArchive(const std::string& filename, Archive::ArchiveStatus status, unsigned int indexBlockSizeHint,Registry::CacheHintOptions useObjectCache) +osgDB::Archive* osgDB::openArchive(const std::string& filename, Archive::ArchiveStatus status, unsigned int indexBlockSizeHint,ReaderWriter::Options* options) { - ReaderWriter::ReadResult result = osgDB::Registry::instance()->openArchive(filename, status, indexBlockSizeHint, useObjectCache); + ReaderWriter::ReadResult result = osgDB::Registry::instance()->openArchive(filename, status, indexBlockSizeHint, options); return result.takeArchive(); } diff --git a/src/osgDB/FileUtils.cpp b/src/osgDB/FileUtils.cpp index ba168aa1e..109de819d 100644 --- a/src/osgDB/FileUtils.cpp +++ b/src/osgDB/FileUtils.cpp @@ -203,19 +203,32 @@ std::string osgDB::findFileInPath(const std::string& filename, const FilePathLis } std::string osgDB::findDataFile(const std::string& filename,CaseSensitivity caseSensitivity) +{ + return findDataFile(filename,static_cast(0),caseSensitivity); +} + +OSGDB_EXPORT std::string osgDB::findDataFile(const std::string& filename,ReaderWriter::Options* options, CaseSensitivity caseSensitivity) { if (filename.empty()) return filename; + + std::string fileFound; + + if (options && !options->getDatabasePathList().empty()) + { + fileFound = findFileInPath(filename, options->getDatabasePathList(), caseSensitivity); + if (!fileFound.empty()) return fileFound; + } const FilePathList& filepath = Registry::instance()->getDataFilePathList(); - std::string fileFound = findFileInPath(filename, filepath,caseSensitivity); + fileFound = findFileInPath(filename, filepath,caseSensitivity); if (!fileFound.empty()) return fileFound; // if a directory is included in the filename, get just the (simple) filename itself and try that std::string simpleFileName = getSimpleFileName(filename); if (simpleFileName!=filename) { - std::string fileFound = findFileInPath(simpleFileName, filepath,caseSensitivity); + fileFound = findFileInPath(simpleFileName, filepath,caseSensitivity); if (!fileFound.empty()) return fileFound; } diff --git a/src/osgDB/Input.cpp b/src/osgDB/Input.cpp index be0594b71..f9ba16f72 100644 --- a/src/osgDB/Input.cpp +++ b/src/osgDB/Input.cpp @@ -80,22 +80,16 @@ osg::Node* Input::readNode() osg::Object* Input::readObject(const std::string& fileName) { - return readObjectFile(fileName); + return readObjectFile(fileName,_options.get()); } osg::Image* Input::readImage(const std::string& fileName) { - if (_options.valid() && !_options->getDatabasePath().empty()) - { - osg::Image* image = readImageFile(_options->getDatabasePath()+'/'+fileName); - if (image) return image; - } - - return readImageFile(fileName); + return readImageFile(fileName,_options.get()); } osg::Node* Input::readNode(const std::string& fileName) { - return readNodeFile(fileName); + return readNodeFile(fileName,_options.get()); } diff --git a/src/osgDB/ReadFile.cpp b/src/osgDB/ReadFile.cpp index 4079b4637..8a086383d 100644 --- a/src/osgDB/ReadFile.cpp +++ b/src/osgDB/ReadFile.cpp @@ -24,42 +24,42 @@ using namespace osg; using namespace osgDB; -Object* osgDB::readObjectFile(const std::string& filename,Registry::CacheHintOptions useObjectCache) +Object* osgDB::readObjectFile(const std::string& filename,const ReaderWriter::Options* options) { - ReaderWriter::ReadResult rr = Registry::instance()->readObject(filename,useObjectCache); + ReaderWriter::ReadResult rr = Registry::instance()->readObject(filename,options); if (rr.validObject()) return rr.takeObject(); if (rr.error()) notify(WARN) << rr.message() << std::endl; return NULL; } -Image* osgDB::readImageFile(const std::string& filename,Registry::CacheHintOptions useObjectCache) +Image* osgDB::readImageFile(const std::string& filename,const ReaderWriter::Options* options) { - ReaderWriter::ReadResult rr = Registry::instance()->readImage(filename,useObjectCache); + ReaderWriter::ReadResult rr = Registry::instance()->readImage(filename,options); if (rr.validImage()) return rr.takeImage(); if (rr.error()) notify(WARN) << rr.message() << std::endl; return NULL; } -HeightField* osgDB::readHeightFieldFile(const std::string& filename,Registry::CacheHintOptions useObjectCache) +HeightField* osgDB::readHeightFieldFile(const std::string& filename,const ReaderWriter::Options* options) { - ReaderWriter::ReadResult rr = Registry::instance()->readHeightField(filename,useObjectCache); + ReaderWriter::ReadResult rr = Registry::instance()->readHeightField(filename,options); if (rr.validHeightField()) return rr.takeHeightField(); if (rr.error()) notify(WARN) << rr.message() << std::endl; return NULL; } -Node* osgDB::readNodeFile(const std::string& filename,Registry::CacheHintOptions useObjectCache) +Node* osgDB::readNodeFile(const std::string& filename,const ReaderWriter::Options* options) { - ReaderWriter::ReadResult rr = Registry::instance()->readNode(filename,useObjectCache); + ReaderWriter::ReadResult rr = Registry::instance()->readNode(filename,options); if (rr.validNode()) return rr.takeNode(); if (rr.error()) notify(WARN) << rr.message() << std::endl; return NULL; } -Node* osgDB::readNodeFiles(std::vector& commandLine,Registry::CacheHintOptions useObjectCache) +Node* osgDB::readNodeFiles(std::vector& commandLine,const ReaderWriter::Options* options) { typedef std::vector NodeList; NodeList nodeList; @@ -73,7 +73,7 @@ Node* osgDB::readNodeFiles(std::vector& commandLine,Registry::Cache if ((*itr)[0]!='-') { // not an option so assume string is a filename. - osg::Node *node = osgDB::readNodeFile( *itr ,useObjectCache ); + osg::Node *node = osgDB::readNodeFile( *itr , options ); if( node != (osg::Node *)0L ) { @@ -108,7 +108,7 @@ Node* osgDB::readNodeFiles(std::vector& commandLine,Registry::Cache } -Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments,Registry::CacheHintOptions useObjectCache) +Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments,const ReaderWriter::Options* options) { typedef std::vector NodeList; @@ -117,13 +117,13 @@ Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments,Registry::CacheHintOpt std::string filename; while (arguments.read("--image",filename)) { - osg::Image* image = readImageFile(filename.c_str(), useObjectCache); + osg::Image* image = readImageFile(filename.c_str(), options); if (image) nodeList.push_back(osg::createGeodeForImage(image)); } while (arguments.read("--dem",filename)) { - osg::HeightField* hf = readHeightFieldFile(filename.c_str(), useObjectCache); + osg::HeightField* hf = readHeightFieldFile(filename.c_str(), options); if (hf) { osg::Geode* geode = new osg::Geode; @@ -138,7 +138,7 @@ Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments,Registry::CacheHintOpt if (!arguments.isOption(pos)) { // not an option so assume string is a filename. - osg::Node *node = osgDB::readNodeFile( arguments[pos], useObjectCache); + osg::Node *node = osgDB::readNodeFile( arguments[pos], options); if(node) { diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 831ccb24a..91325e006 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -138,7 +138,7 @@ Registry::Registry() _createNodeFromImage = false; _openingLibrary = false; - _useObjectCacheHint = CACHE_ARCHIVES; + _useObjectCacheHint = ReaderWriter::Options::CACHE_ARCHIVES; initFilePathLists(); @@ -1185,7 +1185,7 @@ ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor) osg::notify(osg::INFO)<<" archive : "<getUseObjectCacheHint() & ReaderWriter::Options::CACHE_ARCHIVES)) { osgDB::Archive* archive = getFromArchiveCache(fileName); if (archive) return archive; - ReaderWriter::ReadResult result = readImplementation(ReadArchiveFunctor(fileName, status, indexBlockSizeHint, _options.get()),false); + ReaderWriter::ReadResult result = readImplementation(ReadArchiveFunctor(fileName, status, indexBlockSizeHint, options),false); if (result.validArchive()) { addToArchiveCache(fileName,result.getArchive()); @@ -1377,9 +1373,10 @@ ReaderWriter::ReadResult Registry::openArchiveImplementation(const std::string& } -ReaderWriter::ReadResult Registry::readObjectImplementation(const std::string& fileName,CacheHintOptions useObjectCache) +ReaderWriter::ReadResult Registry::readObjectImplementation(const std::string& fileName,const ReaderWriter::Options* options) { - return readImplementation(ReadObjectFunctor(fileName, _options.get()),(useObjectCache&CACHE_OBJECTS)!=0); + return readImplementation(ReadObjectFunctor(fileName, options), + options ? (options->getUseObjectCacheHint()&ReaderWriter::Options::CACHE_OBJECTS): false); } ReaderWriter::WriteResult Registry::writeObjectImplementation(const Object& obj,const std::string& fileName) @@ -1419,9 +1416,10 @@ ReaderWriter::WriteResult Registry::writeObjectImplementation(const Object& obj, -ReaderWriter::ReadResult Registry::readImageImplementation(const std::string& fileName,CacheHintOptions useObjectCache) +ReaderWriter::ReadResult Registry::readImageImplementation(const std::string& fileName,const ReaderWriter::Options* options) { - return readImplementation(ReadImageFunctor(fileName, _options.get()),(useObjectCache&CACHE_IMAGES)!=0); + return readImplementation(ReadImageFunctor(fileName, options), + options ? (options->getUseObjectCacheHint()&ReaderWriter::Options::CACHE_IMAGES): false); } ReaderWriter::WriteResult Registry::writeImageImplementation(const Image& image,const std::string& fileName) @@ -1460,9 +1458,10 @@ ReaderWriter::WriteResult Registry::writeImageImplementation(const Image& image, } -ReaderWriter::ReadResult Registry::readHeightFieldImplementation(const std::string& fileName,CacheHintOptions useObjectCache) +ReaderWriter::ReadResult Registry::readHeightFieldImplementation(const std::string& fileName,const ReaderWriter::Options* options) { - return readImplementation(ReadHeightFieldFunctor(fileName, _options.get()),(useObjectCache&CACHE_HEIGHTFIELDS)!=0); + return readImplementation(ReadHeightFieldFunctor(fileName, options), + options ? (options->getUseObjectCacheHint()&ReaderWriter::Options::CACHE_HEIGHTFIELDS): false); } ReaderWriter::WriteResult Registry::writeHeightFieldImplementation(const HeightField& HeightField,const std::string& fileName) @@ -1501,9 +1500,10 @@ ReaderWriter::WriteResult Registry::writeHeightFieldImplementation(const HeightF } -ReaderWriter::ReadResult Registry::readNodeImplementation(const std::string& fileName,CacheHintOptions useObjectCache) +ReaderWriter::ReadResult Registry::readNodeImplementation(const std::string& fileName,const ReaderWriter::Options* options) { - return readImplementation(ReadNodeFunctor(fileName, _options.get()),(useObjectCache&CACHE_NODES)!=0); + return readImplementation(ReadNodeFunctor(fileName, options), + options ? (options->getUseObjectCacheHint()&ReaderWriter::Options::CACHE_NODES): false); } ReaderWriter::WriteResult Registry::writeNodeImplementation(const Node& node,const std::string& fileName) diff --git a/src/osgPlugins/ive/PagedLOD.cpp b/src/osgPlugins/ive/PagedLOD.cpp index 0d17b9233..7ecbb188d 100644 --- a/src/osgPlugins/ive/PagedLOD.cpp +++ b/src/osgPlugins/ive/PagedLOD.cpp @@ -98,9 +98,9 @@ void PagedLOD::read(DataInputStream* in){ throw Exception("Group::read(): Could not cast this osg::Group to an osg::Node."); - if (getDatabasePath().empty() && in->getOptions()) + if (getDatabasePath().empty() && in->getOptions() && !in->getOptions()->getDatabasePathList().empty()) { - const std::string& path = in->getOptions()->getDatabasePath(); + const std::string& path = in->getOptions()->getDatabasePathList().front(); if (!path.empty()) { setDatabasePath(path); diff --git a/src/osgPlugins/ive/ReaderWriterIVE.cpp b/src/osgPlugins/ive/ReaderWriterIVE.cpp index 56d1c9487..e961ee987 100644 --- a/src/osgPlugins/ive/ReaderWriterIVE.cpp +++ b/src/osgPlugins/ive/ReaderWriterIVE.cpp @@ -38,7 +38,7 @@ class IVEReaderWriter : public ReaderWriter osg::ref_ptr local_opt = const_cast(options); if (!local_opt) local_opt = new Options; - if (local_opt.valid() && local_opt->getDatabasePath().empty()) + if (local_opt.valid() && local_opt->getDatabasePathList().empty()) { local_opt->setDatabasePath(osgDB::getFilePath(fileName)); } diff --git a/src/osgPlugins/net/ReaderWriterNET.cpp b/src/osgPlugins/net/ReaderWriterNET.cpp index 477c46ae8..604b1d9ce 100644 --- a/src/osgPlugins/net/ReaderWriterNET.cpp +++ b/src/osgPlugins/net/ReaderWriterNET.cpp @@ -334,7 +334,7 @@ class NetReader : public osgDB::ReaderWriter osg::ref_ptr local_opt = const_cast(options); if (!local_opt) local_opt = new Options; - if (local_opt.valid() && local_opt->getDatabasePath().empty()) + if (local_opt.valid() && local_opt->getDatabasePathList().empty()) { local_opt->setDatabasePath(osgDB::getFilePath(inFileName)); } diff --git a/src/osgPlugins/obj/ReaderWriterOBJ.cpp b/src/osgPlugins/obj/ReaderWriterOBJ.cpp index eaa1b2b3f..d3b5b41cf 100644 --- a/src/osgPlugins/obj/ReaderWriterOBJ.cpp +++ b/src/osgPlugins/obj/ReaderWriterOBJ.cpp @@ -104,7 +104,18 @@ void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToSt if (!material.map_Kd.empty()) { std::string filename = material.map_Kd; - osg::Image* image = osgDB::readImageFile(filename); + osg::Image* image = 0; + if (!model.getDatabasePath().empty()) + { + // first try with databasr path of parent. + image = osgDB::readImageFile(model.getDatabasePath()+'/'+filename); + } + + if (!image) + { + // if not already set then try the filename as is. + image = osgDB::readImageFile(filename); + } if (image) { osg::Texture2D* texture = new osg::Texture2D(image); @@ -448,9 +459,8 @@ osgDB::ReaderWriter::ReadResult ReaderWriterOBJ::readNode(const std::string& fil if (fin) { - osgDB::PushAndPopDataPath papdp( osgDB::getFilePath(fileName.c_str()) ); - obj::Model model; + model.setDatabasePath(osgDB::getFilePath(fileName.c_str())); model.readOBJ(fin); osg::Node* node = convertModelToSceneGraph(model); diff --git a/src/osgPlugins/obj/obj.h b/src/osgPlugins/obj/obj.h index acfb6f698..7b8d85969 100644 --- a/src/osgPlugins/obj/obj.h +++ b/src/osgPlugins/obj/obj.h @@ -153,6 +153,9 @@ public: Model(): currentElementList(0) {} + void setDatabasePath(const std::string& path) { databasePath = path; } + const std::string& getDatabasePath() const { return databasePath; } + bool readMTL(std::istream& fin); bool readOBJ(std::istream& fin); @@ -173,6 +176,8 @@ public: typedef std::vector< osg::ref_ptr > ElementList; typedef std::map< ElementState,ElementList > ElementStateMap; + + std::string databasePath; MaterialMap materialMap; Vec3Array vertices; diff --git a/src/osgPlugins/osg/PagedLOD.cpp b/src/osgPlugins/osg/PagedLOD.cpp index 1b4edcf28..778c5e93c 100644 --- a/src/osgPlugins/osg/PagedLOD.cpp +++ b/src/osgPlugins/osg/PagedLOD.cpp @@ -28,9 +28,9 @@ bool PagedLOD_readLocalData(Object& obj, Input& fr) PagedLOD& lod = static_cast(obj); - if (lod.getDatabasePath().empty() && fr.getOptions()) + if (lod.getDatabasePath().empty() && fr.getOptions() && !fr.getOptions()->getDatabasePathList().empty()) { - const std::string& path = fr.getOptions()->getDatabasePath(); + const std::string& path = fr.getOptions()->getDatabasePathList().front(); if (!path.empty()) { lod.setDatabasePath(path); diff --git a/src/osgPlugins/osg/ReaderWriterOSG.cpp b/src/osgPlugins/osg/ReaderWriterOSG.cpp index aeb22c8ce..27ebb895c 100644 --- a/src/osgPlugins/osg/ReaderWriterOSG.cpp +++ b/src/osgPlugins/osg/ReaderWriterOSG.cpp @@ -40,7 +40,7 @@ class OSGReaderWriter : public ReaderWriter osg::ref_ptr local_opt = const_cast(opt); if (!local_opt) local_opt = new Options; - if (local_opt.valid() && local_opt->getDatabasePath().empty()) + if (local_opt.valid() && local_opt->getDatabasePathList().empty()) { local_opt->setDatabasePath(osgDB::getFilePath(fileName)); } diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index a9b1ad9e8..6377fdef6 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -66,8 +66,11 @@ osgText::Font* osgText::readFontFile(const std::string& filename) { std::string foundFile = findFontFile(filename); if (foundFile.empty()) return 0; + + osg::ref_ptr options = new osgDB::ReaderWriter::Options; + options->setUseObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS); - osg::Object* object = osgDB::readObjectFile(foundFile, osgDB::Registry::CACHE_OBJECTS); + osg::Object* object = osgDB::readObjectFile(foundFile, options.get()); // if the object is a font then return it. osgText::Font* font = dynamic_cast(object);