// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Visject/GraphParameter.h"
class ParticleSystemInstance;
class ParticleBuffer;
class ParticleSystem;
class ParticleEmitter;
class GPUBuffer;
///
/// Particle system parameter.
///
///
class FLAXENGINE_API ParticleSystemParameter : public GraphParameter
{
public:
ParticleSystemParameter()
: GraphParameter(SpawnParams(Guid::New(), TypeInitializer))
{
}
ParticleSystemParameter(const ParticleSystemParameter& other)
: ParticleSystemParameter()
{
#if !BUILD_RELEASE
CRASH; // Not used
#endif
}
ParticleSystemParameter& operator=(const ParticleSystemParameter& other)
{
#if !BUILD_RELEASE
CRASH; // Not used
#endif
return *this;
}
};
///
/// The particle emitter simulation graph instance data storage. Required to update the particles.
///
class FLAXENGINE_API ParticleEmitterInstance
{
public:
struct SpawnerData
{
///
/// The particles spawning counter fractional parts (used to maintain stable spawn rate over time).
///
float SpawnCounter;
///
/// The custom data for spawn modules (time of the next spawning).
///
float NextSpawnTime;
};
public:
///
/// The instance data version number. Used to sync the Particle Emitter Graph data with the instance state. Handles Particle Emitter reloads to enure data is valid.
///
uint32 Version = 0;
///
/// The total simulation time.
///
float Time;
///
/// The graph parameters collection (instanced, override the default values).
///
Array Parameters;
///
/// The particles spawning modules data (one instance per module).
///
Array SpawnModulesData;
///
/// Custom per-node data (eg. position on spiral module for arc progress tracking)
///
Array CustomData;
struct
{
///
/// The accumulated delta time for the GPU simulation update.
///
float DeltaTime;
///
/// The accumulated amount of the particles to spawn.
///
int32 SpawnCount;
} GPU;
///
/// The buffer for the particles simulation.
///
ParticleBuffer* Buffer = nullptr;
public:
///
/// Initializes a new instance of the class.
///
ParticleEmitterInstance();
///
/// Finalizes an instance of the class.
///
~ParticleEmitterInstance();
///
/// Clears this container state data.
///
void ClearState();
///
/// Synchronizes the instance data with the specified emitter from the given system.
///
/// The system instance data.
/// The system.
/// The emitter index (in the particle system).
void Sync(ParticleSystemInstance& systemInstance, ParticleSystem* system, int32 emitterIndex);
};
///
/// The particle system simulation graph instance data storage. Required to update the particles.
///
class FLAXENGINE_API ParticleSystemInstance
{
public:
///
/// The instance data version number. Used to sync the Particle System data with the instance state. Handles Particle System reloads to enure data is valid.
///
uint32 Version = 0;
///
/// The parameters version number. Incremented every time the instance data gets synchronized with system or emitter when it ahs been modified.
///
uint32 ParametersVersion = 0;
///
/// The total system playback time.
///
float Time;
///
/// The last game time when particle system was updated. Value -1 indicates no previous updates.
///
float LastUpdateTime = -1;
///
/// The particle system emitters data (one per emitter instance).
///
Array Emitters;
///
/// The GPU staging readback buffer used to copy the GPU particles count from the GPU buffers and read them on a CPU.
///
mutable GPUBuffer* GPUParticlesCountReadback = nullptr;
public:
///
/// Finalizes an instance of the class.
///
~ParticleSystemInstance();
///
/// Gets the particles count (total). GPU particles count is read with one frame delay (due to GPU execution).
///
/// The particles amount.
int32 GetParticlesCount() const;
///
/// Clears this container state data.
///
void ClearState();
///
/// Synchronizes the instance data with the specified system.
///
/// The system.
void Sync(ParticleSystem* system);
///
/// Determines whether the specified emitter is used by this instance.
///
/// The emitter.
/// true if the specified emitter is used; otherwise, false.
bool ContainsEmitter(ParticleEmitter* emitter) const;
};