Sign in to follow this  
  • entries
    455
  • comments
    639
  • views
    422550

XNA, particles and physics

Sign in to follow this  

749 views

I was casting around for things last week, looking for a 2D XNA game engine, but in my lookings I came across Project Mercury; a particle engine which supports XNA and, based on the editor, is really sweet.

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.Contains() in both cases)

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...)
Sign in to follow this  


3 Comments


Recommended Comments

I know what you mean regarding SIMD. I heard that the Mono guys are going to take their SIMD stuff to the standards committee, in which case MS would be forced to add it to their own or risk losing compliance [grin]

Also, when you were talking about List.Contains() being a bottleneck, I immediately though of HashSet<T>, which has an O(n) Contains method. Might be helpful either now or in the future.

Share this comment


Link to comment
Quote:
Original post by Mike.Popoloski
Also, when you were talking about List.Contains() being a bottleneck, I immediately though of HashSet<T>, which has an O(n) Contains method. Might be helpful either now or in the future.


I suspect you meant O(1) [grin]

However, in this instance it's a case of the fastest operation is the one you don't do; I know the body and geom for a particle can't be in the world already as such checks like these are a waste of time, be they O(n) or O(1).

That said, I wonder if a HashSet<T> would be a better container in general to use, I'll look into it.

Share this comment


Link to comment
Yeah, I meant O(1) [grin]

Yeah, ever since I found it I use as my generic container of choice whenever I just need some sort of collection of objects. I only use List<T> when I really need sequential access.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now