当前位置:   article > 正文

OSG 节点访问器(NodeVisitor)_osg::nodevisitor

osg::nodevisitor
OSG 节点访问器(NodeVisitor)


前言:学习OSG还有点痛苦,大概是对于新东西学起来都是痛苦的吧!

osg::NodeVisitor 类:

※ NodeVisitor( TraversalModel tm);
    构造函数;传入参数为节点树的遍历方式:
    TRAVERSE_NONE, 仅当前节点;
    TRAVERSE_PARENTS, 向当前节点的父节点遍历;
    TRAVERSE_ALL_CHILDREN, 向子节点遍历;

※ void traverse(Node& node);
    向下一个需要访问的节点推进;

※ void apply(Node& node)
※ void apply(Group& node)
※ void apply(Geode& node)
    虚函数,访问各种类型的节点,并执行访问器中自定义的节点操作;

osg::Node 类:

※ void accept(NodeVisitor& nv);
    接受一个访问器;

对于节点的访问是从节点接收一个访问器开始的,用户执行某个节点的accept()函数,将一个具体的访问器对象传递给节点。

  第二步,节点反过来执行访问器的apply()函数,并将自身传入访问器。

  这两步的实现过程可以用一行十分简单的函数代码来表达:

  1. void Node::accept(NodeVisitor& nv)
  2. {
  3. nv.apply(*this);
  4. }
最后,在具体访问器对象中重写的apply()函数中,执行节点的具体访问操作。使用一个自定义访问器UserVisitor来访问已知场景节点树:
  1. UserVisitor visitor;
  2. subgraph->accept(visitor);

例子:节点属性访问器:
  1. #include <osg/Node>
  2. #include <osgDB/ReadFile>
  3. #include <iostream>
  4. class InfoVisitor : public osg::NodeVisitor
  5. {
  6. public:
  7. InfoVisitor(): osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), _indent(0){} //向子节点遍历
  8. virtual void apply( osg::Node &node){ //获取访问节点对象,并执行自定义节点操作
  9. //当访问到默认的Node节点时,使用该函数打印节点的名称
  10. //并根据节点层次适当使用_indent缩进
  11. for ( int i = 0; i < _indent; ++i)
  12. {
  13. std::cout<< " ";
  14. }
  15. std::cout<< "["<< _indent + 1<< "]"<< node.libraryName()
  16. << "::"<< node.className()<< std::endl;
  17. _indent++;
  18. traverse( node); //向下一个需要的节点推进
  19. _indent--;
  20. }
  21. //当访问到Geode节点时,不仅打印叶节点的名称属性,还打印叶节点所包含的所有可绘制体的名称
  22. virtual void apply( osg::Geode& node){
  23. for ( int i = 0; i < _indent; ++i)
  24. {
  25. std::cout<< " ";
  26. }
  27. std::cout<< "["<< _indent + 1<<"]"<< node.libraryName()
  28. << "::"<< node.className()<< std::endl;
  29. for (unsigned int n = 0; n < node.getNumDrawables(); ++n)
  30. {
  31. osg::Drawable* drawable = node.getDrawable(n);
  32. if(!drawable) continue;
  33. for(int i = 0; i <= _indent; ++i){
  34. std::cout<< " ";
  35. }
  36. std::cout<< drawable->libraryName()<< "::"
  37. << drawable->className()<< std::endl;
  38. }
  39. _indent ++;
  40. traverse( node);
  41. _indent --;
  42. }
  43. protected:
  44. int _indent;
  45. };
  46. int main()
  47. {
  48. osg::ref_ptr<osg::Node> root = osgDB::readNodeFile("axes.osgt");
  49. InfoVisitor infoVisitor;
  50. if (root)
  51. {
  52. root->accept( infoVisitor); //接受自定义访问器
  53. }
  54. return 0;
  55. }

root->accept( infoVisitor);
谁调用accept,就以此为根结点向下进行深度优先遍历,如果想向上遍历,就将traverse()函数改为ascend()函数;

运行截图:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/314917
推荐阅读
相关标签
  

闽ICP备14008679号