Jump to content
  • Advertisement
Sign in to follow this  

sliding collision response

This topic is 2990 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm having trouble with sliding collision response. I can't find any tutorials. I using a BVH acceleration structure and the plane-Sphere intersection test for collision detection. It works great, the sphere is pushed back with the sliding motion but it also slowly sinks through the mesh (the plane) when the sphere motion is zero.
I can't work out how to fix this problem and I've tried pretty much everything I can think of, adding extra values, scaling the push vector, etc. Can anyone help?

I post the code:

void CPhysicsManager::CollideObjects(CCollisionInfoVector& Collisions)
for(unsigned int i = 0; i < Collisions.size(); i++)
CCollisionInfo CollisionInfo = Collisions;
CEntityPtr pEntityA = CollisionInfo.pEntity1;
CEntityPtr pEntityB = CollisionInfo.pEntity2;

CVector3 Normal = CollisionInfo.Normal;

CVector3 VectorAP = CollisionInfo.Point - pEntityA->GetPosition()->GetCenter();
CVector3 VectorBP = CollisionInfo.Point - pEntityB->GetPosition()->GetCenter();

CVector3 VelocityA = pEntityA->GetMotion()->GetVelocity() + CVector3::Cross(pEntityA->GetMotion()->GetAngularVelocity(),VectorAP);
CVector3 VelocityB = pEntityB->GetMotion()->GetVelocity() + CVector3::Cross(pEntityB->GetMotion()->GetAngularVelocity(),VectorBP);

CVector3 VelocityAB = VelocityA - VelocityB;

float dirDiff = CVector3::Dot(VelocityAB,Normal);
if(dirDiff < 0)
float fRestitution = CollisionInfo.fRestitution;
float fFriction = CollisionInfo.fFriction;

CVector3 Tangent = CVector3::Normalize(CVector3::Cross(CVector3::Cross(Normal,VelocityAB),Normal));

float fNumerator = -(1+ fRestitution ) * dirDiff;

CVector3 APTemp = CVector3::Cross(CMatrix::TransformNormal(CVector3::Cross(VectorAP,Normal),pEntityA->GetCollisionModel()->GetInertiaTensorInverse()),VectorAP);
CVector3 BPTemp = CVector3::Cross(CMatrix::TransformNormal(CVector3::Cross(VectorBP,Normal),pEntityB->GetCollisionModel()->GetInertiaTensorInverse()),VectorBP);

float fMassA = pEntityA->GetCollisionModel()->GetOneOverMass();
float fMassB = pEntityB->GetCollisionModel()->GetOneOverMass();

if(fMassA == CCollisionModel::INFINITE_MASS) APTemp = CVector3(0,0,0);
if(fMassB == CCollisionModel::INFINITE_MASS) BPTemp = CVector3(0,0,0);

float fDenominator = fMassA + fMassB + CVector3::Dot((APTemp + BPTemp), Normal);

float fImpulse = fNumerator / fDenominator;
CVector3 ImpulseV = fImpulse * Normal - ((fFriction * fImpulse) * Tangent);

pEntityA->GetMotion()->SetVelocity(pEntityA->GetMotion()->GetVelocity() + ImpulseV * pEntityA->GetCollisionModel()->GetOneOverMass());

CVector3 AngularMomentumChange = CVector3::Cross( VectorAP, ImpulseV);
CVector3 AngularVelocityChange = CMatrix::TransformNormal(AngularMomentumChange,pEntityA->GetCollisionModel()->GetRelativeInertiaTensorInverse());
CVector3 CurrentAngularVelocity = pEntityA->GetMotion()->GetAngularVelocity();

pEntityA->GetMotion()->SetAngularVelocity(CurrentAngularVelocity + AngularVelocityChange);

pEntityB->GetMotion()->SetVelocity(pEntityB->GetMotion()->GetVelocity() - ImpulseV * pEntityB->GetCollisionModel()->GetOneOverMass());

CVector3 AngularMomentumChange = CVector3::Cross( VectorBP, ImpulseV);
CVector3 AngularVelocityChange = CMatrix::TransformNormal(AngularMomentumChange,pEntityB->GetCollisionModel()->GetRelativeInertiaTensorInverse());
CVector3 CurrentAngularVelocity = pEntityB->GetMotion()->GetAngularVelocity();

pEntityB->GetMotion()->SetAngularVelocity(CurrentAngularVelocity - AngularVelocityChange);

Share this post

Link to post
Share on other sites
Check out Erin Catto's GDC tutorial presentation. It is available in the following link. You're looking for the "Solver" *.ppt presentation.

GDC 2009 Presentation

It has a discussion about inequality constraints, including non penetration constraints for things like sliding.

Home page for Box2D, which has links to Erin's downloads, including the link above

Hope that helps!

Share this post

Link to post
Share on other sites
hi, thanks, I was directed to jan bender's solution.



I implemented the collision response and works very well. I perfectly understand the documentation for the first part, but still have problems with resting contacts (which he calls contacts handling). I follow this paper:


Trying to better document I met very often the solution that you mentioned (Erin Catto box2d), but I have no idea if is possible use both simultaneously.

I try to understand the technique of Erin Catto, I hope it is easier for an ignorant like me

Share this post

Link to post
Share on other sites
I have realized that the problem is the order of operations during the simulation step.

I set the simulation in this way (starting with t = 0):

while (sim)
CollisionDetection ();
CollisionResponse ();
AdvanceSimulation (); // update Force and user's input at time t
ContactHandler (); // time t = newt;

For me it's correct... I hope

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!