Open Inventor.docx
《Open Inventor.docx》由会员分享,可在线阅读,更多相关《Open Inventor.docx(21页珍藏版)》请在冰豆网上搜索。
OpenInventor
简介
目前世界上比较成熟的OpenInventor(以下简称OIV)开发包有三个,它们分别由SGI(),TGS()和SIM(http:
//www.coin3d.org)公司开发的。
SGI是最早提出并开发OIV的公司。
但SGI的OIV主要用在UNIX操作系统下,没有提供对MicrosoftWindows操作系统的支持。
TGS公司是最早将OIV由Unix系统移植到MicrosoftWindows下的公司。
TGS的OIV是目前世界上使用最多的OIV版本。
但TGS的OIV是一个商业软件开发包,其购买开发版权的费用非常昂贵,不适合普通用户学习和使用。
SIM公司开发的Coin3DOIV可以同时在UNIX和MicrosoftWindows下使用。
这是一个开放源码的OIV开发包,使用协议采用的是GPL协议。
非常适合希望学习使用OIV的普通用户。
本文将主要介绍Coin3DOIV开发包在MicrosoftWindows操作系统下,VisualC++2003开发环境中的安装与使用。
Coin3D的安装
截至到目前(2007年8月),Coin3D的最新版本已经是Coin2.4.6版本了。
但SIM公司还没有提供Coin2.4.6版本的安装程序。
目前只提供Coin2.3.0的安装程序。
如果读者不希望太麻烦,我们建议读者下载使用Coin2.3.0,因为这可以省去很多手工设置。
读者可以到这里下载Coin2.3.0(http:
//ftp.coin3d.org/coin/bin/win32/all/Coin3D_2.3.0-0.exe大约19M)。
这个安装程序中包含有Coin3DOIV的源码、开发库文件、头文件、例子代码、API文档。
安装程序和Windows中其它的安装程序基本一样,读者应该可以很轻松地完成安装地工作。
如果读者希望使用Coin地最新版本2.4.6,请首先到这里下载Coin2.4.6的压缩包(http:
//ftp.coin3d.org/coin/bin/win32/Coin-2.4.6-bin-msvc7.zip 注意这里下载的是针对VC2003的版本,在SIM的网站中还有针对VC6和VC2005的版本,读者可以根据自己的需要下载),然后解压文件,将解压后的文件拷贝到自己希望的目录下即可。
在压缩包中没有包括文档和例子代码。
也没有设置相关的环境变量。
开发环境设置
本文假设读者将Coin3D安装C:
/Coin3D目录下。
和其它Windows下的开发库类似,Coin3D在VC2003中也需要首先做开发环境的设置。
首先启动VC,选择菜单“Tools”->“Options”,打开VC的Options对话框,然后在对话框中左边的树型列表中选择“Projects”->“VC++Directories”,在右边的窗口中选择设置“Includefiles”,增加上Coin3D的Include路径。
如下图所示:
还需要在右边的窗口中选择设置“Libraryfiles”,增加上Coin3D的Lib路径。
如下图所示:
完成上述两步设置之后,基本上就完成了VC++开发环境的设置。
VC++开发一个简单的Coin3DOIV程序
我们将使用VC++2003和Coin3D开发一个简单的3DViewer程序。
下面的文档是翻译Coin3D的指南文档(http:
//www.coin3d.org/windows/tutorial/hello_coin/)。
中间做了一些修改
1.首先启动VC2003,选择菜单“File”|“New”|“Project”
2.选择“Win32”项目类型,以“Win32ConsoleApplication”为项目模版,项目名称“hello_cone”
3.在Win32ApplicationWizard中,点击Next按钮。
因为我们希望自己提供所有的源文件,所以应该选择“Emptyproject”复选框。
然后点击“Finish”按钮。
这时我们就创建了一个叫做hello_cone的新工程。
4.现在我们开始编写代码。
我们首先需要向工程中增加一个C++源文件。
选择菜单“File”|“AddNewItem”,然后又选择“C++File(.cpp)”模版,名字为hello_cone.cpp,最后点击“Add”按钮。
在Hello_cone.cpp文件中,我们首先需要包含一些必要的头文件:
#include
#include
#include
#include
然后我们将在main函数中编写所有必要的代码
Intmain(int,char**argv)
{
[...]
return0;
}
首先我们初始化SoWin(同时隐含初始化Coin),之后将返回一个顶层窗口供我们使用。
HWNDwindow=SoWin:
:
init(argv[0]);
if(window==NULL)exit
(1);
然后我们创建一个观察器(Viewer):
SoWinExaminerViewer*viewer=newSoWinExaminerViewer(window);
我们的场景是由两个节点组成的:
根节点和几何物体。
我们先创建好这两个节点,然后再将几何物体作为子节点增加到根节点中。
为了防止根节点被删除(因为它的引用计数值为0),我们需要对根节点调用ref()函数。
SoSeparator*root=newSoSeparator;
SoCone*cone=newSoCone;
root->ref();
root->addChild(cone);
现在我们为观察器设置渲染场景(用根节点来表示)
viewer->setSceneGraph(root);
viewer->show();
最后,我们让SoWin显示窗口,并进入消息循环。
SoWin:
:
show(window);
SoWin:
:
mainLoop();
当应用程序结束后,要删除观察器,我们还要对根节点调用unref()函数。
root->unref();
deleteviewer;
下面是例子的完整代码:
#include
#include
#include
#include
int main(int, char ** argv)
{
HWND window = SoWin:
:
init(argv[0]);
if (window==NULL) exit
(1);
SoWinExaminerViewer * viewer = new SoWinExaminerViewer(window);
SoSeparator * root = new SoSeparator;
SoCone * cone = new SoCone;
root->ref();
root->addChild(cone);
viewer->setSceneGraph(root);
viewer->show();
SoWin:
:
show(window);
SoWin:
:
mainLoop();
delete viewer;
root->unref();
return 0;
}
4.在我们开始编译运行代码前,我们还需要对项目做一些有关Coin的设置。
点击菜单“Projects”,选择“hello_coneproperties”
5.选择ConfigurationProperties|C/C++|Preprocessor,增加上COIN_DLL和SOWIN_DLL预定义
6.选择ConfigurationProperties|Linker|Input,增加上coin3d.lib和sowin1d.lib两个库文件
7.现在我们就可以编译并运行hello_cone应用程序了。
选择Build|BuildSolution,然后运行这个应用程序。
程序的运行结果:
这个程序提供了基本的交互功能,读者可以在窗口中点击鼠标,转动Cone。
SGI工作站OpenInventor三维图形编程[转]
解放军测绘学院张华军 (计算机世界报1995年第48期)
SGI图形工作的OpenGL图形库已成为目前通用的图形标准。
OpenInventor是在OpenGL的
基础上开发的一个图形工具库,它与OpenGL一样已经适用于SUN、HP、DEC等工作站以及WI
NDOWSNT等硬件平台。
由于OpenInventor使用了面向对象编程技术,比OpenGL更容易开发
大大减少了编程的工作量,从而使得飞行模拟、虚拟现实等十分复杂的三维图形编程成为
现实,OpenInventor将是前途十分光明的三维图形编程工具。
OpenInventor的图形库内容和图形库结构
1.OpenInventor的图形对象库内容
数据库单元:
包括形状、特性、组和引擎;
交互管理器(interactionobjects):
包括事件(event),各种控制器(manipulators)等
;组成件(components):
包括各种编辑器(editor)以及各种视窗(viewer);
用户对这些图形对象库的操作可以通过C++语言编程实现,也可以按一定格式编辑一个
ASCⅡ文件在程序中通过读取这个文件来实现。
2.OpenInventor的图形库结构
@@48L17900.GIF;图1.OpenInventor图形编程的基本特点@@
1.OpenInventor面向对象编程
OpenInventor把客观世界中的独立的物体作为对象、把对象所包含的特征作为子对象
存储在景象数据中,从而构成一个三维景物世界。
同时把对象的操作(如改变对象的位置、
增删景物中的对象等)也作为景物数据库的一部分,这使得整个图形操作过程的编程变得十
分直观容易。
2.OpenInventor比OpenGL更容易编程
OpenGL从最基本的图形单元开始编程,用这些方式完成一个比较复杂的三维图形模拟
时因需要编制大量的程序而变得十分困难。
OpenInventor正是提供了一个图形对象库,它
本身就包括了大量的景物模型以及景物操作,开发者只要"组装"这些景物部件就可建立一个
景物世界。
OpenInventor编程要点
OpenInventor开发应用软件实际上是一个建立景物模型的过程,在这个过程中开发者
根据具体需要设立模型中各部件,然后用图形应用工具来实现各种操作。
1.建立景象图(SceneGraph)
景象(Scene)是由许多模型单元组成的,如一个机器人模型是由机器人的头部、躯干、
四肢等单元组成,这种单元在OpenInventor中被称为节点(Note),由这些节点组成景物模型
被称为景象图(SceneGraph)。
(1)用基本节点成组(NodesandGroup)
OpenInventor中的节点主要有三类:
形体节点(shapenodes)、属性节点(propertyn
odes)、组节点(groupnodes)。
addChild()函数把每个子点加入组节点中。
用组节点使整个景物模型的结构更加清晰。
例如在景象图中加入一个球体,可以把球体的形体节点,材料属性节点,位置节点组成一个组节点:
SoGroup*myCone=newSoGrop;
myCone->addChild(Camera);
myCone->addChild(Transform);
myCone->addChild(Cone);
每个节点又由一系列的数据域(fields)组成,这些数据域所描述的就是节点的参数。
(2)形体节点(shapenodes)和属性节点(propertynodes)
OpenInventor的形体节点包括:
简单形体,如圆锥、圆柱、椭球等。
复杂形体,如:
面集、线集、三角形集,点集,NURBS曲线和曲面在复杂形体的建立过程中
需要确定形体的坐标值和坐标个数,如:
SbVec3fverts[6];
intcoordnumber;
SoCoordinate3*coord=newSoCoordinate3;
coord->point.setValue(0,coordnumber,verts);
属性节点包括材料、绘制类型、环境、复杂度等,开发者只要根据需要确定形体的属性
特性值并加入数据域中,并且用addChild()把这些属性节点加入某一形体中。
(3)纹理节点(Texture)
OpenInventor中提供了一系列的纹理节点,并且用三种基本方法进行纹理映射。
这些
纹理节点主要有:
SoTexture2
指定二维纹理图象参数
SoTextureCoordinate2
指定二维纹理映射坐标
SoTextureCoordinatePlane2通过一个平面来映射纹理
把纹理映射到形体上主要用三种方法:
·缺省的映射方法:
用指定的映射方法,对于简单形体很适用;
·坐标映射方法:
主要用于复杂形体的纹理映射(用SoTextureCoordinate);
·平面映射方法:
用SoTexturCoordinatePlane。
2.使用景象图
OpenInventor提供了一系列在建立起景象图后使用景象图的图形操作工具。
(1)使用操作
用景象图来进行渲染及其它对景象图的操作,在OpenInventor中称为Actions,开发者
可以根据应用需要利用这些操作来实现自行设计的功能。
这些操作主要包括:
SoGLRenderAction
应用GL图形库对景象图进行渲染
SoGetBoundingBoxAction
在景象图中计算一个对象的三维空间框
SoWriteAction
把景象图写入一个文件
SoHandleEventAction
使在景象图中的对象处理一个事件(Event)
SoRayPickAction
沿直线选择对象
SoCallbackAction
用回调函数对景象图进行操作
(2)事件处理
OpenInventor提供了供键盘、鼠标等外部设备对景象图中的对象(即景物数据库中的
物体)进行操作的事件处理工具。
它是计算机与人交互的接口,这在虚拟现实等领域中的三
维交互有重要的作用。
OpenInventor提供了以下几类操作:
SoButtonEvent(包括键盘、鼠标、空间球)
Solocation2Event
SoMotion3Event
其中SoButtonEvent处理常见的外部设备事件,Solocation2Event使用光标在图形窗口
中的绝对位置值,SoMotion3Event处理三维输入设备如空间球、头盔式跟踪器等。
(3)使用传感器
OpenInventor中传感器是用于检测各类事件以及当这些事件发生时启动用户定义的Calback回调函数,它包括数据传感器和时间传感器。
使用数据传感器的一般方法是:
a.定义一个传感器。
例如定义一个照相机传感器:
SoFieldSensor*mySensor=newSoFieldSensor(CameraChangedCB,camera);
b.建立一个回调函数,如上面的cameraChangedCB即为回调函数名:
staticvoidCameraChangedCB(void*data,SoSenosor*)
{...}
c.用attach()把传感器连接至某一数据域、节点或路径。
如把上面的传感器连接至
照相机的位置:
mySensor->attach(&camera->position);
(4)使用引擎
引擎用于景象图某些单元进行模拟运动或者与其它单元之间相互作用。
引擎对于模拟
物体运动或者机械结构关节等来说是一个很好的工具。
OpenInventor提供了以下几类引擎:
计算引擎(ArithmaticEngine):
如SoCalculator,SoTransform等;
模拟引擎(AnimationEngine):
如SoElapsedTime,SoTimeCounter等;
触发引擎(TrigerEngine):
如SoCounter,SoOnOff,SoGate等;
其它引擎:
如SoSelectOne,SoConcatenate等。
使用引擎起作用的函数是connectFrom(),它使得被作用的景物节点数据域与引擎的数
据域相连接。
例如把计时引擎SoElapsedTime与文本节点相连接:
SoElapsedTime*myCounter=newSoElapsedTime;
SoText3*myText=newSotext3;
myText->string.connectForm(&myCounter->timeout);
3.OpenInventorXt组成件和实用库的用法
OpenInventor还提供了基于X窗口的组成件和实用库,这些组成件和实用库实际上是能够与景象图中的三维对象相联系的外部模块,它们可以处理景象图在X窗口下的输出和控制
等。
OpenInventor提供的组成件主要有:
色彩处理模块:
coloreditor,colorslider,colorwheel
光源处理模块:
directionallighteditor
材料处理模块:
materialeditor,materiallist
文件处理模块:
filebrowser,printingdialog
景物管理模块:
renderarea
一般操作模块:
pushbutton,thumbwheel,togglebutton
具体用法与步骤是:
a.建立一个组成件
如SoMaterialEditor*myEditor=newSoMateriaEditor;
b.用attach()函数把组成件与景象图对象相连接
myEditor->attach(myMaterial);
c.用show()或hide()函数决定组成件是否显示
myEditor->show();
OpenInventor还提供了实用视窗集(viewers),包括examinerviewer、flyviewer、p
laneviewer、walkviewer等,这些视窗已经包含了一系列操作,如examinerviewer包含了
视窗口放大、旋转、绘图方式等功能,开发者只要把视窗定义成这些类型的视窗即可使用其
所有的功能。
结语
三维图形软件往往需要大量编程,开发者不但要编制用户界面,应用算法,图形显示等程
序,还要顾及各种硬整个软件的美学特性,这样就必须做大量的工作,因此选择一种方便又灵
活的开发工具是十分重要的,OpenInventor正是这种选择。
//使用OpenInventor 显示一个红色立方体
#include
#include
#include
#include
int main(int, char **argv)
{
//初始化Inventor
HWNDmyWindow=SoWin:
:
init(argv[0]);
//创建观察器
SoWinExaminerViewer*myViewer= new SoWinExaminerViewer(myWindow);
//创建场景
SoSeparator*root= new SoSeparator;
SoMaterial*myMaterial= new SoMaterial;
myMaterial->diffuseColor.setValue(1.0,0.0,0.0);//红色
root->addChild(myMaterial);
root->addChild(new SoCube);//增加上一个立方体
//观察器和场景相关联
myViewer->setSceneGraph(root);
//显示主窗口
myViewer->show();
SoWin:
:
show(myWindow);
// 主循环
SoWin:
:
mainLoop();
return 0;
}
程序运行的结果:
这两个程序很明显的差别就是使用OIV开发程序的代码要远小于使用OpenGL开发的程序。
当然这不是使用OIV唯一的一点好处。
上面OIV例子代码中,一开始也是先初始化OIV,然后创建一个观察器窗口,接着创建场景,向场景增加上材质对象(材质对象设置为红色),再向场景增加上立方体对象。
最后显示场景,进入程序主循环。
我们可以看到,OIV的程序逻辑性比较好,不像OpenGL那样带有太多的回调函数,导致我们的思路跳来跳去的。
OIV与OpenGL程序之间一个最大的差别就是OIV不需要程序员“画”3D模型。
在上面的OIV例子中,我们只是向场景中增加上一个立方体对象,至于在那里显示,以及何时显示立方体都是OIV自己来决定的,不需要程序员来考虑。
作为对比,在OpenGL程序中,我们需要在display回调函数中一条一条地调用OpenGL命令,只有这样才能将立方体显示出来。
使用OIV的另外一个好处是,OIV的程序是“活”的。
我们可以使用鼠标来操作场景中的物体。
例如,我们可以在观察器窗口上按住鼠标左键,移动鼠标来任意旋转立方体,也可以上下移动鼠标来放大或缩小立方体。
也就是说上面的OIV例子代码其实是一个交互式的3D程序,而我们没有做任何的工作就自动获得了这种交互功能。
相对来说,使用OpenGL就没有这么幸运了,我们的OpenGL例子只是显示了一个立方体,无论用鼠标怎样操作,立方体都不会动。
当然,我们也可以使OpenGL程序具有交互的功能,但要开发一个操作非常顺手的