查看: 3937|回复: 8

使用SmoothingVisitor,调整法线无效

[复制链接]

该用户从未签到

发表于 2009-4-16 16:11:15 | 显示全部楼层 |阅读模式
将模型中(如第一张图所示)的法线信息读出,重新绘制,发现新生成的模型的外观与原模型差别非常大(如第二张图所示),应该是法线没有设置好。根据array的建议用了SmoothingVisitor,但发现生成的模型为黑色,而没有了设置的材质,跟踪到SmoothingVisitor,发现,所有的发现都为(0,0,0),不仅造成材质无效,还使得一些原有的特征也没有了,如比较小的孔,不知为什么。
代码如下:
           osg::Geode* newGeode = new osg::Geode;
        osg::Vec4Array* color = new osg::Vec4Array;
        color->push_back(osg::Vec4(1.0f,0.0f,1.0f,1.0f));
        for (unsigned int i=0; i<Ge.m_numDrawables;i++)
        {
                osg::Geometry* newGeometry = new osg::Geometry;
                newGeometry->setVertexArray(Ge.vertices);
                newGeometry->setVertexIndices(Ge.vertices_index);
                newGeometry->setColorArray(color);
                newGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
        /*        newGeometry->setNormalArray( Ge.normals);
                newGeometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);*/
               
                newGeometry->addPrimitiveSet(new osg:rawArrays(osg:rimitiveSet::TRIANGLES,0,Ge.m_numofTriangles));
               
                newGeode->addDrawable(newGeometry);
                osgUtil::SmoothingVisitor::smooth(*newGeometry);
        }
       
        osg::StateSet* state;
        state = newGeode->getOrCreateStateSet();
        osg::Material* material = new osg::Material;
        material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(0.298039f,0.298039f,0.0f,1.0f));
        material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(0.8f,0.8f,0.0f,1.0f));
        material->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(0.34f,0.34f,0.34f,0.34f));
        material->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f));
        material->setShininess(osg::Material::FRONT_AND_BACK,87.04f);
        state->setAttribute(material,osg::StateAttribute::ON);
        state->setMode( GL_LIGHTING, osg::StateAttribute::ON );
        osg::PolygonMode* pm = new osg::PolygonMode(
                osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL);
        state->setAttributeAndModes( pm,
                osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );

[

[ 本帖最后由 ghczhaolei 于 2009-4-16 16:19 编辑 ]
yuanwenjian.png
chulihou.png

该用户从未签到

发表于 2009-4-16 16:53:25 | 显示全部楼层
是否是顶点顺序的问题?如果各个面的顶点有的顺时针排列,有的逆时针排列,那么很可能造成这种情形。这只能通过规范模型的设计来避免

该用户从未签到

 楼主| 发表于 2009-4-16 16:56:05 | 显示全部楼层

回复 2楼 的帖子

这就不知道,因为顶点信息、顶点索引都是从模型文件中读取的

该用户从未签到

 楼主| 发表于 2009-4-16 17:06:51 | 显示全部楼层
原帖由 array 于 2009-4-16 16:53 发表
是否是顶点顺序的问题?如果各个面的顶点有的顺时针排列,有的逆时针排列,那么很可能造成这种情形。这只能通过规范模型的设计来避免

觉得不应该是模型设计的问题,因为这个模型文件就是osg格式的,该文件能够正确显示,而且我用osg再带的osg格式文件试了后也出现这样的问题,而且觉得即使有顺序不一致的问题,也不应所有的顶点都算不出法线啊?

该用户从未签到

 楼主| 发表于 2009-4-16 20:38:51 | 显示全部楼层

回复 2楼 的帖子

问题解决了,只要将上面的newGeometry->addPrimitiveSet(new osg:rawArrays(osg:rimitiveSet::TRIANGLES,0,Ge.m_numofTriangles));
换成newGeometry->addPrimitiveSet(new osgrawElementsUShort());就行了

该用户从未签到

发表于 2009-4-16 21:44:51 | 显示全部楼层
osg: DrawArrays好像是不支持SmoothingVisitor,用DrawElements吧

该用户从未签到

发表于 2009-4-16 22:20:42 | 显示全部楼层
估计你没有看SmoothingVisitor的源码吧,,,这个有些情况是不能用的~~~
《OSG编程入门指南》部分摘录:
当然,在有些情况下,顶点的顺序是未知且比较混乱的,这个时候就比较麻烦了。这个笔者也没有仔细深入研究,可以推荐一下这篇论文<计算非固定结构序列的多边形的顶点法线>。通过说的方法,即平均三角形法向量求得顶点法向量是一种经验性的方法,不具有通用性。虽然在很多情况下都可以正确的工作,但是,有些情况还是无法正常使用的。

该用户从未签到

 楼主| 发表于 2009-4-16 22:41:32 | 显示全部楼层

回复 7楼 的帖子

呵呵 使用osgDrawElementsUShort()就行,osg文件中就是用这个的,自己用了 osgrawArrays(),所以出错了。

该用户从未签到

 楼主| 发表于 2009-4-16 22:41:54 | 显示全部楼层
是的 呵呵
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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