OSG学习:人机交互——普通键盘事件:着火的飞机

以下内容来自: 

1、《OpenSceneGraph三维渲染引擎编程指南》肖鹏 刘更代 徐明亮 清华大学出版社 
2、《OpenSceneGraph三维渲染引擎设计与实践》王锐 钱学雷 清华大学出版社

3、自己的总结

创建C++项目后,首先需要配置OSG环境,具体步骤看OSG学习:WIN10系统下OSG+VS2017编译及运行第六步:新建OSG项目测试。

OSG中主要使用osgGA库来处理用户的交互工作(详细见OSG学习:OSG组成(一)——组成模块和OSG学习:OSG组成(三)——组成模块(续):OSG核心库中的一些类和方法)。GA全称为GUI Abstraction,图形接口抽象层。即由OSG负责与不同地层窗口的交互工作,而在更高层级为用户提供一套统一的操作接口,方便用户处理,因而构成了OSG与MFC/Qt/wxWidgets等各种窗口系统工具的交互方案。

OSG学习:几何体的操作(一)——交互事件、简化几何体OSG学习:纹理映射(六)——灯光两个例子中,都是使用事件监听或事件响应进行人机交互。在开关节点中展示了着火的飞机,在本例中,使用人机交互方式(键盘按键)来切换正常的飞机与着火的飞机。

下面来看具体的例子:

// stdafx.h


#include <osg/Switch> //控制子类的显示与隐藏,这种隐藏不消耗内存
#include <osgGA/GUIEventHandler> //OSG键盘和鼠标交互事件的处理终端

#include <osgDB/ReadFile>

#include <osgUtil/Optimizer>
#include <osgViewer/Viewer>
//.cpp

/*
 *定义人机交互事件处理器
 */
class KeyboardHandler :public osgGA::GUIEventHandler
{
public:
	virtual bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa, osg::Object *, osg::NodeVisitor *)
	{
		osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer *>(&aa); //将动作适配器us转换为场景视图,通常作为动作适配器的对象都是当前的场景视图
		if (!viewer)
			return false;

		switch (ea.getEventType())
		{
		case osgGA::GUIEventAdapter::KEYDOWN:
			//按下空格键时,获取窗口大小,并把鼠标光标限制到窗口中心 
			//KEY_Space 空格
			if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space)
			{
				//获取事件所来源的图形窗口的位置和尺寸信息,如果该事件来源于窗口的话
				int width = ea.getWindowWidth();
				int height = ea.getWindowHeight();
				viewer->requestWarpPointer(width * 0.5, height * 0.5);
			}
			else
			{
				//按下1或2键,切换开关节点的两个子节点,按1键显示正常飞机,按2键显示着火飞机
				//主键盘上的字母键、数字键,及各种标点符号键都以各自本身来代表,如下面的1就代表主键盘上的1
				osg::Switch *root = dynamic_cast<osg::Switch *>(viewer->getSceneData());
				if (!root)
					return false;
				if (ea.getKey() == '1')
				{
					root->setValue(0, true);
					root->setValue(1, false);
				}
				else if (ea.getKey() == '2')
				{
					root->setValue(0, false);
					root->setValue(1, true);
				}
				return true;
			}
			break;
		default:break;
		}
		return false;
	}
};

int main()
{
	osg::ref_ptr<osg::Switch> root = new osg::Switch();
	root->addChild(osgDB::readNodeFile("cessna.osg"), true);
	root->addChild(osgDB::readNodeFile("cessnafire.osg"), false);

	//优化场景数据
	osgUtil::Optimizer optimizer;
	optimizer.optimize(root.get());

	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
	viewer->addEventHandler(new KeyboardHandler); //将时间处理器使用addEventHandler()方法传递给当前视景器
	viewer->setSceneData(root.get());
	viewer->realize();

	return viewer->run();
}

按下空格键后模型和鼠标都回到窗口中心,按下主键盘上的1键显示正常飞机,按下主键盘上的2键显示着火飞机。

下载完整工程OSG_16_EventKey

猜你喜欢

转载自blog.csdn.net/u013719339/article/details/81254212
今日推荐