blob: 22fb683536062100c63d4f2fe69d7ac182b6bb54 [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
Brian Osman7c979f52019-02-12 13:27:51 -050029class SkParticleEffectParams : public SkRefCnt {
30public:
Brian Osman8b6283f2019-02-14 16:55:21 -050031 int fMaxCount = 128;
32 float fEffectDuration = 1.0f;
33 float fRate = 8.0f;
34 SkCurve fLifetime = 1.0f;
35 SkColor4f fStartColor = { 1.0f, 1.0f, 1.0f, 1.0f };
36 SkColor4f fEndColor = { 1.0f, 1.0f, 1.0f, 1.0f };
Brian Osman7c979f52019-02-12 13:27:51 -050037
38 // Sprite image parameters
39 // TODO: Move sprite stuff in here, out of effect
40 SkString fImage;
41 int fImageCols = 1;
42 int fImageRows = 1;
43
44 // Emitter shape & parameters
45 sk_sp<SkParticleEmitter> fEmitter;
46
Brian Osman5c1f8eb2019-02-14 14:49:55 -050047 // Rules that configure particles at spawn time
48 SkTArray<sk_sp<SkParticleAffector>> fSpawnAffectors;
49
50 // Rules that update existing particles over their lifetime
51 SkTArray<sk_sp<SkParticleAffector>> fUpdateAffectors;
Brian Osman7c979f52019-02-12 13:27:51 -050052
53 void visitFields(SkFieldVisitor* v);
54};
55
56class SkParticleEffect : public SkRefCnt {
57public:
Brian Osman5c1f8eb2019-02-14 14:49:55 -050058 SkParticleEffect(sk_sp<SkParticleEffectParams> params, const SkRandom& random);
Brian Osman7c979f52019-02-12 13:27:51 -050059
Brian Osman5c1f8eb2019-02-14 14:49:55 -050060 void start(const SkAnimTimer& timer, bool looping = false);
61 void update(const SkAnimTimer& timer);
Brian Osman7c979f52019-02-12 13:27:51 -050062 void draw(SkCanvas* canvas);
63
Brian Osman5c1f8eb2019-02-14 14:49:55 -050064 bool isAlive() { return fSpawnTime >= 0; }
65
Brian Osman7c979f52019-02-12 13:27:51 -050066 SkParticleEffectParams* getParams() { return fParams.get(); }
67
68private:
69 void setCapacity(int capacity);
70
71 int spriteCount() const { return fParams->fImageCols * fParams->fImageRows; }
72 SkRect spriteRect(int i) const {
73 SkASSERT(i >= 0 && i < this->spriteCount());
74 int row = i / fParams->fImageCols;
75 int col = i % fParams->fImageCols;
76 return fImageRect.makeOffset(col * fImageRect.width(), row * fImageRect.height());
77 }
78 SkPoint spriteCenter() const {
79 return { fImageRect.width() * 0.5f, fImageRect.height() * 0.5f };
80 }
81
82 struct Particle {
83 double fTimeOfBirth;
84 double fTimeOfDeath;
85 SkRandom fStableRandom;
86
87 // Texture coord rects and colors are stored in parallel arrays for drawAtlas.
88 SkParticlePoseAndVelocity fPV;
89 };
90
91 sk_sp<SkParticleEffectParams> fParams;
92 sk_sp<SkImage> fImage;
93 SkRect fImageRect;
94
Brian Osman5c1f8eb2019-02-14 14:49:55 -050095 SkRandom fRandom;
96
97 bool fLooping;
98 double fSpawnTime;
99
Brian Osman7c979f52019-02-12 13:27:51 -0500100 int fCount;
101 double fLastTime;
102 float fSpawnRemainder;
103
104 SkAutoTMalloc<Particle> fParticles;
105 SkAutoTMalloc<SkRSXform> fXforms;
106 SkAutoTMalloc<SkRect> fSpriteRects;
107 SkAutoTMalloc<SkColor> fColors;
108
109 // Cached
110 int fCapacity;
111};
112
113#endif // SkParticleEffect_DEFINED