From f9fb99dc437b1b156a8de08812671491e0e2d2c0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 2 Nov 2006 12:17:06 +0000 Subject: [PATCH] Added prelimnary work on PolytopeIntersector. --- include/osgUtil/IntersectionVisitor | 57 ++++++++++++++++++ src/osgUtil/IntersectionVisitor.cpp | 92 ++++++++++++++++++++++++++++- 2 files changed, 146 insertions(+), 3 deletions(-) diff --git a/include/osgUtil/IntersectionVisitor b/include/osgUtil/IntersectionVisitor index 93cbc8da5..4d53d96cf 100644 --- a/include/osgUtil/IntersectionVisitor +++ b/include/osgUtil/IntersectionVisitor @@ -142,6 +142,63 @@ class OSGUTIL_EXPORT LineSegmentIntersector : public Intersector }; +/** Concrent class for implementing polytope intersections with the scene graph. + * To be used in conjunction with IntersectionVisitor. */ +class OSGUTIL_EXPORT PolytopeIntersector : public Intersector +{ + public: + + PolytopeIntersector(const osg::Polytope& polytope, PolytopeIntersector* parent=0); + + PolytopeIntersector(CoordinateFrame cf, const osg::Polytope& polytope, PolytopeIntersector* parent=0); + + struct Intersection + { + Intersection() {} + + bool operator < (const Intersection& rhs) const + { + if (nodePath < rhs.nodePath) return true; + if (rhs.nodePath < nodePath ) return false; + return (drawable < rhs.drawable); + } + + osg::NodePath nodePath; + osg::ref_ptr drawable; + }; + + typedef std::set Intersections; + + inline void insertIntersection(const Intersection& intersection) { getIntersections().insert(intersection); } + + inline Intersections& getIntersections() { return _parent ? _parent->_intersections : _intersections; } + + inline Intersection getFirstIntersection() { Intersections& intersections = getIntersections(); return intersections.empty() ? Intersection() : *(intersections.begin()); } + + public: + + virtual Intersector* clone(osgUtil::IntersectionVisitor& iv); + + virtual bool enter(const osg::Node& node); + + virtual void leave(); + + virtual void intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable); + + virtual void reset(); + + virtual bool containsIntersections() { return !_intersections.empty(); } + + protected: + + PolytopeIntersector* _parent; + + osg::Polytope _polytope; + + Intersections _intersections; + +}; + /** Concrent class for passing multiple intersectors through the scene graph. * To be used in conjunction with IntersectionVisitor. */ class OSGUTIL_EXPORT IntersectorGroup : public Intersector diff --git a/src/osgUtil/IntersectionVisitor.cpp b/src/osgUtil/IntersectionVisitor.cpp index 8382c103f..5dad22f81 100644 --- a/src/osgUtil/IntersectionVisitor.cpp +++ b/src/osgUtil/IntersectionVisitor.cpp @@ -495,9 +495,94 @@ bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // -// LineSegmentIntersector +// IntersectorGroup // +PolytopeIntersector::PolytopeIntersector(const osg::Polytope& polytope, PolytopeIntersector* parent): + _parent(parent), + _polytope(polytope) +{ +} +PolytopeIntersector::PolytopeIntersector(CoordinateFrame cf, const osg::Polytope& polytope, PolytopeIntersector* parent): + Intersector(cf), + _parent(parent), + _polytope(polytope) +{ +} + +Intersector* PolytopeIntersector::clone(osgUtil::IntersectionVisitor& iv) +{ + if (_coordinateFrame==MODEL && iv.getModelMatrix()==0) + { + return new PolytopeIntersector(_polytope, this); + } + + // compute the matrix that takes this Intersector from its CoordinateFrame into the local MODEL coordinate frame + // that geometry in the scene graph will always be in. + osg::Matrix matrix; + switch (_coordinateFrame) + { + case(WINDOW): + if (iv.getWindowMatrix()) matrix.preMult( *iv.getWindowMatrix() ); + if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(PROJECTION): + if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() ); + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(VIEW): + if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() ); + if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() ); + break; + case(MODEL): + if (iv.getModelMatrix()) matrix = *iv.getModelMatrix(); + break; + } + + osg::Polytope transformedPolytope; + transformedPolytope.setAndTransformProvidingInverse(_polytope, matrix); + + return new PolytopeIntersector(transformedPolytope, this); +} + +bool PolytopeIntersector::enter(const osg::Node& node) +{ + return !node.isCullingActive() || _polytope.contains( node.getBound() ); +} + + +void PolytopeIntersector::leave() +{ + // do nothing. +} + + +void PolytopeIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) +{ + if ( !_polytope.contains( drawable->getBound() ) ) return; + + Intersection hit; + hit.nodePath = iv.getNodePath(); + hit.drawable = drawable; +} + + +void PolytopeIntersector::reset() +{ + Intersector::reset(); + + _intersections.clear(); +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// IntersectorGroup +// IntersectorGroup::IntersectorGroup() { @@ -782,9 +867,10 @@ void IntersectionVisitor::apply(osg::Projection& projection) void IntersectionVisitor::apply(osg::CameraNode& camera) { - //osg::notify(osg::NOTICE)<<"apply(CameraNode&)"<