The balls work ok when the terrain is flat and sometimes work on the terrain when it has had minor modifications, but with much deeper dips and higher mountains the balls simply fall through it.
The full code can be downloaded from here:
http://alexmac.cc/small-terrain-test.cpp
but here is the physics bit:
Code: Select all
// -----------------------------------------------------------------------------
// Bullet Physics
// -----------------------------------------------------------------------------
const int maxProxies = 32766;
btDynamicsWorld* world;
btCollisionDispatcher* dispatcher;
btOverlappingPairCache* broadphase;
btSequentialImpulseConstraintSolver* solver;
btRigidBody* mesh_body;
btTriangleMeshShape* mesh;
btTriangleIndexVertexArray *mesh_interface;
std::vector<btCollisionShape*> collision_meshes = std::vector<btCollisionShape*>();
std::vector<btRigidBody*> bodies = std::vector<btRigidBody*>();
void init_physics()
{
btVector3 worldAabbMin(-100,-100,-100);
btVector3 worldAabbMax(100,100,100);
dispatcher = new btCollisionDispatcher();
broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
solver = new btSequentialImpulseConstraintSolver();
world = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver);
world->setGravity(btVector3(0,-10,0));
// Trimesh
mesh_interface = new btTriangleIndexVertexArray(terrain_triangle_count,
&(terrain_triangles[0].v1),
sizeof(Triangle),
terrain_vertex_count,
&(terrain_vertices[0].x),
sizeof(Vertex));
mesh = new btTriangleMeshShape(mesh_interface);
btTransform mesh_pos;
mesh_pos.setIdentity();
mesh_pos.setOrigin(btVector3(0,0,0));
btDefaultMotionState* motionstate = new btDefaultMotionState(mesh_pos);
mesh_body = new btRigidBody(1000.0f,motionstate,mesh);
mesh_body->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT);
mesh_body->setActivationState(DISABLE_DEACTIVATION);
world->addRigidBody(mesh_body);
}
void add_ball(float xp, float yp, float zp)
{
float mass = 1.0f;
btVector3 inertia(0,0,0);
btTransform trans;
trans.setIdentity();
trans.setOrigin(btVector3(xp,yp,zp));
btCollisionShape *geom = new btSphereShape (ball_radius);
geom->calculateLocalInertia(mass,inertia);
btDefaultMotionState* motionstate = new btDefaultMotionState(trans);
btRigidBody* body = new btRigidBody(mass,motionstate,geom,inertia);
body->setCcdSquareMotionThreshold( ball_radius );
body->setCcdSweptSphereRadius( 0.2*ball_radius );
body->setActivationState(DISABLE_DEACTIVATION);
world->addRigidBody(body);
bodies.push_back(body);
collision_meshes.push_back(geom);
std::cout << "ball added: " << xp << ", " << yp << ", " << zp << std::endl;
}
void render_balls()
{
int num = bodies.size();
btDefaultMotionState* ms;
float m[16];
for(int i=0; i<num; i++)
{
btPoint3 com = bodies[i]->getCenterOfMassPosition();
ms = (btDefaultMotionState*)bodies[i]->getMotionState();
ms->m_graphicsWorldTrans.getOpenGLMatrix(m);
glColor3f(0.0f, 1.0f, 0.0f);
glPushMatrix();
glMultMatrixf(m);
gluSphere(ball, ball_radius, 10, 10);
glPopMatrix();
}
}
void step_physics()
{
world->updateAabbs();
world->stepSimulation(1.0 / 60.0f);
}
Maybe I need to tell bullet that I've modified the trimesh? I'm a real newbie so any help is greatly appreciated