Sorry for the lack of updates, I am preparing Bullet 3.x initial release and get back to merging Bullet 2.x and Bullet 3.x afterwards.

fix some crash in btSoftBody, related to running out-of-memory. You can configure the default maximum memory allocation for the signed distance field using worldInfo->m_sparsesdf.Initialize(hash, maxAllocation);
fix 'exploding' btSoftBody, related to very small masses. You can configure maximum displacement per frame using worldInfo->m_maxDisplacement 
avoid some crash in the world importer
This commit is contained in:
erwin.coumans@gmail.com
2013-04-22 19:00:58 +00:00
parent 33688fc011
commit 9abd0b6029
4 changed files with 40 additions and 8 deletions

View File

@@ -45,13 +45,14 @@ bool btBulletWorldImporter::loadFile( const char* fileName, const char* preSwapF
bool result = loadFileFromMemory(bulletFile2); bool result = loadFileFromMemory(bulletFile2);
//now you could save the file in 'native' format using //now you could save the file in 'native' format using
//bulletFile2->writeFile("native.bullet"); //bulletFile2->writeFile("native.bullet");
if (result)
{
if (preSwapFilenameOut) if (preSwapFilenameOut)
{ {
bulletFile2->preSwap(); bulletFile2->preSwap();
bulletFile2->writeFile(preSwapFilenameOut); bulletFile2->writeFile(preSwapFilenameOut);
} }
}
delete bulletFile2; delete bulletFile2;
return result; return result;

View File

@@ -1767,7 +1767,23 @@ void btSoftBody::predictMotion(btScalar dt)
{ {
Node& n=m_nodes[i]; Node& n=m_nodes[i];
n.m_q = n.m_x; n.m_q = n.m_x;
n.m_v += n.m_f*n.m_im*m_sst.sdt; btVector3 deltaV = n.m_f*n.m_im*m_sst.sdt;
{
btScalar maxDisplacement = m_worldInfo->m_maxDisplacement;
btScalar clampDeltaV = maxDisplacement/m_sst.sdt;
for (int c=0;c<3;c++)
{
if (deltaV[c]>clampDeltaV)
{
deltaV[c] = clampDeltaV;
}
if (deltaV[c]<-clampDeltaV)
{
deltaV[c]=-clampDeltaV;
}
}
}
n.m_v += deltaV;
n.m_x += n.m_v*m_sst.sdt; n.m_x += n.m_v*m_sst.sdt;
n.m_f = btVector3(0,0,0); n.m_f = btVector3(0,0,0);
} }

View File

@@ -45,6 +45,7 @@ struct btSoftBodyWorldInfo
btScalar air_density; btScalar air_density;
btScalar water_density; btScalar water_density;
btScalar water_offset; btScalar water_offset;
btScalar m_maxDisplacement;
btVector3 water_normal; btVector3 water_normal;
btBroadphaseInterface* m_broadphase; btBroadphaseInterface* m_broadphase;
btDispatcher* m_dispatcher; btDispatcher* m_dispatcher;
@@ -55,6 +56,7 @@ struct btSoftBodyWorldInfo
:air_density((btScalar)1.2), :air_density((btScalar)1.2),
water_density(0), water_density(0),
water_offset(0), water_offset(0),
m_maxDisplacement(1000.f),//avoid soft body from 'exploding' so use some upper threshold of maximum motion that a node can travel per frame
water_normal(0,0,0), water_normal(0,0,0),
m_broadphase(0), m_broadphase(0),
m_dispatcher(0), m_dispatcher(0),

View File

@@ -69,6 +69,7 @@ struct btSparseSdf
btScalar voxelsz; btScalar voxelsz;
int puid; int puid;
int ncells; int ncells;
int m_clampCells;
int nprobes; int nprobes;
int nqueries; int nqueries;
@@ -77,8 +78,11 @@ struct btSparseSdf
// //
// //
void Initialize(int hashsize=2383) void Initialize(int hashsize=2383, int clampCells = 256*1024)
{ {
//avoid a crash due to running out of memory, so clamp the maximum number of cells allocated
//if this limit is reached, the SDF is reset (at the cost of some performance during the reset)
m_clampCells = clampCells;
cells.resize(hashsize,0); cells.resize(hashsize,0);
Reset(); Reset();
} }
@@ -181,6 +185,15 @@ struct btSparseSdf
{ {
++nprobes; ++nprobes;
++ncells; ++ncells;
int sz = sizeof(Cell);
if (ncells>m_clampCells)
{
static int numResets=0;
numResets++;
// printf("numResets=%d\n",numResets);
Reset();
}
c=new Cell(); c=new Cell();
c->next=root;root=c; c->next=root;root=c;
c->pclient=shape; c->pclient=shape;