Added osgUtil::IntersectorGroup to handle groups of osgUtil::Intersectors
This commit is contained in:
parent
0fe424996d
commit
358b96e953
@ -39,10 +39,80 @@ int main(int argc, char **argv)
|
||||
|
||||
std::cout<<"Intersection "<<std::endl;
|
||||
|
||||
osg::Timer_t startTick = osg::Timer::instance()->tick();
|
||||
|
||||
|
||||
osg::BoundingSphere bs = root->getBound();
|
||||
|
||||
|
||||
bool useIntersectorGroup = true;
|
||||
|
||||
if (useIntersectorGroup)
|
||||
{
|
||||
osg::Timer_t startTick = osg::Timer::instance()->tick();
|
||||
|
||||
osg::Vec3d start = bs.center() + osg::Vec3d(0.0,bs.radius(),0.0);
|
||||
osg::Vec3d end = bs.center();// - osg::Vec3d(0.0, bs.radius(),0.0);
|
||||
osg::Vec3d deltaRow( 0.0, 0.0, bs.radius()*0.01);
|
||||
osg::Vec3d deltaColumn( bs.radius()*0.01, 0.0, 0.0);
|
||||
unsigned int numRows = 20;
|
||||
unsigned int numColumns = 20;
|
||||
|
||||
osg::ref_ptr<osgUtil::IntersectorGroup> intersectorGroup = new osgUtil::IntersectorGroup();
|
||||
|
||||
for(unsigned int r=0; r<numRows; ++r)
|
||||
{
|
||||
for(unsigned int c=0; c<numColumns; ++c)
|
||||
{
|
||||
osg::Vec3d s = start + deltaColumn * double(c) + deltaRow * double(r);
|
||||
osg::Vec3d e = end + deltaColumn * double(c) + deltaRow * double(r);
|
||||
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(s, e);
|
||||
intersectorGroup->addIntersector( intersector.get() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
osgUtil::IntersectionVisitor intersectVisitor( intersectorGroup.get(), new MyReadCallback );
|
||||
root->accept(intersectVisitor);
|
||||
|
||||
osg::Timer_t endTick = osg::Timer::instance()->tick();
|
||||
|
||||
std::cout<<"Completed in "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
|
||||
|
||||
if ( intersectorGroup->containsIntersections() )
|
||||
{
|
||||
std::cout<<"Found intersections "<<std::endl;
|
||||
|
||||
osgUtil::IntersectorGroup::Intersectors& intersectors = intersectorGroup->getIntersectors();
|
||||
for(osgUtil::IntersectorGroup::Intersectors::iterator intersector_itr = intersectors.begin();
|
||||
intersector_itr != intersectors.end();
|
||||
++intersector_itr)
|
||||
{
|
||||
osgUtil::LineSegmentIntersector* lsi = dynamic_cast<osgUtil::LineSegmentIntersector*>(intersector_itr->get());
|
||||
if (lsi)
|
||||
{
|
||||
osgUtil::LineSegmentIntersector::Intersections& intersections = lsi->getIntersections();
|
||||
for(osgUtil::LineSegmentIntersector::Intersections::iterator itr = intersections.begin();
|
||||
itr != intersections.end();
|
||||
++itr)
|
||||
{
|
||||
const osgUtil::LineSegmentIntersector::Intersection& intersection = *itr;
|
||||
std::cout<<" ratio "<<intersection.ratio<<std::endl;
|
||||
std::cout<<" point "<<intersection.localIntersectionPoint<<std::endl;
|
||||
std::cout<<" normal "<<intersection.localIntersectionNormal<<std::endl;
|
||||
std::cout<<" indices "<<intersection.indexList.size()<<std::endl;
|
||||
std::cout<<" primitiveIndex "<<intersection.primitiveIndex<<std::endl;
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::Timer_t startTick = osg::Timer::instance()->tick();
|
||||
|
||||
#if 1
|
||||
osg::Vec3d start = bs.center() + osg::Vec3d(0.0,bs.radius(),0.0);
|
||||
osg::Vec3d end = bs.center() - osg::Vec3d(0.0, bs.radius(),0.0);
|
||||
@ -51,7 +121,6 @@ int main(int argc, char **argv)
|
||||
osg::Vec3d end = bs.center() - osg::Vec3d(0.0, 0.0, bs.radius());
|
||||
#endif
|
||||
|
||||
|
||||
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(start, end);
|
||||
|
||||
osgUtil::IntersectionVisitor intersectVisitor( intersector.get(), new MyReadCallback );
|
||||
@ -78,6 +147,7 @@ int main(int argc, char **argv)
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -33,9 +33,10 @@ class Intersector : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
virtual Intersector* clone(osgUtil::IntersectionVisitor& iv) = 0;
|
||||
Intersector():
|
||||
_disabledCount(0) {}
|
||||
|
||||
virtual void merge(Intersector* intersector) = 0;
|
||||
virtual Intersector* clone(osgUtil::IntersectionVisitor& iv) = 0;
|
||||
|
||||
virtual bool enter(const osg::Node& node) = 0;
|
||||
|
||||
@ -43,19 +44,29 @@ class Intersector : public osg::Referenced
|
||||
|
||||
virtual void intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) = 0;
|
||||
|
||||
virtual void reset() = 0;
|
||||
virtual void reset() { _disabledCount = 0; }
|
||||
|
||||
virtual bool containsIntersections() = 0;
|
||||
|
||||
inline bool disabled() const { return _disabledCount!=0; }
|
||||
|
||||
inline void incrementDisabledCount() { ++_disabledCount; }
|
||||
|
||||
inline void decrementDisabledCount() { if (_disabledCount>0) --_disabledCount; }
|
||||
|
||||
protected:
|
||||
|
||||
unsigned int _disabledCount;
|
||||
|
||||
};
|
||||
|
||||
/** Concrent class for implementing line intersections with the scene graph.
|
||||
* To be used in conjunction with IntersectionVisitor. */
|
||||
class LineSegmentIntersector : public Intersector
|
||||
class OSGUTIL_EXPORT LineSegmentIntersector : public Intersector
|
||||
{
|
||||
public:
|
||||
|
||||
LineSegmentIntersector(const osg::Vec3d& start, const osg::Vec3d& end);
|
||||
LineSegmentIntersector(const osg::Vec3d& start, const osg::Vec3d& end, LineSegmentIntersector* parent=0);
|
||||
|
||||
struct Intersection
|
||||
{
|
||||
@ -75,14 +86,15 @@ class LineSegmentIntersector : public Intersector
|
||||
|
||||
typedef std::multiset<Intersection> Intersections;
|
||||
|
||||
Intersections& getIntersections() { return _intersections; }
|
||||
inline void insertIntersection(const Intersection& intersection) { getIntersections().insert(intersection); }
|
||||
|
||||
inline Intersections& getIntersections() { return _parent ? _parent->_intersections : _intersections; }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
virtual Intersector* clone(osgUtil::IntersectionVisitor& iv);
|
||||
|
||||
virtual void merge(Intersector* intersector);
|
||||
|
||||
virtual bool enter(const osg::Node& node);
|
||||
|
||||
virtual void leave();
|
||||
@ -98,6 +110,8 @@ class LineSegmentIntersector : public Intersector
|
||||
bool intersects(const osg::BoundingSphere& bs);
|
||||
bool intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const osg::BoundingBox& bb);
|
||||
|
||||
LineSegmentIntersector* _parent;
|
||||
|
||||
osg::Vec3d _start;
|
||||
osg::Vec3d _end;
|
||||
|
||||
@ -105,6 +119,45 @@ class LineSegmentIntersector : public Intersector
|
||||
|
||||
};
|
||||
|
||||
/** Concrent class for passing multiple intersectors through the scene graph.
|
||||
* To be used in conjunction with IntersectionVisitor. */
|
||||
class OSGUTIL_EXPORT IntersectorGroup : public Intersector
|
||||
{
|
||||
public:
|
||||
|
||||
IntersectorGroup();
|
||||
|
||||
/** Add an Intersector. */
|
||||
void addIntersector(Intersector* intersector);
|
||||
|
||||
typedef std::vector< osg::ref_ptr<Intersector> > Intersectors;
|
||||
|
||||
/** Get the list of intersector. */
|
||||
Intersectors& getIntersectors() { return _intersectors; }
|
||||
|
||||
/** Clear the list of intersectors.*/
|
||||
void clear();
|
||||
|
||||
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();
|
||||
|
||||
protected:
|
||||
|
||||
Intersectors _intersectors;
|
||||
|
||||
};
|
||||
|
||||
/** InteresectionVisitor is used to testing for intersections with the scene, traversing the scene using generic osgUtil::Intersector's to test against the scene.
|
||||
* To implement different types of intersection techniques, one implements custom versions of the osgUtil::Intersector, and then
|
||||
* pass the constructed intersector to the IntersectionVisitor.*/
|
||||
@ -170,7 +223,7 @@ class OSGUTIL_EXPORT IntersectionVisitor : public osg::NodeVisitor
|
||||
inline void leave() { _intersectorStack.back()->leave(); }
|
||||
inline void intersect(osg::Drawable* drawable) { _intersectorStack.back()->intersect(*this, drawable); }
|
||||
inline void push_clone() { _intersectorStack.push_back ( _intersectorStack.front()->clone(*this) ); }
|
||||
inline void pop_clone() { if (_intersectorStack.size()>=2) { _intersectorStack.front()->merge(_intersectorStack.back().get()); _intersectorStack.pop_back(); } }
|
||||
inline void pop_clone() { if (_intersectorStack.size()>=2) _intersectorStack.pop_back(); }
|
||||
|
||||
typedef std::list< osg::ref_ptr<Intersector> > IntersectorStack;
|
||||
IntersectorStack _intersectorStack;
|
||||
|
@ -197,7 +197,8 @@ struct TriangleIntersector
|
||||
// LineSegmentIntersector
|
||||
//
|
||||
|
||||
LineSegmentIntersector::LineSegmentIntersector(const osg::Vec3d& start, const osg::Vec3d& end):
|
||||
LineSegmentIntersector::LineSegmentIntersector(const osg::Vec3d& start, const osg::Vec3d& end, LineSegmentIntersector* parent):
|
||||
_parent(parent),
|
||||
_start(start),
|
||||
_end(end)
|
||||
{
|
||||
@ -211,20 +212,14 @@ Intersector* LineSegmentIntersector::clone(osgUtil::IntersectionVisitor& iv)
|
||||
osg::Matrix inverse;
|
||||
inverse.invert(*model);
|
||||
|
||||
return new LineSegmentIntersector(_start * inverse, _end * inverse);
|
||||
return new LineSegmentIntersector(_start * inverse, _end * inverse, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new LineSegmentIntersector(_start, _end);
|
||||
return new LineSegmentIntersector(_start, _end, this);
|
||||
}
|
||||
}
|
||||
|
||||
void LineSegmentIntersector::merge(Intersector* intersector)
|
||||
{
|
||||
LineSegmentIntersector* lsi = dynamic_cast<LineSegmentIntersector*>(intersector);
|
||||
_intersections.insert(lsi->_intersections.begin(),lsi->_intersections.end());
|
||||
}
|
||||
|
||||
bool LineSegmentIntersector::enter(const osg::Node& node)
|
||||
{
|
||||
return intersects( node.getBound() );
|
||||
@ -282,7 +277,7 @@ void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Dr
|
||||
}
|
||||
}
|
||||
|
||||
_intersections.insert(hit);
|
||||
insertIntersection(hit);
|
||||
|
||||
}
|
||||
}
|
||||
@ -291,6 +286,8 @@ void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Dr
|
||||
|
||||
void LineSegmentIntersector::reset()
|
||||
{
|
||||
Intersector::reset();
|
||||
|
||||
_intersections.clear();
|
||||
}
|
||||
|
||||
@ -447,6 +444,125 @@ bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LineSegmentIntersector
|
||||
//
|
||||
|
||||
|
||||
IntersectorGroup::IntersectorGroup()
|
||||
{
|
||||
}
|
||||
|
||||
void IntersectorGroup::addIntersector(Intersector* intersector)
|
||||
{
|
||||
_intersectors.push_back(intersector);
|
||||
}
|
||||
|
||||
void IntersectorGroup::clear()
|
||||
{
|
||||
_intersectors.clear();
|
||||
}
|
||||
|
||||
Intersector* IntersectorGroup::clone(osgUtil::IntersectionVisitor& iv)
|
||||
{
|
||||
IntersectorGroup* ig = new IntersectorGroup;
|
||||
|
||||
// now copy across all intersectors that arn't disabled.
|
||||
for(Intersectors::iterator itr = _intersectors.begin();
|
||||
itr != _intersectors.end();
|
||||
++itr)
|
||||
{
|
||||
if (!(*itr)->disabled())
|
||||
{
|
||||
ig->addIntersector( (*itr)->clone(iv) );
|
||||
}
|
||||
}
|
||||
|
||||
return ig;
|
||||
}
|
||||
|
||||
bool IntersectorGroup::enter(const osg::Node& node)
|
||||
{
|
||||
if (disabled()) return false;
|
||||
|
||||
bool foundIntersections = false;
|
||||
|
||||
for(Intersectors::iterator itr = _intersectors.begin();
|
||||
itr != _intersectors.end();
|
||||
++itr)
|
||||
{
|
||||
if ((*itr)->disabled()) (*itr)->incrementDisabledCount();
|
||||
else if ((*itr)->enter(node)) foundIntersections = true;
|
||||
else (*itr)->incrementDisabledCount();
|
||||
}
|
||||
|
||||
if (!foundIntersections)
|
||||
{
|
||||
// need to call leave to clean up the DisabledCount's.
|
||||
leave();
|
||||
return false;
|
||||
}
|
||||
|
||||
// we have found at least one suitable intersector, so return true
|
||||
return true;
|
||||
}
|
||||
|
||||
void IntersectorGroup::leave()
|
||||
{
|
||||
for(Intersectors::iterator itr = _intersectors.begin();
|
||||
itr != _intersectors.end();
|
||||
++itr)
|
||||
{
|
||||
if ((*itr)->disabled()) (*itr)->decrementDisabledCount();
|
||||
}
|
||||
}
|
||||
|
||||
void IntersectorGroup::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)
|
||||
{
|
||||
if (disabled()) return;
|
||||
|
||||
unsigned int numTested = 0;
|
||||
for(Intersectors::iterator itr = _intersectors.begin();
|
||||
itr != _intersectors.end();
|
||||
++itr)
|
||||
{
|
||||
if (!(*itr)->disabled())
|
||||
{
|
||||
(*itr)->intersect(iv, drawable);
|
||||
|
||||
++numTested;
|
||||
}
|
||||
}
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Number testing "<<numTested<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void IntersectorGroup::reset()
|
||||
{
|
||||
Intersector::reset();
|
||||
|
||||
for(Intersectors::iterator itr = _intersectors.begin();
|
||||
itr != _intersectors.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool IntersectorGroup::containsIntersections()
|
||||
{
|
||||
for(Intersectors::iterator itr = _intersectors.begin();
|
||||
itr != _intersectors.end();
|
||||
++itr)
|
||||
{
|
||||
if ((*itr)->containsIntersections()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IntersectionVisitor
|
||||
|
Loading…
Reference in New Issue
Block a user