diff --git a/include/osg/ImageSequence b/include/osg/ImageSequence index 1db9baba7..a8f15dcb3 100644 --- a/include/osg/ImageSequence +++ b/include/osg/ImageSequence @@ -19,6 +19,7 @@ #include #include +#include namespace osg { @@ -48,8 +49,8 @@ class OSG_EXPORT ImageSequence : public ImageStream virtual void setTimeMultiplier(double tm) { _timeMultiplier = tm; } virtual double getTimeMultiplier() const { return _timeMultiplier; } - typedef std::list< osg::ref_ptr > Images; - typedef std::list< std::string > FileNames; + typedef std::vector< osg::ref_ptr > Images; + typedef std::vector< std::string > FileNames; virtual void seek(double time); @@ -75,11 +76,29 @@ class OSG_EXPORT ImageSequence : public ImageStream void addImageFile(const std::string& fileName); + void setImageFile(unsigned int pos, const std::string& fileName); + std::string getImageFile(unsigned int pos) const; + + unsigned int getNumImageFiles() const { return _fileNames.size(); } + FileNames& getFileNames() { return _fileNames; } const FileNames& getFileNames() const { return _fileNames; } void addImage(osg::Image* image); + void setImage(int s,int t,int r, + GLint internalTextureformat, + GLenum pixelFormat,GLenum type, + unsigned char* data, + AllocationMode mode, + int packing=1) { Image::setImage(s,t,r,internalTextureformat, pixelFormat, type, data, mode, packing); } + + void setImage(unsigned int pos, osg::Image* image); + Image* getImage(unsigned int pos); + const Image* getImage(unsigned int pos) const; + + unsigned int getNumImages() const { return _images.size(); } + Images& getImages() { return _images; } const Images& getImages() const { return _images; } @@ -95,10 +114,15 @@ class OSG_EXPORT ImageSequence : public ImageStream virtual ~ImageSequence() {} + virtual void applyLoopingMode(); + void setImageToChild(const osg::Image* image); void computeTimePerImage(); + int imageIndex(double time); + + double _referenceTime; double _timeMultiplier; @@ -107,23 +131,21 @@ class OSG_EXPORT ImageSequence : public ImageStream double _timePerImage; - OpenThreads::Mutex _mutex; + mutable OpenThreads::Mutex _mutex; FileNames _fileNames; - FileNames::iterator _fileNamesIterator; - double _fileNamesIteratorTime; Images _images; - typedef std::pair< std::string, osg::ref_ptr > FileNameImagePair; - typedef std::list< FileNameImagePair > FileNameImageList; - FileNameImageList _filesRequested; + typedef std::set< std::string > FilesRequested; + FilesRequested _filesRequested; + + int _previousAppliedImageIndex; - Images::iterator _imageIterator; - double _imageIteratorTime; bool _seekTimeSet; double _seekTime; + }; diff --git a/include/osg/ImageStream b/include/osg/ImageStream index 5c1b543ce..ff3481d3a 100644 --- a/include/osg/ImageStream +++ b/include/osg/ImageStream @@ -65,7 +65,14 @@ class OSG_EXPORT ImageStream : public Image LOOPING }; - void setLoopingMode(LoopingMode mode) { _loopingMode = mode; applyLoopingMode(); } + void setLoopingMode(LoopingMode mode) + { + if (_loopingMode == mode) return; + + _loopingMode = mode; + applyLoopingMode(); + } + LoopingMode getLoopingMode() const { return _loopingMode; } diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index 1f2d83593..ab32f73dd 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -296,7 +296,7 @@ class OSG_EXPORT NodeVisitor : public virtual Referenced virtual osg::Image* readImageFile(const std::string& fileName) = 0; - virtual void requestImageFile(const std::string& fileName,osg::Object* attachmentPoint, double timeToMergeBy, const FrameStamp* framestamp) = 0; + virtual void requestImageFile(const std::string& fileName,osg::Object* attachmentPoint, int attachmentIndex, double timeToMergeBy, const FrameStamp* framestamp) = 0; protected: virtual ~ImageRequestHandler() {} diff --git a/src/osg/ImageSequence.cpp b/src/osg/ImageSequence.cpp index 3b1011a4f..6ef10da87 100644 --- a/src/osg/ImageSequence.cpp +++ b/src/osg/ImageSequence.cpp @@ -44,15 +44,11 @@ ImageSequence::ImageSequence() _mode = PRE_LOAD_ALL_IMAGES; _length = 1.0; _timePerImage = 1.0; - - _fileNamesIterator = _fileNames.end(); - _fileNamesIteratorTime = 0.0; - - _imageIterator = _images.end(); - _imageIteratorTime = 0.0; _seekTime = 0.0; _seekTimeSet = false; + + _previousAppliedImageIndex = -1; } ImageSequence::ImageSequence(const ImageSequence& is,const CopyOp& copyop): @@ -63,14 +59,10 @@ ImageSequence::ImageSequence(const ImageSequence& is,const CopyOp& copyop): _length(is._length), _timePerImage(is._timePerImage) { - _fileNamesIterator = _fileNames.end(); - _fileNamesIteratorTime = 0.0; - - _imageIterator = _images.end(); - _imageIteratorTime = 0.0; - _seekTime = is._seekTime; _seekTimeSet = is._seekTimeSet; + + _previousAppliedImageIndex = -1; } int ImageSequence::compare(const Image& rhs) const @@ -106,6 +98,12 @@ void ImageSequence::setMode(Mode mode) void ImageSequence::setLength(double length) { + if (length<=0.0) + { + osg::notify(osg::NOTICE)<<"ImageSequence::setLength("< lock(_mutex); + + if (pos>=_fileNames.size()) _fileNames.resize(pos); + _fileNames[pos] = fileName; +} + +std::string ImageSequence::getImageFile(unsigned int pos) const +{ + OpenThreads::ScopedLock lock(_mutex); + return pos<_fileNames.size() ? _fileNames[pos] : std::string(); +} + void ImageSequence::addImageFile(const std::string& fileName) { OpenThreads::ScopedLock lock(_mutex); _fileNames.push_back(fileName); computeTimePerImage(); +} + +void ImageSequence::setImage(unsigned int pos, osg::Image* image) +{ + OpenThreads::ScopedLock lock(_mutex); + + osg::notify(osg::INFO)<<"ImageSequence::setImage("<getFileName()<<")"<=_images.size()) _images.resize(pos+1); - if (_fileNamesIterator==_fileNames.end()) - { - _fileNamesIterator = _fileNames.begin(); - _fileNamesIteratorTime = _referenceTime; - } + _images[pos] = image; + + // prune from file requested list. + FilesRequested::iterator itr = _filesRequested.find(image->getFileName()); + if (itr!=_filesRequested.end()) _filesRequested.erase(itr); +} + +Image* ImageSequence::getImage(unsigned int pos) +{ + OpenThreads::ScopedLock lock(_mutex); + return pos<_images.size() ? _images[pos].get() : 0; +} + +const Image* ImageSequence::getImage(unsigned int pos) const +{ + OpenThreads::ScopedLock lock(_mutex); + return pos<_images.size() ? _images[pos].get() : 0; } void ImageSequence::addImage(osg::Image* image) { + if (image==0) return; + OpenThreads::ScopedLock lock(_mutex); - if (!_filesRequested.empty()) - { - // follows is a mechanism that ensures that requested images - // get merged in the correct time order. - if (_filesRequested.front().first != image->getFileName()) - { - for(FileNameImageList::iterator itr = _filesRequested.begin(); - itr != _filesRequested.end(); - ++itr) - { - if (itr->first == image->getFileName()) - { - osg::notify(osg::NOTICE)<<"inserting image into waiting queue : "<getFileName()<second = image; - return; - } - } - // osg::notify(osg::NOTICE)<<"image not expected : "<getFileName()<getFileName()<second.valid(); - ++itr) - { - // osg::notify(osg::NOTICE)<<" merging previously loaded, but out of order file : "<first<second); - } - - _filesRequested.erase(_filesRequested.begin(), itr); - } - } - else - { - _images.push_back(image); - } + // osg::notify(osg::NOTICE)<<"merging image in order expected : "<getFileName()<get()); + setImageToChild(_images.front().get()); } } @@ -194,6 +186,9 @@ void ImageSequence::setImageToChild(const osg::Image* image) if (image==0) return; + // check to see if data is changing, if not don't apply + if (image->data() == data()) return; + setImage(image->s(),image->t(),image->r(), image->getInternalTextureFormat(), image->getPixelFormat(),image->getDataType(), @@ -202,6 +197,24 @@ void ImageSequence::setImageToChild(const osg::Image* image) image->getPacking()); } +void ImageSequence::applyLoopingMode() +{ +} + +int ImageSequence::imageIndex(double time) +{ + if (getLoopingMode()==LOOPING) + { + double positionRatio = time/_length; + time = (positionRatio - floor(positionRatio))*_length; + } + + if (time<0.0) return 0; + int index = int(time/_timePerImage); + if (index>=_images.size()) return _images.size()-1; + return index; +} + void ImageSequence::update(osg::NodeVisitor* nv) { OpenThreads::ScopedLock lock(_mutex); @@ -224,18 +237,29 @@ void ImageSequence::update(osg::NodeVisitor* nv) time = _seekTime; _referenceTime = fs->getSimulationTime() - time/_timeMultiplier; } - - if (time>_length) + else { - time -= floor(time/_length)*_length; + if (looping) + { + while (time>_length) + { + _referenceTime += _length/_timeMultiplier; + time -= _length; + } + } + else + { + if (time>_length) + { + _referenceTime = fs->getSimulationTime() - _length/_timeMultiplier; + time = _length; + } + } } - - _seekTime = time; -// _seekTimeSet = false; - - FileNames::iterator previous_fileNamesIterator = _fileNamesIterator; - Images::iterator previous_imageIterator = _imageIterator; + _seekTime = time; + _seekTimeSet = false; + bool pruneOldImages = false; @@ -269,133 +293,104 @@ void ImageSequence::update(osg::NodeVisitor* nv) } } + int index = int(time/_timePerImage); + // osg::notify(osg::NOTICE)<<"time= "< (_fileNamesIteratorTime + _timePerImage)) + else { - _fileNamesIteratorTime += _timePerImage; - //osg::notify(osg::NOTICE)<<" _fileNamesIteratorTime = "<<_fileNamesIteratorTime<