Merge pull request #2984 from fuchuyuan/cachebarycenter

Cachebarycenter
This commit is contained in:
erwincoumans
2020-08-20 09:43:38 -07:00
committed by GitHub
6 changed files with 53 additions and 52 deletions

View File

@@ -1049,7 +1049,8 @@ btScalar btGjkEpaSolver2::SignedDistance(const btVector3& position,
const btScalar length = delta.length();
results.normal = delta / length;
results.witnesses[0] += results.normal * margin;
return (length - margin);
results.distance = length - margin;
return results.distance;
}
else
{

View File

@@ -30,7 +30,7 @@ class btConjugateResidual : public btKrylovSolver<MatrixX>
public:
btConjugateResidual(const int max_it_in)
: Base(max_it_in, 1e-4)
: Base(max_it_in, 1e-8)
{
}

View File

@@ -216,7 +216,7 @@ public:
class btDeformableFaceRigidContactConstraint : public btDeformableRigidContactConstraint
{
public:
const btSoftBody::Face* m_face;
btSoftBody::Face* m_face;
bool m_useStrainLimiting;
btDeformableFaceRigidContactConstraint(const btSoftBody::DeformableFaceRigidContact& contact, const btContactSolverInfo& infoGlobal, bool useStrainLimiting);
btDeformableFaceRigidContactConstraint(const btDeformableFaceRigidContactConstraint& other);

View File

@@ -452,7 +452,8 @@ void btDeformableContactProjection::checkConstraints(const TVStack& x)
d[j] += lm.m_weights[k] * x[lm.m_indices[k]].dot(lm.m_dirs[j]);
}
}
printf("d = %f, %f, %f\n", d[0], d[1], d[2]);
// printf("d = %f, %f, %f\n", d[0], d[1], d[2]);
// printf("val = %f, %f, %f\n", lm.m_vals[0], lm.m_vals[1], lm.m_vals[2]);
}
}
@@ -493,6 +494,7 @@ void btDeformableContactProjection::setLagrangeMultiplier()
lm.m_dirs[2] = btVector3(0, 0, 1);
m_lagrangeMultipliers.push_back(lm);
}
for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j)
{
if (!m_nodeRigidConstraints[i][j].m_binding)
@@ -519,17 +521,19 @@ void btDeformableContactProjection::setLagrangeMultiplier()
}
m_lagrangeMultipliers.push_back(lm);
}
for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j)
{
if (!m_faceRigidConstraints[i][j].m_binding)
{
continue;
}
const btSoftBody::Face* face = m_faceRigidConstraints[i][j].m_face;
btSoftBody::Face* face = m_faceRigidConstraints[i][j].m_face;
btVector3 bary = m_faceRigidConstraints[i][j].getContact()->m_bary;
LagrangeMultiplier lm;
lm.m_num_nodes = 3;
for (int k = 0; k < 3; ++k)
{
face->m_n[k]->m_constrained = true;
@@ -538,6 +542,7 @@ void btDeformableContactProjection::setLagrangeMultiplier()
}
if (m_faceRigidConstraints[i][j].m_static)
{
face->m_pcontact[3] = 1;
lm.m_num_constraints = 3;
lm.m_dirs[0] = btVector3(1, 0, 0);
lm.m_dirs[1] = btVector3(0, 1, 0);
@@ -545,6 +550,7 @@ void btDeformableContactProjection::setLagrangeMultiplier()
}
else
{
face->m_pcontact[3] = 0;
lm.m_num_constraints = 1;
lm.m_dirs[0] = m_faceRigidConstraints[i][j].m_normal;
}

View File

@@ -2818,46 +2818,10 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO
btTransform wtr = (predict) ? (colObjWrap->m_preTransform != NULL ? tmpCollisionObj->getInterpolationWorldTransform() * (*colObjWrap->m_preTransform) : tmpCollisionObj->getInterpolationWorldTransform())
: colObjWrap->getWorldTransform();
btScalar dst;
btGjkEpaSolver2::sResults results;
//#define USE_QUADRATURE 1
//#define CACHE_PREV_COLLISION
// use the contact position of the previous collision
#ifdef CACHE_PREV_COLLISION
if (f.m_pcontact[3] != 0)
{
for (int i = 0; i < 3; ++i)
bary[i] = f.m_pcontact[i];
contact_point = BaryEval(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary);
dst = m_worldInfo->m_sparsesdf.Evaluate(
wtr.invXform(contact_point),
shp,
nrm,
margin);
nrm = wtr.getBasis() * nrm;
cti.m_colObj = colObjWrap->getCollisionObject();
// use cached contact point
}
else
{
btGjkEpaSolver2::sResults results;
btTransform triangle_transform;
triangle_transform.setIdentity();
triangle_transform.setOrigin(f.m_n[0]->m_x);
btTriangleShape triangle(btVector3(0, 0, 0), f.m_n[1]->m_x - f.m_n[0]->m_x, f.m_n[2]->m_x - f.m_n[0]->m_x);
btVector3 guess(0, 0, 0);
const btConvexShape* csh = static_cast<const btConvexShape*>(shp);
btGjkEpaSolver2::SignedDistance(&triangle, triangle_transform, csh, wtr, guess, results);
dst = results.distance - margin;
contact_point = results.witnesses[0];
getBarycentric(contact_point, f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary);
nrm = results.normal;
cti.m_colObj = colObjWrap->getCollisionObject();
for (int i = 0; i < 3; ++i)
f.m_pcontact[i] = bary[i];
}
return (dst < 0);
#endif
// #define USE_QUADRATURE 1
//#define CACHE_PREV_COLLISION
// use collision quadrature point
#ifdef USE_QUADRATURE
@@ -2895,7 +2859,8 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO
return (dst < 0);
}
#endif
btGjkEpaSolver2::sResults results;
// collision detection using x*
btTransform triangle_transform;
triangle_transform.setIdentity();
triangle_transform.setOrigin(f.m_n[0]->m_q);
@@ -2906,19 +2871,50 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO
dst = results.distance - 2.0 * csh->getMargin() - margin; // margin padding so that the distance = the actual distance between face and rigid - margin of rigid - margin of deformable
if (dst >= 0)
return false;
// Use consistent barycenter to recalculate distance.
#ifdef CACHE_PREV_COLLISION
if (f.m_pcontact[3] != 0)
{
for (int i = 0; i < 3; ++i)
bary[i] = f.m_pcontact[i];
contact_point = BaryEval(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary);
const btConvexShape* csh = static_cast<const btConvexShape*>(shp);
btGjkEpaSolver2::SignedDistance(contact_point, margin, csh, wtr, results);
cti.m_colObj = colObjWrap->getCollisionObject();
dst = results.distance;
cti.m_normal = results.normal;
cti.m_offset = dst;
//point-convex CD
wtr = colObjWrap->getWorldTransform();
btTriangleShape triangle2(btVector3(0, 0, 0), f.m_n[1]->m_x - f.m_n[0]->m_x, f.m_n[2]->m_x - f.m_n[0]->m_x);
triangle_transform.setOrigin(f.m_n[0]->m_x);
btGjkEpaSolver2::SignedDistance(&triangle2, triangle_transform, csh, wtr, guess, results);
dst = results.distance - csh->getMargin() - margin;
return true;
}
#endif
// Use triangle-convex CD.
wtr = colObjWrap->getWorldTransform();
btTriangleShape triangle2(btVector3(0, 0, 0), f.m_n[1]->m_x - f.m_n[0]->m_x, f.m_n[2]->m_x - f.m_n[0]->m_x);
triangle_transform.setOrigin(f.m_n[0]->m_x);
btGjkEpaSolver2::SignedDistance(&triangle2, triangle_transform, csh, wtr, guess, results);
contact_point = results.witnesses[0];
getBarycentric(contact_point, f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary);
for (int i = 0; i < 3; ++i)
f.m_pcontact[i] = bary[i];
dst = results.distance - csh->getMargin() - margin;
cti.m_colObj = colObjWrap->getCollisionObject();
cti.m_normal = results.normal;
cti.m_offset = dst;
return true;
}
//
void btSoftBody::updateNormals()
{
const btVector3 zv(0, 0, 0);

View File

@@ -1686,6 +1686,7 @@ struct btSoftColliders
c.m_c2 = ima;
c.m_c3 = fc;
c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject() ? psb->m_cfg.kKHR : psb->m_cfg.kCHR;
c.m_c5 = n.m_effectiveMass_inv;
if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY)
{
@@ -1695,7 +1696,6 @@ struct btSoftColliders
const btVector3 ra = n.m_x - wtr.getOrigin();
c.m_c0 = ImpulseMatrix(1, n.m_effectiveMass_inv, imb, iwi, ra);
c.m_c5 = n.m_effectiveMass_inv;
// c.m_c0 = ImpulseMatrix(1, ima, imb, iwi, ra);
c.m_c1 = ra;
}
@@ -1766,7 +1766,6 @@ struct btSoftColliders
btVector3 bary;
if (psb->checkDeformableFaceContact(m_colObj1Wrap, f, contact_point, bary, m, c.m_cti, true))
{
f.m_pcontact[3] = 1;
btScalar ima = n0->m_im + n1->m_im + n2->m_im;
const btScalar imb = m_rigidBody ? m_rigidBody->getInvMass() : 0.f;
// todo: collision between multibody and fixed deformable face will be missed.
@@ -1839,10 +1838,9 @@ struct btSoftColliders
psb->m_faceRigidContacts.push_back(c);
}
}
else
{
f.m_pcontact[3] = 0;
}
// Set caching barycenters to be false after collision detection.
// Only turn on when contact is static.
f.m_pcontact[3] = 0;
}
btSoftBody* psb;
const btCollisionObjectWrapper* m_colObj1Wrap;