root/OpenSceneGraph/trunk/src/osgProducer/ViewerEventHandler.cpp @ 3311

Revision 3311, 30.4 kB (checked in by don, 10 years ago)

Fixed assumption that the users's screen is 1280x1024 when toggling
full screen with the 'f' key.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osgProducer/ViewerEventHandler>
2#include <osgGA/AnimationPathManipulator>
3#include <osgDB/WriteFile>
4#include <osgText/Text>
5#include <osg/BlendFunc>
6
7#include <algorithm>
8#include <fstream>
9
10using namespace osgProducer;
11
12
13class ViewerEventHandler::SnapImageDrawCallback : public Producer::Camera::Callback
14{
15public:
16
17    SnapImageDrawCallback(const std::string& filename):
18        _filename(filename),
19        _snapImageOnNextFrame(false)
20    {
21    }
22
23    void setSnapImageOnNextFrame(bool flag) { _snapImageOnNextFrame = flag; }
24    bool getSnapImageOnNextFrame() const { return _snapImageOnNextFrame; }
25   
26    virtual void operator()( const Producer::Camera & camera)
27    {
28        if (!_snapImageOnNextFrame) return;
29       
30        int x,y;
31        unsigned int width,height;
32        camera.getProjectionRectangle(x,y,width,height);
33
34        osg::ref_ptr<osg::Image> image = new osg::Image;
35        image->readPixels(x,y,width,height,
36                          GL_RGB,GL_UNSIGNED_BYTE);
37
38        if (osgDB::writeImageFile(*image,_filename))
39        {
40            osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl;
41        }
42       
43        _snapImageOnNextFrame = false;
44    }
45
46protected:
47   
48    std::string _filename;
49    bool        _snapImageOnNextFrame;
50
51   
52};
53
54class ViewerEventHandler::StatsAndHelpDrawCallback : public Producer::CameraGroup::StatsHandler, public Producer::Camera::Callback
55{
56public:
57
58    StatsAndHelpDrawCallback(ViewerEventHandler* veh, unsigned int cameraNumber):
59        _veh(veh),
60        _cameraNumber(cameraNumber),
61        _helpInitialized(false),
62        _statsInitialized(false),
63        _infoInitialized(false)
64    {
65        _fs.resize(10);
66        _index = 0;
67       
68        _veh->getOsgCameraGroup()->setStatsHandler(this);
69       
70        _stateset = new osg::StateSet;
71        _viewport = new osg::Viewport(0,0,1280,1024);
72        _stateset->setAttribute(_viewport.get());
73        _stateset->setAttribute(new osg::BlendFunc());
74        _stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
75        _stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
76       
77        _projection = new osg::RefMatrix(osg::Matrix::ortho2D(0.0,1280,0,1024));
78        _modelview = new osg::RefMatrix();
79   
80        //createHelpText();
81        //createStatsText();
82       
83        //_helpInitialized = false;
84
85    }
86   
87    void setArraySize(unsigned int size) { _fs.resize(size); }
88    unsigned int getArraySize() { return _fs.size(); }
89
90    void operator() (const Producer::CameraGroup &cg )
91    {
92        _index = (_index + 1) % _fs.size();
93        _fs[_index] = cg.getFrameStats();     
94    }
95
96    virtual void operator()( const Producer::Camera & camera);
97
98protected:
99   
100    ViewerEventHandler* _veh;
101    unsigned int _cameraNumber;
102
103    osg::ref_ptr<osg::StateSet> _stateset;
104    osg::ref_ptr<osg::Viewport> _viewport;
105    osg::ref_ptr<osg::RefMatrix> _projection;
106    osg::ref_ptr<osg::RefMatrix> _modelview;
107   
108    // help related methods and data
109    void displayHelp();
110    void createHelpText();
111   
112    typedef std::vector< osg::ref_ptr<osgText::Text> > TextList;
113    bool        _helpInitialized;
114    TextList    _descriptionList;
115    TextList    _optionList;
116    TextList    _explanationList;
117
118
119    // stats related methods and data.
120    void displayStats();
121    void createStatsText();
122   
123    typedef std::vector<double> CameraTimes;
124
125    bool                        _statsInitialized;
126    osg::ref_ptr<osgText::Text> _frameRateLabelText;
127    osg::ref_ptr<osgText::Text> _frameRateCounterText;
128    TextList                    _statsLabelList;
129    osg::ref_ptr<osgText::Text> _updateTimeText;
130    CameraTimes                 _cullTimes;
131    TextList                    _cullTimeText;
132    CameraTimes                 _drawTimes;
133    TextList                    _drawTimeText;
134   
135    // info related methods and data.
136    void displayInfo();
137    void createInfoText();
138   
139    bool                        _infoInitialized;
140    TextList                    _infoLabelList;
141    osg::ref_ptr<osgText::Text> _positionText;
142    osg::ref_ptr<osgText::Text> _orientationText;
143    osg::ref_ptr<osgText::Text> _speedText;
144
145    std::vector <Producer::CameraGroup::FrameStats> _fs;
146    unsigned int _index;
147
148};
149
150
151void ViewerEventHandler::StatsAndHelpDrawCallback::operator()( const Producer::Camera & camera)
152{
153    if (_veh->getDisplayHelp()==false &&
154        _veh->getFrameStatsMode()==ViewerEventHandler::NO_STATS) return;
155
156    int x,y;
157    unsigned int width,height;
158    camera.getProjectionRectangle(x,y,width,height);
159    _viewport->setViewport(x,y,width,height);
160
161    OsgSceneHandler* osh = _veh->getOsgCameraGroup()->getSceneHandlerList()[_cameraNumber].get();
162    osgUtil::SceneView* sv = osh->getSceneView();
163    osg::State& state = *(sv->getState());
164   
165   
166    state.applyProjectionMatrix(_projection.get());
167    state.applyModelViewMatrix(_modelview.get());
168   
169    state.pushStateSet(_stateset.get());
170    state.apply();
171
172    if (_veh->getFrameStatsMode()!=ViewerEventHandler::NO_STATS && camera.getInstrumentationMode())
173    {
174        displayStats();
175    }
176   
177    if (_veh->getDisplayHelp())
178    {
179        displayHelp();
180    }
181       
182    if (_veh->getDisplayHelp())
183    {
184        displayInfo();
185    }
186
187    state.popStateSet();
188   
189    //state.apply();
190
191}
192
193void ViewerEventHandler::StatsAndHelpDrawCallback::displayHelp()
194{
195    if (!_helpInitialized) createHelpText();
196
197    OsgSceneHandler* osh = _veh->getOsgCameraGroup()->getSceneHandlerList()[_cameraNumber].get();
198    osgUtil::SceneView* sv = osh->getSceneView();
199
200
201    for(TextList::iterator ditr=_descriptionList.begin();
202        ditr!=_descriptionList.end();
203        ++ditr)
204    {
205        (*ditr)->draw(*(sv->getState()));
206    }
207
208    for(TextList::iterator oitr=_optionList.begin();
209        oitr!=_optionList.end();
210        ++oitr)
211    {
212        (*oitr)->draw(*(sv->getState()));
213    }
214
215    for(TextList::iterator eitr=_explanationList.begin();
216        eitr!=_explanationList.end();
217        ++eitr)
218    {
219        (*eitr)->draw(*(sv->getState()));
220    }
221}
222
223void ViewerEventHandler::StatsAndHelpDrawCallback::createHelpText()
224{
225
226    OsgCameraGroup* ocg = _veh->getOsgCameraGroup();
227    if (ocg->getApplicationUsage())
228    {
229
230        const osg::ApplicationUsage::UsageMap& um = ocg->getApplicationUsage()->getKeyboardMouseBindings();
231
232        float maxWidthOfDisplayRegion = 1200.0f;
233        float bottomOfDescription = 1000.0f;
234        osg::Vec3 posDescription(0.0f,bottomOfDescription,0.0f);
235        osg::Vec4 colorDescription(1.0f,1.0f,0.0f,1.0f);
236        float characterSize = 20.0f;
237
238        if (!(ocg->getApplicationUsage()->getDescription()).empty())
239        {
240            osgText::Text* text = new osgText::Text;
241            text->setFont("fonts/arial.ttf");
242            text->setColor(colorDescription);
243            text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize);
244            text->setCharacterSize(characterSize);
245            text->setPosition(posDescription);
246            text->setMaximumWidth(maxWidthOfDisplayRegion);
247            text->setAlignment(osgText::Text::BASE_LINE);
248            text->setText(ocg->getApplicationUsage()->getDescription());
249
250            bottomOfDescription = text->getBound().yMin()-characterSize*2.0f;
251
252            _descriptionList.push_back(text);
253
254        }
255
256        osg::Vec3 posOption(0.0f,bottomOfDescription,0.0f);
257        osg::Vec4 colorOption(1.0f,1.0f,0.0f,1.0f);
258        float maxX = 0.0f;
259
260        // create option strings.
261        osg::ApplicationUsage::UsageMap::const_iterator citr;
262        for(citr=um.begin();
263            citr!=um.end();
264            ++citr)
265        {
266            osgText::Text* text = new osgText::Text;
267            text->setFont("fonts/arial.ttf");
268            text->setColor(colorOption);
269            text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize);
270            text->setCharacterSize(characterSize);
271            text->setPosition(posOption);
272            text->setAlignment(osgText::Text::BASE_LINE);
273            text->setText(citr->first);
274
275            if (text->getBound().xMax()>maxX) maxX=text->getBound().xMax();
276
277            _optionList.push_back(text);
278
279        }
280
281        osg::Vec3 posExplanation(maxX+characterSize,bottomOfDescription,0.0f);
282        osg::Vec4 colorExplanation(1.0f,1.0f,0.0f,1.0f);
283        float maxWidth = maxWidthOfDisplayRegion-maxX;
284
285        TextList::iterator oitr;
286        TextList::iterator eitr;
287        TextList::iterator ditr;
288
289        for(citr=um.begin(), oitr=_optionList.begin();
290            citr!=um.end();
291            ++citr,++oitr)
292        {
293            osgText::Text* text = new osgText::Text;
294            text->setFont("fonts/arial.ttf");
295            text->setColor(colorExplanation);
296            text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize);
297            text->setCharacterSize(characterSize);
298            text->setPosition(posExplanation);
299            text->setMaximumWidth(maxWidth);
300            text->setAlignment(osgText::Text::BASE_LINE);
301            text->setText(citr->second);
302
303            if (text->getBound().xMax()>maxX) maxX=text->getBound().xMax();
304
305            // fix the position of option text to be the same height as the examplanation.
306            osg::Vec3 pos((*oitr)->getPosition());
307            (*oitr)->setPosition(osg::Vec3(pos.x(),posExplanation.y(),pos.z()));
308
309            posExplanation.y() = text->getBound().yMin()-characterSize;
310
311            _explanationList.push_back(text);
312
313        }
314
315        // compute the boundings of the all the text.
316        osg::BoundingBox bb;
317        for(ditr=_descriptionList.begin();
318            ditr!=_descriptionList.end();
319            ++ditr)
320        {
321            bb.expandBy((*ditr)->getBound());
322        }
323
324        for(oitr=_optionList.begin();
325            oitr!=_optionList.end();
326            ++oitr)
327        {
328            bb.expandBy((*oitr)->getBound());
329        }
330
331        for(eitr=_explanationList.begin();
332            eitr!=_explanationList.end();
333            ++eitr)
334        {
335            bb.expandBy((*eitr)->getBound());
336        }
337
338        float totalWidth = bb.xMax()-bb.xMin();
339        float totalHeight = bb.yMax()-bb.yMin();
340        float widthMargin = (1280.0f-totalWidth)*0.5f;
341        float heightMargin = (1024.0f-totalHeight)*0.5f;
342
343        osg::Vec3 delta(widthMargin-bb.xMin(),heightMargin-bb.yMin(),0.0f);
344
345        // shift the text to center it.
346        for(ditr=_descriptionList.begin();
347            ditr!=_descriptionList.end();
348            ++ditr)
349        {
350            (*ditr)->setPosition((*ditr)->getPosition()+delta);
351        }
352
353        for(oitr=_optionList.begin();
354            oitr!=_optionList.end();
355            ++oitr)
356        {
357            (*oitr)->setPosition((*oitr)->getPosition()+delta);
358        }
359
360        for(eitr=_explanationList.begin();
361            eitr!=_explanationList.end();
362            ++eitr)
363        {
364            (*eitr)->setPosition((*eitr)->getPosition()+delta);
365        }
366
367
368    }
369    _helpInitialized = true;
370}
371
372void ViewerEventHandler::StatsAndHelpDrawCallback::displayStats()
373{
374    if (!_statsInitialized) createStatsText();
375
376    OsgSceneHandler* osh = _veh->getOsgCameraGroup()->getSceneHandlerList()[_cameraNumber].get();
377    osgUtil::SceneView* sv = osh->getSceneView();
378
379    // render graphs
380    if (_veh->getFrameStatsMode()>=ViewerEventHandler::CAMERA_STATS)
381    {
382
383        // Set up the Orthographic view
384        glMatrixMode( GL_PROJECTION );
385        glPushMatrix();
386        glLoadIdentity();
387        glOrtho( -.025, .128, 600.0, -10.0, -1.0, 1.0 );
388
389
390        unsigned int lindex = (_index + 1) % _fs.size();
391        Producer::Camera::TimeStamp zero = _fs[lindex]._startOfFrame;
392        unsigned int i;
393        double x1=0.0, x2=0.0, y1=0.0, y2=0.0;
394        for(unsigned int frame = 0; frame < _fs.size(); frame++ )
395        {
396            Producer::CameraGroup::FrameStats fs = _fs[(lindex + frame) % _fs.size()];
397            y1 = 0.0;
398            y2 = y1 + 10;
399            x1 = fs._startOfUpdate - zero;
400            x2 = fs._endOfUpdate   - zero;
401
402            glBegin( GL_QUADS );
403
404            // Draw Update length
405            glColor4f( 0.0, 1.0, 0.0, 0.5 );
406            glVertex2d( x1, y1);
407            glVertex2d( x2, y1);
408            glVertex2d( x2, y2);
409            glVertex2d( x1, y2);
410
411            for( i = 0; i < fs.getNumFrameTimeStampSets(); i++ )
412            {
413                Producer::Camera::FrameTimeStampSet fts = fs.getFrameTimeStampSet(i);
414                y1 += 13.0;
415                y2 = y1 + 10.0;
416                x1 = fts[Producer::Camera::BeginCull] - zero;
417                x2 = fts[Producer::Camera::EndCull]   - zero;
418
419                glColor4f( 0.0, 1.0, 1.0, 0.5 );
420                glVertex2d( x1, y1);
421                glVertex2d( x2, y1);
422                glVertex2d( x2, y2);
423                glVertex2d( x1, y2);
424
425                x1 = fts[Producer::Camera::BeginDraw] - zero;
426                x2 = fts[Producer::Camera::EndDraw]   - zero;
427
428                glColor4f( 1.0, 1.0, 0.0, 0.5 );
429                glVertex2d( x1, y1);
430                glVertex2d( x2, y1);
431                glVertex2d( x2, y2);
432                glVertex2d( x1, y2);
433
434            }
435            glEnd();
436
437            glBegin( GL_LINES );
438            glColor4f( 1, 1, 1, 0.5 );
439            glVertex2d( fs._startOfFrame - zero , 0.0 );
440            y1 = fs.getNumFrameTimeStampSets() * 13.0 + 10.0;
441            glVertex2d( fs._startOfFrame - zero, y1 );
442
443            y1 = 12.5;
444            for( i = 0; i < fs.getNumFrameTimeStampSets(); i++ )
445            {
446                y2 = y1 + 11;
447                Producer::Camera::FrameTimeStampSet fts = fs.getFrameTimeStampSet(i);
448                Producer::Camera::TimeStamp vsync = fts[Producer::Camera::Vsync];
449                double x1 = vsync - zero;
450                glColor4f( 1.0, 1.0, 0.0, 0.5 );
451                glVertex2d( x1, y1 );
452                glVertex2d( x1, y2 );
453                y1 += 13.0;
454            }
455            glEnd();   
456        }
457
458        glBegin( GL_LINES );
459
460        glColor4f( 1, 1, 1, 0.5 );
461        for( i = 0; i < 128; i++ )
462        {
463            glVertex2d((GLdouble)i*.001, y1);
464
465           if( !(i%10) )
466               glVertex2d((GLdouble)i*.001, y1 - 5.0);
467            else if( !(i%5) )
468                glVertex2d((GLdouble)i*.001, y1 - 3.0);
469            else
470                glVertex2d((GLdouble)i*.001, y1 - 1.0);
471        }
472
473        glEnd();
474
475        glMatrixMode( GL_PROJECTION );
476        glPopMatrix();
477        glMatrixMode( GL_MODELVIEW );
478       
479    }
480
481    // render the text
482    if (_veh->getFrameStatsMode()>=ViewerEventHandler::FRAME_RATE)
483    {
484        // update and draw the frame rate text.
485       
486        char tmpText[128];
487
488        _frameRateLabelText->draw(*(sv->getState()));
489
490        if (_fs.size()>1)
491        {
492            unsigned int lindex = (_index + 1) % _fs.size();
493            double timeForFrames = (_fs[_index]._startOfFrame-_fs[lindex]._startOfFrame);
494            double timePerFrame = timeForFrames/(double)(_fs.size()-1);
495            sprintf(tmpText,"%4.2f",1.0/timePerFrame);
496            _frameRateCounterText->setText(tmpText);
497        }
498        _frameRateCounterText->draw(*(sv->getState()));
499       
500
501        if (_veh->getFrameStatsMode()>=ViewerEventHandler::CAMERA_STATS)
502        {
503
504            TextList::iterator itr;
505            for(itr=_statsLabelList.begin();
506                itr!=_statsLabelList.end();
507                ++itr)
508            {
509                (*itr)->draw(*(sv->getState()));
510            }
511
512            double updateTime = 0.0;
513            std::fill(_cullTimes.begin(),_cullTimes.end(),0.0);
514            std::fill(_drawTimes.begin(),_drawTimes.end(),0.0);
515
516            for(unsigned int frame = 0; frame < _fs.size(); frame++ )
517            {
518                Producer::CameraGroup::FrameStats fs = _fs[frame];
519                updateTime += (fs._endOfUpdate-fs._startOfUpdate);
520
521                for(unsigned int i = 0; i < fs.getNumFrameTimeStampSets(); i++ )
522                {
523                    Producer::Camera::FrameTimeStampSet fts = fs.getFrameTimeStampSet(i);
524
525                    _cullTimes[i] += fts[Producer::Camera::EndCull]-fts[Producer::Camera::BeginCull];
526                    _drawTimes[i] += fts[Producer::Camera::EndDraw]-fts[Producer::Camera::BeginDraw];
527                }
528            }
529
530            sprintf(tmpText,"%4.2f",1000.0*updateTime/(double)_fs.size());
531            _updateTimeText->setText(tmpText);
532
533            _updateTimeText->draw(*(sv->getState()));
534
535            CameraTimes::iterator titr;
536            for(itr=_cullTimeText.begin(),titr = _cullTimes.begin();
537                itr!=_cullTimeText.end() && titr!=_cullTimes.end();
538                ++itr,++titr)
539            {
540                sprintf(tmpText,"%4.2f",1000.0*(*titr)/(double)_fs.size());
541                (*itr)->setText(tmpText);
542                (*itr)->draw(*(sv->getState()));
543            }
544            for(itr=_drawTimeText.begin(),titr = _drawTimes.begin();
545                itr!=_drawTimeText.end() && titr!=_drawTimes.end();
546                ++itr,++titr)
547            {
548                sprintf(tmpText,"%4.2f",1000.0*(*titr)/(double)_fs.size());
549                (*itr)->setText(tmpText);
550                (*itr)->draw(*(sv->getState()));
551            }
552        }
553       
554    }
555
556}
557
558void ViewerEventHandler::StatsAndHelpDrawCallback::createStatsText()
559{
560    _statsInitialized = true;
561
562    float characterSize = 20.0f;
563
564    osg::Vec4 colorFR(1.0f,1.0f,1.0f,1.0f);
565    osg::Vec4 colorUpdate( 0.0f,1.0f,0.0f,1.0f);
566    osg::Vec4 colorCull( 0.0f,1.0f,1.0f,1.0f);
567    osg::Vec4 colorDraw( 1.0f,1.0f,0.0f,1.0f);
568   
569    float leftPos = 10.0f;
570   
571    osg::Vec3 pos(leftPos,1000.0f,0.0f);
572
573    _frameRateLabelText = new osgText::Text;
574    _frameRateLabelText->setFont("fonts/arial.ttf");
575    _frameRateLabelText->setColor(colorFR);
576    _frameRateLabelText->setCharacterSize(characterSize);
577    _frameRateLabelText->setPosition(pos);
578    _frameRateLabelText->setAlignment(osgText::Text::BASE_LINE);
579    _frameRateLabelText->setText("Frame Rate: ");
580
581    pos.x() = _frameRateLabelText->getBound().xMax();
582
583    _frameRateCounterText = new osgText::Text;
584    _frameRateCounterText->setFont("fonts/arial.ttf");
585    _frameRateCounterText->setColor(colorFR);
586    _frameRateCounterText->setCharacterSize(characterSize);
587    _frameRateCounterText->setPosition(pos);
588    _frameRateCounterText->setAlignment(osgText::Text::BASE_LINE);
589    _frameRateCounterText->setText("0123456789.");
590
591
592    pos.x() = leftPos;
593    pos.y() -= characterSize;
594
595    {
596        osgText::Text* text = new osgText::Text;
597        text->setFont("fonts/arial.ttf");
598        text->setColor(colorUpdate);
599        text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize);
600        text->setCharacterSize(characterSize);
601        text->setPosition(pos);
602        text->setAlignment(osgText::Text::BASE_LINE);
603        text->setText("Update: ");
604
605        _statsLabelList.push_back(text);
606       
607        pos.x() = text->getBound().xMax();
608
609        _updateTimeText = new osgText::Text;
610
611        _updateTimeText->setFont("fonts/arial.ttf");
612        _updateTimeText->setColor(colorUpdate);
613        _updateTimeText->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize);
614        _updateTimeText->setCharacterSize(characterSize);
615        _updateTimeText->setPosition(pos);
616        _updateTimeText->setAlignment(osgText::Text::BASE_LINE);
617        _updateTimeText->setText("0123456789.");
618       
619    }
620
621    pos.x() = leftPos;
622    pos.y() -= characterSize;
623
624    _cullTimes.clear();
625    _drawTimes.clear();
626
627    OsgCameraGroup* ocg = _veh->getOsgCameraGroup();
628    Producer::CameraConfig* cfg = ocg->getCameraConfig();
629    for (unsigned int i=0;i<cfg->getNumberOfCameras(); ++i )
630    {
631        pos.x() = leftPos;
632
633        osgText::Text* cullLabel = new osgText::Text;
634        cullLabel->setFont("fonts/arial.ttf");
635        cullLabel->setColor(colorCull);
636        cullLabel->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize);
637        cullLabel->setCharacterSize(characterSize);
638        cullLabel->setPosition(pos);
639        cullLabel->setAlignment(osgText::Text::BASE_LINE);
640        cullLabel->setText("Cull: ");
641
642        _statsLabelList.push_back(cullLabel);
643       
644        pos.x() = cullLabel->getBound().xMax();
645
646        osgText::Text* cullField = new osgText::Text;
647
648        cullField->setFont("fonts/arial.ttf");
649        cullField->setColor(colorCull);
650        cullField->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize);
651        cullField->setCharacterSize(characterSize);
652        cullField->setPosition(pos);
653        cullField->setAlignment(osgText::Text::BASE_LINE);
654        cullField->setText("1000.00");
655       
656        _cullTimes.push_back(0.0);
657       
658        _cullTimeText.push_back(cullField);
659
660        pos.x() = cullField->getBound().xMax();
661
662
663        osgText::Text* drawLabel = new osgText::Text;
664        drawLabel->setFont("fonts/arial.ttf");
665        drawLabel->setColor(colorDraw);
666        drawLabel->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize);
667        drawLabel->setCharacterSize(characterSize);
668        drawLabel->setPosition(pos);
669        drawLabel->setAlignment(osgText::Text::BASE_LINE);
670        drawLabel->setText("Draw: ");
671
672        _statsLabelList.push_back(drawLabel);
673       
674        pos.x() = drawLabel->getBound().xMax();
675
676        osgText::Text* drawField = new osgText::Text;
677
678        drawField->setFont("fonts/arial.ttf");
679        drawField->setColor(colorDraw);
680        drawField->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize);
681        drawField->setCharacterSize(characterSize);
682        drawField->setPosition(pos);
683        drawField->setAlignment(osgText::Text::BASE_LINE);
684        drawField->setText("1000.00");
685       
686        _drawTimeText.push_back(drawField);
687
688        _drawTimes.push_back(0.0);
689
690        pos.y() -= characterSize;
691    }
692
693
694}
695
696void ViewerEventHandler::StatsAndHelpDrawCallback::displayInfo()
697{
698}
699
700void ViewerEventHandler::StatsAndHelpDrawCallback::createInfoText()
701{
702}
703
704
705
706ViewerEventHandler::ViewerEventHandler(OsgCameraGroup* cg):
707    _cg(cg),
708    _writeNodeFileName("saved_model.osg"),
709    _displayHelp(false),
710    _frameStatsMode(NO_STATS),
711    _firstTimeTogglingFullScreen(true)
712{
713    Producer::CameraConfig* cfg = _cg->getCameraConfig();
714    Producer::Camera *cam = cfg->getCamera(0);
715   
716    _statsAndHelpDrawCallback = new StatsAndHelpDrawCallback(this,0);
717    cam->addPostDrawCallback(_statsAndHelpDrawCallback);
718
719    std::string basename("saved_image");
720    std::string ext(".jpg");
721    if (cfg->getNumberOfCameras()==1)
722    {
723        SnapImageDrawCallback* snapImageDrawCallback = new SnapImageDrawCallback(basename+ext);
724        cam->addPostDrawCallback(snapImageDrawCallback);
725        _snapImageDrawCallbackList.push_back(snapImageDrawCallback);
726    }
727    else
728    {
729        for(unsigned int i=0;i<cfg->getNumberOfCameras();++i)
730        {
731            std::string filename(basename+"_");
732            filename += ('0'+i);
733            filename += ext;
734            SnapImageDrawCallback* snapImageDrawCallback = new SnapImageDrawCallback(filename);
735            cfg->getCamera(i)->addPostDrawCallback(snapImageDrawCallback);
736            _snapImageDrawCallbackList.push_back(snapImageDrawCallback);
737        }
738    }
739}
740
741bool ViewerEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
742{
743    if(!_cg) return false;
744
745    if(ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN)
746    {
747
748        switch( ea.getKey() )
749        {
750            case 's' :
751            {
752                _frameStatsMode = (FrameStatsMode)((_frameStatsMode+1)%3);
753                if (_frameStatsMode==NO_STATS)
754                {
755                    _cg->setInstrumentationMode(false);
756                }
757                else
758                {
759                    _cg->setInstrumentationMode(true);
760                }
761                return true;
762            }
763            case 'v' :
764            {
765                bool block = !_cg->getBlockOnVsync();
766                _cg->setBlockOnVsync(block);
767                for(unsigned int i=0;i<_cg->getNumberOfCameras();++i)
768                {
769                    _cg->getCamera(i)->setBlockOnVsync(block);
770                }
771                return true;
772            }
773
774            case 'f' :
775            {
776                Producer::CameraConfig* cfg = _cg->getCameraConfig();
777                for( unsigned int i = 0; i < cfg->getNumberOfCameras(); ++i )
778                {
779                    Producer::Camera *cam = cfg->getCamera(i);
780                    Producer::RenderSurface* rs = cam->getRenderSurface();
781                   
782                    if (_firstTimeTogglingFullScreen && rs->isFullScreen())
783                    {
784                        unsigned int screenWidth;
785                        unsigned int screenHeight;
786                        rs->getScreenSize( screenWidth, screenHeight );
787                        unsigned int windowWidth  = (unsigned int)((float)screenWidth * 0.625);
788                        unsigned int windowHeight = (unsigned int)((float)windowWidth * 0.75);
789                        int x = (screenWidth - windowWidth) >> 1;
790                        int y = (screenHeight - windowHeight) >> 1;
791                    #ifndef WIN32                   
792                        rs->useBorder(true);
793                    #else                       
794                        rs->fullScreen(false);
795                    #endif
796                        rs->setWindowRectangle( x, y, windowWidth, windowHeight );
797                    }
798                    else
799                    {
800                        rs->fullScreen(!rs->isFullScreen());
801                    }
802                }
803                _firstTimeTogglingFullScreen = false;
804
805                return true;
806            }
807
808            case 'o' :
809            {
810                osg::Node* node = _cg->getSceneData();
811                if (node)
812                {
813                    if (osgDB::writeNodeFile(*node,_writeNodeFileName.c_str()))
814                    {
815                        std::cout<<"written nodes to file "<<_writeNodeFileName<<std::endl;
816                    }
817                }
818
819                return true;
820            }
821
822            case osgGA::GUIEventAdapter::KEY_Print :
823            case 'O' :
824            {
825                for(SnapImageDrawCallbackList::iterator itr=_snapImageDrawCallbackList.begin();
826                    itr!=_snapImageDrawCallbackList.end();
827                    ++itr)
828                {
829                    (*itr)->setSnapImageOnNextFrame(true);
830                }
831               
832                return true;
833            }
834            case '+' :
835            {
836                //_camera->setFusionDistanceRatio(_camera->getFusionDistanceRatio()*1.25f);
837                return true;
838            }
839            case '-' :
840            {
841                //_camera->setFusionDistanceRatio(_camera->getFusionDistanceRatio()/1.25f);
842                return true;
843            }
844
845            case '*' :
846            case '/' :
847            {
848                if (ea.getKey()=='*') _cg->setLODScale( _cg->getLODScale() * 1.1f);
849                else _cg->setLODScale( _cg->getLODScale() / 1.1f);
850                std::cout<<"New LOD Scale = "<<_cg->getLODScale()<<std::endl;
851                return true;
852            }
853
854            case osgGA::GUIEventAdapter::KEY_Help :
855            case 'h' :
856            {
857                setDisplayHelp(!getDisplayHelp());
858                return true;
859            }
860            case 'Z' :
861            case 'z' :
862            {
863                osgProducer::Viewer* viewer = dynamic_cast<osgProducer::Viewer*>(_cg);
864                if (viewer)
865                {
866                    if (viewer->getRecordingAnimationPath())
867                    {
868                        // have already been recording so switch of recording.
869                        viewer->setRecordingAnimationPath(false);
870
871                        osg::notify(osg::NOTICE) << "finished recording camera animation, press 'Z' to replay."<< std::endl;
872
873                        if (viewer->getAnimationPath())
874                        {
875                            std::ofstream fout("saved_animation.path");
876                            viewer->getAnimationPath()->write(fout);
877                            fout.close();
878
879                            osg::notify(osg::NOTICE) << "Saved camera animation to 'saved_animation.path'"<< std::endl;
880
881                        }
882
883                    }
884                    else if (ea.getKey()=='z')
885                    {
886                        viewer->setRecordingAnimationPath(true);
887                        viewer->setAnimationPath(new osg::AnimationPath());
888                        viewer->getAnimationPath()->setLoopMode(osg::AnimationPath::LOOP);
889                        osg::notify(osg::NOTICE) << "Recording camera animation, press 'z' to finish recording."<< std::endl;
890                    }
891
892                    if (ea.getKey()=='Z')
893                    {
894                        osgGA::AnimationPathManipulator* apm = 0;
895                        unsigned int apmNo = 0;
896                       
897                        osgGA::KeySwitchMatrixManipulator* kscm = viewer->getKeySwitchMatrixManipulator();
898                        if (kscm)
899                        {
900                            for(apmNo=0;apmNo<kscm->getNumMatrixManipulators() && apm==0;++apmNo)
901                            {
902                                apm = dynamic_cast<osgGA::AnimationPathManipulator*>(kscm->getMatrixManipulator(apmNo));
903                            }
904                        }
905
906                        if (!apm)
907                        {
908                            apm = new osgGA::AnimationPathManipulator();
909                            apmNo = viewer->addCameraManipulator(apm);
910                        }
911
912                        apm->setAnimationPath(viewer->getAnimationPath());
913                        apm->home(ea,aa);
914
915                        viewer->selectCameraManipulator(apmNo);
916                    }
917
918                    break;
919                }
920                return true;
921            }
922
923        default:
924            break;
925
926        }
927    }
928    return false;
929
930}
931
932void ViewerEventHandler::accept(osgGA::GUIEventHandlerVisitor& gehv)
933{
934    gehv.visit(*this);
935}
936
937void ViewerEventHandler::getUsage(osg::ApplicationUsage& usage) const
938{
939    usage.addKeyboardMouseBinding("f","Toggle fullscreen");
940    usage.addKeyboardMouseBinding("h","Display help");
941    usage.addKeyboardMouseBinding("o","Write scene graph to \"saved_model.osg\"");
942    usage.addKeyboardMouseBinding("O PrtSrn","Write camera images to \"saved_image*.rgb\"");
943    usage.addKeyboardMouseBinding("s","Toggle instrumention");
944    usage.addKeyboardMouseBinding("v","Toggle block and vsync");
945    usage.addKeyboardMouseBinding("z","Start recording camera path.");
946    usage.addKeyboardMouseBinding("Z","If recording camera path stop recording camera path, save to \"saved_animation.path\"\nThen start viewing from being on animation path");
947//    usage.addKeyboardMouseBinding("+","When in stereo, increase the fusion distance");
948//    usage.addKeyboardMouseBinding("-","When in stereo, reduse the fusion distance");
949}
Note: See TracBrowser for help on using the browser.