1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_RENDER_PARTICLE_H
16 #define RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_RENDER_PARTICLE_H
17 
18 #include <memory>
19 #include <sys/types.h>
20 #include <utility>
21 #include <vector>
22 
23 #include "pixel_map.h"
24 
25 #include "animation/rs_interpolator.h"
26 #include "common/rs_color.h"
27 #include "common/rs_color_palette.h"
28 #include "common/rs_macros.h"
29 #include "common/rs_vector2.h"
30 #include "render/rs_image.h"
31 
32 namespace OHOS {
33 namespace Rosen {
34 enum class ParticleUpdator: uint32_t {NONE = 0, RANDOM, CURVE};
35 
36 enum class ShapeType: uint32_t {RECT = 0, CIRCLE, ELLIPSE};
37 
38 enum class ParticleType: uint32_t {POINTS = 0, IMAGES};
39 
40 enum class DistributionType: uint32_t {UNIFORM = 0, GAUSSIAN};
41 
42 template<typename T>
43 struct Range {
44     T start_, end_;
RangeRange45     Range() : start_(), end_() {}
RangeRange46     Range(T a, T b) : start_(a), end_(b) {}
47 
WidthRange48     T Width() const
49     {
50         return end_ - start_;
51     }
52 };
53 
54 template<typename T>
55 class RSB_EXPORT ChangeInOverLife {
56 public:
57     T fromValue_;
58     T toValue_;
59     int startMillis_ { 0 };
60     int endMillis_ { 0 };
61     std::shared_ptr<RSInterpolator> interpolator_ = nullptr;
ChangeInOverLife()62     ChangeInOverLife() : fromValue_(), toValue_(), startMillis_(), endMillis_(), interpolator_() {}
ChangeInOverLife(const T & fromValue,const T & toValue,const int & startMillis,const int & endMillis,std::shared_ptr<RSInterpolator> interpolator)63     ChangeInOverLife(const T& fromValue, const T& toValue, const int& startMillis, const int& endMillis,
64         std::shared_ptr<RSInterpolator> interpolator)
65         : fromValue_(fromValue), toValue_(toValue), startMillis_(startMillis), endMillis_(endMillis),
66           interpolator_(std::move(interpolator))
67     {}
68     ChangeInOverLife(const ChangeInOverLife& change) = default;
69     ChangeInOverLife& operator=(const ChangeInOverLife& change) = default;
70     ~ChangeInOverLife() = default;
71 };
72 
73 template<typename T>
74 class RSB_EXPORT RenderParticleParaType {
75 public:
76     Range<T> val_;
77     ParticleUpdator updator_;
78     Range<float> random_;
79     std::vector<std::shared_ptr<ChangeInOverLife<T>>> valChangeOverLife_;
RenderParticleParaType(const Range<T> & val,const ParticleUpdator & updator,const Range<float> & random,const std::vector<std::shared_ptr<ChangeInOverLife<T>>> & valChangeOverLife)80     RenderParticleParaType(const Range<T>& val, const ParticleUpdator& updator, const Range<float>& random,
81         const std::vector<std::shared_ptr<ChangeInOverLife<T>>>& valChangeOverLife)
82         : val_(val), updator_(updator), random_(random), valChangeOverLife_(valChangeOverLife)
83     {}
RenderParticleParaType()84     RenderParticleParaType() : val_(), updator_(ParticleUpdator::NONE), random_() {}
85     RenderParticleParaType(const RenderParticleParaType& paraType) = default;
86     RenderParticleParaType& operator=(const RenderParticleParaType& paraType) = default;
87     ~RenderParticleParaType() = default;
88 };
89 
90 class RSB_EXPORT EmitterConfig {
91 public:
92     int emitRate_ { 0 };
93     ShapeType emitShape_;
94     Vector2f position_;
95     Vector2f emitSize_;
96     int32_t particleCount_ { 0 };
97     Range<int64_t> lifeTime_;
98     ParticleType type_;
99     float radius_ { 0.0 };
100     std::shared_ptr<RSImage> image_;
101     Vector2f imageSize_;
102 
EmitterConfig()103     EmitterConfig()
104         : emitRate_(), emitShape_(ShapeType::RECT), position_(), emitSize_(), particleCount_(), lifeTime_(),
105           type_(ParticleType::POINTS), radius_(), image_(), imageSize_()
106     {}
EmitterConfig(const int & emitRate,const ShapeType & emitShape,const Vector2f & position,const Vector2f & emitSize,const int32_t & particleCount,const Range<int64_t> & lifeTime,const ParticleType & type,const float & radius,const std::shared_ptr<RSImage> & image,const Vector2f & imageSize)107     EmitterConfig(const int& emitRate, const ShapeType& emitShape, const Vector2f& position, const Vector2f& emitSize,
108         const int32_t& particleCount, const Range<int64_t>& lifeTime, const ParticleType& type, const float& radius,
109         const std::shared_ptr<RSImage>& image, const Vector2f& imageSize)
110         : emitRate_(emitRate), emitShape_(emitShape), position_(position), emitSize_(emitSize),
111           particleCount_(particleCount), lifeTime_(lifeTime), type_(type), radius_(radius), image_(std::move(image)),
112           imageSize_(imageSize)
113     {
114         if (image_ != nullptr) {
115             if (const auto& pixelMap = image_->GetPixelMap()) {
116                 image_->SetDstRect(RectF(position_.x_, position_.y_, static_cast<float>(pixelMap->GetWidth()),
117                     static_cast<float>(pixelMap->GetHeight())));
118             }
119         }
120     }
121     EmitterConfig(const EmitterConfig& config) = default;
122     EmitterConfig& operator=(const EmitterConfig& config) = default;
123     ~EmitterConfig() = default;
124 };
125 
126 class RSB_EXPORT EmitterUpdater {
127 public:
128     uint32_t emitterIndex_ { 0 };
129     std::optional<Vector2f> position_;
130     std::optional<Vector2f> emitSize_;
131     std::optional<int> emitRate_;
132 
133     explicit EmitterUpdater(
134         uint32_t emitterIndex,
135         const std::optional<Vector2f>& position = std::nullopt,
136         const std::optional<Vector2f>& emitSize = std::nullopt,
137         const std::optional<int>& emitRate = std::nullopt)
138         : emitterIndex_(emitterIndex), position_(position), emitSize_(emitSize), emitRate_(emitRate)
139     {}
140     EmitterUpdater(const EmitterUpdater& config) = default;
141     EmitterUpdater& operator=(const EmitterUpdater& config) = default;
142     ~EmitterUpdater() = default;
143 
144     void Dump(std::string& out) const;
145 };
146 
147 class RSB_EXPORT ParticleVelocity {
148 public:
149     Range<float> velocityValue_;
150     Range<float> velocityAngle_;
151 
ParticleVelocity()152     ParticleVelocity() : velocityValue_(), velocityAngle_() {}
ParticleVelocity(const Range<float> & velocityValue,const Range<float> & velocityAngle)153     ParticleVelocity(const Range<float>& velocityValue, const Range<float>& velocityAngle)
154         : velocityValue_(velocityValue), velocityAngle_(velocityAngle)
155     {}
156     ParticleVelocity(const ParticleVelocity& velocity) = default;
157     ParticleVelocity& operator=(const ParticleVelocity& velocity) = default;
158     ~ParticleVelocity() = default;
159 };
160 
161 class RSB_EXPORT RenderParticleAcceleration {
162 public:
163     RenderParticleParaType<float> accelerationValue_;
164     RenderParticleParaType<float> accelerationAngle_;
165 
166     RenderParticleAcceleration() = default;
RenderParticleAcceleration(const RenderParticleParaType<float> & accelerationValue,const RenderParticleParaType<float> & accelerationAngle)167     RenderParticleAcceleration(
168         const RenderParticleParaType<float>& accelerationValue, const RenderParticleParaType<float>& accelerationAngle)
169         : accelerationValue_(accelerationValue), accelerationAngle_(accelerationAngle)
170     {}
171     RenderParticleAcceleration(const RenderParticleAcceleration& acceleration) = default;
172     RenderParticleAcceleration& operator=(const RenderParticleAcceleration& acceleration) = default;
173     ~RenderParticleAcceleration() = default;
174 };
175 
176 class RSB_EXPORT RenderParticleColorParaType {
177 public:
178     Range<Color> colorVal_;
179     DistributionType distribution_;
180     ParticleUpdator updator_;
181     Range<float> redRandom_;
182     Range<float> greenRandom_;
183     Range<float> blueRandom_;
184     Range<float> alphaRandom_;
185 
186     std::vector<std::shared_ptr<ChangeInOverLife<Color>>> valChangeOverLife_;
RenderParticleColorParaType(const Range<Color> & colorVal,const DistributionType & distribution,const ParticleUpdator & updator,const Range<float> & redRandom,const Range<float> & greenRandom,const Range<float> & blueRandom,const Range<float> & alphaRandom,std::vector<std::shared_ptr<ChangeInOverLife<Color>>> valChangeOverLife)187     RenderParticleColorParaType(const Range<Color>& colorVal, const DistributionType& distribution,
188         const ParticleUpdator& updator, const Range<float>& redRandom, const Range<float>& greenRandom,
189         const Range<float>& blueRandom, const Range<float>& alphaRandom,
190         std::vector<std::shared_ptr<ChangeInOverLife<Color>>> valChangeOverLife)
191         : colorVal_(colorVal), distribution_(distribution), updator_(updator), redRandom_(redRandom),
192           greenRandom_(greenRandom), blueRandom_(blueRandom), alphaRandom_(alphaRandom),
193           valChangeOverLife_(std::move(valChangeOverLife))
194     {}
RenderParticleColorParaType()195     RenderParticleColorParaType()
196         : colorVal_(), distribution_(DistributionType::UNIFORM), updator_(ParticleUpdator::NONE), redRandom_(),
197           greenRandom_(), blueRandom_(), alphaRandom_()
198     {}
199     RenderParticleColorParaType(const RenderParticleColorParaType& color) = default;
200     RenderParticleColorParaType& operator=(const RenderParticleColorParaType& color) = default;
201     ~RenderParticleColorParaType() = default;
202 };
203 
204 class RSB_EXPORT ParticleRenderParams {
205 public:
206     EmitterConfig emitterConfig_;
207     ParticleVelocity velocity_;
208     RenderParticleAcceleration acceleration_;
209     RenderParticleColorParaType color_;
210     RenderParticleParaType<float> opacity_;
211     RenderParticleParaType<float> scale_;
212     RenderParticleParaType<float> spin_;
ParticleRenderParams(const EmitterConfig & emitterConfig,const ParticleVelocity & velocity,const RenderParticleAcceleration & acceleration,const RenderParticleColorParaType & color,const RenderParticleParaType<float> & opacity,const RenderParticleParaType<float> & scale,const RenderParticleParaType<float> & spin)213     explicit ParticleRenderParams(const EmitterConfig& emitterConfig, const ParticleVelocity& velocity,
214         const RenderParticleAcceleration& acceleration, const RenderParticleColorParaType& color,
215         const RenderParticleParaType<float>& opacity, const RenderParticleParaType<float>& scale,
216         const RenderParticleParaType<float>& spin)
217         : emitterConfig_(emitterConfig), velocity_(velocity), acceleration_(acceleration), color_(color),
218           opacity_(opacity), scale_(scale), spin_(spin)
219     {}
ParticleRenderParams()220     ParticleRenderParams() : emitterConfig_(), velocity_(), acceleration_(), color_(), opacity_(), scale_(), spin_() {};
221     ParticleRenderParams(const ParticleRenderParams& params) = default;
222     ParticleRenderParams& operator=(const ParticleRenderParams& params) = default;
223     ~ParticleRenderParams() = default;
224 
225     int GetEmitRate() const;
226     const ShapeType& GetEmitShape() const;
227     const Vector2f& GetEmitPosition() const;
228     const Vector2f& GetEmitSize() const;
229     int32_t GetParticleCount() const;
230     int64_t GetLifeTimeStartValue() const;
231     int64_t GetLifeTimeEndValue() const;
232     const ParticleType& GetParticleType() const;
233     float GetParticleRadius() const;
234     const std::shared_ptr<RSImage>& GetParticleImage();
235     const Vector2f& GetImageSize() const;
236 
237     float GetVelocityStartValue() const;
238     float GetVelocityEndValue() const;
239     float GetVelocityStartAngle() const;
240     float GetVelocityEndAngle() const;
241 
242     float GetAccelerationStartValue() const;
243     float GetAccelerationEndValue() const;
244     float GetAccelerationStartAngle() const;
245     float GetAccelerationEndAngle() const;
246     const ParticleUpdator& GetAccelerationValueUpdator();
247     const ParticleUpdator& GetAccelerationAngleUpdator();
248     float GetAccelRandomValueStart() const;
249     float GetAccelRandomValueEnd() const;
250     float GetAccelRandomAngleStart() const;
251     float GetAccelRandomAngleEnd() const;
252 
253     const Color& GetColorStartValue();
254     const Color& GetColorEndValue();
255     const DistributionType& GetColorDistribution();
256     const ParticleUpdator& GetColorUpdator();
257     float GetRedRandomStart() const;
258     float GetRedRandomEnd() const;
259     float GetGreenRandomStart() const;
260     float GetGreenRandomEnd() const;
261     float GetBlueRandomStart() const;
262     float GetBlueRandomEnd() const;
263     float GetAlphaRandomStart() const;
264     float GetAlphaRandomEnd() const;
265 
266     float GetOpacityStartValue();
267     float GetOpacityEndValue();
268     const ParticleUpdator& GetOpacityUpdator();
269     float GetOpacityRandomStart() const;
270     float GetOpacityRandomEnd() const;
271 
272     float GetScaleStartValue();
273     float GetScaleEndValue();
274     const ParticleUpdator& GetScaleUpdator();
275     float GetScaleRandomStart() const;
276     float GetScaleRandomEnd() const;
277 
278     float GetSpinStartValue();
279     float GetSpinEndValue();
280     const ParticleUpdator& GetSpinUpdator();
281 
282     const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& GetAcceValChangeOverLife();
283     const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& GetAcceAngChangeOverLife();
284     const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& GetOpacityChangeOverLife();
285     const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& GetScaleChangeOverLife();
286     const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& GetSpinChangeOverLife();
287     const std::vector<std::shared_ptr<ChangeInOverLife<Color>>>& GetColorChangeOverLife();
288 
289     float GetSpinRandomStart() const;
290     float GetSpinRandomEnd() const;
291     size_t GetImageIndex() const;
292 
293     void SetEmitConfig(const EmitterConfig& emitConfig);
294     void SetParticleVelocity(const ParticleVelocity& velocity);
295     void SetParticleAcceleration(const RenderParticleAcceleration& acceleration);
296     void SetParticleColor(const RenderParticleColorParaType& color);
297     void SetParticleOpacity(const RenderParticleParaType<float>& opacity);
298     void SetParticleScale(const RenderParticleParaType<float>& scale);
299     void SetParticleSpin(const RenderParticleParaType<float>& spin);
300     void SetImageIndex(size_t imageIndex);
301 
302 private:
303     size_t imageIndex_ = 0;
304 };
305 
306 class RSB_EXPORT RSRenderParticle {
307 public:
308     explicit RSRenderParticle(const std::shared_ptr<ParticleRenderParams>& particleParams);
309     RSRenderParticle() = default;
310     ~RSRenderParticle() = default;
311     // Set methods
312     void SetPosition(const Vector2f& position);
313     void SetVelocity(const Vector2f& velocity);
314     void SetAcceleration(const Vector2f& acceleration);
315     void SetSpin(const float& spin);
316     void SetOpacity(const float& opacity);
317     void SetColor(const Color& color);
318     void SetScale(const float& scale);
319     void SetRadius(const float& radius);
320     void SetImage(const std::shared_ptr<RSImage>& image);
321     void SetImageSize(const Vector2f& imageSize);
322     void SetParticleType(const ParticleType& particleType);
323     void SetActiveTime(const int64_t& activeTime);
324     void SetAccelerationValue(float accelerationValue);
325     void SetAccelerationAngle(float accelerationAngle);
326     void SetRedF(float redF);
327     void SetGreenF(float greenF);
328     void SetBlueF(float blueF);
329     void SetAlphaF(float alphaF);
330 
331     // Get methods
332     const Vector2f& GetPosition();
333     const Vector2f& GetVelocity();
334     const Vector2f& GetAcceleration();
335     float GetSpin();
336     float GetOpacity();
337     const Color& GetColor();
338     float GetScale();
339     float GetRadius();
340     float GetAccelerationValue();
341     float GetAccelerationAngle();
342     float GetRedSpeed();
343     float GetGreenSpeed();
344     float GetBlueSpeed();
345     float GetAlphaSpeed();
346     float GetOpacitySpeed();
347     float GetScaleSpeed();
348     float GetSpinSpeed();
349     float GetAccelerationValueSpeed();
350     float GetAccelerationAngleSpeed();
351     float GetRedF();
352     float GetGreenF();
353     float GetBlueF();
354     float GetAlphaF();
355     const std::shared_ptr<RSImage>& GetImage();
356     const Vector2f& GetImageSize();
357     const ParticleType& GetParticleType();
358     int64_t GetActiveTime();
359     const std::shared_ptr<ParticleRenderParams>& GetParticleRenderParams();
360 
361     size_t GetImageIndex() const;
362 
363     // Other methods
364     void InitProperty();
365     bool IsAlive() const;
366     void SetIsDead();
367     static float GetRandomValue(float min, float max);
368     void SetColor();
369     int GenerateColorComponent(double mean, double stddev);
370     Vector2f CalculateParticlePosition(const ShapeType& emitShape, const Vector2f& position, const Vector2f& emitSize);
371     std::shared_ptr<ParticleRenderParams> particleParams_;
372 
373     bool operator==(const RSRenderParticle& rhs)
374     {
375         return (position_ == rhs.position_) && (velocity_ == rhs.velocity_) && (acceleration_ == rhs.acceleration_) &&
376                (scale_ == rhs.scale_) && (spin_ == rhs.spin_) && (opacity_ == rhs.opacity_) && (color_ == rhs.color_) &&
377                (radius_ == rhs.radius_) && (particleType_ == rhs.particleType_) && (activeTime_ == rhs.activeTime_) &&
378                (lifeTime_ == rhs.lifeTime_) && (imageSize_ == rhs.imageSize_) && (imageIndex_ == rhs.imageIndex_);
379     }
380 
Lerp(const Color & start,const Color & end,float t)381     static Color Lerp(const Color& start, const Color& end, float t)
382     {
383         Color result;
384         result.SetRed(start.GetRed() + static_cast<int>(std::round((end.GetRed() - start.GetRed()) * t)));
385         result.SetGreen(start.GetGreen() + static_cast<int>(std::round((end.GetGreen() - start.GetGreen()) * t)));
386         result.SetBlue(start.GetBlue() + static_cast<int>(std::round((end.GetBlue() - start.GetBlue()) * t)));
387         result.SetAlpha(start.GetAlpha() + static_cast<int>(std::round((end.GetAlpha() - start.GetAlpha()) * t)));
388         return result;
389     }
390 
391 private:
392     Vector2f position_ = {0.f, 0.f};
393     Vector2f velocity_ = {0.f, 0.f};
394     Vector2f acceleration_ = {0.f, 0.f};
395     float scale_ = 1.f;
396     float spin_ = 0.f;
397     float opacity_ = 1.f;
398     Color color_ = RgbPalette::White();
399     float radius_ = 0.f;
400     std::shared_ptr<RSImage> image_;
401     Vector2f imageSize_;
402     ParticleType particleType_ = ParticleType::POINTS;
403     int64_t activeTime_ = 0;
404     int64_t lifeTime_ = 0;
405     bool dead_ = false;
406     float accelerationValue_ = 0.f;
407     float accelerationAngle_ = 0.f;
408     float redSpeed_ = 0.f;
409     float greenSpeed_ = 0.f;
410     float blueSpeed_ = 0.f;
411     float alphaSpeed_ = 0.f;
412     float opacitySpeed_ = 0.f;
413     float scaleSpeed_ = 0.f;
414     float spinSpeed_ = 0.f;
415     float accelerationValueSpeed_ = 0.f;
416     float accelerationAngleSpeed_ = 0.f;
417     float redF_ = 0.f;
418     float greenF_ = 0.f;
419     float blueF_ = 0.f;
420     float alphaF_ = 0.f;
421     size_t imageIndex_ = 0;
422 };
423 
424 class RSB_EXPORT RSRenderParticleVector {
425 public:
RSRenderParticleVector(std::vector<std::shared_ptr<RSRenderParticle>> && renderParticleVector,std::vector<std::shared_ptr<RSImage>> imageVector)426     explicit RSRenderParticleVector(std::vector<std::shared_ptr<RSRenderParticle>>&& renderParticleVector,
427         std::vector<std::shared_ptr<RSImage>> imageVector)
428         : renderParticleVector_(std::move(renderParticleVector)), imageVector_(std::move(imageVector))
429     {}
430     RSRenderParticleVector() = default;
431     ~RSRenderParticleVector() = default;
RSRenderParticleVector(const RSRenderParticleVector & other)432     RSRenderParticleVector(const RSRenderParticleVector& other)
433         : renderParticleVector_(other.renderParticleVector_), imageVector_(other.imageVector_)
434     {}
435 
436     RSRenderParticleVector& operator=(const RSRenderParticleVector& other)
437     {
438         if (this != &other) {
439             renderParticleVector_ = other.renderParticleVector_;
440             imageVector_ = other.imageVector_;
441         }
442         return *this;
443     }
444 
GetParticleSize()445     int GetParticleSize() const
446     {
447         return renderParticleVector_.size();
448     }
449 
GetParticleVector()450     const std::vector<std::shared_ptr<RSRenderParticle>>& GetParticleVector() const
451     {
452         return renderParticleVector_;
453     }
454 
GetParticleImageVector()455     const std::vector<std::shared_ptr<RSImage>>& GetParticleImageVector() const
456     {
457         return imageVector_;
458     }
459 
GetParticleImageCount()460     size_t GetParticleImageCount() const
461     {
462         return imageVector_.size();
463     }
464 
465     bool operator==(const RSRenderParticleVector& rhs) const
466     {
467         bool equal = false;
468         if (this->renderParticleVector_.size() != rhs.renderParticleVector_.size() ||
469             this->imageVector_.size() != rhs.imageVector_.size()) {
470             return false;
471         }
472         if (this->renderParticleVector_.size() == 0 && this->imageVector_.size() == 0) {
473             return true;
474         }
475         for (size_t i = 0; i < this->renderParticleVector_.size(); i++) {
476             equal = equal && (this->renderParticleVector_[i] == rhs.renderParticleVector_[i]) &&
477                     (*(this->renderParticleVector_[i]) == *(rhs.renderParticleVector_[i]));
478         }
479         for (size_t i = 0; i < this->imageVector_.size(); i++) {
480             equal = equal && (this->imageVector_[i] == rhs.imageVector_[i]) &&
481                     ((*(this->imageVector_[i])).IsEqual(*(rhs.imageVector_[i])));
482         }
483         return equal;
484     }
485 
486     friend class RSRenderParticleAnimation;
487 
488 private:
489     std::vector<std::shared_ptr<RSRenderParticle>> renderParticleVector_;
490     std::vector<std::shared_ptr<RSImage>> imageVector_;
491 };
492 } // namespace Rosen
493 } // namespace OHOS
494 
495 #endif // RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_RENDER_PARTICLE_H
496