Added support for using new IntersectFunctor for non kdtree as well as kdtree PolytopeIntersector

This commit is contained in:
Robert Osfield
2017-04-21 19:35:10 +01:00
parent a7d98f80dc
commit e7e372bad2

View File

@@ -565,12 +565,16 @@ void PolytopeIntersector::leave()
struct IntersectFunctor
{
IntersectFunctor(osgUtil::PolytopeIntersector* pi, osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable):
_polytopeIntersector(pi),
_iv(iv),
_drawable(drawable)
{
typedef std::vector<osg::Vec3d> Vertices;
IntersectFunctor():
_polytopeIntersector(0),
_iv(0),
_drawable(0),
_primitiveIndex(0)
{
src.reserve(10);
dest.reserve(10);
}
bool enter(const osg::BoundingBox& bb)
@@ -591,26 +595,50 @@ struct IntersectFunctor
_polytopeIntersector->getPolytope().popCurrentMask();
}
typedef std::vector<osg::Vec3d> Vertices;
Vertices src, dest;
void addIntersection()
{
osg::Vec3d center(0.0,0.0,0.0);
double maxDistance = -DBL_MAX;
const osg::Plane& referencePlane = _polytopeIntersector->getReferencePlane();
for(Vertices::iterator itr = src.begin();
itr != src.end();
++itr)
{
center += *itr;
double d = referencePlane.distance(*itr);
if (d>maxDistance) maxDistance = d;
bool contains(const osg::Vec3f& v0, const osg::Vec3f& v1, const osg::Vec3f& v2)
}
center /= double(src.size());
PolytopeIntersector::Intersection intersection;
intersection.primitiveIndex = _primitiveIndex;
intersection.distance = referencePlane.distance(center);
intersection.maxDistance = maxDistance;
intersection.nodePath = _iv->getNodePath();
intersection.drawable = _drawable;
intersection.matrix = _iv->getModelMatrix();
intersection.localIntersectionPoint = center;
if (src.size()<PolytopeIntersector::Intersection::MaxNumIntesectionPoints) intersection.numIntersectionPoints = src.size();
else intersection.numIntersectionPoints = PolytopeIntersector::Intersection::MaxNumIntesectionPoints;
for(unsigned int i=0; i<intersection.numIntersectionPoints; ++i)
{
intersection.intersectionPoints[i] = src[i];
}
// OSG_NOTICE<<"intersection "<<src.size()<<" center="<<center<<std::endl;
_polytopeIntersector->insertIntersection(intersection);
}
bool contains()
{
const osg::Polytope& polytope = _polytopeIntersector->getPolytope();
const osg::Polytope::PlaneList& planeList = polytope.getPlaneList();
// initialize the set of vertices to test.
src.reserve(4+planeList.size());
dest.reserve(4+planeList.size());
src.clear();
src.push_back(v0);
src.push_back(v1);
src.push_back(v2);
src.push_back(v0);
osg::Polytope::ClippingMask resultMask = polytope.getCurrentMask();
if (!resultMask) return true;
@@ -683,45 +711,107 @@ struct IntersectFunctor
return true;
}
bool intersect(const osg::Vec3Array* vertices, int primtiveIndex, unsigned int p0, unsigned int p1, unsigned int p2)
bool contains(const osg::Vec3f& v0, const osg::Vec3f& v1, const osg::Vec3f& v2)
{
// initialize the set of vertices to test.
src.clear();
src.push_back(v0);
src.push_back(v1);
src.push_back(v2);
src.push_back(v0);
return contains();
}
void operator()(const osg::Vec3& v0, bool /*treatVertexDataAsTemporary*/)
{
++_primitiveIndex;
// initialize the set of vertices to test.
src.clear();
const osg::Polytope& polytope = _polytopeIntersector->getPolytope();
osg::Polytope::ClippingMask resultMask = polytope.getCurrentMask();
if (resultMask)
{
osg::Polytope::ClippingMask selector_mask = 0x1;
const osg::Polytope::PlaneList& planeList = polytope.getPlaneList();
for(osg::Polytope::PlaneList::const_iterator pitr = planeList.begin();
pitr != planeList.end();
++pitr)
{
if (resultMask&selector_mask)
{
const osg::Plane& plane=*pitr;
double d1=plane.distance(v0);
if (d1<0.0f) return; // point outside
}
}
}
src.push_back(v0);
addIntersection();
}
// handle lines
void operator()(const osg::Vec3& v0, const osg::Vec3& v1, bool /*treatVertexDataAsTemporary*/)
{
++_primitiveIndex;
src.clear();
src.push_back(v0);
src.push_back(v1);
src.push_back(v0);
if (contains())
{
addIntersection();
}
}
// handle triangles
void operator()(const osg::Vec3& v0, const osg::Vec3& v1, const osg::Vec3& v2, bool /*treatVertexDataAsTemporary*/)
{
++_primitiveIndex;
src.clear();
src.push_back(v0);
src.push_back(v1);
src.push_back(v2);
src.push_back(v0);
if (contains())
{
addIntersection();
}
}
void operator()(const osg::Vec3& v0, const osg::Vec3& v1, const osg::Vec3& v2, const osg::Vec3& v3, bool /*treatVertexDataAsTemporary*/)
{
++_primitiveIndex;
src.clear();
src.push_back(v0);
src.push_back(v1);
src.push_back(v2);
src.push_back(v3);
src.push_back(v0);
if (contains())
{
addIntersection();
}
}
bool intersect(const osg::Vec3Array* vertices, int primitiveIndex, unsigned int p0, unsigned int p1, unsigned int p2)
{
if (contains((*vertices)[p0], (*vertices)[p1], (*vertices)[p2]))
{
osg::Vec3d center(0.0,0.0,0.0);
double maxDistance = -DBL_MAX;
const osg::Plane& referencePlane = _polytopeIntersector->getReferencePlane();
for(Vertices::iterator itr = src.begin();
itr != src.end();
++itr)
{
center += *itr;
double d = referencePlane.distance(*itr);
if (d>maxDistance) maxDistance = d;
_primitiveIndex = primitiveIndex;
}
center /= double(src.size());
PolytopeIntersector::Intersection intersection;
intersection.primitiveIndex = primtiveIndex;
intersection.distance = referencePlane.distance(center);
intersection.maxDistance = maxDistance;
intersection.nodePath = _iv.getNodePath();
intersection.drawable = _drawable;
intersection.matrix = _iv.getModelMatrix();
intersection.localIntersectionPoint = center;
if (src.size()<PolytopeIntersector::Intersection::MaxNumIntesectionPoints) intersection.numIntersectionPoints = src.size();
else intersection.numIntersectionPoints = PolytopeIntersector::Intersection::MaxNumIntesectionPoints;
for(unsigned int i=0; i<intersection.numIntersectionPoints; ++i)
{
intersection.intersectionPoints[i] = src[i];
}
// OSG_NOTICE<<"intersection "<<src.size()<<" center="<<center<<std::endl;
_polytopeIntersector->insertIntersection(intersection);
addIntersection();
return true;
}
@@ -731,9 +821,12 @@ struct IntersectFunctor
}
}
Vertices src, dest;
osgUtil::PolytopeIntersector* _polytopeIntersector;
osgUtil::IntersectionVisitor& _iv;
osgUtil::IntersectionVisitor* _iv;
osg::Drawable* _drawable;
unsigned int _primitiveIndex;
};
@@ -743,58 +836,63 @@ void PolytopeIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawa
if ( !_polytope.contains( drawable->getBoundingBox() ) ) return;
osg::TemplatePrimitiveFunctor<IntersectFunctor> intersector;
intersector._polytopeIntersector = this;
intersector._iv = &iv;
intersector._drawable = drawable;
osg::KdTree* kdTree = iv.getUseKdTreeWhenAvailable() ? dynamic_cast<osg::KdTree*>(drawable->getShape()) : 0;
if (kdTree)
{
IntersectFunctor intersector(this, iv, drawable);
kdTree->intersect(intersector, kdTree->getNode(0));
//OSG_NOTICE<<"NumHits "<<intersector._numHits<<std::endl;
//OSG_NOTICE<<"NumMisses "<<intersector._numMisses<<std::endl;
return;
}
osg::TemplatePrimitiveFunctor<PolytopeIntersectorUtils::PolytopePrimitiveIntersector> func;
func.setPolytope( _polytope, _referencePlane );
func.setDimensionMask( _dimensionMask );
func.setLimitOneIntersection( _intersectionLimit == LIMIT_ONE_PER_DRAWABLE || _intersectionLimit == LIMIT_ONE );
drawable->accept(func);
if (func.intersections.empty()) return;
for(PolytopeIntersectorUtils::Intersections::const_iterator it=func.intersections.begin();
it!=func.intersections.end();
++it)
else
#if 1
{
const PolytopeIntersectorUtils::PolytopeIntersection& intersection = *it;
Intersection hit;
hit.distance = intersection._distance;
hit.maxDistance = intersection._maxDistance;
hit.primitiveIndex = intersection._index;
hit.nodePath = iv.getNodePath();
hit.drawable = drawable;
hit.matrix = iv.getModelMatrix();
PolytopeIntersectorUtils::Vec3_type center;
for (unsigned int i=0; i<intersection._numPoints; ++i)
{
center += intersection._points[i];
}
center /= PolytopeIntersectorUtils::value_type(intersection._numPoints);
hit.localIntersectionPoint = center;
hit.numIntersectionPoints = intersection._numPoints;
std::copy(&intersection._points[0], &intersection._points[intersection._numPoints],
&hit.intersectionPoints[0]);
insertIntersection(hit);
drawable->accept(intersector);
}
#else
{
osg::TemplatePrimitiveFunctor<PolytopeIntersectorUtils::PolytopePrimitiveIntersector> func;
func.setPolytope( _polytope, _referencePlane );
func.setDimensionMask( _dimensionMask );
func.setLimitOneIntersection( _intersectionLimit == LIMIT_ONE_PER_DRAWABLE || _intersectionLimit == LIMIT_ONE );
drawable->accept(func);
if (func.intersections.empty()) return;
for(PolytopeIntersectorUtils::Intersections::const_iterator it=func.intersections.begin();
it!=func.intersections.end();
++it)
{
const PolytopeIntersectorUtils::PolytopeIntersection& intersection = *it;
Intersection hit;
hit.distance = intersection._distance;
hit.maxDistance = intersection._maxDistance;
hit.primitiveIndex = intersection._index;
hit.nodePath = iv.getNodePath();
hit.drawable = drawable;
hit.matrix = iv.getModelMatrix();
PolytopeIntersectorUtils::Vec3_type center;
for (unsigned int i=0; i<intersection._numPoints; ++i)
{
center += intersection._points[i];
}
center /= PolytopeIntersectorUtils::value_type(intersection._numPoints);
hit.localIntersectionPoint = center;
hit.numIntersectionPoints = intersection._numPoints;
std::copy(&intersection._points[0], &intersection._points[intersection._numPoints],
&hit.intersectionPoints[0]);
insertIntersection(hit);
}
}
#endif
}