您的位置:首页 > 编程语言 > C语言/C++

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

2017-03-22 09:53 120 查看
之前一直使用的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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  osg C++