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

Revision 5032, 24.3 kB (checked in by robert, 9 years ago)

Converted osgGA::GUIEventAdapter into a concrete class capable of respresenting
keyboard and mouse events.

Added osgGA::EventQueue? class to support a thread safe event queue and adaption
of keyboard and mouse events.

Removed osgProducer::EventAdapter? as GUIEventAdapter replaces it.

Adapted osgProducer and examples to work with the new changes to osgGA.

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