Skip to main content
gamedev.net
🔒 Locked

2D collision response

Started by LizardCPP 2 replies 3.1k views
Original Post
LizardCPP
LizardCPP
I'm implementing simple 2D collision detection and now I want to add collision response. I'm thinking of using a simple projection method where I push the dynamic object out of the static by the normal om the static. But that got me thinking: That can result in another collision. How do I know if that object collided again? Do I have to redo the whole collision detection for that object again? And if I solve that collision then it can be pushed into another collision (or in to the first collision again!), how do I solve this? Can't I end up in a infinite loop? Thanx Lizard
jdindia
jdindia
Yeah, it's a big problem. I'm not an expert on this, but I'll give you my 2 cents since I had the problem before. It's particularly bad for cone type corners where an object can just get stuck or spit out somewhere bad.

The exact problems you'll have will really depend on how you project.

1. If you actually flip the object's velocity when it hits, it'll tend to go away from the bad spots, so it won't usually wedge itself in. This is the cross your fingers and hope it doesn't happen much method. It's much more pronounced if you don't do this.

2. You can avoid putting long cone type corners in your game. This helps but you'll be left with the sneaky suspicion that someone will jam themselves in a regular corner.

3. You can identify corners that are convex vs concave and treat them differently (by restricting which projections are possible). This can help a lot *if* the problem is the object getting pushed out an edge not along the normal.

4. The above are all kind of hacks that make things not as bad, but you know, throw in 3 edge collisions and you're in trouble again. The proper way to do this is to build a list of things you hit and then try to resolve them simultaneously (I think). I've never done this because I went with...

5. Use a physics library and let it do everything for you. Box2d, Chipmunk, ODE, Bullet, Havok, PhysX, etc.


Emergent
Emergent
I haven't proven this, but this is so much like the Method of Alternating Projections (a general sort of numerical algorithm, not just a videogame physics thing; see this if you're interested) that I really strongly suspect that if you just cycle through all the static objects that your dynamic object is colliding with and project over and over, you will converge (albeit perhaps asymptotically) to a feasible point (i.e., one where you're not colliding).

Let me put this in pseudocode...

Every frame  // Check for collisions:  Let D be the dynamic object.  Let collisions := 1;  While collisions != 0      collisions := 0;    For every static object S:      If D is colliding with S        Project D out of S // Do the projection, "plus a little bit"        collisions++


Again, let me emphasize that I have not proven that this converges, but I suspect that it does.
jdindia
jdindia
Quote:

Again, let me emphasize that I have not proven that this converges, but I suspect that it does.


You have to be careful about convergence statements. For these type problems, I believe convergence really hangs on 'convexity', so you have to be precise about what it means to be convex in this domain and then argue from there.

The second problem is that convergence alone doesn't mean convergence to the point you actually wanted. It's fairly easy to generate examples where you perform a projection which immediately removes any collisions but puts you far away from where you want to be.

If all you have are a bunch of convex polygons bumping into each other in space, then iteratively projecting should work fine.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.