Node与NodeVisitor

  • Post author:
  • Post category:其他


osg::ref_ptr< osg::Node> model;

NodeVisitor vv( TRAVERSE_ALL_CHILDREN);

model->accept( vv);

假设model的模型结

构如图:

则model->accept( vv);多态,相当于调用Group::accept(NodeVisitor)。

注意,我开始误认为Group没有对accept()进行重写,

但后来在遍历Geode结点时,发现Geode类的定义中有一个META_Node(osg, Geode),才发现这些节点都调用了META_Node宏,而

META_Node宏里有个virtual void accept(osg::NodeVisitor& nv)

{ if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); }

原来这些节点都重写accept虚函数。这样才是正确的。这个宏定义代码和

void


Node::accept

(NodeVisitor& nv)的实现完全相同。


将Group

的META_Node宏中的accept展开,为:


void

Group

::accept

(NodeVisitor& nv)

{


if

(nv.validNodeMask(*

this

))

{

nv.pushOntoNodePath(

this

);


nv.apply(*

this

);

nv.popFromNodePath();

}

}

其中nv.apply(*

this

);因为this指针是Group*型,所以实际调用的是

NodeVisitor::apply( Group& node)




其中node指向Group对象

(注:如果是

void

Node

::accept

(NodeVisitor& nv){


nv.apply(*

this

);

} 则调用的不是NodeVisitor::apply( Group& node),因为nv.apply(*

this

)中的this参数是Node*型,

应与apply( Node*)匹配,而apply( Group*)则无法匹配,因为Node*不能隐式转换为Group*。示例程序如文章最后):


void


NodeVisitor::apply

(

Group

& node)

{


traverse

(node);

}

NodeVisitor类中

inline void traverse(Node& node)

{

if (_traversalMode==TRAVERSE_PARENTS) node.ascend(*this);

else if (_traversalMode!=TRAVERSE_NONE)

node.traverse

(*this);

}

由于此程序代码中NodeVisitor设置的遍历模式为TRAVERSE_ALL_CHILDREN(而不是默认的TRAVERSE_NONE),故调用Group::traverse(NodeVisitor):


void


Group::traverse

(NodeVisitor& nv)

{


for

(NodeList::iterator itr=

_children

.begin();

itr!=_children.end();



版权声明:本文为tmljs1988原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。