<commit_before>// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

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

import {Matrix4, Vector3, equals} from 'math.gl';
import {transformVector, createMat4, extractCameraVectors} from '../math/utils';
import mat4_scale from 'gl-mat4/scale';
import mat4_translate from 'gl-mat4/translate';
import mat4_multiply from 'gl-mat4/multiply';
import mat4_invert from 'gl-mat4/invert';
import mat4_perspective from 'gl-mat4/perspective';

import vec2_lerp from 'gl-vec2/lerp';

const ZERO_VECTOR = [0, 0, 0];

import {
  getMercatorDistanceScales,
  getMercatorWorldPosition,
  getMercatorMeterZoom
} from 'viewport-mercator-project';

import assert from 'assert';

const IDENTITY = createMat4();

const DEFAULT_DISTANCE_SCALES = {
  pixelsPerMeter: [1, 1, 1],
  metersPerPixel: [1, 1, 1],
  pixelsPerDegree: [1, 1, 1],
  degreesPerPixel: [1, 1, 1]
};

const DEFAULT_ZOOM = 0;

const ERR_ARGUMENT = 'Illegal argument to Viewport';

export default class Viewport {
  /**
   * @classdesc
   * Manages coordinate system transformations for deck.gl.
   *
   * Note: The Viewport is immutable in the sense that it only has accessors.
   * A new viewport instance should be created if any parameters have changed.
   */
  /* eslint-disable complexity, max-statements */
  constructor(opts = {}) {
    const {
      id = null,

      // Window width/height in pixels (for pixel projection)
      x = 0,
      y = 0,
      width = 1,
      height = 1,

      // view matrix
      viewMatrix = IDENTITY,

      // Projection matrix
      projectionMatrix = null,

      // Perspective projection matrix parameters, used if projectionMatrix not supplied
      fovy = 75,
      near = 0.1,  // Distance of near clipping plane
      far = 1000, // Distance of far clipping plane

      // Anchor: lng lat zoom will make this viewport work with geospatial coordinate systems
      longitude = null,
      latitude = null,
      zoom = null,

      // Anchor position offset (in meters for geospatial viewports)
      position = null,
      // A model matrix to be applied to position, to match the layer props API
      modelMatrix = null,

      distanceScales = null
    } = opts;

    this.id = id || this.constructor.displayName || 'viewport';

    // Check if we have a geospatial anchor
    this.isGeospatial = Number.isFinite(latitude) && Number.isFinite(longitude);

    // Silently allow apps to send in w,h = 0,0
    this.x = x;
    this.y = y;
    this.width = width || 1;
    this.height = height || 1;

    this.zoom = zoom;
    if (!Number.isFinite(this.zoom)) {
      this.zoom = this.isGeospatial ? getMercatorMeterZoom({latitude}) : DEFAULT_ZOOM;
    }
    this.scale = Math.pow(2, this.zoom);

    // Calculate distance scales if lng/lat/zoom are provided
    this.distanceScales = this.isGeospatial ?
      getMercatorDistanceScales({latitude, longitude, scale: this.scale}) :
      distanceScales || DEFAULT_DISTANCE_SCALES;

    this.focalDistance = opts.focalDistance || 1;

    this.distanceScales.metersPerPixel = new Vector3(this.distanceScales.metersPerPixel);
    this.distanceScales.pixelsPerMeter = new Vector3(this.distanceScales.pixelsPerMeter);

    this.position = ZERO_VECTOR;
    this.meterOffset = ZERO_VECTOR;
    if (position) {
      // Apply model matrix if supplied
      this.position = position;
      this.modelMatrix = modelMatrix;
      this.meterOffset = modelMatrix ? modelMatrix.transformVector(position) : position;
    }

    // Determine camera center
    this.center = this.isGeospatial ?
      getMercatorWorldPosition({
        longitude, latitude, zoom: this.zoom, meterOffset: this.meterOffset
      }) :
      position;

    // console.log(this.scale, this.distanceScales.pixelsPerMeter);

    this.viewMatrixUncentered = viewMatrix;

    // Make a centered version of the matrix for projection modes without an offset
    this.viewMatrix = new Matrix4()
      // Apply the uncentered view matrix
      .multiplyRight(this.viewMatrixUncentered)
      // The Mercator world coordinate system is upper left,
      // but GL expects lower left, so we flip it around the center after all transforms are done
      .scale([1, -1, 1])
      // And center it
      .translate(new Vector3(this.center || ZERO_VECTOR).negate());

    // Create a projection matrix if not supplied
    if (projectionMatrix) {
      this.projectionMatrix = projectionMatrix;
    } else {
      assert(Number.isFinite(fovy));
      const DEGREES_TO_RADIANS = Math.PI / 180;
      const fovyRadians = fovy * DEGREES_TO_RADIANS;
      const aspect = this.width / this.height;
      this.projectionMatrix = mat4_perspective([], fovyRadians, aspect, near, far);
    }

    // Init pixel matrices
    this._initMatrices();

    // Bind methods for easy access
    this.equals = this.equals.bind(this);
    this.project = this.project.bind(this);
    this.unproject = this.unproject.bind(this);
    this.projectFlat = this.projectFlat.bind(this);
    this.unprojectFlat = this.unprojectFlat.bind(this);
    this.getMatrices = this.getMatrices.bind(this);
  }
  /* eslint-enable complexity, max-statements */

