Particle Physics Simulation - OpenGL C++

Soldato
Joined
8 Jan 2012
Posts
2,802
Alright so I'm working on a particle physics simulation (namely rain) for my dissertation using OpenGL. Self explanatory I guess.

So I've been working through getting back into C++ after using C# for Unity for quite some time. Everythings pretty much came back to me by now. I've spent a couple of weeks on this system building it up from almost the ground (I used an old OpenGL framework just so I could get the more important things done quickly :p)

I have particles rendering and falling based on velocity calculated from deltaTime (time between updates) this didn't take long to get working. However I've come across an issue...

I'm using three STL vectors to store my particles which again I'm happy enough with as they are pretty fast for access speeds. The way that I'm using them is a particle is created and added to the newParticleVector to begin with.

After this is done the second vector renderParVector is suppose to have the elements of newParticleVector added to it in chunks of i. Heres the code as it currently stands:

Code:
void Simulation::fillRendVect()
{
	std::vector<Particle*>::iterator npvIt;
	std::vector<Particle*>::iterator onpvIt;

	int i = 0;

	npvIt = newParticleVector.begin();


	for (npvIt = newParticleVector.begin(); npvIt != newParticleVector.end(); npvIt++)
	{
		onpvIt = npvIt;

		if (i != numParOnScrn)
		{
			renderParVector.push_back((*npvIt));
			i++;
		}
		else
		{
			npvIt++;
			i = 0;
			newParticleVector.erase(newParticleVector.begin(), onpvIt);
			return;
		}
	}
}

Now as the elements are added to renderParVector from newParticleVector in sets of i the newParticleVector should clear from the beginning of the vector to what the npvIt was pointing to before it was incremented. (So for the sake of argument the 10th thing it was pointing to is now onpvIt and npvIt has incremented to the next element) This somewhat works until we get to the last i amount left in the newParticleVector which leaves i elements remaining. Now I've tried a couple of changes to the way this bit of code works... But I can't figure out the way to have it so the newParticleVector completely empties. Either I'm stuck on thinking this logic must work this way... Or what I'm trying to do is impossible and shouldn't be done.

Oh also the last vector is just used to store particles that are being flagged for deletion before the next frame update.

Thanks for any help!
 
Associate
Joined
9 Jun 2004
Posts
423
It looks like the path where the loop finishes due to the stop condition (npvIt != end) needs to be handled.

In that case, there were j <= i elements in newParticleVector to start with.

So you probably just want to do newParticleVector.clear() on that path.

Your code would also be clearer in this instance if you didn't bother with iterators, and just used indexed vector access -- then you don't need to track both the counter i and the iterators.
 
Soldato
OP
Joined
8 Jan 2012
Posts
2,802
It looks like the path where the loop finishes due to the stop condition (npvIt != end) needs to be handled.

In that case, there were j <= i elements in newParticleVector to start with.

So you probably just want to do newParticleVector.clear() on that path.

Your code would also be clearer in this instance if you didn't bother with iterators, and just used indexed vector access -- then you don't need to track both the counter i and the iterators.

I've never indexed vectors as of yet. Will probably look into it as something to change. And I'll try sorting that path out. :)
 
Caporegime
Joined
18 Oct 2002
Posts
32,623
I would index, faster and cleaner. Failing that use some nice clean C++11 auto keywords.
I also don't see why you want to copy items to a different vector. This is slow and awkward. What are you trying to achieve? Are you sure a vector is even the right container?
 
Soldato
OP
Joined
8 Jan 2012
Posts
2,802
I would index, faster and cleaner. Failing that use some nice clean C++11 auto keywords.
I also don't see why you want to copy items to a different vector. This is slow and awkward. What are you trying to achieve? Are you sure a vector is even the right container?

Vectors seemed appropriate. I'm up for suggestions of other data structures if it improves efficiency and code readability. And the way I was thinking with copying between vectors is to do with the fact that I may have 1 million particles created at startup but I don't want 1 million particles to be calculated for and rendered immediately. So instead as they are being used they go to the renderVector and then onto the oldParticleVector for deletion. If theres s data structure I've forgotten that would handle this better feel free to advise.
 
Last edited:
Caporegime
Joined
18 Oct 2002
Posts
32,623
Vectors seemed appropriate. I'm up for suggestions of other data structures if it improves efficiency and code readability. And the way I was thinking with copying between vectors is to do with the fact that I may have 1 million particles created at startup but I don't want 1 million particles to be calculated for and rendered immediately. So instead as they are being used they go to the renderVector and then onto the oldParticleVector for deletion. If theres s data structure I've forgotten that would handle this better feel free to advise.



Vectors are good form adding or removing elements form the end of the vector (So it is a LIFO structure) and they are good for accessing elements by index.

if you want to add or remove elements from the beginning or middle then vectors likely aren't the right kind of container.

However, it sounds like to me you have a bigger design issue. You are copying elements from one vector to another and then to another. This is going to be very slow and I suggest you find a way to avoid it. There are at least 2 solutions for the rendering. Add a Boolean flag to each element to indicate if it should be rendered (potentially you might want to keep track of several states, in which case instead of multiple Boolean if you are concerned about speed an integer and bitmask method will be faster). This way you can iterate though all the elements and check for rendering, but in your outlined scenario this would be sub-optimal assuming a small percent of the million particles are rendered at once.

Second method would be to construct a vector of pointers for each element that need to be rendered. Then simply iterate over this list. This will work great if only a small subset require rendering. Very similar would be to create a vector of indices into the master vector. A little slower but somewhat safer.

As for the deletion, i just don't get it. Why can't delete the element directly in the vector.


Moreover, I don't see the need to generate 1 million particles and then only render some subset. Just create the elements as needed when rendering. E.g. if you only display 1000 particles then have a vector of size 1000 particle. Each time a particle is supposed to be removed you simply reset the parameters.
 
Back
Top Bottom