cp的小屋

not yet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

     3D游戏中的骨骼动画一般都是由美术在3DMAX这样的软件中做好的,在游戏中直接播放,游戏逻辑除了播放速度外很难施加更多的控制。但是我们在一些游戏中看到人物的身体部位可以根据玩家的选择改变大小、粗细、长短,在一些游戏中NPC可以将头转向走过身边的玩家角色,目光始终注视着玩家,头也随着玩家角色的移动而转动。在《古墓丽影》中,劳拉拿着枪的手会自动指向目标,并跟随目标的移动而转动。这些功能的实现并不需要复杂的逆向动力学,只要通过游戏逻辑对角色局部骨骼的状态施加一些影响,进行一些修改就行了。

 

     本文不涉及骨骼动画的实现细节,仅就与本文主题相关的内容进行一些讲解,为了完全理解本文,并在自己的系统中实现这些功能,你需要非常清楚骨骼动画的实现细节。

 

     在骨骼动画中对骨骼变换矩阵的处理一般分为两步,第一步根据当前播放的动画和播放时间从动画关键帧中差值获得每一根骨骼相对于父节点的平移、旋转、缩放分量,第二步按照自上而下、从父节点到子节点的顺序遍历整个骨骼树,将每个节点的平移、旋转、缩放分量合成为一个变换矩阵,然后乘以父节点的最终合成矩阵作为本节点的最终合成矩阵。需要注意的是第一步差值的过程是在骨骼局部坐标空间的平移、旋转、缩放分量上进行,而不是将它们合成为矩阵处理。这样做的好处是当旋转用四元素表示时可以进行更加理想的差值,而如果对合成矩阵差值将存在某些缺陷。而且这些分量都有着清晰的几何含义,刚好方便了我们通过游戏逻辑来控制骨骼状态,因此我们对骨骼状态的控制是在第一步完成的,也就是说是在每个分量上完成的。由于第一步是在骨骼的局部坐标空间进行的,而游戏逻辑的控制量往往是在世界空间中给出的,这就需要把某些控制量转换到某根骨骼的局部坐标系中,比如将逻辑指定的NPC头部需要朝向的方向转换到头部骨骼节点的局部坐标系中。

 

     先说说比较简单的对角色某些部位进行缩放的控制,可以实现头部变大、变小,四肢变粗、变细、变长、变短之类的效果。如果我们想将头部变大到原来的两倍,那么我们找到头部的骨骼节点,得到它在第一步中差值后的三个变换分量,将它的缩放分量乘以2.0,这样最后显示出来的画面头部就放大了两倍。再比如我们想将人物的手臂拉长到原来的两倍,首先找到代表上臂、前臂的四根骨骼节点,如果在我们的系统中骨骼的x轴方向与手臂延伸的方向一致,那么我们只需要将缩放向量的x分量乘以2.0就可以使手臂伸长,如果要将手臂变粗,只要给手臂骨骼缩放向量的y、z轴乘以2.0而x轴分量不变就行了。

 

     对骨骼的方向进行控制就要复杂些了,还是举例说明。比如游戏逻辑希望角色的头部朝向方向vDir,根据前面说的我们要将vDir变换到头部骨骼的局部坐标空间去,这个过程涉及到头部骨骼父节点的最终变换矩阵的求逆,这个矩阵只有在第二步递归遍历的时候才能得到,因此这个控制放到第二步遍历到头部骨骼的时候。这个时候父节点的最终合成矩阵已经求得而头部节点矩阵还未合成,头部节点的变换还是以三个分量形式存在。假设我们得到了vDir转换到头部骨骼局部空间中的向量为vLocalDir,再假设角色头部朝向与头部骨骼的y轴方向一致。我们根据vLocalDir,以及当前头部骨骼的局部坐标系的x、y、z轴构造一个新的四元素rotExpect,这个新的四元素代表了将原骨骼局部空间中的y轴转向与vLocalDir一致后的新的局部坐标空间。此时如果我们用rotExpect作为头部骨骼的旋转分量进行后续的合成计算,那么画面上角色的头部就会指向我们希望的方向vDir。事情并未到此结束,如果我们对一根骨骼的旋转方向改动太大,那么出来的画面会很不自然,好像头被扭得太厉害,甚至看上去象扭断了。因此在上面步骤中会加入一个最大旋转角的限制,比如45度。当vLocalDir与原骨骼空间y方向的夹角小于45度时直接用rotExpect代替原旋转四元素,当夹角大于45度时就在原旋转四元素和rotExpect之间进行差值得到新的四元素rotExpectNew,这个四元素表示从原四元素转向rotExpect过程中转到45度时的方向。用rotExpectNew作为头部骨骼的旋转分量参与后续的矩阵合成画面上的角色就会尽量将头部转向vDir,但停在与原方向差45度角的地方,不会超过这个角度。为了让动作更自然,也更符合真实情况,象NPC目光注视指定方向这样的需求,我们不会只控制头部骨骼的转动,而是将视线需要转过的总角度(如60度)分摊给腰部、胸部、颈部、头部四根骨骼,如腰部10度、胸部10度、颈部10度,头部30度。这样分配后最后的画面非常自然,扭头的动作带动腰、胸、颈、头一起转动,并且四根骨骼的联合转动可以实现更大的旋转角度而不受单根骨骼最大旋转角度的限制。

 

     看上去并不太复杂,但实现细节很多,数学计算也需要十分严谨,错一点效果都差之千里。一个含义清晰、明确,简单易用的接口也很重要。

 

第一个是正常情况下的画面,第二个是通过游戏逻辑放大了头部的情况,第三个是通过逻辑拉长了四肢和颈部同时缩小了头部的情况

 

1、2、3为正面视角,4、5、6为从侧面看的视角

1、4为正常的站立姿势,2、5为游戏逻辑控制腰、胸、颈、头旋转使视线转向后上方的情况,3、6为逻辑控制视线转向后下方的情况

 

 

1、2、3为正面视角,4、5、6为从侧面看的视角

1、4为正常的跑步姿势,2、5为游戏逻辑控制腰、胸、颈、头旋转使视线转向后上方的情况,3、6为逻辑控制视线转向后下方的情况

posted on 2008-09-04 21:32  cproom  阅读(3477)  评论(6编辑  收藏  举报