查看: 2724|回复: 12

事件回调的问题

[复制链接]

该用户从未签到

发表于 2011-2-23 20:37:08 | 显示全部楼层 |阅读模式
  1. #include<osgViewer/Viewer>
  2. #include<osgViewer/ViewerEventHandlers>

  3. #include<osg/Node>
  4. #include<osg/Geode>
  5. #include<osg/Group>
  6. #include<osg/MatrixTransform>

  7. #include<osgDB/ReadFile>
  8. #include<osgDB/WriteFile>

  9. #include<osgUtil/Optimizer>

  10. #include<iostream>

  11. class MyEventCallback:public osg::NodeCallback
  12. {
  13. public:
  14. virtual void operator()(osg::Node* node,osg::NodeVisitor* nv)
  15. {
  16. //
  17. if(nv->getVisitorType()==osg::NodeVisitor::EVENT_VISITOR)
  18. {
  19. //
  20. osg::ref_ptr<osgGA::EventVisitor>ev=dynamic_cast<osgGA::EventVisitor*>(nv);
  21. if(ev)
  22. {
  23. //
  24. osgGA::GUIActionAdapter* aa=ev->getActionAdapter();
  25. //
  26. osgGA::EventQueue::Events& events=ev->getEvents();

  27. for(osgGA::EventQueue::Events::iterator itr=events.begin();itr!=events.end();++itr)
  28. {
  29. //
  30. handle(*(*itr),*(aa));
  31. }
  32. }
  33. }
  34. }
  35. virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
  36. {
  37. //
  38. osg::ref_ptr<osgViewer::Viewer> viewer=dynamic_cast<osgViewer::Viewer*>(&aa);
  39. osg::ref_ptr<osg::MatrixTransform> mt=dynamic_cast<osg::MatrixTransform*>(viewer->getSceneData());

  40. switch(ea.getEventType())
  41. {
  42. case(osgGA::GUIEventAdapter::KEYDOWN):
  43. {
  44. if(ea.getKey()==osgGA::GUIEventAdapter::KEY_Down)
  45. {
  46. osg::Matrix mT;
  47. mT.makeTranslate(0.0f,0.0f,-1.0f);
  48. mt->setMatrix(mT);
  49. }
  50. //
  51. if(ea.getKey()==osgGA::GUIEventAdapter::KEY_Up)
  52. {
  53. osg::Matrix mT;
  54. mT.makeTranslate(0.0f,0.0f,1.0f);
  55. mt->setMatrix(mT);
  56. }
  57. //

  58. break;
  59. }
  60. default:
  61. break;
  62. }
  63. return false;
  64. }
  65. };

  66. int main()
  67. {
  68. //创建Viewer对象,场景浏览器
  69. osg::ref_ptr<osgViewer::Viewer>viewer=new osgViewer::Viewer();

  70. osg::ref_ptr<osg::Group> root = new osg::Group();

  71. //读取模型
  72. osg::ref_ptr<osg::Node>node=osgDB::readNodeFile("cow.osg");

  73. //
  74. osg::ref_ptr<osg::MatrixTransform> mt=new osg::MatrixTransform();
  75. mt->addChild(node.get());
  76. mt->setEventCallback(new MyEventCallback());
  77. //

  78. //添加到场景
  79. root->addChild(mt.get());

  80. //优化场景数据
  81. osgUtil::Optimizer optimizer;
  82. optimizer.optimize(mt.get());

  83. //viewer->setSceneData(root.get());
  84. viewer->setSceneData(mt.get());

  85. viewer->realize();
  86. viewer->run();


  87. return 0;
  88. }
复制代码



程序的功能是在按下“Down”键时场景中的模型会向下运动1个单位,如上程序正常,但是当把mt添加到root(Group类型)中时,事件回调就出问题了,而且当按下键时,程序回卡住。。。

请问为甚么会出现这个问题,,还有怎样用键盘事件来对比较深的节点进行控制

该用户从未签到

发表于 2011-2-23 21:04:57 | 显示全部楼层
你的viewer->getSceneData()获得的节点不是MatrixTransform类型的,而是Node类型的,所以你的变换是不正确的。

