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