第7课时《osg交互》

8 篇文章 1 订阅

  1.交互

     所谓交互,一般指的的我们的键盘、鼠标等响应。OSG针对场景的操作封装了一系列的用于交互的事件处理器。

     在osgViewer中存在,addEventHandler方法,用于接收和处理事件。

      viewer->addEventHandler(new osgViewer::StatsHandler);//添加事件的实例,用于显示帧率等状态信息。

    2.自定义事件

      如果想要自己定义处理器,需要了解处理器的格式,一般处理器继承类osgGA::GUIEventHandler.

      class  A :public osgGA::GUIEventHandler,并重写相关的方法。

      viewer->addEventHandler(new A);来使用自定的事件处理类。

     整个过程如下图:

     

   

     实例:改写HelpHandler处理类。

     参照OSG中osgViewer中的HelpHandler的源文件,我们自己定义重写帮助处理类:PintInfo。

  class PrintInfo : public osgGA::GUIEvemtHandler //模拟一个事件类,响应h
    {
     public:
      bool HelpHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){
            return false;
      }
      void HelpHandler::getUsage(osg::ApplicationUsage& usage) const
        {
              usage.addKeyboardMouseBinding(‘h’,"Onscreen help.");
       }
     };
     viewer->addEventHandlers(new PrintInfo); //应用事件处理类
       3. 经典实例

        响应键盘鼠标,改实例功能是鼠标右键单击时牛和飞机隐藏,鼠标左键双击是牛和飞机都显示,按住键盘上的LEFT键,显示牛,按RIGHT键显示飞机。

        详细代码如下:

        

class UseEventHandler : public osgGA::GUIEventHandler
{
public:
    ///
    /// \brief 事件处理的关键函数
    /// \param ea 用于识别事件类型
    /// \param aa 控制显示
    /// \return bool
    ///
    virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
    {
        //获取要响应的view
        osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
        if (!viewer) return false;
        //开始判断事件类型
        switch(ea.getEventType())
        {
        case osgGA::GUIEventAdapter::KEYDOWN:
        {
            if (ea.getKey()== 0xFF51)
            {
                viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(0) ;
                viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(1) ;
            }
            if (ea.getKey()== 0xFF53)
            {
                viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(0) ;
                viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(1) ;
            }
        }
            break;
        case osgGA::GUIEventAdapter ::PUSH:
            if(ea.getButton () == 4)
            {
                viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(0) ;
                viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(0) ;
            }
            break;
        case osgGA::GUIEventAdapter::DOUBLECLICK:
            if(ea.getButton() == 1)
            {
                viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(1) ;
                viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(1) ;
            }
            break;
        default:
            break;
        }
        return false;
    }
    
};

void main()
{
    osgViewer::Viewer viewer;
    osg::ref_ptr<osg::Group> root = new osg::Group() ;
    root ->addChild(osgDB::readNodeFile("cow.osg")) ;
    root ->addChild(osgDB::readNodeFile("glider.osg"));
    viewer.setSceneData(root.get ());
    viewer.addEventHandler(new UseEventHandler) ;
    viewer.realize();
    viewer.run();
}

        


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值