Bug - btSoftBody::updateConstants() and area calculations

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

Bug - btSoftBody::updateConstants() and area calculations

Post by dphil »

I think there is a bug in the way the soft body updateConstants() method is being used. This function effects a change in - among other things - link resting lengths based on the current relative position of the nodes. And, for some reason not obvious to me, it is being called in the btSoftBody transform and scale functions. This means that the "natural" resting state of the soft body gets changed every time I simply want to manually move the body, for example. In my case, I have an initial small spherical soft body which has pressure applied. This pressure causes the body to bulge and wobble outward. While it is wobbling, I translate the body. This results - via the call to updateConstants() in btSoftBody::transform(...) - in an update of link resting lengths to the current, expanded state, relaxing the body and causing the pressure to make it expand even more. Thus successive translations cause the body to keep enlarging. This is obviously not desired behaviour.

So, a couple comments on this. First, I don't really know why updateConstants() is being called at the end of every transform call (and scale call). It isn't 100% clear to me what all parts of the function are doing, but I don't think it's necessary, and I might suggest removing the call from transform(...) and scale(...). Second, I have also previously been making a direct manual call to updateConstants() whenever I change the value of m_cfg.kLST for the soft body. I was doing this because the only place where kLST appears to be used anywhere is one line of calculation in updateConstants(). But with the realization that updateConstants() is messing with the "natural" state of the soft body, I wouldn't want to be making this call anymore. But if I don't, the new kLST will not take effect, unless I manually do the kLST-relevant adjustments that updateConstants() was doing...

This problem is most noticeable when translating/scaling a soft body that is currently "bent out of shape" already, such as one under pressure. A reproducible case can be shown in the 2.77 release softdemo.cpp by adding the indicated line at the bottom of the for loop below to SoftDemo::renderme() and then running the SoftBody "Pressure" demo:

Code: Select all

void	SoftDemo::renderme()
{
	btIDebugDraw*	idraw=m_dynamicsWorld->getDebugDrawer();

	glDisable(GL_TEXTURE_2D);
	m_dynamicsWorld->debugDrawWorld();

	/* Bodies		*/ 
	btVector3	ps(0,0,0);
	int			nps=0;

	btSoftBodyArray&	sbs=getSoftDynamicsWorld()->getSoftBodyArray();
	for(int ib=0;ib<sbs.size();++ib)
	{
		btSoftBody*	psb=sbs[ib];
		nps+=psb->m_nodes.size();
		for(int i=0;i<psb->m_nodes.size();++i)
		{
			ps+=psb->m_nodes[i].m_x;
		}
		psb->translate(btVector3(0, 0.1, 0)); // *** ADD THIS LINE ***
	}
	...
	...
	... 
You would expect this to simply shift the blob up a small increment each frame, but instead it also causes it to blow up due to the issues I described earlier.

Comments? Erwin, I can file a bug report if needed...
Last edited by dphil on Fri Apr 08, 2011 8:56 pm, edited 1 time in total.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Bug? - btSoftBody::updateConstants()

Post by Erwin Coumans »

It makes sense to split the functionality in separate methods indeed.

Do you mind writing a patch and submit it in the tracked, preferably maintaining backward compatibility?
We could use some default arguments, to control what kind of data is updated.

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

Re: Bug? - btSoftBody::updateConstants()

Post by dphil »

Sure, I am looking into it now. Turns out there's a bit more to the issue as well. The only place that the area of faces is calculated is in updateConstants(), which is potentially only ever called once (from predictMotion), unless manually called by the user. This means that the area is never constantly updated, so pressure, volume correction and aerodynamics forces will be applied with reference to the surface area at the time that updateConstants() was called which, in general, will no longer be valid in future simulation steps as the body stretches/distorts/oscillates. I have verified from testing that the area is never recalculated even as my soft body expands due to pressurization. So it seems I will need to add a call (probably from applyForces(), which is the only place area is used anyway) to update area calculations at every time step, which unfortunately will add even more to sb computation, but should produce a more correct result, at least.
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Bug - btSoftBody::updateConstants() and area calculation

Post by dphil »

Here's the associated bug report, along with patched softbody.h/.cpp: http://code.google.com/p/bullet/issues/detail?id=503

It fixes both the issue of resting length changes as well as [a lack of] area updates.
XMight
Posts: 32
Joined: Tue Feb 22, 2011 1:00 pm

Re: Bug - btSoftBody::updateConstants() and area calculation

Post by XMight »

I don't know what you guys did in these patches, but if I replace my original SoftBody.h and cpp, then my whole demo is screwed up. Soft bodies does not behave ok, they do not collide with the rigid bodies at all, and even blow up if in my code I use the following lines:

Code: Select all

	softTriMesh->m_cfg.kAHR = 0.8;
	softTriMesh->m_cfg.kPR = 10.0f;
Did you ever test them?
If you'll want, I will do some video to demonstrate the behavior with the different files, and no change on the code.
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Bug - btSoftBody::updateConstants() and area calculation

Post by dphil »

Looking at the change log and the latest svn code, it seems the patch I made hasn't been included yet (I manually changed my own Bullet code for now, though). Did you manually incorporate the patch into your own code?
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm

Re: Bug - btSoftBody::updateConstants() and area calculation

Post by dphil »

Hm, I think you are right. I was actually aware of the problem where using clusters with the CL_RS collision flag on a pressurized soft body caused explosions, but for some reason thought this was a pre-existing problem. Most of the testing I did with the patch was based on the "Pressure" demo provided with bullet, which doesn't use clusters and works well. I'm not sure why using clusters makes a difference...I'll look into it.

EDIT: Actually, I can reproduce the exploding behaviour in pre-patch code as well. In the bullet "Pressure" demo, in the Init_Pressure function use generateClusters(0) (for max # clusters) and set collision flag to CL_RS. The body should explode when it touches the stairs. With a smaller number of clusters, it takes a greater impact (eg dropping from a higher height) to cause explosion. The patch just seems to make this behaviour a bit more apparent/sensitive, which probably makes sense since it keeps up-to-date surface area calculations rather than a static one from the object's initial form. So I'm back to thinking this is an issue in how the CL_RS solver works. I looked into it a bit, but there's a lot of cryptic code to sift through...
ProfessionalUser
Posts: 14
Joined: Fri Oct 14, 2011 12:10 am

Re: Bug - btSoftBody::updateConstants() and area calculation

Post by ProfessionalUser »

The rest length modification in updateConstants() stung me as well. I ended up disabling the updateConstant call by setting variable m_bUpdateRtCst to false before calling step simulation. However, that means I have to replicate everything updateConstants() does except for changing the rest lengths. This is butt ugly. I just see it's a year later now from the time of your original post, has this bug not found its way into a release?
KelloggsFrost
Posts: 1
Joined: Wed Apr 11, 2012 1:26 pm

Re: Bug - btSoftBody::updateConstants() and area calculation

Post by KelloggsFrost »

I am dealing with the same problem. I need to "go back in time" during my simulation and therefore i need to reinitialize the initial pose of the softbody but also a current deformation state. It works except the described problem, that positioning the nodes programatically makes the softbody forget about it's initial pose.

Has anybody a good workaroud for this problem? Everything i tried until now is ugly .