OpenSceneGraph/include/osgUtil/IntersectVisitor

143 lines
4.0 KiB
Plaintext
Raw Normal View History

2001-01-11 00:32:10 +08:00
#ifndef OSGUTIL_INTERSECTVISITOR
#define OSGUTIL_INTERSECTVISITOR 1
#include <osg/NodeVisitor>
#include <osg/LineSegment>
2001-01-11 00:32:10 +08:00
#include <osg/Geode>
#include <osg/GeoSet>
2001-01-11 00:32:10 +08:00
#include <osg/Matrix>
#include <osgUtil/Export>
#include <map>
#include <set>
#include <vector>
namespace osgUtil {
class OSGUTIL_EXPORT IntersectState : public osg::Referenced
{
public:
IntersectState();
osg::Matrix* _matrix;
osg::Matrix* _inverse;
typedef std::vector< std::pair<osg::LineSegment*,osg::LineSegment*> > LineSegmentList;
LineSegmentList _segList;
2001-01-11 00:32:10 +08:00
typedef unsigned int LineSegmentmentMask;
typedef std::vector<LineSegmentmentMask> LineSegmentmentMaskStack;
LineSegmentmentMaskStack _segmentMaskStack;
2001-01-11 00:32:10 +08:00
bool isCulled(const osg::BoundingSphere& bs,LineSegmentmentMask& segMaskOut);
bool isCulled(const osg::BoundingBox& bb,LineSegmentmentMask& segMaskOut);
2001-01-11 00:32:10 +08:00
protected:
~IntersectState();
};
class OSGUTIL_EXPORT Hit : public osg::Referenced
{
public:
Hit();
Hit(const Hit& hit);
~Hit();
Hit& operator = (const Hit& hit);
typedef std::vector<int> VecIndexList;
bool operator < (const Hit& hit) const
{
if (_originalLineSegment<hit._originalLineSegment) return true;
if (_originalLineSegment>hit._originalLineSegment) return false;
2001-01-11 00:32:10 +08:00
return _ratio<hit._ratio;
}
float _ratio;
osg::LineSegment* _originalLineSegment;
osg::LineSegment* _localLineSegment;
2001-01-11 00:32:10 +08:00
osg::NodePath _nodePath;
osg::Geode* _geode;
osg::GeoSet* _geoset;
osg::Matrix* _matrix;
VecIndexList _vecIndexList;
int _primitiveIndex;
osg::Vec3 _intersectPoint;
osg::Vec3 _intersectNormal;
};
/** Basic visitor for ray based collisions of a scene.
Note, still in development, current version has not
2001-09-28 20:36:40 +08:00
practical functionality!*/
2001-01-11 00:32:10 +08:00
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);
2001-01-11 00:32:10 +08:00
/** 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<Hit> HitList;
typedef std::vector<Hit> HitList;
typedef std::map<osg::LineSegment*,HitList > LineSegmentHitListMap;
HitList& getHitList(osg::LineSegment* seg) { return _segHitList[seg]; }
int getNumHits(osg::LineSegment* seg) { return _segHitList[seg].size(); }
2001-01-11 00:32:10 +08:00
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);
2001-01-11 00:32:10 +08:00
virtual void apply(osg::Switch& node);
virtual void apply(osg::LOD& node);
protected:
bool intersect(osg::GeoSet& gset);
void pushMatrix(const osg::Matrix& matrix);
void popMatrix();
bool enterNode(osg::Node& node);
void leaveNode();
typedef std::vector<osg::ref_ptr<IntersectState> > IntersectStateStack;
2001-01-11 00:32:10 +08:00
IntersectStateStack _intersectStateStack;
osg::NodePath _nodePath;
2001-01-11 00:32:10 +08:00
HitReportingMode _hitReportingMode;
LineSegmentHitListMap _segHitList;
2001-01-11 00:32:10 +08:00
};
};
#endif