Skip to content

Commit

Permalink
ImageParticle Sprite Improvements
Browse files Browse the repository at this point in the history
Sprite updates are now from signals instead of polled, and update
ParticleData as well as vertices.

Change-Id: Ib91604a70f4b1fe849bd27c3212ccc1d1482c075
Reviewed-by: Martin Jones <martin.jones@nokia.com>
  • Loading branch information
Alan Alpert authored and Qt by Nokia committed Oct 31, 2011
1 parent f32e5f5 commit 67079ae
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 29 deletions.
3 changes: 2 additions & 1 deletion examples/declarative/particles/imageparticle/sprites.qml
Expand Up @@ -57,7 +57,8 @@ Rectangle {
width: 250
height: 250
x: 20
y: 20
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
z:4
}

Expand Down
9 changes: 5 additions & 4 deletions src/declarative/items/qquickspriteengine.cpp
Expand Up @@ -48,9 +48,9 @@

QT_BEGIN_NAMESPACE

/* TODO: Split out image logic from stochastic state logic
Also make sharable
Also solve the state data initialization/transfer issue so as to not need to make friends
/* TODO:
make sharable?
solve the state data initialization/transfer issue so as to not need to make friends
*/

QQuickStochasticEngine::QQuickStochasticEngine(QObject *parent) :
Expand Down Expand Up @@ -177,7 +177,8 @@ int QQuickSpriteEngine::spriteCount()//TODO: Actually image state count, need to

