您的位置:首页 > 其它

osg选取

2010-07-11 22:38 295 查看
void PickHandler::pick(osgViewer::View*
view, const osgGA::GUIEventAdapter&
ea)

{

osgUtil::LineSegmentIntersector::Intersections intersections;//求集交互器

float x = ea.getX();

float y = ea.getY();//传入事件的x,y坐标

if (view->computeIntersections(x,y,intersections))//进入computeIntersections()求交集

{

for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr =
intersections.begin();

hitr != intersections.end();

++hitr)

{

}

}

}

先传入x,y坐标,然后进入computeIntersections(x,y,intersections))求交集,在此函数加断点后进入,分析以下函数

bool View::computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,
osg::Node::NodeMask traversalMask)

{

if (!_camera.valid()) return false;

float local_x, local_y = 0.0;

const osg::Camera* camera
= getCameraContainingPosition(x, y, local_x, local_y);

if (!camera) camera = _camera.get();

osgUtil::LineSegmentIntersector::CoordinateFrame cf
= camera->getViewport()
? osgUtil::Intersector::WINDOW : osgUtil::Intersector::PROJECTION;

osg::ref_ptr<
osgUtil::LineSegmentIntersector
> picker = new
osgUtil::LineSegmentIntersector(cf, local_x, local_y);

osgUtil::IntersectionVisitor
iv(picker.get());//用访问者设计模式对各个节点进行访问,函数内部不断的调用各个节点相应的accepte()函数,对节点进行访问,并把节点压入_NodePath,最终对Geode用accept()访问。

iv.setTraversalMask(traversalMask);

const_cast<osg::Camera*>(camera)->accept(iv);//

if (picker->containsIntersections())

{

intersections = picker->getIntersections();

return true;

}

else

{

intersections.clear();

return false;

}

}

void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor&
iv, osg::Drawable* drawable)

{

osg::Vec3d s(_start), e(_end); //最终对某个geode的Drawable循环调用此函数

if ( !intersectAndClip(
s, e, drawable->getBound()
) ) return;

if (iv.getDoDummyTraversal()) return;

osg::KdTree* kdTree = iv.getUseKdTreeWhenAvailable() ? dynamic_cast<osg::KdTree*>(drawable->getShape()) : 0;

if (kdTree)

{

osg::KdTree::LineSegmentIntersections intersections;

intersections.reserve(4);

if (kdTree->intersect(s,e,intersections))

{

// osg::notify(osg::NOTICE)<<"Got KdTree
intersections"<<std::endl;

for(osg::KdTree::LineSegmentIntersections::iterator itr = intersections.begin();

itr != intersections.end();

++itr)

{

osg::KdTree::LineSegmentIntersection& lsi = *(itr);

// get ratio in s,e range

double ratio = lsi.ratio;

// remap ratio into _start, _end range

double remap_ratio
= ((s-_start).length() + ratio
* (e-s).length() )/(_end-_start).length();

Intersection hit;

hit.ratio = remap_ratio;

hit.matrix = iv.getModelMatrix();

hit.nodePath = iv.getNodePath();

hit.drawable = drawable;

hit.primitiveIndex
= lsi.primitiveIndex;

hit.localIntersectionPoint
= _start*(1.0-remap_ratio)
+ _end*remap_ratio;

// osg::notify(osg::NOTICE)<<"KdTree:
ratio="<<hit.ratio<<"
("<<hit.localIntersectionPoint<<")"<<std::endl;

hit.localIntersectionNormal
= lsi.intersectionNormal;

hit.indexList.reserve(3);

hit.ratioList.reserve(3);

if (lsi.r0!=0.0f)

{

hit.indexList.push_back(lsi.p0);

hit.ratioList.push_back(lsi.r0);

}

if (lsi.r1!=0.0f)

{

hit.indexList.push_back(lsi.p1);

hit.ratioList.push_back(lsi.r1);

}

if (lsi.r2!=0.0f)

{

hit.indexList.push_back(lsi.p2);

hit.ratioList.push_back(lsi.r2);

}

insertIntersection(hit);

}

}

return;

}

osg::TriangleFunctor<LineSegmentIntersectorUtils::TriangleIntersector> ti;//定义一个三角形求交器

ti.set(s,e);

drawable->accept(ti);//用三角形求交器对drawable进行访问

if (ti._hit)//如果和drawable有交点

{

osg::Geometry* geometry = drawable->asGeometry();

for(LineSegmentIntersectorUtils::TriangleIntersections::iterator
thitr = ti._intersections.begin();

thitr != ti._intersections.end();

++thitr)

{

// get ratio in s,e range

double ratio = thitr->first;

// remap ratio into _start, _end range

double remap_ratio
= ((s-_start).length() + ratio
* (e-s).length() )/(_end-_start).length();

LineSegmentIntersectorUtils::TriangleIntersection& triHit
= thitr->second;

Intersection hit;

hit.ratio = remap_ratio;

hit.matrix = iv.getModelMatrix();

hit.nodePath = iv.getNodePath();

hit.drawable = drawable;

hit.primitiveIndex
= triHit._index;

hit.localIntersectionPoint
= _start*(1.0-remap_ratio)
+ _end*remap_ratio;

// osg::notify(osg::NOTICE)<<"Conventional:
ratio="<<hit.ratio<<"
("<<hit.localIntersectionPoint<<")"<<std::endl;

hit.localIntersectionNormal
= triHit._normal;

if (geometry)

{

osg::Vec3Array*
vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());

if (vertices)

{

osg::Vec3*
first = &(vertices->front());

if (triHit._v1)

{

hit.indexList.push_back(triHit._v1-first);

hit.ratioList.push_back(triHit._r1);

}

if (triHit._v2)

{

hit.indexList.push_back(triHit._v2-first);

hit.ratioList.push_back(triHit._r2);

}

if (triHit._v3)

{

hit.indexList.push_back(triHit._v3-first);

hit.ratioList.push_back(triHit._r3);

}

}

}

insertIntersection(hit);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: