// Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
part of vector_math_64;

/// Defines a 3-dimensional oriented bounding box defined with a [center],
/// [halfExtents] and axes.
class Obb3 {
  final Vector3 _center;
  final Vector3 _halfExtents;
  final Vector3 _axis0;
  final Vector3 _axis1;
  final Vector3 _axis2;

  /// The center of the OBB.
  Vector3 get center => _center;

  /// The half extends of the OBB.
  Vector3 get halfExtents => _halfExtents;

  /// The first axis of the OBB.
  Vector3 get axis0 => _axis0;

  /// The second axis of the OBB.
  Vector3 get axis1 => _axis1;

  /// The third axis of the OBB.
  Vector3 get axis2 => _axis2;

  /// Create a new OBB with erverything set to zero.
  Obb3()
      : _center = Vector3.zero(),
        _halfExtents = Vector3.zero(),
        _axis0 = Vector3(1.0, 0.0, 0.0),
        _axis1 = Vector3(0.0, 1.0, 0.0),
        _axis2 = Vector3(0.0, 0.0, 1.0);

  /// Create a new OBB as a copy of [other].
  Obb3.copy(Obb3 other)
      : _center = Vector3.copy(other._center),
        _halfExtents = Vector3.copy(other._halfExtents),
        _axis0 = Vector3.copy(other._axis0),
        _axis1 = Vector3.copy(other._axis1),
        _axis2 = Vector3.copy(other._axis2);

  /// Create a new OBB using [center], [halfExtents] and axis.
  Obb3.centerExtentsAxes(Vector3 center, Vector3 halfExtents, Vector3 axis0,
      Vector3 axis1, Vector3 axis2)
      : _center = Vector3.copy(center),
        _halfExtents = Vector3.copy(halfExtents),
        _axis0 = Vector3.copy(axis0),
        _axis1 = Vector3.copy(axis1),
        _axis2 = Vector3.copy(axis2);

  /// Copy from [other] into this.
  void copyFrom(Obb3 other) {
    _center.setFrom(other._center);
    _halfExtents.setFrom(other._halfExtents);
    _axis0.setFrom(other._axis0);
    _axis1.setFrom(other._axis1);
    _axis2.setFrom(other._axis2);
  }

  /// Copy from this into [other].
  void copyInto(Obb3 other) {
    other._center.setFrom(_center);
    other._halfExtents.setFrom(_halfExtents);
    other._axis0.setFrom(_axis0);
    other._axis1.setFrom(_axis1);
    other._axis2.setFrom(_axis2);
  }

  /// Reset the rotation of this.
  void resetRotation() {
    _axis0.setValues(1.0, 0.0, 0.0);
    _axis1.setValues(0.0, 1.0, 0.0);
    _axis2.setValues(0.0, 0.0, 1.0);
  }

  /// Translate this by [offset].
  void translate(Vector3 offset) {
    _center.add(offset);
  }

  /// Rotate this by the rotation matrix [t].
  void rotate(Matrix3 t) {
    t
      ..transform(_axis0..scale(_halfExtents.x))
      ..transform(_axis1..scale(_halfExtents.y))
      ..transform(_axis2..scale(_halfExtents.z));

    _halfExtents
      ..x = _axis0.normalize()
      ..y = _axis1.normalize()
      ..z = _axis2.normalize();
  }

  /// Transform this by the transform [t].
  void transform(Matrix4 t) {
    t
      ..transform3(_center)
      ..rotate3(_axis0..scale(_halfExtents.x))
      ..rotate3(_axis1..scale(_halfExtents.y))
      ..rotate3(_axis2..scale(_halfExtents.z));

    _halfExtents
      ..x = _axis0.normalize()
      ..y = _axis1.normalize()
      ..z = _axis2.normalize();
  }

