File indexing completed on 2024-03-24 15:14:07

0001 /*
0002  * box2dfixture.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 Alessandro Portale <alessandro.portale@nokia.com>
0006  *
0007  * This file is part of the Box2D QML plugin.
0008  *
0009  * This software is provided 'as-is', without any express or implied warranty.
0010  * In no event will the authors be held liable for any damages arising from
0011  * the use of this software.
0012  *
0013  * Permission is granted to anyone to use this software for any purpose,
0014  * including commercial applications, and to alter it and redistribute it
0015  * freely, subject to the following restrictions:
0016  *
0017  * 1. The origin of this software must not be misrepresented; you must not
0018  *    claim that you wrote the original software. If you use this software in
0019  *    a product, an acknowledgment in the product documentation would be
0020  *    appreciated but is not required.
0021  *
0022  * 2. Altered source versions must be plainly marked as such, and must not be
0023  *    misrepresented as being the original software.
0024  *
0025  * 3. This notice may not be removed or altered from any source distribution.
0026  */
0027 
0028 #ifndef BOX2DFIXTURE_H
0029 #define BOX2DFIXTURE_H
0030 
0031 #include <QQuickItem>
0032 #include <QFlags>
0033 
0034 #include <Box2D.h>
0035 
0036 class Box2DBody;
0037 
0038 class Box2DFixture : public QObject
0039 {
0040     Q_OBJECT
0041 
0042     Q_PROPERTY(float density READ density WRITE setDensity NOTIFY densityChanged)
0043     Q_PROPERTY(float friction READ friction WRITE setFriction NOTIFY frictionChanged)
0044     Q_PROPERTY(float restitution READ restitution WRITE setRestitution NOTIFY restitutionChanged)
0045     Q_PROPERTY(bool sensor READ isSensor WRITE setSensor NOTIFY sensorChanged)
0046     Q_PROPERTY(CategoryFlags categories READ categories WRITE setCategories NOTIFY categoriesChanged)
0047     Q_PROPERTY(CategoryFlags collidesWith READ collidesWith WRITE setCollidesWith NOTIFY collidesWithChanged)
0048     Q_PROPERTY(int groupIndex READ groupIndex WRITE setGroupIndex NOTIFY groupIndexChanged)
0049 
0050     Q_ENUMS(CategoryFlag)
0051     Q_FLAGS(CategoryFlags)
0052 
0053 public:
0054     explicit Box2DFixture(QObject *parent = 0);
0055 
0056     enum CategoryFlag {Category1 = 0x0001, Category2 = 0x0002, Category3 = 0x0004, Category4 = 0x0008,
0057                        Category5 = 0x0010, Category6 = 0x0020, Category7 = 0x0040, Category8 = 0x0080,
0058                        Category9 = 0x0100, Category10 = 0x0200, Category11 = 0x0400, Category12 = 0x0800,
0059                        Category13 = 0x1000, Category14 = 0x2000, Category15 = 0x4000, Category16 = 0x8000,
0060                        All = 0xFFFF, None=0x0000};
0061 
0062     Q_DECLARE_FLAGS(CategoryFlags, CategoryFlag)
0063 
0064     float density() const;
0065     void setDensity(float density);
0066 
0067     float friction() const;
0068     void setFriction(float friction);
0069 
0070     float restitution() const;
0071     void setRestitution(float restitution);
0072 
0073     bool isSensor() const;
0074     void setSensor(bool sensor);
0075 
0076     CategoryFlags categories() const;
0077     void setCategories(CategoryFlags layers);
0078 
0079     CategoryFlags collidesWith() const;
0080     void setCollidesWith(CategoryFlags layers);
0081 
0082     int groupIndex() const;
0083     void setGroupIndex(int groupIndex);
0084 
0085     void initialize(Box2DBody *body);
0086     void recreateFixture();
0087 
0088     Q_INVOKABLE Box2DBody *getBody() const;
0089 
0090 signals:
0091     void densityChanged();
0092     void frictionChanged();
0093     void restitutionChanged();
0094     void sensorChanged();
0095     void categoriesChanged();
0096     void collidesWithChanged();
0097     void groupIndexChanged();
0098 
0099     void beginContact(Box2DFixture *other);
0100     void endContact(Box2DFixture *other);
0101 
0102 protected:
0103     virtual b2Shape *createShape() = 0;
0104 
0105     b2Fixture *mFixture;
0106     b2FixtureDef mFixtureDef;
0107     Box2DBody *mBody;
0108 };
0109 
0110 Q_DECLARE_OPERATORS_FOR_FLAGS(Box2DFixture::CategoryFlags)
0111 
0112 class Box2DBox : public Box2DFixture
0113 {
0114     Q_OBJECT
0115 
0116     Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
0117     Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
0118     Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY widthChanged)
0119     Q_PROPERTY(qreal height READ height WRITE setHeight NOTIFY heightChanged)
0120     Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
0121 
0122 public:
0123     explicit Box2DBox(QQuickItem *parent = 0)
0124         : Box2DFixture(parent)
0125         , mPosition(0, 0)
0126         , mSize(0, 0)
0127         , mRotation(0)
0128     {}
0129 
0130     qreal x() const { return mPosition.x(); }
0131     void setX(qreal x);
0132 
0133     qreal y() const { return mPosition.y(); }
0134     void setY(qreal y);
0135 
0136     qreal width() const { return mSize.width(); }
0137     void setWidth(qreal width);
0138 
0139     qreal height() const { return mSize.height(); }
0140     void setHeight(qreal height);
0141 
0142     qreal rotation() const { return mRotation; }
0143     void setRotation(qreal rotation);
0144 
0145 signals:
0146     void xChanged();
0147     void yChanged();
0148     void widthChanged();
0149     void heightChanged();
0150     void rotationChanged();
0151 
0152 protected:
0153     void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
0154 
0155     b2Shape *createShape();
0156 
0157 private:
0158     QPointF mPosition;
0159     QSizeF mSize;
0160     qreal mRotation;
0161 };
0162 
0163 
0164 class Box2DCircle : public Box2DFixture
0165 {
0166     Q_OBJECT
0167 
0168     Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
0169     Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
0170     Q_PROPERTY(float radius READ radius WRITE setRadius NOTIFY radiusChanged)
0171 
0172 public:
0173     explicit Box2DCircle(QQuickItem *parent = 0)
0174         : Box2DFixture(parent)
0175         , mPosition(0, 0)
0176         , mRadius(32)
0177     { }
0178 
0179     qreal x() const { return mPosition.x(); }
0180     void setX(qreal x);
0181 
0182     qreal y() const { return mPosition.y(); }
0183     void setY(qreal y);
0184 
0185     QPointF position() const { return mPosition; }
0186 
0187     float radius() const { return mRadius; }
0188     void setRadius(float radius);
0189 
0190 signals:
0191     void xChanged();
0192     void yChanged();
0193     void radiusChanged();
0194 
0195 protected:
0196     b2Shape *createShape();
0197 
0198 private:
0199     QPointF mPosition;
0200     float mRadius;
0201 };
0202 
0203 
0204 class Box2DPolygon : public Box2DFixture
0205 {
0206     Q_OBJECT
0207 
0208     Q_PROPERTY(QVariantList vertices READ vertices WRITE setVertices NOTIFY verticesChanged)
0209 
0210 public:
0211     explicit Box2DPolygon(QQuickItem *parent = 0) :
0212         Box2DFixture(parent)
0213     { }
0214 
0215     QVariantList vertices() const { return mVertices; }
0216     void setVertices(const QVariantList &vertices);
0217 
0218 signals:
0219     void verticesChanged();
0220 
0221 protected:
0222     b2Shape *createShape();
0223 
0224 private:
0225     QVariantList mVertices;
0226 };
0227 
0228 
0229 class Box2DChain : public Box2DFixture
0230 {
0231     Q_OBJECT
0232 
0233     Q_PROPERTY(QVariantList vertices READ vertices WRITE setVertices NOTIFY verticesChanged)
0234     Q_PROPERTY(bool loop READ loop WRITE setLoop NOTIFY loopChanged)
0235     Q_PROPERTY(QPointF prevVertex READ prevVertex WRITE setPrevVertex NOTIFY prevVertexChanged)
0236     Q_PROPERTY(QPointF nextVertex READ nextVertex WRITE setNextVertex NOTIFY nextVertexChanged)
0237 
0238 public:
0239     explicit Box2DChain(QQuickItem *parent = 0);
0240 
0241     QVariantList vertices() const { return mVertices; }
0242     void setVertices(const QVariantList &vertices);
0243 
0244     bool loop() const { return mLoop; }
0245     void setLoop(bool loop);
0246 
0247     QPointF prevVertex() const { return mPrevVertex; }
0248     void setPrevVertex(const QPointF &prevVertex);
0249 
0250     QPointF nextVertex() const { return mNextVertex; }
0251     void setNextVertex(const QPointF &nextVertex);
0252 
0253 signals:
0254     void verticesChanged();
0255     void loopChanged();
0256     void prevVertexChanged();
0257     void nextVertexChanged();
0258 
0259 protected:
0260     b2Shape *createShape();
0261 
0262 private:
0263     QVariantList mVertices;
0264     QPointF mPrevVertex;
0265     QPointF mNextVertex;
0266     bool mLoop;
0267     bool mPrevVertexFlag;
0268     bool mNextVertexFlag;
0269 };
0270 
0271 
0272 class Box2DEdge : public Box2DFixture
0273 {
0274     Q_OBJECT
0275 
0276     Q_PROPERTY(QVariantList vertices READ vertices WRITE setVertices NOTIFY verticesChanged)
0277 
0278 public:
0279     explicit Box2DEdge(QQuickItem *parent = 0) :
0280         Box2DFixture(parent)
0281     { }
0282 
0283     QVariantList vertices() const { return mVertices; }
0284     void setVertices(const QVariantList &vertices);
0285 
0286 signals:
0287     void verticesChanged();
0288 
0289 protected:
0290     b2Shape *createShape();
0291 
0292 private:
0293     QVariantList mVertices;
0294 };
0295 
0296 
0297 /**
0298  * Convenience function to get the Box2DFixture wrapping a b2Fixture.
0299  */
0300 inline Box2DFixture *toBox2DFixture(b2Fixture *fixture)
0301 {
0302     return static_cast<Box2DFixture*>(fixture->GetUserData());
0303 }
0304 
0305 
0306 #endif // BOX2DFIXTURE_H