Commit db7b6c4e083972a8c19b85f59426e64ae369e3a2

Authored by Adeel Kazmi
1 parent 039475cb

(Particles System) Added a README & removed buttons, cleaned up UI

Change-Id: I0ccedc569e841dbb9b18fa1f583ec3998a6a59a0
examples/particle-system/README.md 0 → 100644
  1 +Particles System Example
  2 +========================
  3 +
  4 +This example shows how the Particle system can be used.
  5 +
  6 +It shows three effects:
  7 +
  8 +* <b>Fire Effect</b>:
  9 +
  10 + This is a simple effect that shows fire particles rising from the center of the window.
  11 +
  12 + ![](./images/fire-effect.png)
  13 +
  14 +* <b>Sparkle Effect</b>:
  15 +
  16 + This shows multiple sized particles starting at the center of the window and going in all directions.
  17 +
  18 + ![](./images/sparkle-effect.png)
  19 +
  20 +* <b>Image Source Effect</b>:
  21 +
  22 + This takes an image source and creates particles from that image and shows them waving.
  23 +
  24 + ![](./images/image-source-effect.png)
  25 +
  26 +By tapping the screen, you can move between one effect to the next.
  27 +You can also press any key to move to the next effect apart from the ESC or Back keys which will exit the application.
0 \ No newline at end of file 28 \ No newline at end of file
examples/particle-system/images/fire-effect.png 0 → 100644

84.5 KB

examples/particle-system/images/image-source-effect.png 0 → 100644

60.2 KB

examples/particle-system/images/sparkle-effect.png 0 → 100644

187 KB

examples/particle-system/particle-system-example.cpp
@@ -17,18 +17,14 @@ @@ -17,18 +17,14 @@
17 17
18 #include <dali-toolkit/dali-toolkit.h> 18 #include <dali-toolkit/dali-toolkit.h>
19 19
20 -#include <dali-toolkit/public-api/particle-system/particle-emitter.h>  
21 -#include <dali-toolkit/public-api/particle-system/particle-source.h>  
22 #include <dali-toolkit/public-api/particle-system/particle-domain.h> 20 #include <dali-toolkit/public-api/particle-system/particle-domain.h>
  21 +#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
23 #include <dali-toolkit/public-api/particle-system/particle-list.h> 22 #include <dali-toolkit/public-api/particle-system/particle-list.h>
24 #include <dali-toolkit/public-api/particle-system/particle-renderer.h> 23 #include <dali-toolkit/public-api/particle-system/particle-renderer.h>
  24 +#include <dali-toolkit/public-api/particle-system/particle-source.h>
25 #include <dali-toolkit/public-api/particle-system/particle-types.h> 25 #include <dali-toolkit/public-api/particle-system/particle-types.h>
26 26
27 -#include <utility>  
28 -#include <ctime>  
29 #include <dali-toolkit/public-api/particle-system/particle-modifier.h> 27 #include <dali-toolkit/public-api/particle-system/particle-modifier.h>
30 -#include <unistd.h>  
31 -#include <map>  
32 28
33 #include "effects/particle-effect.h" 29 #include "effects/particle-effect.h"
34 30
@@ -39,13 +35,16 @@ using Dali::Toolkit::TextLabel; @@ -39,13 +35,16 @@ using Dali::Toolkit::TextLabel;
39 35
40 using namespace Dali::ParticleEffect; 36 using namespace Dali::ParticleEffect;
41 37
  38 +constexpr uint16_t NUMBER_OF_EFFECTS = 3;
  39 +constexpr float TEXT_LABEL_ANIMATION_TIME = 5.0f;
  40 +const TimePeriod TEXT_LABEL_ANIMATION_TIME_PERIOD(3.0, 2.0f);
  41 +
