// 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;

/// 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 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 _r = Matrix3.zero();
  static final _absR = Matrix3.zero();
  static final _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();
  static final _aabb3 = Aabb3();
  static final _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 _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 _quadTriangle0 = Triangle();
  static final _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);
  }
}
