Commit 9fe0bbd7cad662a72ffcadc7d772918e100a8c64

Authored by Adam Bialogonski
1 parent b9aeca68

Particle System Demo

Change-Id: Ib5cc186c001952c8f2f74c2371575a08d94bb607
build/tizen/examples/CMakeLists.txt
@@ -27,7 +27,7 @@ ENDIF() @@ -27,7 +27,7 @@ ENDIF()
27 27
28 FUNCTION(INSTALL_EXAMPLES EXAMPLE) 28 FUNCTION(INSTALL_EXAMPLES EXAMPLE)
29 SET(PARENT_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../") 29 SET(PARENT_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../")
30 - FILE(GLOB SRCS "${EXAMPLES_SRC_DIR}/${EXAMPLE}/*.cpp") 30 + FILE(GLOB_RECURSE SRCS "${EXAMPLES_SRC_DIR}/${EXAMPLE}/*.cpp")
31 SET(SRCS ${SRCS} "${ROOT_SRC_DIR}/shared/resources-location.cpp") 31 SET(SRCS ${SRCS} "${ROOT_SRC_DIR}/shared/resources-location.cpp")
32 IF(SHARED) 32 IF(SHARED)
33 ADD_LIBRARY(${EXAMPLE}.example SHARED ${SRCS}) 33 ADD_LIBRARY(${EXAMPLE}.example SHARED ${SRCS})
demo/dali-demo.cpp
1 /* 1 /*
2 - * Copyright (c) 2020 Samsung Electronics Co., Ltd. 2 + * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
@@ -53,6 +53,7 @@ int DALI_EXPORT_API main(int argc, char** argv) @@ -53,6 +53,7 @@ int DALI_EXPORT_API main(int argc, char** argv)
53 demo.AddExample(Example("motion-blur.example", DALI_DEMO_STR_TITLE_MOTION_BLUR)); 53 demo.AddExample(Example("motion-blur.example", DALI_DEMO_STR_TITLE_MOTION_BLUR));
54 demo.AddExample(Example("page-turn-view.example", DALI_DEMO_STR_TITLE_PAGE_TURN)); 54 demo.AddExample(Example("page-turn-view.example", DALI_DEMO_STR_TITLE_PAGE_TURN));
55 demo.AddExample(Example("particles.example", DALI_DEMO_STR_TITLE_PARTICLES)); 55 demo.AddExample(Example("particles.example", DALI_DEMO_STR_TITLE_PARTICLES));
  56 + demo.AddExample(Example("particle-system.example", DALI_DEMO_STR_TITLE_PARTICLE_SYSTEM));
56 demo.AddExample(Example("reflection-demo.example", DALI_DEMO_STR_TITLE_REFLECTION)); 57 demo.AddExample(Example("reflection-demo.example", DALI_DEMO_STR_TITLE_REFLECTION));
57 demo.AddExample(Example("refraction-effect.example", DALI_DEMO_STR_TITLE_REFRACTION)); 58 demo.AddExample(Example("refraction-effect.example", DALI_DEMO_STR_TITLE_REFRACTION));
58 demo.AddExample(Example("renderer-stencil.example", DALI_DEMO_STR_TITLE_RENDERER_STENCIL)); 59 demo.AddExample(Example("renderer-stencil.example", DALI_DEMO_STR_TITLE_RENDERER_STENCIL));
examples-reel/dali-examples-reel.cpp
1 /* 1 /*
2 - * Copyright (c) 2021 Samsung Electronics Co., Ltd. 2 + * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
@@ -78,6 +78,7 @@ int DALI_EXPORT_API main(int argc, char** argv) @@ -78,6 +78,7 @@ int DALI_EXPORT_API main(int argc, char** argv)
78 demo.AddExample(Example("mesh-morph.example", DALI_DEMO_STR_TITLE_MESH_MORPH)); 78 demo.AddExample(Example("mesh-morph.example", DALI_DEMO_STR_TITLE_MESH_MORPH));
79 demo.AddExample(Example("motion-stretch.example", DALI_DEMO_STR_TITLE_MOTION_STRETCH)); 79 demo.AddExample(Example("motion-stretch.example", DALI_DEMO_STR_TITLE_MOTION_STRETCH));
80 demo.AddExample(Example("native-image-source.example", DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE)); 80 demo.AddExample(Example("native-image-source.example", DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE));
  81 + demo.AddExample(Example("particle-system.example", DALI_DEMO_STR_TITLE_PARTICLE_SYSTEM));
81 demo.AddExample(Example("popup.example", DALI_DEMO_STR_TITLE_POPUP)); 82 demo.AddExample(Example("popup.example", DALI_DEMO_STR_TITLE_POPUP));
82 demo.AddExample(Example("pivot.example", DALI_DEMO_STR_TITLE_PIVOT)); 83 demo.AddExample(Example("pivot.example", DALI_DEMO_STR_TITLE_PIVOT));
83 demo.AddExample(Example("primitive-shapes.example", DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES)); 84 demo.AddExample(Example("primitive-shapes.example", DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES));
examples/particle-system/effects/fire-ring-effect-modifier.cpp 0 → 100644
  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 "fire-ring-effect-modifier.h"
  19 +#include "fire-ring-effect-source.h"
  20 +
  21 +namespace Dali::ParticleEffect
  22 +{
  23 +FireModifier::FireModifier(ParticleEmitter& emitter)
  24 +: mEmitter(emitter)
  25 +{
  26 + // initialize gradient with flame colors
  27 + mFireGradient.PushColor(Vector4(1.0f, 1.0f, 1.0f, 1.0f), 1.0f - 1.0f);
  28 + mFireGradient.PushColor(Vector4(0.975, 0.955, 0.476, 1.0f), 1.0f - 0.947f);
  29 + mFireGradient.PushColor(Vector4(0.999, 0.550, 0.194, 1.0f), 1.0f - 0.800f);
  30 + mFireGradient.PushColor(Vector4(0.861, 0.277, 0.094, 1.0f), 1.0f - 0.670f);
  31 + mFireGradient.PushColor(Vector4(0.367, 0.0, 0.0, 1.0f), 1.0f - 0.456f);
  32 + mFireGradient.PushColor(Vector4(0.3, 0.3, 0.3, 1.0f), 1.0f - 0.400f);
  33 + mFireGradient.PushColor(Vector4(0.3, 0.2, 0.2, 1.0f), 1.0f - 0.200f);
  34 + mFireGradient.PushColor(Vector4(0.2, 0.1, 0.1, 1.0f), 1.0f - 0.150f);
  35 + mFireGradient.PushColor(Vector4(0.1, 0.0, 0.0, 1.0f), 1.0f- 0.100f);
  36 + mFireGradient.PushColor(Vector4(0.0, 0.0, 0.0, 0.5f), 1.0f-0.050f);
  37 + mFireGradient.PushColor(Vector4(0.0, 0.0, 0.0, 0.2f), 1.0f);
  38 +}
  39 +
  40 +bool FireModifier::IsMultiThreaded()
  41 +{
  42 + return false;
  43 +}
  44 +
  45 +void FireModifier::Update(ParticleList& particleList, uint32_t first, uint32_t count)
  46 +{
  47 + // If no acive particles return
  48 + if(!particleList.GetActiveParticleCount())
  49 + {
  50 + return;
  51 + }
  52 +
  53 + mAngle = ((mAngle + 2) % 360);
  54 +
  55 + // Retrieve the Source and get the stream
  56 + if(!mStreamBasePos)
  57 + {
  58 + mStreamBasePos = static_cast<FireSource*>(&mEmitter.GetSource().GetSourceCallback())->mStreamBasePos;
  59 + }
  60 +
  61 + // Missing stream, return!
  62 + if(!mStreamBasePos)
  63 + {
  64 + return;
  65 + }
  66 +
  67 + auto& activeParticles = particleList.GetActiveParticles();
  68 +
  69 + auto it = activeParticles.begin();
  70 + std::advance(it, first);
  71 +
  72 + int i = 0;
  73 + for(; count; ++it, count--)
  74 + {
  75 + i += 1;
  76 +
  77 + // Acquire stream data
  78 + auto& particle = *it;
  79 + auto& position = particle.Get<Vector3>(ParticleStream::POSITION_STREAM_BIT);
  80 + auto& velocity = particle.Get<Vector3>(ParticleStream::VELOCITY_STREAM_BIT);
  81 + auto& color = particle.Get<Vector4>(ParticleStream::COLOR_STREAM_BIT);
  82 + auto& baseLifetime = particle.Get<float>(ParticleStream::LIFETIME_BASE_STREAM_BIT);
  83 + auto& scale = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
  84 +
  85 + // Get base positions
  86 + auto& basePos = particle.GetByIndex<Vector3>(mStreamBasePos);
  87 +
  88 + float lifetime = particle.Get<float>(ParticleStream::LIFETIME_STREAM_BIT);
  89 + position.y += -fabs(velocity.y);
  90 + position.x = basePos.x + 5.0f * sin((((mAngle + i)%360)*M_PI)/180.f );
  91 +
  92 + velocity *= 0.990f;
  93 + auto newColor = mFireGradient.GetColorAt((baseLifetime - lifetime) / baseLifetime);
  94 + float normalizedTime = (lifetime / baseLifetime);
  95 + newColor.a = normalizedTime * normalizedTime;
  96 +
  97 + scale = Vector3(64.0f*(normalizedTime * normalizedTime * normalizedTime * normalizedTime), 64.0f*(normalizedTime * normalizedTime * normalizedTime * normalizedTime), 1.0);
  98 +
  99 + color = newColor;
  100 + }
  101 +}
  102 +}
0 \ No newline at end of file 103 \ No newline at end of file
examples/particle-system/effects/fire-ring-effect-modifier.h 0 → 100644
  1 +#ifndef DALI_PROJECT_FIRE_RING_EFFECT_MODIFIER_H
  2 +#define DALI_PROJECT_FIRE_RING_EFFECT_MODIFIER_H
  3 +
  4 +/*
  5 + * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + *
  19 + */
  20 +
  21 +
  22 +#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
  23 +#include <dali-toolkit/public-api/particle-system/particle-source.h>
  24 +#include <dali-toolkit/public-api/particle-system/particle-modifier.h>
  25 +#include <dali-toolkit/public-api/particle-system/particle-list.h>
  26 +#include <dali-toolkit/public-api/particle-system/particle.h>
  27 +#include <dali/public-api/common/vector-wrapper.h>
  28 +#include <ctime>
  29 +
  30 +namespace Dali::ParticleEffect
  31 +{
  32 +using namespace Dali::Toolkit::ParticleSystem;
  33 +
  34 +class FireModifier : public ParticleModifierInterface
  35 +{
  36 +public:
  37 +
  38 + struct ColorGradient
  39 + {
  40 + std::vector<Vector4> colors;
  41 + std::vector<float> position;
  42 +
  43 + void PushColor(const Vector4& color, float pos)
  44 + {
  45 + colors.emplace_back(color);
  46 + position.emplace_back(pos);
  47 + }
  48 +
  49 + Vector4 GetColorAt(float pos)
  50 + {
  51 + if(pos >= 1.0f)
  52 + {
  53 + return colors.back();
  54 + }
  55 + else if(pos <= 0.0f)
  56 + {
  57 + return colors[0];
  58 + }
  59 + for(auto i = 0u; i < position.size() - 1; ++i)
  60 + {
  61 + if(pos >= position[i] && pos < position[i + 1])
  62 + {
  63 + auto colorDiff = colors[i + 1] - colors[i];
  64 + return colors[i] + (colorDiff * ((pos - position[i]) / (position[i + 1] - position[i])));
  65 + }
  66 + }
  67 + return colors[0];
  68 + }
  69 + };
  70 +
  71 +
  72 + explicit FireModifier(ParticleEmitter& emitter);
  73 +
  74 + bool IsMultiThreaded() override;
  75 +
  76 + void Update(ParticleList& particleList, uint32_t first, uint32_t count) override;
  77 +
  78 + ColorGradient mFireGradient;
  79 + ParticleEmitter mEmitter;
  80 + uint32_t mStreamBasePos{0u};
  81 + uint32_t mAngle{0u};
  82 +};
  83 +
  84 +
  85 +
  86 +}
  87 +
  88 +#endif // DALI_PROJECT_FIRE_RING_EFFECT_MODIFIER_H
examples/particle-system/effects/fire-ring-effect-source.cpp 0 → 100644
  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 "fire-ring-effect-source.h"
  19 +#include <random>
  20 +
  21 +namespace Dali::ParticleEffect
  22 +{
  23 +static float LIFETIME = 5.0f;
  24 +FireSource::FireSource(ParticleEmitter& emitter)
  25 +: mEmitter(emitter)
  26 +{
  27 + std::time_t result = std::time(nullptr);
  28 + srand(result);
  29 + mRadius = Vector2::ONE;
  30 +}
  31 +
  32 +FireSource::FireSource(ParticleEmitter& emitter, Dali::Vector2 ringRadius) :
  33 +mEmitter(emitter)
  34 +{
  35 + std::time_t result = std::time(nullptr);
  36 + srand(result);
  37 + mRadius = ringRadius;
  38 +
  39 +}
  40 +
  41 +void FireSource::Init()
  42 +{
  43 + mStreamBasePos = mEmitter.GetParticleList().AddLocalStream<Vector3>(Vector3::ZERO);
  44 +}
  45 +
  46 +uint32_t FireSource::Update(ParticleList& particleList, uint32_t count)
  47 +{
  48 + while(count--)
  49 + {
  50 + auto particle = particleList.NewParticle(LIFETIME * (float(std::rand() % 1000)/1000.0f) + 1.0f );
  51 + if(!particle)
  52 + {
  53 + return 0u;
  54 + }
  55 +
  56 + auto& basePosition = particle.GetByIndex<Vector3>(mStreamBasePos);
  57 +
  58 + auto& position = particle.Get<Vector3>(ParticleStream::POSITION_STREAM_BIT);
  59 + auto& color = particle.Get<Vector4>(ParticleStream::COLOR_STREAM_BIT);
  60 + auto& velocity = particle.Get<Vector3>(ParticleStream::VELOCITY_STREAM_BIT);
  61 + auto& scale = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
  62 + UpdateParticle(position, basePosition, color, velocity, scale);
  63 + }
  64 +
  65 + return 0;
  66 +}
  67 +
  68 +void FireSource::UpdateParticle(Vector3& position, Vector3& basePosition, Vector4& color, Vector3& velocity, Vector3& scale)
  69 +{
  70 + float posRadians = ((rand() % 360) * M_PI) / 180.0f;
  71 +
  72 + basePosition.x = position.x = mRadius.x * sin(posRadians);
  73 + basePosition.y = position.y = mRadius.y * cos(posRadians);
  74 + color = Dali::Color::WHITE; // white color when emitted
  75 +
  76 + // angle of motion
  77 + float radians = ((rand() % 360) * M_PI) / 180.0f;
  78 + float speed = ((rand() % 5) + 5);
  79 + velocity.x = sin(radians) * speed;
  80 + velocity.y = cos(radians) * speed;
  81 +
  82 + // Random initial scale
  83 + float currentScale = float(rand() % 32) + 32;
  84 + scale = Vector3(currentScale, currentScale, 1);
  85 +}
  86 +
  87 +} // namespace Dali::ParticleEffect
