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 }

 

转载于:https://www.cnblogs.com/hzhg/archive/2010/12/17/1908764.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值