From 4dba5720e03542e0989adad2461358074c7d0dee Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 9 Sep 2011 17:21:14 +1000 Subject: [PATCH] Implement Turbulence properly Or at least closer to. Now uses curl noise off of a source noise image, documented as usable, and not an immense performance drain (just a normal one). Change-Id: Iac11c98cd9589cbe6a41b2b30893ab40d541d18f Reviewed-on: http://codereview.qt-project.org/4510 Reviewed-by: Alan Alpert --- .../declarative/flickr/content/ImageDetails.qml | 3 +- .../declarative/particles/trails/turbulence.qml | 22 ++-- src/declarative/particles/defaultshaders/noise.png | Bin 0 -> 19477 bytes src/declarative/particles/particles.qrc | 1 + src/declarative/particles/qsgturbulence.cpp | 149 +++++++++++--------- src/declarative/particles/qsgturbulence_p.h | 65 ++++----- 6 files changed, 129 insertions(+), 111 deletions(-) create mode 100644 src/declarative/particles/defaultshaders/noise.png diff --git a/examples/declarative/flickr/content/ImageDetails.qml b/examples/declarative/flickr/content/ImageDetails.qml index 8d3cdfb..3d64a33 100644 --- a/examples/declarative/flickr/content/ImageDetails.qml +++ b/examples/declarative/flickr/content/ImageDetails.qml @@ -162,8 +162,7 @@ Flipable { id: turbulence system: imageSystem anchors.fill: parent - frequency: 100 - strength: 250 + strength: 240 enabled: false } diff --git a/examples/declarative/particles/trails/turbulence.qml b/examples/declarative/particles/trails/turbulence.qml index 62216c3..104bb10 100644 --- a/examples/declarative/particles/trails/turbulence.qml +++ b/examples/declarative/particles/trails/turbulence.qml @@ -56,15 +56,19 @@ Rectangle{ ParticleSystem{ id: ps } + MouseArea{ + anchors.fill: parent + onClicked: turb.enabled = !turb.enabled + } Turbulence{ + id: turb system: ps + enabled: true height: (parent.height / 2) width: parent.width / 2 x: parent. width / 4 anchors.fill: parent - strength: 16 - frequency: 64 - gridSize: 16 + strength: 32 } ImageParticle{ particles: ["smoke"] @@ -79,7 +83,7 @@ Rectangle{ source: "content/particle.png" color: "#11ff400f" colorVariation: 0.1 - } + } Emitter{ anchors.centerIn: parent system: ps @@ -96,12 +100,12 @@ Rectangle{ TrailEmitter{ id: smoke1 width: root.width - height: 258 + height: root.height/2 - 20 system: ps particle: "smoke" follow: "flame" - emitRatePerParticle: 4 + emitRatePerParticle: 1 lifeSpan: 2400 lifeSpanVariation: 400 size: 16 @@ -113,16 +117,16 @@ Rectangle{ TrailEmitter{ id: smoke2 width: root.width - height: 232 + height: root.height/2 - 40 system: ps particle: "smoke" follow: "flame" - emitRatePerParticle: 1 + emitRatePerParticle: 4 lifeSpan: 2400 size: 36 endSize: 24 - sizeVariation: 8 + sizeVariation: 12 acceleration: PointDirection{ y: -40 } speed: AngleDirection{ angle: 270; magnitude: 40; angleVariation: 22; magnitudeVariation: 5 } } diff --git a/src/declarative/particles/defaultshaders/noise.png b/src/declarative/particles/defaultshaders/noise.png new file mode 100644 index 0000000000000000000000000000000000000000..3c723e1a5ac4536b029ed3cca3f6d0ebebaadac9 GIT binary patch literal 19477 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%0DaDTPm>eA- zpTSjGPzZ^7;)z<)p}OoU1yYIo`>=0XX>CJUE=ukX3;b1xa*jcd0yZ=nd~<-71toES zx`7`mSa$GtRJ9&yz#ar>2LMHB$LTvd07V&K^cGPz1QPU@oxD*yX-raQ8ttvP!mse*zU~{Sq?2ZvX%Q07*qoM6N<$g4nIAq5uE@ literal 0 HcmV?d00001 diff --git a/src/declarative/particles/particles.qrc b/src/declarative/particles/particles.qrc index 5403f55..db00a57 100644 --- a/src/declarative/particles/particles.qrc +++ b/src/declarative/particles/particles.qrc @@ -6,5 +6,6 @@ defaultshaders/spriteimagevertex.shader defaultshaders/identitytable.png defaultshaders/defaultFadeInOut.png + defaultshaders/noise.png diff --git a/src/declarative/particles/qsgturbulence.cpp b/src/declarative/particles/qsgturbulence.cpp index 2caebc7..c24af1b 100644 --- a/src/declarative/particles/qsgturbulence.cpp +++ b/src/declarative/particles/qsgturbulence.cpp @@ -50,27 +50,43 @@ QT_BEGIN_NAMESPACE \qmlclass Turbulence QSGTurbulenceAffector \inqmlmodule QtQuick.Particles 2 \inherits Affector - \brief The TurbulenceAffector is a bit of a hack and probably shouldn't be used yet. + \brief Turbulence provides fluid like forces based on a noise image. + The Turbulence Element scales the noise source over the area it affects, + and uses the curl of that source to generate force vectors. + + Turbulence requires a fixed size. Unlike other affectors, a 0x0 Turbulence element + will affect no particles. + + The source should be relatively smooth black and white noise, such as perlin noise. */ /*! - \qmlproperty int QtQuick.Particles2::Turbulence::strength - Maximum magnitude of a point in the vector field. -*/ -/*! - \qmlproperty int QtQuick.Particles2::Turbulence::frequency - Times per second vector field is perturbed. + \qmlproperty real QtQuick.Particles2::Turbulence::strength + + The magnitude of the velocity vector at any point varies between zero and + the square root of two. It will then be multiplied by strength to get the + velocity per second for the particles affected by the turbulence. */ /*! - \qmlproperty int QtQuick.Particles2::Turbulence::gridSize - Square root of the number of points in the vector field simulcrum. + \qmlproperty url QtQuick.Particles2::Turbulence::noiseSource + + The source image to generate the turbulence from. It will be scaled to the size of the element, + so equal or larger sizes will give better results. Tweaking this image is the only way to tweak + behavior such as where vortices are or how many exist. + + The source should be a relatively smooth black and white noise image, such as perlin noise. + A default image will be used if none is provided. */ QSGTurbulenceAffector::QSGTurbulenceAffector(QSGItem *parent) : QSGParticleAffector(parent), - m_strength(10), m_lastT(0), m_frequency(64), m_gridSize(10), m_field(0), m_inited(false) + m_strength(10), m_lastT(0), m_gridSize(0), m_field(0), m_vectorField(0), m_inited(false) +{ +} + +void QSGTurbulenceAffector::geometryChanged(const QRectF &, const QRectF &) { - //TODO: Update grid on size change + initializeGrid(); } QSGTurbulenceAffector::~QSGTurbulenceAffector() @@ -80,6 +96,11 @@ QSGTurbulenceAffector::~QSGTurbulenceAffector() free(m_field[i]); free(m_field); } + if (m_vectorField) { + for (int i=0; i m_strength){ - //Speed limit - qreal theta = atan2(m_field[i][j].y(), m_field[i][j].x()); - m_field[i][j].setX(m_strength * cos(theta)); - m_field[i][j].setY(m_strength * sin(theta)); - } - } - } + if (x < 0) + x = 0; + if (x >= m_gridSize) + x = m_gridSize - 1; + if (y < 0) + y = 0; + if (y >= m_gridSize) + y = m_gridSize - 1; + return m_field[x][y]; } +void QSGTurbulenceAffector::ensureInit() +{ + if (m_inited) + return; + m_inited = true; + initializeGrid(); +} void QSGTurbulenceAffector::affectSystem(qreal dt) { if (!m_system || !m_enabled) return; ensureInit(); - qreal period = 1.0/m_frequency; - qreal time = m_system->m_timeInt / 1000.0; - while ( m_lastT < time ){ - mapUpdate(); - m_lastT += period; - } + QRectF boundsRect(0, 0, width()-1, height()-1); foreach (QSGParticleGroupData *gd, m_system->m_groupData){ if (!activeGroup(m_system->m_groupData.key(gd)))//TODO: Surely this can be done better - return; + continue; foreach (QSGParticleData *d, gd->data){ - if (!d || !activeGroup(d->group)) - return; + if (!d || !activeGroup(d->group) || !d->stillAlive()) + continue; + QPoint pos = (QPointF(d->curX(), d->curY()) - m_offset).toPoint(); + if (!boundsRect.contains(pos)) + continue; qreal fx = 0.0; qreal fy = 0.0; - QPointF pos = QPointF(d->curX() - x(), d->curY() - y());//TODO: Offset - QPointF nodePos = QPointF(pos.x() / m_spacing.x(), pos.y() / m_spacing.y()); - QSet > nodes; - nodes << qMakePair((int)ceil(nodePos.x()), (int)ceil(nodePos.y())); - nodes << qMakePair((int)ceil(nodePos.x()), (int)floor(nodePos.y())); - nodes << qMakePair((int)floor(nodePos.x()), (int)ceil(nodePos.y())); - nodes << qMakePair((int)floor(nodePos.x()), (int)floor(nodePos.y())); - typedef QPair intPair; - foreach (const intPair &p, nodes){ - if (!QRect(0,0,m_gridSize-1,m_gridSize-1).contains(QPoint(p.first, p.second))) - continue; - qreal dist = magnitude(pos.x() - p.first*m_spacing.x(), pos.y() - p.second*m_spacing.y());//TODO: Mathematically valid - fx += m_field[p.first][p.second].x() * ((m_magSum - dist)/m_magSum);//Proportionally weight nodes - fy += m_field[p.first][p.second].y() * ((m_magSum - dist)/m_magSum); - } + fx += m_vectorField[pos.x()][pos.y()].x() * m_strength; + fy += m_vectorField[pos.x()][pos.y()].y() * m_strength; if (fx || fy){ d->setInstantaneousVX(d->curVX()+ fx * dt); d->setInstantaneousVY(d->curVY()+ fy * dt); diff --git a/src/declarative/particles/qsgturbulence_p.h b/src/declarative/particles/qsgturbulence_p.h index dd938f1..110ecf4 100644 --- a/src/declarative/particles/qsgturbulence_p.h +++ b/src/declarative/particles/qsgturbulence_p.h @@ -56,68 +56,61 @@ class QSGParticlePainter; class QSGTurbulenceAffector : public QSGParticleAffector { Q_OBJECT - Q_PROPERTY(int strength READ strength WRITE setStrength NOTIFY strengthChanged) - Q_PROPERTY(int frequency READ frequency WRITE setFrequency NOTIFY frequencyChanged) - Q_PROPERTY(int gridSize READ size WRITE setSize NOTIFY sizeChanged) -public: + Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) + Q_PROPERTY(QUrl noiseSource READ noiseSource WRITE setNoiseSource NOTIFY noiseSourceChanged) + public: explicit QSGTurbulenceAffector(QSGItem *parent = 0); ~QSGTurbulenceAffector(); virtual void affectSystem(qreal dt); - int strength() const + qreal strength() const { return m_strength; } - int frequency() const + QUrl noiseSource() const { - return m_frequency; + return m_noiseSource; } - - int size() const - { - return m_gridSize; - } - signals: - void strengthChanged(int arg); - - void frequencyChanged(int arg); + void strengthChanged(qreal arg); - void sizeChanged(int arg); + void noiseSourceChanged(QUrl arg); public slots: + void initializeGrid(); -void setStrength(int arg) -{ - if (m_strength != arg) { - m_strength = arg; - emit strengthChanged(arg); + void setStrength(qreal arg) + { + if (m_strength != arg) { + m_strength = arg; + emit strengthChanged(arg); + } } -} -void setFrequency(int arg) -{ - if (m_frequency != arg) { - m_frequency = arg; - emit frequencyChanged(arg); + void setNoiseSource(QUrl arg) + { + if (m_noiseSource != arg) { + m_noiseSource = arg; + emit noiseSourceChanged(arg); + } } -} - -void setSize(int arg); +protected: + virtual void geometryChanged(const QRectF &newGeometry, + const QRectF &oldGeometry); private: void ensureInit(); void mapUpdate(); - int m_strength; + qreal boundsRespectingField(int x, int y); + qreal m_strength; qreal m_lastT; - int m_frequency; int m_gridSize; - QPointF** m_field; - QPointF m_spacing; - qreal m_magSum; + qreal** m_field; + QPointF** m_vectorField; bool m_inited; + QUrl m_noiseSource; }; QT_END_NAMESPACE -- 1.7.2.5