SVN commit 1191716 by majewsky: Propery set physical velocities with b2Body::ApplyLinearImpulse, and remove dependency of BlackHole::eject on Ball::doAdvance. M +13 -13 canvasitem.cpp M +0 -3 canvasitem.h M +4 -10 game.cpp --- trunk/KDE/kdegames/kolf/canvasitem.cpp #1191715:1191716 @@ -30,7 +30,6 @@ , m_body(0) , m_overlay(0) , m_simulationType(CanvasItem::CollisionSimulation) - , m_velocityChanged(true) { b2BodyDef bodyDef; bodyDef.userData = this; @@ -133,25 +132,30 @@ QPointF CanvasItem::physicalVelocity() const { - return m_physicalVelocity; + b2Vec2 v = m_body->GetLinearVelocity(); + return QPointF(v.x, v.y); } -void CanvasItem::setPhysicalVelocity(const QPointF& physicalVelocity) +void CanvasItem::setPhysicalVelocity(const QPointF& newVelocity) { - if (m_physicalVelocity != physicalVelocity) + const QPointF currentVelocity = this->physicalVelocity(); + if (newVelocity != currentVelocity) { - m_physicalVelocity = physicalVelocity; - m_velocityChanged = true; + const qreal mass = m_body->GetMass(); + if (mass == 0) + m_body->SetLinearVelocity(b2Vec2(newVelocity.x(), newVelocity.y())); + else + { + const QPointF impulse = (newVelocity - currentVelocity) * mass; + m_body->ApplyLinearImpulse(b2Vec2(impulse.x(), impulse.y()), m_body->GetPosition()); } } +} void CanvasItem::startSimulation() { const QPointF position = getPosition(); m_body->SetTransform(b2Vec2(position.x(), position.y()), 0); - if (m_velocityChanged) - m_body->SetLinearVelocity(b2Vec2(m_physicalVelocity.x(), m_physicalVelocity.y())); - m_velocityChanged = false; } void CanvasItem::endSimulation() @@ -165,10 +169,6 @@ //have a non-standard behavior with some classes (e.g. Ball), i.e. these //arguments trigger some black magic setPosition(position); - //read velocity - v = m_body->GetLinearVelocity(); - setPhysicalVelocity(QPointF(v.x, v.y)); - m_velocityChanged = false; //this was no manual change } Kolf::Overlay* CanvasItem::overlay(bool createIfNecessary) --- trunk/KDE/kdegames/kolf/canvasitem.h #1191715:1191716 @@ -183,9 +183,6 @@ Kolf::Overlay* m_overlay; QList m_shapes; CanvasItem::SimulationType m_simulationType; - QPointF m_physicalVelocity; - bool m_velocityChanged; //tells whether velocity has been changed programmatically after last simulation step - //The rationale behind this variable is that Box2D sometimes has very low velocities (~1e-10) during contacts. The QPointF conversion could create rounding errors on some platforms. }; //WARNING: pos() is at center (not at top-left edge of bounding rect!) --- trunk/KDE/kdegames/kolf/game.cpp #1191715:1191716 @@ -1277,17 +1277,11 @@ void BlackHole::eject(Ball *ball, double speed) { - ball->setPos(exitItem->pos()); + //place ball 10 units after exit, and set exit velocity + const Vector direction = Vector::fromMagnitudeDirection(1, -deg2rad(exitDeg)); + ball->setPos(exitItem->pos() + 10 * direction); + ball->setVelocity(speed * direction); - Vector v = Vector::fromMagnitudeDirection(10, -deg2rad(exitDeg)); - ball->setVelocity(v); - - // advance ball by 10 units - ball->doAdvance(); - - v.setMagnitude(speed); - ball->setVelocity(v); - ball->setForceStillGoing(false); ball->setVisible(true); ball->setState(Rolling);