键盘响应和回调的结合

来源:互联网 发布:中国气象数据网 api 编辑:程序博客网 时间:2024/06/05 06:50

响应键盘操作需要定义一个从osgGA::GUIEventHandle派生出来的类,结合自定义的回调类callBack实现对坦克模型的前进、后退,以及炮塔的旋转操作。

键盘响应类keyboardEventHandle与回调类callBack是如何通信的呢?这里我们需要在定义一个用户自定义的类,将对模型的操作的数据封装进去。

用户自定义数据类tankInputDeviceType。

tankInputDeviceType.h

#pragma once#include <osg/Node>#include <osgSim/DOFTransform>#include "myFindNodeVisitor.h"#ifdef _DEBUG#pragma comment(lib,"osgd.lib")#pragma comment(lib,"osgSimd.lib")#else#pragma comment(lib,"osg.lib")#pragma comment(lib,"osgSim.lib")#endifclass tankInputDeviceType{public://构造函数,传递一个结点指针,获得osgSim::DOFTransform*类型的炮塔结点指针并保存起来tankInputDeviceType(osg::Node& node):m_forward(false),m_backward(false),m_turretLeft(false),m_turretRight(false){myFindNodeVisitor findNode("turret");node.accept(findNode);osgSim::DOFTransform* turretNode = dynamic_cast<osgSim::DOFTransform*>(findNode.getFirst());if (turretNode){m_turretNode = turretNode;}else{std::cout<<"tankInputDeviceType::tankInputDeviceType(osg::Node& node):"<<std::endl<<"findNode failed"<<std::endl;}}//重载构造函数,传递一个结点指针,获得osgSim::DOFTransform*类型的炮塔结点指针并保存起来tankInputDeviceType(osg::Transform& node):m_forward(false),m_backward(false),m_turretLeft(false),m_turretRight(false){myFindNodeVisitor findNode("turret");node.accept(findNode);osgSim::DOFTransform* turretNode = dynamic_cast<osgSim::DOFTransform*>(findNode.getFirst());if (turretNode){m_turretNode = turretNode;}else{std::cout<<"tankInputDeviceType::tankInputDeviceType(osg::Node& node):"<<std::endl<<"findNode failed"<<std::endl;}}//对于坦克的前进、后退,炮塔的左旋转、右旋转的设置inline void setForward(bool b){m_forward = b;m_backward = false;}inline void setBackward(bool b){m_backward = b;m_forward = false;}inline void setTurretLeft(bool b){m_turretLeft = b;m_backward = false;}inline void setTurretRight(bool b){m_turretRight = b;m_turretLeft = false;}inline bool getForward(){return m_forward;}inline bool getBackward(){return m_backward;}inline bool getTurretLeft(){return m_turretLeft;}inline bool getTurretRight(){return m_turretRight;}inline osgSim::DOFTransform* getTurretNode(){return m_turretNode;}protected:bool m_forward;bool m_backward;bool m_turretLeft;bool m_turretRight;osgSim::DOFTransform* m_turretNode;};


这里的“myFindNodeVisitor.h”在《DOF和MultiSwitch的使用》这篇博客中有源代码,这里就不赘述了。

keyboardEventHandle.h

#pragma once#include <osgGA/GUIEventHandler>#include "tankInputDeviceType.h"#ifdef _DEBUG#pragma comment(lib,"osgGAd.lib")#else#pragma comment(lib,"osgGA.lib")#endifclass keyboardEventHandle:public osgGA::GUIEventHandler{public:// 构造函数,初始化m_tankInputDeviceData数据成员keyboardEventHandle(tankInputDeviceType* tankInputDeviceData):m_tankInputDeviceData(tankInputDeviceData){}//重载handle函数,使其响应键盘事件virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa);protected:tankInputDeviceType* m_tankInputDeviceData;};bool keyboardEventHandle::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa){switch (ea.getEventType()){case osgGA::GUIEventAdapter::KEYDOWN:{switch(ea.getKey()){case 'w':m_tankInputDeviceData->setForward(true);return true;case 's':m_tankInputDeviceData->setBackward(true);return true;case 'q':m_tankInputDeviceData->setTurretLeft(true);return true;case 'e':m_tankInputDeviceData->setTurretRight(true);return true;default:return false;}}case osgGA::GUIEventAdapter::KEYUP:{switch(ea.getKey()){case 'w':m_tankInputDeviceData->setForward(false);return true;case 's':m_tankInputDeviceData->setBackward(false);return true;case 'q':m_tankInputDeviceData->setTurretLeft(false);return true;case 'e':m_tankInputDeviceData->setTurretRight(false);return true;default:return false;}}default:return false;}}


