root/OpenSceneGraph/trunk/src/osgPresentation/SlideEventHandler.cpp @ 13041

Revision 13041, 37.6 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
2 *
3 * This software is open source and may be redistributed and/or modified under
4 * the terms of the GNU General Public License (GPL) version 2.0.
5 * The full license is in LICENSE.txt file included with this distribution,.
6 *
7 * This software 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 * include LICENSE.txt for more details.
11*/
12
13#include <osgPresentation/SlideEventHandler>
14#include <osgPresentation/SlideShowConstructor>
15
16#include <osg/AnimationPath>
17#include <osg/Transform>
18#include <osg/TexEnvCombine>
19#include <osg/LightSource>
20#include <osg/AlphaFunc>
21#include <osg/io_utils>
22
23#include <osgUtil/TransformCallback>
24#include <osgUtil/GLObjectsVisitor>
25
26#include <osgGA/AnimationPathManipulator>
27
28#include <osgPresentation/AnimationMaterial>
29
30#include <iostream>
31
32using namespace osgPresentation;
33
34static osg::observer_ptr<SlideEventHandler> s_seh;
35
36SlideEventHandler* SlideEventHandler::instance() { return s_seh.get(); }
37
38void LayerAttributes::callEnterCallbacks(osg::Node* node)
39{
40    OSG_INFO<<"LayerAttributes::callEnterCallbacks("<<node<<")"<<std::endl;
41    for(LayerCallbacks::iterator itr = _enterLayerCallbacks.begin();
42        itr != _enterLayerCallbacks.end();
43        ++itr)
44    {
45        (*(*itr))(node);
46    }
47}
48
49void LayerAttributes::callLeaveCallbacks(osg::Node* node)
50{
51    OSG_INFO<<"LayerAttributes::callLeaveCallbacks("<<node<<")"<<std::endl;
52    for(LayerCallbacks::iterator itr = _leaveLayerCallbacks.begin();
53        itr != _leaveLayerCallbacks.end();
54        ++itr)
55    {
56        (*(*itr))(node);
57    }
58}
59
60
61struct ImageStreamOperator : public ObjectOperator
62{
63    ImageStreamOperator(osg::ImageStream* imageStream):
64        _imageStream(imageStream) {}
65
66    virtual void* ptr() const { return _imageStream.get(); }
67
68    virtual void enter()
69    {
70        OSG_INFO<<"enter() : _imageStream->rewind() + play"<<std::endl;
71
72        reset();
73    }
74
75    virtual void maintain()
76    {
77    }
78
79    virtual void leave()
80    {
81       OSG_INFO<<"leave() : _imageStream->pause()"<<std::endl;
82
83        _imageStream->pause();
84    }
85
86    virtual void setPause(bool pause)
87    {
88       OSG_INFO<<"_imageStream->setPause("<<pause<<")"<<std::endl;
89
90        if (pause) _imageStream->pause();
91        else _imageStream->play();
92    }
93
94    virtual void reset()
95    {
96        osg::ImageStream::StreamStatus previousStatus = _imageStream->getStatus();
97
98        _imageStream->rewind();
99
100
101        //_imageStream->setVolume(previousVolume);
102
103        if(previousStatus==osg::ImageStream::PLAYING)
104        {
105            _imageStream->play();
106        }
107
108        // add a delay so that movie thread has a chance to do the rewind
109        float microSecondsToDelay = SlideEventHandler::instance()->getTimeDelayOnNewSlideWithMovies() * 1000000.0f;
110        OpenThreads::Thread::microSleep(static_cast<unsigned int>(microSecondsToDelay));
111    }
112
113    osg::ref_ptr<osg::ImageStream>  _imageStream;
114};
115
116struct CallbackOperator : public ObjectOperator
117{
118    CallbackOperator(osg::Node* node, osg::Referenced* callback):
119        _node(node),
120        _callback(callback) {}
121
122    virtual void* ptr() const { return _callback.get(); }
123
124    virtual void enter()
125    {
126        reset();
127    }
128
129    virtual void maintain()
130    {
131    }
132
133    virtual void leave()
134    {
135    }
136
137    virtual void setPause(bool pause)
138    {
139        osg::AnimationPathCallback* apc = dynamic_cast<osg::AnimationPathCallback*>(_callback.get());
140        osgUtil::TransformCallback* tc = dynamic_cast<osgUtil::TransformCallback*>(_callback.get());
141        AnimationMaterialCallback* amc = dynamic_cast<AnimationMaterialCallback*>(_callback.get());
142        if (apc)
143        {
144            OSG_INFO<<"apc->setPause("<<pause<<")"<<std::endl;
145            apc->setPause(pause);
146        }
147        if (tc)
148        {
149            OSG_INFO<<"tc->setPause("<<pause<<")"<<std::endl;
150            tc->setPause(pause);
151        }
152        if (amc)
153        {
154            OSG_INFO<<"amc->setPause("<<pause<<")"<<std::endl;
155            amc->setPause(pause);
156        }
157    }
158
159    virtual void reset()
160    {
161        osg::AnimationPathCallback* apc = dynamic_cast<osg::AnimationPathCallback*>(_callback.get());
162        osgUtil::TransformCallback* tc = dynamic_cast<osgUtil::TransformCallback*>(_callback.get());
163        AnimationMaterialCallback* amc = dynamic_cast<AnimationMaterialCallback*>(_callback.get());
164        if (apc)
165        {
166            apc->reset();
167            apc->update(*_node);
168        }
169        if (tc)
170        {
171        }
172        if (amc)
173        {
174            amc->reset();
175            amc->update(*_node);
176        }
177    }
178
179
180    osg::ref_ptr<osg::Node>         _node;
181    osg::ref_ptr<osg::Referenced>   _callback;
182};
183
184struct LayerAttributesOperator : public ObjectOperator
185{
186    LayerAttributesOperator(osg::Node* node, LayerAttributes* la):
187        _node(node),
188        _layerAttribute(la)
189    {
190    }
191
192    virtual void* ptr() const { return _layerAttribute.get(); }
193
194    virtual void enter()
195    {
196        _layerAttribute->callEnterCallbacks(_node.get());
197
198        if (!_layerAttribute->_keys.empty())
199        {
200            OSG_INFO<<"applyKeys {"<<std::endl;
201
202            for(LayerAttributes::Keys::iterator itr = _layerAttribute->_keys.begin();
203                itr != _layerAttribute->_keys.end();
204                ++itr)
205            {
206                SlideEventHandler::instance()->dispatchEvent(*itr);
207            }
208
209            OSG_INFO<<"}"<<std::endl;
210        }
211        if (!_layerAttribute->_runStrings.empty())
212        {
213            for(LayerAttributes::RunStrings::iterator itr = _layerAttribute->_runStrings.begin();
214                itr != _layerAttribute->_runStrings.end();
215                ++itr)
216            {
217
218                OSG_NOTICE<<"Run "<<itr->c_str()<<std::endl;
219                osg::Timer_t startTick = osg::Timer::instance()->tick();
220
221                int result = system(itr->c_str());
222
223                OSG_INFO<<"system("<<*itr<<") result "<<result<<std::endl;
224
225                double timeForRun = osg::Timer::instance()->delta_s(startTick, osg::Timer::instance()->tick());
226
227                osgGA::EventQueue* eq = SlideEventHandler::instance()->getViewer()->getEventQueue();
228                if (eq)
229                {
230                    osg::Timer_t new_startTick = eq->getStartTick() + osg::Timer_t(timeForRun / osg::Timer::instance()->getSecondsPerTick());
231                    eq->setStartTick(new_startTick);
232                }
233            }
234        }
235
236    }
237
238    virtual void maintain()
239    {
240    }
241
242    virtual void leave()
243    {
244        OSG_INFO<<"LayerAttribute leave"<<std::endl;
245
246         _layerAttribute->callLeaveCallbacks(_node.get());
247    }
248
249    virtual void setPause(bool pause)
250    {
251    }
252
253    virtual void reset()
254    {
255    }
256
257
258    osg::ref_ptr<osg::Node>                             _node;
259    osg::ref_ptr<LayerAttributes> _layerAttribute;
260};
261
262
263class FindOperatorsVisitor : public osg::NodeVisitor
264{
265public:
266    FindOperatorsVisitor(ActiveOperators::OperatorList& operatorList, osg::NodeVisitor::TraversalMode tm):
267        osg::NodeVisitor(tm),
268        _operatorList(operatorList) {}
269
270    void apply(osg::Node& node)
271    {
272        if (node.getStateSet()) process(node.getStateSet());
273
274        if (node.getUpdateCallback())
275        {
276            _operatorList.insert(new CallbackOperator(&node, node.getUpdateCallback()));
277        }
278
279        LayerAttributes* la = dynamic_cast<LayerAttributes*>(node.getUserData());
280        if (la)
281        {
282            _operatorList.insert(new LayerAttributesOperator(&node, la));
283        }
284
285        traverse(node);
286    }
287
288    void apply(osg::Geode& node)
289    {
290        apply((osg::Node&)node);
291        for(unsigned int i=0;i<node.getNumDrawables();++i)
292        {
293            osg::Drawable* drawable = node.getDrawable(i);
294            if (drawable->getStateSet()) process(drawable->getStateSet());
295        }
296    }
297
298    virtual void process(osg::StateSet* ss)
299    {
300        for(unsigned int i=0;i<ss->getTextureAttributeList().size();++i)
301        {
302            osg::Texture* texture = dynamic_cast<osg::Texture*>(ss->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
303            osg::Image* image = texture ? texture->getImage(0) : 0;
304            osg::ImageStream* imageStream = image ? dynamic_cast<osg::ImageStream*>(image) : 0;
305            if (imageStream)
306            {
307                _operatorList.insert(new ImageStreamOperator(imageStream));
308            }
309        }
310    }
311
312    ActiveOperators::OperatorList& _operatorList;
313};
314
315
316ActiveOperators::ActiveOperators():
317    _pause(false)
318{
319}
320
321ActiveOperators::~ActiveOperators()
322{
323}
324
325void ActiveOperators::collect(osg::Node* incommingNode, osg::NodeVisitor::TraversalMode tm)
326{
327    _previous.swap(_current);
328
329    _current.clear();
330
331    FindOperatorsVisitor fov(_current, tm);
332    incommingNode->accept(fov);
333
334    OSG_INFO<<"ActiveOperators::collect("<<incommingNode<<")"<<std::endl;
335    OSG_INFO<<"  _previous.size()="<<_previous.size()<<std::endl;
336    OSG_INFO<<"  _current.size()="<<_current.size()<<std::endl;
337
338    _outgoing.clear();
339    _incomming.clear();
340    _maintained.clear();
341
342    for(OperatorList::iterator itr = _previous.begin();
343        itr != _previous.end();
344        ++itr)
345    {
346        ObjectOperator* prev = itr->get();
347        if (_current.count(prev)==0) _outgoing.insert(prev);
348        else _maintained.insert(prev);
349    }
350
351    for(OperatorList::iterator itr = _current.begin();
352        itr != _current.end();
353        ++itr)
354    {
355        ObjectOperator* curr = itr->get();
356        if (_previous.count(curr)==0) _incomming.insert(curr);
357    }
358}
359
360void ActiveOperators::setPause(bool pause)
361{
362    _pause = pause;
363    for(OperatorList::iterator itr = _current.begin();
364        itr != _current.end();
365        ++itr)
366    {
367        (*itr)->setPause(_pause);
368    }
369}
370
371
372void ActiveOperators::reset()
373{
374    for(OperatorList::iterator itr = _current.begin();
375        itr != _current.end();
376        ++itr)
377    {
378        (*itr)->reset();
379    }
380}
381
382void ActiveOperators::process()
383{
384    processOutgoing();
385    processMaintained();
386    processIncomming();
387}
388
389void ActiveOperators::processOutgoing()
390{
391    OSG_INFO<<"  outgoing.size()="<<_outgoing.size()<<std::endl;
392    for(OperatorList::iterator itr = _outgoing.begin();
393        itr != _outgoing.end();
394        ++itr)
395    {
396        (*itr)->leave();
397    }
398}
399
400void ActiveOperators::processMaintained()
401{
402    OSG_INFO<<"  maintained.size()="<<_maintained.size()<<std::endl;
403    for(OperatorList::iterator itr = _maintained.begin();
404        itr != _maintained.end();
405        ++itr)
406    {
407        (*itr)->maintain();
408    }
409}
410
411void ActiveOperators::processIncomming()
412{
413    OSG_INFO<<"  incomming.size()="<<_incomming.size()<<std::endl;
414    for(OperatorList::iterator itr = _incomming.begin();
415        itr != _incomming.end();
416        ++itr)
417    {
418        (*itr)->enter();
419        (*itr)->setPause(_pause);
420    }
421}
422
423
424
425
426class FindHomePositionVisitor : public osg::NodeVisitor
427{
428public:
429
430    FindHomePositionVisitor():
431        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN) {}
432
433    void apply(osg::Node& node)
434    {
435        HomePosition* homePosition = dynamic_cast<HomePosition*>(node.getUserData());
436        if (homePosition)
437        {
438            _homePosition = homePosition;
439        }
440
441        traverse(node);
442    }
443
444    osg::ref_ptr<HomePosition> _homePosition;
445
446};
447
448class FindNamedSwitchVisitor : public osg::NodeVisitor
449{
450public:
451
452    FindNamedSwitchVisitor(const std::string& name):
453        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
454        _name(name),
455        _switch(0) {}
456
457    void apply(osg::Switch& sw)
458    {
459        if (sw.getName().find(_name)!=std::string::npos)
460        {
461            _switch = &sw;
462            return; // note, no need to do traverse now we've located the relevant switch
463        }
464
465        traverse(sw);
466    }
467
468    std::string     _name;
469    osg::Switch*    _switch;
470
471};
472
473
474class FindFilePathDataVisitor : public osg::NodeVisitor
475{
476public:
477
478    FindFilePathDataVisitor():
479        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN) {}
480
481    void apply(osg::Node& node)
482    {
483        FilePathData* fdd = dynamic_cast<FilePathData*>(node.getUserData());
484        if (fdd)
485        {
486            OSG_INFO<<"Recorded FilePathData"<<std::endl;
487            osgDB::setDataFilePathList(fdd->filePathList);
488        }
489
490        traverse(node);
491    }
492
493};
494
495class UpdateLightVisitor : public osg::NodeVisitor
496{
497public:
498
499    UpdateLightVisitor(const osg::Matrixd& viewMatrix, float currentX, float currentY):
500        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
501        _viewMatrix(viewMatrix),
502        _currentX(currentX), _currentY(currentY) {}
503
504    void apply(osg::Node& node)
505    {
506        traverse(node);
507    }
508
509    void apply(osg::LightSource& lightsource)
510    {
511        if (lightsource.getLight())
512        {
513            if (lightsource.getReferenceFrame()==osg::LightSource::RELATIVE_RF)
514            {
515                apply( osg::Matrix::identity(), lightsource.getLight());
516            }
517            else
518            {
519                apply(osg::computeEyeToLocal(_viewMatrix,_nodePath), lightsource.getLight());
520            }
521        }
522
523        traverse(lightsource);
524    }
525
526    void apply(const osg::Matrixd& matrix, osg::Light* light)
527    {
528        // compute direction of light based on a projecting onto a hemi-sphere.
529        float sum_x2_y2 = _currentX*_currentX + _currentY*_currentY;
530        osg::Vec3 direction;
531        if (sum_x2_y2<1.0) direction.set(_currentX, _currentY, sqrtf(1.0-sum_x2_y2));
532        else direction.set(_currentX, _currentY, 0.0);
533
534        direction.normalize();
535
536        direction = osg::Matrixd::transform3x3(matrix, direction);
537        direction.normalize();
538
539        light->setPosition(osg::Vec4(direction,0.0f));
540    }
541
542    osg::Matrixd    _viewMatrix;
543    float           _currentX, _currentY;
544
545};
546
547class UpdateAlphaVisitor : public osg::NodeVisitor
548{
549public:
550
551    UpdateAlphaVisitor(bool modAlphaFunc, bool modMaterial, float currentX, float currentY):
552        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
553        _modAlphaFunc(modAlphaFunc), _modMaterial(modMaterial),
554        _currentX(currentX), _currentY(currentY) {}
555
556    void apply(osg::Node& node)
557    {
558        if (node.getStateSet()) apply(*node.getStateSet());
559        traverse(node);
560    }
561
562    void apply(osg::StateSet& stateset)
563    {
564        if (_modAlphaFunc)
565        {
566            osg::AlphaFunc* alphaFunc = dynamic_cast<osg::AlphaFunc*>(stateset.getAttribute(osg::StateAttribute::ALPHAFUNC));
567            if (alphaFunc)
568            {
569                OSG_INFO<<"Adjusting alpha func"<<std::endl;
570
571                float alpha = alphaFunc->getReferenceValue();
572                alpha = osg::clampBetween((1.0f-_currentY)*0.5f,0.0f,1.0f);
573
574                alphaFunc->setReferenceValue(alpha);
575            }
576        }
577
578        if (_modMaterial)
579        {
580            osg::Material* material = dynamic_cast<osg::Material*>(stateset.getAttribute(osg::StateAttribute::MATERIAL));
581            if (material)
582            {
583                OSG_INFO<<"Adjusting material func"<<std::endl;
584                float alpha = osg::clampBetween((_currentY+1.0f)*0.5f,0.0f,1.0f);
585                material->setAlpha(osg::Material::FRONT_AND_BACK,alpha);
586            }
587        }
588    }
589
590    bool _modAlphaFunc, _modMaterial;
591    float   _currentX, _currentY;
592
593};
594
595
596///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
597//
598// SlideEventHandler
599//
600SlideEventHandler::SlideEventHandler(osgViewer::Viewer* viewer):
601    _viewer(viewer),
602    _presentationSwitch(0),
603    _activeSlide(0),
604    _slideSwitch(0),
605    _activeLayer(0),
606    _firstTraversal(true),
607    _previousTime(-1.0f),
608    _timePerSlide(1.0),
609    _autoSteppingActive(false),
610    _loopPresentation(false),
611    _pause(false),
612    _hold(false),
613    _updateLightActive(false),
614    _updateOpacityActive(false),
615    _previousX(0), _previousY(0),
616    _cursorOn(true),
617    _releaseAndCompileOnEachNewSlide(false),
618    _firstSlideOrLayerChange(true),
619    _tickAtFirstSlideOrLayerChange(0),
620    _tickAtLastSlideOrLayerChange(0),
621    _timeDelayOnNewSlideWithMovies(0.25f),
622    _minimumTimeBetweenKeyPresses(0.25),
623    _timeLastKeyPresses(-1.0),
624    _requestReload(false)
625{
626    s_seh = this;
627}
628
629double SlideEventHandler::getDuration(const osg::Node* node) const
630{
631    const LayerAttributes* la = dynamic_cast<const LayerAttributes*>(node->getUserData());
632    return la ? la->_duration : -1.0;
633}
634
635void SlideEventHandler::set(osg::Node* model)
636{
637#if 0
638    // pause all slides, then just reenable the current slide.
639    ActivityUpdateCallbacksVisitor aucv(ALL_OBJECTS, true);
640    aucv.setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
641    model->accept(aucv);
642#endif
643    _firstSlideOrLayerChange = true;
644    _tickAtFirstSlideOrLayerChange = 0;
645    _tickAtLastSlideOrLayerChange = 0;
646    _timeLastKeyPresses = -1;
647
648    ActiveOperators operators;
649    operators.collect(model, osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
650    operators.setPause(true);
651
652    FindNamedSwitchVisitor findPresentation("Presentation");
653    model->accept(findPresentation);
654
655    if (findPresentation._switch)
656    {
657        OSG_INFO<<"Presentation '"<<model->getName()<<"'"<<std::endl;
658        _presentationSwitch = findPresentation._switch;
659
660        double duration = getDuration(_presentationSwitch.get());
661        if (duration>=0.0)
662        {
663            OSG_INFO<<"Presentation time set to "<<duration<<std::endl;
664            _timePerSlide = duration;
665        }
666
667        //selectSlide(0);
668    }
669    else
670    {
671        OSG_INFO<<"No presentation present in scene."<<std::endl;
672
673        _presentationSwitch = 0;
674        _activeSlide = 0;
675
676        FindNamedSwitchVisitor findSlide("Slide");
677        model->accept(findSlide);
678
679        if (findSlide._switch)
680        {
681            OSG_INFO<<"Found presentation slide"<<findSlide._switch->getName()<<std::endl;
682
683            _slideSwitch = findSlide._switch;
684            //selectLayer(0);
685        }
686        else
687        {
688            OSG_INFO<<"No slides present in scene, unable to operate as a slideshow."<<std::endl;
689        }
690
691    }
692}
693
694double SlideEventHandler::getCurrentTimeDelayBetweenSlides() const
695{
696    if (_slideSwitch.valid())
697    {
698        double duration = -1.0;
699        if (_activeLayer<static_cast<int>(_slideSwitch->getNumChildren()))
700        {
701            duration = getDuration(_slideSwitch->getChild(_activeLayer));
702        }
703
704        if (duration < 0.0)
705        {
706            duration = getDuration(_slideSwitch.get());
707        }
708
709        if (duration >=0 )
710        {
711            return duration;
712        }
713    }
714
715    return _timePerSlide;
716}
717
718
719void SlideEventHandler::operator()(osg::Node* node, osg::NodeVisitor* nv)
720{
721    osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
722    if (ev)
723    {
724        if (node->getNumChildrenRequiringEventTraversal()>0) traverse(node,nv);
725
726        if (ev->getActionAdapter() && !ev->getEvents().empty())
727        {
728            for(osgGA::EventQueue::Events::iterator itr = ev->getEvents().begin();
729                itr != ev->getEvents().end();
730                ++itr)
731            {
732                handleWithCheckAgainstIgnoreHandledEventsMask(*(*itr), *(ev->getActionAdapter()), node, nv);
733            }
734        }
735    }
736}
737
738bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
739{
740
741    if (!_viewer)
742    {
743        _viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
744        selectSlide(0);
745        home();
746        OSG_NOTICE<<"Assigned viewer. to SlideEventHandler"<<std::endl;
747    }
748    //else  OSG_NOTICE<<"SlideEventHandler::handle() "<<ea.getTime()<<std::endl;
749
750
751    if (ea.getHandled()) return false;
752
753    switch(ea.getEventType())
754    {
755        case(osgGA::GUIEventAdapter::FRAME):
756        {
757            if (_autoSteppingActive && !_pause)
758            {
759                double time = ea.time();
760
761                if (_firstTraversal)
762                {
763                    _firstTraversal = false;
764                    _previousTime = time;
765                }
766                else if (time-_previousTime>=getCurrentTimeDelayBetweenSlides())
767                {
768                    // _previousTime = time;
769
770                    if (!_hold)
771                    {
772                        // increment the previous by the required time delay, note relative to the current
773                        // to keep the time relative to an absolute time signal, thus avoid drift of timing.
774                        _previousTime += getCurrentTimeDelayBetweenSlides();
775
776                        nextLayerOrSlide();
777                    }
778                    else
779                    {
780                        // we're holding of the move to next layer to slide, but we need slip the time forward accordingly
781                        // componensate for the extra time that this frame is recieving.
782                        _previousTime = time-getCurrentTimeDelayBetweenSlides();
783                    }
784                }
785            }
786            return false;
787        }
788
789        case(osgGA::GUIEventAdapter::KEYDOWN):
790        {
791            double time = ea.time();
792            double deltaTime = time - _timeLastKeyPresses;
793            if (deltaTime < _minimumTimeBetweenKeyPresses)
794            {
795                 break;
796            }
797
798            _timeLastKeyPresses = time;
799
800            if (ea.getKey()=='g')
801            {
802                if (!_autoSteppingActive)
803                {
804                    _autoSteppingActive = true;
805                    _previousTime = ea.time();
806                }
807                return true;
808            }
809            else if (ea.getKey()=='h')
810            {
811                if (_autoSteppingActive)
812                {
813                    _autoSteppingActive = false;
814                    _previousTime = ea.time();
815                }
816                return true;
817            }
818            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Home ||
819                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Home)
820            {
821                _autoSteppingActive = false;
822                selectSlide(0);
823                home(ea,aa);
824                return true;
825            }
826            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_End ||
827                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_End)
828            {
829                _autoSteppingActive = false;
830                selectSlide(LAST_POSITION,LAST_POSITION);
831                home(ea,aa);
832                return true;
833            }
834            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Down ||
835                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Down)
836            {
837                _autoSteppingActive = false;
838                nextLayer();
839                return true;
840            }
841            else if (ea.getKey()=='n')
842            {
843                _autoSteppingActive = false;
844                nextLayerOrSlide();
845                return true;
846            }
847            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Up ||
848                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Up)
849            {
850                _autoSteppingActive = false;
851                previousLayer();
852                return true;
853            }
854            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Down ||
855                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Down)
856            {
857                _autoSteppingActive = false;
858                nextLayerOrSlide();
859                return true;
860            }
861            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Up ||
862                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Up)
863            {
864                _autoSteppingActive = false;
865                previousLayerOrSlide();
866                return true;
867            }
868            else if (ea.getKey()=='N' ||
869                     ea.getKey()==osgGA::GUIEventAdapter::KEY_Right ||
870                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Right)
871            {
872                _autoSteppingActive = false;
873                nextSlide();
874                home(ea,aa);
875                return true;
876            }
877            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left ||
878                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left)
879            {
880                _autoSteppingActive = false;
881                previousSlide();
882                home(ea,aa);
883                return true;
884            }
885            else if (ea.getKey()=='p')
886            {
887                if (!_pause)
888                {
889                    _pause = true;
890#if 0
891                    resetUpdateCallbackActivity(ALL_OBJECTS);
892#endif
893                    _activeOperators.setPause(_pause);
894                }
895
896                return true;
897
898            }
899            else if (ea.getKey()=='o')
900            {
901                if (_pause)
902                {
903                    _pause = false;
904#if 0
905                    resetUpdateCallbackActivity(ALL_OBJECTS);
906#endif
907                    _activeOperators.setPause(_pause);
908                }
909                return true;
910
911            }
912            else if (ea.getKey()=='h')
913            {
914                _hold = true;
915                return true;
916            }
917            else if (ea.getKey()=='r')
918            {
919#if 0
920                resetUpdateCallbacks(ALL_OBJECTS);
921#endif
922                _activeOperators.reset();
923                return true;
924            }
925/*
926            else if (ea.getKey()=='c')
927            {
928                _cursorOn = !_cursorOn;
929
930                for( unsigned int i = 0; i < _viewer->getCameraConfig()->getNumberOfCameras(); i++ )
931                {
932                    Producer::Camera* cam = _viewer->getCameraConfig()->getCamera(i);
933                    Producer::RenderSurface* rs = cam->getRenderSurface();
934                    rs->useCursor(_cursorOn);
935                }
936
937                return true;
938            }
939*/
940            else if (ea.getKey()=='u')
941            {
942                updateAlpha(true,false,ea.getXnormalized(),ea.getYnormalized());
943                return true;
944            }
945            else if (ea.getKey()=='i')
946            {
947                updateAlpha(false,true,ea.getXnormalized(),ea.getYnormalized());
948                return true;
949            }
950            else if (ea.getKey()=='k')
951            {
952                updateLight(ea.getXnormalized(),ea.getYnormalized());
953                return true;
954            }
955
956            return false;
957        }
958        case(osgGA::GUIEventAdapter::KEYUP):
959        {
960            if (ea.getKey()=='h')
961            {
962                _hold = false;
963                return true;
964            }
965            else if (ea.getKey()=='u')
966            {
967                setRequestReload(true);
968                return true;
969            }
970            return false;
971        }
972        default:
973            return false;
974    }
975    return false;
976}
977
978void SlideEventHandler::getUsage(osg::ApplicationUsage& usage) const
979{
980    usage.addKeyboardMouseBinding("a","Toggle on/off the automatic advancement for image to image");
981    usage.addKeyboardMouseBinding("n","Advance to next layer or slide");
982    usage.addKeyboardMouseBinding("p","Move to previous layer or slide");
983}
984
985unsigned int SlideEventHandler::getNumSlides()
986{
987    if (_presentationSwitch.valid()) return _presentationSwitch->getNumChildren();
988    else return 0;
989}
990
991
992bool SlideEventHandler::selectSlide(int slideNum,int layerNum)
993{
994    if (!_presentationSwitch) return false;
995
996    OSG_INFO<<"selectSlide("<<slideNum<<","<<layerNum<<")"<<std::endl;
997
998    if (slideNum>=static_cast<int>(_presentationSwitch->getNumChildren()))
999    {
1000        slideNum = LAST_POSITION;
1001    }
1002
1003    if (slideNum==LAST_POSITION && _presentationSwitch->getNumChildren()>0)
1004    {
1005        slideNum = _presentationSwitch->getNumChildren()-1;
1006    }
1007
1008    if (slideNum>=static_cast<int>(_presentationSwitch->getNumChildren())) return false;
1009
1010
1011    osg::Timer_t tick = osg::Timer::instance()->tick();
1012
1013    if (_firstSlideOrLayerChange)
1014    {
1015        _firstSlideOrLayerChange = false;
1016        _tickAtFirstSlideOrLayerChange = tick;
1017        _tickAtLastSlideOrLayerChange = tick;
1018    }
1019
1020    OSG_INFO<<"selectSlide("<<slideNum<<","<<layerNum<<") at time "<<osg::Timer::instance()->delta_s(_tickAtFirstSlideOrLayerChange, tick)<<" seconds, length ="<<osg::Timer::instance()->delta_s(_tickAtLastSlideOrLayerChange, tick)<<" seconds"<<std::endl;
1021
1022    _tickAtLastSlideOrLayerChange = tick;
1023
1024    // dectivate movies etc on current active slide.
1025    bool newSlide = _activeSlide!=slideNum;
1026    if (newSlide)
1027    {
1028        if (_releaseAndCompileOnEachNewSlide)
1029        {
1030            releaseSlide(_activeSlide);
1031        }
1032    }
1033
1034    _activeSlide = slideNum;
1035    _presentationSwitch->setSingleChildOn(_activeSlide);
1036
1037    //OSG_INFO<<"Selected slide '"<<_presentationSwitch->getChild(_activeSlide)->getName()<<"'"<<std::endl;
1038
1039
1040    FindNamedSwitchVisitor findSlide("Slide");
1041    _presentationSwitch->getChild(_activeSlide)->accept(findSlide);
1042
1043    bool result = false;
1044    if (findSlide._switch)
1045    {
1046        //OSG_INFO<<"Found slide '"<<findSlide._switch->getName()<<"'"<<std::endl;
1047        _slideSwitch = findSlide._switch;
1048
1049        result = selectLayer(layerNum);
1050
1051
1052    }
1053    else
1054    {
1055        //OSG_INFO<<"Not found slide"<<std::endl;
1056        updateOperators();
1057    }
1058
1059
1060    // refersh the viewer.
1061    //_viewer->getKeySwitchMatrixManipulator()->setMinimumDistance(0.001);
1062
1063    _viewer->getCameraManipulator()->setNode(_slideSwitch.get());
1064
1065    _viewer->computeActiveCoordinateSystemNodePath();
1066
1067    // resetUpdateCallbacks(ALL_OBJECTS);
1068
1069    bool _useSlideFilePaths = false;
1070    if (_useSlideFilePaths)
1071    {
1072        // set up the file paths
1073        FindFilePathDataVisitor ffpdv;
1074        _presentationSwitch->accept(ffpdv);
1075    }
1076
1077    if (newSlide && _releaseAndCompileOnEachNewSlide)
1078    {
1079        compileSlide(slideNum);
1080    }
1081
1082    return result;
1083
1084}
1085
1086bool SlideEventHandler::selectLayer(int layerNum)
1087{
1088    if (!_slideSwitch) return false;
1089
1090    bool withinSlide = true;
1091
1092    if (layerNum>=static_cast<int>(_slideSwitch->getNumChildren()))
1093    {
1094        withinSlide = false;
1095        layerNum = LAST_POSITION;
1096    }
1097
1098    if (layerNum==LAST_POSITION && _slideSwitch->getNumChildren()>0)
1099    {
1100        layerNum = _slideSwitch->getNumChildren()-1;
1101    }
1102
1103    if (layerNum>=static_cast<int>(_slideSwitch->getNumChildren())) return false;
1104
1105    _activeLayer = layerNum;
1106    _slideSwitch->setSingleChildOn(_activeLayer);
1107
1108    updateOperators();
1109
1110    OSG_INFO<<"Selected layer '"<<_slideSwitch->getChild(_activeLayer)->getName()<<"' num="<<_activeLayer<< std::endl;
1111
1112    return withinSlide;
1113}
1114
1115bool SlideEventHandler::nextLayerOrSlide()
1116{
1117    if (nextLayer())
1118    {
1119        return true;
1120    }
1121    else
1122    {
1123        return nextSlide();
1124    }
1125}
1126
1127bool SlideEventHandler::previousLayerOrSlide()
1128{
1129    OSG_INFO<<"previousLayerOrSlide()"<<std::endl;
1130    if (previousLayer()) return true;
1131    else return previousSlide();
1132}
1133
1134bool SlideEventHandler::nextSlide()
1135{
1136    OSG_INFO<<"nextSlide()"<<std::endl;
1137    LayerAttributes* la = _slideSwitch.valid() ? dynamic_cast<LayerAttributes*>(_slideSwitch->getUserData()) : 0;
1138    if (la && la->requiresJump())
1139    {
1140        if (la->getRelativeJump())
1141        {
1142            int previousSlide = getActiveSlide();
1143            int previousLayer = getActiveLayer();
1144            int newSlide = previousSlide + la->getSlideNum();
1145            int newLayer = previousLayer + la->getLayerNum();
1146            if (newLayer<0)
1147            {
1148                newLayer = 0;
1149            }
1150
1151            return selectSlide(newSlide, newLayer);
1152        }
1153        else
1154        {
1155            return selectSlide(la->getSlideNum(),la->getLayerNum());
1156        }
1157    }
1158
1159    if (selectSlide(_activeSlide+1)) return true;
1160    else if (_loopPresentation) return selectSlide(0);
1161    else return false;
1162}
1163
1164bool SlideEventHandler::previousSlide()
1165{
1166    OSG_INFO<<"previousSlide()"<<std::endl;
1167#if 1
1168    // start position when doing previous slide set to top of slide
1169    if (_activeSlide>0) return selectSlide(_activeSlide-1);
1170    else if (_loopPresentation && _presentationSwitch.valid()) return selectSlide(_presentationSwitch->getNumChildren()-1);
1171    else return false;
1172#else
1173    // start position when doing previous slide set to end of slide
1174    if (_activeSlide>0) return selectSlide(_activeSlide-1,LAST_POSITION);
1175    else if (_loopPresentation && _presentationSwitch.valid()) return selectSlide(_presentationSwitch->getNumChildren()-1,LAST_POSITION);
1176    else return false;
1177#endif
1178}
1179
1180bool SlideEventHandler::nextLayer()
1181{
1182    LayerAttributes* la = (_slideSwitch.valid() && _activeLayer<static_cast<int>(_slideSwitch->getNumChildren())) ? dynamic_cast<LayerAttributes*>(_slideSwitch->getChild(_activeLayer)->getUserData()) : 0;
1183    if (la)
1184    {
1185        la->callLeaveCallbacks(_slideSwitch->getChild(_activeLayer));
1186
1187        if (la->requiresJump())
1188        {
1189            if (la->getRelativeJump())
1190            {
1191                int previousSlide = getActiveSlide();
1192                int previousLayer = getActiveLayer();
1193                int newSlide = previousSlide + la->getSlideNum();
1194                int newLayer = previousLayer + la->getLayerNum();
1195                if (newLayer<0)
1196                {
1197                    newLayer = 0;
1198                }
1199
1200                return selectSlide(newSlide, newLayer);
1201            }
1202            else
1203            {
1204                return selectSlide(la->getSlideNum(),la->getLayerNum());
1205            }
1206        }
1207    }
1208
1209    OSG_INFO<<"nextLayer() calling selectLayer("<<_activeLayer+1<<")"<<std::endl;
1210    return selectLayer(_activeLayer+1);
1211}
1212
1213bool SlideEventHandler::previousLayer()
1214{
1215    OSG_INFO<<"previousLayer()"<<std::endl;
1216    if (_activeLayer>0) return selectLayer(_activeLayer-1);
1217    else return false;
1218}
1219
1220
1221void SlideEventHandler::updateOperators()
1222{
1223    _activeOperators.collect(_slideSwitch.get());
1224    _activeOperators.process();
1225
1226    if (_viewer.valid())
1227    {
1228        updateLight(0.0f,0.0f);
1229    }
1230}
1231
1232bool SlideEventHandler::home(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
1233{
1234    FindHomePositionVisitor fhpv;
1235    osg::Node* node = _viewer->getSceneData();
1236    if (node) node->accept(fhpv);
1237
1238    if (fhpv._homePosition.valid())
1239    {
1240        OSG_INFO<<"Doing home for stored home position."<<std::endl;
1241
1242        _viewer->getCameraManipulator()->setAutoComputeHomePosition(false);
1243        _viewer->getCameraManipulator()->setHomePosition(
1244                                             fhpv._homePosition->eye,
1245                                             fhpv._homePosition->center,
1246                                             fhpv._homePosition->up);
1247    }
1248    else
1249    {
1250        _viewer->getCameraManipulator()->setAutoComputeHomePosition(true);
1251    }
1252    _viewer->getCameraManipulator()->home(ea,aa);
1253
1254    return true;
1255}
1256
1257bool SlideEventHandler::home()
1258{
1259    osg::ref_ptr<osgGA::GUIEventAdapter> ea =  new osgGA::GUIEventAdapter;
1260    ea->setEventType(osgGA::GUIEventAdapter::FRAME);
1261    ea->setTime(_viewer->getEventQueue()->getTime());
1262
1263    home(*ea,*_viewer);
1264    return true;
1265}
1266
1267void SlideEventHandler::updateAlpha(bool modAlphaFunc, bool modMaterial, float x, float y)
1268{
1269    OSG_INFO<<"updateAlpha("<<x<<","<<y<<")"<<std::endl;
1270
1271    UpdateAlphaVisitor uav(modAlphaFunc, modMaterial, x,y);
1272    if (_presentationSwitch.valid()) _presentationSwitch->accept(uav);
1273    else if (_viewer->getSceneData()) _viewer->getSceneData()->accept(uav);
1274}
1275
1276
1277void SlideEventHandler::updateLight(float x, float y)
1278{
1279    OSG_INFO<<"updateLight("<<x<<", "<<y<<")"<<std::endl;
1280
1281    UpdateLightVisitor uav(_viewer->getCamera()->getViewMatrix(),x,y);
1282    _viewer->getSceneData()->accept(uav);
1283
1284    if (_viewer->getLightingMode()!= osg::View::NO_LIGHT && _viewer->getLight())
1285    {
1286        if (_viewer->getLightingMode()== osg::View::SKY_LIGHT)
1287        {
1288            uav.apply(_viewer->getCamera()->getViewMatrix(), _viewer->getLight());
1289        }
1290        else if (_viewer->getLightingMode()== osg::View::HEADLIGHT)
1291        {
1292            uav.apply(osg::Matrix::identity(), _viewer->getLight());
1293        }
1294    }
1295
1296}
1297
1298void SlideEventHandler::compileSlide(unsigned int slideNum)
1299{
1300    if (!_compileSlideCallback)
1301    {
1302        _compileSlideCallback = new CompileSlideCallback();
1303
1304        osgViewer::Viewer::Cameras cameras;
1305        _viewer->getCameras(cameras);
1306
1307        for(osgViewer::Viewer::Cameras::iterator itr = cameras.begin();
1308            itr != cameras.end();
1309            ++itr)
1310        {
1311            (*itr)->setPreDrawCallback(_compileSlideCallback.get());
1312        }
1313
1314    }
1315
1316    _compileSlideCallback->needCompile(_presentationSwitch->getChild(slideNum));
1317
1318}
1319
1320void SlideEventHandler::releaseSlide(unsigned int slideNum)
1321{
1322    osgUtil::GLObjectsVisitor globjVisitor(osgUtil::GLObjectsVisitor::RELEASE_DISPLAY_LISTS|
1323                                           osgUtil::GLObjectsVisitor::RELEASE_STATE_ATTRIBUTES);
1324    globjVisitor.setNodeMaskOverride(0xffffffff);
1325
1326    _presentationSwitch->getChild(slideNum)->accept(globjVisitor);
1327}
1328
1329void SlideEventHandler::dispatchEvent(const KeyPosition& keyPosition)
1330{
1331    osgGA::EventQueue* eq = _viewer->getEventQueue();
1332
1333    // reset the time of the last key press to ensure that the event is disgarded as a key repeat.
1334    _timeLastKeyPresses = -1.0;
1335
1336    if (keyPosition._x!=FLT_MAX)
1337    {
1338        float xRescaled = eq->getCurrentEventState()->getXmin() + (keyPosition._x+1.0f)*0.5f*(eq->getCurrentEventState()->getXmax()-eq->getCurrentEventState()->getXmin());
1339        eq->getCurrentEventState()->setX(xRescaled);
1340    }
1341
1342    if (keyPosition._y!=FLT_MAX)
1343    {
1344        float y = (eq->getCurrentEventState()->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS) ?
1345                   keyPosition._y : -keyPosition._y;
1346
1347        float yRescaled = eq->getCurrentEventState()->getYmin() + (y+1.0f)*0.5f*(eq->getCurrentEventState()->getYmax()-eq->getCurrentEventState()->getYmin());
1348        eq->getCurrentEventState()->setY(yRescaled);
1349    }
1350
1351    eq->keyPress(keyPosition._key);
1352    eq->keyRelease(keyPosition._key);
1353}
1354
1355
1356void SlideEventHandler::setRequestReload(bool flag)
1357{
1358    _requestReload = flag;
1359}
Note: See TracBrowser for help on using the browser.