// 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.

export default "// EXTERNAL CONSTANTS: these must match JavaScript constants in \"src/core/lib/constants.js\"\nconst float COORDINATE_SYSTEM_IDENTITY = 0.;\nconst float COORDINATE_SYSTEM_LNG_LAT = 1.;\nconst float COORDINATE_SYSTEM_METER_OFFSETS = 2.;\nconst float COORDINATE_SYSTEM_LNGLAT_OFFSETS = 3.;\n\nuniform float project_uCoordinateSystem;\nuniform float project_uScale;\nuniform vec3 project_uPixelsPerMeter;\nuniform vec3 project_uPixelsPerDegree;\nuniform vec3 project_uPixelsPerUnit;\nuniform vec3 project_uPixelsPerUnit2;\nuniform vec4 project_uCenter;\nuniform mat4 project_uModelMatrix;\nuniform mat4 project_uViewProjectionMatrix;\nuniform vec2 project_uViewportSize;\nuniform float project_uDevicePixelRatio;\nuniform float project_uFocalDistance;\nuniform vec3 project_uCameraPosition;\n\nconst float TILE_SIZE = 512.0;\nconst float PI = 3.1415926536;\nconst float WORLD_SCALE = TILE_SIZE / (PI * 2.0);\n\n//\n// Scaling offsets - scales meters to \"pixels\"\n// Note the scalar version of project_scale is for scaling the z component only\n//\nfloat project_scale(float meters) {\n  return meters * project_uPixelsPerMeter.z;\n}\n\nvec2 project_scale(vec2 meters) {\n  return meters * project_uPixelsPerMeter.xy;\n}\n\nvec3 project_scale(vec3 meters) {\n  return meters * project_uPixelsPerMeter;\n}\n\nvec4 project_scale(vec4 meters) {\n  return vec4(meters.xyz * project_uPixelsPerMeter, meters.w);\n}\n\n//\n// Projecting normal - transform deltas from current coordinate system to\n// normals in the worldspace\n//\nvec3 project_normal(vec3 vector) {\n  if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNG_LAT ||\n    project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSETS) {\n    return normalize(vector * project_uPixelsPerDegree);\n  }\n  // Apply model matrix\n  vec4 normal_modelspace = project_uModelMatrix * vec4(vector, 0.0);\n  return normalize(normal_modelspace.xyz * project_uPixelsPerMeter);\n}\n\nvec4 project_offset_(vec4 offset) {\n  vec3 pixelsPerUnit = project_uPixelsPerUnit + project_uPixelsPerUnit2 * offset.y;\n  return vec4(offset.xyz * pixelsPerUnit, offset.w);\n}\n\n//\n// Projecting positions - non-linear projection: lnglats => unit tile [0-1, 0-1]\n//\nvec2 project_mercator_(vec2 lnglat) {\n  return vec2(\n    radians(lnglat.x) + PI,\n    PI - log(tan_fp32(PI * 0.25 + radians(lnglat.y) * 0.5))\n  );\n}\n\n//\n// Projects lnglats (or meter offsets, depending on mode) to pixels\n//\nvec4 project_position(vec4 position) {\n  // TODO - why not simply subtract center and fall through?\n  if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNG_LAT) {\n    return project_uModelMatrix * vec4(\n      project_mercator_(position.xy) * WORLD_SCALE * project_uScale,\n      project_scale(position.z),\n      position.w\n    );\n  }\n\n  if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSETS) {\n    return project_offset_(position);\n  }\n\n  // METER_OFFSETS or IDENTITY\n  // Apply model matrix\n  vec4 position_modelspace = project_uModelMatrix * position;\n  return project_offset_(position_modelspace);\n}\n\nvec3 project_position(vec3 position) {\n  vec4 projected_position = project_position(vec4(position, 1.0));\n  return projected_position.xyz;\n}\n\nvec2 project_position(vec2 position) {\n  vec4 projected_position = project_position(vec4(position, 0.0, 1.0));\n  return projected_position.xy;\n}\n\n//\n// Projects from \"world\" coordinates to clip space.\n// Uses project_uViewProjectionMatrix\n//\nvec4 project_to_clipspace(vec4 position) {\n  if (project_uCoordinateSystem == COORDINATE_SYSTEM_METER_OFFSETS ||\n    project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSETS) {\n    // Needs to be divided with project_uPixelsPerMeter\n    position.w *= project_uPixelsPerMeter.z;\n  }\n  return project_uViewProjectionMatrix * position + project_uCenter;\n}\n\n// Returns a clip space offset that corresponds to a given number of **non-device** pixels\nvec4 project_pixel_to_clipspace(vec2 pixels) {\n  vec2 offset = pixels / project_uViewportSize * project_uDevicePixelRatio;\n  return vec4(offset * project_uFocalDistance, 0.0, 0.0);\n}\n";
//# sourceMappingURL=project.glsl.js.map