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);
}
}
}
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);
}
}
}
相关文章推荐
- OSG——选取和拖拽
- OSG 对线或者点组成的模型选取
- Archie OSG Step By Step⑥ 对象选取
- OSG学习笔记18 - 关于物体绕指定点旋转的问题(非坐标轴原点)
- 机器学习测试集选取常用方法-《机器学习》周志华
- 初学OSG之节点回调的处理过程
- OSG新手使用过程中可能遇到的坑
- iOS 自定义相册和选取 AssetsLibrary 和 Photos(写的不错 一篇足以!感谢)
- OSG学习笔记22——设置物体透明,再恢复
- 四元数在OSG中的应用分析
- 博为峰Java技术文章 ——JavaSE Swing 文件选取器JFileChooser(2)
- #OSG+VS#第七周 关于osgearth中shadowing的理解
- android 调用系统相册选取照片或者打开相机拍照获取图片,返回时回到手机桌面,然后才会跳转到当前activity
- android6.0以后调用相机和选取图片
- html中选取图片并预览
- [原][osg][gdal]两种方式修改tiff高程
- UVA 1151 Buy or Build 最小生成树+二进制选取子集
- android 调用系统相册选取照片或者打开相机拍照获取图片,返回时回到手机桌面,然后才会跳转到当前activity
- 【JavaScript】基于H5 canvas实现的画板绘图工具(类似你画我猜)——整合颜色选取、保存图片到本地功能
- OSG中pick函数的使用