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;
91 if(streamFlags & ParticleStream::LIFETIME_STREAM_BIT)
93 AddStream(0.0f, "aStreamLifetimeBase", true);
94 mBuiltInStreamMap[uint32_t(ParticleStream::LIFETIME_BASE_STREAM_BIT)] = mDataStreams.size() - 1;
98 mFreeChain.resize(capacity);
99 for(auto i = 0u; i < mFreeChain.size(); ++i)
101 mFreeChain[i] = i + 1;
103 mFreeChain[mFreeChain.size() - 1] = 0;
107 ParticleList::~ParticleList() = default;
109 uint32_t ParticleList::AddStream(uint32_t sizeOfDataType, const void* defaultValue, ParticleStream::StreamDataType dataType, const char* streamName, bool localStream)
111 mDataStreams.emplace_back(new ParticleDataStream(mMaxParticleCount, sizeOfDataType, defaultValue, dataType));
114 mDataStreams.back()->SetStreamName(streamName);
117 mDataStreams.back()->SetStreamLocal(localStream);
119 // Update element size
120 mParticleStreamElementSize = 0;
121 mParticleStreamElementSizeWithLocal = 0;
122 for(auto& ds : mDataStreams)
126 mParticleStreamElementSize += ds->dataSize;
128 mParticleStreamElementSizeWithLocal += ds->dataSize;
131 return mDataStreams.size() - 1;
134 void* ParticleList::GetRawStream(uint32_t index)
136 if(index < mDataStreams.size() && mDataStreams[index])
138 return mDataStreams[index]->data.data();
143 uint32_t ParticleList::GetStreamCount() const
145 return mDataStreams.size();
148 uint32_t ParticleList::GetParticleCount() const
150 return mMaxParticleCount;
153 uint32_t ParticleList::GetActiveParticleCount() const
155 return mParticles.size();
158 ParticleStream::StreamDataType ParticleList::GetStreamDataType(uint32_t streamIndex)
160 return mDataStreams[streamIndex]->type;
163 const std::string& ParticleList::GetStreamName(uint32_t streamIndex) const
165 return mDataStreams[streamIndex]->streamName;
168 bool ParticleList::IsStreamLocal(uint32_t streamIndex) const
170 return mDataStreams[streamIndex]->localStream;
173 uint32_t ParticleList::GetStreamDataTypeSize(uint32_t streamIndex) const
175 return mDataStreams[streamIndex]->dataSize;
178 ParticleSystem::Particle ParticleList::NewParticle(float lifetime)
180 if(mParticles.size() < mMaxParticleCount)
182 auto newIndex = int32_t(mFreeIndex);
183 mFreeIndex = int32_t(mFreeChain[mFreeIndex]);
184 mAliveParticleCount++;
187 mParticles.emplace_back(new Internal::Particle(*this, newIndex));
189 // Set particle lifetime
190 auto& particle = mParticles.back();
192 particle.Get<float>(ParticleStream::LIFETIME_STREAM_BIT) = lifetime;
194 // Store initial lifetime
195 particle.Get<float>(ParticleStream::LIFETIME_BASE_STREAM_BIT) = lifetime;
197 return mParticles.back();
202 uint32_t ParticleList::GetStreamElementSize(bool includeLocalStream)
204 if(includeLocalStream)
206 return mParticleStreamElementSizeWithLocal;
210 return mParticleStreamElementSize;
214 void ParticleList::ReleaseParticle(uint32_t particleIndex)
216 auto it = mParticles.begin();
217 std::advance(it, particleIndex);
219 // Point at this slot of memory as next free slot
223 mFreeChain[p.GetIndex()] = mFreeIndex;
225 mFreeIndex = p.GetIndex();
227 // Remove particle from the list
228 mParticles.erase(it);
229 mAliveParticleCount--;
232 void* ParticleList::GetDefaultStream(ParticleStreamTypeFlagBit streamBit)
234 return GetRawStream(mBuiltInStreamMap[streamBit]);
237 uint32_t ParticleList::GetDefaultStreamIndex(ParticleStreamTypeFlagBit streamBit)
239 return mBuiltInStreamMap[uint32_t(streamBit)];
242 std::list<ParticleSystem::Particle>& ParticleList::GetParticles()
247 } // namespace Dali::Toolkit::ParticleSystem::Internal