对象选取示例的代码如程序清单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<osgViewer::View> view = dynamic_cast<osgViewer::View*> (&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<osgViewer::View> view, float x, float y){osg::ref_ptr<osg::Node> node = new osg::Node();osg::ref_ptr<osg::Group> 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<osg::Group*>(nodePath[nodePath.size() - 2]) : 0;}// 用一种高亮显示来显示物体已经被选中if (parent.get() && node.get()){osg::ref_ptr<osgFX::Scribe> parentAsScribe = dynamic_cast<osgFX::Scribe*>(parent.get());if (!parentAsScribe){// 如果对象选择列,高亮显示osg::ref_ptr<osgFX::Scribe> 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<osgViewer::Viewer> viewer = new osgViewer::Viewer();viewer->addEventHandler(new PickHandler());osg::ref_ptr<osg::GraphicsContext::Traits> 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<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());osg::ref_ptr<osg::Camera> 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<osg::Group> root = new osg::Group();// 创建一个节点,读取牛的模型string strDataPath = strDataFolder + "cow.osg";osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(strDataPath);// 添加到场景root->addChild(node);// 优化场景数据osgUtil::Optimizer optimizer;optimizer.optimize(root);viewer->setSceneData(root);viewer->realize();viewer->run();
}
运行程序,截图如图8-24所示。
图8-24对象选取示例截图