Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

[for tl;dr see after listing]

//...Code to determine shapes types involved in collision here...

//...Rectangle-Line collision detected.
if(_rbTest->GetCollisionShape()->Intersects(*_ground->GetCollisionShape())) {

    //Convert incoming shape to a line.
    a2de::Line l(*dynamic_cast<a2de::Line*>(_ground->GetCollisionShape()));

    //Get line's normal.
    a2de::Vector2D normal_vector(l.GetSlope().GetY(), -l.GetSlope().GetX());
    a2de::Vector2D::Normalize(normal_vector);

    //Accumulate forces involved.
    a2de::Vector2D intermediate_forces;
    a2de::Vector2D normal_force = normal_vector * _rbTest->GetMass() * _world->GetGravityHandler()->GetGravityValue();
    intermediate_forces += normal_force;

    //Calculate final velocity: See [1]
    double Ma = _rbTest->GetMass();
    a2de::Vector2D Ua = _rbTest->GetVelocity();

    double Mb = _ground->GetMass();
    a2de::Vector2D Ub = _ground->GetVelocity();

    double mCr = Mb * _ground->GetRestitution();

    a2de::Vector2D collision_velocity( ((Ma * Ua) + (Mb * Ub) + ((mCr * Ub) - (mCr * Ua))) / (Ma + Mb));

    //Calculate reflection vector: See [2]
    a2de::Vector2D reflect_velocity( -collision_velocity + 2 * (a2de::Vector2D::DotProduct(collision_velocity, normal_vector)) * normal_vector );

    //Affect velocity to account for restitution of colliding bodies.
    reflect_velocity *= (_ground->GetRestitution() * _rbTest->GetRestitution());

    _rbTest->SetVelocity(reflect_velocity);

    //THE ULTIMATE ISSUE STEMS FROM THE FOLLOWING LINE:
    //Move object away from collision one pixel to prevent constant collision.
    _rbTest->SetPosition(_rbTest->GetPosition() + normal_vector);
    _rbTest->ApplyImpulse(intermediate_forces);
}

Sources:

(1) Wikipedia: Coefficient of Restitution: Speeds after impact

(2) Wikipedia: Specular Reflection: Direction of reflection

First, I have a system in place to account for friction (that is, a coefficient of friction) but is not used right now (in addition, it is zero, which should not affect the math anyway). I'll deal with that after I get this working.

Anyway, when the restitution of either object involved in the collision is zero the object stops as required, but if movement along the same direction (again, irrespective of the friction value that isn't used) as the line is attempted the object moves as if slogging through knee deep snow. If I remove the line of code in question and the object is not push away one pixel the object barely moves at all. All because the object collides, is stopped, is pushed up, collides, is stopped...etc. OR collides, is stopped, collides, is stopped, etc...

TL;DR

How do I only account for a collision ONCE for restitution purposes (BONUS: but CONTINUALLY for frictional purposes, to be implemented later)

share|improve this question

closed as unclear what you're asking by Anko, Vaughan Hilts, Josh Petrie Dec 15 at 17:14

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question.If this question can be reworded to fit the rules in the help center, please edit the question.

1  
I'm having a hard time visualizing this. Do you mean like a flying rectangle crashing into and then sliding up a sloped line? –  Eric B Nov 26 '12 at 16:21
    
@EricB Yes, although the line can have any slope, including zero and undefined. –  Casey Nov 26 '12 at 22:11
    
This question is confusing. Could you clearly state what exactly you're trying to do, how exactly you've tried doing it and in what ways your current solution fails? It's hard to tell just from reading the code. For complex collision or physics stuff, pictures are often really helpful. –  Anko Dec 11 at 2:13