diff options
author | Alan Alpert <alan.alpert@nokia.com> | 2011-06-07 19:39:38 +1000 |
---|---|---|
committer | Alan Alpert <alan.alpert@nokia.com> | 2011-06-07 19:43:41 +1000 |
commit | 984f21f18d1a3981e7363df467ff2e24e69aa847 (patch) | |
tree | db4665cbc1591a77f988b0b4f8925fe5636f5672 /src/declarative/particles | |
parent | 21d0c6ef9a7df3e5fa69ff344e9dee2d2159c43c (diff) |
Immense Particles Refactor Part B
Examples work again. Also augmented Wander and PointAttractor with
physics modes.
Diffstat (limited to 'src/declarative/particles')
-rw-r--r-- | src/declarative/particles/qsgmaskextruder.cpp | 11 | ||||
-rw-r--r-- | src/declarative/particles/qsgparticleaffector_p.h | 1 | ||||
-rw-r--r-- | src/declarative/particles/qsgpointattractor.cpp | 32 | ||||
-rw-r--r-- | src/declarative/particles/qsgpointattractor_p.h | 48 | ||||
-rw-r--r-- | src/declarative/particles/qsgwander.cpp | 36 | ||||
-rw-r--r-- | src/declarative/particles/qsgwander_p.h | 29 |
6 files changed, 147 insertions, 10 deletions
diff --git a/src/declarative/particles/qsgmaskextruder.cpp b/src/declarative/particles/qsgmaskextruder.cpp index 3fe28b30a3..d9a463910d 100644 --- a/src/declarative/particles/qsgmaskextruder.cpp +++ b/src/declarative/particles/qsgmaskextruder.cpp @@ -53,7 +53,7 @@ QSGMaskExtruder::QSGMaskExtruder(QObject *parent) : QPointF QSGMaskExtruder::extrude(const QRectF &r) { ensureInitialized(r); - if(!m_mask.count()) + if(!m_mask.count() || m_img.isNull()) return r.topLeft(); const QPointF p = m_mask[rand() % m_mask.count()]; //### Should random sub-pixel positioning be added? @@ -63,6 +63,8 @@ QPointF QSGMaskExtruder::extrude(const QRectF &r) bool QSGMaskExtruder::contains(const QRectF &bounds, const QPointF &point) { ensureInitialized(bounds);//###Current usage patterns WILL lead to different bounds/r calls. Separate list? + if(m_img.isNull()) + return false; QPoint p = point.toPoint() - bounds.topLeft().toPoint(); return m_img.rect().contains(p) && (bool)m_img.pixelIndex(p); } @@ -70,14 +72,19 @@ bool QSGMaskExtruder::contains(const QRectF &bounds, const QPointF &point) void QSGMaskExtruder::ensureInitialized(const QRectF &r) { if(m_lastWidth == r.width() && m_lastHeight == r.height()) - return; + return;//Same as before m_lastWidth = r.width(); m_lastHeight = r.height(); + m_img = QImage(); m_mask.clear(); if(m_source.isEmpty()) return; m_img = QImage(m_source.toLocalFile()); + if(m_img.isNull()){ + qWarning() << "MaskShape: Cannot load" << qPrintable(m_source.toLocalFile()); + return; + } m_img = m_img.createAlphaMask(); m_img = m_img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier m_img = m_img.scaled(r.size().toSize());//TODO: Do they need aspect ratio stuff? Or tiling? diff --git a/src/declarative/particles/qsgparticleaffector_p.h b/src/declarative/particles/qsgparticleaffector_p.h index 1572ad8102..b299158069 100644 --- a/src/declarative/particles/qsgparticleaffector_p.h +++ b/src/declarative/particles/qsgparticleaffector_p.h @@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) - class QSGParticleAffector : public QSGItem { Q_OBJECT diff --git a/src/declarative/particles/qsgpointattractor.cpp b/src/declarative/particles/qsgpointattractor.cpp index 3c3ca33086..4c675237ba 100644 --- a/src/declarative/particles/qsgpointattractor.cpp +++ b/src/declarative/particles/qsgpointattractor.cpp @@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE QSGPointAttractorAffector::QSGPointAttractorAffector(QSGItem *parent) : QSGParticleAffector(parent), m_strength(0.0), m_x(0), m_y(0) + , m_physics(Velocity), m_proportionalToDistance(Linear) { } @@ -52,15 +53,36 @@ bool QSGPointAttractorAffector::affectParticle(QSGParticleData *d, qreal dt) { if(m_strength == 0.0) return false; - qreal dx = m_x - d->curX(); - qreal dy = m_y - d->curY(); + qreal dx = m_y - d->curX(); + qreal dy = m_x - d->curY(); qreal r = sqrt((dx*dx) + (dy*dy)); qreal theta = atan2(dy,dx); - qreal ds = (m_strength / r) * dt; + qreal ds = 0; + switch(m_proportionalToDistance){ + case Quadratic: + ds = (m_strength / qMax(1.,r*r)) * dt; + break; + case Linear://also default + default: + ds = (m_strength / qMax(1.,r)) * dt; + } dx = ds * cos(theta); dy = ds * sin(theta); - d->setInstantaneousSX(d->pv.sx + dx); - d->setInstantaneousSY(d->pv.sy + dy); + switch(m_physics){ + case Position: + d->pv.x = (d->pv.x + dx); + d->pv.y = (d->pv.y + dy); + break; + case Acceleration: + d->setInstantaneousAX(d->pv.ax + dx); + d->setInstantaneousAY(d->pv.ay + dy); + break; + case Velocity: //also default + default: + d->setInstantaneousSX(d->pv.sx + dx); + d->setInstantaneousSY(d->pv.sy + dy); + } + return true; } QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgpointattractor_p.h b/src/declarative/particles/qsgpointattractor_p.h index d4f715928a..3ca29dfa96 100644 --- a/src/declarative/particles/qsgpointattractor_p.h +++ b/src/declarative/particles/qsgpointattractor_p.h @@ -57,7 +57,23 @@ class QSGPointAttractorAffector : public QSGParticleAffector Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) + Q_PROPERTY(PhysicsAffects physics READ physics WRITE setPhysics NOTIFY physicsChanged) + Q_PROPERTY(Proportion proportionalToDistance READ proportionalToDistance WRITE setProportionalToDistance NOTIFY proportionalToDistanceChanged) + Q_ENUMS(PhysicsAffects) + Q_ENUMS(Proportion) + public: + enum Proportion{ + Linear, + Quadratic + }; + + enum PhysicsAffects { + Position, + Velocity, + Acceleration + }; + explicit QSGPointAttractorAffector(QSGItem *parent = 0); qreal strength() const @@ -75,6 +91,16 @@ public: return m_y; } + PhysicsAffects physics() const + { + return m_physics; + } + + Proportion proportionalToDistance() const + { + return m_proportionalToDistance; + } + signals: void strengthChanged(qreal arg); @@ -83,6 +109,10 @@ signals: void yChanged(qreal arg); + void physicsChanged(PhysicsAffects arg); + + void proportionalToDistanceChanged(Proportion arg); + public slots: void setStrength(qreal arg) { @@ -107,12 +137,30 @@ void setY(qreal arg) emit yChanged(arg); } } +void setPhysics(PhysicsAffects arg) +{ + if (m_physics != arg) { + m_physics = arg; + emit physicsChanged(arg); + } +} + +void setProportionalToDistance(Proportion arg) +{ + if (m_proportionalToDistance != arg) { + m_proportionalToDistance = arg; + emit proportionalToDistanceChanged(arg); + } +} + protected: virtual bool affectParticle(QSGParticleData *d, qreal dt); private: qreal m_strength; qreal m_x; qreal m_y; +PhysicsAffects m_physics; +Proportion m_proportionalToDistance; }; QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgwander.cpp b/src/declarative/particles/qsgwander.cpp index e6787f2570..6e56d6a05b 100644 --- a/src/declarative/particles/qsgwander.cpp +++ b/src/declarative/particles/qsgwander.cpp @@ -44,7 +44,8 @@ QT_BEGIN_NAMESPACE QSGWanderAffector::QSGWanderAffector(QSGItem *parent) : - QSGParticleAffector(parent) + QSGParticleAffector(parent), m_xVariance(0), m_yVariance(0), m_pace(0) + , m_physics(Velocity) { m_needsReset = true; } @@ -81,6 +82,7 @@ void QSGWanderAffector::reset(int systemIdx) bool QSGWanderAffector::affectParticle(QSGParticleData* data, qreal dt) { + /*TODO: Add a mode which does basically this - picking a direction, going in it (random speed) and then going back WanderData* d = getData(data->systemIndex); if (m_xVariance != 0.) { if ((d->x_vel > d->x_peak && d->x_var > 0.0) || (d->x_vel < -d->x_peak && d->x_var < 0.0)) { @@ -106,5 +108,37 @@ bool QSGWanderAffector::affectParticle(QSGParticleData* data, qreal dt) p->y += dy; return true; + */ + qreal dx = dt * m_pace * (2 * qreal(qrand())/RAND_MAX - 1); + qreal dy = dt * m_pace * (2 * qreal(qrand())/RAND_MAX - 1); + qreal newX, newY; + switch(m_physics){ + case Position: + newX = data->curX() + dx; + if(m_xVariance > qAbs(newX) ) + data->pv.x += dx; + newY = data->curY() + dy; + if(m_yVariance > qAbs(newY) ) + data->pv.y += dy; + break; + default: + case Velocity: + newX = data->curSX() + dx; + if(m_xVariance > qAbs(newX) ) + data->setInstantaneousSX(newX); + newY = data->curSY() + dy; + if(m_yVariance > qAbs(newY) ) + data->setInstantaneousSY(newY); + break; + case Acceleration: + newX = data->pv.ax + dx; + if(m_xVariance > qAbs(newX) ) + data->setInstantaneousAX(newX); + newY = data->pv.ay + dy; + if(m_yVariance > qAbs(newY) ) + data->setInstantaneousAY(newY); + break; + } + return true; } QT_END_NAMESPACE diff --git a/src/declarative/particles/qsgwander_p.h b/src/declarative/particles/qsgwander_p.h index 45c8ca8b20..783efc8636 100644 --- a/src/declarative/particles/qsgwander_p.h +++ b/src/declarative/particles/qsgwander_p.h @@ -63,11 +63,19 @@ struct WanderData{ class QSGWanderAffector : public QSGParticleAffector { Q_OBJECT + Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) Q_PROPERTY(qreal xVariance READ xVariance WRITE setXVariance NOTIFY xVarianceChanged) Q_PROPERTY(qreal yVariance READ yVariance WRITE setYVariance NOTIFY yVarianceChanged) - Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) + Q_PROPERTY(PhysicsAffects physics READ physics WRITE setPhysics NOTIFY physicsChanged) + Q_ENUMS(PhysicsAffects) public: + enum PhysicsAffects { + Position, + Velocity, + Acceleration + }; + explicit QSGWanderAffector(QSGItem *parent = 0); ~QSGWanderAffector(); virtual void reset(int systemIdx); @@ -86,6 +94,12 @@ public: { return m_pace; } + + PhysicsAffects physics() const + { + return m_physics; + } + protected: virtual bool affectParticle(QSGParticleData *d, qreal dt); signals: @@ -96,6 +110,9 @@ signals: void paceChanged(qreal arg); + + void physicsChanged(PhysicsAffects arg); + public slots: void setXVariance(qreal arg) { @@ -121,12 +138,22 @@ void setPace(qreal arg) } } + +void setPhysics(PhysicsAffects arg) +{ + if (m_physics != arg) { + m_physics = arg; + emit physicsChanged(arg); + } +} + private: WanderData* getData(int idx); QHash<int, WanderData*> m_wanderData; qreal m_xVariance; qreal m_yVariance; qreal m_pace; + PhysicsAffects m_physics; }; QT_END_NAMESPACE |