void tgBulletContactSpringCable::step(double dt)
{    
    updateManifolds();
#if (0) // Typically causes contacts to be lost
    int numPruned = 1;
    while (numPruned > 0)
    {
        numPruned = updateAnchorPositions();
    } 
#endif
	updateAnchorList();
	
	// Update positions and remove bad anchors
	pruneAnchors();

#ifdef VERBOSE 
    if (getActualLength() > m_prevLength + 0.2)
    {
//         throw std::runtime_error("Large length change!");
        std::cout << "Previous length " << m_prevLength << " actual length " << getActualLength() << std::endl;
    }
#endif
    
	calculateAndApplyForce(dt);
	
	// Do this last so the ghost object gets populated with collisions before it is deleted
    updateCollisionObject();
    
    assert(invariant());
}
// The step function is what's called from other places in NTRT.
void tgBulletCompressionSpring::step(double dt)
{
    if (dt <= 0.0)
    {
        throw std::invalid_argument("dt is not positive!");
    }

    calculateAndApplyForce(dt);

    // If the spring distance has gone negative, crash the simulator on purpose.
    // TO-DO: find a way to apply a hard stop here instead.
    if( getCurrentSpringLength() <= 0.0)
    {
      throw std::runtime_error("Compression spring has negative length, simulation stopping. Increase your stiffness coefficient. TO-DO: implement a 'hard stop' inside the step method of tgBulletCompressionSpring instead of crashing the simulator.");
    }
    
    assert(invariant());
}
void TwoParticleForce::calculateAndApplyForce(Atom *atom1, Atom *atom2)
{
    calculateAndApplyForce(atom1, atom2, Vector3::zeroVector());
}
void KohenThreeParticleForce::calculateAndApplyForce(Atom *atom1, Atom *atom2, Atom *atom3)
{
    calculateAndApplyForce(atom1, atom2, atom3, Vector3::zeroVector(), Vector3::zeroVector());
}