Integrated support for relative paths, and http hosted presentations

This commit is contained in:
Robert Osfield
2009-05-14 13:40:02 +00:00
parent 2dad77a102
commit b80247f385
7 changed files with 811 additions and 301 deletions

View File

@@ -7,6 +7,7 @@ SET(TARGET_SRC
PointsEventHandler.cpp
present3D.cpp
ReaderWriterP3D.cpp
ReaderWriterPaths.cpp
ReadShowFile.cpp
ShowEventHandler.cpp
SlideEventHandler.cpp

View File

@@ -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);

View File

@@ -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)

View 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();
}

View File

@@ -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;
};

View File

@@ -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);
}
}
}
}

View File

@@ -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);
};
}