2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/particle-system/particle-list-impl.h>
22 #include <dali-toolkit/internal/particle-system/particle-impl.h>
24 namespace Dali::Toolkit::ParticleSystem::Internal
27 ParticleStream::StreamDataType StreamDataTypeWrapper<Vector3>::GetType()
29 return ParticleStream::StreamDataType::FLOAT3;
33 ParticleStream::StreamDataType StreamDataTypeWrapper<Vector4>::GetType()
35 return ParticleStream::StreamDataType::FLOAT4;
39 ParticleStream::StreamDataType StreamDataTypeWrapper<Vector2>::GetType()
41 return ParticleStream::StreamDataType::FLOAT2;
45 ParticleStream::StreamDataType StreamDataTypeWrapper<float>::GetType()
47 return ParticleStream::StreamDataType::FLOAT;
50 ParticleList::ParticleList(uint32_t capacity, ParticleSystem::ParticleList::ParticleStreamTypeFlags streamFlags)
52 // capacity makes for max immutable particle count
53 mMaxParticleCount = capacity;
55 // initialize built-in streams and build map (to optimize later)
56 if(streamFlags & ParticleStream::POSITION_STREAM_BIT)
58 AddStream(Vector3::ZERO, "aStreamPosition", false);
59 mBuiltInStreamMap[uint32_t(ParticleStream::POSITION_STREAM_BIT)] = mDataStreams.size() - 1;
61 if(streamFlags & ParticleStream::ROTATION_STREAM_BIT)
63 AddStream(Vector4::ZERO, "aStreamRotation", false);
64 mBuiltInStreamMap[uint32_t(ParticleStream::ROTATION_STREAM_BIT)] = mDataStreams.size() - 1;
66 if(streamFlags & ParticleStream::SCALE_STREAM_BIT)
68 AddStream(Vector3::ONE, "aStreamScale", false);
69 mBuiltInStreamMap[uint32_t(ParticleStream::SCALE_STREAM_BIT)] = mDataStreams.size() - 1;
71 if(streamFlags & ParticleStream::VELOCITY_STREAM_BIT)
73 AddStream(Vector3::ZERO, "aStreamVelocity", false);
74 mBuiltInStreamMap[uint32_t(ParticleStream::VELOCITY_STREAM_BIT)] = mDataStreams.size() - 1;
76 if(streamFlags & ParticleStream::COLOR_STREAM_BIT)
78 AddStream(Color::YELLOW, "aStreamColor", false);
79 mBuiltInStreamMap[uint32_t(ParticleStream::COLOR_STREAM_BIT)] = mDataStreams.size() - 1;
81 if(streamFlags & ParticleStream::OPACITY_STREAM_BIT)
83 AddStream(0.0f, "aStreamOpacity", false);
84 mBuiltInStreamMap[uint32_t(ParticleStream::OPACITY_STREAM_BIT)] = mDataStreams.size() - 1;
86 if(streamFlags & ParticleStream::LIFETIME_STREAM_BIT)
88 AddStream(0.0f, "aStreamLifetime", true);
89 mBuiltInStreamMap[uint32_t(ParticleStream::LIFETIME_STREAM_BIT)] = mDataStreams.size() - 1;
90 AddStream(0.0f, "aStreamLifetimeBase", true);
91 mBuiltInStreamMap[uint32_t(ParticleStream::LIFETIME_BASE_STREAM_BIT)] = mDataStreams.size() - 1;
95 mFreeChain.resize(capacity);
96 for(auto i = 0u; i < mFreeChain.size(); ++i)
98 mFreeChain[i] = i + 1;
100 mFreeChain[mFreeChain.size() - 1] = 0;
104 ParticleList::~ParticleList() = default;
106 uint32_t ParticleList::AddStream(uint32_t sizeOfDataType, const void* defaultValue, ParticleStream::StreamDataType dataType, const char* streamName, bool localStream)
108 mDataStreams.emplace_back(new ParticleDataStream(mMaxParticleCount, sizeOfDataType, defaultValue, dataType));
111 mDataStreams.back()->SetStreamName(streamName);
114 mDataStreams.back()->SetStreamLocal(localStream);
116 // Update element size
117 mParticleStreamElementSize = 0;
118 mParticleStreamElementSizeWithLocal = 0;
119 for(auto& ds : mDataStreams)
123 mParticleStreamElementSize += ds->dataSize;
125 mParticleStreamElementSizeWithLocal += ds->dataSize;
128 return mDataStreams.size() - 1;
131 void* ParticleList::GetRawStream(uint32_t index)
133 if(index < mDataStreams.size() && mDataStreams[index])
135 return mDataStreams[index]->data.data();
140 uint32_t ParticleList::GetStreamCount() const
142 return mDataStreams.size();
145 uint32_t ParticleList::GetParticleCount() const
147 return mMaxParticleCount;
150 uint32_t ParticleList::GetActiveParticleCount() const
152 return mParticles.size();
155 ParticleStream::StreamDataType ParticleList::GetStreamDataType(uint32_t streamIndex)
157 return mDataStreams[streamIndex]->type;
160 const std::string& ParticleList::GetStreamName(uint32_t streamIndex) const
162 return mDataStreams[streamIndex]->streamName;
165 bool ParticleList::IsStreamLocal(uint32_t streamIndex) const
167 return mDataStreams[streamIndex]->localStream;
170 uint32_t ParticleList::GetStreamDataTypeSize(uint32_t streamIndex) const
172 return mDataStreams[streamIndex]->dataSize;
175 ParticleSystem::Particle ParticleList::NewParticle(float lifetime)
177 if(mParticles.size() < mMaxParticleCount)
179 auto newIndex = int32_t(mFreeIndex);
180 mFreeIndex = int32_t(mFreeChain[mFreeIndex]);
181 mAliveParticleCount++;
184 mParticles.emplace_back(new Internal::Particle(*this, newIndex));
186 // Set particle lifetime
187 auto& particle = mParticles.back();
189 particle.Get<float>(ParticleStream::LIFETIME_STREAM_BIT) = lifetime;
191 // Store initial lifetime
192 particle.Get<float>(ParticleStream::LIFETIME_BASE_STREAM_BIT) = lifetime;
194 return mParticles.back();
199 uint32_t ParticleList::GetStreamElementSize(bool includeLocalStream)
201 if(includeLocalStream)
203 return mParticleStreamElementSizeWithLocal;
207 return mParticleStreamElementSize;
211 void ParticleList::ReleaseParticle(uint32_t particleIndex)
213 auto it = mParticles.begin();
214 std::advance(it, particleIndex);
216 // Point at this slot of memory as next free slot
220 mFreeChain[p.GetIndex()] = mFreeIndex;
222 mFreeIndex = p.GetIndex();
224 // Remove particle from the list
225 mParticles.erase(it);
226 mAliveParticleCount--;
229 void* ParticleList::GetDefaultStream(ParticleStreamTypeFlagBit streamBit)
231 return GetRawStream(mBuiltInStreamMap[streamBit]);
234 uint32_t ParticleList::GetDefaultStreamIndex(ParticleStreamTypeFlagBit streamBit)
236 return mBuiltInStreamMap[uint32_t(streamBit)];
239 std::list<ParticleSystem::Particle>& ParticleList::GetParticles()
244 } // namespace Dali::Toolkit::ParticleSystem::Internal