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;
}
}
Mobeen