From 52ff51e0ebc9ea361d1d5a9085a798f57fae743b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 14 Mar 2011 21:36:32 +0000 Subject: [PATCH] Implemented billboard="on" option for image, bullet and paragraph tags --- include/osgPresentation/SlideShowConstructor | 27 ++++++---- src/osgPlugins/p3d/ReaderWriterP3D.cpp | 54 ++++++++++++++++--- src/osgPresentation/SlideShowConstructor.cpp | 55 ++++++++++++++++---- 3 files changed, 111 insertions(+), 25 deletions(-) diff --git a/include/osgPresentation/SlideShowConstructor b/include/osgPresentation/SlideShowConstructor index 46274bc40..4dec63332 100644 --- a/include/osgPresentation/SlideShowConstructor +++ b/include/osgPresentation/SlideShowConstructor @@ -129,8 +129,11 @@ public: path_loop_mode(osg::AnimationPath::NO_LOOPING), animation_material_time_offset(0.0), animation_material_time_multiplier(1.0), - animation_material_loop_mode(AnimationMaterial::NO_LOOPING) {} - + animation_material_loop_mode(AnimationMaterial::NO_LOOPING), + autoRotate(false), + autoScale(false) {} + + bool requiresPosition() const { return (position[0]!=0.0f || position[1]!=1.0f || position[2]!=1.0f); @@ -173,6 +176,8 @@ public: AnimationMaterial::LoopMode animation_material_loop_mode; std::string animation_material_filename; std::string fade; + bool autoRotate; + bool autoScale; }; struct ModelData @@ -247,19 +252,21 @@ public: layout(osgText::Text::LEFT_TO_RIGHT), alignment(osgText::Text::LEFT_BASE_LINE), axisAlignment(osgText::Text::XZ_PLANE), + characterSizeMode(osgText::Text::OBJECT_COORDS), characterSize(0.04f), maximumHeight(1.0f), maximumWidth(1.0f), color(1.0f,1.0f,1.0f,1.0f) {} - std::string font; - osgText::Text::Layout layout; - osgText::Text::AlignmentType alignment; - osgText::Text::AxisAlignment axisAlignment; - float characterSize; - float maximumHeight; - float maximumWidth; - osg::Vec4 color; + std::string font; + osgText::Text::Layout layout; + osgText::Text::AlignmentType alignment; + osgText::Text::AxisAlignment axisAlignment; + osgText::Text::CharacterSizeMode characterSizeMode; + float characterSize; + float maximumHeight; + float maximumWidth; + osg::Vec4 color; }; diff --git a/src/osgPlugins/p3d/ReaderWriterP3D.cpp b/src/osgPlugins/p3d/ReaderWriterP3D.cpp index 9bb1ab5aa..ce764a964 100644 --- a/src/osgPlugins/p3d/ReaderWriterP3D.cpp +++ b/src/osgPlugins/p3d/ReaderWriterP3D.cpp @@ -72,6 +72,10 @@ public: _alignmentMap["RIGHT_BASE_LINE"] = osgText::Text::RIGHT_BASE_LINE; _alignmentMap["BASE_LINE"] = osgText::Text::LEFT_BASE_LINE; + _characterSizeModeMap["OBJECT_COORDS"] = osgText::Text::OBJECT_COORDS; + _characterSizeModeMap["SCREEN_COORDS"] = osgText::Text::SCREEN_COORDS; + _characterSizeModeMap["OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT"] = osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT; + _stringKeyMap["Home"]=' '; _stringKeyMap["Start"]= osgGA::GUIEventAdapter::KEY_Home; _stringKeyMap["Next"]= osgGA::GUIEventAdapter::KEY_Page_Down; @@ -185,6 +189,7 @@ public: bool getTrimmedProperty(osgDB::XmlNode*cur, const char* token, std::string& value) const; bool getProperty(osgDB::XmlNode*cur, const char* token, osgText::Text::Layout& value) const; bool getProperty(osgDB::XmlNode*cur, const char* token, osgText::Text::AlignmentType& value) const; + bool getProperty(osgDB::XmlNode*cur, const char* token, osgText::Text::CharacterSizeMode& value) const; bool getProperties(osgDB::XmlNode*cur, osgPresentation::SlideShowConstructor::PositionData& value) const; bool getProperties(osgDB::XmlNode*cur, osgPresentation::SlideShowConstructor::FontData& value) const; @@ -198,15 +203,17 @@ public: typedef std::map ColorMap; typedef std::map LayoutMap; typedef std::map AlignmentMap; + typedef std::map CharacterSizeModeMap; typedef std::map StringKeyMap; std::string expandEnvVarsInFileName(const std::string& filename) const; - ColorMap _colorMap; - LayoutMap _layoutMap; - AlignmentMap _alignmentMap; - StringKeyMap _stringKeyMap; + ColorMap _colorMap; + LayoutMap _layoutMap; + AlignmentMap _alignmentMap; + CharacterSizeModeMap _characterSizeModeMap; + StringKeyMap _stringKeyMap; typedef std::map > TemplateMap; mutable TemplateMap _templateMap; @@ -459,6 +466,20 @@ bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode*cur, const char* token, osgT return true; } +bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode*cur, const char* token, osgText::Text::CharacterSizeMode& value) const +{ + osgDB::XmlNode::Properties::iterator pitr = cur->properties.find(token); + if (pitr==cur->properties.end()) return false; + + const std::string& str = pitr->second; + CharacterSizeModeMap::const_iterator itr = _characterSizeModeMap.find(str); + if (itr!=_characterSizeModeMap.end()) + { + value = itr->second; + } + return true; +} + bool ReaderWriterP3DXML::getProperties(osgDB::XmlNode*cur, osgPresentation::SlideShowConstructor::PositionData& value) const { bool propertiesRead=false; @@ -698,6 +719,20 @@ bool ReaderWriterP3DXML::getProperties(osgDB::XmlNode*cur, osgPresentation::Slid propertiesRead = true; } + if (getProperty(cur, "billboard", str)) + { + value.autoRotate = (str != "off" && str != "Off" && str != "OFF"); + OSG_NOTIFY(_notifyLevel)<<"billboard, str="<setFont(fontData.font); text->setColor(fontData.color); text->setCharacterSize(fontData.characterSize*_slideHeight); + text->setCharacterSizeMode(fontData.characterSizeMode); text->setFontResolution(110,120); text->setMaximumWidth(fontData.maximumWidth*_slideWidth); text->setLayout(fontData.layout); text->setAlignment(fontData.alignment); text->setAxisAlignment(fontData.axisAlignment); text->setPosition(localPosition); - + + if (positionData.autoRotate) + { + text->setAxisAlignment(osgText::Text::SCREEN); + } + + if (positionData.autoScale) + { + text->setCharacterSizeMode(osgText::Text::SCREEN_COORDS); + } + text->setText(bullet); osg::BoundingBox bb = text->getBound(); @@ -595,6 +606,7 @@ void SlideShowConstructor::addParagraph(const std::string& paragraph, PositionDa text->setFont(fontData.font); text->setColor(fontData.color); text->setCharacterSize(fontData.characterSize*_slideHeight); + text->setCharacterSizeMode(fontData.characterSizeMode); text->setFontResolution(110,120); text->setMaximumWidth(fontData.maximumWidth*_slideWidth); text->setLayout(fontData.layout); @@ -602,6 +614,15 @@ void SlideShowConstructor::addParagraph(const std::string& paragraph, PositionDa text->setAxisAlignment(fontData.axisAlignment); text->setPosition(localPosition); + if (positionData.autoRotate) + { + text->setAxisAlignment(osgText::Text::SCREEN); + } + + if (positionData.autoScale) + { + text->setCharacterSizeMode(osgText::Text::SCREEN_COORDS); + } text->setText(paragraph); osg::BoundingBox bb = text->getBound(); @@ -819,21 +840,37 @@ void SlideShowConstructor::addImage(const std::string& filename, const PositionD 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; //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; + 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::StateSet* pictureStateSet = pictureQuad->getOrCreateStateSet(); attachTexMat(pictureStateSet, imageData, s, t, usedTextureRectangle); - 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()) @@ -853,7 +890,7 @@ void SlideShowConstructor::addImage(const std::string& filename, const PositionD 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])));