  // Two viewports are equal if width and height are identical, and if<commit_msg>Remove the y-flip scale and camera re-center logic for non-geospatial viewport (#1125)<commit_after>// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

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

import {Matrix4, Vector3, equals} from 'math.gl';
import {transformVector, createMat4, extractCameraVectors} from '../math/utils';
import mat4_scale from 'gl-mat4/scale';
import mat4_translate from 'gl-mat4/translate';
import mat4_multiply from 'gl-mat4/multiply';
import mat4_invert from 'gl-mat4/invert';
import mat4_perspective from 'gl-mat4/perspective';

import vec2_lerp from 'gl-vec2/lerp';

const ZERO_VECTOR = [0, 0, 0];

import {
  getMercatorDistanceScales,
  getMercatorWorldPosition,
  getMercatorMeterZoom
} from 'viewport-mercator-project';

import assert from 'assert';

const IDENTITY = createMat4();

const DEFAULT_DISTANCE_SCALES = {
  pixelsPerMeter: [1, 1, 1],
  metersPerPixel: [1, 1, 1],
  pixelsPerDegree: [1, 1, 1],
  degreesPerPixel: [1, 1, 1]
};

const DEFAULT_ZOOM = 0;

const ERR_ARGUMENT = 'Illegal argument to Viewport';

export default class Viewport {
  /**
   * @classdesc
   * Manages coordinate system transformations for deck.gl.
   *
   * Note: The Viewport is immutable in the sense that it only has accessors.
   * A new viewport instance should be created if any parameters have changed.
   */
  /* eslint-disable complexity, max-statements */
  constructor(opts = {}) {
    const {
      id = null,

      // Window width/height in pixels (for pixel projection)
      x = 0,
      y = 0,
      width = 1,
      height = 1,

      // view matrix
      viewMatrix = IDENTITY,

      // Projection matrix
      projectionMatrix = null,

      // Perspective projection matrix parameters, used if projectionMatrix not supplied
      fovy = 75,
      near = 0.1,  // Distance of near clipping plane
      far = 1000, // Distance of far clipping plane

      // Anchor: lng lat zoom will make this viewport work with geospatial coordinate systems
      longitude = null,
      latitude = null,
      zoom = null,

      // Anchor position offset (in meters for geospatial viewports)
      position = null,
      // A model matrix to be applied to position, to match the layer props API
      modelMatrix = null,

      distanceScales = null
    } = opts;

    this.id = id || this.constructor.displayName || 'viewport';

    // Check if we have a geospatial anchor
    this.isGeospatial = Number.isFinite(latitude) && Number.isFinite(longitude);

    // Silently allow apps to send in w,h = 0,0
    this.x = x;
    this.y = y;
    this.width = width || 1;
    this.height = height || 1;

    this.zoom = zoom;
    if (!Number.isFinite(this.zoom)) {
      this.zoom = this.isGeospatial ? getMercatorMeterZoom({latitude}) : DEFAULT_ZOOM;
    }
    this.scale = Math.pow(2, this.zoom);

    // Calculate distance scales if lng/lat/zoom are provided
    this.distanceScales = this.isGeospatial ?
      getMercatorDistanceScales({latitude, longitude, scale: this.scale}) :
      distanceScales || DEFAULT_DISTANCE_SCALES;

    this.focalDistance = opts.focalDistance || 1;

    this.distanceScales.metersPerPixel = new Vector3(this.distanceScales.metersPerPixel);
    this.distanceScales.pixelsPerMeter = new Vector3(this.distanceScales.pixelsPerMeter);

    this.position = ZERO_VECTOR;
    this.meterOffset = ZERO_VECTOR;
    if (position) {
      // Apply model matrix if supplied
      this.position = position;
      this.modelMatrix = modelMatrix;
      this.meterOffset = modelMatrix ? modelMatrix.transformVector(position) : position;
    }

    this.viewMatrixUncentered = viewMatrix;

    if (this.isGeospatial) {
      // Determine camera center
      this.center = getMercatorWorldPosition({
        longitude, latitude, zoom: this.zoom, meterOffset: this.meterOffset
      });

      // Make a centered version of the matrix for projection modes without an offset
      this.viewMatrix = new Matrix4()
      // Apply the uncentered view matrix
        .multiplyRight(this.viewMatrixUncentered)
        // The Mercator world coordinate system is upper left,
        // but GL expects lower left, so we flip it around the center after all transforms are done
        .scale([1, -1, 1])
        // And center it
        .translate(new Vector3(this.center || ZERO_VECTOR).negate());
    } else {
      this.center = position;
      this.viewMatrix = viewMatrix;
    }

    // Create a projection matrix if not supplied
    if (projectionMatrix) {
      this.projectionMatrix = projectionMatrix;
    } else {
      assert(Number.isFinite(fovy));
      const DEGREES_TO_RADIANS = Math.PI / 180;
      const fovyRadians = fovy * DEGREES_TO_RADIANS;
      const aspect = this.width / this.height;
      this.projectionMatrix = mat4_perspective([], fovyRadians, aspect, near, far);
    }

    // Init pixel matrices
    this._initMatrices();

    // Bind methods for easy access
    this.equals = this.equals.bind(this);
    this.project = this.project.bind(this);
    this.unproject = this.unproject.bind(this);
    this.projectFlat = this.projectFlat.bind(this);
    this.unprojectFlat = this.unprojectFlat.bind(this);
    this.getMatrices = this.getMatrices.bind(this);
  }
  /* eslint-enable complexity, max-statements */

  // Two viewports are equal if width and height are identical, and if
{'fraction_non_alphanumeric': 0.0946978649649413, 'fraction_numerical': 0.01118726857322934, 'mean_word_length': 3.13754889178618, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5501201', 'n_tokens_mistral': 3893, 'n_tokens_neox': 3671, 'n_words': 1253}