查看: 2314|回复: 5

求助: 旋转视角后平面消失问题

[复制链接]

该用户从未签到

发表于 2012-8-24 09:40:14 | 显示全部楼层 |阅读模式
本帖最后由 xulin_2005 于 2012-8-24 10:17 编辑

旋转视角后平面消失问题

背景:
   我在写一个网格区域随鼠标高亮的功能。即,鼠标在网格上移动,相应的网格区域会高亮显示。

问题描述:
    当放大视角时,高亮区域的平面会消失,然后转动视角后又会出现。具体见图:

其他线索:
    我以为是法线角度设置的问题,因为一开始绘制的平面,未经过鼠标移动后放大视角不会出现这个问题,具体见图:

截图:

随鼠标移动的高亮区域
网格高亮1.png 网格高亮2.png 网格高亮3.png
初始化时画的高亮平面
网格高亮4.png 网格高亮5.png
相关代码:

  1. // 更新高亮区域
  2. void GridGround::UpdateHL()
  3. {
  4.         if ( !m_gmQuaz || !m_bNeedUpdate )
  5.                 return;

  6.         osg::Vec3Array * vertices = dynamic_cast<osg::Vec3Array *> ( m_gmQuaz->getVertexArray() );

  7.         if ( vertices && (vertices->size() == 4) )
  8.         {
  9.                 vertices->at(0).set(g_center + g_dx*(float)m_x + g_dy*(float)m_y);
  10.                 vertices->at(1).set(g_center + g_dx*(float)(m_x+m_w) + g_dy*(float)m_y);
  11.                 vertices->at(2).set(g_center + g_dx*(float)(m_x+m_w) + g_dy*(float)(m_y+m_l));
  12.                 vertices->at(3).set(g_center + g_dx*(float)m_x + g_dy*(float)(m_y+m_l));
  13.         }

  14.        // 法线重置
  15.        osg::Vec3Array* normals = new osg::Vec3Array;
  16.        normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
  17.        m_gmQuaz->setNormalArray(normals);
  18.        m_gmQuaz->setNormalBinding(osg::Geometry::BIND_OVERALL);

  19.         // 准备更新
  20.         vertices->dirty();
  21.         m_bNeedUpdate = false;
  22. }
复制代码


  1. // 绘制网格区域
  2. osg::Node* GridGround::create(const osg::Vec3& center,float radius, int x = 0, int y = 0, int w = 1, int l = 1, int g_iNumTiles = 10)
  3. {
  4. // 画网格线
  5. ...

  6. // 绘制高亮区域
  7. //m_gmQuaz = new osg::Geometry;
  8. m_gmQuaz->setName("HeightLight");

  9. // 绘制矩形区域
  10. osg::Vec3Array* crdsQuaz = new osg::Vec3Array;
  11. crdsQuaz->push_back(g_v000 + g_dx*(float)x + g_dy*(float)y);
  12. crdsQuaz->push_back(g_v000 + g_dx*(float)(x+w) + g_dy*(float)y);
  13. crdsQuaz->push_back(g_v000 + g_dx*(float)(x+w) + g_dy*(float)(y+l));
  14. crdsQuaz->push_back(g_v000 + g_dx*(float)x + g_dy*(float)(y+l));

  15. m_gmQuaz->setVertexArray(crdsQuaz);

  16. m_gmQuaz->setColorArray(colors);
  17. m_gmQuaz->setColorBinding(osg::Geometry::BIND_OVERALL);

  18. m_gmQuaz->setNormalArray(normals);
  19. m_gmQuaz->setNormalBinding(osg::Geometry::BIND_OVERALL);

  20. m_gmQuaz->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,crdsQuaz->size()));

  21. m_gmQuaz->setUseDisplayList( false );
  22. m_gmQuaz->setUseVertexBufferObjects( true );

  23. osg::Geode* geode = new osg::Geode;

  24. geode->addDrawable(m_gmGrid);

  25. // 贴地表图
  26. ...

  27. return geode;
  28. }
复制代码
  1. case (osgGA::GUIEventAdapter::MOVE): // 鼠标移动事件处理
  2. {
  3.       bool bRet = getPosition(m_Viewer, ea, position);

  4.       if ( bRet )
  5.      {
  6.             m_pGridGround->Caculate(position, 1, 1);
  7.             m_pGridGround->UpdateHL();
  8.      }
  9. }
复制代码

该用户从未签到

发表于 2012-8-24 10:33:41 | 显示全部楼层
这应该由三部分组成:网格线、网格面、小网格面
考虑可能是叠加时,视角扩大,小网格面被大网格面遮挡了,可将小网格面提升一点距离后再测试观察

该用户从未签到

 楼主| 发表于 2012-8-24 16:58:25 | 显示全部楼层
本帖最后由 xulin_2005 于 2012-8-24 17:02 编辑

谢谢,的确是这个问题。
另外,再引申一点想法:
1、我目前是通过addDrawable()添加两个Geometry来实现网格区域的高亮显示的,因为顶点设定后就没有尝试增删,如果要做成一个Geometry的话,是否可以通过重新设置顶点、颜色、法线来实现,这种方法是否可取?

该用户从未签到

发表于 2012-8-24 17:07:23 | 显示全部楼层
楼主这个先标记下 以后也许有用

该用户从未签到

发表于 2012-8-27 08:01:59 | 显示全部楼层
xulin_2005 发表于 2012-8-24 16:58
谢谢,的确是这个问题。
另外,再引申一点想法:
1、我目前是通过addDrawable()添加两个Geometry来实现网 ...

可以从新设置,dirty()

该用户从未签到

 楼主| 发表于 2012-8-27 15:16:10 | 显示全部楼层
本帖最后由 xulin_2005 于 2012-8-27 15:16 编辑
liuzhiyu123 发表于 2012-8-27 08:01
可以从新设置,dirty()


不太明白,我在UpdateHL的代码中已经用了dirty(),您说的重新设置,是把整个Geometry对象重新设定一遍么?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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