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
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.