This is for a school project, and I'm having a bit of trouble with Bullet acting strangely.
I have an OpenGL project with Bullet Physics library working with Assimp model loaders and Magick++ texture loading. I load the triangulated faces of a walled table into the btTriangle mesh and load this into a btBvhTriangleMeshShape in the main program. This works fine when a sphere object is loaded into the program and constrained to the x-z axes, but when I allow the ball to roll around in all three dimensions, the ball simply goes through the mesh or pops underneath it. I've tried raising and lowering the ball and base table meshes, but at best, I get a weird orbiting movement around the walls that I can't quite figure out. My group tried asking the teaching assistants, but this is beyond their experience.
I make the models in Blender and checked that the faces are triangulated and normals are pointing outward, but nothing seems to help. As another attempt, I pulled out the floor of the model and just use the walls as btBvhTriangleMeshShapes with the floor acting as a btStaticPlaneShape. Both are set with collision flags as static objects and have their collision flags facing each other (ball to floor and floor to ball, etc), but nothing is helping. I would deeply appreciate any insight into this or if anyone has a great tutorial for this situation to help me understand it better.
///Initialize all of our resources(shaders, geometry) bool init = initialize(FileName); btBvhTriangleMeshShape *table = new btBvhTriangleMeshShape(tableMesh, false); //new btBvhTriangleMeshShape(tableMesh, true); // btScalar sphereDim(0.25); btScalar baseDim(5.0); btVector3 baseNorm(0, -1, 0); btCollisionShape *ball = new btSphereShape(sphereDim); btCollisionShape *base = new btStaticPlaneShape(baseNorm, baseDim); //new //Bullet //Tells Bullet how to check for collisions between objects btBroadphaseInterface *broadphase = new btDbvtBroadphase; //collision algorithm: used to register a callback that filters overlapping broadphase proxies btDefaultCollisionConfiguration *collisionConfiguration = new btDefaultCollisionConfiguration(); //Sends events to objects btCollisionDispatcher *dispatcher = new btCollisionDispatcher(collisionConfiguration); //causes objects to interact properly btSequentialImpulseConstraintSolver *solver = new btSequentialImpulseConstraintSolver; //Create a Physical world dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); //sets gravity dynamicsWorld->setGravity(btVector3(0, -9.81, 0)); dynamicsWorld->setInternalTickCallback(myTickCallback); // Table btScalar groundMass(0); btVector3 groundInertia(0,0,0); btDefaultMotionState *tableMotion = NULL; tableMotion = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(0, 0, 0))); table->calculateLocalInertia(groundMass, groundInertia); btRigidBody::btRigidBodyConstructionInfo tableRigidBodyCI(groundMass, tableMotion, table, groundInertia); tableRigidBody = new btRigidBody(tableRigidBodyCI); tableRigidBody->setFriction(1.0); tableRigidBody->setRestitution(0.975); tableRigidBody->setCollisionFlags(tableRigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); tableRigidBody->setActivationState(DISABLE_DEACTIVATION); dynamicsWorld-> addRigidBody(tableRigidBody, COL_TABLE, tableCollidesWith); // Base btScalar baseMass(0); btVector3 baseInertia(0,0,0); btDefaultMotionState *baseMotion = NULL; baseMotion = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(0, 0, 0))); base->calculateLocalInertia(baseMass, baseInertia); btRigidBody::btRigidBodyConstructionInfo baseRigidBodyCI(baseMass, baseMotion, base, baseInertia); baseRigidBody = new btRigidBody(baseRigidBodyCI); baseRigidBody->setFriction(1.0); baseRigidBody->setRestitution(0.975); baseRigidBody->setCollisionFlags(baseRigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); baseRigidBody->setActivationState(DISABLE_DEACTIVATION); dynamicsWorld-> addRigidBody(baseRigidBody, COL_BASE, baseCollidesWith); // Ball btScalar sphereMass(0.5); btVector3 sphereInertia(0.0, 0.0, 0.0); btDefaultMotionState *ballMotion = NULL; ballMotion = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(0, 1, 0))); ball->calculateLocalInertia(sphereMass, sphereInertia); btRigidBody::btRigidBodyConstructionInfo ballRigidBodyCI(sphereMass, ballMotion, ball, sphereInertia); ballRigidBody = new btRigidBody(ballRigidBodyCI); ballRigidBody->setActivationState(DISABLE_DEACTIVATION); ballRigidBody->setFriction(1.0); ballRigidBody->setRestitution(0.975); ballRigidBody->setLinearFactor(btVector3(1, 1, 1)); ballRigidBody->setAngularFactor(btVector3(1, 1, 1)); dynamicsWorld->addRigidBody(ballRigidBody, COL_BALL, ballCollidesWith);