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