分类: LINUX
2011-12-16 21:28:03
骨骼动画的实现思路是从我们人的身体的运动方式而来的(所以VR就是对现实世界的虚拟嘛 :-))。动画人物的身体(肉、皮肤)是一个网格(Mesh)模型,网格的内部是一个骨架结构。当人物的骨架运动时,身体就会跟着骨架一起运动。骨架是由一定数目的骨骼组成的层次结构,每一个骨骼的排列和连接关系对整个骨架的运动有很重要的影响。每一个骨骼数据都包含其自身的动画数据。和每个骨架相关联的是一个“蒙皮”(Skin)模型,它提供动画绘制所需要的几何模型(Vertex,Normal,etc)和纹理材质信息。每个顶点都有相应的权值(Weight),这些权值定义了骨骼的运动对有关顶点的影响因子。当把动画人物的姿势和全局运动信息作用到骨架上时,这个“蒙皮”模型就会跟随骨架一起运动。如下图所示:
所以关键是对骨架进行动画生成,生成的方法也是用关键帧。关键帧动画是对人物的网格(Mesh)模型采用关键帧生成动画;而骨骼动画则是对人物的骨架采用关键帧生成动画,然后再让网格(Mesh)模型跟随骨架运动。关键帧动画实现的2个关键点是:关键帧的选取和中间帧的插补。
关键帧的指定有2种基本的方法:前向动力学(FK)和逆向动力学(IK)。前向动力学用一组节点的角度来找到末端受动器的位置;而逆向动力学则是找到将末端受动器置于所要位置所需的一组节点角度。前向动力学的优点是:计算简单,运算速度快,缺点是:需指定每个关节的角度和位置,而由于骨架的各个节点之间有内在的关联性,直接指定各关节的值很容易产生不自然协调的动作;逆向动力学的优点是:只需指定主要关节点的位置,负担轻,缺点是:计算模型比较复杂,开发者需要机械运动和动力学、几何学以及向量数学等方面的相关知识。
中间帧的插值分2步:(1) 根据当前时间,通过插值计算出每个骨骼的旋转、平移等值,形成中间帧的骨架。插值算法一般采用四元数(Quternion)的球面线性插值(Spherical linear interpolation)SLERP,SLERP特别适合在两个方位之间进行插值,不会出现像对欧拉角插值那样出现万象锁的现象,而且这种插值能产生更平滑和连续的旋转,表达方式也很简洁;(2) 根据骨架的变化情况,插值计算出骨架的“蒙皮”模型的各个顶点的位置变化。对于某个特定骨骼,“蒙皮”模型的顶点变换矩阵=初始姿势的变换矩阵的逆×姿势变换后的矩阵。另外还要考虑顶点可能受多个骨骼运动的影响。这时我们对每个与当前顶点相关联的骨骼,将其运动姿势变换矩阵×当前顶点相对于该骨骼的偏移向量×该骨骼对当前顶点的影响因子(即权重Weight),对所有与当前顶点相关联的骨骼都这么处理,然后相加,就得到当前顶点的新位置。
由此看出,如何设置各关键帧的骨架的各节点的位置和骨骼的转向(也就是骨架的POSE)是其中的关键,有2种方法:一种是由动画师手工放置,这个对动画师的技术要求就比较高,要求动画师对现实生活中的人和动物等的动作有细心的观察。否则设置的骨架动作就会不自然、不协调;另外一种是基于运动捕捉(Motion Capture)的方法,就是在人的各个关节处安置运动捕捉传感器,当人做各种动作时,捕捉仪器就将各节点的位置数据记录下来,这样我们就可以根据这些节点数据进行骨架建模。由于这是捕捉的真实的人的动作,所以这种方式得到的动画就很自然、很真实,但捕捉仪器造价昂贵,国内估计只有很少几家有财力的游戏公司才购置了这些设备吧。
目前有好多3D模型格式支持Skeletal Animation,像Microsoft的.X格式、MilkShape的MS3D格式、Half Life的MDL格式、ID Software的MD5格式等。我准备首先研究一下MS3D格式,因为它有公开的格式说明文档,阅读起来比较容易,而且应用很广。当然,首先要深入学习Skeletal Animation的底层技术,打好坚实的基础,呵呵!