[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdegames/kolf
From: Stefan Majewsky <majewsky () gmx ! net>
Date: 2010-10-31 23:23:19
Message-ID: 20101031232319.CF028AC8A6 () svn ! kde ! org
[Download RAW message or body]
SVN commit 1191712 by majewsky:
Add methods to CanvasItem to synchronize visual and physical \
representation.
Box2D's bodies maintain their own coordinate systems and velocities,
which we have to keep in sync with the CanvasItems. I've added a new
physicalVelocity property to CanvasItem which is temporarily separate
from the current velocity, because both the home-grown and Box2D-based
time evolution will run in parallel for some time, until everything has
been ported to Box2D.
Setting CanvasItem::velocity() will result in the object participating
in the home-grown time evolution, while a non-zero physicalVelocity()
will be applied by Box2D. Hence, while the ball does not yet have a
physicalVelocity(), Box2D will not resolve its collisions.
M +38 -0 canvasitem.cpp
M +21 -0 canvasitem.h
M +16 -0 game.h
M +2 -0 slope.h
--- trunk/KDE/kdegames/kolf/canvasitem.cpp #1191711:1191712
@@ -30,6 +30,7 @@
, m_body(0)
, m_overlay(0)
, m_simulationType(CanvasItem::CollisionSimulation)
+ , m_velocityChanged(true)
{
b2BodyDef bodyDef;
bodyDef.userData = this;
@@ -130,6 +131,43 @@
}
}
+QPointF CanvasItem::physicalVelocity() const
+{
+ return m_physicalVelocity;
+}
+
+void CanvasItem::setPhysicalVelocity(const QPointF& physicalVelocity)
+{
+ if (m_physicalVelocity != physicalVelocity)
+ {
+ m_physicalVelocity = physicalVelocity;
+ m_velocityChanged = true;
+ }
+}
+
+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()
+{
+ //read position
+ b2Vec2 v = m_body->GetPosition();
+ setPosition(QPointF(v.x, v.y));
+ //read velocity
+ v = m_body->GetLinearVelocity();
+ const QPointF velocity(v.x, v.y);
+ setVelocity(velocity);
+ //unset m_velocityChanged if there was no manual change since last \
simulation step (TODO: necessary?) + if (velocity == m_physicalVelocity)
+ m_velocityChanged = false;
+}
+
Kolf::Overlay* CanvasItem::overlay(bool createIfNecessary)
{
//the overlay is created once it is requested
--- trunk/KDE/kdegames/kolf/canvasitem.h #1191711:1191712
@@ -117,6 +117,10 @@
virtual void setVelocity(const Vector& velocity) { m_velocity = velocity; \
} Vector velocity() const { return m_velocity; }
virtual void moveBy(double , double) { kDebug(12007) << "Warning, empty \
moveBy used";} //needed so that float can call the own custom moveBy()s of \
everything on it +
+ //The following is needed temporarily while CanvasItem is not a \
QGraphicsItem by itself. + virtual void setPosition(const QPointF& pos) = \
0; + virtual QPointF getPosition() const = 0;
protected:
///pointer to main KolfGame
KolfGame *game;
@@ -151,10 +155,21 @@
QList<Kolf::Shape*> shapes() const { return m_shapes; }
Kolf::Overlay* overlay(bool createIfNecessary = true);
+
+ ///This is the velocity used by the physics engine: In each time step,
+ ///the position of this canvas item changes by the value of this \
property. + QPointF physicalVelocity() const;
+ void setPhysicalVelocity(const QPointF& physicalVelocity);
protected:
void addShape(Kolf::Shape* shape);
///Configure how this object will participate in physical simulation.
void setSimulationType(CanvasItem::SimulationType type);
+
+ ///The physics engine calls this method to prepare the object for the \
following simulation step. Subclass implementations have to call the base \
implementation just before returning. + virtual void startSimulation();
+ ///The physics engine calls this method after calculating the next \
frame, to let the objects update their representation. Subclass \
implementations have to call the base implementation before anything else. \
+ virtual void endSimulation(); +
///Creates the optimal overlay for this object. The implementation does \
not have to propagate its properties to the overlay, as the overlay is \
updated just after it has been created. ///@warning Do not actually call \
this function from subclass implementations. Use overlay() instead. \
virtual Kolf::Overlay* createOverlay() { return 0; } //TODO: make this pure \
virtual when all CanvasItems are QGraphicsItems and implement \
createOverlay() (and then disallow createOverlay() == 0) @@ -167,6 +182,9 \
@@ Kolf::Overlay* m_overlay;
QList<Kolf::Shape*> 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!)
@@ -189,6 +207,9 @@
void saveSize(KConfigGroup* group);
void loadSize(KConfigGroup* group);
+
+ virtual void setPosition(const QPointF& pos) { \
QGraphicsItem::setPos(pos); } + virtual QPointF getPosition() const { \
return QGraphicsItem::pos(); } private:
QGraphicsEllipseItem* m_ellipseItem;
};
--- trunk/KDE/kdegames/kolf/game.h #1191711:1191712
@@ -170,6 +170,8 @@
void setSizeFactor(double newFactor) { m_sizeFactor = newFactor; }
virtual void setSize(const QSizeF& size);
+ virtual void setPosition(const QPointF& pos) { \
QGraphicsItem::setPos(pos); } + virtual QPointF getPosition() const { \
return QGraphicsItem::pos(); } protected:
Tagaro::SpriteObjectItem *rect;
double m_sizeFactor;
@@ -312,6 +314,9 @@
void setArrowPen(QPen pen) { arrow->setPen(pen); }
virtual Config *config(QWidget *parent);
BlackHole *blackHole;
+
+ virtual void setPosition(const QPointF& pos) { \
QGraphicsItem::setPos(pos); } + virtual QPointF getPosition() const { \
return QGraphicsItem::pos(); } protected:
Arrow *arrow;
};
@@ -422,6 +427,8 @@
void setLine(const QLineF& line);
+ virtual void setPosition(const QPointF& pos) { \
QGraphicsItem::setPos(pos); } + virtual QPointF getPosition() const { \
return QGraphicsItem::pos(); } protected:
WallPoint *startItem;
WallPoint *endItem;
@@ -454,6 +461,9 @@
double height() { return rect().height(); }
Wall *parentWall() { return wall; }
+
+ virtual void setPosition(const QPointF& pos) { \
QGraphicsItem::setPos(pos); } + virtual QPointF getPosition() const { \
return QGraphicsItem::pos(); } protected:
Wall *wall;
bool editing;
@@ -491,6 +501,8 @@
virtual void moveBy(double dx, double dy);
void setShowGuideLine(bool yes);
+ virtual void setPosition(const QPointF& pos) { \
QGraphicsItem::setPos(pos); } + virtual QPointF getPosition() const { \
return QGraphicsItem::pos(); } private:
QPointF midPoint;
double maxAngle;
@@ -566,6 +578,8 @@
double width() {return Tagaro::SpriteObjectItem::size().width(); }
double height() {return Tagaro::SpriteObjectItem::size().height(); }
+ virtual void setPosition(const QPointF& pos) { \
QGraphicsItem::setPos(pos); } + virtual QPointF getPosition() const { \
return QGraphicsItem::pos(); } protected:
Wall *topWall;
Wall *botWall;
@@ -702,6 +716,8 @@
void borderWallsChanged(bool yes);
bool borderWalls() const { return m_borderWalls; }
+ virtual void setPosition(const QPointF& pos) { Q_UNUSED(pos) }
+ virtual QPointF getPosition() const { return QPointF(); }
private:
QString m_author;
QString m_name;
--- trunk/KDE/kdegames/kolf/slope.h #1191711:1191712
@@ -88,6 +88,8 @@
double width() const { return size().width(); }
double height() const { return size().height(); }
+ virtual void setPosition(const QPointF& pos) { \
QGraphicsItem::setPos(pos); } + virtual QPointF getPosition() const { \
return QGraphicsItem::pos(); } private:
GradientType type;
inline void setType(GradientType type);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic