Archie OSG Step By Step⑥ 对象选取

⑤位置显示X,原理还不懂,先学习简单的这节,不用另外设置Camera。

添加事件处理类CSelectHandler,勾选内联,公共继承自osgGA::GUIEventHandler,并添加cpp文件SelectHandler.cpp

添加变量

public:
    //得到鼠标位置
    float _mx;
    float _my;


修改构造函数

CSelectHandler(void):_mx(0.0f), _my(0.0f){}


添加handle事件处理虚函数

Archie OSG Step By Step⑥ 对象选取_第1张图片

// 事件处理函数
bool CSelectHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    osg::ref_ptr<osgViewer::View> view = dynamic_cast<osgViewer::View*>(&ea);
    if (!view)
    {
        return false;
    }
    switch(ea.getEventType())
    {
        // 鼠标按下
    case(osgGA::GUIEventAdapter::PUSH):
        {
            //更新鼠标位置
            _mx = ea.getX();
            _my = ea.getY();
            break;
        }
        //释放
    case (osgGA::GUIEventAdapter::RELEASE):
        {
            //不为0,也即鼠标按下 且按下前后都是同一点
            if (_mx==ea.getX() && _my==ea.getY())
            {
                //执行对象选取
                Select(view.get(),ea.getX(),ea.getY());
            } 
            break;

        }
    default:
        break;
    }
    return false;
}


 

添加Selcet对象选取事件处理器

Archie OSG Step By Step⑥ 对象选取_第2张图片

 

// 对象选取事件处理器
void CSelectHandler::Select(osg::ref_ptr<osgViewer::View> view, float x, float y)
{
   osg::ref_ptr<osg::Node> node = new osg::Node();
   osg::ref_ptr<osg::Group> parent = new osg::Group();

   //创建一个线段交集检测函数
   osgUtil::LineSegmentIntersector::Intersections intersections;
   if (view->computeIntersections(x,y,intersections))
   {
       osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin();
       osg::NodePath& nodePath = intersection.nodePath;
       // 得到选择的物体
       node = (nodePath.size()>=1)?nodePath[nodePath.size()-1]:0;
       parent = (nodePath.size()>=2) ? dynamic_cast<osg::Group*>(nodePath[nodePath.size()-2]:0);

   }
   // 用高亮来显示选中的物体
   if (parent.get)&& node.get())
   {
       osg::ref_ptr<osgFX::Scribe> parentAsScribe = dynamic_cast<osgFX::Scribe*>(parent.get());
       if (!parentAsScribe)
       {
           // 如果对象选择到,高亮显示
           osg::ref_ptr<osgFX::Scribe> scribe = new osgFX::Scribe();
           scribe->addChild(node.get());
           parent->replaceChild(node.get(),scribe.get());
       }
       else
       {
           // 如果没有选择到,则移除高亮显示的对象
           osg::Node::ParentList parentList = parentAsScribe->getParents();
           for (osg::Node::ParentList::iterator itr = parentList.begin();itr!=parentList.end();itr++)
           {
               (*itr)->replaceChild(parentAsScribe.get(),node.get());
           }
       }
   }
}

添加事件关联

  // 对象选取事件
    mViewer->addEventHandler(new CSelectHandler());



 

 

你可能感兴趣的:(Archie OSG Step By Step⑥ 对象选取)