+ add option to set pre-tick callback, called at the beginning of each internal simulation step

+ use real-time for soft body demo (using this pre-tick callback)
+ optimize the generation of bending constraints for the special case where the distance is 2
This commit is contained in:
erwin.coumans
2009-08-14 21:36:51 +00:00
parent e89fe1cbfa
commit 34699f6de6
5 changed files with 135 additions and 40 deletions

View File

@@ -704,6 +704,9 @@ void btSoftBody::clusterDCImpulse(Cluster* cluster,const btVector3& impulse)
cluster->m_ndimpulses++;
}
//
int btSoftBody::generateBendingConstraints(int distance,Material* mat)
{
@@ -715,14 +718,21 @@ int btSoftBody::generateBendingConstraints(int distance,Material* mat)
const int n=m_nodes.size();
const unsigned inf=(~(unsigned)0)>>1;
unsigned* adj=new unsigned[n*n];
#define IDX(_x_,_y_) ((_y_)*n+(_x_))
for(j=0;j<n;++j)
{
for(i=0;i<n;++i)
{
if(i!=j) adj[IDX(i,j)]=adj[IDX(j,i)]=inf;
if(i!=j)
{
adj[IDX(i,j)]=adj[IDX(j,i)]=inf;
}
else
{
adj[IDX(i,j)]=adj[IDX(j,i)]=0;
}
}
}
for( i=0;i<m_links.size();++i)
@@ -732,20 +742,76 @@ int btSoftBody::generateBendingConstraints(int distance,Material* mat)
adj[IDX(ia,ib)]=1;
adj[IDX(ib,ia)]=1;
}
for(int k=0;k<n;++k)
//special optimized case for distance == 2
if (distance == 2)
{
for(j=0;j<n;++j)
struct NodeLinks
{
for(i=j+1;i<n;++i)
btAlignedObjectArray<int> m_links;
};
btAlignedObjectArray<NodeLinks> nodeLinks;
/* Build node links */
nodeLinks.resize(m_nodes.size());
for( i=0;i<m_links.size();++i)
{
const int ia=(int)(m_links[i].m_n[0]-&m_nodes[0]);
const int ib=(int)(m_links[i].m_n[1]-&m_nodes[0]);
if (nodeLinks[ia].m_links.findLinearSearch(ib)==nodeLinks[ia].m_links.size())
nodeLinks[ia].m_links.push_back(ib);
if (nodeLinks[ib].m_links.findLinearSearch(ia)==nodeLinks[ib].m_links.size())
nodeLinks[ib].m_links.push_back(ia);
}
for (int ii=0;ii<nodeLinks.size();ii++)
{
int i=ii;
for (int jj=0;jj<nodeLinks[ii].m_links.size();jj++)
{
const unsigned sum=adj[IDX(i,k)]+adj[IDX(k,j)];
if(adj[IDX(i,j)]>sum)
int k = nodeLinks[ii].m_links[jj];
for (int kk=0;kk<nodeLinks[k].m_links.size();kk++)
{
adj[IDX(i,j)]=adj[IDX(j,i)]=sum;
int j = nodeLinks[k].m_links[kk];
if (i!=j)
{
const unsigned sum=adj[IDX(i,k)]+adj[IDX(k,j)];
btAssert(sum==2);
if(adj[IDX(i,j)]>sum)
{
adj[IDX(i,j)]=adj[IDX(j,i)]=sum;
}
}
}
}
}
} else
{
///generic Floyd's algorithm
for(int k=0;k<n;++k)
{
for(j=0;j<n;++j)
{
for(i=j+1;i<n;++i)
{
const unsigned sum=adj[IDX(i,k)]+adj[IDX(k,j)];
if(adj[IDX(i,j)]>sum)
{
adj[IDX(i,j)]=adj[IDX(j,i)]=sum;
}
}
}
}
}
/* Build links */
int nlinks=0;
for(j=0;j<n;++j)