游戏开发者联盟

bullet物理引擎(2) 碰撞检测

主要数据结构

  • btCollisionObject :包含transform和碰撞形状。
  • btCollisionShape:碰撞形状。多个碰撞体可以使用同一个碰撞形状。
  • btGhostObject:一个特殊碰撞体,用于加速本地碰撞检测。
  • btCollisionWorld:存储所有btCollisionObjects并提供查询接口

broad phase:粗略筛选阶段:

碰撞检测分为两大阶段:粗略筛选和精细计算。粗略阶段使用AABB通过特定算法,快速过滤掉不可能碰撞的物体。有3种方法可选,一般选第一种:
• btDbvtBroadphase: uses a fast dynamic bounding volume hierarchy based on AABB tree
• btAxisSweep3 and bt32BitAxisSweep3: implement incremental 3d sweep and prune
• btSimpleBroadphase: is a brute force reference implementation. It is slow but easy to understand and useful for debugging and testing a more advanced broadphase.

碰撞形状

Bullet支持多种不同的碰撞形状,并且可以添加您自己的形状。为了最好性能和质量,选择适合您目的的碰撞形状很重要。官方手册上有个如果选择形状的图,参考即可。
QQ图片20200123094444

  • 优先选静态形状:btHeightfieldTerrainShape > btScaledBvhTriangleMeshShape > btBvhTriangleMeshShape
  • 其次优先选基本形状:长方体,球体,胶囊,圆柱体,圆锥体。
  • 其次是凸包多面体 btConvexHullShape
  • 复合体:btCompoundShape
  • 最后是三角形mesh:btGimpactTriangleMeshShape

对于我来说,都是基本形状和静态物体。

形状详解:

  • 长方体:用边长的一半来定义。
  • 球体:半径
  • btBoxShape : Box defined by the half extents (half length) of its sides
  • btSphereShape : Sphere defined by its radius
  • btCapsuleShape: Capsule around the Y axis. Also btCapsuleShapeX/Z
  • btCylinderShape : Cylinder around the Y axis. Also btCylinderShapeX/Z.
  • btConeShape : Cone around the Y axis. Also btConeShapeX/Z.
  • btMultiSphereShape : Convex hull of multiple spheres, that can be used to create a Capsule (by
    passing 2 spheres) or other convex shapes.
  • Compound Shapes : 组合图形:由凸多面体组成接近凹面体。
  • btConvexHullShape:凸包:bullet支持多重方式来创建三角mesh,最简单的方式就是用凸包。
  • Concave Triangle Meshes: 凹面三角网格:构建静态凹面三角网格的有效方式是btBvhTriangleMeshShape;如果要同一个形状需要创建多个实例,彼此只是缩放不同,那么可以多次使用btScaledBvhTriangleMeshShape创建一个btBvhTriangleMeshShape,btBvhTriangleMeshShape 可以存储多个网格。

Convex Decomposition :凸面化分解:

理想情况下凹面体只用于静态物体。否则就只能用btConvexHullShape。如果单个凸面体无法体现物体形状,那么可以用多个:btCompoundShape。“Convex Decomposition”就是把凹面体分解为多个凸面体。

Height field:高度图

btHeightfieldTerrainShape

btStaticPlaneShape

顾名思义,btStaticPlaneShape可以表示无限的平面或半空间。这个形状只能用于静态的,不可移动的对象。此形状主要用于演示目的。

碰撞形状的缩放

一些图形可以通过调用btCollisionShape::setScaling(vector3)进行局部缩放. 非均匀缩放可以在3个轴上分别进行, 适用于 btBoxShape, btMultiSphereShape, btConvexShape,
btTriangleMeshShape. 均匀缩放,3个轴的缩放量相同,可以用于btSphereShape. 注意:也可以用只有一个球体的btMultiSphereShape 来创建一个非均匀缩放的球体。如前所述,可以用btScaledBvhTriangleMeshShape 进行非均匀缩放,来创建一个btBvhTriangleMeshShape。btUniformScalingShape则是通过均与缩放来创建凸面体, 达到降低内存占用.

Collision Margin : 碰撞外边距

Bullet对碰撞形状使用较小的碰撞外边距,以提高碰撞检测的性能和可靠性。最好不要修改这个默认值, 非改不可的话一定要用正值,0会出问题。 默认值是 0.04, 如果你的单位是米(推荐)话,就是4cm。对于不同的形状,外边距有不同的含义。 通常,外边距会扩展物体。 这将产生一个小的缝隙。为了弥补这一点,一些形状会从实际大小中减去边距。比如,

  • btBoxShape 会从半变长减去外边距。
  • 对于 btSphereShape,整个半径就是碰撞外边距,所以没有缝隙。 不要重写球体的碰撞外边距。
  • 对于凸包,圆柱体和圆锥体,边距被添加到物体的体积,这就回出现缝隙,除非您调整图形mesh或者碰撞尺寸。
  • 对于凸包, 通过缩小对象,可以消除缝隙。See the examples/Importers/ImportBsp for this advanced use.

碰撞矩阵

对于每一对物体形状,bullet都会选用合适的碰撞算法。以下表格就是各种组合下的算法。这个看看就好,一般不会自己开发算法。
By default, the entire matrix is filled with the following algorithms. Note that Convex represents
convex polyhedron, cylinder, cone and capsule and other GJK compatible primitives. GJK stands for
Gilbert, Johnson and Keerthi, the people behind this convex distance calculation algorithm. It is
combined with EPA for penetration depth calculation. EPA stands for Expanding Polythope
Algorithm by Gino van den Bergen. Bullet has its own free implementation of GJK and EPA.
QQ图片20200123093549

自定义碰撞形状和碰撞算法

The user can register a custom collision detection algorithm and override any entry in this Collision
Matrix by using the btDispatcher::registerCollisionAlgorithm. See
examples/UserCollisionAlgorithm for an example, that registers a SphereSphere collision
algorithm.

相关文章: