原文地址:http://blog.csdn.net/sunxiaoju/article/details/50225647

1、首先定义一个类,该类继承与osgGA::GUIEventHandler,在此类中存在一个handle函数,所有的事件都在此函数中进行处理,如下类的代码:

 

[cpp] view plain copy
 
  1. //声明类UseEventHandler,由于它是从osgGA::GUIEventHandler派生而来,所以它拥有处理事件的能力,其中这种能力体现在一个虚函数handle上。  
  2. //一切的处理都在handle当中。  
  3. class UseEventHandler:public::osgGA::GUIEventHandler  
  4. {  
  5. public:  
  6.     //handle函数,其中有两个极其重要的参数,  
  7.     //一个是const osgGA::GUIEventAdapter,注意有不少人在写时少写了个const结果就不灵了,  
  8.     //因为是虚函数,参数必须与父类中虚函数相应一致。该参数是用来识别各种事件类型的参数。  
  9.     //第二个参数也很重要:osgGA::GUIActionAdapter,它是控制显示的参数,其实最重要的是它是Viewer的祖父类,由它可以得到viewer,在操作中有体现。  
  10.     virtual bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa)  
  11.     {  
  12.         //将aa强制转换为viewer对象  
  13.         osgViewer::Viewer *viewer=dynamic_cast<osgViewer::Viewer*>(&aa);  
  14.         if (!viewer)//如果转换失败则直接退出  
  15.         {  
  16.             return false;  
  17.         }  
  18.         switch(ea.getEventType())//获取事件的类型,是键盘上的事件,还是鼠标上的事件以及鼠标单击,右击,双击等等。  
  19.         {  
  20.         case osgGA::GUIEventAdapter::KEYDOWN://键盘响应事件  
  21.             if (ea.getKey()==0xFF51)  
  22.             {  
  23.                 //首先获得场景中的数据,然后在获得Group,然后在获得Group的子节点,最后设置显示模式  
  24.                 viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);//按向左的方向键  
  25.                 viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0);  
  26.             }  
  27.             if (ea.getKey()==0xFF53)  
  28.             {  
  29.                 viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(0);//按下向右的方向键  
  30.                 viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(1);  
  31.             }  
  32.             break;  
  33.         case osgGA::GUIEventAdapter::PUSH:  
  34.             if (ea.getButton()==4)//表示按鼠标右键  
  35.             {  
  36.                 viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(0);  
  37.                 viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0);  
  38.             }  
  39.             break;  
  40.         case osgGA::GUIEventAdapter::DOUBLECLICK://表示双击类型  
  41.             if (ea.getButton()==1)//表示按鼠标左键  
  42.             {  
  43.                 viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);  
  44.                 viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(1);  
  45.             }  
  46.             break;  
  47.         default:  
  48.             break;  
  49.         }  
  50.         return false;  
  51.     }  
  52. };  

2、写完了类,然后就是在场景中通过viewer.addEventHandler(new UseEventHandler());为场景添加定义好的事件类,如下代码所示:

 

 

[cpp] view plain copy
 
  1. //将UseEventHandler加入到viewer事件中,在UseEventHandler会有一个handle函数,此函数有两个参数,第一个参数是捕捉事件的,比如鼠标单击,双击,键盘事件等等  
  2. //第二个参数则是viewer的祖父GUIActionAdapter,可以通过强制转换来获得viewer对象,这样就可以在事件中控制场景中的物体模型了  
  3. viewer.addEventHandler(new UseEventHandler());  


3、完整的代码如下:

 

 

[cpp] view plain copy
 
  1. #include "stdafx.h"  
  2. #include <osgDB/ReadFile>  
  3. #include <osgViewer/Viewer>  
  4. #include <osg/Node>  
  5. //声明类UseEventHandler,由于它是从osgGA::GUIEventHandler派生而来,所以它拥有处理事件的能力,其中这种能力体现在一个虚函数handle上。  
  6. //一切的处理都在handle当中。  
  7. class UseEventHandler:public::osgGA::GUIEventHandler  
  8. {  
  9. public:  
  10.     //handle函数,其中有两个极其重要的参数,  
  11.     //一个是const osgGA::GUIEventAdapter,注意有不少人在写时少写了个const结果就不灵了,  
  12.     //因为是虚函数,参数必须与父类中虚函数相应一致。该参数是用来识别各种事件类型的参数。  
  13.     //第二个参数也很重要:osgGA::GUIActionAdapter,它是控制显示的参数,其实最重要的是它是Viewer的祖父类,由它可以得到viewer,在操作中有体现。  
  14.     virtual bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa)  
  15.     {  
  16.         //将aa强制转换为viewer对象  
  17.         osgViewer::Viewer *viewer=dynamic_cast<osgViewer::Viewer*>(&aa);  
  18.         if (!viewer)//如果转换失败则直接退出  
  19.         {  
  20.             return false;  
  21.         }  
  22.         switch(ea.getEventType())//获取事件的类型,是键盘上的事件,还是鼠标上的事件以及鼠标单击,右击,双击等等。  
  23.         {  
  24.         case osgGA::GUIEventAdapter::KEYDOWN://键盘响应事件  
  25.             if (ea.getKey()==0xFF51)  
  26.             {  
  27.                 //首先获得场景中的数据,然后在获得Group,然后在获得Group的子节点,最后设置显示模式  
  28.                 viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);//按向左的方向键  
  29.                 viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0);  
  30.             }  
  31.             if (ea.getKey()==0xFF53)  
  32.             {  
  33.                 viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(0);//按下向右的方向键  
  34.                 viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(1);  
  35.             }  
  36.             break;  
  37.         case osgGA::GUIEventAdapter::PUSH:  
  38.             if (ea.getButton()==4)//表示按鼠标右键  
  39.             {  
  40.                 viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(0);  
  41.                 viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0);  
  42.             }  
  43.             break;  
  44.         case osgGA::GUIEventAdapter::DOUBLECLICK://表示双击类型  
  45.             if (ea.getButton()==1)//表示按鼠标左键  
  46.             {  
  47.                 viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);  
  48.                 viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(1);  
  49.             }  
  50.             break;  
  51.         default:  
  52.             break;  
  53.         }  
  54.         return false;  
  55.     }  
  56. };  
  57. int _tmain(int argc, _TCHAR* argv[])  
  58. {  
  59.     osgViewer::Viewer viewer;  
  60.     osg::ref_ptr<osg::Group> root=new osg::Group();  
  61.     root->addChild(osgDB::readNodeFile("avatar.osg"));  
  62.     root->addChild(osgDB::readNodeFile("glider.osg"));  
  63.     viewer.setSceneData(root.get());  
  64.     //将UseEventHandler加入到viewer事件中,在UseEventHandler会有一个handle函数,此函数有两个参数,第一个参数是捕捉事件的,比如鼠标单击,双击,键盘事件等等  
  65.     //第二个参数则是viewer的祖父GUIActionAdapter,可以通过强制转换来获得viewer对象,这样就可以在事件中控制场景中的物体模型了  
  66.     viewer.addEventHandler(new UseEventHandler());  
  67.     viewer.realize();  
  68.     return viewer.run();  
  69. }  

4、ea.getEventType()可获取的类型包括以下内容:

 

OSG中常用的事件类型
代码 事件类型
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中支持的键盘编码值列表如下:

 

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
posted on 2017-07-06 21:52  非宁静,无以致远  阅读(3158)  评论(0)    收藏  举报