SVN commit 1191717 by majewsky: Decouple Box2D coordinates and scale them to a size which Box2D handles well. This is especially necessary because velocities are cut off by Box2D at 2 units per timestep (which it interprets as 2 m/s). M +10 -5 canvasitem.cpp M +11 -6 shape.cpp M +5 -0 shape.h --- trunk/KDE/kdegames/kolf/canvasitem.cpp #1191716:1191717 @@ -133,7 +133,7 @@ QPointF CanvasItem::physicalVelocity() const { b2Vec2 v = m_body->GetLinearVelocity(); - return QPointF(v.x, v.y); + return QPointF(v.x, v.y) / Kolf::Box2DScaleFactor; } void CanvasItem::setPhysicalVelocity(const QPointF& newVelocity) @@ -143,10 +143,15 @@ { const qreal mass = m_body->GetMass(); if (mass == 0) - m_body->SetLinearVelocity(b2Vec2(newVelocity.x(), newVelocity.y())); + { + m_body->SetLinearVelocity(b2Vec2( + newVelocity.x() * Kolf::Box2DScaleFactor, + newVelocity.y() * Kolf::Box2DScaleFactor + )); + } else { - const QPointF impulse = (newVelocity - currentVelocity) * mass; + const QPointF impulse = (newVelocity - currentVelocity) * mass * Kolf::Box2DScaleFactor; m_body->ApplyLinearImpulse(b2Vec2(impulse.x(), impulse.y()), m_body->GetPosition()); } } @@ -154,7 +159,7 @@ void CanvasItem::startSimulation() { - const QPointF position = getPosition(); + const QPointF position = getPosition() * Kolf::Box2DScaleFactor; m_body->SetTransform(b2Vec2(position.x(), position.y()), 0); } @@ -162,7 +167,7 @@ { //read position b2Vec2 v = m_body->GetPosition(); - QPointF position(v.x, v.y); + QPointF position = QPointF(v.x, v.y) / Kolf::Box2DScaleFactor; if (position != getPosition()) //HACK: The above condition can be removed later, but for now we need to //prevent moveBy() from being called with (0, 0) arguments because such --- trunk/KDE/kdegames/kolf/shape.cpp #1191716:1191717 @@ -44,7 +44,7 @@ , m_shape(0) { m_fixtureDef->density = 1; - m_fixtureDef->restitution = 0.8; + m_fixtureDef->restitution = 1; m_fixtureDef->friction = 0; m_fixtureDef->userData = this; } @@ -152,8 +152,9 @@ b2Shape* Kolf::EllipseShape::createShape() { - const b2Vec2 c = toB2Vec2(m_rect.center()); - const qreal rx = m_rect.width() / 2, ry = m_rect.height() / 2; + const b2Vec2 c = toB2Vec2(m_rect.center() * Kolf::Box2DScaleFactor); + const qreal rx = m_rect.width() * Kolf::Box2DScaleFactor / 2; + const qreal ry = m_rect.height() * Kolf::Box2DScaleFactor / 2; if (rx == ry) { //use circle shape when possible because it's cheaper and exact @@ -216,8 +217,9 @@ { b2PolygonShape* shape = new b2PolygonShape; shape->SetAsBox( - m_rect.width() / 2, m_rect.height() / 2, - toB2Vec2(m_rect.center()), + m_rect.width() * Kolf::Box2DScaleFactor / 2, + m_rect.height() * Kolf::Box2DScaleFactor / 2, + toB2Vec2(m_rect.center() * Kolf::Box2DScaleFactor), 0 //intrinsic rotation angle ); return shape; @@ -256,7 +258,10 @@ b2Shape* Kolf::LineShape::createShape() { b2EdgeShape* shape = new b2EdgeShape; - shape->Set(toB2Vec2(m_line.p1()), toB2Vec2(m_line.p2())); + shape->Set( + toB2Vec2(m_line.p1() * Kolf::Box2DScaleFactor), + toB2Vec2(m_line.p2() * Kolf::Box2DScaleFactor) + ); return shape; } --- trunk/KDE/kdegames/kolf/shape.h #1191716:1191717 @@ -29,6 +29,11 @@ namespace Kolf { + //All coordinates and units of Kolf's coordinate system are internally + //scaled with the following factor before using them with Box2D, because + //Box2D works best with lengths between 0.1 and 10 metres. + static const qreal Box2DScaleFactor = 0.025; + /** * @class Kolf::Shape *