Skip to content

Commit

Permalink
Affector Augmentation
Browse files Browse the repository at this point in the history
Affectors gained shape and signal properties, and the affected(x,y)
signal (turned on by the signal property, a theorized performance
improvement).
  • Loading branch information
Alan Alpert committed May 3, 2011
1 parent fc345a6 commit 94c1a9d
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 10 deletions.
1 change: 1 addition & 0 deletions examples/declarative/particles/allsmiles/smilefactory.qml
Expand Up @@ -51,6 +51,7 @@ Rectangle{
particles: ["goingLeft", "goingRight"]
image: "content/singlesmile.png"
rotation: 90
rotationSpeed: 90
autoRotation: true
}
DeformableParticle{
Expand Down
3 changes: 2 additions & 1 deletion src/imports/particles/followemitter.cpp
Expand Up @@ -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)
Expand All @@ -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);
Expand Down
15 changes: 8 additions & 7 deletions src/imports/particles/maskextruder.cpp
Expand Up @@ -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)
Expand All @@ -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<r.width(); i++){
for(int j=0; j<r.height(); j++){
if(img.pixelIndex(i,j))//Direct bit manipulation is presumably more efficient
if(m_img.pixelIndex(i,j))//Direct bit manipulation is presumably more efficient
m_mask << QPointF(i,j);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/imports/particles/maskextruder.h
Expand Up @@ -43,6 +43,7 @@
#define MASKEXTRUDER_H
#include "particleextruder.h"
#include <QUrl>
#include <QImage>

QT_BEGIN_HEADER

Expand Down Expand Up @@ -85,6 +86,7 @@ public slots:
void ensureInitialized(const QRectF &r);
int m_lastWidth;
int m_lastHeight;
QImage m_img;
QList<QPointF> m_mask;//TODO: More memory efficient datastructures
};

Expand Down
10 changes: 8 additions & 2 deletions src/imports/particles/particleaffector.cpp
Expand Up @@ -43,7 +43,8 @@
#include <QDebug>
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()));
Expand Down Expand Up @@ -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());
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions src/imports/particles/particleaffector.h
Expand Up @@ -44,6 +44,7 @@

#include <QObject>
#include "particlesystem.h"
#include "particleextruder.h"

QT_BEGIN_HEADER

Expand All @@ -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);
Expand All @@ -84,6 +87,16 @@ class ParticleAffector : public QSGItem
return m_onceOff;
}

ParticleExtruder* shape() const
{
return m_shape;
}

bool signal() const
{
return m_signal;
}

signals:

void systemChanged(ParticleSystem* arg);
Expand All @@ -94,6 +107,11 @@ class ParticleAffector : public QSGItem

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)
{
Expand Down Expand Up @@ -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);
Expand All @@ -146,6 +180,10 @@ void setOnceOff(bool arg)

bool m_onceOff;

ParticleExtruder* m_shape;

bool m_signal;

private slots:
void updateOffsets();
};
Expand Down
2 changes: 2 additions & 0 deletions src/imports/particles/particlesystem.cpp
Expand Up @@ -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()
Expand All @@ -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;
Expand Down

0 comments on commit 94c1a9d

Please sign in to comment.