Using btTriangleShape objects as btCompoundShape children (C++)

Post Reply
danilopeixoto
Posts: 1
Joined: Tue Jun 12, 2018 7:16 am

Using btTriangleShape objects as btCompoundShape children (C++)

Post by danilopeixoto »

Hi,

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;
}
Thanks.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Using btTriangleShape objects as btCompoundShape children (C++)

Post by drleviathan »

I ran your code and it printed out some results, but it wasn't consistent after subsequent runs. I modified the output to be more verbose and present the results of repeated runs below.

The results are not deterministic. I don't understand why.

Code: Select all

manifoldCount = 12
manifold0  contactCount = 0
manifold1  contactCount = 0
manifold2  contactCount = 0
manifold3  contactCount = 0
manifold4  contactCount = 0
manifold5  contactCount = 0
manifold6  contactCount = 0
manifold7  contactCount = 0
manifold8  contactCount = 0
manifold9  contactCount = 0
manifold10  contactCount = 0
manifold11  contactCount = 0

manifoldCount = 12
manifold0  contactCount = 0
manifold1  contactCount = 0
manifold2  contactCount = 0
manifold3  contactCount = 0
manifold4  contactCount = 0
manifold5  contactCount = 0
manifold6  contactCount = 0
manifold7  contactCount = 0
manifold8  contactCount = 0
manifold9  contactCount = 0
manifold10  contactCount = 0
manifold11  contactCount = 0

manifoldCount = 12
manifold0  contactCount = 0
manifold1  contactCount = 0
manifold2  contactCount = 0
manifold3  contactCount = 0
manifold4  contactCount = 0
manifold5  contactCount = 0
manifold6  contactCount = 0
manifold7  contactCount = 0
manifold8  contactCount = 0
manifold9  contactCount = 0
manifold10  contactCount = 0
manifold11  contactCount = 0

manifoldCount = 12
manifold0  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, -0.000447213, -2.7457e-11)  normalOnB = (-0.894427, 0.447213, 1.12476e-08)  indexes = 3,2
manifold1  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (-0.00268328, -0.00134164, -1.62095e-11)  normalOnB = (0.894427, 0.447214, -8.6762e-22)  indexes = 1,2
manifold2  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, -0.000447213, -2.7457e-11)  normalOnB = (-0.894427, 0.447213, 1.12476e-08)  indexes = 3,3
manifold3  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (-0.00268328, -0.00134164, -1.62095e-11)  normalOnB = (0.894427, 0.447214, -8.6762e-22)  indexes = 1,3
manifold4  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (-0.00268328, 0.00134164, 1.75332e-11)  normalOnB = (0.894427, -0.447213, -1.12476e-08)  indexes = 3,1
manifold5  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, 0.000447214, -1.62095e-11)  normalOnB = (-0.894427, -0.447214, 8.6762e-22)  indexes = 1,1
manifold6  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, 0.000447214, -1.62095e-11)  normalOnB = (-0.894427, -0.447214, 8.6762e-22)  indexes = 0,2
manifold7  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, 0.000447214, -1.62095e-11)  normalOnB = (-0.894427, -0.447214, 8.6762e-22)  indexes = 0,3
manifold8  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, 0.000447214, -1.62095e-11)  normalOnB = (-0.894427, -0.447214, 8.6762e-22)  indexes = 0,1
manifold9  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, -0.000447213, -2.7457e-11)  normalOnB = (-0.894427, 0.447213, 1.12476e-08)  indexes = 3,0
manifold10  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (-0.00268328, -0.00134164, -1.62095e-11)  normalOnB = (0.894427, 0.447214, -3.92791e-31)  indexes = 1,0
manifold11  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, 0.000447214, -1.62095e-11)  normalOnB = (-0.894427, -0.447214, 3.92791e-31)  indexes = 0,0

manifoldCount = 12
manifold0  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, -0.000447213, -1.1993e-11)  normalOnB = (-0.894427, 0.447213, 1.12476e-08)  indexes = 3,2
manifold1  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (-0.00268328, -0.00134164, -7.45433e-13)  normalOnB = (0.894427, 0.447214, -1.78683e-24)  indexes = 1,2
manifold2  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, -0.000447213, -1.1993e-11)  normalOnB = (-0.894427, 0.447213, 1.12476e-08)  indexes = 3,3
manifold3  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (-0.00268328, -0.00134164, -7.45433e-13)  normalOnB = (0.894427, 0.447214, -1.78683e-24)  indexes = 1,3
manifold4  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (-0.00268328, 0.00134164, 3.29972e-11)  normalOnB = (0.894427, -0.447213, -1.12476e-08)  indexes = 3,1
manifold5  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, 0.000447214, -7.45433e-13)  normalOnB = (-0.894427, -0.447214, 1.78683e-24)  indexes = 1,1
manifold6  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, 0.000447214, -7.45433e-13)  normalOnB = (-0.894427, -0.447214, 1.78683e-24)  indexes = 0,2
manifold7  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, 0.000447214, -7.45433e-13)  normalOnB = (-0.894427, -0.447214, 1.78683e-24)  indexes = 0,3
manifold8  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, 0.000447214, -7.45433e-13)  normalOnB = (-0.894427, -0.447214, 1.78683e-24)  indexes = 0,1
manifold9  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, -0.000447213, -1.1993e-11)  normalOnB = (-0.894427, 0.447213, 1.12476e-08)  indexes = 3,0
manifold10  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (-0.00268328, -0.00134164, -7.45433e-13)  normalOnB = (0.894427, 0.447214, -1.162e-33)  indexes = 1,0
manifold11  contactCount = 1
  contactPoint0  distance = -0.002  pointOnA = (0.000894427, 0.000447214, -7.45433e-13)  normalOnB = (-0.894427, -0.447214, 1.162e-33)  indexes = 0,0

manifoldCount = 12
manifold0  contactCount = 0
manifold1  contactCount = 0
manifold2  contactCount = 0
manifold3  contactCount = 0
manifold4  contactCount = 0
manifold5  contactCount = 0
manifold6  contactCount = 0
manifold7  contactCount = 0
manifold8  contactCount = 0
manifold9  contactCount = 0
manifold10  contactCount = 0
manifold11  contactCount = 0
hyyou
Posts: 96
Joined: Wed Mar 16, 2016 10:11 am

Re: Using btTriangleShape objects as btCompoundShape children (C++)

Post by hyyou »

This line ......

Code: Select all

 tetrahedralShape0->addChildShape(btTransform(), triangle0);
"btTransform()" <----- No initialization constructor is called!
Please "setIdentity ()" before you use it.

Reference: http://bulletphysics.org/Bullet/BulletF ... sform.html

By the way, I don't think inheriting Bullet's class is a good idea for a non-trivial project.
Post Reply