摘要:介绍了基于Vega平台的虚拟现实系统;GL Studio平台的工作流程;针对GL Studio制作的仪表仿真模型不能在Vega场景中直接应用的问题,分析了Vega和GL Studio的底层软件开发原理;对GL Studio模型向Vega场景移植的几项关键技术进行了研究,解决了坐标系差异、坐标系基本单位转换、模型载入以及场景中的模型操作等问题。
关键词:Vega;GL Studio;视景仿真;虚拟座舱
0引言
虚拟现实技术的最初应用是针对飞行员的飞行训练的,时至今日,利用虚拟现实技术来实现虚拟座舱仍是个热门的话题。之所以如此,是因为飞机座舱系统复杂,利用单一的系统仿真软件开发平台进行模拟往往会顾此失彼。就拿Vega来说,作为一款优秀的视景驱动软件平台,利用它可以很好地对飞机及其座舱的3D环境进行模拟仿真,然而,其自身提供的仪表仿真组件的功能相对较弱,仪表的模型建立要在没有程序开发接口支持的Creator中完成,这对机舱内复杂仪表的全面仿真是不可能的。因而,对仪表的仿真多数人的目光还是要投向专业的仪表仿真平台GL Studio。但是纯粹的GL Studio应用又似乎有些单调,对机座舱环境及其飞行环境难以模拟,仿真过程往往缺乏沉浸式的真实感。因此,若能将GL Studio的仪表仿真模型载入到Vega场景中将会是多数人的理想选择。然而,Vega本身对于GL Studio是不直接支持的,需要开发人员从底层将代码植入。本文结合某型飞机虚拟座舱的实现,对这一问题进行研究解决。
1 Veqa简介
Vega是MultiGen-Paradigm公司为视景仿真软件开发提供的一套系统解决方案,它由LynX***形界面、Vega API以及一些可选的功能模块组成。
通过LynX及其提供的功能模块,用户只需对一些参数进行简单的设置,不需要编写任何代码就可实现视景仿真对象的构造,创建对象属性及其之间的关系,并可生成ADF(程序定义)文件供Vega API调用。
在Windows环境中,可以利用Vc++或其它软件开发平台通过调用Vega API,来实现对LynX中定义的场景对象的管理,进而实现复杂的视景仿真系统开发。Vega API来源于SGI***形工作站的OpenGL Performer,因此,其底层具有与OpenGL的完美接口,使开发者能够根据不同需要,直接利用OpenGL开发出具有自身特色和功能的组件嵌入到Vega场景中。其开发流程如***1所示。
本文就是采用对Vega底层API的调用来实现GL Studio模型向Vega场景的移植。
2 GL Studio简介
GL Studio是DISTI公司为仪表仿真软件开发提供的一套系统解决方案。用户可以利用其***形交互界面以所见即所得的方式来完成仪表面板的制作,通过其代码编辑器来完成仪表内部逻辑仿真。其代码生成器能够将用户的制作结果自动生成c++和OpenGL源代码,用户既可以将其代码进行单独编译也可嵌入到其它程序中进行编译,从而避免了大量繁琐的底层OpenGL开发细节。其逻辑结构如***2所示。
3 GL Studio向Vega移植的关键问题
将OpenGL实现的功能嵌入到Vega场景中,一般利用Vega的回调函数来实现,而GL Studio对仪表的绘制也是通过OpenGL编程实现的,因此,GL Studio模型向Vega场景的移植自然也要通过回调函数来实现。但是,移植过程中有如下几个问题要解决。
3.1 GL Studio与Vega坐标系的差异问题
虽然GL Studio与Vega都是在OpenGL基础上的应用,使用的都是右手坐标系,但是Vega的坐标系与OpenGL的坐标系又有所差别,如***3所示。
从***3中可以看出,Vega坐标系是在OpenGL坐标系的基础上绕x轴逆时针旋转90。得到的,因此,若要在Vega场景中绘制或添加GL Studio模型,首先要保存坐标系的一致。这可以通过两种途径来实现:
(1)在GL Studio环境中制作虚拟仪表时直接在XZ平面上绘制(这里所指的均是绘制二维仪表)。这样,在移植过程中就不需要旋转仪表模型,但是会给单独调试虚拟仪表带来不便。
(2)在GL Studio环境中制作虚拟仪表时仍在XY平面上绘制,只是在移植时要将仪表在原来基础上绕x轴顺时针旋转90°。
本文中采用的是第二种方式。但是无论采用哪种方式,在将GL Studio模型放入Vega场景中之前,都要先保存Vega当前的显示状态,绘制完之后再恢复其显示状态。
3.2 GL Studio与Vega坐标系中基本单位变换问题
在Vega中根据场景及模型的大小不同,坐标所采用的基本单位可以是米、千米、英尺或英寸,而在GL Studio中制作虚拟仪表是以像素为基本单位的。因此在移植过程中存在着基本单位的转换问题。
笔者经过多次试验发现,GL Studio在移植过程中以Vega场景中的基本单位为基准进行l:l转换,即若Vega中以米为基本单位,转换后GL Studio的1像素即为Vega中的l米。那么,GL Studio模型在无缩放载入场景时,就会变得非常大,需要将其按要求进行缩小。一般情况下GL Studio模型在载入场景时都要以现有的Creator模型为背景,因为GLStudio所模拟的往往是在Creator建模时难以完成的某些仪表面盘,因此,在进行缩放时应根据Creator模型某个面的大小来制定缩放比例。
3.3将GL Studio模型载入场景的问题
在将GL Studio模型载入Vega场景时,应对其绘制过程进行合理封装。本文采用在Vega场景中首先利用MakeObj()函数动态构建Object数据模型,然后将GL Studio模型作为一个Node节点添加到该Object,并为该节点增加回调函数Obj_CB()将其载入场景。具体代码实现如下:
vgObject*MakeObj()
{vgObject*oglObj=NULL;
vgDataSet*dataset=NULL;//创建空的vgDataSet数据结构
pfGroup*group=NULL;//创建空的Group节点
DfNode*node=NULL;
//该Node节点指向新创建Object的Node节点
dataset=vgNewDS():
group=pfNewGroup():
……
if(vgMakeDS(dataset,group,VGDS_GEOMETRY)
==VG_SUCCESS、
{oglObj=vgNewObj():
vgName(oglObj,“_oglobj”):
vgProp(oglObj,VGOBJ_CS,VGOBJ_DYNAMIC);
vgObjDS(oglObj.dataset);
//利用DataSet数据结构创建新的Object
vgMakeObj(oglObj,VGOBJ_USE);
vgUpdate(oglObj):+
}
……
node=(#Node*)vgGetObjPfNode(oglObj):
……
pfNodeTravFuncs(node.PFTRAV_DRAW,Obj_CB,NULL);
//为新创建的Object增加回调函数pfNodeTmvData(node。PFTRAV_DRAW,NULL);return oglObj;
//返回新创建的Object地址指针
}
为创建的Object的Node节点增加的回调函数体:int obj_cB(onraverser*trav.void。data){pfPushState():
pfPushMatrix():
pfBasicState()://保存当前场景状态
GIsObj・>Draw()://GL Studio模型绘制过程
……
glFlush()://恢复保存的场景状态
glPopARdb():
pfPopMatrix():
pfPopState();
return PFTRAV_CONT;
}
3.4 GL Studio模型在Vega场景中的交互问题
在将GL Studio模型移植到Vega场景之后,它并不能自动捕获用户的输入事件,这是由GL Studio本身底层的消息管理机制决定的。因此,若要它能够响应窗口消息,就需要手动将消息发送给GL Studio模型,让其处理。这里,我们在Windows窗体消息循环中增加了一个HandleEvent()函数,让其主动捕获消息事件发给GL Studio模型处理。其函数体如下:
Void HandleEvent(int eventType,int eventSubtype.inl
buttonMask,UINT nFlags.CPoint point)
{MouseEvent eV://定义GL Studio环境下的鼠标事件ev.eventType。eventType;
//将Windows消息转化为GL Studio能够识别的消息ev.eventSubtype=eventSubtype;eV.buttonMask=buttonMask;
GIs_O bj->handle(&ev);//将消息发给GL Studio模型处理
}
4结束语
本文详细介绍了用GL Studio制作的仪表模型向Vega场景移植过程中的一些关键问题及其解决方法,并对Vega和GLStudio的底层工作原理作了简要介绍。所述方法解决了Vega场景中不能直接支持GL Studio虚拟仪表的问题,对于在Vega场景中复杂仪表的仿真有一定的参考和应用价值。移植到Vega场景中某型飞机虚拟座舱面板的效果如***4所示。
(注:本文中所涉及到的***表、注解、公式等内容请以PDF格式阅读原文。)
转载请注明出处学文网 » GL Studio在飞机虚拟座舱实现中的应用