CustomEmitter/Affector now affect whole lists at once
Better performance potential (fewer drops to JS, possibility of more optimzed JS). Change-Id: If386f06ac8714162a5bfc6b5eef7f2e67f9dae95 Reviewed-on: http://codereview.qt-project.org/5189 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Martin Jones <martin.jones@nokia.com>
This commit is contained in:
parent
4114b9dcff
commit
ef98f5a803
|
@ -71,7 +71,7 @@ Item {
|
|||
property real speed: 1.5
|
||||
width: parent.width
|
||||
height: parent.height - 100
|
||||
onAffectParticle:{
|
||||
onAffectParticles:{
|
||||
/* //Linear movement
|
||||
if (particle.r == 0){
|
||||
particle.r = Math.random() > 0.5 ? -1 : 1;
|
||||
|
@ -86,14 +86,17 @@ Item {
|
|||
}
|
||||
*/
|
||||
//Wobbly movement
|
||||
if (particle.r == 0.0){
|
||||
particle.r = Math.random() + 0.01;
|
||||
for (var i=0; i<particles.length; i++) {
|
||||
var particle = particles[i];
|
||||
if (particle.r == 0.0) {
|
||||
particle.r = Math.random() + 0.01;
|
||||
}
|
||||
particle.rotation += speed * particle.r * dt;
|
||||
particle.r -= particle.rotation * coefficient;
|
||||
if (particle.r == 0.0)
|
||||
particle.r -= particle.rotation * 0.000001;
|
||||
particle.update = 1;
|
||||
}
|
||||
particle.rotation += speed * particle.r * dt;
|
||||
particle.r -= particle.rotation * coefficient;
|
||||
if (particle.r == 0.0)
|
||||
particle.r -= particle.rotation * 0.000001;
|
||||
particle.update = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,19 +107,22 @@ Item {
|
|||
width: parent.width + 120
|
||||
height: 100
|
||||
anchors.bottom: parent.bottom
|
||||
onAffectParticle:{
|
||||
var pseudoRand = (Math.floor(particle.t*1327) % 10) + 1;
|
||||
var yslow = pseudoRand * 0.01 + 1.01;
|
||||
var xslow = pseudoRand * 0.005 + 1.0;
|
||||
if (particle.vy < 1)
|
||||
particle.vy = 0;
|
||||
else
|
||||
particle.vy = (particle.vy / yslow);
|
||||
if (particle.vx < 1)
|
||||
particle.vx = 0;
|
||||
else
|
||||
particle.vx = (particle.vx / xslow);
|
||||
particle.update = 1;
|
||||
onAffectParticles:{
|
||||
for (var i=0; i<particles.length; i++) {
|
||||
var particle = particles[i];
|
||||
var pseudoRand = (Math.floor(particle.t*1327) % 10) + 1;
|
||||
var yslow = dt * pseudoRand * 0.5 + 1;
|
||||
var xslow = dt * pseudoRand * 0.05 + 1;
|
||||
if (particle.vy < 1)
|
||||
particle.vy = 0;
|
||||
else
|
||||
particle.vy = (particle.vy / yslow);
|
||||
if (particle.vx < 1)
|
||||
particle.vx = 0;
|
||||
else
|
||||
particle.vx = (particle.vx / xslow);
|
||||
particle.update = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImageParticle{
|
||||
|
|
|
@ -66,15 +66,18 @@ ParticleSystem{
|
|||
emitRate: 120
|
||||
size: 12
|
||||
anchors.centerIn: parent
|
||||
onEmitParticle:{
|
||||
particle.startSize = Math.max(02,Math.min(492,Math.tan(particle.t/2)*24));
|
||||
var theta = Math.floor(Math.random() * 6.0) / 6.0;
|
||||
theta *= 2.0*Math.PI;
|
||||
theta += sys.convert(sys.petalRotation);
|
||||
particle.initialVX = petalLength * Math.cos(theta);
|
||||
particle.initialVY = petalLength * Math.sin(theta);
|
||||
particle.initialAX = particle.initialVX * -0.5;
|
||||
particle.initialAY = particle.initialVY * -0.5;
|
||||
onEmitParticles:{
|
||||
for (var i=0; i<particles.length; i++) {
|
||||
var particle = particles[i];
|
||||
particle.startSize = Math.max(02,Math.min(492,Math.tan(particle.t/2)*24));
|
||||
var theta = Math.floor(Math.random() * 6.0) / 6.0;
|
||||
theta *= 2.0*Math.PI;
|
||||
theta += sys.convert(sys.petalRotation);
|
||||
particle.initialVX = petalLength * Math.cos(theta);
|
||||
particle.initialVY = petalLength * Math.sin(theta);
|
||||
particle.initialAX = particle.initialVX * -0.5;
|
||||
particle.initialAY = particle.initialVY * -0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImageParticle{
|
||||
|
|
|
@ -40,15 +40,18 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "qsgcustomaffector_p.h"
|
||||
#include <private/qv8engine_p.h>
|
||||
#include <private/qdeclarativeengine_p.h>
|
||||
#include <QDeclarativeEngine>
|
||||
#include <QDebug>
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
//TODO: Move docs (and inherit) to real base when docs can propagate
|
||||
//TODO: Document particle 'type'
|
||||
/*!
|
||||
\qmlsignal QtQuick.Particles2::Affector::affectParticle(particle, dt)
|
||||
\qmlsignal QtQuick.Particles2::Affector::affectParticles(Array particles, real dt)
|
||||
|
||||
This handler is called when particles are selected to be affected.
|
||||
This handler is called when particles are selected to be affected. particles contains
|
||||
an array of particle objects which can be directly manipulated.
|
||||
|
||||
dt is the time since the last time it was affected. Use dt to normalize
|
||||
trajectory manipulations to real time.
|
||||
|
@ -63,18 +66,38 @@ QSGCustomAffector::QSGCustomAffector(QSGItem *parent) :
|
|||
|
||||
bool QSGCustomAffector::isAffectConnected()
|
||||
{
|
||||
static int idx = QObjectPrivate::get(this)->signalIndex("affectParticle(QDeclarativeV8Handle,qreal)");
|
||||
static int idx = QObjectPrivate::get(this)->signalIndex("affectParticles(QDeclarativeV8Handle,qreal)");
|
||||
return QObjectPrivate::get(this)->isSignalConnected(idx);
|
||||
}
|
||||
|
||||
bool QSGCustomAffector::affectParticle(QSGParticleData *d, qreal dt)
|
||||
void QSGCustomAffector::affectSystem(qreal dt)
|
||||
{
|
||||
if (isAffectConnected()){
|
||||
d->update = 0.0;
|
||||
emit affectParticle(d->v8Value(), dt);
|
||||
return d->update == 1.0;
|
||||
if (!isAffectConnected()) {
|
||||
QSGParticleAffector::affectSystem(dt);
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
if (!m_enabled)
|
||||
return;
|
||||
updateOffsets();
|
||||
|
||||
QList<QSGParticleData*> toAffect;
|
||||
foreach (QSGParticleGroupData* gd, m_system->m_groupData)
|
||||
if (activeGroup(m_system->m_groupData.key(gd)))
|
||||
foreach (QSGParticleData* d, gd->data)
|
||||
if (shouldAffect(d))
|
||||
toAffect << d;
|
||||
|
||||
v8::HandleScope handle_scope;
|
||||
v8::Context::Scope scope(QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this))->context());
|
||||
v8::Handle<v8::Array> array = v8::Array::New(toAffect.size());
|
||||
for (int i=0; i<toAffect.size(); i++)
|
||||
array->Set(i, toAffect[i]->v8Value().toHandle());
|
||||
|
||||
emit affectParticles(QDeclarativeV8Handle::fromHandle(array), dt);
|
||||
|
||||
foreach (QSGParticleData* d, toAffect)
|
||||
if (d->update == 1.0)
|
||||
postAffect(d);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -59,13 +59,13 @@ class QSGCustomAffector : public QSGParticleAffector
|
|||
|
||||
public:
|
||||
explicit QSGCustomAffector(QSGItem *parent = 0);
|
||||
virtual void affectSystem(qreal dt);
|
||||
|
||||
signals:
|
||||
void affectParticle(QDeclarativeV8Handle particle, qreal dt);
|
||||
void affectParticles(QDeclarativeV8Handle particles, qreal dt);
|
||||
public slots:
|
||||
protected:
|
||||
bool isAffectConnected();
|
||||
virtual bool affectParticle(QSGParticleData *d, qreal dt);
|
||||
private:
|
||||
};
|
||||
|
||||
|
|
|
@ -163,6 +163,8 @@ void setWhenCollidingWith(QStringList arg)
|
|||
emit whenCollidingWithChanged(arg);
|
||||
}
|
||||
}
|
||||
public slots:
|
||||
void updateOffsets();
|
||||
|
||||
protected:
|
||||
friend class QSGParticleSystem;
|
||||
|
@ -189,8 +191,6 @@ private:
|
|||
QStringList m_whenCollidingWith;
|
||||
|
||||
bool isColliding(QSGParticleData* d);
|
||||
private slots:
|
||||
void updateOffsets();
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "qsgparticleemitter_p.h"
|
||||
#include <private/qdeclarativeengine_p.h>
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
|
@ -183,12 +184,12 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
Default value is 0.
|
||||
*/
|
||||
//TODO: Document particle 'type'
|
||||
/*!
|
||||
\qmlsignal QtQuick.Particles2::Emitter::onEmitParticle(Particle particle)
|
||||
|
||||
This handler is called when a particle is emitted. You can modify particle
|
||||
attributes from within the handler.
|
||||
/*!
|
||||
\qmlsignal QtQuick.Particles2::Emitter::onEmitParticles(Array particles)
|
||||
|
||||
This handler is called when particles are emitted. particles is a javascript
|
||||
array of Particle objects. You can modify particle attributes directly within the handler.
|
||||
|
||||
Note that JS is slower to execute, so it is not recommended to use this in
|
||||
high-volume particle systems.
|
||||
|
@ -252,7 +253,7 @@ QSGParticleEmitter::~QSGParticleEmitter()
|
|||
|
||||
bool QSGParticleEmitter::isEmitConnected()
|
||||
{
|
||||
static int idx = QObjectPrivate::get(this)->signalIndex("emitParticle(QDeclarativeV8Handle)");
|
||||
static int idx = QObjectPrivate::get(this)->signalIndex("emitParticles(QDeclarativeV8Handle)");
|
||||
return QObjectPrivate::get(this)->isSignalConnected(idx);
|
||||
}
|
||||
|
||||
|
@ -396,6 +397,9 @@ void QSGParticleEmitter::emitWindow(int timeStamp)
|
|||
qreal emitter_y_offset = m_last_emitter.y() - y();
|
||||
if (!m_burstQueue.isEmpty() && !m_burstLeft && !m_enabled)//'outside time' emissions only
|
||||
pt = time;
|
||||
|
||||
QList<QSGParticleData*> toEmit;
|
||||
|
||||
while ((pt < time && m_emitCap) || !m_burstQueue.isEmpty()) {
|
||||
//int pos = m_last_particle % m_particle_count;
|
||||
QSGParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_group], !m_overwrite);
|
||||
|
@ -459,9 +463,7 @@ void QSGParticleEmitter::emitWindow(int timeStamp)
|
|||
datum->size = size;// * float(m_emitting);
|
||||
datum->endSize = endSize;// * float(m_emitting);
|
||||
|
||||
if (isEmitConnected())
|
||||
emitParticle(datum->v8Value());//A chance for arbitrary JS changes
|
||||
m_system->emitParticle(datum);
|
||||
toEmit << datum;
|
||||
}
|
||||
if (m_burstQueue.isEmpty()){
|
||||
pt += particleRatio;
|
||||
|
@ -471,6 +473,19 @@ void QSGParticleEmitter::emitWindow(int timeStamp)
|
|||
m_burstQueue.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
if (isEmitConnected()) {
|
||||
v8::HandleScope handle_scope;
|
||||
v8::Context::Scope scope(QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this))->context());
|
||||
v8::Handle<v8::Array> array = v8::Array::New(toEmit.size());
|
||||
for (int i=0; i<toEmit.size(); i++)
|
||||
array->Set(i, toEmit[i]->v8Value().toHandle());
|
||||
|
||||
emitParticles(QDeclarativeV8Handle::fromHandle(array));//A chance for arbitrary JS changes
|
||||
}
|
||||
foreach (QSGParticleData* d, toEmit)
|
||||
m_system->emitParticle(d);
|
||||
|
||||
m_last_emission = pt;
|
||||
|
||||
m_last_last_last_emitter = m_last_last_emitter;
|
||||
|
|
|
@ -123,7 +123,7 @@ public:
|
|||
void setSpeedFromMovement(qreal s);
|
||||
virtual void componentComplete();
|
||||
signals:
|
||||
void emitParticle(QDeclarativeV8Handle particle);
|
||||
void emitParticles(QDeclarativeV8Handle particles);
|
||||
void particlesPerSecondChanged(qreal);
|
||||
void particleDurationChanged(int);
|
||||
void enabledChanged(bool);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "qsgtrailemitter_p.h"
|
||||
#include <private/qdeclarativeengine_p.h>
|
||||
#include <cmath>
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -102,18 +103,17 @@ QSGTrailEmitter::QSGTrailEmitter(QSGItem *parent) :
|
|||
\qmlproperty real QtQuick.Particles2::TrailEmitter::emitRatePerParticle
|
||||
*/
|
||||
/*!
|
||||
\qmlsignal QtQuick.Particles2::TrailEmitter::emitFollowParticle(particle, followed)
|
||||
\qmlsignal QtQuick.Particles2::TrailEmitter::emitFollowParticles(Array particles, real followed)
|
||||
|
||||
This handler is called when a particle is emitted. You can modify particle
|
||||
attributes from within the handler. followed is the particle that this is being
|
||||
emitted off of.
|
||||
This handler is called when particles are emitted from the \a followed particle. \a particles contains an array of particle objects which can be directly manipulated.
|
||||
|
||||
If you use this signal handler, emitParticles will not be emitted.
|
||||
|
||||
If you use this signal handler, emitParticle will not be emitted.
|
||||
*/
|
||||
|
||||
bool QSGTrailEmitter::isEmitFollowConnected()
|
||||
{
|
||||
static int idx = QObjectPrivate::get(this)->signalIndex("emitFollowParticle(QDeclarativeV8Handle,QDeclarativeV8Handle)");
|
||||
static int idx = QObjectPrivate::get(this)->signalIndex("emitFollowParticles(QDeclarativeV8Handle,QDeclarativeV8Handle)");
|
||||
return QObjectPrivate::get(this)->isSignalConnected(idx);
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,9 @@ void QSGTrailEmitter::emitWindow(int timeStamp)
|
|||
m_lastEmission[d->index] = time;//jump over this time period without emitting, because it's outside
|
||||
continue;
|
||||
}
|
||||
|
||||
QList<QSGParticleData*> toEmit;
|
||||
|
||||
while (pt < time || !m_burstQueue.isEmpty()){
|
||||
QSGParticleData* datum = m_system->newDatum(gId2, !m_overwrite);
|
||||
if (datum){//else, skip this emission
|
||||
|
@ -235,10 +238,7 @@ void QSGTrailEmitter::emitWindow(int timeStamp)
|
|||
datum->size = size * float(m_enabled);
|
||||
datum->endSize = endSize * float(m_enabled);
|
||||
|
||||
if (isEmitFollowConnected())
|
||||
emitFollowParticle(datum->v8Value(), d->v8Value());//A chance for many arbitrary JS changes
|
||||
else if (isEmitConnected())
|
||||
emitParticle(datum->v8Value());//A chance for arbitrary JS changes
|
||||
toEmit << datum;
|
||||
|
||||
m_system->emitParticle(datum);
|
||||
}
|
||||
|
@ -250,6 +250,21 @@ void QSGTrailEmitter::emitWindow(int timeStamp)
|
|||
pt += particleRatio;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEmitConnected() || isEmitFollowConnected()) {
|
||||
v8::HandleScope handle_scope;
|
||||
v8::Context::Scope scope(QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this))->context());
|
||||
v8::Handle<v8::Array> array = v8::Array::New(toEmit.size());
|
||||
for (int i=0; i<toEmit.size(); i++)
|
||||
array->Set(i, toEmit[i]->v8Value().toHandle());
|
||||
|
||||
if (isEmitFollowConnected())
|
||||
emitFollowParticles(QDeclarativeV8Handle::fromHandle(array), d->v8Value());//A chance for many arbitrary JS changes
|
||||
else if (isEmitConnected())
|
||||
emitParticles(QDeclarativeV8Handle::fromHandle(array));//A chance for arbitrary JS changes
|
||||
}
|
||||
foreach (QSGParticleData* d, toEmit)
|
||||
m_system->emitParticle(d);
|
||||
m_lastEmission[d->index] = pt;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
}
|
||||
|
||||
signals:
|
||||
void emitFollowParticle(QDeclarativeV8Handle group, QDeclarativeV8Handle followed);
|
||||
void emitFollowParticles(QDeclarativeV8Handle particles, QDeclarativeV8Handle followed);
|
||||
|
||||
void particlesPerParticlePerSecondChanged(int arg);
|
||||
|
||||
|
|
Loading…
Reference in New Issue