"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var THREE = _interopRequireWildcard(require("three"));
var _Coordinates = _interopRequireDefault(require("../../Geographic/Coordinates"));
var _Extent = _interopRequireDefault(require("../../Geographic/Extent"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
var PI_OV_FOUR = Math.PI / 4;
var INV_TWO_PI = 1.0 / (Math.PI * 2);
var axisZ = new THREE.Vector3(0, 0, 1);
var axisY = new THREE.Vector3(0, 1, 0);
var quatToAlignLongitude = new THREE.Quaternion();
var quatToAlignLatitude = new THREE.Quaternion();
var quatNormalToZ = new THREE.Quaternion();
function WGS84ToOneSubY(latitude) {
  return 1.0 - (0.5 - Math.log(Math.tan(PI_OV_FOUR + THREE.MathUtils.degToRad(latitude) * 0.5)) * INV_TWO_PI);
}
var BuilderEllipsoidTile = /*#__PURE__*/function () {
  function BuilderEllipsoidTile() {
    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    (0, _classCallCheck2["default"])(this, BuilderEllipsoidTile);
    this.tmp = {
      coords: [new _Coordinates["default"]('EPSG:4326', 0, 0), new _Coordinates["default"]('EPSG:4326', 0, 0)],
      position: new THREE.Vector3(),
      dimension: new THREE.Vector2()
    };
    this.crs = options.crs;
    // Order crs projection on tiles
    this.uvCount = options.uvCount;
    this.computeUvs = [
    // Normalized coordinates (from degree) on the entire tile
    // EPSG:4326
    function () {},
    // Float row coordinate from Pseudo mercator coordinates
    // EPSG:3857
    function (params) {
      var t = WGS84ToOneSubY(params.projected.latitude) * params.nbRow;
      return (!isFinite(t) ? 0 : t) - params.deltaUV1;
    }];
  }
  // prepare params
  // init projected object -> params.projected
  (0, _createClass2["default"])(BuilderEllipsoidTile, [{
    key: "prepare",
    value: function prepare(params) {
      params.nbRow = Math.pow(2, params.level + 1.0);
      var st1 = WGS84ToOneSubY(params.extent.south);
      if (!isFinite(st1)) {
        st1 = 0;
      }
      var sizeTexture = 1.0 / params.nbRow;
      var start = st1 % sizeTexture;
      params.deltaUV1 = (st1 - start) * params.nbRow;

      // transformation to align tile's normal to z axis
      params.quatNormalToZ = quatNormalToZ.setFromAxisAngle(axisY, -(Math.PI * 0.5 - THREE.MathUtils.degToRad(params.extent.center().latitude)));

      // let's avoid building too much temp objects
      params.projected = {
        longitude: 0,
        latitude: 0
      };
      params.extent.planarDimensions(this.tmp.dimension);
    }

    // get center tile in cartesian 3D
  }, {
    key: "center",
    value: function center(extent) {
      return extent.center(this.tmp.coords[0]).as(this.crs, this.tmp.coords[1]).toVector3();
    }

    // get position 3D cartesian
  }, {
    key: "vertexPosition",
    value: function vertexPosition(params) {
      this.tmp.coords[0].setFromValues(params.projected.longitude, params.projected.latitude);
      this.tmp.coords[0].as(this.crs, this.tmp.coords[1]).toVector3(this.tmp.position);
      return this.tmp.position;
    }

    // get normal for last vertex
  }, {
    key: "vertexNormal",
    value: function vertexNormal() {
      return this.tmp.coords[1].geodesicNormal;
    }

    // coord u tile to projected
  }, {
    key: "uProjecte",
    value: function uProjecte(u, params) {
      params.projected.longitude = params.extent.west + u * this.tmp.dimension.x;
    }

    // coord v tile to projected
  }, {
    key: "vProjecte",
    value: function vProjecte(v, params) {
      params.projected.latitude = params.extent.south + v * this.tmp.dimension.y;
    }
  }, {
    key: "computeSharableExtent",
    value: function computeSharableExtent(extent) {
      // Compute sharable extent to pool the geometries
      // the geometry in common extent is identical to the existing input
      // with a transformation (translation, rotation)

      // TODO: It should be possible to use equatorial plan symetrie,
      // but we should be reverse UV on tile
      // Common geometry is looking for only on longitude
      var sizeLongitude = Math.abs(extent.west - extent.east) / 2;
      var sharableExtent = new _Extent["default"](extent.crs, -sizeLongitude, sizeLongitude, extent.south, extent.north);

      // compute rotation to transform tile to position it on ellipsoid
      // this transformation take into account the transformation of the parents
      var rotLon = THREE.MathUtils.degToRad(extent.west - sharableExtent.west);
      var rotLat = THREE.MathUtils.degToRad(90 - extent.center(this.tmp.coords[0]).latitude);
      quatToAlignLongitude.setFromAxisAngle(axisZ, rotLon);
      quatToAlignLatitude.setFromAxisAngle(axisY, rotLat);
      quatToAlignLongitude.multiply(quatToAlignLatitude);
      return {
        sharableExtent: sharableExtent,
        quaternion: quatToAlignLongitude.clone(),
        position: this.center(extent)
      };
    }
  }]);
  return BuilderEllipsoidTile;
}();
var _default = BuilderEllipsoidTile;
exports["default"] = _default;