I have uploaded a new alpha version which I hope brings a lot more stability. After the new 3d version I wanted to refactor a lot of the underlying library to try and optimise it more. I’ve spent a long time thinking about the best way to update particles and in the end I think I’ve come up with a reasonably decent way of doing it by having a 3 separate methods depending on the nature of the particle effects being updated. These 3 different scenarios are:
For a lot of particle effects you’re not worried about the order that they’re updated and drawn, either because every particle is drawn with an additive blend so it won’t matter which order they’re drawn in or there’s just not enough alpha blended particles to worry about it. For this method each emitter can simply maintain it’s own list of particles and update them all as and when. This has a few advantages as far as optimisation goes, for example as each particle is updated it needs to know about some of the properties of the emitter so this data can be loaded ahead of time and then all the particles in the emitter updated in one go which helps with CPU caching. When the particles need to be drawn in a certain order then different properties in different emitters may need to be accessed all the time as each particle is updated so it won’t be quite as cache friendly.
The other advantage of this method is that it’s a lot easier to multi thread, you can just let each emitter update it’s particles in a separate thread and write out it’s sprites to a predesignated area each frame.
Particles ordered by age
You may want particles to be drawn in the order that they’re spawned in order to achieve a certain aesthetic such as additive particles mixed with alpha blended particles to create a nice smoke trail with sparks. For this method as each particle is spawned it’s added to a particle buffer which is double buffered. Each frame each particle in the current buffer will be updated and added to the next buffer if it hasn’t expired. This means that particles from different emitters can be mixed together and kept in the order that they are spawned. This method is less cache friendly and harder to multithread but still works well.
Particles ordered by depth
For some 3d effects you may want to order the particles by depth. This method uses the same as ordered by age but it also adds a few ways to the sort the particles. Firstly when the particles are spawned they are ordered using quick sort so that they’re spawned in order, then thanks to the fact that the particles are double buffered they can be easily inserted into the buffer in the correct place by comparing with the current particle being updated before adding to the next buffer. Then you have a couple of options to keep particles in order depending on the effect: You can either use a bubble sort with a defined number of parses each frame – bubble sort is effective if the particles are already more-or-less in order. The second option if you need to guarantee the particles stay in order each frame is to use insertion sort which is also the fastest sort method for lists that are mostly ordered which is the case here.
There’s still plenty of optimising to be done, for example implementing multi-threading which I haven’t done yet. I think before I do that though I’d like to keep concentrating on stability and adding some new features that would be good to have has I near going into a beta release.
So for the next alpha I’d like to maybe implement the following:
- Being able to import the old TimelineFX libraries.
- Be able to adjust the hue of all emitters in the effect (with the option to exclude some emitters), I’ve always thought this would be very useful to have, and maybe even put it on a graph so that it can be adjusted overtime.
- Add new emitter types for 2d/3d: ring, cylinder, splines (maybe), images as spawn data.
- It would be nice to add preset window layouts for the UI.
- The usual bug fixes and more stability.
Here’s the full list of updates for this alpha:
* Large refactor and optimisations of the way particles are updated.
* A lot of various crash bug fixes.
* Each effect now has it’s own preview camera settings in 3D.
* Isometric view now saves properly on animation tab.
* Fixed some bugs relating to converting effects and emitters from 2d to 3d.
* Fixed more issues relating to timing.
* File now marked as unsaved when dragging the emitter size.
* Arrow library navigation now back at the proper sensitivity.
* Changed traverse edge to traverse line.
* Clicking mouse in isometric mode now places effect that the correct place.
* Added order by age effect property. There is now Order by age, depth or unordered if none are selected.
* Fixed crash when saving a file that has no path.
* More optimised memory usage.
* Previewing an import effect has a default camera applied in 3d.
* Fixed some issues with auto-playing effect in some edge cases.
* Fixed issues when changing sync refresh rate – may still be some issues though.
* History now added when pasting a sub effect.
* History now added when selecting a colour preset.
* Fixed S curve graph preset when applying to any graph that isn’t overtime.
* Fixed issues when adding a 2d emitter to a 3d effect.
* Non uniform emitters should work properly now.
‘Till next alpha!