7、osg中响应键盘鼠标事件以及鼠标和键盘编码表

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

3、完整的代码如下:

#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()可获取的类型包括以下内容:

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
 


你可能感兴趣的:(7、osg中响应键盘鼠标事件以及鼠标和键盘编码表)