root/OpenSceneGraph/trunk/src/osg/ImageSequence.cpp @ 13191

Revision 13191, 11.8 kB (checked in by robert, 2 days ago)

From Alberto Luaces,"the current code uses the preprocessor for generating the plugin path in
a way that when CMAKE_INSTALL_PREFIX contains something along the lines
of

/usr/x86_64-linux-gnu/

it gets substituted as

/usr/x86_64-1-gnu/

that is, the string is preprocessed again, thereby making changes to
anything that matches any defined symbol, as "linux" in this example
(https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=763816).

Quoting that path directly in CMake scripts solves that problem.
"

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <OpenThreads/ScopedLock>
15#include <osg/ImageSequence>
16#include <osg/Notify>
17#include <osg/Camera>
18#include <osg/NodeVisitor>
19#include <osg/Texture2D>
20
21#include <math.h>
22
23using namespace osg;
24
25ImageSequence::ImageData::ImageData()
26{
27}
28
29ImageSequence::ImageData::ImageData(const ImageData& id):
30    _filename(id._filename),
31    _image(id._image),
32    _imageRequest(id._imageRequest)
33{
34}
35
36ImageSequence::ImageData& ImageSequence::ImageData::operator = (const ImageSequence::ImageData& rhs)
37{
38    if (&rhs!=this)
39    {
40        _filename = rhs._filename;
41        _image = rhs._image;
42        _imageRequest = rhs._imageRequest;
43    }
44    return *this;
45}
46
47ImageSequence::ImageSequence()
48{
49    _referenceTime = DBL_MAX;
50    _timeMultiplier = 1.0;
51
52    _mode = PRE_LOAD_ALL_IMAGES;
53    _length = 1.0;
54    _timePerImage = 1.0;
55
56    _seekTime = 0.0;
57    _seekTimeSet = false;
58
59    _previousAppliedImageIndex = -1;
60}
61
62ImageSequence::ImageSequence(const ImageSequence& is,const CopyOp& copyop):
63    osg::ImageStream(is,copyop),
64    _referenceTime(is._referenceTime),
65    _timeMultiplier(is._timeMultiplier),
66    _mode(is._mode),
67    _length(is._length),
68    _timePerImage(is._timePerImage)
69{
70    _seekTime = is._seekTime;
71    _seekTimeSet = is._seekTimeSet;
72
73    _previousAppliedImageIndex = -1;
74}
75
76int ImageSequence::compare(const Image& rhs) const
77{
78    return ImageStream::compare(rhs);
79}
80
81void ImageSequence::seek(double time)
82{
83    _seekTime = time;
84    _seekTimeSet = true;
85}
86
87void ImageSequence::play()
88{
89    _status=PLAYING;
90}
91
92void ImageSequence::pause()
93{
94    _status=PAUSED;
95}
96
97void ImageSequence::rewind()
98{
99    seek(0.0f);
100}
101
102void ImageSequence::setMode(Mode mode)
103{
104    _mode = mode;
105}
106
107void ImageSequence::setLength(double length)
108{
109    if (length<=0.0)
110    {
111        OSG_NOTICE<<"ImageSequence::setLength("<<length<<") invalid length value, must be greater than 0."<<std::endl;
112        return;
113    }
114
115    _length = length;
116    computeTimePerImage();
117}
118
119void ImageSequence::computeTimePerImage()
120{
121    if (!_imageDataList.empty()) _timePerImage = _length / double(_imageDataList.size());
122    else _timePerImage = _length;
123}
124
125void ImageSequence::setImageFile(unsigned int pos, const std::string& fileName)
126{
127    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
128
129    if (pos>=_imageDataList.size()) _imageDataList.resize(pos);
130    _imageDataList[pos]._filename = fileName;
131}
132
133std::string ImageSequence::getImageFile(unsigned int pos) const
134{
135    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
136    return pos<_imageDataList.size() ? _imageDataList[pos]._filename : std::string();
137}
138
139void ImageSequence::addImageFile(const std::string& fileName)
140{
141    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
142    _imageDataList.push_back(ImageData());
143    _imageDataList.back()._filename = fileName;
144    computeTimePerImage();
145}
146
147void ImageSequence::setImage(unsigned int pos, osg::Image* image)
148{
149    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
150
151    if (pos>=_imageDataList.size()) _imageDataList.resize(pos+1);
152
153    _imageDataList[pos]._image = image;
154    _imageDataList[pos]._filename = image->getFileName();
155}
156
157Image* ImageSequence::getImage(unsigned int pos)
158{
159    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
160    return pos<_imageDataList.size() ? _imageDataList[pos]._image.get() : 0;
161}
162
163const Image* ImageSequence::getImage(unsigned int pos) const
164{
165    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
166    return pos<_imageDataList.size() ? _imageDataList[pos]._image.get() : 0;
167}
168
169void ImageSequence::addImage(osg::Image* image)
170{
171    if (image==0) return;
172
173    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
174
175    // OSG_NOTICE<<"merging image in order expected : "<<image->getFileName()<<std::endl;
176    _imageDataList.push_back(ImageData());
177    _imageDataList.back()._image = image;
178
179    computeTimePerImage();
180
181    if (data()==0)
182    {
183        setImageToChild(_imageDataList.size()-1);
184    }
185}
186
187void ImageSequence::setImageToChild(int pos)
188{
189   
190    const osg::Image* image = (pos>=0 && pos<static_cast<int>(_imageDataList.size())) ? _imageDataList[pos]._image.get() : 0;
191    if (image==0) return;
192
193    // check to see if data is changing, if not don't apply
194    if (image->data() == data())
195    {
196        return;
197    }
198
199
200    if (_mode==PAGE_AND_DISCARD_USED_IMAGES && _previousAppliedImageIndex>=0)
201    {
202        if (_previousAppliedImageIndex<pos)
203        {
204            OSG_INFO<<"Moving forward from "<<_previousAppliedImageIndex<<" to "<<pos<<std::endl;
205            while(_previousAppliedImageIndex<pos)
206            {
207                _imageDataList[_previousAppliedImageIndex]._image = 0;
208                OSG_INFO<<"   deleting "<<_previousAppliedImageIndex<<std::endl;
209                ++_previousAppliedImageIndex;
210            }
211        }
212        else if (_previousAppliedImageIndex>pos)
213        {
214            OSG_INFO<<"Moving back from "<<_previousAppliedImageIndex<<" to "<<pos<<std::endl;
215            while(_previousAppliedImageIndex>pos)
216            {
217                _imageDataList[_previousAppliedImageIndex]._image = 0;
218                OSG_INFO<<"   deleting "<<_previousAppliedImageIndex<<std::endl;
219                --_previousAppliedImageIndex;
220            }
221        }       
222    }
223   
224
225    _previousAppliedImageIndex = pos;
226
227    setImage(image->s(),image->t(),image->r(),
228             image->getInternalTextureFormat(),
229             image->getPixelFormat(),image->getDataType(),
230             const_cast<unsigned char*>(image->data()),
231             osg::Image::NO_DELETE,
232             image->getPacking());
233}
234
235void ImageSequence::applyLoopingMode()
236{
237}
238
239int ImageSequence::imageIndex(double time)
240{
241    if (getLoopingMode()==LOOPING)
242    {
243        double positionRatio = time/_length;
244        time = (positionRatio - floor(positionRatio))*_length;
245    }
246
247    if (time<0.0) return 0;
248    int index = int(time/_timePerImage);
249    if (index>=int(_imageDataList.size())) return int(_imageDataList.size())-1;
250    return index;
251}
252
253void ImageSequence::update(osg::NodeVisitor* nv)
254{
255    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
256
257    osg::NodeVisitor::ImageRequestHandler* irh = nv->getImageRequestHandler();
258    const osg::FrameStamp* fs = nv->getFrameStamp();
259
260    // OSG_NOTICE<<"ImageSequence::update("<<fs<<", "<<irh<<")"<<std::endl;
261
262    if (_referenceTime == DBL_MAX)
263    {
264        _referenceTime = fs->getSimulationTime();
265    }
266
267    bool looping = getLoopingMode()==LOOPING;
268    double time = (fs->getSimulationTime() - _referenceTime)*_timeMultiplier;
269    bool useDirectTimeRequest = _seekTimeSet;
270   
271    if (_seekTimeSet || _status==PAUSED || _status==INVALID)
272    {
273        time = _seekTime;
274        useDirectTimeRequest = true;
275        _referenceTime =  fs->getSimulationTime() - time/_timeMultiplier;
276    }
277    else
278    {
279        if (looping)
280        {
281            while (time>_length)
282            {
283                _referenceTime += _length/_timeMultiplier;
284                time -= _length;
285            }
286        }
287        else
288        {
289            if (time>_length)
290            {
291                _referenceTime = fs->getSimulationTime() - _length/_timeMultiplier;
292                time = _length;
293            }
294        }
295    }
296
297    _seekTime = time;
298    _seekTimeSet = false;
299
300    if (irh && _mode==PRE_LOAD_ALL_IMAGES)
301    {
302        for(ImageDataList::iterator itr = _imageDataList.begin();
303            itr != _imageDataList.end();
304            ++itr)
305        {
306            if (!(itr->_image) && !(itr->_filename.empty()))
307            {
308                itr->_image = irh->readImageFile(itr->_filename);
309            }
310        }
311    }
312
313    int index = int(time/_timePerImage);
314    // OSG_NOTICE<<"time= "<<time<<" _timePerImage="<<_timePerImage<<" index="<<index<<" _length="<<_length<<std::endl;
315
316    if (index>=int(_imageDataList.size())) index = int(_imageDataList.size())-1;
317
318    if (index>=0 && index<int(_imageDataList.size()))
319    {
320        // need to find the nearest relevant change.
321        if (!_imageDataList[index]._image)
322        {           
323            if (_previousAppliedImageIndex<index)
324            {
325                OSG_DEBUG<<"ImageSequence::update(..) Moving forward by "<<index-_previousAppliedImageIndex<<std::endl;
326                while (index>=0 && !_imageDataList[index]._image.valid())
327                {
328                    --index;
329                }
330            }
331            else if (_previousAppliedImageIndex>index)
332            {
333                OSG_DEBUG<<"ImageSequence::update(..) Moving back by "<<_previousAppliedImageIndex-index<<std::endl;
334                while (index<static_cast<int>(_imageDataList.size()) && !_imageDataList[index]._image.valid())
335                {
336                    ++index;
337                }
338            }
339        }
340       
341        if (index>=0 && index!=_previousAppliedImageIndex)
342        {
343            setImageToChild(index);
344        }
345    }
346
347    // OSG_NOTICE<<"time = "<<time<<std::endl;
348
349    if (!irh) return;
350
351    if (useDirectTimeRequest)
352    {
353        int i = int(time/_timePerImage);
354        if ((i>=int(_imageDataList.size()) || !_imageDataList[i]._image))
355        {
356             i = osg::clampTo<int>(i, 0, _imageDataList.size()-1);
357
358             OSG_INFO<<"Requesting file, entry="<<i<<" : _fileNames[i]="<<_imageDataList[i]._filename<<std::endl;
359             irh->requestImageFile(_imageDataList[i]._filename, this, i, time, fs, _imageDataList[i]._imageRequest, _readOptions.get());
360        }
361    }
362    else
363    {
364        double preLoadTime = time + osg::minimum(irh->getPreLoadTime()*_timeMultiplier, _length);
365
366        int startLoadIndex = int(time/_timePerImage);
367        if (startLoadIndex>=int(_imageDataList.size())) startLoadIndex = int(_imageDataList.size())-1;
368        if (startLoadIndex<0) startLoadIndex = 0;
369
370        int endLoadIndex = int(preLoadTime/_timePerImage);
371        if (endLoadIndex>=int(_imageDataList.size()))
372        {
373            if (looping)
374            {
375                endLoadIndex -= int(_imageDataList.size());
376            }
377            else
378            {
379                endLoadIndex = int(_imageDataList.size())-1;
380            }
381        }
382        if (endLoadIndex<0) endLoadIndex = 0;
383
384        double requestTime = time;
385
386        if (endLoadIndex<startLoadIndex)
387        {
388            for(int i=startLoadIndex; i<int(_imageDataList.size()); ++i)
389            {
390                if (!_imageDataList[i]._image)
391                {
392                    irh->requestImageFile(_imageDataList[i]._filename, this, i, requestTime, fs, _imageDataList[i]._imageRequest, _readOptions.get());
393                }
394                requestTime += _timePerImage;
395            }
396
397            for(int i=0; i<=endLoadIndex; ++i)
398            {
399                if (!_imageDataList[i]._image)
400                {
401                    irh->requestImageFile(_imageDataList[i]._filename, this, i, requestTime, fs, _imageDataList[i]._imageRequest, _readOptions.get());
402                }
403                requestTime += _timePerImage;
404            }
405        }
406        else
407        {
408            for(int i=startLoadIndex; i<=endLoadIndex; ++i)
409            {
410                if (!_imageDataList[i]._image)
411                {
412                    irh->requestImageFile(_imageDataList[i]._filename, this, i, requestTime, fs, _imageDataList[i]._imageRequest, _readOptions.get());
413                }
414                requestTime += _timePerImage;
415            }
416        }
417
418    }
419
420}
Note: See TracBrowser for help on using the browser.