Does OgreBullet support soft body simulation?


23-06-2008 19:05:24

Bullet 2.69 has support for soft body simulation, and what about OgreBullet? Can OgreBullet also handle it?
If not, is there a prevision for when it will be implemented?


28-09-2008 22:32:37


i know you created this topic 2-3 months ago but i will answer it anyway.

I dont think OgreBullet has SoftBody..
Anyway, you should use pure Bullet to use it's full power. OgreBullet contain the minimum to easily use Bullet with Ogre, not thw whole stuff.

I hope i correctly answered your question


28-09-2008 23:42:06

Using the softbody part of bullet is easier than it it might seem in the beginning. After creating the softbody, you have to update your Ogre mesh, so that the changes are visible. Below is an example of how this could be done. The example doesn't work for all meshes, but it is just an example ;)

void BulletFrameListener::updateOgreMeshFromBulletMesh(btSoftBody *softBody)
//retrieve the vertex data from the softbody.
SoftBody *ogreSoftBody= static_cast<SoftBody*>(softBody->getUserPointer());
MeshPtr mesh= ogreSoftBody->getEntity()->getMesh();
Ogre::SubMesh* submesh = mesh->getSubMesh(0);
Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;

if (!submesh->useSharedVertices)
const Ogre::VertexElement* posElem =vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
Ogre::HardwareVertexBufferSharedPtr vbuf= vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
unsigned char* vertex =static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));

float* pReal;

//get the vertex data from bullet.
btSoftBody::tNodeArray& nodes(softBody->m_nodes);

//now we simply update the coords of the vertices. Of course this only works
//properly when the Ogre data and the Bullet data have the same number of vertices
//and when they are in the same order. It seems that bullet doesn't shuffle the
//vertices, but this is only an observation!
for (int j=0;j<nodes.size();++j)
posElem->baseVertexPointerToElement(vertex, &pReal);
vertex += vSize;
*pReal++= nodes[j].m_x.x();
*pReal++= nodes[j].m_x.y();
*pReal++= nodes[j].m_x.z();

The interesting part is softBody->m_nodes. You can directly access the verticx information of Bullet using the variable m_nodes. The screenshot shows an example of how it might look like. The performance is fine, there is no relevant drop in the FPS. At least as long as your mesh doesn't have to many vertices or you have to many softbodies which can collide.
As the first try might fail, the usage of the debug draw feature of bullet helps a lot. In the Wiki there is an example. Helps a lot to find out where your bullet object really is...


25-10-2008 21:20:12


Just One question (edited)

Is it possible to somehow share vertices, so updating the vertices in bullet automatically updates the vertices in the mesh?



30-01-2009 18:07:48

Don't know if I should've started my own thread, but by looking at imajia's code I can't seem to comprehend why the new vertex data written manual to the buffer is not overwritten by Ogre during rendering. This code is obviously in the FrameListener, so it's called before Ogre does any rendering. And also if you discard the whole buffer isn't there a danger that vertices from other meshes might get discarded as well?


30-01-2009 19:04:07

No, that's fine. Because it only modifies the vertex buffer of a mesh. Actually, a submesh of a mesh.
In Ogre, all meshes have their own vertex/index buffers, most of them are using separate vertex/index buffers per submesh. :wink:


31-01-2009 12:11:49

I see! Thanks jacmoe, that clear some clouds in my head. So, can I safely assume that these vertex buffers will stay valid throughout application runtime, so if I store pointers to mesh vertices as opposed to their value, these pointers will point to a valid data?

tuan kuranes

02-02-2009 08:30:50

So, can I safely assume that these vertex buffers will stay valid throughout application runtime, so if I store pointers to mesh vertices as opposed to their value, these pointers will point to a valid data?
No. most likely Vertex Data lies on Gpu, and if you "read" it from there you would get a freshly new memcpi'ed array.
Better keep a complete vertex data buffer on you side and upload it after each modification from simulation.


02-02-2009 09:20:05

