zoukankan      html  css  js  c++  java
  • OSG:先导篇 访问器机制

    一.简介

    osg::NodeVisitor 类是设计模式 Visitor (观察者模式)的实现,osg::NodeVisitor 类继承自 osg::Reference 类

    osg::NodeVisitor是一个虚基类,在程序中无法实例化

    osg::NodeVisitor中主要有 apply():决定了遍历的方式,可以获得各个节点的属性,也可以修改节点属性

                accept():关联需要访问的节点,并启动访问器进行遍历

    在用户应用程序中,可以编写继承自osg::NodeVisitor的新类,再通过重载 apply() 来实现功能

    二.顶点访问器

    三.纹理访问器

    四.节点访问器

    //main.cpp
    
    #include "osgViewer/Viewer"
    
    #include "osg/Node"
    #include "osg/Geode"
    #include <osg/Group>
    
    #include "osgDB/ReadFile"
    #include "osgDB/WriteFile"
    
    #include "osgUtil/Optimizer"
    
    #include "FindNodeVisitor.h"
    
    int main()
    {
        //创建Viewer对象,场景浏览器
        osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
        osg::ref_ptr<osg::Group> root = new osg::Group();
    
        //创建一个节点,读取牛的模型
        osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
    
        //创建节点查找访问器
        FindNodeVisitor cow("cow.osg");
    
        //启动访问器,开始执行遍历
        node->accept(cow);
    
        if(!cow.getFirst()){
            std::cout<<"无法找到节点,查找失败"<<std::endl;
        }
        else{
            std::cout<<"查找节点成功,成功找到节点"<<std::endl;
        }
    
        root->addChild(node.get());
        
    
        //优化场景数据
        osgUtil::Optimizer optimizer;
        optimizer.optimize(root.get());
    
        viewer->setSceneData(root.get());
        viewer->realize();
        viewer->run();
        return 0;
    
    }
    //FindNodeVisitor.h
    
    #ifndef FIND_NODE_VISITOR_H
    #define FIND_NODE_VISITOR_H
    
    #include <osg/NodeVisitor>
    #include <osg/Node>
    
    #include <osgSim/DOFTransform>
    #include <iostream>
    #include <vector>
    #include <string>
    
    //节点查找访问器,继承自osg::NodeVisitor
    class FindNodeVisitor:public osg::NodeVisitor
    {
    public:
    
        //构造函数,参数为需要查找的节点名
        FindNodeVisitor(const std::string& searchName);
    
        //重载apply()方法
        virtual void apply(osg::Node& searchNode);
    
        virtual void apply(osg::Geode& geode);
    
        virtual void apply(osg::Transform& searchNode);
    
        //设置要查找的节点名
        void setNameToFind(const std::string& searchName);
    
        //得到查找节点向量的第一个节点
        osg::Node* getFirst();
    
        //定义一个节点向量
        typedef std::vector<osg::Node*> nodeListType;
    
        //得到查找节点向量
        nodeListType& getNodeList()
        {
            return foundNodeList;
        }
    
    private:
    
        //节点名
        std::string searchForName;
    
        //用来保存查找的节点
        nodeListType foundNodeList;
    
    };
    
    #endif
    //FindNodeVisitor.cpp
    
    #include "FindNodeVisitor.h"
    
    //构造函数,初始化并设置遍历所有的子节点
    FindNodeVisitor::FindNodeVisitor(const std::string& searchName):
        osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),
        searchForName(searchName)
    {
    
    }
    
    
    //重载apply()方法
    void FindNodeVisitor::apply(osg::Node& searchNode)
    {
        //判断节点名称是否与查找的节点名称一样
        if(searchNode.getName() == searchForName)
        {
            //添加到节点系列
            foundNodeList.push_back(&searchNode);
        }
    
        //继续遍历
        traverse(searchNode);
    }
    
    //重载apply()方法
    void FindNodeVisitor::apply(osg::Transform& searchNode)
    {
        //判断节点名称是否与查找的节点名称一样
        if(searchNode.getName() == searchForName)
        {
            //添加到节点系列
            foundNodeList.push_back(&searchNode);
        }
    
        //继续遍历
        traverse(searchNode);
    }
    
    //重载apply()方法
    void FindNodeVisitor::apply(osg::Geode& geode)
    {
        apply((osg::Node&)geode);
        traverse((osg::Node&)geode);
    }
    
    //设置要查找的节点名称
    void FindNodeVisitor::setNameToFind(const std::string& searchName)
    {
    
        searchForName = searchName;
        foundNodeList.clear();
    }
    
    //得到查找节点向量中的第一个节点
    osg::Node* FindNodeVisitor::getFirst()
    {
        return *(foundNodeList.begin());
    }
  • 相关阅读:
    Eclipse打jar包的方法
    Eclipse中SVN插件的安装
    无法远程访问 MySql Server
    TCP(Socket基础编程)
    安装淘宝镜像cnpm时出现问题及解决方案
    搭建vue脚手架---vue-cli
    padding和margin设置成百分比
    响应式布局
    响应式网页:用em,rem设置网页字体大小自适应
    url两次编码
  • 原文地址:https://www.cnblogs.com/k5bg/p/11460839.html
Copyright © 2011-2022 走看看