From 256da4879e4bb7a0b3e32caf75eaf32cd3424c9d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 16 Mar 2011 10:51:42 +0000 Subject: [PATCH] Added hud and billboard support to image, stereo_image, pdf, browser and vnc image placement --- include/osgPresentation/SlideShowConstructor | 51 +++- src/osgPlugins/p3d/ReaderWriterP3D.cpp | 8 + src/osgPresentation/SlideShowConstructor.cpp | 243 ++++++++++++------- 3 files changed, 217 insertions(+), 85 deletions(-) diff --git a/include/osgPresentation/SlideShowConstructor b/include/osgPresentation/SlideShowConstructor index 6797d6c27..93a8b0e82 100644 --- a/include/osgPresentation/SlideShowConstructor +++ b/include/osgPresentation/SlideShowConstructor @@ -32,6 +32,44 @@ namespace osgPresentation { +class OSGPRESENTATION_EXPORT HUDSettings : public osg::Referenced +{ + public: + HUDSettings(double slideDistance, float eyeOffset, unsigned int leftMask, unsigned int rightMask); + + virtual bool getModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const; + + virtual bool getInverseModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const; + + double _slideDistance; + double _eyeOffset; + unsigned int _leftMask; + unsigned int _rightMask; + +protected: + + virtual ~HUDSettings(); +}; + + +class OSGPRESENTATION_EXPORT HUDTransform : public osg::Transform +{ + public: + + HUDTransform(HUDSettings* hudSettings); + + virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const; + + virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const; + +protected: + + virtual ~HUDTransform(); + + osg::ref_ptr _hudSettings; + +}; + class OSGPRESENTATION_EXPORT SlideShowConstructor { public: @@ -303,6 +341,7 @@ public: _slideTitle = name; } + void setSlideBackgrondHUD(bool hud) { _slideBackgroundAsHUD = hud; } void setSlideBackground(const std::string& name) { _slideBackgroundImageFileName = name; } void setSlideDuration(double duration); @@ -380,6 +419,10 @@ public: void setAutoSteppingActive(bool flag = true) { _autoSteppingActive = flag; } bool getAutoSteppingActive() const { return _autoSteppingActive; } + void setHUDSettings(HUDSettings* hudSettings) { _hudSettings = hudSettings; } + HUDSettings* getHUDSettings() { return _hudSettings.get(); } + const HUDSettings* getHUDSettings() const { return _hudSettings.get(); } + protected: @@ -416,9 +459,10 @@ protected: double _slideWidth; double _slideHeight; double _slideDistance; - unsigned _leftEyeMask; - unsigned _rightEyeMask; - double _eyeOffset; + unsigned int _leftEyeMask; + unsigned int _rightEyeMask; + + osg::ref_ptr _hudSettings; // title settings FontData _titleFontData; @@ -456,6 +500,7 @@ protected: osg::ref_ptr _slide; std::string _slideTitle; std::string _slideBackgroundImageFileName; + bool _slideBackgroundAsHUD; osg::ref_ptr _previousLayer; osg::ref_ptr _currentLayer; diff --git a/src/osgPlugins/p3d/ReaderWriterP3D.cpp b/src/osgPlugins/p3d/ReaderWriterP3D.cpp index 58ebb0979..e2f29a2b4 100644 --- a/src/osgPlugins/p3d/ReaderWriterP3D.cpp +++ b/src/osgPlugins/p3d/ReaderWriterP3D.cpp @@ -1550,6 +1550,14 @@ void ReaderWriterP3DXML::parseSlide (osgPresentation::SlideShowConstructor& cons else if (cur->name == "background") { constructor.setSlideBackground(cur->contents); + + std::string str; + if (getProperty(cur, "hud", str)) + { + bool hud = (str != "off" && str != "Off" && str != "OFF"); + OSG_NOTIFY(_notifyLevel)<<"background hud, str="<(nv); +bool HUDSettings::getModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const +{ + matrix.makeLookAt(osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,_slideDistance,0.0),osg::Vec3d(0.0,0.0,1.0)); + + if (nv->getTraversalMask()==_leftMask) + { + matrix.postMultTranslate(osg::Vec3(_eyeOffset,0.0,0.0)); + } + else if (nv->getTraversalMask()==_rightMask) + { + matrix.postMultTranslate(osg::Vec3(-_eyeOffset,0.0,0.0)); + } + return true; +} + +bool HUDSettings::getInverseModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const +{ + osg::Matrix modelView; + getModelViewMatrix(modelView,nv); + matrix.invert(modelView); + return true; +} - matrix.makeLookAt(osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,_slideDistance,0.0),osg::Vec3d(0.0,0.0,1.0)); +HUDTransform::HUDTransform(HUDSettings* hudSettings): + _hudSettings(hudSettings) +{ + setDataVariance(osg::Object::DYNAMIC); + setReferenceFrame(osg::Transform::ABSOLUTE_RF); +} - if (cullVisitor) - { - if (cullVisitor->getTraversalMask()==_leftMask) - { - matrix.postMultTranslate(osg::Vec3(_eyeOffset,0.0,0.0)); - } - else if (cullVisitor->getTraversalMask()==_rightMask) - { - matrix.postMultTranslate(osg::Vec3(-_eyeOffset,0.0,0.0)); - } - } +HUDTransform::~HUDTransform() {} - return true; - } +bool HUDTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const +{ + return _hudSettings->getModelViewMatrix(matrix,nv); +} - virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const - { - osg::Matrix localToWorld; - localToWorld.makeLookAt(osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,_slideDistance,0.0),osg::Vec3d(0.0,0.0,1.0)); - matrix.invert(localToWorld); - return true; - } - -protected: - - double _slideDistance; - double _eyeOffset; - unsigned int _leftMask; - unsigned int _rightMask; -}; +bool HUDTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const +{ + return _hudSettings->getInverseModelViewMatrix(matrix,nv); +} SlideShowConstructor::SlideShowConstructor(osgDB::Options* options): _options(options) { - _slideHeight = osg::DisplaySettings::instance()->getScreenHeight(); - _slideWidth = osg::DisplaySettings::instance()->getScreenWidth(); - _slideDistance = osg::DisplaySettings::instance()->getScreenDistance(); + osg::DisplaySettings* ds = osg::DisplaySettings::instance(); + + _slideHeight = ds->getScreenHeight(); + _slideWidth = ds->getScreenWidth(); + _slideDistance = ds->getScreenDistance(); _leftEyeMask = 0x01; _rightEyeMask = 0x02; - _eyeOffset = 0.025; + + _hudSettings = new HUDSettings(_slideDistance, ds->getEyeSeparation()*0.5, _leftEyeMask, _rightEyeMask); _backgroundColor.set(0.0f,0.0f,0.0f,1.0f); @@ -159,7 +166,7 @@ SlideShowConstructor::SlideShowConstructor(osgDB::Options* options): // set up title defaults _titleFontDataDefault.font = "fonts/arial.ttf"; _titleFontDataDefault.color.set(1.0f,1.0f,1.0f,1.0f); - _titleFontDataDefault.layout = osgText::Text::LEFT_TO_RIGHT; + _titleFontDataDefault.layout =osgText::Text::LEFT_TO_RIGHT; _titleFontDataDefault.alignment = osgText::Text::CENTER_BASE_LINE; _titleFontDataDefault.axisAlignment = osgText::Text::XZ_PLANE; _titleFontDataDefault.characterSize = 0.06f; @@ -180,6 +187,8 @@ SlideShowConstructor::SlideShowConstructor(osgDB::Options* options): _loopPresentation = false; _autoSteppingActive = false; + + _slideBackgroundAsHUD = false; } void SlideShowConstructor::setPresentationAspectRatio(float aspectRatio) @@ -422,7 +431,16 @@ void SlideShowConstructor::addLayer(bool inheritPreviousLayers, bool defineAsBas background->addDrawable(backgroundQuad); - _currentLayer->addChild(background); + if (_slideBackgroundAsHUD) + { + HUDTransform* hudTransform = new HUDTransform(_hudSettings.get()); + hudTransform->addChild(background); + _currentLayer->addChild(hudTransform); + } + else + { + _currentLayer->addChild(background); + } } if (!_slideTitle.empty()) @@ -609,7 +627,7 @@ osg::Node* SlideShowConstructor::decorateSubgraphForPosition(osg::Node* node, Po if (positionData.hud) { - HUDTransform* hudTransform = new HUDTransform(_slideDistance, _eyeOffset, _leftEyeMask, _rightEyeMask); + HUDTransform* hudTransform = new HUDTransform(_hudSettings.get()); hudTransform->addChild(subgraph); subgraph = hudTransform; @@ -928,7 +946,6 @@ void SlideShowConstructor::addImage(const std::string& filename, const PositionD subgraph = picture; } - // attach any meterial animation. if (positionData.requiresMaterialAnimation()) subgraph = attachMaterialAnimation(subgraph,positionData); @@ -983,6 +1000,14 @@ void SlideShowConstructor::addImage(const std::string& filename, const PositionD subgraph = animation_transform; } + if (positionData.hud) + { + HUDTransform* hudTransform = new HUDTransform(_hudSettings.get()); + hudTransform->addChild(subgraph); + + subgraph = hudTransform; + } + _currentLayer->addChild(subgraph); } @@ -1031,10 +1056,8 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c float s = imageLeft->s(); float t = imageLeft->t(); - - // temporary hack - float height = 0.0f; + float sx = imageDataLeft.region_in_pixel_coords ? 1.0f : s; float sy = imageDataLeft.region_in_pixel_coords ? 1.0f : t; @@ -1048,18 +1071,18 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c float image_width = _slideWidth*positionData.scale.x(); float image_height = image_width*aspectRatio*positionData.scale.y()/positionData.scale.x(); - float offset = height*image_height*0.1f; - + float offset = 0.0f; + bool usedTextureRectangle = false; - osg::Vec3 pos = computePositionInModelCoords(positionData) + - osg::Vec3(-image_width*0.5f+offset,-offset,-image_height*0.5f-offset); + osg::Vec3 pos = computePositionInModelCoords(positionData); + osg::Vec3 image_local_pos = osg::Vec3(-image_width*0.5f+offset,-offset,-image_height*0.5f-offset); + osg::Vec3 image_pos = positionData.autoRotate ? image_local_pos : (pos+image_local_pos); - osg::Geode* pictureLeft = new osg::Geode; + + osg::Node* pictureLeft = 0; { - pictureLeft->setNodeMask(_leftEyeMask); - - osg::Geometry* pictureLeftQuad = createTexturedQuadGeometry(pos, positionData.rotate, image_width,image_height,imageLeft.get(),usedTextureRectangle); + osg::Geometry* pictureLeftQuad = createTexturedQuadGeometry(image_pos, positionData.rotate, image_width,image_height,imageLeft.get(),usedTextureRectangle); osg::StateSet* pictureLeftStateSet = pictureLeftQuad->getOrCreateStateSet(); if (isImageTranslucent) @@ -1069,15 +1092,28 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c attachTexMat(pictureLeftStateSet, imageDataLeft, s, t, usedTextureRectangle); - pictureLeft->addDrawable(pictureLeftQuad); + if (positionData.autoRotate) + { + osg::Billboard* billboard = new osg::Billboard; + billboard->setMode(osg::Billboard::POINT_ROT_EYE); + billboard->setNormal(osg::Vec3(0.0f,-1.0f,0.0f)); + billboard->setAxis(osg::Vec3(0.0f,0.0f,1.0f)); + billboard->addDrawable(pictureLeftQuad,pos); + pictureLeft = billboard; + } + else + { + osg::Geode* geode = new osg::Geode; + geode->addDrawable(pictureLeftQuad); + pictureLeft = geode; + } + pictureLeft->setNodeMask(_leftEyeMask); } - osg::Geode* pictureRight = new osg::Geode; + osg::Node* pictureRight = 0; { - pictureRight->setNodeMask(_rightEyeMask); - - osg::Geometry* pictureRightQuad = createTexturedQuadGeometry(pos, positionData.rotate, image_width,image_height,imageRight.get(),usedTextureRectangle); + osg::Geometry* pictureRightQuad = createTexturedQuadGeometry(image_pos, positionData.rotate, image_width,image_height,imageRight.get(),usedTextureRectangle); osg::StateSet* pictureRightStateSet = pictureRightQuad->getOrCreateStateSet(); if (isImageTranslucent) @@ -1087,7 +1123,23 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c attachTexMat(pictureRightStateSet, imageDataRight, s, t, usedTextureRectangle); - pictureRight->addDrawable(pictureRightQuad); + if (positionData.autoRotate) + { + osg::Billboard* billboard = new osg::Billboard; + billboard->setMode(osg::Billboard::POINT_ROT_EYE); + billboard->setNormal(osg::Vec3(0.0f,-1.0f,0.0f)); + billboard->setAxis(osg::Vec3(0.0f,0.0f,1.0f)); + billboard->addDrawable(pictureRightQuad,pos); + pictureRight = billboard; + } + else + { + osg::Geode* geode = new osg::Geode; + geode->addDrawable(pictureRightQuad); + pictureRight = geode; + } + + pictureRight->setNodeMask(_rightEyeMask); } osg::Group* subgraph = new osg::Group; @@ -1145,6 +1197,14 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c subgraph = animation_transform; } + if (positionData.hud) + { + HUDTransform* hudTransform = new HUDTransform(_hudSettings.get()); + hudTransform->addChild(subgraph); + + subgraph = hudTransform; + } + _currentLayer->addChild(subgraph); } @@ -1268,10 +1328,7 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam float s = image->s(); float t = image->t(); - - // temporary hack - float height = 0.0f; - + float sx = imageData.region_in_pixel_coords ? 1.0f : s; float sy = imageData.region_in_pixel_coords ? 1.0f : t; @@ -1284,16 +1341,14 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam float image_width = _slideWidth*positionData.scale.x(); float image_height = image_width*aspectRatio*positionData.scale.y()/positionData.scale.x(); - float offset = height*image_height*0.1f; - - osg::Vec3 pos = computePositionInModelCoords(positionData) + osg::Vec3(-image_width*0.5f+offset,-offset,-image_height*0.5f-offset); - - osg::Geode* picture = new osg::Geode; - osg::Node* subgraph = picture; + float offset = 0.0f; + osg::Vec3 pos = computePositionInModelCoords(positionData); + osg::Vec3 image_local_pos = osg::Vec3(-image_width*0.5f+offset,-offset,-image_height*0.5f-offset); + osg::Vec3 image_pos = positionData.autoRotate ? image_local_pos : (pos+image_local_pos); bool usedTextureRectangle = false; - osg::Geometry* pictureQuad = createTexturedQuadGeometry(pos, positionData.rotate, image_width, image_height, image, usedTextureRectangle); + osg::Geometry* pictureQuad = createTexturedQuadGeometry(image_pos, positionData.rotate, image_width, image_height, image, usedTextureRectangle); osg::ref_ptr handler = new osgViewer::InteractiveImageHandler(image); pictureQuad->setEventCallback(handler.get()); @@ -1305,7 +1360,23 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam pictureStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - picture->addDrawable(pictureQuad); + osg::Node* subgraph = 0; + + if (positionData.autoRotate) + { + osg::Billboard* picture = new osg::Billboard; + picture->setMode(osg::Billboard::POINT_ROT_EYE); + picture->setNormal(osg::Vec3(0.0f,-1.0f,0.0f)); + picture->setAxis(osg::Vec3(0.0f,0.0f,1.0f)); + picture->addDrawable(pictureQuad,pos); + subgraph = picture; + } + else + { + osg::Geode* picture = new osg::Geode; + picture->addDrawable(pictureQuad); + subgraph = picture; + } // attach any meterial animation. if (positionData.requiresMaterialAnimation()) @@ -1318,7 +1389,7 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam osg::MatrixTransform* animation_transform = new osg::MatrixTransform; animation_transform->setDataVariance(osg::Object::DYNAMIC); animation_transform->setUpdateCallback( - new osgUtil::TransformCallback(picture->getBound().center(), + new osgUtil::TransformCallback(subgraph->getBound().center(), osg::Vec3(positionData.rotation[1],positionData.rotation[2],positionData.rotation[3]), osg::DegreesToRadians(positionData.rotation[0]))); @@ -1354,8 +1425,16 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam subgraph = animation_transform; } + if (positionData.hud) + { + HUDTransform* hudTransform = new HUDTransform(_hudSettings.get()); + hudTransform->addChild(subgraph); + + subgraph = hudTransform; + } + _currentLayer->addChild(subgraph); - + osgWidget::PdfImage* pdfImage = dynamic_cast(image); if (pdfImage && imageData.page>=0) {