diff --git a/include/osg/KdTree b/include/osg/KdTree index a2950ed54..cc9829f23 100644 --- a/include/osg/KdTree +++ b/include/osg/KdTree @@ -34,10 +34,7 @@ class OSG_EXPORT KdTree : public osg::Shape struct BuildOptions { - BuildOptions(): - _numVerticesProcessed(0), - _targetNumTrianglesPerLeaf(4), - _maxNumLevels(24) {} + BuildOptions(); int _numVerticesProcessed; int _targetNumTrianglesPerLeaf; @@ -163,6 +160,17 @@ class OSG_EXPORT KdTree : public osg::Shape return _kdLeaves[num]; } + const KdLeaf& getLeaf(int leafNum) const + { + int num = -leafNum-1; + if (num<0 || num>static_cast(_kdLeaves.size())-1) + { + osg::notify(osg::NOTICE)<<"Warning: getLeaf("<0) intersect(getNode(node.first), start, end, ls, le, intersections); + else if (node.first<0) intersect(getLeaf(node.first), start, end, intersections); + + if (node.second>0) intersect(getNode(node.second), start, end, ls, le, intersections); + else if (node.second<0) intersect(getLeaf(node.second), start, end, intersections); + } + return numIntersectionsBefore != intersections.size(); +} + +bool KdTree::intersectAndClip(osg::Vec3& s, osg::Vec3& e, const osg::BoundingBox& bb) const +{ + // compate s and e against the xMin to xMax range of bb. + if (s.x()<=e.x()) + { + + // trivial reject of segment wholely outside. + if (e.x()bb.xMax()) return false; + + if (s.x()bb.xMax()) + { + // clip e to xMax. + e = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x()); + } + } + else + { + if (s.x()bb.xMax()) return false; + + if (e.x()bb.xMax()) + { + // clip e to xMax. + s = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x()); + } + } + + // compate s and e against the yMin to yMax range of bb. + if (s.y()<=e.y()) + { + + // trivial reject of segment wholely outside. + if (e.y()bb.yMax()) return false; + + if (s.y()bb.yMax()) + { + // clip e to yMax. + e = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y()); + } + } + else + { + if (s.y()bb.yMax()) return false; + + if (e.y()bb.yMax()) + { + // clip e to yMax. + s = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y()); + } + } + + // compate s and e against the zMin to zMax range of bb. + if (s.z()<=e.z()) + { + + // trivial reject of segment wholely outside. + if (e.z()bb.zMax()) return false; + + if (s.z()bb.zMax()) + { + // clip e to zMax. + e = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z()); + } + } + else + { + if (s.z()bb.zMax()) return false; + + if (e.z()bb.zMax()) + { + // clip e to zMax. + s = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z()); + } + } + + // osg::notify(osg::NOTICE)<<"clampped segment "<bb)) + { + if (intersect(*itr, start, end, intersections)) intersects = true; + } + } + break; + } + + case(2): + { + //osg::notify(osg::NOTICE)<<"_kdNodes.size()="<<_kdNodes.size()< #include #include +#include using namespace osgUtil; @@ -294,13 +295,18 @@ void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Dr e += (delta_e_end * scale); } + osg::Timer_t before_kdTree = osg::Timer::instance()->tick(); + unsigned int numKdTreeHits = 0; + unsigned int numConventionalHits = 0; + osg::KdTree* kdTree = dynamic_cast(drawable->getShape()); + osg::Vec3d kdTreeHit; if (kdTree) { osg::KdTree::LineSegmentIntersections intersections; if (kdTree->intersect(s,e,intersections)) { - osg::notify(osg::NOTICE)<<"Got KdTree intersections"<tick(); + osg::TriangleFunctor ti; ti.set(s,e); drawable->accept(ti); + osg::Vec3d conventionalHit; if (ti._hit) { osg::Geometry* geometry = drawable->asGeometry(); @@ -371,6 +382,7 @@ void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Dr hit.primitiveIndex = triHit._index; hit.localIntersectionPoint = _start*(1.0-remap_ratio) + _end*remap_ratio; + conventionalHit = hit.localIntersectionPoint; // osg::notify(osg::NOTICE)<<"Conventional: ratio="<tick(); + + double timeKdTree = osg::Timer::instance()->delta_m(before_kdTree, after_kdTree); + double timeConventional = osg::Timer::instance()->delta_m(after_kdTree, after_conventional); + +#if 1 + if (kdTree) + { + osg::notify(osg::NOTICE)<<"KdTree ("<