NodeVisitor
来源:互联网 发布:阿儿法营编程学校 编辑:程序博客网 时间:2024/06/05 20:36
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)。
对于节点的访问是从节点接收一个访问器开始的,用户执行某个节点的accept()函数,将一个具体的访问器对象传递给节点。
第二步,节点反过来执行访问器的apply()函数,并将自身传入访问器。
这两步的实现过程可以用一行十分简单的函数代码来表达:
void Node::accept(NodeVisitor& nv){ nv.apply(*this);}
1. 从根遍历节点
#ifdef _DEBUG#pragma comment(lib, "osgd.lib")#pragma comment(lib, "osgDBd.lib")#pragma comment(lib, "osgViewerd.lib")#pragma comment(lib, "OpenThreadsd.lib")#pragma comment(lib, "osgUtild.lib")#else#pragma comment(lib, "osg.lib")#pragma comment(lib, "osgDB.lib")#pragma comment(lib, "osgViewer.lib")#pragma comment(lib, "osgUtil.lib")#pragma comment(lib, "OpenThreads.lib")#endif#include <osg/GraphicsContext>#include <osgGA/GUIEventHandler>#include <osgGA/GUIActionAdapter>#include <osgViewer/Viewer>#include <osgDB/ReadFile>#include <osg/Geode>#include <iostream>#include <osg/MatrixTransform>#include <osg/NodeVisitor>class VisitorNodePath : public osg::NodeVisitor{public: VisitorNodePath():osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {} void apply(osg::Node &node) { std::cout<<"Apply node:"<< node.getName()<<std::endl; if(node.getName() == "glider") { //Do something } traverse(node); } void apply(osg::Group &group) { std::cout<<"Apply group:"<< group.getName()<<std::endl; if(group.getName() == "root") { //Do something } traverse(group); } void app(osg::MatrixTransform &mt) { std::cout<<"Apply mtransfor:"<<mt.getName()<<std::endl; if(mt.getName() == "child2") { //Do something } traverse(mt); }};int main(){ osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer; osg::ref_ptr<osg::Group> root = new osg::Group; osg::ref_ptr<osg::Node> glider = osgDB::readNodeFile("glider.osg"); osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile("cow.osg"); osg::ref_ptr<osg::MatrixTransform> child1 = new osg::MatrixTransform; osg::ref_ptr<osg::MatrixTransform> child2 = new osg::MatrixTransform; osg::ref_ptr<osg::MatrixTransform> child3 = new osg::MatrixTransform; osg::ref_ptr<osg::MatrixTransform> child4 = new osg::MatrixTransform; osg::ref_ptr<osg::MatrixTransform> child5 = new osg::MatrixTransform; VisitorNodePath vn; root->setName("root"); glider->setName("glider"); cow->setName("cow"); root->addChild(glider);//root->glider root->addChild(child1); root->addChild(child2); child1->setName("child1"); child1->setMatrix(osg::Matrix::translate(-5, -5, 0)); child1->addChild(glider); child1->addChild(child3); child1->addChild(child4); child2->setName("child2"); child2->setMatrix(osg::Matrix::translate(5, -5, 0)); child2->addChild(glider); child2->addChild(child5); child3->setName("child3"); child3->setMatrix(osg::Matrix::translate(-5, -5, 0)); child3->addChild(cow); child4->setName("child4"); child4->setMatrix(osg::Matrix::translate(5, -5, 0)); child4->addChild(cow); child5->setName("child5"); child5->setMatrix(osg::Matrix::translate(5, -5, 0)); child5->addChild(cow); root->addChild(glider); viewer->setSceneData(root); root->accept(vn); return viewer->run();}
2.从叶节点遍历
#ifdef _DEBUG#pragma comment(lib, "osgd.lib")#pragma comment(lib, "osgDBd.lib")#pragma comment(lib, "osgViewerd.lib")#pragma comment(lib, "OpenThreadsd.lib")#pragma comment(lib, "osgUtild.lib")#else#pragma comment(lib, "osg.lib")#pragma comment(lib, "osgDB.lib")#pragma comment(lib, "osgViewer.lib")#pragma comment(lib, "osgUtil.lib")#pragma comment(lib, "OpenThreads.lib")#endif#include <osg/GraphicsContext>#include <osgGA/GUIEventHandler>#include <osgGA/GUIActionAdapter>#include <osgViewer/Viewer>#include <osgDB/ReadFile>#include <osg/Geode>#include <iostream>#include <osg/MatrixTransform>#include <osg/NodeVisitor>class VisitorNodePath : public osg::NodeVisitor{public: //从根节点开始遍历 //VisitorNodePath():osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {} //从叶节点开始遍历 VisitorNodePath():osg::NodeVisitor(TRAVERSE_PARENTS) {} void apply(osg::Node &node) { std::cout<<"Apply node:"<< node.getName()<<std::endl; if(node.getName() == "glider") { //Do something } traverse(node); } void apply(osg::Group &group) { std::cout<<"Apply group:"<< group.getName()<<std::endl; if(group.getName() == "root") { //Do something } traverse(group); } void app(osg::MatrixTransform &mt) { std::cout<<"Apply mtransfor:"<<mt.getName()<<std::endl; if(mt.getName() == "child2") { //Do something } traverse(mt); }};int main(){ osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer; osg::ref_ptr<osg::Group> root = new osg::Group; osg::ref_ptr<osg::Node> glider = osgDB::readNodeFile("glider.osg"); osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile("cow.osg"); osg::ref_ptr<osg::MatrixTransform> child1 = new osg::MatrixTransform; osg::ref_ptr<osg::MatrixTransform> child2 = new osg::MatrixTransform; osg::ref_ptr<osg::MatrixTransform> child3 = new osg::MatrixTransform; osg::ref_ptr<osg::MatrixTransform> child4 = new osg::MatrixTransform; osg::ref_ptr<osg::MatrixTransform> child5 = new osg::MatrixTransform; VisitorNodePath vn; root->setName("root"); glider->setName("glider"); cow->setName("cow"); root->addChild(glider);//root->glider root->addChild(child1); root->addChild(child2); child1->setName("child1"); child1->setMatrix(osg::Matrix::translate(-5, -5, 0)); child1->addChild(glider); child1->addChild(child3); child1->addChild(child4); child2->setName("child2"); child2->setMatrix(osg::Matrix::translate(5, -5, 0)); child2->addChild(glider); child2->addChild(child5); child3->setName("child3"); child3->setMatrix(osg::Matrix::translate(-5, -5, 0)); child3->addChild(cow); child4->setName("child4"); child4->setMatrix(osg::Matrix::translate(5, -5, 0)); child4->addChild(cow); child5->setName("child5"); child5->setMatrix(osg::Matrix::translate(5, -5, 0)); child5->addChild(cow); root->addChild(glider); viewer->setSceneData(root); //从叶节点开始遍历 cow->accept(vn); return viewer->run();}
阅读全文
0 0
- NodeVisitor
- NodeVisitor & Picking
- Node与NodeVisitor
- 使用NodeVisitor访问HTML页面的TAG
- 10、osg::AnimationPath,osg::NodeVisitor类
- OSG 节点访问器(NodeVisitor)
- 3.osg中的CallBack回调、NodeVisitor与鼠标键盘的交互
- 快速幂取模 (位优化)
- 感悟
- 二叉树--实现二叉树的前序/中序/后序非递归遍历。
- Libevent源码分析-----连接监听器evconnlistener
- Guava学习记录
- NodeVisitor
- js获取当前时间并存到数据中
- C#关于委托的那些事儿
- VC++ 中LoadLibrary的路径问题
- Comparing system calls and C libraries
- 棋盘问题
- BZOJ 3065 带插入区间K小值
- Shell 定时5分钟一次监控Tomcat状态,自动重启
- iOS tableView滑动卡顿的问题之一