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 #include "animation/rs_render_particle.h"
16 
17 #include <algorithm>
18 #include <cstdint>
19 #include <random>
20 
21 #include "animation/rs_interpolator.h"
22 #include "animation/rs_render_particle_system.h"
23 #include "common/rs_color.h"
24 namespace OHOS {
25 namespace Rosen {
26 constexpr float DEGREE_TO_RADIAN = M_PI / 180;
27 constexpr int RAND_PRECISION = 10000;
28 constexpr float SIGMA = 3.f;
29 
GetEmitRate() const30 int ParticleRenderParams::GetEmitRate() const
31 {
32     return emitterConfig_.emitRate_;
33 }
34 
GetEmitShape() const35 const ShapeType& ParticleRenderParams::GetEmitShape() const
36 {
37     return emitterConfig_.emitShape_;
38 }
39 
GetEmitPosition() const40 const Vector2f& ParticleRenderParams::GetEmitPosition() const
41 {
42     return emitterConfig_.position_;
43 }
44 
GetEmitSize() const45 const Vector2f& ParticleRenderParams::GetEmitSize() const
46 {
47     return emitterConfig_.emitSize_;
48 }
49 
GetParticleCount() const50 int32_t ParticleRenderParams::GetParticleCount() const
51 {
52     return emitterConfig_.particleCount_;
53 }
54 
GetLifeTimeStartValue() const55 int64_t ParticleRenderParams::GetLifeTimeStartValue() const
56 {
57     if (emitterConfig_.lifeTime_.start_ > std::numeric_limits<int64_t>::max() / NS_PER_MS) {
58         return std::numeric_limits<int64_t>::max();
59     }
60     return emitterConfig_.lifeTime_.start_ * NS_PER_MS;
61 }
62 
GetLifeTimeEndValue() const63 int64_t ParticleRenderParams::GetLifeTimeEndValue() const
64 {
65     if (emitterConfig_.lifeTime_.end_ > std::numeric_limits<int64_t>::max() / NS_PER_MS) {
66         return std::numeric_limits<int64_t>::max();
67     }
68     return emitterConfig_.lifeTime_.end_ * NS_PER_MS;
69 }
70 
GetParticleType() const71 const ParticleType& ParticleRenderParams::GetParticleType() const
72 {
73     return emitterConfig_.type_;
74 }
75 
GetParticleRadius() const76 float ParticleRenderParams::GetParticleRadius() const
77 {
78     return emitterConfig_.radius_;
79 }
80 
GetParticleImage()81 const std::shared_ptr<RSImage>& ParticleRenderParams::GetParticleImage()
82 {
83     return emitterConfig_.image_;
84 }
85 
GetImageSize() const86 const Vector2f& ParticleRenderParams::GetImageSize() const
87 {
88     return emitterConfig_.imageSize_;
89 }
90 
GetVelocityStartValue() const91 float ParticleRenderParams::GetVelocityStartValue() const
92 {
93     return velocity_.velocityValue_.start_;
94 }
95 
GetVelocityEndValue() const96 float ParticleRenderParams::GetVelocityEndValue() const
97 {
98     return velocity_.velocityValue_.end_;
99 }
100 
GetVelocityStartAngle() const101 float ParticleRenderParams::GetVelocityStartAngle() const
102 {
103     return velocity_.velocityAngle_.start_;
104 }
105 
GetVelocityEndAngle() const106 float ParticleRenderParams::GetVelocityEndAngle() const
107 {
108     return velocity_.velocityAngle_.end_;
109 }
110 
GetAccelerationStartValue() const111 float ParticleRenderParams::GetAccelerationStartValue() const
112 {
113     return acceleration_.accelerationValue_.val_.start_;
114 }
115 
GetAccelerationEndValue() const116 float ParticleRenderParams::GetAccelerationEndValue() const
117 {
118     return acceleration_.accelerationValue_.val_.end_;
119 }
120 
GetAccelerationStartAngle() const121 float ParticleRenderParams::GetAccelerationStartAngle() const
122 {
123     return acceleration_.accelerationAngle_.val_.start_;
124 }
125 
GetAccelerationEndAngle() const126 float ParticleRenderParams::GetAccelerationEndAngle() const
127 {
128     return acceleration_.accelerationAngle_.val_.end_;
129 }
130 
GetAccelerationValueUpdator()131 const ParticleUpdator& ParticleRenderParams::GetAccelerationValueUpdator()
132 {
133     return acceleration_.accelerationValue_.updator_;
134 }
135 
GetAccelerationAngleUpdator()136 const ParticleUpdator& ParticleRenderParams::GetAccelerationAngleUpdator()
137 {
138     return acceleration_.accelerationAngle_.updator_;
139 }
140 
GetAccelRandomValueStart() const141 float ParticleRenderParams::GetAccelRandomValueStart() const
142 {
143     return acceleration_.accelerationValue_.random_.start_;
144 }
145 
GetAccelRandomValueEnd() const146 float ParticleRenderParams::GetAccelRandomValueEnd() const
147 {
148     return acceleration_.accelerationValue_.random_.end_;
149 }
150 
GetAccelRandomAngleStart() const151 float ParticleRenderParams::GetAccelRandomAngleStart() const
152 {
153     return acceleration_.accelerationAngle_.random_.start_;
154 }
155 
GetAccelRandomAngleEnd() const156 float ParticleRenderParams::GetAccelRandomAngleEnd() const
157 {
158     return acceleration_.accelerationAngle_.random_.end_;
159 }
160 
GetColorStartValue()161 const Color& ParticleRenderParams::GetColorStartValue()
162 {
163     return color_.colorVal_.start_;
164 }
165 
GetColorEndValue()166 const Color& ParticleRenderParams::GetColorEndValue()
167 {
168     return color_.colorVal_.end_;
169 }
170 
GetColorDistribution()171 const DistributionType& ParticleRenderParams::GetColorDistribution()
172 {
173     return color_.distribution_;
174 }
175 
GetColorUpdator()176 const ParticleUpdator& ParticleRenderParams::GetColorUpdator()
177 {
178     return color_.updator_;
179 }
180 
GetRedRandomStart() const181 float ParticleRenderParams::GetRedRandomStart() const
182 {
183     return color_.redRandom_.start_;
184 }
185 
GetRedRandomEnd() const186 float ParticleRenderParams::GetRedRandomEnd() const
187 {
188     return color_.redRandom_.end_;
189 }
190 
GetGreenRandomStart() const191 float ParticleRenderParams::GetGreenRandomStart() const
192 {
193     return color_.greenRandom_.start_;
194 }
195 
GetGreenRandomEnd() const196 float ParticleRenderParams::GetGreenRandomEnd() const
197 {
198     return color_.greenRandom_.end_;
199 }
200 
GetBlueRandomStart() const201 float ParticleRenderParams::GetBlueRandomStart() const
202 {
203     return color_.blueRandom_.start_;
204 }
205 
GetBlueRandomEnd() const206 float ParticleRenderParams::GetBlueRandomEnd() const
207 {
208     return color_.blueRandom_.end_;
209 }
210 
GetAlphaRandomStart() const211 float ParticleRenderParams::GetAlphaRandomStart() const
212 {
213     return color_.alphaRandom_.start_;
214 }
215 
GetAlphaRandomEnd() const216 float ParticleRenderParams::GetAlphaRandomEnd() const
217 {
218     return color_.alphaRandom_.end_;
219 }
220 
GetOpacityStartValue()221 float ParticleRenderParams::GetOpacityStartValue()
222 {
223     return opacity_.val_.start_;
224 }
225 
GetOpacityEndValue()226 float ParticleRenderParams::GetOpacityEndValue()
227 {
228     return opacity_.val_.end_;
229 }
230 
GetOpacityUpdator()231 const ParticleUpdator& ParticleRenderParams::GetOpacityUpdator()
232 {
233     return opacity_.updator_;
234 }
235 
GetOpacityRandomStart() const236 float ParticleRenderParams::GetOpacityRandomStart() const
237 {
238     return opacity_.random_.start_;
239 }
240 
GetOpacityRandomEnd() const241 float ParticleRenderParams::GetOpacityRandomEnd() const
242 {
243     return opacity_.random_.end_;
244 }
245 
GetScaleStartValue()246 float ParticleRenderParams::GetScaleStartValue()
247 {
248     return scale_.val_.start_;
249 }
250 
GetScaleEndValue()251 float ParticleRenderParams::GetScaleEndValue()
252 {
253     return scale_.val_.end_;
254 }
255 
GetScaleUpdator()256 const ParticleUpdator& ParticleRenderParams::GetScaleUpdator()
257 {
258     return scale_.updator_;
259 }
260 
GetScaleRandomStart() const261 float ParticleRenderParams::GetScaleRandomStart() const
262 {
263     return scale_.random_.start_;
264 }
265 
GetScaleRandomEnd() const266 float ParticleRenderParams::GetScaleRandomEnd() const
267 {
268     return scale_.random_.end_;
269 }
270 
GetSpinStartValue()271 float ParticleRenderParams::GetSpinStartValue()
272 {
273     return spin_.val_.start_;
274 }
275 
GetSpinEndValue()276 float ParticleRenderParams::GetSpinEndValue()
277 {
278     return spin_.val_.end_;
279 }
280 
GetSpinUpdator()281 const ParticleUpdator& ParticleRenderParams::GetSpinUpdator()
282 {
283     return spin_.updator_;
284 }
285 
GetAcceValChangeOverLife()286 const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& ParticleRenderParams::GetAcceValChangeOverLife()
287 {
288     return acceleration_.accelerationValue_.valChangeOverLife_;
289 }
290 
GetAcceAngChangeOverLife()291 const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& ParticleRenderParams::GetAcceAngChangeOverLife()
292 {
293     return acceleration_.accelerationAngle_.valChangeOverLife_;
294 }
295 
GetOpacityChangeOverLife()296 const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& ParticleRenderParams::GetOpacityChangeOverLife()
297 {
298     return opacity_.valChangeOverLife_;
299 }
300 
GetScaleChangeOverLife()301 const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& ParticleRenderParams::GetScaleChangeOverLife()
302 {
303     return scale_.valChangeOverLife_;
304 }
305 
GetSpinChangeOverLife()306 const std::vector<std::shared_ptr<ChangeInOverLife<float>>>& ParticleRenderParams::GetSpinChangeOverLife()
307 {
308     return spin_.valChangeOverLife_;
309 }
310 
GetColorChangeOverLife()311 const std::vector<std::shared_ptr<ChangeInOverLife<Color>>>& ParticleRenderParams::GetColorChangeOverLife()
312 {
313     return color_.valChangeOverLife_;
314 }
315 
GetSpinRandomStart() const316 float ParticleRenderParams::GetSpinRandomStart() const
317 {
318     return spin_.random_.start_;
319 }
320 
GetSpinRandomEnd() const321 float ParticleRenderParams::GetSpinRandomEnd() const
322 {
323     return spin_.random_.end_;
324 }
325 
GetImageIndex() const326 size_t ParticleRenderParams::GetImageIndex() const
327 {
328     return imageIndex_;
329 }
330 
SetEmitConfig(const EmitterConfig & emiterConfig)331 void ParticleRenderParams::SetEmitConfig(const EmitterConfig& emiterConfig)
332 {
333     emitterConfig_ = emiterConfig;
334 }
335 
SetParticleVelocity(const ParticleVelocity & velocity)336 void ParticleRenderParams::SetParticleVelocity(const ParticleVelocity& velocity)
337 {
338     velocity_ = velocity;
339 }
340 
SetParticleAcceleration(const RenderParticleAcceleration & acceleration)341 void ParticleRenderParams::SetParticleAcceleration(const RenderParticleAcceleration& acceleration)
342 {
343     acceleration_ = acceleration;
344 }
345 
SetParticleColor(const RenderParticleColorParaType & color)346 void ParticleRenderParams::SetParticleColor(const RenderParticleColorParaType& color)
347 {
348     color_ = color;
349 }
350 
SetParticleOpacity(const RenderParticleParaType<float> & opacity)351 void ParticleRenderParams::SetParticleOpacity(const RenderParticleParaType<float>& opacity)
352 {
353     opacity_ = opacity;
354 }
355 
SetParticleScale(const RenderParticleParaType<float> & scale)356 void ParticleRenderParams::SetParticleScale(const RenderParticleParaType<float>& scale)
357 {
358     scale_ = scale;
359 }
360 
SetParticleSpin(const RenderParticleParaType<float> & spin)361 void ParticleRenderParams::SetParticleSpin(const RenderParticleParaType<float>& spin)
362 {
363     spin_ = spin;
364 }
365 
SetImageIndex(size_t imageIndex)366 void ParticleRenderParams::SetImageIndex(size_t imageIndex)
367 {
368     imageIndex_ = imageIndex;
369 }
370 
RSRenderParticle(const std::shared_ptr<ParticleRenderParams> & particleParams)371 RSRenderParticle::RSRenderParticle(const std::shared_ptr<ParticleRenderParams>& particleParams)
372     : particleParams_(particleParams)
373 {
374     if (particleParams_ != nullptr) {
375         InitProperty();
376     }
377 }
378 
379 // Set methods
SetPosition(const Vector2f & position)380 void RSRenderParticle::SetPosition(const Vector2f& position)
381 {
382     position_ = position;
383 }
384 
SetVelocity(const Vector2f & velocity)385 void RSRenderParticle::SetVelocity(const Vector2f& velocity)
386 {
387     velocity_ = velocity;
388 }
389 
SetAcceleration(const Vector2f & acceleration)390 void RSRenderParticle::SetAcceleration(const Vector2f& acceleration)
391 {
392     acceleration_ = acceleration;
393 }
394 
SetSpin(const float & spin)395 void RSRenderParticle::SetSpin(const float& spin)
396 {
397     spin_ = spin;
398 }
399 
SetOpacity(const float & opacity)400 void RSRenderParticle::SetOpacity(const float& opacity)
401 {
402     opacity_ = opacity;
403 }
404 
SetColor(const Color & color)405 void RSRenderParticle::SetColor(const Color& color)
406 {
407     color_ = color;
408 }
409 
SetScale(const float & scale)410 void RSRenderParticle::SetScale(const float& scale)
411 {
412     scale_ = scale;
413 }
414 
SetRadius(const float & radius)415 void RSRenderParticle::SetRadius(const float& radius)
416 {
417     radius_ = radius;
418 }
419 
SetImage(const std::shared_ptr<RSImage> & image)420 void RSRenderParticle::SetImage(const std::shared_ptr<RSImage>& image)
421 {
422     image_ = image;
423 }
424 
SetImageSize(const Vector2f & imageSize)425 void RSRenderParticle::SetImageSize(const Vector2f& imageSize)
426 {
427     imageSize_ = imageSize;
428 }
429 
SetParticleType(const ParticleType & particleType)430 void RSRenderParticle::SetParticleType(const ParticleType& particleType)
431 {
432     particleType_ = particleType;
433 }
434 
SetActiveTime(const int64_t & activeTime)435 void RSRenderParticle::SetActiveTime(const int64_t& activeTime)
436 {
437     activeTime_ = activeTime;
438 }
439 
SetAccelerationValue(float accelerationValue)440 void RSRenderParticle::SetAccelerationValue(float accelerationValue)
441 {
442     accelerationValue_ = accelerationValue;
443 }
444 
SetAccelerationAngle(float accelerationAngle)445 void RSRenderParticle::SetAccelerationAngle(float accelerationAngle)
446 {
447     accelerationAngle_ = accelerationAngle;
448 }
449 
SetRedF(float redF)450 void RSRenderParticle::SetRedF(float redF)
451 {
452     redF_ = redF;
453 }
454 
SetGreenF(float greenF)455 void RSRenderParticle::SetGreenF(float greenF)
456 {
457     greenF_ = greenF;
458 }
459 
SetBlueF(float blueF)460 void RSRenderParticle::SetBlueF(float blueF)
461 {
462     blueF_ = blueF;
463 }
464 
SetAlphaF(float alphaF)465 void RSRenderParticle::SetAlphaF(float alphaF)
466 {
467     alphaF_ = alphaF;
468 }
469 
470 // Get methods
GetPosition()471 const Vector2f& RSRenderParticle::GetPosition()
472 {
473     return position_;
474 }
475 
GetVelocity()476 const Vector2f& RSRenderParticle::GetVelocity()
477 {
478     return velocity_;
479 }
480 
GetAcceleration()481 const Vector2f& RSRenderParticle::GetAcceleration()
482 {
483     return acceleration_;
484 }
485 
GetSpin()486 float RSRenderParticle::GetSpin()
487 {
488     return spin_;
489 }
490 
GetOpacity()491 float RSRenderParticle::GetOpacity()
492 {
493     return opacity_;
494 }
495 
GetColor()496 const Color& RSRenderParticle::GetColor()
497 {
498     return color_;
499 }
500 
GetScale()501 float RSRenderParticle::GetScale()
502 {
503     return scale_;
504 }
505 
GetRadius()506 float RSRenderParticle::GetRadius()
507 {
508     return radius_;
509 }
510 
GetAccelerationValue()511 float RSRenderParticle::GetAccelerationValue()
512 {
513     return accelerationValue_;
514 }
515 
GetAccelerationAngle()516 float RSRenderParticle::GetAccelerationAngle()
517 {
518     return accelerationAngle_;
519 }
520 
GetRedSpeed()521 float RSRenderParticle::GetRedSpeed()
522 {
523     return redSpeed_;
524 }
525 
GetGreenSpeed()526 float RSRenderParticle::GetGreenSpeed()
527 {
528     return greenSpeed_;
529 }
530 
GetBlueSpeed()531 float RSRenderParticle::GetBlueSpeed()
532 {
533     return blueSpeed_;
534 }
535 
GetAlphaSpeed()536 float RSRenderParticle::GetAlphaSpeed()
537 {
538     return alphaSpeed_;
539 }
540 
GetOpacitySpeed()541 float RSRenderParticle::GetOpacitySpeed()
542 {
543     return opacitySpeed_;
544 }
545 
GetScaleSpeed()546 float RSRenderParticle::GetScaleSpeed()
547 {
548     return scaleSpeed_;
549 }
550 
GetSpinSpeed()551 float RSRenderParticle::GetSpinSpeed()
552 {
553     return spinSpeed_;
554 }
555 
GetAccelerationValueSpeed()556 float RSRenderParticle::GetAccelerationValueSpeed()
557 {
558     return accelerationValueSpeed_;
559 }
560 
GetAccelerationAngleSpeed()561 float RSRenderParticle::GetAccelerationAngleSpeed()
562 {
563     return accelerationAngleSpeed_;
564 }
565 
GetRedF()566 float RSRenderParticle::GetRedF()
567 {
568     return redF_;
569 }
570 
GetGreenF()571 float RSRenderParticle::GetGreenF()
572 {
573     return greenF_;
574 }
575 
GetBlueF()576 float RSRenderParticle::GetBlueF()
577 {
578     return blueF_;
579 }
580 
GetAlphaF()581 float RSRenderParticle::GetAlphaF()
582 {
583     return alphaF_;
584 }
585 
GetImage()586 const std::shared_ptr<RSImage>& RSRenderParticle::GetImage()
587 {
588     return image_;
589 }
590 
GetImageSize()591 const Vector2f& RSRenderParticle::GetImageSize()
592 {
593     return imageSize_;
594 }
595 
GetParticleType()596 const ParticleType& RSRenderParticle::GetParticleType()
597 {
598     return particleType_;
599 }
600 
GetActiveTime()601 int64_t RSRenderParticle::GetActiveTime()
602 {
603     return activeTime_;
604 }
605 
GetParticleRenderParams()606 const std::shared_ptr<ParticleRenderParams>& RSRenderParticle::GetParticleRenderParams()
607 {
608     return particleParams_;
609 }
610 
GetImageIndex() const611 size_t RSRenderParticle::GetImageIndex() const
612 {
613     return imageIndex_;
614 }
615 
InitProperty()616 void RSRenderParticle::InitProperty()
617 {
618     if (particleParams_ == nullptr) {
619         return;
620     }
621     position_ = CalculateParticlePosition(
622         particleParams_->GetEmitShape(), particleParams_->GetEmitPosition(), particleParams_->GetEmitSize());
623 
624     float velocityValue =
625         GetRandomValue(particleParams_->GetVelocityStartValue(), particleParams_->GetVelocityEndValue());
626     float velocityAngle =
627         GetRandomValue(particleParams_->GetVelocityStartAngle(), particleParams_->GetVelocityEndAngle());
628     velocityAngle *= DEGREE_TO_RADIAN;
629     velocity_ = Vector2f { velocityValue * std::cos(velocityAngle), velocityValue * std::sin(velocityAngle) };
630 
631     accelerationValue_ =
632         GetRandomValue(particleParams_->GetAccelerationStartValue(), particleParams_->GetAccelerationEndValue());
633     accelerationAngle_ =
634         GetRandomValue(particleParams_->GetAccelerationStartAngle(), particleParams_->GetAccelerationEndAngle());
635     acceleration_ = Vector2f { accelerationValue_ * std::cos(accelerationAngle_ * DEGREE_TO_RADIAN),
636         accelerationValue_ * std::sin(accelerationAngle_ * DEGREE_TO_RADIAN) };
637 
638     spin_ = GetRandomValue(particleParams_->GetSpinStartValue(), particleParams_->GetSpinEndValue());
639     opacity_ = GetRandomValue(particleParams_->GetOpacityStartValue(), particleParams_->GetOpacityEndValue());
640     scale_ = GetRandomValue(particleParams_->GetScaleStartValue(), particleParams_->GetScaleEndValue());
641     opacitySpeed_ = GetRandomValue(particleParams_->GetOpacityRandomStart(), particleParams_->GetOpacityRandomEnd());
642     scaleSpeed_ = GetRandomValue(particleParams_->GetScaleRandomStart(), particleParams_->GetScaleRandomEnd());
643     spinSpeed_ = GetRandomValue(particleParams_->GetSpinRandomStart(), particleParams_->GetSpinRandomEnd());
644     accelerationValueSpeed_ =
645         GetRandomValue(particleParams_->GetAccelRandomValueStart(), particleParams_->GetAccelRandomValueEnd());
646     accelerationAngleSpeed_ =
647         GetRandomValue(particleParams_->GetAccelRandomAngleStart(), particleParams_->GetAccelRandomAngleEnd());
648 
649     particleType_ = particleParams_->GetParticleType();
650     if (particleType_ == ParticleType::POINTS) {
651         SetColor();
652         radius_ = particleParams_->GetParticleRadius();
653     } else if (particleType_ == ParticleType::IMAGES) {
654         image_ = particleParams_->GetParticleImage();
655         imageSize_ = particleParams_->GetImageSize();
656         imageIndex_ = particleParams_->GetImageIndex();
657         if (image_ != nullptr) {
658             auto pixelMap = image_->GetPixelMap();
659             if (pixelMap != nullptr) {
660                 image_->SetDstRect(RectF(position_.x_, position_.y_, pixelMap->GetWidth(), pixelMap->GetHeight()));
661             }
662         }
663     }
664     activeTime_ = 0;
665     lifeTime_ = GetRandomValue(particleParams_->GetLifeTimeStartValue(), particleParams_->GetLifeTimeEndValue());
666 }
667 
IsAlive() const668 bool RSRenderParticle::IsAlive() const
669 {
670     if (dead_ == true) {
671         return false;
672     }
673     if (particleParams_ != nullptr && particleParams_->GetLifeTimeStartValue() == (-1 * NS_PER_MS) &&
674         particleParams_->GetLifeTimeEndValue() == (-1 * NS_PER_MS)) {
675         return true;
676     }
677     return activeTime_ < lifeTime_;
678 }
679 
SetIsDead()680 void RSRenderParticle::SetIsDead()
681 {
682     dead_ = true;
683 }
684 
GetRandomValue(float min,float max)685 float RSRenderParticle::GetRandomValue(float min, float max)
686 {
687     if (ROSEN_EQ(min, max)) {
688         return min;
689     }
690     if (min > max) {
691         std::swap(min, max);
692     }
693     int rand_int = rand() % RAND_PRECISION;
694     float rand_float = min + (static_cast<float>(rand_int) / RAND_PRECISION) * (max - min);
695     return rand_float;
696 }
697 
SetColor()698 void RSRenderParticle::SetColor()
699 {
700     if (particleParams_ == nullptr) {
701         return;
702     }
703     if (particleParams_->GetColorDistribution() == DistributionType::GAUSSIAN) {
704         auto& colorStart = particleParams_->GetColorStartValue();
705         auto& colorEnd = particleParams_->GetColorEndValue();
706         auto redScale = std::abs(colorEnd.GetRed() - colorStart.GetRed());
707         auto greenScale = std::abs(colorEnd.GetGreen() - colorStart.GetGreen());
708         auto blueScale = std::abs(colorEnd.GetBlue() - colorStart.GetBlue());
709         auto alphaScale = std::abs(colorEnd.GetAlpha() - colorStart.GetAlpha());
710         auto meanRed = (colorStart.GetRed() + colorEnd.GetRed()) / 2;
711         auto meanGreen = (colorStart.GetGreen() + colorEnd.GetGreen()) / 2;
712         auto meanBlue = (colorStart.GetBlue() + colorEnd.GetBlue()) / 2;
713         auto meanAlpha = (colorStart.GetAlpha() + colorEnd.GetAlpha()) / 2;
714 
715         color_.SetRed(GenerateColorComponent(meanRed, SIGMA * redScale));
716         color_.SetGreen(GenerateColorComponent(meanGreen, SIGMA * greenScale));
717         color_.SetBlue(GenerateColorComponent(meanBlue, SIGMA * blueScale));
718         color_.SetAlpha(GenerateColorComponent(meanAlpha, SIGMA * alphaScale));
719     } else {
720         float colorRandomValue = GetRandomValue(0.0f, 1.0f);
721         color_ = Lerp(particleParams_->GetColorStartValue(), particleParams_->GetColorEndValue(), colorRandomValue);
722     }
723     redSpeed_ = GetRandomValue(particleParams_->GetRedRandomStart(), particleParams_->GetRedRandomEnd());
724     greenSpeed_ = GetRandomValue(particleParams_->GetGreenRandomStart(), particleParams_->GetGreenRandomEnd());
725     blueSpeed_ = GetRandomValue(particleParams_->GetBlueRandomStart(), particleParams_->GetBlueRandomEnd());
726     alphaSpeed_ = GetRandomValue(particleParams_->GetAlphaRandomStart(), particleParams_->GetAlphaRandomEnd());
727 }
728 
729 // Generate color components that follow normal distribution
GenerateColorComponent(double mean,double stddev)730 int RSRenderParticle::GenerateColorComponent(double mean, double stddev)
731 {
732     // Creates a random number engine and a normal distribution object.
733     std::random_device rd;
734     std::mt19937 gen(rd());
735     std::normal_distribution<> dis(mean, stddev);
736 
737     double number = dis(gen);
738     int component = static_cast<int>(std::round(std::abs(number)));
739     component = std::max(0, std::min(component, 255)); // 255 is RGB Component max.
740     return component;
741 }
742 
CalculateParticlePosition(const ShapeType & emitShape,const Vector2f & position,const Vector2f & emitSize)743 Vector2f RSRenderParticle::CalculateParticlePosition(
744     const ShapeType& emitShape, const Vector2f& position, const Vector2f& emitSize)
745 {
746     float positionX = 0.f;
747     float positionY = 0.f;
748     if (emitShape == ShapeType::RECT) {
749         float minX = position.x_;
750         float maxX = position.x_ + emitSize.x_;
751         positionX = GetRandomValue(minX, maxX);
752         float minY = position.y_;
753         float maxY = position.y_ + emitSize.y_;
754         positionY = GetRandomValue(minY, maxY);
755     }
756     if (emitShape == ShapeType::CIRCLE || emitShape == ShapeType::ELLIPSE) {
757         float dx = emitSize.x_;
758         float dy = emitSize.y_;
759         float x = position.x_ + dx / 2;
760         float y = position.y_ + dy / 2;
761         float theta = GetRandomValue(0.f, 2 * PI);
762         if (emitShape == ShapeType::CIRCLE) {
763             float d = std::min(emitSize.x_, emitSize.y_);
764             float r = GetRandomValue(0.f, d) / 2;
765             positionX = x + r * cos(theta);
766             positionY = y + r * sin(theta);
767         } else {
768             float rx = GetRandomValue(0.f, dx) / 2;
769             float ry = GetRandomValue(0.f, dy) / 2;
770             positionX = x + rx * cos(theta);
771             positionY = y + ry * sin(theta);
772         }
773     }
774     return Vector2f { positionX, positionY };
775 }
776 
Dump(std::string & out) const777 void EmitterUpdater::Dump(std::string& out) const
778 {
779     out += "[emitterIndex:" + std::to_string(emitterIndex_);
780     if (position_) {
781         out += " position[" + std::to_string(position_->x_) + " ";
782         out += std::to_string(position_->y_) + "]";
783     }
784     if (emitSize_) {
785         out += " emitSize[" + std::to_string(emitSize_->x_) + " ";
786         out += std::to_string(emitSize_->y_) + "]";
787     }
788     if (emitRate_) {
789         out += " emitRate:" + std::to_string(emitRate_.value());
790     }
791     out += ']';
792 }
793 } // namespace Rosen
794 } // namespace OHOS
795