您的位置:首页 > 其它

空间实体可视化组件的设计与实现

2013-04-10 21:50 246 查看
空间实体可视化组件的设计与实现
汪荣峰

摘要:实体是空间虚拟战场的重要组成部分。在深入剖析卫星工具软件包STK实体模型格式的基础上,设计了相应的数据结构,包括图元、命令、关节动作等;解决了解码和绘制模型所需关键技术,包括逆命令机制、纹理处理等;最后按照组件对象模型规范对其进行了封装。所实现的空间实体可视化组件与其他组件一起构成空间场景控件,支持快速构建空间战场可视化系统。
关键词:实体;STK模型;组件对象模型

在空间战场可视化系统中,卫星、空间站等实体是不可或缺的重要组成部分。虽然有一些研究基于自主开发或者其他平台可实现空间战场可视化,但是更普遍的还是借助于美国AGI公司的卫星工具软件包STK(satellite tool kit)来实现,如文献[3—4]。STK的一个重要优点是建立了丰富的空间任务相关实体模型,不仅支持模型静态显示,而且支持关节动作,如卫星帆板展开等。但该软件只适于对象数目不多、非实时的场合[5]。因此,有必要在自主开发的空间战场可视化系统中,应用STK中丰富的模型资源。

为应用STK模型,需分析并解决如下问题:①STK模型文件格式的剖析,需要分析大量技术细节;②数据结构设计,用于表示图元、变换、纹理、组件等各种要素;③模型加载,解决图元几何数据生成和纹理数据生成、模型树结构生成、命令和关节动作解析等;④模型绘制;⑤组件化封装,以便于应用。

1 STK实体模型分析

模型以文本文件的方式存储,相关文档中对其格式进行了简要描述,韩潮等[6-7]对于该格式的转化进行了研究。但现有信息并不充分,很多技术细节需深入剖析。为此,手工修改关键字参数,并利用STK的Modeler软件进行测试,进行大量试验和对比,剖析文件格式。

STK模型为树形结构,依赖2对关键字:Component和EndComponent之间包含一个组件,如一组件含Root关键字,则是树根;Refer和EndRefer定义引用,引用内可包含其他组件或图元,相当于指向子节点的指针。如一卫星模型结构如图1所示,卫星由卫星主体和左右帆板组成,主体又包括其他组件,左右帆板每个包括1~4级,每一级又均指向同一个包括最基本描述图元的组件。



STK模型包括8类图元:Cylinder、Extrusion,Helix,Polygon,PolygonMesh,Revolve,Skin、Sphere,每种图元具有相应参数,适于描述不同形状,如火箭箭体用Revolve描述。

模型利用几何变换将定义在各自局部坐标系的图元组合而成,支持的几何变换有4个:比例变换、旋转变换、平移变换和等比变换。图I中卫星帆板就是由同一个基本结构经过变换组合而成。与几何变换对应的还有纹理坐标变换,在纹理空间应用上述4个变换。

影响图元的另一重要因素称为参数,相当于状态设置,包括颜色、填充模式、透明度、纹理相关参数等,每种参数具有自己的语法形式。

模型支持关节动作,由Articulation和EndArticulation关键字定义。命令格式一致,形式为{命令,名字,最小值,当前值,最大值},支持的关节动作有:绕各个轴旋转、沿各个轴平移、各个轴向缩放、等比缩放,以及以上变换对应的纹理空间变换。

2 图元处理

2.1 图元类定义

针对图元定义基类,而8类图元由该类派生,所有图元需要的功能由基类实现,如顶点数据管理、包围盒计算等,而各类图元比较独立的部分由派生类处理,如解码、绘制等,图元类层次如图2所示。



2.2 关键技术

图元处理的核心是解码和绘制。绘制根据图元类型采用恰当方式完成,如Cylinder图元,其顶端和底端采用离散后的三角形扇绘制,圆柱部分采用四边形带绘制。

解码是绘制的基础和前提,解码根据输入数据流解析出各种数据,一般过程描述如下。

