aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/particles
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2011-06-07 19:39:38 +1000
committerAlan Alpert <alan.alpert@nokia.com>2011-06-07 19:43:41 +1000
commit984f21f18d1a3981e7363df467ff2e24e69aa847 (patch)
treedb4665cbc1591a77f988b0b4f8925fe5636f5672 /src/declarative/particles
parent21d0c6ef9a7df3e5fa69ff344e9dee2d2159c43c (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.cpp11
-rw-r--r--src/declarative/particles/qsgparticleaffector_p.h1
-rw-r--r--src/declarative/particles/qsgpointattractor.cpp32
-rw-r--r--src/declarative/particles/qsgpointattractor_p.h48
-rw-r--r--src/declarative/particles/qsgwander.cpp36
-rw-r--r--src/declarative/particles/qsgwander_p.h29
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