前言
在前几节中,我自己觉得讲的比较粗糙,因为实在是时间上不是很充足,今天我想弥补一下,希望不是亡羊补牢。我们在osgViewer::Viewer::eventTraversal()函数中经常看到这么两个函数:camera->accept(*_eventVisitor);以及getSceneData()->accept(*_eventVisitor);今天我们第一步就是要介绍一下这两个函数。首先我们通过查找camera和getSceneData()的定义可以发现其实他们都是继承自osg::Node类,所以我们就找到了accept函数的定义。
NodeVisitor的作用
在介绍这两个函数之前我们需要先了解NodeVisitor的作用:作为访问者在osg :: Nodes上进行类型安全的操作。 基于GOF的访客模式。 NodeVisitor对于保护场景图中的节点类型安全操作非常有用(根据访问者模式),并添加了对可选场景图遍历的支持,以允许操作立即应用于整个场景。 Visitor模式使用双重调度技术作为调用NodeVisitor的相应apply(..)方法的机制。 要使用此功能,必须使用在每个Node子类中扩展的Node :: accept(NodeVisitor),而不是直接应用NodeVisitor。 所以使用root-> accept(myVisitor); 而不是myVisitor.apply(* root)。 后一种方法将绕过双重调度,并且有可能调用错误的NodeVisitor :: apply(..)方法。
Node::accept(NodeVisitor& nv)
这个函数看上去很简单,就是一个if判断,一共4句代码。但是其内部的乾坤非常的庞大。我们一步一步的分解他。首先我们进入
第一个函数if语句中的NodeVisitor:: validNodeMask():主要作用是用来判断是否对这个node及其他的子节点进行操作。getTraversalMask()函数是用来得到NodeVisitor :: _ traversalMask,而 getNodeMaskOverride()得到_nodeMaskOverride和node.getNodeMask()得到Node::_nodeMask。也就是当如果NodeVisitor :: _ traversalMask为0则将关闭所有节点的所有操作。将_traversalMask和_nodeMaskOverride设置为0xffffffff将允许访问者在所有节点上工作,而不管他们自己的Node :: _ nodeMask状态。
第二个函数void NodeVisitor::pushOntoNodePath(Node* node),作用是用来把node节点添加到nodevisitor可访问的nodepath的队列的尾部,当_traversalMode!=TRAVERSE_PARENTS。而node不是父节点(也就是叶子节点时)就把node节点添加到nodevisitor可访问的nodepath的队列的头部。
第三个函数nv.apply(*this);apply函数在nodeVisitor中是一个纯虚函数,他分别在CollectCompileCosts,CollectDrawCosts以及CollectParentPaths三个子类中实现。虽然三个子类前期的处理工作有所不同但是最后都调用了NodeVisitor::traverse(node)方法。在这个方法中会判断node是否在场景中作为父节点出现,如果是叶子节点则调用子节点中实现的traverse方法,来访问自定义的方法。如果是父节点则调用Node:: ascend方法,继续循环这个父节点下的所有子节点,直到是叶子节点调用traverse方法,来访问自定义的方法。
总结
我们最后用一张图总结今天的内容
相关推荐
创建一个`NodeVisitor`的派生类,并重写`apply(osg::Node& node)`方法,这样每次访问到一个节点时,都会调用这个方法。然后使用`node.accept(yourNodeVisitor)`来启动遍历。 ```cpp class MyNodeVisitor : public ...
同一个osg::Geometry或osg::Geode或osg::Group对象 在不同的位置 用不同的颜色、大小、角度显示
std::vector<osg::ref_ptr<osg::Node>> nodes = {nodeA, nodeB, nodeC}; void switchVisibility() { nodes[currentNodeIndex]->setNodeMask(1); if (++currentNodeIndex >= nodes.size()) { currentNodeIndex ...
通过osg::ShapeDrawable实现简单的点线面标绘。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
bool KeyboardHandler::handle(osgGA::EventQueue* eq, osg::Object* obj, osg::NodeVisitor* nv) { // 检查键盘事件并切换模型 } bool MouseHandler::handle(osgGA::EventQueue* eq, osg::Object* obj, osg::...
“osgEarth数据加载及组织解析.docx”文档应该详细介绍了以上概念和步骤,可能还包括了代码示例和最佳实践。通过阅读这份文档,开发者能够深入理解如何在实际项目中有效地组织和使用OSGEarth的数据,从而创建出富有...
总的来说,OSG通过其强大的文件读取和场景管理能力,使得加载和展示地形及3D模型变得简单易行。通过熟练掌握这些技术,开发者可以创建出复杂且动态的3D应用。在实际项目中,可能会涉及到地形的LOD(Level of Detail...
在3D图形编程领域,OpenSceneGraph (OSG) 是一个强大的开源库,它提供了丰富的功能,用于构建高性能的实时3D应用。本教程将详细讲解如何在OSG中为模型添加纹理,让3D场景更加生动逼真。 首先,我们要理解纹理的基本...
例如,你可以使用osg::Geode和osg::Shape类创建几何物体,使用osg::Texture和osg::Image加载纹理,使用osg::Switch控制节点的可见性,以及使用osg::MatrixTransform进行几何变换。 多窗口渲染的一个常见应用场景是...
4. **引入OSG头文件**:在需要使用OSG的源文件中,包含必要的OSG头文件,如`<osgViewer/Viewer>`、`<osg/Node>`、`<osgDB/ReadFile>`等。 接下来,我们来实现OSG模型的显示: 1. **创建OSG Viewer**:在MFC视图类...
- **RainNode**: 在OSG中,你可以创建一个自定义的`osg::Node`子类,比如`RainNode`,来表示雨效果。这个节点会包含所有与生成和更新雨滴相关的方法。 - **几何体生成**: 雨滴通常用一系列小的线段或点表示,可以...
5.保证无毒 1.简单,方便,实用 3.实例可以自行改用 1.如有非法,本人无法律责任! 8.更多作品,查找标签“朱建强”7.... 4.如需联系我请看左边数字!1.如不知代表何物,那就放弃计算机吧! 0....CSDN老板不让我上传联系方式。
在OpenSceneGraph (osg) 中实现雾(Fog)功能是一项关键的任务,它能为三维场景增添真实感和深度感。OpenSceneGraph 是一个高性能的3D图形库,基于C++编写,广泛用于构建复杂的实时三维应用。在本文中,我们将深入...
在OpenSceneGraph (osg) 的世界里,地形的绘制是一个重要的功能,特别是在3D地理信息系统、游戏开发或者虚拟现实应用中。osgTerrain是osg库的一个关键模块,它提供了高级的地形渲染技术,允许开发者创建复杂且逼真的...
osg纹理坐标环绕 osg纹理坐标环绕是指在osg中对纹理坐标的处理和设置。纹理坐标是在纹理空间中的坐标,通常定义在0-1范围内,但是这并不是说纹理坐标只能在0-1范围内,纹理坐标可以超出0-1范围内。超出范围后,在...
Qt加载Osg的老方式是使用osg3.4以及以前的某些版本中提供的osgQt项目加载osg,不过这种方式,在3.6等新版本中不再支持,更改起来比较麻烦,osg::GraphicsContext类不再提供osg::GraphicsContext::...
#### 一、OSG简介及历史 - **OpenSceneGraph (OSG)**:是一款跨平台、开源的场景图形API,主要用于三维图形的应用开发。 - **发展历程**: - OSG最初由Garth Zeglin在1999年创建。 - 随着时间的发展,OSG逐渐成为...
**osg和osgEarth简介** osg(OpenSceneGraph)是一个开源的3D图形库,它基于OpenGL,用于构建高性能的3D应用。OSG提供了一系列高级功能,如场景管理、动画系统、几何处理、光照和纹理处理等,为开发者提供了一个...
此外,动画可以通过`osg::AnimationPath`、`osg::StateSet`的定时器或者`osg::NodeVisitor`来实现。 在学习这份指南时,你将接触到OSG的加载器,如`osgDB::readNodeFile()`,用于读取常见的3D文件格式,如`.obj`、`...
- 在创建颜色数组(`osg::Vec4Array`)时,通过传递一个包含RGBA四个通道的`osg::Vec4`值来设定每个面的颜色及透明度。 - 对于半透明面,可以将alpha值设为小于1的浮点数来实现不同的透明度效果。 #### 三、代码...