+ 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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user