查看: 4338|回复: 12

请问如何使用planeintersector来点选线段?

[复制链接]

该用户从未签到

发表于 2008-6-6 10:22:16 | 显示全部楼层 |阅读模式
以前都用LineSegmentIntersector来选择物体,后来发现它似乎对LINE_STRIP不感冒,想想也觉得理所当然,线和线的交集不好检测到。

听说planeintersector可以检测到线段,但我不知道怎么使用。

请大家帮忙,最好能贴出一小段代码,让小弟学习,谢谢。

该用户从未签到

 楼主| 发表于 2008-6-6 18:47:43 | 显示全部楼层
呼唤Array版主~~

该用户从未签到

发表于 2008-6-6 22:19:39 | 显示全部楼层
呼唤Array版主~~

该用户从未签到

 楼主| 发表于 2008-6-7 11:40:05 | 显示全部楼层
Array版主看来最近很忙啊。

该用户从未签到

发表于 2008-6-7 18:14:18 | 显示全部楼层
原帖由 soda 于 2008-6-7 11:40 发表
Array版主看来最近很忙啊。


晚上我试着写一写吧,我也没写过类似的例子呢~~
最近是很忙啊,有很多要做的事,大家见谅见谅~~

该用户从未签到

 楼主| 发表于 2008-6-7 20:03:38 | 显示全部楼层
好的,谢谢锐兄了
原帖由 array 于 2008-6-7 18:14 发表


晚上我试着写一写吧,我也没写过类似的例子呢~~
最近是很忙啊,有很多要做的事,大家见谅见谅~~

该用户从未签到

发表于 2008-6-7 23:10:52 | 显示全部楼层
参照osgSim::ElevationSlice::computeIntersections的实现方式吧,今晚一直没抽出时间来写程序。注意PlaneIntersector是用于将指定平面与场景节点作交集判断的,它的输入参数有两个,第一个Plane用于指定相交平面,第二个PolyTope用于指定这个平面的边界(也是用平面表示的)。基本的实现流程是:
[code]osg::ref_ptr〈osgUtil:: PlaneIntersector〉 intersector = new osgUtil:: PlaneIntersector( plane, polytope );
osgUtil:: IntersectionVisitor intersectionVisitor( intersector.get() );
scene-〉accept( intersectionVisitor );
osgUtil:: PlaneIntersector:: Intersections& intersections = intersector-〉getIntersections();
……[/code]

该用户从未签到

 楼主| 发表于 2008-6-7 23:27:56 | 显示全部楼层
实在太感谢王锐兄了,明天白天我试一下。
有什么不明了的地方可能还要请教哦

[ 本帖最后由 soda 于 2008-6-7 23:33 编辑 ]

该用户从未签到

 楼主| 发表于 2008-6-8 15:38:56 | 显示全部楼层
原帖由 array 于 2008-6-7 23:10 发表
参照osgSim::ElevationSlice::computeIntersections的实现方式吧,今晚一直没抽出时间来写程序。注意PlaneIntersector是用于将指定平面与场景节点作交集判断的,它的输入参数有两个,第一个Plane用于指定相交平面,第 ...

我按照Array的意见参照osgSim::ElevationSlice::computeIntersections进行了平面与场景节点的交集判断。
我的场景中有一个Line Strip,共四个点,从起点到终点依次为:(0,0,0) (10,0,0) (10,10,0) (10,10,10)
结果没有成功,请Array版有空的话,帮小弟我检查一下。我搞不太懂plane和boundingPolytope是如何指定平面的。

