I've successfully set up an application doing 2D collision/physics using Bullet 2.75. Currently, my app basically bounces a shape through a grid of other shapes. I've used btBox2dShape (from the 2D collision demo in Bullet 2.75) and btSphereShape to do collisions between boxes and circles (both static and dynamic). I'm trying to set up collision shapes for arbitrary convex polygons, and that's where I'm running into trouble. I think btConvexHullShape is what I should use for this, but when I collide with a btBox2dShape, the reaction of a dynamic box hitting a static hexagon (created with btConvexHullShape) is all wrong. The box goes through the hexagon, deflecting off the center of mass a little bit. A collision is registered (the collision callback is called), but the box penetrates the hexagon completely instead of bouncing off the surface.
Am I following the correct steps for setting up a hexagon collision shape? What's the best way to set up an arbitrary convex polygon collision shape in 2D?
Here is my dynamics world initilaization:
Code: Select all
btVector3 worldAabbMin(0,0,0);
btVector3 worldAabbMax(2000,2500,0);
int maxProxies = 1024;
btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
dispatcher->registerCollisionCreateFunc(CUSTOM_CONVEX_SHAPE_TYPE, CUSTOM_CONVEX_SHAPE_TYPE, new btBox2dBox2dCollisionAlgorithm::CreateFunc);
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
m_dynamicsWorld->setGravity(btVector3(0,-200,0));
Code: Select all
btScalar hexagonVerts[] =
{
-10.0f, 20.0f, 0.0f,
10.0f, 20.0f, 0.0f,
20.0f, 0.0f, 0.0f,
10.0f, -20.0f, 0.0f,
-10.0f, -20.0f, 0.0f,
-20.0f, 0.0f, 0.0f,
};
btConvexHullShape* hexShape = new btConvexHullShape(hexagonVerts, 6, sizeof(btScalar) * 3);
btScalar mass = 0;
for(int i = WORLD_HEIGHT - 150; i > 80; i -= 150)
{
for(int j = offset * toggle; j < WORLD_WIDTH; j += 100)
{
btTransform trans(btVector3(0,0,0,1), btVector3(j,i,0));
btRigidBody* body = createRigidBody(*hexShape, trans, mass);
m_dynamicsWorld->addRigidBody(body);
}
}
Code: Select all
btRigidBody* Bullet2dTest::createRigidBody(btCollisionShape& shape, btTransform& transform, btScalar& mass)
{
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic)
{
shape.calculateLocalInertia(mass,localInertia);
}
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(transform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,&shape,localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
// constrain movement and rotation to the XY plane
body->setLinearFactor(btVector3(1,1,0));
body->setAngularFactor(btVector3(0,0,1));
return body;
}