I was looking at some forum posts about it and some people where talking about having the particles bounce off things etc to give a bit of life to them and someone brought up the idea of doing it with Farseer.
For some reason I got it into my head that this would be a really good idea and so on saturday I set about my task.
While I do intent to change things, and release the code when I'm happy with it, right now what after a fair amount of work, is Mercury being powered by Farseer and particles which can bounce off things; huzzah!
There are however a couple of 'issues'.
The first one I hit was how slow it ran on the PC. Some profiling later and it became apprent that a major issue was adding a 'body' to farseer for it to move. In order to do this it first of all checks the body isn't already in an 'add list' before adding it there, and then when adding to the world it checks a body list to see if it is in there as well (using List
When firing off a large amount of particles in one go (a worse case I admit, but still) these two calls to Contains() is a massive red spot in the runtime.
My first attempt to bypass this involved adding all the bodies an emitter can fire to the world but having them 'off' to start with, then on firing they were activated so they could simulate. This improved the worse case, however it introduced overhead even when particles were active AND caused a massive startup time which was clearly not very helpful.
I then realised that as I knew the particle system was keeping track of things properly with no chance of a double add I decided to bypass this, adding bodies directly to the world as required.
The second problem occured when I went to run it on the 360; it utterly tanked. Indeed, it still does. While my PC could spit out 20K particles over 2 emitters with no problem the 360 fell apart fps wise, making at best 10fps.
At this point I added the debug visualisr from Farseer to see what was going on, the truth was quite nasty; while on the PC I was processing those particles in about 8ms, the 360 version was taking 75ms, a little over 9x longer.
There isn't really a great deal I can do about this right now; a 'solution' is likely to be running all the particle creation/update code on it's own core which means with the pre-collision code I could get 6 to 8K and probably hold 30fps for updating and drawing.
However, as it was working, I decided to forge onwards on the PC and worry about scaling to the 360 later.
I set about the collision response, which required some minor code changes to get around some issues I'd introduced, and the first pass suffered from a case of insane scale for the collision geom. With that fixed I finally saw what I was aiming for; particle explosions which bounce off a solid object.
However even this isn't perfect; upon adding the collision geometry to the world there is a pause while the physics system creates and sets up a few things. I suspect I'm going to have to go into Farseer and do some more 'fast insert' work here as well. As the geoms aren't going to change then I can probably simply reuse them.
There are a few NaN corner cases to work on, and with collisions firing off 20K particles at once is an exercise in 'omg! HOW SLOW?' but still, getting somewhere [smile]
For the 360 solution I might end up taking a look at doing the physics on the GPU, that or splitting the update over 2 hardware threads in order to squeeze as much cpu time as possible out of the 360.
What would REALLY be nice however is if MS would improve the floating point handling on the 360 and give us access to some SIMD stuff; I happen to know that all the floating point power for the 360 is in the SIMD stuff, without it you are pretty crippled at times as this shows.
My other pondering is would I be able to do better than sprite batch for the rendering of them, such as with point sprites.
For now however I'm pretty happy with what I've got [smile]
(and if I had something which could grab the output of the window and make a video then I'd show all you people as well...)