Added support for read the various animaton materials/paths from http

This commit is contained in:
Robert Osfield
2009-05-14 13:05:32 +00:00
parent cbd07774f0
commit c72124e449
5 changed files with 298 additions and 193 deletions

View File

@@ -1,6 +1,7 @@
SET(TARGET_SRC
SlideShowConstructor.cpp
ReaderWriterP3D.cpp
ReaderWriterPaths.cpp
PickEventHandler.cpp
AnimationMaterial.cpp
SlideEventHandler.cpp

View File

@@ -94,7 +94,7 @@ public:
_stringKeyMap["F12"]=osgGA::GUIEventAdapter::KEY_F12;
_notifyLevel = osg::INFO;
_notifyLevel = osg::NOTICE;
}
virtual const char* className() const
@@ -1444,7 +1444,7 @@ class OSGDB_EXPORT MyReadFileCallback : public virtual osgDB::ReadFileCallback
osgDB::ReaderWriter::ReadResult readLocal(ObjectType type, const std::string& filename, const osgDB::Options* options)
{
osg::notify(osg::INFO)<<"Trying local file "<<filename<<std::endl;
osg::notify(osg::NOTICE)<<"Trying local file "<<filename<<std::endl;
switch(type)
{
@@ -1465,7 +1465,7 @@ class OSGDB_EXPORT MyReadFileCallback : public virtual osgDB::ReadFileCallback
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;
osg::notify(osg::NOTICE)<<"Trying fileCache "<<filename<<std::endl;
osgDB::ReaderWriter::ReadResult result;
if (fileCache && fileCache->isFileAppropriateForFileCache(filename))
@@ -1511,7 +1511,7 @@ class OSGDB_EXPORT MyReadFileCallback : public virtual osgDB::ReadFileCallback
osgDB::ReaderWriter::ReadResult readServer(ObjectType type, const std::string& filename, const osgDB::Options* options)
{
osg::notify(osg::INFO)<<"Trying server file "<<filename<<std::endl;
osg::notify(osg::NOTICE)<<"Trying server file "<<filename<<std::endl;
osgDB::ReaderWriter::ReadResult result;
osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension("curl");
@@ -1549,6 +1549,7 @@ class OSGDB_EXPORT MyReadFileCallback : public virtual osgDB::ReadFileCallback
fileCache->writeObject(*result.getObject(),filename,options);
break;
case(IMAGE):
result.getImage()->setFileName(filename);
fileCache->writeImage(*result.getImage(),filename,options);
break;
case(HEIGHT_FIELD):
@@ -1607,7 +1608,7 @@ class OSGDB_EXPORT MyReadFileCallback : public virtual osgDB::ReadFileCallback
if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache();
if (fileCache && !fileCache->isFileAppropriateForFileCache(filename)) fileCache = 0;
osg::notify(osg::INFO)<<"reading file "<<filename<<std::endl;
osg::notify(osg::NOTICE)<<"reading file "<<filename<<std::endl;
ObjectCache::iterator itr = _objectCache.find(filename);
if (itr != _objectCache.end())
{
@@ -1659,6 +1660,11 @@ class OSGDB_EXPORT MyReadFileCallback : public virtual osgDB::ReadFileCallback
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);

View File

@@ -0,0 +1,254 @@
/* -*-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::NOTICE)<<"ReaderWriterPaths::readObject("<<file<<")"<<std::endl;
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
osg::notify(osg::NOTICE)<<" 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::NOTICE)<<"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::NOTICE)<<" 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;
osg::notify(osg::NOTICE)<<"rotation_path "<<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<<std::endl;
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

@@ -1253,9 +1253,10 @@ void SlideShowConstructor::addModel(const std::string& filename, const PositionD
if (subgraph) recordOptionsFilePath(_options.get());
}
if (!subgraph) return;
addModel(subgraph, positionData, modelData);
if (subgraph)
{
addModel(subgraph, positionData, modelData);
}
osg::notify(osg::NOTICE)<<"end of SlideShowConstructor::addModel("<<filename<<")"<<std::endl<<std::endl;
@@ -1322,6 +1323,7 @@ void SlideShowConstructor::addModel(osg::Node* subgraph, const PositionData& pos
if (positionData.requiresMaterialAnimation())
subgraph = attachMaterialAnimation(subgraph,positionData);
osg::notify(osg::NOTICE)<<"positionData.rotation "<<positionData.rotation<<std::endl;
// attached any rotation
if (positionData.rotation[0]!=0.0)
@@ -1335,7 +1337,7 @@ void SlideShowConstructor::addModel(osg::Node* subgraph, const PositionData& pos
animation_transform->addChild(subgraph);
osg::notify(osg::INFO)<<"Rotation Matrix "<<animation_transform->getMatrix()<<std::endl;
osg::notify(osg::NOTICE)<<"Rotation Matrix "<<animation_transform->getMatrix()<<std::endl;
subgraph = animation_transform;
}
@@ -1345,7 +1347,7 @@ void SlideShowConstructor::addModel(osg::Node* subgraph, const PositionData& pos
osg::AnimationPathCallback* animation = getAnimationPathCallback(positionData);
if (animation)
{
osg::notify(osg::INFO)<<"Have animation path for model"<<std::endl;
osg::notify(osg::NOTICE)<<"Have animation path for model"<<std::endl;
osg::Vec3 pivot = positionData.absolute_path ? osg::Vec3(0.0f,0.0f,0.0f) : subgraph->getBound().center();
@@ -1575,6 +1577,7 @@ osg::Node* SlideShowConstructor::attachMaterialAnimation(osg::Node* model, const
if (!positionData.animation_material_filename.empty())
{
#if 0
std::string absolute_animation_file_path = osgDB::findDataFile(positionData.animation_material_filename, _options.get());
if (!absolute_animation_file_path.empty())
{
@@ -1585,6 +1588,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())
{
@@ -1630,204 +1638,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, _options.get());
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, _options.get()); // 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)

View File

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