The WPF animation system is very powerful and at the same time also very easy to program. For most animations Storyboards should suffice but for some scenarios you may have to resort to using Frame-based animations. Ideally I would want to fit all animations into a Storyboard, in one form or the other. However that may not be feasible all the time. Take the case of particle effects like fire, snow, bubbles, smoke etc. Creating these effects is fun but not always easy to integrate into a real-world app.
That is where Neon will help. Neon is a particle engine that I have built for WPF that brings in some of the best ideas from a few other systems. I have taken some good ideas from the Mercury Particle Engine, ParticleSystem.org and some articles listed on the Wiki page for Particle system. However the primary influence in terms of the architecture is the Mercury Particle Engine.
There is some well-known theory and vocabulary about Particle systems which one should be familiar with. This includes terms like Emitter, Particle, Sprite, Effect and also some terms related to the attributes of a single particle (LifeTime, Age, Position, Velocity, etc). The links that I listed above should get you upto speed on all this.
First comes the demo, then the details…
A demo is always more exciting that some details about how a particle system was implemented. So have a look at this demo video I put up that shows some simple particle effects I created using Neon. Effects include Fire, Smoke, Bubbles, Snow, Fountain and FireFlies. Click the image to go to the video.
The details are exciting too…
As mentioned earlier, I took lot of good ideas from the Mercury Particle Engine because of its extensible architecture. Mercury works great for the Microsoft XNA framework and I wanted something similar for WPF. However I skipped some features and added some others to make it work well for WPF. For example, I took out the rendering part completely, so the engine itself doesn’t do any rendering. In Mercury the rendering is part of the engine.
Every particle effect that you create is an instance of the ParticleSystem class. A ParticleSystem is driven by a set of Emitters which are responsible for creating new Particles. An Emitter’s primary function is to position the Particles at the start of the effect, give them some Velocity, LifeTime and other attributes. Every Emitter can also have a set of Modifiers that can change the attributes of the Particle over its LifeTime. These attributes are changed whenever the Update() method is called on the Emitter, which in turn is called from the Update() method of the ParticleSystem, in every time interval. The ParticleSystem has no knowledge of the timer and neither does it know anything about rendering the particles. It is the responsibility of an outside class to setup the timer and draw the particles every interval. This is important because I want to eventually make the engine completely driven by Storyboards (the ultimate goal).
As an example of how these classes are used, lets look at the ParticleSystem for the Bubbles effect.
LineEmitter: randomly positions all the particles on a line
EmitterWakeupModifier: the Emitter by default kills the particles once their lifetime is over. This modifier restores the lifetime of the particles again. This is how I get the non-stop effect.
SineForceModifier: makes the particles move in a curve as they float upwards
TrackMouseModifier: this gets me the mouse interaction
WindowBounceModifier: bounces the particles off a virtual window. The particles also lose some energy when they hit the walls
I have already made a library of simple Emitters and Modifiers (including the ones I mentioned) and extending it is also straightforward. For example if you wanted your particles to move along a spiral path, you could just add a SpiralModifier, say, that orients the particle along a spiral.
One last thing…
If you are interested in trying this Demo on your machine, go ahead and download the binary!