🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

3D Collision Resolution - Sequential Impulses?

Started by
3 comments, last by Deku 6 years, 4 months ago

Hi all,

I posted here a few weeks ago to get some pointers on my SAT collision detection implementation. The help I got was great, so I thought I'd pester this forum again with another question:

Best ways to handle 3D collision resolution? If anyone has any resources on the topic, I'd love to see them. I have looked over a few so far but sometimes I feel like I'm reading another language when looking into this topic. Having done some preliminary research, sequential impulses seems to be the way to go but I'm having trouble understanding it. The mathematics has me confused straight away.

Looking at Erin Catto's GDC slides on the subject it seems I need to calculate a normal impulse first to resolve penetration. I'm going to highlight my process so far cause I do not feel I have interpreted the calculations correctly, and hopefully I can get some pointers on where things may be going wrong.

 

First I calculate a relative velocity between the two objects:

relV = v2 + w2 x r2 - v1 - w1 x r1 (where v is the linear velocity, w is the angular velocity, and r is the contact point relative to the center of mass)

Then I need to compute that along the normal:

vn = relV . n (where n is the contact normal)

Then I need to calculate k:

kn = invM1 + invM2 + [invI1(r1 x n) x r1 + invI2(r2 x n) x r2] . n (where invM is the inverse mass and invI is the inverse inertia in world space)

Combining these calculations I get a normal impulse:

Pn = max(-vn / kn, 0)

Then I can get the magnitude of my normal impulse by multiplying with the contact normal:

P = Pn * n

This can be added/subtracted to my linear velocities by multiplying it against the inverse mass of the object:

linearVel += P * invM

And to the angular velocities by transforming the relative contact point

angularVel += invI(r x P)

 

The resulting velocities should be adjusted by a basic normal impulse to counteract any penetrations occurring between the colliding objects (not yet dealing with velocity correction), but currently I don't seem to be getting any impulse (Pn = 0). Maybe that's just the case since I haven't added any bias impulses yet?

Advertisement

Make sure you also take a look at Erin's old Box2D *Lite* from 2006 (not the full Box2D library) download here, so you can see a straightforward implementation. Then you can verify your own equations and understanding by comparing with working code: http://box2d.org/files/GDC2006/Box2D_Lite.zip

The solver is very easy to port to 3D. Getting collision detection in 3D is another story. For a full 3D example you can try reading my own code here (basically a Box2D *Lite* port to 3D): https://github.com/RandyGaul/qu3e

This looks conceptually correct. Did you add gravity into the linear velocities before the solve? E.g. v += g * dt

Another thing I am not sure is your effective mass (k). I use

me = invM1 + invM2 + dot( r1 x n, invI1 * (r1 x n) ) + dot( r2 x n, invI2 * (r2 x n)

It is totally possible (and also likely) that our formulas are equivalent! I just cannot tell from just looking and would need to write it down.

 

 

 

Thanks guys! It's a great help to have the added confidence that I am on the right track as I was not really sure of my current direction at the time of posting.

Randy, your code is elegant and a fantastic resource on the topic. Thanks for the link! I took a look at the Box2d Lite implementation as well, but found your implementation much easier on the eyes.

Dirk, I do believe our equations are equivalent and yes, I was adding gravity (as a force) to the velocities before solving. At a high level I am currently doing the following each update step:

Add forces -> Integrate velocities -> Collision detection -> Solve contacts -> Integrate positions

 

I will probably be slowly chipping away at this for a while but already I'm getting some more promising results, albeit still very buggy.


 

 

This topic is closed to new replies.

Advertisement