diff --git a/examples/declarative/animation/basics/color-animation.qml b/examples/declarative/animation/basics/color-animation.qml index a83dbab5697d19f38fd6aa08d1438a0c2b3219fa..9e0f29c4ecbd6287356f3bb19f18fbd635ac90fc 100644 --- a/examples/declarative/animation/basics/color-animation.qml +++ b/examples/declarative/animation/basics/color-animation.qml @@ -86,7 +86,7 @@ Item { width: parent.width; height: parent.height/2 ImageParticle { source: "images/star.png" - particles: ["star"] + groups: ["star"] color: "#00333333" SequentialAnimation on opacity { loops: Animation.Infinite @@ -95,7 +95,7 @@ Item { } } Emitter { - particle: "star" + group: "star" anchors.fill: parent emitRate: parent.width / 50 lifeSpan: 5000 diff --git a/examples/declarative/flickr/flickr.qml b/examples/declarative/flickr/flickr.qml index 14e4fcaedf969812beff897e3ee1d17af0a2ff1a..4397d0ad7651ff04f494b45a7ec74ca3a9b0bab1 100644 --- a/examples/declarative/flickr/flickr.qml +++ b/examples/declarative/flickr/flickr.qml @@ -56,7 +56,7 @@ Item { id: bgParticles anchors.fill: parent ImageParticle { - particles: ["trail"] + groups: ["trail"] source: "content/images/particle.png" color: "#1A1A6F" alpha: 0.1 @@ -64,7 +64,7 @@ Item { blueVariation: 0.8 } Emitter { - particle: "drops" + group: "drops" width: parent.width emitRate: 0.5 lifeSpan: 20000 @@ -75,7 +75,7 @@ Item { } TrailEmitter { follow: "drops" - particle: "trail" + group: "trail" emitRatePerParticle: 18 size: 32 endSize: 0 diff --git a/examples/declarative/minehunt/MinehuntCore/Explosion.qml b/examples/declarative/minehunt/MinehuntCore/Explosion.qml index 225c19d8a34775622a8607c4aa09e513f557805b..af98ad130981569a26235377b5be493c49ec1a66 100644 --- a/examples/declarative/minehunt/MinehuntCore/Explosion.qml +++ b/examples/declarative/minehunt/MinehuntCore/Explosion.qml @@ -48,14 +48,14 @@ Item { width: 40 height: 40 ImageParticle { - particles: ["star"] + groups: ["star"] source: "file:MinehuntCore/pics/star.png" // TODO: Use qrc path once QTBUG-21129 is fixed } Emitter { id: particles emitting: false anchors.centerIn: parent - particle: "star" + group: "star" speed: AngledDirection { angleVariation: 360; magnitude: 150; magnitudeVariation: 50 } emitRate: 200 z: 100 diff --git a/examples/declarative/particles/allsmiles/smilefactory.qml b/examples/declarative/particles/allsmiles/smilefactory.qml index fe651491b9e621093740c64bdfcbe59955d8f483..4b01862f99c54957778dcbe2fe63a06fbc3f8e40 100644 --- a/examples/declarative/particles/allsmiles/smilefactory.qml +++ b/examples/declarative/particles/allsmiles/smilefactory.qml @@ -48,7 +48,7 @@ Rectangle{ ParticleSystem{id:sys} ImageParticle{ system: sys - particles: ["goingLeft", "goingRight"] + groups: ["goingLeft", "goingRight"] source: "content/singlesmile.png" rotation: 90 rotationSpeed: 90 @@ -56,7 +56,7 @@ Rectangle{ } ImageParticle{ system: sys - particles: ["goingDown"] + groups: ["goingDown"] source: "content/squarefacespriteXX.png" yVector: PointDirection{ y: 0.5; yVariation: 0.25; xVariation: 0.25; } rotation: 180 @@ -85,7 +85,7 @@ Rectangle{ y: 120 system: sys enabled: false - particle: "goingRight" + group: "goingRight" speed: PointDirection{ x: 100 } lifeSpan: 4000 emitRate: 2 @@ -97,7 +97,7 @@ Rectangle{ y: 240 system: sys enabled: false - particle: "goingLeft" + group: "goingLeft" speed: PointDirection{ x: -100 } lifeSpan: 4000 emitRate: 2 @@ -109,7 +109,7 @@ Rectangle{ y: 360 system: sys enabled: false - particle: "goingDown" + group: "goingDown" speed: PointDirection{ x: 100 } lifeSpan: 4000 emitRate: 2 diff --git a/examples/declarative/particles/allsmiles/spriteparticles.qml b/examples/declarative/particles/allsmiles/spriteparticles.qml index 705016e05019c8093a68304aa40a23623aa699cc..0586dfd8db3b356c558bf4e8c3d1ff351a3a98ac 100644 --- a/examples/declarative/particles/allsmiles/spriteparticles.qml +++ b/examples/declarative/particles/allsmiles/spriteparticles.qml @@ -47,7 +47,7 @@ Rectangle{ height: 400 ImageParticle{ id: test - particles: ["Test"] + groups: ["Test"] source: "content/particle.png" system: sys z: 2 @@ -57,7 +57,7 @@ Rectangle{ } ImageParticle{ id: single - particles: ["Face"] + groups: ["Face"] system: sys z: 2 anchors.fill: parent @@ -73,7 +73,7 @@ Rectangle{ } Emitter{ system: sys - particle: "Test" + group: "Test" anchors.fill: parent id: particles2 emitRate: 6000 @@ -83,7 +83,7 @@ Rectangle{ } Emitter{ system: sys - particle: "Face" + group: "Face" anchors.fill: parent id: particles emitRate: 60 diff --git a/examples/declarative/particles/asteroid/asteroid.qml b/examples/declarative/particles/asteroid/asteroid.qml index ea2fabd51d5b8426de3e0d13bd62abea0d82c0dc..6d556997c703c22871d90d728f98c13b4e3844d5 100644 --- a/examples/declarative/particles/asteroid/asteroid.qml +++ b/examples/declarative/particles/asteroid/asteroid.qml @@ -67,7 +67,7 @@ Item { } ImageParticle { system: sys - particles: ["starfield"] + groups: ["starfield"] source: "content/star.png" colorVariation: 0.3 color: "white" @@ -75,7 +75,7 @@ Item { Emitter { id: starField system: sys - particle: "starfield" + group: "starfield" emitRate: 80 lifeSpan: 2500 @@ -91,7 +91,7 @@ Item { } Emitter{ system: sys - particle: "meteor" + group: "meteor" emitRate: 12 lifeSpan: 5000 acceleration: PointDirection{ xVariation: 80; yVariation: 80; } @@ -101,7 +101,7 @@ Item { } ImageParticle{ system: sys - particles: ["meteor"] + groups: ["meteor"] sprites:[Sprite{ id: spinState name: "spinning" @@ -126,7 +126,7 @@ Item { ] } SpriteGoal{ - particles: ["meteor"] + groups: ["meteor"] system: sys goalState: "explode" jump: true @@ -170,7 +170,7 @@ Item { ImageParticle{ z:0 system: sys - particles: ["exhaust"] + groups: ["exhaust"] source: "content/particle4.png" color: "orange" @@ -193,7 +193,7 @@ Item { Emitter{ id: trailsNormal2 system: sys - particle: "exhaust" + group: "exhaust" emitRate: 300 lifeSpan: 500 diff --git a/examples/declarative/particles/asteroid/blackhole.qml b/examples/declarative/particles/asteroid/blackhole.qml index 7e8a7a9edcd12b996deb7172a5355488be8fbdb9..00fca7ef3c35fd5580f5e83c7ac079216752af5b 100644 --- a/examples/declarative/particles/asteroid/blackhole.qml +++ b/examples/declarative/particles/asteroid/blackhole.qml @@ -66,7 +66,7 @@ Rectangle{ } Emitter{ - particle: "stars" + group: "stars" system: particles emitRate: 40 lifeSpan: 4000 @@ -77,7 +77,7 @@ Rectangle{ height: parent.height } Emitter{ - particle: "roids" + group: "roids" system: particles emitRate: 10 lifeSpan: 4000 @@ -93,7 +93,7 @@ Rectangle{ } ImageParticle{ id: stars - particles: ["stars"] + groups: ["stars"] system: particles source: "content/star.png" color: "white" @@ -102,7 +102,7 @@ Rectangle{ } ImageParticle{ id: roids - particles: ["roids"] + groups: ["roids"] system: particles sprites: Sprite{ id: spinState @@ -115,7 +115,7 @@ Rectangle{ } ImageParticle{ id: shot - particles: ["shot"] + groups: ["shot"] system: particles source: "content/star.png" @@ -124,7 +124,7 @@ Rectangle{ } ImageParticle{ id: engine - particles: ["engine"] + groups: ["engine"] system: particles source: "content/particle4.png" @@ -170,7 +170,7 @@ Rectangle{ drag.target: ship } Emitter{ - particle: "engine" + group: "engine" system: particles emitRate: 200 lifeSpan: 1000 @@ -182,7 +182,7 @@ Rectangle{ width: 20 } Emitter{ - particle: "shot" + group: "shot" system: particles emitRate: 32 lifeSpan: 2000 diff --git a/examples/declarative/particles/trails/combustion.qml b/examples/declarative/particles/trails/combustion.qml index e4a21e9beb479275e71a9ebf29566f3a31a5a554..238dbe8a79eb74fffa319352d069be559b830782 100644 --- a/examples/declarative/particles/trails/combustion.qml +++ b/examples/declarative/particles/trails/combustion.qml @@ -57,71 +57,67 @@ Rectangle { ParticleSystem{ id: particles anchors.fill: parent + ParticleGroup{ + name: "unlit" + duration: 1000 + to: {"lighting":1, "unlit":99} + ImageParticle{ + source: "content/particleA.png" + colorVariation: 0.1 + color: "#2060160f" + } + SpriteGoal{ + whenCollidingWith: ["lit"] + goalState: "lighting" + jump: true + systemStates: true + } + } + ParticleGroup{ + name: "lighting" + duration: 100 + to: {"lit":1} + } + ParticleGroup{ + name: "lit" + duration: 10000 + onEntered: score++; + TrailEmitter{ + id: fireballFlame + group: "flame" + emitRatePerParticle: 48 + lifeSpan: 200 + emitWidth: 8 + emitHeight: 8 - particleStates:[ - Sprite{ - name: "unlit" - duration: 1000 - to: {"lighting":1, "unlit":99} - ImageParticle{ - source: "content/particleA.png" - colorVariation: 0.1 - color: "#2060160f" - } - SpriteGoal{ - whenCollidingWith: ["lit"] - goalState: "lighting" - jump: true - systemStates: true - } - }, - Sprite{ - name: "lighting" - duration: 100 - to: {"lit":1} - }, - Sprite{ - name: "lit" - duration: 10000 - onEntered: score++; - TrailEmitter{ - id: fireballFlame - particle: "flame" - - emitRatePerParticle: 48 - lifeSpan: 200 - emitWidth: 8 - emitHeight: 8 - - size: 24 - sizeVariation: 8 - endSize: 4 - } + size: 24 + sizeVariation: 8 + endSize: 4 + } - TrailEmitter{ - id: fireballSmoke - particle: "smoke" + TrailEmitter{ + id: fireballSmoke + group: "smoke" - emitRatePerParticle: 120 - lifeSpan: 2000 - emitWidth: 16 - emitHeight: 16 + emitRatePerParticle: 120 + lifeSpan: 2000 + emitWidth: 16 + emitHeight: 16 - speed: PointDirection{yVariation: 16; xVariation: 16} - acceleration: PointDirection{y: -16} + speed: PointDirection{yVariation: 16; xVariation: 16} + acceleration: PointDirection{y: -16} - size: 24 - sizeVariation: 8 - endSize: 8 - } + size: 24 + sizeVariation: 8 + endSize: 8 } - ] + } ImageParticle{ id: smoke anchors.fill: parent - particles: ["smoke"] + groups: ["smoke"] source: "content/particle.png" colorVariation: 0 color: "#00111111" @@ -129,7 +125,7 @@ Rectangle { ImageParticle{ id: pilot anchors.fill: parent - particles: ["pilot"] + groups: ["pilot"] source: "content/particle.png" redVariation: 0.01 blueVariation: 0.4 @@ -138,7 +134,7 @@ Rectangle { ImageParticle{ id: flame anchors.fill: parent - particles: ["flame", "lit", "lighting"] + groups: ["flame", "lit", "lighting"] source: "content/particleA.png" colorVariation: 0.1 color: "#00ff400f" @@ -152,14 +148,14 @@ Rectangle { sizeVariation: 4 speed: PointDirection{x:120; xVariation: 80; yVariation: 50} acceleration: PointDirection{y:120} - particle: "unlit" + group: "unlit" } Emitter{ id: flamer x: 100 y: 300 - particle: "pilot" + group: "pilot" emitRate: 80 lifeSpan: 600 size: 24 @@ -167,7 +163,7 @@ Rectangle { endSize: 0 speed: PointDirection{ y:-100; yVariation: 4; xVariation: 4 } SpriteGoal{ - particles: ["unlit"] + groups: ["unlit"] goalState: "lit" jump: true systemStates: true @@ -181,7 +177,7 @@ Rectangle { } //Click to enflame SpriteGoal{//TODO: Aux emiiters in the state definition (which allows the occasional ball to spontaneously combust) - particles: ["unlit"] + groups: ["unlit"] goalState: "lighting" jump: true systemStates: true diff --git a/examples/declarative/particles/trails/fireballs.qml b/examples/declarative/particles/trails/fireballs.qml index 97a0c0ac5f4a3f86c83359642729df616608e2fa..c7c042004927bf7286439e4e8ed51abddda23225 100644 --- a/examples/declarative/particles/trails/fireballs.qml +++ b/examples/declarative/particles/trails/fireballs.qml @@ -55,7 +55,7 @@ Rectangle { ImageParticle{ id: fireball anchors.fill: parent - particles: ["E"] + groups: ["E"] system: particles source: "content/particleA.png" colorVariation: 0.2 @@ -66,7 +66,7 @@ Rectangle { id: smoke system: particles anchors.fill: parent - particles: ["A", "B"] + groups: ["A", "B"] source: "content/particle.png" colorVariation: 0 color: "#00111111" @@ -75,7 +75,7 @@ Rectangle { id: flame anchors.fill: parent system: particles - particles: ["C", "D"] + groups: ["C", "D"] source: "content/particle.png" colorVariation: 0.1 color: "#00ff400f" @@ -83,7 +83,7 @@ Rectangle { Emitter{ id: fire system: particles - particle: "C" + group: "C" y: parent.height width: parent.width @@ -100,7 +100,7 @@ Rectangle { } TrailEmitter{ id: fireSmoke - particle: "B" + group: "B" system: particles follow: "C" width: root.width @@ -120,7 +120,7 @@ Rectangle { id: fireballFlame anchors.fill: parent system: particles - particle: "D" + group: "D" follow: "E" emitRatePerParticle: 120 @@ -137,7 +137,7 @@ Rectangle { id: fireballSmoke anchors.fill: parent system: particles - particle: "A" + group: "A" follow: "E" emitRatePerParticle: 128 @@ -155,7 +155,7 @@ Rectangle { Emitter{ id: balls system: particles - particle: "E" + group: "E" y: parent.height width: parent.width diff --git a/examples/declarative/particles/trails/fireworks.qml b/examples/declarative/particles/trails/fireworks.qml index 437d9ee3d6bc018326bb9ec526d53ff3758cc203..6b370b3991391216a1e6dec250688a44299891e5 100644 --- a/examples/declarative/particles/trails/fireworks.qml +++ b/examples/declarative/particles/trails/fireworks.qml @@ -48,36 +48,34 @@ Rectangle{ ParticleSystem{ anchors.fill: parent id: syssy - particleStates:[ - Sprite{ - name: "fire" - duration: 2000 - durationVariation: 2000 - to: {"splode":1} - }, - Sprite{ - name: "splode" - duration: 400 - to: {"dead":1} - TrailEmitter{ - particle: "works" - emitRatePerParticle: 100 - lifeSpan: 1000 - maximumEmitted: 1200 - size: 8 - speed: AngleDirection{angle: 270; angleVariation: 45; magnitude: 20; magnitudeVariation: 20;} - acceleration: PointDirection{y:100; yVariation: 20} - } - }, - Sprite{ - name: "dead" - duration: 1000 - Affector{ - once: true - onAffected: worksEmitter.burst(400,x,y) - } + ParticleGroup{ + name: "fire" + duration: 2000 + durationVariation: 2000 + to: {"splode":1} + } + ParticleGroup{ + name: "splode" + duration: 400 + to: {"dead":1} + TrailEmitter{ + group: "works" + emitRatePerParticle: 100 + lifeSpan: 1000 + maximumEmitted: 1200 + size: 8 + speed: AngleDirection{angle: 270; angleVariation: 45; magnitude: 20; magnitudeVariation: 20;} + acceleration: PointDirection{y:100; yVariation: 20} + } + } + ParticleGroup{ + name: "dead" + duration: 1000 + Affector{ + once: true + onAffected: worksEmitter.burst(400,x,y) } - ] + } Timer{ interval: 6000 running: true @@ -87,7 +85,7 @@ Rectangle{ } Emitter{ id: startingEmitter - particle: "fire" + group: "fire" width: parent.width y: parent.height enabled: false @@ -98,7 +96,7 @@ Rectangle{ } Emitter{ id: worksEmitter - particle: "works" + group: "works" enabled: false emitRate: 100 lifeSpan: 1600 @@ -111,7 +109,7 @@ Rectangle{ acceleration: PointDirection{y:100; yVariation: 20} } ImageParticle{ - particles: ["works", "fire", "splode"] + groups: ["works", "fire", "splode"] source: "content/particle.png" entryEffect: ImageParticle.Scale } diff --git a/examples/declarative/particles/trails/portal.qml b/examples/declarative/particles/trails/portal.qml index 85efd9a5941e540288a792e839b8052bd93cdfc9..adf620fd9b58aba44b016c0ae381b4ee8598c109 100644 --- a/examples/declarative/particles/trails/portal.qml +++ b/examples/declarative/particles/trails/portal.qml @@ -54,7 +54,7 @@ Rectangle{ id: particles } ImageParticle{ - particles: ["center","edge"] + groups: ["center","edge"] anchors.fill: parent system: particles source: "content/particle.png" @@ -63,7 +63,7 @@ Rectangle{ } Emitter{ anchors.fill: parent - particle: "center" + group: "center" system: particles emitRate: 200 lifeSpan: 2000 @@ -80,7 +80,7 @@ Rectangle{ } Emitter{ anchors.fill: parent - particle: "edge" + group: "edge" startTime: 2000 system: particles emitRate: 4000 diff --git a/examples/declarative/particles/trails/turbulence.qml b/examples/declarative/particles/trails/turbulence.qml index 104bb10e801fe98f51657e8feef71b40d55c6aeb..13eae162f4c2d36873140e2773f8739547ddaa01 100644 --- a/examples/declarative/particles/trails/turbulence.qml +++ b/examples/declarative/particles/trails/turbulence.qml @@ -71,14 +71,14 @@ Rectangle{ strength: 32 } ImageParticle{ - particles: ["smoke"] + groups: ["smoke"] system: ps source: "content/particle.png" color: "#11111111" colorVariation: 0 } ImageParticle{ - particles: ["flame"] + groups: ["flame"] system: ps source: "content/particle.png" color: "#11ff400f" @@ -87,7 +87,7 @@ Rectangle{ Emitter{ anchors.centerIn: parent system: ps - particle: "flame" + group: "flame" emitRate: 120 lifeSpan: 1200 @@ -102,7 +102,7 @@ Rectangle{ width: root.width height: root.height/2 - 20 system: ps - particle: "smoke" + group: "smoke" follow: "flame" emitRatePerParticle: 1 @@ -119,7 +119,7 @@ Rectangle{ width: root.width height: root.height/2 - 40 system: ps - particle: "smoke" + group: "smoke" follow: "flame" emitRatePerParticle: 4 diff --git a/examples/declarative/plasmapatrol/content/BlasterHardpoint.qml b/examples/declarative/plasmapatrol/content/BlasterHardpoint.qml index 384275fc946459cf14e3842a193edec0e676c80b..3e751f4e15b6a8a00f2f6be3012c345162173f5e 100644 --- a/examples/declarative/plasmapatrol/content/BlasterHardpoint.qml +++ b/examples/declarative/plasmapatrol/content/BlasterHardpoint.qml @@ -55,7 +55,7 @@ Item { height: 24 Emitter{ id: visualization - particle: "blaster" + group: "blaster" system: container.system enabled: show anchors.fill: parent @@ -114,7 +114,7 @@ Item { } Emitter{ id: emitter - particle: "blaster" + group: "blaster" enabled: false system: container.system anchors.centerIn: parent diff --git a/examples/declarative/plasmapatrol/content/CannonHardpoint.qml b/examples/declarative/plasmapatrol/content/CannonHardpoint.qml index b2c7aca1fd18201987407657020ec91d0853c86a..dc15f0cae1946b2741926493b22317ae3abb6b56 100644 --- a/examples/declarative/plasmapatrol/content/CannonHardpoint.qml +++ b/examples/declarative/plasmapatrol/content/CannonHardpoint.qml @@ -51,7 +51,7 @@ Item { height: 24 Emitter{ id: visualization - particle: "cannon" + group: "cannon" enabled: container.show system: container.system anchors.centerIn: parent @@ -80,7 +80,7 @@ Item { } Emitter{ id: emitter - particle: "cannon" + group: "cannon" enabled: false system: container.system anchors.centerIn: parent diff --git a/examples/declarative/plasmapatrol/content/Cruiser.qml b/examples/declarative/plasmapatrol/content/Cruiser.qml index b0d20023db934f1891581422a5a453cb03a807cf..a4983fc2a0184ea03c8cc31e33fbc475dfc77da5 100644 --- a/examples/declarative/plasmapatrol/content/Cruiser.qml +++ b/examples/declarative/plasmapatrol/content/Cruiser.qml @@ -58,7 +58,7 @@ Item { //TODO: Cooler would be an 'orbiting' affector //TODO: On the subject, opacity and size should be grouped type 'overLife' if we can cram that in the particles system: container.system - particle: container.shipParticle + group: container.shipParticle anchors.centerIn: parent width: 64 height: 64 @@ -76,7 +76,7 @@ Item { } Emitter{ system: container.system - particle: "cruiserArmor" + group: "cruiserArmor" anchors.fill: parent shape: EllipseShape{ fill: false } enabled: hp>0 @@ -92,7 +92,7 @@ Item { system: container.system enabled: container.hp <=0 anchors.fill: parent - particles: ["cruiserArmor"] + groups: ["cruiserArmor"] goalState: "death" // jump: true once: true diff --git a/examples/declarative/plasmapatrol/content/Frigate.qml b/examples/declarative/plasmapatrol/content/Frigate.qml index 8d493b81d5d8f66078eda21fb7e52b78938ea7c4..f26e7e881c34242180c00662a1e193a5c49c8772 100644 --- a/examples/declarative/plasmapatrol/content/Frigate.qml +++ b/examples/declarative/plasmapatrol/content/Frigate.qml @@ -56,7 +56,7 @@ Item { height: 128 Emitter{ system: container.system - particle: "frigateShield" + group: "frigateShield" anchors.centerIn: parent size: 92 emitRate: 1 @@ -65,7 +65,7 @@ Item { } Emitter{ system: container.system - particle: container.shipParticle + group: container.shipParticle anchors.centerIn: parent width: 64 height: 16 diff --git a/examples/declarative/plasmapatrol/content/LaserHardpoint.qml b/examples/declarative/plasmapatrol/content/LaserHardpoint.qml index 45712bf68a729f4f9092aed0d4fee764e6b28c33..56fd91b5b3ec94a72009790baf64cdad4df3631a 100644 --- a/examples/declarative/plasmapatrol/content/LaserHardpoint.qml +++ b/examples/declarative/plasmapatrol/content/LaserHardpoint.qml @@ -51,7 +51,7 @@ Item { height: 24 Emitter{ id: visualization - particle: "laser" + group: "laser" system: container.system anchors.fill: parent enabled: container.show @@ -86,7 +86,7 @@ Item { } Emitter{ id: emitter - particle: "laser" + group: "laser" enabled: false system: container.system x: Math.min(container.width/2, target.x); diff --git a/examples/declarative/plasmapatrol/content/PlasmaPatrolParticles.qml b/examples/declarative/plasmapatrol/content/PlasmaPatrolParticles.qml index 792ba7ab72f7537ea8b44ec20442378e48415359..7a8c3e61b31d519e10d735fd896636eb6ad246a6 100644 --- a/examples/declarative/plasmapatrol/content/PlasmaPatrolParticles.qml +++ b/examples/declarative/plasmapatrol/content/PlasmaPatrolParticles.qml @@ -45,7 +45,7 @@ Item{ property ParticleSystem sys ImageParticle{ system: sys - particles: ["default"] + groups: ["default"] source: "pics/blur-circle3.png" color: "#003A3A3A" colorVariation: 0.1 @@ -53,7 +53,7 @@ Item{ } ImageParticle{ system: sys - particles: ["redTeam"] + groups: ["redTeam"] source: "pics/blur-circle3.png" color: "#0028060A" colorVariation: 0.1 @@ -61,7 +61,7 @@ Item{ } ImageParticle{ system: sys - particles: ["greenTeam"] + groups: ["greenTeam"] source: "pics/blur-circle3.png" color: "#0006280A" colorVariation: 0.1 @@ -69,7 +69,7 @@ Item{ } ImageParticle{ system: sys - particles: ["blaster"] + groups: ["blaster"] source: "pics/star2.png" //color: "#0F282406" color: "#0F484416" @@ -78,7 +78,7 @@ Item{ } ImageParticle{ system: sys - particles: ["laser"] + groups: ["laser"] source: "pics/star3.png" //color: "#00123F68" color: "#00428FF8" @@ -87,7 +87,7 @@ Item{ } ImageParticle{ system: sys - particles: ["cannon"] + groups: ["cannon"] source: "pics/particle.png" color: "#80FFAAFF" colorVariation: 0.1 @@ -95,7 +95,7 @@ Item{ } ImageParticle{ system: sys - particles: ["cannonCore"] + groups: ["cannonCore"] source: "pics/particle.png" color: "#00666666" colorVariation: 0.8 @@ -103,7 +103,7 @@ Item{ } ImageParticle{ system: sys - particles: ["cannonWake"] + groups: ["cannonWake"] source: "pics/star.png" color: "#00CCCCCC" colorVariation: 0.2 @@ -111,7 +111,7 @@ Item{ } ImageParticle{ system: sys - particles: ["frigateShield"] + groups: ["frigateShield"] source: "pics/blur-circle2.png" color: "#00000000" colorVariation: 0.05 @@ -121,7 +121,7 @@ Item{ } ImageParticle{ system: sys - particles: ["cruiserArmor"] + groups: ["cruiserArmor"] z: 1 sprites:[Sprite{ id: spinState @@ -146,7 +146,7 @@ Item{ } TrailEmitter{ system: sys - particle: "cannonWake" + group: "cannonWake" follow: "cannon" emitRatePerParticle: 64 lifeSpan: 600 @@ -160,7 +160,7 @@ Item{ } TrailEmitter{ system: sys - particle: "cannonCore" + group: "cannonCore" follow: "cannon" emitRatePerParticle: 256 lifeSpan: 128 diff --git a/examples/declarative/plasmapatrol/content/Sloop.qml b/examples/declarative/plasmapatrol/content/Sloop.qml index 82e57f5161a69badd2f1181294a4b48ca7dad897..59678a75ea38cad42e665ec3efbf0556f37265e7 100644 --- a/examples/declarative/plasmapatrol/content/Sloop.qml +++ b/examples/declarative/plasmapatrol/content/Sloop.qml @@ -60,7 +60,7 @@ Item { //TODO: Cooler would be an 'orbiting' affector //TODO: On the subject, opacity and size should be grouped type 'overLife' if we can cram that in the particles system: container.system - particle: container.shipParticle + group: container.shipParticle shape: EllipseShape{} emitRate: hp > 0 ? hp + 20 : 0 diff --git a/examples/declarative/plasmapatrol/plasmapatrol.qml b/examples/declarative/plasmapatrol/plasmapatrol.qml index 4ea464b9f8a51a7418888ae6dcc9bd8271a5789a..2fa9f449295b527c6639165bf2736d9cd23f10e1 100644 --- a/examples/declarative/plasmapatrol/plasmapatrol.qml +++ b/examples/declarative/plasmapatrol/plasmapatrol.qml @@ -97,7 +97,7 @@ Rectangle { anchors.fill: parent system: particles enabled: true - particle: "default" + group: "default" emitRate: 1200 lifeSpan: 1200 shape: MaskShape{source:"content/pics/TitleText.png"} diff --git a/examples/declarative/samegame/SamegameCore/BoomBlock.qml b/examples/declarative/samegame/SamegameCore/BoomBlock.qml index 1c84fa861475fd11d1cfe17e43329ac85e06dd4e..df3e9bd8faaa2313843828c5fa3c28e401bcc70a 100644 --- a/examples/declarative/samegame/SamegameCore/BoomBlock.qml +++ b/examples/declarative/samegame/SamegameCore/BoomBlock.qml @@ -75,7 +75,7 @@ Item { Emitter { id: particles system: particleSystem - particle: { + group: { if(type == 0){ "red"; } else if (type == 1) { diff --git a/examples/declarative/samegame/SamegameCore/GameArea.qml b/examples/declarative/samegame/SamegameCore/GameArea.qml index 967e2995778a40767973ea4511401740f7cfd87d..9a8f68ad893dea02d63aad897452e3a6b0956c9f 100644 --- a/examples/declarative/samegame/SamegameCore/GameArea.qml +++ b/examples/declarative/samegame/SamegameCore/GameArea.qml @@ -65,21 +65,21 @@ Item { id: particleSystem; z:2 ImageParticle { - particles: ["red"] + groups: ["red"] color: Qt.darker("red");//Actually want desaturated... source: "pics/particle.png" colorVariation: 0.4 alpha: 0.1 } ImageParticle { - particles: ["green"] + groups: ["green"] color: Qt.darker("green");//Actually want desaturated... source: "pics/particle.png" colorVariation: 0.4 alpha: 0.1 } ImageParticle { - particles: ["blue"] + groups: ["blue"] color: Qt.darker("blue");//Actually want desaturated... source: "pics/particle.png" colorVariation: 0.4 diff --git a/examples/declarative/snake/content/Cookie.qml b/examples/declarative/snake/content/Cookie.qml index e3b3bbf3f5df4301cd086400ac919bf8d3f34276..d9fedd9436b409727956fc93f968ff45fc33875c 100644 --- a/examples/declarative/snake/content/Cookie.qml +++ b/examples/declarative/snake/content/Cookie.qml @@ -71,13 +71,13 @@ Item { ParticleSystem { width:1; height:1; anchors.centerIn: parent; ImageParticle { - particles: ["star"] + groups: ["star"] source: "pics/yellowStar.png" } Emitter { id: particles anchors.fill: parent - particle: "star" + group: "star" emitRate: 50 emitting: false lifeSpan: 700 diff --git a/examples/declarative/snake/content/Link.qml b/examples/declarative/snake/content/Link.qml index 82e0359a1abe21e2303ebbcbfd7ca84afb99ec5f..31ad62248c7a6b66e5d767812d13766ec4c05945 100644 --- a/examples/declarative/snake/content/Link.qml +++ b/examples/declarative/snake/content/Link.qml @@ -96,13 +96,13 @@ Item { id:link ParticleSystem { width:1; height:1; anchors.centerIn: parent; ImageParticle { - particles: ["star"] + groups: ["star"] source: type == 1 ? "pics/blueStar.png" : "pics/redStar.png" } Emitter { id: particles anchors.fill: parent - particle: "star" + group: "star" emitRate: 50 emitting: false lifeSpan: 700 diff --git a/examples/declarative/toys/dynamicscene/dynamicscene.qml b/examples/declarative/toys/dynamicscene/dynamicscene.qml index 5670aacfa77ae868d71f394a18c9655352275633..179d633c97cc3f31b7dcc464b1dfe9489d41e822 100644 --- a/examples/declarative/toys/dynamicscene/dynamicscene.qml +++ b/examples/declarative/toys/dynamicscene/dynamicscene.qml @@ -104,7 +104,7 @@ Item { ImageParticle { id: stars source: "content/images/star.png" - particles: ["stars"] + groups: ["stars"] opacity: .5 } @@ -113,7 +113,7 @@ Item { anchors.fill: parent emitRate: parent.width / 50 lifeSpan: 5000 - particle: "stars" + group: "stars" } } diff --git a/src/declarative/items/qsgsprite.cpp b/src/declarative/items/qsgsprite.cpp index 806f7a9ad8c11f2c5772afc5e75b4f98ca1355ad..63d1951b7cd1c22d2477374b6978d84940709160 100644 --- a/src/declarative/items/qsgsprite.cpp +++ b/src/declarative/items/qsgsprite.cpp @@ -40,42 +40,17 @@ ****************************************************************************/ #include "qsgsprite_p.h" -//TODO: Split out particle system dependency -#include "qsgparticlesystem_p.h" #include <QDebug> QT_BEGIN_NAMESPACE QSGSprite::QSGSprite(QObject *parent) : - QObject(parent) + QSGStochasticState(parent) , m_generatedCount(0) , m_framesPerRow(0) - , m_frames(1) , m_frameHeight(0) , m_frameWidth(0) - , m_duration(1000) { } -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() -{ - QSGParticleSystem* system = qobject_cast<QSGParticleSystem*>(parent()); - if (system) - return QDeclarativeListProperty<QObject>(this, 0, &QSGParticleSystem::stateRedirect); - else - 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 diff --git a/src/declarative/items/qsgsprite_p.h b/src/declarative/items/qsgsprite_p.h index c18e9b45054daa714efd2cbe236ad0a3497c718e..ed7c6c4be457689261ced96326994e9252df8da8 100644 --- a/src/declarative/items/qsgsprite_p.h +++ b/src/declarative/items/qsgsprite_p.h @@ -46,6 +46,7 @@ #include <QUrl> #include <QVariantMap> #include <QDeclarativeListProperty> +#include "qsgspriteengine_p.h" QT_BEGIN_HEADER @@ -54,38 +55,23 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) -class QSGSprite : public QObject +class QSGSprite : public QSGStochasticState { Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) - Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY framesChanged) - //If frame height or width is not specified, it is assumed to be a single long row of frames. + //If frame height or width is not specified, it is assumed to be a single long row of square frames. //Otherwise, it can be multiple contiguous rows, when one row runs out the next will be used. Q_PROPERTY(int frameHeight READ frameHeight WRITE setFrameHeight NOTIFY frameHeightChanged) Q_PROPERTY(int frameWidth READ frameWidth WRITE setFrameWidth NOTIFY frameWidthChanged) - Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged) - Q_PROPERTY(int durationVariation READ durationVariance WRITE setDurationVariance NOTIFY durationVarianceChanged) - Q_PROPERTY(qreal speedModifiesDuration READ speedModifer WRITE setSpeedModifier NOTIFY speedModifierChanged) - Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged) - Q_PROPERTY(QDeclarativeListProperty<QObject> particleChildren READ particleChildren DESIGNABLE false)//### Hidden property for in-state system definitions - ought not to be used in actual "Sprite" states - Q_CLASSINFO("DefaultProperty", "particleChildren") public: explicit QSGSprite(QObject *parent = 0); - QDeclarativeListProperty<QObject> particleChildren(); - QUrl source() const { return m_source; } - int frames() const - { - return m_frames; - } - int frameHeight() const { return m_frameHeight; @@ -96,55 +82,15 @@ public: return m_frameWidth; } - int duration() const - { - return m_duration; - } - - QString name() const - { - return m_name; - } - - QVariantMap to() const - { - return m_to; - } - - qreal speedModifer() const - { - return m_speedModifier; - } - - int durationVariance() const - { - return m_durationVariance; - } - - int variedDuration() const; signals: void sourceChanged(QUrl arg); - void framesChanged(int arg); - void frameHeightChanged(int arg); void frameWidthChanged(int arg); - void durationChanged(int arg); - - void nameChanged(QString arg); - - void toChanged(QVariantMap arg); - - void speedModifierChanged(qreal arg); - - void durationVarianceChanged(int arg); - - void entered();//### Just playing around - don't expect full state API - public slots: void setSource(QUrl arg) @@ -155,14 +101,6 @@ public slots: } } - void setFrames(int arg) - { - if (m_frames != arg) { - m_frames = arg; - emit framesChanged(arg); - } - } - void setFrameHeight(int arg) { if (m_frameHeight != arg) { @@ -179,60 +117,16 @@ public slots: } } - void setDuration(int arg) - { - if (m_duration != arg) { - m_duration = arg; - emit durationChanged(arg); - } - } - - void setName(QString arg) - { - if (m_name != arg) { - m_name = arg; - emit nameChanged(arg); - } - } - - void setTo(QVariantMap arg) - { - if (m_to != arg) { - m_to = arg; - emit toChanged(arg); - } - } - - void setSpeedModifier(qreal arg) - { - if (m_speedModifier != arg) { - m_speedModifier = arg; - emit speedModifierChanged(arg); - } - } - - void setDurationVariance(int arg) - { - if (m_durationVariance != arg) { - m_durationVariance = arg; - emit durationVarianceChanged(arg); - } - } private: friend class QSGImageParticle; friend class QSGSpriteEngine; + friend class QSGStochasticEngine; int m_generatedCount; int m_framesPerRow; QUrl m_source; - int m_frames; int m_frameHeight; int m_frameWidth; - int m_duration; - QString m_name; - QVariantMap m_to; - qreal m_speedModifier; - int m_durationVariance; }; diff --git a/src/declarative/items/qsgspriteengine.cpp b/src/declarative/items/qsgspriteengine.cpp index 1915db6000b7d7c15420c38f23a852735d359672..0391ce1281a7d70ae3ba9e1b119ff5304d4e1807 100644 --- a/src/declarative/items/qsgspriteengine.cpp +++ b/src/declarative/items/qsgspriteengine.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE Also solve the state data initialization/transfer issue so as to not need to make friends */ -QSGSpriteEngine::QSGSpriteEngine(QObject *parent) : +QSGStochasticEngine::QSGStochasticEngine(QObject *parent) : QObject(parent), m_timeOffset(0) { //Default size 1 @@ -61,7 +61,7 @@ QSGSpriteEngine::QSGSpriteEngine(QObject *parent) : m_advanceTime.start(); } -QSGSpriteEngine::QSGSpriteEngine(QList<QSGSprite*> states, QObject *parent) : +QSGStochasticEngine::QSGStochasticEngine(QList<QSGStochasticState*> states, QObject *parent) : QObject(parent), m_states(states), m_timeOffset(0) { //Default size 1 @@ -69,10 +69,27 @@ QSGSpriteEngine::QSGSpriteEngine(QList<QSGSprite*> states, QObject *parent) : m_advanceTime.start(); } +QSGStochasticEngine::~QSGStochasticEngine() +{ +} + +QSGSpriteEngine::QSGSpriteEngine(QObject *parent) + : QSGStochasticEngine(parent) +{ +} + +QSGSpriteEngine::QSGSpriteEngine(QList<QSGSprite*> sprites, QObject *parent) + : QSGStochasticEngine(parent) +{ + foreach (QSGSprite* sprite, sprites) + m_states << (QSGStochasticState*)sprite; +} + QSGSpriteEngine::~QSGSpriteEngine() { } + int QSGSpriteEngine::maxFrames() { return m_maxFrames; @@ -87,46 +104,46 @@ 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) + int state = m_things[sprite]; + if (!m_sprites[state]->m_generatedCount) return state; - int rowDuration = m_duration[sprite] * m_states[state]->m_framesPerRow; + int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow; int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; return state + extra; } int QSGSpriteEngine::spriteStart(int sprite) { - int state = m_sprites[sprite]; - if (!m_states[state]->m_generatedCount) + int state = m_things[sprite]; + if (!m_sprites[state]->m_generatedCount) return m_startTimes[sprite]; - int rowDuration = m_duration[sprite] * m_states[state]->m_framesPerRow; + int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow; int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; return state + extra*rowDuration; } int QSGSpriteEngine::spriteFrames(int sprite) { - int state = m_sprites[sprite]; - if (!m_states[state]->m_generatedCount) - return m_states[state]->frames(); - int rowDuration = m_duration[sprite] * m_states[state]->m_framesPerRow; + int state = m_things[sprite]; + if (!m_sprites[state]->m_generatedCount) + return m_sprites[state]->frames(); + int rowDuration = m_duration[sprite] * m_sprites[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; + if (extra == m_sprites[state]->m_generatedCount - 1)//last state + return m_sprites[state]->frames() % m_sprites[state]->m_framesPerRow; else - return m_states[state]->m_framesPerRow; + return m_sprites[state]->m_framesPerRow; } int QSGSpriteEngine::spriteDuration(int sprite) { - int state = m_sprites[sprite]; - if (!m_states[state]->m_generatedCount) + int state = m_things[sprite]; + if (!m_sprites[state]->m_generatedCount) return m_duration[sprite]; - int rowDuration = m_duration[sprite] * m_states[state]->m_framesPerRow; + int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow; int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration; - if (extra == m_states[state]->m_generatedCount - 1)//last state - return (m_duration[sprite] * m_states[state]->frames()) % rowDuration; + if (extra == m_sprites[state]->m_generatedCount - 1)//last state + return (m_duration[sprite] * m_sprites[state]->frames()) % rowDuration; else return rowDuration; } @@ -136,21 +153,21 @@ int QSGSpriteEngine::spriteCount()//TODO: Actually image state count, need to re return m_imageStateCount; } -void QSGSpriteEngine::setGoal(int state, int sprite, bool jump) +void QSGStochasticEngine::setGoal(int state, int sprite, bool jump) { - if (sprite >= m_sprites.count() || state >= m_states.count()) + if (sprite >= m_things.count() || state >= m_states.count()) return; if (!jump){ m_goals[sprite] = state; return; } - if (m_sprites[sprite] == state) + if (m_things[sprite] == state) return;//Already there - m_sprites[sprite] = state; + m_things[sprite] = state; m_duration[sprite] = m_states[state]->variedDuration(); m_goals[sprite] = -1; - restartSprite(sprite); + restart(sprite); emit stateChanged(sprite); emit m_states[state]->entered(); return; @@ -165,8 +182,15 @@ QImage QSGSpriteEngine::assembledImage() int maxSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); + foreach (QSGStochasticState* s, m_states){ + QSGSprite* sprite = qobject_cast<QSGSprite*>(s); + if (sprite) + m_sprites << sprite; + else + qDebug() << "Error: Non-sprite in QSGSpriteEngine"; + } - foreach (QSGSprite* state, m_states){ + foreach (QSGSprite* state, m_sprites){ if (state->frames() > m_maxFrames) m_maxFrames = state->frames(); @@ -224,7 +248,7 @@ QImage QSGSpriteEngine::assembledImage() image.fill(0); QPainter p(&image); int y = 0; - foreach (QSGSprite* state, m_states){ + foreach (QSGSprite* state, m_sprites){ QImage img(state->source().toLocalFile()); if (img.height() == frameHeight && img.width() < maxSize){//Simple case p.drawImage(0,y,img); @@ -271,51 +295,51 @@ QImage QSGSpriteEngine::assembledImage() return image; } -void QSGSpriteEngine::setCount(int c) +void QSGStochasticEngine::setCount(int c) { - m_sprites.resize(c); + m_things.resize(c); m_goals.resize(c); m_duration.resize(c); m_startTimes.resize(c); } -void QSGSpriteEngine::startSprite(int index, int state) +void QSGStochasticEngine::start(int index, int state) { - if (index >= m_sprites.count()) + if (index >= m_things.count()) return; - m_sprites[index] = state; + m_things[index] = state; m_duration[index] = m_states[state]->variedDuration(); m_goals[index] = -1; - restartSprite(index); + restart(index); } -void QSGSpriteEngine::stopSprite(int index) +void QSGStochasticEngine::stop(int index) { - if (index >= m_sprites.count()) + if (index >= m_things.count()) return; //Will never change until start is called again with a new state - this is not a 'pause' for (int i=0; i<m_stateUpdates.count(); i++) m_stateUpdates[i].second.removeAll(index); } -void QSGSpriteEngine::restartSprite(int index) +void QSGStochasticEngine::restart(int index) { m_startTimes[index] = m_timeOffset + m_advanceTime.elapsed(); - int time = m_duration[index] * m_states[m_sprites[index]]->frames() + m_startTimes[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); } -uint QSGSpriteEngine::updateSprites(uint time)//### would returning a list of changed idxs be faster than signals? +uint QSGStochasticEngine::updateSprites(uint time)//### would returning a list of changed idxs be faster than signals? { //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_sprites.count()) + if (idx >= m_things.count()) continue;//TODO: Proper fix(because this does happen and I'm just ignoring it) - int stateIdx = m_sprites[idx]; + int stateIdx = m_things[idx]; int nextIdx = -1; int goalPath = goalSeek(stateIdx, idx); if (goalPath == -1){//Random @@ -347,7 +371,7 @@ uint QSGSpriteEngine::updateSprites(uint time)//### would returning a list of ch if (nextIdx == -1)//No to states means stay here nextIdx = stateIdx; - m_sprites[idx] = nextIdx; + m_things[idx] = nextIdx; m_duration[idx] = m_states[nextIdx]->variedDuration(); m_startTimes[idx] = time; if (nextIdx != stateIdx){ @@ -370,7 +394,7 @@ uint QSGSpriteEngine::updateSprites(uint time)//### would returning a list of ch return m_stateUpdates.first().first; } -int QSGSpriteEngine::goalSeek(int curIdx, int spriteIdx, int dist) +int QSGStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist) { QString goalName; if (m_goals[spriteIdx] != -1) @@ -386,7 +410,7 @@ int QSGSpriteEngine::goalSeek(int curIdx, int spriteIdx, int dist) return curIdx; if (dist < 0) dist = m_states.count(); - QSGSprite* curState = m_states[curIdx]; + QSGStochasticState* curState = m_states[curIdx]; for (QVariantMap::const_iterator iter = curState->m_to.constBegin(); iter!=curState->m_to.constEnd(); iter++){ if (iter.key() == goalName) @@ -445,7 +469,7 @@ int QSGSpriteEngine::goalSeek(int curIdx, int spriteIdx, int dist) return -1; } -void QSGSpriteEngine::addToUpdateList(uint t, int idx) +void QSGStochasticEngine::addToUpdateList(uint t, int idx) { for (int i=0; i<m_stateUpdates.count(); i++){ if (m_stateUpdates[i].first==t){ diff --git a/src/declarative/items/qsgspriteengine_p.h b/src/declarative/items/qsgspriteengine_p.h index 10860a51f137eddc74dcf32999868710711b7d8b..b2a06f2c87963ccc0b1cf140eb450c744ed55a01 100644 --- a/src/declarative/items/qsgspriteengine_p.h +++ b/src/declarative/items/qsgspriteengine_p.h @@ -58,48 +58,171 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QSGSprite; +class QSGStochasticState : public QObject //For internal use +{ + Q_OBJECT + Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged) + Q_PROPERTY(int durationVariation READ durationVariance WRITE setDurationVariance NOTIFY durationVarianceChanged) + Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged) + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(qreal speedModifiesDuration READ speedModifer WRITE setSpeedModifier NOTIFY speedModifierChanged) + Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY framesChanged) + +public: + QSGStochasticState(QObject* parent = 0) + : QObject(parent) + , m_frames(1) + , m_duration(1000) + { + } + + int duration() const + { + return m_duration; + } + + QString name() const + { + return m_name; + } + + QVariantMap to() const + { + return m_to; + } + + qreal speedModifer() const + { + return m_speedModifier; + } + + int durationVariance() const + { + return m_durationVariance; + } + + + int variedDuration() const + { + return m_duration + + (m_durationVariance * ((qreal)qrand()/RAND_MAX) * 2) + - m_durationVariance; + } -class QSGSpriteEngine : public QObject + int frames() const + { + return m_frames; + } + +signals: + void durationChanged(int arg); + + void nameChanged(QString arg); + + void toChanged(QVariantMap arg); + + void speedModifierChanged(qreal arg); + + void durationVarianceChanged(int arg); + + void entered();//### Just playing around - don't expect full state API + void framesChanged(int arg); + +public slots: + void setDuration(int arg) + { + if (m_duration != arg) { + m_duration = arg; + emit durationChanged(arg); + } + } + + void setName(QString arg) + { + if (m_name != arg) { + m_name = arg; + emit nameChanged(arg); + } + } + + void setTo(QVariantMap arg) + { + if (m_to != arg) { + m_to = arg; + emit toChanged(arg); + } + } + + void setSpeedModifier(qreal arg) + { + if (m_speedModifier != arg) { + m_speedModifier = arg; + emit speedModifierChanged(arg); + } + } + + void setDurationVariance(int arg) + { + if (m_durationVariance != arg) { + m_durationVariance = arg; + emit durationVarianceChanged(arg); + } + } + + void setFrames(int arg) + { + if (m_frames != arg) { + m_frames = arg; + emit framesChanged(arg); + } + } + +private: + QString m_name; + int m_frames; + QVariantMap m_to; + int m_duration; + qreal m_speedModifier; + int m_durationVariance; + + friend class QSGStochasticEngine; +}; + +class QSGStochasticEngine : public QObject { Q_OBJECT - //TODO: Optimize single sprite case - Q_PROPERTY(QDeclarativeListProperty<QSGSprite> sprites READ sprites) + //TODO: Optimize single state case? Q_PROPERTY(QString globalGoal READ globalGoal WRITE setGlobalGoal NOTIFY globalGoalChanged) + Q_PROPERTY(QDeclarativeListProperty<QSGStochasticState> states READ states) public: - explicit QSGSpriteEngine(QObject *parent = 0); - QSGSpriteEngine(QList<QSGSprite*> sprites, QObject *parent=0); - ~QSGSpriteEngine(); + explicit QSGStochasticEngine(QObject *parent = 0); + QSGStochasticEngine(QList<QSGStochasticState*> states, QObject *parent=0); + ~QSGStochasticEngine(); - QDeclarativeListProperty<QSGSprite> sprites() + QDeclarativeListProperty<QSGStochasticState> states() { - return QDeclarativeListProperty<QSGSprite>(this, m_states); + return QDeclarativeListProperty<QSGStochasticState>(this, m_states); } + QString globalGoal() const { return m_globalGoal; } - int count() const {return m_sprites.count();} + int count() const {return m_things.count();} void setCount(int c); - int spriteState(int sprite=0);// {return m_sprites[sprite];} - int spriteStart(int sprite=0);// {return m_startTimes[sprite];} - int spriteFrames(int sprite=0); - int spriteDuration(int sprite=0); - int spriteCount();//Like state count, but for the image states - int maxFrames(); - void setGoal(int state, int sprite=0, bool jump=false); - QImage assembledImage(); - void startSprite(int index=0, int state=0); - void stopSprite(int index=0); + void setGoal(int state, int sprite=0, bool jump=false); + void start(int index=0, int state=0); + void stop(int index=0); + int curState(int index=0) {return m_things[index];} -private://Nothing outside should use this? - friend class QSGSpriteGoalAffector;//XXX: Fix interface + QSGStochasticState* state(int idx){return m_states[idx];} + int stateIndex(QSGStochasticState* s){return m_states.indexOf(s);} int stateCount() {return m_states.count();} - int stateIndex(QSGSprite* s){return m_states.indexOf(s);}//TODO: Does this need to be hidden? - QSGSprite* state(int idx){return m_states[idx];}//Used by spritegoal affector +private: signals: void globalGoalChanged(QString arg); @@ -116,14 +239,14 @@ public slots: uint updateSprites(uint time); -private: +protected: friend class QSGParticleSystem; - void restartSprite(int sprite); + void restart(int index); void addToUpdateList(uint t, int idx); - int goalSeek(int curState, int spriteIdx, int dist=-1); - QList<QSGSprite*> m_states; + int goalSeek(int curState, int idx, int dist=-1); + QList<QSGStochasticState*> 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_things;//int is the index in m_states of the current state QVector<int> m_goals; QVector<int> m_duration; QVector<int> m_startTimes; @@ -136,6 +259,31 @@ private: int m_imageStateCount; }; +class QSGSpriteEngine : public QSGStochasticEngine +{ + Q_OBJECT + Q_PROPERTY(QDeclarativeListProperty<QSGSprite> sprites READ sprites) +public: + explicit QSGSpriteEngine(QObject *parent = 0); + QSGSpriteEngine(QList<QSGSprite*> sprites, QObject *parent=0); + ~QSGSpriteEngine(); + QDeclarativeListProperty<QSGSprite> sprites() + { + return QDeclarativeListProperty<QSGSprite>(this, m_sprites); + } + + + int spriteState(int sprite=0); + int spriteStart(int sprite=0); + int spriteFrames(int sprite=0); + int spriteDuration(int sprite=0); + int spriteCount();//Like state count, but for the image states + int maxFrames(); + QImage assembledImage(); +private: + QList<QSGSprite*> m_sprites; +}; + //Common use is to have your own list property which is transparently an engine inline void spriteAppend(QDeclarativeListProperty<QSGSprite> *p, QSGSprite* s) { diff --git a/src/declarative/items/qsgspriteimage.cpp b/src/declarative/items/qsgspriteimage.cpp index afa80e4aa1f339a51ce8519964fa977ed737f545..5557ea564a6754389b27e773958b4509c7e60156 100644 --- a/src/declarative/items/qsgspriteimage.cpp +++ b/src/declarative/items/qsgspriteimage.cpp @@ -263,7 +263,7 @@ QSGGeometryNode* QSGSpriteImage::buildNode() g->setDrawingMode(GL_TRIANGLES); SpriteVertices *p = (SpriteVertices *) g->vertexData(); - m_spriteEngine->startSprite(0); + m_spriteEngine->start(0); p->v1.animT = p->v2.animT = p->v3.animT = p->v4.animT = 0; p->v1.animIdx = p->v2.animIdx = p->v3.animIdx = p->v4.animIdx = 0; p->v1.frameCount = p->v2.frameCount = p->v3.frameCount = p->v4.frameCount = m_spriteEngine->spriteFrames(); diff --git a/src/declarative/particles/particles.pri b/src/declarative/particles/particles.pri index 527bd9ae61e266b02fb23d1ec404e2463d96f1cb..8676e521726f4edef1a2c0bbd664404d317b1b5a 100644 --- a/src/declarative/particles/particles.pri +++ b/src/declarative/particles/particles.pri @@ -29,7 +29,8 @@ HEADERS += \ $$PWD/qsgtargetaffector_p.h \ $$PWD/qsgcumulativedirection_p.h \ $$PWD/qsgv8particledata_p.h \ - $$PWD/qsgrectangleextruder_p.h + $$PWD/qsgrectangleextruder_p.h \ + $$PWD/qsgparticlegroup_p.h SOURCES += \ $$PWD/qsgangledirection.cpp \ @@ -60,7 +61,8 @@ SOURCES += \ $$PWD/qsgtargetaffector.cpp \ $$PWD/qsgcumulativedirection.cpp \ $$PWD/qsgv8particledata.cpp \ - $$PWD/qsgrectangleextruder.cpp + $$PWD/qsgrectangleextruder.cpp \ + $$PWD/qsgparticlegroup.cpp RESOURCES += \ $$PWD/particles.qrc diff --git a/src/declarative/particles/qsgcustomparticle.cpp b/src/declarative/particles/qsgcustomparticle.cpp index ab4cfa0a3aefa467dfaed02011483c06978100be..a1d65a5360f5c4ea12dad7574a672ed9d84b59b9 100644 --- a/src/declarative/particles/qsgcustomparticle.cpp +++ b/src/declarative/particles/qsgcustomparticle.cpp @@ -465,7 +465,7 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNodes() s.vertexCode = qt_particles_default_vertex_code; s.vertexCode = qt_particles_template_vertex_code + s.vertexCode; m_material.setProgramSource(s); - foreach (const QString &str, m_particles){ + foreach (const QString &str, m_groups){ int gIdx = m_system->m_groupIds[str]; int count = m_system->m_groupData[gIdx]->size(); //Create Particle Geometry diff --git a/src/declarative/particles/qsgimageparticle.cpp b/src/declarative/particles/qsgimageparticle.cpp index 581024d5787b627984f0ed4a5aee05e76e16aa52..b1aef784e87984f2bfdb592791791a5518d01f6a 100644 --- a/src/declarative/particles/qsgimageparticle.cpp +++ b/src/declarative/particles/qsgimageparticle.cpp @@ -1021,7 +1021,7 @@ QSGGeometryNode* QSGImageParticle::buildParticleNodes() m_material->setFlag(QSGMaterial::Blending); } - foreach (const QString &str, m_particles){ + foreach (const QString &str, m_groups){ int gIdx = m_system->m_groupIds[str]; int count = m_system->m_groupData[gIdx]->size(); QSGGeometryNode* node = new QSGGeometryNode(); @@ -1151,7 +1151,7 @@ void QSGImageParticle::prepareNextFrame() //Advance State getState<ImageMaterialData>(m_material)->animcount = m_spriteEngine->spriteCount(); m_spriteEngine->updateSprites(timeStamp); - foreach (const QString &str, m_particles){ + foreach (const QString &str, m_groups){ int gIdx = m_system->m_groupIds[str]; int count = m_system->m_groupData[gIdx]->size(); @@ -1199,7 +1199,7 @@ void QSGImageParticle::initialize(int gIdx, int pIdx) datum->animT = datum->t; datum->animIdx = 0; if (m_spriteEngine){ - m_spriteEngine->startSprite(spriteIdx); + m_spriteEngine->start(spriteIdx); datum->frameCount = m_spriteEngine->spriteFrames(spriteIdx); datum->frameDuration = m_spriteEngine->spriteDuration(spriteIdx); }else{ diff --git a/src/declarative/particles/qsgimageparticle_p.h b/src/declarative/particles/qsgimageparticle_p.h index 01eacbad995930d72e858d5b38ee4c8c623ec270..1f87b16f63cf1580a544eaaa7115f28be91d81b1 100644 --- a/src/declarative/particles/qsgimageparticle_p.h +++ b/src/declarative/particles/qsgimageparticle_p.h @@ -56,7 +56,7 @@ class ImageMaterialData; class QSGGeometryNode; class QSGSprite; -class QSGSpriteEngine; +class QSGStochasticEngine; struct SimpleVertex { float x; @@ -186,7 +186,7 @@ public: QDeclarativeListProperty<QSGSprite> sprites(); - QSGSpriteEngine* spriteEngine() {return m_spriteEngine;} + QSGStochasticEngine* spriteEngine() {return m_spriteEngine;} enum EntryEffect { None = 0, diff --git a/src/declarative/particles/qsgitemparticle.cpp b/src/declarative/particles/qsgitemparticle.cpp index c33088098095bcb04f4d78f5388fa3f309f61c64..2572d677833bc7e5a5fc9e8e78a398b47710395d 100644 --- a/src/declarative/particles/qsgitemparticle.cpp +++ b/src/declarative/particles/qsgitemparticle.cpp @@ -226,7 +226,7 @@ void QSGItemParticle::prepareNextFrame() return; //TODO: Size, better fade? - foreach (const QString &str, m_particles){ + foreach (const QString &str, m_groups){ int gIdx = m_system->m_groupIds[str]; int count = m_system->m_groupData[gIdx]->size(); diff --git a/src/declarative/particles/qsgparticleaffector.cpp b/src/declarative/particles/qsgparticleaffector.cpp index cff3c294443158e50bae29fca6615583984a4563..7cb4869f3eeb32059955d36e5535aee3fbe289cf 100644 --- a/src/declarative/particles/qsgparticleaffector.cpp +++ b/src/declarative/particles/qsgparticleaffector.cpp @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE If the Affector is a direct child of a ParticleSystem, it will automatically be associated with it. */ /*! - \qmlproperty list<string> QtQuick.Particles2::Affector::particles + \qmlproperty list<string> QtQuick.Particles2::Affector::groups Which logical particle groups will be affected. If empty, it will affect all particles. @@ -100,9 +100,9 @@ QT_BEGIN_NAMESPACE x,y are the coordinates of the affected particle, relative to the ParticleSystem. */ -//TODO: Document particle 'type' + /*! - \qmlsignal QtQuick.Particles2::Affector::affectParticle(particle, dt) + \qmlsignal QtQuick.Particles2::Affector::affectParticle(particle particle, real dt) This handler is called when particles are selected to be affected. @@ -113,7 +113,7 @@ QT_BEGIN_NAMESPACE high-volume particle systems. */ /*! - \qmlsignal QtQuick.Particles2::Affector::affected(x, y) + \qmlsignal QtQuick.Particles2::Affector::affected(real x, real y) This handler is called when a particle is selected to be affected. It will only be called if signal is set to true. @@ -142,12 +142,12 @@ void QSGParticleAffector::componentComplete() bool QSGParticleAffector::activeGroup(int g) { if (m_updateIntSet){ - m_groups.clear(); - foreach (const QString &p, m_particles) - m_groups << m_system->m_groupIds[p];//###Can this occur before group ids are properly assigned? + m_groupIds.clear(); + foreach (const QString &p, m_groups) + m_groupIds << m_system->m_groupIds[p];//###Can this occur before group ids are properly assigned? m_updateIntSet = false; } - return m_groups.isEmpty() || m_groups.contains(g); + return m_groupIds.isEmpty() || m_groupIds.contains(g); } void QSGParticleAffector::affectSystem(qreal dt) @@ -195,7 +195,7 @@ bool QSGParticleAffector::affectParticle(QSGParticleData *, qreal ) void QSGParticleAffector::reset(QSGParticleData* pd) {//TODO: This, among other ones, should be restructured so they don't all need to remember to call the superclass if (m_onceOff) - if (m_groups.isEmpty() || m_groups.contains(pd->group)) + if (m_groups.isEmpty() || m_groupIds.contains(pd->group)) m_onceOffed.remove(qMakePair(pd->group, pd->index)); } diff --git a/src/declarative/particles/qsgparticleaffector_p.h b/src/declarative/particles/qsgparticleaffector_p.h index 5700969aad8d140198c444958acbd25afd24813f..0dadeff6a746d82ed1ad9f3191c2c32a3f8eaa8e 100644 --- a/src/declarative/particles/qsgparticleaffector_p.h +++ b/src/declarative/particles/qsgparticleaffector_p.h @@ -56,7 +56,7 @@ class QSGParticleAffector : public QSGItem { Q_OBJECT Q_PROPERTY(QSGParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) - Q_PROPERTY(QStringList particles READ particles WRITE setParticles NOTIFY particlesChanged) + Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged) Q_PROPERTY(QStringList whenCollidingWith READ whenCollidingWith WRITE setWhenCollidingWith NOTIFY whenCollidingWithChanged) Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(bool once READ onceOff WRITE setOnceOff NOTIFY onceChanged) @@ -71,9 +71,9 @@ public: return m_system; } - QStringList particles() const + QStringList groups() const { - return m_particles; + return m_groups; } bool enabled() const @@ -100,7 +100,7 @@ signals: void systemChanged(QSGParticleSystem* arg); - void particlesChanged(QStringList arg); + void groupsChanged(QStringList arg); void enabledChanged(bool arg); @@ -122,12 +122,12 @@ void setSystem(QSGParticleSystem* arg) } } -void setParticles(QStringList arg) +void setGroups(QStringList arg) { - if (m_particles != arg) { - m_particles = arg; + if (m_groups != arg) { + m_groups = arg; m_updateIntSet = true; - emit particlesChanged(arg); + emit groupsChanged(arg); } } @@ -169,14 +169,14 @@ protected: virtual bool affectParticle(QSGParticleData *d, qreal dt); bool m_needsReset;//### What is this really saving? QSGParticleSystem* m_system; - QStringList m_particles; + QStringList m_groups; bool activeGroup(int g); bool m_enabled; virtual void componentComplete(); QPointF m_offset; bool isAffectedConnected(); private: - QSet<int> m_groups; + QSet<int> m_groupIds; QSet<QPair<int, int> > m_onceOffed; bool m_updateIntSet; diff --git a/src/declarative/particles/qsgparticleemitter.cpp b/src/declarative/particles/qsgparticleemitter.cpp index 13ab3e61855d80225dbbec0d6b052afec9aac6ce..fdba3def415c5cdba7ed44af7286d24f274f4a51 100644 --- a/src/declarative/particles/qsgparticleemitter.cpp +++ b/src/declarative/particles/qsgparticleemitter.cpp @@ -68,9 +68,9 @@ QT_BEGIN_NAMESPACE This can be omitted if the Emitter is a direct child of the ParticleSystem */ /*! - \qmlproperty string QtQuick.Particles2::Emitter::particle + \qmlproperty string QtQuick.Particles2::Emitter::group - This is the type of logical particle which it will emit. + This is the logical particle group which it will emit into. Default value is "" (empty string). */ @@ -396,7 +396,7 @@ void QSGParticleEmitter::emitWindow(int timeStamp) pt = time; while ((pt < time && m_emitCap) || !m_burstQueue.isEmpty()) { //int pos = m_last_particle % m_particle_count; - QSGParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_particle], !m_overwrite); + QSGParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_group], !m_overwrite); if (datum){//actually emit(otherwise we've been asked to skip this one) datum->e = this;//###useful? qreal t = 1 - (pt - opt) / dt; diff --git a/src/declarative/particles/qsgparticleemitter_p.h b/src/declarative/particles/qsgparticleemitter_p.h index 8ed7ee7053f0c2c5532b2ac44103631a5647d7f8..8bd205b207b7b59666ed85aaf813668e8790798e 100644 --- a/src/declarative/particles/qsgparticleemitter_p.h +++ b/src/declarative/particles/qsgparticleemitter_p.h @@ -61,7 +61,7 @@ class QSGParticleEmitter : public QSGItem { Q_OBJECT Q_PROPERTY(QSGParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) - Q_PROPERTY(QString particle READ particle WRITE setParticle NOTIFY particleChanged) + Q_PROPERTY(QString group READ group WRITE setGroup NOTIFY groupChanged) Q_PROPERTY(QSGParticleExtruder* shape READ extruder WRITE setExtruder NOTIFY extruderChanged) Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged) @@ -109,9 +109,9 @@ public: return m_system; } - QString particle() const + QString group() const { - return m_particle; + return m_group; } int particleDurationVariation() const @@ -130,7 +130,7 @@ signals: void systemChanged(QSGParticleSystem* arg); - void particleChanged(QString arg); + void groupChanged(QString arg); void particleDurationVariationChanged(int arg); @@ -185,11 +185,11 @@ public slots: } } - void setParticle(QString arg) + void setGroup(QString arg) { - if (m_particle != arg) { - m_particle = arg; - emit particleChanged(arg); + if (m_group != arg) { + m_group = arg; + emit groupChanged(arg); } } @@ -308,7 +308,7 @@ protected: int m_particleDurationVariation; bool m_enabled; QSGParticleSystem* m_system; - QString m_particle; + QString m_group; QSGParticleExtruder* m_extruder; QSGParticleExtruder* m_defaultExtruder; QSGParticleExtruder* effectiveExtruder(); diff --git a/src/declarative/particles/qsgparticlegroup.cpp b/src/declarative/particles/qsgparticlegroup.cpp new file mode 100644 index 0000000000000000000000000000000000000000..28eb4d2c85287132e84b96c8949fc8f2ee4bf64a --- /dev/null +++ b/src/declarative/particles/qsgparticlegroup.cpp @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** 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 Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgparticlegroup_p.h" + +/*! + \qmlclass ParticleGroup QSGParticleGroup + \inqmlmodule QtQuick.Particles 2 + \brief ParticleGroup elements allow you to set attributes on a logical particle group. + + This element allows you to set timed transitions on particle groups. + + You can also use this element to group particle system elements related to the logical + particle group. Emitters, Affectors and Painters set as direct children of a ParticleGroup + will automatically apply to that logical particle group. TrailEmitters will automatically follow + the group. + + If a ParticleGroup element is not defined for a group, the group will function normally as if + none of the transition properties were set. +*/ +/*! + \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::system + This is the system which will contain the group. + + If the ParticleGroup is a direct child of a ParticleSystem, it will automatically be associated with it. +*/ +/*! + \qmlproperty string QtQuick.Particles2::ParticleGroup::name + This is the name of the particle group, and how it is generally referred to by other elements. + + If elements refer to a name which does not have an explicit ParticleGroup created, it will + work normally (with no transitions specified for the group). If you do not need to assign + duration based transitions to a group, you do not need to create a ParticleGroup with that name (although you may). +*/ +/*! + \qmlproperty int QtQuick.Particles2::ParticleGroup::duration + The time in milliseconds before the group will attempt to transition. + +*/ +/*! + \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::durationVariation + The maximum number of milliseconds that the duration of the transition cycle varies per particle in the group. + + Default value is zero. +*/ +/*! + \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::to + The weighted list of transitions valid for this group. + + If the chosen transition stays in this group, another duration (+/- up to durationVariation) + milliseconds will occur before another transition is attempted. +*/ + +QSGParticleGroup::QSGParticleGroup(QObject* parent) + : QSGStochasticState(parent) +{ + +} + +void delayedRedirect(QDeclarativeListProperty<QObject> *prop, QObject *value) +{ + QSGParticleGroup* pg = qobject_cast<QSGParticleGroup*>(prop->object); + if (pg) + pg->delayRedirect(value); +} + +QDeclarativeListProperty<QObject> QSGParticleGroup::particleChildren() +{ + QSGParticleSystem* system = qobject_cast<QSGParticleSystem*>(parent()); + if (system) + return QDeclarativeListProperty<QObject>(this, 0, &QSGParticleSystem::statePropertyRedirect); + else + return QDeclarativeListProperty<QObject>(this, 0, &delayedRedirect); +} + +void QSGParticleGroup::setSystem(QSGParticleSystem* arg) +{ + if (m_system != arg) { + m_system = arg; + m_system->registerParticleGroup(this); + performDelayedRedirects(); + emit systemChanged(arg); + } +} + +void QSGParticleGroup::delayRedirect(QObject *obj) +{ + m_delayedRedirects << obj; +} + +void QSGParticleGroup::performDelayedRedirects() +{ + if (!m_system) + return; + foreach (QObject* obj, m_delayedRedirects) + m_system->stateRedirect(this, m_system, obj); + + m_delayedRedirects.clear(); +} + +void QSGParticleGroup::componentComplete(){ + if (!m_system && qobject_cast<QSGParticleSystem*>(parent())) + setSystem(qobject_cast<QSGParticleSystem*>(parent())); +} diff --git a/src/declarative/particles/qsgparticlegroup_p.h b/src/declarative/particles/qsgparticlegroup_p.h new file mode 100644 index 0000000000000000000000000000000000000000..346b4ab77e80988cc97d316f82e9a327fab67754 --- /dev/null +++ b/src/declarative/particles/qsgparticlegroup_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** 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 Declarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QSGPARTICLEGROUP +#define QSGPARTICLEGROUP +#include "qsgspriteengine_p.h" +#include "qsgparticlesystem_p.h" +#include "qdeclarativeparserstatus.h" + +class QSGParticleGroup : public QSGStochasticState, public QDeclarativeParserStatus +{ + Q_OBJECT + //### Would setting limits per group be useful? Or clutter the API? + //Q_PROPERTY(int maximumAlive READ maximumAlive WRITE setMaximumAlive NOTIFY maximumAliveChanged) + + Q_PROPERTY(QSGParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) + + //Intercept children requests and assign to the group & system + Q_PROPERTY(QDeclarativeListProperty<QObject> particleChildren READ particleChildren DESIGNABLE false)//### Hidden property for in-state system definitions - ought not to be used in actual "Sprite" states + Q_CLASSINFO("DefaultProperty", "particleChildren") + +public: + explicit QSGParticleGroup(QObject* parent = 0); + + QDeclarativeListProperty<QObject> particleChildren(); + + int maximumAlive() const + { + return m_maximumAlive; + } + + QSGParticleSystem* system() const + { + return m_system; + } + +public slots: + + void setMaximumAlive(int arg) + { + if (m_maximumAlive != arg) { + m_maximumAlive = arg; + emit maximumAliveChanged(arg); + } + } + + void setSystem(QSGParticleSystem* arg); + + void delayRedirect(QObject* obj); + +signals: + + void maximumAliveChanged(int arg); + + void systemChanged(QSGParticleSystem* arg); + +protected: + virtual void componentComplete(); + virtual void classBegin(){;} + +private: + + void performDelayedRedirects(); + + int m_maximumAlive; + QSGParticleSystem* m_system; + QList<QObject*> m_delayedRedirects; +}; + +#endif diff --git a/src/declarative/particles/qsgparticlepainter.cpp b/src/declarative/particles/qsgparticlepainter.cpp index f4639c20a2c49d8b24ebfbaae852b724a7005969..670c1f21182cf7f7233bf8683af5297bb1807bdd 100644 --- a/src/declarative/particles/qsgparticlepainter.cpp +++ b/src/declarative/particles/qsgparticlepainter.cpp @@ -58,10 +58,10 @@ QT_BEGIN_NAMESPACE If the ParticlePainter is a direct child of a ParticleSystem, it will automatically be associated with it. */ /*! - \qmlproperty list<string> QtQuick.Particles2::ParticlePainter::particles + \qmlproperty list<string> QtQuick.Particles2::ParticlePainter::groups Which logical particle groups will be painted. - If empty, it will paint the default particle (""). + If empty, it will paint the default particle group (""). */ QSGParticlePainter::QSGParticlePainter(QSGItem *parent) : QSGItem(parent), @@ -144,7 +144,7 @@ void QSGParticlePainter::calcSystemOffset(bool resetPending) m_systemOffset = -1 * this->mapFromItem(m_system, QPointF(0.0, 0.0)); if (lastOffset != m_systemOffset && !resetPending){ //Reload all particles//TODO: Necessary? - foreach (const QString &g, m_particles){ + foreach (const QString &g, m_groups){ int gId = m_system->m_groupIds[g]; foreach (QSGParticleData* d, m_system->m_groupData[gId]->data) reload(d); diff --git a/src/declarative/particles/qsgparticlepainter_p.h b/src/declarative/particles/qsgparticlepainter_p.h index 08ae3aede814d4ff5a542c14a797210023ff421b..d469947453c7ed4aa30f3a4fd3721280ed20bcdf 100644 --- a/src/declarative/particles/qsgparticlepainter_p.h +++ b/src/declarative/particles/qsgparticlepainter_p.h @@ -58,7 +58,7 @@ class QSGParticlePainter : public QSGItem { Q_OBJECT Q_PROPERTY(QSGParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) - Q_PROPERTY(QStringList particles READ particles WRITE setParticles NOTIFY particlesChanged) + Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged) public: explicit QSGParticlePainter(QSGItem *parent = 0); @@ -74,25 +74,25 @@ public: } - QStringList particles() const + QStringList groups() const { - return m_particles; + return m_groups; } signals: void countChanged(); void systemChanged(QSGParticleSystem* arg); - void particlesChanged(QStringList arg); + void groupsChanged(QStringList arg); public slots: void setSystem(QSGParticleSystem* arg); -void setParticles(QStringList arg) +void setGroups(QStringList arg) { - if (m_particles != arg) { - m_particles = arg; - emit particlesChanged(arg); + if (m_groups != arg) { + m_groups = arg; + emit groupsChanged(arg); } } @@ -121,7 +121,7 @@ protected: friend class QSGParticleSystem; int m_count; bool m_pleaseReset; - QStringList m_particles; + QStringList m_groups; QPointF m_systemOffset; private: diff --git a/src/declarative/particles/qsgparticlesmodule.cpp b/src/declarative/particles/qsgparticlesmodule.cpp index 9fa0ebad97d38d6ea5a14b38c017616086eef7a4..f880842acb1d4d96d5c385991a80dd309e5b7787 100644 --- a/src/declarative/particles/qsgparticlesmodule.cpp +++ b/src/declarative/particles/qsgparticlesmodule.cpp @@ -67,6 +67,7 @@ #include "qsgcumulativedirection_p.h" #include "qsgcustomaffector_p.h" #include "qsgrectangleextruder_p.h" +#include "qsgparticlegroup_p.h" QT_BEGIN_NAMESPACE @@ -75,6 +76,7 @@ void QSGParticlesModule::defineModule() const char* uri = "QtQuick.Particles"; qmlRegisterType<QSGParticleSystem>(uri, 2, 0, "ParticleSystem"); + qmlRegisterType<QSGParticleGroup>(uri, 2, 0, "ParticleGroup"); qmlRegisterType<QSGImageParticle>(uri, 2, 0, "ImageParticle"); qmlRegisterType<QSGCustomParticle>(uri, 2, 0, "CustomParticle"); diff --git a/src/declarative/particles/qsgparticlesystem.cpp b/src/declarative/particles/qsgparticlesystem.cpp index 085e6afe649d7392d84b5f648e05e08f4ff80cb8..bc2707314235e0ebaf418f89eca4516f6393c9ad 100644 --- a/src/declarative/particles/qsgparticlesystem.cpp +++ b/src/declarative/particles/qsgparticlesystem.cpp @@ -47,6 +47,7 @@ #include "qsgspriteengine_p.h" #include "qsgsprite_p.h" #include "qsgv8particledata_p.h" +#include "qsgparticlegroup_p.h" #include "qsgtrailemitter_p.h"//###For auto-follow on states, perhaps should be in emitter? #include <private/qdeclarativeengine_p.h> @@ -549,8 +550,8 @@ void QSGParticleData::debugDump() { qDebug() << "Particle" << systemIndex << group << "/" << index << stillAlive() << "Pos: " << x << "," << y - //<< "Vel: " << vx << "," << sy - //<< "Acc: " << ax << "," << ay + << "Vel: " << vx << "," << vy + << "Acc: " << ax << "," << ay << "Size: " << size << "," << endSize << "Time: " << t << "," <<lifeSpan << ";" << (system->m_timeInt / 1000.0) ; } @@ -559,7 +560,6 @@ bool QSGParticleData::stillAlive() { if (!system) return false; - //fprintf(stderr, "%.9lf %.9lf\n",((qreal)system->m_timeInt/1000.0), (t+lifeSpan)); return (t + lifeSpan - EPSILON) > ((qreal)system->m_timeInt/1000.0); } @@ -601,7 +601,7 @@ void QSGParticleData::extendLife(float time) QSGParticleSystem::QSGParticleSystem(QSGItem *parent) : QSGItem(parent), m_particle_count(0), m_running(true), m_paused(false) - , m_nextIndex(0), m_componentComplete(false), m_spriteEngine(0) + , m_nextIndex(0), m_componentComplete(false), m_stateEngine(0) { connect(&m_painterMapper, SIGNAL(mapped(QObject*)), this, SLOT(loadPainter(QObject*))); @@ -630,16 +630,11 @@ void QSGParticleSystem::initGroups() m_nextGroupId = 1; } - QDeclarativeListProperty<QSGSprite> QSGParticleSystem::particleStates() -{ - return QDeclarativeListProperty<QSGSprite>(this, &m_states, spriteAppend, spriteCount, spriteAt, spriteClear); -} - void QSGParticleSystem::registerParticlePainter(QSGParticlePainter* p) { //TODO: a way to Unregister emitters, painters and affectors m_painters << QPointer<QSGParticlePainter>(p);//###Set or uniqueness checking? - connect(p, SIGNAL(particlesChanged(QStringList)), + connect(p, SIGNAL(groupsChanged(QStringList)), &m_painterMapper, SLOT(map())); loadPainter(p); } @@ -649,7 +644,7 @@ void QSGParticleSystem::registerParticleEmitter(QSGParticleEmitter* e) m_emitters << QPointer<QSGParticleEmitter>(e);//###How to get them out? connect(e, SIGNAL(particleCountChanged()), this, SLOT(emittersChanged())); - connect(e, SIGNAL(particleChanged(QString)), + connect(e, SIGNAL(groupChanged(QString)), this, SLOT(emittersChanged())); emittersChanged(); e->reset();//Start, so that starttime factors appropriately @@ -660,6 +655,12 @@ void QSGParticleSystem::registerParticleAffector(QSGParticleAffector* a) m_affectors << QPointer<QSGParticleAffector>(a); } +void QSGParticleSystem::registerParticleGroup(QSGParticleGroup* g) +{ + m_groups << QPointer<QSGParticleGroup>(g); + createEngine(); +} + void QSGParticleSystem::setRunning(bool arg) { if (m_running != arg) { @@ -685,40 +686,45 @@ void QSGParticleSystem::setPaused(bool arg){ } } -void QSGParticleSystem::stateRedirect(QDeclarativeListProperty<QObject> *prop, QObject *value) +void QSGParticleSystem::statePropertyRedirect(QDeclarativeListProperty<QObject> *prop, QObject *value) { //Hooks up automatic state-associated stuff QSGParticleSystem* sys = qobject_cast<QSGParticleSystem*>(prop->object->parent()); - QSGSprite* sprite = qobject_cast<QSGSprite*>(prop->object); - if (!sprite || !sys) + QSGParticleGroup* group = qobject_cast<QSGParticleGroup*>(prop->object); + if (!group || !sys || !value) return; + stateRedirect(group, sys, value); +} + +void QSGParticleSystem::stateRedirect(QSGParticleGroup* group, QSGParticleSystem* sys, QObject *value) +{ QStringList list; - list << sprite->name(); + list << group->name(); QSGParticleAffector* a = qobject_cast<QSGParticleAffector*>(value); if (a){ a->setParentItem(sys); - a->setParticles(list); + a->setGroups(list); a->setSystem(sys); return; } QSGTrailEmitter* fe = qobject_cast<QSGTrailEmitter*>(value); if (fe){ fe->setParentItem(sys); - fe->setFollow(sprite->name()); + fe->setFollow(group->name()); fe->setSystem(sys); return; } QSGParticleEmitter* e = qobject_cast<QSGParticleEmitter*>(value); if (e){ e->setParentItem(sys); - e->setParticle(sprite->name()); + e->setGroup(group->name()); e->setSystem(sys); return; } QSGParticlePainter* p = qobject_cast<QSGParticlePainter*>(value); if (p){ p->setParentItem(sys); - p->setParticles(list); + p->setGroups(list); p->setSystem(sys); return; } @@ -785,14 +791,14 @@ void QSGParticleSystem::loadPainter(QObject *p) foreach (QSGParticleGroupData* sg, m_groupData) sg->painters.remove(painter); int particleCount = 0; - if (painter->particles().isEmpty()){//Uses default particle + if (painter->groups().isEmpty()){//Uses default particle QStringList def; def << ""; - painter->setParticles(def); + painter->setGroups(def); particleCount += m_groupData[0]->size(); m_groupData[0]->painters << painter; }else{ - foreach (const QString &group, painter->particles()){ + foreach (const QString &group, painter->groups()){ if (group != QLatin1String("") && !m_groupIds[group]){//new group int id = m_nextGroupId++; QSGParticleGroupData* gd = new QSGParticleGroupData(id, this); @@ -824,16 +830,16 @@ void QSGParticleSystem::emittersChanged() } foreach (QSGParticleEmitter* e, m_emitters){//Populate groups and set sizes. - if (!m_groupIds.contains(e->particle()) - || (!e->particle().isEmpty() && !m_groupIds[e->particle()])){//or it was accidentally inserted by a failed lookup earlier + if (!m_groupIds.contains(e->group()) + || (!e->group().isEmpty() && !m_groupIds[e->group()])){//or it was accidentally inserted by a failed lookup earlier int id = m_nextGroupId++; QSGParticleGroupData* gd = new QSGParticleGroupData(id, this); - m_groupIds.insert(e->particle(), id); + m_groupIds.insert(e->group(), id); m_groupData.insert(id, gd); previousSizes << 0; newSizes << 0; } - newSizes[m_groupIds[e->particle()]] += e->particleCount(); + newSizes[m_groupIds[e->group()]] += e->particleCount(); //###: Cull emptied groups? } @@ -850,7 +856,7 @@ void QSGParticleSystem::emittersChanged() foreach (QSGParticlePainter *p, m_painters) loadPainter(p); - if (!m_states.isEmpty()) + if (!m_groups.isEmpty()) createEngine(); if (m_debugMode) @@ -861,58 +867,63 @@ void QSGParticleSystem::createEngine() { if (!m_componentComplete) return; + if (m_stateEngine && m_debugMode) + qDebug() << "Resetting Existing Sprite Engine..."; //### Solve the losses if size/states go down - foreach (QSGSprite* sprite, m_states){ + foreach (QSGParticleGroup* group, m_groups){ bool exists = false; foreach (const QString &name, m_groupIds.keys()) - if (sprite->name() == name) + if (group->name() == name) exists = true; if (!exists){ int id = m_nextGroupId++; QSGParticleGroupData* gd = new QSGParticleGroupData(id, this); - m_groupIds.insert(sprite->name(), id); + m_groupIds.insert(group->name(), id); m_groupData.insert(id, gd); } } - if (m_states.count()){ - //Reorder Sprite List so as to have the same order as groups - QList<QSGSprite*> newList; + if (m_groups.count()){ + //Reorder groups List so as to have the same order as groupData + QList<QSGParticleGroup*> newList; for (int i=0; i<m_nextGroupId; i++){ bool exists = false; QString name = m_groupData[i]->name(); - foreach (QSGSprite* existing, m_states){ + foreach (QSGParticleGroup* existing, m_groups){ if (existing->name() == name){ newList << existing; exists = true; } } if (!exists){ - newList << new QSGSprite(this); + newList << new QSGParticleGroup(this); newList.back()->setName(name); } } - m_states = newList; + m_groups = newList; + QList<QSGStochasticState*> states; + foreach (QSGParticleGroup* g, m_groups) + states << (QSGStochasticState*)g; - if (!m_spriteEngine) - m_spriteEngine = new QSGSpriteEngine(this); - m_spriteEngine->setCount(m_particle_count); - m_spriteEngine->m_states = m_states; + if (!m_stateEngine) + m_stateEngine = new QSGStochasticEngine(this); + m_stateEngine->setCount(m_particle_count); + m_stateEngine->m_states = states; - connect(m_spriteEngine, SIGNAL(stateChanged(int)), + connect(m_stateEngine, SIGNAL(stateChanged(int)), this, SLOT(particleStateChange(int))); }else{ - if (m_spriteEngine) - delete m_spriteEngine; - m_spriteEngine = 0; + if (m_stateEngine) + delete m_stateEngine; + m_stateEngine = 0; } } void QSGParticleSystem::particleStateChange(int idx) { - moveGroups(m_bySysIdx[idx], m_spriteEngine->spriteState(idx)); + moveGroups(m_bySysIdx[idx], m_stateEngine->curState(idx)); } void QSGParticleSystem::moveGroups(QSGParticleData *d, int newGIdx) @@ -934,8 +945,8 @@ int QSGParticleSystem::nextSystemIndex() } if (m_nextIndex >= m_bySysIdx.size()){ m_bySysIdx.resize(m_bySysIdx.size() < 10 ? 10 : m_bySysIdx.size()*1.1);//###+1,10%,+10? Choose something non-arbitrarily - if (m_spriteEngine) - m_spriteEngine->setCount(m_bySysIdx.size()); + if (m_stateEngine) + m_stateEngine->setCount(m_bySysIdx.size()); } return m_nextIndex++; @@ -954,8 +965,8 @@ QSGParticleData* QSGParticleSystem::newDatum(int groupId, bool respectLimits, in ret->systemIndex = nextSystemIndex(); }else{ if (ret->systemIndex != -1){ - if (m_spriteEngine) - m_spriteEngine->stopSprite(ret->systemIndex); + if (m_stateEngine) + m_stateEngine->stop(ret->systemIndex); m_reusableIndexes << ret->systemIndex; m_bySysIdx[ret->systemIndex] = 0; } @@ -963,8 +974,8 @@ QSGParticleData* QSGParticleSystem::newDatum(int groupId, bool respectLimits, in } m_bySysIdx[ret->systemIndex] = ret; - if (m_spriteEngine) - m_spriteEngine->startSprite(ret->systemIndex, ret->group); + if (m_stateEngine) + m_stateEngine->start(ret->systemIndex, ret->group); m_empty = false; return ret; @@ -1011,8 +1022,8 @@ void QSGParticleSystem::updateCurrentTime( int currentTime ) foreach (QSGParticleGroupData* gd, m_groupData)//Recycle all groups and see if they're out of live particles m_empty = gd->recycle() && m_empty; - if (m_spriteEngine) - m_spriteEngine->updateSprites(m_timeInt); + if (m_stateEngine) + m_stateEngine->updateSprites(m_timeInt); foreach (QSGParticleEmitter* emitter, m_emitters) if (emitter) diff --git a/src/declarative/particles/qsgparticlesystem_p.h b/src/declarative/particles/qsgparticlesystem_p.h index 25a0c87f53ae6d1b47c5ececae24e43cdc302dba..f531e7fcf95a6087a7113654251fdd30ac88a48b 100644 --- a/src/declarative/particles/qsgparticlesystem_p.h +++ b/src/declarative/particles/qsgparticlesystem_p.h @@ -65,9 +65,10 @@ class QSGParticleEmitter; class QSGParticlePainter; class QSGParticleData; class QSGParticleSystemAnimation; -class QSGSpriteEngine; +class QSGStochasticEngine; class QSGSprite; class QSGV8ParticleData; +class QSGParticleGroup; struct QSGParticleDataHeapNode{ int time;//in ms @@ -223,12 +224,10 @@ class QSGParticleSystem : public QSGItem Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged) - Q_PROPERTY(QDeclarativeListProperty<QSGSprite> particleStates READ particleStates) public: explicit QSGParticleSystem(QSGItem *parent = 0); ~QSGParticleSystem(); - QDeclarativeListProperty<QSGSprite> particleStates(); //TODO: Hook up running and temporal manipulators to the animation bool isRunning() const @@ -286,7 +285,7 @@ public://###but only really for related class usage. Perhaps we should all be fr QVector<QSGParticleData*> m_bySysIdx; //Another reference to the data (data owned by group), but by sysIdx QHash<QString, int> m_groupIds; QHash<int, QSGParticleGroupData*> m_groupData; - QSGSpriteEngine* m_spriteEngine; + QSGStochasticEngine* m_stateEngine; int m_timeInt; bool m_initialized; @@ -294,9 +293,11 @@ public://###but only really for related class usage. Perhaps we should all be fr void registerParticlePainter(QSGParticlePainter* p); void registerParticleEmitter(QSGParticleEmitter* e); void registerParticleAffector(QSGParticleAffector* a); + void registerParticleGroup(QSGParticleGroup* g); int m_particle_count; - static void stateRedirect(QDeclarativeListProperty<QObject> *prop, QObject *value);//From QSGSprite + static void statePropertyRedirect(QDeclarativeListProperty<QObject> *prop, QObject *value); + static void stateRedirect(QSGParticleGroup* group, QSGParticleSystem* sys, QObject *value); bool isPaused() const { return m_paused; @@ -315,11 +316,11 @@ private: QList<QPointer<QSGParticleAffector> > m_affectors; QList<QPointer<QSGParticlePainter> > m_painters; QList<QPointer<QSGParticlePainter> > m_syncList; + QList<QSGParticleGroup*> m_groups; int m_nextGroupId; int m_nextIndex; QSet<int> m_reusableIndexes; bool m_componentComplete; - QList<QSGSprite*> m_states; QSignalMapper m_painterMapper; QSignalMapper m_emitterMapper; diff --git a/src/declarative/particles/qsgspritegoal.cpp b/src/declarative/particles/qsgspritegoal.cpp index 183716781378c153dc4cfecc1d5732bb0bc7cda9..ec2be02326d3a366cb271826fe139fb549df2e34 100644 --- a/src/declarative/particles/qsgspritegoal.cpp +++ b/src/declarative/particles/qsgspritegoal.cpp @@ -64,16 +64,12 @@ QT_BEGIN_NAMESPACE \qmlproperty bool QtQuick.Particles2::SpriteGoal::systemStates */ - Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged) - Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged) - Q_PROPERTY(bool systemStates READ systemStates WRITE setSystemStates NOTIFY systemStatesChanged) - QSGSpriteGoalAffector::QSGSpriteGoalAffector(QSGItem *parent) : QSGParticleAffector(parent), m_goalIdx(-1), m_jump(false), m_systemStates(false), m_lastEngine(0), m_notUsingEngine(false) { } -void QSGSpriteGoalAffector::updateStateIndex(QSGSpriteEngine* e) +void QSGSpriteGoalAffector::updateStateIndex(QSGStochasticEngine* e) { if (m_systemStates){ m_goalIdx = m_system->m_groupIds[m_goalState]; @@ -104,14 +100,14 @@ void QSGSpriteGoalAffector::setGoalState(QString arg) bool QSGSpriteGoalAffector::affectParticle(QSGParticleData *d, qreal dt) { Q_UNUSED(dt); - QSGSpriteEngine *engine = 0; + QSGStochasticEngine *engine = 0; if (!m_systemStates){ //TODO: Affect all engines foreach (QSGParticlePainter *p, m_system->m_groupData[d->group]->painters) if (qobject_cast<QSGImageParticle*>(p)) engine = qobject_cast<QSGImageParticle*>(p)->spriteEngine(); }else{ - engine = m_system->m_spriteEngine; + engine = m_system->m_stateEngine; if (!engine) m_notUsingEngine = true; } @@ -126,7 +122,7 @@ bool QSGSpriteGoalAffector::affectParticle(QSGParticleData *d, qreal dt) if (m_notUsingEngine){//systemStates && no stochastic states defined. So cut out the engine //TODO: It's possible to move to a group that is intermediate and not used by painters or emitters - but right now that will redirect to the default group m_system->moveGroups(d, m_goalIdx); - }else if (engine->spriteState(index) != m_goalIdx){ + }else if (engine->curState(index) != m_goalIdx){ engine->setGoal(m_goalIdx, index, m_jump); emit affected(QPointF(d->curX(), d->curY()));//###Expensive if unconnected? Move to Affector? return true; //Doesn't affect particle data, but necessary for onceOff diff --git a/src/declarative/particles/qsgspritegoal_p.h b/src/declarative/particles/qsgspritegoal_p.h index 7c799b13b102729b87f4f6bbf05f622ec4edfe25..043970b90b6ad165c6128ed0015309596aa904b8 100644 --- a/src/declarative/particles/qsgspritegoal_p.h +++ b/src/declarative/particles/qsgspritegoal_p.h @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) -class QSGSpriteEngine; +class QSGStochasticEngine; class QSGSpriteGoalAffector : public QSGParticleAffector { @@ -106,10 +106,10 @@ void setSystemStates(bool arg) } private: - void updateStateIndex(QSGSpriteEngine* e); + void updateStateIndex(QSGStochasticEngine* e); QString m_goalState; int m_goalIdx; - QSGSpriteEngine* m_lastEngine; + QSGStochasticEngine* m_lastEngine; bool m_jump; bool m_systemStates; diff --git a/src/declarative/particles/qsgtrailemitter.cpp b/src/declarative/particles/qsgtrailemitter.cpp index 427b587cafc16a8415cbdd86c9d6f0ca52c65afd..5a19ac508b65ebd16b3b320c9151ef26564e425f 100644 --- a/src/declarative/particles/qsgtrailemitter.cpp +++ b/src/declarative/particles/qsgtrailemitter.cpp @@ -166,7 +166,7 @@ void QSGTrailEmitter::emitWindow(int timeStamp) qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize; int gId = m_system->m_groupIds[m_follow]; - int gId2 = m_system->m_groupIds[m_particle]; + int gId2 = m_system->m_groupIds[m_group]; foreach (QSGParticleData *d, m_system->m_groupData[gId]->data){ if (!d || !d->stillAlive()){ m_lastEmission[d->index] = time; //Should only start emitting when it returns to life diff --git a/src/declarative/particles/qsgtrailemitter_p.h b/src/declarative/particles/qsgtrailemitter_p.h index 5ab6f2427096b2261a1fbc287a052c03a65a8fc7..009ccd508c06075f0818d9a64211edf9829fe141 100644 --- a/src/declarative/particles/qsgtrailemitter_p.h +++ b/src/declarative/particles/qsgtrailemitter_p.h @@ -94,7 +94,7 @@ public: } signals: - void emitFollowParticle(QDeclarativeV8Handle particle, QDeclarativeV8Handle followed); + void emitFollowParticle(QDeclarativeV8Handle group, QDeclarativeV8Handle followed); void particlesPerParticlePerSecondChanged(int arg);