计算机科学与应用  >> Vol. 9 No. 10 (October 2019)

GL STUDIO虚拟仪表在OSG中的集成和应用
Integration and Application of GL STUDIO in OSG

DOI: 10.12677/CSA.2019.910214, PDF, HTML, XML, 下载: 287  浏览: 439 

作者: 朱国涛*, 孙忠云:海军航空大学青岛校区,山东 青岛

关键词: 虚拟现实虚拟仪表飞行仿真Virtual Reality Virtual Instrument Flight Simulation

摘要: GL STUDIO是一套功能强大的虚拟仪表开发工具,可以用于创建实时的、三维的虚拟仪表交互仿真图形界面。本文通过分析GLS虚拟仪表的结构,针对OSG视景渲染引擎的特点,将GL STUDIO制作的虚拟仪表移植到了OSG视景色仿真引擎中,在OSG环境下实现了GL STUDIO虚拟仪表的加载、显示、更新和交互,为使用OSG视景仿真引擎构建飞行仿真训练系统虚拟座舱提供了一种新的方法。
Abstract: GL STUDIO is a powerful and virtual instrument development tool that can be used to create real-time, three-dimensional virtual instrumentation interactive simulation graphical interface. By analyzing the structure of GLS virtual instrument object, aimed for OSG rendering engine, GL STUDIO virtual instrument was transplanted to the OSG environment, the GL STUDIO virtual instrument was realized to load, display, update, and interact under OSG environment.

文章引用: 朱国涛, 孙忠云. GL STUDIO虚拟仪表在OSG中的集成和应用[J]. 计算机科学与应用, 2019, 9(10): 1912-1919. https://doi.org/10.12677/CSA.2019.910214

1. 引言

Open Scene Graph (简称OSG)是一个开源的高性能3D图形开发工具,它使用工业标准的OpenGL底层渲染API,为3D应用程序提供了场景组织管理和图形渲染优化等功能,广泛应用于视景仿真、虚拟现实、科学可视化等领域 [1] [2] [3] 。OSG可以运行在大多数操作系统之上,使用OSG进行开发能明显地减少费用,由于OSG优异的特性,越来越多的飞行仿真、舰船仿真等软件开始采用OSG进行开发 [4] [5] ,例如开源的飞行仿真软件FlightGear、MAK公司的三维态势软件VR-Stealth等,OSG在世界可视化仿真市场的占有率逐年提高。

利用OSG完全能够满足一般仿真的需要,但是在飞行仿真领域,飞机座舱仪表的构建一般都需要使用专门的虚拟仪表软件完成,OSG目前并没有提供专门的虚拟仪表开发工具,另一方面目前在国内飞行仿真领域广泛使用的虚拟仪表开发工具是DISTI公司的GL STUIDO软件,它提供了功能强大、开发便捷的虚拟仪表建模手段。如果能够将OSG的场景管理和图像渲染能力与GL STUDIO的虚拟仪表仿真建模能力结合起来,将有助于推动OSG在飞机仿真领域的应用。

2. 虚拟仪表工具GL STUDIO简介

GL STUDIO (简称GLS)是DISTI公司开发的虚拟仪表开发工具,它是一个独立平台的快速原型工具,用来创建实时的、三维的虚拟仪表互动图形界面。使用GL STUDIO进行虚拟仪表仿真的过程如图1所示,用户可以使用GLS提供的可视化图形编辑器完成虚拟仪表面板、开关、按钮等元件的建模,然后使用GLS代码编辑器完成仪表内部逻辑的仿真,最后使用GLS代码生成器生成C++/OpenGL源代码。这些源代码既可以编译成独立的可执行程序(standalone模式),也可以编译成动态库(component模式) [6] [7] [8] 。

