http://www.paper.edu.cn
一种基于OpenGL的三维人体运动模型实现
陈忠1,赵学辉2,孙秋瑞1
1.北京师范大学信息科学与技术学院,北京(100875)
2.北京师范大学教育技术学院,北京(100875)
E-mail: Coocoochen@163.com
摘 要:随着计算机图形学的发展,虚拟现实技术已成为当前最为流行的研究领域之一,而虚拟人物造型及人体骨骼动画则是虚拟现实技术中一大难点。OpenGL是目前广泛流行的一种三维图形编程接口,在传统方法中,利用OpenGL对人体动画进行模拟时,由于OpenGL是基于顶点坐标和面片的操作,需要保存动画中每一个关键帧的顶点及面片信息,所以通常要进行大量的计算。而BVH格式的文件提供了关于人体关节的运动信息,这将大大减少动画的计算量。本文提出了一种基于BVH文件格式的模型实现人体动画的技术,并给出实验结果。
关键词:骨骼动画;OpenGL;关键帧;BVH 中图分类号: TP31
1. 引言
OpenGL是一个强大的三维图形开发接口,它可以利用几种基本的图形元素构建任何三维模型[1],但在进行复杂的三维建模时,直接使用OpenGL中的图元绘制函数或曲面绘制命令是不太现实的,尤其涉及到复杂的动画模型时,而人体运动模型则是一种复杂的三维动画模型。因此,一般情况下可以利用目前较为流行的三维建模工具,如3DMAX,MAYA等软件进行建模,再在OpenGL中读取模型,这样就可以减少编程的工作量,为日后修改模型提供了方便。在传统的三维动画构建中,通常采用基于关键帧动画的技术来实现,而关键帧动画涉及大量的顶点及面片信息,存储和计算量庞大。而骨骼动画不需要像关键帧动画那样存储每一个顶点数据,它只需存储每一帧的骨骼信息,因此大大减少了动画模拟的计算量。因此,针对传统方法的各种缺陷,本文提出一种基于骨骼模型的人物运动模型的算法,通过读取BVH格式文件的动画模型,实现对人体动画的模拟。
2. BVH文件介绍
BVH是Biovision Hierarchy的缩写,它是由Biovision公司开发的一种描述动作捕获的数据文件格式[2]。这种文件描述的人体动画十分逼真,因为它可以通过真实的人体模特穿上带有传感器的特殊衣服捕获动画[3],这就比用软件制作出来的动画更为形象逼真;BVH文件来源也相当广泛,且易于制作,它可以利用3DMAX、POSER等软件制作;此外,这种文件是以文本形式存储的,因此操作简单,容易开发。
2.1 BVH文件的结构
BVH文件由两个部分组成:骨架信息和关键帧数据块。
骨架信息按树型结构组织,定义了从根“ROOT”节点到终端节点“END SITE”的数据描述,包括各节点的偏移信息和旋转度。对于根节点,还包含X,Y,Z坐标,即模型在三维场景中的坐标值;对于非根节点,则只含有偏移量和旋转度,偏移量是指该节点针对它的父节点的偏移位置。骨架信息以关键字“HIERARCHY”开头,然后定义根节点,再定义根节点下的每一个子节点。根节点无父节点,每一个非根节点只有一个父节点,可以有0个或多个子节点。“OFFSET”关键字用来定义本节点针对父节点的偏移量,根节点的x、y、z三个坐标的
- 1 -
http://www.paper.edu.cn
偏移量均为0。接下来是关键字“CHANNELS”,它给出了关于channel的个数和名称,对于根节点,它由6个channels组成,分别为:Xposition,Yposition,Zposition以及Zrotation,Xrotation和Yrotation。它们分别表示根节点在三维场景中的XYZ坐标位置以及在Z轴、X轴和Y轴上的旋转分量。对于非根节点,只有3个channel值,非根节点只需要记录旋转分量而无需记录节点在三维场景中的坐标位置,因为非根节点的坐标位置可以通过计算父节点的位置以及本节点针对于父节点的偏移位置和旋转分量来获得。当定义完一个节点后,可以用关键字“JOINT”定义子节点。而对于没有子节点的终节点,其标识关键字为“END SITE”。理论上,一个节点可以拥有无穷个子节点[2]。
数据块则用来存放运动帧信息。数据块以关键字“MOTION”开始,关键字“FRAMES”定义了帧数,“Frame Time”定义每一帧的播放时间,如0.03333则表示采用每帧播放0.03333秒,即每秒播放30帧。接下来就是每帧的实际数据,它对应了骨架信息提供的每一个节点。对于根节点来说,平移量为OFFSET与MOTION定义的平移量之和,对于子节点,平移信息来自骨架信息中的OFFSET,而旋转信息则来自MOTION定义的数据部分,叶子节点没有旋转分量。下图给出了一个BVH文件例子。
图1 BVH文件样例
- 2 -
http://www.paper.edu.cn
2.2 BVH文件定义的骨架结构
一个完整的BVH文件所描述的人体骨架结构如图2所示:
图2 人体骨骼模型
其中,根节点为Hip,它控制整个模型在三维场景中的坐标位置,其它节点的位置可以通过计算与该节点的偏移量和旋转度计算获得。
3. 骨骼模型的计算
要正确计算当前节点在场景中的位置,需要使用变换矩阵模型[4]。一个顶点的当前位置v通过与变换矩阵M相乘后得到目标位置v’,可以用公式(3.1)来表示:
v’=M×v (3.1)
模型中的每一个骨骼都包含平移以及旋转信息(BVH文件不包含缩放信息,因此在这里不讨论缩放的处理),将它们组合就可以形成最终的变换矩阵M,变换矩阵M的计算公式如下:
M=T×R (3.2)
公式(3.2)中,T表示平移矩阵,R为旋转矩阵。 因此,节点v的目标位置计算可以通过公式(3.3)表示:
- 3 -
http://www.paper.edu.cn
v’=T×R×v (3.3)
由BVH文件所描述的骨骼模型是一种树型结构,除根节点外,每一个关键帧数据中它并没有给出节点在三维场景中的绝对位置,所有的非根节点在三维场景中的位置都是通过计算其相对于父节点的旋转度及偏移量,再乘以父节点当前的模型矩阵获得的,而父节点的位置则又是通过父节点的OFFSET和ROTATION及父节点的父节点模型矩阵计算出来的……如此回溯,直至找到根节点。那么,模型中所有节点在场景中的目标位置v’计算如下:
v’=M×Mparent×Mgrandparent….×Mroot×v (3.4)
4. 骨骼模型的算法实现
针对BVH文件给定的骨骼模型,可以建立如下数据结构进行描述: struct Node //定义节点信息 {
float offX,offY,offZ; //存储三个偏移分量 float xRot,yRot,zRot; //存储三个旋转分量
class Bvh //定义BVH骨架模型类 {
public:
};
定义好骨架模型的数据结构后,便可以通过调用ReadSkeleton()函数读取BVH文件,生成模型的静态结构,最后调用Draw()函数绘制骨骼模型,在Draw()函数中调用递归函数DrawRecursive()完成对整个骨架树模型的绘制。在绘制骨骼模型时,可以通过调用OpenGL的glTranslatef()函数以及glRotatef()函数来完成模型矩阵的变换运算。另外,在绘制每个骨架节点时需要注意将当前的模型视图矩阵进行压栈操作,以免影响后续不受当前节点影响的节点在场景中的位置,完成所有子节点绘制后,再将视图矩阵还原。OpenGL中对当前模型
- 4 -
};
Node *Parent; //存储所在节点的父节点 String NodeName; //节点名称
Vector Children; //存储当前节点的所有子节点Node *Root; //存储根节点
int FrameLocation, curFrame; //存储运动帧信息(帧信息所在位置、当前所在帧) float FrameTime; //每帧显示的时间 bool LoadFile(String &); //导入BVH文件 Bvh(); //构造函数 ~Bvh(); //析构函数 void ReadSkeleton(); //读取骨骼信息 void ReadFrame(); //读取运动帧信息 void Draw(); //绘制骨骼模型
int FrameNumber, FrameLength; //帧数、每帧长度
http://www.paper.edu.cn
矩阵压栈和出栈的函数分别是glPushMatrix()和glPopMatrix()。完成模型绘制的算法采用递归的方式实现:
void DrawRecursive(Node *n) { }
以上是实现该骨骼动画模型的关键数据结构和算法,此外,还需要对OpenGL进行相应的设置,如视口、光照、材质等,通过调用相关的OpenGL函数即可实现。
glPushMatrix(); //将当前模型视图矩阵压栈 glRotatef(n->xRot, 1.0f,0.0f,0.0f); // x轴上的旋转变换 glRotatef(n->yRot, 0.0f,1.0f,0.0f); // y轴上的旋转变换 glRotatef(n->zRot, 0.0f,0.0f,1.0f); // z轴上的旋转变换
for(int i=0;iChildren.Len; i++) //遍历当前节点的所有子节点DrawRecursive(n->Children[i]); //对所有子节点递归调用绘制函数
glTranslatef( n->offX,n->offY,n->offZ); //对视图矩阵进行平移变换
glutSolidSphere(1.0,20,16); //绘制当前节点(这里用点阵模型) { }
glPopMatrix(); //还原视图矩阵
5. 程序实验结果
运行采用本文算法编写的程序,其结果如图3和图4所示,两个图分别给出了该骨骼动画的的点阵模型及火柴棒模型表示。
图3 点阵模型中截取的四个关键帧
- 5 -
http://www.paper.edu.cn
图4 火柴棒模型中截取的四个关键帧
6. 总结与展望
由于三维骨骼动画的一些优势,如存储和计算量小、易于制作、生成动画逼真等,骨骼动画的应用相当广泛,在3D游戏、影视动画、虚拟现实等方面的应用十分普遍,这也是目前动画技术的一个重要分支。
本文对骨骼动画以及基于BVH文件格式的骨架模型进行了深入探讨和研究,提出了一种基于该模型格式的算法,并给出了实验结果。在此基础上,可以对该模型加以改进,对骨架模型进行蒙皮,并作纹理贴图处理,就可以形成真实感较强的人物模型。这也将是作者今后进一步研究的内容。
参考文献
[1] Dave Shreiner. Mason Woo. Jackie Neider .Tom Davis著,徐波 等译.OpenGL编程指南[M]. 北京:机制工业出版社,2006.
[2] M.Meredith, S.Maddock.Motion Capture File Formats Explained [Z] . Department of Computer Science, University of Sheffield, 2001.
[3] 朱强,张越挺,潘云鹤. 基于紧身衣的人体动画研究[BD/CD] .软件学报,2002. [4] 徐明亮 卢红星 王琬 著,OpenGL游戏编程[M]. 北京:机械工业出版社,2008.
[5] James D. Foley, Andries van Dam, Steven K. Feiner & John F. Hughes. Computer Graphics: Principles and Practice[M] . Addison-Wesley, 1990
- 6 -
http://www.paper.edu.cn
An Implementation of Human Animation Based on
OpenGL
Chen Zhong1, Zhao XueHui2, Sun QiuRui1
1.College of Computer Science and Technology, Beijing Normal University, Beijing (100875)
2.College of Educational Technology, Beijing Normal University, Beijing (100875) Abstract
As the development of computer graphics, virtual reality has become one of the most popular research fields, to create a human animation model is a difficult task. OpenGL is widely used 3D graphical interface for programming. Traditionally, people use OpenGL to simulate human animation. But OpenGL is based on vertices and faces, so every key frame needs to save the information of all these vertices and faces. Thus, large amounts of calculations are necessary. The BVH file supports a simple skeletal model to complete such work, and it needs much less information to store and calculate. In this article, an algorithm to implement human animation by BVH model is proposed, and the result of the application is given too.
Keywords: Skeletal animation; OpenGL; key frame; BVH
- 7 -