diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index 8827cd670..95c186f3a 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -348,6 +348,10 @@ SOURCE=..\..\src\osg\NodeCallback.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\NodeTrackerCallback.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\NodeVisitor.cpp # End Source File # Begin Source File @@ -832,6 +836,10 @@ SOURCE=..\..\include\osg\NodeCallback # End Source File # Begin Source File +SOURCE=..\..\include\osg\NodeTrackerCallback +# End Source File +# Begin Source File + SOURCE=..\..\Include\Osg\NodeVisitor # End Source File # Begin Source File diff --git a/doc/ProgrammingGuide/ProgrammingGuide.odt b/doc/ProgrammingGuide/ProgrammingGuide.odt new file mode 100644 index 000000000..4b09b9148 Binary files /dev/null and b/doc/ProgrammingGuide/ProgrammingGuide.odt differ diff --git a/include/osg/NodeTrackerCallback b/include/osg/NodeTrackerCallback new file mode 100644 index 000000000..389db15b1 --- /dev/null +++ b/include/osg/NodeTrackerCallback @@ -0,0 +1,56 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 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_NODETRACKERCALLBACK +#define OSG_NODETRACKERCALLBACK 1 + +#include +#include +#include + +namespace osg +{ + +class OSG_EXPORT NodeTrackerCallback : public NodeCallback +{ + public: + + + void setTrackNodePath(const osg::RefNodePath& nodePath) { _trackNodePath = nodePath; } + void setTrackNodePath(const osg::NodePath& nodePath) { _trackNodePath = nodePath; } + + osg::RefNodePath& getTrackNodePath() { return _trackNodePath; } + const osg::RefNodePath& getTrackNodePath() const { return _trackNodePath; } + + void setTrackNode(osg::Node* node); + osg::Node* getTrackNode() { return _trackNodePath.empty() ? 0 : _trackNodePath.back().get(); } + const osg::Node* getTrackNode() const { return _trackNodePath.empty() ? 0 : _trackNodePath.back().get(); } + + + /** Implements the callback. */ + virtual void operator()(Node* node, NodeVisitor* nv); + + /** update the node to track the nodepath.*/ + void update(osg::Node& node); + + inline bool validateNodePath() const; + + protected: + + osg::RefNodePath _trackNodePath; + +}; + +} + +#endif diff --git a/src/osg/GNUmakefile b/src/osg/GNUmakefile index 1b9f381ea..f145e0177 100644 --- a/src/osg/GNUmakefile +++ b/src/osg/GNUmakefile @@ -64,6 +64,7 @@ CXXFILES =\ MatrixTransform.cpp\ Multisample.cpp\ NodeCallback.cpp\ + NodeTrackerCallback.cpp\ Node.cpp\ NodeVisitor.cpp\ Notify.cpp\ diff --git a/src/osg/NodeTrackerCallback.cpp b/src/osg/NodeTrackerCallback.cpp new file mode 100644 index 000000000..3850c8138 --- /dev/null +++ b/src/osg/NodeTrackerCallback.cpp @@ -0,0 +1,135 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 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 + +using namespace osg; + +class CollectParentPaths : public osg::NodeVisitor +{ +public: + CollectParentPaths() : + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS) {} + + virtual void apply(osg::Node& node) + { + if (node.getNumParents()==0) + { + _nodePaths.push_back(getNodePath()); + } + traverse(node); + } + + osg::NodePath _nodePath; + typedef std::vector< osg::NodePath > NodePathList; + NodePathList _nodePaths; +}; + +class ApplyMatrixVisitor : public NodeVisitor +{ + public: + + ApplyMatrixVisitor(const osg::Matrix& matrix): + _matrix(matrix) {} + + virtual void apply(CameraNode& camera) + { + camera.setViewMatrix(_matrix); + } + + virtual void apply(CameraView& cv) + { + Quat rotation; + _matrix.get(rotation); + + cv.setPosition(_matrix.getTrans()); + cv.setAttitude(rotation); + } + + virtual void apply(MatrixTransform& mt) + { + mt.setMatrix(_matrix); + } + + virtual void apply(PositionAttitudeTransform& pat) + { + Quat rotation; + _matrix.get(rotation); + + pat.setPosition(_matrix.getTrans()); + pat.setAttitude(rotation); + } + + osg::Matrix _matrix; +}; + + +void NodeTrackerCallback::setTrackNode(osg::Node* node) +{ + if (!node) + { + osg::notify(osg::NOTICE)<<"NodeTrackerCallback::setTrackNode(Node*): Unable to set tracked node due to null Node*"<accept(cpp); + + if (!cpp._nodePaths.empty()) + { + osg::notify(osg::INFO)<<"NodeTrackerCallback::setTrackNode(Node*): Path set"<getVisitorType()==NodeVisitor::UPDATE_VISITOR) + { + update(*node); + } + + traverse(node,nv); +} + +void NodeTrackerCallback::update(osg::Node& node) +{ + ApplyMatrixVisitor applyMatrix(computeWorldToLocal(_trackNodePath)); + node.accept(applyMatrix); +} + +bool NodeTrackerCallback::validateNodePath() const +{ + if (!_trackNodePath.valid()) + { + if (_trackNodePath.empty()) + { + osg::notify(osg::NOTICE)<<"Warning: tracked node path has been invalidated by changes in the scene graph."<(this); + non_const_this->_trackNodePath.clear(); + } + return false; + } + return true; +} +