I have set up a very simple demo using Bullet where an object moves along the ground using linear velocity which is constantly set to the same value over 200 frames and then the object falls through the ground but only up to a third of its height. E.g.: If I have a RidgidBody with a box collision of size x: 2, y: 8, z: 2 (half extents x: 1, y: 4, z: 1) after 200 or so frames the object falls from position 4 to 1 (ground's top is at zero).
I have set it up with the following:
- Time step and fixed time step set to 0.0167f (so 60hz)
- Added a ground with box collision, zero mass.
- The dynamic object has a box collision.
Any ideas why this is happening?
My code is all wrapped up with custom code, so I have pulled out all the Bullet Physics specific code and placed it below:
Code: Select all
float timeStep = 0.0167f;
btDiscreteDynamicsWorld* dynamicsWorld = // Standard set up of btDiscreteDynamicsWorld
dynamicsWorld->setGravity(btVector3(0, -5, 0));
dynamicsWorld->getSimulationIslandManager()->setSplitIslands(false);
{
btCollisionShape* groundShape = new btBoxShape(btVector3(40, 5, 40));
btVector3 localInertia(0, 0, 0);
btTransform initialTransform;
initialTransform.setIdentity();
initialTransform.setOrigin(btVector3(0, -5, 0));
btDefaultMotionState* myMotionState = new btDefaultMotionState(initialTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(0, myMotionState, groundShape, localInertia);
btRigidBody* rb = new btRigidBody(rbInfo);
rb->setActivationState(DISABLE_DEACTIVATION);
rb->setSleepingThresholds(0,0);
dynamicsWorld->addRigidBody(rb, 1, 1);
}
{
float mass = 1;
btCollisionShape* playerShape = new btBoxShape(btVector3(1, 4, 1));
btVector3 localInertia(0, 0, 0);
playerShape ->calculateLocalInertia(mass, localInertia);
btTransform initialTransform;
initialTransform.setIdentity();
initialTransform.setOrigin(btVector3(0, 4, 0));
btDefaultMotionState* myMotionState = new btDefaultMotionState(initialTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, playerShape, localInertia);
btRigidBody* rb = new btRigidBody(rbInfo);
rb->setActivationState(DISABLE_DEACTIVATION);
rb->setSleepingThresholds(0,0);
dynamicsWorld->addRigidBody(rb, 1, 1);
}
for (int i = 0; i < 1000; i++)
{
dynamicsWorld->stepSimulation(timeStep , 10, timeStep);
btRigidBody* playerRb = //get the player object.
// Simulate a constant velocity
if(i > 50 && i < 200)
{
btVector3 newVelocity = btVector3(2.0f, 0, 0);
playerRb->setLinearVelocity(newVelocity);
}
}