aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2011-09-13 09:39:11 +1000
committerQt by Nokia <qt-info@nokia.com>2011-09-13 04:53:33 +0200
commit29993ff8e91715bdfbaf964c91e07a112f6d2a24 (patch)
tree46a7b25ba1091f1d6ada9decaa9bf9d77d3a8004
parent4dba5720e03542e0989adad2461358074c7d0dee (diff)
Refactor SpriteEngine out of StochasticEngine
Also add ParticleGroups which use only StochasticStates Simplistic change for now, just to focus the API for the particle system. ParticleGroup elements replace the particleStates property on the system, and the term "group" is now used more consistently. Change-Id: I6456f9c521b8166ccd94ea953275557bcfbf6423 Reviewed-on: http://codereview.qt-project.org/4699 Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
-rw-r--r--examples/declarative/animation/basics/color-animation.qml4
-rw-r--r--examples/declarative/flickr/flickr.qml6
-rw-r--r--examples/declarative/minehunt/MinehuntCore/Explosion.qml4
-rw-r--r--examples/declarative/particles/allsmiles/smilefactory.qml10
-rw-r--r--examples/declarative/particles/allsmiles/spriteparticles.qml8
-rw-r--r--examples/declarative/particles/asteroid/asteroid.qml14
-rw-r--r--examples/declarative/particles/asteroid/blackhole.qml16
-rw-r--r--examples/declarative/particles/trails/combustion.qml116
-rw-r--r--examples/declarative/particles/trails/fireballs.qml16
-rw-r--r--examples/declarative/particles/trails/fireworks.qml62
-rw-r--r--examples/declarative/particles/trails/portal.qml6
-rw-r--r--examples/declarative/particles/trails/turbulence.qml10
-rw-r--r--examples/declarative/plasmapatrol/content/BlasterHardpoint.qml4
-rw-r--r--examples/declarative/plasmapatrol/content/CannonHardpoint.qml4
-rw-r--r--examples/declarative/plasmapatrol/content/Cruiser.qml6
-rw-r--r--examples/declarative/plasmapatrol/content/Frigate.qml4
-rw-r--r--examples/declarative/plasmapatrol/content/LaserHardpoint.qml4
-rw-r--r--examples/declarative/plasmapatrol/content/PlasmaPatrolParticles.qml24
-rw-r--r--examples/declarative/plasmapatrol/content/Sloop.qml2
-rw-r--r--examples/declarative/plasmapatrol/plasmapatrol.qml2
-rw-r--r--examples/declarative/samegame/SamegameCore/BoomBlock.qml2
-rw-r--r--examples/declarative/samegame/SamegameCore/GameArea.qml6
-rw-r--r--examples/declarative/snake/content/Cookie.qml4
-rw-r--r--examples/declarative/snake/content/Link.qml4
-rw-r--r--examples/declarative/toys/dynamicscene/dynamicscene.qml4
-rw-r--r--src/declarative/items/qsgsprite.cpp27
-rw-r--r--src/declarative/items/qsgsprite_p.h114
-rw-r--r--src/declarative/items/qsgspriteengine.cpp112
-rw-r--r--src/declarative/items/qsgspriteengine_p.h204
-rw-r--r--src/declarative/items/qsgspriteimage.cpp2
-rw-r--r--src/declarative/particles/particles.pri6
-rw-r--r--src/declarative/particles/qsgcustomparticle.cpp2
-rw-r--r--src/declarative/particles/qsgimageparticle.cpp6
-rw-r--r--src/declarative/particles/qsgimageparticle_p.h4
-rw-r--r--src/declarative/particles/qsgitemparticle.cpp2
-rw-r--r--src/declarative/particles/qsgparticleaffector.cpp18
-rw-r--r--src/declarative/particles/qsgparticleaffector_p.h20
-rw-r--r--src/declarative/particles/qsgparticleemitter.cpp6
-rw-r--r--src/declarative/particles/qsgparticleemitter_p.h18
-rw-r--r--src/declarative/particles/qsgparticlegroup.cpp142
-rw-r--r--src/declarative/particles/qsgparticlegroup_p.h107
-rw-r--r--src/declarative/particles/qsgparticlepainter.cpp6
-rw-r--r--src/declarative/particles/qsgparticlepainter_p.h18
-rw-r--r--src/declarative/particles/qsgparticlesmodule.cpp2
-rw-r--r--src/declarative/particles/qsgparticlesystem.cpp117
-rw-r--r--src/declarative/particles/qsgparticlesystem_p.h13
-rw-r--r--src/declarative/particles/qsgspritegoal.cpp12
-rw-r--r--src/declarative/particles/qsgspritegoal_p.h6
-rw-r--r--src/declarative/particles/qsgtrailemitter.cpp2
-rw-r--r--src/declarative/particles/qsgtrailemitter_p.h2
50 files changed, 803 insertions, 507 deletions
diff --git a/examples/declarative/animation/basics/color-animation.qml b/examples/declarative/animation/basics/color-animation.qml
index a83dbab569..9e0f29c4ec 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 14e4fcaedf..4397d0ad76 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 225c19d8a3..af98ad1309 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 fe651491b9..4b01862f99 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 705016e050..0586dfd8db 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 ea2fabd51d..6d556997c7 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 7e8a7a9edc..00fca7ef3c 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 e4a21e9beb..238dbe8a79 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 97a0c0ac5f..c7c0420049 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 437d9ee3d6..6b370b3991 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 85efd9a594..adf620fd9b 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 104bb10e80..13eae162f4 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 384275fc94..3e751f4e15 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 b2c7aca1fd..dc15f0cae1 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 b0d20023db..a4983fc2a0 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 8d493b81d5..f26e7e881c 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 45712bf68a..56fd91b5b3 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 792ba7ab72..7a8c3e61b3 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 82e57f5161..59678a75ea 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 4ea464b9f8..2fa9f44929 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 1c84fa8614..df3e9bd8fa 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 967e299577..9a8f68ad89 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 e3b3bbf3f5..d9fedd9436 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 82e0359a1a..31ad62248c 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 5670aacfa7..179d633c97 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 806f7a9ad8..63d1951b7c 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 c18e9b4505..ed7c6c4be4 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 1915db6000..0391ce1281 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 10860a51f1..b2a06f2c87 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 afa80e4aa1..5557ea564a 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 527bd9ae61..8676e52172 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 ab4cfa0a3a..a1d65a5360 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 581024d578..b1aef784e8 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 01eacbad99..1f87b16f63 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 c330880980..2572d67783 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 cff3c29444..7cb4869f3e 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 5700969aad..0dadeff6a7 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 13ab3e6185..fdba3def41 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 8ed7ee7053..8bd205b207 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 0000000000..28eb4d2c85
--- /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 0000000000..346b4ab77e
--- /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 f4639c20a2..670c1f2118 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 08ae3aede8..d469947453 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 9fa0ebad97..f880842acb 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 085e6afe64..bc27073142 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 25a0c87f53..f531e7fcf9 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 1837167813..ec2be02326 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 7c799b13b1..043970b90b 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 427b587caf..5a19ac508b 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 5ab6f24270..009ccd508c 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);