• 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);

     

            }

        }

    }

  • 相关阅读:
    连接AI与用户,京东云推出视音频通信技术方案
    我身边的高T,问了Java面试者这样的问题......
    解密协议层的攻击——HTTP请求走私
    产业实践推动科技创新,京东科技集团3篇论文入选ICASSP 2021
    2021年人工智能数据采集标注行业四大趋势预测;清华提出深度对齐聚类用于新意图发现
    京东科技集团21篇论文高票入选国际顶会AAAI 2021
    别困惑,不是你的错!90%的开发者把Clubhouse看成了Clickhouse
    京东App Swift 混编及组件化落地
    对话京东科技算法科学家吴友政:回望2020,NLP技术发展速度强劲
    关于京东技术,你想了解的都在这里丨征文活动获奖及优秀专栏推荐
  • 原文地址:https://www.cnblogs.com/lizhengjin/p/1775406.html
Copyright © 2020-2023  润新知