aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickspriteengine.cpp
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2012-01-13 13:54:29 +1000
committerQt by Nokia <qt-info@nokia.com>2012-01-23 07:38:34 +0100
commit379e388568f5d5408b4be13ce6a1faba0b74be6b (patch)
tree55d6684817c566dad5939ff5e8ad652215fef7a2 /src/quick/items/qquickspriteengine.cpp
parent69920f4ddeaa5dbdee555e0a607fd21eb42e2bbc (diff)
Per-frame Sprites patch one
To allow for sprites to be advanced by the rendering framerate, two minor redesigns were needed. A) Sprite texture location is now calculated on the CPU and passed to the GPU per frame. B) Stochastic State engine now supports states that do not advance on a timer, and states can be advanced manually. This patch implements B and A for ImageParticle. A for SpriteImage will be done in a separate patch. Task-number: QTBUG-22236 Change-Id: If1c54a6a03fa48b95bb1e672283292859656457b Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
Diffstat (limited to 'src/quick/items/qquickspriteengine.cpp')
-rw-r--r--src/quick/items/qquickspriteengine.cpp106
1 files changed, 56 insertions, 50 deletions
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index 5a2d831f92..b48fc71767 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -339,67 +339,73 @@ void QQuickStochasticEngine::restart(int index)
int time = m_duration[index] * m_states[m_things[index]]->frames() + m_startTimes[index];
for (int i=0; i<m_stateUpdates.count(); i++)
m_stateUpdates[i].second.removeAll(index);
- addToUpdateList(time, index);
+ if (m_duration[index] > 0)
+ addToUpdateList(time, index);
}
-uint QQuickStochasticEngine::updateSprites(uint time)//### would returning a list of changed idxs be faster than signals?
+// Doesn't remove from update list. If you want to cancel pending timed updates, call restart() first.
+// Usually sprites are either manually advanced or in the list, and mixing is not recommended anyways.
+void QQuickStochasticEngine::advance(int idx)
{
- //Sprite State Update;
- QSet<int> changedIndexes;
- while (!m_stateUpdates.isEmpty() && time >= m_stateUpdates.first().first){
- foreach (int idx, m_stateUpdates.first().second){
- if (idx >= m_things.count())
- continue;//TODO: Proper fix(because this does happen and I'm just ignoring it)
- int stateIdx = m_things[idx];
- int nextIdx = -1;
- int goalPath = goalSeek(stateIdx, idx);
- if (goalPath == -1){//Random
- qreal r =(qreal) qrand() / (qreal) RAND_MAX;
- qreal total = 0.0;
- for (QVariantMap::const_iterator iter=m_states[stateIdx]->m_to.constBegin();
- iter!=m_states[stateIdx]->m_to.constEnd(); iter++)
- total += (*iter).toReal();
- r*=total;
- for (QVariantMap::const_iterator iter= m_states[stateIdx]->m_to.constBegin();
- iter!=m_states[stateIdx]->m_to.constEnd(); iter++){
- if (r < (*iter).toReal()){
- bool superBreak = false;
- for (int i=0; i<m_states.count(); i++){
- if (m_states[i]->name() == iter.key()){
- nextIdx = i;
- superBreak = true;
- break;
- }
- }
- if (superBreak)
- break;
+ if (idx >= m_things.count())
+ return;//TODO: Proper fix(because this has happened and I just ignored it)
+ int stateIdx = m_things[idx];
+ int nextIdx = nextState(stateIdx,idx);
+ m_things[idx] = nextIdx;
+ m_duration[idx] = m_states[nextIdx]->variedDuration();
+ m_startTimes[idx] = m_timeOffset;//This will be the last time updateSprites was called
+ emit m_states[nextIdx]->entered();
+ emit stateChanged(idx); //TODO: emit this when a psuedostate changes too(but manually in SpriteEngine)
+ if (m_duration[idx] >= 0)
+ addToUpdateList((m_duration[idx] * m_states[nextIdx]->frames()) + m_startTimes[idx], idx);
+}
+
+int QQuickStochasticEngine::nextState(int curState, int curThing)
+{
+ int nextIdx = -1;
+ int goalPath = goalSeek(curState, curThing);
+ if (goalPath == -1){//Random
+ qreal r =(qreal) qrand() / (qreal) RAND_MAX;
+ qreal total = 0.0;
+ for (QVariantMap::const_iterator iter=m_states[curState]->m_to.constBegin();
+ iter!=m_states[curState]->m_to.constEnd(); iter++)
+ total += (*iter).toReal();
+ r*=total;
+ for (QVariantMap::const_iterator iter= m_states[curState]->m_to.constBegin();
+ iter!=m_states[curState]->m_to.constEnd(); iter++){
+ if (r < (*iter).toReal()){
+ bool superBreak = false;
+ for (int i=0; i<m_states.count(); i++){
+ if (m_states[i]->name() == iter.key()){
+ nextIdx = i;
+ superBreak = true;
+ break;
}
- r -= (*iter).toReal();
}
- }else{//Random out of shortest paths to goal
- nextIdx = goalPath;
- }
- if (nextIdx == -1)//No to states means stay here
- nextIdx = stateIdx;
-
- m_things[idx] = nextIdx;
- m_duration[idx] = m_states[nextIdx]->variedDuration();
- m_startTimes[idx] = time;
- if (nextIdx != stateIdx){
- changedIndexes << idx;
- emit m_states[nextIdx]->entered();
+ if (superBreak)
+ break;
}
- addToUpdateList((m_duration[idx] * m_states[nextIdx]->frames()) + time, idx);
+ r -= (*iter).toReal();
}
- m_stateUpdates.pop_front();
+ }else{//Random out of shortest paths to goal
+ nextIdx = goalPath;
}
+ if (nextIdx == -1)//No 'to' states means stay here
+ nextIdx = curState;
+ return nextIdx;
+}
+uint QQuickStochasticEngine::updateSprites(uint time)//### would returning a list of changed idxs be faster than signals?
+{
+ //Sprite State Update;
m_timeOffset = time;
- m_advanceTime.start();
- //TODO: emit this when a psuedostate changes too
- foreach (int idx, changedIndexes){//Batched so that update list doesn't change midway
- emit stateChanged(idx);
+ while (!m_stateUpdates.isEmpty() && time >= m_stateUpdates.first().first){
+ foreach (int idx, m_stateUpdates.first().second)
+ advance(idx);
+ m_stateUpdates.pop_front();
}
+
+ m_advanceTime.start();
if (m_stateUpdates.isEmpty())
return -1;
return m_stateUpdates.first().first;