OpenSceneGraph 场景节点

OpenSceneGraph 场景节点

一、OSG场景节点简介及组合模式介绍

OSG中的场景是树形结构表示的层次结构,如下图所示:

Figure 1.1 OpenSceneGraph场景树形层次结构

根据其源码中的注释得知,OSG中场景节点的管理采用了组合(Composite)模式。先简要介绍一下组合模式,其类图为:

Figure 1.2 Composite Pattern's Structure

使用组合模式的目的是为了将对象合成树形结构以表示“部分—整体”的层次结构。Composite使得用户对单个对象和组合的使用具有一致性。组合模式通常用于以下情况:

l 你想表示对象的部分—整体层次结构;

l 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象;

为了达到叶子节点与组合节点的一致性,也可以给叶子节点定义与组合节点一样的操作,但是这些操作什么也不做,与引入Null Object模式类似,这里引入Null Operation

组合模式中主要的参与者有三个:

l Component

n Declares the interface for objects in the composition

n Implements default behavior for the interface common to all classes, as appropriate;

n Declares and interface for accessing and managing its child components;

n (optional)Defines an interface for accessing a component's parent in the recursive structure and implements it if that's appropriate;

l Leaf

n Represents leaf objects in the composition. A leaf has no children;

n Defines behavior for primitive objects in the composition;

l Composite

n Defines behavior for components having children;

n Stores child components;

l Client

n Manipulates objects in the composition through the Component interface.

二、OSG中组合Composite模式的应用

根据OSG的文档得到其场景节点的类图,如下图所示:

Figure 1.3 Inheritance Diagram for osg::Node

结合红星标示出的三个类:osg::Nodeosg::Geodeosg::Group来讲述组合模式的具体应用。以下为声明类osg::Node时给出的注释:

/** Base class for all internal nodes in the scene graph.

Provides interface for most common node operations (Composite Pattern).

*/

osg::Node类为所有场景图形的基类,为大多数能用节点操作提供接口,采用提组合模式。

以下为声明类osg::Geode时给出的注释:

/** A \c Geode is a "geometry node", that is, a leaf node on the scene graph

* that can have "renderable things" attached to it. In OSG, renderable things

* are represented by objects from the \c Drawable class, so a \c Geode is a

* \c Node whose purpose is grouping <tt>Drawable</tt>s.

*/

osg::Geode类是一个几何节点,即场景节点中的一个叶子节点,可以把可渲染的东西绑定在它上面。在OSG中,可渲染的东西表示为由类Drawable生成的对象。所以,一个Geode目的就是使Drawable成组。具体实现的程序代码为:

typedef std::vector< ref_ptr<Drawable> > DrawableList;

保护成员变量:

DrawableList _drawables;

以下为声明类osg::Group时给出的注释:

/** General group node which maintains a list of children.

* Children are reference counted. This allows children to be shared

* with memory management handled automatically via osg::Referenced.

*/

osg::Group节点维护一个孩子表,孩子是引用计数的。这样就可以由内存管理机制来管理这些孩子。具体实现的程序代码为:

typedef std::vector< ref_ptr<Node> > NodeList;

保护成员变量:

NodeList _children;

综上所述,得出它们的类图:

Figure 1.4 OSG Node Class Diagram

由类图可知,这个类图与图1.2所示的组合模式的类图相似。其中,类osg::Node可以看成是Component类,为所有的场景节点的通用操作声明接口;osg::Geode类可看作Leaf类,是一个具体的可渲染的场景节点;osg::Group类可看作Composite类,它可以包含叶节点或其它节点。

三、程序示例

编程实现由多个模型来构成一个场景,为了简便起见,模型由文件得到。场景的树形层次结构如下图所示:

Figure 1.5 Add More Models to Scene Graph

程序代码如下:

//--------------------------------------------------------------------------

// Copyright (c) 2012 eryar All Rights Reserved.

//

// File : Main.cpp

// Author : eryar@163.com

// Date : 2012-1-3 20:58

// Version : 1.0v

//

// Description : Add more models to the Secne.

//

//==========================================================================

#include <osg/Node>

#include <osgDB/ReadFile>

#include <osgViewer/Viewer>

#include <osgViewer/ViewerEventHandlers>

int main(int argc, char* argv[])

{

osgViewer::Viewer viewer;

osg::ref_ptr<osg::Group> root = new osg::Group;

osg::ref_ptr<osg::Group> group = new osg::Group;

root->addChild(osgDB::readNodeFile("glider.osg"));

group->addChild(osgDB::readNodeFile("osgcool.osgt"));

group->addChild(osgDB::readNodeFile("axes.osgt"));

root->addChild(group);

viewer.setSceneData(root);

viewer.realize();

viewer.addEventHandler(new osgViewer::WindowSizeHandler);

viewer.addEventHandler(new osgViewer::StatsHandler);

return viewer.run();

}

程序效果图如下图所示:

Figure 1.6 Render OSG Node

 

PDF Version

时间: 2024-10-28 20:48:57

OpenSceneGraph 场景节点的相关文章

Cocos2d-x Lua中多场景切换生命周期

在多个场景切换时候,场景的生命周期会更加复杂.这一节我们介绍一下场景切换生命周期.多个场景切换时候分为几种情况:情况1,使用pushScene函数从实现GameScene场景进入SettingScene场景.情况2,使用replaceScene函数实现从GameScene场景进入SettingScene场景.情况3,使用popScene函数从实现SettingScene场景回到GameScene场景.我们参考GameScene重写SettingScene的中几个生命周期函数,代码如下: func

