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 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 17  
18 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 20 #include <dali-toolkit/public-api/particle-system/particle-domain.h>
  21 +#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
23 22 #include <dali-toolkit/public-api/particle-system/particle-list.h>
24 23 #include <dali-toolkit/public-api/particle-system/particle-renderer.h>
  24 +#include <dali-toolkit/public-api/particle-system/particle-source.h>
25 25 #include <dali-toolkit/public-api/particle-system/particle-types.h>
26 26  
27   -#include <utility>
28   -#include <ctime>
29 27 #include <dali-toolkit/public-api/particle-system/particle-modifier.h>
30   -#include <unistd.h>
31   -#include <map>
32 28  
33 29 #include "effects/particle-effect.h"
34 30  
... ... @@ -39,13 +35,16 @@ using Dali::Toolkit::TextLabel;
39 35  
40 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 43 * This example shows Particle System feature
44 44 */
45 45 class ParticleEffectController : public ConnectionTracker
46 46 {
47 47 public:
48   -
49 48 ParticleEffectController(Application& application)
50 49 : mApplication(application)
51 50 {
... ... @@ -55,135 +54,105 @@ public:
55 54  
56 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 158 void OnKeyEvent(const KeyEvent& event)
... ... @@ -194,25 +163,31 @@ public:
194 163 {
195 164 mApplication.Quit();
196 165 }
  166 + else
  167 + {
  168 + NextEffect();
  169 + }
197 170 }
198 171 }
199 172  
200 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 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 191 ParticleEffectController test(application);
217 192 application.MainLoop();
218 193 return 0;
... ...