物理引擎Havok教程(三)
物理组件初探
作者:上官婉儿
这一期将初步介绍Havok最重要的一个组件Physics组件。这个组件主要做刚体物理学的模拟。这一期讲一下它的工作原理和流程。
1.它是如何工作的?
在游戏中使用Havok,一般遵循这样的步骤,先创建好一个连续的模拟并准备好渲染系统,然后进行一次模拟,渲染器取得模拟的结果,在一秒内进行若干次的渲染。在Havok的SDK中,就称这样的一个时间片叫一帧。我们来看一下,Havok的工作流程。假设所有工作都已经初始化好了,Havok在每一帧的工作流程如下所示:
图片取自Havok的SDK文档。
下面分别介绍各个步骤。
1.1 建立模拟区域(Set up simulation islands)
Havok使用模拟区域来划分一组一组的物理对象。通过将所有整个物理世界的对象划分为各个小的区域来进行模拟,可以更好的利用系统的CPU和内存资源。而且,如果某个区域内的所有对象都已失效(deactivated),那么简单的失效整个区域即可,以后就不必再参与模拟。模拟区域是由系统自动设置的,用户不必自己建立。
模拟区域还管理Havok的失效系统(deactivation system),任何停止移动的对象,都符合失效的条件,一个失效的对象就不必再模拟了,这样可以节约CPU资源。每一个对象都有一个失效器(deactivator),通过查询自己的状态,它可以告诉系统,是否可以安全的使自己失效。
如果使用默认的失效类型,如果一个模拟区域内的所有对象都符合失效的条件,整个区域就会被失效。而一旦区域内的某个刚体重新有效,这个区域内的所有其他刚体也会被重新有效。
下面的步骤都是基于每一个模拟区域来说的。
1.2 施加作用(Applying actions)
通过施加作用,你可以在模拟的过程中控制物体的状态。每一个模拟步骤,系统都会调用你向物理世界中添加的每一个作用的applyAction()方法。使用Havok提供的接口,可以实现自定义的作用(actions)。
1.3 建立约束(Setup Constraints)
场景中的约束都是经过处理的。包括接触约束,它可以防止两个物体相互穿插。你也可以在物体之间指定特定的约束类型,比如,铰链或者球状关节(hinges,ball-and-socket joints)。当然你也可以创建自定义的约束。
1.4 Solve
在刚体世界里,物体是不应该相互穿插的,如果出现,就是一个错误。为了避免这样的错误,我们需要移动一下物体。而解决器(Solver)的职责就是计算避免这个错误所需要的移动量,并把这个信息传递给下一个步骤,整合。
1.5 整合(Integration)
整合器(integrator)计算新的运动状态(初始和终了的位置的旋转,速度,加速度等等),对每个模拟的对象,会考虑解决器提供的信息。然后对象新的位置和旋转就可以传递给游戏,更新游戏对象。
1.6 碰撞检测(Collision detection)
在Havok中,碰撞检测被分成了三个阶段。broadphase碰撞检测,它可以快速地得到一个近似的结果,它查找所以潜在的可能碰撞的一对对的物体。midphase碰撞检测,它从潜在的碰撞中提取更多的细节信息。最后是narrowphase碰撞检测,它确认这些成对的物体中到底哪些实际碰撞了。如果发现了碰撞,narrowphase就用这些信息,创建碰撞代理(collision agents)和碰撞接触点。这些碰撞代理和接触点,会提供给接下来的一个模拟帧使用。
每个物理对象都有hkpCollidable成员,它有一个hkpShape成员,定义用于碰撞检测的对象的形状。物体可以有各种形状,从简单的方体、球体到更复杂的混合形状以及网格。
说明,这里我讲SDK中的专用术语都翻译成了中文,翻译得不一定准确,所以每一个术语后面都有它的英文原词,方便你查看SDK文档。
有任何意见和建议,欢迎联系,我的邮箱[email protected]