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
28 ParticleStream::StreamDataType StreamDataTypeWrapper<Vector3>::GetType()
30 return ParticleStream::StreamDataType::FLOAT3;
34 ParticleStream::StreamDataType StreamDataTypeWrapper<Vector4>::GetType()
36 return ParticleStream::StreamDataType::FLOAT4;
40 ParticleStream::StreamDataType StreamDataTypeWrapper<Vector2>::GetType()
42 return ParticleStream::StreamDataType::FLOAT2;
46 ParticleStream::StreamDataType StreamDataTypeWrapper<float>::GetType()
48 return ParticleStream::StreamDataType::FLOAT;
51 ParticleList::ParticleList(uint32_t capacity, ParticleSystem::ParticleList::ParticleStreamTypeFlags streamFlags)
53 // capacity makes for max immutable particle count
54 mMaxParticleCount = capacity;
56 // initialize built-in streams and build map (to optimize later)
57 if(streamFlags & ParticleStream::POSITION_STREAM_BIT)
59 AddStream(Vector3::ZERO, "aStreamPosition", false);
60 mBuiltInStreamMap[uint32_t(ParticleStream::POSITION_STREAM_BIT)] = mDataStreams.size() - 1;
62 if(streamFlags & ParticleStream::ROTATION_STREAM_BIT)
64 AddStream(Vector4::ZERO, "aStreamRotation", false);
65 mBuiltInStreamMap[uint32_t(ParticleStream::ROTATION_STREAM_BIT)] = mDataStreams.size() - 1;
67 if(streamFlags & ParticleStream::SCALE_STREAM_BIT)
69 AddStream(Vector3::ONE, "aStreamScale", false);
70 mBuiltInStreamMap[uint32_t(ParticleStream::SCALE_STREAM_BIT)] = mDataStreams.size() - 1;
72 if(streamFlags & ParticleStream::VELOCITY_STREAM_BIT)
74 AddStream(Vector3::ZERO, "aStreamVelocity", false);
75 mBuiltInStreamMap[uint32_t(ParticleStream::VELOCITY_STREAM_BIT)] = mDataStreams.size() - 1;
77 if(streamFlags & ParticleStream::COLOR_STREAM_BIT)
79 AddStream(Color::YELLOW, "aStreamColor", false);
80 mBuiltInStreamMap[uint32_t(ParticleStream::COLOR_STREAM_BIT)] = mDataStreams.size() - 1;
82 if(streamFlags & ParticleStream::OPACITY_STREAM_BIT)
84 AddStream(0.0f, "aStreamOpacity", false);
85 mBuiltInStreamMap[uint32_t(ParticleStream::OPACITY_STREAM_BIT)] = mDataStreams.size() - 1;
87 if(streamFlags & ParticleStream::LIFETIME_STREAM_BIT)
89 AddStream(0.0f, "aStreamLifetime", false);
90 mBuiltInStreamMap[uint32_t(ParticleStream::LIFETIME_STREAM_BIT)] = mDataStreams.size() - 1;
94 mFreeChain.resize(capacity);
95 for(auto i = 0u; i < mFreeChain.size(); ++i)
97 mFreeChain[i] = i + 1;
99 mFreeChain[mFreeChain.size() - 1] = 0;
103 ParticleList::~ParticleList() = default;
105 uint32_t ParticleList::AddStream(uint32_t sizeOfDataType, const void* defaultValue, ParticleStream::StreamDataType dataType, const char* streamName, bool localStream)
107 mDataStreams.emplace_back(new ParticleDataStream(mMaxParticleCount, sizeOfDataType, defaultValue, dataType));
110 mDataStreams.back()->SetStreamName(streamName);
113 mDataStreams.back()->SetStreamLocal(localStream);
115 // Update element size
116 mParticleStreamElementSize = 0;
117 mParticleStreamElementSizeWithLocal = 0;
118 for(auto& ds : mDataStreams)
122 mParticleStreamElementSize += ds->dataSize;
124 mParticleStreamElementSizeWithLocal += ds->dataSize;
127 return mDataStreams.size() - 1;
130 void* ParticleList::GetRawStream(uint32_t index)
132 if(index < mDataStreams.size() && mDataStreams[index])
134 return mDataStreams[index]->data.data();
139 uint32_t ParticleList::GetStreamCount() const
141 return mDataStreams.size();
144 uint32_t ParticleList::GetParticleCount() const
146 return mMaxParticleCount;
149 uint32_t ParticleList::GetActiveParticleCount() const
151 return mParticles.size();
154 ParticleStream::StreamDataType ParticleList::GetStreamDataType(uint32_t streamIndex)
156 return mDataStreams[streamIndex]->type;
159 const std::string& ParticleList::GetStreamName(uint32_t streamIndex) const
161 return mDataStreams[streamIndex]->streamName;
164 bool ParticleList::IsStreamLocal(uint32_t streamIndex) const
166 return mDataStreams[streamIndex]->localStream;
169 uint32_t ParticleList::GetStreamDataTypeSize(uint32_t streamIndex) const
171 return mDataStreams[streamIndex]->dataSize;
174 ParticleSystem::Particle ParticleList::NewParticle(float lifetime)
176 if(mParticles.size() < mMaxParticleCount)
178 auto newIndex = int32_t(mFreeIndex);
179 mFreeIndex = int32_t(mFreeChain[mFreeIndex]);
180 mAliveParticleCount++;
183 mParticles.emplace_back(new Internal::Particle(*this, newIndex));
185 // Set particle lifetime
186 auto& particle = mParticles.back();
188 particle.Get<float>(ParticleStream::LIFETIME_STREAM_BIT) = lifetime;
190 return mParticles.back();
195 uint32_t ParticleList::GetStreamElementSize(bool includeLocalStream)
197 if(includeLocalStream)
199 return mParticleStreamElementSizeWithLocal;
203 return mParticleStreamElementSize;
207 void ParticleList::ReleaseParticle(uint32_t particleIndex)
209 auto it = mParticles.begin();
210 std::advance(it, particleIndex);
212 // Point at this slot of memory as next free slot
216 mFreeChain[p.GetIndex()] = mFreeIndex;
217 mFreeIndex = p.GetIndex();
220 // Remove particle from the list
221 mParticles.erase(it);
222 mAliveParticleCount--;
225 void* ParticleList::GetDefaultStream(ParticleStreamTypeFlagBit streamBit)
227 return GetRawStream(mBuiltInStreamMap[streamBit]);
230 uint32_t ParticleList::GetDefaultStreamIndex(ParticleStreamTypeFlagBit streamBit)
232 return mBuiltInStreamMap[uint32_t(streamBit)];
235 std::list<ParticleSystem::Particle>& ParticleList::GetParticles()
240 } // namespace Dali::Toolkit::ParticleSystem::Internal