blob: 83d5fb08963000a167f0d219ebdda425406bd7f8 [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;
47 float fRate = 8.0f;
48 SkRangedFloat fLifetime = { 1.0f, 1.0f };
49 SkColor4f fStartColor = { 1.0f, 1.0f, 1.0f, 1.0f };
50 SkColor4f fEndColor = { 1.0f, 1.0f, 1.0f, 1.0f };
51
52 SkCurve fSize = 1.0f;
53
54 // TODO: Add local vs. world copies of these
55 // Initial velocity controls
56 InitialVelocityParams fVelocity;
57
58 // Sprite image parameters
59 // TODO: Move sprite stuff in here, out of effect
60 SkString fImage;
61 int fImageCols = 1;
62 int fImageRows = 1;
63
64 // Emitter shape & parameters
65 sk_sp<SkParticleEmitter> fEmitter;
66
67 // Update rules
68 SkTArray<sk_sp<SkParticleAffector>> fAffectors;
69
70 void visitFields(SkFieldVisitor* v);
71};
72
73class SkParticleEffect : public SkRefCnt {
74public:
75 SkParticleEffect(sk_sp<SkParticleEffectParams> params);
76
77 void update(SkRandom& random, const SkAnimTimer& timer);
78 void draw(SkCanvas* canvas);
79
80 SkParticleEffectParams* getParams() { return fParams.get(); }
81
82private:
83 void setCapacity(int capacity);
84
85 int spriteCount() const { return fParams->fImageCols * fParams->fImageRows; }
86 SkRect spriteRect(int i) const {
87 SkASSERT(i >= 0 && i < this->spriteCount());
88 int row = i / fParams->fImageCols;
89 int col = i % fParams->fImageCols;
90 return fImageRect.makeOffset(col * fImageRect.width(), row * fImageRect.height());
91 }
92 SkPoint spriteCenter() const {
93 return { fImageRect.width() * 0.5f, fImageRect.height() * 0.5f };
94 }
95
96 struct Particle {
97 double fTimeOfBirth;
98 double fTimeOfDeath;
99 SkRandom fStableRandom;
100
101 // Texture coord rects and colors are stored in parallel arrays for drawAtlas.
102 SkParticlePoseAndVelocity fPV;
103 };
104
105 sk_sp<SkParticleEffectParams> fParams;
106 sk_sp<SkImage> fImage;
107 SkRect fImageRect;
108
109 int fCount;
110 double fLastTime;
111 float fSpawnRemainder;
112
113 SkAutoTMalloc<Particle> fParticles;
114 SkAutoTMalloc<SkRSXform> fXforms;
115 SkAutoTMalloc<SkRect> fSpriteRects;
116 SkAutoTMalloc<SkColor> fColors;
117
118 // Cached
119 int fCapacity;
120};
121
122#endif // SkParticleEffect_DEFINED