From c53f036492deeaf21b9e9c666efa901775bca4b3 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 1 Jul 2011 16:12:23 +1000 Subject: [PATCH] Hook up durationVariation on Sprites Change-Id: I11ea38fc87373604debd469e03af3447b8adcecb Reviewed-on: http://codereview.qt.nokia.com/985 Reviewed-by: Qt Sanity Bot Reviewed-by: Martin Jones --- .../declarative/particles/trails/fireworks.qml | 14 +++++++++++- src/declarative/items/qsgsprite.cpp | 10 ++++++++- src/declarative/items/qsgsprite_p.h | 2 + src/declarative/items/qsgspriteengine.cpp | 21 ++++++++++++------- src/declarative/items/qsgspriteengine_p.h | 2 + 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/examples/declarative/particles/trails/fireworks.qml b/examples/declarative/particles/trails/fireworks.qml index 59627f8..b40b300 100644 --- a/examples/declarative/particles/trails/fireworks.qml +++ b/examples/declarative/particles/trails/fireworks.qml @@ -52,6 +52,7 @@ Rectangle{ Sprite{ name: "fire" duration: 2000 + durationVariation: 2000 to: {"splode":1} }, Sprite{ @@ -78,13 +79,22 @@ Rectangle{ } } ] + Timer{ + interval: 6000 + running: true + triggeredOnStart: true + repeat: true + onTriggered:startingEmitter.pulse(0.1); + } Emitter{ + id: startingEmitter particle: "fire" width: parent.width y: parent.height - emitRate: 2 + emitting: false + emitRate: 80 lifeSpan: 6000 - speed: PointDirection{y:-100; yVariation: 40} + speed: PointDirection{y:-100;} size: 32 } Emitter{ diff --git a/src/declarative/items/qsgsprite.cpp b/src/declarative/items/qsgsprite.cpp index e96c0f5..806f7a9 100644 --- a/src/declarative/items/qsgsprite.cpp +++ b/src/declarative/items/qsgsprite.cpp @@ -62,7 +62,8 @@ void redirectError(QDeclarativeListProperty *prop, QObject *value) qWarning() << "Could not add " << value << " to state" << prop->object << "as it is not associated with a particle system."; } -QDeclarativeListProperty QSGSprite::particleChildren(){ +QDeclarativeListProperty QSGSprite::particleChildren() +{ QSGParticleSystem* system = qobject_cast(parent()); if (system) return QDeclarativeListProperty(this, 0, &QSGParticleSystem::stateRedirect); @@ -70,4 +71,11 @@ QDeclarativeListProperty QSGSprite::particleChildren(){ return QDeclarativeListProperty(this, 0, &redirectError); } +int QSGSprite::variedDuration() const +{ + return m_duration + + (m_durationVariance * ((qreal)qrand()/RAND_MAX) * 2) + - m_durationVariance; +} + QT_END_NAMESPACE diff --git a/src/declarative/items/qsgsprite_p.h b/src/declarative/items/qsgsprite_p.h index 389cc94..c18e9b4 100644 --- a/src/declarative/items/qsgsprite_p.h +++ b/src/declarative/items/qsgsprite_p.h @@ -121,6 +121,8 @@ public: return m_durationVariance; } + int variedDuration() const; + signals: void sourceChanged(QUrl arg); diff --git a/src/declarative/items/qsgspriteengine.cpp b/src/declarative/items/qsgspriteengine.cpp index 736b1f8..1915db6 100644 --- a/src/declarative/items/qsgspriteengine.cpp +++ b/src/declarative/items/qsgspriteengine.cpp @@ -83,13 +83,14 @@ int QSGSpriteEngine::maxFrames() Therefore the below functions abstract sprite from the viewpoint of classes that pass the details onto shaders But States maintain their listed index for internal structures TODO: All these calculations should be pre-calculated and cached during initialization for a significant performance boost +TODO: Above idea needs to have the varying duration offset added to it */ int QSGSpriteEngine::spriteState(int sprite) { int state = m_sprites[sprite]; if (!m_states[state]->m_generatedCount) return state; - int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; + int rowDuration = m_duration[sprite] * m_states[state]->m_framesPerRow; int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; return state + extra; } @@ -99,7 +100,7 @@ int QSGSpriteEngine::spriteStart(int sprite) int state = m_sprites[sprite]; if (!m_states[state]->m_generatedCount) return m_startTimes[sprite]; - int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; + int rowDuration = m_duration[sprite] * m_states[state]->m_framesPerRow; int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; return state + extra*rowDuration; } @@ -109,7 +110,7 @@ int QSGSpriteEngine::spriteFrames(int sprite) int state = m_sprites[sprite]; if (!m_states[state]->m_generatedCount) return m_states[state]->frames(); - int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; + int rowDuration = m_duration[sprite] * m_states[state]->m_framesPerRow; int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; if (extra == m_states[state]->m_generatedCount - 1)//last state return m_states[state]->frames() % m_states[state]->m_framesPerRow; @@ -121,11 +122,11 @@ int QSGSpriteEngine::spriteDuration(int sprite) { int state = m_sprites[sprite]; if (!m_states[state]->m_generatedCount) - return m_states[state]->duration(); - int rowDuration = m_states[state]->duration() * m_states[state]->m_framesPerRow; + return m_duration[sprite]; + int rowDuration = m_duration[sprite] * m_states[state]->m_framesPerRow; int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; if (extra == m_states[state]->m_generatedCount - 1)//last state - return (m_states[state]->duration() * m_states[state]->frames()) % rowDuration; + return (m_duration[sprite] * m_states[state]->frames()) % rowDuration; else return rowDuration; } @@ -147,6 +148,7 @@ void QSGSpriteEngine::setGoal(int state, int sprite, bool jump) if (m_sprites[sprite] == state) return;//Already there m_sprites[sprite] = state; + m_duration[sprite] = m_states[state]->variedDuration(); m_goals[sprite] = -1; restartSprite(sprite); emit stateChanged(sprite); @@ -273,6 +275,7 @@ void QSGSpriteEngine::setCount(int c) { m_sprites.resize(c); m_goals.resize(c); + m_duration.resize(c); m_startTimes.resize(c); } @@ -281,6 +284,7 @@ void QSGSpriteEngine::startSprite(int index, int state) if (index >= m_sprites.count()) return; m_sprites[index] = state; + m_duration[index] = m_states[state]->variedDuration(); m_goals[index] = -1; restartSprite(index); } @@ -297,7 +301,7 @@ void QSGSpriteEngine::stopSprite(int index) void QSGSpriteEngine::restartSprite(int index) { m_startTimes[index] = m_timeOffset + m_advanceTime.elapsed(); - int time = m_states[m_sprites[index]]->duration() * m_states[m_sprites[index]]->frames() + m_startTimes[index]; + int time = m_duration[index] * m_states[m_sprites[index]]->frames() + m_startTimes[index]; for (int i=0; ivariedDuration(); m_startTimes[idx] = time; if (nextIdx != stateIdx){ changedIndexes << idx; emit m_states[nextIdx]->entered(); } - addToUpdateList((m_states[nextIdx]->duration() * m_states[nextIdx]->frames()) + time, idx); + addToUpdateList((m_duration[idx] * m_states[nextIdx]->frames()) + time, idx); } m_stateUpdates.pop_front(); } diff --git a/src/declarative/items/qsgspriteengine_p.h b/src/declarative/items/qsgspriteengine_p.h index 643b21c..10860a5 100644 --- a/src/declarative/items/qsgspriteengine_p.h +++ b/src/declarative/items/qsgspriteengine_p.h @@ -122,8 +122,10 @@ private: void addToUpdateList(uint t, int idx); int goalSeek(int curState, int spriteIdx, int dist=-1); QList m_states; + //### Consider struct or class for the four data variables? QVector m_sprites;//int is the index in m_states of the current state QVector m_goals; + QVector m_duration; QVector m_startTimes; QList > > m_stateUpdates;//### This could be done faster - priority queue? -- 1.7.2.5