void StrokeIntersector::intersect(osgUtil::IntersectionVisitor &iv, osg::Drawable *drawable) { osg::BoundingBox bb = drawable->getBoundingBox(); bb.xMin() -= m_offset; bb.xMax() += m_offset; bb.yMin() -= m_offset; bb.yMax() += m_offset; bb.zMin() -= m_offset; bb.zMax() += m_offset; osg::Vec3d s(_start), e(_end); if (!intersectAndClip(s, e, bb)) return; if (iv.getDoDummyTraversal()) return; entity::Stroke* geometry = dynamic_cast<entity::Stroke*>(drawable->asGeometry()); if (geometry) { osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()); if (!vertices) return; for (unsigned int i=1; i<vertices->size(); ++i) { double distance = Utilities::getSkewLinesDistance(s,e,(*vertices)[i], (*vertices)[i-1]); if (m_offset<distance) continue; Intersection hit; hit.ratio = distance; hit.nodePath = iv.getNodePath(); hit.drawable = drawable; hit.matrix = iv.getModelMatrix(); hit.localIntersectionPoint = (*vertices)[i]; m_hitIndices.push_back(i); insertIntersection(hit); } } }
void PolytopeIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) { if (reachedLimit()) return; if ( !_polytope.contains( drawable->getBoundingBox() ) ) 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) { 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); } }
void PrimitiveIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) { if (reachedLimit() || !drawable) return; osg::BoundingBox bb = drawable->getBoundingBox(); if (bb.valid()) bb.expandBy(osg::BoundingSphere(bb.center(), (_thickness - _start).length())); osg::Vec3d s(_start), e(_end); if ( !intersectAndClip( s, e, bb ) ) return; if (iv.getDoDummyTraversal()) return; osg::TemplatePrimitiveFunctor<PrimitiveIntersectorFunctor> ti; ti.set(s,e,_thickness-_start); ti._limitOneIntersection = (_intersectionLimit == LIMIT_ONE_PER_DRAWABLE || _intersectionLimit == LIMIT_ONE); drawable->accept(ti); if (ti._hit) { osg::Geometry* geometry = drawable->asGeometry(); for(PrimitiveIntersections::iterator thitr = ti._intersections.begin(); thitr != ti._intersections.end(); ++thitr) { // get ratio in s,e range double ratio = thitr->first; // remap ratio into _start, _end range double remap_ratio = ((s-_start).length() + ratio * (e-s).length() )/(_end-_start).length(); if ( _intersectionLimit == LIMIT_NEAREST && !getIntersections().empty() ) { if (remap_ratio >= getIntersections().begin()->ratio ) break; else getIntersections().clear(); } PrimitiveIntersection& triHit = thitr->second; Intersection hit; hit.ratio = remap_ratio; hit.matrix = iv.getModelMatrix(); hit.nodePath = iv.getNodePath(); hit.drawable = drawable; hit.primitiveIndex = findPrimitiveIndex(drawable, triHit._index); hit.localIntersectionPoint = _start*(1.0-remap_ratio) + _end*remap_ratio; hit.localIntersectionNormal = triHit._normal; if (geometry) { osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()); if (vertices) { osg::Vec3* first = &(vertices->front()); if (triHit._v1) { hit.indexList.push_back(triHit._v1-first); hit.ratioList.push_back(triHit._r1); } if (triHit._v2) { hit.indexList.push_back(triHit._v2-first); hit.ratioList.push_back(triHit._r2); } if (triHit._v3) { hit.indexList.push_back(triHit._v3-first); hit.ratioList.push_back(triHit._r3); } } } insertIntersection(hit); } } }
void DPLineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) { if (reachedLimit()) return; osg::Vec3d s(_start), e(_end); if ( !intersectAndClip( s, e, drawable->getBound() ) ) return; if (iv.getDoDummyTraversal()) return; osg::KdTree* kdTree = iv.getUseKdTreeWhenAvailable() ? dynamic_cast<osg::KdTree*>(drawable->getShape()) : 0; if (kdTree) { osg::KdTree::LineSegmentIntersections intersections; intersections.reserve(4); if (kdTree->intersect(s,e,intersections)) { // OSG_NOTICE<<"Got KdTree intersections"<<std::endl; for(osg::KdTree::LineSegmentIntersections::iterator itr = intersections.begin(); itr != intersections.end(); ++itr) { osg::KdTree::LineSegmentIntersection& lsi = *(itr); // get ratio in s,e range double ratio = lsi.ratio; // remap ratio into _start, _end range double remap_ratio = ((s-_start).length() + ratio * (e-s).length() )/(_end-_start).length(); Intersection hit; hit.ratio = remap_ratio; hit.matrix = iv.getModelMatrix(); hit.nodePath = iv.getNodePath(); hit.drawable = drawable; hit.primitiveIndex = lsi.primitiveIndex; hit.localIntersectionPoint = _start*(1.0-remap_ratio) + _end*remap_ratio; // OSG_NOTICE<<"KdTree: ratio="<<hit.ratio<<" ("<<hit.localIntersectionPoint<<")"<<std::endl; hit.localIntersectionNormal = lsi.intersectionNormal; hit.indexList.reserve(3); hit.ratioList.reserve(3); if (lsi.r0!=0.0f) { hit.indexList.push_back(lsi.p0); hit.ratioList.push_back(lsi.r0); } if (lsi.r1!=0.0f) { hit.indexList.push_back(lsi.p1); hit.ratioList.push_back(lsi.r1); } if (lsi.r2!=0.0f) { hit.indexList.push_back(lsi.p2); hit.ratioList.push_back(lsi.r2); } insertIntersection(hit); } } return; } // GW: changed this ONE line osg::TriangleFunctor<DoublePrecisionTriangleIntersector> ti; ti.set(s,e); ti._limitOneIntersection = (_intersectionLimit == LIMIT_ONE_PER_DRAWABLE || _intersectionLimit == LIMIT_ONE); drawable->accept(ti); if (ti._hit) { osg::Geometry* geometry = drawable->asGeometry(); for(TriangleIntersections::iterator thitr = ti._intersections.begin(); thitr != ti._intersections.end(); ++thitr) { // get ratio in s,e range double ratio = thitr->first; // remap ratio into _start, _end range double remap_ratio = ((s-_start).length() + ratio * (e-s).length() )/(_end-_start).length(); if ( _intersectionLimit == LIMIT_NEAREST && !getIntersections().empty() ) { if (remap_ratio >= getIntersections().begin()->ratio ) break; else getIntersections().clear(); } TriangleIntersection& triHit = thitr->second; Intersection hit; hit.ratio = remap_ratio; hit.matrix = iv.getModelMatrix(); hit.nodePath = iv.getNodePath(); hit.drawable = drawable; hit.primitiveIndex = triHit._index; hit.localIntersectionPoint = _start*(1.0-remap_ratio) + _end*remap_ratio; // OSG_NOTICE<<"Conventional: ratio="<<hit.ratio<<" ("<<hit.localIntersectionPoint<<")"<<std::endl; hit.localIntersectionNormal = triHit._normal; if (geometry) { osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()); if (vertices) { osg::Vec3* first = &(vertices->front()); if (triHit._v1) { hit.indexList.push_back(triHit._v1-first); hit.ratioList.push_back(triHit._r1); } if (triHit._v2) { hit.indexList.push_back(triHit._v2-first); hit.ratioList.push_back(triHit._r2); } if (triHit._v3) { hit.indexList.push_back(triHit._v3-first); hit.ratioList.push_back(triHit._r3); } } } insertIntersection(hit); } } }
void intersectWithQuadTree(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable , const osg::Vec3d s, const osg::Vec3d e , const osg::Vec3d _start, const osg::Vec3d _end , QuadTree* quadTree , DPLineSegmentIntersector& intersector) { QuadTree::LineSegmentIntersections intersections; intersections.reserve(4); if (quadTree->intersect(s,e,intersections)) { // OSG_NOTICE<<"Got QuadTree intersections"<<std::endl; for(QuadTree::LineSegmentIntersections::iterator itr = intersections.begin(); itr != intersections.end(); ++itr) { QuadTree::LineSegmentIntersection& lsi = *(itr); // get ratio in s,e range double ratio = lsi.ratio; // remap ratio into _start, _end range double remap_ratio = ((s-_start).length() + ratio * (e-s).length() )/(_end-_start).length(); osgUtil::LineSegmentIntersector::Intersection hit; hit.ratio = remap_ratio; hit.matrix = iv.getModelMatrix(); hit.nodePath = iv.getNodePath(); hit.drawable = drawable; hit.primitiveIndex = lsi.primitiveIndex; hit.localIntersectionPoint = _start*(1.0-remap_ratio) + _end*remap_ratio; // OSG_NOTICE<<"QuadTree: ratio="<<hit.ratio<<" ("<<hit.localIntersectionPoint<<")"<<std::endl; hit.localIntersectionNormal = lsi.intersectionNormal; hit.indexList.reserve(3); hit.ratioList.reserve(3); if (lsi.r0!=0.0f) { hit.indexList.push_back(lsi.p0); hit.ratioList.push_back(lsi.r0); } if (lsi.r1!=0.0f) { hit.indexList.push_back(lsi.p1); hit.ratioList.push_back(lsi.r1); } if (lsi.r2!=0.0f) { hit.indexList.push_back(lsi.p2); hit.ratioList.push_back(lsi.r2); } intersector.insertIntersection(hit); } } }