参照 Bullet Physics 官方例程 VolumetricDeformable,梳理软体形变仿真流程。
0 环境搭建
仿真场景类为 btDeformableMultiBodyDynamicsWorld
,碰撞检测 broadphase 使用类 btDbvtBroadphase
完成,碰撞检测 narrowphase 使用类 btSoftBodyRigidBodyCollisionConfiguration
及 btCollisionDispatcher
完成。软体 solver 使用 btDeformableBodySolver
,约束求解使用 btDeformableMultiBodyConstraintSolver
仿真场景搭建部分代码:
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
1 初始化
1.1 新建软体对象
通过函数 btSoftBodyHelpers::CreateFromTetGenData(...)
建立了 btSoftBody
对象。新建及初始化 btSoftBody
的过程大致为:
(1) new 新的对象
(2) 新建碰撞对象 btSoftBody::m_collisionShape = new btSoftBodyCollisionShape(this);
(3) 添加软体对象中的节点 btSoftBody::m_nodes
在这个过程中,还会初始化软体对象的 CollisionObject 相关信息。
(4)根据四面体单元信息,向 btSoftBody
中添加四面体单元,线段等: psb->appendTetra(..)
psb->appendLink(..)
。并初始化四面体单元的初始信息:
psb->initializeDmInverse();
psb->m_tetraScratches.resize(psb->m_tetras.size());
psb->m_tetraScratchesTn.resize(psb->m_tetras.size());
(5)生成软体的表面网格: btSoftBodyHelpers::generateBoundaryFaces(psb)
1.2 向仿真场景添加软体对象
通过函数 btDeformableMultiBodyDynamicsWorld::addSoftBody(..)
完成。主要做了以下几件事:(1)将软体对象存入 btDeformableMultiBodyDynamicsWorld::m_softBodies
中;(2)将仿真场景中的 softBodySolver 添加到该软体对象中,即 body->setSoftBodySolver(m_deformableBodySolver)
;(3)将该软体对象添加到碰撞检测场景中,即 btCollisionWorld::addCollisionObject(..)
1.3 向软体对象添加作用力
在该实例中,软体对象内有两种作用力:重力、N-H 弹性力。
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(30,100,0.05);
getDeformableDynamicsWorld()->addForce(psb, neohookean);
其中,函数 btDeformableMultiBodyDynamicsWorld::addForce(...) 做了两件事,一是将 force 对象添加到了
btDeformableMultiBodyDynamicsWorld::m_deformableBodySolver->m_objective->m_lf` 中,二是将 softBody 添加到了 force 对象中。
至此,便完成了软体对象的初始化,并将软体对象添加到了仿真场景中。接下来,便是软体对象在场景中的仿真过程。