Particle System Demo
[platform/core/uifw/dali-demo.git] / examples / particle-system / effects / sparkles-effect-modifier.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include "sparkles-effect-modifier.h"
19 #include "sparkles-effect-source.h"
20
21 namespace Dali::ParticleEffect
22 {
23 static float LIFETIME = 3.0f;
24 SparklesModifier::SparklesModifier(ParticleEmitter& emitter)
25 : mEmitter(emitter)
26 {
27 }
28
29 bool SparklesModifier::IsMultiThreaded()
30 {
31   return true;
32 }
33
34 void SparklesModifier::Update(ParticleList& particleList, uint32_t first, uint32_t count)
35 {
36   // If no acive particles return
37   if(!particleList.GetActiveParticleCount())
38   {
39     return;
40   }
41
42   mAngle = ((mAngle + 2) % 360);
43
44   // Retrieve the Source and get the stream
45   if(!mStreamBasePos)
46   {
47     mStreamBasePos = static_cast<SparklesSource*>(&mEmitter.GetSource().GetSourceCallback())->mStreamBasePos;
48   }
49   if(!mStreamBaseAngle)
50   {
51     mStreamBaseAngle = static_cast<SparklesSource*>(&mEmitter.GetSource().GetSourceCallback())->mStreamBaseAngle;
52   }
53
54   // Missing stream, return!
55   if(!mStreamBasePos)
56   {
57     return;
58   }
59
60   auto& activeParticles = particleList.GetActiveParticles();
61
62   auto it = activeParticles.begin();
63   std::advance(it, first);
64
65   for(; count; ++it, count--)
66   {
67     // Acquire stream data
68     auto&                  particle = *it;
69     auto&                  position = particle.Get<Vector3>(ParticleStream::POSITION_STREAM_BIT);
70     auto&                  velocity = particle.Get<Vector3>(ParticleStream::VELOCITY_STREAM_BIT);
71     auto&                  color    = particle.Get<Vector4>(ParticleStream::COLOR_STREAM_BIT);
72     auto&                  scale    = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
73
74     // Get base positions
75     [[maybe_unused]] auto& basePos = particle.GetByIndex<Vector3>(mStreamBasePos);
76
77     auto angle = particle.GetByIndex<float>(mStreamBaseAngle);
78     auto                   radians  = ((angle * M_PI)/180.f);
79     float                  lifetime = particle.Get<float>(ParticleStream::LIFETIME_STREAM_BIT);
80     position.y += velocity.y *sin(radians);
81     position.x += velocity.x * cos(radians);
82
83     velocity *= 0.990f;
84     float normalizedTime = (lifetime / LIFETIME);
85     color.a = normalizedTime;
86     scale      = Vector3(64.0f*(normalizedTime * normalizedTime * normalizedTime * normalizedTime), 64.0f*(normalizedTime * normalizedTime * normalizedTime * normalizedTime), 1.0);
87   }
88 }
89 }