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>
25 #include <dali/public-api/common/vector-wrapper.h>
28 namespace Dali::Toolkit::ParticleSystem::Internal
32 ParticleStream::StreamDataType StreamDataTypeWrapper<Vector3>::GetType()
34 return ParticleStream::StreamDataType::FLOAT3;
38 ParticleStream::StreamDataType StreamDataTypeWrapper<Vector4>::GetType()
40 return ParticleStream::StreamDataType::FLOAT4;
44 ParticleStream::StreamDataType StreamDataTypeWrapper<Vector2>::GetType()
46 return ParticleStream::StreamDataType::FLOAT2;
50 ParticleStream::StreamDataType StreamDataTypeWrapper<float>::GetType()
52 return ParticleStream::StreamDataType::FLOAT;
55 ParticleList::ParticleList(uint32_t capacity, ParticleSystem::ParticleList::ParticleStreamTypeFlags streamFlags)
57 // capacity makes for max immutable particle count
58 mMaxParticleCount = capacity;
60 // initialize built-in streams and build map (to optimize later)
61 if(streamFlags & ParticleStream::POSITION_STREAM_BIT)
63 AddStream(Vector3::ZERO, "aStreamPosition", false);
64 mBuiltInStreamMap[uint32_t(ParticleStream::POSITION_STREAM_BIT)] = mDataStreams.size() - 1;
66 if(streamFlags & ParticleStream::ROTATION_STREAM_BIT)
68 AddStream(Vector4::ZERO, "aStreamRotation", false);
69 mBuiltInStreamMap[uint32_t(ParticleStream::ROTATION_STREAM_BIT)] = mDataStreams.size() - 1;
71 if(streamFlags & ParticleStream::SCALE_STREAM_BIT)
73 AddStream(Vector3::ONE, "aStreamScale", false);
74 mBuiltInStreamMap[uint32_t(ParticleStream::SCALE_STREAM_BIT)] = mDataStreams.size() - 1;
76 if(streamFlags & ParticleStream::VELOCITY_STREAM_BIT)
78 AddStream(Vector3::ZERO, "aStreamVelocity", false);
79 mBuiltInStreamMap[uint32_t(ParticleStream::VELOCITY_STREAM_BIT)] = mDataStreams.size() - 1;
81 if(streamFlags & ParticleStream::COLOR_STREAM_BIT)
83 AddStream(Color::YELLOW, "aStreamColor", false);
84 mBuiltInStreamMap[uint32_t(ParticleStream::COLOR_STREAM_BIT)] = mDataStreams.size() - 1;
86 if(streamFlags & ParticleStream::OPACITY_STREAM_BIT)
88 AddStream(0.0f, "aStreamOpacity", false);
89 mBuiltInStreamMap[uint32_t(ParticleStream::OPACITY_STREAM_BIT)] = mDataStreams.size() - 1;
91 if(streamFlags & ParticleStream::LIFETIME_STREAM_BIT)
93 AddStream(0.0f, "aStreamLifetime", false);
94 mBuiltInStreamMap[uint32_t(ParticleStream::LIFETIME_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 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;
221 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