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 SLIDESHOWCONSTRUCTOR 14#define SLIDESHOWCONSTRUCTOR 15 16#include <osg/Vec3> 17#include <osg/Vec4> 18#include <osg/ImageUtils> 19#include <osg/Group> 20#include <osg/ClearNode> 21#include <osg/Switch> 22#include <osg/AnimationPath> 23#include <osg/TransferFunction> 24#include <osg/ImageStream> 25#include <osg/ImageSequence> 26#include <osg/ScriptEngine> 27#include <osgText/Text> 28#include <osgGA/GUIEventAdapter> 29 30#include <osgDB/FileUtils> 31 32#include <osgVolume/VolumeTile> 33#include <osgVolume/VolumeSettings> 34 35#include <osgPresentation/AnimationMaterial> 36#include <osgPresentation/SlideEventHandler> 37#include <osgPresentation/PropertyManager> 38#include <osgPresentation/Timeout> 39 40namespace osgPresentation 41{ 42 43 44 45class OSGPRESENTATION_EXPORT HUDTransform : public osg::Transform 46{ 47 public: 48 49 HUDTransform(HUDSettings* hudSettings); 50 51 virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const; 52 53 virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const; 54 55protected: 56 57 virtual ~HUDTransform(); 58 59 osg::ref_ptr<HUDSettings> _hudSettings; 60 61}; 62 63class OSGPRESENTATION_EXPORT SlideShowConstructor 64{ 65public: 66 67 68 enum CoordinateFrame { SLIDE, MODEL }; 69 70 71 72 LayerAttributes* getOrCreateLayerAttributes(osg::Node* node); 73 74 void setDuration(osg::Node* node,double duration) 75 { 76 getOrCreateLayerAttributes(node)->setDuration(duration); 77 } 78 79 void addKey(osg::Node* node,const KeyPosition& kp) 80 { 81 getOrCreateLayerAttributes(node)->addKey(kp); 82 } 83 84 void addRunString(osg::Node* node, const std::string& runString) 85 { 86 getOrCreateLayerAttributes(node)->addRunString(runString); 87 } 88 89 void setJump(osg::Node* node, const JumpData& jumpData) 90 { 91 getOrCreateLayerAttributes(node)->setJump(jumpData); 92 } 93 94 void addPresentationKey(const KeyPosition& kp) 95 { 96 if (!_presentationSwitch) createPresentation(); 97 if (_presentationSwitch.valid()) addKey( _presentationSwitch.get(), kp); 98 } 99 100 void addPresentationRunString(const std::string& runString) 101 { 102 if (!_presentationSwitch) createPresentation(); 103 if (_presentationSwitch.valid()) addRunString( _presentationSwitch.get(),runString); 104 } 105 106 void addSlideKey(const KeyPosition& kp) 107 { 108 if (!_slide) addSlide(); 109 if (_slide.valid()) addKey(_slide.get(),kp); 110 } 111 112 void addSlideRunString(const std::string& runString) 113 { 114 if (!_slide) addSlide(); 115 if (_slide.valid()) addRunString(_slide.get(),runString); 116 } 117 118 void setSlideJump(const JumpData& jumpData) 119 { 120 if (!_slide) addSlide(); 121 if (_slide.valid()) setJump(_slide.get(),jumpData); 122 } 123 124 void addLayerKey(const KeyPosition& kp) 125 { 126 if (!_currentLayer) addLayer(); 127 if (_currentLayer.valid()) addKey(_currentLayer.get(),kp); 128 } 129 130 void addLayerRunString(const std::string& runString) 131 { 132 if (!_currentLayer) addLayer(); 133 if (_currentLayer.valid()) addRunString(_currentLayer.get(),runString); 134 } 135 136 137 void setLayerJump(const JumpData& jumpData) 138 { 139 if (!_currentLayer) addLayer(); 140 if (_currentLayer.valid()) setJump(_currentLayer.get(),jumpData); 141 } 142 143 144 145 struct PositionData 146 { 147 PositionData(): 148 frame(SlideShowConstructor::SLIDE), 149 position(0.0f,1.0f,0.0f), 150 //position(0.5f,0.5f,0.0f), 151 scale(1.0f,1.0f,1.0f), 152 rotate(0.0f,0.0f,0.0f,1.0f), 153 rotation(0.0f,0.0f,1.0f,0.0f), 154 absolute_path(false), 155 inverse_path(false), 156 path_time_offset(0.0), 157 path_time_multiplier(1.0f), 158 path_loop_mode(osg::AnimationPath::NO_LOOPING), 159 animation_material_time_offset(0.0), 160 animation_material_time_multiplier(1.0), 161 animation_material_loop_mode(AnimationMaterial::NO_LOOPING), 162 autoRotate(false), 163 autoScale(false), 164 hud(false) {} 165 166 167 bool requiresPosition() const 168 { 169 return (position[0]!=0.0f || position[1]!=1.0f || position[2]!=1.0f); 170 } 171 172 bool requiresScale() const 173 { 174 return (scale[0]!=1.0f || scale[1]!=1.0f || scale[2]!=1.0f); 175 } 176 177 bool requiresRotate() const 178 { 179 return rotate[0]!=0.0f; 180 } 181 182 bool requiresAnimation() const 183 { 184 return (rotation[0]!=0.0f || !path.empty()); 185 } 186 187 bool requiresMaterialAnimation() const 188 { 189 return !animation_material_filename.empty() || !fade.empty(); 190 } 191 192 CoordinateFrame frame; 193 osg::Vec3 position; 194 osg::Vec3 scale; 195 osg::Vec4 rotate; 196 osg::Vec4 rotation; 197 std::string animation_name; 198 bool absolute_path; 199 bool inverse_path; 200 double path_time_offset; 201 double path_time_multiplier; 202 osg::AnimationPath::LoopMode path_loop_mode; 203 std::string path; 204 double animation_material_time_offset; 205 double animation_material_time_multiplier; 206 AnimationMaterial::LoopMode animation_material_loop_mode; 207 std::string animation_material_filename; 208 std::string fade; 209 bool autoRotate; 210 bool autoScale; 211 bool hud; 212 }; 213 214 struct ModelData 215 { 216 ModelData() {} 217 218 std::string region; 219 std::string effect; 220 std::string options; 221 }; 222 223 struct ImageData 224 { 225 ImageData(): 226 width(1.0f), 227 height(1.0f), 228 region(0.0f,0.0f,1.0f,1.0f), 229 region_in_pixel_coords(false), 230 texcoord_rotate(0.0f), 231 loopingMode(osg::ImageStream::NO_LOOPING), 232 page(-1), 233 backgroundColor(1.0f,1.0f,1.0f,1.0f), 234 fps(30.0), 235 duration(-1.0), 236 imageSequence(false), 237 imageSequencePagingMode(osg::ImageSequence::PAGE_AND_DISCARD_USED_IMAGES), 238 imageSequenceInteractionMode(PLAY_AUTOMATICALLY_LIKE_MOVIE), 239 blendingHint(USE_IMAGE_ALPHA), 240 delayTime(0.0), 241 startTime(0.0), 242 stopTime(-1.0), 243 volume("") 244 {} 245 246 std::string options; 247 float width; 248 float height; 249 osg::Vec4 region; 250 bool region_in_pixel_coords; 251 float texcoord_rotate; 252 osg::ImageStream::LoopingMode loopingMode; 253 int page; 254 osg::Vec4 backgroundColor; 255 double fps; 256 double duration; 257 258 bool imageSequence; 259 osg::ImageSequence::Mode imageSequencePagingMode; 260 261 enum ImageSequenceInteractionMode 262 { 263 PLAY_AUTOMATICALLY_LIKE_MOVIE, 264 USE_MOUSE_X_POSITION, 265 USE_MOUSE_Y_POSITION 266 }; 267 ImageSequenceInteractionMode imageSequenceInteractionMode; 268 269 enum BlendingHint 270 { 271 USE_IMAGE_ALPHA, 272 OFF, 273 ON 274 }; 275 276 BlendingHint blendingHint; 277 278 double delayTime; 279 double startTime; 280 double stopTime; 281 std::string volume; 282 283 }; 284 285 struct VolumeData 286 { 287 typedef osgVolume::VolumeSettings::ShadingModel ShadingModel; 288 typedef osgVolume::VolumeSettings::Technique Technique; 289 290 VolumeData(): 291 shadingModel(osgVolume::VolumeSettings::Standard), 292 useTabbedDragger(false), 293 useTrackballDragger(false), 294 region_in_pixel_coords(false), 295 alphaValue(), 296 cutoffValue(), 297 exteriorTransparencyFactorValue(), 298 sampleDensityValue(), 299 sampleRatioValue(), 300 colorSpaceOperation(osg::NO_COLOR_SPACE_OPERATION), 301 colorModulate(1.0f,1.0f,1.0f,1.0f), 302 technique(osgVolume::VolumeSettings::RayTraced) 303 { 304 hullPositionData.position = osg::Vec3(0.0,0.0,0.0); 305 hullPositionData.frame = osgPresentation::SlideShowConstructor::MODEL; 306 } 307 308 osg::ref_ptr<osgVolume::VolumeSettings> volumeSettings; 309 310 std::string options; 311 ShadingModel shadingModel; 312 osg::ref_ptr<osg::TransferFunction1D> transferFunction; 313 bool useTabbedDragger; 314 bool useTrackballDragger; 315 std::string region; 316 bool region_in_pixel_coords; 317 std::string alphaValue; 318 std::string cutoffValue; 319 std::string exteriorTransparencyFactorValue; 320 std::string sampleDensityValue; 321 std::string sampleDensityWhenMovingValue; 322 323 std::string sampleRatioValue; 324 std::string sampleRatioWhenMovingValue; 325 326 osg::ColorSpaceOperation colorSpaceOperation; 327 osg::Vec4 colorModulate; 328 Technique technique; 329 std::string hull; 330 PositionData hullPositionData; 331 }; 332 333 334 struct FontData 335 { 336 FontData(): 337 font("fonts/arial.ttf"), 338 layout(osgText::Text::LEFT_TO_RIGHT), 339 alignment(osgText::Text::LEFT_BASE_LINE), 340 axisAlignment(osgText::Text::XZ_PLANE), 341 characterSizeMode(osgText::Text::OBJECT_COORDS), 342 characterSize(0.04f), 343 maximumHeight(1.0f), 344 maximumWidth(1.0f), 345 color(1.0f,1.0f,1.0f,1.0f) {} 346 347 std::string font; 348 osgText::Text::Layout layout; 349 osgText::Text::AlignmentType alignment; 350 osgText::Text::AxisAlignment axisAlignment; 351 osgText::Text::CharacterSizeMode characterSizeMode; 352 float characterSize; 353 float maximumHeight; 354 float maximumWidth; 355 osg::Vec4 color; 356 }; 357 358 enum ScriptCallbackType 359 { 360 UPDATE_SCRIPT, 361 EVENT_SCRIPT 362 }; 363 364 typedef std::pair<ScriptCallbackType, std::string> ScriptPair; 365 366 struct ScriptData 367 { 368 ScriptData() {} 369 370 typedef std::vector<ScriptPair> Scripts; 371 Scripts scripts; 372 373 bool hasScripts() const { return !scripts.empty(); } 374 }; 375 376 SlideShowConstructor(osgDB::Options* options); 377 378 void createPresentation(); 379 380 void setBackgroundColor(const osg::Vec4& color, bool updateClearNode); 381 const osg::Vec4& getBackgroundColor() const { return _backgroundColor; } 382 383 void setTextColor(const osg::Vec4& color); 384 const osg::Vec4& getTextColor() const { return _textFontDataDefault.color; } 385 386 void setPresentationName(const std::string& name); 387 388 void setPresentationAspectRatio(float aspectRatio); 389 390 void setPresentationAspectRatio(const std::string& str); 391 392 void setPresentationDuration(double duration); 393 394 void addScriptEngine(const std::string& scriptEngineName); 395 396 void addScriptFile(const std::string& name, const std::string& filename); 397 398 void addScript(const std::string& name, const std::string& language, const std::string& script); 399 400 void addSlide(); 401 402 void selectSlide(int slideNum); 403 404 405 void setSlideTitle(const std::string& name, PositionData& positionData, FontData& fontData) 406 { 407 _titlePositionData = positionData; 408 _titleFontData = fontData; 409 _slideTitle = name; 410 } 411 412 void setSlideBackgrondHUD(bool hud) { _slideBackgroundAsHUD = hud; } 413 void setSlideBackground(const std::string& name) { _slideBackgroundImageFileName = name; } 414 415 void setSlideDuration(double duration); 416 417 Timeout* addTimeout(); 418 419 void addLayer(bool inheritPreviousLayers=true, bool defineAsBaseLayer=false); 420 421 void selectLayer(int layerNum); 422 423 void setLayerDuration(double duration); 424 425 426 // title settings 427 FontData& getTitleFontData() { return _titleFontData; } 428 FontData& getTitleFontDataDefault() { return _titleFontDataDefault; } 429 430 PositionData& getTitlePositionData() { return _titlePositionData; } 431 PositionData& getTitlePositionDataDefault() { return _titlePositionDataDefault; } 432 433 // text settings 434 FontData& getTextFontData() { return _textFontData; } 435 FontData& getTextFontDataDefault() { return _textFontDataDefault; } 436 437 PositionData& getTextPositionData() { return _textPositionData; } 438 PositionData& getTextPositionDataDefault() { return _textPositionDataDefault; } 439 440 void translateTextCursor(const osg::Vec3& delta) { _textPositionData.position += delta; } 441 442 // image settings 443 PositionData& getImagePositionData() { return _imagePositionData; } 444 PositionData& getImagePositionDataDefault() { return _imagePositionDataDefault; } 445 446 // model settings 447 PositionData& getModelPositionData() { return _modelPositionData; } 448 PositionData& getModelPositionDataDefault() { return _modelPositionDataDefault; } 449 450 451 enum PresentationContext { 452 CURRENT_PRESENTATION, 453 CURRENT_SLIDE, 454 CURRENT_LAYER 455 }; 456 457 void addEventHandler(PresentationContext presentationContext, osg::ref_ptr<osgGA::GUIEventHandler> handler); 458 459 void keyToDoOperation(PresentationContext presentationContext, int key, Operation operation, const JumpData& jumpData=JumpData()); 460 void keyToDoOperation(PresentationContext presentationContext, int key, const std::string& command, Operation operation, const JumpData& jumpData=JumpData()); 461 void keyEventOperation(PresentationContext presentationContext, int key, const KeyPosition& keyPos, const JumpData& jumpData=JumpData()); 462 463 void layerClickToDoOperation(Operation operation, const JumpData& jumpData=JumpData()); 464 void layerClickToDoOperation(const std::string& command, Operation operation, const JumpData& jumpData=JumpData()); 465 void layerClickEventOperation(const KeyPosition& keyPos, const JumpData& jumpData=JumpData()); 466 467 void addPropertyAnimation(PresentationContext presentationContext, PropertyAnimation* propertyAnimation); 468 469 void addScriptCallback(PresentationContext presentationContext, ScriptCallbackType scriptCallbackType, const std::string& functionName); 470 471 void addScriptToNode(ScriptCallbackType scriptCallbackType, const std::string& name, osg::Node* node); 472 473 void addScriptsToNode(const ScriptData& scriptData, osg::Node* node); 474 475 void addToCurrentLayer(osg::Node* subgraph); 476 477 void addBullet(const std::string& bullet, PositionData& positionData, FontData& fontData, const ScriptData& scriptData); 478 479 void addParagraph(const std::string& paragraph, PositionData& positionData, FontData& fontData, const ScriptData& scriptData); 480 481 osg::Image* readImage(const std::string& filename, const ImageData& imageData); 482 483 void addImage(const std::string& filename,const PositionData& positionData, const ImageData& imageData, const ScriptData& scriptData); 484 485 void addStereoImagePair(const std::string& filenameLeft, const ImageData& imageDataLeft, const std::string& filenameRight,const ImageData& imageDataRight, const PositionData& positionData, const ScriptData& scriptData); 486 487 void addGraph(const std::string& filename,const PositionData& positionData, const ImageData& imageData, const ScriptData& scriptData); 488 void addVNC(const std::string& filename,const PositionData& positionData, const ImageData& imageData, const std::string& password, const ScriptData& scriptData); 489 void addBrowser(const std::string& filename,const PositionData& positionData, const ImageData& imageData, const ScriptData& scriptData); 490 void addPDF(const std::string& filename,const PositionData& positionData, const ImageData& imageData, const ScriptData& scriptData); 491 osg::Image* addInteractiveImage(const std::string& filename,const PositionData& positionData, const ImageData& imageData, const ScriptData& scriptData); 492 493 void addModel(osg::Node* subgraph, const PositionData& positionData, const ModelData& modelData, const ScriptData& scriptData); 494 495 void addModel(const std::string& filename, const PositionData& positionData, const ModelData& modelData, const ScriptData& scriptData); 496 497 void setUpVolumeScalarProperty(osgVolume::VolumeTile* tile, osgVolume::ScalarProperty* property, const std::string& source); 498 499 void addVolume(const std::string& filename, const PositionData& positionData, const VolumeData& volumeData, const ScriptData& scriptData); 500 501 osg::Group* takePresentation() { return _root.release(); } 502 503 osg::Group* getPresentation() { return _root.get(); } 504 505 osg::Switch* getPresentationSwitch() { return _presentationSwitch.get(); } 506 507 osg::Switch* getCurrentSlide() { return _slide.get(); } 508 509 void pushCurrentLayer(osg::Group* newLayerGroup); 510 void popCurrentLayer(); 511 512 osg::Group* getCurrentLayer() { return _currentLayer.get(); } 513 514 void setLoopPresentation(bool loop) { _loopPresentation = loop; } 515 bool getLoopPresentation() const { return _loopPresentation; } 516 517 void setAutoSteppingActive(bool flag = true) { _autoSteppingActive = flag; } 518 bool getAutoSteppingActive() const { return _autoSteppingActive; } 519 520 void setHUDSettings(HUDSettings* hudSettings) { _hudSettings = hudSettings; } 521 HUDSettings* getHUDSettings() { return _hudSettings.get(); } 522 const HUDSettings* getHUDSettings() const { return _hudSettings.get(); } 523 524 osg::ScriptEngine* getOrCreateScriptEngine(const std::string& language); 525 526protected: 527 528 void findImageStreamsAndAddCallbacks(osg::Node* node); 529 530 osg::Geometry* createTexturedQuadGeometry(const osg::Vec3& pos, const osg::Vec4& rotation, float width,float height, osg::Image* image, bool& usedTextureRectangle); 531 void setUpMovieVolume(osg::Node* subgraph, osg::ImageStream* imageStream, const ImageData& imageData); 532 533 osg::Vec3 computePositionInModelCoords(const PositionData& positionData) const; 534 void updatePositionFromInModelCoords(const osg::Vec3& vertex, PositionData& positionData) const; 535 536 osg::Vec3 convertSlideToModel(const osg::Vec3& position) const; 537 osg::Vec3 convertModelToSlide(const osg::Vec3& position) const; 538 539 osg::AnimationPathCallback* getAnimationPathCallback(const PositionData& positionData); 540 541 osg::Node* attachMaterialAnimation(osg::Node* model, const PositionData& positionData); 542 bool attachTexMat(osg::StateSet* stateset, const ImageData& imageData, float s, float t, bool textureRectangle); 543 544 osg::StateSet* createTransformStateSet() 545 { 546 osg::StateSet* stateset = new osg::StateSet; 547 #if !defined(OSG_GLES2_AVAILABLE) 548 stateset->setMode(GL_NORMALIZE,osg::StateAttribute::ON); 549 #endif 550 return stateset; 551 } 552 553 osg::Node* decorateSubgraphForPosition(osg::Node* node, PositionData& positionData); 554 osg::Node* decorateSubgraphForPositionAndAnimation(osg::Node* node, const PositionData& positionData); 555 556 osg::ref_ptr<osgDB::Options> _options; 557 558 osg::Vec3 _slideOrigin; 559 osg::Vec3 _eyeOrigin; 560 double _slideWidth; 561 double _slideHeight; 562 double _slideDistance; 563 unsigned int _leftEyeMask; 564 unsigned int _rightEyeMask; 565 566 osg::ref_ptr<HUDSettings> _hudSettings; 567 568 // title settings 569 FontData _titleFontData; 570 FontData _titleFontDataDefault; 571 572 PositionData _titlePositionData; 573 PositionData _titlePositionDataDefault; 574 575 // text settings 576 FontData _textFontData; 577 FontData _textFontDataDefault; 578 579 PositionData _textPositionData; 580 PositionData _textPositionDataDefault; 581 582 // image settings 583 PositionData _imagePositionData; 584 PositionData _imagePositionDataDefault; 585 586 // model settings 587 PositionData _modelPositionData; 588 PositionData _modelPositionDataDefault; 589 590 591 bool _loopPresentation; 592 bool _autoSteppingActive; 593 osg::Vec4 _backgroundColor; 594 std::string _presentationName; 595 double _presentationDuration; 596 597 osg::ref_ptr<osgPresentation::PropertyManager> _propertyManager; 598 osg::ref_ptr<osgPresentation::PropertyEventCallback> _propertyEventCallback; 599 600 osg::ref_ptr<osg::Group> _root; 601 osg::ref_ptr<osg::Switch> _presentationSwitch; 602 603 typedef std::map< std::string, osg::ref_ptr<osg::ScriptEngine> > ScriptEngineMap; 604 ScriptEngineMap _scriptEngines; 605 606 typedef std::map< std::string, osg::ref_ptr<osg::Script> > ScriptMap; 607 ScriptMap _scripts; 608 609 osg::ref_ptr<osg::ClearNode> _slideClearNode; 610 osg::ref_ptr<osg::Switch> _slide; 611 std::string _slideTitle; 612 std::string _slideBackgroundImageFileName; 613 bool _slideBackgroundAsHUD; 614 615 osg::ref_ptr<osg::Group> _previousLayer; 616 osg::ref_ptr<osg::Group> _currentLayer; 617 typedef std::vector< osg::ref_ptr<osg::Group> > LayerStack; 618 LayerStack _layerStack; 619 620 osg::ref_ptr<FilePathData> _filePathData; 621 622 osg::ref_ptr<osg::Group> _layerToApplyEventCallbackTo; 623 624 typedef std::list< osg::ref_ptr<osgGA::GUIEventHandler> > EventHandlerList; 625 EventHandlerList _currentEventCallbacksToApply; 626 627 628 std::string findFileAndRecordPath(const std::string& filename); 629 630 void recordOptionsFilePath(const osgDB::Options* options); 631 632}; 633 634} 635 636#endif 637