I am trying to collide two deformable tetrahedral meshes using the Bullet Physics C++ Library. I'm only using the external faces (triangular shell) of the tetrahedral mesh to detect collision. These external triangles are added to a btCompoundShape using btTriangleShape with fast AABB computation. Contact manifolds are calculated correctly, but no contact points are available. Am I doing something wrong about using btTriangleShape class?
Source code:
Code: Select all
#include <iostream>
#include <btBulletCollisionCommon.h>
#include <BulletCollision/CollisionShapes/btTriangleShape.h>
class TriangleShape : public btTriangleShape {
public:
TriangleShape(const btVector3 & v0, const btVector3 & v1, const btVector3 & v2)
: btTriangleShape(v0, v1, v2) {
setMargin(0.001);
}
void getAabb(const btTransform & transform, btVector3 & min, btVector3 & max) const {
min.setValue(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT);
max.setValue(-BT_LARGE_FLOAT, -BT_LARGE_FLOAT, -BT_LARGE_FLOAT);
btVector3 vertex;
for (int i = 0; i < 3; i++) {
getVertex(i, vertex);
min.setMin(vertex);
max.setMax(vertex);
}
min[0] -= m_collisionMargin;
min[1] -= m_collisionMargin;
min[2] -= m_collisionMargin;
max[0] += m_collisionMargin;
max[1] += m_collisionMargin;
max[2] += m_collisionMargin;
}
};
int main(int argc, char ** argv) {
// Single tetrahedron (outward normal)
btCollisionShape * triangle0 =
new TriangleShape(
btVector3(-1.962423, -0.962423, 0.962423),
btVector3(-0.037577, -0.962423, 0.000000),
btVector3(-1.000000, 0.962423, 0.000000));
btCollisionShape * triangle1 =
new TriangleShape(
btVector3(-1.000000, 0.962423, 0.000000),
btVector3(-0.037577, -0.962423, 0.000000),
btVector3(-1.962423, -0.962423, -0.962423));
btCollisionShape * triangle2 =
new TriangleShape(
btVector3(-1.962423, -0.962423, -0.962423),
btVector3(-0.037577, -0.962423, 0.000000),
btVector3(-1.962423, -0.962423, 0.962423));
btCollisionShape * triangle3 =
new TriangleShape(
btVector3(-1.962423, -0.962423, -0.962423),
btVector3(-1.962423, -0.962423, 0.962423),
btVector3(-1.000000, 0.962423, 0.000000));
// Same tetrahedron with y coordinate translated 1.5 units up from its original position.
double offset = 1.5;
btCollisionShape * triangle4 =
new TriangleShape(
btVector3(-1.962423, -0.962423 + offset, 0.962423),
btVector3(-0.037577, -0.962423 + offset, 0.000000),
btVector3(-1.000000, 0.962423 + offset, 0.000000));
btCollisionShape * triangle5 =
new TriangleShape(
btVector3(-1.000000, 0.962423 + offset, 0.000000),
btVector3(-0.037577, -0.962423 + offset, 0.000000),
btVector3(-1.962423, -0.962423 + offset, -0.962423));
btCollisionShape * triangle6 =
new TriangleShape(
btVector3(-1.962423, -0.962423 + offset, -0.962423),
btVector3(-0.037577, -0.962423 + offset, 0.000000),
btVector3(-1.962423, -0.962423 + offset, 0.962423));
btCollisionShape * triangle7 =
new TriangleShape(
btVector3(-1.962423, -0.962423 + offset, -0.962423),
btVector3(-1.962423, -0.962423 + offset, 0.962423),
btVector3(-1.000000, 0.962423 + offset, 0.000000));
btCompoundShape * tetrahedralShape0 = new btCompoundShape();
tetrahedralShape0->addChildShape(btTransform(), triangle0);
tetrahedralShape0->addChildShape(btTransform(), triangle1);
tetrahedralShape0->addChildShape(btTransform(), triangle2);
tetrahedralShape0->addChildShape(btTransform(), triangle3);
btCompoundShape * tetrahedralShape1 = new btCompoundShape();
tetrahedralShape1->addChildShape(btTransform(), triangle4);
tetrahedralShape1->addChildShape(btTransform(), triangle5);
tetrahedralShape1->addChildShape(btTransform(), triangle6);
tetrahedralShape1->addChildShape(btTransform(), triangle7);
btCollisionObject * object0 = new btCollisionObject();
object0->setCollisionShape(tetrahedralShape0);
btCollisionObject * object1 = new btCollisionObject();
object1->setCollisionShape(tetrahedralShape1);
btCollisionConfiguration * configuration = new btDefaultCollisionConfiguration();
btCollisionDispatcher * dispatcher = new btCollisionDispatcher(configuration);
btBroadphaseInterface * broadphase = new btDbvtBroadphase();
btCollisionWorld * world = new btCollisionWorld(dispatcher, broadphase, configuration);
world->addCollisionObject(object0);
world->addCollisionObject(object1);
world->performDiscreteCollisionDetection();
int manifoldCount = dispatcher->getNumManifolds();
for (int i = 0; i < manifoldCount; i++) {
btPersistentManifold * contactManifold = dispatcher->getManifoldByIndexInternal(i);
int contactCount = contactManifold->getNumContacts();
const btCollisionObject * a = contactManifold->getBody0();
const btCollisionObject * b = contactManifold->getBody1();
for (int j = 0; j < contactCount; j++) {
btManifoldPoint & contactPoint = contactManifold->getContactPoint(j);
if (contactPoint.getDistance() < 0) {
const btVector3 & point = contactPoint.getPositionWorldOnA();
std::cout << '(' << point.x() << ", " << point.y() << ", " << point.z() << ')' << std::endl;
}
}
}
delete world, broadphase, dispatcher, configuration;
delete object0, object1, tetrahedralShape0, tetrahedralShape1;
delete triangle0, triangle1, triangle2, triangle3;
delete triangle4, triangle5, triangle6, triangle7;
return 0;
}