Page 1 of 1

Sinking Bodies

Posted: Fri Nov 16, 2012 1:06 pm
by cc_dev
So I finally decided to make the switch from Box2D to Chipmunk, although I'm having a problem. Basically, bodies can "sink" into each other. I found a video that shows the problem I'm having:

http://www.youtube.com/watch?v=3Ho4oCr7FVM

It happens for vertical and horizontal movements. Horizontal (IE: moving against a wall) is much worse, and will actually pass through the wall. My first thought was that it had something to do with the timestep. I've tried a lot of different implementations (both variable and fixed), however it doesn't seem to make a difference. I was able to get the player body from passing through the wall with one implementation, but he would still sink into the wall about half way (with a small timestep).

Any ideas what I could be doing wrong? Any help would be greatly appreciated. Must say that so far, I'm quite happy that I made the switch :D

Re: Sinking Bodies

Posted: Fri Nov 16, 2012 2:25 pm
by slembcke
Chipmunk doesn't support swept collisions. So what is happening that causes the overlap is that in one frame the player is not touching the ground, then the next frame it's position is updated and it's overlapping the ground quite a bit. Box2D has support for swept collisions meaning it finds the sub-frame time that objects collide and handle that. By default it's only enabled between moving and static objects, and enabling it between moving objects can get quite expensive. Even between moving and static objects, disabling it will give you a pretty sizable performance boost. The issue with embedding the player in the wall, I suspect it's because you are directly modifying the body's velocity or applying impulses before calling cpSpaceStep().

Anyway, Chipmunk doesn't currently support swept collisions. It's on the list of things I want to do, but isn't really a priority right now. In most cases you can trivially work around the issues, and still have much better performance.

This platformer game I collaborated on for a contest about year ago or so. I spent a while trying to make the platforming experience as smooth as possible.
https://github.com/maximile/Your-Story (video)

1) Make most input changes (modifying the velocity or applying impulses) in the player body's velocity update callback. This is a sort-of-mostly-undocumented tip. The reason is because this runs after the position is updated, but before the solver runs. So when you tell the player to push against an immovable wall, the solver gets a chance to reduce that velocity back to 0 before the position is updated next frame causing it to overlap the wall a lot. When making velocity changes, do them smoothly. Instead of setting the velocity to a specific value, accelerate to that value over a short interval instead. See the surface velocity tip below too.

2) Use surface velocities to move the player. Things like moving platforms and slopes work very nicely without any extra work. In YourStory, I calculated the friction coefficient based on the duration of the acceleration to the player's running speed that I wanted. I think it worked really well.

3) Cheat on the drawing position by storing the collision normal and penetration distance of the shape you are standing on. The physics will still have the overlap, but the rendering will be look aligned correctly. You can really only do this in one axis at a time, so I always picked to project the player out of the ground.

4) Use a fairly high, fixed size timestep. Chipmunk supports variable timesteps, but it's highly discouraged. 60hz works mostly fine (I would never recommend less), but for fast action games consider an even smaller timestep. I think YourStory ran at 120 or 180hz. If you don't have a lot of dynamic objects, or a lot of them are sleeping at any given time this shouldn't cause a performance issue. If your timestep is smaller than your frame time, I wouldn't really bother with extrapolation or interpolation. I've never bothered with interpolation as the position artifacts with extrapolation tend to be very subtle and it's much simpler to implement engine-wide.

Re: Sinking Bodies

Posted: Mon Nov 19, 2012 11:22 am
by cc_dev
Wow, very detailed response, thanks :D

I went back and added a very quick acceleration, and now the player won't pass through the wall :D He still sinks into it slightly, but it's a small enough amount that I can't see it being a problem. I like the cheat the drawing tip you suggested as well, will definitely try that for the ground. I think that, plus a smaller timestep, should work nicely.

Re: Sinking Bodies

Posted: Tue Aug 05, 2014 3:27 am
by icepower
@slembcke
Thank you very much, I was borhered with this issue these days. I'll try your tips right now! :mrgreen: