Skip to content

Commit df18296

Browse files
brianosmanSkia Commit-Bot
authored andcommitted
Add accessors to get/set SkParticleEffect fields
Simplify burst handling. Scripts should just add to burst (if they want to handle programmatic bursting, as well). Update most effects to handle dynamic updates to position better, and add a sample effect meant to be used with mouse tracking. Change-Id: Ia302e1d04e62e2b07974807c44067786cc10a8ad Bug: skia:9513 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/248798 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
1 parent f22c57d commit df18296

File tree

10 files changed

+78
-21
lines changed

10 files changed

+78
-21
lines changed

modules/particles/include/SkParticleEffect.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,28 @@ class SkParticleEffect : public SkRefCnt {
156156
}
157157
int getCount() const { return fCount; }
158158

159+
float getRate() const { return fState.fRate; }
160+
int getBurst() const { return fState.fBurst; }
161+
SkPoint getPosition() const { return fState.fPosition; }
162+
SkVector getHeading() const { return fState.fHeading; }
163+
float getScale() const { return fState.fScale; }
164+
SkVector getVelocity() const { return fState.fVelocity; }
165+
float getSpin() const { return fState.fSpin; }
166+
SkColor4f getColor() const { return fState.fColor; }
167+
float getFrame() const { return fState.fFrame; }
168+
uint32_t getFlags() const { return fState.fFlags; }
169+
170+
void setRate (float r) { fState.fRate = r; }
171+
void setBurst (int b) { fState.fBurst = b; }
172+
void setPosition(SkPoint p) { fState.fPosition = p; }
173+
void setHeading (SkVector h) { fState.fHeading = h; }
174+
void setScale (float s) { fState.fScale = s; }
175+
void setVelocity(SkVector v) { fState.fVelocity = v; }
176+
void setSpin (float s) { fState.fSpin = s; }
177+
void setColor (SkColor4f c) { fState.fColor = c; }
178+
void setFrame (float f) { fState.fFrame = f; }
179+
void setFlags (uint32_t f) { fState.fFlags = f; }
180+
159181
static void RegisterParticleTypes();
160182