42 /** 42 /**
43 * This example shows Particle System feature 43 * This example shows Particle System feature
44 */ 44 */
45 class ParticleEffectController : public ConnectionTracker 45 class ParticleEffectController : public ConnectionTracker
46 { 46 {
47 public: 47 public:
48 -  
49 ParticleEffectController(Application& application) 48 ParticleEffectController(Application& application)
50 : mApplication(application) 49 : mApplication(application)
51 { 50 {
@@ -55,135 +54,105 @@ public: @@ -55,135 +54,105 @@ public:
55 54
56 ~ParticleEffectController() = default; // Nothing to do in destructor 55 ~ParticleEffectController() = default; // Nothing to do in destructor
57 56
58 - template<class ButtonType>  
59 - ButtonType MakeButton( std::string title,  
60 - Vector2 position,  
61 - Vector2 size,  
62 - bool toggleable,  
63 - std::function<bool(Button)> onClick ) 57 +private:
  58 + // The Init signal is received once (only) during the Application lifetime
  59 + void Create(Application& application)
64 { 60 {
65 - ButtonType button = ButtonType::New();  
66 - button.SetProperty( Button::Property::LABEL, title);  
67 - button.SetProperty( Actor::Property::POSITION, position);  
68 - button.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);  
69 - button.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);  
70 - button.SetProperty(Button::Property::TOGGLABLE, toggleable);  
71 - static std::map<RefObject*, std::function<bool(Button)>> callbackMap;  
72 - struct OnClick  
73 - {  
74 - static bool Slot(Button btn)  
75 - {  
76 - auto ptr = btn.GetObjectPtr();  
77 - return callbackMap[ptr](btn);  
78 - }  
79 - }; 61 + Window window = application.GetWindow();
  62 + window.SetBackgroundColor(Color::BLACK);
  63 + auto windowSize = window.GetSize();
  64 +
  65 + // Set up emitter actor to be the full size of the window as some particles may be outside a particular size
  66 + mEmitterActor = Handle::New<Actor>({{Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER},
  67 + {Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER},
  68 + {Actor::Property::POSITION, Vector2::ZERO},
  69 + {Actor::Property::SIZE, Vector2(windowSize.GetWidth(), windowSize.GetHeight())}});
  70 + window.Add(mEmitterActor);
80 71
81 - mUILastControlPosition = position;  
82 - mUILastControlSize = (size == Vector2::ZERO ? Vector2(button.GetNaturalSize()) : size); 72 + // Create a tap gesture detector, attach the actor & connect
  73 + mTapDetector = TapGestureDetector::New();
  74 + mTapDetector.Attach(mEmitterActor);
  75 + mTapDetector.DetectedSignal().Connect(this, [&](Actor actor, const TapGesture& tap) { NextEffect(); });
83 76
84 - callbackMap[button.GetObjectPtr()] = onClick;  
85 - button.ClickedSignal().Connect(OnClick::Slot);  
86 - return button; 77 + // Respond to key events
  78 + window.KeyEventSignal().Connect(this, &ParticleEffectController::OnKeyEvent);
  79 +
  80 + // Create a Text Label at the bottom of the screen
  81 + mTextLabel = Handle::New<TextLabel>({{Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER},
  82 + {Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER},
  83 + {TextLabel::Property::MULTI_LINE, true},
  84 + {TextLabel::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::CENTER},
  85 + {TextLabel::Property::TEXT_COLOR, Color::WHITE}});
  86 + window.Add(mTextLabel);
  87 +
  88 + // Create a fade out animation for the text label after a few seconds
  89 + mTextLabelAnimation = Animation::New(TEXT_LABEL_ANIMATION_TIME);
  90 + mTextLabelAnimation.AnimateTo(Property(mTextLabel, Actor::Property::COLOR_ALPHA), 0.0f, TEXT_LABEL_ANIMATION_TIME_PERIOD);
  91 + mTextLabelAnimation.Play();
  92 +
  93 + // Start the default effect
  94 + StartEffect(EffectType(mCurrentEffectType));
  95 +
  96 + // Add extra line to text for further instructions only the first time
  97 + std::string label = mTextLabel[TextLabel::Property::TEXT];
  98 + label += "\nTap to change particle effect";
  99 + mTextLabel[TextLabel::Property::TEXT] = label;
87 } 100 }
88 101
89 - // The Init signal is received once (only) during the Application lifetime  
90 - void Create(Application& application) 102 + void StartEffect(EffectType effectType)
91 { 103 {
92 - using namespace Dali::ParticleEffect; 104 + if(mCurrentEmitter)
  105 + {
  106 + mCurrentEmitter.Stop();
  107 + mCurrentEmitter.Reset();
  108 + }
93 109
94 - // Get a handle to the window  
95 - Window window = application.GetWindow();  
96 - window.SetBackgroundColor(Color::BLACK); 110 + ParticleEffectParams params{};
  111 + std::string effectName;
  112 +
  113 + switch(effectType)
97 { 114 {
98 - Actor emitterActor = Actor::New();  
99 - emitterActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);  
100 - emitterActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);  
101 - emitterActor.SetProperty(Actor::Property::POSITION, Vector2(0.0, 0.0f));  
102 - emitterActor.SetProperty(Actor::Property::SIZE, Vector2(1.0, 1.0f));  
103 - emitterActor.SetProperty(Actor::Property::UPDATE_AREA_HINT, Vector4(0, 0, window.GetSize().GetWidth(), window.GetSize().GetHeight()));  
104 -  
105 - window.Add(emitterActor);  
106 -  
107 - mEmitterActor = emitterActor;  
108 - PushButton lastButton;  
109 - window.Add(  
110 - MakeButton<PushButton>("Fire Effect", Vector2::ZERO, {}, true, [&](Button button){  
111 -  
112 - if(mCurrentEmitter)  
113 - {  
114 - mCurrentEmitter.Stop();  
115 - mCurrentEmitter.Reset();  
116 - }  
117 -  
118 - ParticleEffectParams params{};  
119 - params.particleCount = 5000;  
120 - params.emissionRate = 1000;  
121 - params.initialParticleCount = 0;  
122 - params.sourceSize = Vector2(200, 10);  
123 - params.strTexture = "sparkle-part1.png";  
124 -  
125 - mCurrentEmitter = mParticleSystem->CreateEffectEmitter( EffectType::FIRE_RING, mEmitterActor, params );  
126 - mCurrentEmitter.Start();  
127 - return true;  
128 - })  
129 - );  
130 -  
131 - window.Add(  
132 - MakeButton<PushButton>("Sparkle Effect", Vector2(0.0f, mUILastControlSize.height), {}, true, [&](Button button){  
133 - if(mCurrentEmitter)  
134 - {  
135 - mCurrentEmitter.Stop();  
136 - mCurrentEmitter.Reset();  
137 - }  
138 -  
139 - ParticleEffectParams params{};  
140 - params.particleCount = 10000;  
141 - params.emissionRate = 500;  
142 - params.initialParticleCount = 0;  
143 - params.sourceSize = Vector2(10, 10);  
144 - params.strTexture = "blue-part2.png";  
145 -  
146 - mCurrentEmitter = mParticleSystem->CreateEffectEmitter( EffectType::SPARKLES, mEmitterActor, params );  
147 - mCurrentEmitter.Start();  
148 - return true;  
149 - })  
150 - );  
151 -  
152 - window.Add(  
153 - MakeButton<PushButton>("Image Source Effect", Vector2(0.0f, mUILastControlPosition.y + mUILastControlSize.height), {}, true, [&](Button button){  
154 - if(mCurrentEmitter)  
155 - {  
156 - mCurrentEmitter.Stop();  
157 - mCurrentEmitter.Reset();  
158 - }  
159 -  
160 - ParticleEffectParams params{};  
161 - params.particleCount = 20000;  
162 - params.emissionRate = 0;  
163 - params.initialParticleCount = 10;  
164 - params.sourceSize = Vector2(64, 64);  
165 - params.strImageSourceName = "particle-image-source.jpg";  
166 -  
167 - mCurrentEmitter = mParticleSystem->CreateEffectEmitter( EffectType::IMAGE_EXPLOSION, mEmitterActor, params );  
168 - mCurrentEmitter.Start();  
169 - return true;  
170 - })  
171 - );  
172 - window.Add(  
173 - MakeButton<PushButton>("Quit", Vector2(0.0f, mUILastControlPosition.y + mUILastControlSize.height * 2), {}, true, [&](Button button){  
174 - if(mCurrentEmitter)  
175 - {  
176 - mCurrentEmitter.Stop();  
177 - mCurrentEmitter.Reset();  
178 - }  
179 - mApplication.Quit();  
180 - return true;  
181 - })  
182 - ); 115 + case EffectType::FIRE_RING:
  116 + params.particleCount = 5000;
  117 + params.emissionRate = 1000;
  118 + params.initialParticleCount = 0;
  119 + params.sourceSize = Vector2(200, 10);
  120 + params.strTexture = "sparkle-part1.png";
  121 + effectName = "Fire Effect";
  122 + break;
  123 +
  124 + case EffectType::SPARKLES:
  125 + params.particleCount = 10000;
  126 + params.emissionRate = 500;
  127 + params.initialParticleCount = 0;
  128 + params.sourceSize = Vector2(10, 10);
  129 + params.strTexture = "blue-part2.png";
  130 + effectName = "Sparkle Effect";
  131 + break;
  132 +
  133 + case EffectType::IMAGE_EXPLOSION:
  134 + params.particleCount = 20000;
  135 + params.emissionRate = 0;
  136 + params.initialParticleCount = 10;
  137 + params.sourceSize = Vector2(64, 64);
  138 + params.strImageSourceName = "particle-image-source.jpg";
  139 + effectName = "Image Source Effect";
  140 + break;
183 } 141 }
184 142
185 - // Respond to key events  
186 - window.KeyEventSignal().Connect(this, &ParticleEffectController::OnKeyEvent); 143 + mCurrentEmitter = mParticleSystem->CreateEffectEmitter(effectType, mEmitterActor, params);
  144 + mCurrentEmitter.Start();
  145 +
  146 + // Set text and reset TextLabel properties and animation
  147 + mTextLabel[Toolkit::TextLabel::Property::TEXT] = effectName;
  148 + mTextLabel[Actor::Property::COLOR_ALPHA] = 1.0f;
  149 + mTextLabelAnimation.SetCurrentProgress(0.0f);
  150 + mTextLabelAnimation.Play();
  151 + }
  152 +
  153 + void NextEffect()
  154 + {
  155 + StartEffect(EffectType(++mCurrentEffectType %= NUMBER_OF_EFFECTS));
187 } 156 }
188 157
189 void OnKeyEvent(const KeyEvent& event) 158 void OnKeyEvent(const KeyEvent& event)
@@ -194,25 +163,31 @@ public: @@ -194,25 +163,31 @@ public:
194 { 163 {
195 mApplication.Quit(); 164 mApplication.Quit();
196 } 165 }
  166 + else
  167 + {
  168 + NextEffect();
  169 + }
