Integrated support for relative paths, and http hosted presentations
This commit is contained in:
@@ -7,6 +7,7 @@ SET(TARGET_SRC
|
||||
PointsEventHandler.cpp
|
||||
present3D.cpp
|
||||
ReaderWriterP3D.cpp
|
||||
ReaderWriterPaths.cpp
|
||||
ReadShowFile.cpp
|
||||
ShowEventHandler.cpp
|
||||
SlideEventHandler.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 "<<result<<std::endl;
|
||||
|
||||
osg::notify(osg::INFO)<<"system("<<_command<<") result "<<result<<std::endl;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -186,7 +186,7 @@ void PickEventHandler::doOperation()
|
||||
if (requiresJump())
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Requires jump "<<_relativeJump<<", "<<_slideNum<<", "<<_layerNum<<std::endl;
|
||||
|
||||
|
||||
if (_relativeJump)
|
||||
{
|
||||
int previousSlide = SlideEventHandler::instance()->getActiveSlide();
|
||||
@@ -197,7 +197,7 @@ void PickEventHandler::doOperation()
|
||||
{
|
||||
newLayer = 0;
|
||||
}
|
||||
|
||||
|
||||
osg::notify(osg::NOTICE)<<" jump to "<<newSlide<<", "<<newLayer<<std::endl;
|
||||
|
||||
SlideEventHandler::instance()->selectSlide(newSlide, newLayer);
|
||||
|
||||
@@ -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 <iostream>
|
||||
|
||||
|
||||
struct MyFindFileCallback : public osgDB::FindFileCallback
|
||||
{
|
||||
virtual std::string findDataFile(const std::string& filename, const osgDB::Options* options, osgDB::CaseSensitivity caseSensitivity)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<std::endl<<std::endl<<"find file "<<filename<<std::endl;
|
||||
|
||||
const osgDB::FilePathList& paths = options ? options->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 "<<newpath<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<" we have curl rw= "<<rw<<std::endl;
|
||||
if (rw && rw->fileExists(newpath, options))
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" FOUND on server "<<newpath<<std::endl;
|
||||
return newpath;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(osgDB::fileExists(newpath))
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" FOUND "<<newpath<<std::endl;
|
||||
return newpath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return osgDB::Registry::instance()->findDataFileImplementation(filename, options, caseSensitivity);
|
||||
}
|
||||
};
|
||||
|
||||
class OSGDB_EXPORT MyReadFileCallback : public virtual osgDB::ReadFileCallback
|
||||
{
|
||||
public:
|
||||
|
||||
osgDB::FilePathList _paths;
|
||||
|
||||
typedef std::map< std::string, osg::ref_ptr<osg::Object> > 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 "<<filename<<std::endl;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case(OBJECT): return osgDB::Registry::instance()->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 "<<filename<<std::endl;
|
||||
|
||||
osgDB::ReaderWriter::ReadResult result;
|
||||
if (fileCache && 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."<<std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE)<<" File in FileCache, but not successfully read"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::INFO)<<" File does not exist in FileCache: "<<fileCache->createCacheFileName(filename)<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
}
|
||||
|
||||
osgDB::ReaderWriter::ReadResult readServer(ObjectType type, const std::string& filename, const osgDB::Options* options)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Trying server file "<<filename<<std::endl;
|
||||
|
||||
osgDB::ReaderWriter::ReadResult result;
|
||||
osgDB::ReaderWriter* rw = osgDB::Registry::instance()->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 "<<filename<<", "<<result.getObject()<<std::endl;
|
||||
_objectCache[filename] = result.getObject();
|
||||
|
||||
options->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 "<<filename<<std::endl;
|
||||
ObjectCache::iterator itr = _objectCache.find(filename);
|
||||
if (itr != _objectCache.end())
|
||||
{
|
||||
// object is in cache, just retrieve it.
|
||||
if (itr->second.valid())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"File retrieved from cache, filename="<<filename<<std::endl;
|
||||
return itr->second.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::INFO)<<"File failed to load previously, won't attempt a second time "<<filename<<std::endl;
|
||||
return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
bool checkLocalFiles = true;
|
||||
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;
|
||||
}
|
||||
|
||||
{
|
||||
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<osgDB::ReaderWriter::Options> local_opt = options ? static_cast<osgDB::ReaderWriter::Options*>(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<osgDB::ReaderWriter::Options> local_opt = options ? static_cast<osgDB::ReaderWriter::Options*>(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"<<std::endl;
|
||||
|
||||
// doc->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("<<str<<")"<<std::endl;
|
||||
putenv(str);
|
||||
}
|
||||
}
|
||||
|
||||
std::string pathToPresentation;
|
||||
MyReadFileCallback* readFileCallback = options ? dynamic_cast<MyReadFileCallback*>(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 = "<<cur->contents<<", newpath="<<newpath<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"absolute path = "<<cur->contents<<", newpath="<<newpath<<std::endl;
|
||||
}
|
||||
|
||||
if (readFileCallback) readFileCallback->_paths.push_back(newpath);
|
||||
else options->getDatabasePathList().push_back(newpath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(osgDB::XmlNode::Children::iterator itr = root->children.begin();
|
||||
itr != root->children.end();
|
||||
++itr)
|
||||
|
||||
252
applications/present3D/ReaderWriterPaths.cpp
Normal file
252
applications/present3D/ReaderWriterPaths.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
|
||||
*
|
||||
* This software is open source and may be redistributed and/or modified under
|
||||
* the terms of the GNU General Public License (GPL) version 2.0.
|
||||
* The full license is in LICENSE.txt file included with this distribution,.
|
||||
*
|
||||
* This software 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. See the
|
||||
* include LICENSE.txt for more details.
|
||||
*/
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osg/io_utils>
|
||||
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include <osgWidget/PdfReader>
|
||||
|
||||
#include "SlideShowConstructor.h"
|
||||
#include "AnimationMaterial.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <osgDB/XmlParser>
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
/**
|
||||
* 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<ReaderWriterPaths> 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("<<file<<")"<<std::endl;
|
||||
|
||||
std::string fileName = osgDB::findDataFile( file, options );
|
||||
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
osg::notify(osg::INFO)<<" Found path file :"<<fileName<<std::endl;
|
||||
|
||||
// code for setting up the database path so that internally referenced file are searched for on relative paths.
|
||||
osg::ref_ptr<osgDB::ReaderWriter::Options> local_opt = options ? static_cast<osgDB::ReaderWriter::Options*>(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"<<std::endl;
|
||||
|
||||
if (!options) return ReadResult::FILE_NOT_HANDLED;
|
||||
if (!fin) return ReadResult::ERROR_IN_READING_FILE;
|
||||
|
||||
|
||||
std::string filename = options->getPluginStringData("filename");
|
||||
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(filename);
|
||||
|
||||
osg::notify(osg::INFO)<<" filename found in options: "<<filename<<" extension="<<ext<<std::endl;
|
||||
|
||||
|
||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
|
||||
if (ext=="path") return read_path(fin, options);
|
||||
else if (ext=="material") return read_material(fin, options);
|
||||
else if (ext=="pivot_path") return read_pivot_path(fin, options);
|
||||
else if (ext=="rotation_path") return read_rotation_path(fin, options);
|
||||
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
|
||||
osgDB::ReaderWriter::ReadResult ReaderWriterPaths::read_material(std::istream& fin, const osgDB::Options* options) const
|
||||
{
|
||||
osg::ref_ptr<ss3d::AnimationMaterial> 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<osg::AnimationPath> 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<osg::AnimationPath> 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<osg::AnimationPath> 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<num;
|
||||
++i, r+=dr)
|
||||
{
|
||||
RotationPathData localValue;
|
||||
localValue.time = currValue.time *r + prevValue.time * (1.0f-r);
|
||||
localValue.pivot = currValue.pivot *r + prevValue.pivot * (1.0f-r);
|
||||
localValue.position = currValue.position *r + prevValue.position * (1.0f-r);
|
||||
localValue.scale = currValue.scale *r + prevValue.scale * (1.0f-r);
|
||||
localValue.azim = currValue.azim *r + prevValue.azim * (1.0f-r);
|
||||
localValue.elevation = currValue.elevation *r + prevValue.elevation * (1.0f-r);
|
||||
|
||||
localValue.addToPath(animation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currValue.addToPath(animation);
|
||||
}
|
||||
prevValue = currValue;
|
||||
first = false;
|
||||
}
|
||||
|
||||
}
|
||||
osg::notify(osg::NOTICE)<<"finished"<<std::endl;
|
||||
|
||||
return animation.get();
|
||||
}
|
||||
@@ -136,44 +136,44 @@ struct CallbackOperator : public ObjectOperator
|
||||
|
||||
virtual void setPause(bool pause)
|
||||
{
|
||||
osg::AnimationPathCallback* apc = dynamic_cast<osg::AnimationPathCallback*>(_callback.get());
|
||||
osgUtil::TransformCallback* tc = dynamic_cast<osgUtil::TransformCallback*>(_callback.get());
|
||||
ss3d::AnimationMaterialCallback* amc = dynamic_cast<ss3d::AnimationMaterialCallback*>(_callback.get());
|
||||
if (apc)
|
||||
{
|
||||
osg::AnimationPathCallback* apc = dynamic_cast<osg::AnimationPathCallback*>(_callback.get());
|
||||
osgUtil::TransformCallback* tc = dynamic_cast<osgUtil::TransformCallback*>(_callback.get());
|
||||
ss3d::AnimationMaterialCallback* amc = dynamic_cast<ss3d::AnimationMaterialCallback*>(_callback.get());
|
||||
if (apc)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"apc->setPause("<<pause<<")"<<std::endl;
|
||||
apc->setPause(pause);
|
||||
}
|
||||
if (tc)
|
||||
{
|
||||
}
|
||||
if (tc)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"tc->setPause("<<pause<<")"<<std::endl;
|
||||
tc->setPause(pause);
|
||||
}
|
||||
if (amc)
|
||||
{
|
||||
}
|
||||
if (amc)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"amc->setPause("<<pause<<")"<<std::endl;
|
||||
amc->setPause(pause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void reset()
|
||||
{
|
||||
osg::AnimationPathCallback* apc = dynamic_cast<osg::AnimationPathCallback*>(_callback.get());
|
||||
osgUtil::TransformCallback* tc = dynamic_cast<osgUtil::TransformCallback*>(_callback.get());
|
||||
ss3d::AnimationMaterialCallback* amc = dynamic_cast<ss3d::AnimationMaterialCallback*>(_callback.get());
|
||||
if (apc)
|
||||
{
|
||||
osg::AnimationPathCallback* apc = dynamic_cast<osg::AnimationPathCallback*>(_callback.get());
|
||||
osgUtil::TransformCallback* tc = dynamic_cast<osgUtil::TransformCallback*>(_callback.get());
|
||||
ss3d::AnimationMaterialCallback* amc = dynamic_cast<ss3d::AnimationMaterialCallback*>(_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 "<<result<<std::endl;
|
||||
osg::notify(osg::INFO)<<"system("<<*itr<<") result "<<result<<std::endl;
|
||||
|
||||
double timeForRun = osg::Timer::instance()->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<LayerAttributes*>(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;i<node.getNumDrawables();++i)
|
||||
{
|
||||
osg::Drawable* drawable = node.getDrawable(i);
|
||||
@@ -308,8 +307,8 @@ public:
|
||||
_operatorList.insert(new ImageStreamOperator(imageStream));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ActiveOperators::OperatorList& _operatorList;
|
||||
};
|
||||
|
||||
|
||||
@@ -86,7 +86,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
SlideShowConstructor::SlideShowConstructor()
|
||||
SlideShowConstructor::SlideShowConstructor(const osgDB::ReaderWriter::Options* options):
|
||||
_options(options)
|
||||
{
|
||||
_slideDistance = osg::DisplaySettings::instance()->getScreenDistance();
|
||||
_slideHeight = osg::DisplaySettings::instance()->getScreenHeight();
|
||||
@@ -321,7 +322,7 @@ void SlideShowConstructor::addLayer(bool inheritPreviousLayers, bool defineAsBas
|
||||
// osg::notify(osg::NOTICE)<<" new layer background = "<<_slideBackgroundImageFileName<<std::endl;
|
||||
|
||||
osg::ref_ptr<osg::Image> 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<node.getNumDrawables();++i)
|
||||
{
|
||||
osg::Drawable* drawable = node.getDrawable(i);
|
||||
@@ -680,7 +681,7 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
void SlideShowConstructor::findImageStreamsAndAddCallbacks(osg::Node* node)
|
||||
@@ -774,8 +775,9 @@ void SlideShowConstructor::addImage(const std::string& filename, const PositionD
|
||||
{
|
||||
if (!_currentLayer) addLayer();
|
||||
|
||||
osg::Image* image = osgDB::readImageFile(filename);
|
||||
|
||||
osg::Image* image = osgDB::readImageFile(filename, _options.get());
|
||||
if (image) recordOptionsFilePath(_options.get());
|
||||
|
||||
if (!image) return;
|
||||
|
||||
bool isImageTranslucent = false;
|
||||
@@ -888,8 +890,11 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c
|
||||
if (!_currentLayer) addLayer();
|
||||
|
||||
|
||||
osg::ref_ptr<osg::Image> imageLeft = osgDB::readImageFile(filenameLeft);
|
||||
osg::ref_ptr<osg::Image> imageRight = (filenameRight==filenameLeft) ? imageLeft.get() : osgDB::readImageFile(filenameRight);
|
||||
osg::ref_ptr<osg::Image> imageLeft = osgDB::readImageFile(filenameLeft, _options.get());
|
||||
if (imageLeft.valid()) recordOptionsFilePath(_options.get());
|
||||
|
||||
osg::ref_ptr<osg::Image> 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("<<filename<<") "<<image<<std::endl;
|
||||
|
||||
@@ -1202,7 +1207,7 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam
|
||||
|
||||
std::string SlideShowConstructor::findFileAndRecordPath(const std::string& filename)
|
||||
{
|
||||
std::string foundFile = osgDB::findDataFile(filename);
|
||||
std::string foundFile = osgDB::findDataFile(filename, _options.get());
|
||||
if (foundFile.empty()) return foundFile;
|
||||
|
||||
osg::notify(osg::INFO)<<"foundFile "<<foundFile<<std::endl;
|
||||
@@ -1224,6 +1229,8 @@ std::string SlideShowConstructor::findFileAndRecordPath(const std::string& filen
|
||||
|
||||
void SlideShowConstructor::addModel(const std::string& filename, const PositionData& positionData, const ModelData& modelData)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"SlideShowConstructor::addModel("<<filename<<")"<<std::endl;
|
||||
|
||||
osg::Node* subgraph = 0;
|
||||
|
||||
if (filename=="sphere")
|
||||
@@ -1242,15 +1249,17 @@ void SlideShowConstructor::addModel(const std::string& filename, const PositionD
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string foundFile = findFileAndRecordPath(filename);
|
||||
if (foundFile.empty()) return;
|
||||
|
||||
subgraph = osgDB::readNodeFile(foundFile);
|
||||
subgraph = osgDB::readNodeFile(filename, _options.get());
|
||||
if (subgraph) recordOptionsFilePath(_options.get());
|
||||
}
|
||||
|
||||
if (!subgraph) return;
|
||||
if (subgraph)
|
||||
{
|
||||
addModel(subgraph, positionData, modelData);
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)<<"end of SlideShowConstructor::addModel("<<filename<<")"<<std::endl<<std::endl;
|
||||
|
||||
addModel(subgraph, positionData, modelData);
|
||||
}
|
||||
|
||||
void SlideShowConstructor::addModel(osg::Node* subgraph, const PositionData& positionData, const ModelData& modelData)
|
||||
@@ -1314,7 +1323,6 @@ void SlideShowConstructor::addModel(osg::Node* subgraph, const PositionData& pos
|
||||
if (positionData.requiresMaterialAnimation())
|
||||
subgraph = attachMaterialAnimation(subgraph,positionData);
|
||||
|
||||
|
||||
// attached any rotation
|
||||
if (positionData.rotation[0]!=0.0)
|
||||
{
|
||||
@@ -1324,9 +1332,9 @@ void SlideShowConstructor::addModel(osg::Node* subgraph, const PositionData& pos
|
||||
new osgUtil::TransformCallback(subgraph->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 "<<animation_transform->getMatrix()<<std::endl;
|
||||
|
||||
subgraph = animation_transform;
|
||||
@@ -1338,9 +1346,9 @@ void SlideShowConstructor::addModel(osg::Node* subgraph, const PositionData& pos
|
||||
if (animation)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Have animation path for model"<<std::endl;
|
||||
|
||||
|
||||
osg::Vec3 pivot = positionData.absolute_path ? osg::Vec3(0.0f,0.0f,0.0f) : subgraph->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<osg::Image> 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<osg::Object> object = osgDB::readObjectFile(positionData.animation_material_filename, _options.get());
|
||||
animationMaterial = dynamic_cast<ss3d::AnimationMaterial*>(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<num;
|
||||
++i, r+=dr)
|
||||
{
|
||||
RotationPathData localValue;
|
||||
localValue.time = currValue.time *r + prevValue.time * (1.0f-r);
|
||||
localValue.pivot = currValue.pivot *r + prevValue.pivot * (1.0f-r);
|
||||
localValue.position = currValue.position *r + prevValue.position * (1.0f-r);
|
||||
localValue.scale = currValue.scale *r + prevValue.scale * (1.0f-r);
|
||||
localValue.azim = currValue.azim *r + prevValue.azim * (1.0f-r);
|
||||
localValue.elevation = currValue.elevation *r + prevValue.elevation * (1.0f-r);
|
||||
|
||||
localValue.addToPath(animation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currValue.addToPath(animation);
|
||||
}
|
||||
prevValue = currValue;
|
||||
first = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return animation;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
osg::AnimationPathCallback* SlideShowConstructor::getAnimationPathCallback(const PositionData& positionData)
|
||||
{
|
||||
if (!positionData.path.empty())
|
||||
{
|
||||
std::string absolute_animation_file_path = osgDB::findDataFile(positionData.path);
|
||||
if (!absolute_animation_file_path.empty())
|
||||
{
|
||||
|
||||
osg::AnimationPath* animation = 0;
|
||||
|
||||
std::string extension = osgDB::getLowerCaseFileExtension(absolute_animation_file_path);
|
||||
if (osgDB::equalCaseInsensitive(extension,"pivot_path"))
|
||||
osg::ref_ptr<osg::Object> object = osgDB::readObjectFile(positionData.path, _options.get());
|
||||
osg::AnimationPath* animation = dynamic_cast<osg::AnimationPath*>(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<osg::AnimationPath> s_path = new osg::AnimationPath;
|
||||
osg::ref_ptr<osg::Object> object = osgDB::readObjectFile(absolute_animation_file_path); // fr.readObjectOfType(*s_path);
|
||||
object = fr.readObject(); // fr.readObjectOfType(*s_path);
|
||||
if (object.valid())
|
||||
{
|
||||
animation = dynamic_cast<osg::AnimationPath*>(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 "<<positionData.inverse_path<<std::endl;
|
||||
|
||||
osg::AnimationPathCallback* apc = new osg::AnimationPathCallback(animation);
|
||||
apc->setTimeOffset(positionData.path_time_offset);
|
||||
apc->setTimeMultiplier(positionData.path_time_multiplier);
|
||||
apc->setUseInverseMatrix(positionData.inverse_path);
|
||||
|
||||
osg::notify(osg::INFO)<<"UseInverseMatrix "<<positionData.inverse_path<<std::endl;
|
||||
return apc;
|
||||
|
||||
return apc;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
osg::Vec3 SlideShowConstructor::computePositionInModelCoords(const PositionData& positionData) const
|
||||
{
|
||||
if (positionData.frame==SLIDE)
|
||||
@@ -1851,3 +1710,22 @@ void SlideShowConstructor::updatePositionFromInModelCoords(const osg::Vec3& vert
|
||||
positionData.position = vertex;
|
||||
}
|
||||
}
|
||||
|
||||
void SlideShowConstructor::recordOptionsFilePath(const osgDB::Options* options)
|
||||
{
|
||||
if (options)
|
||||
{
|
||||
std::string filename_used = _options->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="<<path<<" filename_used="<<filename_used<<std::endl;
|
||||
_filePathData->filePathList.push_front(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
|
||||
struct PositionData
|
||||
{
|
||||
PositionData():
|
||||
PositionData():
|
||||
frame(SlideShowConstructor::SLIDE),
|
||||
position(0.0f,1.0f,0.0f),
|
||||
//position(0.5f,0.5f,0.0f),
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
rotate(0.0f,0.0f,0.0f,1.0f),
|
||||
rotation(0.0f,0.0f,1.0f,0.0f),
|
||||
absolute_path(false),
|
||||
inverse_path(false),
|
||||
inverse_path(false),
|
||||
path_time_offset(0.0),
|
||||
path_time_multiplier(1.0f),
|
||||
path_loop_mode(osg::AnimationPath::NO_LOOPING),
|
||||
@@ -155,23 +155,23 @@ public:
|
||||
return !animation_material_filename.empty() || !fade.empty();
|
||||
}
|
||||
|
||||
CoordinateFrame frame;
|
||||
osg::Vec3 position;
|
||||
osg::Vec3 scale;
|
||||
osg::Vec4 rotate;
|
||||
osg::Vec4 rotation;
|
||||
CoordinateFrame frame;
|
||||
osg::Vec3 position;
|
||||
osg::Vec3 scale;
|
||||
osg::Vec4 rotate;
|
||||
osg::Vec4 rotation;
|
||||
std::string animation_name;
|
||||
bool absolute_path;
|
||||
bool inverse_path;
|
||||
bool absolute_path;
|
||||
bool inverse_path;
|
||||
double path_time_offset;
|
||||
double path_time_multiplier;
|
||||
osg::AnimationPath::LoopMode path_loop_mode;
|
||||
std::string path;
|
||||
std::string path;
|
||||
double animation_material_time_offset;
|
||||
double animation_material_time_multiplier;
|
||||
ss3d::AnimationMaterial::LoopMode animation_material_loop_mode;
|
||||
std::string animation_material_filename;
|
||||
std::string fade;
|
||||
std::string animation_material_filename;
|
||||
std::string fade;
|
||||
};
|
||||
|
||||
struct ModelData
|
||||
@@ -206,28 +206,28 @@ public:
|
||||
|
||||
struct FontData
|
||||
{
|
||||
FontData():
|
||||
font("fonts/arial.ttf"),
|
||||
layout(osgText::Text::LEFT_TO_RIGHT),
|
||||
alignment(osgText::Text::LEFT_BASE_LINE),
|
||||
axisAlignment(osgText::Text::XZ_PLANE),
|
||||
characterSize(0.04f),
|
||||
maximumHeight(1.0f),
|
||||
maximumWidth(1.0f),
|
||||
color(1.0f,1.0f,1.0f,1.0f) {}
|
||||
|
||||
std::string font;
|
||||
osgText::Text::Layout layout;
|
||||
osgText::Text::AlignmentType alignment;
|
||||
osgText::Text::AxisAlignment axisAlignment;
|
||||
float characterSize;
|
||||
float maximumHeight;
|
||||
float maximumWidth;
|
||||
osg::Vec4 color;
|
||||
FontData():
|
||||
font("fonts/arial.ttf"),
|
||||
layout(osgText::Text::LEFT_TO_RIGHT),
|
||||
alignment(osgText::Text::LEFT_BASE_LINE),
|
||||
axisAlignment(osgText::Text::XZ_PLANE),
|
||||
characterSize(0.04f),
|
||||
maximumHeight(1.0f),
|
||||
maximumWidth(1.0f),
|
||||
color(1.0f,1.0f,1.0f,1.0f) {}
|
||||
|
||||
std::string font;
|
||||
osgText::Text::Layout layout;
|
||||
osgText::Text::AlignmentType alignment;
|
||||
osgText::Text::AxisAlignment axisAlignment;
|
||||
float characterSize;
|
||||
float maximumHeight;
|
||||
float maximumWidth;
|
||||
osg::Vec4 color;
|
||||
};
|
||||
|
||||
|
||||
SlideShowConstructor();
|
||||
SlideShowConstructor(const osgDB::ReaderWriter::Options* options);
|
||||
|
||||
void createPresentation();
|
||||
|
||||
@@ -346,9 +346,6 @@ protected:
|
||||
osg::Vec3 convertSlideToModel(const osg::Vec3& position) const;
|
||||
osg::Vec3 convertModelToSlide(const osg::Vec3& position) const;
|
||||
|
||||
osg::AnimationPath* readPivotPath(const std::string& filename) const;
|
||||
osg::AnimationPath* readRotationPath(const std::string& filename) const;
|
||||
|
||||
osg::AnimationPathCallback* getAnimationPathCallback(const PositionData& positionData);
|
||||
|
||||
osg::Node* attachMaterialAnimation(osg::Node* model, const PositionData& positionData);
|
||||
@@ -361,6 +358,8 @@ protected:
|
||||
return stateset;
|
||||
}
|
||||
|
||||
osg::ref_ptr<const osgDB::ReaderWriter::Options> _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);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user