• 场景交互与场景漫游-对象选取(8-2)


            对象选取示例的代码如程序清单8-11所示:

    1. /******************************************* 对象选取示例 *************************************/
    2. // 对象选取事件处理器
    3. class PickHandler :public osgGA::GUIEventHandler
    4. {
    5. public:
    6. PickHandler() :_mx(0.0f), _my(0.0f)
    7. {
    8. }
    9. ~PickHandler()
    10. {
    11. }
    12. // 事件处理函数
    13. bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
    14. {
    15. osg::ref_ptr view = dynamic_cast (&aa);
    16. if (!view)
    17. {
    18. return false;
    19. }
    20. switch (ea.getEventType())
    21. {
    22. // 鼠标按下
    23. case(osgGA::GUIEventAdapter::PUSH) :
    24. {
    25. // 更新鼠标位置
    26. _mx = ea.getX();
    27. _my = ea.getY();
    28. break;
    29. }
    30. case(osgGA::GUIEventAdapter::RELEASE) :
    31. {
    32. if (_mx == ea.getX() && _my == ea.getY())
    33. {
    34. // 执行对象选取
    35. pick(view.get(), ea.getX(), ea.getY());
    36. }
    37. break;
    38. }
    39. default:
    40. break;
    41. }
    42. return false;
    43. }
    44. // 对象选取事件处理器
    45. void pick(osg::ref_ptr view, float x, float y)
    46. {
    47. osg::ref_ptr node = new osg::Node();
    48. osg::ref_ptr parent = new osg::Group();
    49. // 创建一个线段交集检测函数
    50. osgUtil::LineSegmentIntersector::Intersections intersections;
    51. if (view->computeIntersections(x, y, intersections))
    52. {
    53. osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin();
    54. osg::NodePath &nodePath = intersection.nodePath;
    55. // 得到选择的物体
    56. node = (nodePath.size() >= 1) ? nodePath[nodePath.size() - 1] : 0;
    57. parent = (nodePath.size() >= 2) ? dynamic_cast(nodePath[nodePath.size() - 2]) : 0;
    58. }
    59. // 用一种高亮显示来显示物体已经被选中
    60. if (parent.get() && node.get())
    61. {
    62. osg::ref_ptr parentAsScribe = dynamic_cast(parent.get());
    63. if (!parentAsScribe)
    64. {
    65. // 如果对象选择列,高亮显示
    66. osg::ref_ptr scribe = new osgFX::Scribe();
    67. scribe->addChild(node.get());
    68. parent->replaceChild(node.get(), scribe.get());
    69. }
    70. else
    71. {
    72. // 乳沟没有选择到,则移除高亮显示的对象
    73. osg::Node::ParentList parentList = parentAsScribe->getParents();
    74. for (osg::Node::ParentList::iterator itr = parentList.begin(); itr != parentList.end(); ++itr)
    75. {
    76. (*itr)->replaceChild(parentAsScribe.get(), node.get());
    77. }
    78. }
    79. }
    80. }
    81. public:
    82. // 得到鼠标的位置
    83. float _mx;
    84. float _my;
    85. };
    86. /* 对象选取示例 */
    87. void pickObject_8_11(const string &strDataFolder);
    88. /* 对象选取示例 */
    89. void pickObject_8_11(const string &strDataFolder)
    90. {
    91. // 创建Viewer对象,场景浏览器
    92. osg::ref_ptr viewer = new osgViewer::Viewer();
    93. viewer->addEventHandler(new PickHandler());
    94. osg::ref_ptr traits = new osg::GraphicsContext::Traits;
    95. traits->x = 40;
    96. traits->y = 40;
    97. traits->width = 600;
    98. traits->height = 480;
    99. traits->windowDecoration = true;
    100. traits->doubleBuffer = true;
    101. traits->sharedContext = 0;
    102. osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get());
    103. osg::ref_ptr camera = new osg::Camera;
    104. camera->setGraphicsContext(gc.get());
    105. camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
    106. GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
    107. camera->setDrawBuffer(buffer);
    108. camera->setReadBuffer(buffer);
    109. viewer->addSlave(camera.get());
    110. // 创建场景租节点
    111. osg::ref_ptr root = new osg::Group();
    112. // 创建一个节点,读取牛的模型
    113. string strDataPath = strDataFolder + "cow.osg";
    114. osg::ref_ptr node = osgDB::readNodeFile(strDataPath);
    115. // 添加到场景
    116. root->addChild(node);
    117. // 优化场景数据
    118. osgUtil::Optimizer optimizer;
    119. optimizer.optimize(root);
    120. viewer->setSceneData(root);
    121. viewer->realize();
    122. viewer->run();
    123. }

            运行程序,截图如图8-24所示。

    图8-24对象选取示例截图

  • 相关阅读:
    CentOS8安装KSA服务端并设置开机自启
    PAT 1029 Median
    【附源码】计算机毕业设计JAVA宠物论坛设计网站测试视频2021
    JavaScript:实现弧度到度算法 (附完整源码)
    第一章:网络协议的奥秘
    零代码与低代码快速开发平台的区别
    zookeeper集群
    Dart学习——函数、类
    算法与数据结构【30天】集训营——时间复杂度与空间复杂度(02)
    Tendis(Redis)冷热混合存储怎么解决缓存击穿、雪崩、一致性3大难题
  • 原文地址:https://blog.csdn.net/liangfei868/article/details/134519809