对象选取示例的代码如程序清单8-11所示:
- /******************************************* 对象选取示例 *************************************/
- // 对象选取事件处理器
- class PickHandler :public osgGA::GUIEventHandler
- {
- public:
- PickHandler() :_mx(0.0f), _my(0.0f)
- {
-
- }
- ~PickHandler()
- {
-
- }
-
- // 事件处理函数
- bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
- {
- osg::ref_ptr
view = dynamic_cast (&aa); - if (!view)
- {
- return false;
- }
-
- switch (ea.getEventType())
- {
- // 鼠标按下
- case(osgGA::GUIEventAdapter::PUSH) :
- {
- // 更新鼠标位置
- _mx = ea.getX();
- _my = ea.getY();
- break;
- }
- case(osgGA::GUIEventAdapter::RELEASE) :
- {
- if (_mx == ea.getX() && _my == ea.getY())
- {
- // 执行对象选取
- pick(view.get(), ea.getX(), ea.getY());
- }
- break;
- }
- default:
- break;
- }
-
- return false;
- }
-
- // 对象选取事件处理器
- void pick(osg::ref_ptr
view, float x, float y) - {
- osg::ref_ptr
node = new osg::Node(); - osg::ref_ptr
parent = new osg::Group(); -
- // 创建一个线段交集检测函数
- osgUtil::LineSegmentIntersector::Intersections intersections;
- if (view->computeIntersections(x, y, intersections))
- {
- osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin();
- osg::NodePath &nodePath = intersection.nodePath;
-
- // 得到选择的物体
- node = (nodePath.size() >= 1) ? nodePath[nodePath.size() - 1] : 0;
- parent = (nodePath.size() >= 2) ? dynamic_cast
(nodePath[nodePath.size() - 2]) : 0; - }
-
- // 用一种高亮显示来显示物体已经被选中
- if (parent.get() && node.get())
- {
- osg::ref_ptr
parentAsScribe = dynamic_cast(parent.get()); - if (!parentAsScribe)
- {
- // 如果对象选择列,高亮显示
- osg::ref_ptr
scribe = new osgFX::Scribe(); - scribe->addChild(node.get());
- parent->replaceChild(node.get(), scribe.get());
- }
- else
- {
- // 乳沟没有选择到,则移除高亮显示的对象
- osg::Node::ParentList parentList = parentAsScribe->getParents();
- for (osg::Node::ParentList::iterator itr = parentList.begin(); itr != parentList.end(); ++itr)
- {
- (*itr)->replaceChild(parentAsScribe.get(), node.get());
- }
- }
- }
- }
- public:
- // 得到鼠标的位置
- float _mx;
- float _my;
- };
-
- /* 对象选取示例 */
- void pickObject_8_11(const string &strDataFolder);
-
- /* 对象选取示例 */
- void pickObject_8_11(const string &strDataFolder)
- {
- // 创建Viewer对象,场景浏览器
- osg::ref_ptr
viewer = new osgViewer::Viewer(); - viewer->addEventHandler(new PickHandler());
-
- osg::ref_ptr
traits = new osg::GraphicsContext::Traits; - traits->x = 40;
- traits->y = 40;
- traits->width = 600;
- traits->height = 480;
- traits->windowDecoration = true;
- traits->doubleBuffer = true;
- traits->sharedContext = 0;
-
- osg::ref_ptr
gc = osg::GraphicsContext::createGraphicsContext(traits.get()); -
- osg::ref_ptr
camera = new osg::Camera; - camera->setGraphicsContext(gc.get());
- camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
- GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
- camera->setDrawBuffer(buffer);
- camera->setReadBuffer(buffer);
-
- viewer->addSlave(camera.get());
-
- // 创建场景租节点
- osg::ref_ptr
root = new osg::Group(); -
- // 创建一个节点,读取牛的模型
- string strDataPath = strDataFolder + "cow.osg";
- osg::ref_ptr
node = osgDB::readNodeFile(strDataPath); -
- // 添加到场景
- root->addChild(node);
-
- // 优化场景数据
- osgUtil::Optimizer optimizer;
- optimizer.optimize(root);
- viewer->setSceneData(root);
- viewer->realize();
- viewer->run();
- }
运行程序,截图如图8-24所示。

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