Proper integration in a shock-situation

Started by
4 comments, last by johnnyk 18 years, 4 months ago
I'm following the methods of the NonConvex Rigid Bodies with Stacking paper and wanted to improve my integration. Right now, the method i'm using breaks up the movement into two steps - compute the change in velocity and resolve collisions, then compute the change in position and resolve contacts. So if I have a motionless object affected for one frame, the change in location is x = vt, where v = g * t So with a gravity of 10 and a timestep of .1, we get a change in position of 1. However I would rather use a better integration, like this: x = .5at^2 + vt and then compute the change in position before we update v. So now with a gravity of 10 and a timestep of .1, we get a change in position of 0.05, a factor of 20 less than the first method!!!! That would, i'm sure, do wonders for the jittering I'm trying to fix. Problem is I cant integrate this way, because the processing is split up into two steps - use accelleration to update the velocity, do some processing (which might change the velocity), then use velocity to update the position; we never go directly from acceleration to position so I cant do the superior style of integration... Does that make sense? Anyone familiar with this method and might have some suggestions? I looked at MrRowl's code (the only implementation of the shock algorithm I know about) and he appears to use the first method of integration. Thanks, -John
Advertisement
Quote:Original post by johnnyk
I looked at MrRowl's code (the only implementation of the shock algorithm I know about) and he appears to use the first method of integration.


I feel I should confess - my implementation of the shock has a bug (I forget the details - I think it sometimes calculate the shock impulse as if both bodies could move, but then only applies the impulse to the "upper" body). Unfortunately fixing this actually makes the unphysical part of this much more obviously.

As for implementing a higher order integration scheme, yes it's tricky. You might be able to do it by doing a simple Euler step to predict the collisions as normal. Then for any colliding bodies, continue as you are, but for the non-colliding bodies backtrack and apply the higher order scheme to obtain their final positions/velocities.

Finally, it's best to use the penetration depth calculated at the _start_ of the step. Then if objects are genuinely overlapping the penetration depth is > 0 and your separation code kicks in. If they're colliding then the penetration depth will be -ve - and you can use this to calculate an impulse that will result in the objects _just_ touching at the start of the next update. This solves the problem you get when you drop an inelastic object onto a surface and (with the jiggle implementation) it stops above the surface. I did this in jiglib and it works pretty well.



[Edited by - MrRowl on December 18, 2005 3:03:57 PM]
Well, if I'm still using lower-order integration for cases where things are colliding, that wont help the problem I'm trying to solve (things trying to travel too far and making too strong a collision). Actually, higher-order integration wouldnt help me after all, since I'm going to use the final velocity to determine the collision response anyway, it doesnt matter what order my integration is to determine the position! The final velocity will always be the same, and thus the collision response (the jitter i'm trying to kill) will be the same whether I'm using lower order or higher order integration. Hmm alright forget that. I might get objects moving slightly better in freefall but i dont care about that so much :)

How is it you got such stability in your system using shock approach? Or did you find that once you fixed the bug you mentioned you got a lot of jitters? My jenga-tower falls down right away.

Image hosted by Photobucket.com

I didnt understand your last statement, "If they're colliding then the penetration depth will be -ve - and you can use this to calculate an impulse that will result in the objects _just_ touching at the start of the next update."
the penetration depth will be what?

Thanks for the quick reply!
-John
Also, let me ask you.. (or anyone else reading this)

How reliant is your stability on your deactivation code? If you disable deactivation, and you have an object sitting motionless on the ground, will it still move? How about a pile of objects, will they move? Mine move, which makes sense, since its continually doing collisions and responses sequentially - is that overcome only by deactivating it, or are there other methods?

So basically, does your sleep algorithm provide you stability, or is it some other technique?
Inspired by the new gamedev theme: Happy Christmas. I don't believe there's anything in there that I haven't described in words elsewhere, and in its current form it's not actually very useable either.

I found that with a "properly implemented" shock step either:

1. if you let it affect rotation then rotational effects get propogated up stacks and tend to grow, resulting in big jitters.

2. if you don't let it affect rotation then the unphysical nature is really obvious.

Drifting of heaps of objects is probably inevitable unless you either (1) process all collisions/contacts exactly (either don't terminate your iterative solver early, or don't use an iterative solver) or (2) cache collisions between steps (see b34r's demos/discussions here on gamedev).

Sorry my explanation wasn't so clear. I meant that if (say) you have a ball and a plane, and the ball is moving towards the plane, but at the start of the step is in front of (not touching) the plane. So during collision detection detect if the bool will hit the plane during the time step. If it does, record the penetration depth at the beginning of the time step - this is a -ve value (i.e. it indicates the ball/plane were initially separate). Now calculate the velocity that the ball should have if it is to just touch the plane at the beginning of the next timestep - this is simply (-penetrationDepth / dt). In your contact/collision processing simply make the "final" relative velocity equal to this when you calculate the impulse.

Another bad explanation I expect!
Thanks for the code, merry christmas :) And that explanation makes more sense now, thanks. As for contact cachine, it didnt really sound any different then deactivation (you force objects back to their previous positions if you detect its the same collision) but maybe I didnt completely understand from the decriptions I got.

Happy Holidays! Time off work = time to work on physics code.. oh and family too

This topic is closed to new replies.

Advertisement