该用户从未签到

 楼主| 发表于 2011-2-23 21:28:35 | 显示全部楼层
上面的程序是能运行的,当换成root时就出问题了

该用户从未签到

发表于 2011-2-23 21:37:38 | 显示全部楼层
不懂你的意思,怎么换?

该用户从未签到

 楼主| 发表于 2011-2-23 21:40:51 | 显示全部楼层
直接viewer->setSceneData(mt.get());可以运行,
但是root->addChild(mt.get());viewer->setSceneData(root.get());
中间加了一个root程序就出问题了,事件回调就不顶用了

该用户从未签到

发表于 2011-2-23 23:08:44 | 显示全部楼层
osg::ref_ptr<osg::MatrixTransform> mt=dynamic_cast<osg::MatrixTransform*>(viewer->getSceneData());
您这里的代码是什么意思?您如何确信getSceneData()是MatrixTransform类型?从您的程序中看来明显不是这样的

该用户从未签到

 楼主| 发表于 2011-2-24 07:14:54 | 显示全部楼层
  1. osg::ref_ptr<osg::MatrixTransform> mt=dynamic_cast<osg::MatrixTransform*>(viewer->getSceneData());
复制代码
这行的意思应该是将getSceneData()强制转换成MatrixTransform类型,以便进行平移变换。
我的问题还可以理解为,如果程序中有多个模型节点,怎样才能控制指定的模型节点

该用户从未签到

 楼主| 发表于 2011-2-24 07:46:24 | 显示全部楼层
  1. osg::ref_ptr<osg::MatrixTransform> mt=dynamic_cast<osg::MatrixTransform*>(viewer->getSceneData()->asGroup()->getChild(0));
复制代码
谢谢大家了,我用上面的方法成功了,多亏大家提醒

可是如果节点比较深的话,可以一直getChild()下去吗?有没有什末别的方法来替代viewer->getSceneData()->asGroup()->getChild(0)的吗?

该用户从未签到

发表于 2011-2-24 09:06:39 | 显示全部楼层
这行的意思应该是将getSceneData()强制转换成MatrixTransform类型,以便进行平移变换
不可能的,dynamic_cast是安全的转换,它不能将非MatrixTransform类型的节点转换为变换节点;这和我们不能指鹿为马是同一个道理

可是如果节点比较深的话,可以一直getChild()下去吗
可以,不过我不明白您为什么这么做。既然您已经用到了EventCallback,那么
  1. operator()(osg::Node* node,osg::NodeVisitor* nv)
复制代码
中的node就是应用这个callback的节点,为什么您不直接使用这个参数呢

该用户从未签到

 楼主| 发表于 2011-2-24 12:18:55 | 显示全部楼层
非常感谢啊,以前不知道这个是怎么回事,现在知道了,感谢ls

该用户从未签到

发表于 2013-3-4 14:43:28 | 显示全部楼层
我也是这个程序移植到OSG-CLI时卡了,原来在main()中用的viewer->setSceneData(mt.get());

这样就和class MyEventCallback:public osg::NodeCallback{}中的virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
{//
.....
osg::ref_ptr<osg::MatrixTransform> mt=dynamic_cast<osg::MatrixTransform*>(viewer->getSceneData());
对应了。


{

该用户从未签到

发表于 2013-3-4 16:16:02 | 显示全部楼层
我想问下 我给场景添加PositionAttitudeTransform类型的节点  然后我想通过viewer->getSceneData()获得这些节点 getChild返回的是node类型  我可以用dynamic_cast<osg:ositionAttitudeTransform*> 强制转换下 调用getPosition()等函数 这样有问题么?

该用户从未签到

发表于 2016-12-14 11:22:58 | 显示全部楼层
  1. 1>main.cpp(42): error C2664: “MyEventCallback::handle”: 不能将参数 1 从“osgGA::Event”转换为“const osgGA::GUIEventAdapter &”
  2. 1>          原因如下: 无法从“osgGA::Event”转换为“const osgGA::GUIEventAdapter”
  3. 1>          没有可用于执行该转换的用户定义的转换运算符,或者无法调用该运算符
复制代码


这个是什么问题?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表