diff --git a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp index b17034669..3fa17d06b 100644 --- a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp +++ b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp @@ -45,13 +45,14 @@ bool btBulletWorldImporter::loadFile( const char* fileName, const char* preSwapF bool result = loadFileFromMemory(bulletFile2); //now you could save the file in 'native' format using //bulletFile2->writeFile("native.bullet"); - - if (preSwapFilenameOut) + if (result) { - bulletFile2->preSwap(); - bulletFile2->writeFile(preSwapFilenameOut); + if (preSwapFilenameOut) + { + bulletFile2->preSwap(); + bulletFile2->writeFile(preSwapFilenameOut); + } } - delete bulletFile2; return result; diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index 8fe34658e..a0c8cca4a 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -1767,7 +1767,23 @@ void btSoftBody::predictMotion(btScalar dt) { Node& n=m_nodes[i]; 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_f = btVector3(0,0,0); } diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h index 2116c34f0..ee1a3d952 100644 --- a/src/BulletSoftBody/btSoftBody.h +++ b/src/BulletSoftBody/btSoftBody.h @@ -45,6 +45,7 @@ struct btSoftBodyWorldInfo btScalar air_density; btScalar water_density; btScalar water_offset; + btScalar m_maxDisplacement; btVector3 water_normal; btBroadphaseInterface* m_broadphase; btDispatcher* m_dispatcher; @@ -55,6 +56,7 @@ struct btSoftBodyWorldInfo :air_density((btScalar)1.2), water_density(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), m_broadphase(0), m_dispatcher(0), diff --git a/src/BulletSoftBody/btSparseSDF.h b/src/BulletSoftBody/btSparseSDF.h index 180e3c218..bcf0c7982 100644 --- a/src/BulletSoftBody/btSparseSDF.h +++ b/src/BulletSoftBody/btSparseSDF.h @@ -69,6 +69,7 @@ struct btSparseSdf btScalar voxelsz; int puid; int ncells; + int m_clampCells; int nprobes; int nqueries; @@ -77,10 +78,13 @@ 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); - Reset(); + Reset(); } // void Reset() @@ -181,6 +185,15 @@ struct btSparseSdf { ++nprobes; ++ncells; + int sz = sizeof(Cell); + if (ncells>m_clampCells) + { + static int numResets=0; + numResets++; +// printf("numResets=%d\n",numResets); + Reset(); + } + c=new Cell(); c->next=root;root=c; c->pclient=shape;