  /// Store the corner with [cornerIndex] in [corner].
  void copyCorner(int cornerIndex, Vector3 corner) {
    assert(cornerIndex >= 0 || cornerIndex < 8);

    corner.setFrom(_center);

    switch (cornerIndex) {
      case 0:
        corner
          ..addScaled(_axis0, -_halfExtents.x)
          ..addScaled(_axis1, -_halfExtents.y)
          ..addScaled(_axis2, -_halfExtents.z);
        break;
      case 1:
        corner
          ..addScaled(_axis0, -_halfExtents.x)
          ..addScaled(_axis1, -_halfExtents.y)
          ..addScaled(_axis2, _halfExtents.z);
        break;
      case 2:
        corner
          ..addScaled(_axis0, -_halfExtents.x)
          ..addScaled(_axis1, _halfExtents.y)
          ..addScaled(_axis2, -_halfExtents.z);
        break;
      case 3:
        corner
          ..addScaled(_axis0, -_halfExtents.x)
          ..addScaled(_axis1, _halfExtents.y)
          ..addScaled(_axis2, _halfExtents.z);
        break;
      case 4:
        corner
          ..addScaled(_axis0, _halfExtents.x)
          ..addScaled(_axis1, -_halfExtents.y)
          ..addScaled(_axis2, -_halfExtents.z);
        break;
      case 5:
        corner
          ..addScaled(_axis0, _halfExtents.x)
          ..addScaled(_axis1, -_halfExtents.y)
          ..addScaled(_axis2, _halfExtents.z);
        break;
      case 6:
        corner
          ..addScaled(_axis0, _halfExtents.x)
          ..addScaled(_axis1, _halfExtents.y)
          ..addScaled(_axis2, -_halfExtents.z);
        break;
      case 7:
        corner
          ..addScaled(_axis0, _halfExtents.x)
          ..addScaled(_axis1, _halfExtents.y)
          ..addScaled(_axis2, _halfExtents.z);
        break;
    }
  }

  /// Find the closest point [q] on the OBB to the point [p] and store it in [q].
  void closestPointTo(Vector3 p, Vector3 q) {
    final Vector3 d = p - _center;

    q.setFrom(_center);

    var dist = d.dot(_axis0);
    dist = dist.clamp(-_halfExtents.x, _halfExtents.x).toDouble();
    q.addScaled(_axis0, dist);

    dist = d.dot(_axis1);
    dist = dist.clamp(-_halfExtents.y, _halfExtents.y).toDouble();
    q.addScaled(_axis1, dist);

    dist = d.dot(_axis2);
    dist = dist.clamp(-_halfExtents.z, _halfExtents.z).toDouble();
    q.addScaled(_axis2, dist);
  }

  // Avoid allocating these instance on every call to intersectsWithObb3
  static final Matrix3 _r = Matrix3.zero();
  static final Matrix3 _absR = Matrix3.zero();
  static final Vector3 _t = Vector3.zero();

