Regarding soft body physics

Please don't post Bullet support questions here, use the above forums instead.
mobeen
Posts: 122
Joined: Thu May 05, 2011 11:47 am

Regarding soft body physics

Post by mobeen »

Hi all,
I have been looking around for answer for this but I have not been able to get one. I am trying to understand how the bullet physics engine calculates dynamics of soft bodies. I know that typically a tetrahedral representation is generated out of the triangular mesh. Then certain constraints are applied like bending and volume constraints to prevent the tetrahedra from collapsing. I want to understand
1) the maths behind this and what are the eq. used. What solver (explicit/implicit) is used in bullet?
2) If the conjugate gradient solver is to be implemented, how do i get started with it to implement something like baraffs large step in cloth simulation paper in bullet? Any ideas/books/references would be appreciated?
3) Just checking the softbodysolver_cpu.cpp integrate function as well as the integrate opencl kernel (Integrate.cl) it seems bullet is doing explicit euler integration I may be wrong though.

Code: Select all

void btCPUSoftBodySolver::integrate( float solverdt )
{
	using namespace Vectormath::Aos;
	int numVertices = m_vertexData.getNumVertices();
	for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex )
	{
		Point3 &position( m_vertexData.getPosition(vertexIndex) );
		Point3 &previousPosition( m_vertexData.getPreviousPosition(vertexIndex) );
		Vector3 &forceAccumulator( m_vertexData.getForceAccumulator(vertexIndex) );
		Vector3 &velocity( m_vertexData.getVelocity(vertexIndex) );
		float inverseMass = m_vertexData.getInverseMass(vertexIndex);

		previousPosition = position;
		[b]velocity += forceAccumulator * inverseMass * solverdt;
		position += velocity * solverdt;[/b]		
                         forceAccumulator = Vector3(0.f, 0.f, 0.f);
	}	
}

//From Integrate.cl
__kernel void
IntegrateKernel( 
	const int numNodes,
	const float solverdt,
	__global float * g_vertexInverseMasses,
	__global float4 * g_vertexPositions,
	__global float4 * g_vertexVelocity,
	__global float4 * g_vertexPreviousPositions,
	__global float4 * g_vertexForceAccumulator GUID_ARG)
{
	int nodeID = get_global_id(0);
	if( nodeID < numNodes )
	{	
		float4 position   = g_vertexPositions[nodeID];
		float4 velocity   = g_vertexVelocity[nodeID];
		float4 force      = g_vertexForceAccumulator[nodeID];
		float inverseMass = g_vertexInverseMasses[nodeID];
		
		g_vertexPreviousPositions[nodeID] = position;
		velocity += force * inverseMass * solverdt;
		position += velocity * solverdt;
		
		g_vertexForceAccumulator[nodeID] = (float4)(0.f, 0.f, 0.f, 0.0f);
		g_vertexPositions[nodeID]        = position;
		g_vertexVelocity[nodeID]         = velocity;	
	}
}
Regards,
Mobeen