I have visualised this and the cube and the plane definitely collide, so it is not an issue with the vertex coordinates. I have used btGImpactMeshShape for the shape of both the plane and the cube, and then btDefaultCollisionConfiguration to detect collisions. Are these two compatible?
I know that I can make a plane using something much more simple than a triangle mesh, but this is just a toy example, simplified from something more complex I am trying to make.
Below is my code for setting up Bullet and creating the two objects. After stepping through the simulation of the dynamics world, I get the behaviour describe above where the cube passes right through the plane.
Any help? Thank you!

Code: Select all
// Set up Bullet
btDefaultCollisionConfiguration* collision_configuration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collision_configuration);
btBroadphaseInterface* broadphase = new btDbvtBroadphase();
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
dynamics_world = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collision_configuration);
dynamics_world->setGravity(btVector3(0, -9.81, 0));
// Make the Plane
btTriangleIndexVertexArray* plane_mesh = MakePlaneMesh(); // My own function to create a thin plane mesh
btGImpactMeshShape* plane_shape = new btGImpactMeshShape(plane_mesh);
plane_shape->setLocalScaling(btVector3(1., 1., 1.));
plane_shape->setMargin(0.04f);
plane_shape->updateBound();
btVector3 plane_inertia(0,0,0);
btScalar plane_mass(0.0f); // Zero mass so that the plane is static
plane_shape->calculateLocalInertia(plane_mass, plane_inertia);
btTransform plane_start_transform;
plane_start_transform.setFromOpenGLMatrix(GetPlanePose()); // GetPlanePose() is my own function to get the pose of the plane, which is set to be below the cube
btDefaultMotionState* plane_start_motion_state = new btDefaultMotionState(plane_start_transform);
btRigidBody* plane = new btRigidBody(plane_mass, plane_start_motion_state, plane_shape, plane_inertia);
plane->setFriction(0.5);
plane->setRestitution(0.5);
dynamics_world->addRigidBody(plane);
// Make the Cube
btTriangleIndexVertexArray* cube_mesh = MakeCubeMesh(); // My own function to create a cube mesh
btGImpactMeshShape* cube_shape = new btGImpactMeshShape(cube_mesh);
cube_shape->setLocalScaling(btVector3(1., 1., 1.));
cube_shape->setMargin(0.04f);
cube_shape->updateBound();
btVector3 cube_inertia(0,0,0);
btScalar cube_mass(1.0f);
cube_shape->calculateLocalInertia(cube_mass, cube_inertia);
btTransform cube_start_transform;
cube_start_transform.setFromOpenGLMatrix(GetCubePose()); // GetCubePose() is my own function to get the pose of the cube, which is set to be above the plane
btDefaultMotionState* cube_start_motion_state = new btDefaultMotionState(cube_start_transform);
btRigidBody* cube = new btRigidBody(cube_mass, cube_start_motion_state, cube_shape, cube_inertia);
cube->setFriction(0.5);
cube->setRestitution(0.5);
dynamics_world->addRigidBody(cube);