From 9f5e13120326d909f3c62c04f5f2b08b19c166bf Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 4 Sep 2013 10:33:11 +0000 Subject: [PATCH] Added Action class NodeVisitor that supports osgPresentation nodes. --- examples/osgpresentation/osgpresentation.cpp | 42 ++++--- include/osgPresentation/Action | 88 ++++++++++++++ include/osgPresentation/Audio | 2 +- include/osgPresentation/Element | 21 ++-- include/osgPresentation/Group | 59 ++++++++- include/osgPresentation/Image | 2 +- include/osgPresentation/Layer | 2 +- include/osgPresentation/Model | 2 +- include/osgPresentation/Movie | 2 +- include/osgPresentation/Presentation | 2 +- include/osgPresentation/Section | 2 +- include/osgPresentation/Slide | 2 +- include/osgPresentation/Text | 4 +- include/osgPresentation/Volume | 2 +- src/osgPresentation/Action.cpp | 120 +++++++++++++++++++ src/osgPresentation/CMakeLists.txt | 2 + src/osgPresentation/Element.cpp | 34 ------ src/osgPresentation/Group.cpp | 25 +++- src/osgPresentation/Text.cpp | 20 +++- 19 files changed, 354 insertions(+), 79 deletions(-) create mode 100644 include/osgPresentation/Action create mode 100644 src/osgPresentation/Action.cpp diff --git a/examples/osgpresentation/osgpresentation.cpp b/examples/osgpresentation/osgpresentation.cpp index f0d43f6cc..936a68a8a 100644 --- a/examples/osgpresentation/osgpresentation.cpp +++ b/examples/osgpresentation/osgpresentation.cpp @@ -29,32 +29,28 @@ #include -class PrintSupportedProperties : public osg::NodeVisitor +class PrintSupportedProperties : public osgPresentation::Action { public: - PrintSupportedProperties() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + PrintSupportedProperties() : + osgPresentation::Action(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} - void apply(osg::Node& node) + void apply(osgPresentation::Group& group) { - osgPresentation::Group* pres_group = dynamic_cast(&node); - if (pres_group) + OSG_NOTICE<<"osgPresentation object : "<className()<getSupportedProperties(properties)) + for(osgPresentation::PropertyList::iterator itr = properties.begin(); + itr != properties.end(); + ++itr) { - for(osgPresentation::PropertyList::iterator itr = properties.begin(); - itr != properties.end(); - ++itr) - { - osgPresentation::ObjectDescription& od = *itr; - OSG_NOTICE<<" "<className()<<" : "<getName()<<", description = "<className()<<" : "<getName()<<", description = "< layer = new osgPresentation::Layer; osg::ref_ptr group = new osgPresentation::Group; osg::ref_ptr element = new osgPresentation::Element; + osg::ref_ptr text = new osgPresentation::Text; presentation->addChild(slide.get()); slide->addChild(layer.get()); //layer->addChild(element.get()); @@ -148,15 +145,24 @@ int main(int argc, char** argv) group->addChild(element.get()); element->addChild(model.get()); group->addChild(new osgPresentation::Model); - group->addChild(new osgPresentation::Text); + group->addChild(text.get()); group->addChild(new osgPresentation::Audio); group->addChild(new osgPresentation::Movie); group->addChild(new osgPresentation::Volume); + text->setProperty("string",std::string("This is a first test")); + text->setProperty("font",std::string("times.ttf")); + text->setProperty("character_size",2.2); + text->setProperty("width",std::string("103.2")); + + PrintSupportedProperties psp; presentation->accept(psp); + osgPresentation::LoadAction load; + presentation->accept( load ); + viewer.setSceneData( presentation.get() ); diff --git a/include/osgPresentation/Action b/include/osgPresentation/Action new file mode 100644 index 000000000..1c5c7c01e --- /dev/null +++ b/include/osgPresentation/Action @@ -0,0 +1,88 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2013 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGPRESENTATION_ACTION +#define OSGPRESENTATION_ACTION 1 + +#include +#include + +namespace osgPresentation +{ + +// forward declare osgPresention nodes +class Group; + +class Element; +class Text; +class Volume; +class Model; +class Image; +class Movie; + +class Section; +class Layer; +class Slide; +class Presentation; + +/** Action base class that is a NodeVistor that addes osgPresentation node support.*/ +class OSGPRESENTATION_EXPORT Action : public osg::NodeVisitor +{ + public: + Action(osg::NodeVisitor::TraversalMode traversalMode=osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN): + osg::NodeVisitor(traversalMode) {} + + virtual void apply(osgPresentation::Group& group); + + virtual void apply(osgPresentation::Element& element); + virtual void apply(osgPresentation::Text& text); + virtual void apply(osgPresentation::Volume& volume); + virtual void apply(osgPresentation::Model& model); + virtual void apply(osgPresentation::Image& image); + virtual void apply(osgPresentation::Movie& movie); + + virtual void apply(osgPresentation::Section& section); + virtual void apply(osgPresentation::Layer& layer); + virtual void apply(osgPresentation::Slide& slide); + virtual void apply(osgPresentation::Presentation& presentation); +}; + + +struct OSGPRESENTATION_EXPORT LoadAction : public Action +{ + void apply(osgPresentation::Element& element); +}; + +struct OSGPRESENTATION_EXPORT UnloadAction : public Action +{ + void apply(osgPresentation::Element& element); +}; + +struct OSGPRESENTATION_EXPORT ResetAction : public Action +{ + void apply(osgPresentation::Element& element); +}; + +struct OSGPRESENTATION_EXPORT PauseAction : public Action +{ + void apply(osgPresentation::Element& element); +}; + +struct OSGPRESENTATION_EXPORT PlayAction : public Action +{ + void apply(osgPresentation::Element& element); +}; + +} + +#endif diff --git a/include/osgPresentation/Audio b/include/osgPresentation/Audio index a4765e008..388b660df 100644 --- a/include/osgPresentation/Audio +++ b/include/osgPresentation/Audio @@ -29,7 +29,7 @@ class OSGPRESENTATION_EXPORT Audio : public osgPresentation::Element /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Audio(const Audio& audio,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Element(audio,copyop) {} - META_Node(osgPresentation, Audio); + META_Presentation(Audio); protected : diff --git a/include/osgPresentation/Element b/include/osgPresentation/Element index 3dc57bee8..6d5d07cc4 100644 --- a/include/osgPresentation/Element +++ b/include/osgPresentation/Element @@ -1,4 +1,4 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2013 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -31,9 +31,7 @@ class OSGPRESENTATION_EXPORT Element : public osgPresentation::Group /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Element(const Element& element,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Group(element,copyop) {} - META_Node(osgPresentation, Element); - - virtual void traverse(osg::NodeVisitor& nv); + META_Presentation(Element); /** Load the subgraph implementation of the element.*/ virtual bool load() { return false; } @@ -45,12 +43,6 @@ class OSGPRESENTATION_EXPORT Element : public osgPresentation::Group virtual bool loaded() const { return getNumChildren()!=0; } - /** Do updates as part of the update traversal.*/ - virtual void updateTraversal(osgUtil::UpdateVisitor& uv); - - /** Do updates as part of the event traversal.*/ - virtual void eventTraversal(osgGA::EventVisitor& ev); - /** Enter the element for the first time, starting any animations, movies, audio etc..*/ virtual void enter() {} @@ -58,6 +50,15 @@ class OSGPRESENTATION_EXPORT Element : public osgPresentation::Group virtual void leave() {} + /** Pause any animatios, videos, audio etc.*/ + virtual void pause() {} + + /** Play any animatios, videos, audio etc.*/ + virtual void play() {} + + /** Reset any animations, vidoes, audio etc. back to the begininng.*/ + virtual void reset() {} + protected : virtual ~Element() {} diff --git a/include/osgPresentation/Group b/include/osgPresentation/Group index 1e72eb903..3461c3ecd 100644 --- a/include/osgPresentation/Group +++ b/include/osgPresentation/Group @@ -1,4 +1,4 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2013 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -15,14 +15,37 @@ #define OSGPRESENTATION_GROUP 1 #include -#include +#include +#include + +#include namespace osgPresentation { - typedef std::pair< osg::ref_ptr, std::string> ObjectDescription; typedef std::list< ObjectDescription > PropertyList; +/** META_Presentation macro define the standard clone, isSameKindAs, className + * and accept methods. Use when subclassing from Node to make it + * more convenient to define the required pure virtual methods.*/ +#define META_Presentation(name) \ + virtual osg::Object* cloneType() const { return new name (); } \ + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new name (*this,copyop); } \ + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } \ + virtual const char* className() const { return #name; } \ + virtual const char* libraryName() const { return "osgPresentation"; } \ + virtual void accept(osg::NodeVisitor& nv) \ + { \ + if (nv.validNodeMask(*this)) \ + { \ + nv.pushOntoNodePath(this); \ + osgPresentation::Action* action = dynamic_cast(&nv); \ + if (action) action->apply(*this); \ + else nv.apply(*this); \ + nv.popFromNodePath(); \ + } \ + } + /** osgPresentation::Group */ class OSGPRESENTATION_EXPORT Group : public osg::MatrixTransform @@ -34,7 +57,7 @@ class OSGPRESENTATION_EXPORT Group : public osg::MatrixTransform /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Group(const Group& group,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osg::MatrixTransform(group,copyop) {} - META_Node(osgPresentation, Group); + META_Presentation(Group); /** Convinience method that casts the named UserObject to osg::TemplateValueObject and gets the value. * To use this template method you need to include the osg/ValueObject header.*/ @@ -53,6 +76,34 @@ class OSGPRESENTATION_EXPORT Group : public osg::MatrixTransform return setUserValue(name, value); } + /** Check for named Property, if it doesn't exist on this object check parents recursively for instances.*/ + osg::Object* getPropertyObject(const std::string& name, bool checkParents = true); + + /** Check for name Property, and convert to desired template value where possible. */ + template + bool getPropertyValue(const std::string& name, T& value, bool checkParents = true) + { + osg::Object* object = getPropertyObject(name, checkParents); + if (!object) return false; + + typedef osg::TemplateValueObject UserValueObject; + const UserValueObject* uvo = dynamic_cast(object); + if (uvo) + { + value = uvo->getValue(); + return true; + } + + osg::StringValueObject* svo = dynamic_cast(object); + if (svo) + { + std::istringstream str(svo->getValue()); + str >> value; + return !str.fail(); + } + return false; + } + /** Get all types of Properties supported by Presentation Object type, return true if the Properties are supported, false otherwise.*/ virtual bool getSupportedProperties(PropertyList&) { return false; } diff --git a/include/osgPresentation/Image b/include/osgPresentation/Image index eb7b0df8f..59075cdb4 100644 --- a/include/osgPresentation/Image +++ b/include/osgPresentation/Image @@ -29,7 +29,7 @@ class OSGPRESENTATION_EXPORT Image : public osgPresentation::Element /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Image(const Image& image,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Element(image,copyop) {} - META_Node(osgPresentation, Image); + META_Presentation(Image); protected : diff --git a/include/osgPresentation/Layer b/include/osgPresentation/Layer index 394461ae6..2594dee70 100644 --- a/include/osgPresentation/Layer +++ b/include/osgPresentation/Layer @@ -29,7 +29,7 @@ class OSGPRESENTATION_EXPORT Layer : public osgPresentation::Group /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Layer(const Layer& layer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Group(layer,copyop) {} - META_Node(osgPresentation, Layer); + META_Presentation(Layer); protected : diff --git a/include/osgPresentation/Model b/include/osgPresentation/Model index a638d1a68..a74a15474 100644 --- a/include/osgPresentation/Model +++ b/include/osgPresentation/Model @@ -29,7 +29,7 @@ class OSGPRESENTATION_EXPORT Model : public osgPresentation::Element /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Model(const Model& model,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Element(model,copyop) {} - META_Node(osgPresentation, Model); + META_Presentation(Model); protected : diff --git a/include/osgPresentation/Movie b/include/osgPresentation/Movie index 59578a216..97ad5f96f 100644 --- a/include/osgPresentation/Movie +++ b/include/osgPresentation/Movie @@ -29,7 +29,7 @@ class OSGPRESENTATION_EXPORT Movie : public osgPresentation::Element /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Movie(const Movie& movie,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Element(movie,copyop) {} - META_Node(osgPresentation, Movie); + META_Presentation(Movie); protected : diff --git a/include/osgPresentation/Presentation b/include/osgPresentation/Presentation index 28e991904..3616eef6f 100644 --- a/include/osgPresentation/Presentation +++ b/include/osgPresentation/Presentation @@ -29,7 +29,7 @@ class OSGPRESENTATION_EXPORT Presentation : public osgPresentation::Group /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Presentation(const Presentation& presentation,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Group(presentation,copyop) {} - META_Node(osgPresentation, Presentation); + META_Presentation(Presentation); protected : diff --git a/include/osgPresentation/Section b/include/osgPresentation/Section index b0f058be0..cd201384d 100644 --- a/include/osgPresentation/Section +++ b/include/osgPresentation/Section @@ -29,7 +29,7 @@ class OSGPRESENTATION_EXPORT Section : public osgPresentation::Group /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Section(const Section& section,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Group(section,copyop) {} - META_Node(osgPresentation, Section); + META_Presentation(Section); protected : diff --git a/include/osgPresentation/Slide b/include/osgPresentation/Slide index 6a35dc3cc..59e71a5b0 100644 --- a/include/osgPresentation/Slide +++ b/include/osgPresentation/Slide @@ -29,7 +29,7 @@ class OSGPRESENTATION_EXPORT Slide : public osgPresentation::Group /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Slide(const Slide& slide,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Group(slide,copyop) {} - META_Node(osgPresentation, Slide); + META_Presentation(Slide); protected : diff --git a/include/osgPresentation/Text b/include/osgPresentation/Text index 2e08a76ee..4d1d7384c 100644 --- a/include/osgPresentation/Text +++ b/include/osgPresentation/Text @@ -1,4 +1,4 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2013 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -29,7 +29,7 @@ class OSGPRESENTATION_EXPORT Text : public osgPresentation::Element /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Text(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Element(text,copyop) {} - META_Node(osgPresentation, Text); + META_Presentation(Text); /** load the text subgraph.*/ virtual bool load(); diff --git a/include/osgPresentation/Volume b/include/osgPresentation/Volume index ed1660309..56738eebb 100644 --- a/include/osgPresentation/Volume +++ b/include/osgPresentation/Volume @@ -29,7 +29,7 @@ class OSGPRESENTATION_EXPORT Volume : public osgPresentation::Element /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Volume(const Volume& volume,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osgPresentation::Element(volume,copyop) {} - META_Node(osgPresentation, Volume); + META_Presentation(Volume); protected : diff --git a/src/osgPresentation/Action.cpp b/src/osgPresentation/Action.cpp new file mode 100644 index 000000000..861474632 --- /dev/null +++ b/src/osgPresentation/Action.cpp @@ -0,0 +1,120 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2013 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace osgPresentation; + +////////////////////////////////////////////////////////////////////////////////// +// +// Action base class +// +void Action::apply(osgPresentation::Group& group) +{ + OSG_NOTICE<<"LoadAction::apply()"<(element)); +} + +void Action::apply(osgPresentation::Text& text) +{ + apply(static_cast(text)); +} + +void Action::apply(osgPresentation::Volume& volume) +{ + apply(static_cast(volume)); +} + +void Action::apply(osgPresentation::Model& model) +{ + apply(static_cast(model)); +} + +void Action::apply(osgPresentation::Image& image) +{ + apply(static_cast(image)); +} + +void Action::apply(osgPresentation::Movie& movie) +{ + apply(static_cast(movie)); +} + + +void Action::apply(osgPresentation::Section& section) +{ + apply(static_cast(section)); +} + +void Action::apply(osgPresentation::Layer& layer) +{ + apply(static_cast(layer)); +} + +void Action::apply(osgPresentation::Slide& slide) +{ + apply(static_cast(slide)); +} + +void Action::apply(osgPresentation::Presentation& presentation) +{ + apply(static_cast(presentation)); +} + + +///////////////////////////////////////////////////////////////////////// +// +// Specific Action implementations +// +void LoadAction::apply(osgPresentation::Element& element) +{ + OSG_NOTICE<<"LoadAction::apply()"<(&nv); - if (uv) - { - updateTraversal(*uv); - return; - } - } - else if (nv.getVisitorType()==osg::NodeVisitor::EVENT_VISITOR) - { - osgGA::EventVisitor* ev = dynamic_cast(&nv); - if (ev) - { - eventTraversal(*ev); - return; - } - } - osgPresentation::Group::traverse(nv); -} - -void Element::updateTraversal(osgUtil::UpdateVisitor& uv) -{ - OSG_NOTICE<<"Element::updateTraversal()"< #include using namespace osgPresentation; -/** Nothing to implement yet...*/ \ No newline at end of file +class PropertyVisitor : public osg::NodeVisitor +{ + public: + PropertyVisitor(const std::string& name) : _name(name), _object(0) {} + + void apply(osg::Node& node) + { + osg::UserDataContainer* udc = node.getUserDataContainer(); + _object = udc ? udc->getUserObject(_name) : 0; + if (!_object) traverse(node); + }; + + std::string _name; + osg::Object* _object; +}; + +osg::Object* Group::getPropertyObject(const std::string& name, bool checkParents) +{ + PropertyVisitor pv(name); + if (checkParents) pv.setTraversalMode(osg::NodeVisitor::TRAVERSE_PARENTS); + accept(pv); + return pv._object; +} \ No newline at end of file diff --git a/src/osgPresentation/Text.cpp b/src/osgPresentation/Text.cpp index f35cb6c99..d2806f211 100644 --- a/src/osgPresentation/Text.cpp +++ b/src/osgPresentation/Text.cpp @@ -20,7 +20,25 @@ using namespace osgPresentation; bool Text::load() { - OSG_NOTICE<<"Not implemented yet"<