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

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

Added simple test script for osgUI's TabWidget?

  • 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.