CStk3DPrimitive :: Decode( ){

图元数据初始化;

while(TRUE){

读入一行数据,解析关键字;

if(是图元结束关键字)   break;

else if(是本图元所需关键字)  按其含义处理;

else if(关键字是TxGen)   设置纹理产生标志;

else if(关键字是Articulation)   调用关节动作类的解码模块;

else   调用命令解码模块;}

生成各顶点法向数据;

if(纹理产生标志被设置)   生成顶点纹理坐标;}

多边形和多边形网格图元进行三角化;}

图元处理涉及如下关键技术:

1)图元顶点生成

不同图元具有自己的语法形式,如圆柱图元定义在Cylinder和EndCylinder关键字之间,给定的参数包括圆柱顶端和底端的半径、法线,圆柱面离散的个数,圆柱长度等,圆柱沿x轴方向定义,底部位于x坐标为0的平面上。解码过程就是根据以上参数,计算出表示该图元的离散多边形以及多边形每个顶点的过程。其他图元也需生成几何数据,其中Polygon和PolygonMesh图元可以直接得到顶点坐标。

2)法向计算

光照可以有效增强实体真实感,必须正确地计算法向。顶点法向的计算方法主要有几种:①Cylinder图元,顶面和底面采用数据中给定的法线,描述侧面顶点的法向则采用圆柱中心到该点的方向作为法向;②对于其他类图元,每个顶点的法向必须为该顶点相邻多边形法向的平均值,采用的方法是首先将每个顶点法向设为零向量,并且为每个顶点分配一个初值为0的计数器,然后遍历所有多边形,计算每个多边形的法向,归一化后加到该多边形所对应的每个顶点法向中,使对应计数器加1,最后所有顶点法向除以计数器;③Extrusion图元可能设置SharpEdges关键字,PolygonMesh图元可能遇到SmoothShading命令,在这2种情况下,法向不采用相邻多边形法向均值,而是根据所绘制多边形的法向来确定,因此其法向计算推迟至绘制时再进行。

3)纹理坐标计算

在8类图元中,PolygonMesh图元的纹理计算较为特殊,一种情况是模型数据中提供纹理坐标;另一种情况是定义了AutoGenTxCoord X(或Y、Z)关键字,此时要利用相应的坐标平面产生纹理坐标,如以上关键字中为X,则根据顶点Y、Z坐标生成纹理坐标。除了PolygonMesh之外的图元,如果定义了TxGen关键字,则需要根据图元本身的特征生成纹理坐标,如对于Cylinder图元,底端顶点纹理坐标u值都为0,顶端纹理坐标u值为1,v值根据离散个数由0至1。

4)三角化

对于Polygon和PolygonMesh图元,模型中数据构成的多边形可能为凹多边形,而OpenGL并不支持凹多边形,因此对于这2类图元,读人数据后需要将其转化为OpenGL支持的三角形或凸多边形。借助OpenGL辅助库中的镶嵌器(tessellation)来实现,该功能通过回调函数实现对三角化后数据的访问,一般将其封装在显示列表中。由于这项工作是在数据加载时完成,应避免和硬件相关,因此构造一个支持OpenGL中基本图元的类,而在回调函数中,取得三角化后数据并存储,以后绘制时再使用这些数据。

3 变换、参数、关节动作的处理

作用于图元乃至组件的有几何变换、纹理空间变换、参数设置、关节动作等。将变换和参数结合在一起,构造命令类,所有变换和参数设置由该类派生;关节动作与其类似,但是定义成另一个类。下面分析绘制时面临的问题,然后给出类层次与关键技术。

3.1 问题分析

目前的三维开发包如OpenGL可以认为是一个状态机[8],几何变换也可以认为是改变了当前变换矩阵(current transform matrix,CTM),纹理空间变换和状态变换也是如此。

树形结构对象的绘制,一般利用开发包所提供的堆栈进行递归调用完成绘制,其编程模型为
RenderNode( ){

glPushMatrix( );glPushAttrib( );

变换,改变状态;

绘制当前节点;

递归绘制子节点  RenderNode( );

glPopAttrib( );glPopMatrix( );}
以上方法非常简洁,然而由于堆栈深度与显示设备相关(如可能只支持32级堆栈),所以当表示实体树的层次超出了设备能力时(如树可能为36层),绘制将不正确。