161183
private:
@@ -165,7 +187,7 @@ class SkParticleEffect : public SkRefCnt {
165187
void advanceTime(double now);
166188

167189
void processEffectSpawnRequests(double now);
168-
int runEffectScript(double now, const char* entry);
190+
void runEffectScript(double now, const char* entry);
169191

170192
void processParticleSpawnRequests(double now, int start);
171193
void runParticleScript(double now, const char* entry, int start, int count);

modules/particles/src/SkParticleEffect.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,7 @@ void SkParticleEffect::processEffectSpawnRequests(double now) {
226226
fSpawnRequests.reset();
227227
}
228228

229-
int SkParticleEffect::runEffectScript(double now, const char* entry) {
230-
fState.fBurst = 0;
229+
void SkParticleEffect::runEffectScript(double now, const char* entry) {
231230
if (const auto& byteCode = fParams->fEffectProgram.fByteCode) {
232231
if (auto fun = byteCode->getFunction(entry)) {
233232
for (const auto& value : fParams->fEffectProgram.fExternalValues) {
@@ -241,7 +240,6 @@ int SkParticleEffect::runEffectScript(double now, const char* entry) {
241240
this->processEffectSpawnRequests(now);
242241
}
243242
}
244-
return fState.fBurst;
245243
}
246244

247245
void SkParticleEffect::processParticleSpawnRequests(double now, int start) {
@@ -304,24 +302,22 @@ void SkParticleEffect::advanceTime(double now) {
304302
this->setCapacity(fParams->fMaxCount);
305303
}
306304

307-
int burstCount = 0;
308-
309305
// Is this the first update after calling start()?
310306
// Run 'effectSpawn' to set initial emitter properties.
311307
if (fState.fAge == 0.0f && fState.fLoopCount == 0) {
312-
burstCount += this->runEffectScript(now, "effectSpawn");
308+
this->runEffectScript(now, "effectSpawn");
313309
}
314310

315311
fState.fAge += fState.fDeltaTime / fState.fLifetime;
316312
if (fState.fAge > 1) {
317313
// We always run effectDeath when age crosses 1, whether we're looping or actually dying
318-
burstCount += this->runEffectScript(now, "effectDeath");
314+
this->runEffectScript(now, "effectDeath");
319315

320316
if (fLooping) {
321317
// If we looped, then run effectSpawn again (with the updated loop count)
322318
fState.fLoopCount += sk_float_floor2int(fState.fAge);
323319
fState.fAge = fmodf(fState.fAge, 1.0f);
324-
burstCount += this->runEffectScript(now, "effectSpawn");
320+
this->runEffectScript(now, "effectSpawn");
325321
} else {
326322
// Effect is dead if we've reached the end (and are not looping)
327323
return;
@@ -349,7 +345,7 @@ void SkParticleEffect::advanceTime(double now) {
349345
this->runParticleScript(now, "death", fCount, numDyingParticles);
350346

351347
// Run 'effectUpdate' to adjust emitter properties
352-
burstCount += this->runEffectScript(now, "effectUpdate");
348+
this->runEffectScript(now, "effectUpdate");
353349

354350
// Do integration of effect position and orientation
355351
{
@@ -362,10 +358,11 @@ void SkParticleEffect::advanceTime(double now) {
362358
}
363359

364360
// Spawn new particles
365-
float desired = fState.fRate * fState.fDeltaTime + fSpawnRemainder;
361+
float desired = fState.fRate * fState.fDeltaTime + fSpawnRemainder + fState.fBurst;
362+
fState.fBurst = 0;
366363
int numToSpawn = sk_float_round2int(desired);
367364
fSpawnRemainder = desired - numToSpawn;
368-
numToSpawn = SkTPin(numToSpawn + burstCount, 0, fParams->fMaxCount - fCount);
365+
numToSpawn = SkTPin(numToSpawn, 0, fParams->fMaxCount - fCount);
369366
if (numToSpawn) {
370367
const int spawnBase = fCount;
371368

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"MaxCount": 2000,
3+
"Drawable": {
4+
"Type": "SkCircleDrawable",
5+
"Radius": 4
6+
},
7+
"EffectCode": [
8+
"void effectSpawn(inout Effect effect) {",
9+
" effect.rate = 800;",
10+
"}",
11+
""
12+
],
13+
"Code": [
14+
"void spawn(inout Particle p) {",
15+
" p.lifetime = 2 + rand;",
16+
" float a = radians(rand * 360);",
17+
" p.vel = float2(cos(a), sin(a)) * mix(5, 15, rand);",
18+
" p.scale = mix(0.25, 0.75, rand);",
19+
"}",
20+
"",
21+
"void update(inout Particle p) {",
22+
" p.color.r = p.age;",
23+
" p.color.g = 1 - p.age;",
24+
"}",
25+
""
26+
],
27+
"Bindings": []
28+
}

resources/particles/sinusoidal_emitter.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
"}",
1111
"",
1212
"void effectUpdate(inout Effect effect) {",
13-
" effect.pos.y = sin(effect.age * 6.28) * 40;",
1413
"}",
1514
""
1615
],
1716
"Code": [
1817
"void spawn(inout Particle p) {",
18+
" p.pos.y += sin(effect.age * 6.28) * 40;",
1919
" p.lifetime = 2 + (rand * 2);",
2020
" p.vel.x = (30 * rand) + 50;",
2121
" p.vel.y = (20 * rand) - 10;",

resources/particles/sprite_frame.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@
2525
"",
2626
"void spawn(inout Particle p) {",
2727
" p.lifetime = 1.0 + rand * 2.0;",
28-
" p.pos = circle() * 60;",
29-
" p.vel = p.pos / 3;",
28+
" float2 ofs = circle() * 60;",
29+
" p.pos += ofs;",
30+
" p.vel = ofs / 3;",
3031
"}",
3132
"",
3233
"void update(inout Particle p) {",

resources/particles/text.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
" float s = mix(10, 30, rand);",
1818
" p.vel.x = cos(a) * s;",
1919
" p.vel.y = sin(a) * s;",
20-
" p.pos = text(rand).xy;",
20+
" p.pos += text(rand).xy;",
2121
"}",
2222
"",
2323
"void update(inout Particle p) {",

resources/particles/variable_rate.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
"void spawn(inout Particle p) {",
1515
" p.lifetime = 6;",
1616
" float a = radians(rand * 360);",
17-
" p.pos = float2(cos(a), sin(a)) * 40;",
18-
" p.vel = p.pos;",
17+
" float2 ofs = float2(cos(a), sin(a)) * 40;",
18+
" p.pos += ofs;",
19+
" p.vel = ofs;",
1920
" p.scale = 0.5;",
2021
"}",
2122
""

resources/particles/warp.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
"",
2424
"void spawn(inout Particle p) {",
2525
" p.lifetime = 30;",
26-
" p.pos = circle() * 40;",
26+
" p.pos += circle() * 40;",
2727
"}",
2828
"",
2929
"void update(inout Particle p) {",
30-
" p.vel += normalize(p.pos) * dt * 10;",
30+
" p.vel += normalize(p.pos - effect.pos) * dt * 10;",
3131
" p.scale = mix(0.25, 3, p.age);",
3232
"}",
3333
""

tools/viewer/ParticlesSlide.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ void ParticlesSlide::draw(SkCanvas* canvas) {
281281
if (fAnimated && ImGui::Button("Play")) {
282282
sk_sp<SkParticleEffect> effect(new SkParticleEffect(fLoaded[i].fParams, fRandom));
283283
effect->start(fAnimationTime, looped);
284-
fRunning.push_back({ fPlayPosition, fLoaded[i].fName, effect });
284+
fRunning.push_back({ fPlayPosition, fLoaded[i].fName, effect, false });
285285
fRandom.nextU();
286286
}
287287
ImGui::SameLine();
@@ -302,10 +302,17 @@ void ParticlesSlide::draw(SkCanvas* canvas) {
302302
if (ImGui::Begin("Running")) {
303303
for (int i = 0; i < fRunning.count(); ++i) {
304304
ImGui::PushID(i);
305+
ImGui::Checkbox("##Track", &fRunning[i].fTrackMouse);
306+
ImGui::SameLine();
305307
bool remove = ImGui::Button("X") || !fRunning[i].fEffect->isAlive();
306308
ImGui::SameLine();
307309
ImGui::Text("%4g, %4g %5d %s", fRunning[i].fPosition.fX, fRunning[i].fPosition.fY,
308310
fRunning[i].fEffect->getCount(), fRunning[i].fName.c_str());
311+
if (fRunning[i].fTrackMouse) {
312+
fRunning[i].fEffect->setPosition({ ImGui::GetMousePos().x,
313+
ImGui::GetMousePos().y });
314+
fRunning[i].fPosition.set(0, 0);
315+
}
309316
if (remove) {
310317
fRunning.removeShuffle(i);
311318
}

tools/viewer/ParticlesSlide.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class ParticlesSlide : public Slide {
4949
SkPoint fPosition;
5050
SkString fName;
5151
sk_sp<SkParticleEffect> fEffect;
52+
bool fTrackMouse;
5253
};
5354
SkTArray<RunningEffect> fRunning;
5455
};

0 commit comments

Comments
 (0)