So, I’ve been doing some planning. Trying to work out how exactly I want this particle system to come together. I’ve looked over a couple of different particle systems and guides on various things and tried to come up with a simple, clean way to sort this.
I don’t think it exists. What I mean is. I don’t think there’s a “nice” way to organise the data, at least for what I’m planning. I would like to be able to, potentially, have multiple particle emitters interacting with each other. A direct example is, in my game, I want to have a smokey room. Potentially I can put an emitter near the ceiling which will create a smokey ceiling. That should work reasonably well. But I also would like to have someone walk into the room and have them smoking, and their smoke join with the smoke on the ceiling. I guess I could just have separate emitters and them not actually effect one another, it would probably look alright, but I think, if possible, I’d like the ability to have particle systems merging.
So, what that suggests is splitting the code into 3 different classes, at least initially. The first will be the emitter itself, this will be a behaviour and be able to attach onto any object. I would like to have a derived MObject3d, but I don’t think that it’s possible at this stage, so I’ll make do. The second is a particle system. I’m playing with the idea of having multiple systems, but I think I’m probably going to stick with a singleton. This will be in charge of updating and managing the particles. Finally, the particles themselves. As far as I can see, they don’t need to be much more than pure data.
But, with one “system”, we can maybe have crazy things happening, like water getting blocked by smoke and stuff, right? Well, yes and no. I’m hoping to put in some sort of rudinemtary physics, probably bounding spheres on the particles, and then give each one a mass, so water should, theoretically, be able to push the smoke aside in a semi-realistic manner. Whether this is going to work or not is a different matter. Secondly, you could easily add flags to each emitter, stating different emitter types it doesn’t interact with, so the smoke wouldn’t be affected at all. That would obviously be a lot cheaper and might avoid nasty effects of cheap physics. We’ll see how this goes.
So, my issue from the previous post. Where does the positional data live? Indeed, where is the ownership of any data at all? Does the particle manage it’s own lifetime? Does the particle system? Or the emitter that created it? This is where I feel it really gets messy. When you start thinking of the fact that you could potentially have thousands of particles to manage every frame, some newly created, some about to die, you don’t really want a huge load of reallocations. So, it’s probably best to keep a pool of particles within the system. That way we can just have a giant array within the particle system that we can use. But the issue still stands about the positional data. We really want one big array of positions in the emitter, so we can draw it as one array of point sprites. So we have to have a similar pool within the emitter of positions, then, when we emit a particle, we give it the address of it’s own position. For both these pools, we also need to keep some sort of list of the available free data which we can use for allocating new particles.
It’s sort of nasty having the particles themselves being managed by one thing and their position being owned by the emitter, but I can’t think of a much nicer easy to do it. At least with this plan, the particles are being managed separately so we can make them interact, but don’t have to build a new vertex array every frame.
What about dead particles though? Well, nonactive ones can be skipped from updates with a simple flag. Removing them from being drawn is a slightly bigger issue. Ideally, we don’t want them in the vertex array at all, so they won’t take up draw time. However, as we probably want random lifetimes fort particles (within a range) then there’s no simple easy to guarantee which ones will be alive, again without rebuilding the vertex array every frame. The solution I will try is to also have a colour array. Usually this can be set by the particle definition, our even interpolated over time, but dead particles will then be able to be made totally transparent. They are still being drawn, which isn’t great, but I hope, as I would like to be using point sprites, that this overhead will be less than the alternative. There will be further investigation, I’m sure.
So, all this talk, no action? Not at all. I haven’t pushed anything to github yet, because I have nothing much to show, I’m still in a planning phase really. I do, however, have the majority of what I’ve got mentioned above. I don’t have any physics or rendering, but I have the majority of the framework in place to do these things. And thanks to debuggers, I can verify that everything is working pretty well.
I just hope I haven’t overlooked anything major.
Please let me know what you think. Do you think this is likely to work or had something I’ve suggested got a much larger overhead than could be usable?
Edit: So, I’ve got the particles moving “up” and also rendering. I’ve already noticed two problems. The first is that I can’t seem to be able to set the alpha on the particles. Not too big an issue, I probably don’t have alpha blending on or something, I’m sure that’s solvable. The second is that, from what I can tell, Maratis doesn’t support Point Sprites as a primitive type (yet). I guess this means that I’m going to be modifying Maratis code some more. Code will be uploaded to github presently though