bool IntrHalfspace3Box3<Real>::Find ( Real tmax,
                                          const Vector3<Real>& velocity0, const Vector3<Real>& velocity1 )
    {
        mContactTime = ( Real )0;
        Real tlast = Math<Real>::MAX_REAL;
        Vector3<Real> relVelocity = velocity1 - velocity0;

        IntrConfiguration<Real> cfg;
        IntrAxis<Real>::GetConfiguration( mHalfspace->Normal, *mBox, cfg );

        if ( !IntrAxis<Real>::Test( mHalfspace->Normal, relVelocity,
                                    -Math<Real>::MAX_REAL, mHalfspace->Constant, cfg.mMin, cfg.mMax,
                                    tmax, mContactTime, tlast ) )
        {
            // Never intersecting.
            return false;
        }

        if ( mContactTime == ( Real )0 )
        {
            // Intersecting now.
            return false;
        }

        // Box on positive side (right).
        if ( cfg.mMap == IntrConfiguration<Real>::m1_1 )
        {
            // Point intersection.
            mQuantity = 1;
            mPoint[0] = GetPointFromIndex( cfg.mIndex[0], *mBox );
        }
        else if ( cfg.mMap == IntrConfiguration<Real>::m2_2 )
        {
            // Segment intersection.
            mQuantity = 2;
            mPoint[0] = GetPointFromIndex( cfg.mIndex[0], *mBox );
            mPoint[1] = GetPointFromIndex( cfg.mIndex[1], *mBox );
        }
        else // cfg.mMap == IntrConfiguration<Real>::m44
        {
            // Face intersection.
            mQuantity = 4;
            mPoint[0] = GetPointFromIndex( cfg.mIndex[0], *mBox );
            mPoint[1] = GetPointFromIndex( cfg.mIndex[1], *mBox );
            mPoint[2] = GetPointFromIndex( cfg.mIndex[2], *mBox );
            mPoint[3] = GetPointFromIndex( cfg.mIndex[3], *mBox );
        }

        // Adjust points to the correct place in time, as well.
        Vector3<Real> diff = mContactTime * velocity1;
        for ( int i = 0; i < mQuantity; ++i )
        {
            mPoint[i] += diff;
        }

        return true;
    }
DistanceChecker::DistanceChecker(const CenteredBox& box, const CenteredBox& map_size)
  : hitbox_(box), map_size_(map_size), cache_resolution_(10.0)
{
  cache_rows_front_ = static_cast<int>(map_size_.length_front * cache_resolution_);
  cache_rows_back_ = static_cast<int>(map_size_.length_back * cache_resolution_);
  cache_rows_ = cache_rows_front_ + cache_rows_back_;
  cache_cols_left_ = static_cast<int>(map_size_.width_left * cache_resolution_);
  cache_cols_right_ = static_cast<int>(map_size_.width_right * cache_resolution_);
  cache_cols_ = cache_cols_left_ + cache_cols_right_;

  auto cache_size = static_cast<size_t>(cache_rows_ * cache_cols_);
  cache_.resize(cache_size);
  cache_visited_.resize(cache_size);
  for (int i = 0; i < static_cast<int>(cache_size); i++) {
    cache_[i].location = GetPointFromIndex(i);
    cache_[i].might_hit_points.clear();
    cache_[i].nearest_point = nullptr;
    cache_visited_[i] = false;
  }

  double half_length = (hitbox_.length_front + hitbox_.length_back) / 2.;
  double half_width = (hitbox_.width_left + hitbox_.width_right) / 2.;
  hitbox_corner_dist_ = std::sqrt(half_length * half_length + half_width * half_width);
}