0 \ No newline at end of file 88 \ No newline at end of file
examples/particle-system/effects/fire-ring-effect-source.h 0 → 100644
  1 +#ifndef DALI_FIRE_RING_EFFECT_SOURCE_H
  2 +#define DALI_FIRE_RING_EFFECT_SOURCE_H
  3 +
  4 +/*
  5 + * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + *
  19 + */
  20 +
  21 +#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
  22 +#include <dali-toolkit/public-api/particle-system/particle-source.h>
  23 +#include <dali-toolkit/public-api/particle-system/particle-modifier.h>
  24 +#include <dali-toolkit/public-api/particle-system/particle-list.h>
  25 +#include <dali-toolkit/public-api/particle-system/particle.h>
  26 +#include <ctime>
  27 +
  28 +namespace Dali::ParticleEffect
  29 +{
  30 +using namespace Dali::Toolkit::ParticleSystem;
  31 +
  32 +class FireSource : public Toolkit::ParticleSystem::ParticleSourceInterface
  33 +{
  34 +public:
  35 +
  36 + explicit FireSource(ParticleEmitter& emitter);
  37 +
  38 + explicit FireSource(ParticleEmitter& emitter, Dali::Vector2 ringRadius);
  39 +
  40 + uint32_t Update(ParticleList& particleList, uint32_t count) override;
  41 +
  42 + void Init() override;
  43 +
  44 + void UpdateParticle(Vector3& position, Vector3& basePosition, Vector4& color, Vector3& velocity, Vector3& scale);
  45 +
  46 + ParticleEmitter mEmitter;
  47 +
  48 + Dali::Vector2 mRadius;
  49 +
  50 + uint32_t mStreamBasePos{0u};
  51 +
  52 +};
  53 +
  54 +}
  55 +#endif // DALI_FIRE_RING_EFFECT_SOURCE_H
examples/particle-system/effects/image-effect-modifier.cpp 0 → 100644
  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 "image-effect-modifier.h"
  19 +#include "image-effect-source.h"
  20 +namespace Dali::ParticleEffect
  21 +{
  22 +
  23 +#define RAD(x) (float(x)*M_PI/180.0f)
  24 +
  25 +ImageExplodeEffectModifier::ImageExplodeEffectModifier(ParticleEmitter& emitter)
  26 +: mEmitter(emitter)
  27 +{
  28 +
  29 +}
  30 +
  31 +bool ImageExplodeEffectModifier::IsMultiThreaded()
  32 +{
  33 + return false;
  34 +}
  35 +
  36 +void ImageExplodeEffectModifier::Update(ParticleList& particleList, uint32_t first, uint32_t count)
  37 +{
  38 + // If no acive particles return
  39 + if(!particleList.GetActiveParticleCount())
  40 + {
  41 + return;
  42 + }
  43 +
  44 + // Retrieve the Source and get the stream
  45 + if(!mStreamBasePos)
  46 + {
  47 + mStreamBasePos = static_cast<ImageExplodeEffectSource*>(&mEmitter.GetSource().GetSourceCallback())->mStreamBasePos;
  48 + }
  49 +
  50 + // Missing stream, return!
  51 + if(!mStreamBasePos)
  52 + {
  53 + return;
  54 + }
  55 +
  56 + auto& activeParticles = particleList.GetActiveParticles();
  57 +
  58 + auto it = activeParticles.begin();
  59 + std::advance(it, first);
  60 +
  61 + mAngle += 5.0f;
  62 +
  63 + for(; count; ++it, count--)
  64 + {
  65 + // Acquire stream data
  66 + auto& particle = *it;
  67 + auto& position = particle.Get<Vector3>(ParticleStream::POSITION_STREAM_BIT);
  68 + auto& color = particle.Get<Vector4>(ParticleStream::COLOR_STREAM_BIT);
  69 +
  70 + // Get base positions
  71 + auto& basePos = particle.GetByIndex<Vector3>(mStreamBasePos);
  72 + position.z = 200.f * sin(RAD(mAngle+basePos.x));
  73 + color.a = position.z < 0.0f ? 1.0f : 1.0f - position.z/500.0f;
  74 + position.z = 500 + position.z;
  75 + }
  76 +}
  77 +}
0 \ No newline at end of file 78 \ No newline at end of file
examples/particle-system/effects/image-effect-modifier.h 0 → 100644
  1 +#ifndef DALI_IMAGE_EFFECT_MODIFIER_H
  2 +#define DALI_IMAGE_EFFECT_MODIFIER_H
  3 +
  4 +/*
  5 + * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + *
  19 + */
  20 +
  21 +
  22 +#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
  23 +#include <dali-toolkit/public-api/particle-system/particle-source.h>
  24 +#include <dali-toolkit/public-api/particle-system/particle-modifier.h>
  25 +#include <dali-toolkit/public-api/particle-system/particle-list.h>
  26 +#include <dali-toolkit/public-api/particle-system/particle.h>
  27 +#include <ctime>
  28 +
  29 +namespace Dali::ParticleEffect
  30 +{
  31 +using namespace Dali::Toolkit::ParticleSystem;
  32 +
  33 +class ImageExplodeEffectModifier : public ParticleModifierInterface
  34 +{
  35 +public:
  36 +
  37 + explicit ImageExplodeEffectModifier(ParticleEmitter& emitter);
  38 +
  39 + bool IsMultiThreaded() override;
  40 +
  41 + void Update(ParticleList& particleList, uint32_t first, uint32_t count) override;
  42 +
  43 + ParticleEmitter mEmitter;
  44 + uint32_t mStreamBasePos{0u};
  45 + float mAngle{0.0f};
  46 +
  47 +};
  48 +
  49 +
  50 +
  51 +}
  52 +
  53 +#endif // DALI_IMAGE_EFFECT_MODIFIER_H
examples/particle-system/effects/image-effect-source.cpp 0 → 100644
  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 "image-effect-source.h"
  19 +#include <dali/devel-api/rendering/texture-devel.h>
  20 +#include <dali/devel-api/adaptor-framework/image-loading.h>
  21 +#include <random>
  22 +
  23 +namespace Dali::ParticleEffect
  24 +{
  25 +namespace
  26 +{
  27 +Vector4 GetColorAt(uint32_t x, uint32_t y, Devel::PixelBuffer& buffer)
  28 +{
  29 + if(buffer.GetPixelFormat() == Pixel::Format::RGBA8888)
  30 + {
  31 + const auto ptr = reinterpret_cast<uint32_t*>(buffer.GetBuffer());
  32 + auto value = *(ptr + x + (y * buffer.GetHeight()));
  33 + auto rgba = reinterpret_cast<uint8_t*>(&value);
  34 + return Vector4(float(rgba[0]) / 255.0f, float(rgba[1]) / 255.0f, float(rgba[2]) / 255.0f, 1.0f);
  35 + }
  36 + else
  37 + {
  38 + auto rgba = reinterpret_cast<uint8_t*>(buffer.GetBuffer() + (y*buffer.GetWidth()*3) + (x*3));
  39 + return Vector4(float(rgba[0]) / 255.0f, float(rgba[1]) / 255.0f, float(rgba[2]) / 255.0f, 1.0f);
  40 + }
  41 +}
  42 +}
  43 +
  44 +static float LIFETIME = 50000.0f; // we need infinite lifetime?
  45 +ImageExplodeEffectSource::ImageExplodeEffectSource(ParticleEmitter& emitter)
  46 +: mEmitter(emitter)
  47 +{
  48 +}
  49 +
  50 +ImageExplodeEffectSource::ImageExplodeEffectSource(ParticleEmitter& emitter, const std::string& imageFileName, uint32_t width, uint32_t height) :
  51 +mEmitter(emitter)
  52 +{
  53 +
  54 + // Create texture
  55 + std::string filePath(DEMO_IMAGE_DIR);
  56 + filePath += imageFileName;
  57 + ImageDimensions dimensions(width, height);
  58 + // Pixel buffer will be used as a source of pixels (populating colors of particles based on image pixels)
  59 + Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromFile(filePath, dimensions, FittingMode::SHRINK_TO_FIT, SamplingMode::DEFAULT, false);
  60 + mImageWidth = pixelBuffer.GetWidth();
  61 + mImageHeight = pixelBuffer.GetHeight();
  62 + mPixelBuffer = pixelBuffer;
  63 +}
  64 +
  65 +void ImageExplodeEffectSource::Init()
  66 +{
  67 + mStreamBasePos = mEmitter.GetParticleList().AddLocalStream<Vector3>(Vector3::ZERO);
  68 +}
  69 +
  70 +uint32_t ImageExplodeEffectSource::Update(ParticleList& particleList, uint32_t count)
  71 +{
  72 + if(!mShouldEmit)
  73 + {
  74 + return 0;
  75 + }
  76 +
  77 + if(mPixelBuffer.GetPixelFormat() != Dali::Pixel::RGBA8888 &&
  78 + mPixelBuffer.GetPixelFormat() != Dali::Pixel::RGB888)
  79 + {
  80 + return 0;
  81 + }
  82 +
  83 + auto i = 0u;
  84 + float particleScale = 4.0f;
  85 + float pixelSize = 2.0f;
  86 +
  87 + uint32_t halfWidth = (mImageWidth/2) * particleScale;
  88 + uint32_t halfHeight = (mImageHeight/2) * particleScale;
  89 +
  90 + for(auto y = 0u ; y < mImageHeight; ++y)
  91 + {
  92 + for(auto x = 0u; x < mImageWidth; ++x)
  93 + {
  94 + if(i < particleList.GetCapacity())
  95 + {
  96 + // Ignore count, populating all pixels instantly (emitter must account for all the points)
  97 + auto particle = particleList.NewParticle(LIFETIME);
  98 +
  99 + auto& basePosition = particle.GetByIndex<Vector3>(mStreamBasePos);
  100 + auto& position = particle.Get<Vector3>(ParticleStream::POSITION_STREAM_BIT);
  101 + auto& color = particle.Get<Vector4>(ParticleStream::COLOR_STREAM_BIT);
  102 + auto& velocity = particle.Get<Vector3>(ParticleStream::VELOCITY_STREAM_BIT);
  103 + auto& scale = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
  104 + color = GetColorAt(x, y, mPixelBuffer);
  105 + // Set basePosition
  106 + position = basePosition = Vector3(x* particleScale -halfWidth, y* particleScale -halfHeight, 0);
  107 + scale = Vector3(pixelSize, pixelSize, 1);
  108 + velocity = Vector3::ZERO;
  109 + }
  110 + ++i;
  111 + }
  112 + }
  113 +
  114 + mShouldEmit = false;
  115 + return mImageWidth * mImageHeight;
  116 +}
  117 +
  118 +
  119 +} // namespace Dali::ParticleEffect
