Softbody offset from the ground plane

mobeen
Posts: 122
Joined: Thu May 05, 2011 11:47 am

Softbody offset from the ground plane

Post by mobeen »

Hi all,
I tried to find similar question but could not find. I am trying to render the bunny soft body (one that comes with the demo application) in my own code base. It runs fine however, there is an offset between where the plane is and where the collision takes place. Here is the output that I get
Image
This is how I render the mesh

Code: Select all

int cnt=0;
for(size_t i=0;i<	bunny->m_nodes.size();i++) {
   gVerticesBunny[cnt++] = bunny->m_nodes[i].m_x.x();
   gVerticesBunny[cnt++] = bunny->m_nodes[i].m_x.y();
   gVerticesBunny[cnt++] = bunny->m_nodes[i].m_x.z();
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(float)*3, gVerticesBunny);
      glDrawElements(GL_TRIANGLES, BUNNY_NUM_TRIANGLES*3, GL_UNSIGNED_INT , gIndicesBunny);
glDisableClientState(GL_VERTEX_ARRAY);
If I subtract .35 from the y value like this,

Code: Select all

gVerticesBunny[cnt++] = bunny->m_nodes[i].m_x.y()-0.35;
I get the correct result as shown here.
Image
My question is why is this 0.35 offset in the rendered output ?
Am i rendering the mesh wrongly.

Here is the scene setup code.

Code: Select all

void InitBullet() {
const int maxProxies = 32766;
collisionConfiguration	= new btSoftBodyRigidBodyCollisionConfiguration();
dispatcher				= new btCollisionDispatcher(collisionConfiguration);
solver					= new btSequentialImpulseConstraintSolver;
btVector3 worldAabbMin(-1000,-1000,-1000);
btVector3 worldAabbMax(1000,1000,1000);
broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
softBodyWorldInfo.m_broadphase = broadphase;
dynamicsWorld			= new btSoftRigidDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);

btVector3 gravity = btVector3(0,-9.8f,0);
dynamicsWorld->getDispatchInfo().m_enableSPU = true;
dynamicsWorld->setGravity(gravity);

groundShape = new btStaticPlaneShape(btVector3(0,1,0),0.0);

btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,0,0)));
btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));
groundRigidBody = new btRigidBody(groundRigidBodyCI);
dynamicsWorld->addRigidBody(groundRigidBody);
	
softBodyWorldInfo.m_dispatcher = dispatcher;	
softBodyWorldInfo.m_gravity=gravity;
softBodyWorldInfo.m_sparsesdf.Initialize();

bunny=btSoftBodyHelpers::CreateFromTriMesh(softBodyWorldInfo, gVerticesBunny,		&gIndicesBunny[0][0],		BUNNY_NUM_TRIANGLES);
 
bunny->m_cfg.kDF 	=	0.75f;
bunny->m_cfg.kMT	=	0.25f;
bunny->m_cfg.kVC	             =	0.5f;	
bunny->m_cfg.piterations	=	5;
bunny->m_cfg.collisions      = btSoftBody::fCollision::CL_RS;
bunny->randomizeConstraints();
bunny->generateClusters(5);

bunny->setTotalMass(100,true);
bunny->setPose(false,true);
bunny->translate(btVector3(0,10,0));
dynamicsWorld->addSoftBody(bunny);	
}
Regards,
Mobeen
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Softbody offset from the ground plane

Post by dphil »

Perhaps it's the collision margin on one or both colliding objects (bunny + ground), though 0.35 seems a bit much for the default setting (given you aren't setting the margins yourself).
Mr.Orange
Posts: 11
Joined: Mon Apr 18, 2011 10:03 am

Re: Softbody offset from the ground plane

Post by Mr.Orange »

Hi Mobeen,

I can't give you a proper reason for this, but try

Code: Select all

groundRigidBody->setCenterOfMassTransform(btTransform(btQuaternion(0,0,0,1),btVector3(0,0,0)));
I know the ground plane has no mass, but I had a very similar problem, and it did the job for me.

cya,
Mr.Orange
XMight
Posts: 32
Joined: Tue Feb 22, 2011 1:00 pm

Re: Softbody offset from the ground plane

Post by XMight »

I agree with dphil, though you didn't post the rendering code, so we cannot be shure what you are doing. Anyway, the default collision margin is 0.04 as I found. Maybe you're translating somehow elsewhere your graphics? (If the soft body is simulated well)

From the code that you posted, everything must be OK.
mobeen
Posts: 122
Joined: Thu May 05, 2011 11:47 am

Re: Softbody offset from the ground plane

