本节课NeHe课程主要想我们介绍了OpenGL中的拾取(Selection)的方式来和场景中的物体进行交换,在OSG中并没有封装OpenGL中的拾取方式,而是用了更高效的一种方式来实现与场景中的模型进行求交的操作,对于OSG这样处理的原因可以参考OSG中的这个MailList: New to OSG, some questions (selection buffer, parametric curves)
在NeHe课程中本课中实现的关键在Selection函数中,它实现了OpenGL中Selection的方式,在我们OSG中进行选择求交的代码就相对比较简单:
通过osgUtil提供的几种求交器实现:本课中使用的是osgUtil::LIneSegmentIntersector,用来检测指定线段与场景图形之间的相交情况
case (osgGA::GUIEventAdapter::PUSH): { int choose = 0; osg::Node *node; osgUtil::LineSegmentIntersector::Intersections intersections; if (viewer->computeIntersections(ea,intersections)) { osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin(); osg::NodePath &nodepath = intersection.nodePath; node = (nodepath.size() >= 1) ? nodepath[nodepath.size()-1]:0; const char *name = node->getName().c_str(); choose = atoi(name); } if (!object[choose].hit) { object[choose].hit=TRUE; score+=1; kills+=1; if (kills>level*5) { miss=0; kills=0; level+=1; if (level>30) level=30; } } }
代码中的其他部分涉及大量的回调更新与位置的计算,十分繁琐,但这些内容在以前的课程中都有介绍,具体的过程读者可以参考NeHe课程中的内容进行。