You know, sometimes the simplest solutions are the best.
Just spent the last couple days on the particle stuff ( since the 4th ) and have gone through about 4-5 rewrites and the final solution was much cleaner, easier to understand and easier to work with.
Just because it's easier, doesn't mean there isn't some work to be had to get the results you expect.
I have uploaded what I have so far. The demo this time is Fireworks. It's all in the master branch. I have two out of four particle emitters made. The first is a single emitter, it fires a single particle or single stream of particles depending on the delay, if any, between launches. The second is a radial emitter. It emits particles in a radius and random speeds. I played with this one the most. I probably need to make that a ranged variable, but for now you just enter a speed and it randomly chooses a value between 0 and speed.
The other two I haven't done yet, are going to be single stream and conical. The first I'm planning will hopefully be something like fire and the second would be water from a faucet or afterburners from a jet or ship. Just have to throw something together and see what comes out.
At present, and hopefully there won't be many changes, the way you create an emitter is:
Code: Select all
// SingleEmitter
m_baseEmitter =
SingleEmitter( StartPosition, NumParticlesToLaunch, MaxParticlesToStore, DirectionEmitterIsFacing );
// RadialEmitter
m_burstEmitter =
RadialEmitter( StartPosition, NumParticlesToLaunch, MaxParticlesToStore );
RadialEmitter fires in all directions, so no need to pass a direction. The direction should be normalized btw. If not, it will throw off the velocity of the particles.
and to create/spawn particles:
Code: Select all
const float speed = 5.f;
const float minRadius = 5.f;
const float maxRadius = 5.f;
const float minTTL = .016f * 40.f;
const float maxTTL = .016f * 70.f;
const Color color = Colors::Orange;
m_emitter.SetPosition( position );
m_emitter.SpawnParticles( ParticleSetupDesc{
speed, minRadius, maxRadius, minTTL, maxTTL, color
} );
For the Fireworks demo, I have the radial emitters spawn particles at the locations of the dead particles that were fired from the single emitter. Each group of particles that gets spawn from the radial emitter gets their own color. Those colors are stored in an array and randomly selected.
Right now, particles are dynamically allocated both using std::unique_ptr and std::vector, or more precisely, a std::vector<std::unique_ptr<Particle>>. My original idea was to pass around the dead particles in a messaging system, but that got complicated and messy. I think I will try having a vector for each emitter that is sized for what the user passes in, and just reuse those slots, moving the dead ones to the end or just finding a dead one and replacing it with a new one. This should cut down on dynamic allocations/reallocations and deallocations. Hopefully, this won't affect the interface too much.
Right now in Release I only use about 8% cpu and 6.3 MB of memory when spawning in 500 particles. I didn't setup a fps text on screen so I'm not sure if there was any frame rate issues, probably not with only 8% usage. In debug mode, you will notice a performance hit and is to be expected. I'll share results when I change from using vector of unique_ptrs to vector of Particles. Also, I'll put up a fps counter before and after.