//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield //Distributed under the terms of the GNU Library General Public License (LGPL) //as published by the Free Software Foundation. #ifndef OSGUTIL_INTERSECTVISITOR #define OSGUTIL_INTERSECTVISITOR 1 #include #include #include #include #include #include #include #include namespace osgUtil { class OSGUTIL_EXPORT Hit { public: Hit(); Hit(const Hit& hit); ~Hit(); Hit& operator = (const Hit& hit); typedef std::vector VecIndexList; bool operator < (const Hit& hit) const { if (_originalLineSegmenthit._originalLineSegment) return false; return _ratio _originalLineSegment; osg::ref_ptr _localLineSegment; osg::NodePath _nodePath; osg::ref_ptr _geode; osg::ref_ptr _drawable; osg::ref_ptr _matrix; osg::ref_ptr _inverse; VecIndexList _vecIndexList; int _primitiveIndex; osg::Vec3 _intersectPoint; osg::Vec3 _intersectNormal; }; /** Basic visitor for ray based collisions of a scene.*/ class OSGUTIL_EXPORT IntersectVisitor : public osg::NodeVisitor { public: IntersectVisitor(); virtual ~IntersectVisitor(); void reset(); /** Add a line segment to use for intersection testing during scene traversal.*/ void addLineSegment(osg::LineSegment* seg); /** Modes to control how IntersectVisitor reports hits. */ enum HitReportingMode { ONLY_NEAREST_HIT, ALL_HITS }; /** Set the mode of how hits should reported back from a traversal.*/ void setHitReportingMode(HitReportingMode hrm) { _hitReportingMode = hrm; } /** Get the mode of how hits should reported back from a traversal.*/ HitReportingMode getHitReportingMode() { return _hitReportingMode; } //typedef std::multiset HitList; typedef std::vector HitList; typedef std::map LineSegmentHitListMap; HitList& getHitList(osg::LineSegment* seg) { return _segHitList[seg]; } int getNumHits(osg::LineSegment* seg) { return _segHitList[seg].size(); } bool hits(); virtual void apply(osg::Node&); virtual void apply(osg::Geode& node); virtual void apply(osg::Billboard& node); virtual void apply(osg::Group& node); virtual void apply(osg::Transform& node); virtual void apply(osg::Switch& node); virtual void apply(osg::LOD& node); protected: class IntersectState : public osg::Referenced { public: IntersectState(); osg::ref_ptr _matrix; osg::ref_ptr _inverse; typedef std::pair,osg::ref_ptr > LineSegmentPair; typedef std::vector< LineSegmentPair > LineSegmentList; LineSegmentList _segList; typedef unsigned int LineSegmentmentMask; typedef std::vector LineSegmentmentMaskStack; LineSegmentmentMaskStack _segmentMaskStack; bool isCulled(const osg::BoundingSphere& bs,LineSegmentmentMask& segMaskOut); bool isCulled(const osg::BoundingBox& bb,LineSegmentmentMask& segMaskOut); void addLineSegmentPair(osg::LineSegment* first,osg::LineSegment* second) { _segList.push_back(LineSegmentPair(first,second)); } protected: ~IntersectState(); }; bool intersect(osg::Drawable& gset); void pushMatrix(const osg::Matrix& matrix); void popMatrix(); bool enterNode(osg::Node& node); void leaveNode(); typedef std::vector > IntersectStateStack; IntersectStateStack _intersectStateStack; osg::NodePath _nodePath; HitReportingMode _hitReportingMode; LineSegmentHitListMap _segHitList; }; } #endif