basic implementation of self-collision for btSoftBody with collision clusters: perform regular soft body versus soft body, but disable collision detection between clusters that are connected/share any node (vertex).

currently self-collision is always enabled for soft bodies that use clusters collision detectoin. to disable, call 'softbody.m_clusterConnectivity.clear' after 'generateClusters(...) call.
This commit is contained in:
erwin.coumans
2009-03-02 05:13:26 +00:00
parent 210fe36106
commit 5be9f8f301
4 changed files with 73 additions and 12 deletions

View File

@@ -911,6 +911,35 @@ int btSoftBody::generateClusters(int k,int maxiterations)
initializeClusters(); initializeClusters();
updateClusters(); updateClusters();
//for self-collision
m_clusterConnectivity.resize(m_clusters.size()*m_clusters.size());
{
for (int c0=0;c0<m_clusters.size();c0++)
{
m_clusters[c0]->m_clusterIndex=c0;
for (int c1=0;c1<m_clusters.size();c1++)
{
bool connected=false;
Cluster* cla = m_clusters[c0];
Cluster* clb = m_clusters[c1];
for (int i=0;!connected&&i<cla->m_nodes.size();i++)
{
for (int j=0;j<clb->m_nodes.size();j++)
{
if (cla->m_nodes[i] == clb->m_nodes[j])
{
connected=true;
break;
}
}
}
m_clusterConnectivity[c0+c1*m_clusters.size()]=connected;
}
}
}
return(m_clusters.size()); return(m_clusters.size());
} }
return(0); return(0);
@@ -2059,8 +2088,13 @@ void btSoftBody::updateClusters()
} }
} }
} }
} }
// //
void btSoftBody::cleanupClusters() void btSoftBody::cleanupClusters()
{ {
@@ -2319,6 +2353,7 @@ void btSoftBody::CJoint::Terminate(btScalar dt)
// //
void btSoftBody::applyForces() void btSoftBody::applyForces()
{ {
BT_PROFILE("SoftBody applyForces"); BT_PROFILE("SoftBody applyForces");
const btScalar dt=m_sst.sdt; const btScalar dt=m_sst.sdt;
const btScalar kLF=m_cfg.kLF; const btScalar kLF=m_cfg.kLF;

View File

@@ -296,6 +296,7 @@ public:
btScalar m_adamping; /* Angular damping */ btScalar m_adamping; /* Angular damping */
btScalar m_matching; btScalar m_matching;
bool m_collide; bool m_collide;
int m_clusterIndex;
Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) {} Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) {}
}; };
/* Impulse */ /* Impulse */
@@ -603,6 +604,7 @@ public:
btDbvt m_fdbvt; // Faces tree btDbvt m_fdbvt; // Faces tree
btDbvt m_cdbvt; // Clusters tree btDbvt m_cdbvt; // Clusters tree
tClusterArray m_clusters; // Clusters tClusterArray m_clusters; // Clusters
btAlignedObjectArray<bool>m_clusterConnectivity;//cluster connectivity, for self-collision
// //
// Api // Api

View File

@@ -766,6 +766,16 @@ struct btSoftColliders
{ {
btSoftBody::Cluster* cla=(btSoftBody::Cluster*)la->data; btSoftBody::Cluster* cla=(btSoftBody::Cluster*)la->data;
btSoftBody::Cluster* clb=(btSoftBody::Cluster*)lb->data; btSoftBody::Cluster* clb=(btSoftBody::Cluster*)lb->data;
bool connected=false;
if ((bodies[0]==bodies[1])&&(bodies[0]->m_clusterConnectivity.size()))
{
connected = bodies[0]->m_clusterConnectivity[cla->m_clusterIndex+bodies[0]->m_clusters.size()*clb->m_clusterIndex];
}
if (!connected)
{
btSoftClusterCollisionShape csa(cla); btSoftClusterCollisionShape csa(cla);
btSoftClusterCollisionShape csb(clb); btSoftClusterCollisionShape csb(clb);
btGjkEpaSolver2::sResults res; btGjkEpaSolver2::sResults res;
@@ -782,6 +792,13 @@ struct btSoftColliders
pj->m_split *= (bodies[0]->m_cfg.kSS_SPLT_CL+bodies[1]->m_cfg.kSS_SPLT_CL)/2; pj->m_split *= (bodies[0]->m_cfg.kSS_SPLT_CL+bodies[1]->m_cfg.kSS_SPLT_CL)/2;
} }
} }
} else
{
static int count=0;
count++;
//printf("count=%d\n",count);
}
} }
void Process(btSoftBody* psa,btSoftBody* psb) void Process(btSoftBody* psa,btSoftBody* psb)
{ {

View File

@@ -63,6 +63,13 @@ void btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
///solve soft bodies constraints ///solve soft bodies constraints
solveSoftBodiesConstraints(); solveSoftBodiesConstraints();
//self collisions
for ( int i=0;i<m_softBodies.size();i++)
{
btSoftBody* psb=(btSoftBody*)m_softBodies[i];
psb->defaultCollisionHandler(psb);
}
///update soft bodies ///update soft bodies
updateSoftBodies(); updateSoftBodies();