From 6a48a3ffe777e8b26f4afda6434fc10a7ce8391b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 9 Sep 2004 13:18:45 +0000 Subject: [PATCH] Added osg::RefNodePath class for handling node paths. --- include/osg/RefNodePath | 101 +++++++++++++++++++++++++++++++++++++ include/osgProducer/Viewer | 9 ++-- src/osgProducer/Viewer.cpp | 15 ++---- 3 files changed, 108 insertions(+), 17 deletions(-) create mode 100644 include/osg/RefNodePath diff --git a/include/osg/RefNodePath b/include/osg/RefNodePath new file mode 100644 index 000000000..bdef818cc --- /dev/null +++ b/include/osg/RefNodePath @@ -0,0 +1,101 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 OSG_REFNODEPATH +#define OSG_REFNODEPATH 1 + +#include + +namespace osg { + +class RefNodePath : public NodeList +{ + public : + + inline RefNodePath() {} + + inline RefNodePath(const RefNodePath& refNodePath): + NodeList(refNodePath) {} + + inline explicit RefNodePath(const NodePath& nodePath) + { + for(osg::NodePath::const_iterator itr=nodePath.begin(); + itr != nodePath.end(); + ++itr) + { + push_back(*itr); + } + } + + inline operator NodePath () const + { + NodePath nodePath; + for(NodeList::const_iterator itr=begin(); + itr != end(); + ++itr) + { + nodePath.push_back(const_cast(itr->get())); + } + + return nodePath; + } + + /** Check the validity of the RefNodePath to ensure that the parent path + * matches those availble in the leaf node of the path.*/ + bool valid() const + { + // an empty NodePaath is invalid. + if (empty()) return false; + + // check to make sure that this RefNodeList isn't the only + // place that the nodes are referenced, if one node has + // a ref count of 1 then nodes must have been removed + // from the scene graph elsewhere invalidating this RefNodePath. + for(const_iterator itr=begin(); + itr != end(); + ++itr) + { + if ((*itr)->referenceCount()<=1) return false; + } + + const_reverse_iterator ritr=rbegin(); + const osg::Node* node = ritr->get(); + ++ritr; + while (ritr!=rend()) + { + const osg::Node* parent = ritr->get(); + // search of parent in current nodes parent list + const osg::Node::ParentList& parents = node->getParents(); + osg::Node::ParentList::const_iterator pitr=parents.begin(); + for(; pitr!=parents.end() && parent!=*pitr; ++pitr) {} + if (pitr==parents.end()) + { + // original parent not found, so linkage must have changed + // invalidating this RefNodePath. + return false; + } + + node = parent; + ++ritr; + } + + // we've passed all the test that could invalidate this RefNodePath + return true; + } + +}; + +} // namespace + +#endif + diff --git a/include/osgProducer/Viewer b/include/osgProducer/Viewer index 943abc7bd..a945bf4f0 100644 --- a/include/osgProducer/Viewer +++ b/include/osgProducer/Viewer @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -102,15 +103,13 @@ class OSGPRODUCER_EXPORT Viewer : public OsgCameraGroup, public osgGA::GUIAction const osg::NodeVisitor* getUpdateVisitor() const { return _updateVisitor.get(); } - typedef std::vector< osg::ref_ptr > RefNodePath; - void computeActiveCoordindateSystemNodePath(); - void setCoordindateSystemNodePath(const RefNodePath& nodePath) { _coordinateSystemNodePath = nodePath; } + void setCoordindateSystemNodePath(const osg::RefNodePath& nodePath) { _coordinateSystemNodePath = nodePath; } void setCoordindateSystemNodePath(const osg::NodePath& nodePath); - const RefNodePath& getCoordindateSystemNodePath() const { return _coordinateSystemNodePath; } + const osg::RefNodePath& getCoordindateSystemNodePath() const { return _coordinateSystemNodePath; } /** Dispatch the cull and draw for each of the Camera's for this frame.*/ virtual void frame(); @@ -194,7 +193,7 @@ class OSGPRODUCER_EXPORT Viewer : public OsgCameraGroup, public osgGA::GUIAction osg::ref_ptr _updateVisitor; - RefNodePath _coordinateSystemNodePath; + osg::RefNodePath _coordinateSystemNodePath; bool _recordingAnimationPath; double _recordingStartTime; diff --git a/src/osgProducer/Viewer.cpp b/src/osgProducer/Viewer.cpp index 2dd90ba46..85afddc0a 100644 --- a/src/osgProducer/Viewer.cpp +++ b/src/osgProducer/Viewer.cpp @@ -183,22 +183,13 @@ public: { osg::notify(osg::INFO)<<"getCoordinateFrame("<getCoordindateSystemNodePath(); + // do automatic conversion between RefNodePath and NodePath. + osg::NodePath tmpPath = _viewer->getCoordindateSystemNodePath(); - if (!refNodePath.empty()) + if (!tmpPath.empty()) { osg::Matrixd coordinateFrame; - // have to create a copy of the RefNodePath to create an osg::NodePath - // to allow it to be used along with the computeLocalToWorld call. - osg::NodePath tmpPath; - for(Viewer::RefNodePath::const_iterator itr=refNodePath.begin(); - itr!=refNodePath.end(); - ++itr) - { - tmpPath.push_back(const_cast(itr->get())); - } - osg::CoordinateSystemNode* csn = dynamic_cast(tmpPath.back()); if (csn) {