Hook up durationVariation on Sprites
authorAlan Alpert <alan.alpert@nokia.com>
Fri, 1 Jul 2011 06:12:23 +0000 (16:12 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 20 Jul 2011 06:22:07 +0000 (08:22 +0200)
Change-Id: I11ea38fc87373604debd469e03af3447b8adcecb
Reviewed-on: http://codereview.qt.nokia.com/985
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>

examples/declarative/particles/trails/fireworks.qml
src/declarative/items/qsgsprite.cpp
src/declarative/items/qsgsprite_p.h
src/declarative/items/qsgspriteengine.cpp
src/declarative/items/qsgspriteengine_p.h

index 59627f8..b40b300 100644 (file)
@@ -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{
index e96c0f5..806f7a9 100644 (file)
@@ -62,7 +62,8 @@ void redirectError(QDeclarativeListProperty<QObject> *prop, QObject *value)
     qWarning() << "Could not add " << value << " to state" << prop->object << "as it is not associated with a particle system.";
 }
 
-QDeclarativeListProperty<QObject> QSGSprite::particleChildren(){
+QDeclarativeListProperty<QObject> QSGSprite::particleChildren()
+{
     QSGParticleSystem* system = qobject_cast<QSGParticleSystem*>(parent());
     if (system)
         return QDeclarativeListProperty<QObject>(this, 0, &QSGParticleSystem::stateRedirect);
@@ -70,4 +71,11 @@ QDeclarativeListProperty<QObject> QSGSprite::particleChildren(){
         return QDeclarativeListProperty<QObject>(this, 0, &redirectError);
 }
 
+int QSGSprite::variedDuration() const
+{
+    return m_duration
+            + (m_durationVariance * ((qreal)qrand()/RAND_MAX) * 2)
+            - m_durationVariance;
+}
+
 QT_END_NAMESPACE
index 389cc94..c18e9b4 100644 (file)
@@ -121,6 +121,8 @@ public:
         return m_durationVariance;
     }
 
+    int variedDuration() const;
+
 signals:
 
     void sourceChanged(QUrl arg);
index 736b1f8..1915db6 100644 (file)
@@ -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; i<m_stateUpdates.count(); i++)
         m_stateUpdates[i].second.removeAll(index);
     addToUpdateList(time, index);
@@ -344,12 +348,13 @@ uint QSGSpriteEngine::updateSprites(uint time)//### would returning a list of ch
                 nextIdx = stateIdx;
 
             m_sprites[idx] = nextIdx;
+            m_duration[idx] = m_states[nextIdx]->variedDuration();
             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();
     }
index 643b21c..10860a5 100644 (file)
@@ -122,8 +122,10 @@ private:
     void addToUpdateList(uint t, int idx);
     int goalSeek(int curState, int spriteIdx, int dist=-1);
     QList<QSGSprite*> m_states;
+    //### Consider struct or class for the four data variables?
     QVector<int> m_sprites;//int is the index in m_states of the current state
     QVector<int> m_goals;
+    QVector<int> m_duration;
     QVector<int> m_startTimes;
     QList<QPair<uint, QList<int> > > m_stateUpdates;//### This could be done faster - priority queue?