  /// Check for intersection between this and [other].
  bool intersectsWithObb3(Obb3 other, [double epsilon = 1e-3]) {
    // Compute rotation matrix expressing other in this's coordinate frame
    _r
      ..setEntry(0, 0, _axis0.dot(other._axis0))
      ..setEntry(1, 0, _axis1.dot(other._axis0))
      ..setEntry(2, 0, _axis2.dot(other._axis0))
      ..setEntry(0, 1, _axis0.dot(other._axis1))
      ..setEntry(1, 1, _axis1.dot(other._axis1))
      ..setEntry(2, 1, _axis2.dot(other._axis1))
      ..setEntry(0, 2, _axis0.dot(other._axis2))
      ..setEntry(1, 2, _axis1.dot(other._axis2))
      ..setEntry(2, 2, _axis2.dot(other._axis2));

    // Compute translation vector t
    _t
      ..setFrom(other._center)
      ..sub(_center);

    // Bring translation into this's coordinate frame
    _t.setValues(_t.dot(_axis0), _t.dot(_axis1), _t.dot(_axis2));

    // Compute common subexpressions. Add in an epsilon term to
    // counteract arithmetic errors when two edges are parallel and
    // their cross product is (near) null.
    for (var i = 0; i < 3; i++) {
      for (var j = 0; j < 3; j++) {
        _absR.setEntry(i, j, _r.entry(i, j).abs() + epsilon);
      }
    }

    double ra;
    double rb;

    // Test axes L = A0, L = A1, L = A2
    for (var i = 0; i < 3; i++) {
      ra = _halfExtents[i];
      rb = other._halfExtents[0] * _absR.entry(i, 0) +
          other._halfExtents[1] * _absR.entry(i, 1) +
          other._halfExtents[2] * _absR.entry(i, 2);

      if (_t[i].abs() > ra + rb) {
        return false;
      }
    }

    // Test axes L = B0, L = B1, L = B2
    for (var i = 0; i < 3; i++) {
      ra = _halfExtents[0] * _absR.entry(0, i) +
          _halfExtents[1] * _absR.entry(1, i) +
          _halfExtents[2] * _absR.entry(2, i);
      rb = other._halfExtents[i];

      if ((_t[0] * _r.entry(0, i) +
                  _t[1] * _r.entry(1, i) +
                  _t[2] * _r.entry(2, i))
              .abs() >
          ra + rb) {
        return false;
      }
    }

    // Test axis L = A0 x B0
    ra = _halfExtents[1] * _absR.entry(2, 0) +
        _halfExtents[2] * _absR.entry(1, 0);
    rb = other._halfExtents[1] * _absR.entry(0, 2) +
        other._halfExtents[2] * _absR.entry(0, 1);
    if ((_t[2] * _r.entry(1, 0) - _t[1] * _r.entry(2, 0)).abs() > ra + rb) {
      return false;
    }

    // Test axis L = A0 x B1
    ra = _halfExtents[1] * _absR.entry(2, 1) +
        _halfExtents[2] * _absR.entry(1, 1);
    rb = other._halfExtents[0] * _absR.entry(0, 2) +
        other._halfExtents[2] * _absR.entry(0, 0);
    if ((_t[2] * _r.entry(1, 1) - _t[1] * _r.entry(2, 1)).abs() > ra + rb) {
      return false;
    }

    // Test axis L = A0 x B2
    ra = _halfExtents[1] * _absR.entry(2, 2) +
        _halfExtents[2] * _absR.entry(1, 2);
    rb = other._halfExtents[0] * _absR.entry(0, 1) +
        other._halfExtents[1] * _absR.entry(0, 0);
    if ((_t[2] * _r.entry(1, 2) - _t[1] * _r.entry(2, 2)).abs() > ra + rb) {
      return false;
    }

    // Test axis L = A1 x B0
    ra = _halfExtents[0] * _absR.entry(2, 0) +
        _halfExtents[2] * _absR.entry(0, 0);
    rb = other._halfExtents[1] * _absR.entry(1, 2) +
        other._halfExtents[2] * _absR.entry(1, 1);
    if ((_t[0] * _r.entry(2, 0) - _t[2] * _r.entry(0, 0)).abs() > ra + rb) {
      return false;
    }

    // Test axis L = A1 x B1
    ra = _halfExtents[0] * _absR.entry(2, 1) +
        _halfExtents[2] * _absR.entry(0, 1);
    rb = other._halfExtents[0] * _absR.entry(1, 2) +
        other._halfExtents[2] * _absR.entry(1, 0);
    if ((_t[0] * _r.entry(2, 1) - _t[2] * _r.entry(0, 1)).abs() > ra + rb) {
      return false;
    }

    // Test axis L = A1 x B2
    ra = _halfExtents[0] * _absR.entry(2, 2) +
        _halfExtents[2] * _absR.entry(0, 2);
    rb = other._halfExtents[0] * _absR.entry(1, 1) +
        other._halfExtents[1] * _absR.entry(1, 0);
    if ((_t[0] * _r.entry(2, 2) - _t[2] * _r.entry(0, 2)).abs() > ra + rb) {
      return false;
    }

    // Test axis L = A2 x B0
    ra = _halfExtents[0] * _absR.entry(1, 0) +
        _halfExtents[1] * _absR.entry(0, 0);
    rb = other._halfExtents[1] * _absR.entry(2, 2) +
        other._halfExtents[2] * _absR.entry(2, 1);
    if ((_t[1] * _r.entry(0, 0) - _t[0] * _r.entry(1, 0)).abs() > ra + rb) {
      return false;
    }

    // Test axis L = A2 x B1
    ra = _halfExtents[0] * _absR.entry(1, 1) +
        _halfExtents[1] * _absR.entry(0, 1);
    rb = other._halfExtents[0] * _absR.entry(2, 2) +
        other._halfExtents[2] * _absR.entry(2, 0);
    if ((_t[1] * _r.entry(0, 1) - _t[0] * _r.entry(1, 1)).abs() > ra + rb) {
      return false;
    }

    // Test axis L = A2 x B2
    ra = _halfExtents[0] * _absR.entry(1, 2) +
        _halfExtents[1] * _absR.entry(0, 2);
    rb = other._halfExtents[0] * _absR.entry(2, 1) +
        other._halfExtents[1] * _absR.entry(2, 0);
    if ((_t[1] * _r.entry(0, 2) - _t[0] * _r.entry(1, 2)).abs() > ra + rb) {
      return false;
    }

    // Since no separating axis is found, the OBBs must be intersecting
    return true;
  }

