diff --git a/src/osgSim/SphereSegment.cpp b/src/osgSim/SphereSegment.cpp index ab596b155..6ab8f33cc 100644 --- a/src/osgSim/SphereSegment.cpp +++ b/src/osgSim/SphereSegment.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include @@ -961,9 +963,129 @@ void SphereSegment::setAllColors(const osg::Vec4& c) setSideColor(c); } +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// SphereSegment interesection code. + +class PolytopeVisitor : public osg::NodeVisitor +{ + public: + + typedef std::pair MatrixPolytopePair; + typedef std::vector PolytopeStack; + + struct Hit + { + Hit(const osg::Matrix& matrix, osg::NodePath& nodePath, osg::Drawable* drawable): + _matrix(matrix), + _nodePath(nodePath), + _drawable(drawable) {} + + osg::Matrix _matrix; + osg::NodePath _nodePath; + osg::ref_ptr _drawable; + }; + + typedef std::vector HitList; + + + PolytopeVisitor(const osg::Matrix& matrix, const osg::Polytope& polytope): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN) + { + _polytopeStack.push_back(MatrixPolytopePair()); + _polytopeStack.back().first = matrix; + _polytopeStack.back().second.setAndTransformProvidingInverse(polytope, _polytopeStack.back().first); + } + + void reset() + { + _polytopeStack.clear(); + _hits.clear(); + } + + void apply(osg::Node& node) + { + if (_polytopeStack.back().second.contains(node.getBound())) + { + traverse(node); + } + } + + void apply(osg::Transform& transform) + { + if (_polytopeStack.back().second.contains(transform.getBound())) + { + const osg::Polytope& polytope = _polytopeStack.front().second; + + osg::Matrix matrix = _polytopeStack.back().first; + transform.computeLocalToWorldMatrix(matrix, this); + + _polytopeStack.push_back(MatrixPolytopePair()); + _polytopeStack.back().first = matrix; + _polytopeStack.back().second.setAndTransformProvidingInverse(polytope, matrix); + + traverse(transform); + + _polytopeStack.back(); + } + } + + void apply(osg::Geode& node) + { + if (_polytopeStack.back().second.contains(node.getBound())) + { + for(unsigned int i=0; igetBound())) + { + _hits.push_back(Hit(_polytopeStack.back().first,getNodePath(),node.getDrawable(i))); + } + + } + + traverse(node); + } + } + + HitList& getHits() { return _hits; } + + protected: + + PolytopeStack _polytopeStack; + HitList _hits; + +}; + + SphereSegment::LineList SphereSegment::computeIntersection(osg::Node* subgraph, const osg::Matrixd& transform) { osg::notify(osg::NOTICE)<<"Creating line intersection between sphere segment and subgraph."<accept(polytopeVisitor); + + if (polytopeVisitor.getHits().empty()) + { + osg::notify(osg::NOTICE)<<"No hits found."<