GL STUDIO制作的虚拟仪表在其它视景引擎中使用时,通常编译成component模式,即将生成的仪表代码编译成一个动态链接库。因为OSG视景引擎底层与GL STUDIO一样使用OpenGL进行视景的渲染,因此从方法上来说,只要能够解决GLS虚拟仪表对象(即GL STUDIO制作包含虚拟仪表的动态链接库)的加载、显示、更新和交互问题,就能够将GL STUDIO虚拟仪表移植到OSG环境下。

在Component模式下,由GLS生成的虚拟仪表对象都是从disti::ComponentBase类派生的,它有几个重要的成员函数,其中PreDraw负责准备绘制环境,Draw完成虚拟仪表绘制,GetExtents返回虚拟仪表的包围盒,SetResource/GetResource负责更新/获取对象的属性,HandleInput负责处理用户鼠标或键盘交互事件,Calculate函数(从disti::Group继承)负责对仪表状态进行计算和更新。此外在GLS虚拟仪表对象动态链接库中,还具有类似于CreateRSOInterface1_xxxClass形式的导出函数(其中xxx是虚拟仪表对象的名称),调用这个函数将返回仪表对象的RSO远程共享指针,通过RSO指针的相关成员函数可以调用到仪表对象的PreDraw、Draw、GetExtents、SetResource、HandleInput、Calculate等成员函数。

Figure 1. GL STUDIO virtual instrument development process

图1. GL STUDIO虚拟仪表开发过程

在其它OpenGL视景渲染环境中集成GLS虚拟仪表动态链接库,其调用顺序如图2所示,具体过程如下:

Figure 2. Call sequence of GL STUDIO virtual instrument dynamic library

图2. GL STUDIO虚拟仪表动态库调用顺序

1. 首先加载动态链接库,然后从中获取函数CreateRSOInterface1_xxxClass的地址,最后调用此函数获取仪表对象的RSO指针;

2. 在视景渲染的每个周期中,首先调用Calculate函数进行仪表状态计算和更新,然后调用HandleInput处理用户交互,最后调用PreDraw和Draw绘制虚拟仪表;

3. 程序退出时,销毁仪表对象并卸载动态链接库。

3. 基于OSG的GLS仪表集成

要完成GLS虚拟仪表在OSG场景中的更新、绘制和交互,还需要综合考虑到OSG场景结构和渲染流程,并解决以下问题:

1. 如何完成虚拟仪表的绘制?在OSG中,所有的可绘制对象都是从osg::Drawable类派生的,虚拟仪表的集成也需要从osg::Drawable类派生一个子类来完成。

2. 如何将GLS虚拟仪表对象组织到OSG场景图中?可以从osg::Geode几何节点类派生一个子类,osg::Geode对象是OSG场景图中的叶子节点,负责几何体的绘制,一个osg::Geode对象可以包含一个或者多个osg::Drawable对象。

3. 如何更新虚拟仪表的属性和状态?虚拟仪表的更新可以通过设置对象的更新回调实现,可绘制对象的更新回调必须由osg::Drawable::UpdateCallback派生,在更新回调中调用disti::ComponentBase:: Calculate函数即可计算和更新虚拟仪表的属性和状态。

4. 如何处理用户交互事件?交互事件处理可以自定义一个事件处理器完成,它由osgGA::GUIEvent Handler派生,并重载其handle函数即可截获OSG事件并将其中的鼠标事件转换为GLS事件,然后调用disti::ComponentBase::HandleInput函数驱动虚拟仪表进行交互事件处理。

按照上述思路,设计插件的主要类图如图3所示。

Figure 3. Class diagram of GL STUDIO virtual instrument integration plugin

图3. GL STUDIO虚拟仪表集成插件类图

