Fixed timestep with box2d and SFML

Started by
3 comments, last by sun1 9 years, 10 months ago

Hi, I've tried to implement a simple demo using box2d and SFML (a simple moving box). I've managed to implement a fixed timestep to the one described here http://www.unagames.com/blog/daniele/2010/06/fixed-time-step-implementation-box2d . The only problem is that moving my simple square around, it seems to become slightly blurred and stretched. This maybe because its moving to fast (since it doesn't happen when moving slowly). I've ported this code to SDL as well and it seems to give similar results and I can't put my finger on why this is happening. I'm working on ubuntu but I've made a visual studios project for windows as well showing the problem:

Linux (executable) https://www.dropbox.com/s/dzf4f8w6f6fl1o0/FixedTimeStepTest.rar

WIndows (visual studios project) https://www.dropbox.com/s/ghazj8tqyppk8v9/sfml%20test.zip

Should work, but let me know if you have issues (mostly likely need to have box2d and sfml install if your running on linux and running on windows you'll need to point to sfml directory for the include directories).

The actual implementation of the fixed timestep can be found below:


void B2DWorld::update(float dt, ActionController<std::string>& actionController){
    m_fixedTimestepAccumulator += dt;
    const int steps = floor(m_fixedTimestepAccumulator / FIXED_TIMESTEP);

    if (steps > 0)
	{
		m_fixedTimestepAccumulator -= steps * FIXED_TIMESTEP;
	}

	assertAccumilation();
    m_fixedTimestepAccumulatorRatio = m_fixedTimestepAccumulator / FIXED_TIMESTEP;

    const int clampedSteps = std::min(steps, MAX_STEPS);
	for (int i = 0; i < clampedSteps; ++ i)
	{
		resetStates();
		actionController.triggerCallbacks(m_fixedTimestepAccumulatorRatio);
		step(FIXED_TIMESTEP);
	}

	interpolateStates();
	m_world.DrawDebugData();

}

void B2DWorld::step(float dt){
    m_world.Step(dt, VELOCITY_ITERATIONS, POSITION_ITERATIONS);
}

void B2DWorld::interpolateStates(){

	const float oneMinusRatio = 1.0f - m_fixedTimestepAccumulatorRatio;

	for (b2Body * b = m_world.GetBodyList (); b != NULL; b = b->GetNext ())
	{
		if (b->GetType () == b2_staticBody)
		{
			continue;
		}

		PhysicsComponent *c   = (PhysicsComponent*) b->GetUserData();
		c->smoothedPosition = m_fixedTimestepAccumulatorRatio * b->GetPosition () + oneMinusRatio * c->previousPosition;
		c->smoothedAngle = floor (m_fixedTimestepAccumulatorRatio * b->GetAngle () + oneMinusRatio * c->previousAngle);
	}

}

void B2DWorld::assertAccumilation(){
	assert (
		"Accumulator must have a value lesser than the fixed time step" &&
		m_fixedTimestepAccumulator < FIXED_TIMESTEP + FLT_EPSILON
	);
}

void B2DWorld::resetStates(){
for (b2Body * b = m_world.GetBodyList (); b != NULL; b = b->GetNext ())
	{
		if (b->GetType () == b2_staticBody)
		{
			continue;
		}
 		PhysicsComponent *c   = (PhysicsComponent*) b->GetUserData();
		c->smoothedPosition = c->previousPosition = b->GetPosition ();
		c->smoothedAngle = c->previousAngle = b->GetAngle ();
	}
}

The whole project is here: https://github.com/SundeepK/Clone/tree/wip/fix_time_step

After a bit of playing around, it looks like it maybe the way opengl renders things or the way its being setup. Any idea's on what maybe causing this issue? Thanks.

Advertisement
Looks like you are interpolating the position/previous position okay based on the error factor.

Don't do OpenGL but D3D single lines tend to look very blurry in motion. Guess that is how debug render is drawing them? I'd try putting some solid filled quads on and see if it is as apparent.

Looks like you are interpolating the position/previous position okay based on the error factor.

Don't do OpenGL but D3D single lines tend to look very blurry in motion. Guess that is how debug render is drawing them? I'd try putting some solid filled quads on and see if it is as apparent.

Yeah, I tried this and it still looks odd.

You can try temporarily setting m_fixedTimestepAccumulatorRatio to 1 before you call the draw call. That will at least tell you if this is anything to do with the interpolation or not.

I did a lot of that sort of thing when I was first trying to get interpolated motion working back in the day. Very handy to be able to rule out errors in the interpolation system.

I'm pretty sure that its not to do with the interpolation, since I've tried using the position from the box2d body directly. I've also written things to work by directly limiting frame rate as a test to 60 fps as well. Still cannot see why I'm getting this odd blurring. Thanks.

This topic is closed to new replies.

Advertisement