下面是我写的代码:
  1. void PickHandler::pick(osgViewer::Viewer* viewer, const osgGA::GUIEventAdapter& ea)
  2. {
  3.         //osgUtil::PlaneIntersector::Intersections intersections;
  4.         osg::Plane plane;
  5.         osg::Polytope polytope;
  6.         plane.set(osg::Vec3(1,1,0), osg::Vec3(5,0,0));

  7.         osg::Vec3 startPlaneNormal = osg::Vec3(1,1,0);
  8.         startPlaneNormal.normalize();
  9.         polytope.add(osg::Plane(startPlaneNormal,osg::Vec3(4,0,0)));

  10.         osg::Vec3 endPlaneNormal = osg::Vec3(1,1,0);
  11.         endPlaneNormal.normalize();
  12.         polytope.add(osg::Plane(endPlaneNormal,osg::Vec3(6,0,0)));

  13.         osg::ref_ptr<osgUtil::PlaneIntersector> planepick = new osgUtil::PlaneIntersector(plane,polytope);
  14.         osgUtil::IntersectionVisitor iv(planepick.get());
  15.         //iv.setIntersector(planepick.get());
  16.         viewer->getCamera()->accept(iv);
  17.         osgUtil::PlaneIntersector::Intersections& ints = planepick->getIntersections();
  18.         if (!ints.empty())
  19.         {
  20.                 cout<<"Plane Intersector OK"<<endl;
  21.         }
  22. }
复制代码
cout<<"lane Intersector OK"<<endl;这名话始终没有被执行。

[ 本帖最后由 soda 于 2008-6-8 15:43 编辑 ]

该用户从未签到

发表于 2008-6-8 22:14:14 | 显示全部楼层
献上一段短小的代码吧~~我自己写的
中间有一段注释,加入以后可以设定平面在X方向的边界在(-1,1)之间,从而改变了交集判断的范围。

  1. osg::ref_ptr〈osg::Node〉 mynode = osgDB::readNodeFile( "cow.osg" );
  2. osg::ref_ptr〈osg::Group〉 root = new osg::Group;
  3. root-〉addChild( mynode.get() );

  4. osg::Plane plane( osg::Vec3(0,1,0), osg::Vec3(0,0,0) );
  5. osg::Polytope polytope;
  6. /*polytope.add( osg::Plane(osg::Vec3(1,0,0), osg::Vec3(-1,0,0)) );
  7. polytope.add( osg::Plane(osg::Vec3(-1,0,0), osg::Vec3(1,0,0)) );*/
  8. osg::ref_ptr〈osgUtil::PlaneIntersector〉 intersector = new osgUtil::PlaneIntersector( plane, polytope );

  9. osgUtil::IntersectionVisitor iv( intersector.get() );
  10. root-〉accept( iv );

  11. if ( intersector-〉containsIntersections() )
  12. {
  13.         osgUtil::PlaneIntersector::Intersections& intersections = intersector-〉getIntersections();
  14.         osgUtil::PlaneIntersector::Intersections::iterator itr;
  15.         for ( itr = intersections.begin(); itr != intersections.end(); ++itr )
  16.         {
  17.                 for ( unsigned int i=0; i〈(*itr).polyline.size(); ++i )
  18.                         std::cout 〈〈 " X" 〈〈 (*itr).polyline[i].x()
  19.                                   〈〈 " Y" 〈〈 (*itr).polyline[i].y()
  20.                                   〈〈 " Z" 〈〈 (*itr).polyline[i].z() 〈〈 std::endl;
  21.         }
  22. }
复制代码

该用户从未签到

 楼主| 发表于 2008-6-8 22:34:57 | 显示全部楼层
  1. polytope.add( osg::Plane(osg::Vec3(1,0,0), osg::Vec3(-1,0,0)) );
  2. polytope.add( osg::Plane(osg::Vec3(-1,0,0), osg::Vec3(1,0,0)) );
复制代码
十分感谢Array!!!
不过我有一事不甚明了,还请麻烦Array解释一下
为什么上面这两个边界的法线需要相反呢,如果不相反的话,是不是就不行?

[ 本帖最后由 soda 于 2008-6-9 01:15 编辑 ]

该用户从未签到

发表于 2008-6-9 09:12:14 | 显示全部楼层
我想是的,因为边界平面的法线方向不同,它所包围起来的区域也可能不同
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表