Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 22 Aug 2013
Offline Last Active Apr 19 2015 11:46 PM

Posts I've Made

In Topic: Sequential Impulse Solver and Sliding Contacts

15 June 2014 - 11:47 PM

The example above that uses appliedVelocity was part of my less-stable version which I am not using anymore. The idea comes from "Game Physics Engine Development" by Ian Millington (section 16.1.2 of 2nd ed) and is intended to remove the previous frame's applied velocity (primarily acceleration due to gravity) in order to reduce jitteriness. With position correction integrated, my engine was stable enough that the term wasn't needed anymore, so I've since removed it. :)


If you still want to use it, my understanding is that you determine it's magnitude along the collision normal (appliedVel dot normal), and subtract it from the amount of desired change in velocity for that frame in order to prevent over-compensation.


Regarding restitution, for my needs, I really don't need much to be "bouncy", so I'm setting the change in vel to be only enough to remove the relative velocity w.r.t the normal (i.e. changeInVel = -magnitudeOfRelativeVelOnNormal). But anyways, the added energy may be coming because of the integration of the position correction. Remember position correction only needs to be applied for a single frame; and so when we apply it as an impulse, it will continue to affect the bodies in question over several frames. To account for this, you should experiment with only applying a fraction of this corrective impulse. This combined with warm starting should be enough. If you dig into the full Box2D (rather than Box2D lite) I believe it handles coefficients of restitution more dynamically.


Something else to consider. If you are caching your contacts across multiple frames or have implemented any type of relaxation to solve your velocity constraints, you'll want to make sure that you update the  "velAlongNormal" each time you apply an impulse to either body otherwise you may accumulate error which *could* be causing any extra bounciness.

In Topic: Sequential Impulse Solver and Sliding Contacts

11 June 2014 - 10:01 PM



For collision detection my engine implements a mix between GJK and the Xenocollide algorithm with Minkowski Portal Refinement (MPR) to get contact points. You can find the algorithm described in detail in Game Programming Gems 7 section 2.5. A simple 2D example is given on the authors website. Other special-case detection I follow Real-Time Collision Detection by Ericson modifying to my specific needs.


For resolution I used a mixture of the following resources to understand the equations of motion and implement a sequential impulse solver:

  • Game Physics Engine Development by Ian Millington -- while a good resource for general physics engine development, I do not recommend following this approach if you want a stable system for stacking more than 3 or 4 boxes high. The latest edition has an addendum for 2D physics if that is your interest.
  • Game Physics by David H. Eberly -- This book is very thorough and gives lots of details on the math for resolution. At an implementation level this book tends to be more focused on block solvers and simultaneous resolution.


Finally, I followed Box2D lite for ordering the integration / detection / resolution pipeline as well as for how to resolve via impulses only (with no direct position corrections), and how to best do warm-starting.


All this said, the two features that added the most to the stability were:


   1) Warm starting on normal and tangential impulses

   2) Impulses for penetration correction

   3) Adjusting the coefficient of restitution (bouncy objects don't lend well to stacking). Box2D lite effectively sets this to 0 along the normal if you look in the code.


Hope this helps!

In Topic: Sequential Impulse Solver and Sliding Contacts

30 May 2014 - 01:29 AM

Okay, just to update with some results...


So I went back and revamped my resolution system; gutted out the penetration resolution via direct position corrections and switched to impulse only adjustments. This along with warmstarting my impulses (both normal and tangential) made a rather dramatic difference to both the stability and performance of my system.


Here are some videos demonstrating the improved results (sorry for the poor compression quality... but I think you'll get the point. Also I made the blocks smaller so I could fit more on screen):




Here's one with 50 rows (slow w/out any broadphase implementation, but stable!!):




Another with 30 rows and projectile box w/higher mass:




Also, I went back to the book I had been following for so long and realized that it indeed does focus on doing what I was doing wrong: direct position corrections. So I'm not as slow / crazy as I was beginning to think; just misled. smile.png  Direct position corrections is so much slower due to the constant need to re-run the detection system (as Dirk already mentioned). 


I was actually very surprised how easy it was to apply penetration corrections via impulses. Simply convert the contact's overlap by the change in time to obtain a velocity and add it to your desired change in velocity when computing your resolution impulse. You'll want to only take a fraction of it otherwise you end up adding energy to the system resulting in jitters. Also you'll want to clamp overlap to be positive (which I'm not showing here):

contact.penetrationAsVel = amntOverlapResolve * contact.overlap * dtInv;
impulseMag = (changeInVel + contact.penetrationAsVel) * contact.effectiveNormalMassInv;

Thanks Dirk for the help.

In Topic: Sequential Impulse Solver and Sliding Contacts

24 May 2014 - 01:03 PM

Wow, this is great info, and will definitely keep me be busy for a while smile.png. Thank you for taking the time to list all of these.


I've had an interest in 2D physics simulations for the past 12 years; started in high school building really small orbit and spring simulations. About 5 years ago I decided I want to build an engine so started collecting / reading books in my spare time (so very slowly). My first go at it I built a basic engine w/spatial grids for broadphase, and SAT for narrow but then got stuck on resolution so essentially copied the parts of Box2D I didn't understand. Feeling unsatisfied that I didn't really understand the resolution math and wanting to do something in C++ I started over back in November and built an engine that does GJK / MPR for narrow (saving broadphase for after I get resolution working). 


But all of this time I've always had this notion of having to solve penetration through position corrections. I think my previous mindset came from "Game Physics Engine Development" by Ian Millington. For instance Pg. 122 he says "We could combine interpenetration resolution with collision resolution. A better solution, in practice, is to separate the two into distinct phases. First we resolve collisions... Second we resolve the interpenetrations."  And I think I just always assumed that "interpenetration resolution" meant fixing pos... Which doesn't make any sense looking back because the book only ever talks about impulses.... Ahhh!! All this time....... (bangs head on desk).


Anyways, an epiphany for a slow guy. Thanks again for your help.

In Topic: Sequential Impulse Solver and Sliding Contacts

24 May 2014 - 12:46 AM

So came across slide #54+ of Erin's "Understanding Constraints" presentation titled "Why not work with positions directly?" which kind-of answers my question (though it seems to be addressing "position-only" solvers rather than position and vel solvers):




I think it's sounding like both solvers could be accurate, but overkill since a velocity solver should do just fine in most cases according to the presentation.