吴 琦,卜祥报,卜凡亮
(中国人民公安大学警务信息工程学院,北京 102623)
侦查人员在进行犯罪案件过程分析时, 都是利用现场勘验采集的二维图像信息与案件现场的描述文字,这种传统的方法缺乏直观性和形象性,不利于案件侦破。案件过程的动态反演系统可以对案件过程进行三维仿真,有助于侦查人员对案情的了解。动态反演技术是20世纪末发展起来的新技术,能够实现对某场景或某事件发生发展过程的动态重现,且能够对重现的场景状态进行全视角观察。在国外警务工作中,动态反演技术已被应用到现场勘验、案件侦破、灾害事故等的过程重现方面。国内公安机关对动态反演技术的开发与使用重视程度还不高。目前常用动画制作软件主要有flash、maya、3ds max等,利用这些软件虽然可以制作出形象逼真的人物动画,但这些软件侧重于模型的建立,对模型的运动控制相对薄弱[1],不能满足公安工作的需求。因此,针对公安工作特点而开发的动态反演系统,需要综合考虑模型建模与模型控制两方面因素。人物模型是案件过程动态反演系统中使用最多的三维模型,因其结构的复杂性又使它成为最难构建的一类模型。
本文重点研究案件过程动态反演中人物骨骼模型的构建与数据载入。结合公安工作现实需求,利用专业建模软件3ds max构建人物骨骼模型,并将其载入到基于OpenGL绘制的三维案件场景中,实现案件过程的动态反演。
人体骨骼是一个十分复杂的结构,由200多块骨骼组成。骨骼与肌肉、皮肤等组织共同完成人的行为动作[2]。人物骨骼模型的组织结构根据使用领域的不同而各有特点,但都是参照人体骨骼运动原理,构造一副骨骼层次架构。驱动骨骼,实现三维人物模型运动。
在能够说明案件人物基本行为动作,重现案件发生发展过程的情况下,动态反演系统中使用的人物骨骼模型层次架构应尽可能简单。图1所示为本文所使用的人物骨骼模型结构。人物的动作大多集中在四肢,身体主躯干的运动在案件分析时可以忽略。为了简化模型构建与缩小数据量,将模型头部、胸部、腹部合为一体,形成所示的“士”字结构,此结构为人物模型的根骨骼节点,决定了模型的位置与朝向。其上连接四个子骨骼链,分别为左、右上肢和左、右下肢。模型上、下肢骨骼链为方向相反的同一结构,由图2可以看出,每个子骨骼链由三个互为子父的骨骼组成,手与脚的结构则简化为一个节点。
图1 简化骨骼模型
图2 骨骼模型层次结构
根据简化的骨骼模型结构,利用3ds max中骨骼建模工具对简化的骨骼模型进行构建,步骤如下:
首先,建立人物模型主躯干结构,并将其组合为一体,如图3(a)所示。其次,创建四肢骨骼链结构,为其添加反向运动学的“HI IK解算器”,如图3(b)所示。最后,将四肢骨骼链与模型主躯干相链接,完成人物骨骼模型的构建,如图1所示。
图3 人物骨骼模型构建
在案件过程的动态反演系统中,所需人物骨骼模型动作简单,不追求其观赏性与艺术性,能够正确演示人物普通动作即可,如:行走、跳跃、射击、跌倒等。在3ds max中,选择使用“设置关键点”模式对人物骨骼模型进行动画设置,手动调整每个关键点,根据案件动态反演需求控制当前帧模型的动画形态[3]。如图4所示,为同一模型设置不同的运动数据。
图4 人物骨骼模型的动画设置
数据载入的基本思路是将3ds max、maya之类的工具以直观的方式建立的物体模型保存成特定的文件格式,再用专门的解码工具将模型转换成一系列的节点(node),使OpenGL能够正确显示。解码工具有三类:插件、工具软件、程序库[4]。为了使动态反演系统各功能模块更易于开发利用,本文使用程序库的方法,创建模型数据载入模块,人物骨骼模型为.3ds格式文件,该格式能够存储模型的动画数据,且易于读取。
3ds文件格式是由块组成的树形层次结构,每个块结构由两部分组成,块信息(占用6个字节)与块内容(大小由所载内容而定)。块信息又分为两部分,块ID(占用2个字节)和块长度(占用4个字节)。根据块ID确定了一个层次结构,又根据块的长度可以确定下一个块的起始位置(块的长度减去6就是块内容的长度)。正因为块的这种结构特点,在读取模型数据过程中可以跳过那些不需要的块,直接获取所需的模型信息,提高工作效率[5]。由表1可以看出各个块结构所含的模型信息。
(1)自定义模型文件数据格式。
struct Lib3dsFile {
表1 各块ID代表信息
Lib3dsDword mesh_version; ∥网格版本
Lib3dsWord keyf_revision; ∥关键帧版本
char name[12+1]; ∥文件名
Lib3dsFloat master_scale; ∥比例值
Lib3dsVector construction_plane; ∥顶点
Lib3dsRgb ambient; ∥颜色信息
Lib3dsShadow shadow; ∥阴影信息
Lib3dsIntd frames; ∥动画帧信息
Lib3dsIntd segment_from; ∥由上层结构获取的数据
Lib3dsIntd segment_to; ∥向下层结构传递的数据
Lib3dsIntd current_frame; ∥当前动画帧信息
Lib3dsMaterial *materials; ∥材质信息
Lib3dsMesh *meshes; ∥网格信息
Lib3dsNode *nodes; ∥节点信息
};
(2)对人物模型数据进行读取操作,使其存储在(1)中定义的格式。
∥载入3ds数据文件,filename为文件存储路径。
Lib3dsFile* lib3ds_file_load(const char *filename){
FILE *f;
Lib3dsFile *file;
Lib3dsIo *io;
∥以读写的方式打开模型文件。
f=fopen(filename,"rb");
∥如果未能正常打开模型文件,则返回数值0。
if (!f) {
return(0);
}
∥创建并返回一个自定义结构的文件格式,如果未能创建返回NULL。
file = lib3ds_file_new();
∥如果未能正确创建,则关闭文件。
if (!file) {
fclose(f);
return(0);
}
∥创建一系列用于输入输出的函数,io为指向这些函数的指针。
io = lib3ds_io_new(
f,
fileio_error_func,
fileio_seek_func,
fileio_tell_func,
fileio_read_func,
fileio_write_func
);
∥如果未能正确创建,则释放模型文件对象及其所有资源,关闭文件。
if (!io) {
lib3ds_file_free(file);
fclose(f);
return(0);
}
∥读取模型文件数据进入自定义格式对象中,如果成功返回真,失败则执行if语句。
if (!lib3ds_file_read(file, io)){
free(file);
lib3ds_io_free(io);
fclose(f);
return(0);
}
∥释放io指向的输入输出函数。
lib3ds_io_free(io);
∥关闭文件。
fclose(f);
∥返回读取的文件。
return(file);
}
(3)应用显示列表在OpenGL的场景中绘制模型。
∥因为3ds数据结构为树形结构,所以递归调用render_node函数,循环绘制每个节点。
render_node(Lib3dsNode *node){
ASSERT(file);{
Lib3dsNode *p;
for (p=node->childs; p!=0; p=p->next) {
render_node(p);
}
}
……
∥调用显示列表
if (mesh->user.d) {
Lib3dsObjectData *d;
glPushMatrix();
d=&node->data.object;
glMultMatrixf(&node->matrix[0][0]);
glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]);
glCallList(mesh->user.d);
glPopMatrix();
if( flush )
glFlush();
}
(4)关键帧数据的调用
timer_cb(int value){
∥标记当前窗口需要重新绘制
glutPostRedisplay();
∥控制模型动画帧循环,超出后返回第0帧
if (!halt) {
current_frame+=1.0;
if (current_frame>file->frames) {
current_frame=0;
}
∥计算当前帧下模型节点的数量
lib3ds_file_eval(file, current_frame);
∥定时器的回调函数
glutTimerFunc(10, timer_cb, 0);
}
}
在3ds max中设计制作完成骨骼动画后,将其载入动态反演系统框架中进行演示。为了提高模型的重复利用率,不在模型制作阶段进行骨骼蒙皮,而是在最终制作案件过程动态反演时根据需求为模型绑定蒙皮。因此,本文只进行骨架层次结构与动画数据的载入。
在Visual Studio 2010中建立Win32控制台应用程序,用OpenGL图形接口创建案件三维场景。根据案件重建需求,在场景中选择添加地面以及全景图。载入模型数据,通过鼠标与键盘的操作,可以控制不同视口观察模型的运动过程。系统运行仿真结果如图5所示。
仿真结果表明,创建的人物骨骼层级模型结构简单,易于读取和显示。模型动画流畅真实,在程序中加入计算帧率的代码,显示动画每秒达到60帧,且没有出现一般模型动画中人物在地面滑行的情况。模型与案件场景融合较好,能够正确、直观地分辨出模型动作,完全可以满足案件侦查人员对案件分析、汇报等工作的需求。本实验仿真中对模型的控制操作较少,仅能实现对摄像机视角的控制,不能随意切换模型动作,设定模型初始载入点与朝向。实验程序只能载入一个模型,还不能满足对于多人作案、有受害人等情形的案件过程重现。本文的数据载入是将所有模型数据作为一个整体载入到场景中,且是在Win32控制台应用程序中实现的。创建案件过程动态反演系统中的模型数据载入模块,还需要进一步将其与MFC应用程序框架相结合,优化操作界面,增加系统交互性,并将数据载入细分为静态模型与模型动画两部分,添加更多的案件资料,充实动态反演系统。
图5 动态反演人物骨骼模型显示
本文主要讨论了公安领域所需动态反演人物骨骼模型的结构特点、制作方案,以及模型数据的载入方法。创建了特点鲜明的人物骨骼模型,并为其设定了基本人物特征动作,实现了在动态反演系统窗口的显示。本文提出的方法与思路,能够初步满足案件过程的动态反演系统需求,为科学办案提供技术支撑。但该方法还存在一些不足,以后的研究主要集中在正确读取与显示绑定蒙皮的人物骨骼动画模型,多个动态模型多次添加,以及对载入的人物模型进行运动控制等方面。
[1]和平鸽工作室.OpenGL高级编程与可视化系统开发 系统开发篇[M].北京:中国水利水电出版社,2005:1.
[2]王晓.角色动画在游戏中的设计及实现[D].上海:上海交通大学,2012.
[3]王珂.全视频3ds Max动画设计与制作深度剖析[M].北京:清华大学出版社,2013: 2-5.
[4]游资网. OpenGL 入门教程(七)[EB/OL].(2006-04-13).[2014-03-31].http:∥dev.gameres.com/Program/Visual/3D/OpenGLTutorial/OpenGL_7.htm.
[5]The Labs. Com. 3D Studio File Format (3ds) [EB/OL].(2013-10-11).[ 2014-03-31]. http:∥www.the-labs.com/Blender/3dsspec.html.