197 } 170 }
198 } 171 }
199 172
200 private: 173 private:
  174 + using ParticleEffectPtr = std::unique_ptr<Dali::ParticleEffect::ParticleEffect>;
201 175
202 - Application& mApplication;  
203 - std::unique_ptr<Dali::ParticleEffect::ParticleEffect> mParticleSystem;  
204 - ParticleEmitter mCurrentEmitter;  
205 - Actor mEmitterActor; 176 + Application& mApplication;
  177 + ParticleEffectPtr mParticleSystem;
  178 + ParticleEmitter mCurrentEmitter;
  179 + Actor mEmitterActor;
206 180
207 - // Needed for buttons  
208 - Vector2 mUILastControlPosition;  
209 - Vector2 mUILastControlSize; 181 + TapGestureDetector mTapDetector;
210 182
  183 + uint32_t mCurrentEffectType{0u};
  184 + Actor mTextLabel;
  185 + Animation mTextLabelAnimation;
211 }; 186 };
212 187
213 int DALI_EXPORT_API main(int argc, char** argv) 188 int DALI_EXPORT_API main(int argc, char** argv)
214 { 189 {
215 - Application application = Application::New(&argc, &argv); 190 + Application application = Application::New(&argc, &argv);
216 ParticleEffectController test(application); 191 ParticleEffectController test(application);
217 application.MainLoop(); 192 application.MainLoop();
218 return 0; 193 return 0;