void QQuickStochasticEngine::setGoal(int state, int sprite, bool jump)
{
if (sprite >= m_things.count() || state >= m_states.count())
if (sprite >= m_things.count() || state >= m_states.count()
|| sprite < 0 || state < 0)
return;
if (!jump){
m_goals[sprite] = state;
Expand Down
67 changes: 43 additions & 24 deletions src/declarative/particles/qquickimageparticle.cpp
Expand Up @@ -1114,11 +1114,15 @@ void QQuickImageParticle::createEngine()
{
if (m_spriteEngine)
delete m_spriteEngine;
if (m_sprites.count())
if (m_sprites.count()) {
m_spriteEngine = new QQuickSpriteEngine(m_sprites, this);
else
connect(m_spriteEngine, SIGNAL(stateChanged(int)),
this, SLOT(spriteAdvance(int)));
m_explicitAnimation = true;
} else {
m_spriteEngine = 0;
m_explicitAnimation = true;
m_explicitAnimation = false;
}
reset();
}

Expand Down Expand Up @@ -1329,6 +1333,7 @@ QSGGeometryNode* QQuickImageParticle::buildParticleNodes()

m_nodes.insert(gIdx, node);
m_idxStarts.insert(gIdx, m_lastIdxStart);
m_startsIdx.append(qMakePair<int,int>(m_lastIdxStart, gIdx));
m_lastIdxStart += count;

//Create Particle Geometry
Expand Down Expand Up @@ -1404,6 +1409,7 @@ QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
m_nodes.clear();

m_idxStarts.clear();
m_startsIdx.clear();
m_lastIdxStart = 0;

m_material = 0;
Expand Down Expand Up @@ -1448,26 +1454,6 @@ void QQuickImageParticle::prepareNextFrame()
case Sprites:
//Advance State
m_spriteEngine->updateSprites(timeStamp);
foreach (const QString &str, m_groups){
int gIdx = m_system->groupIds[str];
int count = m_system->groupData[gIdx]->size();

Vertices<SpriteVertex>* particles = (Vertices<SpriteVertex> *) m_nodes[gIdx]->geometry()->vertexData();
for (int i=0; i < count; i++){
int spriteIdx = m_idxStarts[gIdx] + i;
Vertices<SpriteVertex> &p = particles[i];
int curY = m_spriteEngine->spriteY(spriteIdx);//Y is fixed per sprite row, used to distinguish rows here
if (curY != p.v1.animY){
p.v1.animT = p.v2.animT = p.v3.animT = p.v4.animT = m_spriteEngine->spriteStart(spriteIdx)/1000.0;
p.v1.frameCount = p.v2.frameCount = p.v3.frameCount = p.v4.frameCount = m_spriteEngine->spriteFrames(spriteIdx);
p.v1.frameDuration = p.v2.frameDuration = p.v3.frameDuration = p.v4.frameDuration = m_spriteEngine->spriteDuration(spriteIdx);
p.v1.animX = p.v2.animX = p.v3.animX = p.v4.animX = m_spriteEngine->spriteX(spriteIdx);
p.v1.animY = p.v2.animY = p.v3.animY = p.v4.animY = m_spriteEngine->spriteY(spriteIdx);
p.v1.animWidth = p.v2.animWidth = p.v3.animWidth = p.v4.animWidth = m_spriteEngine->spriteWidth(spriteIdx);
p.v1.animHeight = p.v2.animHeight = p.v3.animHeight = p.v4.animHeight = m_spriteEngine->spriteHeight(spriteIdx);
}
}
}
case Tabled:
case Deformable:
case Colored:
Expand All @@ -1481,6 +1467,38 @@ void QQuickImageParticle::prepareNextFrame()
node->markDirty(QSGNode::DirtyMaterial);
}

void QQuickImageParticle::spriteAdvance(int spriteIdx)
{
if (!m_startsIdx.count())//Probably overly defensive
return;

int gIdx = -1;
int i;
for (i = 0; i<m_startsIdx.count(); i++) {
if (spriteIdx < m_startsIdx[i].first) {
gIdx = m_startsIdx[i-1].second;
break;
}
}
if (gIdx == -1)
gIdx = m_startsIdx[i-1].second;
int pIdx = spriteIdx - m_startsIdx[i-1].first;

QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
QQuickParticleData* d = (datum->animationOwner == this ? datum : getShadowDatum(datum));

d->animIdx = m_spriteEngine->spriteState(spriteIdx);
Vertices<SpriteVertex>* particles = (Vertices<SpriteVertex> *) m_nodes[gIdx]->geometry()->vertexData();
Vertices<SpriteVertex> &p = particles[pIdx];
d->animT = p.v1.animT = p.v2.animT = p.v3.animT = p.v4.animT = m_spriteEngine->spriteStart(spriteIdx)/1000.0;
d->frameCount = p.v1.frameCount = p.v2.frameCount = p.v3.frameCount = p.v4.frameCount = m_spriteEngine->spriteFrames(spriteIdx);
d->frameDuration = p.v1.frameDuration = p.v2.frameDuration = p.v3.frameDuration = p.v4.frameDuration = m_spriteEngine->spriteDuration(spriteIdx);
d->animX = p.v1.animX = p.v2.animX = p.v3.animX = p.v4.animX = m_spriteEngine->spriteX(spriteIdx);
d->animY = p.v1.animY = p.v2.animY = p.v3.animY = p.v4.animY = m_spriteEngine->spriteY(spriteIdx);
d->animWidth = p.v1.animWidth = p.v2.animWidth = p.v3.animWidth = p.v4.animWidth = m_spriteEngine->spriteWidth(spriteIdx);
d->animHeight = p.v1.animHeight = p.v2.animHeight = p.v3.animHeight = p.v4.animHeight = m_spriteEngine->spriteHeight(spriteIdx);
}

void QQuickImageParticle::reloadColor(const Color4ub &c, QQuickParticleData* d)
{
d->color = c;
Expand Down Expand Up @@ -1518,7 +1536,8 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx)
}else{
writeTo->frameCount = 1;
writeTo->frameDuration = 9999;
writeTo->animX = writeTo->animY = writeTo->animWidth = writeTo->animHeight = 0;
writeTo->animX = writeTo->animY = 0;
writeTo->animWidth = writeTo->animHeight = 1;
}
}
case Tabled:
Expand Down
3 changes: 3 additions & 0 deletions src/declarative/particles/qquickimageparticle_p.h
Expand Up @@ -348,6 +348,7 @@ public slots:
private slots:
void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty

void spriteAdvance(int spriteIndex);
private:
QUrl m_image_name;
QUrl m_colortable_name;
Expand All @@ -362,6 +363,8 @@ private slots:
QSGGeometryNode *m_rootNode;
QHash<int, QSGGeometryNode *> m_nodes;
QHash<int, int> m_idxStarts;//TODO: Proper resizing will lead to needing a spriteEngine per particle - do this after sprite engine gains transparent sharing?
QList<QPair<int, int> > m_startsIdx;//Same data, optimized for alternate retrieval

int m_lastIdxStart;
QSGMaterial *m_material;

Expand Down

0 comments on commit 67079ae

Please sign in to comment.