//==============================================================================
bool DARTCollisionDetector::collide(
    CollisionGroup* group1,
    CollisionGroup* group2,
    const CollisionOption& option, CollisionResult& result)
{
  result.clear();

  if ((this != group1->getCollisionDetector().get())
      || (this != group2->getCollisionDetector().get()))
  {
    dterr << "[DARTCollisionDetector::detect] Attempting to check collision "
          << "for a collision group that is created from a different collision "
          << "detector instance.\n";

    return false;
  }

  auto casted1 = static_cast<DARTCollisionGroup*>(group1);
  auto casted2 = static_cast<DARTCollisionGroup*>(group2);

  const auto& objects1 = casted1->mCollisionObjects;
  const auto& objects2 = casted2->mCollisionObjects;

  if (objects1.empty() || objects2.empty())
    return false;

  auto done = false;
  const auto& filter = option.collisionFilter;

  for (auto i = 0u; i < objects1.size(); ++i)
  {
    auto collObj1 = objects1[i];

    for (auto j = 0u; j < objects2.size(); ++j)
    {
      auto collObj2 = objects2[j];

      if (filter && !filter->needCollision(collObj1, collObj2))
        continue;

      checkPair(collObj1, collObj2, option, result);

      if (result.getNumContacts() >= option.maxNumContacts)
      {
        done = true;
        break;
      }
    }

    if (done)
      break;
  }

  return result.isCollision();
}