0 \ No newline at end of file 120 \ No newline at end of file
examples/particle-system/effects/image-effect-source.h 0 → 100644
  1 +#ifndef DALI_IMAGE_EFFECT_SOURCE_H
  2 +#define DALI_IMAGE_EFFECT_SOURCE_H
  3 +
  4 +/*
  5 + * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + *
  19 + */
  20 +
  21 +#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
  22 +#include <dali-toolkit/public-api/particle-system/particle-source.h>
  23 +#include <dali-toolkit/public-api/particle-system/particle-modifier.h>
  24 +#include <dali-toolkit/public-api/particle-system/particle-list.h>
  25 +#include <dali-toolkit/public-api/particle-system/particle.h>
  26 +#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
  27 +#include <ctime>
  28 +
  29 +namespace Dali::ParticleEffect
  30 +{
  31 +using namespace Dali::Toolkit::ParticleSystem;
  32 +
  33 +/**
  34 + * Image source will use 2D image to populate points for the emitter
  35 + * This particular implementation populates points only once.
  36 + */
  37 +class ImageExplodeEffectSource : public Toolkit::ParticleSystem::ParticleSourceInterface
  38 +{
  39 +public:
  40 +
  41 + explicit ImageExplodeEffectSource(ParticleEmitter& emitter);
  42 +
  43 + explicit ImageExplodeEffectSource(ParticleEmitter& emitter, const std::string& imageFileName, uint32_t width, uint32_t height);
  44 +
  45 + uint32_t Update(ParticleList& particleList, uint32_t count) override;
  46 +
  47 + void Init() override;
  48 +
  49 + ParticleEmitter mEmitter;
  50 +
  51 + uint32_t mImageWidth{0u};
  52 + uint32_t mImageHeight{0u};
  53 +
  54 + uint32_t mStreamBasePos{0u};
  55 +
  56 + Devel::PixelBuffer mPixelBuffer;
  57 +
  58 + bool mShouldEmit {true};
  59 +};
  60 +
  61 +}
  62 +#endif // DALI_IMAGE_EFFECT_SOURCE_H
examples/particle-system/effects/particle-effect.cpp 0 → 100644
  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 "particle-effect.h"
  19 +#include "fire-ring-effect-source.h"
  20 +#include "sparkles-effect-source.h"
  21 +#include "image-effect-source.h"
  22 +#include "fire-ring-effect-modifier.h"
  23 +#include "sparkles-effect-modifier.h"
  24 +#include "image-effect-modifier.h"
  25 +
  26 +#include <dali-toolkit/public-api/particle-system/particle-domain.h>
  27 +#include <dali-toolkit/public-api/particle-system/particle-renderer.h>
  28 +#include <dali-toolkit/dali-toolkit.h>
  29 +#include <dali/public-api/common/vector-wrapper.h>
  30 +#include <functional>
  31 +
  32 +#ifndef DEMO_IMAGE_DIR
  33 +#define DEMO_IMAGE_DIR ""
  34 +#endif
  35 +
  36 +namespace Dali::ParticleEffect
  37 +{
  38 +using ParticleEmitter = Dali::Toolkit::ParticleSystem::ParticleEmitter;
  39 +using ParticleSource = Dali::Toolkit::ParticleSystem::ParticleSource;
  40 +using ParticleModifier = Dali::Toolkit::ParticleSystem::ParticleModifier;
  41 +
  42 +struct FunctorReturn
  43 +{
  44 + ParticleEmitter emitter;
  45 + ParticleSource source;
  46 + ParticleModifier modifier;
  47 +};
  48 +
  49 +static std::vector<FunctorReturn(*)(const ParticleEffectParams&)> gEffectInitializers =
  50 +{
  51 + [](const ParticleEffectParams& params){
  52 + ParticleEmitter emitter = ParticleEmitter::New();
  53 + return FunctorReturn{emitter, ParticleSource::New<FireSource>(emitter, params.sourceSize), ParticleModifier::New<FireModifier>(emitter) };
  54 + },
  55 + [](const ParticleEffectParams& params){
  56 + ParticleEmitter emitter = ParticleEmitter::New();
  57 + return FunctorReturn{emitter, ParticleSource::New<SparklesSource>(emitter), ParticleModifier::New<SparklesModifier>(emitter) };
  58 + },
  59 + [](const ParticleEffectParams& params){
  60 + ParticleEmitter emitter = ParticleEmitter::New();
  61 + return FunctorReturn{emitter, ParticleSource::New<ImageExplodeEffectSource>(emitter,
  62 + params.strImageSourceName,
  63 + uint32_t(params.sourceSize.width),
  64 + uint32_t(params.sourceSize.height)
  65 + ), ParticleModifier::New<ImageExplodeEffectModifier>(emitter) };
  66 + },
  67 +};
  68 +
  69 +ParticleEffect::ParticleEffect() = default;
  70 +
  71 +ParticleEffect::~ParticleEffect() = default;
  72 +
  73 +Dali::Toolkit::ParticleSystem::ParticleEmitter ParticleEffect::CreateEffectEmitter( EffectType effectType, Actor parentActor, const ParticleEffectParams& params )
  74 +{
  75 + auto retval = gEffectInitializers[int(effectType)](params);
  76 + auto emitter = retval.emitter;
  77 +
  78 + ParticleRenderer renderer = ParticleRenderer::New();
  79 +
  80 + if(!params.strTexture.empty())
  81 + {
  82 + // Create texture
  83 + std::string filename(DEMO_IMAGE_DIR);
  84 + filename += params.strTexture;
  85 + Dali::PixelData pixelData = Dali::Toolkit::SyncImageLoader::Load(filename);
  86 + auto texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight());
  87 + texture.Upload(pixelData);
  88 + renderer.SetTexture(texture);
  89 + }
  90 +
  91 + emitter.AttachTo(std::move(parentActor));
  92 + emitter.SetEmissionRate( params.emissionRate ); // 20 particles emitted per second
  93 + emitter.SetParticleCount( params.particleCount );
  94 + emitter.SetSource( retval.source );
  95 + emitter.SetDomain( ParticleDomain::New() );
  96 + emitter.AddModifier(retval.modifier);
  97 + emitter.SetRenderer( renderer );
  98 + renderer.SetBlendingMode(Dali::Toolkit::ParticleSystem::BlendingMode::SCREEN);
  99 + emitter.SetInitialParticleCount( params.initialParticleCount );
  100 +
  101 + return emitter;
  102 +}
  103 +
  104 +
  105 +}
  106 +
