Hello.
I am using Bullet Physics 2.82 and am getting some weird results. I build some voxel terrain and pass the mesh information to Bullet Physics (via btTriangleIndexVertexArray with btBvhTriangleMeshShape). It works fantastically, except that in certain spots basic shapes can fall through the terrain. Here is a video of it:
I have tried quite a bit to fix it, and post here as a "last resort" of sorts. Help is very much appreciated! I have tried:
- Rebuilding Bullet Physics with double precision.
- Increasing the cycles-per second to 120 and even 240 simulations/second.
- Increased all objects' collision margins (btCollisionShape::setMargin()) to larger values (0.1, 0.5, 1.0).
- Reversed the vertex winding order (in-case it was a backward facing polygon allowing the fall-through).
And still objects fall through the terrain! There is no visual deformity-- the terrain is built and displayed correctly. The debug drawer also shows the terrain is built in that area. The physics shape is built off of the same data that is used for the rendering. Any idea on what could cause this?
Terrain initialization (performed on each chunk of the terrain's octree):
// pre-filled, just here to show you the declaration
s32 * indices;
btScalar * vertices;
physicsMesh = new btTriangleIndexVertexArray(mesh->indices.size() / 3, indices, sizeof(s32) * 3, mesh->vertices.size(), vertices, sizeof(btScalar) * 3);
physicsShape = new btBvhTriangleMeshShape(physicsMesh, true, true);
physicsShape->setMargin(0.04); // tried changing to 0.1/0.5/1.0
btVector3 inertia(0, 0, 0);
physicsShape->calculateLocalInertia(0.0, inertia);
physicsMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, 0)));
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(
0, // mass
physicsMotionState,// initial position
physicsShape, // collision shape of body
inertia // local inertia
);
physicsRigidBody = new btRigidBody(rigidBodyCI);
physicsRigidBody->setLinearVelocity(btVector3(0, 0, 0));
physicsRigidBody->setAngularVelocity(btVector3(0, 0, 0));
physicsRigidBody->setFriction(1.0);
// This is done in a separate threads. Making it single-threaded made no difference.
bulletManager.lock();
bulletManager.addRigidBody(physicsRigidBody);
bulletManager.unlock();
Basic shape initialization:
physicsShape = new btSphereShape(minGroupRange);
physicsShape->setMargin(0.04); // tried 0.1/0.5/1.0
btVector3 inertia(0, 0, 0);
physicsShape->calculateLocalInertia(1.0, inertia);
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(
1.0, // mass
this, // initial position
physicsShape, // collision shape of body
inertia // local inertia
);
physicsRigidBody = new btRigidBody(rigidBodyCI);
physicsRigidBody->clearForces();
physicsRigidBody->setLinearVelocity(btVector3(0, 0, 0));
physicsRigidBody->setAngularVelocity(btVector3(0, 0, 0));
//physicsRigidBody->setActivationState(DISABLE_DEACTIVATION);
BulletManager::get().addRigidBody(physicsRigidBody);
And updating Bullet Physics:
dynamicsWorld->stepSimulation(timer.getDeltaTime_Seconds());
//dynamicsWorld->stepSimulation(timer.getDeltaTime_Seconds(), 10, 1.0 / 240);