openscenegraph
SlideEventHandler
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2018 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef SLIDEEVENTHANDLER
15#define SLIDEEVENTHANDLER 1
16
17#include <osg/Switch>
18#include <osg/Timer>
19#include <osg/ValueObject>
20#include <osg/ImageSequence>
21
22#include <osgGA/GUIEventHandler>
23#include <osgViewer/Viewer>
24
25#include <osgPresentation/CompileSlideCallback>
26#include <osgPresentation/PropertyManager>
27
28namespace osgPresentation
29{
30
31// forward declare
32class SlideEventHandler;
33
34/// Operations related to click to run/load/key events.
35enum Operation
36{
37 RUN,
38 LOAD,
39 EVENT,
40 JUMP,
41 FORWARD_MOUSE_EVENT,
42 FORWARD_TOUCH_EVENT
43};
44
45struct JumpData : public osg::Object
46{
47 JumpData():
48 relativeJump(true),
49 slideNum(0),
50 layerNum(0) {}
51
52 JumpData(bool in_relativeJump, int in_slideNum, int in_layerNum):
53 relativeJump(in_relativeJump),
54 slideNum(in_slideNum),
55 layerNum(in_layerNum) {}
56
57 JumpData(const std::string& in_slideName, const std::string& in_layerName):
58 relativeJump(true),
59 slideNum(0),
60 layerNum(0),
61 slideName(in_slideName),
62 layerName(in_layerName) {}
63
64 JumpData(const JumpData& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
65 osg::Object(rhs, copyop),
66 relativeJump(rhs.relativeJump),
67 slideNum(rhs.slideNum),
68 layerNum(rhs.layerNum),
69 slideName(rhs.slideName),
70 layerName(rhs.layerName) {}
71
72 JumpData& operator = (const JumpData& rhs)
73 {
74 if (&rhs==this) return *this;
75 relativeJump = rhs.relativeJump;
76 slideNum = rhs.slideNum;
77 layerNum = rhs.layerNum;
78 slideName = rhs.slideName;
79 layerName = rhs.layerName;
80 return *this;
81 }
82
83 META_Object(osgPresentation, JumpData);
84
85 bool requiresJump() const
86 {
87 if (!slideName.empty() || !layerName.empty()) return true;
88 return relativeJump ? (slideNum!=0 || layerNum!=0) : true;
89 }
90
91 bool jump(SlideEventHandler* seh) const;
92
93 void setRelativeJump(bool flag) { relativeJump = flag; }
94 bool getRelativeJump() const { return relativeJump; }
95
96 void setSlideNum(int num) { slideNum = num; }
97 int getSlideNum() const { return slideNum; }
98
99 void setLayerNum(int num) { layerNum = num; }
100 int getLayerNum() const { return layerNum; }
101
102 void setSlideName(const std::string& name) { slideName = name; }
103 const std::string& getSlideName() const { return slideName; }
104
105 void setLayerName(const std::string& name) { layerName = name; }
106 const std::string& getLayerName() const { return layerName; }
107
108 bool relativeJump;
109 int slideNum;
110 int layerNum;
111
112 std::string slideName;
113 std::string layerName;
114};
115
116
117struct HomePosition : public osg::Object
118{
119 HomePosition():
120 eye(0.0, -1.0, 0.0),
121 center(0.0, 0.0, 0.0),
122 up(0.0, 0.0, 1.0) {}
123
124 HomePosition(const osg::Vec3& in_eye, const osg::Vec3& in_center, const osg::Vec3& in_up):
125 eye(in_eye),
126 center(in_center),
127 up(in_up) {}
128
129 HomePosition(const HomePosition& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
130 osg::Object(rhs, copyop),
131 eye(rhs.eye),
132 center(rhs.center),
133 up(rhs.up) {}
134
135 HomePosition& operator = (const HomePosition& rhs)
136 {
137 if (&rhs==this) return *this;
138 eye = rhs.eye;
139 center = rhs.center;
140 up = rhs.up;
141 return *this;
142 }
143
144 META_Object(osgPresentation, HomePosition);
145
146 void setEye(const osg::Vec3d& e) { eye = e; }
147 const osg::Vec3d& getEye() const { return eye; }
148
149 void setCenter(const osg::Vec3d& c) { center = c; }
150 const osg::Vec3d& getCenter() const { return center; }
151
152 void setUp(const osg::Vec3d& u) { up = u; }
153 const osg::Vec3d& getUp() const { return up; }
154
155 osg::Vec3d eye;
156 osg::Vec3d center;
157 osg::Vec3d up;
158};
159
160struct KeyPosition : public osg::Object
161{
162 KeyPosition(unsigned int key=0, float x=FLT_MAX, float y=FLT_MAX, bool forward_to_devices = false):
163 _key((osgGA::GUIEventAdapter::KeySymbol)key),
164 _x(x),
165 _y(y),
166 _forwardToDevices(forward_to_devices) {}
167
168 KeyPosition(const KeyPosition& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
169 osg::Object(rhs, copyop),
170 _key(rhs._key),
171 _x(rhs._x),
172 _y(rhs._y),
173 _forwardToDevices(rhs._forwardToDevices) {}
174
175 META_Object(osgPresentation, KeyPosition);
176
177 KeyPosition& operator = (const KeyPosition& rhs)
178 {
179 if (&rhs==this) return *this;
180 _key = rhs._key;
181 _x = rhs._x;
182 _y = rhs._y;
183 _forwardToDevices = rhs._forwardToDevices;
184 return *this;
185 }
186
187 void set(unsigned int key=0, float x=FLT_MAX, float y=FLT_MAX, bool forward_to_devices = false)
188 {
189 _key = (osgGA::GUIEventAdapter::KeySymbol)key;
190 _x = x;
191 _y = y;
192 _forwardToDevices = forward_to_devices;
193 }
194
195 void setKey(int key) { _key = static_cast<osgGA::GUIEventAdapter::KeySymbol>(key); }
196 int getKey() const { return _key; }
197
198 void setX(float x) { _x = x; }
199 float getX() const { return _x; }
200
201 void setY(float y) { _y = y; }
202 float getY() const { return _y; }
203
204 void setForwardToDevices(bool flag) { _forwardToDevices = flag; }
205 bool getForwardToDevices() const { return _forwardToDevices; }
206
207
208 osgGA::GUIEventAdapter::KeySymbol _key;
209 float _x;
210 float _y;
211 bool _forwardToDevices;
212};
213
214struct LayerCallback : public virtual osg::Referenced
215{
216 virtual void operator() (osg::Node* node) const = 0;
217};
218
219struct OSGPRESENTATION_EXPORT LayerAttributes : public virtual osg::Referenced
220{
221 LayerAttributes():_duration(0) {}
222 LayerAttributes(double in_duration):_duration(in_duration) {}
223
224 void setDuration(double duration) { _duration = duration; }
225 double getDuration() const { return _duration; }
226
227 typedef std::vector<KeyPosition> Keys;
228 typedef std::vector<std::string> RunStrings;
229
230 void setKeys(const Keys& keys) { _keys = keys; }
231 const Keys& getKeys() const { return _keys; }
232
233 void addKey(const KeyPosition& kp) { _keys.push_back(kp); }
234
235 void setRunStrings(const RunStrings& runStrings) { _runStrings = runStrings; }
236 const RunStrings& getRunStrings() const { return _runStrings; }
237
238 void addRunString(const std::string& runString) { _runStrings.push_back(runString); }
239
240 void setJump(const JumpData& jumpData) { _jumpData = jumpData; }
241 const JumpData& getJumpData() const { return _jumpData; }
242
243 double _duration;
244 Keys _keys;
245 RunStrings _runStrings;
246 JumpData _jumpData;
247
248 void addEnterCallback(LayerCallback* lc) { _enterLayerCallbacks.push_back(lc); }
249 void addLeaveCallback(LayerCallback* lc) { _leaveLayerCallbacks.push_back(lc); }
250
251 void callEnterCallbacks(osg::Node* node);
252 void callLeaveCallbacks(osg::Node* node);
253
254 typedef std::list< osg::ref_ptr<LayerCallback> > LayerCallbacks;
255 LayerCallbacks _enterLayerCallbacks;
256 LayerCallbacks _leaveLayerCallbacks;
257};
258
259struct FilePathData : public virtual osg::Referenced
260{
261 FilePathData(const osgDB::FilePathList& fpl):filePathList(fpl) {}
262
263 osgDB::FilePathList filePathList;
264};
265
266
267struct dereference_less
268{
269 template<class T, class U>
270 inline bool operator() (const T& lhs,const U& rhs) const
271 {
272 return *lhs < *rhs;
273 }
274};
275
276struct ObjectOperator : public osg::Referenced
277{
278 inline bool operator < (const ObjectOperator& rhs) const { return ptr() < rhs.ptr(); }
279
280 virtual void* ptr() const = 0;
281
282 virtual void enter(SlideEventHandler*) = 0;
283 virtual void frame(SlideEventHandler*) {} ;
284 virtual void maintain(SlideEventHandler*) = 0;
285 virtual void leave(SlideEventHandler*) = 0;
286 virtual void setPause(SlideEventHandler*, bool pause) = 0;
287 virtual void reset(SlideEventHandler*) = 0;
288
289 virtual ~ObjectOperator() {}
290};
291
292class OSGPRESENTATION_EXPORT ActiveOperators
293{
294public:
295 ActiveOperators();
296 ~ActiveOperators();
297
298 void collect(osg::Node* incomingNode, osg::NodeVisitor::TraversalMode tm = osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
299
300 void process(SlideEventHandler* seh);
301
302 void frame(SlideEventHandler*);
303
304 void setPause(SlideEventHandler* seh, bool pause);
305 bool getPause() const { return _pause; }
306
307 void reset(SlideEventHandler* seh);
308
309 typedef std::set< osg::ref_ptr<ObjectOperator>, dereference_less > OperatorList;
310
311protected:
312
313 void processOutgoing(SlideEventHandler* seh);
314 void processIncoming(SlideEventHandler* seh);
315 void processMaintained(SlideEventHandler* seh);
316
317 bool _pause;
318
319 OperatorList _previous;
320 OperatorList _current;
321
322 OperatorList _outgoing;
323 OperatorList _incoming;
324 OperatorList _maintained;
325
326};
327
328class OSGPRESENTATION_EXPORT SlideEventHandler : public osgGA::GUIEventHandler
329{
330public:
331
332 SlideEventHandler(osgViewer::Viewer* viewer=0);
333
334 SlideEventHandler(const SlideEventHandler& seh,const osg::CopyOp& copyop);
335
336 static SlideEventHandler* instance();
337
338 META_Object(osgPresentation,SlideEventHandler);
339
340 void set(osg::Node* model);
341
342 virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
343
344 virtual void getUsage(osg::ApplicationUsage& usage) const;
345
346 osgViewer::Viewer* getViewer() { return _viewer.get(); }
347
348 osg::Switch* getPresentationSwitch() { return _presentationSwitch.get(); }
349
350
351 enum WhichPosition
352 {
353 FIRST_POSITION = 0,
354 LAST_POSITION = -1
355 };
356
357 void compileSlide(unsigned int slideNum);
358 void releaseSlide(unsigned int slideNum);
359
360 unsigned int getNumSlides();
361
362 int getActiveSlide() const { return _activeSlide; }
363 int getActiveLayer() const { return _activeLayer; }
364
365 osg::Switch* getSlide(int slideNum);
366 osg::Node* getLayer(int slideNum, int layerNum);
367
368 bool selectSlide(int slideNum,int layerNum=FIRST_POSITION);
369 bool selectLayer(int layerNum);
370
371 bool nextLayerOrSlide();
372 bool previousLayerOrSlide();
373
374 bool nextSlide();
375 bool previousSlide();
376
377 bool nextLayer();
378 bool previousLayer();
379
380 bool home();
381
382 void setAutoSteppingActive(bool flag = true) { _autoSteppingActive = flag; }
383 bool getAutoSteppingActive() const { return _autoSteppingActive; }
384
385 void setTimeDelayBetweenSlides(double dt) { _timePerSlide = dt; }
386 double getTimeDelayBetweenSlides() const { return _timePerSlide; }
387
388 double getDuration(const osg::Node* node) const;
389
390 double getCurrentTimeDelayBetweenSlides() const;
391
392 void setReleaseAndCompileOnEachNewSlide(bool flag) { _releaseAndCompileOnEachNewSlide = flag; }
393 bool getReleaseAndCompileOnEachNewSlide() const { return _releaseAndCompileOnEachNewSlide; }
394
395 void setTimeDelayOnNewSlideWithMovies(float t) { _timeDelayOnNewSlideWithMovies = t; }
396 float getTimeDelayOnNewSlideWithMovies() const { return _timeDelayOnNewSlideWithMovies; }
397
398 void setLoopPresentation(bool loop) { _loopPresentation = loop; }
399 bool getLoopPresentation() const { return _loopPresentation; }
400
401
402 void dispatchEvent(const KeyPosition& keyPosition);
403 void dispatchEvent(osgGA::Event* event);
404
405 void forwardEventToDevices(osgGA::Event* event);
406
407 void setRequestReload(bool flag);
408 bool getRequestReload() const { return _requestReload; }
409
410 double getReferenceTime() const { return _referenceTime; }
411
412 virtual bool checkNeedToDoFrame();
413
414protected:
415
416 ~SlideEventHandler() {}
417
418 bool home(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa);
419
420 void updateAlpha(bool, bool, float x, float y);
421 void updateLight(float x, float y);
422
423 void updateOperators();
424
425
426 osg::observer_ptr<osgViewer::Viewer> _viewer;
427
428 osg::observer_ptr<osg::Switch> _showSwitch;
429 int _activePresentation;
430
431 osg::observer_ptr<osg::Switch> _presentationSwitch;
432 int _activeSlide;
433
434 osg::observer_ptr<osg::Switch> _slideSwitch;
435 int _activeLayer;
436
437 bool _firstTraversal;
438 double _referenceTime;
439 double _previousTime;
440 double _timePerSlide;
441 bool _autoSteppingActive;
442 bool _loopPresentation;
443 bool _pause;
444 bool _hold;
445
446 bool _updateLightActive;
447 bool _updateOpacityActive;
448 float _previousX, _previousY;
449
450 bool _cursorOn;
451
452 bool _releaseAndCompileOnEachNewSlide;
453
454 bool _firstSlideOrLayerChange;
455 osg::Timer_t _tickAtFirstSlideOrLayerChange;
456 osg::Timer_t _tickAtLastSlideOrLayerChange;
457
458 float _timeDelayOnNewSlideWithMovies;
459
460 double _minimumTimeBetweenKeyPresses;
461 double _timeLastKeyPresses;
462
463 ActiveOperators _activeOperators;
464
465 osg::ref_ptr<CompileSlideCallback> _compileSlideCallback;
466
467 bool _requestReload;
468};
469
470}
471
472#endif