解决上述问题的一个可行的办法是修改递归绘制方法为逐图元绘制:针对每个最终绘制的图元,构造一个新的数据结构,包括指向图元的指针和一个变换链表,这个链表包括由根节点到图元所在节点的所有变换;当模型中所有组件加载完毕构造出树状结构后,构造一个命令类堆栈,按深度优先顺序遍历树,遇到一个命令则将其输出到堆栈中;如果遇到一个图元,则生成一个新的数据项,将当前堆栈中所有命令按顺序输出到数据项链表中,并为数据项中的图元指针赋值;遍历后,所有数据项组织为一个数组;绘制时,访问数组中所有数据项,在每个数据项中,按顺序执行链表中的命令,然后绘制图元。该方法有大量的重复变换,效率很低,实验表明,其耗时平均在直接绘制的5倍以上。

3.2 命令与逆命令机制

为解决上述问题,构造了命令与逆命令机制:将变换、参数设置等都表示为命令,如平移命令、颜色设置命令、背面裁剪命令等,而每个命令有一个对应的逆命令,如平移命令的逆命令为反向平移同样距离。通过逆命令还原每个节点状态,而非借助堆栈操作,这样仍可以按树结构递归绘制,上述编程模型变为

RenderNode( )(

for(所有命令对象)  执行命令;

绘镧当前节点;

递归绘制子节点  RenderNode ();

for(所有命令对象) 执行逆命令;}

采用上述方法,既保持了绘制的效率,又解决了树层次过多时绘制的正确性问题。

3.3 命令类

命令类一共有19个派生类,分别对应STK模型中的如下关键字:BackFaceCull、FaceColor、FaceStyle、FrontFaceCCW、Rotate、Scale、Shininess、SmoothShading、Specularity、Texture、Translate、Translucency、TxDef、TxGen、TxScale、TxRotate、TxTranslate、TxUniformScale和UniformScale。

图3给出了其中的一部分命令类,其中的ExecuteByGL( )为执行命令,ExecuteByGLInv( )则表示执行逆命令,Decode( )在读人模型时进行解码,TransByOwn( )等用于计算各组成部分位置。



3.4 关节命令类

关节命令与命令类的含义类似,只包含几何变换和纹理空间的变换。实现也与命令类类似,由于所有的关节命令格式是相同的,因此其解码由基类进行,数据也组织在基类中。一共有20个派生类,分别对应于STK模型中的如下关键字:TxuniformScale,uniformScale,XRotate, XScale,XTranslate、XTxRotate、XTxScale、XTxTranslate,YRotate、YScale,YTranslate,YTxRotate,YTxScale、YTxTranslate、ZRotate、ZScale、ZTranslate、ZTxRotate、ZTxScale和ZTxTranslate。图4给出了部分类的层次。



4 其他关键技术

除了上面讨论的技术外,还涉及其他一些关键技术。

4.1 包围盒计算

当实体绘制在场景中时,需要根据实体的包围盒来确定其可见性、根据包围盒的投影选择绘制策略等,因此在模型加载时需要计算其包围盒,而这种计算应该是与设备无关的,不应该利用OpenGL中的变换矩阵。采用的方法是:定义一个当前变换矩阵(不是OpenGL中的矩阵,而是自定义矩阵),初始化为单位矩阵;按树结构遍历模型,对于每个几何变换,执行相应的变换和逆变换(图3中TransByOwn和TransByOwnlnv);遇到具体图元时,计算图元各个顶点与当前变换矩阵的积,改变包围盒数据。

4.2 纹理对象与纹理池

应用纹理涉及以下技术:①模型支持2种类型纹理,RGB和Alpha,分别用于表示颜色纹理和透明度,通过透明度可以表现诸如尾焰等效果,2种纹理的格式是一样的,采用的技术是将AIpha纹理和对应的RGB纹理组合在一起形成RGBA格式图像,然后再进行纹理映射;②纹理参数允许支持透明效果,此时选择纹理图像左上角像素的颜色作为透明色,纹理图像中任何与该颜色相同的像素都是透明的,采用的办法是:根据该透明色值将RGB格式的图像转换为RGBA格式的图像,再作为纹理使用;③纹理数据量较大,且经常存在多个图元使用同一纹理的情况,因此使用纹理对象使得纹理数据驻留在显存,避免主存和显存间频繁的数据交换;④由于纹理可在多个图元甚至多个模型间重复使用,因此需构造纹理池管理所有纹理,当需要使用纹理时,首先判断其是否已在纹理池中,再决定是否加载纹理数据。

