zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Detect loop in a singly linked list
    Partition an array around an interger
    Binary search for the first element greater than target
    Searching in a rotated and sorted array
    where, group by, having
    [scalability] Find all documents that contain a list of words
    [DP] 堆盒子问题
    cocos2dx 内存管理的理解
    cocos2dx 2.x版本:简化提炼tolua++绑定自定义类到lua中使用
    OpenGl从零开始之坐标变换(下)
  • 原文地址:https://www.cnblogs.com/hzhg/p/1908764.html
Copyright © 2011-2022 走看看