I've just started to get into Bullet, and I have been working for a few days now to get a simple implementation of it running in my game engine. I normally don't like to clutter these message boards with newbie questions, but I am just at a road block with this.
I dove into the BasicDemo and HelloWorld demos packaged with Bullet, and read the User Manual cover to cover. I then wrote (more like copied) the following code. The SetupBasicDemo() function is a line for line copy of BasicDemo::initPhysics(). When I run this, I get a 125 balls falling down, but they do not collide with the box or ground plane I also set up. The balls simply fall right through the box (or plane). I've been scrambling around the Demos to see if I have missed a call or something, but can't find an answer.
You guys see anything wrong? Thanks!
Code: Select all
//...
//Bunch of globals
//...
void BasicDemoSetup()
{
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btDefaultCollisionConfiguration();
//m_collisionConfiguration->setConvexConvexMultipointIterations();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
m_solver = sol;
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
m_dynamicsWorld->setDebugDrawer(new debugDrawer());
///create a few basic rigid bodies
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
//btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
//pm->addCollisionShape(groundShape);
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
{
btScalar mass(0.);
//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)
groundShape->calculateLocalInertia(mass,localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
//add the body to the dynamics world
m_dynamicsWorld->addRigidBody(body);
testGround = body;
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
//btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1));
btCollisionShape* colShape = new btSphereShape(1.0);
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
m_collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
//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)
colShape->calculateLocalInertia(mass,localInertia);
float start_x = START_POS_X - ARRAY_SIZE_X/2;
float start_y = START_POS_Y;
float start_z = START_POS_Z - ARRAY_SIZE_Z/2;
for (int k=0;k<ARRAY_SIZE_Y;k++)
{
for (int i=0;i<ARRAY_SIZE_X;i++)
{
for(int j = 0;j<ARRAY_SIZE_Z;j++)
{
startTransform.setOrigin(SCALING*btVector3(
2.0*i + start_x,
20+2.0*k + start_y,
2.0*j + start_z));
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
//body->setContactProcessingThreshold(colShape->getContactBreakingThreshold());
m_dynamicsWorld->addRigidBody(body);
testBody = body;
}
}
}
}
}
int mainLoop2()
{
qeConsClear();
qefnDrawGrid(20,1);
//update a draw physics
m_dynamicsWorld->stepSimulation(1.f/60.f,10);
m_dynamicsWorld->debugDrawWorld();
return 0;
}
int qeMain(int argc,chr *argv[])
{
BasicDemoSetup();
qeObjAddFnc(mainLoop2);
qeForever();
return 0;
}