diff --git a/applications/present3D/CMakeLists.txt b/applications/present3D/CMakeLists.txt index 62095f815..bfe76afc6 100644 --- a/applications/present3D/CMakeLists.txt +++ b/applications/present3D/CMakeLists.txt @@ -7,6 +7,7 @@ SET(TARGET_SRC PointsEventHandler.cpp present3D.cpp ReaderWriterP3D.cpp + ReaderWriterPaths.cpp ReadShowFile.cpp ShowEventHandler.cpp SlideEventHandler.cpp diff --git a/applications/present3D/PickEventHandler.cpp b/applications/present3D/PickEventHandler.cpp index 16aad1c8e..5bf8b9a42 100644 --- a/applications/present3D/PickEventHandler.cpp +++ b/applications/present3D/PickEventHandler.cpp @@ -130,7 +130,7 @@ void PickEventHandler::doOperation() std::string delimintor(":"); #endif std::string filepath("OSG_FILE_PATH="); - + bool needDeliminator = false; for(osgDB::FilePathList::iterator itr = paths.begin(); itr != paths.end(); @@ -145,7 +145,7 @@ void PickEventHandler::doOperation() std::string binpath("PATH="); char* path = getenv("PATH"); if (path) binpath += path; - + needDeliminator = true; for(osgDB::FilePathList::iterator itr = paths.begin(); itr != paths.end(); @@ -158,10 +158,10 @@ void PickEventHandler::doOperation() putenv( (char*) binpath.c_str()); } -#endif +#endif int result = system(_command.c_str()); - - osg::notify(osg::INFO)<<"system("<<_command<<") result "<getActiveSlide(); @@ -197,7 +197,7 @@ void PickEventHandler::doOperation() { newLayer = 0; } - + osg::notify(osg::NOTICE)<<" jump to "<selectSlide(newSlide, newLayer); diff --git a/applications/present3D/ReaderWriterP3D.cpp b/applications/present3D/ReaderWriterP3D.cpp index b11d6cee0..84b76f34b 100644 --- a/applications/present3D/ReaderWriterP3D.cpp +++ b/applications/present3D/ReaderWriterP3D.cpp @@ -113,7 +113,7 @@ public: virtual ReadResult readNode(std::istream& fin, const Options* options) const; - ReadResult readNode(osgDB::XmlNode::Input& input, const osgDB::ReaderWriter::Options* options) const; + ReadResult readNode(osgDB::XmlNode::Input& input, osgDB::ReaderWriter::Options* options) const; void parseModel(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur) const; @@ -870,10 +870,10 @@ void ReaderWriterP3DXML::parseStereoPair(osgPresentation::SlideShowConstructor& getProperties(cur,imageDataRight); } } - + if (!filenameLeft.empty() && !filenameRight.empty()) constructor.addStereoImagePair(filenameLeft,imageDataLeft, - filenameRight, imageDataRight, + filenameRight, imageDataRight, positionRead ? positionData : constructor.getImagePositionData()); } @@ -1385,6 +1385,312 @@ void ReaderWriterP3DXML::parseSlide (osgPresentation::SlideShowConstructor& cons #include + +struct MyFindFileCallback : public osgDB::FindFileCallback +{ + virtual std::string findDataFile(const std::string& filename, const osgDB::Options* options, osgDB::CaseSensitivity caseSensitivity) + { + osg::notify(osg::NOTICE)<getDatabasePathList() : osgDB::getDataFilePathList(); + + for(osgDB::FilePathList::const_iterator itr = paths.begin(); + itr != paths.end(); + ++itr) + { + const std::string& path = *itr; + std::string newpath = osgDB::concatPaths(path, filename); + if (osgDB::containsServerAddress(path)) + { + osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension("curl"); + osg::notify(osg::NOTICE)<<" file on server "<<*itr<<", try path "<findDataFileImplementation(filename, options, caseSensitivity); + } +}; + +class OSGDB_EXPORT MyReadFileCallback : public virtual osgDB::ReadFileCallback +{ + public: + + osgDB::FilePathList _paths; + + typedef std::map< std::string, osg::ref_ptr > ObjectCache; + + enum ObjectType + { + OBJECT, + IMAGE, + HEIGHT_FIELD, + NODE, + SHADER + }; + + osgDB::ReaderWriter::ReadResult readLocal(ObjectType type, const std::string& filename, const osgDB::Options* options) + { + osg::notify(osg::INFO)<<"Trying local file "<readObjectImplementation(filename,options); + case(IMAGE): return osgDB::Registry::instance()->readImageImplementation(filename,options); + case(HEIGHT_FIELD): return osgDB::Registry::instance()->readHeightFieldImplementation(filename,options); + case(NODE): return osgDB::Registry::instance()->readNodeImplementation(filename,options); + case(SHADER): return osgDB::Registry::instance()->readShaderImplementation(filename,options); + } + return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; + } + + + osgDB::ReaderWriter::ReadResult readFileCache(ObjectType type, const std::string& filename, const osgDB::Options* options) + { + + osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; + if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); + if (!fileCache) return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; + + osg::notify(osg::INFO)<<"Trying fileCache "<isFileAppropriateForFileCache(filename)) + { + if (fileCache->existsInCache(filename)) + { + switch(type) + { + case(OBJECT): + result = fileCache->readObject(filename, 0); + break; + case(IMAGE): + result = fileCache->readImage(filename, 0); + break; + case(HEIGHT_FIELD): + result = fileCache->readHeightField(filename, 0); + break; + case(NODE): + result = fileCache->readNode(filename,0); + break; + case(SHADER): + result = fileCache->readShader(filename, 0); + break; + } + + if (result.success()) + { + osg::notify(osg::INFO)<<" File read from FileCache."<createCacheFileName(filename)<getReaderWriterForExtension("curl"); + if (!rw) return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; + + switch(type) + { + case(OBJECT): + result = rw->readObject(filename,options); + break; + case(IMAGE): + result = rw->readImage(filename,options); + break; + case(HEIGHT_FIELD): + result = rw->readHeightField(filename,options); + break; + case(NODE): + result = rw->readNode(filename,options); + break; + case(SHADER): + result = rw->readShader(filename,options); + break; + } + + if (result.success()) + { + osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; + if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); + + if (fileCache && fileCache->isFileAppropriateForFileCache(filename)) + { + switch(type) + { + case(OBJECT): + fileCache->writeObject(*result.getObject(),filename,options); + break; + case(IMAGE): + result.getImage()->setFileName(filename); + fileCache->writeImage(*result.getImage(),filename,options); + break; + case(HEIGHT_FIELD): + fileCache->writeHeightField(*result.getHeightField(),filename,options); + break; + case(NODE): + fileCache->writeNode(*result.getNode(),filename,options); + break; + case(SHADER): + fileCache->writeShader(*result.getShader(),filename,options); + break; + } + } + + return result; + } + return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; + } + + + osgDB::ReaderWriter::ReadResult read(const osgDB::FilePathList& filePathList, ObjectType type, const std::string& filename, const osgDB::Options* options, bool checkLocalFiles) + { + // go look in http paths + for(osgDB::FilePathList::const_iterator itr = filePathList.begin(); + itr != filePathList.end(); + ++itr) + { + const std::string& path = *itr; + std::string newpath = path.empty() ? filename : osgDB::concatPaths(path, filename); + osgDB::ReaderWriter::ReadResult result; + if (osgDB::containsServerAddress(newpath)) + { + if (checkLocalFiles) result = readFileCache(type, newpath, options); + else result = readServer(type, newpath, options); + } + else if (checkLocalFiles && osgDB::fileExists(newpath)) + { + result = readLocal(type, newpath, options); + } + + if (result.success()) + { + osg::notify(osg::INFO)<<" inserting object into file cache "<setPluginStringData("filename",newpath); + return result; + } + } + return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; + } + + osgDB::ReaderWriter::ReadResult read(ObjectType type, const std::string& filename, const osgDB::Options* options) + { + osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; + if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); + if (fileCache && !fileCache->isFileAppropriateForFileCache(filename)) fileCache = 0; + + osg::notify(osg::INFO)<<"reading file "<second.valid()) + { + osg::notify(osg::INFO)<<"File retrieved from cache, filename="<second.get(); + } + else + { + osg::notify(osg::INFO)<<"File failed to load previously, won't attempt a second time "<getDatabasePathList().empty())) + { + result = read(options->getDatabasePathList(), type, filename, options, checkLocalFiles); + if (result.success()) return result; + } + + result = read(osgDB::Registry::instance()->getDataFilePathList(), type, filename, options, checkLocalFiles); + if (result.success()) return result; + } + + { + bool checkLocalFiles = false; + osgDB::ReaderWriter::ReadResult result = read(_paths, type, filename, options, checkLocalFiles); + if (result.success()) return result; + + if (options && !(options->getDatabasePathList().empty())) + { + result = read(options->getDatabasePathList(), type, filename, options, checkLocalFiles); + if (result.success()) return result; + } + + result = read(osgDB::Registry::instance()->getDataFilePathList(), type, filename, options, checkLocalFiles); + if (result.success()) return result; + } + + _objectCache[filename] = 0; + + return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; + } + + virtual osgDB::ReaderWriter::ReadResult readObject(const std::string& filename, const osgDB::Options* options) + { + return read(OBJECT, filename, options); + } + + virtual osgDB::ReaderWriter::ReadResult readImage(const std::string& filename, const osgDB::Options* options) + { + return read(IMAGE, filename, options); + } + + virtual osgDB::ReaderWriter::ReadResult readHeightField(const std::string& filename, const osgDB::Options* options) + { + return read(HEIGHT_FIELD, filename, options); + } + + virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& filename, const osgDB::Options* options) + { + return read(NODE, filename, options); + } + + virtual osgDB::ReaderWriter::ReadResult readShader(const std::string& filename, const osgDB::Options* options) + { + return read(SHADER, filename, options); + } + + protected: + virtual ~MyReadFileCallback() {} + + ObjectCache _objectCache; +}; + osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const { @@ -1394,11 +1700,17 @@ osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(const std::string& std::string fileName = osgDB::findDataFile( file ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + // code for setting up the database path so that internally referenced file are searched for on relative paths. + osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; + local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName)); + //local_opt->setFindFileCallback(new MyFindFileCallback); + local_opt->setReadFileCallback(new MyReadFileCallback); + osgDB::XmlNode::Input input; input.open(fileName); input.readAllDataIntoBuffer(); - return readNode(input, options); + return readNode(input, local_opt); } osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(std::istream& fin, const Options* options) const @@ -1407,10 +1719,14 @@ osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(std::istream& fin, input.attach(fin); input.readAllDataIntoBuffer(); - return readNode(input, options); + osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; + //local_opt->setFindFileCallback(new MyFindFileCallback); + local_opt->setReadFileCallback(new MyReadFileCallback); + + return readNode(input, local_opt); } -osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(osgDB::XmlNode::Input& input, const osgDB::ReaderWriter::Options* options) const +osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(osgDB::XmlNode::Input& input, osgDB::ReaderWriter::Options* options) const { bool readOnlyHoldingPage = options ? options->getOptionString()=="holding_slide" : false; @@ -1423,6 +1739,9 @@ osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(osgDB::XmlNode::Inp doc->read(input); + + osg::notify(osg::NOTICE)<<"P3D parsing"<write(std::cout); if (doc == NULL ) @@ -1450,12 +1769,72 @@ osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(osgDB::XmlNode::Inp return ReadResult::FILE_NOT_HANDLED; } - osgPresentation::SlideShowConstructor constructor; + osgPresentation::SlideShowConstructor constructor(options); osgDB::FilePathList previousPaths = osgDB::getDataFilePathList(); bool readSlide = false; + + for(osgDB::XmlNode::Children::iterator itr = root->children.begin(); + itr != root->children.end(); + ++itr) + { + osgDB::XmlNode* cur = itr->get(); + + if (cur->name=="env") + { + char* str = strdup(cur->contents.c_str()); + osg::notify(osg::INFO)<<"putenv("<(options->getReadFileCallback()) : 0; + + if (options && !(options->getDatabasePathList().empty())) + { + pathToPresentation = options->getDatabasePathList().front(); + + if (readFileCallback) readFileCallback->_paths.push_front(pathToPresentation); + } + + + for(osgDB::XmlNode::Children::iterator itr = root->children.begin(); + itr != root->children.end(); + ++itr) + { + osgDB::XmlNode* cur = itr->get(); + + if (cur->name == "path") + { + std::string newpath = expandEnvVarsInFileName(cur->contents); + + // now check if an absolue or http path + std::string::size_type colonPos = newpath.find_first_of(':'); + std::string::size_type backslashPos = newpath.find_first_of('/'); + std::string::size_type forwardslashPos = newpath.find_first_of('\\'); + bool relativePath = colonPos == std::string::npos && + backslashPos != 0 && + forwardslashPos != 0; + + if (relativePath && !pathToPresentation.empty()) + { + newpath = osgDB::concatPaths(pathToPresentation, newpath); + osg::notify(osg::NOTICE)<<"relative path = "<contents<<", newpath="< +#include +#include + +#include + +#include +#include + + +/** + * OpenSceneGraph plugin wrapper/converter. + */ +class ReaderWriterPaths : public osgDB::ReaderWriter +{ +public: + ReaderWriterPaths() + { + supportsExtension("material","Material animation Ascii file format"); + supportsExtension("path","Animation path Ascii file format"); + supportsExtension("pivot_path","Animation pivot path Ascii file format"); + supportsExtension("rotation_path","Animation rotation path Ascii file format"); + } + + virtual const char* className() const + { + return "Path Reader/Writer"; + } + + virtual bool acceptsExtension(const std::string& extension) const + { + return osgDB::equalCaseInsensitive(extension,"material") || + osgDB::equalCaseInsensitive(extension,"path") || + osgDB::equalCaseInsensitive(extension,"pivot_path") || + osgDB::equalCaseInsensitive(extension,"rotation_path"); + } + + virtual osgDB::ReaderWriter::ReadResult readObject(const std::string& fileName, const osgDB::Options* options) const; + + virtual osgDB::ReaderWriter::ReadResult readObject(std::istream& fin, const osgDB::Options* options) const; + + virtual osgDB::ReaderWriter::ReadResult read_material(std::istream& fin, const osgDB::Options* options) const; + virtual osgDB::ReaderWriter::ReadResult read_path(std::istream& fin, const osgDB::Options* options) const; + virtual osgDB::ReaderWriter::ReadResult read_pivot_path(std::istream& fin, const osgDB::Options* options) const; + virtual osgDB::ReaderWriter::ReadResult read_rotation_path(std::istream& fin, const osgDB::Options* options) const; +}; + +// Register with Registry to instantiate the above reader/writer. +osgDB::RegisterReaderWriterProxy g_readerWriter_PathsL_Proxy; + +osgDB::ReaderWriter::ReadResult ReaderWriterPaths::readObject(const std::string& file, const osgDB::Options* options) const +{ + + + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + osg::notify(osg::INFO)<<"ReaderWriterPaths::readObject("< local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; + local_opt->setPluginStringData("filename",fileName); + + std::ifstream input(fileName.c_str()); + + return readObject(input, local_opt); +} + +osgDB::ReaderWriter::ReadResult ReaderWriterPaths::readObject(std::istream& fin, const osgDB::Options* options) const +{ + osg::notify(osg::INFO)<<"ReaderWriterPaths::readObject(std::istream& fin"<getPluginStringData("filename"); + + std::string ext = osgDB::getLowerCaseFileExtension(filename); + + osg::notify(osg::INFO)<<" filename found in options: "< animationMaterial = new ss3d::AnimationMaterial; + animationMaterial->read(fin); + + return animationMaterial.get(); +} + +osgDB::ReaderWriter::ReadResult ReaderWriterPaths::read_path(std::istream& fin, const osgDB::Options* options) const +{ + osg::ref_ptr animation = new osg::AnimationPath; + animation->read(fin); + return animation.get(); +} + +osgDB::ReaderWriter::ReadResult ReaderWriterPaths::read_pivot_path(std::istream& fin, const osgDB::Options* options) const +{ + osg::ref_ptr animation = new osg::AnimationPath; + + while (!fin.eof()) + { + double time; + osg::Vec3 pivot; + osg::Vec3 position; + float scale; + osg::Quat rotation; + fin >> time >> pivot.x() >> pivot.y() >> pivot.z() >> position.x() >> position.y() >> position.z() >> rotation.x() >> rotation.y() >> rotation.z() >> rotation.w() >> scale; + if(!fin.eof()) + { + osg::Matrix SR = osg::Matrix::scale(scale,scale,scale)* + osg::Matrixf::rotate(rotation); + + osg::Matrix invSR; + invSR.invert(SR); + + position += (invSR*pivot)*SR; + + animation->insert(time,osg::AnimationPath::ControlPoint(position,rotation,osg::Vec3(scale,scale,scale))); + } + } + + return animation.get(); +} + +struct RotationPathData +{ + RotationPathData(): + time(0.0), + scale(1.0f), + azim(0.0f), + elevation(0.0f) {} + + double time; + osg::Vec3 pivot; + osg::Vec3 position; + float scale; + float azim; + float elevation; + + void addToPath(osg::AnimationPath* animation) const + { + osg::Quat Rx, Rz, rotation; + + Rx.makeRotate(osg::DegreesToRadians(elevation),1.0f,0.0f,0.0f); + Rz.makeRotate(osg::DegreesToRadians(azim),0.0f,0.0f,1.0f); + rotation = Rz * Rx; // note, I believe this is the wrong way round, but I had to put it in this order to fix the Quat properly. + + osg::Matrix SR = osg::Matrix::scale(scale,scale,scale)* + osg::Matrixf::rotate(rotation); + + osg::Matrix invSR; + invSR.invert(SR); + + osg::Vec3 local_position = position + (invSR*pivot)*SR; + + animation->insert(time,osg::AnimationPath::ControlPoint(local_position,rotation,osg::Vec3(scale,scale,scale))); + } + +}; + +osgDB::ReaderWriter::ReadResult ReaderWriterPaths::read_rotation_path(std::istream& fin, const osgDB::Options* options) const +{ + osg::ref_ptr animation = new osg::AnimationPath; + + RotationPathData prevValue; + bool first = true; + while (!fin.eof()) + { + RotationPathData currValue; + fin >> currValue.time >> currValue.pivot.x() >> currValue.pivot.y() >> currValue.pivot.z() >> currValue.position.x() >> currValue.position.y() >> currValue.position.z() >> currValue.azim >> currValue.elevation >> currValue.scale; + + if(!fin.eof()) + { + + if (!first) + { + + unsigned int num = 20; + float dr = 1.0f/(float)num; + float r=dr; + for(unsigned int i=0; + i(_callback.get()); - osgUtil::TransformCallback* tc = dynamic_cast(_callback.get()); - ss3d::AnimationMaterialCallback* amc = dynamic_cast(_callback.get()); - if (apc) - { + osg::AnimationPathCallback* apc = dynamic_cast(_callback.get()); + osgUtil::TransformCallback* tc = dynamic_cast(_callback.get()); + ss3d::AnimationMaterialCallback* amc = dynamic_cast(_callback.get()); + if (apc) + { osg::notify(osg::INFO)<<"apc->setPause("<setPause(pause); - } - if (tc) - { + } + if (tc) + { osg::notify(osg::INFO)<<"tc->setPause("<setPause(pause); - } - if (amc) - { + } + if (amc) + { osg::notify(osg::INFO)<<"amc->setPause("<setPause(pause); - } + } } virtual void reset() { - osg::AnimationPathCallback* apc = dynamic_cast(_callback.get()); - osgUtil::TransformCallback* tc = dynamic_cast(_callback.get()); - ss3d::AnimationMaterialCallback* amc = dynamic_cast(_callback.get()); - if (apc) - { + osg::AnimationPathCallback* apc = dynamic_cast(_callback.get()); + osgUtil::TransformCallback* tc = dynamic_cast(_callback.get()); + ss3d::AnimationMaterialCallback* amc = dynamic_cast(_callback.get()); + if (apc) + { apc->reset(); apc->update(*_node); - } - if (tc) - { - } - if (amc) - { + } + if (tc) + { + } + if (amc) + { amc->reset(); amc->update(*_node); - } + } } @@ -220,7 +220,7 @@ struct LayerAttributesOperator : public ObjectOperator int result = system(itr->c_str()); - osg::notify(osg::INFO)<<"system("<<*itr<<") result "<delta_s(startTick, osg::Timer::instance()->tick()); @@ -266,29 +266,28 @@ public: FindOperatorsVisitor(ActiveOperators::OperatorList& operatorList, osg::NodeVisitor::TraversalMode tm): osg::NodeVisitor(tm), _operatorList(operatorList) {} - - void apply(osg::Node& node) - { - if (node.getStateSet()) process(node.getStateSet()); - if (node.getUpdateCallback()) - { + void apply(osg::Node& node) + { + if (node.getStateSet()) process(node.getStateSet()); + + if (node.getUpdateCallback()) + { _operatorList.insert(new CallbackOperator(&node, node.getUpdateCallback())); - } + } LayerAttributes* la = dynamic_cast(node.getUserData()); if (la) { _operatorList.insert(new LayerAttributesOperator(&node, la)); } - + traverse(node); } void apply(osg::Geode& node) { apply((osg::Node&)node); - for(unsigned int i=0;igetScreenDistance(); _slideHeight = osg::DisplaySettings::instance()->getScreenHeight(); @@ -321,7 +322,7 @@ void SlideShowConstructor::addLayer(bool inheritPreviousLayers, bool defineAsBas // osg::notify(osg::NOTICE)<<" new layer background = "<<_slideBackgroundImageFileName< image = !_slideBackgroundImageFileName.empty() ? - osgDB::readImageFile(_slideBackgroundImageFileName) : + osgDB::readImageFile(_slideBackgroundImageFileName, _options.get()) : 0; // create the background and title.. @@ -635,23 +636,23 @@ class FindImageStreamsVisitor : public osg::NodeVisitor public: FindImageStreamsVisitor(): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} - + virtual void apply(osg::Node& node) { - if (node.getStateSet()) - { - process(node.getStateSet()); - } - traverse(node); - } + if (node.getStateSet()) + { + process(node.getStateSet()); + } + traverse(node); + } virtual void apply(osg::Geode& node) { - if (node.getStateSet()) - { - process(node.getStateSet()); - } - + if (node.getStateSet()) + { + process(node.getStateSet()); + } + for(unsigned int i=0;i imageLeft = osgDB::readImageFile(filenameLeft); - osg::ref_ptr imageRight = (filenameRight==filenameLeft) ? imageLeft.get() : osgDB::readImageFile(filenameRight); + osg::ref_ptr imageLeft = osgDB::readImageFile(filenameLeft, _options.get()); + if (imageLeft.valid()) recordOptionsFilePath(_options.get()); + + osg::ref_ptr imageRight = (filenameRight==filenameLeft) ? imageLeft.get() : osgDB::readImageFile(filenameRight, _options.get()); + if (imageRight.valid()) recordOptionsFilePath(_options.get()); if (!imageLeft && !imageRight) return; @@ -961,7 +966,7 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c pictureLeftStateSet->setMode(GL_BLEND, osg::StateAttribute::ON); } - attachTexMat(pictureLeftStateSet, imageDataLeft, s, t, usedTextureRectangle); + attachTexMat(pictureLeftStateSet, imageDataLeft, s, t, usedTextureRectangle); pictureLeft->addDrawable(pictureLeftQuad); @@ -979,7 +984,7 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c pictureRightStateSet->setMode(GL_BLEND, osg::StateAttribute::ON); } - attachTexMat(pictureRightStateSet, imageDataRight, s, t, usedTextureRectangle); + attachTexMat(pictureRightStateSet, imageDataRight, s, t, usedTextureRectangle); pictureRight->addDrawable(pictureRightQuad); } @@ -1083,7 +1088,7 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam { if (!_currentLayer) addLayer(); - osg::Image* image = osgDB::readImageFile(filename); + osg::Image* image = osgDB::readImageFile(filename, _options.get()); osg::notify(osg::INFO)<<"addInteractiveImage("<getBound().center(), osg::Vec3(positionData.rotation[1],positionData.rotation[2],positionData.rotation[3]), osg::DegreesToRadians(positionData.rotation[0]))); - + animation_transform->addChild(subgraph); - + osg::notify(osg::INFO)<<"Rotation Matrix "<getMatrix()<getBound().center(); - + osg::AnimationPath* path = animation->getAnimationPath(); if (positionData.animation_name=="wheel" && (path->getTimeControlPointMap()).size()>=2) { @@ -1438,11 +1446,17 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position osg::ref_ptr image; if (fileType == osgDB::DIRECTORY) { - image = osgDB::readImageFile(foundFile+".dicom"); + image = osgDB::readImageFile(foundFile+".dicom", _options.get()); } else if (fileType == osgDB::REGULAR_FILE) { - image = osgDB::readImageFile( foundFile ); + image = osgDB::readImageFile( foundFile, _options.get() ); + } + else + { + // not found image, so fallback to plguins/callbacks to find the model. + image = osgDB::readImageFile( filename, _options.get() ); + if (image) recordOptionsFilePath(_options.get() ); } if (!image) return; @@ -1561,7 +1575,8 @@ osg::Node* SlideShowConstructor::attachMaterialAnimation(osg::Node* model, const if (!positionData.animation_material_filename.empty()) { - std::string absolute_animation_file_path = osgDB::findDataFile(positionData.animation_material_filename); +#if 0 + std::string absolute_animation_file_path = osgDB::findDataFile(positionData.animation_material_filename, _options.get()); if (!absolute_animation_file_path.empty()) { std::ifstream animation_filestream(absolute_animation_file_path.c_str()); @@ -1571,6 +1586,11 @@ osg::Node* SlideShowConstructor::attachMaterialAnimation(osg::Node* model, const animationMaterial->read(animation_filestream); } } +#else + osg::ref_ptr object = osgDB::readObjectFile(positionData.animation_material_filename, _options.get()); + animationMaterial = dynamic_cast(object.get()); +#endif + } else if (!positionData.fade.empty()) { @@ -1616,204 +1636,43 @@ osg::Node* SlideShowConstructor::attachMaterialAnimation(osg::Node* model, const return model; } -osg::AnimationPath* SlideShowConstructor::readPivotPath(const std::string& filename) const -{ - std::ifstream in(filename.c_str()); - if (!in.eof()) - { - osg::AnimationPath* animation = new osg::AnimationPath; - - while (!in.eof()) - { - double time; - osg::Vec3 pivot; - osg::Vec3 position; - float scale; - osg::Quat rotation; - in >> time >> pivot.x() >> pivot.y() >> pivot.z() >> position.x() >> position.y() >> position.z() >> rotation.x() >> rotation.y() >> rotation.z() >> rotation.w() >> scale; - if(!in.eof()) - { - osg::Matrix SR = osg::Matrix::scale(scale,scale,scale)* - osg::Matrixf::rotate(rotation); - - osg::Matrix invSR; - invSR.invert(SR); - - position += (invSR*pivot)*SR; - - animation->insert(time,osg::AnimationPath::ControlPoint(position,rotation,osg::Vec3(scale,scale,scale))); - } - } - - return animation; - } - return 0; -} - -struct RotationPathData -{ - RotationPathData(): - time(0.0), - scale(1.0f), - azim(0.0f), - elevation(0.0f) {} - - double time; - osg::Vec3 pivot; - osg::Vec3 position; - float scale; - float azim; - float elevation; - - void addToPath(osg::AnimationPath* animation) const - { - osg::Quat Rx, Rz, rotation; - - Rx.makeRotate(osg::DegreesToRadians(elevation),1.0f,0.0f,0.0f); - Rz.makeRotate(osg::DegreesToRadians(azim),0.0f,0.0f,1.0f); - rotation = Rz * Rx; // note, I believe this is the wrong way round, but I had to put it in this order to fix the Quat properly. - - osg::Matrix SR = osg::Matrix::scale(scale,scale,scale)* - osg::Matrixf::rotate(rotation); - - osg::Matrix invSR; - invSR.invert(SR); - - osg::Vec3 local_position = position + (invSR*pivot)*SR; - - animation->insert(time,osg::AnimationPath::ControlPoint(local_position,rotation,osg::Vec3(scale,scale,scale))); - } - -}; -osg::AnimationPath* SlideShowConstructor::readRotationPath(const std::string& filename) const -{ - std::ifstream in(filename.c_str()); - if (!in.eof()) - { - osg::AnimationPath* animation = new osg::AnimationPath; - - RotationPathData prevValue; - bool first = true; - while (!in.eof()) - { - RotationPathData currValue; - in >> currValue.time >> currValue.pivot.x() >> currValue.pivot.y() >> currValue.pivot.z() >> currValue.position.x() >> currValue.position.y() >> currValue.position.z() >> currValue.azim >> currValue.elevation >> currValue.scale; - if(!in.eof()) - { - - if (!first) - { - - unsigned int num = 20; - float dr = 1.0f/(float)num; - float r=dr; - for(unsigned int i=0; - i object = osgDB::readObjectFile(positionData.path, _options.get()); + osg::AnimationPath* animation = dynamic_cast(object.get()); + if (animation) + { + if (positionData.frame==SlideShowConstructor::SLIDE) { - animation = readPivotPath(absolute_animation_file_path); - } - else if (osgDB::equalCaseInsensitive(extension,"rotation_path")) - { - animation = readRotationPath(absolute_animation_file_path); - } - else if (osgDB::equalCaseInsensitive(extension,"path")) - { - std::ifstream animation_filestream(absolute_animation_file_path.c_str()); - if (!animation_filestream.eof()) + osg::AnimationPath::TimeControlPointMap& controlPoints = animation->getTimeControlPointMap(); + for(osg::AnimationPath::TimeControlPointMap::iterator itr=controlPoints.begin(); + itr!=controlPoints.end(); + ++itr) { - animation = new osg::AnimationPath; - animation->read(animation_filestream); + osg::AnimationPath::ControlPoint& cp = itr->second; + cp.setPosition(convertSlideToModel(cp.getPosition()+positionData.position)); } } - else - { - std::ifstream animation_filestream(absolute_animation_file_path.c_str()); - osgDB::Input fr; - fr.attach(&animation_filestream); + animation->setLoopMode(positionData.path_loop_mode); - static osg::ref_ptr s_path = new osg::AnimationPath; - osg::ref_ptr object = osgDB::readObjectFile(absolute_animation_file_path); // fr.readObjectOfType(*s_path); - object = fr.readObject(); // fr.readObjectOfType(*s_path); - if (object.valid()) - { - animation = dynamic_cast(object.get()); - } - } - - if (animation) - { - if (positionData.frame==SlideShowConstructor::SLIDE) - { - osg::AnimationPath::TimeControlPointMap& controlPoints = animation->getTimeControlPointMap(); - for(osg::AnimationPath::TimeControlPointMap::iterator itr=controlPoints.begin(); - itr!=controlPoints.end(); - ++itr) - { - osg::AnimationPath::ControlPoint& cp = itr->second; - cp.setPosition(convertSlideToModel(cp.getPosition()+positionData.position)); - } - } + osg::AnimationPathCallback* apc = new osg::AnimationPathCallback(animation); + apc->setTimeOffset(positionData.path_time_offset); + apc->setTimeMultiplier(positionData.path_time_multiplier); + apc->setUseInverseMatrix(positionData.inverse_path); - animation->setLoopMode(positionData.path_loop_mode); + osg::notify(osg::INFO)<<"UseInverseMatrix "<setTimeOffset(positionData.path_time_offset); - apc->setTimeMultiplier(positionData.path_time_multiplier); - apc->setUseInverseMatrix(positionData.inverse_path); - - osg::notify(osg::INFO)<<"UseInverseMatrix "<getPluginStringData("filename"); + std::string path = osgDB::getFilePath(filename_used); + if (!path.empty() && _filePathData.valid()) + { + osgDB::FilePathList::iterator itr = std::find(_filePathData->filePathList.begin(),_filePathData->filePathList.end(),path); + if (itr==_filePathData->filePathList.end()) + { + osg::notify(osg::INFO)<<"SlideShowConstructor::recordOptionsFilePath(..) - new path to record path="< _options; + osg::Vec3 _slideOrigin; osg::Vec3 _eyeOrigin; float _slideWidth; @@ -411,6 +410,8 @@ protected: std::string findFileAndRecordPath(const std::string& filename); + void recordOptionsFilePath(const osgDB::Options* options); + }; }