Better keep a complete vertex data buffer on you side and upload it after each modification from simulation.
That's what I'll do so. Thanks tuan.


04-04-2009 09:17:13


Did someone manage to do the opposite - creating a btSoftBody from a mesh?
I have it almost working, but some vertices are not shared on the mesh, so I don't know how to link the triangles - It ends up loading the triangles correctly, but not linked to each other, so the object 'falls apart' on the simulation.

Here's my current code (two versions with the same result):

// using btSoftBodyHelpers::CreateFromTriMesh
btScalar vertices[mVertexCount * 3];
int i,j;
for(i=0, j=0; i < mVertexCount; i++)
Vector3 v = mVertexBuffer[i];
vertices[j++] = v.x;
vertices[j++] = v.y;
vertices[j++] = v.z;

int ntriangles = mIndexCount / 3;
int *indexes = (int*) mIndexBuffer;
return btSoftBodyHelpers::CreateFromTriMesh(*worldInfo, vertices, indexes, ntriangles);

// doing basically what btSoftBodyHelpers::CreateFromTriMesh does
unsigned int ntriangles = mIndexCount / 3;

btAlignedObjectArray<bool> chks;
btAlignedObjectArray<btVector3> vtx;

unsigned int maxidx = mVertexCount;

int i, j;
for(i=0; i < mVertexCount; i++)
vtx[i] = Convert::toBullet(mVertexBuffer[i]);

btSoftBody* psb=new btSoftBody(worldInfo,vtx.size(),&vtx[0],0);

#define IDX(_x_,_y_) ((_y_)*maxidx+(_x_))

for( i=0; i < mIndexCount; i+=3)
const int idx[]={mIndexBuffer[i],mIndexBuffer[i+1],mIndexBuffer[i+2]};
for(int j=2,k=0;k<3;j=k++)
printf("face %d %d %d \n", idx[0],idx[1],idx[2]);


#undef IDX


Any ideas?


04-04-2009 10:35:38

I think you just need to set your SoftBody material properties. Try tweaking these values

// _softBody->m_cfg.kDP = 0.001; // Damping coefficient
_softBody->m_cfg.kDF = 0.5; // Dynamic friction coefficient
// _softBody->m_cfg.kMT = 0.01; // Pose matching coefficient
// _softBody->m_cfg.kPR = 2500;
// _softBody->m_cfg.kCHR = 1; // Rigid contacts hardness
// _softBody->m_cfg.kKHR = 0.8; // Kinetic contacts hardness
// _softBody->m_cfg.kSHR = 1; // Soft contacts hardness
_softBody->m_cfg.piterations = 2; // Positions solver iterations
_softBody->m_materials[0]->m_kLST = 0.45;

btSoftBody::Material* softBodyMaterial = _softBody->appendMaterial();
softBodyMaterial->m_kLST = 0.5; // Linear stiffness coefficient
softBodyMaterial->m_kAST = 0.1; // Area/Angular stiffness coefficient
softBodyMaterial->m_kVST = 0.5; // Volume stiffness coefficient

btScalar mass(WorldMetricsHelper::kg(60));
_softBody->setTotalMass(mass, true);
// _softBody->setPose(false, true); // XXX Set current state as a pose
// _softBody->generateBendingConstraints(2, softBodyMaterial);


04-04-2009 14:18:09


Thanks but it didn't work :(
The triangles are not linked to each other, so they act like they were independent objects.. I'll try to capture a video later.
If I bind them together with btSoftBody->appendLink(idx[j],idx[k]) the pieces that I linked work, but then I'd have to do all the links manually, triangle by triangle...



06-04-2009 08:05:27


I got it working by removing the duplicated vertices before creating the soft body.

More detais here: ... f=9&t=3428



14-08-2009 16:05:46

could you post your full code here?



27-04-2010 19:31:39

I was trying to use Igvier softbody solution, but I cannot really figure out how to create a simple softbody.

Could anyone post an example how to use and create a softbody ?

Help would me much appreciated :)