Optimized Collision Detection & Physics

Started by
17 comments, last by force_of_will 14 years, 8 months ago
yeah, understandable, I went ahead and listened to you guys:

void BroadPhaseCollision(){	grid->Refresh(particles, particles_length);	for(int i = 0; i < grid->Width * grid->Height; ++i)	{		for(unsigned int j = 0; j < grid->m_grid.size(); ++j)		{			Particle p1 = particles[grid->m_grid[j]];			for(unsigned int k = j + 1; k < grid->m_grid.size(); ++k)			{				Particle p2 = particles[grid->m_grid[k]];				if(p1.id == p2.id) continue;				float d_x = p2.p_x - p1.p_x;				float d_y = p2.p_y - p1.p_y;				float R = p1.radius + p2.radius;				if(R * R > d_x * d_x + d_y * d_y)					NarrowPhaseCollision(particles[grid->m_grid[j]], particles[grid->m_grid[k]]);			}		}	}}


its actually faster(at least its not as slow as it was before with 400 particles), though the collision itself is still acting funny.. I'll continue to try and figure that out :[

The problem is, that after the collisions are dealt with, more collisions are created, though its finished checking for collision, and continues to update the particles, resulting in a rather buggy Simulation.
Advertisement
Quote:Original post by pinknation
it shouldn't matter if I swept through cells, or particles.. because either way I'd loop through each particle, adding the cell loop, would simply add an extra loop.


Yes, it matters a lot...even more if at each step, you compute the neighbours of every particle. So if you have one thousand particles, for each step( time step ), you, at least, allocate( and deallocate ) one thousand lists of neighbours. This is very costly.
The point was: you don't need computing neighbouring information, since you already have it. Avoiding computing redundant information, is an optimization.
I was not recommending you to add another loop to an existing one, I was simply recommending you to write a faster loop.

You don't need doing things particle-wise, because if A collides with B, then B collides with A: so computing forces, impulses or any other things to maintain your simulation in a coherent state, can be done for each couple of interacting particles, instead of doing it twice, as if the two interacting particles were not affected by the same event.

P.S: I noticed you were computing for every two possible interacting objects, their force of interaction. You should test first if they can possibly interact, and then only compute their force of interaction.

Quote:
Edit: Would AABB method of collision detection be better? Currently I am using a Spatial Index Grid.. which I've seen used in SPH systems.

I don't know if I perfectly understood your question...Your spatial index grid algorithm is a recommended one, and basically does not depend on the bounding volume you use to detect collisions.
You'll still need it( or any other possible divide and conqueer method ) no matter the bounding volume you use.
As you may know, detecting collisions between two spheres( as your collision test shows ) is faster than detecting collision between two AABBs. The only problem is that spheres give many false positives, in general. AABBs are generally better: it depends of the simulation. But if your particles are particles in the most common acception, then there's no need of using bouding volumes.

[edit]Sorry, I didn't see your post...
It's all good, thanks.. I'm just having issues now with particles colliding with one another, after the collision tests have completed. :[ I've been reading up on more collision detection & response, though I'm not understanding how to resolve this problem in an non-costly manner, like all that keeps coming to mind is 'BRUTE-FORCE BRUTE-FORCE BRUTE-FORCE'. ^_^
Quote:Original post by pinknation
yeah, understandable, I went ahead and listened to you guys:

*** Source Snippet Removed ***

its actually faster(at least its not as slow as it was before with 400 particles), though the collision itself is still acting funny.. I'll continue to try and figure that out :[

The problem is, that after the collisions are dealt with, more collisions are created, though its finished checking for collision, and continues to update the particles, resulting in a rather buggy Simulation.


This is to be expected. Actually you should try detecting the time of the first collision after having checked all possible collisions. Let's tfc be the time of first collision. Then advance your simulation to that time, if it is inside your timestep( otherwise don't care )...That is, if the actual simulation time is to and your timestep dt, if tfc < to + dt, then dt = tfc - to. You'll have the assurance that only two objects are colliding at time tfc. Your timestep will not, on the contrary, be fixed.
Quote:Original post by pinknation
It's all good, thanks.. I'm just having issues now with particles colliding with one another, after the collision tests have completed. :[ I've been reading up on more collision detection & response, though I'm not understanding how to resolve this problem in an non-costly manner, like all that keeps coming to mind is 'BRUTE-FORCE BRUTE-FORCE BRUTE-FORCE'. ^_^


One thing is certain, you won't find an easy way of detecting collisions and compute collision responses, if you have a lot of "fast moving" object, in a "small" region of space.

Quote:Original post by pinknation
Hi, my simulation is slowing down @ 200 particles, this mainly was because of the collision detection at first, where every particle, checked for collision against every other particle, meaning 200 * 199 iterations were processed each frame


Didn't really read the thread, so maybe this has been said, but you should be able to get that to 200*100 really easily.

If A collides B, then B collides A. Therefore, only test each pair of items once. Psuedo-coded:

for each item:    for each item after other item:        collide 'em


This, of course, is still quadratic time but it's still a strong improvement for no real overhead.
If you're doing a distance check in NarrowPhaseCollision, you don't need to do it in BroadPhaseCollision. Your issue with resolving one collision and creating another in the process doesn't have any fast solution that I know of, but you can make it look better by performing your collision phase multiple times.
thanks again Flounder. <3 not 100% sure why I did that..

think I'm done w/ help for now, unless anyone can explain how to solve the collision issue..
you could also consider not returning by-value and instead receive by reference in this function.
vector<int> FindContacts(Particle &particle)


Specially if you know at hand how many vector<int> you will need.

or you can always receive by reference the destination vector<int> and do a swap with contacts instead of returning saving that way a temporary value and a call to the copy constructor (copying all elements from contacts to thetemp)

Also a good compiler will remove most of the declaration in the scope of the for but we can never be sure :P (well actaually we can always look at asm)
but its better always to on the safe safe side and declare those outside the scope of the for:
cNorm, nX, nY, a1, a2 etc.

Finally if you want to achieve a really high count of particles you should look into aceleration structures (BVH, BSPs etc) and use the principle that if one particle is a node of the BVH then it doesn't need to be tested for colision with any other node.

Cheers

This topic is closed to new replies.

Advertisement