Bullet 学习笔记之 软体仿真流程(二) 软体碰撞检测与响应

简述 Bullet 中软体的碰撞检测与响应算法,仅针对 Soft 类型,Deformable 类型不包含在这篇文章中。


1. 软体碰撞检测

在 Bullet Physics 中,软体的碰撞检测采用的是 “点-面” 的方法,即分别用两个软体的 m_ndbvtm_fdbvt 做碰撞检测,两个 bvh 树之间的遍历方法不在此展开,当 NodeFace 的包围盒发生碰撞时,便执行 CollideVF_SS::Process(...) 函数进行点和三角形的精确碰撞检测,该函数在 btSoftBodyInternals.h 文件中。

点和面的碰撞检测采用的是投影法(专业名词不确定),即计算点在三角形上的投影点(或最近点)。具体流程和思路如下:

btVector3 o = node->mx;      // 假设 `Node` 点为空间原点,即在 `Node` 点处建立空间坐标系,那么,将三角形的位置减去 o,再计算空间原点到三角形的投影点(或最近点)。
btVector3 p;                 // 在 `Node` 空间坐标系下,原点到三角形的投影点(或最近点) 
btScalar d = SIMD_INFINITY;  // Node 点到投影点(最近点)的距离(的平方)

ProjectOrigin(face->m_n[0]->m_x - o,
              face->m_n[1]->m_x - o,
              face->m_n[2]->m_x - o,
              p, d);

其中, ProjectOrign(...) 函数就是计算原点到三角形上的投影点(或最近点),并给出距离(的平方)。具体,可参见该函数。

接下来,便是判断 Node 点是否与 Face 碰撞。在这里,是根据 “边界”+“位移” 大于 “投影距离” 的方法。即,

const btScalar m = mrg + (o - node->m_q).length() * 2;
if (d < (m * m))
{ ... }

当发生碰撞后,便计算碰撞信息,具体碰撞信息如下:

btSoftBody::SContact c;
c.m_normal = p / -btSqrt(d);    // 法向量,即由三角形面片指向 `Node` 点
c.m_margin = m;                 // 边界,是 mrg + (o - node->m_q).length() * 2
c.m_node = node;
c.m_face = face;
c.m_weights = w;                // 投影点(或最近点)在三角形上的位置,采用质心坐标表示
c.m_friction = btMax(psb[0]->m_cfg.kDF, psb[1]->m_cfg.kDF);
c.m_cfm[0] = ma / ms * psb[0]->m_cfg.kSHR;
c.m_cfm[1] = mb / ms * psb[1]->m_cfg.kSHR;

软体碰撞的检测算法相对还是比较简单的。接下来,便是软体的碰撞响应。

2. 软体碰撞响应

posted @ 2024-07-09 18:33  wghou09  阅读(10)  评论(0编辑  收藏  举报