4.3 组件的解码过程

组件是实体的基本组成,其解码过程为

CComponent : : Decode( )(

whilie(TRUE){
解码出当前行的关键字,遇到EndComponent结束;

if(关键字为8类图元的关键字)

读人数据流,直到遇到表示图元结束的关键字;

将数据流交由各类图元对象的解码模块进行解码;

else if(关键字为Refer)  读人数据后由CRefer类对象进行解码;
else if(关键字为Articulation)  读人数据由CArticulation类对象进行解码;

else交由命令类解码模块进行解码;}}

同样,引用类、命令类和关节命令类也有相应解码模块。

4.4 总的处理流程

应用模型的核心是解码和绘制,解码后可在任何需要的时候进行绘制,绘制过程已经在3.2节阐述,下面阐述解码时的流程。由于采用了定义良好的类层次,因此模型加载过程由各个类协作完成,协作依赖于向各个类传递数据流,模型加载的流程为

CSTKModel : : Decode( ){

打开文件,读人数据流;

while(1){

读人一行数据,遇到文件结束跳出;

if(数据中为Component关键字)

持续读入散据,直到遇到EndComponent关键字;

将以上数据流交由CComponent类对象进行解码;}

for(所有CComponent)

根据其Refer,建立树结构;

计算实体包围盒;}

5 组件化封装与应用实例

此处的组件指的是组件对象模型(component object model,COM)中的组件,而非STK模型中的组件。利用活动模板库(active template library,ATL)进行了封装,主要提供2个接口:IWStkEntityEnv接口主要是设置与环境有关的参数,包括设置纹理数据所在路径、是否启用纹理对象、是否启用显示列表、加载颜色表、设置视锥参数等;IWStkEntity接口则是用来设置空间实体对象的属性,包括设置实体模型文件名,设置实体位置、朝向、比例关系,设置实体关节动作参数等。利用该组件,开发了空间实体浏览软件,其界面如图5(a)所示;设计实现了空间场景可视化控件,空间实体可视化组件与传感器探测能力可视化组件、地球可视化组件、航天器轨道可视化组件等相互结合,快速构建空间场景,利用该控件实现的1个场景如图5(b)所示。





6  结束语

STK模型非常适于描述空间实体,目前已建立了大量的空间实体模型资源,包括各种型号的卫星、导弹、空间站等。在对其格式进行深入剖析及解决一系列关键技术的基础上,开发了空间实体可视化组件。以该组件作为重要组成部分的空间场景控件可方便地嵌入各种战场可视化系统中,从而使得开发者和用户可以脱离STK环境使用这些模型。需进一步研究的内容有:①目前组件接口通过设置关节命令参数的形式实现关节动作,下一步要支持基于脚本的关节动作;②加入基于粒子系统的特殊效果。

参考文献(References)

[1]郑娟,姜振东.空间战场可视化系统的设计与实现[J].计算机仿真,2005,22(1):36—39.

[23唐凯,康风举,楮彦军,等.一种空间战场视景仿真系统的开发[J].系统仿真学报,2004。16(11):2435-2437.

[3]徐凯川,朱隆魁,郑伟。等.STK在空间作战系统仿真中的应用[J].计算机仿真,2007,24(5):47-49.

[4]张万鹏,陈绿,沈林成.基于STK/VO的航天任务视景仿真系统[J].计算机仿真,2005,22(10):82—85.

[5]张占月,狳艳丽,曾国强.基于STK的航天任务仿真方案分析[J].装备指挥技术学院学报,2006,17(1):48—51.

[6]宋殿宇,韩潮.关于在VRML技术中应用STK模型的研究[J].计算机仿真。2004,21(10):22—25.

[7]韩潮,曲艺.OpenInventor在STK模型转换中的应用[J].计算机仿真,2005,22(10):63—66.

[8]SHREINER D,WOO M,NEIDER J,et al.OpenGL program—ming guide[M].6”ed.America:Addison-Wesley Profes—monal,2008:9.10.

更多STK学习资料免费下载:

http://download.csdn.net/user/appe1943
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stk