diff --git a/src/osgPlugins/dae/ReaderWriterDAE.cpp b/src/osgPlugins/dae/ReaderWriterDAE.cpp index 4d736d4de..a22bb85f5 100644 --- a/src/osgPlugins/dae/ReaderWriterDAE.cpp +++ b/src/osgPlugins/dae/ReaderWriterDAE.cpp @@ -32,6 +32,71 @@ #define SERIALIZER() OpenThreads::ScopedLock lock(_serializerMutex) +osgDB::ReaderWriter::ReadResult +ReaderWriterDAE::readNode(std::istream& fin, + const osgDB::ReaderWriter::Options* options) const +{ + SERIALIZER(); + + bool bOwnDAE = false; + DAE* pDAE = NULL; + + // Process options + osgDAE::daeReader::Options pluginOptions; + if( options ) + { + pDAE = (DAE*)options->getPluginData("DAE"); + + pluginOptions.precisionHint = options->getPrecisionHint(); + + std::istringstream iss( options->getOptionString() ); + std::string opt; + while (iss >> opt) + { + if( opt == "StrictTransparency") pluginOptions.strictTransparency = true; + else if (opt == "daeTessellateNone") pluginOptions.tessellateMode = osgDAE::daeReader::TESSELLATE_NONE; + else if (opt == "daeTessellatePolygonsAsTriFans") pluginOptions.tessellateMode = osgDAE::daeReader::TESSELLATE_POLYGONS_AS_TRIFAN; + else if (opt == "daeTessellatePolygons") pluginOptions.tessellateMode = osgDAE::daeReader::TESSELLATE_POLYGONS; + else if (opt == "daeUsePredefinedTextureUnits") pluginOptions.usePredefinedTextureUnits = true; + else if (opt == "daeUseSequencedTextureUnits") pluginOptions.usePredefinedTextureUnits = false; + } + } + + if (NULL == pDAE) + { + bOwnDAE = true; + pDAE = new DAE; + } + + std::auto_ptr scopedDae(bOwnDAE ? pDAE : NULL); // Deallocates locally created structure at scope exit + + osgDAE::daeReader daeReader(pDAE, &pluginOptions); + + if ( ! daeReader.convert( fin ) ) + { + OSG_WARN << "Load failed in COLLADA DOM conversion" << std::endl; + return ReadResult::ERROR_IN_READING_FILE; + } + + if ( options ) + { + // Return the document URI + if (options->getPluginData("DAE-DocumentURI")) + *(std::string*)options->getPluginData("DAE-DocumentURI") = std::string("/dev/null"); + // Return some additional information about the document + if (options->getPluginData("DAE-AssetUnitName")) + *(std::string*)options->getPluginData("DAE-AssetUnitName") = daeReader.getAssetUnitName(); + if (options->getPluginData("DAE-AssetUnitMeter")) + *(float*)options->getPluginData("DAE-AssetUnitMeter") = daeReader.getAssetUnitMeter(); + if (options->getPluginData("DAE-AssetUp_axis")) + *(domUpAxisType*)options->getPluginData("DAE-AssetUp_axis") = daeReader.getAssetUpAxis(); + } + + osg::Node* rootNode( daeReader.getRootNode() ); + return rootNode; +} + + osgDB::ReaderWriter::ReadResult ReaderWriterDAE::readNode(const std::string& fname, const osgDB::ReaderWriter::Options* options) const diff --git a/src/osgPlugins/dae/ReaderWriterDAE.h b/src/osgPlugins/dae/ReaderWriterDAE.h index 523c9a1b9..63ee6bd00 100644 --- a/src/osgPlugins/dae/ReaderWriterDAE.h +++ b/src/osgPlugins/dae/ReaderWriterDAE.h @@ -37,9 +37,10 @@ public: const char* className() const { return "COLLADA 1.4.x DAE reader/writer"; } - ReadResult readNode(const std::string&, const Options*) const; + ReadResult readNode(std::istream&, const Options* = NULL) const; + ReadResult readNode(const std::string&, const Options* = NULL) const; - WriteResult writeNode(const osg::Node&, const std::string&, const Options*) const; + WriteResult writeNode(const osg::Node&, const std::string&, const Options* = NULL) const; static std::string ConvertFilePathToColladaCompatibleURI(const std::string& FilePath); static std::string ConvertColladaCompatibleURIToFilePath(const std::string& uri); diff --git a/src/osgPlugins/dae/daeReader.cpp b/src/osgPlugins/dae/daeReader.cpp index 347e025da..e4892b65a 100644 --- a/src/osgPlugins/dae/daeReader.cpp +++ b/src/osgPlugins/dae/daeReader.cpp @@ -51,20 +51,14 @@ daeReader::~daeReader() { } -bool daeReader::convert( const std::string &fileURI ) +bool daeReader::processDocument( const std::string& fileURI) { - // Clear caches - _geometryMap.clear(); - _materialMap.clear(); - _materialMap2.clear(); daeElement *colladaElement; daeInt count, result; - _document = _dae->open(fileURI); - if (!_document) { OSG_WARN << "Load failed in COLLADA DOM" << std::endl; @@ -278,6 +272,43 @@ bool daeReader::convert( const std::string &fileURI ) return true; } +void daeReader::clearCaches () +{ + _geometryMap.clear(); + _materialMap.clear(); + _materialMap2.clear(); +} + +bool daeReader::convert( std::istream& fin ) +{ + clearCaches(); + + // set fileURI to null device + const std::string fileURI("from std::istream"); + + // get the size of the file and rewind + fin.seekg(0, std::ios::end); + std::streampos length = fin.tellg(); + fin.seekg(0, std::ios::beg); + + // use a vector as buffer and read from stream + std::vector buffer(length); + fin.read(&buffer[0], length); + + _document = _dae->openFromMemory(fileURI, buffer.data()); + + return processDocument (fileURI); +} + +bool daeReader::convert( const std::string &fileURI ) +{ + clearCaches(); + + _document = _dae->open(fileURI); + + return processDocument (fileURI); +} + void daeReader::addChild(osg::Group* group, osg::Node* node) { if (dynamic_cast(node)) diff --git a/src/osgPlugins/dae/daeReader.h b/src/osgPlugins/dae/daeReader.h index 7acd498ae..7b28d14d7 100644 --- a/src/osgPlugins/dae/daeReader.h +++ b/src/osgPlugins/dae/daeReader.h @@ -152,6 +152,7 @@ public: daeReader(DAE *dae_, const Options * pluginOptions); virtual ~daeReader(); + bool convert( std::istream &fin ); bool convert( const std::string &fileURI ); osg::Node* getRootNode() { return _rootNode; } @@ -255,6 +256,9 @@ public: typedef std::multimap, std::pair, GLuint> > OldToNewIndexMap; private: + bool processDocument( const std::string& ); + void clearCaches(); + // If the node is a bone then it should be added before any other types of // node, this function makes that happen. static void addChild(osg::Group*, osg::Node*);