blob: 34d3c51b61eeca3425b962aa931fc20cdbfc04c3 [file] [log] [blame]
Brian Osman7c979f52019-02-12 13:27:51 -05001/*
2* Copyright 2019 Google LLC
3*
4* Use of this source code is governed by a BSD-style license that can be
5* found in the LICENSE file.
6*/
7
8#ifndef SkParticleEffect_DEFINED
9#define SkParticleEffect_DEFINED
10
11#include "SkAutoMalloc.h"
12#include "SkColor.h"
13#include "SkCurve.h"
14#include "SkParticleData.h"
15#include "SkRandom.h"
16#include "SkRect.h"
17#include "SkRefCnt.h"
18#include "SkString.h"
19#include "SkTArray.h"
20
21class SkAnimTimer;
22class SkCanvas;
23class SkFieldVisitor;
24class SkImage;
25class SkParticleAffector;
26class SkParticleEmitter;
27struct SkRSXform;
28
29// TODO: Phase this out, once all properties are driven by the two-lists-of-affectors
30struct InitialVelocityParams {
31 float fAngle = 0.0f;
32 float fAngleSpread = 0.0f;
33 SkRangedFloat fStrength = { 0.0f, 0.0f };
34 bool fBidirectional = false;
35
36 SkRangedFloat fSpin = { 0.0f, 0.0f };
37 bool fBidirectionalSpin = false;
38
39 SkParticleVelocity eval(SkRandom& random) const;
40
41 void visitFields(SkFieldVisitor* v);
42};
43
44class SkParticleEffectParams : public SkRefCnt {
45public:
46 int fMaxCount = 128;
Brian Osman5c1f8eb2019-02-14 14:49:55 -050047 float fEffectDuration = 1.0f;
Brian Osman7c979f52019-02-12 13:27:51 -050048 float fRate = 8.0f;
49 SkRangedFloat fLifetime = { 1.0f, 1.0f };
50 SkColor4f fStartColor = { 1.0f, 1.0f, 1.0f, 1.0f };
51 SkColor4f fEndColor = { 1.0f, 1.0f, 1.0f, 1.0f };
52
53 SkCurve fSize = 1.0f;
54
55 // TODO: Add local vs. world copies of these
56 // Initial velocity controls
57 InitialVelocityParams fVelocity;
58
59 // Sprite image parameters
60 // TODO: Move sprite stuff in here, out of effect
61 SkString fImage;
62 int fImageCols = 1;
63 int fImageRows = 1;
64
65 // Emitter shape & parameters
66 sk_sp<SkParticleEmitter> fEmitter;
67
Brian Osman5c1f8eb2019-02-14 14:49:55 -050068 // Rules that configure particles at spawn time
69 SkTArray<sk_sp<SkParticleAffector>> fSpawnAffectors;
70
71 // Rules that update existing particles over their lifetime
72 SkTArray<sk_sp<SkParticleAffector>> fUpdateAffectors;
Brian Osman7c979f52019-02-12 13:27:51 -050073
74 void visitFields(SkFieldVisitor* v);
75};
76
77class SkParticleEffect : public SkRefCnt {
78public:
Brian Osman5c1f8eb2019-02-14 14:49:55 -050079 SkParticleEffect(sk_sp<SkParticleEffectParams> params, const SkRandom& random);
Brian Osman7c979f52019-02-12 13:27:51 -050080
Brian Osman5c1f8eb2019-02-14 14:49:55 -050081 void start(const SkAnimTimer& timer, bool looping = false);
82 void update(const SkAnimTimer& timer);
Brian Osman7c979f52019-02-12 13:27:51 -050083 void draw(SkCanvas* canvas);
84
Brian Osman5c1f8eb2019-02-14 14:49:55 -050085 bool isAlive() { return fSpawnTime >= 0; }
86
Brian Osman7c979f52019-02-12 13:27:51 -050087 SkParticleEffectParams* getParams() { return fParams.get(); }
88
89private:
90 void setCapacity(int capacity);
91
92 int spriteCount() const { return fParams->fImageCols * fParams->fImageRows; }
93 SkRect spriteRect(int i) const {
94 SkASSERT(i >= 0 && i < this->spriteCount());
95 int row = i / fParams->fImageCols;
96 int col = i % fParams->fImageCols;
97 return fImageRect.makeOffset(col * fImageRect.width(), row * fImageRect.height());
98 }
99 SkPoint spriteCenter() const {
100 return { fImageRect.width() * 0.5f, fImageRect.height() * 0.5f };
101 }
102
103 struct Particle {
104 double fTimeOfBirth;
105 double fTimeOfDeath;
106 SkRandom fStableRandom;
107
108 // Texture coord rects and colors are stored in parallel arrays for drawAtlas.
109 SkParticlePoseAndVelocity fPV;
110 };
111
112 sk_sp<SkParticleEffectParams> fParams;
113 sk_sp<SkImage> fImage;
114 SkRect fImageRect;
115
Brian Osman5c1f8eb2019-02-14 14:49:55 -0500116 SkRandom fRandom;
117
118 bool fLooping;
119 double fSpawnTime;
120
Brian Osman7c979f52019-02-12 13:27:51 -0500121 int fCount;
122 double fLastTime;
123 float fSpawnRemainder;
124
125 SkAutoTMalloc<Particle> fParticles;
126 SkAutoTMalloc<SkRSXform> fXforms;
127 SkAutoTMalloc<SkRect> fSpriteRects;
128 SkAutoTMalloc<SkColor> fColors;
129
130 // Cached
131 int fCapacity;
132};
133
134#endif // SkParticleEffect_DEFINED