查看: 7590|回复: 9

osg场景中的物体如何点选与框选

[复制链接]

该用户从未签到

发表于 2011-9-19 09:44:12 | 显示全部楼层 |阅读模式
小弟最近要实现在场景中点选物体,框选物体。通过鼠标位置点选,框选多个物体,例如魔兽争霸中 点选 框选小兵
请问有没有实现过的,指点一下。

该用户从未签到

发表于 2011-9-21 08:52:03 | 显示全部楼层
当然实现过,但是不知道要怎样“指点”您。简单来说就是通过IntersectionVisitor得到交点和被选对象,绘制框线的话可以用一个单独的HUD相机来完成

该用户从未签到

发表于 2011-11-8 13:25:08 | 显示全部楼层
本帖最后由 garyliyong 于 2011-11-8 13:26 编辑
array 发表于 2011-9-21 08:52
当然实现过,但是不知道要怎样“指点”您。简单来说就是通过IntersectionVisitor得到交点和被选对象,绘制框 ...


array大侠,我框选是实现了,关键是框选的那个框子,我按照你的提示添加了一个HUD,但是在DrawThreadPerContext下回出现线程冲突,后来我在UpdateCallback中动态添加HUD,也会出现线程冲突,不知道你是如何解决的?另外,你已经实现了框选的框子,不知道您是如何实现的?能将你的代码简单贴出来吗?谢谢 我的代码你能帮我看看吗?
  1. class CSelectWindow:public osgGA:GUIEventHandler
  2. {
  3. public:
  4.     virtual handler(..)
  5.     {
  6.        ..........(Drag)
  7.        获取HUD适口大小
  8.     }
  9. }

  10. class SelectWindowCallback:public osg::NodeCallback
  11. {
  12.    void operator()
  13.    {
  14.        根据视口大小创建HUD
  15.        pCameraHUD = new osg::Camera;

  16.        m_pView->addSlave(pCameraHUD);

  17.        m_pView->getSceneData(pCameraHUD);
  18.    }
  19. }

  20. osg::ref_ptr<osg::Geoup> pParent = NULL;
  21. pParent = new osg::Group;
  22. pParent->setUpdateCallback(new SelectWindowCallback());
复制代码

该用户从未签到

发表于 2011-11-10 10:38:01 | 显示全部楼层
  1. void operator()
  2.    void operator()
  3.    {
  4.        根据视口大小创建HUD
  5.        pCameraHUD = new osg::Camera;

  6.        m_pView->addSlave(pCameraHUD);

  7.        m_pView->getSceneData(pCameraHUD);
  8.    }
复制代码
这里您想干什么?这种行为貌似无异于自杀。。。
HUD窗口在一开始创建就好了,然后在其中构建矩形框几何体就好了,我不知道您想要实现的逻辑是怎样的

该用户从未签到

发表于 2012-5-27 11:43:43 | 显示全部楼层
garyliyong 发表于 2011-11-8 13:25
array大侠,我框选是实现了,关键是框选的那个框子,我按照你的提示添加了一个HUD,但是在DrawThreadPe ...

大侠,能把代码发给小弟看看吗?liaojinmin0413@126.com

该用户从未签到

发表于 2012-10-17 14:56:21 | 显示全部楼层
楼主  同求框选详细代码 suxing304@126.com

该用户从未签到

发表于 2012-10-18 08:01:41 | 显示全部楼层
本帖最后由 liuzhiyu123 于 2012-10-18 08:05 编辑
suxing304 发表于 2012-10-17 14:56
楼主  同求框选详细代码


