From 94c1a9d0e137a7c2adfd3ac86f3a439759306dc7 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 3 May 2011 10:23:21 +1000 Subject: [PATCH] Affector Augmentation Affectors gained shape and signal properties, and the affected(x,y) signal (turned on by the signal property, a theorized performance improvement). --- .../particles/allsmiles/smilefactory.qml | 1 + src/imports/particles/followemitter.cpp | 3 +- src/imports/particles/maskextruder.cpp | 15 +++++---- src/imports/particles/maskextruder.h | 2 ++ src/imports/particles/particleaffector.cpp | 10 ++++-- src/imports/particles/particleaffector.h | 38 ++++++++++++++++++++++ src/imports/particles/particlesystem.cpp | 2 ++ 7 files changed, 61 insertions(+), 10 deletions(-) diff --git a/examples/declarative/particles/allsmiles/smilefactory.qml b/examples/declarative/particles/allsmiles/smilefactory.qml index 1b43adb..47becb5 100644 --- a/examples/declarative/particles/allsmiles/smilefactory.qml +++ b/examples/declarative/particles/allsmiles/smilefactory.qml @@ -51,6 +51,7 @@ Rectangle{ particles: ["goingLeft", "goingRight"] image: "content/singlesmile.png" rotation: 90 + rotationSpeed: 90 autoRotation: true } DeformableParticle{ diff --git a/src/imports/particles/followemitter.cpp b/src/imports/particles/followemitter.cpp index 825b9ea..9e1ec7b 100644 --- a/src/imports/particles/followemitter.cpp +++ b/src/imports/particles/followemitter.cpp @@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE FollowEmitter::FollowEmitter(QSGItem *parent) : ParticleEmitter(parent) + , m_particlesPerParticlePerSecond(0) , m_lastTimeStamp(0) , m_emitterXVariation(0) , m_emitterYVariation(0) @@ -66,7 +67,7 @@ void FollowEmitter::recalcParticlesPerSecond(){ return; m_followCount = m_system->m_groupData[m_system->m_groupIds[m_follow]]->size; if(!m_followCount){ - setParticlesPerSecond(1000);//XXX: Fix this horrendous hack, needed so they aren't turned off from start + setParticlesPerSecond(1000);//XXX: Fix this horrendous hack, needed so they aren't turned off from start (causes crashes - test that when gone you don't crash with 0 PPPS) }else{ setParticlesPerSecond(m_particlesPerParticlePerSecond * m_followCount); m_lastEmission.resize(m_followCount); diff --git a/src/imports/particles/maskextruder.cpp b/src/imports/particles/maskextruder.cpp index 16c64e0..2683010 100644 --- a/src/imports/particles/maskextruder.cpp +++ b/src/imports/particles/maskextruder.cpp @@ -63,7 +63,8 @@ QPointF MaskExtruder::extrude(const QRectF &r) bool MaskExtruder::contains(const QRectF &bounds, const QPointF &point) { ensureInitialized(bounds);//###Current usage patterns WILL lead to different bounds/r calls. Separate list? - return m_mask.contains(QPointF(point.toPoint() - bounds.topLeft().toPoint())); + QPoint p = point.toPoint() - bounds.topLeft().toPoint(); + return m_img.rect().contains(p) && (bool)m_img.pixelIndex(p); } void MaskExtruder::ensureInitialized(const QRectF &r) @@ -76,14 +77,14 @@ void MaskExtruder::ensureInitialized(const QRectF &r) m_mask.clear(); if(m_source.isEmpty()) return; - - QImage img(m_source.toLocalFile()); - img = img.createAlphaMask(); - img = img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier - img = img.scaled(r.size().toSize());//TODO: Do they need aspect ratio stuff? Or tiling? + qDebug() << "Rebuild required"; + m_img = QImage(m_source.toLocalFile()); + 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? for(int i=0; i +#include QT_BEGIN_HEADER @@ -85,6 +86,7 @@ private: void ensureInitialized(const QRectF &r); int m_lastWidth; int m_lastHeight; + QImage m_img; QList m_mask;//TODO: More memory efficient datastructures }; diff --git a/src/imports/particles/particleaffector.cpp b/src/imports/particles/particleaffector.cpp index 0d7bab5..73564a9 100644 --- a/src/imports/particles/particleaffector.cpp +++ b/src/imports/particles/particleaffector.cpp @@ -43,7 +43,8 @@ #include QT_BEGIN_NAMESPACE ParticleAffector::ParticleAffector(QSGItem *parent) : - QSGItem(parent), m_needsReset(false), m_system(0), m_active(true), m_updateIntSet(false) + QSGItem(parent), m_needsReset(false), m_system(0), m_active(true) + , m_updateIntSet(false), m_shape(new ParticleExtruder(this)), m_signal(false) { connect(this, SIGNAL(systemChanged(ParticleSystem*)), this, SLOT(updateOffsets())); @@ -82,11 +83,16 @@ void ParticleAffector::affectSystem(qreal dt) if(!d || (m_onceOff && m_onceOffed.contains(d->systemIndex))) continue; if(m_groups.isEmpty() || m_groups.contains(d->group)){ - if(width() == 0 || height() == 0 || QRectF(m_offset.x(), m_offset.y(), width(), height()).contains(d->curX(), d->curY())){ + //Need to have previous location for affected. if signal || shape might be faster? + QPointF curPos = QPointF(d->curX(), d->curY()); + if(width() == 0 || height() == 0 + || m_shape->contains(QRectF(m_offset.x(), m_offset.y(), width(), height()),curPos)){ if(affectParticle(d, dt)){ m_system->m_needsReset << d; if(m_onceOff) m_onceOffed << d->systemIndex; + if(m_signal) + emit affected(curPos.x(), curPos.y()); } } } diff --git a/src/imports/particles/particleaffector.h b/src/imports/particles/particleaffector.h index 1acb405..3a92263 100644 --- a/src/imports/particles/particleaffector.h +++ b/src/imports/particles/particleaffector.h @@ -44,6 +44,7 @@ #include #include "particlesystem.h" +#include "particleextruder.h" QT_BEGIN_HEADER @@ -59,6 +60,8 @@ class ParticleAffector : public QSGItem Q_PROPERTY(QStringList particles READ particles WRITE setParticles NOTIFY particlesChanged) Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) Q_PROPERTY(bool onceOff READ onceOff WRITE setOnceOff NOTIFY onceOffChanged) + Q_PROPERTY(ParticleExtruder* shape READ shape WRITE setShape NOTIFY shapeChanged) + Q_PROPERTY(bool signal READ signal WRITE setSignal NOTIFY signalChanged) public: explicit ParticleAffector(QSGItem *parent = 0); @@ -84,6 +87,16 @@ public: return m_onceOff; } + ParticleExtruder* shape() const + { + return m_shape; + } + + bool signal() const + { + return m_signal; + } + signals: void systemChanged(ParticleSystem* arg); @@ -94,6 +107,11 @@ signals: void onceOffChanged(bool arg); + void shapeChanged(ParticleExtruder* arg); + + void affected(qreal x, qreal y);//###Idx too? + void signalChanged(bool arg); + public slots: void setSystem(ParticleSystem* arg) { @@ -129,6 +147,22 @@ void setOnceOff(bool arg) } } +void setShape(ParticleExtruder* arg) +{ + if (m_shape != arg) { + m_shape = arg; + emit shapeChanged(arg); + } +} + +void setSignal(bool arg) +{ + if (m_signal != arg) { + m_signal = arg; + emit signalChanged(arg); + } +} + protected: friend class ParticleSystem; virtual bool affectParticle(ParticleData *d, qreal dt); @@ -146,6 +180,10 @@ private: bool m_onceOff; + ParticleExtruder* m_shape; + + bool m_signal; + private slots: void updateOffsets(); }; diff --git a/src/imports/particles/particlesystem.cpp b/src/imports/particles/particlesystem.cpp index 571d33c..854d512 100644 --- a/src/imports/particles/particlesystem.cpp +++ b/src/imports/particles/particlesystem.cpp @@ -186,6 +186,7 @@ void ParticleSystem::initializeSystem() m_timestamp.start(); m_initialized = true; emit systemInitialized(); + qDebug() << "System Initialized. Size:" << m_particle_count; } void ParticleSystem::reset() @@ -210,6 +211,7 @@ void ParticleSystem::reset() ParticleData* ParticleSystem::newDatum(int groupId) { Q_ASSERT(groupId < m_groupData.count());//XXX shouldn't really be an assert + Q_ASSERT(m_groupData[groupId]->size); int nextIdx = m_groupData[groupId]->start + m_groupData[groupId]->nextIdx++; if( m_groupData[groupId]->nextIdx >= m_groupData[groupId]->size) m_groupData[groupId]->nextIdx = 0; -- 2.7.4