Soft Body 是 Bullet 引擎中用于布料、软体等形变仿真的类。
1、软体的基本组成元素 Node 、Link、Face、Tetra 以及 Material
在 soft body 中,一般是由点、线、面、四面体单元等基本元素构成。下面将分别介绍一下,各个元素的代码,以及使用方法。
1.1、Node
Node
是软体中的节点类,其定义为:
/* Node */
struct Node : Feature
{
btVector3 m_x; // Position
btVector3 m_q; // Previous step position/Test position
btVector3 m_v; // Velocity
btVector3 m_vsplit; // Temporary Velocity in addintion to velocity used in split impulse
btVector3 m_vn; // Previous step velocity
btVector3 m_f; // Force accumulator
btVector3 m_n; // Normal
btScalar m_im; // 1/mass
btScalar m_area; // Area
btDbvtNode* m_leaf; // Leaf data
bool m_constrained; // constrained node
int m_battach : 1; // Attached
int index;
};
其中,包含了(当前时刻的)位置 m_x
前一时刻的位置 m_q
、(当前时刻的)速度 m_v
、某速度 m_vsplit
、前一时刻的速度 m_vn
、所受的合力 m_f
、法向量 m_n
(不知道做什么的)、质量的倒数 m_im
、面积 m_area
、btDvtNode 、约束标志位 m_constrained
、固定标志位 m_battach
、节点编号 index
。以及材料参数 Feature::m_material
。
大致也能明白这些参数/信息是什么。
1.2、Link
连线类的定义为:
/* Link */
ATTRIBUTE_ALIGNED16(struct)
Link : Feature
{
btVector3 m_c3; // gradient
Node* m_n[2]; // Node pointers
btScalar m_rl; // Rest length
int m_bbending : 1; // Bending link
btScalar m_c0; // (ima+imb)*kLST
btScalar m_c1; // rl^2
btScalar m_c2; // |gradient|^2/c0
BT_DECLARE_ALIGNED_ALLOCATOR();
};
连线类 Link
包含了连线的两个顶点(指针)、gradient、初始长度、一些参数、以及材料参数 Feature::m_material
。
具体的一些参数的用法,后面再细究吧。可能有的也不一定会用到。因为,不同的算法,所用到的参数也不尽相同。
1.3、Face
三角形面片类的定义为:
/* Face */
struct Face : Feature
{
Node* m_n[3]; // Node pointers
btVector3 m_normal; // Normal
btScalar m_ra; // Rest area
btDbvtNode* m_leaf; // Leaf data
btVector4 m_pcontact; // barycentric weights of the persistent contact
btVector3 m_n0, m_n1, m_vn;
int m_index;
};
三角形面片类 Face
包含了三个顶点(指针)、法向量、初始面积、btDvtNode*
、m_pcontact
应该是碰撞点在三角形面片中的质心坐标(barycentric weights)、m_n0、m_n1、m_n2(应该是三个顶点的法向量?)、编号 m_index 、以及材料参数 Feature::m_material
。
大致也能明白这些信息。个别信息的用处,后面再慢慢细究吧。
1.4、Tetra
四面体单元类其定义为:
/* Tetra */
struct Tetra : Feature
{
Node* m_n[4]; // Node pointers
btScalar m_rv; // Rest volume
btDbvtNode* m_leaf; // Leaf data
btVector3 m_c0[4]; // gradients
btScalar m_c1; // (4*kVST)/(im0+im1+im2+im3)
btScalar m_c2; // m_c1/sum(|g0..3|^2)
btMatrix3x3 m_Dm_inverse; // rest Dm^-1
btMatrix3x3 m_F;
btScalar m_element_measure;
};
也就是说,Tetra 包含了四面体单元顶点(指针)、初始体积、btDbvtNode*(不知道做什么的)、gradient、某某变量、invDm、形变梯度 (oldsymbol{F}) 、某某变量、材料参数 Feature::m_material
。
这些也基本上包含了软体形变仿真中四面体单元相关的变量。只是,有几个变量还不太清楚是做什么的。
1.5、Mateiral
材料参数的定义如下
/* Material */
struct Material : Element
{
btScalar m_kLST; // Linear stiffness coefficient [0,1]
btScalar m_kAST; // Area/Angular stiffness coefficient [0,1]
btScalar m_kVST; // Volume stiffness coefficient [0,1]
int m_flags; // Flags
};
具体,这个材料参数是用来做什么的,后续再看吧
2 软体的建立及初始化
在 btSoftBody
中,软体的节点、网格、面片等数据,存储在以下成员变量中:
tNodeArray m_nodes; // Nodes
tNodeArray m_renderNodes; // Nodes
tLinkArray m_links; // Links
tFaceArray m_faces; // Faces
tFaceArray m_renderFaces; // Faces
tTetraArray m_tetras; // Tetras
btAlignedObjectArray<btVector3> m_X; // initial positions
btSoftBody
的建立及初始化过程可以参见 btSoftBody* btSoftBodyHelpers::CreateFromTetGenData(..)
2.1、构造函数
首先,读取节点的位置,并由此新建一个 btSoftBody
对象:
btSoftBody* psb = new btSoftBody(&worldInfo, nnode, &pos[0], 0);
在btSoftBody
的构造函数中,初始化了一系列的内部参数;新建并初始化了材料 Material m_materials
;新建了 N 个 Node
,存入节点位置等信息,并将初始节点位置放入 m_X
中;在 m_ndbvt
中插入节点,并将该节点的指针放入节点的 n.m_leaf
中;更新 m_bounds
(这个估计跟 AABB 类似,就是一个边界包围盒吧);更新 m_quads
(不知道是用来做什么的)
2.2、添加面片 Face
通过函数 btSoftBody::appendFace(...)
向软体对象中添加三角形面片。通常情况下,添加四面体单元时,已经添加过边线了,这里就不需要再重复添加表面网格的边线。
2.3、添加四面体单元 Tetra
通过函数 btSoftBody::appendTetra(...)
向软体对象中添加四面体单元。此外,还需要添加四面体单元的四条边线 Line
,即通过 btSoftBody::appendLink(...)
向软体对象中添加边线。
2.4、进一步初始化
添加完软体对象的网格数据后,还需要进一步初始化,比如,计算四面体单元的 invDm。
3、btDbvt
Tree
在 Bullet 物理引擎中,对于 btDbvt
类的定义及说明如下:
///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree).
///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes.
///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure.
struct btDbvt
{ ... }
也就是说,这个本质上是一个用于碰撞检测(broad phase)的 AABB tree 。关于它是如何实现的,就先不讨论了。在 btSoftBody
中,相关的 AABB tree 有如下这些:
btDbvt m_ndbvt; // Nodes tree
btDbvt m_fdbvt; // Faces tree
btDbvntNode* m_fdbvnt; // Faces tree with normals
btDbvt m_cdbvt; // Clusters tree
4、btSoftBody
的其他成员变量
如 Anchor
、 RContact
、 SContact
、 Joint
、 Cluster
、等等
5、位移预计算 btSoftBody::predictMotion
参见 Bullet 学习笔记之 btSoftBody::predictMotion
6、约束计算 btSoftBody::solveClusters
参见 Bullet 学习笔记之 btSoftBody::predictMotion
7、碰撞处理 btSoftBody::defaultCollisionHandler(btSoftBody* psb)
参见 Bullet 学习笔记之 btSoftBody::predictMotion
8、总结
待续