approximate face contact WIP
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user