Silverlight游戏设计:(九)三国策(Demo) 之 “江山一统”②

目前市面上的游戏无论单机的还是网游,具备多角度.多类型场景早已屡见不鲜.经典的如<轩辕剑3 >,最传统的中国风RPG角色扮演游戏,整个游戏包含3大类场景:世界(大地图)场景.具体(城市.洞穴 等)场景及战斗(回合)场景.精灵在各场景中的移动.视角.事件等方面均有不同约束与实现:三国策同 样不例外,游戏中除了上一节讲解的RPG场景外,当战役开始时,游戏将切换到SLG回合对战场景.因此, 2D游戏要做到丰富多彩则游戏引擎架构必须搭建在以场景(Scene)为核心的框架上,这也印证了贯穿教程 始终的唯

irrlicht引擎:实现天龙八部的RPG换装

又是夜深人静时 看了看时间,已经3点过了,突然想写点什么,却又不知从何说起. 那就从今天这个用irrlicht做天龙八部的模型换装说起吧.   也不知道是为什么,最近又捣鼓起了OGRE和irrlicht. 并且,总想用irrlicht实现一些OGRE中的东西. 当然,这不是商业项目,也没有商业目的,纯属蛋疼而已.   一切行动的由来,都来自于vczh那天晚上的举动. 记得有一天晚上在群里聊天,大伙就称赞各位菊苣是多么的厉害. 最后vc发了一个自己的桌面截图说:让你们看看菊苣是如何练成的(这不是原

Ogre:StaticObject和projective mapping、

StaticObject 在场景中,通常所有物体都是被放在场景节点上的,每次渲染时都会根据物体的移动来更新维护场景树,这样是花费极大的效率的,所以,如果某些物体不必移动,那么可以不把他放在场景树上,这就是StaticObject,将你不必移动物体(如很多山.树)等做成静态物体,会大大提高效率,使用方法很简单: 首先用场景管理器创建一个静态物体 StaticGeometry* sg=smgr->createStaticGeometry("static ge"); 然后在这个静态物体

Irrlicht(鬼火引擎)中多设备的支持

理清一个引擎,不得不先理清它的层次结构,进而理清渲染流程. 本文给出了鬼火引擎中的设备抽象层,有助于对鬼火引擎源码的快速阅读. IrrlichtDevice *device =   createDevice(driverType, core::dimension2d<u32>(640, 480),   16, false, shadows); 这个函数大家都很熟悉,那闲话不多说,我们就从这里开始... IrrlichtDevice 设备的顶层接口 CIrrDeviceStub  实现设备顶层接

Ogre:ManualObject

通常在Ogre中我们是导入点mesh文件来进行构造实体的,但是很多情况下我们可能就需要创建一个非常简单的平面或是线,或是有时想自己在程序中创建这样物体,这就需要用到Ogre的manual object,它就像你用opengl在程序中绘制一个物体的道理一样,在程序中定义你绘制的信息,而是用起来也很像在opengl中绘制物体. 创建一个人造物体的方法通常是这样的: 1.需要先用场景管理器去创建一个人造物体的指针 ManualObject* mo=smgr->createManualObject(&quo

Ajax应用场景-Ajax使用说明

ajax Ajax不是万能的,在适合的场合使用Ajax,才能充分发挥它的长处,改善系统性能和用户体验,绝不可以为了技术而滥用.Ajax的特点在于异步交互,动态更新web页面,因此它的适用范围是交互较多,频繁读取数据的web应用.现在来看几个Ajax的应用实例,读者可以了解如何使用Ajax技术改进现有的web应用系统.  场景1.数据验证  在填写表单内容时,需要保证数据的唯一性(例如新用户注册填写的用户名),因此必须对用户输入的内容进行数据验证.数据验证通常有两种方式:一种是直接填写,然后提交表

Silverlight游戏设计:(七)创建基于场景编辑器的新游戏Demo

场景编辑器的功能强大且灵活,从设计之初我已毫不惭愧的将其定位到"让Silverlight游戏场景架设 更简单.更快捷"这样一个高度.源码公布后,很多朋友均迫切想知道如何将其运用到实际的游戏制作中 .其实,为了能让大家更轻松的掌握此编辑器的架构原理及应用,我早已计划好在后续教程中陆续为大家 展示讲解大量的基于此场景编辑器构建的经典游戏Demo,比如<三国策>.<仙剑奇侠传>.<梦幻模拟 战>.<帝国时代>等等.本节,我肩负着艰巨的使命,目的

datanode单块盘故障导致节点失效的脚本解决方案

问题: 在hadoop的1.2.0中由于单个磁盘故障导致datanode节点失效,生产环境中datanode节点大多都有多块磁盘,我们现在需要一种方法,让datanode不会被单块磁盘的故障导致整个节点失效. 解决方法及适用场景: 1.修改hadoop源代码(介个在作者能力之外) 2.修改hdfs-site.xml中的dfs.data.dir的值,将故障盘的挂载点删除并重启(推荐在手动部署的hadoop环境中,将此方法做成脚本使用) 3.卸载故障盘,临时将数据写入根目录的挂载点,不修改配置文件(