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

Revision 12529, 23.9 kB (checked in by robert, 3 years ago)

Replaced .osg with .osgt file usage

  • 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(4);
212        (*coords)[0].set(0.0f,0.0,height);
213        (*coords)[1].set(0.0f,0.0,0);
214        (*coords)[2].set(width,0.0,0);
215        (*coords)[3].set(width,0.0,height);
216        geom->setVertexArray(coords);
217       
218
219        osg::Vec3Array* normals = new osg::Vec3Array(4);
220        (*normals)[0].set(-1.0f,0.0f,0.0f);
221        (*normals)[1].set(0.0f,0.0f,-1.0f);
222        (*normals)[2].set(1.0f,0.0f,0.0f);
223        (*normals)[3].set(0.0f,0.0f,1.0f);
224        geom->setNormalArray(normals);
225        geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
226
227        osg::Vec2Array* tcoords = new osg::Vec2Array(4);
228        (*tcoords)[0].set(0.0f,1.0f);
229        (*tcoords)[1].set(0.0f,0.0f);
230        (*tcoords)[2].set(1.0f,0.0f);
231        (*tcoords)[3].set(1.0f,1.0f);
232        geom->setTexCoordArray(0,tcoords);
233
234        osg::Vec4Array* colours = new osg::Vec4Array(1);
235        (*colours)[0].set(1.0f,1.0f,1.0,1.0f);
236        geom->setColorArray(colours);
237        geom->setColorBinding(osg::Geometry::BIND_OVERALL);
238
239        osg::UByteArray* vindices = new osg::UByteArray(8);
240        (*vindices)[0]=0;
241        (*vindices)[1]=1;
242        (*vindices)[2]=1;
243        (*vindices)[3]=2;
244        (*vindices)[4]=2;
245        (*vindices)[5]=3;
246        (*vindices)[6]=3;
247        (*vindices)[7]=0;
248
249        geom->setVertexIndices(vindices);
250        geom->setTexCoordIndices(0,vindices);
251
252        geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,8));
253
254        // set up the geode.
255        osg::Geode* geode = new osg::Geode;
256        geode->addDrawable(geom);
257       
258   
259        non_visible_page->addChild(geode);
260    }
261
262
263    // set up visible page.
264    osg::Group* front_page = new osg::Group;
265    _switch->addChild(front_page);
266
267    {
268
269        osg::Geometry* geom = new osg::Geometry;
270        geom->setStateSet(album->getBackgroundStateSet());
271
272        osg::Vec3Array* coords = new osg::Vec3Array(4);
273        (*coords)[0].set(0.0f,0.0,height);
274        (*coords)[1].set(0.0f,0.0,0);
275        (*coords)[2].set(width,0.0,0);
276        (*coords)[3].set(width,0.0,height);
277        geom->setVertexArray(coords);
278
279        osg::Vec3Array* normals = new osg::Vec3Array(1);
280        (*normals)[0].set(0.0f,-1.0f,0.0f);
281        geom->setNormalArray(normals);
282        geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
283
284        osg::Vec2Array* tcoords = new osg::Vec2Array(4);
285        (*tcoords)[0].set(0.0f,1.0f);
286        (*tcoords)[1].set(0.0f,0.0f);
287        (*tcoords)[2].set(1.0f,0.0f);
288        (*tcoords)[3].set(1.0f,1.0f);
289        geom->setTexCoordArray(0,tcoords);
290
291        osg::Vec4Array* colours = new osg::Vec4Array(1);
292        (*colours)[0].set(1.0f,1.0f,1.0,1.0f);
293        geom->setColorArray(colours);
294        geom->setColorBinding(osg::Geometry::BIND_OVERALL);
295
296        geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
297
298        // set up the geode.
299        osg::Geode* geode = new osg::Geode;
300        geode->addDrawable(geom);
301       
302   
303        front_page->addChild(geode);
304    }
305
306    if (!frontFileName.empty())
307    {
308        float cut_off_distance = 8.0f;
309        float max_visible_distance = 300.0f;
310       
311        osg::Vec3 center(width*0.5f,0.0f,height*0.5f);
312
313        osgText::Text* text = new osgText::Text;
314        text->setFont("fonts/arial.ttf");
315        text->setPosition(center);
316        text->setCharacterSize(height/20.0f);
317        text->setAlignment(osgText::Text::CENTER_CENTER);
318        text->setAxisAlignment(osgText::Text::XZ_PLANE);
319        text->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
320        text->setText(std::string("Loading ")+frontFileName);
321
322        osg::Geode* geode = new osg::Geode;
323        geode->addDrawable(text);
324       
325        osg::PagedLOD* pagedlod = new osg::PagedLOD;
326        pagedlod->setCenter(center);
327        pagedlod->setRadius(1.6f);
328        pagedlod->setNumChildrenThatCannotBeExpired(2);
329       
330        pagedlod->setRange(0,max_visible_distance,1e7);
331        pagedlod->addChild(geode);
332       
333        pagedlod->setRange(1,cut_off_distance,max_visible_distance);
334        pagedlod->setFileName(1,rw->insertReference(frontFileName,256,width,height,false));
335
336        pagedlod->setRange(2,0.0f,cut_off_distance);
337        pagedlod->setFileName(2,rw->insertReference(frontFileName,1024,width,height,false));
338
339        front_page->addChild(pagedlod);
340    }
341     
342     
343    // set up back of page.
344    osg::Group* back_page = new osg::Group;
345    _switch->addChild(back_page);
346
347    {
348
349        osg::Geometry* geom = new osg::Geometry;
350        geom->setStateSet(album->getBackgroundStateSet());
351
352        osg::Vec3Array* coords = new osg::Vec3Array(4);
353        (*coords)[0].set(width,0.0,height);
354        (*coords)[1].set(width,0.0,0);
355        (*coords)[2].set(0.0f,0.0,0);
356        (*coords)[3].set(0.0f,0.0,height);
357        geom->setVertexArray(coords);
358
359        osg::Vec3Array* normals = new osg::Vec3Array(1);
360        (*normals)[0].set(0.0f,1.0f,0.0f);
361        geom->setNormalArray(normals);
362        geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
363
364        osg::Vec2Array* tcoords = new osg::Vec2Array(4);
365        (*tcoords)[0].set(1.0f,1.0f);
366        (*tcoords)[1].set(1.0f,0.0f);
367        (*tcoords)[2].set(0.0f,0.0f);
368        (*tcoords)[3].set(0.0f,1.0f);
369        geom->setTexCoordArray(0,tcoords);
370
371        osg::Vec4Array* colours = new osg::Vec4Array(1);
372        (*colours)[0].set(1.0f,1.0f,1.0,1.0f);
373        geom->setColorArray(colours);
374        geom->setColorBinding(osg::Geometry::BIND_OVERALL);
375
376        geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
377
378        // set up the geode.
379        osg::Geode* geode = new osg::Geode;
380        geode->addDrawable(geom);
381       
382   
383        back_page->addChild(geode);
384    }
385
386    if (!backFileName.empty())
387    {
388        float cut_off_distance = 8.0f;
389        float max_visible_distance = 300.0f;
390       
391        osg::Vec3 center(width*0.5f,0.0f,height*0.5f);
392
393        osgText::Text* text = new osgText::Text;
394        text->setFont("fonts/arial.ttf");
395        text->setPosition(center);
396        text->setCharacterSize(height/20.0f);
397        text->setAlignment(osgText::Text::CENTER_CENTER);
398        text->setAxisAlignment(osgText::Text::REVERSED_XZ_PLANE);
399        text->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
400        text->setText(std::string("Loading ")+backFileName);
401
402        osg::Geode* geode = new osg::Geode;
403        geode->addDrawable(text);
404       
405        osg::PagedLOD* pagedlod = new osg::PagedLOD;
406        pagedlod->setCenter(center);
407        pagedlod->setRadius(1.6f);
408        pagedlod->setNumChildrenThatCannotBeExpired(2);
409       
410        pagedlod->setRange(0,max_visible_distance,1e7);
411        pagedlod->addChild(geode);
412       
413        pagedlod->setRange(1,cut_off_distance,max_visible_distance);
414        pagedlod->setFileName(1,rw->insertReference(backFileName,256,width,height,true));
415
416        pagedlod->setRange(2,0.0f,cut_off_distance);
417        pagedlod->setFileName(2,rw->insertReference(backFileName,1024,width,height,true));
418
419        back_page->addChild(pagedlod);
420    }
421
422    addChild(_switch.get());
423}
424
425void Page::traverse(osg::NodeVisitor& nv)
426{
427    // if app traversal update the frame count.
428    if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
429    {
430        const osg::FrameStamp* framestamp = nv.getFrameStamp();
431        if (framestamp)
432        {
433            double t = framestamp->getSimulationTime();
434           
435            if (_rotation!=_targetRotation)
436            {
437                if (t>=_targetTime) _rotation = _targetRotation;
438                else _rotation += (_targetRotation-_rotation)*(t-_lastTimeTraverse)/(_targetTime-_lastTimeTraverse);
439               
440                dirtyBound();
441            }
442           
443            _lastTimeTraverse = t;
444
445        }
446    }
447    Transform::traverse(nv);
448}
449
450
451////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
452
453Album::Album(osg::ArgumentParser& arguments, float width, float height)
454{
455
456
457    typedef std::vector<std::string> FileList;
458    FileList fileList;
459
460    for(int pos=1;pos<arguments.argc();++pos)
461    {
462        if (arguments.isString(pos))
463        {
464            std::string filename(arguments[pos]);
465            if (osgDB::getLowerCaseFileExtension(filename)=="album")
466            {
467                PhotoArchive* photoArchive = PhotoArchive::open(filename);
468                if (photoArchive)
469                {
470                    g_ImageReaderWriter.get()->addPhotoArchive(photoArchive);
471                    photoArchive->getImageFileNameList(fileList);
472                }
473               
474            }
475            else
476            {
477                fileList.push_back(arguments[pos]);
478            }
479        }
480    }
481   
482    _radiusOfRings = 0.02;
483    _startAngleOfPages = 0.0f;
484    _deltaAngleBetweenPages = osg::PI/(float)fileList.size();
485   
486    _group = new osg::Group;
487    _group->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace,osg::StateAttribute::ON);
488   
489    _backgroundStateSet = new osg::StateSet;
490    _backgroundStateSet->setAttributeAndModes(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON);
491   
492    // load the images.
493    unsigned int i;
494    for(i=0;i<fileList.size();i+=2)
495    {
496        Page* page = i+1<fileList.size()?
497                     Page::createPage(this,_pages.size(),fileList[i],fileList[i+1], width, height):
498                     Page::createPage(this,_pages.size(),fileList[i],"", width, height);
499        if (page)
500        {
501            _pages.push_back(page);
502            _group->addChild(page);
503        }
504    }
505   
506    setVisibility();
507
508}
509
510osg::Matrix Album::getPageOffset(unsigned int pageNo) const
511{
512    float angleForPage = _startAngleOfPages+_deltaAngleBetweenPages*(float)pageNo;
513    osg::Vec3 delta(_radiusOfRings*sinf(angleForPage),-_radiusOfRings*cosf(angleForPage),0.0f);
514    return osg::Matrix::translate(delta);
515}
516
517bool Album::gotoPage(unsigned int pageNo, float timeToRotateBy)
518{
519    if (pageNo>=_pages.size()) return false;
520
521    if (pageNo>_currentPageNo)
522    {
523        for(unsigned int i=_currentPageNo;i<pageNo;++i)
524        {
525            _pages[i]->rotateTo(osg::PI,timeToRotateBy);
526        }
527        _currentPageNo = pageNo;
528       
529        return true;
530    }
531    else if (pageNo<_currentPageNo)
532    {
533        for(unsigned int i=pageNo;i<_currentPageNo;++i)
534        {
535            _pages[i]->rotateTo(0,timeToRotateBy);
536        }
537        _currentPageNo = pageNo;
538       
539        return true;
540    }
541   
542    return false;
543}
544
545void Album::setVisibility()
546{
547    for(unsigned int i=0;i<_pages.size();++i)
548    {
549        bool front_visible = _pages[i]->rotating() ||
550                             (i>0?_pages[i-1]->rotating():false) ||
551                             i==_currentPageNo ||
552                             i==0;
553
554        bool back_visible = _pages[i]->rotating() ||
555                            ((i+1)<_pages.size()?_pages[i+1]->rotating():false) ||
556                            i==_currentPageNo-1 ||
557                            i==_pages.size()-1;
558   
559        _pages[i]->setPageVisible(front_visible,back_visible);
560    }
561   
562}
563
564
565////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
566
567
568class SlideEventHandler : public osgGA::GUIEventHandler
569{
570public:
571
572    SlideEventHandler();
573   
574    META_Object(osgStereImageApp,SlideEventHandler);
575
576    void set(Album* album, float timePerSlide, bool autoSteppingActive);
577
578    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
579   
580    virtual void getUsage(osg::ApplicationUsage& usage) const;
581
582protected:
583
584    ~SlideEventHandler() {}
585    SlideEventHandler(const SlideEventHandler&,const osg::CopyOp&) {}
586
587    osg::ref_ptr<Album>         _album;
588    bool                        _firstTraversal;
589    double                      _previousTime;
590    double                      _timePerSlide;
591    bool                        _autoSteppingActive;
592};
593
594SlideEventHandler::SlideEventHandler():
595    _album(0),
596    _firstTraversal(true),
597    _previousTime(-1.0f),
598    _timePerSlide(5.0),
599    _autoSteppingActive(false)
600{
601}
602
603void SlideEventHandler::set(Album* album, float timePerSlide, bool autoSteppingActive)
604{
605    _album = album;
606
607    _timePerSlide = timePerSlide;
608    _autoSteppingActive = autoSteppingActive;   
609   
610}
611
612bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
613{
614    switch(ea.getEventType())
615    {
616        case(osgGA::GUIEventAdapter::KEYDOWN):
617        {
618            if (ea.getKey()=='a')
619            {
620                _autoSteppingActive = !_autoSteppingActive;
621                _previousTime = ea.getTime();
622                return true;
623            }
624            else if (ea.getKey()=='n')
625            {
626                _album->nextPage(ea.getTime()+1.0f);
627                return true;
628            }
629            else if (ea.getKey()=='p')
630            {
631                _album->previousPage(ea.getTime()+1.0f);
632                return true;
633            }
634            return false;
635        }
636        case(osgGA::GUIEventAdapter::FRAME):
637        {
638            if (_autoSteppingActive)
639            {
640                if (_firstTraversal)
641                {
642                    _firstTraversal = false;
643                    _previousTime = ea.getTime();
644                }
645                else if (ea.getTime()-_previousTime>_timePerSlide)
646                {
647                    _previousTime = ea.getTime();
648
649                    _album->nextPage(ea.getTime()+1.0f);
650                }
651            }
652           
653            _album->setVisibility();
654
655        }
656
657        default:
658            return false;
659    }
660}
661
662void SlideEventHandler::getUsage(osg::ApplicationUsage& usage) const
663{
664    usage.addKeyboardMouseBinding("Space","Reset the image position to center");
665    usage.addKeyboardMouseBinding("a","Toggle on/off the automatic advancement for image to image");
666    usage.addKeyboardMouseBinding("n","Advance to next image");
667    usage.addKeyboardMouseBinding("p","Move to previous image");
668}
669
670int main( int argc, char **argv )
671{
672
673    // use an ArgumentParser object to manage the program arguments.
674    osg::ArgumentParser arguments(&argc,argv);
675   
676    // set up the usage document, in case we need to print out how to use this program.
677    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use node masks to create stereo images.");
678    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file [image_file]");
679    arguments.getApplicationUsage()->addCommandLineOption("-d <float>","Time delay in seconds between the display of successive image pairs when in auto advance mode.");
680    arguments.getApplicationUsage()->addCommandLineOption("-a","Enter auto advance of image pairs on start up.");
681    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
682    arguments.getApplicationUsage()->addCommandLineOption("--create <filename>","Create an photo archive of specified files");
683   
684
685    // construct the viewer.
686    osgViewer::Viewer viewer(arguments);
687   
688    viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
689
690    // register the handler to add keyboard and mouse handling.
691    SlideEventHandler* seh = new SlideEventHandler();
692    viewer.addEventHandler(seh);
693
694    // read any time delay argument.
695    float timeDelayBetweenSlides = 5.0f;
696    while (arguments.read("-d",timeDelayBetweenSlides)) {}
697
698    bool autoSteppingActive = false;
699    while (arguments.read("-a")) autoSteppingActive = true;
700
701    // if user request help write it out to cout.
702    if (arguments.read("-h") || arguments.read("--help"))
703    {
704        arguments.getApplicationUsage()->write(std::cout);
705        return 1;
706    }
707
708    std::string archiveName;
709    while (arguments.read("--create",archiveName)) {}
710   
711    // any option left unread are converted into errors to write out later.
712    arguments.reportRemainingOptionsAsUnrecognized();
713
714    // report any errors if they have occurred when parsing the program arguments.
715    if (arguments.errors())
716    {
717        arguments.writeErrorMessages(std::cout);
718        return 1;
719    }
720   
721    if (arguments.argc()<=1)
722    {
723        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
724        return 1;
725    }
726
727
728    if (!archiveName.empty())
729    {
730        // archive name set to create
731        PhotoArchive::FileNameList fileNameList;
732        for(int i=1;i<arguments.argc();++i)
733        {
734            if (arguments.isString(i)) fileNameList.push_back(std::string(arguments[i]));
735        }
736       
737        PhotoArchive::buildArchive(archiveName,fileNameList);
738       
739        return 0;
740    }
741
742
743    // now the windows have been realized we switch off the cursor to prevent it
744    // distracting the people seeing the stereo images.
745    double fovy, aspectRatio, zNear, zFar;
746    viewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
747
748    fovy = osg::DegreesToRadians(fovy);
749    double fovx = atan(tan(fovy*0.5)*aspectRatio)*2.0;
750   
751    float radius = 1.0f;
752    float width = 2*radius*tan(fovx*0.5f);
753    float height = 2*radius*tan(fovy*0.5f);
754
755    osg::ref_ptr<Album> album = new Album(arguments,width,height);
756
757    // creat the scene from the file list.
758    osg::ref_ptr<osg::Group> rootNode = album->getScene();
759   
760    if (!rootNode) return 0;
761
762
763    //osgDB::writeNodeFile(*rootNode,"test.osgt");
764
765    // set the scene to render
766    viewer.setSceneData(album->getScene());
767
768    // set up the SlideEventHandler.
769    seh->set(album.get(),timeDelayBetweenSlides,autoSteppingActive);
770   
771    viewer.realize();
772   
773    // switch off the cursor
774    osgViewer::Viewer::Windows windows;
775    viewer.getWindows(windows);
776    for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
777        itr != windows.end();
778        ++itr)
779    {
780        (*itr)->useCursor(false);
781    }
782
783
784    return viewer.run();
785}
Note: See TracBrowser for help on using the browser.