Hi guys, here's a little question I'm sure some of you will be able to respond in under 5 secs...
I'm going to implement game that resembels Gish physics (you know, Jacobsen-like Verlets with relaxation etc), and now I'm prototyping some physics code. First, I solved FPS independent movement using technique presented by http://www.gaffer.org/game-physics/fix-your-timestep/ and everything works fine using Euler, RK4 and Verlet integration schemes. Objects move on the screen smoothly, without any visible jerking etc. So far so good.
However, problems arise when I throw a "few" more objects - the framerate drops very badly at even moderate numbers. Obviously, I'm testing the stuff in release mode and here are some sample values:
Euler: 350 objects at 30 fps
Verlet: 330 objects at 30fps
RK4: 70 objects at 30fps, drops below 5 with ~100 objects
It runs at ~500 fps with 1 object for all integration schemes. (yup, no vsync)
Here's code I use for integration:
// ------------- RK4
{
previous = current;
Derivative2d a = Evaluate(current, t);
Derivative2d b = Evaluate(current, t, dt*0.5f, a);
Derivative2d c = Evaluate(current, t, dt*0.5f, b);
Derivative2d d = Evaluate(current, t, dt, c);
const float dxdt = 1.0f/6.0f * (a.d_pos.x + 2.0f*(b.d_pos.x + c.d_pos.x) + d.d_pos.x);
const float dydt = 1.0f/6.0f * (a.d_pos.y + 2.0f*(b.d_pos.y + c.d_pos.y) + d.d_pos.y);
const float dvxdt = 1.0f/6.0f * (a.d_vel.x + 2.0f*(b.d_vel.x + c.d_vel.x) + d.d_vel.x);
const float dvydt = 1.0f/6.0f * (a.d_vel.y + 2.0f*(b.d_vel.y + c.d_vel.y) + d.d_vel.y);
current.pos.x = current.pos.x + dxdt*dt;
current.pos.y = current.pos.y + dydt*dt;
current.vel.x = current.vel.x + dvxdt*dt;
current.vel.y = current.vel.y + dvydt*dt;
}
// ------------- Euler
{
previous = current;
Derivative2d a = Evaluate(current, t);
current.pos.x = current.pos.x + a.d_pos.x*dt;
current.pos.y = current.pos.y + a.d_pos.y*dt;
current.vel.x = current.vel.x + a.d_vel.x*dt;
current.vel.y = current.vel.y + a.d_vel.y*dt;
}
// ------------- Verlet
{
Vector2 tmp = state.pos_current;
state.pos_current = (state.pos_current * 2 - state.pos_previous) + state.acceleration * (dt * dt);
state.pos_previous = tmp;
state.acceleration.Set(0,0);
}
// --- for curious ones
Derivative2d TEntity :: Evaluate( const State2d & _initial, float t )
{
Derivative2d output;
output.d_pos.x = _initial.vel.x;
output.d_pos.y = _initial.vel.y;
Acceleration(_initial, t, output ); // now does nothing
return output;
}
Here's the main loop:
float new_time = timer->GetTime();
float delta_time = new_time - current_time;
current_time = new_time;
accumulator += delta_time;
while (accumulator >= dt) // dt = 0.01
{
for (EntitiesItor itor = entities.begin(); itor != entities.end(); ++itor)
(*itor)->Integrate(t, dt);
t += dt;
accumulator -= dt;
}
const float alpha = accumulator / dt;
State2d state;
for (EntitiesItor itor = entities.begin(); itor != entities.end(); ++itor)
{
(*itor)->Update();
(*itor)->Render(renderer, (*itor)->Interpolate(alpha));
}
Does anyone have any ideas why this works so slow?
I don't believe that today powerful computers that run things like Unreal 3 or Crysis on >30 fps could have problems
moving a few dozens of objects, without any collision detection / collision resolving / any other activity taking place, so there's either sth inherently bad with my code, or that's the hard truth I'll have to accept.
I tried removing the rendering of objects, and it raised fps by only a few percent, so obviously I'm not GPU but CPU bound. Also, I have AMD 3500+ with plenty of DDR2 RAM, Radeon X1600 which is not that bad, so IMHO slow computer config is not the case.