Post by mobeen »

THanks for your replies XMight, dphil and Mr. Orange.
Mr Orange wrote: Hi Mobeen,
I can't give you a proper reason for this, but try

Code: Select all

groundRigidBody->setCenterOfMassTransform(btTransform(btQuaternion(0,0,0,1),btVector3(0,0,0)));
I know the ground plane has no mass, but I had a very similar problem, and it did the job for me.
Does not work same result. Infact I am setting the default motion state to identity so it does not make sense to add this.
dphil wrote: Perhaps it's the collision margin on one or both colliding objects (bunny + ground), though 0.35 seems a bit much for the default setting (given you aren't setting the margins yourself).
XMight wrote: I agree with dphil, though you didn't post the rendering code, so we cannot be shure what you are doing.
Here is the complete rendering code

Code: Select all

void OnRender() {
      //Calculate fps
      totalFrames++;
      int current = glutGet(GLUT_ELAPSED_TIME);
      if((current-startTime)>1000)
      {		
	float elapsedTime = float(current-startTime);
	fps = ((totalFrames * 1000.0f)/ elapsedTime) ;
	startTime = current;
  	totalFrames=0;
      }

      sprintf_s(buffer, "FPS: %3.2f",fps);

      StepBullet(); //calls dynamicsWorld->stepSimulation(1/60.f,10);

      glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
      glLoadIdentity();
      //setup the viewing transformation
      gluLookAt(0,0,5,0,0,0,0,1,0);

      //Draw the grid and axes
      DrawAxes();	
      DrawGrid(10);	
	 
      glPolygonMode(GL_FRONT, GL_LINE);
         RenderMesh(); 
      glPolygonMode(GL_FRONT, GL_FILL);
	 
      SetOrthoForFont();		
      glColor3f(1,1,1);
      //Show the fps
      RenderSpacedBitmapString(20,20,0,GLUT_BITMAP_HELVETICA_12,buffer);

   ResetPerspectiveProjection();
   glutSwapBuffers();
}

To make sure that there are no problem in the rendering code, I added in an immediate mode rendering function like this but still the same result.
Is my physics setup correct?

Code: Select all

void RenderMeshImmediateMode() {
   glBegin(GL_TRIANGLES);
   for(int i=0; i<BUNNY_NUM_TRIANGLES; i++) {
      int ind0 = gIndicesBunny[i][0]*3;
      int ind1 = gIndicesBunny[i][1]*3;
      int ind2 = gIndicesBunny[i][2]*3;
      glVertex3fv(&gVerticesBunny[ind0]);
      glVertex3fv(&gVerticesBunny[ind1]); 
      glVertex3fv(&gVerticesBunny[ind2]);    
   }
   glEnd();
}
mobeen
Posts: 122
Joined: Thu May 05, 2011 11:47 am

Re: Softbody offset from the ground plane

Post by mobeen »

OK I checked the collision margin for the two objects
for groundplane it is 0
for bunny it is 0.25

So I set the collision margin for bunny to 0 as follows,

Code: Select all

bunny->getCollisionShape()->setMargin(0);
Now the gap has reduced but it still exists. Here is the new snapshot.
Image
Is this what I should expect?
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Softbody offset from the ground plane

Post by dphil »

