Openflight API开发(MultiGen Creator)

     Openflight API是一个包含头文件和链接库的C语言库,它提供了访问Openflight数据库和Creator模型系统的接口方法。通过API可以进行Openflight模型的转换、实时的模拟仿真、自动建模以及通过插件的形式对Creator进行功能扩展。

整个API由四个模块构成:
Read: 读取,遍历和查询Openflight数据库中的元素;
Write: 写入,创建和修改Openflight数据库中的层级节点;
Extensions: 扩展,定制Openflight格式的文件,自定义扩展的数据结构以便给已存在的节点添加新属性或创建自定义节点;
Tools: 根据需求创建嵌入式的Creator插件

 

常用的API的自定义的数据类型包括:

mgstatus--只是程序运行状态的整型值,出错则返回非0,否则返回0;

mgrec--存储模型数据库中的记录集对象,一般是层级结构的节点;

mgcode--mgrec类型的整型标识符,每个mgrec对象具有唯一的整型值;

在编写独立的可执行程序时,调用API函数前必须先调用mgInit()初始化,即标志开始使用API库;所有API函数调用结束后必须调用mgExit()中止API库运行。

Openflight开发库提供可控的消息机制。应用程序的消息可以被截获并打印以提示代码的运行状态,并且该机制可以通过调用mgSetMessagesEnable(bool)被关闭或开启,这无疑为我们调试程序带来了极大的便利。在控制台或MFC环境下的可执行程序的调试中,可以利用mgGetLastError()截获出错处的消息并利用printf()或者MessageBox()实时地反馈给我们;而在Creator环境下则可通过mgSengMessage()在状态栏中提示程序的执行信息。

Openflight文件是以数据库格式存取的。API提供了数据库的新建、打开、保存、写入、关闭等方法。对于任意的记录集,均可以通过调用mgRec2Db方法转换成独立的数据库文件。

 

Openflight格式简介
OpenFlight格式及API OpenFlight是Multigen开发的,在视觉仿真领域最为流行的标准文件格式。OpenFlight采用几何层次结构和节点(数据库头节点、组、物体、面等)属性来描述三维物体,如图2.6所示。允许用户直接对层次结构及节点进行操作,保证从大型数据库到物体单个顶点的精确控制[19]。
它的逻辑层次结构及细节层次、截取组、绘制优先级、分离面等功能,使得图像产生器知道何时及如何绘制三维场景,极大地提高了实时系统的性能。

 

 

图2.6  Openflight数据库层级结构       
一个OpenFlight数据库的层次结构被作为一个文件存储在磁盘上。文件由线性的二进制流记录组成。字节在文件中的存储顺序是按照Big Endian方式存储的(即0x1234在内存中存储顺序为0x12 0x34)。所有的OpenFlight记录都是以4个字节序列开始的。序列的前两个字节标识了记录类型(opcode),后两个字节指明记录的长度。在这种结构规律下,OpenFlight记录很容易从磁盘中读取并加以分析[20]。
◇  所有的OpenFlight记录的长度都是4字节的整数倍。当一个记录不到4字节的整数倍时,会自动填补成4的整数倍。在某些情况下,OpenFlight记录被填补成8字节的整数倍。
◇  所有记录的长度(所有记录的值)同所有值的偏移值都是以字节为单位的。
◇   除非明确的说明,位域和掩码都是从0开始计算的(例如第一个位的位号为0)。
◇   除非明确的说明,矩阵记录的元素是以行为主要顺序存储在OpenFlight文件中的。
◇   所有OpenFlight记录的长度都被限制在能被2个字节或16个bit位(65535)表示的最大长度。对于长度固定的记录,这个最大长度是足够的。

 

Openflight文件的创建和读写方法
一个基本的完整Openflight文件创建读写算法流程如图2.7所示,主要包括程序初始化,创建数据库头节点,创建组节点和其他特殊节点,绘制几何节点,建立节点间的层级关系,写入并关闭数据库,程序退出等步骤。

Openflight文件读写流程
控制台主参数初始化->新建数据库头节->写入数据库mgWriteDb(db)->创建特殊节点(光、声…) (fltLight,fltSound,fltLod…)->赋予记录集属性(光照、声音…)->通过3维坐标创建顶点mgSetCoord3d->创建子面addVertex()->创建面集makePoly()->创建体节点fltObject->创建组节点 fltGroup->写入数据库mgWriteDb(db)

