From 67e8e0b28786a3f87f7cd03f50c27ead086211da Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 8 Sep 2005 18:56:37 +0000 Subject: [PATCH] Added PolytopeVisitor to SphereSegment.cpp to help cull down to only drawables that intersect with the frustum of the SphereSegment. PolytopeVisitor may eventually be pulled out to be more generally used along the lines of osgUtil::IntersectVisitor. --- src/osgSim/SphereSegment.cpp | 122 +++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) 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."<