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();