1
\$\begingroup\$

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);
\$\endgroup\$
  • \$\begingroup\$ Your bodies seem to be kinematic instead of static, any reason for that? \$\endgroup\$ – akaltar Dec 5 '15 at 10:54
  • \$\begingroup\$ Sorry about the delay in responding to this. You were totally right. I don't know why I thought to make it kinematic. I removed the flags, and it's working much better, now. Thank you! You saved my bacon. Have a great weekend! \$\endgroup\$ – Brittany Mcgarr Dec 5 '15 at 19:14
2
\$\begingroup\$

You should make your bodies static instead of kinematic. Basically remove lines like this:

tableRigidBody->setCollisionFlags(
            tableRigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);

For kinematic bodies you need to supply the transforms via a btMotionState.

\$\endgroup\$
  • \$\begingroup\$ @BrittanyMcgarr if this solved your problem, please consider marking it as the accepted answer. \$\endgroup\$ – Pip Jan 5 '16 at 0:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.