From 0976607eb93b8154bfb3e93970e73bcb4bb8bab8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Aug 2014 21:21:04 +0200 Subject: [PATCH] Added fixed step update Switched back to defaulted operator=(ParticleEmitter&&) since it can't throw exception anyway Former-commit-id: 178b040a735ef01dcda21b45a317b6c534b5782e --- include/Nazara/Graphics/ParticleEmitter.hpp | 9 ++- src/Nazara/Graphics/ParticleEmitter.cpp | 68 +++++++++++++-------- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index 47d6a6b0b..f9d279fcc 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -35,6 +35,8 @@ class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable void* CreateParticle(); void* CreateParticles(unsigned int count); + void EnableFixedStep(bool fixedStep); + void* GenerateParticle(); void* GenerateParticles(unsigned int count); @@ -49,6 +51,7 @@ class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable nzSceneNodeType GetSceneNodeType() const override; bool IsDrawable() const; + bool IsFixedStepEnabled() const; void KillParticle(unsigned int index); void KillParticles(); @@ -58,10 +61,11 @@ class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable void SetEmissionCount(unsigned int count); void SetEmissionRate(float rate); + void SetFixedStepSize(float step); void SetRenderer(NzParticleRenderer* renderer); NzParticleEmitter& operator=(const NzParticleEmitter& emitter); - NzParticleEmitter& operator=(NzParticleEmitter&& emitter); + NzParticleEmitter& operator=(NzParticleEmitter&& emitter) = default; private: void GenerateAABB() const; @@ -79,9 +83,12 @@ class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable NzParticleDeclarationConstRef m_declaration; NzParticleRendererRef m_renderer; mutable bool m_boundingVolumeUpdated; + bool m_fixedStepEnabled; bool m_processing; float m_emissionAccumulator; float m_emissionRate; + float m_stepAccumulator; + float m_stepSize; unsigned int m_emissionCount; unsigned int m_maxParticleCount; unsigned int m_particleCount; diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index b6dc13244..7a54ef7f7 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -19,8 +19,12 @@ NzParticleEmitter(maxParticleCount, NzParticleDeclaration::Get(layout)) NzParticleEmitter::NzParticleEmitter(unsigned int maxParticleCount, NzParticleDeclaration* declaration) : m_declaration(declaration), m_boundingVolumeUpdated(false), +m_fixedStepEnabled(false), +m_processing(false), m_emissionAccumulator(0.f), m_emissionRate(0.f), +m_stepAccumulator(0.f), +m_stepSize(1.f/60.f), m_emissionCount(1), m_maxParticleCount(maxParticleCount), m_particleCount(0) @@ -41,9 +45,12 @@ m_boundingVolume(emitter.m_boundingVolume), m_declaration(emitter.m_declaration), m_renderer(emitter.m_renderer), m_boundingVolumeUpdated(emitter.m_boundingVolumeUpdated), +m_fixedStepEnabled(emitter.m_fixedStepEnabled), m_processing(false), m_emissionAccumulator(0.f), m_emissionRate(emitter.m_emissionRate), +m_stepAccumulator(0.f), +m_stepSize(emitter.m_stepSize), m_emissionCount(emitter.m_emissionCount), m_maxParticleCount(emitter.m_maxParticleCount), m_particleCount(emitter.m_particleCount), @@ -95,6 +102,16 @@ void* NzParticleEmitter::CreateParticles(unsigned int count) return &m_buffer[particlesIndex*m_particleSize]; } +void NzParticleEmitter::EnableFixedStep(bool fixedStep) +{ + // On teste pour empêcher que cette méthode ne remette systématiquement le step accumulator à zéro + if (m_fixedStepEnabled != fixedStep) + { + m_fixedStepEnabled = fixedStep; + m_stepAccumulator = 0.f; + } +} + void* NzParticleEmitter::GenerateParticle() { return GenerateParticles(1); @@ -156,6 +173,11 @@ bool NzParticleEmitter::IsDrawable() const return true; } +bool NzParticleEmitter::IsFixedStepEnabled() const +{ + return m_fixedStepEnabled; +} + void NzParticleEmitter::KillParticle(unsigned int index) { ///FIXME: Vérifier index @@ -218,16 +240,19 @@ NzParticleEmitter& NzParticleEmitter::operator=(const NzParticleEmitter& emitter m_declaration = emitter.m_declaration; m_emissionCount = emitter.m_emissionCount; m_emissionRate = emitter.m_emissionRate; + m_fixedStepEnabled = emitter.m_fixedStepEnabled; m_generators = emitter.m_generators; m_maxParticleCount = emitter.m_maxParticleCount; m_particleCount = emitter.m_particleCount; m_particleSize = emitter.m_particleSize; m_renderer = emitter.m_renderer; + m_stepSize = emitter.m_stepSize; // La copie ne peut pas (ou plutôt ne devrait pas) avoir lieu pendant une mise à jour, inutile de copier m_dyingParticles.clear(); m_emissionAccumulator = 0.f; m_processing = false; + m_stepAccumulator = 0.f; m_buffer.clear(); // Pour éviter une recopie lors du resize() qui ne servira pas à grand chose ResizeBuffer(); @@ -238,31 +263,6 @@ NzParticleEmitter& NzParticleEmitter::operator=(const NzParticleEmitter& emitter return *this; } -NzParticleEmitter& NzParticleEmitter::operator=(NzParticleEmitter&& emitter) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - NzSceneNode::operator=(emitter); - - m_boundingVolume = std::move(emitter.m_boundingVolume); - m_boundingVolumeUpdated = std::move(emitter.m_boundingVolumeUpdated); - m_buffer = std::move(emitter.m_buffer); - m_controllers = std::move(emitter.m_controllers); - m_declaration = std::move(emitter.m_declaration); - m_dyingParticles = std::move(emitter.m_dyingParticles); - m_emissionAccumulator = std::move(emitter.m_emissionAccumulator); - m_emissionCount = std::move(emitter.m_emissionCount); - m_emissionRate = std::move(emitter.m_emissionRate); - m_generators = std::move(emitter.m_generators); - m_maxParticleCount = std::move(emitter.m_maxParticleCount); - m_particleCount = std::move(emitter.m_particleCount); - m_particleSize = std::move(emitter.m_particleSize); - m_processing = std::move(emitter.m_processing); - m_renderer = std::move(emitter.m_renderer); - - return *this; -} - void NzParticleEmitter::GenerateAABB() const { m_boundingVolume.MakeInfinite(); @@ -343,8 +343,22 @@ void NzParticleEmitter::Update() m_processing = false; }); - for (NzParticleController* controller : m_controllers) - controller->Apply(*this, mapper, 0, m_particleCount-1, elapsedTime); + if (m_fixedStepEnabled) + { + m_stepAccumulator += elapsedTime; + while (m_stepAccumulator >= m_stepSize) + { + for (NzParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, m_particleCount-1, m_stepAccumulator); + + m_stepAccumulator -= m_stepSize; + } + } + else + { + for (NzParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, m_particleCount-1, elapsedTime); + } m_processing = false; onExit.Reset();