root/OpenSceneGraph/trunk/src/osgPresentation/deprecated/SlideEventHandler.cpp @ 13734

Revision 13734, 45.4 kB (checked in by robert, 3 days ago)

Moved widgets from VolumeEditorWidget? to TransferFunctionWidget?, and widget utilities into WidgetUtils?.

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