"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 THREE = _interopRequireWildcard(require("three"));
var _OrientedImageCamera = _interopRequireDefault(require("../Renderer/OrientedImageCamera"));
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; }
/**
 * The CameraCalibrationParser module provide a [parse]{@link module:CameraCalibrationParser.parse}
 * method that takes a JSON array of camera calibrations in and yields an array of {@link OrientedImageCamera}
 *
 * @module CameraCalibrationParser
 */

var textureLoader = new THREE.TextureLoader();
var matrix3 = new THREE.Matrix3();

// the json format encodes the following transformation:
// extrinsics: p_local = rotation * (p_world - position)
// intrinsics: p_pixel = projection * p_local
// distortion: p_raw = distortion(p_pixel)
function parseCalibration(calibration) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var useMask = options.useMask == undefined ? true : options.useMask;
  var imageYDown = options.imageYDown == undefined ? true : options.imageYDown;
  // parse intrinsics
  var proj = calibration.projection;
  var size = new THREE.Vector2().fromArray(calibration.size);
  var focal = new THREE.Vector2(proj[0], proj[4]);
  // Center of image,  convention in digital image is Y dow
  // To transform image space to webGl texture. It could inverse Y axis.
  var center = new THREE.Vector2(proj[2], imageYDown ? size.y - proj[5] : proj[5]);
  var skew = proj[1];
  var camera = new _OrientedImageCamera["default"](size, focal, center, options.near, options.far, skew);

  // parse extrinsics: Object3d.matrix is from local to world
  // p_world = position + transpose(rotation) * p_local
  camera.position.fromArray(calibration.position);
  // calibration.rotation is row-major but fromArray expects a column-major array, yielding the transposed matrix
  var rotationInverse = matrix3.fromArray(calibration.rotation);
  camera.matrix.setFromMatrix3(rotationInverse);
  camera.quaternion.setFromRotationMatrix(camera.matrix);

  // local axes for cameras is (X right, Y up, Z back) rather than (X right, Y down, Z front)
  camera.rotateX(Math.PI);
  if (calibration.distortion) {
    camera.distortion.setFromMicmacCalibration(calibration.distortion, imageYDown);
  }
  camera.maskPath = calibration.mask;
  camera.name = calibration.id;
  var resolve;
  var deferred = new Promise(function (r) {
    resolve = r;
  });
  if (useMask && camera.maskPath) {
    textureLoader.load(camera.maskPath, function (mask) {
      camera.maskTexture = mask;
      resolve(camera);
    });
  } else {
    resolve(camera);
  }
  return deferred;
}
var _default = {
  /**
   * Description of a camera calibration in a JSON file.
   *
   * @typedef CameraCalibrationJson
   * @type {Object}
   *
   * @property {number[]} projection - projection matrix,
   * @property {number[]} size - image size in pixel.
   * @property {number[]} position - position of the camera.
   * @property {number[]} rotation - rotation matrix
   * @property {Object} [distorsion={}] - distorsion
   * @property {number[]} [distorsion.pps]
   * @property {number[]} [distorsion.poly357]
   * @property {number[]} [distorsion.limit]
   * @property {number[]} [distorsion.l1l2]
   * @property {number[]} [distorsion.etat]
   */
  /**
   * Parser a JSON array of camera calibrations and return an array of {@link OrientedImageCamera}.
   * @param {string|JSON} json - the json content of the calibration file.
   * @param {Object} [options={}] - Options controlling the parsing.
   * @param {string} [options.near=0.1] - Near of the created cameras. Default value comes from created {@link OrientedImageCamera}
   * @param {string} [options.far=1000] - Far of the created cameras. Default value comes from created {@link OrientedImageCamera}
   * @return {Promise} - A promise resolving with an array of {@link OrientedImageCamera}.
   */
  parse: function parse(json) {
    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    if (typeof json === 'string') {
      json = JSON.parse(json);
    }
    return Promise.all(json.map(function (calibration) {
      return parseCalibration(calibration, options);
    }));
  }
};
exports["default"] = _default;