improve contact stability for implicit scheme

This commit is contained in:
Xuchen Han
2020-06-17 18:43:49 -07:00
parent 4594927d02
commit f7354751a9
5 changed files with 47 additions and 38 deletions

View File

@@ -48,6 +48,7 @@ struct btContactSolverInfoData
btScalar m_erp2; //error reduction for contact constraints
btScalar m_deformable_erp; //error reduction for deformable constraints
btScalar m_deformable_cfm; //constraint force mixing for deformable constraints
btScalar m_deformable_maxErrorReduction; // maxErrorReduction for deformable contact
btScalar m_globalCfm; //constraint force mixing for contacts and non-contacts
btScalar m_frictionERP; //error reduction for friction constraints
btScalar m_frictionCFM; //constraint force mixing for friction constraints
@@ -86,6 +87,7 @@ struct btContactSolverInfo : public btContactSolverInfoData
m_erp2 = btScalar(0.2);
m_deformable_erp = btScalar(0.06);
m_deformable_cfm = btScalar(0.01);
m_deformable_maxErrorReduction = btScalar(0.1);
m_globalCfm = btScalar(0.);
m_frictionERP = btScalar(0.2); //positional friction 'anchors' are disabled by default
m_frictionCFM = btScalar(0.);

View File

@@ -49,7 +49,7 @@ public:
A.precondition(r, z);
A.project(z);
btScalar r_dot_z = this->dot(z,r);
if (r_dot_z <= Base::m_tolerance*d0) {
if (r_dot_z <= Base::m_tolerance * d0) {
if (verbose)
{
std::cout << "Iteration = 0" << std::endl;
@@ -86,7 +86,7 @@ public:
if (r_dot_z_new < Base::m_tolerance * d0) {
if (verbose)
{
std::cout << "ConjugateGradient iterations " << k << std::endl;
std::cout << "ConjugateGradient iterations " << k << " residual = " << r_dot_z_new << std::endl;
}
return k;
}

View File

@@ -438,12 +438,19 @@ void btDeformableBodySolver::predictDeformableMotion(btSoftBody* psb, btScalar d
// apply drag
n.m_v *= (1 - psb->m_cfg.drag);
// scale velocity back
if (n.m_v.norm() > max_v)
{
n.m_v.safeNormalize();
n.m_v *= max_v;
}
n.m_q = n.m_x + n.m_v * dt;
if (m_implicit)
{
n.m_q = n.m_x;
}
else
{
if (n.m_v.norm() > max_v)
{
n.m_v.safeNormalize();
n.m_v *= max_v;
}
n.m_q = n.m_x + n.m_v * dt;
}
n.m_splitv.setZero();
n.m_constrained = false;
}

View File

@@ -362,7 +362,7 @@ btScalar btDeformableRigidContactConstraint::solveConstraint(const btContactSolv
btScalar btDeformableRigidContactConstraint::solveSplitImpulse(const btContactSolverInfo& infoGlobal)
{
btScalar MAX_PENETRATION_CORRECTION = 0.1;
btScalar MAX_PENETRATION_CORRECTION = infoGlobal.m_deformable_maxErrorReduction;
const btSoftBody::sCti& cti = m_contact->m_cti;
btVector3 vb = getSplitVb();
btVector3 va = getSplitVa();

View File

@@ -70,6 +70,12 @@ btScalar btDeformableContactProjection::solveSplitImpulse(btCollisionObject** de
{
continue;
}
for (int k = 0; k < m_nodeRigidConstraints[j].size(); ++k)
{
btDeformableNodeRigidContactConstraint& constraint = m_nodeRigidConstraints[j][k];
btScalar localResidualSquare = constraint.solveSplitImpulse(infoGlobal);
residualSquare = btMax(residualSquare, localResidualSquare);
}
for (int k = 0; k < m_faceRigidConstraints[j].size(); ++k)
{
btDeformableFaceRigidContactConstraint& constraint = m_faceRigidConstraints[j][k];
@@ -140,15 +146,6 @@ void btDeformableContactProjection::setConstraints(const btContactSolverInfo& in
}
btDeformableFaceRigidContactConstraint constraint(contact, infoGlobal, m_useStrainLimiting);
m_faceRigidConstraints[i].push_back(constraint);
// btVector3 va = constraint.getVa();
// btVector3 vb = constraint.getVb();
// const btVector3 vr = vb - va;
// const btSoftBody::sCti& cti = contact.m_cti;
// const btScalar dn = btDot(vr, cti.m_normal);
// if (dn < SIMD_EPSILON)
// {
// m_faceRigidConstraints[i].push_back(constraint);
// }
}
}
}
@@ -255,33 +252,36 @@ void btDeformableContactProjection::setProjection()
{
int index = m_nodeRigidConstraints[i][j].m_node->index;
m_nodeRigidConstraints[i][j].m_node->m_constrained = true;
if (m_nodeRigidConstraints[i][j].m_static)
if (m_nodeRigidConstraints[i][j].m_binding)
{
if (m_projectionsDict.find(index) == NULL)
if (m_nodeRigidConstraints[i][j].m_static)
{
m_projectionsDict.insert(index, units);
}
else
{
btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
for (int k = 0; k < 3; ++k)
if (m_projectionsDict.find(index) == NULL)
{
projections.push_back(units[k]);
m_projectionsDict.insert(index, units);
}
else
{
btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
for (int k = 0; k < 3; ++k)
{
projections.push_back(units[k]);
}
}
}
}
else
{
if (m_projectionsDict.find(index) == NULL)
{
btAlignedObjectArray<btVector3> projections;
projections.push_back(m_nodeRigidConstraints[i][j].m_normal);
m_projectionsDict.insert(index, projections);
}
else
{
btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
projections.push_back(m_nodeRigidConstraints[i][j].m_normal);
if (m_projectionsDict.find(index) == NULL)
{
btAlignedObjectArray<btVector3> projections;
projections.push_back(m_nodeRigidConstraints[i][j].m_normal);
m_projectionsDict.insert(index, projections);
}
else
{
btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
projections.push_back(m_nodeRigidConstraints[i][j].m_normal);
}
}
}
}