private void ResolveVelocity(float duration)
    {
        float separatingVelocity = CalculateSeparatingVelocity();

        if (-separatingVelocity > 0)
        {
            return;
        }

        float newSeparatingVelocity = -separatingVelocity * restitution;

        Vector3 accelerationCausedVelocity = particle.GetAcceleration();

        float accelerationCausedSeparatingVelocity = accelerationCausedVelocity.ScalarProduct(contactNormal) * duration;

        if (accelerationCausedSeparatingVelocity < 0)
        {
            newSeparatingVelocity += restitution * accelerationCausedSeparatingVelocity;
            if (newSeparatingVelocity < 0)
            {
                newSeparatingVelocity = 0;
            }
        }

        float   deltaVelocity = newSeparatingVelocity - separatingVelocity;
        Vector3 impulse       = contactNormal * deltaVelocity;
        Vector3 totalVelocity = particle.GetVelocity() + impulse;

        particle.SetVelocity(totalVelocity.x, totalVelocity.y, totalVelocity.z);
    }
    private float CalculateSeparatingVelocity()
    {
        Vector3 velocity = particle.GetVelocity();

        return(velocity.ScalarProduct(contactNormal));
    }