回调类tankCallBack

tankCallBack.h

#pragma once#include <osg/NodeCallback>#include <osg/PositionAttitudeTransform>#include "tankInputDeviceType.h"#ifdef _DEBUG#pragma comment(lib,"osgd.lib")#else#pragma comment(lib,"osg.lib")#endifclass tankCallBack:public osg::NodeCallback{public:tankCallBack(tankInputDeviceType *tankInputData):m_tankInputData(tankInputData){}virtual void operator()(osg::Node* node, osg::NodeVisitor* nv){ //模型前进if (m_tankInputData->getForward()){osg::PositionAttitudeTransform* pos = dynamic_cast<osg::PositionAttitudeTransform*>(node);if (pos){tankPos = pos->getPosition();tankPos += osg::Vec3(0.0f,0.01f,0.0f);pos->setPosition(tankPos);}}//后退if (m_tankInputData->getBackward()){osg::PositionAttitudeTransform* pos = dynamic_cast<osg::PositionAttitudeTransform*>(node);if (pos){tankPos = pos->getPosition();tankPos -= osg::Vec3(0.0f,0.01f,0.0f);pos->setPosition(tankPos);}}//炮塔左旋转if (m_tankInputData->getTurretLeft()){tankRot = m_tankInputData->getTurretNode()->getCurrentHPR();tankRot += osg::Vec3(0.001f,0,0);m_tankInputData->getTurretNode()->setCurrentHPR(tankRot);}//炮塔右旋转if (m_tankInputData->getTurretRight()){tankRot = m_tankInputData->getTurretNode()->getCurrentHPR();tankRot -= osg::Vec3(0.001f,0,0);m_tankInputData->getTurretNode()->setCurrentHPR(tankRot);}traverse(node,nv);}protected:tankInputDeviceType* m_tankInputData;osg::Vec3 tankRot;osg::Vec3 tankPos;};

main.cpp

#include "tankCallBack.h"#include "tankInputDeviceType.h"#include "keyboardEventHandle.h"#include <osgDB/readfile>#include <osgViewer/Viewer>#include <osg/Group>#include <osg/Node>#include <osg/PositionAttitudeTransform>#include <iostream>#ifdef _DEBUG#pragma comment(lib,"osgd.lib")#pragma comment(lib,"osgDBd.lib")#pragma comment(lib,"osgViewerd.lib")#else#pragma comment(lib,"osg.lib")#pragma comment(lib,"osgDB.lib")#pragma commnet(lib,"osgViewer.lib")#endifint main(){//载入坦克模型和地形模型osg::ref_ptr<osg::Group> root = new osg::Group;osg::ref_ptr<osg::Node> tank = osgDB::readNodeFile("/T72-tank/t72-tank_des.flt");osg::ref_ptr<osg::Node> land = osgDB::readNodeFile("/T72-tank/JoeDirt.flt");if (!land.get()){std::cout<<"land node load error"<<std::endl;return -1;}if (!tank.get()){std::cout<<"tank node load error"<<std::endl;return -1;}osg::PositionAttitudeTransform* tankPos = new osg::PositionAttitudeTransform;tankPos->setPosition(osg::Vec3(10,10,8));tankPos->addChild(tank.get());root->addChild(land.get());root->addChild(tankPos);//声明用户自定义数据类实例,用这个类对象分别初始化回调类和键盘响应类tankInputDeviceType* tankData = new tankInputDeviceType(*tankPos);keyboardEventHandle* keyEH = new keyboardEventHandle(tankData);tankCallBack* callBack = new tankCallBack(tankData);//安装回调类tankPos->setUpdateCallback(callBack);//循环仿真osgViewer::Viewer myViewer;myViewer.addEventHandler(keyEH);myViewer.setSceneData(root.get());myViewer.realize();myViewer.run();}


移动前和炮塔为旋转

移动加炮塔旋转。

原创粉丝点击