examples/particle-system/effects/particle-effect.h 0 → 100644
  1 +#ifndef DALI_PARTICLE_EFFECT_H
  2 +#define DALI_PARTICLE_EFFECT_H
  3 +
  4 +/*
  5 + * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + *
  19 + */
  20 +
  21 +#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
  22 +#include <memory>
  23 +
  24 +namespace Dali::ParticleEffect
  25 +{
  26 +
  27 +using EffectIndex = uint32_t;
  28 +
  29 +enum class EffectType
  30 +{
  31 + FIRE_RING,
  32 + SPARKLES,
  33 + IMAGE_EXPLOSION
  34 +};
  35 +
  36 +struct ParticleEffectParams
  37 +{
  38 + uint32_t emissionRate;
  39 + uint32_t particleCount;
  40 + uint32_t initialParticleCount;
  41 + Vector2 sourceSize;
  42 + std::string strTexture;
  43 + std::string strImageSourceName;
  44 +};
  45 +
  46 +/**
  47 + * Simple manager to spawn and control partcile emitters
  48 + */
  49 +class ParticleEffect
  50 +{
  51 +public:
  52 +
  53 + ParticleEffect();
  54 +
  55 + ~ParticleEffect();
  56 +
  57 + Dali::Toolkit::ParticleSystem::ParticleEmitter CreateEffectEmitter( EffectType effectType, Actor parentActor, const ParticleEffectParams& params );
  58 +
  59 +private:
  60 +
  61 +
  62 +};
  63 +}
  64 +
  65 +#endif // DALI_PARTICLE_MANAGER_H
0 \ No newline at end of file 66 \ No newline at end of file
examples/particle-system/effects/sparkles-effect-modifier.cpp 0 → 100644
  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 +}
0 \ No newline at end of file 90 \ No newline at end of file
examples/particle-system/effects/sparkles-effect-modifier.h 0 → 100644
  1 +#ifndef DALI_PARTICLES_SPARKLES_EFFECT_MODIFIER_H
  2 +#define DALI_PARTICLES_SPARKLES_EFFECT_MODIFIER_H
  3 +
  4 +/*
  5 + * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + *
  19 + */
  20 +
  21 +
  22 +#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
  23 +#include <dali-toolkit/public-api/particle-system/particle-source.h>
  24 +#include <dali-toolkit/public-api/particle-system/particle-modifier.h>
  25 +#include <dali-toolkit/public-api/particle-system/particle-list.h>
  26 +#include <dali-toolkit/public-api/particle-system/particle.h>
  27 +#include <dali/public-api/common/vector-wrapper.h>
  28 +#include <ctime>
  29 +
  30 +namespace Dali::ParticleEffect
  31 +{
  32 +using namespace Dali::Toolkit::ParticleSystem;
  33 +
  34 +class SparklesModifier : public ParticleModifierInterface
  35 +{
  36 +public:
  37 +
  38 + explicit SparklesModifier(ParticleEmitter& emitter);
  39 +
  40 + bool IsMultiThreaded() override;
  41 +
  42 + void Update(ParticleList& particleList, uint32_t first, uint32_t count) override;
  43 +
  44 + ParticleEmitter mEmitter;
  45 + uint32_t mStreamBasePos{0u};
  46 + uint32_t mStreamBaseAngle{0u};
  47 + uint32_t mAngle{0u};
  48 +};
  49 +
  50 +
  51 +
  52 +}
  53 +
  54 +#endif // DALI_PARTICLES_SPARKLES_EFFECT_MODIFIER_H
examples/particle-system/effects/sparkles-effect-source.cpp 0 → 100644
  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-source.h"
  19 +
  20 +namespace Dali::ParticleEffect
  21 +{
  22 +static float LIFETIME = 3.0f;
  23 +SparklesSource::SparklesSource(ParticleEmitter& emitter)
  24 +: mEmitter(emitter)
  25 +{
  26 + std::time_t result = std::time(nullptr);
  27 + srand(result);
  28 + mRadius = Vector2::ONE;
  29 +}
  30 +
  31 +SparklesSource::SparklesSource(ParticleEmitter& emitter, Dali::Vector2 ringRadius) :
  32 +mEmitter(emitter)
  33 +{
  34 + std::time_t result = std::time(nullptr);
  35 + srand(result);
  36 + mRadius = ringRadius;
  37 +
  38 +}
  39 +
  40 +void SparklesSource::Init()
  41 +{
  42 + mStreamBasePos = mEmitter.GetParticleList().AddLocalStream<Vector3>(Vector3::ZERO);
  43 + mStreamBaseAngle = mEmitter.GetParticleList().AddLocalStream<float>(0.0f);
  44 +}
  45 +
  46 +uint32_t SparklesSource::Update(ParticleList& particleList, uint32_t count)
  47 +{
  48 + while(count--)
  49 + {
  50 + auto particle = particleList.NewParticle(LIFETIME);
  51 + if(!particle)
  52 + {
  53 + return 0u;
  54 + }
  55 +
  56 + auto& basePosition = particle.GetByIndex<Vector3>(mStreamBasePos);
  57 + auto& angle = particle.GetByIndex<float>(mStreamBaseAngle);
  58 + auto& position = particle.Get<Vector3>(ParticleStream::POSITION_STREAM_BIT);
  59 + auto& color = particle.Get<Vector4>(ParticleStream::COLOR_STREAM_BIT);
  60 + auto& velocity = particle.Get<Vector3>(ParticleStream::VELOCITY_STREAM_BIT);
  61 + auto& scale = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
  62 +
  63 +
  64 + UpdateParticle(position, basePosition, color, velocity, scale, angle);
  65 + }
  66 +
  67 + return 0;
  68 +}
  69 +
  70 +void SparklesSource::UpdateParticle(Vector3& position, Vector3& basePosition, Vector4& color, Vector3& velocity, Vector3& scale, float& angle)
  71 +{
  72 + static uint32_t a = 0.0f;
  73 + float posRadians = ((rand() % 360) * M_PI) / 180.0f;
  74 +
  75 + basePosition.x = position.x = mRadius.x * sin(posRadians);
  76 + basePosition.y = position.y = mRadius.y * cos(posRadians);
  77 + color = Dali::Color::WHITE;
  78 +
  79 + angle = float(a);
  80 + a = ((a+5)%360);
  81 + float rad = ((rand() % 360) * M_PI) / 180.0f;
  82 + float speed = ((rand() % 5) + 5);
  83 + velocity.x = sin(rad) * speed;
  84 + velocity.y = cos(rad) * speed;
  85 +
  86 + // Random initial scale
  87 + float initialScale = float(rand() % 32) + 32;
  88 + scale = Vector3(initialScale, initialScale, 1);
  89 +}
  90 +
  91 +} // namespace Dali::ParticleEffect
