首先来讲布,第一个问题是:为什么要模拟布的运动?游戏中很多地方都有布,那么目前大部分的做法是什么样的呢?目前大多数游戏所采用的方法是对布建立骨骼,然后由美工针对每个动作做不同的布料骨骼动画,这种做法带来的弊端就是布料不会随着周围环境的变化来变化。比如说,周围刮来一阵风,或者骑在马上,披风不能披落在马背上,等等之类的。而且如果游戏中动作很多的情况下,针对每个动作都需要做不同的布料骨骼的调整,加大的美工的工作量以及工作复杂度,另外如果披风的骨骼的数目不多的话,还会导致即使是调出来的动作也会产生很不美观的效果。 OK,罗嗦了一大堆,那么我们要实现什么呢?我们要实现一套针对布料的物理系统,要求在没有风的情况下,布料会受重力的影响,慢慢的飘落,并且在有风刮起来的时候,你的布要能“随风飘摆”。 下面来看看传统物理中,布料的模型。根据流体力学来说,布料上每个顶点的力可以用圣维南方程组来求,但是在数学里面来说,圣维南方程组是没有精确解的,那么我们就需来设计一种模型来求该方程的近似解。无数的物理高手,在模拟布的过程中,总结出了两套经典的模型,一套是“质点-弹簧”模型,另外一套是由微软中国研究院研究出来的“半钢体-复杂摆”模型,在我的布料引擎中所用到的是“质点-弹簧”模型,理由是该模型所存在的时间比“半钢体-复杂摆”模型要久很多,在稳定性,以及效率方面几乎没有风险。而如果采用“半钢体-复杂摆”,这还只是一个实验品,目前来讲还没有任何的应用,采用这种模型有一定的风险。 那么我们下面就来详细看看经典的“质点-弹簧”模型究竟是怎么样一回事: 物理模型选定之后,就需要我们来针对传送进来的顶点进行编程进行建模,一般的方法是将布料的顶点,按照从左到右,从上到下的顺序传递进来,然后按照布料的宽度来进行程序上的物理建模。当模型建立好之后,我们就需要每一帧对模型中的每一个质点进行物理运算: 另外来算弹簧的弯取应力,在矩形模型中,则是通过计算“上面质点”和“下面质点”的夹角以及“左边质点”和“右边质点”的夹角来乘以一个弯取应系数来获得一个以当前质点为圆,两个质点的距离为半径的圆在邻质点的切线方向的一个力。 到这里,布料的内力都已经计算完成了,那么就需要来计算布料所受的外力了。 至此,质点的内力和外力都计算完毕,那么接下来如果通过这个力来获得下一帧的质点的位置呢?首先根据质点的质量和合力的大小来获得一个带方向的加速度,这一步只需要将算出来的力乘以1/质点的质量,得到加速度之后,就可以根据vt = v0 + at来计算这一帧的速度向量,随后将当前质点在空间中的位置加上v * t就是下一帧的质点的位置。 至此,对于布的模拟已经完全搞定了,不用怀疑,就这么简单,但是目前所实现的东西还无法应用,为什么?很简单,因为还没有做布的碰撞,如果一块披风在人身上穿过来穿过去的,那么做不做布还有什么意义? 对布做精确碰撞检测?这是不可能的,如果你要这样做你的游戏将只有20帧不到的FPS,用AABB包围盒碰撞?你希望看到一阵风吹过来,你的披风贴在一个正正方方的“人”上面?那么这里就提出一个新的概念“椭球包围体”碰撞。注意,这里的椭球体是不存在的,只是一个数学模型,并不是由三角型等组成的,这种椭球体可以绑定在人物骨骼上,随人物骨骼的运动而动,比如说人的头,就是一个x-y-z轴相等的椭球体,髋骨,盆骨,肩胛骨等都可以比较好的用椭球体体现出来。 椭球体是个很有意思的东西,在做FPS类游戏的时候,要实现上下楼梯的效果,用椭球包围体碰撞就是个非常好的方法,而在这里,不是椭球体跟三角型碰,而是顶点跟椭球体碰。那么下面来看看究竟如何比较好的描叙,以及来使用一个椭球体: 椭球体的方程是: 至此,整个布料运算+椭球体碰撞的模型介绍完毕。 |
-
2006-09-15