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