昨天利用下班前的10分钟完成的一个小demo,还有优化的地方,只做一个示意,仅供参考
  1. class BoxPicker : public osgGA::GUIEventHandler
  2. {
  3. public:
  4.         BoxPicker()
  5.         {
  6.                 x=0.0f;
  7.                 y=0.0f;
  8.                 OK= false;
  9.         }

  10.         osg::observer_ptr<osg::Geometry> geometry;

  11.         virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
  12.         {

  13.                 bool doit = false;

  14.                 osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
  15.                 if (!viewer)
  16.                 {
  17.                         return false;
  18.                 }

  19.                 if(ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
  20.                 {
  21.                         x = ea.getXnormalized();
  22.                         y = ea.getYnormalized();
  23.                        
  24.                         x_pick = ea.getX();
  25.                         y_pick = ea.getY();
  26.                        
  27.                         OK = true;

  28.                 }

  29.                 if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG)
  30.                 {
  31.                         if (OK)
  32.                         {
  33.                                 float end_x = ea.getXnormalized();
  34.                                 float end_y = ea.getYnormalized();

  35.                                 if (geometry.valid())
  36.                                 {
  37.                                         osg::Vec3Array* vertex = new osg::Vec3Array(4);
  38.                                         (*vertex)[0]=osg::Vec3(x,0,y);
  39.                                         (*vertex)[1]=osg::Vec3(x,0,end_y);
  40.                                         (*vertex)[2]=osg::Vec3(end_x,0,end_y);
  41.                                         (*vertex)[3]=osg::Vec3(end_x,0,y);
  42.                                         geometry->setVertexArray(vertex);
  43.                                         geometry->dirtyDisplayList();

  44.                                         //std::cout<<x<<" "<<y<<" "<<end_x<<" "<<end_y<<std::endl;
  45.                                 }
  46.                                 if (ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT)
  47.                                 {
  48.                                         doit = true;
  49.                                 }
  50.                         }
  51.                 }

  52.                 if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
  53.                 {
  54.                         OK=false;

  55.                         float pick_x = ea.getX();
  56.                         float pick_y = ea.getY();

  57.                         float xMin,xMax,yMin,yMax;
  58.                        
  59.                         xMin=osg::minimum(x_pick, pick_x);
  60.                         xMax=osg::maximum(x_pick, pick_x);
  61.                         yMin=osg::minimum(y_pick, pick_y);
  62.                         yMax=osg::maximum(y_pick, pick_y);

  63.                         osg::ref_ptr<osgUtil::PolytopeIntersector> intersector =
  64.                                 new osgUtil::PolytopeIntersector(osgUtil::Intersector::WINDOW, xMin, yMin, xMax, yMax);

  65.                         osgUtil::IntersectionVisitor iv( intersector.get() );
  66.                         viewer->getCamera()->accept( iv );
  67.                        
  68.                         if ( intersector->containsIntersections() )
  69.                         {
  70.                                 std::cout<<"OK"<<std::endl;
  71.                                 /*
  72.                                 for(osgUtil::PolytopeIntersector::Intersections::iterator
  73.                                         hitr = intersector->getIntersections().begin();
  74.                                         hitr != intersector->getIntersections().end();
  75.                                         ++hitr)
  76.                                 {
  77.                                        
  78.                                         osg::NodePath np = hitr->nodePath;
  79.                                         for (osg::NodePath::iterator itr = np.begin(); itr != np.end(); itr++)
  80.                                         {
  81.                                                 if (!(*itr)->getName().empty())
  82.                                                 {
  83.                                                         std::cout<<(*itr)->getName()<<std::endl;
  84.                                                 }
  85.                                         }
  86.                                        
  87.                                         break;
  88.                                 }
  89.                                 */
  90.                         }

  91.                         if (geometry.valid())
  92.                         {
  93.                                 osg::Vec3Array* vertex = new osg::Vec3Array(4);
  94.                                 (*vertex)[0]=osg::Vec3(0,0,0);
  95.                                 (*vertex)[1]=osg::Vec3(0,0,0);
  96.                                 (*vertex)[2]=osg::Vec3(0,0,0);
  97.                                 (*vertex)[3]=osg::Vec3(0,0,0);
  98.                                 geometry->setVertexArray(vertex);
  99.                                 geometry->dirtyDisplayList();
  100.                         }
  101.                 }
  102.                
  103.                 return doit;
  104.         }

  105.         float x,y;
  106.         float x_pick, y_pick;

  107.         bool OK;
  108. };

  109. int _tmain(int argc, char* argv[])
  110. {
  111.         osg::ArgumentParser argument(&argc,argv);

  112.         osg::Node* model1 = osgDB::readNodeFile("axes.osgt");
  113.         model1->setName("COW1");
  114.         osg::MatrixTransform* mt1 = new osg::MatrixTransform;
  115.         mt1->setMatrix(osg::Matrix::translate(osg::Vec3(10,0,0)));
  116.         mt1->addChild(model1);

  117.         osg::Node* model2 = osgDB::readNodeFile("axes.osgt");
  118.         model2->setName("COW2");
  119.        
  120.         osgViewer::Viewer viewer;

  121.         osg::ref_ptr<BoxPicker> picker = new BoxPicker;
  122.         viewer.addEventHandler(picker.get());

  123.         osg::ref_ptr<osg::Geometry> geo = new osg::Geometry;
  124.         geo->setDataVariance(osg::Object::DYNAMIC);
  125.         geo->setUseDisplayList(false);
  126.         osg::Vec3Array* vertex = new osg::Vec3Array(4);
  127.         (*vertex)[0] = osg::Vec3(-0.5, 0.0, -0.5);
  128.         (*vertex)[1] = osg::Vec3(0.5, 0.0, -0.5);
  129.         (*vertex)[2] = osg::Vec3(0.5, 0.0, 0.5);
  130.         (*vertex)[3] = osg::Vec3(-0.5, 0.0, 0.5);
  131.         geo->setVertexArray(vertex);

  132.         osg::Vec4Array* colors = new osg::Vec4Array;
  133.         colors->push_back(osg::Vec4(1.0,1.0,0.0,1.0));
  134.         geo->setColorArray(colors);
  135.         geo->setColorBinding(osg::Geometry::BIND_OVERALL);

  136.         osg::Vec3Array* normal = new osg::Vec3Array(1);
  137.         (*normal)[0]=osg::Vec3(0,-1,0);
  138.         geo->setNormalArray(normal);
  139.         geo->setNormalBinding(osg::Geometry::BIND_OVERALL);

  140.         osg::ref_ptr<osg::DrawArrays> pri = new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,4);

  141.         geo->addPrimitiveSet(pri.get());

  142.         osg::ref_ptr<osg::PolygonMode> polyMode = new osg::PolygonMode;
  143.         polyMode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
  144.         geo->getOrCreateStateSet()->setAttributeAndModes(polyMode.get());
  145.         geo->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
  146.         picker->geometry = geo;

  147.         osg::Camera* camera = new osg::Camera;
  148.         camera->setProjectionMatrix(osg::Matrix::ortho2D(-1.0,1.0,-1.0,1.0));
  149.         camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
  150.         camera->setViewMatrixAsLookAt(osg::Vec3(0,-1,0), osg::Vec3(0,0,0), osg::Vec3(0,0,1));
  151.         camera->setClearMask(GL_DEPTH_BUFFER_BIT);
  152.         camera->setRenderOrder(osg::Camera::POST_RENDER);
  153.         camera->setAllowEventFocus(false);
  154.        
  155.         osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  156.         geode->addDrawable(geo.get());

  157.         camera->addChild(geode.get());
  158.         osg::ref_ptr<osg::Group> root = new osg::Group;
  159.         root->addChild(camera);
  160.         root->addChild(mt1);
  161.         root->addChild(model2);

  162.         viewer.setSceneData(root.get());
  163.         viewer.setCameraManipulator(new osgGA::OrbitManipulator);
  164.         viewer.run();
  165.         return 0;
  166. }
复制代码


123.png

该用户从未签到

发表于 2012-10-18 17:17:37 | 显示全部楼层
liuzhiyu123 发表于 2012-10-18 08:01
昨天利用下班前的10分钟完成的一个小demo,还有优化的地方,只做一个示意,仅供参考

真实太感谢了!!! 学习学习!

该用户从未签到

发表于 2012-10-19 14:57:16 | 显示全部楼层
liuzhiyu123 发表于 2012-10-18 08:01
昨天利用下班前的10分钟完成的一个小demo,还有优化的地方,只做一个示意,仅供参考

按照你的

osg::ref_ptr< osgUtil:olytopeIntersector > intersector = new osgUtil::PolytopeIntersector( osgUtil::Intersector::WINDOW, xMin, yMin, xMax, yMax);

osgUtil::IntersectionVisitor iv( intersector.get() );

多面体球交,没有得到正确的结果,请问这是怎么回事?

我用的是vs的winform窗体控件加载模型。

bool b = intersector->containsIntersections();

返回值很多时候是false

该用户从未签到

发表于 2012-10-19 15:01:50 | 显示全部楼层
看一下您构造的xMin, yMin, xMax, yMax 是不是正确吧 WinForm没有用过不太清楚
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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