OSG学习笔记19——再看pick点选物体

来源:互联网 发布:win10桌面软件不见了 编辑:程序博客网 时间:2024/05/22 14:25

之前一直使用的pick方法就是将第一个点选到的节点保存下来,如果场景中只有一个物体,当然是没有问题的。当场景中出现多个物体,并且每个物体设置了标签,是可以被修改还是不能被修改,当两个物体重合的时候就不能得到正确的结果。

正确的做法是:用迭代器遍历所有获取到的节点并再遍历nodePath,找到需要的节点,并根据标签判断其是否可以被选中来执行操作。

这里我对物体标签设置的方法应该是不够科学的,我用了一个全局变量,一个map来保存了模型的名字和一个布尔值

extern ModelIndex modelIndex;
主函数中是

std::list<ModelManage> modelList;model1->setName("aorta");modelIndex[model1->getName()] = true;
其中 ModelIndex是 std::map < std::string, bool >的别名,每添加一个模型,就给map中以模型节点为名字,bool为值向map中新增节点。

暂时想不到更好的方法。如果你们有好一点的想法,请务必告诉我!

下面贴出pick的实现。其实和之前的没有多大的变化,详细介绍见 <OSG学习笔记16>

void PQEventHandler::pick(double x, double y){osgUtil::LineSegmentIntersector::Intersections intersections;if (viewer->computeIntersections(x, y, intersections)){std::cout << " trying to pick sth" << "x: " << x << " y: " << y << std::endl;osgUtil::LineSegmentIntersector::Intersections::iterator hitr;for (hitr = intersections.begin(); hitr != intersections.end(); ++hitr){if (!hitr->nodePath.empty() ){const osg::NodePath& np = hitr->nodePath;for (int i = np.size() - 1; i >= 0;--i){osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(np[i]);if (mt != NULL){std::cout << mt->getName() << std::endl;ModelIndex::iterator miitr;miitr = modelIndex.find(mt->getName());if (miitr == modelIndex.end()){continue;}else{if (modelIndex[mt->getName()]){PickObject = true;picked = mt;rotateCenter =hitr->getWorldIntersectPoint();}else{continue;}}}}}}}else{PickObject = false;picked = NULL;}}


1 0