0 \ No newline at end of file 92 \ No newline at end of file
examples/particle-system/effects/sparkles-effect-source.h 0 → 100644
  1 +#ifndef DALI_PARTICLES_SPARKLES_EFFECT_SOURCE_H
  2 +#define DALI_PARTICLES_SPARKLES_EFFECT_SOURCE_H
  3 +
  4 +/*
  5 + * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + *
  19 + */
  20 +
  21 +#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
  22 +#include <dali-toolkit/public-api/particle-system/particle-source.h>
  23 +#include <dali-toolkit/public-api/particle-system/particle-modifier.h>
  24 +#include <dali-toolkit/public-api/particle-system/particle-list.h>
  25 +#include <dali-toolkit/public-api/particle-system/particle.h>
  26 +#include <ctime>
  27 +
  28 +namespace Dali::ParticleEffect
  29 +{
  30 +using namespace Dali::Toolkit::ParticleSystem;
  31 +
  32 +class SparklesSource : public Toolkit::ParticleSystem::ParticleSourceInterface
  33 +{
  34 +public:
  35 +
  36 + explicit SparklesSource(ParticleEmitter& emitter);
  37 +
  38 + explicit SparklesSource(ParticleEmitter& emitter, Dali::Vector2 ringRadius);
  39 +
  40 + uint32_t Update(ParticleList& particleList, uint32_t count) override;
  41 +
  42 + void Init() override;
  43 +
  44 + void UpdateParticle(Vector3& position, Vector3& basePosition, Vector4& color, Vector3& velocity, Vector3& scale, float& angle);
  45 +
  46 + ParticleEmitter mEmitter;
  47 +
  48 + Dali::Vector2 mRadius;
  49 +
  50 + uint32_t mStreamBasePos{0u};
  51 + uint32_t mStreamBaseAngle{0u};
  52 +
  53 +};
  54 +
  55 +}
  56 +#endif // DALI_PARTICLES_SPARKLES_EFFECT_SOURCE_H
examples/particle-system/particle-system-example.cpp 0 → 100644
  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 <dali-toolkit/dali-toolkit.h>
  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>
  23 +#include <dali-toolkit/public-api/particle-system/particle-list.h>
  24 +#include <dali-toolkit/public-api/particle-system/particle-renderer.h>
  25 +#include <dali-toolkit/public-api/particle-system/particle-types.h>
  26 +
  27 +#include <utility>
  28 +#include <ctime>
  29 +#include <dali-toolkit/public-api/particle-system/particle-modifier.h>
  30 +#include <unistd.h>
  31 +#include <map>
  32 +
  33 +#include "effects/particle-effect.h"
  34 +
  35 +using namespace Dali;
  36 +using namespace Dali::Toolkit::ParticleSystem;
  37 +using namespace Dali::Toolkit;
  38 +using Dali::Toolkit::TextLabel;
  39 +
  40 +using namespace Dali::ParticleEffect;
  41 +
  42 +/**
  43 + * This example shows Particle System feature
  44 + */
  45 +class ParticleEffectController : public ConnectionTracker
  46 +{
  47 +public:
  48 +
  49 + ParticleEffectController(Application& application)
  50 + : mApplication(application)
  51 + {
  52 + // Connect to the Application's Init signal
  53 + mApplication.InitSignal().Connect(this, &ParticleEffectController::Create);
  54 + }
  55 +
  56 + ~ParticleEffectController() = default; // Nothing to do in destructor
  57 +
  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 )
  64 + {
  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 + };
  80 +
  81 + mUILastControlPosition = position;
  82 + mUILastControlSize = (size == Vector2::ZERO ? Vector2(button.GetNaturalSize()) : size);
  83 +
  84 + callbackMap[button.GetObjectPtr()] = onClick;
  85 + button.ClickedSignal().Connect(OnClick::Slot);
  86 + return button;
  87 + }
  88 +
  89 + // The Init signal is received once (only) during the Application lifetime
  90 + void Create(Application& application)
  91 + {
  92 + using namespace Dali::ParticleEffect;
  93 +
  94 + // Get a handle to the window
  95 + Window window = application.GetWindow();
  96 + window.SetBackgroundColor(Color::BLACK);
  97 + {
  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 + window.Add(emitterActor);
  104 +
  105 + mEmitterActor = emitterActor;
  106 + PushButton lastButton;
  107 + window.Add(
  108 + MakeButton<PushButton>("Fire Effect", Vector2::ZERO, {}, true, [&](Button button){
  109 +
  110 + if(mCurrentEmitter)
  111 + {
  112 + mCurrentEmitter.Stop();
  113 + mCurrentEmitter.Reset();
  114 + }
  115 +
  116 + ParticleEffectParams params{};
  117 + params.particleCount = 5000;
  118 + params.emissionRate = 1000;
  119 + params.initialParticleCount = 0;
  120 + params.sourceSize = Vector2(200, 10);
  121 + params.strTexture = "sparkle-part1.png";
  122 +
  123 + mCurrentEmitter = mParticleSystem->CreateEffectEmitter( EffectType::FIRE_RING, mEmitterActor, params );
  124 + mCurrentEmitter.Start();
  125 + return true;
  126 + })
  127 + );
  128 +
  129 + window.Add(
  130 + MakeButton<PushButton>("Sparkle Effect", Vector2(0.0f, mUILastControlSize.height), {}, true, [&](Button button){
  131 + if(mCurrentEmitter)
  132 + {
  133 + mCurrentEmitter.Stop();
  134 + mCurrentEmitter.Reset();
  135 + }
  136 +
  137 + ParticleEffectParams params{};
  138 + params.particleCount = 10000;
  139 + params.emissionRate = 500;
  140 + params.initialParticleCount = 0;
  141 + params.sourceSize = Vector2(10, 10);
  142 + params.strTexture = "blue-part2.png";
  143 +
  144 + mCurrentEmitter = mParticleSystem->CreateEffectEmitter( EffectType::SPARKLES, mEmitterActor, params );
  145 + mCurrentEmitter.Start();
  146 + return true;
  147 + })
  148 + );
  149 +
  150 + window.Add(
  151 + MakeButton<PushButton>("Image Source Effect", Vector2(0.0f, mUILastControlPosition.y + mUILastControlSize.height), {}, true, [&](Button button){
  152 + if(mCurrentEmitter)
  153 + {
  154 + mCurrentEmitter.Stop();
  155 + mCurrentEmitter.Reset();
  156 + }
  157 +
  158 + ParticleEffectParams params{};
  159 + params.particleCount = 20000;
  160 + params.emissionRate = 0;
  161 + params.initialParticleCount = 10;
  162 + params.sourceSize = Vector2(64, 64);
  163 + params.strImageSourceName = "particle-image-source.jpg";
  164 +
  165 + mCurrentEmitter = mParticleSystem->CreateEffectEmitter( EffectType::IMAGE_EXPLOSION, mEmitterActor, params );
  166 + mCurrentEmitter.Start();
  167 + return true;
  168 + })
  169 + );
  170 + window.Add(
  171 + MakeButton<PushButton>("Quit", Vector2(0.0f, mUILastControlPosition.y + mUILastControlSize.height * 2), {}, true, [&](Button button){
  172 + if(mCurrentEmitter)
  173 + {
  174 + mCurrentEmitter.Stop();
  175 + mCurrentEmitter.Reset();
  176 + }
  177 + mApplication.Quit();
  178 + return true;
  179 + })
  180 + );
  181 + }
  182 +
  183 + // Respond to key events
  184 + window.KeyEventSignal().Connect(this, &ParticleEffectController::OnKeyEvent);
  185 + }
  186 +
  187 + void OnKeyEvent(const KeyEvent& event)
  188 + {
  189 + if(event.GetState() == KeyEvent::DOWN)
  190 + {
  191 + if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
  192 + {
  193 + mApplication.Quit();
  194 + }
  195 + }
  196 + }
  197 +
  198 +private:
  199 +
  200 + Application& mApplication;
  201 + std::unique_ptr<Dali::ParticleEffect::ParticleEffect> mParticleSystem;
  202 + ParticleEmitter mCurrentEmitter;
  203 + Actor mEmitterActor;
  204 +
  205 + // Needed for buttons
  206 + Vector2 mUILastControlPosition;
  207 + Vector2 mUILastControlSize;
  208 +
  209 +};
  210 +
  211 +int DALI_EXPORT_API main(int argc, char** argv)
  212 +{
  213 + Application application = Application::New(&argc, &argv);
  214 + ParticleEffectController test(application);
  215 + application.MainLoop();
  216 + return 0;
  217 +}
