File indexing completed on 2024-04-14 14:08:22

0001 /*
0002  * box2dbody.h
0003  * Copyright (c) 2010-2011 Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
0004  * Copyright (c) 2011 Daker Fernandes Pinheiro <daker.pinheiro@openbossa.org>
0005  * Copyright (c) 2011 Tan Miaoqing <miaoqing.tan@nokia.com>
0006  * Copyright (c) 2011 Antonio Aloisio <antonio.aloisio@nokia.com>
0007  * Copyright (c) 2011 Joonas Erkinheimo <joonas.erkinheimo@nokia.com>
0008  * Copyright (c) 2011 Antti Krats <antti.krats@digia.com>
0009  *
0010  * This file is part of the Box2D QML plugin.
0011  *
0012  * This software is provided 'as-is', without any express or implied warranty.
0013  * In no event will the authors be held liable for any damages arising from
0014  * the use of this software.
0015  *
0016  * Permission is granted to anyone to use this software for any purpose,
0017  * including commercial applications, and to alter it and redistribute it
0018  * freely, subject to the following restrictions:
0019  *
0020  * 1. The origin of this software must not be misrepresented; you must not
0021  *    claim that you wrote the original software. If you use this software in
0022  *    a product, an acknowledgment in the product documentation would be
0023  *    appreciated but is not required.
0024  *
0025  * 2. Altered source versions must be plainly marked as such, and must not be
0026  *    misrepresented as being the original software.
0027  *
0028  * 3. This notice may not be removed or altered from any source distribution.
0029  */
0030 
0031 #ifndef BOX2DBODY_H
0032 #define BOX2DBODY_H
0033 
0034 #include <QQuickItem>
0035 #include <Box2D.h>
0036 
0037 class Box2DFixture;
0038 class Box2DWorld;
0039 
0040 /**
0041  * The Box2D body, build up from a list of shapes.
0042  */
0043 class Box2DBody : public QObject, public QQmlParserStatus
0044 {
0045     Q_OBJECT
0046 
0047     Q_ENUMS(BodyType)
0048     Q_PROPERTY(Box2DWorld *world READ world WRITE setWorld NOTIFY worldChanged)
0049     Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged)
0050     Q_PROPERTY(float linearDamping READ linearDamping WRITE setLinearDamping NOTIFY linearDampingChanged)
0051     Q_PROPERTY(float angularDamping READ angularDamping WRITE setAngularDamping NOTIFY angularDampingChanged)
0052     Q_PROPERTY(BodyType bodyType READ bodyType WRITE setBodyType NOTIFY bodyTypeChanged)
0053     Q_PROPERTY(bool bullet READ isBullet WRITE setBullet NOTIFY bulletChanged)
0054     Q_PROPERTY(bool sleepingAllowed READ sleepingAllowed WRITE setSleepingAllowed NOTIFY sleepingAllowedChanged)
0055     Q_PROPERTY(bool fixedRotation READ fixedRotation WRITE setFixedRotation NOTIFY fixedRotationChanged)
0056     Q_PROPERTY(bool active READ isActive WRITE setActive)
0057     Q_PROPERTY(bool awake READ isAwake WRITE setAwake)
0058     Q_PROPERTY(QPointF linearVelocity READ linearVelocity WRITE setLinearVelocity NOTIFY linearVelocityChanged)
0059     Q_PROPERTY(float angularVelocity READ angularVelocity WRITE setAngularVelocity NOTIFY angularVelocityChanged)
0060     Q_PROPERTY(QQmlListProperty<Box2DFixture> fixtures READ fixtures)
0061     Q_PROPERTY(float gravityScale READ gravityScale WRITE setGravityScale NOTIFY gravityScaleChanged)
0062 
0063     Q_INTERFACES(QQmlParserStatus)
0064     Q_CLASSINFO("DefaultProperty", "fixtures")
0065 
0066 public:
0067     enum BodyType {
0068         Static = 0,
0069         Kinematic,
0070         Dynamic
0071     };
0072 
0073     explicit Box2DBody(QObject *parent = 0);
0074     ~Box2DBody();
0075 
0076     Box2DWorld *world() const;
0077     void setWorld(Box2DWorld *world);
0078 
0079     QQuickItem *target() const;
0080     void setTarget(QQuickItem *target);
0081 
0082     float linearDamping() const;
0083     void setLinearDamping(float linearDamping);
0084 
0085     float angularDamping() const;
0086     void setAngularDamping(float angularDamping);
0087 
0088     BodyType bodyType() const;
0089     void setBodyType(BodyType bodyType);
0090 
0091     bool isBullet() const;
0092     void setBullet(bool bullet);
0093 
0094     bool sleepingAllowed() const;
0095     void setSleepingAllowed(bool sleepingAllowed);
0096 
0097     bool fixedRotation() const;
0098     void setFixedRotation(bool fixedRotation);
0099 
0100     bool isActive() const;
0101     void setActive(bool active);
0102 
0103     bool isAwake() const;
0104     void setAwake(bool awake);
0105 
0106     QPointF linearVelocity() const;
0107     void setLinearVelocity(const QPointF &velocity);
0108 
0109     float angularVelocity() const;
0110     void setAngularVelocity(float velocity);
0111 
0112     float gravityScale() const;
0113     void setGravityScale(float gravityScale);
0114 
0115     QQmlListProperty<Box2DFixture> fixtures();
0116 
0117     void synchronize();
0118     void nullifyBody();
0119 
0120     Q_INVOKABLE void applyForce(const QPointF &force, const QPointF &point);
0121     Q_INVOKABLE void applyForceToCenter(const QPointF &force);
0122     Q_INVOKABLE void applyTorque(qreal torque);
0123     Q_INVOKABLE void applyLinearImpulse(const QPointF &impulse, const QPointF &point);
0124     Q_INVOKABLE void applyAngularImpulse(qreal impulse);
0125     Q_INVOKABLE QPointF getWorldCenter() const;
0126     Q_INVOKABLE QPointF getLocalCenter() const;
0127     Q_INVOKABLE float getMass() const;
0128     Q_INVOKABLE void resetMassData();
0129     Q_INVOKABLE float getInertia() const;
0130     Q_INVOKABLE QPointF toWorldPoint(const QPointF &localPoint) const;
0131     Q_INVOKABLE QPointF toWorldVector(const QPointF &localVector) const;
0132     Q_INVOKABLE QPointF toLocalPoint(const QPointF &worldPoint) const;
0133     Q_INVOKABLE QPointF toLocalVector(const QPointF &worldVector) const;
0134     Q_INVOKABLE QPointF getLinearVelocityFromWorldPoint(const QPointF &point) const;
0135     Q_INVOKABLE QPointF getLinearVelocityFromLocalPoint(const QPointF &point) const;
0136     Q_INVOKABLE void addFixture(Box2DFixture *fixture);
0137 
0138     void classBegin();
0139     void componentComplete();
0140 
0141     b2Body *body() const;
0142 
0143     bool transformDirty() const;
0144     void updateTransform();
0145 
0146 signals:
0147     void worldChanged();
0148     void targetChanged();
0149     void linearDampingChanged();
0150     void angularDampingChanged();
0151     void bodyTypeChanged();
0152     void bulletChanged();
0153     void sleepingAllowedChanged();
0154     void fixedRotationChanged();
0155     void linearVelocityChanged();
0156     void angularVelocityChanged();
0157     void bodyCreated();
0158     void gravityScaleChanged();
0159     void positionChanged();
0160 
0161 private slots:
0162     void markTransformDirty();
0163     void onWorldPixelsPerMeterChanged();
0164 
0165 private:
0166     void createBody();
0167 
0168     Box2DWorld *mWorld;
0169     QQuickItem *mTarget;
0170     b2Body *mBody;
0171     b2BodyDef mBodyDef;
0172     bool mComponentComplete;
0173     bool mTransformDirty;
0174     bool mCreatePending;
0175     QList<Box2DFixture*> mFixtures;
0176 
0177     static void append_fixture(QQmlListProperty<Box2DFixture> *list,
0178                                Box2DFixture *fixture);
0179     static int count_fixture(QQmlListProperty<Box2DFixture> *list);
0180     static Box2DFixture *at_fixture(QQmlListProperty<Box2DFixture> *list, int index);
0181     QPointF originOffset() const;
0182 };
0183 
0184 inline QQuickItem *Box2DBody::target() const
0185 {
0186     return mTarget;
0187 }
0188 
0189 inline float Box2DBody::linearDamping() const
0190 {
0191     return mBodyDef.linearDamping;
0192 }
0193 
0194 inline float Box2DBody::angularDamping() const
0195 {
0196     return mBodyDef.angularDamping;
0197 }
0198 
0199 inline Box2DBody::BodyType Box2DBody::bodyType() const
0200 {
0201     return static_cast<Box2DBody::BodyType>(mBodyDef.type);
0202 }
0203 
0204 inline bool Box2DBody::isBullet() const
0205 {
0206     return mBodyDef.bullet;
0207 }
0208 
0209 inline bool Box2DBody::sleepingAllowed() const
0210 {
0211     return mBodyDef.allowSleep;
0212 }
0213 
0214 inline bool Box2DBody::fixedRotation() const
0215 {
0216     return mBodyDef.fixedRotation;
0217 }
0218 
0219 inline bool Box2DBody::isActive() const
0220 {
0221     return mBodyDef.active;
0222 }
0223 
0224 inline float Box2DBody::gravityScale() const
0225 {
0226     return mBodyDef.gravityScale;
0227 }
0228 
0229 inline void Box2DBody::nullifyBody()
0230 {
0231     mBody = 0;
0232 }
0233 
0234 inline b2Body *Box2DBody::body() const
0235 {
0236     return mBody;
0237 }
0238 
0239 inline Box2DWorld *Box2DBody::world() const
0240 {
0241     return mWorld;
0242 }
0243 
0244 inline bool Box2DBody::transformDirty() const
0245 {
0246     return mTransformDirty;
0247 }
0248 
0249 
0250 /**
0251  * Convenience function to get the Box2DBody wrapping a b2Body.
0252  */
0253 inline Box2DBody *toBox2DBody(b2Body *body)
0254 {
0255     return static_cast<Box2DBody*>(body->GetUserData());
0256 }
0257 
0258 #endif // BOX2DBODY_H