root/OpenSceneGraph/trunk/applications/present3D/SlideEventHandler.cpp @ 10132

Revision 10132, 38.3 kB (checked in by robert, 6 years ago)

Warning fixes

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 "SlideEventHandler.h"
14#include "SlideShowConstructor.h"
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 "AnimationMaterial.h"
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::notify(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::notify(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::notify(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::notify(osg::INFO)<<"leave() : _imageStream->pause()"<<std::endl;
82
83        _imageStream->pause();
84    }
85
86    virtual void setPause(bool pause)
87    {
88       osg::notify(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        ss3d::AnimationMaterialCallback* amc = dynamic_cast<ss3d::AnimationMaterialCallback*>(_callback.get());
142        if (apc)
143        {
144            osg::notify(osg::INFO)<<"apc->setPause("<<pause<<")"<<std::endl;
145            apc->setPause(pause);
146        }
147        if (tc)
148        {
149            osg::notify(osg::INFO)<<"tc->setPause("<<pause<<")"<<std::endl;
150            tc->setPause(pause);
151        }
152        if (amc)
153        {
154            osg::notify(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        ss3d::AnimationMaterialCallback* amc = dynamic_cast<ss3d::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::notify(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::notify(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::notify(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::notify(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::notify(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       
292        for(unsigned int i=0;i<node.getNumDrawables();++i)
293        {
294            osg::Drawable* drawable = node.getDrawable(i);
295            if (drawable->getStateSet()) process(drawable->getStateSet());
296        }
297    }
298
299    virtual void process(osg::StateSet* ss)
300    {
301        for(unsigned int i=0;i<ss->getTextureAttributeList().size();++i)
302        {
303            osg::Texture* texture = dynamic_cast<osg::Texture*>(ss->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
304            osg::Image* image = texture ? texture->getImage(0) : 0;
305            osg::ImageStream* imageStream = image ? dynamic_cast<osg::ImageStream*>(image) : 0;
306            if (imageStream)
307            {
308                _operatorList.insert(new ImageStreamOperator(imageStream));
309            }
310        }
311    }   
312   
313    ActiveOperators::OperatorList& _operatorList;
314};
315
316
317ActiveOperators::ActiveOperators():
318    _pause(false)
319{
320}
321
322ActiveOperators::~ActiveOperators()
323{
324}
325
326void ActiveOperators::collect(osg::Node* incommingNode, osg::NodeVisitor::TraversalMode tm)
327{
328    _previous.swap(_current);
329   
330    _current.clear();
331   
332    FindOperatorsVisitor fov(_current, tm);
333    incommingNode->accept(fov);
334   
335    osg::notify(osg::INFO)<<"ActiveOperators::collect("<<incommingNode<<")"<<std::endl;
336    osg::notify(osg::INFO)<<"  _previous.size()="<<_previous.size()<<std::endl;
337    osg::notify(osg::INFO)<<"  _current.size()="<<_current.size()<<std::endl;
338   
339    _outgoing.clear();
340    _incomming.clear();
341    _maintained.clear();
342   
343    for(OperatorList::iterator itr = _previous.begin();
344        itr != _previous.end();
345        ++itr)
346    {
347        ObjectOperator* prev = itr->get();
348        if (_current.count(prev)==0) _outgoing.insert(prev);
349        else _maintained.insert(prev);
350    }
351   
352    for(OperatorList::iterator itr = _current.begin();
353        itr != _current.end();
354        ++itr)
355    {
356        ObjectOperator* curr = itr->get();
357        if (_previous.count(curr)==0) _incomming.insert(curr);
358    }
359}
360
361void ActiveOperators::setPause(bool pause)
362{
363    _pause = pause;
364    for(OperatorList::iterator itr = _current.begin();
365        itr != _current.end();
366        ++itr)
367    {
368        (*itr)->setPause(_pause);
369    }
370}
371
372
373void ActiveOperators::reset()
374{
375    for(OperatorList::iterator itr = _current.begin();
376        itr != _current.end();
377        ++itr)
378    {
379        (*itr)->reset();
380    }
381}
382
383void ActiveOperators::process()
384{
385    processOutgoing();
386    processMaintained();
387    processIncomming();
388}
389
390void ActiveOperators::processOutgoing()
391{
392    osg::notify(osg::INFO)<<"  outgoing.size()="<<_outgoing.size()<<std::endl;   
393    for(OperatorList::iterator itr = _outgoing.begin();
394        itr != _outgoing.end();
395        ++itr)
396    {
397        (*itr)->leave();
398    }
399}
400
401void ActiveOperators::processMaintained()
402{
403    osg::notify(osg::INFO)<<"  maintained.size()="<<_maintained.size()<<std::endl;
404    for(OperatorList::iterator itr = _maintained.begin();
405        itr != _maintained.end();
406        ++itr)
407    {
408        (*itr)->maintain();
409    }
410}
411
412void ActiveOperators::processIncomming()
413{
414    osg::notify(osg::INFO)<<"  incomming.size()="<<_incomming.size()<<std::endl;
415    for(OperatorList::iterator itr = _incomming.begin();
416        itr != _incomming.end();
417        ++itr)
418    {
419        (*itr)->enter();
420        (*itr)->setPause(_pause);
421    }
422}
423
424
425
426
427class FindHomePositionVisitor : public osg::NodeVisitor
428{
429public:
430
431    FindHomePositionVisitor():
432        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN) {}
433       
434    void apply(osg::Node& node)
435    {
436        HomePosition* homePosition = dynamic_cast<HomePosition*>(node.getUserData());
437        if (homePosition)
438        {
439            _homePosition = homePosition;
440        }
441       
442        traverse(node);
443    }
444       
445    osg::ref_ptr<HomePosition> _homePosition;
446       
447};
448
449class FindNamedSwitchVisitor : public osg::NodeVisitor
450{
451public:
452
453    FindNamedSwitchVisitor(const std::string& name):
454        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
455        _name(name),
456        _switch(0) {}
457       
458    void apply(osg::Switch& sw)
459    {
460        if (sw.getName().find(_name)!=std::string::npos)
461        {
462            _switch = &sw;
463            return; // note, no need to do traverse now we've located the relevant switch
464        }
465       
466        traverse(sw);
467    }
468       
469    std::string     _name;
470    osg::Switch*    _switch;
471       
472};
473
474
475class FindFilePathDataVisitor : public osg::NodeVisitor
476{
477public:
478
479    FindFilePathDataVisitor():
480        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN) {}
481       
482    void apply(osg::Node& node)
483    {
484        FilePathData* fdd = dynamic_cast<FilePathData*>(node.getUserData());
485        if (fdd)
486        {
487            osg::notify(osg::INFO)<<"Recorded FilePathData"<<std::endl;
488            osgDB::setDataFilePathList(fdd->filePathList);
489        }
490       
491        traverse(node);
492    }
493       
494};
495
496class UpdateLightVisitor : public osg::NodeVisitor
497{
498public:
499
500    UpdateLightVisitor(const osg::Matrixd& viewMatrix, float currentX, float currentY):
501        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
502        _viewMatrix(viewMatrix),
503        _currentX(currentX), _currentY(currentY) {}
504       
505    void apply(osg::Node& node)
506    {
507        if (node.getStateSet())
508        {
509            apply(*node.getStateSet());
510        }
511       
512        traverse(node);
513    }
514   
515    void apply(osg::LightSource& lightsource)
516    {
517        if (lightsource.getStateSet())
518        {
519            apply(*lightsource.getStateSet());
520        }
521   
522        if (lightsource.getLight())
523        {
524            osg::notify(osg::INFO)<<"Adjusting light"<<std::endl;
525
526            osg::Light* light = lightsource.getLight();
527
528            float azim = _currentX*osg::PI;
529            float elevation = _currentY*osg::PI_2;
530            osg::Vec3 direction(sin(azim)*cos(elevation),sin(elevation),cos(azim)*cos(elevation));
531           
532            if (lightsource.getReferenceFrame()==osg::LightSource::RELATIVE_RF)
533            {
534                osg::notify(osg::INFO)<<"Relative to absolute"<<std::endl;
535            }
536            else
537            {
538                osg::Matrix matrix(osg::computeEyeToLocal(_viewMatrix,_nodePath));
539                osg::notify(osg::INFO)<<"ModelView"<<matrix<<std::endl;
540
541                //direction = osg::Matrixd::transform3x3(matrix,direction);
542                //direction.normalize();
543
544                //direction = direction*matrix;
545                //direction.normalize();
546
547            }
548
549            light->setPosition(osg::Vec4(direction,0.0f));
550
551        }
552       
553        traverse(lightsource);
554    }
555
556    void apply(osg::StateSet& stateset)
557    {
558        osg::TexEnvCombine* texenvcombine = dynamic_cast<osg::TexEnvCombine*>(stateset.getTextureAttribute(0,osg::StateAttribute::TEXENV));
559        if (texenvcombine)
560        {
561            apply(*texenvcombine);
562        }
563    }
564       
565    void apply(osg::TexEnvCombine& texenv)
566    {
567        osg::notify(osg::INFO)<<"Adjusting tex env combine"<<std::endl;
568       
569        osg::Matrix matrix(osg::computeEyeToLocal(_viewMatrix,_nodePath));
570       
571        osg::notify(osg::INFO)<<"ModelView"<<matrix<<std::endl;
572
573        float azim = _currentX*osg::PI;
574        float elevation = _currentY*osg::PI_2;
575        osg::Vec3 direction(sin(azim)*cos(elevation),sin(elevation),cos(azim)*cos(elevation));
576
577        direction = osg::Matrixd::transform3x3(matrix,direction);
578        direction.normalize();
579
580        texenv.setConstantColor(osg::Vec4((direction.x()+1.0f)*0.5f,(direction.y()+1.0f)*0.5f,(direction.z()+1.0f)*0.5f,1.0f));
581    }
582
583
584    osg::Matrixd    _viewMatrix;
585    float           _currentX, _currentY;
586       
587};
588
589class UpdateAlphaVisitor : public osg::NodeVisitor
590{
591public:
592
593    UpdateAlphaVisitor(bool modAlphaFunc, bool modMaterial, float currentX, float currentY):
594        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
595        _modAlphaFunc(modAlphaFunc), _modMaterial(modMaterial),
596        _currentX(currentX), _currentY(currentY) {}
597       
598    void apply(osg::Node& node)
599    {
600        if (node.getStateSet()) apply(*node.getStateSet());
601        traverse(node);
602    }
603   
604    void apply(osg::StateSet& stateset)
605    {
606        if (_modAlphaFunc)
607        {
608            osg::AlphaFunc* alphaFunc = dynamic_cast<osg::AlphaFunc*>(stateset.getAttribute(osg::StateAttribute::ALPHAFUNC));
609            if (alphaFunc)
610            {
611                osg::notify(osg::INFO)<<"Adjusting alpha func"<<std::endl;
612
613                float alpha = alphaFunc->getReferenceValue();
614                alpha = osg::clampBetween((1.0f-_currentY)*0.5f,0.0f,1.0f);
615
616                alphaFunc->setReferenceValue(alpha);
617            }
618        }
619       
620        if (_modMaterial)
621        {       
622            osg::Material* material = dynamic_cast<osg::Material*>(stateset.getAttribute(osg::StateAttribute::MATERIAL));
623            if (material)
624            {
625                osg::notify(osg::INFO)<<"Adjusting material func"<<std::endl;
626                float alpha = osg::clampBetween((_currentY+1.0f)*0.5f,0.0f,1.0f);
627                material->setAlpha(osg::Material::FRONT_AND_BACK,alpha);
628            }
629        }
630    }
631
632    bool _modAlphaFunc, _modMaterial;
633    float   _currentX, _currentY;
634       
635};
636
637
638///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
639//
640// SlideEventHandler
641//
642SlideEventHandler::SlideEventHandler(osgViewer::Viewer* viewer):
643    _viewer(viewer),
644    _presentationSwitch(0),
645    _activeSlide(0),
646    _slideSwitch(0),
647    _activeLayer(0),
648    _firstTraversal(true),
649    _previousTime(-1.0f),
650    _timePerSlide(1.0),
651    _autoSteppingActive(false),
652    _loopPresentation(false),
653    _pause(false),
654    _hold(false),
655    _updateLightActive(false),
656    _updateOpacityActive(false),
657    _previousX(0), _previousY(0),
658    _cursorOn(true),
659    _releaseAndCompileOnEachNewSlide(false),
660    _firstSlideOrLayerChange(true),
661    _tickAtFirstSlideOrLayerChange(0),
662    _tickAtLastSlideOrLayerChange(0),
663    _timeDelayOnNewSlideWithMovies(0.25f),
664    _minimumTimeBetweenKeyPresses(0.25),
665    _timeLastKeyPresses(-1.0)
666{
667    s_seh = this;
668}
669
670double SlideEventHandler::getDuration(const osg::Node* node) const
671{
672    const LayerAttributes* la = dynamic_cast<const LayerAttributes*>(node->getUserData());
673    return la ? la->_duration : -1.0;
674}
675
676void SlideEventHandler::set(osg::Node* model)
677{
678#if 0
679    // pause all slides, then just reenable the current slide.
680    ActivityUpdateCallbacksVisitor aucv(ALL_OBJECTS, true);
681    aucv.setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
682    model->accept(aucv);
683#endif
684
685    ActiveOperators operators;
686    operators.collect(model, osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
687    operators.setPause(true);
688
689    FindNamedSwitchVisitor findPresentation("Presentation");
690    model->accept(findPresentation);
691   
692    if (findPresentation._switch)
693    {
694        osg::notify(osg::INFO)<<"Presentation '"<<model->getName()<<"'"<<std::endl;
695        _presentationSwitch = findPresentation._switch;
696       
697        double duration = getDuration(_presentationSwitch.get());
698        if (duration>=0.0)
699        {
700            osg::notify(osg::INFO)<<"Presentation time set to "<<duration<<std::endl;
701            _timePerSlide = duration;
702        }
703       
704        //selectSlide(0);
705    }
706    else
707    {
708        osg::notify(osg::INFO)<<"No presentation present in scene."<<std::endl;
709
710        _presentationSwitch = 0;
711        _activeSlide = 0;
712       
713        FindNamedSwitchVisitor findSlide("Slide");
714        model->accept(findSlide);
715       
716        if (findSlide._switch)
717        {
718            osg::notify(osg::INFO)<<"Found presentation slide"<<findSlide._switch->getName()<<std::endl;
719
720            _slideSwitch = findSlide._switch;
721            //selectLayer(0);
722        }
723        else
724        {
725            osg::notify(osg::INFO)<<"No slides present in scene, unable to operate as a slideshow."<<std::endl;
726        }
727   
728    }
729}
730
731double SlideEventHandler::getCurrentTimeDelayBetweenSlides() const
732{
733    if (_slideSwitch.valid())
734    {
735        double duration = -1.0;
736        if (_activeLayer<static_cast<int>(_slideSwitch->getNumChildren()))
737        {
738            duration = getDuration(_slideSwitch->getChild(_activeLayer));
739        }
740
741        if (duration < 0.0)
742        {
743            duration = getDuration(_slideSwitch.get());
744        }
745
746        if (duration >=0 )
747        {
748            return duration;
749        }       
750    }
751       
752    return _timePerSlide;
753}
754
755
756void SlideEventHandler::operator()(osg::Node* node, osg::NodeVisitor* nv)
757{
758    osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
759    if (ev)
760    {
761        if (node->getNumChildrenRequiringEventTraversal()>0) traverse(node,nv);
762
763        if (ev->getActionAdapter() && !ev->getEvents().empty())
764        {
765            for(osgGA::EventQueue::Events::iterator itr = ev->getEvents().begin();
766                itr != ev->getEvents().end();
767                ++itr)
768            {
769                handleWithCheckAgainstIgnoreHandledEventsMask(*(*itr), *(ev->getActionAdapter()), node, nv);
770            }
771        }
772    }
773}
774
775bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
776{
777
778    if (!_viewer)
779    {
780        _viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
781        selectSlide(0);
782        home();
783        osg::notify(osg::NOTICE)<<"Assigned viewer. to SlideEventHandler"<<std::endl;
784    }
785    // else  osg::notify(osg::NOTICE)<<"SlideEventHandler::handle()"<<std::endl;
786
787
788    if (ea.getHandled()) return false;
789
790    switch(ea.getEventType())
791    {
792        case(osgGA::GUIEventAdapter::FRAME):
793        {
794            if (_autoSteppingActive && !_pause)
795            {
796                double time = ea.time();
797               
798                if (_firstTraversal)
799                {
800                    _firstTraversal = false;
801                    _previousTime = time;
802                }
803                else if (time-_previousTime>=getCurrentTimeDelayBetweenSlides())
804                {
805                    // _previousTime = time;
806                   
807                    if (!_hold)
808                    {
809                        // increment the previous by the required time delay, note relative to the current
810                        // to keep the time relative to an absolute time signal, thus avoid drift of timing.
811                        _previousTime += getCurrentTimeDelayBetweenSlides();
812
813                        nextLayerOrSlide();
814                    }
815                    else
816                    {
817                        // we're holding of the move to next layer to slide, but we need slip the time forward accordingly
818                        // componensate for the extra time that this frame is recieving.
819                        _previousTime = time-getCurrentTimeDelayBetweenSlides();
820                    }
821                }
822            }
823            return false;
824        }
825
826        case(osgGA::GUIEventAdapter::KEYDOWN):
827        {
828            double time = ea.time();
829            double deltaTime = time - _timeLastKeyPresses;
830            if (deltaTime < _minimumTimeBetweenKeyPresses)
831            {
832                 break;
833            }
834           
835            _timeLastKeyPresses = time;
836
837            if (ea.getKey()=='a')
838            {
839                if (!_autoSteppingActive)
840                {
841                    _autoSteppingActive = true;
842                    _previousTime = ea.time();
843                }
844                return true;
845            }
846            else if (ea.getKey()=='q')
847            {
848                if (_autoSteppingActive)
849                {
850                    _autoSteppingActive = false;
851                    _previousTime = ea.time();
852                }
853                return true;
854            }
855            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Home ||
856                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Home)
857            {
858                _autoSteppingActive = false;
859                selectSlide(0);
860                home(ea,aa);
861                return true;
862            }
863            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_End ||
864                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_End)
865            {
866                _autoSteppingActive = false;
867                selectSlide(LAST_POSITION,LAST_POSITION);
868                home(ea,aa);
869                return true;
870            }
871            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Down ||
872                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Down)
873            {
874                _autoSteppingActive = false;
875                nextLayer();
876                return true;
877            }
878            else if (ea.getKey()=='n')
879            {
880                _autoSteppingActive = false;
881                nextLayerOrSlide();
882                return true;
883            }
884            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Up ||
885                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Up)
886            {
887                _autoSteppingActive = false;
888                previousLayer();
889                return true;
890            }
891            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Down ||
892                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Down)
893            {
894                _autoSteppingActive = false;
895                nextLayerOrSlide();
896                return true;
897            }
898            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Up ||
899                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Up)
900            {
901                _autoSteppingActive = false;
902                previousLayerOrSlide();
903                return true;
904            }
905            else if (ea.getKey()=='N' ||
906                     ea.getKey()==osgGA::GUIEventAdapter::KEY_Right ||
907                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Right)
908            {
909                _autoSteppingActive = false;
910                nextSlide();
911                home(ea,aa);
912                return true;
913            }
914            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left ||
915                     ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left)
916            {
917                _autoSteppingActive = false;
918                previousSlide();
919                home(ea,aa);
920                return true;
921            }
922            else if (ea.getKey()=='p')
923            {
924                if (!_pause)
925                {
926                    _pause = true;
927#if 0                   
928                    resetUpdateCallbackActivity(ALL_OBJECTS);
929#endif
930                    _activeOperators.setPause(_pause);
931                }
932               
933                return true;
934               
935            }
936            else if (ea.getKey()=='o')
937            {
938                if (_pause)
939                {
940                    _pause = false;
941#if 0                   
942                    resetUpdateCallbackActivity(ALL_OBJECTS);
943#endif
944                    _activeOperators.setPause(_pause);
945                }
946                return true;
947               
948            }
949            else if (ea.getKey()=='h')
950            {
951                _hold = true;
952                return true;
953            }
954            else if (ea.getKey()=='r')
955            {
956#if 0
957                resetUpdateCallbacks(ALL_OBJECTS);
958#endif
959                _activeOperators.reset();
960                return true;
961            }
962/*           
963            else if (ea.getKey()=='c')
964            {
965                _cursorOn = !_cursorOn;
966           
967                for( unsigned int i = 0; i < _viewer->getCameraConfig()->getNumberOfCameras(); i++ )
968                {
969                    Producer::Camera* cam = _viewer->getCameraConfig()->getCamera(i);
970                    Producer::RenderSurface* rs = cam->getRenderSurface();
971                    rs->useCursor(_cursorOn);
972                }
973
974                return true;
975            }
976*/
977            else if (ea.getKey()=='u')
978            {
979                updateAlpha(true,false,ea.getX(),ea.getY());
980                return true;
981            }
982            else if (ea.getKey()=='i')
983            {
984                updateAlpha(false,true,ea.getX(),ea.getY());
985                return true;
986            }
987            else if (ea.getKey()=='k')
988            {
989                updateLight(ea.getX(),ea.getY());
990                return true;
991            }
992
993            return false;
994        }
995        case(osgGA::GUIEventAdapter::KEYUP):
996        {
997            if (ea.getKey()=='h')
998            {
999                _hold = false;
1000                return true;
1001            }
1002            return false;
1003        }
1004        default:
1005            return false;
1006    }
1007    return false;
1008}
1009
1010void SlideEventHandler::getUsage(osg::ApplicationUsage& usage) const
1011{
1012    usage.addKeyboardMouseBinding("a","Toggle on/off the automatic advancement for image to image");
1013    usage.addKeyboardMouseBinding("n","Advance to next layer or slide");
1014    usage.addKeyboardMouseBinding("p","Move to previous layer or slide");
1015}
1016
1017unsigned int SlideEventHandler::getNumSlides()
1018{
1019    if (_presentationSwitch.valid()) return _presentationSwitch->getNumChildren();
1020    else return 0;
1021}
1022
1023
1024bool SlideEventHandler::selectSlide(int slideNum,int layerNum)
1025{
1026    if (!_presentationSwitch) return false;
1027
1028    osg::notify(osg::INFO)<<"selectSlide("<<slideNum<<","<<layerNum<<")"<<std::endl;
1029   
1030    if (slideNum==LAST_POSITION && _presentationSwitch->getNumChildren()>0)
1031    {
1032        slideNum = _presentationSwitch->getNumChildren()-1;
1033    }
1034   
1035    if (slideNum>=static_cast<int>(_presentationSwitch->getNumChildren())) return false;
1036
1037
1038    osg::Timer_t tick = osg::Timer::instance()->tick();
1039
1040    if (_firstSlideOrLayerChange)
1041    {
1042        _firstSlideOrLayerChange = false;
1043        _tickAtFirstSlideOrLayerChange = tick;
1044        _tickAtLastSlideOrLayerChange = tick;
1045    }
1046
1047    osg::notify(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;
1048   
1049    _tickAtLastSlideOrLayerChange = tick;
1050   
1051    // dectivate movies etc on current active slide.
1052    bool newSlide = _activeSlide!=slideNum;
1053    if (newSlide)
1054    {
1055        if (_releaseAndCompileOnEachNewSlide)
1056        {
1057            releaseSlide(_activeSlide);
1058        }
1059    }
1060
1061    _activeSlide = slideNum;
1062    _presentationSwitch->setSingleChildOn(_activeSlide);
1063
1064    //osg::notify(osg::INFO)<<"Selected slide '"<<_presentationSwitch->getChild(_activeSlide)->getName()<<"'"<<std::endl;
1065
1066   
1067    FindNamedSwitchVisitor findSlide("Slide");
1068    _presentationSwitch->getChild(_activeSlide)->accept(findSlide);
1069
1070    bool result = false;
1071    if (findSlide._switch)
1072    {
1073        //osg::notify(osg::INFO)<<"Found slide '"<<findSlide._switch->getName()<<"'"<<std::endl;
1074        _slideSwitch = findSlide._switch;
1075
1076        result = selectLayer(layerNum);
1077
1078       
1079    }
1080    else
1081    {
1082        //osg::notify(osg::INFO)<<"Not found slide"<<std::endl;
1083        updateOperators();
1084    }
1085   
1086
1087    // refersh the viewer.
1088    //_viewer->getKeySwitchMatrixManipulator()->setMinimumDistance(0.001);
1089   
1090    _viewer->getCameraManipulator()->setNode(_slideSwitch.get());
1091   
1092    _viewer->computeActiveCoordinateSystemNodePath();
1093   
1094    // resetUpdateCallbacks(ALL_OBJECTS);
1095   
1096    bool _useSlideFilePaths = false;
1097    if (_useSlideFilePaths)
1098    {
1099        // set up the file paths
1100        FindFilePathDataVisitor ffpdv;
1101        _presentationSwitch->accept(ffpdv);
1102    }
1103   
1104    if (newSlide && _releaseAndCompileOnEachNewSlide)
1105    {
1106        compileSlide(slideNum);
1107    }
1108
1109    return result;
1110   
1111}
1112
1113bool SlideEventHandler::selectLayer(int layerNum)
1114{
1115    if (!_slideSwitch) return false;
1116
1117    if (layerNum==LAST_POSITION && _slideSwitch->getNumChildren()>0)
1118    {
1119        layerNum = _slideSwitch->getNumChildren()-1;
1120    }
1121
1122    if (layerNum>=static_cast<int>(_slideSwitch->getNumChildren())) return false;
1123   
1124    _activeLayer = layerNum;
1125    _slideSwitch->setSingleChildOn(_activeLayer);
1126
1127    updateOperators();
1128
1129    osg::notify(osg::INFO)<<"Selected layer '"<<_slideSwitch->getChild(_activeLayer)->getName()<<"' num="<<_activeLayer<< std::endl;
1130
1131    return true;
1132}
1133
1134bool SlideEventHandler::nextLayerOrSlide()
1135{
1136    if (nextLayer()) return true;
1137    else return nextSlide();
1138}
1139
1140bool SlideEventHandler::previousLayerOrSlide()
1141{
1142    if (previousLayer()) return true;
1143    else return previousSlide();
1144}
1145
1146bool SlideEventHandler::nextSlide()
1147{
1148    LayerAttributes* la = _slideSwitch.valid() ? dynamic_cast<LayerAttributes*>(_slideSwitch->getUserData()) : 0;
1149    if (la && la->requiresJump())
1150    {
1151        if (la->getRelativeJump())
1152        {
1153            int previousSlide = getActiveSlide();
1154            int previousLayer = getActiveLayer();
1155            int newSlide = previousSlide + la->getSlideNum();
1156            int newLayer = previousLayer + la->getLayerNum();
1157            if (newLayer<0)
1158            {
1159                newLayer = 0;
1160            }
1161
1162            return selectSlide(newSlide, newLayer);
1163        }
1164        else
1165        {
1166            return selectSlide(la->getSlideNum(),la->getLayerNum());
1167        }
1168    }
1169
1170    if (selectSlide(_activeSlide+1)) return true;
1171    else if (_loopPresentation) return selectSlide(0);
1172    else return false;
1173}
1174
1175bool SlideEventHandler::previousSlide()
1176{
1177#if 1
1178    // start position when doing previous slide set to top of slide
1179    if (_activeSlide>0) return selectSlide(_activeSlide-1);
1180    else if (_loopPresentation && _presentationSwitch.valid()) return selectSlide(_presentationSwitch->getNumChildren()-1);
1181    else return false;
1182#else
1183    // start position when doing previous slide set to end of slide
1184    if (_activeSlide>0) return selectSlide(_activeSlide-1,LAST_POSITION);
1185    else if (_loopPresentation && _presentationSwitch.valid()) return selectSlide(_presentationSwitch->getNumChildren()-1,LAST_POSITION);
1186    else return false;
1187#endif
1188}
1189
1190bool SlideEventHandler::nextLayer()
1191{
1192    LayerAttributes* la = (_slideSwitch.valid() && _activeLayer>=0) ? dynamic_cast<LayerAttributes*>(_slideSwitch->getChild(_activeLayer)->getUserData()) : 0;
1193    if (la)
1194    {
1195        la->callLeaveCallbacks(_slideSwitch->getChild(_activeLayer));
1196   
1197        if (la->requiresJump())
1198        {
1199            if (la->getRelativeJump())
1200            {
1201                int previousSlide = getActiveSlide();
1202                int previousLayer = getActiveLayer();
1203                int newSlide = previousSlide + la->getSlideNum();
1204                int newLayer = previousLayer + la->getLayerNum();
1205                if (newLayer<0)
1206                {
1207                    newLayer = 0;
1208                }
1209
1210                return selectSlide(newSlide, newLayer);
1211            }
1212            else
1213            {
1214                return selectSlide(la->getSlideNum(),la->getLayerNum());
1215            }
1216        }
1217    }
1218
1219    return selectLayer(_activeLayer+1);
1220}
1221
1222bool SlideEventHandler::previousLayer()
1223{
1224    if (_activeLayer>0) return selectLayer(_activeLayer-1);
1225    else return false;
1226}
1227
1228
1229void SlideEventHandler::updateOperators()
1230{
1231    _activeOperators.collect(_slideSwitch.get());
1232    _activeOperators.process();
1233
1234    if (_viewer.valid())
1235    {
1236        UpdateLightVisitor uav(_viewer->getCamera()->getViewMatrix(),0.0f,0.0f);
1237        _viewer->getSceneData()->accept(uav);
1238    }
1239}
1240
1241bool SlideEventHandler::home(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
1242{
1243    FindHomePositionVisitor fhpv;
1244    osg::Node* node = _viewer->getSceneData();
1245    if (node) node->accept(fhpv);
1246
1247    if (fhpv._homePosition.valid())
1248    {
1249        osg::notify(osg::INFO)<<"Doing home for stored home position."<<std::endl;
1250
1251        _viewer->getCameraManipulator()->setAutoComputeHomePosition(false);
1252        _viewer->getCameraManipulator()->setHomePosition(
1253                                             fhpv._homePosition->eye,
1254                                             fhpv._homePosition->center,
1255                                             fhpv._homePosition->up);
1256    }
1257    else
1258    {
1259        _viewer->getCameraManipulator()->setAutoComputeHomePosition(true);
1260    }
1261    _viewer->getCameraManipulator()->home(ea,aa);
1262
1263    return true;
1264}
1265
1266bool SlideEventHandler::home()
1267{
1268    osg::ref_ptr<osgGA::GUIEventAdapter> ea =  new osgGA::GUIEventAdapter;
1269    ea->setEventType(osgGA::GUIEventAdapter::FRAME);
1270    ea->setTime(_viewer->getEventQueue()->getTime());
1271
1272    home(*ea,*_viewer);
1273    return true;
1274}
1275
1276void SlideEventHandler::updateAlpha(bool modAlphaFunc, bool modMaterial, float x, float y)
1277{
1278    osg::notify(osg::INFO)<<"updateAlpha("<<x<<","<<y<<")"<<std::endl;
1279   
1280    UpdateAlphaVisitor uav(modAlphaFunc, modMaterial, x,y);
1281    if (_presentationSwitch.valid()) _presentationSwitch->accept(uav);
1282    else if (_viewer->getSceneData()) _viewer->getSceneData()->accept(uav);
1283}
1284
1285
1286void SlideEventHandler::updateLight(float x, float y)
1287{
1288    osg::notify(osg::INFO)<<"updateLight("<<x<<", "<<y<<")"<<std::endl;
1289
1290    UpdateLightVisitor uav(_viewer->getCamera()->getViewMatrix(),x,y);
1291    _viewer->getSceneData()->accept(uav);
1292}
1293
1294void SlideEventHandler::compileSlide(unsigned int slideNum)
1295{
1296    if (!_compileSlideCallback)
1297    {
1298        _compileSlideCallback = new ss3d::CompileSlideCallback();
1299
1300        osgViewer::Viewer::Cameras cameras;
1301        _viewer->getCameras(cameras);
1302
1303        for(osgViewer::Viewer::Cameras::iterator itr = cameras.begin();
1304            itr != cameras.end();
1305            ++itr)
1306        {
1307            (*itr)->setPreDrawCallback(_compileSlideCallback.get());
1308        }
1309
1310    }           
1311   
1312    _compileSlideCallback->needCompile(_presentationSwitch->getChild(slideNum));
1313   
1314}
1315
1316void SlideEventHandler::releaseSlide(unsigned int slideNum)
1317{
1318    osgUtil::GLObjectsVisitor globjVisitor(osgUtil::GLObjectsVisitor::RELEASE_DISPLAY_LISTS|
1319                                           osgUtil::GLObjectsVisitor::RELEASE_STATE_ATTRIBUTES);
1320    globjVisitor.setNodeMaskOverride(0xffffffff);
1321   
1322    _presentationSwitch->getChild(slideNum)->accept(globjVisitor);
1323}
1324
1325void SlideEventHandler::dispatchEvent(const KeyPosition& keyPosition)
1326{
1327    osg::notify(osg::INFO)<<" keyPosition._key "<<keyPosition._key<<" "<<keyPosition._x<<" "<<keyPosition._y<<std::endl;
1328
1329    osgGA::EventQueue* eq = _viewer->getEventQueue();
1330
1331    // reset the time of the last key press to ensure thatthe event is disgarded as a key repeat.
1332    _timeLastKeyPresses = -1.0;
1333   
1334    if (keyPosition._x!=FLT_MAX)
1335    {
1336        float xRescaled = eq->getCurrentEventState()->getXmin() + (keyPosition._x+1.0f)*0.5f*(eq->getCurrentEventState()->getXmax()-eq->getCurrentEventState()->getXmin());
1337        eq->getCurrentEventState()->setX(xRescaled);
1338    }
1339   
1340    if (keyPosition._y!=FLT_MAX)
1341    {
1342        float yRescaled = eq->getCurrentEventState()->getYmin() + (keyPosition._y+1.0f)*0.5f*(eq->getCurrentEventState()->getXmax()-eq->getCurrentEventState()->getYmin());
1343        eq->getCurrentEventState()->setY(yRescaled);
1344    }
1345
1346    eq->keyPress(keyPosition._key);
1347    eq->keyRelease(keyPosition._key);
1348}
1349
1350
Note: See TracBrowser for help on using the browser.