查看: 4159|回复: 13

如何取得模型的各个面,并改变颜色

[复制链接]

该用户从未签到

发表于 2011-4-6 20:29:06 | 显示全部楼层 |阅读模式
有个问题想请教各位老师。先谢谢了!我想取的一个模型的某个面,然后使其颜色发生变化。比如在3DMax中建立两个立方体,导出为osg格式,文本打开,发现,只有两个Geode节点,每个节点只有一个Geometry几何体。我通过PolytopeIntersector求交想取出某个面,但是得到的永远是一个整体的几何体,改变颜色也是整个立方体改变,没办法定位到面,然后改变颜色。我的理解:其实一个geometry就是一个独立的drawable,有自己的stateset,向下再追溯,除非面作为独立的drawable,否则,不应该有自己的stateSet。似乎此路不通啊,请问各位老师我该如何实现我的要求?还曾经尝试用Multigen Creator将各个面单独放在自己的group下,然后转换为osg或者直接读flt,是可以实现单独的面颜色改变的(因为此时转换后的osg文件中已经将每个面都保存为一个geode了)。这种办法肯定不可取,还请各位老师赐教啊。再次感谢了!

该用户从未签到

发表于 2011-4-6 21:46:22 | 显示全部楼层
建议先实现opengl版本,因为osg中基本的绘制单元是Drawable。

该用户从未签到

 楼主| 发表于 2011-4-6 22:08:17 | 显示全部楼层
谢谢您的关注!稍微复杂一点的模型都需要借助如3dsmax等的建模软件建模。那么如何才能通过模型格式转换,取得的模型能让osg读取,并且使模型的每个多边形面片保存为单独的drawable,以便获取面的信息和改变其stateset呢?

该用户从未签到

发表于 2011-4-6 22:36:26 | 显示全部楼层
这样会使渲染树变得很大,冗余了很多的stateSet,效率上不会好。如果一定要用osg,可以取出要改变颜色的面的顶点,新建一个geometry包含这个面,然后改变它的颜色。
关键是你如何去取出这个面。

该用户从未签到

发表于 2011-4-7 08:57:19 | 显示全部楼层
可以用IntersectionVisitor求交并得到结果中的indexList,即所有与线段有交集的三角形的顶点索引号,从中取出您需要的那个面并修改颜色数组即可

该用户从未签到

发表于 2011-4-7 10:22:57 | 显示全部楼层
回复 5# array
原来还能直接改变颜色数组。学习了

该用户从未签到

发表于 2011-4-7 10:44:25 | 显示全部楼层
回复 5# array


    谢谢array,明白您的意思了,这就去试试看

该用户从未签到

 楼主| 发表于 2011-4-7 11:01:12 | 显示全部楼层
感谢大家的热情解答!特别要感谢Array老师的方法,感觉有很强的可操作性。我这就试试,再次表示感谢!

该用户从未签到

 楼主| 发表于 2011-4-7 21:07:57 | 显示全部楼层
大家好,我根据Array老师的提议实验了一下,发现一些问题:
osgUtil:ineSegmentIntersector::Intersection 结构体中有IndexList 类型的变量,可以直
接取出。但是osgUtil:: PolytopeIntersector::Intersection 结构体中没有IndexList,而只有
primitiveIndex和包含交点的数组intersectionPoints,通过这些参数如何取得相交面和面上的
法线(因为交点数量不定,会小于3,所以叉乘求不可靠)?我感觉有可能通过primitiveIndex
可以取到,但是不知道如何做?如果还望老师能稍微讲得具体一点,多谢了

该用户从未签到

发表于 2011-4-8 08:26:35 | 显示全部楼层
primitiveIndex只是图元的索引,通过它您恐怕得不到三角形的具体信息。如果默认的求交器没有提供这样的功能,那么这种时候最好的方法是自己参考它构建一个,然后如果可能的话,把您的成果贡献给osg本身

该用户从未签到

 楼主| 发表于 2011-4-8 10:02:15 | 显示全部楼层
谢谢Array老师!我还只是学习阶段,还没有那个水平啊。呵呵,如果有需要,那是我的荣幸。呵呵。我想了个笨一点的办法:gm为取出来的被碰撞节点的Geometry,通过osg::Vec3Array* vec3array=dynamic_cast<osg::Vec3Array*>(gm->getVertexArray())可以得到所有的节点,通过osg::Geometry:rimitiveSetList primitiveSetList=gm->getPrimitiveSetList()可以得到基本图元绘制方法的列表,每一个绘制方法都能得到绘制类型( PrimitiveType, DrawArraysPrimitiveType, DrawArrayLengthsPrimitiveType, DrawElementsUBytePrimitiveType,   DrawElementsUShortPrimitiveType, DrawElementsUIntPrimitiveType )和绘制模式( POINTS = GL_POINTS, LINES = GL_LINES, LINE_STRIP = GL_LINE_STRIP, LINE_LOOP = GL_LINE_LOOP,   TRIANGLES = GL_TRIANGLES, TRIANGLE_STRIP = GL_TRIANGLE_STRIP, TRIANGLE_FAN = GL_TRIANGLE_FAN, QUADS = GL_QUADS,  QUAD_STRIP = GL_QUAD_STRIP, POLYGON = GL_POLYGON, LINES_ADJACENCY = GL_LINES_ADJACENCY_EXT, LINE_STRIP_ADJACENCY = GL_LINE_STRIP_ADJACENCY_EXT,   TRIANGLES_ADJACENCY = GL_TRIANGLES_ADJACENCY_EXT, TRIANGLE_STRIP_ADJACENCY = GL_TRIANGLE_STRIP_ADJACENCY_EXT ),并且可以得到每一个绘制图元的从哪一点开始绘制,哪一点终止或者绘制的图元个数,都可以取得到。这样应该可以把那取出来的一堆顶点信息分割开来,然后再通过多面体求教器提供的碰撞时的图元索引primitiveIndex,应该可以得到该图元(面)的所有信息才对。也不知道可否

该用户从未签到

发表于 2011-4-11 08:44:26 | 显示全部楼层
您的意思是自己去遍历所有的顶点和图元数据并且找出符合您需要的那一组?这没什么不可以的

该用户从未签到

发表于 2012-4-12 09:40:31 | 显示全部楼层
哥们,你好,看到你的贴子了。我正想实现的功能就是: 鼠标点击某一个加载的3D模型,然后改变这个模型的颜色,现在我可以检测到点击事件,但是关于获取点击的模型,然后改变其颜色这一块不太明白,请您指点一下,谢谢

该用户从未签到

 楼主| 发表于 2012-4-26 13:40:49 | 显示全部楼层
osg:: ref_ptr<osg:: Material> mat = new osg:: Material;
mat->setDiffuse( osg:: Material:: FRONT_AND_BACK,osg:: Vec4( 1.f, 0.f, 0.f, 1.f ));
stateOfCollidedPlane=node->getOrCreateStateSet();       
//这样即可将相关部分设置成红色                       
stateOfCollidedPlane->setAttribute(mat.get(),osg:: StateAttribute:: ON);
//这样可恢复为原来的颜色
stateOfCollidedFinger->removeAttribute(osg:: StateAttribute:: MATERIAL);
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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