查看: 2277|回复: 12

新手跪求:空间中实时画线的效果调试~

[复制链接]

该用户从未签到

发表于 2012-10-30 12:27:13 | 显示全部楼层 |阅读模式
  现在我已经能在地面上点击一个点,垂直拖拽,松开键位后形成一条直线~可是问题来了,效果确实实时画这条线的时候,线不跟鼠标拖动走(鼠标到哪里,线就垂直拉到一个高度)。。。。而且鼠标刚一Drag。。线就窜得老高!!
    handle中有关此部分的代码和问题截图已贴出,求高手们详细指点和纠正~调了好几天了,不知道怎么改了

  1.         case osgGA::GUIEventAdapter::PUSH:
  2.                 {
  3.                    if(ea.getButton() == 1)
  4.                    {
  5.                       osgUtil::LineSegmentIntersector::Intersections intersections;
  6.                       float x=ea.getX();
  7.                       float y=ea.getY();

  8.                
  9.                       if (viewer->computeIntersections(x,y,intersections))
  10.                      {
  11.                         for (osgUtil::LineSegmentIntersector::Intersections::iterator hitr=intersections.begin();hitr!=intersections.end();++hitr)
  12.                            {
  13.                         m_point=osg::Vec3( hitr->getWorldIntersectPoint());
  14.                         pointList->push_back(m_point);

  15.                         vertices->push_back(pointList->at(0));
  16.                         _current_geometry->setVertexArray(vertices);

  17.                         osg::ref_ptr <osg::Vec4Array> colors = new osg::Vec4Array;
  18.                         colors->push_back( osg::Vec4(  1.0f, 0.0f, 0.0f, 1.0f) );//红色
  19.                         _current_geometry->setColorArray(colors);
  20.                         _current_geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
  21.                         _current_geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP,0,1));

  22.                         return true;
  23.                             }
  24.                         }
  25.                         else
  26.                           {
  27.                                    std::cout<<"必须在地面上选择一个点!";
  28.                                    return false;
  29.                           }
  30.                          }
  31.                 }

  32.         case osgGA::GUIEventAdapter::DRAG:               
  33.                 {       
  34.                        vertices = dynamic_cast<osg::Vec3Array*>(_current_geometry->getVertexArray());
  35.                        osg::Matrix mtxModelView= viewer->getCamera()->getViewMatrix();
  36.                        osg::Matrix mtxProject = viewer->getCamera()->getProjectionMatrix();
  37.                    osg::Matrix mtxWindow = viewer->getCamera()->getViewport()->computeWindowMatrix();

  38.                         osg::Vec3 vecWindowPt(ea.getX(), ea.getY(), 0.0f);

  39.                         osg::Matrix mtxMVPW = mtxModelView * mtxProject * mtxWindow;
  40.                         osg::Matrix mtxInverseMVPW = osg::Matrix::inverse(mtxMVPW);

  41.                         osg::Vec3 vecWorldPt = vecWindowPt * mtxInverseMVPW;

  42.                         osg::Vec3 WorldPt(vertices->at(0).x(),vertices->at(0).y(),vecWorldPt.z());

  43.                         vertices->push_back(WorldPt);

  44.                 dynamic_cast<osg::DrawArrays*>(_current_geometry->getPrimitiveSet(0))->setCount(vertices->size());

  45.                 _current_geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP,0,2));

  46.                         _current_geometry->getPrimitiveSet(0)->dirty();
  47.                         _current_geometry->dirtyDisplayList();

  48.                         return true;
  49.                 }

  50.         case osgGA::GUIEventAdapter::RELEASE:               
  51.                 {
  52.                         _current_geometry = NULL;

  53.                         return true;
  54.                 }
复制代码
问题效果:
问题截图.jpg

该用户从未签到

发表于 2012-10-30 12:49:40 | 显示全部楼层
osg::Vec3 vecWorldPt = vecWindowPt * mtxInverseMVPW;
osg::Vec3 WorldPt(vertices->at(0).x(),vertices->at(0).y(),vecWorldPt.z());

这么设置 不是垂直的才怪

该用户从未签到

 楼主| 发表于 2012-10-30 12:59:55 | 显示全部楼层
