查看: 2472|回复: 14

关于NodeVisitor

[复制链接]

该用户从未签到

发表于 2009-2-13 17:15:54 | 显示全部楼层 |阅读模式
我用findNodeVisitor去查找osg中的某个模型的时候,为什么这个模型的所有子节点被查找了两遍?

该用户从未签到

发表于 2009-2-13 18:48:55 | 显示全部楼层
我不知道您是怎样使用Visitor类的,所以也无法得知出现此问题的原因。只能说findNodeVisitor虽然比较旧一些,但应该不会出现查找两遍的情形。能否麻烦您描述的详细一点?

该用户从未签到

 楼主| 发表于 2009-2-13 19:05:39 | 显示全部楼层

我的代码如下:

osg::ref_ptr<osg::Node>                tankNode = osgDB::readNodeFile("D:/osg/13.osg");  //读入osg场景文件

        osg::ref_ptr<osg::MatrixTransform> tform = dynamic_cast<osg::MatrixTransform* >(tankNode.get()); //将节点转换为MatrixTransform类

        int numchildren = tform->getNumChildren();  //统计该节点的子节点个数

        osg::ref_ptr<osg::Node> child_node = tform->getChild(1); //得到他的某个节点

        findNodeVisitor findGeoNode("Box09-GEODE");   // 查找名字为"Box09-GEODE"的节点

        child_node->asGroup()->accept(findGeoNode);  // 安装findnodevisitor

        numchildren = child_node->asGroup()->getNumChildren(); //如附图中的场景 这个值为21( 应该是正确的)

        int num_leaves = findGeoNode.getNodeList().size(); // 这个值为4 (很奇怪.................)
13.PNG

该用户从未签到

 楼主| 发表于 2009-2-13 19:22:41 | 显示全部楼层

谢谢版主的热心指导

谢谢版主

该用户从未签到

 楼主| 发表于 2009-2-13 20:14:25 | 显示全部楼层

怎么还是没有人回答啊?

知道的请指教,多谢

该用户从未签到

发表于 2009-2-13 20:25:10 | 显示全部楼层
findGeoNode.getNodeList()这个函数的含义是:将所有同名的节点保存到一个列表中,并返回这个列表。其值为4说明整个节点树中有4个同为此名的节点,但它们之间恐怕没有什么亲子关系——这是NAVY教程作者个人编写的代码,您完全可以根据自己的需要再改写

此外还是希望您稍微谅解一下,不要催促版主回答问题,毕竟我们是完全无偿地维护论坛的,从未从中获得一分的好处。我个人每天需要总共3个小时上下班奔波,回到家直接打开电脑,尽量了解和回复论坛上的疑问;然后才吃饭。也许您的工作更为繁忙,但我自己确实有的时候比较疲累,仅凭着热情来坚持……
稍微发一发牢骚,请不要在意,并希望大家一如既往地支持OSG的发展,以及有更多朋友能将自己的经验感受贡献给大家。

该用户从未签到

 楼主| 发表于 2009-2-13 20:31:54 | 显示全部楼层

楼主您辛苦了

谢谢版主

该用户从未签到

 楼主| 发表于 2009-2-13 20:34:11 | 显示全部楼层
我所有的节点躲在那个图片上了,包括名称,名字为"Box09-GEODE"的节点其实只有一个啊,不会有四个的。难道是因为在Update,Cull中都调用了findNodeVisitor?所以才重复遍历了?

该用户从未签到

发表于 2009-2-13 20:38:29 | 显示全部楼层
不会的,自定义的Visitor只有在调用节点的accept方法时才会被调用(而不是“安装”,您的注释可能会误导您的理解),其他时候都不会被自动调用。至于为什么会有重名,我想您可以在查看一下自己其他的代码(那个VistaEdit是您自己的作品?),或者将模型文件,如果可能的话,上传到论坛上大家一起研究

该用户从未签到

 楼主| 发表于 2009-2-13 20:45:54 | 显示全部楼层

这是我的模型

如上图所示的模型

13.rar

95.11 KB, 下载次数: 101, 下载积分: 威望 1

该用户从未签到

 楼主| 发表于 2009-2-13 20:47:51 | 显示全部楼层

版主您辛苦了

非常羡慕您的激情,可以使您如此的投入到自己热爱的osg中!

该用户从未签到

发表于 2009-2-13 21:11:45 | 显示全部楼层
我没有仔细看您的模型文件,不过提供一种可能性:您的模型代码中可能有“多个父节点指向同一子节点”的结构(不一定都指向Box09,可能有多个节点指向它的父节点),因此遍历树的时候会多次遍历到同一子节点上。findNodeVisitor本身没有什么问题,您可以用别的模型来试验一下

该用户从未签到

 楼主| 发表于 2009-2-14 10:08:07 | 显示全部楼层
感谢版主的耐心解答。昨晚上我看了quick referece guide手册,发现要重载Nodevisitor的apply( )方法的时候,如果把apply的参数设置为osg::Geode&时,查找结果是正确的,只返回一个叶子节点。而把apply的参数设置为osg::Node&时,返回值为4。不解

该用户从未签到

发表于 2009-2-14 11:19:41 | 显示全部楼层
嗯,今天把findNodeVisitor的代码从柜子里翻出来仔细地看了一遍,我想应当说这是NAVY教程作者的一个编程错误,修改这个类的成员函数apply(osg:: Transform &searchNode)的内容,屏蔽这一行:
  1. //apply ( (osg::Node&) searchNode);
复制代码
很显然这里作者犯了逻辑上的问题,在遍历到MatrixTransform节点的时候又启动了另一个遍历,因此任何MT的所有子节点都会被遍历两遍;而作为MT节点子节点的MT节点则遍历其子节点4遍!以至更多。
因此,由于Box09-Geode的父节点执行了四次遍历(building01 -> Box09 -> Box09-GEODE),这个Geode也就被写入了四次;您可以试验对场景的根节点而不是getChild(1)使用accept函数,得到的结果将是8,原因也不言而喻。
相信楼主如果自行继续研究,也会发现问题的所在。毕竟这些历史悠久的代码的作者和我们一样也是普通人,不必迷信他们的权威,也不必总是自比“菜鸟”。很欣赏楼主的钻研精神,期待见到更多楼主所写的教程和研究心得;只是尽量不要催促版主工作就好

[ 本帖最后由 array 于 2009-2-14 11:23 编辑 ]

该用户从未签到

 楼主| 发表于 2009-2-14 11:38:22 | 显示全部楼层

Great! 终于解决了

版主强悍!因为比较急,所以总是不停的发贴,呵呵。版主辛苦了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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