组件式开发方法
        Creator是商品化的虚拟现实建模工具,因此,软件源码是不可获取的。但是, 在Openflight API平台上可以通过“Plug_in”的方法对Creator的功能进行扩展。所谓“Plug_in”,就是 Creator的嵌入式组件。在Creator的加载过程中,除了加载Multigen公司提供的基本模块外,主程序亦会加载系统环境变量MPI_CREATOR_PLUGINDIR所指示的目录下的所有第三方的扩展模块,这些模块都是以动态链接的方式被Creator加载的。也就是说,只要通过Openflight API将需要的功能编译成动态链接库文件并放在Creator加载路径下即可以实现基于Creator平台的二次开发。
        Creator提供了六种插件形式的功能扩展[21]:
        ◇        数据库导入器:将不支持的数据库格式导入至Creator中
        ◇        数据库导出器:Openflight格式导出成外部数据库格式供其他应用程序使用
        ◇        图像导入器:将不支持的图像或纹理导入Creator中
        ◇        Viewer:相当于数据库的视图,可供查询但不能被修改
        ◇        Editor:修改数据库的编辑器
        ◇        输入设备:将外部输入设备获取的几何信息转换成Creator模型
        dll 文件可以被Creator加载,必须在编码阶段注意以下几点:
首先模块在编码阶段必须声明并注册,其形式如下:
mgDeclarePlugin(
/*开发者名称*/ MVENDOR_NUAACBT,   
/*插件名称*/ "My Plug_in",
/* UUID */ "8c1560c0-083d-11d5-91a0-006008a37a65");
其中UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。可以利用Visual Studio提供的Uuidgen工具生成这个独立的标识。
其次必须有dll入口函数的声明和初始化以供Creator加载模块时调用,同样的,相应的出口函数也必须被定义,它负责模块的中止和退出。其关键编码如下:
MGPIDECLARE(mgbool) mgpInit ( mgplugin plugin, int* argc, char* argv [] ){
moduleHandle = mgGetModuleHandle ( plugin ); //获取模块句柄
Resource = mgLoadResource ( moduleHandle ); //加载模块中定义的资源
initOk = InitMenu ( plugin, Resource, argc, argv ); //模块入口
}
MGPIDECLARE(void) mgpExit ( mgplugin plugin ){
           ExitPlugin ( plugin ); //中止模块执行
   mgUnregisterAllTools ( plugin ); //清空模块注册信息
   mgUnloadResource ( Resource ); //释放资源
}
        最后必须 定义启动功能模块的GUI(Graphic User Interface)环境。 所谓GUI,是指用户与Creator界面交互的接口,如菜单、对话框、工具条等。比如在Creator的Info菜单下添加名为“My Plug_in”的子菜单以实现自定义功能,关键编码形式如下:
mgbool InitMenu ( mgplugin plugin, mgresource resource, int* argc, char* argv [] ){
                   pluginTool = mgRegisterViewer (
                      plugin,  "MyPlugin",  StartMenuFunc,  //子菜单响应函数
resource,  MTA_VERSION,  "1.0",        MTA_MENULOCATION, MENU_INFO, MTA_MENULABEL, "My Plug_in",        MG_NULL);
                   return ( pluginTool ? MG_TRUE : MG_FALSE );
}
以上关键的步骤只是向Creator中加载了一个空的菜单项,要实现更多的交互功能,就要用到对话框、控件以及Creator内部的数据交换(DDX)机制。
对话框和控件是预先在工程的资源里定义的,可以利用Visual C++的资源编辑器创建对话框以及编辑框、进度条、单选和复选框、列表框等标准的Windows控件。但是 ,对话框和控件的交互机制却和Windows有很大的不同。 对话框分为如下几种类型[21]:
消息对话框:类似于Windows的弹出式警告框,通过调用mgMessageDialog实现
文件对话框:类似于Windows的文件打开保存对话框,通过调用mgPromtDialogFile直接创建并弹出
模态对话框:即Windows用于数据交换的通用对话框,其特点是不关闭则无法对程序继续操作,通过调用mgResourceModalDialog从资源文件创建并弹出。
无模态对话框:类似模态对话框,唯一区别在于不关闭可以对程序的其他部分继续操作,通过调用mgResourceGetDialog从资源文件创建,调用mgShowDialog弹出。
API也提供了大量操纵控件的函数,控件从工程的资源中获取后可以通过这些函数初始化或进行相应的变更。这和Windows的控件编程方法类似,具体不再赘述。
控件和主程序之间的数据交换机制是通过回调函数实现的。假如按下对话框中的一个按钮控件OK对应的操作是在函数OKisClicked()中实现的,那么可以定义这样的回调函数 OkCallback去实现操作:
if ( gui = mgFindGuiById (dialog, MGID_OK ) )  //返回标识为OK的控件
mgSetGuiCallback ( gui, MGCB_ACTIVATE, OkCallback,userData );
static mgstatus OKCallback ( mggui gui, mgcontrolid controlId,                                        mgguicallbackreason callbackReason, void *userData, void *callData ){
          switch ( callbackReason ){ //对控件回调消息的相应
                case MGCB_ACTIVATE:
                        if ( mgControlIdsMatch ( controlId, MGID_OK) )
                                OKisClicked();  //若按钮OK激活,则调用相应的操作函数
        }……



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值