| 189 | } |
| 190 | |
| 191 | void ParticleSystem::OnUpdate(float timeMult) |
| 192 | { |
| 193 | if (!updateEnabled_) { |
| 194 | return; |
| 195 | } |
| 196 | |
| 197 | // Overridden `update()` method should call `transform()` like `SceneNode::update()` does |
| 198 | SceneNode::transform(); |
| 199 | |
| 200 | for (std::int32_t i = std::int32_t(children_.size()) - 1; i >= 0; i--) { |
| 201 | Particle* particle = static_cast<Particle*>(children_[i]); |
| 202 | |
| 203 | // Update the particle if it's alive |
| 204 | if (particle->isAlive()) { |
| 205 | // Calculating the normalized age only once per particle |
| 206 | const float normalizedAge = 1.0f - particle->life_ / particle->startingLife; |
| 207 | for (auto& affector : affectors_) { |
| 208 | affector->affect(particle, normalizedAge); |
| 209 | } |
| 210 | |
| 211 | particle->OnUpdate(timeMult); |
| 212 | |
| 213 | // Releasing the particle if it has just died |
| 214 | if (!particle->isAlive()) { |
| 215 | poolTop_++; |
| 216 | particlePool_[poolTop_] = particle; |
| 217 | removeChildNodeAt(i); |
| 218 | continue; |
| 219 | } |
| 220 | |
| 221 | // Transforming the particle only if it's still alive |
| 222 | particle->transform(); |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | lastFrameUpdated_ = theApplication().GetFrameCount(); |
| 227 | |
| 228 | #if defined(WITH_TRACY) |
| 229 | // TODO: Tracy |
| 230 | //tracyInfoString.format("Alive: %d", numAliveParticles()); |
| 231 | //ZoneText(tracyInfoString.data(), tracyInfoString.length()); |
| 232 | #endif |
| 233 | } |
| 234 | |
| 235 | ParticleSystem::ParticleSystem(const ParticleSystem& other) |
| 236 | : SceneNode(other), poolSize_(other.poolSize_), poolTop_(other.poolSize_ - 1), particlePool_(other.poolSize_), |
nothing calls this directly
no test coverage detected