OSG视景引擎底层与GL STUDIO一样使用OpenGL进行视景的渲染,因此从方法上来说,只要能够解决GLS虚拟仪表对象(即GL STUDIO制作包含虚拟仪表的动态链接库)的加载、显示、更新和交互问题,就能够将GL STUDIO虚拟仪表移植到OSG环境下。上述类图中GLSDrawable负责虚拟仪表的绘制,GLSEventHandler负责处理用户交互,即拦截OSG鼠标事件并将其转换为GLS鼠标事件并驱动动态库进行鼠标事件的处理,GLSUpdateCallback负责更新虚拟仪表,GLSGeode负责实现虚拟仪表动态库的加载和场景图的组织。

3.1. 虚拟仪表的加载

按照类图结构,虚拟仪表的加载需要从osg::Geode派生子类GLSGeode完成,GLSGeode负责从动态库中加载GLS虚拟仪表并将虚拟仪表组织到场景图中,其加载过程在loadGLSComponent函数中实现,步骤如下:

1. 首先调用Windows API函数LoadLibrary加载指定的动态库,获取其句柄并保存到成员_hInstance中;

2. 然后调用GetProcAddress函数获取CreateRSOInterface1_xxxClass导出函数的地址(其中xxx是虚拟仪表对象的名称);

3. 最后调用上述导出函数获取指向仪表对象的RSO指针_pGlsRSO,然后使用此指针构造一个GlsDrawable对象并添加到GLSGeode对象中。

4. 在GLSGeode对象析构时,需要移出所有的Drawable对象并释放动态库。

3.2. 虚拟仪表的绘制

虚拟仪表的绘制在GLSDrawable::drawImplementation函数中完成,其绘制的关键代码如下:

对于需要标注编号的公式,编号应写作“(1)”,不要写“Eq. (1)”或“Equation (1)”。

3.3. 虚拟仪表的更新

GLS虚拟仪表对象的更新依赖于周期性的Calculate函数调用,这个调用在OSG环境下可以通过更新回调实现。首先从osg::Drawable::UpdateCallBack类派生GlsUpdateCallBack,然后重载update函数,在update中通过虚拟仪表对象的RSO指针调用Calculate进行虚拟仪表的计算和更新。由于OSG在每一帧的渲染之前,都会调用更新回调对场景中的对象进行计算和更新,那么设置更新回调后OSG在渲染GLS虚拟仪表之前都会GlsUpdateCallBack::update更新虚拟仪表,其关键代码如下:

更新过程为:如果传入的第二个参数即osg::Drawable对象指针是一个GLSDrawable对象的实例,则获取当前时间值(单位毫秒)并调用Calculate函数进行更新。

3.4. 交互事件的处理

GLS虚拟仪表移植到OSG环境后,它并不能自动捕获并处理用户交互事件,因此如果需要它响应用户的交互事件,就需要在OSG中将交互事件转发给GLS虚拟仪表进行处理,这可以通过事件处理器实现。

在OSG中,从osgGA::GUIEventHandler派生一个事件处理器GlsEventHandler,重载其handle函数可以截获到所有的用户交互事件,但是截获到的事件是由OSG定义的,GLS并不能理解这些事件的意义,因此必须将OSG事件转换成GLS本身的事件格式,然后才能由GLS处理。其关键实现代码如下:

4. 一些其它问题及解决方法

4.1. 鼠标事件的投影点击问题

鼠标事件的投影点击问题出现在VEGA PRIME GL Studio Plug in version 2.6中。此问题描述如图4所示,当用户在视口a位置点击鼠标时,用户的本意是按动仪表1左下角的b按钮,如果此时仪表2左下角的c按钮恰好处于仪表1后面并且在鼠标点击方向上,那么此时按钮c的动作也将被触发。在使用GLS虚拟仪表构建前后双座舱的飞机仿真系统时,这个问题特别严重,很可能导致在后舱进行鼠标操作时反而错误地触发前舱虚拟仪表的动作。

Figure 4. Click projection of mouse events

图4. 鼠标事件的点击投影问题

