查看: 1749|回复: 10

FindNodeVisitor是否支持Switch类型的查找?

[复制链接]

该用户从未签到

发表于 2010-3-29 15:33:23 | 显示全部楼层 |阅读模式
如题,用的是flysky大大书中的FindNodeVisitor例子,源码如下:#include "FindNodeVisitor.h"

//构造函数,初始化并设置遍历所有的子节点
FindNodeVisitor::FindNodeVisitor(const std::string &searchName) :

osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),

searchForName(searchName)
{

//
}

//重载apply方法
   
void FindNodeVisitor::apply(osg::Node &searchNode)
{

//判断节点名称是否与查找的节点名称一样

if (searchNode.getName() == searchForName)

{

//添加到节点系列

foundNodeList.push_back(&searchNode);

}


//继续遍历

traverse(searchNode);
}

//重载apply方法
void FindNodeVisitor::apply(osg::Transform &searchNode)
{

apply ((osg::Node&)searchNode);


traverse(searchNode);
}

//重载apply方法
void FindNodeVisitor::apply(osg::Geode &geode)
{

apply ( (osg::Node&)geode);


traverse((osg::Node&)geode);
}

//设置要查找的节点名称
void FindNodeVisitor::setNameToFind(const std::string &searchName)
{

searchForName = searchName;


foundNodeList.clear();
}

//得到查找节点向量中第一个节点
osg::Node* FindNodeVisitor::getFirst()
{

return *(foundNodeList.begin());
}




osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);               
osg::Switch* root = dynamic_cast<osg::Switch*>(view->getSceneData());

FindNodeVisitor find1("stream1");
root->accept(find1);
osg::ref_ptr<osg::Node> stream1 = dynamic_cast  <osg::Node*> (find1.getFirst());
现在的问题是root为group节点则可以查找成功,为switch则在root->accept(find1)处出现访问冲突

该用户从未签到

发表于 2010-3-29 16:36:52 | 显示全部楼层
您似乎应该先判断一下,root指针是否为空,也就是您的场景根节点是否真的为Switch类型?
我作了很简单的实验,运行无误

该用户从未签到

 楼主| 发表于 2010-3-29 19:07:34 | 显示全部楼层
2# array
场景的根节点是switch无误,但是通过view->getSceneData()得到的,似乎只能转换成group,转换成switch后,root指针就为空。

该用户从未签到

发表于 2010-3-29 19:10:35 | 显示全部楼层
你可以下载:教程中 修改的节点访问器 对flysky的查找节点作了修改,我运行效果不错

该用户从未签到

发表于 2010-3-30 08:38:04 | 显示全部楼层
似乎只能转换成group,转换成switch后,root指针就为空
那似乎只能说明场景的根节点不是Switch节点,事实胜于一切~~

该用户从未签到

 楼主| 发表于 2010-3-31 13:57:18 | 显示全部楼层
5# array
场景的根节点确实是switch,
尝试后发现static_cast<osg::Switch*> (view->getSceneData());才能获得switch,用dynamic_cast获得的为空,很诡异。。。。

该用户从未签到

 楼主| 发表于 2010-3-31 15:45:10 | 显示全部楼层
5# array
又有新问题,static_cast获得的switch虽然不为空,但是里面的值有问题。。。。

该用户从未签到

发表于 2010-4-1 09:10:45 | 显示全部楼层
如果一个对象不是osg::Switch,您使用static_cast强制按照osg:Switch的内存布局来解释的话,值有问题几乎是一定的,在osg中个人建议使用osg::Node::asSwitch来转换,如果IDE是VC之类的话,应该能够在调试器中看到对象真正的类型的~

该用户从未签到

发表于 2010-4-1 11:04:29 | 显示全部楼层
dynamic_cast可以保证指定类型的安全转换,它得到空值的唯一可能性就是您所转换的节点并非Switch!这是唯一的事实。而static_cast是不安全的转换,它不考虑您要转换的节点的类型

该用户从未签到

 楼主| 发表于 2010-4-1 15:14:13 | 显示全部楼层
9# array
发现问题了,原来getSceneData()获得的场景结构和原来的不同,我说原来在直接在root下放置的东西位置不对了呢。

解决方案是
FindNodeVisitor find1("stream1");
root->accept(find1);
osg::ref_ptr<osg::Node> stream1 = dynamic_cast  <osg::Node*> (find1.getFirst());
获得需要的节点指针之后,使用osg::ref_ptr<osg::Switch> parent =(osg::Switch*)   stream1->getParent(0);获得父节点,然后parent->setChildValue(stream1, false);

该用户从未签到

发表于 2010-4-1 17:00:44 | 显示全部楼层
您的解决方案也许只对应您自己遇到的情形,我想这和您的程序代码编写有一定的关系
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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