"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getOffsetOrigin = getOffsetOrigin;
exports.getUniformsFromViewport = getUniformsFromViewport;

var _core = require("@math.gl/core");

var _constants = require("../../lib/constants");

var _memoize = _interopRequireDefault(require("../../utils/memoize"));

var ZERO_VECTOR = [0, 0, 0, 0];
var VECTOR_TO_POINT_MATRIX = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0];
var IDENTITY_MATRIX = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
var DEFAULT_PIXELS_PER_UNIT2 = [0, 0, 0];
var DEFAULT_COORDINATE_ORIGIN = [0, 0, 0];
var getMemoizedViewportUniforms = (0, _memoize.default)(calculateViewportUniforms);

function getOffsetOrigin(viewport, coordinateSystem) {
  var coordinateOrigin = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_COORDINATE_ORIGIN;

  if (coordinateOrigin.length < 3) {
    coordinateOrigin = [coordinateOrigin[0], coordinateOrigin[1], 0];
  }

  var shaderCoordinateOrigin = coordinateOrigin;
  var geospatialOrigin;
  var offsetMode = true;

  if (coordinateSystem === _constants.COORDINATE_SYSTEM.LNGLAT_OFFSETS || coordinateSystem === _constants.COORDINATE_SYSTEM.METER_OFFSETS) {
    geospatialOrigin = coordinateOrigin;
  } else {
    geospatialOrigin = viewport.isGeospatial ? [Math.fround(viewport.longitude), Math.fround(viewport.latitude), 0] : null;
  }

  switch (viewport.projectionMode) {
    case _constants.PROJECTION_MODE.WEB_MERCATOR:
      if (coordinateSystem === _constants.COORDINATE_SYSTEM.LNGLAT || coordinateSystem === _constants.COORDINATE_SYSTEM.CARTESIAN) {
        geospatialOrigin = [0, 0, 0];
        offsetMode = false;
      }

      break;

    case _constants.PROJECTION_MODE.WEB_MERCATOR_AUTO_OFFSET:
      if (coordinateSystem === _constants.COORDINATE_SYSTEM.LNGLAT) {
        shaderCoordinateOrigin = geospatialOrigin;
      } else if (coordinateSystem === _constants.COORDINATE_SYSTEM.CARTESIAN) {
        shaderCoordinateOrigin = [Math.fround(viewport.center[0]), Math.fround(viewport.center[1]), 0];
        geospatialOrigin = viewport.unprojectPosition(shaderCoordinateOrigin);
        shaderCoordinateOrigin[0] -= coordinateOrigin[0];
        shaderCoordinateOrigin[1] -= coordinateOrigin[1];
        shaderCoordinateOrigin[2] -= coordinateOrigin[2];
      }

      break;

    case _constants.PROJECTION_MODE.IDENTITY:
      shaderCoordinateOrigin = viewport.position.map(Math.fround);
      shaderCoordinateOrigin[2] = shaderCoordinateOrigin[2] || 0;
      break;

    case _constants.PROJECTION_MODE.GLOBE:
      offsetMode = false;
      geospatialOrigin = null;
      break;

    default:
      offsetMode = false;
  }

  return {
    geospatialOrigin: geospatialOrigin,
    shaderCoordinateOrigin: shaderCoordinateOrigin,
    offsetMode: offsetMode
  };
}

function calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin) {
  var viewMatrixUncentered = viewport.viewMatrixUncentered,
      projectionMatrix = viewport.projectionMatrix;
  var viewMatrix = viewport.viewMatrix,
      viewProjectionMatrix = viewport.viewProjectionMatrix;
  var projectionCenter = ZERO_VECTOR;
  var originCommon = ZERO_VECTOR;
  var cameraPosCommon = viewport.cameraPosition;

  var _getOffsetOrigin = getOffsetOrigin(viewport, coordinateSystem, coordinateOrigin),
      geospatialOrigin = _getOffsetOrigin.geospatialOrigin,
      shaderCoordinateOrigin = _getOffsetOrigin.shaderCoordinateOrigin,
      offsetMode = _getOffsetOrigin.offsetMode;

  if (offsetMode) {
    originCommon = viewport.projectPosition(geospatialOrigin || shaderCoordinateOrigin);
    cameraPosCommon = [cameraPosCommon[0] - originCommon[0], cameraPosCommon[1] - originCommon[1], cameraPosCommon[2] - originCommon[2]];
    originCommon[3] = 1;
    projectionCenter = _core.vec4.transformMat4([], originCommon, viewProjectionMatrix);
    viewMatrix = viewMatrixUncentered || viewMatrix;
    viewProjectionMatrix = _core.mat4.multiply([], projectionMatrix, viewMatrix);
    viewProjectionMatrix = _core.mat4.multiply([], viewProjectionMatrix, VECTOR_TO_POINT_MATRIX);
  }

  return {
    viewMatrix: viewMatrix,
    viewProjectionMatrix: viewProjectionMatrix,
    projectionCenter: projectionCenter,
    originCommon: originCommon,
    cameraPosCommon: cameraPosCommon,
    shaderCoordinateOrigin: shaderCoordinateOrigin,
    geospatialOrigin: geospatialOrigin
  };
}