  // Avoid allocating these instance on every call to intersectsWithTriangle
  static final Triangle _triangle = Triangle();
  static final Aabb3 _aabb3 = Aabb3();
  static final Vector3 _zeroVector = Vector3.zero();

  /// Return if this intersects with [other]
  bool intersectsWithTriangle(Triangle other, {IntersectionResult result}) {
    _triangle.copyFrom(other);

    _triangle.point0
      ..sub(_center)
      ..setValues(_triangle.point0.dot(axis0), _triangle.point0.dot(axis1),
          _triangle.point0.dot(axis2));
    _triangle.point1
      ..sub(_center)
      ..setValues(_triangle.point1.dot(axis0), _triangle.point1.dot(axis1),
          _triangle.point1.dot(axis2));
    _triangle.point2
      ..sub(_center)
      ..setValues(_triangle.point2.dot(axis0), _triangle.point2.dot(axis1),
          _triangle.point2.dot(axis2));

    _aabb3.setCenterAndHalfExtents(_zeroVector, _halfExtents);

    return _aabb3.intersectsWithTriangle(_triangle, result: result);
  }

  // Avoid allocating these instance on every call to intersectsWithVector3
  static final Vector3 _vector = Vector3.zero();

  /// Return if this intersects with [other]
  bool intersectsWithVector3(Vector3 other) {
    _vector
      ..setFrom(other)
      ..sub(_center)
      ..setValues(_vector.dot(axis0), _vector.dot(axis1), _vector.dot(axis2));

    _aabb3.setCenterAndHalfExtents(_zeroVector, _halfExtents);

    return _aabb3.intersectsWithVector3(_vector);
  }

  // Avoid allocating these instance on every call to intersectsWithTriangle
  static final Triangle _quadTriangle0 = Triangle();
  static final Triangle _quadTriangle1 = Triangle();

  /// Return if this intersects with [other]
  bool intersectsWithQuad(Quad other, {IntersectionResult result}) {
    other.copyTriangles(_quadTriangle0, _quadTriangle1);

    return intersectsWithTriangle(_quadTriangle0, result: result) ||
        intersectsWithTriangle(_quadTriangle1, result: result);
  }
}