resources/images/blue-part2.png 0 → 100644

27.4 KB

resources/images/particle-image-source.jpg 0 → 100644

18 KB

resources/images/sparkle-part1.png 0 → 100644

7.58 KB

resources/po/en_GB.po
@@ -178,6 +178,9 @@ msgstr &quot;Creation View Performance&quot; @@ -178,6 +178,9 @@ msgstr &quot;Creation View Performance&quot;
178 msgid "DALI_DEMO_STR_TITLE_POINT_MESH" 178 msgid "DALI_DEMO_STR_TITLE_POINT_MESH"
179 msgstr "Point Mesh" 179 msgstr "Point Mesh"
180 180
  181 +msgid "DALI_DEMO_STR_TITLE_PARTICLE_SYSTEM"
  182 +msgstr "Particle System"
  183 +
181 msgid "DALI_DEMO_STR_TITLE_POPUP" 184 msgid "DALI_DEMO_STR_TITLE_POPUP"
182 msgstr "Popup" 185 msgstr "Popup"
183 186
resources/po/en_US.po
@@ -178,6 +178,9 @@ msgstr &quot;Page Turn&quot; @@ -178,6 +178,9 @@ msgstr &quot;Page Turn&quot;
178 msgid "DALI_DEMO_STR_TITLE_PARTICLES" 178 msgid "DALI_DEMO_STR_TITLE_PARTICLES"
179 msgstr "Particles" 179 msgstr "Particles"
180 180
  181 +msgid "DALI_DEMO_STR_TITLE_PARTICLE_SYSTEM"
  182 +msgstr "Particle System"
  183 +
181 msgid "DALI_DEMO_STR_TITLE_PERF_SCROLL" 184 msgid "DALI_DEMO_STR_TITLE_PERF_SCROLL"
182 msgstr "Scrolling Performance" 185 msgstr "Scrolling Performance"
183 186
shared/dali-demo-strings.h
1 /* 1 /*
2 - * Copyright (c) 2022 Samsung Electronics Co., Ltd. 2 + * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
@@ -97,6 +97,7 @@ extern &quot;C&quot; @@ -97,6 +97,7 @@ extern &quot;C&quot;
97 #define DALI_DEMO_STR_TITLE_NEGOTIATE_SIZE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_NEGOTIATE_SIZE") 97 #define DALI_DEMO_STR_TITLE_NEGOTIATE_SIZE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_NEGOTIATE_SIZE")
98 #define DALI_DEMO_STR_TITLE_PAGE_TURN dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PAGE_TURN") 98 #define DALI_DEMO_STR_TITLE_PAGE_TURN dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PAGE_TURN")
99 #define DALI_DEMO_STR_TITLE_PARTICLES dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PARTICLES") 99 #define DALI_DEMO_STR_TITLE_PARTICLES dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PARTICLES")
  100 +#define DALI_DEMO_STR_TITLE_PARTICLE_SYSTEM dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PARTICLE_SYSTEM")
100 #define DALI_DEMO_STR_TITLE_PBR dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PBR") 101 #define DALI_DEMO_STR_TITLE_PBR dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PBR")
101 #define DALI_DEMO_STR_TITLE_PERF_SCROLL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PERF_SCROLL") 102 #define DALI_DEMO_STR_TITLE_PERF_SCROLL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PERF_SCROLL")
102 #define DALI_DEMO_STR_TITLE_PERF_VIEW_CREATION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PERF_VIEW_CREATION") 103 #define DALI_DEMO_STR_TITLE_PERF_VIEW_CREATION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_PERF_VIEW_CREATION")
@@ -211,6 +212,7 @@ extern &quot;C&quot; @@ -211,6 +212,7 @@ extern &quot;C&quot;
211 #define DALI_DEMO_STR_TITLE_NEGOTIATE_SIZE "Negotiate Size" 212 #define DALI_DEMO_STR_TITLE_NEGOTIATE_SIZE "Negotiate Size"
212 #define DALI_DEMO_STR_TITLE_PAGE_TURN "Page Turn" 213 #define DALI_DEMO_STR_TITLE_PAGE_TURN "Page Turn"
213 #define DALI_DEMO_STR_TITLE_PARTICLES "Particles" 214 #define DALI_DEMO_STR_TITLE_PARTICLES "Particles"
  215 +#define DALI_DEMO_STR_TITLE_PARTICLE_SYSTEM "Particle System"
214 #define DALI_DEMO_STR_TITLE_PBR "PBR" 216 #define DALI_DEMO_STR_TITLE_PBR "PBR"
215 #define DALI_DEMO_STR_TITLE_PERF_SCROLL "Scrolling Performance" 217 #define DALI_DEMO_STR_TITLE_PERF_SCROLL "Scrolling Performance"
216 #define DALI_DEMO_STR_TITLE_PERF_VIEW_CREATION "Creation View Performance" 218 #define DALI_DEMO_STR_TITLE_PERF_VIEW_CREATION "Creation View Performance"