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