This may be normal, I am not certain. One thing you could do is turn off the clusters (in which case you'd probably want to generate bending constraints to support the body) and see what result you get. Since clusters use convex hulls of portions of the soft body, perhaps the clusters are creating an additional margin.
mobeen
Posts: 122
Joined: Thu May 05, 2011 11:47 am

Re: Softbody offset from the ground plane

Post by mobeen »

dphil wrote:This may be normal, I am not certain. One thing you could do is turn off the clusters (in which case you'd probably want to generate bending constraints to support the body) and see what result you get. Since clusters use convex hulls of portions of the soft body, perhaps the clusters are creating an additional margin.
If I turn off the clusters and add in the bending constraints like this,

Code: Select all

bunny->generateBendingConstraints(1);
the bunny first half sinks at the ground plane and then passes through it. Is this the right way to setup the bending constraint. The documentation says the first parameter is the distance in the graph. What does this distance stand for?

Meanwhile, i went back to see how the demos did it and they create a box shape and assign the collision shape to the object like this.

Code: Select all

groundBox = new btBoxShape (btVector3(100,0.01,100));
//create ground object
btTransform tr;
tr.setIdentity();
	
newOb = new btCollisionObject();
newOb->setWorldTransform(tr);
newOb->setInterpolationWorldTransform( tr);
newOb->setCollisionShape(groundBox);
dynamicsWorld->addCollisionObject(newOb);
Replacing the ground plane with the above object while keeping everything else as it is (not changing the clusters also) gives me the correct output as shown below.
Image
One thing that I notice is that the console is giving me a warning.

Code: Select all

warning btCollisionDispatcher::needsCollision: static-static collision!
whats does this mean?
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Softbody offset from the ground plane

Post by dphil »

So the box shape gives a clean contact, while the plane leaves a gap? Interesting. I don't know why that would be.
Is this the right way to setup the bending constraint. The documentation says the first parameter is the distance in the graph. What does this distance stand for?
Yes that is the one line of code you need, however the number should normally be larger than 1 to be of any real use. Picture the connectivity graph of all the soft body nodes (vertices). Since you used the soft body helper method to create a soft body from a mesh, the nodes are connected as in the mesh via links (the "springs"). Connecting nodes to their immediate neighbours via such links is sufficient to give a "soft" material surface. However it can still completely collapse and fold on itself. So mass-spring systems often incorporate "bending springs" connecting (via links) nodes with other nodes that are at slightly further distances away. This helps resist folding of the material, giving an additional dimension of structural support. This is one way to help preserve volume for bullet's soft bodies. So using a "distance" of 1 will simply duplicate all the surface links in the soft body, adding no additional internal supports. Higher values create structural links connecting more distant nodes with each other (up to a point), which generally gives better volume support.

All that said, I realize I was a bit mistaken before. First, you don't actually need bending constraints in place of clusters, since clusters are just for collision handling, not structural support. Second, I overlooked the fact that the code calls:
bunny->setPose(false,true);
This is a way in which bullet can attempt to automatically preserve a soft body's shape without the need for internal bending constraints.
whats does this mean?
From my understanding, the warning is just because you didn't set any collision flags. See collision object reference, specifically the setCollisionFlags function, and associated CollisionFlags enum. By default, collision object flags are set to CF_STATIC_OBJECT, which is probably not correct for your bunny, assuming it is dynamic. However I don't believe this causes any problems in most cases (in fact I just realized I never change the default in my own dynamic simulation, but it works fine :lol: ). At any rate, this is why it gets confused when you have 2 objects that are flagged as static (and thus should not be moving) that are coming into contact with each other. There doesn't seem to be an explicit enum value for a dynamic body, but I'm guessing that doing the following:

Code: Select all

bunny->setCollisionFlags(0);
// since other enum options have non-zero values, I'm assuming 0 means simply "not one of the other types"
would avoid the warning(?).

On a side note, I found this comment from Erwin in a post (http://bulletphysics.org/Bullet/phpBB3/ ... 5831#p5831) back in 2007 about that warning:
This warning will be removed, it was just to notify developers something is potentially wrong (usually you don't want static-static collision detection). A new type would probably better.
So take that as you will.
mobeen
Posts: 122
Joined: Thu May 05, 2011 11:47 am

Re: Softbody offset from the ground plane

Post by mobeen »

Thanks for the detailed response dphil.
Yes setting the collision flag to 0 removes the warning.

Two more questions that are bugging me:
1) Have u encountered this offset thing before? The box shape works fine, the planeshape has an offset? I wonder why the demo samples showing the soft body collision with the plane did not use the planeshape?

2) I want to know more about the mathematical model used by bullet for simulating soft bodies. I asked this question in another forum (http://www.bulletphysics.org/Bullet/php ... f=4&t=6743) on this site but there were no replies.
One tedious way is to go through the code but I want to ask the professionals to guide me on how to obtain this information. Do u know any links/reference/papers on the model used by bullet so that it is easier for me to follow what's going on underneath?

Thanks,
Mobeen
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Softbody offset from the ground plane

Post by dphil »

Have u encountered this offset thing before?
1) I'm afraid I haven't, or at least I haven't noticed (can't say I've really looked carefully; high accuracy rendering/collision is not terribly important for my work at the moment).
Do u know any links/reference/papers on the model used by bullet so that it is easier for me to follow what's going on underneath?
2) All I know is that it is based on standard mass-spring systems. I am not sure what kind of integration, etc is used. For one particular aspect - pressurization (using the m_cfg.kPR field) - I do know that the implementation is akin to that in this paper: http://www.ep.liu.se/ecp/010/007/ecp01007.pdf
mobeen
Posts: 122
Joined: Thu May 05, 2011 11:47 am

Re: Softbody offset from the ground plane

Post by mobeen »

Hi dphil,
I must say I am pleased to have u here. Thanks for spotting that paper for me. I will give it a read.

Regards,
Mobeen