本帖最后由 mxl12315 于 2012-10-30 13:01 编辑
liuzhiyu123 发表于 2012-10-30 12:49
osg::Vec3 vecWorldPt = vecWindowPt * mtxInverseMVPW;
osg::Vec3 WorldPt(vertices->at(0).x(),vertices ...


您来了哈~~呵呵,我是让它垂直的。。您想啊,我点完地面的点后,鼠标开始拖拽,我不想随便到处拖拽那种,而是强行指定鼠标拖拽时的那条线垂直提升,提升的高度跟鼠标实时的高度一致。。。您看我这样的效果应该怎么改呢?

PS:vecWorldPt为鼠标的世界坐标,vecWorldPt.z()为鼠标实时的高度——>实时直线的长度(垂直方向)

该用户从未签到

发表于 2012-10-30 13:22:54 | 显示全部楼层
mxl12315 发表于 2012-10-30 12:59
您来了哈~~呵呵,我是让它垂直的。。您想啊,我点完地面的点后,鼠标开始拖拽,我不想随便到处拖拽那种 ...

没看明白 您想要实现什么效果

该用户从未签到

 楼主| 发表于 2012-10-30 13:33:17 | 显示全部楼层
liuzhiyu123 发表于 2012-10-30 13:22
没看明白 您想要实现什么效果

3Dmax中,可以控制模型沿X、Y或者Z轴移动。。。我想把这个效果放进实时画线中。恩呢,就是实时画线的基础上,我强行定义它只能画垂直方向,也就是鼠标拖拽一旦响应,随着鼠标往上抬升,从地面到鼠标实时高度的过程里始终有一条线实时的生成。。。。这就是我想做的效果。。。现在问题就是:鼠标拖拽刚一响应,随便轻微抬升鼠标,顿时一根线段“一柱擎天”。。随着我不断的移动鼠标,它越来越高~
  PS:按常理,应该是我鼠标到哪个高度,那条垂直的线段应该画多长才对。。。哎

想要的效果:
1.jpg

这是另一个程序(和实时画线完全不是一个套路)但是方便您看(比如鼠标抬升到房顶同齐的高度,那么线段也就画到这个高度)

该用户从未签到

 楼主| 发表于 2012-10-30 16:20:49 | 显示全部楼层
就没有人做过楼房的水平测距和垂直测距吗?难道我这个实时画线的想法又不行了?。。。可是地面点一点,房屋上点一点。。啪!形成一条测距线,真的很难看。。。求上面的指点

该用户从未签到

 楼主| 发表于 2012-10-30 16:20:53 | 显示全部楼层
本帖最后由 mxl12315 于 2012-10-30 16:27 编辑

我鼠标轻微移动一下,立刻从地上窜起一条线段。。。。针对上面的代码部分,求各位高人指点!扣了几天了这个,就像实现个“实时”的画垂线,线的高度取决于鼠标移动时离地面的高度。。。

111.jpg

该用户从未签到

发表于 2012-10-30 17:01:34 | 显示全部楼层
其实我也想弄出这个效果!能够让线跟鼠标实时移动!但是鼠标和场景没有交点!如何知道鼠标离地面的高度呢!

该用户从未签到

 楼主| 发表于 2012-10-30 17:15:13 | 显示全部楼层
木子匕 发表于 2012-10-30 17:01
其实我也想弄出这个效果!能够让线跟鼠标实时移动!但是鼠标和场景没有交点!如何知道鼠标离地面的高度呢!

你沾上我这点代码,完后你调调试试~鼠标动线就长。。其实,我在拖拽时是通过矩阵变换,将鼠标的屏幕坐标(getX(),getY(),0.0f)转换为世界坐标下。。完后鼠标实时移动的世界坐标值就是画线的另一头儿。。地面上的点当然是起点咯~哎,可惜我这样写,总觉得稍微改改就能得到最好的效果,但一直身在局中看不清。。。几天了都。。快迷失了

该用户从未签到

发表于 2012-10-30 17:41:34 | 显示全部楼层
(getX(),getY(),0.0f) 这个点相当于你打射线与投影空间相交!近截面的那个坐标点吗!

该用户从未签到

发表于 2012-10-30 17:41:37 | 显示全部楼层
(getX(),getY(),0.0f) 这个点相当于你打射线与投影空间相交!近截面的那个坐标点吗!

该用户从未签到

 楼主| 发表于 2012-10-30 17:55:27 | 显示全部楼层
木子匕 发表于 2012-10-30 17:41
(getX(),getY(),0.0f) 这个点相当于你打射线与投影空间相交!近截面的那个坐标点吗!

应该是吧~我也是之前看论坛里的帖子,这个矩阵变换可以使得屏幕坐标转换为世界坐标~你帮忙看看,为什么我会出现这种恶心的效果截图呢?

该用户从未签到

发表于 2012-10-31 09:38:11 | 显示全部楼层
本帖最后由 木子匕 于 2012-10-31 09:47 编辑
mxl12315 发表于 2012-10-30 17:55
应该是吧~我也是之前看论坛里的帖子,这个矩阵变换可以使得屏幕坐标转换为世界坐标~你帮忙看看,为什么我 ...


osg::Vec3 vecWorldPt = vecWindowPt * mtxInverseMVPW;
osg::Vec3 WorldPt(vertices->at(0).x(),vertices ...

你这里直接采取的是鼠标屏幕坐标与投影空间近截面zf = 0相交的点的Z值!如果这条射线与你所画线的垂直面相交的话!实际的Z值可能远比这个Z值小!所以出现了串的老高的情况!你可以试试直接pushback这个点! osg::Vec3 vecWorldPt = vecWindowPt * mtxInverseMVPW; 我想应该你所画的线是随你的鼠标实施移动的!然后当你鼠标移动到房屋时可以求个交点!那时候在把Z值代替第一个点的Z值,这样画的垂线应该准确了吧!  个人想法仅供参考!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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