root/OpenSceneGraph/trunk/examples/osgphotoalbum/osgphotoalbum.cpp @ 13687

Revision 13576, 23.4 kB (checked in by robert, 10 hours ago)

Changed the osgUI behaviour so that events are set to be handled by Widgets that have focus even if they don't directly use them.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgphotoalbum.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osg/Notify>
20#include <osg/MatrixTransform>
21#include <osg/Switch>
22#include <osg/PolygonOffset>
23#include <osg/CullFace>
24
25#include <osgUtil/Optimizer>
26
27#include <osgDB/FileNameUtils>
28
29#include <osgText/Text>
30
31#include <osgViewer/Viewer>
32
33#include "ImageReaderWriter.h"
34
35#include <iostream>
36
37using namespace osg;
38
39// now register with Registry to instantiate the above reader/writer,
40// declaring in main so that the code to set up PagedLOD can get a handle
41// to the ImageReaderWriter's
42osgDB::RegisterReaderWriterProxy<ImageReaderWriter> g_ImageReaderWriter;
43
44class Album;
45
46class Page : public osg::Transform
47{
48public:
49
50
51    static Page* createPage(Album* album, unsigned int pageNo, const std::string& frontFileName, const std::string& backFileName, float width, float height)
52    {
53        osg::ref_ptr<Page> page = new Page(album, pageNo, frontFileName, backFileName, width, height);
54        if (page.valid()) return page.release();
55        else return 0;
56    }
57
58    virtual void traverse(osg::NodeVisitor& nv);
59
60    void setRotation(float angle)
61    {
62        _rotation = angle;
63        _targetRotation = angle;
64        dirtyBound();
65    }
66
67    float getRotation() const { return _rotation; }
68
69    void rotateTo(float angle, float timeToRotateBy)
70    {
71        _targetRotation = angle;
72        _targetTime = timeToRotateBy;
73    }
74
75    bool rotating() const { return _targetRotation!=_rotation; }
76
77    void setPageVisible(bool frontVisible,bool backVisible)
78    {
79        _switch->setValue(0,!frontVisible && !backVisible);
80        _switch->setValue(1,frontVisible);
81        _switch->setValue(2,backVisible);
82    }
83
84    osg::Switch* getSwitch() { return _switch.get(); }
85    const osg::Switch* getSwitch() const { return _switch.get(); }
86
87public:
88
89    virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const
90    {
91        if (_referenceFrame==RELATIVE_RF)
92        {
93            matrix.preMult(getMatrix());
94        }
95        else // absolute
96        {
97            matrix = getMatrix();
98        }
99        return true;
100    }
101
102    /** Get the transformation matrix which moves from world coords to local coords.*/
103    virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const
104    {
105        const osg::Matrix& inverse = getInverseMatrix();
106
107        if (_referenceFrame==RELATIVE_RF)
108        {
109            matrix.postMult(inverse);
110        }
111        else // absolute
112        {
113            matrix = inverse;
114        }
115        return true;
116    }
117
118    osg::Matrix getMatrix() const { return _pageOffset*osg::Matrix::rotate(-_rotation,0.0f,0.0f,1.0f); }
119    osg::Matrix getInverseMatrix() const { return osg::Matrix::inverse(getMatrix()); }
120
121protected:
122
123    Page(Album* album, unsigned int pageNo, const std::string& frontFileName, const std::string& backFileName, float width, float height);
124
125    float       _rotation;
126    osg::Matrix _pageOffset;
127
128    float       _targetRotation;
129    float       _targetTime;
130    float       _lastTimeTraverse;
131
132    osg::ref_ptr<osg::Switch>     _switch;
133
134};
135
136
137class Album : public osg::Referenced
138{
139public:
140
141    Album(osg::ArgumentParser& ap, float width, float height);
142
143    osg::Group* getScene() { return _group.get(); }
144
145    const osg::Group* getScene() const { return _group.get(); }
146
147    osg::Matrix getPageOffset(unsigned int pageNo) const;
148
149    bool nextPage(float timeToRotateBy) { return gotoPage(_currentPageNo+1,timeToRotateBy); }
150
151    bool previousPage(float timeToRotateBy) { return _currentPageNo>=1?gotoPage(_currentPageNo-1,timeToRotateBy):false; }
152
153    bool gotoPage(unsigned int pageNo, float timeToRotateBy);
154
155    osg::StateSet* getBackgroundStateSet() { return _backgroundStateSet.get(); }
156
157    void setVisibility();
158
159protected:
160
161    typedef std::vector< osg::ref_ptr<Page> > PageList;
162
163    osg::ref_ptr<osg::Group>    _group;
164    PageList                    _pages;
165
166    osg::ref_ptr<osg::StateSet> _backgroundStateSet;
167
168    unsigned int                _currentPageNo;
169    float                       _radiusOfRings;
170    float                       _startAngleOfPages;
171    float                       _deltaAngleBetweenPages;
172
173};
174
175
176////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
177
178
179Page::Page(Album* album, unsigned int pageNo, const std::string& frontFileName, const std::string& backFileName, float width, float height)
180{
181    // set up transform parts.
182    _rotation = 0;
183    _targetRotation = 0;
184    _targetTime = 0;
185    _lastTimeTraverse = 0;
186
187    _pageOffset = album->getPageOffset(pageNo);
188
189    setNumChildrenRequiringUpdateTraversal(1);
190
191
192    // set up subgraph
193    osgDB::ReaderWriter* readerWriter = osgDB::Registry::instance()->getReaderWriterForExtension("gdal");
194    if (!readerWriter)
195    {
196        std::cout<<"Error: GDAL plugin not available, cannot preceed with database creation"<<std::endl;
197    }
198
199    _switch = new osg::Switch;
200
201    ImageReaderWriter* rw = g_ImageReaderWriter.get();
202
203
204    // set up non visible page.
205    osg::Group* non_visible_page = new osg::Group;
206    _switch->addChild(non_visible_page);
207    {
208        osg::Geometry* geom = new osg::Geometry;
209        geom->setStateSet(album->getBackgroundStateSet());
210
211        osg::Vec3Array* coords = new osg::Vec3Array(8);
212        (*coords)[0].set(0.0f,0.0f,0.0f);
213        (*coords)[1].set(0.0f,0.0f,height);
214        (*coords)[2].set(0.0f,0.0f,height);
215        (*coords)[3].set(width,0.0f,height);
216        (*coords)[4].set(width,0.0f,height);
217        (*coords)[5].set(width,0.0f,0.0f);
218        (*coords)[6].set(width,0.0f,0.0f);
219        (*coords)[7].set(0.0f,0.0f,0.0f);
220        geom->setVertexArray(coords);
221
222
223        osg::Vec3Array* normals = new osg::Vec3Array(8);
224        (*normals)[0].set(-1.0f,0.0f,0.0f);
225        (*normals)[1].set(-1.0f,0.0f,0.0f);
226        (*normals)[2].set(0.0f,0.0f,-1.0f);
227        (*normals)[3].set(0.0f,0.0f,-1.0f);
228        (*normals)[4].set(1.0f,0.0f,0.0f);
229        (*normals)[5].set(1.0f,0.0f,0.0f);
230        (*normals)[6].set(0.0f,0.0f,1.0f);
231        (*normals)[7].set(0.0f,0.0f,1.0f);
232        geom->setNormalArray(normals, osg::Array::BIND_PER_VERTEX);
233
234        osg::Vec2Array* tcoords = new osg::Vec2Array(8);
235        (*tcoords)[0].set(0.0f,0.0f);
236        (*tcoords)[1].set(0.0f,1.0f);
237        (*tcoords)[2].set(0.0f,1.0f);
238        (*tcoords)[3].set(1.0f,1.0f);
239        (*tcoords)[4].set(1.0f,1.0f);
240        (*tcoords)[5].set(0.0f,1.0f);
241        (*tcoords)[6].set(0.0f,1.0f);
242        (*tcoords)[7].set(0.0f,0.0f);
243        geom->setTexCoordArray(0,tcoords);
244
245        osg::Vec4Array* colours = new osg::Vec4Array(1);
246        (*colours)[0].set(1.0f,1.0f,1.0,1.0f);
247        geom->setColorArray(colours, osg::Array::BIND_OVERALL);
248
249        geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,8));
250
251        // set up the geode.
252        osg::Geode* geode = new osg::Geode;
253        geode->addDrawable(geom);
254
255
256        non_visible_page->addChild(geode);
257    }
258
259
260    // set up visible page.
261    osg::Group* front_page = new osg::Group;
262    _switch->addChild(front_page);
263
264    {
265
266        osg::Geometry* geom = new osg::Geometry;
267        geom->setStateSet(album->getBackgroundStateSet());
268
269        osg::Vec3Array* coords = new osg::Vec3Array(4);
270        (*coords)[0].set(0.0f,0.0,height);
271        (*coords)[1].set(0.0f,0.0,0);
272        (*coords)[2].set(width,0.0,0);
273        (*coords)[3].set(width,0.0,height);
274        geom->setVertexArray(coords);
275
276        osg::Vec3Array* normals = new osg::Vec3Array(1);
277        (*normals)[0].set(0.0f,-1.0f,0.0f);
278        geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
279
280        osg::Vec2Array* tcoords = new osg::Vec2Array(4);
281        (*tcoords)[0].set(0.0f,1.0f);
282        (*tcoords)[1].set(0.0f,0.0f);
283        (*tcoords)[2].set(1.0f,0.0f);
284        (*tcoords)[3].set(1.0f,1.0f);
285        geom->setTexCoordArray(0,tcoords);
286
287        osg::Vec4Array* colours = new osg::Vec4Array(1);
288        (*colours)[0].set(1.0f,1.0f,1.0,1.0f);
289        geom->setColorArray(colours, osg::Array::BIND_OVERALL);
290
291        geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
292
293        // set up the geode.
294        osg::Geode* geode = new osg::Geode;
295        geode->addDrawable(geom);
296
297
298        front_page->addChild(geode);
299    }
300
301    if (!frontFileName.empty())
302    {
303        float cut_off_distance = 8.0f;
304        float max_visible_distance = 300.0f;
305
306        osg::Vec3 center(width*0.5f,0.0f,height*0.5f);
307
308        osgText::Text* text = new osgText::Text;
309        text->setFont("fonts/arial.ttf");
310        text->setPosition(center);
311        text->setCharacterSize(height/20.0f);
312        text->setAlignment(osgText::Text::CENTER_CENTER);
313        text->setAxisAlignment(osgText::Text::XZ_PLANE);
314        text->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
315        text->setText(std::string("Loading ")+frontFileName);
316
317        osg::Geode* geode = new osg::Geode;
318        geode->addDrawable(text);
319
320        osg::PagedLOD* pagedlod = new osg::PagedLOD;
321        pagedlod->setCenter(center);
322        pagedlod->setRadius(1.6f);
323        pagedlod->setNumChildrenThatCannotBeExpired(2);
324
325        pagedlod->setRange(0,max_visible_distance,1e7);
326        pagedlod->addChild(geode);
327
328        pagedlod->setRange(1,cut_off_distance,max_visible_distance);
329        pagedlod->setFileName(1,rw->insertReference(frontFileName,256,width,height,false));
330
331        pagedlod->setRange(2,0.0f,cut_off_distance);
332        pagedlod->setFileName(2,rw->insertReference(frontFileName,1024,width,height,false));
333
334        front_page->addChild(pagedlod);
335    }
336
337
338    // set up back of page.
339    osg::Group* back_page = new osg::Group;
340    _switch->addChild(back_page);
341
342    {
343
344        osg::Geometry* geom = new osg::Geometry;
345        geom->setStateSet(album->getBackgroundStateSet());
346
347        osg::Vec3Array* coords = new osg::Vec3Array(4);
348        (*coords)[0].set(width,0.0,height);
349        (*coords)[1].set(width,0.0,0);
350        (*coords)[2].set(0.0f,0.0,0);
351        (*coords)[3].set(0.0f,0.0,height);
352        geom->setVertexArray(coords);
353
354        osg::Vec3Array* normals = new osg::Vec3Array(1);
355        (*normals)[0].set(0.0f,1.0f,0.0f);
356        geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
357
358        osg::Vec2Array* tcoords = new osg::Vec2Array(4);
359        (*tcoords)[0].set(1.0f,1.0f);
360        (*tcoords)[1].set(1.0f,0.0f);
361        (*tcoords)[2].set(0.0f,0.0f);
362        (*tcoords)[3].set(0.0f,1.0f);
363        geom->setTexCoordArray(0,tcoords);
364
365        osg::Vec4Array* colours = new osg::Vec4Array(1);
366        (*colours)[0].set(1.0f,1.0f,1.0,1.0f);
367        geom->setColorArray(colours, osg::Array::BIND_OVERALL);
368
369        geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
370
371        // set up the geode.
372        osg::Geode* geode = new osg::Geode;
373        geode->addDrawable(geom);
374
375
376        back_page->addChild(geode);
377    }
378
379    if (!backFileName.empty())
380    {
381        float cut_off_distance = 8.0f;
382        float max_visible_distance = 300.0f;
383
384        osg::Vec3 center(width*0.5f,0.0f,height*0.5f);
385
386        osgText::Text* text = new osgText::Text;
387        text->setFont("fonts/arial.ttf");
388        text->setPosition(center);
389        text->setCharacterSize(height/20.0f);
390        text->setAlignment(osgText::Text::CENTER_CENTER);
391        text->setAxisAlignment(osgText::Text::REVERSED_XZ_PLANE);
392        text->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
393        text->setText(std::string("Loading ")+backFileName);
394
395        osg::Geode* geode = new osg::Geode;
396        geode->addDrawable(text);
397
398        osg::PagedLOD* pagedlod = new osg::PagedLOD;
399        pagedlod->setCenter(center);
400        pagedlod->setRadius(1.6f);
401        pagedlod->setNumChildrenThatCannotBeExpired(2);
402
403        pagedlod->setRange(0,max_visible_distance,1e7);
404        pagedlod->addChild(geode);
405
406        pagedlod->setRange(1,cut_off_distance,max_visible_distance);
407        pagedlod->setFileName(1,rw->insertReference(backFileName,256,width,height,true));
408
409        pagedlod->setRange(2,0.0f,cut_off_distance);
410        pagedlod->setFileName(2,rw->insertReference(backFileName,1024,width,height,true));
411
412        back_page->addChild(pagedlod);
413    }
414
415    addChild(_switch.get());
416}
417
418void Page::traverse(osg::NodeVisitor& nv)
419{
420    // if app traversal update the frame count.
421    if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
422    {
423        const osg::FrameStamp* framestamp = nv.getFrameStamp();
424        if (framestamp)
425        {
426            double t = framestamp->getSimulationTime();
427
428            if (_rotation!=_targetRotation)
429            {
430                if (t>=_targetTime) _rotation = _targetRotation;
431                else _rotation += (_targetRotation-_rotation)*(t-_lastTimeTraverse)/(_targetTime-_lastTimeTraverse);
432
433                dirtyBound();
434            }
435
436            _lastTimeTraverse = t;
437
438        }
439    }
440    Transform::traverse(nv);
441}
442
443
444////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
445
446Album::Album(osg::ArgumentParser& arguments, float width, float height)
447{
448
449
450    typedef std::vector<std::string> FileList;
451    FileList fileList;
452
453    for(int pos=1;pos<arguments.argc();++pos)
454    {
455        if (arguments.isString(pos))
456        {
457            std::string filename(arguments[pos]);
458            if (osgDB::getLowerCaseFileExtension(filename)=="album")
459            {
460                PhotoArchive* photoArchive = PhotoArchive::open(filename);
461                if (photoArchive)
462                {
463                    g_ImageReaderWriter.get()->addPhotoArchive(photoArchive);
464                    photoArchive->getImageFileNameList(fileList);
465                }
466
467            }
468            else
469            {
470                fileList.push_back(arguments[pos]);
471            }
472        }
473    }
474
475    _radiusOfRings = 0.02;
476    _startAngleOfPages = 0.0f;
477    _deltaAngleBetweenPages = osg::PI/(float)fileList.size();
478
479    _group = new osg::Group;
480    _group->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace,osg::StateAttribute::ON);
481
482    _backgroundStateSet = new osg::StateSet;
483    _backgroundStateSet->setAttributeAndModes(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON);
484
485    // load the images.
486    unsigned int i;
487    for(i=0;i<fileList.size();i+=2)
488    {
489        Page* page = i+1<fileList.size()?
490                     Page::createPage(this,_pages.size(),fileList[i],fileList[i+1], width, height):
491                     Page::createPage(this,_pages.size(),fileList[i],"", width, height);
492        if (page)
493        {
494            _pages.push_back(page);
495            _group->addChild(page);
496        }
497    }
498
499    setVisibility();
500
501}
502
503osg::Matrix Album::getPageOffset(unsigned int pageNo) const
504{
505    float angleForPage = _startAngleOfPages+_deltaAngleBetweenPages*(float)pageNo;
506    osg::Vec3 delta(_radiusOfRings*sinf(angleForPage),-_radiusOfRings*cosf(angleForPage),0.0f);
507    return osg::Matrix::translate(delta);
508}
509
510bool Album::gotoPage(unsigned int pageNo, float timeToRotateBy)
511{
512    if (pageNo>=_pages.size()) return false;
513
514    if (pageNo>_currentPageNo)
515    {
516        for(unsigned int i=_currentPageNo;i<pageNo;++i)
517        {
518            _pages[i]->rotateTo(osg::PI,timeToRotateBy);
519        }
520        _currentPageNo = pageNo;
521
522        return true;
523    }
524    else if (pageNo<_currentPageNo)
525    {
526        for(unsigned int i=pageNo;i<_currentPageNo;++i)
527        {
528            _pages[i]->rotateTo(0,timeToRotateBy);
529        }
530        _currentPageNo = pageNo;
531
532        return true;
533    }
534
535    return false;
536}
537
538void Album::setVisibility()
539{
540    for(unsigned int i=0;i<_pages.size();++i)
541    {
542        bool front_visible = _pages[i]->rotating() ||
543                             (i>0?_pages[i-1]->rotating():false) ||
544                             i==_currentPageNo ||
545                             i==0;
546
547        bool back_visible = _pages[i]->rotating() ||
548                            ((i+1)<_pages.size()?_pages[i+1]->rotating():false) ||
549                            i==_currentPageNo-1 ||
550                            i==_pages.size()-1;
551
552        _pages[i]->setPageVisible(front_visible,back_visible);
553    }
554
555}
556
557
558////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
559
560
561class SlideEventHandler : public osgGA::GUIEventHandler
562{
563public:
564
565    SlideEventHandler();
566
567    META_Object(osgStereImageApp,SlideEventHandler);
568
569    void set(Album* album, float timePerSlide, bool autoSteppingActive);
570
571    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
572
573    virtual void getUsage(osg::ApplicationUsage& usage) const;
574
575protected:
576
577    ~SlideEventHandler() {}
578    SlideEventHandler(const SlideEventHandler&,const osg::CopyOp&) {}
579
580    osg::ref_ptr<Album>         _album;
581    bool                        _firstTraversal;
582    double                      _previousTime;
583    double                      _timePerSlide;
584    bool                        _autoSteppingActive;
585};
586
587SlideEventHandler::SlideEventHandler():
588    _album(0),
589    _firstTraversal(true),
590    _previousTime(-1.0f),
591    _timePerSlide(5.0),
592    _autoSteppingActive(false)
593{
594}
595
596void SlideEventHandler::set(Album* album, float timePerSlide, bool autoSteppingActive)
597{
598    _album = album;
599
600    _timePerSlide = timePerSlide;
601    _autoSteppingActive = autoSteppingActive;
602
603}
604
605bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
606{
607    switch(ea.getEventType())
608    {
609        case(osgGA::GUIEventAdapter::KEYDOWN):
610        {
611            if (ea.getKey()=='a')
612            {
613                _autoSteppingActive = !_autoSteppingActive;
614                _previousTime = ea.getTime();
615                return true;
616            }
617            else if (ea.getKey()=='n')
618            {
619                _album->nextPage(ea.getTime()+1.0f);
620                return true;
621            }
622            else if (ea.getKey()=='p')
623            {
624                _album->previousPage(ea.getTime()+1.0f);
625                return true;
626            }
627            return false;
628        }
629        case(osgGA::GUIEventAdapter::FRAME):
630        {
631            if (_autoSteppingActive)
632            {
633                if (_firstTraversal)
634                {
635                    _firstTraversal = false;
636                    _previousTime = ea.getTime();
637                }
638                else if (ea.getTime()-_previousTime>_timePerSlide)
639                {
640                    _previousTime = ea.getTime();
641
642                    _album->nextPage(ea.getTime()+1.0f);
643                }
644            }
645
646            _album->setVisibility();
647
648        }
649
650        default:
651            return false;
652    }
653}
654
655void SlideEventHandler::getUsage(osg::ApplicationUsage& usage) const
656{
657    usage.addKeyboardMouseBinding("Space","Reset the image position to center");
658    usage.addKeyboardMouseBinding("a","Toggle on/off the automatic advancement for image to image");
659    usage.addKeyboardMouseBinding("n","Advance to next image");
660    usage.addKeyboardMouseBinding("p","Move to previous image");
661}
662
663int main( int argc, char **argv )
664{
665
666    // use an ArgumentParser object to manage the program arguments.
667    osg::ArgumentParser arguments(&argc,argv);
668
669    // set up the usage document, in case we need to print out how to use this program.
670    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use node masks to create stereo images.");
671    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file [image_file]");
672    arguments.getApplicationUsage()->addCommandLineOption("-d <float>","Time delay in seconds between the display of successive image pairs when in auto advance mode.");
673    arguments.getApplicationUsage()->addCommandLineOption("-a","Enter auto advance of image pairs on start up.");
674    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
675    arguments.getApplicationUsage()->addCommandLineOption("--create <filename>","Create an photo archive of specified files");
676
677
678    // construct the viewer.
679    osgViewer::Viewer viewer(arguments);
680
681    viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
682
683    // register the handler to add keyboard and mouse handling.
684    SlideEventHandler* seh = new SlideEventHandler();
685    viewer.addEventHandler(seh);
686
687    // read any time delay argument.
688    float timeDelayBetweenSlides = 5.0f;
689    while (arguments.read("-d",timeDelayBetweenSlides)) {}
690
691    bool autoSteppingActive = false;
692    while (arguments.read("-a")) autoSteppingActive = true;
693
694    // if user request help write it out to cout.
695    if (arguments.read("-h") || arguments.read("--help"))
696    {
697        arguments.getApplicationUsage()->write(std::cout);
698        return 1;
699    }
700
701    std::string archiveName;
702    while (arguments.read("--create",archiveName)) {}
703
704    // any option left unread are converted into errors to write out later.
705    arguments.reportRemainingOptionsAsUnrecognized();
706
707    // report any errors if they have occurred when parsing the program arguments.
708    if (arguments.errors())
709    {
710        arguments.writeErrorMessages(std::cout);
711        return 1;
712    }
713
714    if (arguments.argc()<=1)
715    {
716        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
717        return 1;
718    }
719
720
721    if (!archiveName.empty())
722    {
723        // archive name set to create
724        PhotoArchive::FileNameList fileNameList;
725        for(int i=1;i<arguments.argc();++i)
726        {
727            if (arguments.isString(i)) fileNameList.push_back(std::string(arguments[i]));
728        }
729
730        PhotoArchive::buildArchive(archiveName,fileNameList);
731
732        return 0;
733    }
734
735
736    // now the windows have been realized we switch off the cursor to prevent it
737    // distracting the people seeing the stereo images.
738    double fovy, aspectRatio, zNear, zFar;
739    viewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
740
741    fovy = osg::DegreesToRadians(fovy);
742    double fovx = atan(tan(fovy*0.5)*aspectRatio)*2.0;
743
744    float radius = 1.0f;
745    float width = 2*radius*tan(fovx*0.5f);
746    float height = 2*radius*tan(fovy*0.5f);
747
748    osg::ref_ptr<Album> album = new Album(arguments,width,height);
749
750    // creat the scene from the file list.
751    osg::ref_ptr<osg::Group> rootNode = album->getScene();
752
753    if (!rootNode) return 0;
754
755
756    //osgDB::writeNodeFile(*rootNode,"test.osgt");
757
758    // set the scene to render
759    viewer.setSceneData(album->getScene());
760
761    // set up the SlideEventHandler.
762    seh->set(album.get(),timeDelayBetweenSlides,autoSteppingActive);
763
764    viewer.realize();
765
766    // switch off the cursor
767    osgViewer::Viewer::Windows windows;
768    viewer.getWindows(windows);
769    for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
770        itr != windows.end();
771        ++itr)
772    {
773        (*itr)->useCursor(false);
774    }
775
776
777    return viewer.run();
778}
Note: See TracBrowser for help on using the browser.