Bullet 学习笔记之 软体仿真流程(二) 碰撞检测
下面梳理 Bullet Physics 中关于软体的碰撞检测流程及算法。
在 Bullet Physics 中,涉及软体的碰撞检测主要由函数 btDiscreteDynamicsWorld::performDiscreteCollisionDetection()
和函数 btDeformableRigidDynamicsWorld::softBodySelfCollision()
完成。
1、碰撞检测类型
涉及软体的碰撞检测,其类型主要包括如下:
enum _
{
RVSmask = 0x000f, ///Rigid versus soft mask
SDF_RS = 0x0001, ///SDF based rigid vs soft
CL_RS = 0x0002, ///Cluster vs convex rigid vs soft
SDF_RD = 0x0003, ///DF based rigid vs deformable
SDF_RDF = 0x0004, ///DF based rigid vs deformable faces
SVSmask = 0x00F0, ///Rigid versus soft mask
VF_SS = 0x0010, ///Vertex vs face soft vs soft handling
CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling
CL_SELF = 0x0040, ///Cluster soft body self collision
VF_DD = 0x0050, ///Vertex vs face soft vs soft handling
/* presets */
Default = SDF_RS,
END
};
分为 “刚体 vs 软体” 和 “软体 vs 软体” 两类,又细分为不同的算法。其算法定义在 btSoftColliders
中。通过 btSoftBody.cpp
可知,仅实现了 fCollision::SDF_RS
(SDF based rigid vs soft)、 fCollision::CL_RS
(Cluster vs convex rigid vs soft)、 fCollision::SDF_RD
(DF based rigid vs deformable) 三种碰撞检测。
2、碰撞检测信息
在 btSoftBody
中,碰撞所需要的信息,主要涉及以下成员变量:
// m_leaf 存在与 Feature 中
btDbvtNode* m_leaf; // Leaf data
btVector3 m_bounds[2]; // Spatial bounds
bool m_bUpdateRtCst; // Update runtime constants
btDbvt m_ndbvt; // Nodes tree
btDbvt m_fdbvt; // Faces tree
btDbvt m_cdbvt; // Clusters tree
btAlignedObjectArray<btVector3> m_quads; // quadrature points for collision detection
在软体的碰撞检测中,是通过建立类型为 btDbvt
的数据结构,从而实现快速碰撞检测的。它由 btDbvtNode
组成树状结构。官方表述为:a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree)
在 Node
Face
Tetra
等特征(Feature)中,均包含 btDbvtNode* m_leaf
信息。在软体初始化阶段,插入 Node
Face
Tetra
等时,都会将相应的 btDbvtNode
插入到相应的 btDbvt
中。
3、碰撞检测函数
执行碰撞检测是由函数 btSoftBody::defaultCollisionHandler(..)
完成。具体内容,是在 btSoftColliders
类中完成。
4、碰撞检测结果
碰撞检测得到的结果,存放在 btSoftBody
的成员函数中,如下:
btAlignedObjectArray<DeformableNodeRigidContact> m_nodeRigidContacts;
btAlignedObjectArray<DeformableFaceNodeContact> m_faceNodeContacts;
btAlignedObjectArray<DeformableFaceRigidContact> m_faceRigidContacts;
tSContactArray m_scontacts; // Soft contacts
(这儿有个小小的疑问。刚体与软体的碰撞,在刚体中,会不会也有一份存储呢?)
5、碰撞检测流程
碰撞检测的流程,应该包括 初始化 、状态更新 、 检测 、结果处理 等几个步骤。具体细节如下: