1 /*
2 * box2dbody.h
3 * Copyright (c) 2010-2011 Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
4 * Copyright (c) 2011 Daker Fernandes Pinheiro <daker.pinheiro@openbossa.org>
5 * Copyright (c) 2011 Tan Miaoqing <miaoqing.tan@nokia.com>
6 * Copyright (c) 2011 Antonio Aloisio <antonio.aloisio@nokia.com>
7 * Copyright (c) 2011 Joonas Erkinheimo <joonas.erkinheimo@nokia.com>
8 * Copyright (c) 2011 Antti Krats <antti.krats@digia.com>
9 *
10 * This file is part of the Box2D QML plugin.
11 *
12 * This software is provided 'as-is', without any express or implied warranty.
13 * In no event will the authors be held liable for any damages arising from
14 * the use of this software.
15 *
16 * Permission is granted to anyone to use this software for any purpose,
17 * including commercial applications, and to alter it and redistribute it
18 * freely, subject to the following restrictions:
19 *
20 * 1. The origin of this software must not be misrepresented; you must not
21 * claim that you wrote the original software. If you use this software in
22 * a product, an acknowledgment in the product documentation would be
23 * appreciated but is not required.
24 *
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 *
28 * 3. This notice may not be removed or altered from any source distribution.
29 */
30
31 #ifndef BOX2DBODY_H
32 #define BOX2DBODY_H
33
34 #include <QQuickItem>
35 #include <Box2D.h>
36
37 class Box2DFixture;
38 class Box2DWorld;
39
40 /**
41 * The Box2D body, build up from a list of shapes.
42 */
43 class Box2DBody : public QObject, public QQmlParserStatus
44 {
45 Q_OBJECT
46
47 Q_ENUMS(BodyType)
48 Q_PROPERTY(Box2DWorld *world READ world WRITE setWorld NOTIFY worldChanged)
49 Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged)
50 Q_PROPERTY(float linearDamping READ linearDamping WRITE setLinearDamping NOTIFY linearDampingChanged)
51 Q_PROPERTY(float angularDamping READ angularDamping WRITE setAngularDamping NOTIFY angularDampingChanged)
52 Q_PROPERTY(BodyType bodyType READ bodyType WRITE setBodyType NOTIFY bodyTypeChanged)
53 Q_PROPERTY(bool bullet READ isBullet WRITE setBullet NOTIFY bulletChanged)
54 Q_PROPERTY(bool sleepingAllowed READ sleepingAllowed WRITE setSleepingAllowed NOTIFY sleepingAllowedChanged)
55 Q_PROPERTY(bool fixedRotation READ fixedRotation WRITE setFixedRotation NOTIFY fixedRotationChanged)
56 Q_PROPERTY(bool active READ isActive WRITE setActive)
57 Q_PROPERTY(bool awake READ isAwake WRITE setAwake)
58 Q_PROPERTY(QPointF linearVelocity READ linearVelocity WRITE setLinearVelocity NOTIFY linearVelocityChanged)
59 Q_PROPERTY(float angularVelocity READ angularVelocity WRITE setAngularVelocity NOTIFY angularVelocityChanged)
60 Q_PROPERTY(QQmlListProperty<Box2DFixture> fixtures READ fixtures)
61 Q_PROPERTY(float gravityScale READ gravityScale WRITE setGravityScale NOTIFY gravityScaleChanged)
62
63 Q_INTERFACES(QQmlParserStatus)
64 Q_CLASSINFO("DefaultProperty", "fixtures")
65
66 public:
67 enum BodyType {
68 Static = 0,
69 Kinematic,
70 Dynamic
71 };
72
73 explicit Box2DBody(QObject *parent = 0);
74 ~Box2DBody();
75
76 Box2DWorld *world() const;
77 void setWorld(Box2DWorld *world);
78
79 QQuickItem *target() const;
80 void setTarget(QQuickItem *target);
81
82 float linearDamping() const;
83 void setLinearDamping(float linearDamping);
84
85 float angularDamping() const;
86 void setAngularDamping(float angularDamping);
87
88 BodyType bodyType() const;
89 void setBodyType(BodyType bodyType);
90
91 bool isBullet() const;
92 void setBullet(bool bullet);
93
94 bool sleepingAllowed() const;
95 void setSleepingAllowed(bool sleepingAllowed);
96
97 bool fixedRotation() const;
98 void setFixedRotation(bool fixedRotation);
99
100 bool isActive() const;
101 void setActive(bool active);
102
103 bool isAwake() const;
104 void setAwake(bool awake);
105
106 QPointF linearVelocity() const;
107 void setLinearVelocity(const QPointF &velocity);
108
109 float angularVelocity() const;
110 void setAngularVelocity(float velocity);
111
112 float gravityScale() const;
113 void setGravityScale(float gravityScale);
114
115 QQmlListProperty<Box2DFixture> fixtures();
116
117 void synchronize();
118 void nullifyBody();
119
120 Q_INVOKABLE void applyForce(const QPointF &force, const QPointF &point);
121 Q_INVOKABLE void applyForceToCenter(const QPointF &force);
122 Q_INVOKABLE void applyTorque(qreal torque);
123 Q_INVOKABLE void applyLinearImpulse(const QPointF &impulse, const QPointF &point);
124 Q_INVOKABLE void applyAngularImpulse(qreal impulse);
125 Q_INVOKABLE QPointF getWorldCenter() const;
126 Q_INVOKABLE QPointF getLocalCenter() const;
127 Q_INVOKABLE float getMass() const;
128 Q_INVOKABLE void resetMassData();
129 Q_INVOKABLE float getInertia() const;
130 Q_INVOKABLE QPointF toWorldPoint(const QPointF &localPoint) const;
131 Q_INVOKABLE QPointF toWorldVector(const QPointF &localVector) const;
132 Q_INVOKABLE QPointF toLocalPoint(const QPointF &worldPoint) const;
133 Q_INVOKABLE QPointF toLocalVector(const QPointF &worldVector) const;
134 Q_INVOKABLE QPointF getLinearVelocityFromWorldPoint(const QPointF &point) const;
135 Q_INVOKABLE QPointF getLinearVelocityFromLocalPoint(const QPointF &point) const;
136 Q_INVOKABLE void addFixture(Box2DFixture *fixture);
137
138 void classBegin();
139 void componentComplete();
140
141 b2Body *body() const;
142
143 bool transformDirty() const;
144 void updateTransform();
145
146 signals:
147 void worldChanged();
148 void targetChanged();
149 void linearDampingChanged();
150 void angularDampingChanged();
151 void bodyTypeChanged();
152 void bulletChanged();
153 void sleepingAllowedChanged();
154 void fixedRotationChanged();
155 void linearVelocityChanged();
156 void angularVelocityChanged();
157 void bodyCreated();
158 void gravityScaleChanged();
159 void positionChanged();
160
161 private slots:
162 void markTransformDirty();
163 void onWorldPixelsPerMeterChanged();
164
165 private:
166 void createBody();
167
168 Box2DWorld *mWorld;
169 QQuickItem *mTarget;
170 b2Body *mBody;
171 b2BodyDef mBodyDef;
172 bool mComponentComplete;
173 bool mTransformDirty;
174 bool mCreatePending;
175 QList<Box2DFixture*> mFixtures;
176
177 static void append_fixture(QQmlListProperty<Box2DFixture> *list,
178 Box2DFixture *fixture);
179 static int count_fixture(QQmlListProperty<Box2DFixture> *list);
180 static Box2DFixture *at_fixture(QQmlListProperty<Box2DFixture> *list, int index);
181 QPointF originOffset() const;
182 };
183
target()184 inline QQuickItem *Box2DBody::target() const
185 {
186 return mTarget;
187 }
188
linearDamping()189 inline float Box2DBody::linearDamping() const
190 {
191 return mBodyDef.linearDamping;
192 }
193
angularDamping()194 inline float Box2DBody::angularDamping() const
195 {
196 return mBodyDef.angularDamping;
197 }
198
bodyType()199 inline Box2DBody::BodyType Box2DBody::bodyType() const
200 {
201 return static_cast<Box2DBody::BodyType>(mBodyDef.type);
202 }
203
isBullet()204 inline bool Box2DBody::isBullet() const
205 {
206 return mBodyDef.bullet;
207 }
208
sleepingAllowed()209 inline bool Box2DBody::sleepingAllowed() const
210 {
211 return mBodyDef.allowSleep;
212 }
213
fixedRotation()214 inline bool Box2DBody::fixedRotation() const
215 {
216 return mBodyDef.fixedRotation;
217 }
218
isActive()219 inline bool Box2DBody::isActive() const
220 {
221 return mBodyDef.active;
222 }
223
gravityScale()224 inline float Box2DBody::gravityScale() const
225 {
226 return mBodyDef.gravityScale;
227 }
228
nullifyBody()229 inline void Box2DBody::nullifyBody()
230 {
231 mBody = 0;
232 }
233
body()234 inline b2Body *Box2DBody::body() const
235 {
236 return mBody;
237 }
238
world()239 inline Box2DWorld *Box2DBody::world() const
240 {
241 return mWorld;
242 }
243
transformDirty()244 inline bool Box2DBody::transformDirty() const
245 {
246 return mTransformDirty;
247 }
248
249
250 /**
251 * Convenience function to get the Box2DBody wrapping a b2Body.
252 */
toBox2DBody(b2Body * body)253 inline Box2DBody *toBox2DBody(b2Body *body)
254 {
255 return static_cast<Box2DBody*>(body->GetUserData());
256 }
257
258 #endif // BOX2DBODY_H
259