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

Revision 2578, 24.3 kB (checked in by robert, 11 years ago)

Added support for a photo archive.

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