1、首先定义一个类,该类继承与osgGA::GUIEventHandler,在此类中存在一个handle函数,所有的事件都在此函数中进行处理,如下类的代码:
//声明类UseEventHandler,由于它是从osgGA::GUIEventHandler派生而来,所以它拥有处理事件的能力,其中这种能力体现在一个虚函数handle上。 //一切的处理都在handle当中。 class UseEventHandler:public::osgGA::GUIEventHandler { public: //handle函数,其中有两个极其重要的参数, //一个是const osgGA::GUIEventAdapter,注意有不少人在写时少写了个const结果就不灵了, //因为是虚函数,参数必须与父类中虚函数相应一致。该参数是用来识别各种事件类型的参数。 //第二个参数也很重要:osgGA::GUIActionAdapter,它是控制显示的参数,其实最重要的是它是Viewer的祖父类,由它可以得到viewer,在操作中有体现。 virtual bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa) { //将aa强制转换为viewer对象 osgViewer::Viewer *viewer=dynamic_cast<osgViewer::Viewer*>(&aa); if (!viewer)//如果转换失败则直接退出 { return false; } switch(ea.getEventType())//获取事件的类型,是键盘上的事件,还是鼠标上的事件以及鼠标单击,右击,双击等等。 { case osgGA::GUIEventAdapter::KEYDOWN://键盘响应事件 if (ea.getKey()==0xFF51) { //首先获得场景中的数据,然后在获得Group,然后在获得Group的子节点,最后设置显示模式 viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);//按向左的方向键 viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0); } 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; } };2、写完了类,然后就是在场景中通过viewer.addEventHandler(new UseEventHandler());为场景添加定义好的事件类,如下代码所示:
//将UseEventHandler加入到viewer事件中,在UseEventHandler会有一个handle函数,此函数有两个参数,第一个参数是捕捉事件的,比如鼠标单击,双击,键盘事件等等 //第二个参数则是viewer的祖父GUIActionAdapter,可以通过强制转换来获得viewer对象,这样就可以在事件中控制场景中的物体模型了 viewer.addEventHandler(new UseEventHandler());
#include "stdafx.h" #include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osg/Node> //声明类UseEventHandler,由于它是从osgGA::GUIEventHandler派生而来,所以它拥有处理事件的能力,其中这种能力体现在一个虚函数handle上。 //一切的处理都在handle当中。 class UseEventHandler:public::osgGA::GUIEventHandler { public: //handle函数,其中有两个极其重要的参数, //一个是const osgGA::GUIEventAdapter,注意有不少人在写时少写了个const结果就不灵了, //因为是虚函数,参数必须与父类中虚函数相应一致。该参数是用来识别各种事件类型的参数。 //第二个参数也很重要:osgGA::GUIActionAdapter,它是控制显示的参数,其实最重要的是它是Viewer的祖父类,由它可以得到viewer,在操作中有体现。 virtual bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa) { //将aa强制转换为viewer对象 osgViewer::Viewer *viewer=dynamic_cast<osgViewer::Viewer*>(&aa); if (!viewer)//如果转换失败则直接退出 { return false; } switch(ea.getEventType())//获取事件的类型,是键盘上的事件,还是鼠标上的事件以及鼠标单击,右击,双击等等。 { case osgGA::GUIEventAdapter::KEYDOWN://键盘响应事件 if (ea.getKey()==0xFF51) { //首先获得场景中的数据,然后在获得Group,然后在获得Group的子节点,最后设置显示模式 viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);//按向左的方向键 viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0); } 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; } }; int _tmain(int argc, _TCHAR* argv[]) { osgViewer::Viewer viewer; osg::ref_ptr<osg::Group> root=new osg::Group(); root->addChild(osgDB::readNodeFile("avatar.osg")); root->addChild(osgDB::readNodeFile("glider.osg")); viewer.setSceneData(root.get()); //将UseEventHandler加入到viewer事件中,在UseEventHandler会有一个handle函数,此函数有两个参数,第一个参数是捕捉事件的,比如鼠标单击,双击,键盘事件等等 //第二个参数则是viewer的祖父GUIActionAdapter,可以通过强制转换来获得viewer对象,这样就可以在事件中控制场景中的物体模型了 viewer.addEventHandler(new UseEventHandler()); viewer.realize(); return viewer.run(); }
4、ea.getEventType()可获取的类型包括以下内容:
代码 | 值 | 事件类型 |
NONE | 0 | 无事件。 |
PUSH | 1 | 鼠标某键按下 |
RELEASE | 2 | 鼠标某键弹起。 |
DOUBLECLICK | 4 | 鼠标某键双击。 |
DRAG | 8 | 鼠标某键拖动。 |
MOVE | 16 | 鼠标移动。 |
KEYDOWN | 32 | 键盘上某键按下。 |
KEYUP | 64 | 键盘上某键弹起。 |
FRAME | 128 | 应该是鼠标每帧。没用过。 |
RESIZE | 256 | 窗口大小改变时会有的事件。 |
SCROLL | 512 | 鼠标轮滚动。 |
PEN_PRESSURE | 1024 | 手写板的某事件? |
PEN_PROXIMITY_ENTER | 2048 | 手写板的某事件? |
PEN_PROXIMITY_LEAVE | 4096 | 手写板的某事件? |
CLOSE_WINDOWS | 8192 | 关闭窗口。 |
QUIT_APPLICATION | 16384 | 退出程序。 |
USER | 32768 | 用户定义。 |
5、osg中支持的键盘编码值列表如下:
键 | 值 | 键 | 值 |
KEY_Space | 0x20 | KEY_KP_Tab | 0xFF89 |
KEY_BackSpace | 0xFF08 | KEY_KP_Enter | 0xFF8D |
KEY_Tab | 0xFF09 | KEY_KP_F1 | 0xFF91 |
KEY_Linefeed | 0xFF0A | KEY_KP_F2 | 0xFF92 |
KEY_Clear | 0xFF0B | KEY_KP_F3 | 0xFF93 |
KEY_Return | 0xFF0D | KEY_KP_F4 | 0xFF94 |
KEY_Pause | 0xFF13 | KEY_KP_Home | 0xFF95 |
KEY_Scroll_Lock | 0xFF14 | KEY_KP_Left | 0xFF96 |
KEY_Sys_Req | 0xFF15 | KEY_KP_Up | 0xFF97 |
KEY_Escape | 0xFF1B | KEY_KP_Right | 0xFF98 |
KEY_Delete | 0xFFFF | KEY_KP_Down | 0xFF99 |
KEY_Home | 0xFF50 | KEY_KP_Prior | 0xFF9A |
KEY_Left | 0xFF51 | KEY_KP_Page_Up | 0xFF9A |
KEY_Up | 0xFF52 | KEY_KP_Next | 0xFF9B |
KEY_Right | 0xFF53 | KEY_KP_Page_Down | 0xFF9B |
KEY_Down | 0xFF54 | KEY_KP_End | 0xFF9C |
KEY_Prior | 0xFF55 | KEY_KP_Begin | 0xFF9D |
KEY_Page_Up | 0xFF55 | KEY_KP_Insert | 0xFF9E |
KEY_Next | 0xFF56 | KEY_KP_Delete | 0xFF9F |
KEY_Page_Down | 0xFF56 | KEY_KP_Equal | 0xFFBD |
KEY_End | 0xFF57 | KEY_KP_Multiply | 0xFFAA |
KEY_Begin | 0xFF58 | KEY_KP_Add | 0xFFAB |
KEY_Select | 0xFF60 | KEY_KP_Separator | 0xFFAC |
KEY_Print | 0xFF61 | KEY_KP_Subtract | 0xFFAD |
KEY_Execute | 0xFF62 | KEY_KP_Decimal | 0xFFAE |
KEY_Insert | 0xFF63 | KEY_KP_Divide | 0xFFAF |
KEY_Undo | 0xFF65 | ||
KEY_Redo | 0xFF66 | KEY_KP_0 | 0xFFB0 |
KEY_Menu | 0xFF67 | KEY_KP_1 | 0xFFB1 |
KEY_Find | 0xFF68 | KEY_KP_2 | 0xFFB2 |
KEY_Cancel | 0xFF69 | KEY_KP_3 | 0xFFB3 |
KEY_Help | 0xFF6A | KEY_KP_4 | 0xFFB4 |
KEY_Break | 0xFF6B | KEY_KP_5 | 0xFFB5 |
KEY_Mode_switch | 0xFF7E | KEY_KP_6 | 0xFFB6 |
KEY_Script_switch | 0xFF7E | KEY_KP_7 | 0xFFB7 |
KEY_Num_Lock | 0xFF7F | KEY_KP_8 | 0xFFB8 |
KEY_KP_Space | 0xFF80 | KEY_KP_9 | 0xFFB9 |
KEY_F1 | 0xFFBE | KEY_F24 | 0xFFD5 |
KEY_F2 | 0xFFBF | KEY_F25 | 0xFFD6 |
KEY_F3 | 0xFFC0 | KEY_F26 | 0xFFD7 |
KEY_F4 | 0xFFC1 | KEY_F27 | 0xFFD8 |
KEY_F5 | 0xFFC2 | KEY_F28 | 0xFFD9 |
KEY_F6 | 0xFFC3 | KEY_F29 | 0xFFDA |
KEY_F7 | 0xFFC4 | KEY_F30 | 0xFFDB |
KEY_F8 | 0xFFC5 | KEY_F31 | 0xFFDC |
KEY_F9 | 0xFFC6 | KEY_F32 | 0xFFDD |
KEY_F10 | 0xFFC7 | KEY_F33 | 0xFFDE |
KEY_F11 | 0xFFC8 | KEY_F34 | 0xFFDF |
KEY_F12 | 0xFFC9 | KEY_F35 | 0xFFE0 |
KEY_F13 | 0xFFCA | KEY_Shift_L | 0xFFE1 |
KEY_F14 | 0xFFCB | KEY_Shift_R | 0xFFE2 |
KEY_F15 | 0xFFCC | KEY_Control_L | 0xFFE3 |
KEY_F16 | 0xFFCD | KEY_Control_R | 0xFFE4 |
KEY_F17 | 0xFFCE | KEY_Caps_Lock | 0xFFE5 |
KEY_F18 | 0xFFCF | KEY_Shift_Lock | 0xFFE6 |
KEY_F19 | 0xFFD0 | ||
KEY_F20 | 0xFFD1 | KEY_Meta_L | 0xFFE7 |
KEY_F21 | 0xFFD2 | KEY_Meta_R | 0xFFE8 |
KEY_F22 | 0xFFD3 | KEY_Alt_L | 0xFFE9 |
KEY_F23 | 0xFFD4 | KEY_Alt_R | 0xFFEA |
KEY_Super_L | 0xFFEB | KEY_Hyper_L | 0xFFED |
KEY_Super_R | 0xFFEC | KEY_Hyper_R | 0xFFEE |