// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Ilya Baran <ibaran@mit.edu>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0

#include "main.h"
#include <Eigen/StdVector>
#include <Eigen/Geometry>
#include <contrib/Eigen/BVH>

namespace Eigen {

template <typename Scalar, int Dim>
AlignedBox<Scalar, Dim> bounding_box(const Matrix<Scalar, Dim, 1> &v) {
  return AlignedBox<Scalar, Dim>(v);
}

}  // namespace Eigen

template <int Dim>
struct Ball {
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(double, Dim)

  typedef Matrix<double, Dim, 1> VectorType;

  Ball() {}
  Ball(const VectorType &c, double r) : center(c), radius(r) {}

  VectorType center;
  double radius;
};
template <int Dim>
AlignedBox<double, Dim> bounding_box(const Ball<Dim> &b) {
  return AlignedBox<double, Dim>(b.center.array() - b.radius, b.center.array() + b.radius);
}

inline double SQR(double x) { return x * x; }

template <int Dim>
struct BallPointStuff  // this class provides functions to be both an intersector and a minimizer, both for a ball and a
                       // point and for two trees
{
  typedef double Scalar;
  typedef Matrix<double, Dim, 1> VectorType;
  typedef Ball<Dim> BallType;
  typedef AlignedBox<double, Dim> BoxType;

  BallPointStuff() : calls(0), count(0) {}
  BallPointStuff(const VectorType &inP) : p(inP), calls(0), count(0) {}

  bool intersectVolume(const BoxType &r) {
    ++calls;
    return r.contains(p);
  }
  bool intersectObject(const BallType &b) {
    ++calls;
    if ((b.center - p).squaredNorm() < SQR(b.radius)) ++count;
    return false;  // continue
  }

  bool intersectVolumeVolume(const BoxType &r1, const BoxType &r2) {
    ++calls;
    return !(r1.intersection(r2)).isNull();
  }
  bool intersectVolumeObject(const BoxType &r, const BallType &b) {
    ++calls;
    return r.squaredExteriorDistance(b.center) < SQR(b.radius);
  }
  bool intersectObjectVolume(const BallType &b, const BoxType &r) {
    ++calls;
    return r.squaredExteriorDistance(b.center) < SQR(b.radius);
  }
  bool intersectObjectObject(const BallType &b1, const BallType &b2) {
    ++calls;
    if ((b1.center - b2.center).norm() < b1.radius + b2.radius) ++count;
    return false;
  }
  bool intersectVolumeObject(const BoxType &r, const VectorType &v) {
    ++calls;
    return r.contains(v);
  }
  bool intersectObjectObject(const BallType &b, const VectorType &v) {
    ++calls;
    if ((b.center - v).squaredNorm() < SQR(b.radius)) ++count;
    return false;
  }

  double minimumOnVolume(const BoxType &r) {
    ++calls;
    return r.squaredExteriorDistance(p);
  }
  double minimumOnObject(const BallType &b) {
    ++calls;
    return (std::max)(0., (b.center - p).squaredNorm() - SQR(b.radius));
  }
  double minimumOnVolumeVolume(const BoxType &r1, const BoxType &r2) {
    ++calls;
    return r1.squaredExteriorDistance(r2);
  }
  double minimumOnVolumeObject(const BoxType &r, const BallType &b) {
    ++calls;
    return SQR((std::max)(0., r.exteriorDistance(b.center) - b.radius));
  }
  double minimumOnObjectVolume(const BallType &b, const BoxType &r) {
    ++calls;
    return SQR((std::max)(0., r.exteriorDistance(b.center) - b.radius));
  }
  double minimumOnObjectObject(const BallType &b1, const BallType &b2) {
    ++calls;
    return SQR((std::max)(0., (b1.center - b2.center).norm() - b1.radius - b2.radius));
  }
  double minimumOnVolumeObject(const BoxType &r, const VectorType &v) {
    ++calls;
    return r.squaredExteriorDistance(v);
  }
  double minimumOnObjectObject(const BallType &b, const VectorType &v) {
    ++calls;
    return SQR((std::max)(0., (b.center - v).norm() - b.radius));
  }

  VectorType p;
  int calls;
  int count;
};

