void Entity::sync_visible(const b2Body * source, sf::Transformable& target) { if( source == NULL ) { BOOST_THROW_EXCEPTION(Game::Exception()); } // sync position { b2Vec2 b2_position = source->GetPosition(); sf::Vector2f sf_position( Game::Util::meter_to_pixel(b2_position.x), Game::Util::meter_to_pixel(b2_position.y) ); target.setPosition(sf_position); } // sync angle { target.setRotation( Game::Util::rad_to_deg(source->GetAngle()) ); } }
// Simple integrator. Accumulates error as time passes. void Integrator::Euler(PhysicState& physics, sf::Transformable& transf, const HiResDuration& dt) { float dtValue = ((float)dt.count()/ONE_SECOND.count()); transf.setPosition(transf.getPosition() + physics.getVelocity() * dtValue); physics.setVelocity(physics.getVelocity() + (physics.getForce() / physics.getMass()) * dtValue); }
// More accurate than Euler, but a bit more resource-consuming. void Integrator::RK4(PhysicState& physics, sf::Transformable& transf, const HiResDuration& dt) { float dtValue = ((float)dt.count()/ONE_SECOND.count()); Derivative a,b,c,d; Derivative initial; a = evaluateRK4(physics, transf, HiResDuration::zero(), initial); b = evaluateRK4(physics, transf, dt / 2, a); c = evaluateRK4(physics, transf, dt / 2, b); d = evaluateRK4(physics, transf, dt, c); sf::Vector2f dpdt = 1.0f / 6.0f * ( a.dp + 2.0f * (b.dp + c.dp) + d.dp ); sf::Vector2f dvdt = 1.0f / 6.0f * ( a.dv + 2.0f * (b.dv + c.dv) + d.dv ); transf.setPosition(transf.getPosition() + dpdt * dtValue); physics.setVelocity(physics.getVelocity() + dvdt * dtValue); }