I am using Bullet Physics and the gravity in my world seems to be too weak.
This means that items fall too slowly and general values don't make as much sense as they should.
While I know that "values" used in bullet are arbitrary, but the general usages suggests that 1 unit == 1 meter.
So gravity would be -9.80665f and one meter cube would be 1.0f,1.0f,1.0f
But when I set my world up in this way it takes about 18 seconds for my box to fall 100 units.
This is much much slower then I would expect.
So am I setting up the world incorrectly?
My world
CollisionConfiguration = new btDefaultCollisionConfiguration();
Dispatcher = new btCollisionDispatcher(CollisionConfiguration);
Broadphase = new btDbvtBroadphase();
Solver = new btSequentialImpulseConstraintSolver();
DynamicsWorld = new btDiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConfiguration);
DynamicsWorld->setGravity(btVector3(0.0f, -9.80665f, 0.0f));
PhysicsClock.reset();
Stepping the world (this gets called 32 times a second)
Microseconds = PhysicsClock.getTimeMicroseconds();
PhysicsClock.reset();
DynamicsWorld->stepSimulation(Microseconds / 1000000.0f);
My body
btCapsuleShape Shape(0.25f, 1.75f);
Body = new btRigidBody(80, &MotionState, &Shape);
Removed Body.setDamping(0.6f, .9999f);
Removed Body.setAngularFactor(btVector3(0, 0, 0));
Removed Body.setActivationState(DISABLE_DEACTIVATION);
Adding to the world
DynamicsWorld.addRigidBody(Body);
Motion state
void getWorldTransform(btTransform& centerOfMassWorldTrans) const override
{
centerOfMassWorldTrans = m_Transform;
}
void setWorldTransform(const btTransform& centerOfMassWorldTrans) override
{
m_Transform = centerOfMassWorldTrans;
...
Code used to control the stepping of the world
void WorldServer::UpdateWorldThread(void)
{
LARGE_INTEGER l_Frequency;
float l_TickInterval;
float l_Scale;
float l_Delay;
int l_TickBase;
LARGE_INTEGER l_TimeBase;
LARGE_INTEGER l_Now;
QueryPerformanceFrequency(&l_Frequency); //How many ticks per second
l_TickInterval = l_Frequency.QuadPart / c_WorldUpdateFrequency; //How many ticks per interval
l_Scale = l_Frequency.QuadPart / 1000.0f; //Scale for milliseconds
//Create a base that will allow us to catch frames up
QueryPerformanceCounter(&l_TimeBase); //Store base time
l_TickBase = 1; //Store base tick
while (IsRunning()) //While the world is running
{
************This bit is what calls the method to step the world
UpdateAll(); //Update
//Number of milliseconds to wait
QueryPerformanceCounter(&l_Now);
l_Delay = ((l_TimeBase.QuadPart - l_Now.QuadPart) + (l_TickBase * l_TickInterval)) / l_Scale;
//If there has been a large delay then we need to reset the base
if (l_Delay < -c_WorldUpdateDelayTolerance)
{
QueryPerformanceCounter(&l_TimeBase); //Store base time
l_TickBase = 0; //Store base tick
LogWarning("World has dropped %.2f ticks.", l_Delay / -l_TickInterval);
}
Sleep(max(0.0f, l_Delay)); //Yield CPU (this allows the thread to execute at a constant frequency)
l_TickBase++; //Count tick from base
}
//LogMessage("World UpdateWorldThread exited.");
}
I do have a number of other setting, but when I remove them I still have the same problems.
So what am I missing!
Note I know I could scale the world and simply multiple particular values by a common scale. But should i need to do this when my objects are in the "expected" scale?
I can definitely post more code if needed. Just ask.
I have done some more testing and I can now say that it takes 19.374506 seconds to fall 100 units.
I know this by using the following code
l_Microseconds = m_PhysicsClock.getTimeMicroseconds();
m_PhysicsClock.reset();
m_DynamicsWorld->stepSimulation(l_Microseconds / 1000000.0f);
total += l_Microseconds;
When the cube hits the ground I took a look at total and it was 19374506.