osg选取

void PickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea)

{

    osgUtil::LineSegmentIntersector::Intersections intersections;//求集交互器

    float x = ea.getX();

    float y = ea.getY();//传入事件的x,y坐标

    if (view->computeIntersections(x,y,intersections))//进入computeIntersections()求交集

    {

        for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();

            hitr != intersections.end();

            ++hitr)

       {

          

          }

}

}

先传入x,y坐标,然后进入computeIntersections(x,y,intersections))求交集,在此函数加断点后进入,分析以下函数

bool View::computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections, osg::Node::NodeMask traversalMask)

{

    if (!_camera.valid()) return false;

    float local_x, local_y = 0.0;   

    const osg::Camera* camera = getCameraContainingPosition(x, y, local_x, local_y);

    if (!camera) camera = _camera.get();

   

    osgUtil::LineSegmentIntersector::CoordinateFrame cf = camera->getViewport() ? osgUtil::Intersector::WINDOW : osgUtil::Intersector::PROJECTION;

    osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new osgUtil::LineSegmentIntersector(cf, local_x, local_y);

 

    osgUtil::IntersectionVisitor iv(picker.get());//用访问者设计模式对各个节点进行访问,函数内部不断的调用各个节点相应的accepte()函数,对节点进行访问,并把节点压入_NodePath,最终对Geodeaccept()访问。

    iv.setTraversalMask(traversalMask);

        const_cast<osg::Camera*>(camera)->accept(iv);//

 

    if (picker->containsIntersections())

    {

        intersections = picker->getIntersections();

        return true;

    }

    else

    {

        intersections.clear();

        return false;

    }

}

 

void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)

{

    osg::Vec3d s(_start), e(_end);    //最终对某个geodeDrawable循环调用此函数

    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::notify(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::notify(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;

    }

 

    osg::TriangleFunctor<LineSegmentIntersectorUtils::TriangleIntersector> ti;//定义一个三角形求交器

    ti.set(s,e);

    drawable->accept(ti);//用三角形求交器对drawable进行访问

 

    if (ti._hit)//如果和drawable有交点

    {

        osg::Geometry* geometry = drawable->asGeometry();

 

        for(LineSegmentIntersectorUtils::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();

 

            LineSegmentIntersectorUtils::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::notify(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);

 

        }

    }

}

转载于:https://www.cnblogs.com/lizhengjin/archive/2010/07/11/1775406.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值