[osg]节点遍历nodevisitor浅析

参考:https://www.cnblogs.com/hzhg/archive/2010/12/17/1908764.html

 

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

 


  

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 OpenSceneGraph (OSG) 中,您可以使用 `NodeVisitor` 类来遍历场景图的节点,并对每个子节点进行旋转和平移操作。下面是一个示例代码片段,展示了如何使用 `NodeVisitor` 来对子节点进行旋转和平移: ```cpp #include <osg/NodeVisitor> #include <osg/MatrixTransform> #include <osg/Geode> #include <osgDB/ReadFile> // 自定义的 NodeVisitor 子类 class MyVisitor : public osg::NodeVisitor { public: MyVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} // 重写 apply 方法,在遍历每个节点时执行操作 virtual void apply(osg::Node& node) { // 在这里添加旋转和平移的代码 osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(&node); if (transform) { // 旋转节点 osg::Matrix rotationMatrix; rotationMatrix.makeRotate(osg::Quat(osg::PI / 4, osg::Vec3(0, 0, 1))); // 绕 Z 轴旋转 45 度 transform->setMatrix(transform->getMatrix() * rotationMatrix); // 平移节点 osg::Matrix translationMatrix; translationMatrix.makeTranslate(osg::Vec3(1, 0, 0)); // 沿 X 轴平移 1 单位 transform->setMatrix(transform->getMatrix() * translationMatrix); } // 继续遍历节点 traverse(node); } }; int main() { // 加载场景文件 osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("path/to/your/scene.osg"); // 创建 MyVisitor 对象并应用于场景节点 MyVisitor visitor; scene->accept(visitor); // 运行场景图的渲染循环... return 0; } ``` 在上面的示例中,我们首先定义了一个名为 `MyVisitor` 的自定义 `NodeVisitor` 子类。在 `apply` 方法中,我们使用 `dynamic_cast` 操作将节点转换为 `osg::MatrixTransform` 类型,然后对其进行旋转和平移操作。然后,我们调用 `traverse` 方法继续遍历节点。 在 `main` 函数中,我们加载场景文件并创建了 `MyVisitor` 对象,并将其应用于场景节点。然后,您可以根据需要执行场景图的渲染循环。 请注意,上述示例中的旋转和平移操作仅作为演示。您可以根据实际需求修改旋转和平移的参数。同时,您可能需要添加其他条件来筛选出特定的节点进行操作。 希望对您有所帮助!如果您有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值