** This file is part of the Declarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
QSGMaterialShader *UltraMaterial::createShader() const
{
- if(usesSprites)//TODO: Perhaps just swap the shaders, and don't mind the extra vector?
+ if (usesSprites)//TODO: Perhaps just swap the shaders, and don't mind the extra vector?
return new UltraMaterialData;
else
return new UltraMaterialData;
: QSGParticlePainter(parent)
, m_do_reset(false)
, m_color_variation(0.0)
- , m_node(0)
+ , m_rootNode(0)
, m_material(0)
, m_alphaVariation(0.0)
, m_alpha(1.0)
, m_lastLevel(Unknown)
{
setFlag(ItemHasContents);
- //TODO: Clean up defaults here and in custom
- m_defaultUltra = new UltraVertices;
- m_defaultSimple = new SimpleVertices;
- UltraVertex *vertices = (UltraVertex *) m_defaultUltra;
- SimpleVertex *vertices2 = (SimpleVertex *) m_defaultSimple;
- for (int i=0; i<4; ++i) {
- vertices2[i].x = vertices[i].x = 0;
- vertices2[i].y = vertices[i].y = 0;
- vertices2[i].t = vertices[i].t = -1;
- vertices2[i].lifeSpan = vertices[i].lifeSpan = 0;
- vertices2[i].size = vertices[i].size = 0;
- vertices2[i].endSize = vertices[i].endSize = 0;
- vertices2[i].sx = vertices[i].sx = 0;
- vertices2[i].sy = vertices[i].sy = 0;
- vertices2[i].ax = vertices[i].ax = 0;
- vertices2[i].ay = vertices[i].ay = 0;
- vertices[i].xx = 1;
- vertices[i].xy = 0;
- vertices[i].yx = 0;
- vertices[i].yy = 1;
- vertices[i].rotation = 0;
- vertices[i].rotationSpeed = 0;
- vertices[i].autoRotate = 0;
- vertices[i].animIdx = -1;
- vertices[i].frameDuration = 1;
- vertices[i].frameCount = 0;
- vertices[i].animT = -1;
- vertices[i].color.r = 255;
- vertices[i].color.g = 255;
- vertices[i].color.b = 255;
- vertices[i].color.a = 255;
- }
-
- vertices[0].tx = 0;
- vertices[0].ty = 0;
-
- vertices[1].tx = 1;
- vertices[1].ty = 0;
-
- vertices[2].tx = 0;
- vertices[2].ty = 1;
-
- vertices[3].tx = 1;
- vertices[3].ty = 1;
-
- vertices2[0].tx = 0;
- vertices2[0].ty = 0;
-
- vertices2[1].tx = 1;
- vertices2[1].ty = 0;
-
- vertices2[2].tx = 0;
- vertices2[2].ty = 1;
-
- vertices2[3].tx = 1;
- vertices2[3].ty = 1;
}
QDeclarativeListProperty<QSGSprite> QSGImageParticle::sprites()
return;
m_color = color;
emit colorChanged();
- if(perfLevel < Coloured)
+ if (perfLevel < Colored)
reset();
}
return;
m_color_variation = var;
emit colorVariationChanged();
- if(perfLevel < Coloured)
+ if (perfLevel < Colored)
reset();
}
m_alphaVariation = arg;
emit alphaVariationChanged(arg);
}
- if(perfLevel < Coloured)
+ if (perfLevel < Colored)
reset();
}
m_alpha = arg;
emit alphaChanged(arg);
}
- if(perfLevel < Coloured)
+ if (perfLevel < Colored)
reset();
}
m_redVariation = arg;
emit redVariationChanged(arg);
}
- if(perfLevel < Coloured)
+ if (perfLevel < Colored)
reset();
}
m_greenVariation = arg;
emit greenVariationChanged(arg);
}
- if(perfLevel < Coloured)
+ if (perfLevel < Colored)
reset();
}
m_blueVariation = arg;
emit blueVariationChanged(arg);
}
- if(perfLevel < Coloured)
+ if (perfLevel < Colored)
reset();
}
m_rotation = arg;
emit rotationChanged(arg);
}
- if(perfLevel < Deformable)
+ if (perfLevel < Deformable)
reset();
}
m_rotationVariation = arg;
emit rotationVariationChanged(arg);
}
- if(perfLevel < Deformable)
+ if (perfLevel < Deformable)
reset();
}
m_rotationSpeed = arg;
emit rotationSpeedChanged(arg);
}
- if(perfLevel < Deformable)
+ if (perfLevel < Deformable)
reset();
}
m_rotationSpeedVariation = arg;
emit rotationSpeedVariationChanged(arg);
}
- if(perfLevel < Deformable)
+ if (perfLevel < Deformable)
reset();
}
m_autoRotation = arg;
emit autoRotationChanged(arg);
}
- if(perfLevel < Deformable)
+ if (perfLevel < Deformable)
reset();
}
m_xVector = arg;
emit xVectorChanged(arg);
}
- if(perfLevel < Deformable)
+ if (perfLevel < Deformable)
reset();
}
m_yVector = arg;
emit yVectorChanged(arg);
}
- if(perfLevel < Deformable)
+ if (perfLevel < Deformable)
reset();
}
m_bloat = arg;
emit bloatChanged(arg);
}
- if(perfLevel < 9999)
+ if (perfLevel < 9999)
reset();
}
void QSGImageParticle::reset()
{
QSGParticlePainter::reset();
- m_pleaseReset = true;
+ m_pleaseReset = true;
+ update();
}
void QSGImageParticle::createEngine()
{
- if(m_spriteEngine)
+ if (m_spriteEngine)
delete m_spriteEngine;
- if(m_sprites.count())
+ if (m_sprites.count())
m_spriteEngine = new QSGSpriteEngine(m_sprites, this);
else
m_spriteEngine = 0;
UltraParticle_Attributes
};
-QSGGeometryNode* QSGImageParticle::buildSimpleParticleNode()
+QSGGeometryNode* QSGImageParticle::buildSimpleParticleNodes()
{
perfLevel = Simple;//TODO: Intermediate levels
QImage image = QImage(m_image_name.toLocalFile());
printf("UltraParticle: loading image failed... '%s'\n", qPrintable(m_image_name.toLocalFile()));
return 0;
}
- int vCount = m_count * 4;
- int iCount = m_count * 6;
- qDebug() << "Simple Case";
-
- QSGGeometry *g = new QSGGeometry(SimpleParticle_AttributeSet, vCount, iCount);
- g->setDrawingMode(GL_TRIANGLES);
-
- SimpleVertices *vertices = (SimpleVertices *) g->vertexData();
- for (int p=0; p<m_count; ++p)
- memcpy(vertices++, m_defaultSimple, sizeof(SimpleVertices));
-
- quint16 *indices = g->indexDataAsUShort();
- for (int i=0; i<m_count; ++i) {
- int o = i * 4;
- indices[0] = o;
- indices[1] = o + 1;
- indices[2] = o + 2;
- indices[3] = o + 1;
- indices[4] = o + 3;
- indices[5] = o + 2;
- indices += 6;
- }
if (m_material) {
delete m_material;
m_material->texture = sceneGraphEngine()->createTextureFromImage(image);
m_material->texture->setFiltering(QSGTexture::Linear);
m_material->framecount = 1;
- m_node = new QSGGeometryNode();
- m_node->setGeometry(g);
- m_node->setMaterial(m_material);
- m_last_particle = 0;
+ foreach (const QString &str, m_particles){
+ int gIdx = m_system->m_groupIds[str];
+ int count = m_system->m_groupData[gIdx]->size();
+
+ QSGGeometryNode* node = new QSGGeometryNode();
+ m_nodes.insert(gIdx, node);
+ node->setMaterial(m_material);
+
+ int vCount = count * 4;
+ int iCount = count * 6;
+
+ QSGGeometry *g = new QSGGeometry(SimpleParticle_AttributeSet, vCount, iCount);
+ node->setGeometry(g);
+ g->setDrawingMode(GL_TRIANGLES);
+
+ SimpleVertex *vertices = (SimpleVertex *) g->vertexData();
+ for (int p=0; p < count; ++p){
+ commit(gIdx, p);
+ vertices[0].tx = 0;
+ vertices[0].ty = 0;
+
+ vertices[1].tx = 1;
+ vertices[1].ty = 0;
+
+ vertices[2].tx = 0;
+ vertices[2].ty = 1;
+
+ vertices[3].tx = 1;
+ vertices[3].ty = 1;
+
+ vertices += 4;
+ }
+
+ quint16 *indices = g->indexDataAsUShort();
+ for (int i=0; i < count; ++i) {
+ int o = i * 4;
+ indices[0] = o;
+ indices[1] = o + 1;
+ indices[2] = o + 2;
+ indices[3] = o + 1;
+ indices[4] = o + 3;
+ indices[5] = o + 2;
+ indices += 6;
+ }
+ }
+
+ foreach (QSGGeometryNode* node, m_nodes){
+ if (node == *(m_nodes.begin()))
+ continue;
+ (*(m_nodes.begin()))->appendChildNode(node);
+ }
- return m_node;
+ return *(m_nodes.begin());
}
-QSGGeometryNode* QSGImageParticle::buildParticleNode()
+QSGGeometryNode* QSGImageParticle::buildParticleNodes()
{
if (m_count * 4 > 0xffff) {
- printf("UltraParticle: Too many particles... \n");//####Why is this here?
+ printf("UltraParticle: Too many particles... \n");//### Why is this here?
return 0;
}
- if(m_count <= 0) {
- printf("UltraParticle: Too few particles... \n");
+ if (count() <= 0)
return 0;
- }
- m_resizePending = false;
- if(!m_sprites.count() && !m_bloat
+ if (!m_sprites.count() && !m_bloat
&& m_colortable_name.isEmpty()
&& m_sizetable_name.isEmpty()
&& m_opacitytable_name.isEmpty()
&& !m_redVariation && !m_blueVariation && !m_greenVariation
&& !m_color.isValid()
)
- return buildSimpleParticleNode();
+ return buildSimpleParticleNodes();
perfLevel = Sprites;//TODO: intermediate levels
- if(!m_color.isValid())//But we're in colored level (or higher)
+ if (!m_color.isValid())//But we're in colored level (or higher)
m_color = QColor(Qt::white);
- qDebug() << "Complex Case";
QImage image;
- if(m_sprites.count()){
+ if (m_sprites.count()){
if (!m_spriteEngine) {
qWarning() << "UltraParticle: No sprite engine...";
return 0;
}
image = m_spriteEngine->assembledImage();
- if(image.isNull())//Warning is printed in engine
+ if (image.isNull())//Warning is printed in engine
return 0;
}else{
image = QImage(m_image_name.toLocalFile());
}
}
- int vCount = m_count * 4;
- int iCount = m_count * 6;
-
- QSGGeometry *g = new QSGGeometry(UltraParticle_AttributeSet, vCount, iCount);
- g->setDrawingMode(GL_TRIANGLES);
-
- UltraVertex *vertices = (UltraVertex *) g->vertexData();
- SimpleVertex *oldSimple = (SimpleVertex *) m_lastData;//TODO: Other levels
- if(m_lastLevel == 1)
- qDebug() << "Theta" << m_lastLevel << oldSimple[0].x << oldSimple[0].y << oldSimple[0].t;
- for (int p=0; p<m_count; ++p) {
- memcpy(vertices, m_defaultUltra, sizeof(UltraVertices));
- if (m_lastLevel == 1 && m_lastCount > p) {//Transplant/IntermediateVertices?
- for (int i=0; i<4; ++i) {
- vertices[i].x = oldSimple[i].x;
- vertices[i].y = oldSimple[i].y;
- vertices[i].t = oldSimple[i].t;
- vertices[i].lifeSpan = oldSimple[i].lifeSpan;
- vertices[i].size = oldSimple[i].size;
- vertices[i].endSize = oldSimple[i].endSize;
- vertices[i].sx = oldSimple[i].sx;
- vertices[i].sy = oldSimple[i].sy;
- vertices[i].ax = oldSimple[i].ax;
- vertices[i].ay = oldSimple[i].ay;
- /*
- vertices[i].frameDuration = oldSimple[i].lifeSpan;
- vertices[i].frameCount = 1;
- vertices[i].animT = oldSimple[i].t;
- */
- }
- }
-
- vertices += 4;
- oldSimple += 4;
- }
-
- quint16 *indices = g->indexDataAsUShort();//TODO: Speed gains by copying this over if count unchanged?
- for (int i=0; i<m_count; ++i) {
- int o = i * 4;
- indices[0] = o;
- indices[1] = o + 1;
- indices[2] = o + 2;
- indices[3] = o + 1;
- indices[4] = o + 3;
- indices[5] = o + 2;
- indices += 6;
- }
-
- qFree(m_lastData);
if (m_material) {
delete m_material;
m_material = 0;
QImage sizetable(m_sizetable_name.toLocalFile());
QImage opacitytable(m_opacitytable_name.toLocalFile());
m_material = new UltraMaterial();
- if(colortable.isNull())
+ if (colortable.isNull())
colortable = QImage(":defaultshaders/identitytable.png");
- if(sizetable.isNull())
+ if (sizetable.isNull())
sizetable = QImage(":defaultshaders/identitytable.png");
- if(opacitytable.isNull())
+ if (opacitytable.isNull())
opacitytable = QImage(":defaultshaders/defaultFadeInOut.png");
Q_ASSERT(!colortable.isNull());
Q_ASSERT(!sizetable.isNull());
m_material->texture->setFiltering(QSGTexture::Linear);
m_material->framecount = 1;
- if(m_spriteEngine){
+ if (m_spriteEngine){
m_material->framecount = m_spriteEngine->maxFrames();
m_spriteEngine->setCount(m_count);
}
- m_node = new QSGGeometryNode();
- m_node->setGeometry(g);
- m_node->setMaterial(m_material);
+ foreach (const QString &str, m_particles){
+ int gIdx = m_system->m_groupIds[str];
+ int count = m_system->m_groupData[gIdx]->size();
+ QSGGeometryNode* node = new QSGGeometryNode();
+ node->setMaterial(m_material);
- m_last_particle = 0;
+ m_nodes.insert(gIdx, node);
+ m_idxStarts.insert(gIdx, m_lastIdxStart);
+ m_lastIdxStart += count;
- return m_node;
-}
+ //Create Particle Geometry
+ int vCount = count * 4;
+ int iCount = count * 6;
-void QSGImageParticle::resize(int oldCount, int newCount)
-{
- //If perf level changes at the same time as a resize, we reset instead of doing pending resize
- if(!m_node)
- return;
- switch(perfLevel){
- default:
- case Sprites:
- if(m_spriteEngine)
- reset();//TODO: Handle sprite resizeing (have to shuffle the engine too...)
- case Coloured:
- case Deformable:
- case Tabled:
- if(!m_resizePending){
- m_resizePendingUltra.resize(oldCount);
- UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData();
- for(int i=0; i<oldCount; i++)
- m_resizePendingUltra[i] = &particles[i];
- }
- groupShuffle(m_resizePendingUltra, m_defaultUltra);
- break;
- case Simple:
- if(!m_resizePending){
- m_resizePendingSimple.resize(oldCount);
- SimpleVertices *particles = (SimpleVertices *) m_node->geometry()->vertexData();
- for(int i=0; i<oldCount; i++)
- m_resizePendingSimple[i] = &particles[i];
+ QSGGeometry *g = new QSGGeometry(UltraParticle_AttributeSet, vCount, iCount);
+ node->setGeometry(g);
+ g->setDrawingMode(GL_TRIANGLES);
+
+ UltraVertex *vertices = (UltraVertex *) g->vertexData();
+ for (int p=0; p < count; ++p) {
+ commit(gIdx, p);//commit sets geometry for the node
+
+ vertices[0].tx = 0;
+ vertices[0].ty = 0;
+
+ vertices[1].tx = 1;
+ vertices[1].ty = 0;
+
+ vertices[2].tx = 0;
+ vertices[2].ty = 1;
+
+ vertices[3].tx = 1;
+ vertices[3].ty = 1;
+
+ vertices += 4;
}
- groupShuffle(m_resizePendingSimple, m_defaultSimple);
- break;
- }
- m_resizePending = true;
-}
-void QSGImageParticle::performPendingResize()
-{
- m_resizePending = false;
- if(!m_node)
- return;
- UltraVertices tmp1[m_count];//###More vast memcpys that will decrease performance
- SimpleVertices tmp2[m_count];//###More vast memcpys that will decrease performance
- switch(perfLevel){
- case Sprites:
- case Coloured:
- case Deformable:
- case Tabled:
- Q_ASSERT(m_resizePendingUltra.size() == m_count);//XXX
- for(int i=0; i<m_count; i++){
- Q_ASSERT(m_resizePendingUltra[i]);
- tmp1[i] = *m_resizePendingUltra[i];
+ quint16 *indices = g->indexDataAsUShort();
+ for (int i=0; i < count; ++i) {
+ int o = i * 4;
+ indices[0] = o;
+ indices[1] = o + 1;
+ indices[2] = o + 2;
+ indices[3] = o + 1;
+ indices[4] = o + 3;
+ indices[5] = o + 2;
+ indices += 6;
}
- m_node->setFlag(QSGNode::OwnsGeometry, false);
- m_node->geometry()->allocate(m_count*4, m_count*6);
- memcpy(m_node->geometry()->vertexData(), tmp1, sizeof(UltraVertices) * m_count);
- m_node->setFlag(QSGNode::OwnsGeometry, true);
- break;
- case Simple:
- Q_ASSERT(m_resizePendingSimple.size() == m_count);//XXX
- for(int i=0; i<m_count; i++)
- tmp2[i] = *m_resizePendingSimple[i];
- m_node->setFlag(QSGNode::OwnsGeometry, false);
- m_node->geometry()->allocate(m_count*4, m_count*6);
- memcpy(m_node->geometry()->vertexData(), tmp2, sizeof(SimpleVertices) * m_count);
- m_node->setFlag(QSGNode::OwnsGeometry, true);
- break;
+
}
- quint16 *indices = m_node->geometry()->indexDataAsUShort();
- for (int i=0; i<m_count; ++i) {
- int o = i * 4;
- indices[0] = o;
- indices[1] = o + 1;
- indices[2] = o + 2;
- indices[3] = o + 1;
- indices[4] = o + 3;
- indices[5] = o + 2;
- indices += 6;
+
+ foreach (QSGGeometryNode* node, m_nodes){
+ if (node == *(m_nodes.begin()))
+ continue;
+ (*(m_nodes.begin()))->appendChildNode(node);
}
- m_node->setFlag(QSGNode::OwnsGeometry, true);
+
+ return *(m_nodes.begin());
}
QSGNode *QSGImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
{
- if(m_pleaseReset){
- if(m_node){
- if(perfLevel == 1){
- qDebug() << "Beta";
- m_lastCount = m_node->geometry()->vertexCount() / 4;
- m_lastData = qMalloc(m_lastCount*sizeof(SimpleVertices));
- memcpy(m_lastData, m_node->geometry()->vertexData(), m_lastCount * sizeof(SimpleVertices));//TODO: Multiple levels
- }
- m_lastLevel = perfLevel;
- delete m_node;
- }
- if(m_material)
- delete m_material;
+ if (m_pleaseReset){
+ m_lastLevel = perfLevel;
+
+ delete m_rootNode;//Automatically deletes children
+ m_rootNode = 0;
+ m_nodes.clear();
- m_node = 0;
+ m_idxStarts.clear();
+ m_lastIdxStart = 0;
+
+ if (m_material)
+ delete m_material;
m_material = 0;
+
m_pleaseReset = false;
}
- if(m_resizePending)
- performPendingResize();
- if(m_system && m_system->isRunning())
+ if (m_system && m_system->isRunning())
prepareNextFrame();
- if (m_node){
+ if (m_rootNode){
update();
- m_node->markDirty(QSGNode::DirtyMaterial);
+ //### Should I be using dirty geometry too/instead?
+ foreach (QSGGeometryNode* node, m_nodes)
+ node->markDirty(QSGNode::DirtyMaterial);
}
- return m_node;
+ return m_rootNode;
}
void QSGImageParticle::prepareNextFrame()
{
- if (m_node == 0){ //TODO: Staggered loading (as emitted)
- m_node = buildParticleNode();
- if(m_node == 0)
+ if (m_rootNode == 0){//TODO: Staggered loading (as emitted)
+ m_rootNode = buildParticleNodes();
+ if (m_rootNode == 0)
return;
- qDebug() << "Feature level: " << perfLevel;
+ //qDebug() << "Feature level: " << perfLevel;
}
qint64 timeStamp = m_system->systemSync(this);
m_material->timestamp = time;
//Advance State
- if(m_spriteEngine){//perfLevel == Sprites?
+ if (m_spriteEngine){//perfLevel == Sprites?//TODO: use signals?
+
m_material->animcount = m_spriteEngine->spriteCount();
- UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData();
m_spriteEngine->updateSprites(timeStamp);
- for(int i=0; i<m_count; i++){
- UltraVertices &p = particles[i];
- int curIdx = m_spriteEngine->spriteState(i);
- if(curIdx != p.v1.animIdx){
- p.v1.animIdx = p.v2.animIdx = p.v3.animIdx = p.v4.animIdx = curIdx;
- p.v1.animT = p.v2.animT = p.v3.animT = p.v4.animT = m_spriteEngine->spriteStart(i)/1000.0;
- p.v1.frameCount = p.v2.frameCount = p.v3.frameCount = p.v4.frameCount = m_spriteEngine->spriteFrames(i);
- p.v1.frameDuration = p.v2.frameDuration = p.v3.frameDuration = p.v4.frameDuration = m_spriteEngine->spriteDuration(i);
+ foreach (const QString &str, m_particles){
+ int gIdx = m_system->m_groupIds[str];
+ int count = m_system->m_groupData[gIdx]->size();
+
+ UltraVertices *particles = (UltraVertices *) m_nodes[gIdx]->geometry()->vertexData();
+ for (int i=0; i < count; i++){
+ int spriteIdx = m_idxStarts[gIdx] + i;
+ UltraVertices &p = particles[i];
+ int curIdx = m_spriteEngine->spriteState(spriteIdx);
+ if (curIdx != p.v1.animIdx){
+ p.v1.animIdx = p.v2.animIdx = p.v3.animIdx = p.v4.animIdx = curIdx;
+ 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);
+ }
}
}
}else{
}
}
-template <typename VT>
-IntermediateVertices* transplant(IntermediateVertices* iv, VT &v)
-{//Deliberate typemangling cast
- iv->v1 = (UltraVertex*)&(v.v1);
- iv->v2 = (UltraVertex*)&(v.v2);
- iv->v3 = (UltraVertex*)&(v.v3);
- iv->v4 = (UltraVertex*)&(v.v4);
- return iv;
-}
-
-IntermediateVertices* QSGImageParticle::fetchIntermediateVertices(int pos)
-{
- //Note that this class ruins typesafety for you. Maybe even thread safety.
- //TODO: Something better, possibly with templates or inheritance
- static IntermediateVertices iv;
- SimpleVertices *sv;
- UltraVertices *uv;
- switch(perfLevel){
- case Simple:
- sv = (SimpleVertices *) m_node->geometry()->vertexData();
- return transplant(&iv, sv[pos]);
- case Coloured:
- case Deformable:
- case Tabled:
- case Sprites:
- default:
- uv = (UltraVertices *) m_node->geometry()->vertexData();
- return transplant(&iv,uv[pos]);
- }
-}
-
void QSGImageParticle::reloadColor(const Color4ub &c, QSGParticleData* d)
{
- UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData();
- int pos = particleTypeIndex(d);
- UltraVertices &p = particles[pos];
- p.v1.color = p.v2.color = p.v3.color = p.v4.color = c;
-}
-
-void QSGImageParticle::reload(QSGParticleData *d)
-{
- if (m_node == 0)
- return;
-
- int pos = particleTypeIndex(d);
- IntermediateVertices* p = fetchIntermediateVertices(pos);
-
- //Perhaps we could be more efficient?
- vertexCopy(*p->v1, d->pv);
- vertexCopy(*p->v2, d->pv);
- vertexCopy(*p->v3, d->pv);
- vertexCopy(*p->v4, d->pv);
+ d->color = c;
+ //TODO: get index for reload - or make function take an index
}
-void QSGImageParticle::load(QSGParticleData *d)
+void QSGImageParticle::initialize(int gIdx, int pIdx)
{
- if (m_node == 0)
- return;
-
- int pos = particleTypeIndex(d);
- IntermediateVertices* p = fetchIntermediateVertices(pos);//Remember this removes typesafety!
Color4ub color;
+ QSGParticleData* datum = m_system->m_groupData[gIdx]->data[pIdx];
qreal redVariation = m_color_variation + m_redVariation;
qreal greenVariation = m_color_variation + m_greenVariation;
qreal blueVariation = m_color_variation + m_blueVariation;
- switch(perfLevel){//Fall-through is intended on all of them
+ int spriteIdx = m_idxStarts[gIdx] + datum->index;
+ switch (perfLevel){//Fall-through is intended on all of them
case Sprites:
// Initial Sprite State
- p->v1->animT = p->v2->animT = p->v3->animT = p->v4->animT = p->v1->t;
- p->v1->animIdx = p->v2->animIdx = p->v3->animIdx = p->v4->animIdx = 0;
- if(m_spriteEngine){
- m_spriteEngine->startSprite(pos);
- p->v1->frameCount = p->v2->frameCount = p->v3->frameCount = p->v4->frameCount = m_spriteEngine->spriteFrames(pos);
- p->v1->frameDuration = p->v2->frameDuration = p->v3->frameDuration = p->v4->frameDuration = m_spriteEngine->spriteDuration(pos);
+ datum->animT = datum->t;
+ datum->animIdx = 0;
+ if (m_spriteEngine){
+ m_spriteEngine->startSprite(spriteIdx);
+ datum->frameCount = m_spriteEngine->spriteFrames(spriteIdx);
+ datum->frameDuration = m_spriteEngine->spriteDuration(spriteIdx);
}else{
- p->v1->frameCount = p->v2->frameCount = p->v3->frameCount = p->v4->frameCount = 1;
- p->v1->frameDuration = p->v2->frameDuration = p->v3->frameDuration = p->v4->frameDuration = 9999;
+ datum->frameCount = 1;
+ datum->frameDuration = 9999;
}
case Tabled:
case Deformable:
//Initial Rotation
- if(m_xVector){
- const QPointF &ret = m_xVector->sample(QPointF(d->pv.x, d->pv.y));
- p->v1->xx = p->v2->xx = p->v3->xx = p->v4->xx = ret.x();
- p->v1->xy = p->v2->xy = p->v3->xy = p->v4->xy = ret.y();
+ if (m_xVector){
+ const QPointF &ret = m_xVector->sample(QPointF(datum->x, datum->y));
+ datum->xx = ret.x();
+ datum->xy = ret.y();
}
- if(m_yVector){
- const QPointF &ret = m_yVector->sample(QPointF(d->pv.x, d->pv.y));
- p->v1->yx = p->v2->yx = p->v3->yx = p->v4->yx = ret.x();
- p->v1->yy = p->v2->yy = p->v3->yy = p->v4->yy = ret.y();
+ if (m_yVector){
+ const QPointF &ret = m_yVector->sample(QPointF(datum->x, datum->y));
+ datum->yx = ret.x();
+ datum->yy = ret.y();
}
- p->v1->rotation = p->v2->rotation = p->v3->rotation = p->v4->rotation =
+ datum->rotation =
(m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV;
- p->v1->rotationSpeed = p->v2->rotationSpeed = p->v3->rotationSpeed = p->v4->rotationSpeed =
+ datum->rotationSpeed =
(m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV;
- p->v1->autoRotate = p->v2->autoRotate = p->v3->autoRotate = p->v4->autoRotate = m_autoRotation?1.0:0.0;
- case Coloured:
+ datum->autoRotate = m_autoRotation?1.0:0.0;
+ case Colored:
//Color initialization
// Particle color
color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation;
color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation;
color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation;
color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation;
- p->v1->color = p->v2->color = p->v3->color = p->v4->color = color;
+ datum->color = color;
default:
break;
}
-
- vertexCopy(*p->v1, d->pv);
- vertexCopy(*p->v2, d->pv);
- vertexCopy(*p->v3, d->pv);
- vertexCopy(*p->v4, d->pv);
}
-/*
-void QSGImageParticle::verticesUpgrade(void *prev, void *next)
+void QSGImageParticle::commit(int gIdx, int pIdx)
{
- PerformanceLevel copyLevel = qMin(perfLevel, m_lastLevel);
- switch(perfLevel){//Intentional fall-through
- case Sprites:
- if(copyLevel >= Sprites)
- case Tabled:
- case Deformable:
- case Coloured:
+ if (m_pleaseReset)
+ return;
+ QSGGeometryNode *node = m_nodes[gIdx];
+ if (!node)
+ return;
+ QSGParticleData* datum = m_system->m_groupData[gIdx]->data[pIdx];
+
+ node->setFlag(QSGNode::OwnsGeometry, false);
+ UltraVertex *ultraVertices = (UltraVertex *) node->geometry()->vertexData();
+ SimpleVertex *simpleVertices = (SimpleVertex *) node->geometry()->vertexData();
+ switch (perfLevel){
+ case Sprites:
+ ultraVertices += pIdx*4;
+ for (int i=0; i<4; i++){
+ ultraVertices[i].x = datum->x - m_systemOffset.x();
+ ultraVertices[i].y = datum->y - m_systemOffset.y();
+ ultraVertices[i].t = datum->t;
+ ultraVertices[i].lifeSpan = datum->lifeSpan;
+ ultraVertices[i].size = datum->size;
+ ultraVertices[i].endSize = datum->endSize;
+ ultraVertices[i].sx = datum->sx;
+ ultraVertices[i].sy = datum->sy;
+ ultraVertices[i].ax = datum->ax;
+ ultraVertices[i].ay = datum->ay;
+ ultraVertices[i].xx = datum->xx;
+ ultraVertices[i].xy = datum->xy;
+ ultraVertices[i].yx = datum->yx;
+ ultraVertices[i].yy = datum->yy;
+ ultraVertices[i].rotation = datum->rotation;
+ ultraVertices[i].rotationSpeed = datum->rotationSpeed;
+ ultraVertices[i].autoRotate = datum->autoRotate;
+ ultraVertices[i].animIdx = datum->animIdx;
+ ultraVertices[i].frameDuration = datum->frameDuration;
+ ultraVertices[i].frameCount = datum->frameCount;
+ ultraVertices[i].animT = datum->animT;
+ ultraVertices[i].color.r = datum->color.r;
+ ultraVertices[i].color.g = datum->color.g;
+ ultraVertices[i].color.b = datum->color.b;
+ ultraVertices[i].color.a = datum->color.a;
+ }
+ break;
+ case Tabled://TODO: Us
+ case Deformable:
+ case Colored:
+ case Simple:
+ simpleVertices += pIdx*4;
+ for (int i=0; i<4; i++){
+ simpleVertices[i].x = datum->x - m_systemOffset.x();
+ simpleVertices[i].y = datum->y - m_systemOffset.y();
+ simpleVertices[i].t = datum->t;
+ simpleVertices[i].lifeSpan = datum->lifeSpan;
+ simpleVertices[i].size = datum->size;
+ simpleVertices[i].endSize = datum->endSize;
+ simpleVertices[i].sx = datum->sx;
+ simpleVertices[i].sy = datum->sy;
+ simpleVertices[i].ax = datum->ax;
+ simpleVertices[i].ay = datum->ay;
+ }
+ break;
+ default:
+ break;
}
+ node->setFlag(QSGNode::OwnsGeometry, true);
}
-*/
+
QT_END_NAMESPACE