var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

import Viewport from './viewport';
// import log from '../utils/log';

import { createMat4, transformVector } from '../utils/math-utils';

import mat4_multiply from 'gl-mat4/multiply';
import mat4_lookAt from 'gl-mat4/lookAt';
import mat4_scale from 'gl-mat4/scale';
import mat4_perspective from 'gl-mat4/perspective';
import mat4_translate from 'gl-mat4/translate';
import mat4_rotateX from 'gl-mat4/rotateX';
import mat4_rotateY from 'gl-mat4/rotateY';
import mat4_rotateZ from 'gl-mat4/rotateZ';

const DEGREES_TO_RADIANS = Math.PI / 180;

/*
 * A deck.gl Viewport class used by OrbitController
 * Adds zoom and pixel translation on top of the PerspectiveViewport
 */
export default class OrbitViewport extends Viewport {
  constructor({
    id = 'orbit-viewport',
    // viewport arguments
    width, // Width of viewport
    height, // Height of viewport
    // view matrix arguments
    distance, // From eye position to lookAt
    rotationX = 0, // Rotating angle around X axis
    rotationOrbit = 0, // Rotating angle around orbit axis
    orbitAxis = 'Z', // Orbit axis with 360 degrees rotating freedom, can only be 'Y' or 'Z'
    lookAt = [0, 0, 0], // Which point is camera looking at, default origin
    up = [0, 1, 0], // Defines up direction, default positive y axis
    // projection matrix arguments
    fov = 75, // Field of view covered by camera
    near = 1, // Distance of near clipping plane
    far = 100, // Distance of far clipping plane
    zoom = 1
  }) {
    // TODO - Once OrbitViewport is aligned with the View system, deprecated it
    // log.deprecated('OrbitViewport', 'OrbitView')();

    const rotationMatrix = mat4_rotateX([], createMat4(), -rotationX / 180 * Math.PI);
    if (orbitAxis === 'Z') {
      mat4_rotateZ(rotationMatrix, rotationMatrix, -rotationOrbit / 180 * Math.PI);
    } else {
      mat4_rotateY(rotationMatrix, rotationMatrix, -rotationOrbit / 180 * Math.PI);
    }

    const translateMatrix = createMat4();
    mat4_scale(translateMatrix, translateMatrix, [zoom, zoom, zoom]);
    mat4_translate(translateMatrix, translateMatrix, [-lookAt[0], -lookAt[1], -lookAt[2]]);

    const viewMatrix = mat4_lookAt([], [0, 0, distance], [0, 0, 0], up);
    const fovRadians = fov * DEGREES_TO_RADIANS;
    const aspect = width / height;
    const perspectiveMatrix = mat4_perspective([], fovRadians, aspect, near, far);

    super({
      id,
      viewMatrix: mat4_multiply(viewMatrix, viewMatrix, mat4_multiply(rotationMatrix, rotationMatrix, translateMatrix)),
      projectionMatrix: perspectiveMatrix,
      width,
      height
    });

    this.width = width;
    this.height = height;
    this.distance = distance;
    this.rotationX = rotationX;
    this.rotationOrbit = rotationOrbit;
    this.orbitAxis = orbitAxis;
    this.lookAt = lookAt;
    this.up = up;
    this.fov = fov;
    this.near = near;
    this.far = far;
    this.zoom = zoom;
  }

  project(xyz, { topLeft = false } = {}) {
    const v = transformVector(this.pixelProjectionMatrix, [...xyz, 1]);

    var _v = _slicedToArray(v, 3);

    const x = _v[0],
          y = _v[1],
          z = _v[2];

    const y2 = topLeft ? this.height - y : y;
    return [x, y2, z];
  }

  unproject(xyz, { topLeft = false } = {}) {
    var _xyz = _slicedToArray(xyz, 3);

    const x = _xyz[0],
          y = _xyz[1],
          z = _xyz[2];

    const y2 = topLeft ? this.height - y : y;

    return transformVector(this.pixelUnprojectionMatrix, [x, y2, z, 1]);
  }

  /** Move camera to make a model bounding box centered at lookat position fit in the viewport.
   * @param {Array} sizes - [sizeX, sizeY, sizeZ]], define the dimensions of bounding box
   * @returns a new OrbitViewport object
   */
  fitBounds(sizes) {
    const width = this.width,
          height = this.height,
          rotationX = this.rotationX,
          rotationOrbit = this.rotationOrbit,
          orbitAxis = this.orbitAxis,
          lookAt = this.lookAt,
          up = this.up,
          fov = this.fov,
          near = this.near,
          far = this.far,
          zoom = this.zoom;

    const size = Math.max(sizes[0], sizes[1], sizes[2]) / 2;
    const newDistance = size / Math.tan(fov / 180 * Math.PI / 2);

    return new OrbitViewport({
      width,
      height,
      rotationX,
      rotationOrbit,
      orbitAxis,
      up,
      fov,
      near,
      far,
      zoom,
      lookAt,
      distance: newDistance
    });
  }
}

OrbitViewport.displayName = 'OrbitViewport';
//# sourceMappingURL=orbit-viewport.js.map