diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index b7a168262..8bd26a4bd 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -20,7 +20,7 @@ namespace Nz { public: ParticleEmitter(); - ParticleEmitter(const ParticleEmitter& emitter) = default; + ParticleEmitter(const ParticleEmitter& emitter); ParticleEmitter(ParticleEmitter&& emitter); virtual ~ParticleEmitter(); @@ -40,7 +40,7 @@ namespace Nz ParticleEmitter& operator=(ParticleEmitter&& emitter); // Signals: - NazaraSignal(OnParticleEmitterMove, const ParticleEmitter* /*oldParticleEmitter*/, const ParticleEmitter* /*newParticleEmitter*/); + NazaraSignal(OnParticleEmitterMove, ParticleEmitter* /*oldParticleEmitter*/, ParticleEmitter* /*newParticleEmitter*/); NazaraSignal(OnParticleEmitterRelease, const ParticleEmitter* /*particleEmitter*/); private: diff --git a/include/Nazara/Graphics/ParticleGroup.hpp b/include/Nazara/Graphics/ParticleGroup.hpp index 4d4704171..9e48d5797 100644 --- a/include/Nazara/Graphics/ParticleGroup.hpp +++ b/include/Nazara/Graphics/ParticleGroup.hpp @@ -68,12 +68,22 @@ namespace Nz private: void MakeBoundingVolume() const override; + void OnEmitterMove(ParticleEmitter* oldEmitter, ParticleEmitter* newEmitter); + void OnEmitterRelease(const ParticleEmitter* emitter); void ResizeBuffer(); + struct EmitterEntry + { + NazaraSlot(ParticleEmitter, OnParticleEmitterMove, moveSlot); + NazaraSlot(ParticleEmitter, OnParticleEmitterRelease, releaseSlot); + + ParticleEmitter* emitter; + }; + std::set> m_dyingParticles; mutable std::vector m_buffer; std::vector m_controllers; - std::vector m_emitters; + std::vector m_emitters; std::vector m_generators; ParticleDeclarationConstRef m_declaration; ParticleRendererRef m_renderer; diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 10f057dce..fe27575e7 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -32,6 +32,14 @@ namespace Nz { } + ParticleEmitter::ParticleEmitter(const ParticleEmitter& emitter) : + m_lagCompensationEnabled(emitter.m_lagCompensationEnabled), + m_emissionAccumulator(0.f), + m_emissionRate(emitter.m_emissionRate), + m_emissionCount(emitter.m_emissionCount) + { + } + ParticleEmitter::ParticleEmitter(ParticleEmitter&& emitter) : m_lagCompensationEnabled(emitter.m_lagCompensationEnabled), m_emissionAccumulator(0.f), diff --git a/src/Nazara/Graphics/ParticleGroup.cpp b/src/Nazara/Graphics/ParticleGroup.cpp index 87dbb390c..5aca6c2b4 100644 --- a/src/Nazara/Graphics/ParticleGroup.cpp +++ b/src/Nazara/Graphics/ParticleGroup.cpp @@ -109,7 +109,12 @@ namespace Nz { NazaraAssert(emitter, "Invalid particle emitter"); - m_emitters.emplace_back(emitter); + EmitterEntry entry; + entry.emitter = emitter; + entry.moveSlot.Connect(emitter->OnParticleEmitterMove, this, &ParticleGroup::OnEmitterMove); + entry.releaseSlot.Connect(emitter->OnParticleEmitterRelease, this, &ParticleGroup::OnEmitterRelease); + + m_emitters.emplace_back(std::move(entry)); } /*! @@ -336,9 +341,14 @@ namespace Nz void ParticleGroup::RemoveEmitter(ParticleEmitter* emitter) { - auto it = std::find(m_emitters.begin(), m_emitters.end(), emitter); - if (it != m_emitters.end()) - m_emitters.erase(it); + for (auto it = m_emitters.begin(); it != m_emitters.end(); ++it) + { + if (it->emitter == emitter) + { + m_emitters.erase(it); + break; + } + } } /*! @@ -374,8 +384,8 @@ namespace Nz void ParticleGroup::Update(float elapsedTime) { // Emission - for (ParticleEmitter* emitter : m_emitters) - emitter->Emit(*this, elapsedTime); + for (const EmitterEntry& entry : m_emitters) + entry.emitter->Emit(*this, elapsedTime); // Update if (m_particleCount > 0) @@ -443,6 +453,26 @@ namespace Nz m_boundingVolume.MakeInfinite(); } + void ParticleGroup::OnEmitterMove(ParticleEmitter* oldEmitter, ParticleEmitter* newEmitter) + { + for (EmitterEntry& entry : m_emitters) + { + if (entry.emitter == oldEmitter) + entry.emitter = newEmitter; + } + } + + void ParticleGroup::OnEmitterRelease(const ParticleEmitter* emitter) + { + for (auto it = m_emitters.begin(); it != m_emitters.end();) + { + if (it->emitter == emitter) + it = m_emitters.erase(it); + else + ++it; + } + } + /*! * \brief Resizes the internal buffer *