这个问题解决方案如下:在分发鼠标事件之前,先以鼠标点击位置为端点,以垂直于视口向内的方向构造一条射线(即上图中以a为端点指向c点的射线),然后使用此射线与场景中的对象(包含GLS虚拟仪表对象)进行相交检测并且按照交点位置的远近进行排序,如果最近的相交对象是GLS虚拟仪表对象,那么则将事件分发到这个最近的GLS虚拟仪表对象,否则事件将不会被分发和处理。

4.2. 场景中仪表的位置和姿态

将包含虚拟仪表的GLSGeode对象加入到场景图中,OSG就可以渲染GLS虚拟仪表并与之交互。那么如何将虚拟仪表放置在场景中的合适位置呢?这可以通过合理的组织OSG场景图实现。某飞机仿真训练系统的场景组织如图5所示。其要点是首先构造一个osg::Transform变换节点,并将GLSGeode对象作为变换节点的子节点加入到场景图中,这样以来OSG在绘制GLSGeode对象之前,首先会将执行节点变换,节点变换将影响到OpenGL状态机当前的投影矩阵、模型视图矩阵和视口变换等,在GLSGeode:: drawImplementation绘制过程中可以得到OpenGL投影矩阵、模型视图矩阵、视口变换的值,并以这些值为参数绘制虚拟仪表,这样虚拟仪表的位置、姿态就受到osg::Transform变换节点的影响。从而可以通过设置osg::Transform变换节点的位置、姿态、缩放等在场景中合理的放置虚拟仪表。

Figure 5. Example of scene diagram organization structure of GLS virtual instruments

图5. 包含GLS虚拟仪表的场景图组织结构示例

5. 结论

Figure 6. Aircraft virtual cockpit constructed by GLS virtual instrument in OSG environment

图6. 在OSG环境中使用GLS虚拟仪表构建的飞机虚拟座舱

伴随着开源视景仿真软件的兴起,越来越多的飞行仿真、舰船仿真等软件开始采用OSG进行开发,本文通过分析GL STUDIO虚拟仪表的结构,针对Open Scene Graph视景渲染引擎的特点,在OSG环境下实现了GL STUDIO虚拟仪表对象的加载、显示、更新和交互。在某型飞机飞行仿真训练系统中,我们首先使用3D MAX三维建模软件制作了包含座舱内部细节的飞机三维模型,然后使用GL STUDIO对飞机的主要仪表板进行了建模和仿真,这些仪表板编译成动态库后,在OSG中通过集成插件将虚拟仪表贴合到三维座舱模型中并进行交互驱动,其座舱仿真效果如图6所示。实践表明该方法能够从GLS开发工具生成的动态库中加载虚拟仪表并进行显示、更新和交互,其渲染效果、渲染效率能够满足飞机仿真、舰船仿真的要求。

参考文献

[1] Kessenich, J., Sellers, G. and Shreiner, D. (2016) OpenGL Programming Guide. 9th Edition, OpenGL Architecture Re-view Board, 7.
[2] Martz, P. (2007) Open Scene Graph Quick Start Guide. Skew Matrix Software LLC, Louisville, 13-31.
[3] 王锐, 钱学雷. Open Scene Graph三维渲染引擎设计与实践[M]. 北京: 清华大学出版社, 2010.
[4] 孙艳丽, 王玲玲, 陈佳琪. 基于GL Studio的虚拟仪器仪表设计与仿真[J]. 系统仿真技术, 2015, 11(2): 151-155.
[5] 刘超慧, 韩晨, 魏家华. 基于GL Studio某型飞行训练模拟器导航界面的建模与仿真[J]. 舰船电子工程, 2018, 38(12): 114-117.
[6] Distributed Simulation Technology Inc., GL Studio Version 5.0 API Documentation. USA, 2014.
[7] Distributed Simulation Technology Inc., GL Studio User’s Guide. Version 5.0 USA, 2014.
[8] 李建海, 何青洋, 孙艳丽. 基于GL Studio的航空虚拟仪表设计[J]. 计算机与数字工程, 2017, 45(5): 999-1002.