template <int Dim>
struct TreeTest {
  typedef Matrix<double, Dim, 1> VectorType;
  typedef std::vector<VectorType, aligned_allocator<VectorType> > VectorTypeList;
  typedef Ball<Dim> BallType;
  typedef std::vector<BallType, aligned_allocator<BallType> > BallTypeList;
  typedef AlignedBox<double, Dim> BoxType;

  void testIntersect1() {
    BallTypeList b;
    for (int i = 0; i < 500; ++i) {
      b.push_back(BallType(VectorType::Random(), 0.5 * internal::random(0., 1.)));
    }
    KdBVH<double, Dim, BallType> tree(b.begin(), b.end());

    VectorType pt = VectorType::Random();
    BallPointStuff<Dim> i1(pt), i2(pt);

    for (int i = 0; i < (int)b.size(); ++i) i1.intersectObject(b[i]);

    BVIntersect(tree, i2);

    VERIFY(i1.count == i2.count);
  }

  void testMinimize1() {
    BallTypeList b;
    for (int i = 0; i < 500; ++i) {
      b.push_back(BallType(VectorType::Random(), 0.01 * internal::random(0., 1.)));
    }
    KdBVH<double, Dim, BallType> tree(b.begin(), b.end());

    VectorType pt = VectorType::Random();
    BallPointStuff<Dim> i1(pt), i2(pt);

    double m1 = (std::numeric_limits<double>::max)(), m2 = m1;

    for (int i = 0; i < (int)b.size(); ++i) m1 = (std::min)(m1, i1.minimumOnObject(b[i]));

    m2 = BVMinimize(tree, i2);

    VERIFY_IS_APPROX(m1, m2);
  }

  void testIntersect2() {
    BallTypeList b;
    VectorTypeList v;

    for (int i = 0; i < 50; ++i) {
      b.push_back(BallType(VectorType::Random(), 0.5 * internal::random(0., 1.)));
      for (int j = 0; j < 3; ++j) v.push_back(VectorType::Random());
    }

    KdBVH<double, Dim, BallType> tree(b.begin(), b.end());
    KdBVH<double, Dim, VectorType> vTree(v.begin(), v.end());

    BallPointStuff<Dim> i1, i2;

    for (int i = 0; i < (int)b.size(); ++i)
      for (int j = 0; j < (int)v.size(); ++j) i1.intersectObjectObject(b[i], v[j]);

    BVIntersect(tree, vTree, i2);

    VERIFY(i1.count == i2.count);
  }

  void testMinimize2() {
    BallTypeList b;
    VectorTypeList v;

    for (int i = 0; i < 50; ++i) {
      b.push_back(BallType(VectorType::Random(), 1e-7 + 1e-6 * internal::random(0., 1.)));
      for (int j = 0; j < 3; ++j) v.push_back(VectorType::Random());
    }

    KdBVH<double, Dim, BallType> tree(b.begin(), b.end());
    KdBVH<double, Dim, VectorType> vTree(v.begin(), v.end());

    BallPointStuff<Dim> i1, i2;

    double m1 = (std::numeric_limits<double>::max)(), m2 = m1;

    for (int i = 0; i < (int)b.size(); ++i)
      for (int j = 0; j < (int)v.size(); ++j) m1 = (std::min)(m1, i1.minimumOnObjectObject(b[i], v[j]));

    m2 = BVMinimize(tree, vTree, i2);

    VERIFY_IS_APPROX(m1, m2);
  }
};

EIGEN_DECLARE_TEST(BVH) {
  for (int i = 0; i < g_repeat; i++) {
#ifdef EIGEN_TEST_PART_1
    TreeTest<2> test2;
    CALL_SUBTEST(test2.testIntersect1());
    CALL_SUBTEST(test2.testMinimize1());
    CALL_SUBTEST(test2.testIntersect2());
    CALL_SUBTEST(test2.testMinimize2());
#endif

#ifdef EIGEN_TEST_PART_2
    TreeTest<3> test3;
    CALL_SUBTEST(test3.testIntersect1());
    CALL_SUBTEST(test3.testMinimize1());
    CALL_SUBTEST(test3.testIntersect2());
    CALL_SUBTEST(test3.testMinimize2());
#endif

#ifdef EIGEN_TEST_PART_3
    TreeTest<4> test4;
    CALL_SUBTEST(test4.testIntersect1());
    CALL_SUBTEST(test4.testMinimize1());
    CALL_SUBTEST(test4.testIntersect2());
    CALL_SUBTEST(test4.testMinimize2());
#endif
  }
}
