aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);