OSG节点访问和遍历

节点访问:

  OSG中节点的访问使用的是一种访问器模式。

  一个典型的访问器涉及抽象访问者角色(Visitor), 具体访问者(Concrete Visitor), 节点角色(Node)。

  OSG中访问者角色为NodeVisitor类,其基本结构如下:

  NodeVisitor(TraversalMode tm)    //构造函数,TraversalMode为节点树的遍历方式

  //TRAVERSE_NONE, 仅当前节点

  //TRAVERSE_PARENTS, 向当前节点的父节点遍历

  //TRAVERSE_ALL_CHILDREN, 向子节点遍历

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

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

  void apply(Group& node)

  void apply(Geode& node)

  …………

  NodeVisitor 只是访问器角色的抽象接口,要使用访问器访问节点并执行自定义操作时,需要继承并重写

  apply(……)函数实现自定义功能。osg::Node类中的访问接口为 void accept(NodeVisitor& nv)。对节点

  的访问从节点接受一个访问器开始,将一个具体的访问器对象传递给节点,节点反过来执行访问器的apply(...)

  函数,并将自己传入访问器。可如下简单表示:

  void Node::accept(NodeVisitor& nv)

  {

  nv.apply(*ths) ;

  }

  遍历节点树:

  osg::Node类中有两个辅助函数:

  void ascend(NodeVisitor& nv)     //虚函数,向上一级节点推进访问器

  void traverse(NodeVisitor& nv)   //虚函数,向下一级节点推进访问器

  NodeVisitor的traverse()函数实现如下:

  inline void traverse(Node& node)

  {

  if (_traversalMode == TRAVERSE_PARENTS)

  node.ascend(*this);

  else if (_traversalMode != TRAVERSE_NONE)

  node.traverse(*this);

  }

  示例如下:

  代码

  1 #include <osg/Node>

  2 #include <osgDB/ReadFile>

  3 #include <iostream>

  4

  5  using namespace std;

  6

  7 class InfoVisitor: public osg::NodeVisitor

  8 {

  9 public:

  10     InfoVisitor()

  11         :osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), _indent(0)

  12     {}

  13

  14     virtual void apply(osg::Node& node)

  15     {

  16         for(int i = 0; i < _indent; i++)  cout << "    ";

  17         cout << "[" << _indent << "]"<< node.libraryName()

  18                << "::" << node.className() << endl;

  19

  20         _indent++;

  21         traverse(node);

  22         _indent--;

  23

  24        for(int i = 0; i < _indent; i++)  cout << "    ";

  25         cout << "[" << _indent << "] "<< node.libraryName()

  26                << "::" << node.className() << endl;

  27     }

  28

  29     virtual void apply(osg::Geode& node)

  30     {

  31         for(int i = 0; i < _indent; i++)  cout << "    ";

  32         cout << "[" << _indent << "] "<< node.libraryName()

  33                 << "::" << node.className() << endl;

  34

  35         _indent++;

  36

  37         for(unsigned int n = 0; n < node.getNumDrawables(); n++)

  38         {

  39             osg::Drawable* draw = node.getDrawable(n);

  40             if(!draw)

  41                 continue;

  42             for(int i = 0; i <  _indent; i++)  cout << "    ";

  43             cout << "[" << _indent << "]" << draw->libraryName() << "::"

  44                    << draw->className() << endl;

  45         }

  46

  47         traverse(node);

  48         _indent--;

  49

  50         for(int i = 0; i < _indent; i++)  cout << "    ";

  51         cout << "[" << _indent << "]"<< node.libraryName()

  52                 << "::" << node.className() << endl;

  53     }

  54 private:

  55     int _indent;

  56 };

  57

  58 int main(int argc, char** argv)

  59 {

  60     osg::ArgumentParser  parser(&argc, argv);

  61     osg::Node* root = osgDB::readNodeFiles(parser);

  62

  63     if(!root)

  64     {

  65         root = osgDB::readNodeFile("avatar.osg");

  66     }

  67

  68     InfoVisitor infoVisitor;

  69     if(root)

  70     {

  71         root->accept(infoVisitor);

  72     }

  73

  74     system("pause");

  75     return 0;

  76 }

posted on 2011-08-05 10:39 Smart Pointer 阅读(893) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


<2011年8月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

导航

统计

常用链接

留言簿

随笔档案

收藏夹

搜索

最新评论

阅读排行榜

评论排行榜