From: Alan Alpert Date: Mon, 19 Sep 2011 05:27:49 +0000 (+1000) Subject: Initial ImageParticle sharing X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=c3a78d52c6edad42f05b4474c495f7201a902dca;p=konrad%2Fqtdeclarative.git Initial ImageParticle sharing This allows particles rendered by ImageParticle to share some of their randomly generated state. Still to come are reset methods and animData sharing (so animations can look synced) Change-Id: Ia805e1b3735b15fba7bd14778ed7abd795b11f06 Reviewed-on: http://codereview.qt-project.org/5114 Reviewed-by: Qt Sanity Bot Reviewed-by: Martin Jones --- diff --git a/examples/declarative/particles/imageparticle/sharing.qml b/examples/declarative/particles/imageparticle/sharing.qml new file mode 100644 index 0000000..621f672 --- /dev/null +++ b/examples/declarative/particles/imageparticle/sharing.qml @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// This example shows how to create your own highlight delegate for a ListView +// that uses a SpringAnimation to provide custom movement when the +// highlight bar is moved between items. + +import QtQuick 2.0 +import QtQuick.Particles 2.0 + +Rectangle { + property real delegateHeight: 65 + width: 200; height: 300 + gradient: Gradient { + GradientStop { position: 0.0; color: "#EEEEFF" } + GradientStop { position: 1.0; color: "lightblue" } + } + + // Define a delegate component. A component will be + // instantiated for each visible item in the list. + Component { + id: petDelegate + Item { + id: wrapper + width: 200; height: delegateHeight + z: 10 + Column { + Text {color: "white"; text: name; font.pixelSize: 18 } + Text {color: "white"; text: 'Type: ' + type; font.pixelSize: 14 } + Text {color: "white"; text: 'Age: ' + age; font.pixelSize: 14 } + } + // indent the item if it is the current item + states: State { + name: "Current" + when: wrapper.ListView.isCurrentItem + PropertyChanges { target: wrapper; x: 20 } + } + transitions: Transition { + NumberAnimation { properties: "x"; duration: 200 } + } + } + } + + // Define a highlight with customised movement between items. + Component { + id: highlightBar + Rectangle { + z: 0 + width: 200; height: delegateHeight + gradient: Gradient { + GradientStop { position: 0.0; color: "#99FF99" } + GradientStop { position: 1.0; color: "#88FF88" } + } + y: listView.currentItem.y; + Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } } + ImageParticle { + anchors.fill: parent + system: particles + source: "../images/flower.png" + color: "red" + clip: true + alpha: 1.0 + } + } + } + ListView { + id: listView + width: 200; height: parent.height + + model: petsModel + delegate: petDelegate + focus: true + + // Set the highlight delegate. Note we must also set highlightFollowsCurrentItem + // to false so the highlight delegate can control how the highlight is moved. + highlight: highlightBar + highlightFollowsCurrentItem: false + + ParticleSystem { id: particles } + Emitter { + system: particles + anchors.fill: parent + emitRate: 1 + lifeSpan: 10000 + size: 24 + sizeVariation: 8 + speed: AngleDirection{ angleVariation: 360; magnitude: 3 } + maximumEmitted: 10 + startTime: 5000 + } + + ImageParticle { + anchors.fill: parent + system: particles + source: "../images/flower.png" + alpha: 0.1 + color: "white" + opacityTable: "opacity.png" + rotationVariation: 180 + z: -1 + } + } + + ListModel { + id: petsModel + ListElement { + name: "Polly" + type: "Parrot" + age: 12 + size: "Small" + } + ListElement { + name: "Penny" + type: "Turtle" + age: 4 + size: "Small" + } + ListElement { + name: "Warren" + type: "Rabbit" + age: 2 + size: "Small" + } + ListElement { + name: "Spot" + type: "Dog" + age: 9 + size: "Medium" + } + ListElement { + name: "Schrödinger" + type: "Cat" + age: 2 + size: "Medium" + } + ListElement { + name: "Joey" + type: "Kangaroo" + age: 1 + size: "Medium" + } + ListElement { + name: "Kimba" + type: "Bunny" + age: 65 + size: "Large" + } + ListElement { + name: "Rover" + type: "Dog" + age: 5 + size: "Large" + } + ListElement { + name: "Tiny" + type: "Elephant" + age: 15 + size: "Large" + } + } + +} diff --git a/examples/declarative/particles/images/flower.png b/examples/declarative/particles/images/flower.png new file mode 100644 index 0000000..b5c6062 Binary files /dev/null and b/examples/declarative/particles/images/flower.png differ diff --git a/src/declarative/particles/qsgimageparticle.cpp b/src/declarative/particles/qsgimageparticle.cpp index ea1bf38..a4b1b47 100644 --- a/src/declarative/particles/qsgimageparticle.cpp +++ b/src/declarative/particles/qsgimageparticle.cpp @@ -446,10 +446,20 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size) \brief The ImageParticle element visualizes logical particles using an image This element renders a logical particle as an image. The image can be - - colorized - - rotated - - deformed - - a sprite-based animation + \list + \o colorized + \o rotated + \o deformed + \o a sprite-based animation + \endlist + + ImageParticles implictly share data on particles if multiple ImageParticles are painting + the same logical particle group. This is broken down along the four capabilities listed + above. So if one ImageParticle defines data for rendering the particles in one of those + capabilities, and the other does not, then both will draw the particles the same in that + aspect automatically. This is primarily useful when there is some random variation on + the particle which is supposed to stay with it when switching painters. If both ImageParticles + define how they should appear for that aspect, they diverge and each appears as it is defined. */ /*! \qmlproperty url QtQuick.Particles2::ImageParticle::source @@ -635,6 +645,10 @@ QSGImageParticle::QSGImageParticle(QSGItem* parent) , m_xVector(0) , m_yVector(0) , m_spriteEngine(0) + , m_explicitColor(false) + , m_explicitRotation(false) + , m_explicitDeformation(false) + , m_explicitAnimation(false) , m_bloat(false) , perfLevel(Unknown) , m_lastLevel(Unknown) @@ -698,6 +712,7 @@ void QSGImageParticle::setColor(const QColor &color) return; m_color = color; emit colorChanged(); + m_explicitColor = true; if (perfLevel < Colored) reset(); } @@ -708,6 +723,7 @@ void QSGImageParticle::setColorVariation(qreal var) return; m_color_variation = var; emit colorVariationChanged(); + m_explicitColor = true; if (perfLevel < Colored) reset(); } @@ -718,6 +734,7 @@ void QSGImageParticle::setAlphaVariation(qreal arg) m_alphaVariation = arg; emit alphaVariationChanged(arg); } + m_explicitColor = true; if (perfLevel < Colored) reset(); } @@ -728,6 +745,7 @@ void QSGImageParticle::setAlpha(qreal arg) m_alpha = arg; emit alphaChanged(arg); } + m_explicitColor = true; if (perfLevel < Colored) reset(); } @@ -738,6 +756,7 @@ void QSGImageParticle::setRedVariation(qreal arg) m_redVariation = arg; emit redVariationChanged(arg); } + m_explicitColor = true; if (perfLevel < Colored) reset(); } @@ -748,6 +767,7 @@ void QSGImageParticle::setGreenVariation(qreal arg) m_greenVariation = arg; emit greenVariationChanged(arg); } + m_explicitColor = true; if (perfLevel < Colored) reset(); } @@ -758,6 +778,7 @@ void QSGImageParticle::setBlueVariation(qreal arg) m_blueVariation = arg; emit blueVariationChanged(arg); } + m_explicitColor = true; if (perfLevel < Colored) reset(); } @@ -768,6 +789,7 @@ void QSGImageParticle::setRotation(qreal arg) m_rotation = arg; emit rotationChanged(arg); } + m_explicitRotation = true; if (perfLevel < Deformable) reset(); } @@ -778,6 +800,7 @@ void QSGImageParticle::setRotationVariation(qreal arg) m_rotationVariation = arg; emit rotationVariationChanged(arg); } + m_explicitRotation = true; if (perfLevel < Deformable) reset(); } @@ -788,6 +811,7 @@ void QSGImageParticle::setRotationSpeed(qreal arg) m_rotationSpeed = arg; emit rotationSpeedChanged(arg); } + m_explicitRotation = true; if (perfLevel < Deformable) reset(); } @@ -798,6 +822,7 @@ void QSGImageParticle::setRotationSpeedVariation(qreal arg) m_rotationSpeedVariation = arg; emit rotationSpeedVariationChanged(arg); } + m_explicitRotation = true; if (perfLevel < Deformable) reset(); } @@ -808,6 +833,7 @@ void QSGImageParticle::setAutoRotation(bool arg) m_autoRotation = arg; emit autoRotationChanged(arg); } + m_explicitRotation = true; if (perfLevel < Deformable) reset(); } @@ -818,6 +844,7 @@ void QSGImageParticle::setXVector(QSGDirection* arg) m_xVector = arg; emit xVectorChanged(arg); } + m_explicitDeformation = true; if (perfLevel < Deformable) reset(); } @@ -828,6 +855,7 @@ void QSGImageParticle::setYVector(QSGDirection* arg) m_yVector = arg; emit yVectorChanged(arg); } + m_explicitDeformation = true; if (perfLevel < Deformable) reset(); } @@ -867,6 +895,7 @@ void QSGImageParticle::createEngine() m_spriteEngine = new QSGSpriteEngine(m_sprites, this); else m_spriteEngine = 0; + m_explicitAnimation = true; reset(); } @@ -932,6 +961,32 @@ static QSGGeometry::AttributeSet SpriteParticle_AttributeSet = SpriteParticle_Attributes }; +void QSGImageParticle::clearShadows() +{ + m_shadowInit = false; + foreach (const QVector data, m_shadowData) + qDeleteAll(data); + m_shadowData.clear(); +} + +//Only call if you need to, may initialize the whole array first time +QSGParticleData* QSGImageParticle::getShadowDatum(QSGParticleData* datum) +{ + QSGParticleGroupData* gd = m_system->m_groupData[datum->group]; + if (!m_shadowData.contains(datum->group)) { + QVector data; + for (int i=0; isize(); i++){ + QSGParticleData* datum = new QSGParticleData(m_system); + *datum = *(gd->data[i]); + data << datum; + } + m_shadowData.insert(datum->group, data); + } + //### If dynamic resize is added, remember to potentially resize the shadow data on out-of-bounds access request + + return m_shadowData[datum->group][datum->index]; +} + QSGGeometryNode* QSGImageParticle::buildParticleNodes() { #ifdef QT_OPENGL_ES_2 @@ -959,6 +1014,25 @@ QSGGeometryNode* QSGImageParticle::buildParticleNodes() perfLevel = Simple; } + foreach (const QString &str, m_groups){//For sharing higher levels, need to have highest used so it renders + int gIdx = m_system->m_groupIds[str]; + foreach (QSGParticlePainter* p, m_system->m_groupData[gIdx]->painters){ + QSGImageParticle* other = qobject_cast(p); + if (other){ + if (other->perfLevel > perfLevel) { + if (other->perfLevel >= Tabled){//Deformable is the highest level needed for this, anything higher isn't shared (or requires your own sprite) + if (perfLevel < Deformable) + perfLevel = Deformable; + } else { + perfLevel = other->perfLevel; + } + } else if (other->perfLevel < perfLevel) { + other->reset(); + } + } + } + } + if (perfLevel >= Colored && !m_color.isValid()) m_color = QColor(Qt::white);//Hidden default, but different from unset @@ -979,7 +1053,7 @@ QSGGeometryNode* QSGImageParticle::buildParticleNodes() } } - + clearShadows(); if (m_material) { delete m_material; m_material = 0; @@ -1193,6 +1267,9 @@ void QSGImageParticle::initialize(int gIdx, int pIdx) qreal greenVariation = m_color_variation + m_greenVariation; qreal blueVariation = m_color_variation + m_blueVariation; int spriteIdx = m_idxStarts[gIdx] + datum->index; + float rotation; + float rotationSpeed; + float autoRotate; switch (perfLevel){//Fall-through is intended on all of them case Sprites: // Initial Sprite State @@ -1209,29 +1286,64 @@ void QSGImageParticle::initialize(int gIdx, int pIdx) case Tabled: case Deformable: //Initial Rotation - if (m_xVector){ - const QPointF &ret = m_xVector->sample(QPointF(datum->x, datum->y)); - datum->xx = ret.x(); - datum->xy = ret.y(); + if (m_explicitDeformation){ + if (!datum->deformationOwner) + datum->deformationOwner = this; + if (m_xVector){ + const QPointF &ret = m_xVector->sample(QPointF(datum->x, datum->y)); + if (datum->deformationOwner == this) { + datum->xx = ret.x(); + datum->xy = ret.y(); + } else { + getShadowDatum(datum)->xx = ret.x(); + getShadowDatum(datum)->xy = ret.y(); + } + } + if (m_yVector){ + const QPointF &ret = m_yVector->sample(QPointF(datum->x, datum->y)); + if (datum->deformationOwner == this) { + datum->yx = ret.x(); + datum->yy = ret.y(); + } else { + getShadowDatum(datum)->yx = ret.x(); + getShadowDatum(datum)->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(); + + if (m_explicitRotation){ + if (!datum->rotationOwner) + datum->rotationOwner = this; + rotation = + (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV; + rotationSpeed = + (m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV; + autoRotate = m_autoRotation?1.0:0.0; + if (datum->rotationOwner == this) { + datum->rotation = rotation; + datum->rotationSpeed = rotationSpeed; + datum->autoRotate = autoRotate; + } else { + getShadowDatum(datum)->rotation = rotation; + getShadowDatum(datum)->rotationSpeed = rotationSpeed; + getShadowDatum(datum)->autoRotate = autoRotate; + } } - datum->rotation = - (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV; - datum->rotationSpeed = - (m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV; - 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; - datum->color = color; + if (m_explicitColor) { + if (!datum->colorOwner) + datum->colorOwner = this; + 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; + if (datum->colorOwner == this) + datum->color = color; + else + getShadowDatum(datum)->color = color; + } default: break; } @@ -1264,21 +1376,52 @@ void QSGImageParticle::commit(int gIdx, int pIdx) spriteVertices[i].vy = datum->vy; spriteVertices[i].ax = datum->ax; spriteVertices[i].ay = datum->ay; - spriteVertices[i].xx = datum->xx; - spriteVertices[i].xy = datum->xy; - spriteVertices[i].yx = datum->yx; - spriteVertices[i].yy = datum->yy; - spriteVertices[i].rotation = datum->rotation; - spriteVertices[i].rotationSpeed = datum->rotationSpeed; - spriteVertices[i].autoRotate = datum->autoRotate; - spriteVertices[i].animIdx = datum->animIdx; - spriteVertices[i].frameDuration = datum->frameDuration; - spriteVertices[i].frameCount = datum->frameCount; - spriteVertices[i].animT = datum->animT; - spriteVertices[i].color.r = datum->color.r; - spriteVertices[i].color.g = datum->color.g; - spriteVertices[i].color.b = datum->color.b; - spriteVertices[i].color.a = datum->color.a; + if (m_explicitDeformation && datum->deformationOwner != this) { + QSGParticleData* shadow = getShadowDatum(datum); + spriteVertices[i].xx = shadow->xx; + spriteVertices[i].xy = shadow->xy; + spriteVertices[i].yx = shadow->yx; + spriteVertices[i].yy = shadow->yy; + } else { + spriteVertices[i].xx = datum->xx; + spriteVertices[i].xy = datum->xy; + spriteVertices[i].yx = datum->yx; + spriteVertices[i].yy = datum->yy; + } + if (m_explicitRotation && datum->rotationOwner != this) { + QSGParticleData* shadow = getShadowDatum(datum); + spriteVertices[i].rotation = shadow->rotation; + spriteVertices[i].rotationSpeed = shadow->rotationSpeed; + spriteVertices[i].autoRotate = shadow->autoRotate; + } else { + spriteVertices[i].rotation = datum->rotation; + spriteVertices[i].rotationSpeed = datum->rotationSpeed; + spriteVertices[i].autoRotate = datum->autoRotate; + } + if (m_explicitAnimation && datum->animationOwner != this) { + QSGParticleData* shadow = getShadowDatum(datum); + spriteVertices[i].animIdx = shadow->animIdx; + spriteVertices[i].frameDuration = shadow->frameDuration; + spriteVertices[i].frameCount = shadow->frameCount; + spriteVertices[i].animT = shadow->animT; + } else { + spriteVertices[i].animIdx = datum->animIdx; + spriteVertices[i].frameDuration = datum->frameDuration; + spriteVertices[i].frameCount = datum->frameCount; + spriteVertices[i].animT = datum->animT; + } + if (m_explicitColor && datum->colorOwner != this) { + QSGParticleData* shadow = getShadowDatum(datum); + spriteVertices[i].color.r = shadow->color.r; + spriteVertices[i].color.g = shadow->color.g; + spriteVertices[i].color.b = shadow->color.b; + spriteVertices[i].color.a = shadow->color.a; + } else { + spriteVertices[i].color.r = datum->color.r; + spriteVertices[i].color.g = datum->color.g; + spriteVertices[i].color.b = datum->color.b; + spriteVertices[i].color.a = datum->color.a; + } } break; case Tabled: //Fall through until it has its own vertex class @@ -1295,17 +1438,40 @@ void QSGImageParticle::commit(int gIdx, int pIdx) deformableVertices[i].vy = datum->vy; deformableVertices[i].ax = datum->ax; deformableVertices[i].ay = datum->ay; - deformableVertices[i].xx = datum->xx; - deformableVertices[i].xy = datum->xy; - deformableVertices[i].yx = datum->yx; - deformableVertices[i].yy = datum->yy; - deformableVertices[i].rotation = datum->rotation; - deformableVertices[i].rotationSpeed = datum->rotationSpeed; - deformableVertices[i].autoRotate = datum->autoRotate; - deformableVertices[i].color.r = datum->color.r; - deformableVertices[i].color.g = datum->color.g; - deformableVertices[i].color.b = datum->color.b; - deformableVertices[i].color.a = datum->color.a; + if (m_explicitDeformation && datum->deformationOwner != this) { + QSGParticleData* shadow = getShadowDatum(datum); + deformableVertices[i].xx = shadow->xx; + deformableVertices[i].xy = shadow->xy; + deformableVertices[i].yx = shadow->yx; + deformableVertices[i].yy = shadow->yy; + } else { + deformableVertices[i].xx = datum->xx; + deformableVertices[i].xy = datum->xy; + deformableVertices[i].yx = datum->yx; + deformableVertices[i].yy = datum->yy; + } + if (m_explicitRotation && datum->rotationOwner != this) { + QSGParticleData* shadow = getShadowDatum(datum); + deformableVertices[i].rotation = shadow->rotation; + deformableVertices[i].rotationSpeed = shadow->rotationSpeed; + deformableVertices[i].autoRotate = shadow->autoRotate; + } else { + deformableVertices[i].rotation = datum->rotation; + deformableVertices[i].rotationSpeed = datum->rotationSpeed; + deformableVertices[i].autoRotate = datum->autoRotate; + } + if (m_explicitColor && datum->colorOwner != this) { + QSGParticleData* shadow = getShadowDatum(datum); + deformableVertices[i].color.r = shadow->color.r; + deformableVertices[i].color.g = shadow->color.g; + deformableVertices[i].color.b = shadow->color.b; + deformableVertices[i].color.a = shadow->color.a; + } else { + deformableVertices[i].color.r = datum->color.r; + deformableVertices[i].color.g = datum->color.g; + deformableVertices[i].color.b = datum->color.b; + deformableVertices[i].color.a = datum->color.a; + } } break; case Colored: @@ -1321,10 +1487,18 @@ void QSGImageParticle::commit(int gIdx, int pIdx) coloredVertices[i].vy = datum->vy; coloredVertices[i].ax = datum->ax; coloredVertices[i].ay = datum->ay; - coloredVertices[i].color.r = datum->color.r; - coloredVertices[i].color.g = datum->color.g; - coloredVertices[i].color.b = datum->color.b; - coloredVertices[i].color.a = datum->color.a; + if (m_explicitColor && datum->colorOwner != this) { + QSGParticleData* shadow = getShadowDatum(datum); + coloredVertices[i].color.r = shadow->color.r; + coloredVertices[i].color.g = shadow->color.g; + coloredVertices[i].color.b = shadow->color.b; + coloredVertices[i].color.a = shadow->color.a; + } else { + coloredVertices[i].color.r = datum->color.r; + coloredVertices[i].color.g = datum->color.g; + coloredVertices[i].color.b = datum->color.b; + coloredVertices[i].color.a = datum->color.a; + } } break; case Simple: diff --git a/src/declarative/particles/qsgimageparticle_p.h b/src/declarative/particles/qsgimageparticle_p.h index d40be5d..4225829 100644 --- a/src/declarative/particles/qsgimageparticle_p.h +++ b/src/declarative/particles/qsgimageparticle_p.h @@ -371,6 +371,16 @@ private: QList m_sprites; QSGSpriteEngine* m_spriteEngine; + //TODO: Reset methods + bool m_explicitColor; + bool m_explicitRotation; + bool m_explicitDeformation; + bool m_explicitAnimation;//TODO: Implement this + QHash > m_shadowData; + bool m_shadowInit; + void clearShadows(); + QSGParticleData* getShadowDatum(QSGParticleData* datum); + bool m_bloat; PerformanceLevel perfLevel; diff --git a/src/declarative/particles/qsgparticlesystem.cpp b/src/declarative/particles/qsgparticlesystem.cpp index 7d70c3b..26c6d05 100644 --- a/src/declarative/particles/qsgparticlesystem.cpp +++ b/src/declarative/particles/qsgparticlesystem.cpp @@ -389,6 +389,10 @@ QSGParticleData::QSGParticleData(QSGParticleSystem* sys) , index(0) , systemIndex(-1) , v8Datum(0) + , colorOwner(0) + , rotationOwner(0) + , deformationOwner(0) + , animationOwner(0) { x = 0; y = 0; @@ -450,6 +454,11 @@ void QSGParticleData::clone(const QSGParticleData& other) r = other.r; delegate = other.delegate; modelIndex = other.modelIndex; + + colorOwner = other.colorOwner; + rotationOwner = other.rotationOwner; + deformationOwner = other.deformationOwner; + animationOwner = other.animationOwner; } QDeclarativeV8Handle QSGParticleData::v8Value() diff --git a/src/declarative/particles/qsgparticlesystem_p.h b/src/declarative/particles/qsgparticlesystem_p.h index f531e7f..d17a46f 100644 --- a/src/declarative/particles/qsgparticlesystem_p.h +++ b/src/declarative/particles/qsgparticlesystem_p.h @@ -69,6 +69,7 @@ class QSGStochasticEngine; class QSGSprite; class QSGV8ParticleData; class QSGParticleGroup; +class QSGImageParticle; struct QSGParticleDataHeapNode{ int time;//in ms @@ -207,6 +208,12 @@ public: int modelIndex; float update;//Used by custom affectors + //Used by image particle + QSGImageParticle* colorOwner; + QSGImageParticle* rotationOwner; + QSGImageParticle* deformationOwner; + QSGImageParticle* animationOwner; + void debugDump(); bool stillAlive(); float lifeLeft();