approximate face contact WIP

This commit is contained in:
Xuchen Han
2019-11-12 11:50:47 -08:00
parent 794614f269
commit 42b5c93bad
3 changed files with 46 additions and 20 deletions

View File

@@ -117,7 +117,7 @@ void btSoftBody::initDefaults()
m_restLengthScale = btScalar(1.0); m_restLengthScale = btScalar(1.0);
m_dampingCoefficient = 1; m_dampingCoefficient = 1;
m_sleepingThreshold = 0.1; m_sleepingThreshold = 0.1;
m_useFaceContact = false; m_useFaceContact = true;
m_useSelfCollision = false; m_useSelfCollision = false;
m_collisionFlags = 0; m_collisionFlags = 0;
} }
@@ -2443,7 +2443,7 @@ static void getBarycentric(const btVector3& p, btVector3& a, btVector3& b, btVec
// //
bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colObjWrap, bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colObjWrap,
const Face& f, Face& f,
btVector3& contact_point, btVector3& contact_point,
btVector3& bary, btVector3& bary,
btScalar margin, btScalar margin,
@@ -2454,26 +2454,46 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO
const btCollisionObject* tmpCollisionObj = colObjWrap->getCollisionObject(); const btCollisionObject* tmpCollisionObj = colObjWrap->getCollisionObject();
// use the position x_{n+1}^* = x_n + dt * v_{n+1}^* where v_{n+1}^* = v_n + dtg for collision detect // use the position x_{n+1}^* = x_n + dt * v_{n+1}^* where v_{n+1}^* = v_n + dtg for collision detect
// but resolve contact at x_n // but resolve contact at x_n
btTransform wtr = (predict) ? // btTransform wtr = (predict) ?
(colObjWrap->m_preTransform != NULL ? tmpCollisionObj->getInterpolationWorldTransform()*(*colObjWrap->m_preTransform) : tmpCollisionObj->getInterpolationWorldTransform()) // (colObjWrap->m_preTransform != NULL ? tmpCollisionObj->getInterpolationWorldTransform()*(*colObjWrap->m_preTransform) : tmpCollisionObj->getInterpolationWorldTransform())
: colObjWrap->getWorldTransform(); // : colObjWrap->getWorldTransform();
const btTransform& wtr = colObjWrap->getWorldTransform();
btGjkEpaSolver2::sResults results; btScalar dst;
btTransform triangle_transform; // if (f.m_pcontact[3] != 0)
triangle_transform.setIdentity(); if (0)
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); for (int i = 0; i < 3; ++i)
btVector3 guess(0,0,0); bary[i] = f.m_pcontact[i];
const btConvexShape* csh = static_cast<const btConvexShape*>(shp); contact_point = BaryEval(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary);
btGjkEpaSolver2::SignedDistance(&triangle, triangle_transform, csh, wtr, guess, results); dst = m_worldInfo->m_sparsesdf.Evaluate(
btScalar dst = results.distance - margin; wtr.invXform(contact_point),
contact_point = results.witnesses[0]; shp,
getBarycentric(contact_point, f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary); nrm,
margin);
nrm = wtr.getBasis() * nrm;
// 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;
for (int i = 0; i < 3; ++i)
f.m_pcontact[i] = bary[i];
}
if (!predict) if (!predict)
{ {
cti.m_colObj = colObjWrap->getCollisionObject(); cti.m_colObj = colObjWrap->getCollisionObject();
// cti.m_normal = wtr.getBasis() * results.normal; cti.m_normal = nrm;
cti.m_normal = results.normal;
cti.m_offset = dst; cti.m_offset = dst;
} }
if (dst < 0) if (dst < 0)

View File

@@ -288,6 +288,7 @@ public:
btVector3 m_normal; // Normal btVector3 m_normal; // Normal
btScalar m_ra; // Rest area btScalar m_ra; // Rest area
btDbvtNode* m_leaf; // Leaf data btDbvtNode* m_leaf; // Leaf data
btVector4 m_pcontact; // barycentric weights of the persistent contact
int m_index; int m_index;
}; };
/* Tetra */ /* Tetra */
@@ -1120,7 +1121,7 @@ public:
void initializeFaceTree(); void initializeFaceTree();
btVector3 evaluateCom() const; btVector3 evaluateCom() const;
bool checkDeformableContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const; bool checkDeformableContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const;
bool checkDeformableFaceContact(const btCollisionObjectWrapper* colObjWrap, const Face& x, btVector3& contact_point, btVector3& bary, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const; bool checkDeformableFaceContact(const btCollisionObjectWrapper* colObjWrap, Face& x, btVector3& contact_point, btVector3& bary, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const;
bool checkContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti) const; bool checkContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti) const;
void updateNormals(); void updateNormals();
void updateBounds(); void updateBounds();

View File

@@ -1166,6 +1166,7 @@ struct btSoftColliders
btVector3 bary; btVector3 bary;
if (psb->checkDeformableFaceContact(m_colObj1Wrap, f, contact_point, bary, m, c.m_cti, true)) 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; btScalar ima = n0->m_im + n1->m_im + n2->m_im;
const btScalar imb = m_rigidBody ? m_rigidBody->getInvMass() : 0.f; const btScalar imb = m_rigidBody ? m_rigidBody->getInvMass() : 0.f;
// todo: collision between multibody and fixed deformable face will be missed. // todo: collision between multibody and fixed deformable face will be missed.
@@ -1236,6 +1237,10 @@ struct btSoftColliders
psb->m_faceRigidContacts.push_back(c); psb->m_faceRigidContacts.push_back(c);
} }
} }
else
{
f.m_pcontact[3] = 0;
}
} }
btSoftBody* psb; btSoftBody* psb;
const btCollisionObjectWrapper* m_colObj1Wrap; const btCollisionObjectWrapper* m_colObj1Wrap;