function getUniformsFromViewport(_ref) {
  var viewport = _ref.viewport,
      _ref$devicePixelRatio = _ref.devicePixelRatio,
      devicePixelRatio = _ref$devicePixelRatio === void 0 ? 1 : _ref$devicePixelRatio,
      _ref$modelMatrix = _ref.modelMatrix,
      modelMatrix = _ref$modelMatrix === void 0 ? null : _ref$modelMatrix,
      _ref$coordinateSystem = _ref.coordinateSystem,
      coordinateSystem = _ref$coordinateSystem === void 0 ? _constants.COORDINATE_SYSTEM.DEFAULT : _ref$coordinateSystem,
      _ref$coordinateOrigin = _ref.coordinateOrigin,
      coordinateOrigin = _ref$coordinateOrigin === void 0 ? DEFAULT_COORDINATE_ORIGIN : _ref$coordinateOrigin,
      _ref$autoWrapLongitud = _ref.autoWrapLongitude,
      autoWrapLongitude = _ref$autoWrapLongitud === void 0 ? false : _ref$autoWrapLongitud;

  if (coordinateSystem === _constants.COORDINATE_SYSTEM.DEFAULT) {
    coordinateSystem = viewport.isGeospatial ? _constants.COORDINATE_SYSTEM.LNGLAT : _constants.COORDINATE_SYSTEM.CARTESIAN;
  }

  var uniforms = getMemoizedViewportUniforms({
    viewport: viewport,
    devicePixelRatio: devicePixelRatio,
    coordinateSystem: coordinateSystem,
    coordinateOrigin: coordinateOrigin
  });
  uniforms.project_uWrapLongitude = autoWrapLongitude;
  uniforms.project_uModelMatrix = modelMatrix || IDENTITY_MATRIX;
  return uniforms;
}

function calculateViewportUniforms(_ref2) {
  var viewport = _ref2.viewport,
      devicePixelRatio = _ref2.devicePixelRatio,
      coordinateSystem = _ref2.coordinateSystem,
      coordinateOrigin = _ref2.coordinateOrigin;

  var _calculateMatrixAndOf = calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin),
      projectionCenter = _calculateMatrixAndOf.projectionCenter,
      viewProjectionMatrix = _calculateMatrixAndOf.viewProjectionMatrix,
      originCommon = _calculateMatrixAndOf.originCommon,
      cameraPosCommon = _calculateMatrixAndOf.cameraPosCommon,
      shaderCoordinateOrigin = _calculateMatrixAndOf.shaderCoordinateOrigin,
      geospatialOrigin = _calculateMatrixAndOf.geospatialOrigin;

  var distanceScales = viewport.getDistanceScales();
  var viewportSize = [viewport.width * devicePixelRatio, viewport.height * devicePixelRatio];
  var focalDistance = _core.vec4.transformMat4([], [0, 0, -viewport.focalDistance, 1], viewport.projectionMatrix)[3] || 1;
  var uniforms = {
    project_uCoordinateSystem: coordinateSystem,
    project_uProjectionMode: viewport.projectionMode,
    project_uCoordinateOrigin: shaderCoordinateOrigin,
    project_uCommonOrigin: originCommon.slice(0, 3),
    project_uCenter: projectionCenter,
    project_uPseudoMeters: Boolean(viewport._pseudoMeters),
    project_uViewportSize: viewportSize,
    project_uDevicePixelRatio: devicePixelRatio,
    project_uFocalDistance: focalDistance,
    project_uCommonUnitsPerMeter: distanceScales.unitsPerMeter,
    project_uCommonUnitsPerWorldUnit: distanceScales.unitsPerMeter,
    project_uCommonUnitsPerWorldUnit2: DEFAULT_PIXELS_PER_UNIT2,
    project_uScale: viewport.scale,
    project_uWrapLongitude: false,
    project_uViewProjectionMatrix: viewProjectionMatrix,
    project_uModelMatrix: IDENTITY_MATRIX,
    project_uCameraPosition: cameraPosCommon
  };

  if (geospatialOrigin) {
    var distanceScalesAtOrigin = viewport.getDistanceScales(geospatialOrigin);

    switch (coordinateSystem) {
      case _constants.COORDINATE_SYSTEM.METER_OFFSETS:
        uniforms.project_uCommonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerMeter;
        uniforms.project_uCommonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerMeter2;
        break;

      case _constants.COORDINATE_SYSTEM.LNGLAT:
      case _constants.COORDINATE_SYSTEM.LNGLAT_OFFSETS:
        if (!viewport._pseudoMeters) {
          uniforms.project_uCommonUnitsPerMeter = distanceScalesAtOrigin.unitsPerMeter;
        }

        uniforms.project_uCommonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerDegree;
        uniforms.project_uCommonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerDegree2;
        break;

      case _constants.COORDINATE_SYSTEM.CARTESIAN:
        uniforms.project_uCommonUnitsPerWorldUnit = [1, 1, distanceScalesAtOrigin.unitsPerMeter[2]];
        uniforms.project_uCommonUnitsPerWorldUnit2 = [0, 0, distanceScalesAtOrigin.unitsPerMeter2[2]];
        break;

      default:
        break;
    }
  }

  return uniforms;
}
//# sourceMappingURL=viewport-uniforms.js.map