Added fixed step update

Switched back to defaulted operator=(ParticleEmitter&&) since it can't
throw exception anyway


Former-commit-id: 178b040a735ef01dcda21b45a317b6c534b5782e
This commit is contained in:
Lynix 2014-08-08 21:21:04 +02:00
parent 202f675301
commit 0976607eb9
2 changed files with 49 additions and 28 deletions

View File

@ -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;

View File

@ -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();