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()); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)