btActionInterface, apply force, impulses springs

opaque_megane
Posts: 2
Joined: Sat Feb 26, 2011 7:05 am

btActionInterface, apply force, impulses springs

Post by opaque_megane »

I'm trying to model muscles as springs with dynamic rest lengths. I've spent a long time reading and experimenting with btGeneric6DofSpringConstraint, but even after much googling/hacking I couldn't figure out how to get it restrict the relative distance of 2 bodies in a springy way, or control the rest length. Moreover in the constraint demo, the damping seemed to have no effect.

The suspension in btRayCastVehicle has a variation of what I want, so I figured I would follow suit and implement btActionInterface. The problem is that when "updateAction" gets called (it really does get called) to apply the requisite forces to the nodes of a soft body through addForce and addVelocity, nothing happens.

You can just temporarily replace the "SoftDemo" source directory with the contents of the following zip to try my code.
http://www.cs.ucla.edu/~alexalex/SoftDemo.zip

I got it to work with rigid bodies, but I need soft bodies too. I suppose I could just move my code into the same place the mouse picking is done, but this would be a lot better I think.

::: My "Spring" class. Currently it just attempts to apply a random impulse to the 0th node :::

Code: Select all

class Spring4Soft : public btActionInterface
{
public:
	btSoftBody* mBodyB;
	btScalar mRestLength;
	btScalar mStiffness;
	btScalar mDamping;
	int softBodyNodeA;
	
	
	Spring4Soft()
	{
		mRestLength = btScalar(2.);
		mStiffness= btScalar(50);
		mDamping= btScalar(.5);
		
	}
	
	virtual void updateAction( btCollisionWorld* collisionWorld, btScalar step)
	{
		btVector3 forceVector = btVector3(-10,10,10);
		mBodyB->addVelocity(-forceVector, 0); //try to apply a random impulse to the first soft body node.
	}
	void 	debugDraw (btIDebugDraw *debugDrawer){}
};
::: Here's where I plug in my action in soft demo.cpp :::

Code: Select all

//
// 100kg Stanford's bunny
//
static void	Init_Bunny(SoftDemo* pdemo)
{
	//TRACEDEMO
	btSoftBody*	psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny,
		&gIndicesBunny[0][0],
		BUNNY_NUM_TRIANGLES);
	btSoftBody::Material*	pm=psb->appendMaterial();
	pm->m_kLST				=	0.5;
	pm->m_flags				-=	btSoftBody::fMaterial::DebugDraw;
	psb->generateBendingConstraints(2,pm);
	psb->m_cfg.piterations	=	2;
	psb->m_cfg.kDF			=	0.5;
	psb->randomizeConstraints();
	psb->scale(btVector3(6,6,6));
	psb->setTotalMass(100,true);	
	
	Spring4Soft* springo = new Spring4Soft();
	springo->mBodyB = psb;
	pdemo->getSoftDynamicsWorld()->addAction(springo);
	
	pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
	pdemo->m_cutting=true;

}
Thanks!
opaque_megane
Posts: 2
Joined: Sat Feb 26, 2011 7:05 am

Re: btActionInterface, apply force, impulses springs

Post by opaque_megane »

*squeak squeak squeak* I'm a squeaky wheel.

I did my very best to be easily helped... Is what I'm asking stupid somehow?

If so, what's the preferred method for applying forces/impulses at every timestep?
XMight
Posts: 32
Joined: Tue Feb 22, 2011 1:00 pm

Re: btActionInterface, apply force, impulses springs

Post by XMight »

Try to play with the value of the applied force. In my case, my bodies have a mass of 2 or something, and I apply a force nearly equal to yours (and negative).

That's how I apply a force to the whole soft body:

Code: Select all

						softBody->activate(true);
						softBody->addForce(btVector3(forceVec[0], forceVec[1],forceVec[2]));
						softBody->applyForces();

In the case of particular nodes, I don't know for the moment, I try to figure it right now, since I need to know the nodes that are in collision with my 3D cursor, and after that to apply a force to the nearest node.