maplibre-gl 6.4.1 → 6.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/maplibre-gl-dev.mjs +254 -201
- package/dist/maplibre-gl-dev.mjs.map +1 -1
- package/dist/maplibre-gl-shared-dev.mjs +696 -335
- package/dist/maplibre-gl-shared-dev.mjs.map +1 -1
- package/dist/maplibre-gl-shared.mjs +2 -2
- package/dist/maplibre-gl-shared.mjs.map +1 -1
- package/dist/maplibre-gl-worker-dev.mjs +1 -1
- package/dist/maplibre-gl-worker.mjs +1 -1
- package/dist/maplibre-gl.d.ts +72 -3
- package/dist/maplibre-gl.mjs +15 -15
- package/dist/maplibre-gl.mjs.map +1 -1
- package/package.json +5 -5
- package/src/geo/projection/globe_utils.ts +2 -1
- package/src/geo/projection/vertical_perspective_camera_helper.test.ts +52 -0
- package/src/geo/projection/vertical_perspective_camera_helper.ts +2 -1
- package/src/index.ts +2 -1
- package/src/shaders/glsl/raster.vertex.glsl +20 -3
- package/src/shaders/glsl/raster.vertex.glsl.g.ts +1 -1
- package/src/source/image_source.test.ts +160 -30
- package/src/source/image_source.ts +170 -74
- package/src/webgl/draw/draw_raster.ts +12 -10
- package/src/webgl/program/raster_program.ts +11 -8
package/dist/maplibre-gl-dev.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MapLibre GL JS
|
|
3
|
-
* @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v6.
|
|
3
|
+
* @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v6.5.0/LICENSE.txt
|
|
4
4
|
*/
|
|
5
5
|
import { $ as tileCoordinatesToMercatorCoordinates, $n as deepEqual, $r as mul, $t as TRANSITION_SUFFIX, A as evaluateSizeForFeature, Ai as perspective, An as getVideo, Ar as remapSaturate, At as toEvaluationFeature, Bi as invert, Br as wrap, Bt as SegmentVector, C as isCustomStyleLayer, Ci as equals, Cn as Event, Cr as nextPowerOfTwo, Ct as HEATMAP_FULL_RENDER_FBO_KEY, D as SymbolBucket, Di as invert$1, Dn as getArrayBuffer, Dr as radiansToDegrees, Dt as RGBAImage, E as isSymbolStyleLayer, Ei as identity, En as GLOBAL_DISPATCHER_ID, Er as pointPlaneSignedDistance, Et as AlphaImage, F as ImagePosition, Fi as translate, Fn as removeProtocol, Fr as subscribe, Ft as Uniform4f, G as isFillExtrusionStyleLayer, Gn as bezier, Gr as length, Gt as PosArray, H as isLineStyleLayer, Hi as isOffscreenCanvasDistorted, Hn as angleToRotateBetweenVectors2D, Hr as pixelsToTileUnits, Ht as CollisionCircleLayoutArray, I as potpack, Ii as create$4, In as config, Ir as threePlaneIntersection, It as UniformColor, J as cameraDirectionFromPitchBearing, Jn as createIdentityMat4f32, Jr as zero, Jt as TriangleIndexArray, Kn as clamp, Kr as scale$1, Kt as QuadTriangleArray, L as isStyleImageWebGLData, Li as fromRotation, Ln as AbortError, Lr as translatePosition, Lt as UniformColorArray, Mi as rotateY$1, Mn as sameOrigin, Mr as rollPitchBearingToQuat, Mt as Uniform1i, N as getAnchorAlignment, Ni as rotateZ, Nn as addProtocol, Nr as scaleZoom, Nt as Uniform2f, O as addDynamicAttributes, Oi as multiply, On as getJSON, Or as rayPlaneIntersection, Ot as isCircleStyleLayer, Pi as scale, Pn as getProtocol, Pr as sphericalToCartesian, Pt as Uniform3f, Q as projectToWorldCoordinates, Qn as createVec4f64, Qr as slerp, Qt as Properties, R as renderStyleImage, Ri as create$2, Rn as isAbortError, Rr as uniqueId, Rt as UniformFloatArray, S as createStyleLayer, Si as create$1, Sn as ErrorEvent, Sr as mod, St as isHillshadeStyleLayer, T as isBackgroundStyleLayer, Ti as fromScaling, Tn as AJAXError, Tr as pick, Tt as renderColorRamp, Ui as offscreenCanvasSupported, Un as arrayBufferToImage, Ur as EXTENT, Ut as LineStripIndexArray, V as collisionCircleLayout, Vi as rotate, Vn as MAX_VALID_LATITUDE, Vr as zoomScale, Vt as CollisionBoxArray, Wi as Point, Wn as arrayBufferToImageBitmap, Wr as create$3, Wt as Pos3dArray, X as getMercatorHorizon, Xn as createMat4f64, Xr as fromValues, Xt as isRasterStyleLayer, Y as cameraMercatorCoordinateFromCenterAndRotation, Yn as createIdentityMat4f64, Yr as fromEuler, Yt as createLayout, Z as maxMercatorHorizonAngle, Zn as createVec3f64, Zr as multiply$1, Zt as DataConstantProperty, _ as UnwrappedTileID, _i as transformMat4$1, _n as emptyStyle, _r as isTouchableEvent, _t as SubdivisionGranularityExpression, a as clipLine, ai as dot, ar as evaluateZoomSnap, at as mercatorXfromLng, b as isInBoundsForZoomLngLat, bi as clone$1, bn as interpolateFactory, br as lerp, ci as negate, cn as validateAndEmit, cr as findLineIntersection, ct as LngLat, di as rotateY, dn as Color, dr as getEdgeTiles, dt as EXTENT_BOUNDS, ei as scale$3, en as Transitionable, er as defaultEasing, et as unprojectFromWorldCoordinates, f as GEOJSON_TILE_LAYER_NAME, fi as rotateZ$1, fn as ProjectionDefinition, ft as Bounds, g as OverscaledTileID, gi as transformMat3, gn as diff, gr as isSafari, gt as SOUTH_POLE_Y, h as CanonicalTileID, hi as sub, hn as derefLayers, hr as isPointableEvent, ht as NORTH_POLE_Y, ii as cross, in as ZoomHistory, ir as ensureError, it as lngFromMercatorX, j as evaluateSizeForZoom, ji as rotateX, jn as makeRequest, jr as rollPitchBearingEqual, jt as Uniform1f, k as getOverlapMode, ki as ortho, kn as getReferrer, kr as readImageUsingVideoFrame, kt as polygonIntersectsPolygon, li as normalize, ln as validateStyle, lr as getAABB, lt as earthRadius, mi as scaleAndAdd, mr as isImageBitmap, ni as add, nr as differenceOfAnglesDegrees, nt as altitudeFromMercatorZ, oi as len, on as SPEC_SOURCE_TYPES, or as extend, ot as mercatorYfromLat, pi as scale$2, pn as ValidationError, pr as getRollPitchBearing, pt as isFillStyleLayer, q as calculateTileMatrix, qn as clone$2, qr as sqrLen, qt as RasterBoundsArray, r as TextAnchorEnum, ri as clone, rn as codePointUsesLocalIdeographFontFamily, rr as distanceOfAnglesRadians, rt as latFromMercatorY, s as TileCache, si as length$1, sn as emitValidationErrors, sr as filterObject, st as mercatorZfromAltitude, t as getAnchorJustification, ti as transformMat4, tn as EvaluationParameters, tr as degreesToRadians, tt as MercatorCoordinate, u as GeoJSONFeature, ui as rotateX$1, un as validateStyleAndEmit, ur as getAngleDelta, v as calculateTileKey, vi as transformQuat, vn as featureFilter, vr as isTouchableOrPointableType, vt as SubdivisionGranularitySetting, w as validateCustomStyleLayer, wi as exactEquals, wn as Evented, wr as parseCacheControl, wt as isHeatmapStyleLayer, x as Actor, xi as copy, xn as latest, xr as mapObject, xt as Texture, y as compareTileId, yi as zero$1, yr as isWorker, yt as isColorReliefStyleLayer, z as parseGlyphPbf, zi as determinant, zn as throwIfAborted, zr as warnOnce, zt as UniformMatrix4f } from "./maplibre-gl-shared-dev.mjs";
|
|
6
6
|
//#region package.json
|
|
7
|
-
var version$2 = "6.
|
|
7
|
+
var version$2 = "6.5.0";
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/util/browser.ts
|
|
10
10
|
let linkEl;
|
|
@@ -3808,10 +3808,8 @@ var GeoJSONSource = class extends Evented {
|
|
|
3808
3808
|
};
|
|
3809
3809
|
//#endregion
|
|
3810
3810
|
//#region src/webgl/program/raster_program.ts
|
|
3811
|
-
/**
|
|
3812
|
-
|
|
3813
|
-
*/
|
|
3814
|
-
const identityPerspectiveTransform = [
|
|
3811
|
+
/** The bilinear warp, which is also the affine one that a rectangle or a parallelogram needs. */
|
|
3812
|
+
const bilinearImageWarp = [
|
|
3815
3813
|
0,
|
|
3816
3814
|
0,
|
|
3817
3815
|
1
|
|
@@ -3820,7 +3818,7 @@ const rasterUniforms = (context, locations) => ({
|
|
|
3820
3818
|
"u_tl_parent": new Uniform2f(context, locations.u_tl_parent),
|
|
3821
3819
|
"u_scale_parent": new Uniform1f(context, locations.u_scale_parent),
|
|
3822
3820
|
"u_buffer_scale": new Uniform1f(context, locations.u_buffer_scale),
|
|
3823
|
-
"
|
|
3821
|
+
"u_image_warp": new Uniform3f(context, locations.u_image_warp),
|
|
3824
3822
|
"u_fade_t": new Uniform1f(context, locations.u_fade_t),
|
|
3825
3823
|
"u_opacity": new Uniform1f(context, locations.u_opacity),
|
|
3826
3824
|
"u_image0": new Uniform1i(context, locations.u_image0),
|
|
@@ -3833,11 +3831,11 @@ const rasterUniforms = (context, locations) => ({
|
|
|
3833
3831
|
"u_coords_top": new Uniform4f(context, locations.u_coords_top),
|
|
3834
3832
|
"u_coords_bottom": new Uniform4f(context, locations.u_coords_bottom)
|
|
3835
3833
|
});
|
|
3836
|
-
const rasterUniformValues = (parentTL, parentScaleBy, fade, layer, cornerCoords,
|
|
3834
|
+
const rasterUniformValues = (parentTL, parentScaleBy, fade, layer, cornerCoords, imageWarp) => ({
|
|
3837
3835
|
"u_tl_parent": parentTL,
|
|
3838
3836
|
"u_scale_parent": parentScaleBy,
|
|
3839
3837
|
"u_buffer_scale": 1,
|
|
3840
|
-
"
|
|
3838
|
+
"u_image_warp": imageWarp,
|
|
3841
3839
|
"u_fade_t": fade.mix,
|
|
3842
3840
|
"u_opacity": fade.opacity * layer.paint.get("raster-opacity"),
|
|
3843
3841
|
"u_image0": 0,
|
|
@@ -3877,8 +3875,150 @@ function saturationFactor(saturation) {
|
|
|
3877
3875
|
return saturation > 0 ? 1 - 1 / (1.001 - saturation) : -saturation;
|
|
3878
3876
|
}
|
|
3879
3877
|
//#endregion
|
|
3878
|
+
//#region src/render/mesh.ts
|
|
3879
|
+
var Mesh = class {
|
|
3880
|
+
constructor(vertexBuffer, indexBuffer, segments) {
|
|
3881
|
+
this.vertexBuffer = vertexBuffer;
|
|
3882
|
+
this.indexBuffer = indexBuffer;
|
|
3883
|
+
this.segments = segments;
|
|
3884
|
+
}
|
|
3885
|
+
destroy() {
|
|
3886
|
+
this.vertexBuffer.destroy();
|
|
3887
|
+
this.indexBuffer.destroy();
|
|
3888
|
+
this.segments.destroy();
|
|
3889
|
+
this.vertexBuffer = null;
|
|
3890
|
+
this.indexBuffer = null;
|
|
3891
|
+
this.segments = null;
|
|
3892
|
+
}
|
|
3893
|
+
};
|
|
3894
|
+
//#endregion
|
|
3895
|
+
//#region src/data/pos_attributes.ts
|
|
3896
|
+
const posAttributes = createLayout([{
|
|
3897
|
+
name: "a_pos",
|
|
3898
|
+
type: "Int16",
|
|
3899
|
+
components: 2
|
|
3900
|
+
}]);
|
|
3901
|
+
//#endregion
|
|
3902
|
+
//#region src/util/create_tile_mesh.ts
|
|
3903
|
+
/**
|
|
3904
|
+
* The size of border region for stencil masks, in internal tile coordinates.
|
|
3905
|
+
* Used for globe rendering.
|
|
3906
|
+
*/
|
|
3907
|
+
const EXTENT_STENCIL_BORDER = EXTENT / 128;
|
|
3908
|
+
/**
|
|
3909
|
+
* @internal
|
|
3910
|
+
* Creates a mesh of a quad that covers the entire tile (covering positions in range 0..EXTENT),
|
|
3911
|
+
* is optionally subdivided into finer quads, optionally includes a border
|
|
3912
|
+
* and optionally extends to the north and/or special pole vertices.
|
|
3913
|
+
* Also allocates and populates WebGL buffers for the mesh.
|
|
3914
|
+
* Forces 16 bit indices that are used throughout MapLibre.
|
|
3915
|
+
* @param context - The WebGL context wrapper.
|
|
3916
|
+
* @param options - Specify options for tile mesh creation such as granularity or border.
|
|
3917
|
+
* @returns The mesh vertices and indices, already allocated and uploaded into WebGL buffers.
|
|
3918
|
+
*/
|
|
3919
|
+
function createTileMeshWithBuffers(context, options) {
|
|
3920
|
+
const tileMesh = createTileMesh(options, "16bit");
|
|
3921
|
+
const vertices = PosArray.deserialize({
|
|
3922
|
+
arrayBuffer: tileMesh.vertices,
|
|
3923
|
+
length: tileMesh.vertices.byteLength / 2 / 2
|
|
3924
|
+
});
|
|
3925
|
+
const indices = TriangleIndexArray.deserialize({
|
|
3926
|
+
arrayBuffer: tileMesh.indices,
|
|
3927
|
+
length: tileMesh.indices.byteLength / 2 / 3
|
|
3928
|
+
});
|
|
3929
|
+
return new Mesh(context.createVertexBuffer(vertices, posAttributes.members), context.createIndexBuffer(indices), SegmentVector.simpleSegment(0, 0, vertices.length, indices.length));
|
|
3930
|
+
}
|
|
3931
|
+
/**
|
|
3932
|
+
* Creates a mesh of a quad that covers the entire tile (covering positions in range 0..EXTENT),
|
|
3933
|
+
* is optionally subdivided into finer quads, optionally includes a border
|
|
3934
|
+
* and optionally extends to the north and/or special pole vertices.
|
|
3935
|
+
* Additionally the resulting mesh indices type can be specified using `forceIndicesSize`.
|
|
3936
|
+
* @example
|
|
3937
|
+
* ```
|
|
3938
|
+
* // Creating a mesh for a tile that can be used for raster layers, hillshade, etc.
|
|
3939
|
+
* const meshBuffers = createTileMesh({
|
|
3940
|
+
* granularity: map.style.projection.subdivisionGranularity.tile.getGranularityForZoomLevel(tileID.z),
|
|
3941
|
+
* generateBorders: true,
|
|
3942
|
+
* extendToNorthPole: tileID.y === 0,
|
|
3943
|
+
* extendToSouthPole: tileID.y === (1 << tileID.z) - 1,
|
|
3944
|
+
* }, '16bit');
|
|
3945
|
+
* ```
|
|
3946
|
+
* @see [Add a custom layer with tiles to a globe](https://maplibre.org/maplibre-gl-js/docs/examples/add-a-custom-layer-with-tiles-to-a-globe/)
|
|
3947
|
+
* @param options - Specify options for tile mesh creation such as granularity or border.
|
|
3948
|
+
* @param forceIndicesSize - Specifies what indices type to use. The values '32bit' and '16bit' force their respective indices size. If undefined, the mesh may use either size, and will pick 16 bit indices if possible. If '16bit' is specified and the mesh exceeds 65536 vertices, an exception is thrown.
|
|
3949
|
+
* @returns Typed arrays of the mesh vertices and indices.
|
|
3950
|
+
*/
|
|
3951
|
+
function createTileMesh(options, forceIndicesSize) {
|
|
3952
|
+
const granularity = options.granularity !== void 0 ? Math.max(options.granularity, 1) : 1;
|
|
3953
|
+
const quadsPerAxisX = granularity + (options.generateBorders ? 2 : 0);
|
|
3954
|
+
const quadsPerAxisY = granularity + (options.extendToNorthPole || options.generateBorders ? 1 : 0) + (options.extendToSouthPole || options.generateBorders ? 1 : 0);
|
|
3955
|
+
const verticesPerAxisX = quadsPerAxisX + 1;
|
|
3956
|
+
const verticesPerAxisY = quadsPerAxisY + 1;
|
|
3957
|
+
const offsetX = options.generateBorders ? -1 : 0;
|
|
3958
|
+
const offsetY = options.generateBorders || options.extendToNorthPole ? -1 : 0;
|
|
3959
|
+
const endX = granularity + (options.generateBorders ? 1 : 0);
|
|
3960
|
+
const endY = granularity + (options.generateBorders || options.extendToSouthPole ? 1 : 0);
|
|
3961
|
+
const vertexCount = verticesPerAxisX * verticesPerAxisY;
|
|
3962
|
+
const indexCount = quadsPerAxisX * quadsPerAxisY * 6;
|
|
3963
|
+
const overflows16bitIndices = verticesPerAxisX * verticesPerAxisY > 65536;
|
|
3964
|
+
if (overflows16bitIndices && forceIndicesSize === "16bit") throw new Error("Granularity is too large and meshes would not fit inside 16 bit vertex indices.");
|
|
3965
|
+
const use32bitIndices = overflows16bitIndices || forceIndicesSize === "32bit";
|
|
3966
|
+
const vertices = new Int16Array(vertexCount * 2);
|
|
3967
|
+
let vertexId = 0;
|
|
3968
|
+
for (let y = offsetY; y <= endY; y++) for (let x = offsetX; x <= endX; x++) {
|
|
3969
|
+
let vx = x / granularity * EXTENT;
|
|
3970
|
+
if (x === -1) vx = -EXTENT_STENCIL_BORDER;
|
|
3971
|
+
if (x === granularity + 1) vx = EXTENT + EXTENT_STENCIL_BORDER;
|
|
3972
|
+
let vy = y / granularity * EXTENT;
|
|
3973
|
+
if (y === -1) vy = options.extendToNorthPole ? NORTH_POLE_Y : -EXTENT_STENCIL_BORDER;
|
|
3974
|
+
if (y === granularity + 1) vy = options.extendToSouthPole ? SOUTH_POLE_Y : EXTENT + EXTENT_STENCIL_BORDER;
|
|
3975
|
+
vertices[vertexId++] = vx;
|
|
3976
|
+
vertices[vertexId++] = vy;
|
|
3977
|
+
}
|
|
3978
|
+
const indices = use32bitIndices ? new Uint32Array(indexCount) : new Uint16Array(indexCount);
|
|
3979
|
+
let indexId = 0;
|
|
3980
|
+
for (let y = 0; y < quadsPerAxisY; y++) for (let x = 0; x < quadsPerAxisX; x++) {
|
|
3981
|
+
const v0 = x + y * verticesPerAxisX;
|
|
3982
|
+
const v1 = x + 1 + y * verticesPerAxisX;
|
|
3983
|
+
const v2 = x + (y + 1) * verticesPerAxisX;
|
|
3984
|
+
const v3 = x + 1 + (y + 1) * verticesPerAxisX;
|
|
3985
|
+
indices[indexId++] = v0;
|
|
3986
|
+
indices[indexId++] = v2;
|
|
3987
|
+
indices[indexId++] = v1;
|
|
3988
|
+
indices[indexId++] = v1;
|
|
3989
|
+
indices[indexId++] = v2;
|
|
3990
|
+
indices[indexId++] = v3;
|
|
3991
|
+
}
|
|
3992
|
+
return {
|
|
3993
|
+
vertices: vertices.buffer.slice(0),
|
|
3994
|
+
indices: indices.buffer.slice(0),
|
|
3995
|
+
uses32bitIndices: use32bitIndices
|
|
3996
|
+
};
|
|
3997
|
+
}
|
|
3998
|
+
//#endregion
|
|
3880
3999
|
//#region src/source/image_source.ts
|
|
3881
4000
|
/**
|
|
4001
|
+
* How many grid cells per axis the mesh of a subdivided quad has. Within a cell the bilinear warp
|
|
4002
|
+
* is still approximated by one mapping per triangle, so the error falls off with the cell size.
|
|
4003
|
+
*/
|
|
4004
|
+
const SUBDIVIDED_QUAD_GRANULARITY = 16;
|
|
4005
|
+
/**
|
|
4006
|
+
* How much a warp may foreshorten the image, as the ratio between the largest and the smallest
|
|
4007
|
+
* homogeneous denominator over the quad, while staying purely projective. Ordinary oblique imagery
|
|
4008
|
+
* stays well below it.
|
|
4009
|
+
*/
|
|
4010
|
+
const PROJECTIVE_FORESHORTENING = 4;
|
|
4011
|
+
/**
|
|
4012
|
+
* The foreshortening at which a warp is taken to be purely bilinear.
|
|
4013
|
+
*
|
|
4014
|
+
* The denominator vanishes on the warp's vanishing line, and that line touches the quad exactly when
|
|
4015
|
+
* the quad degenerates into a triangle, so foreshortening grows without bound as a corner approaches
|
|
4016
|
+
* the diagonal between its neighbours. Left alone, such a quad keeps a valid but wildly lopsided
|
|
4017
|
+
* warp, squeezing nearly the whole image into a sliver along one edge and magnifying a handful of
|
|
4018
|
+
* texels over the rest of the quad.
|
|
4019
|
+
*/
|
|
4020
|
+
const BILINEAR_FORESHORTENING = 512;
|
|
4021
|
+
/**
|
|
3882
4022
|
* A data source containing an image.
|
|
3883
4023
|
* (See the [Style Specification](https://maplibre.org/maplibre-style-spec/#sources-image) for detailed documentation of options.)
|
|
3884
4024
|
*
|
|
@@ -3929,9 +4069,12 @@ var ImageSource = class extends Evented {
|
|
|
3929
4069
|
/** @internal */
|
|
3930
4070
|
constructor(id, options, dispatcher, eventedParent) {
|
|
3931
4071
|
super();
|
|
3932
|
-
this.
|
|
4072
|
+
this.imageWarp = bilinearImageWarp;
|
|
3933
4073
|
this.flippedWindingOrder = false;
|
|
4074
|
+
this._warp = "auto";
|
|
3934
4075
|
this._imageDirty = false;
|
|
4076
|
+
this._subdividedQuad = false;
|
|
4077
|
+
this._subdividedMesh = null;
|
|
3935
4078
|
this.id = id;
|
|
3936
4079
|
this.dispatcher = dispatcher;
|
|
3937
4080
|
this.coordinates = options.coordinates;
|
|
@@ -4000,6 +4143,23 @@ var ImageSource = class extends Evented {
|
|
|
4000
4143
|
this.image = image;
|
|
4001
4144
|
this._imageDirty = true;
|
|
4002
4145
|
}
|
|
4146
|
+
/**
|
|
4147
|
+
* @internal
|
|
4148
|
+
* The mesh the image is drawn with, or null to use the tile mesh of the current projection.
|
|
4149
|
+
*
|
|
4150
|
+
* The raster vertex shader evaluates {@link imageWarp} per vertex, so a pair of triangles only
|
|
4151
|
+
* samples it at the four corners. That is enough for the affine mapping of a parallelogram, and
|
|
4152
|
+
* for a purely projective mapping, whose straight lines survive linear interpolation across the
|
|
4153
|
+
* diagonal. Anything in between is neither, and would be textured as two independently warped
|
|
4154
|
+
* halves with a visible seam along that diagonal, so it needs the warp evaluated per grid cell.
|
|
4155
|
+
*
|
|
4156
|
+
* A projection that subdivides its own tile meshes already does this, so it keeps them.
|
|
4157
|
+
*/
|
|
4158
|
+
getMesh(context, projectionSubdividesTiles) {
|
|
4159
|
+
if (!this._subdividedQuad || projectionSubdividesTiles) return null;
|
|
4160
|
+
this._subdividedMesh ??= createTileMeshWithBuffers(context, { granularity: SUBDIVIDED_QUAD_GRANULARITY });
|
|
4161
|
+
return this._subdividedMesh;
|
|
4162
|
+
}
|
|
4003
4163
|
/** Teardown only: dropping the reference alone leaves the allocation to the GC. */
|
|
4004
4164
|
_disposeTexture() {
|
|
4005
4165
|
this.texture?.destroy();
|
|
@@ -4021,10 +4181,42 @@ var ImageSource = class extends Evented {
|
|
|
4021
4181
|
this._abortController = null;
|
|
4022
4182
|
}
|
|
4023
4183
|
this._disposeTexture();
|
|
4184
|
+
this._subdividedMesh?.destroy();
|
|
4185
|
+
this._subdividedMesh = null;
|
|
4024
4186
|
this.image = null;
|
|
4025
4187
|
this.tiles = {};
|
|
4026
4188
|
}
|
|
4027
4189
|
/**
|
|
4190
|
+
* @experimental
|
|
4191
|
+
* Sets how the image is warped onto its coordinates and re-renders the map.
|
|
4192
|
+
*
|
|
4193
|
+
* This only has an effect while the coordinates do not form a rectangle, and it is not part of
|
|
4194
|
+
* the style specification, so it does not survive `map.setStyle`.
|
|
4195
|
+
*
|
|
4196
|
+
* @param warp - The warp to use, see {@link ImageSourceWarp}.
|
|
4197
|
+
*
|
|
4198
|
+
* @example
|
|
4199
|
+
* ```ts
|
|
4200
|
+
* // Keep the image pinned to its corners while the user drags them around.
|
|
4201
|
+
* map.getSource('some id').setWarp('flat');
|
|
4202
|
+
* ```
|
|
4203
|
+
*/
|
|
4204
|
+
setWarp(warp) {
|
|
4205
|
+
if (this._warp === warp) return this;
|
|
4206
|
+
this._warp = warp;
|
|
4207
|
+
if (this.tileCoords) this.setCoordinates(this.coordinates);
|
|
4208
|
+
return this;
|
|
4209
|
+
}
|
|
4210
|
+
/**
|
|
4211
|
+
* @experimental
|
|
4212
|
+
* Returns how the image is warped onto its coordinates.
|
|
4213
|
+
*
|
|
4214
|
+
* @returns The warp in use, see {@link ImageSourceWarp}.
|
|
4215
|
+
*/
|
|
4216
|
+
getWarp() {
|
|
4217
|
+
return this._warp;
|
|
4218
|
+
}
|
|
4219
|
+
/**
|
|
4028
4220
|
* Sets the image's coordinates and re-renders the map.
|
|
4029
4221
|
*
|
|
4030
4222
|
* @param coordinates - Four geographical coordinates,
|
|
@@ -4039,7 +4231,8 @@ var ImageSource = class extends Evented {
|
|
|
4039
4231
|
this.terrainTileRanges = this._getOverlappingTileRanges(cornerCoords);
|
|
4040
4232
|
this.minzoom = this.maxzoom = this.tileID.z;
|
|
4041
4233
|
this.tileCoords = cornerCoords.map((coord) => this.tileID.getTilePoint(coord)._round());
|
|
4042
|
-
this.
|
|
4234
|
+
this.imageWarp = calculateImageWarp(this.tileCoords, this._warp);
|
|
4235
|
+
this._subdividedQuad = this.imageWarp[2] > 0 && !isParallelogram(this.tileCoords);
|
|
4043
4236
|
this.flippedWindingOrder = hasWrongWindingOrder(this.tileCoords);
|
|
4044
4237
|
this.fire(new MapSourceDataEvent("data", { sourceDataType: "content" }));
|
|
4045
4238
|
return this;
|
|
@@ -4137,13 +4330,11 @@ function hasWrongWindingOrder(coords) {
|
|
|
4137
4330
|
const e1x = coords[2].x - coords[0].x;
|
|
4138
4331
|
return e0x * (coords[2].y - coords[0].y) - e0y * e1x < 0;
|
|
4139
4332
|
}
|
|
4140
|
-
const perspectiveEpsilon = Number.EPSILON;
|
|
4141
|
-
const perspectiveErrorFactor = 8;
|
|
4142
4333
|
/**
|
|
4143
|
-
*
|
|
4144
|
-
*
|
|
4145
|
-
*
|
|
4146
|
-
*
|
|
4334
|
+
* How the image is warped onto its coordinates, given the corners in tile space and what the user
|
|
4335
|
+
* asked for. The projective warp is the perspective view of a plane, so it is the one a photograph
|
|
4336
|
+
* wants; the bilinear warp is a rubber sheet pinned at the corners, and is the only one left once
|
|
4337
|
+
* the corners stop describing a perspective view at all.
|
|
4147
4338
|
*
|
|
4148
4339
|
* Based on Paul S. Heckbert, "Fundamentals of Texture Mapping and Image
|
|
4149
4340
|
* Warping", UCB/CSD-89-516, 1989, section 2.2.3 and appendix A.2.
|
|
@@ -4151,68 +4342,50 @@ const perspectiveErrorFactor = 8;
|
|
|
4151
4342
|
* @see https://www2.eecs.berkeley.edu/Pubs/TechRpts/1989/5504.html
|
|
4152
4343
|
* @see https://www.cs.cmu.edu/~ph/texfund/texfund.pdf
|
|
4153
4344
|
*/
|
|
4154
|
-
function
|
|
4155
|
-
if (isParallelogram(cornerCoords)) return
|
|
4345
|
+
function calculateImageWarp(cornerCoords, warp) {
|
|
4346
|
+
if (warp === "flat" || isParallelogram(cornerCoords)) return bilinearImageWarp;
|
|
4156
4347
|
const [topLeft, topRight, bottomRight, bottomLeft] = cornerCoords;
|
|
4157
|
-
const
|
|
4158
|
-
const
|
|
4159
|
-
const
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
const perspectiveX = (sx * dy2 - dx2 * sy) / determinant$1;
|
|
4171
|
-
const perspectiveY = (dx1 * sy - sx * dy1) / determinant$1;
|
|
4172
|
-
const forwardDenominators = [
|
|
4348
|
+
const sumX = topLeft.x - topRight.x + bottomRight.x - bottomLeft.x;
|
|
4349
|
+
const sumY = topLeft.y - topRight.y + bottomRight.y - bottomLeft.y;
|
|
4350
|
+
const basis = [
|
|
4351
|
+
topRight.x - bottomRight.x,
|
|
4352
|
+
topRight.y - bottomRight.y,
|
|
4353
|
+
bottomLeft.x - bottomRight.x,
|
|
4354
|
+
bottomLeft.y - bottomRight.y
|
|
4355
|
+
];
|
|
4356
|
+
const [rightX, rightY, downX, downY] = basis;
|
|
4357
|
+
const determinant$1 = determinant(basis);
|
|
4358
|
+
const perspectiveX = (sumX * downY - downX * sumY) / determinant$1;
|
|
4359
|
+
const perspectiveY = (rightX * sumY - sumX * rightY) / determinant$1;
|
|
4360
|
+
const denominators = [
|
|
4173
4361
|
1,
|
|
4174
4362
|
1 + perspectiveX,
|
|
4175
4363
|
1 + perspectiveX + perspectiveY,
|
|
4176
4364
|
1 + perspectiveY
|
|
4177
4365
|
];
|
|
4178
|
-
const
|
|
4179
|
-
const
|
|
4180
|
-
if (!
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
const inverseDenominator = [
|
|
4186
|
-
0,
|
|
4187
|
-
0,
|
|
4188
|
-
0
|
|
4366
|
+
const foreshortening = Math.max(...denominators) / Math.min(...denominators);
|
|
4367
|
+
const blend = warp === "perspective" ? 0 : bilinearBlend(foreshortening);
|
|
4368
|
+
if (!(foreshortening >= 1 && foreshortening <= BILINEAR_FORESHORTENING) || blend >= 1) return bilinearImageWarp;
|
|
4369
|
+
return [
|
|
4370
|
+
perspectiveX,
|
|
4371
|
+
perspectiveY,
|
|
4372
|
+
blend
|
|
4189
4373
|
];
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
const
|
|
4200
|
-
|
|
4201
|
-
x,
|
|
4202
|
-
y,
|
|
4203
|
-
1
|
|
4204
|
-
]));
|
|
4205
|
-
const cornerDenominatorErrors = cornerCoords.map(({ x, y }) => perspectiveErrorFactor * perspectiveEpsilon * (Math.abs(inverseDenominator[0] * x) + Math.abs(inverseDenominator[1] * y) + Math.abs(inverseDenominator[2])));
|
|
4206
|
-
const denominatorScale = Math.max(...cornerDenominators.map((value) => Math.abs(value)));
|
|
4207
|
-
const denominatorSign = Math.sign(cornerDenominators[0]);
|
|
4208
|
-
const hasInvalidDenominator = cornerDenominators.some((value, index) => !Number.isFinite(value) || Math.abs(value) <= Math.max(perspectiveEpsilon * denominatorScale, cornerDenominatorErrors[index]) || Math.sign(value) !== denominatorSign);
|
|
4209
|
-
if (!Number.isFinite(normalizationScale) || normalizationScale === 0 || !Number.isFinite(denominatorScale) || denominatorScale === 0 || hasInvalidDenominator) return identityPerspectiveTransform;
|
|
4210
|
-
const transform = inverseDenominator.map((value) => value / normalizationScale);
|
|
4211
|
-
return transform.every(Number.isFinite) ? transform : identityPerspectiveTransform;
|
|
4374
|
+
}
|
|
4375
|
+
/**
|
|
4376
|
+
* How far a warp of the given foreshortening is blended towards the bilinear one, ramping from
|
|
4377
|
+
* purely projective at {@link PROJECTIVE_FORESHORTENING} to purely bilinear at
|
|
4378
|
+
* {@link BILINEAR_FORESHORTENING}. Blending rather than switching keeps the image continuous as the
|
|
4379
|
+
* quad is reshaped: the two warps only agree for a parallelogram, and diverge by roughly a tenth of
|
|
4380
|
+
* the quad per unit of foreshortening, so a switch would visibly displace the image.
|
|
4381
|
+
*/
|
|
4382
|
+
function bilinearBlend(foreshortening) {
|
|
4383
|
+
const ramp = (1 - PROJECTIVE_FORESHORTENING / foreshortening) / (1 - PROJECTIVE_FORESHORTENING / BILINEAR_FORESHORTENING);
|
|
4384
|
+
return Math.max(0, ramp);
|
|
4212
4385
|
}
|
|
4213
4386
|
function isParallelogram(cornerCoords) {
|
|
4214
|
-
const [
|
|
4215
|
-
return
|
|
4387
|
+
const [topLeft, topRight, bottomRight, bottomLeft] = cornerCoords;
|
|
4388
|
+
return topLeft.x + bottomRight.x === topRight.x + bottomLeft.x && topLeft.y + bottomRight.y === topRight.y + bottomLeft.y;
|
|
4216
4389
|
}
|
|
4217
4390
|
//#endregion
|
|
4218
4391
|
//#region src/source/video_source.ts
|
|
@@ -8604,7 +8777,7 @@ const shaders = {
|
|
|
8604
8777
|
lineSDF: prepare("uniform lowp float u_device_pixel_ratio;uniform lowp float u_lineatlas_width;uniform sampler2D u_image;uniform float u_mix;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float sdfdist_a=texture(u_image,v_tex_a).a;float sdfdist_b=texture(u_image,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0/u_device_pixel_ratio)/min(dasharray_from.w,dasharray_to.w);alpha*=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;flat out vec2 v_width2;out vec2 v_tex_a;out vec2 v_tex_b;out float v_gamma_scale;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define highp vec4 color\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize highp vec4 color\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nfloat u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}"),
|
|
8605
8778
|
lineGradientSDF: prepare("uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;uniform sampler2D u_image_dash;uniform float u_mix;uniform lowp float u_lineatlas_width;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;in highp vec2 v_uv;\n#ifdef GLOBE\nin float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nclipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);float sdfdist_a=texture(u_image_dash,v_tex_a).a;float sdfdist_b=texture(u_image_dash,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0)/min(dasharray_from.w,dasharray_to.w);float dash_alpha=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*dash_alpha*opacity);\n#ifdef GLOBE\nif (v_depth > 1.0) {discard;}\n#endif\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "\n#define scale 0.015873016\n#define LINE_DISTANCE_SCALE 2.0\nlayout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;layout(location=2) in float a_uv_x;layout(location=3) in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;out vec2 v_tex_a;out vec2 v_tex_b;\n#ifdef GLOBE\nout float v_depth;\n#endif\n#pragma maplibre: define lowp float blur\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define mediump float gapwidth\n#pragma maplibre: define lowp float offset\n#pragma maplibre: define mediump float width\n#pragma maplibre: define lowp float floorwidth\n#pragma maplibre: define mediump vec4 dasharray_from\n#pragma maplibre: define mediump vec4 dasharray_to\nvoid main() {\n#pragma maplibre: initialize lowp float blur\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize mediump float gapwidth\n#pragma maplibre: initialize lowp float offset\n#pragma maplibre: initialize mediump float width\n#pragma maplibre: initialize lowp float floorwidth\n#pragma maplibre: initialize mediump vec4 dasharray_from\n#pragma maplibre: initialize mediump vec4 dasharray_to\nif (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;float texel_height=1.0/u_image_height;float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\n#ifdef GLOBE\nv_depth=gl_Position.z/gl_Position.w;\n#endif\n#ifdef TERRAIN3D\nv_gamma_scale=1.0;\n#else\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\n#endif\nfloat u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}"),
|
|
8606
8779
|
layerOpacity: prepare("uniform sampler2D u_image;uniform float u_opacity;in vec2 v_pos;void main() {fragColor=texture(u_image,v_pos)*u_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(0.0);\n#endif\n}", "layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=vec4(a_pos.x*2.0-1.0,1.0-a_pos.y*2.0,0.0,1.0);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}"),
|
|
8607
|
-
raster: prepare("uniform float u_fade_t;uniform float u_opacity;uniform sampler2D u_image0;uniform sampler2D u_image1;in vec3 v_pos0;in vec3 v_pos1;uniform float u_brightness_low;uniform float u_brightness_high;uniform float u_saturation_factor;uniform float u_contrast_factor;uniform vec3 u_spin_weights;void main() {vec4 color0=texture(u_image0,v_pos0.xy/v_pos0.z);vec4 color1=texture(u_image1,v_pos1.xy/v_pos1.z);if (color0.a > 0.0) {color0.rgb=color0.rgb/color0.a;}if (color1.a > 0.0) {color1.rgb=color1.rgb/color1.a;}vec4 color=mix(color0,color1,u_fade_t);color.a*=u_opacity;vec3 rgb=color.rgb;rgb=vec3(dot(rgb,u_spin_weights.xyz),dot(rgb,u_spin_weights.zxy),dot(rgb,u_spin_weights.yzx));float average=(color.r+color.g+color.b)/3.0;rgb+=(average-rgb)*u_saturation_factor;rgb=(rgb-0.5)*u_contrast_factor+0.5;vec3 u_high_vec=vec3(u_brightness_low,u_brightness_low,u_brightness_low);vec3 u_low_vec=vec3(u_brightness_high,u_brightness_high,u_brightness_high);fragColor=vec4(mix(u_high_vec,u_low_vec,rgb)*color.a,color.a);\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_tl_parent;uniform float u_scale_parent;uniform float u_buffer_scale;uniform vec3
|
|
8780
|
+
raster: prepare("uniform float u_fade_t;uniform float u_opacity;uniform sampler2D u_image0;uniform sampler2D u_image1;in vec3 v_pos0;in vec3 v_pos1;uniform float u_brightness_low;uniform float u_brightness_high;uniform float u_saturation_factor;uniform float u_contrast_factor;uniform vec3 u_spin_weights;void main() {vec4 color0=texture(u_image0,v_pos0.xy/v_pos0.z);vec4 color1=texture(u_image1,v_pos1.xy/v_pos1.z);if (color0.a > 0.0) {color0.rgb=color0.rgb/color0.a;}if (color1.a > 0.0) {color1.rgb=color1.rgb/color1.a;}vec4 color=mix(color0,color1,u_fade_t);color.a*=u_opacity;vec3 rgb=color.rgb;rgb=vec3(dot(rgb,u_spin_weights.xyz),dot(rgb,u_spin_weights.zxy),dot(rgb,u_spin_weights.yzx));float average=(color.r+color.g+color.b)/3.0;rgb+=(average-rgb)*u_saturation_factor;rgb=(rgb-0.5)*u_contrast_factor+0.5;vec3 u_high_vec=vec3(u_brightness_low,u_brightness_low,u_brightness_low);vec3 u_low_vec=vec3(u_brightness_high,u_brightness_high,u_brightness_high);fragColor=vec4(mix(u_high_vec,u_low_vec,rgb)*color.a,color.a);\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "uniform vec2 u_tl_parent;uniform float u_scale_parent;uniform float u_buffer_scale;uniform vec3 u_image_warp;uniform vec4 u_coords_top;uniform vec4 u_coords_bottom;layout(location=0) in vec2 a_pos;out vec3 v_pos0;out vec3 v_pos1;void main() {vec2 fractionalPos=a_pos/8192.0;vec2 topLeft=u_coords_top.xy;vec2 topRight=u_coords_top.zw;vec2 bottomLeft=u_coords_bottom.xy;vec2 bottomRight=u_coords_bottom.zw;vec2 bilinearPos=mix(mix(topLeft,topRight,fractionalPos.x),mix(bottomLeft,bottomRight,fractionalPos.x),fractionalPos.y);float denominator=dot(u_image_warp.xy,fractionalPos)+1.0;vec2 acrossTop=topRight-topLeft+u_image_warp.x*topRight;vec2 downLeft=bottomLeft-topLeft+u_image_warp.y*bottomLeft;vec2 projectivePos=(acrossTop*fractionalPos.x+downLeft*fractionalPos.y+topLeft)/denominator;vec2 position=mix(projectivePos,bilinearPos,u_image_warp.z);gl_Position=projectTile(position,position);vec2 texturePos=((fractionalPos-0.5)/u_buffer_scale)+0.5;\n#ifdef GLOBE\nif (a_pos.y <-32767.5) {texturePos.y=0.0;}if (a_pos.y > 32766.5) {texturePos.y=1.0;}\n#endif\nfloat perspectiveRatio=mix(1.0/denominator,1.0,u_image_warp.z);v_pos0=vec3(texturePos*perspectiveRatio,perspectiveRatio);vec2 parentPos=(texturePos*u_scale_parent)+u_tl_parent;v_pos1=vec3(parentPos*perspectiveRatio,perspectiveRatio);}"),
|
|
8608
8781
|
symbolIcon: prepare("uniform sampler2D u_texture;in vec2 v_tex;flat in float v_total_opacity;void main() {fragColor=texture(u_texture,v_tex)*v_total_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec4 a_pixeloffset;layout(location=3) in vec3 a_projected_pos;layout(location=4) in uint a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform highp float u_camera_to_center_distance;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform float u_fade_change;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform vec2 u_texsize;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;out vec2 v_tex;flat out float v_total_opacity;\n#pragma maplibre: define lowp float opacity\nvoid main() {\n#pragma maplibre: initialize lowp float opacity\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);vec2 a_pxoffset=a_pixeloffset.xy;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float visibility=calculate_visibility(projectedPoint);v_total_opacity=opacity*max(0.0,min(visibility,fade_opacity[0]+fade_change));if (v_total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset/16.0)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}gl_Position=finalPos;v_tex=a_tex/u_texsize;}"),
|
|
8609
8782
|
symbolSDF: prepare("#define SDF_PX 8.0\nuniform bool u_is_halo;uniform bool u_is_plain;uniform sampler2D u_texture;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;uniform bool u_is_text;in vec2 v_data0;in vec3 v_data1;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nfloat EDGE_GAMMA=0.105/u_device_pixel_ratio;vec2 tex=v_data0.xy;float gamma_scale=v_data1.x;float size=v_data1.y;float total_opacity=v_data1[2];float fontScale=u_is_text ? size/24.0 : size;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float inner_edge=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out_text,color_alpha_out_halo;if (u_is_plain){highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(inner_edge-gamma_scaled,inner_edge+gamma_scaled,dist);color_alpha_out_text=total_opacity*alpha*fill_color;}if (u_is_halo) {float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);float inner_edge_halo=inner_edge+gamma_halo*gamma_scale;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(inner_edge_halo-gamma_scaled_halo,inner_edge_halo+gamma_scaled_halo,dist);highp float halo_edge=(6.0-halo_width/fontScale)/SDF_PX;alpha_halo= min(smoothstep(halo_edge-gamma_scaled_halo,halo_edge+gamma_scaled_halo,dist),1.0-alpha_halo);color_alpha_out_halo=total_opacity*alpha_halo*halo_color;}if (u_is_plain && u_is_halo) {fragColor=color_alpha_out_text+(1.-color_alpha_out_text.a)*color_alpha_out_halo;} else if (u_is_halo){fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out_text;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec4 a_pixeloffset;layout(location=3) in vec3 a_projected_pos;layout(location=4) in uint a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;out vec2 v_data0;out vec3 v_data1;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);vec2 a_pxoffset=a_pixeloffset.xy/16.0;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));float total_opacity=opacity*interpolated_fade_opacity;if (total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;v_data0=a_tex/u_texsize;v_data1=vec3(gamma_scale,size,total_opacity);}"),
|
|
8610
8783
|
symbolTextAndIcon: prepare("#define SDF_PX 8.0\n#define SDF 1.0\n#define ICON 0.0\nuniform bool u_is_halo;uniform bool u_is_text;uniform sampler2D u_texture;uniform sampler2D u_texture_icon;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;in vec4 v_data0;in vec3 v_data1;flat in float v_is_sdf;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nfloat total_opacity=v_data1[2];if (v_is_sdf==ICON) {vec2 tex_icon=v_data0.zw;fragColor=texture(u_texture_icon,tex_icon)*total_opacity;\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\nreturn;}vec2 tex=v_data0.xy;float EDGE_GAMMA=0.105/u_device_pixel_ratio;float gamma_scale=v_data1.x;float size=v_data1.y;float fontScale=size/24.0;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out,color_alpha_out_halo;if (u_is_text) {highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);color_alpha_out=fill_color*(alpha*total_opacity);}if (u_is_halo) {highp float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);lowp float buff_halo=(6.0-halo_width/fontScale)/SDF_PX;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(buff_halo-gamma_scaled_halo,buff_halo+gamma_scaled_halo,dist);color_alpha_out_halo=halo_color*(alpha_halo*total_opacity);}if (u_is_text && u_is_halo) {fragColor=color_alpha_out+(1.-color_alpha_out.a)*color_alpha_out_halo;} else if (u_is_halo) {fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out;}\n#ifdef OVERDRAW_INSPECTOR\nfragColor=vec4(1.0);\n#endif\n}", "layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec3 a_projected_pos;layout(location=3) in uint a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_texsize_icon;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;out vec4 v_data0;out vec3 v_data1;flat out float v_is_sdf;\n#pragma maplibre: define highp vec4 fill_color\n#pragma maplibre: define highp vec4 halo_color\n#pragma maplibre: define lowp float opacity\n#pragma maplibre: define lowp float halo_width\n#pragma maplibre: define lowp float halo_blur\nvoid main() {\n#pragma maplibre: initialize highp vec4 fill_color\n#pragma maplibre: initialize highp vec4 halo_color\n#pragma maplibre: initialize lowp float opacity\n#pragma maplibre: initialize lowp float halo_width\n#pragma maplibre: initialize lowp float halo_blur\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);float is_sdf=float(a_data.z & 1u);float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));float total_opacity=opacity*interpolated_fade_opacity;if (total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\ncamera_to_anchor_distance/u_camera_to_center_distance :\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=size/24.0;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\n#ifdef GLOBE\nif(u_pitch_with_map && !u_is_along_line) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\n#endif\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;v_data0.xy=a_tex/u_texsize;v_data0.zw=a_tex/u_texsize_icon;v_data1=vec3(gamma_scale,size,total_opacity);v_is_sdf=is_sdf;}"),
|
|
@@ -8696,30 +8869,6 @@ uniform ${precision} ${type} u_${name};
|
|
|
8696
8869
|
};
|
|
8697
8870
|
}
|
|
8698
8871
|
//#endregion
|
|
8699
|
-
//#region src/render/mesh.ts
|
|
8700
|
-
var Mesh = class {
|
|
8701
|
-
constructor(vertexBuffer, indexBuffer, segments) {
|
|
8702
|
-
this.vertexBuffer = vertexBuffer;
|
|
8703
|
-
this.indexBuffer = indexBuffer;
|
|
8704
|
-
this.segments = segments;
|
|
8705
|
-
}
|
|
8706
|
-
destroy() {
|
|
8707
|
-
this.vertexBuffer.destroy();
|
|
8708
|
-
this.indexBuffer.destroy();
|
|
8709
|
-
this.segments.destroy();
|
|
8710
|
-
this.vertexBuffer = null;
|
|
8711
|
-
this.indexBuffer = null;
|
|
8712
|
-
this.segments = null;
|
|
8713
|
-
}
|
|
8714
|
-
};
|
|
8715
|
-
//#endregion
|
|
8716
|
-
//#region src/data/pos_attributes.ts
|
|
8717
|
-
const posAttributes = createLayout([{
|
|
8718
|
-
name: "a_pos",
|
|
8719
|
-
type: "Int16",
|
|
8720
|
-
components: 2
|
|
8721
|
-
}]);
|
|
8722
|
-
//#endregion
|
|
8723
8872
|
//#region src/geo/projection/mercator_projection.ts
|
|
8724
8873
|
const MercatorShaderDefine = "#define PROJECTION_MERCATOR";
|
|
8725
8874
|
const MercatorShaderVariantKey = "mercator";
|
|
@@ -10626,103 +10775,6 @@ var MercatorCameraHelper = class {
|
|
|
10626
10775
|
let properties;
|
|
10627
10776
|
const getProperties = () => properties = properties || new Properties({ "type": new DataConstantProperty(latest["projection"]["type"], "type") });
|
|
10628
10777
|
//#endregion
|
|
10629
|
-
//#region src/util/create_tile_mesh.ts
|
|
10630
|
-
/**
|
|
10631
|
-
* The size of border region for stencil masks, in internal tile coordinates.
|
|
10632
|
-
* Used for globe rendering.
|
|
10633
|
-
*/
|
|
10634
|
-
const EXTENT_STENCIL_BORDER = EXTENT / 128;
|
|
10635
|
-
/**
|
|
10636
|
-
* @internal
|
|
10637
|
-
* Creates a mesh of a quad that covers the entire tile (covering positions in range 0..EXTENT),
|
|
10638
|
-
* is optionally subdivided into finer quads, optionally includes a border
|
|
10639
|
-
* and optionally extends to the north and/or special pole vertices.
|
|
10640
|
-
* Also allocates and populates WebGL buffers for the mesh.
|
|
10641
|
-
* Forces 16 bit indices that are used throughout MapLibre.
|
|
10642
|
-
* @param context - The WebGL context wrapper.
|
|
10643
|
-
* @param options - Specify options for tile mesh creation such as granularity or border.
|
|
10644
|
-
* @returns The mesh vertices and indices, already allocated and uploaded into WebGL buffers.
|
|
10645
|
-
*/
|
|
10646
|
-
function createTileMeshWithBuffers(context, options) {
|
|
10647
|
-
const tileMesh = createTileMesh(options, "16bit");
|
|
10648
|
-
const vertices = PosArray.deserialize({
|
|
10649
|
-
arrayBuffer: tileMesh.vertices,
|
|
10650
|
-
length: tileMesh.vertices.byteLength / 2 / 2
|
|
10651
|
-
});
|
|
10652
|
-
const indices = TriangleIndexArray.deserialize({
|
|
10653
|
-
arrayBuffer: tileMesh.indices,
|
|
10654
|
-
length: tileMesh.indices.byteLength / 2 / 3
|
|
10655
|
-
});
|
|
10656
|
-
return new Mesh(context.createVertexBuffer(vertices, posAttributes.members), context.createIndexBuffer(indices), SegmentVector.simpleSegment(0, 0, vertices.length, indices.length));
|
|
10657
|
-
}
|
|
10658
|
-
/**
|
|
10659
|
-
* Creates a mesh of a quad that covers the entire tile (covering positions in range 0..EXTENT),
|
|
10660
|
-
* is optionally subdivided into finer quads, optionally includes a border
|
|
10661
|
-
* and optionally extends to the north and/or special pole vertices.
|
|
10662
|
-
* Additionally the resulting mesh indices type can be specified using `forceIndicesSize`.
|
|
10663
|
-
* @example
|
|
10664
|
-
* ```
|
|
10665
|
-
* // Creating a mesh for a tile that can be used for raster layers, hillshade, etc.
|
|
10666
|
-
* const meshBuffers = createTileMesh({
|
|
10667
|
-
* granularity: map.style.projection.subdivisionGranularity.tile.getGranularityForZoomLevel(tileID.z),
|
|
10668
|
-
* generateBorders: true,
|
|
10669
|
-
* extendToNorthPole: tileID.y === 0,
|
|
10670
|
-
* extendToSouthPole: tileID.y === (1 << tileID.z) - 1,
|
|
10671
|
-
* }, '16bit');
|
|
10672
|
-
* ```
|
|
10673
|
-
* @see [Add a custom layer with tiles to a globe](https://maplibre.org/maplibre-gl-js/docs/examples/add-a-custom-layer-with-tiles-to-a-globe/)
|
|
10674
|
-
* @param options - Specify options for tile mesh creation such as granularity or border.
|
|
10675
|
-
* @param forceIndicesSize - Specifies what indices type to use. The values '32bit' and '16bit' force their respective indices size. If undefined, the mesh may use either size, and will pick 16 bit indices if possible. If '16bit' is specified and the mesh exceeds 65536 vertices, an exception is thrown.
|
|
10676
|
-
* @returns Typed arrays of the mesh vertices and indices.
|
|
10677
|
-
*/
|
|
10678
|
-
function createTileMesh(options, forceIndicesSize) {
|
|
10679
|
-
const granularity = options.granularity !== void 0 ? Math.max(options.granularity, 1) : 1;
|
|
10680
|
-
const quadsPerAxisX = granularity + (options.generateBorders ? 2 : 0);
|
|
10681
|
-
const quadsPerAxisY = granularity + (options.extendToNorthPole || options.generateBorders ? 1 : 0) + (options.extendToSouthPole || options.generateBorders ? 1 : 0);
|
|
10682
|
-
const verticesPerAxisX = quadsPerAxisX + 1;
|
|
10683
|
-
const verticesPerAxisY = quadsPerAxisY + 1;
|
|
10684
|
-
const offsetX = options.generateBorders ? -1 : 0;
|
|
10685
|
-
const offsetY = options.generateBorders || options.extendToNorthPole ? -1 : 0;
|
|
10686
|
-
const endX = granularity + (options.generateBorders ? 1 : 0);
|
|
10687
|
-
const endY = granularity + (options.generateBorders || options.extendToSouthPole ? 1 : 0);
|
|
10688
|
-
const vertexCount = verticesPerAxisX * verticesPerAxisY;
|
|
10689
|
-
const indexCount = quadsPerAxisX * quadsPerAxisY * 6;
|
|
10690
|
-
const overflows16bitIndices = verticesPerAxisX * verticesPerAxisY > 65536;
|
|
10691
|
-
if (overflows16bitIndices && forceIndicesSize === "16bit") throw new Error("Granularity is too large and meshes would not fit inside 16 bit vertex indices.");
|
|
10692
|
-
const use32bitIndices = overflows16bitIndices || forceIndicesSize === "32bit";
|
|
10693
|
-
const vertices = new Int16Array(vertexCount * 2);
|
|
10694
|
-
let vertexId = 0;
|
|
10695
|
-
for (let y = offsetY; y <= endY; y++) for (let x = offsetX; x <= endX; x++) {
|
|
10696
|
-
let vx = x / granularity * EXTENT;
|
|
10697
|
-
if (x === -1) vx = -EXTENT_STENCIL_BORDER;
|
|
10698
|
-
if (x === granularity + 1) vx = EXTENT + EXTENT_STENCIL_BORDER;
|
|
10699
|
-
let vy = y / granularity * EXTENT;
|
|
10700
|
-
if (y === -1) vy = options.extendToNorthPole ? NORTH_POLE_Y : -EXTENT_STENCIL_BORDER;
|
|
10701
|
-
if (y === granularity + 1) vy = options.extendToSouthPole ? SOUTH_POLE_Y : EXTENT + EXTENT_STENCIL_BORDER;
|
|
10702
|
-
vertices[vertexId++] = vx;
|
|
10703
|
-
vertices[vertexId++] = vy;
|
|
10704
|
-
}
|
|
10705
|
-
const indices = use32bitIndices ? new Uint32Array(indexCount) : new Uint16Array(indexCount);
|
|
10706
|
-
let indexId = 0;
|
|
10707
|
-
for (let y = 0; y < quadsPerAxisY; y++) for (let x = 0; x < quadsPerAxisX; x++) {
|
|
10708
|
-
const v0 = x + y * verticesPerAxisX;
|
|
10709
|
-
const v1 = x + 1 + y * verticesPerAxisX;
|
|
10710
|
-
const v2 = x + (y + 1) * verticesPerAxisX;
|
|
10711
|
-
const v3 = x + 1 + (y + 1) * verticesPerAxisX;
|
|
10712
|
-
indices[indexId++] = v0;
|
|
10713
|
-
indices[indexId++] = v2;
|
|
10714
|
-
indices[indexId++] = v1;
|
|
10715
|
-
indices[indexId++] = v1;
|
|
10716
|
-
indices[indexId++] = v2;
|
|
10717
|
-
indices[indexId++] = v3;
|
|
10718
|
-
}
|
|
10719
|
-
return {
|
|
10720
|
-
vertices: vertices.buffer.slice(0),
|
|
10721
|
-
indices: indices.buffer.slice(0),
|
|
10722
|
-
uses32bitIndices: use32bitIndices
|
|
10723
|
-
};
|
|
10724
|
-
}
|
|
10725
|
-
//#endregion
|
|
10726
10778
|
//#region src/geo/projection/vertical_perspective_projection.ts
|
|
10727
10779
|
const VerticalPerspectiveShaderDefine = "#define GLOBE";
|
|
10728
10780
|
const VerticalPerspectiveShaderVariantKey = "globe";
|
|
@@ -11043,11 +11095,12 @@ function versorSetLocationAtPoint(tr, lnglat, point, panDelta, fixedBearing = tr
|
|
|
11043
11095
|
const delta = l ? fromValues(w[1] / l * s, -w[0] / l * s, w[2] / l * s, Math.cos(t)) : fromValues(0, 0, 0, 1);
|
|
11044
11096
|
const { lng: newCenterLng, lat: newCenterLat, bearing: newBearing } = lngLatBearingFromOrientation(multiply$1(createVec4f64(), centerQuat, delta));
|
|
11045
11097
|
const oldLat = tr.center.lat;
|
|
11098
|
+
const oldZoom = tr.zoom;
|
|
11046
11099
|
const finalLat = clamp(newCenterLat, -90, 90);
|
|
11047
11100
|
const finalLng = fixedBearing ? fixedBearingLongitude(tr, point, panDelta, newCenterLng) : newCenterLng;
|
|
11048
11101
|
tr.setCenter(new LngLat(wrap(finalLng, -180, 180), finalLat));
|
|
11049
11102
|
if (!fixedBearing) tr.setBearing(newBearing);
|
|
11050
|
-
tr.setZoom(
|
|
11103
|
+
tr.setZoom(oldZoom + getZoomAdjustment(oldLat, tr.center.lat));
|
|
11051
11104
|
}
|
|
11052
11105
|
/**
|
|
11053
11106
|
* Returns the center longitude for a bearing-preserving drag.
|
|
@@ -12856,7 +12909,7 @@ var VerticalPerspectiveCameraHelper = class VerticalPerspectiveCameraHelper {
|
|
|
12856
12909
|
*/
|
|
12857
12910
|
handleMapControlsPan(deltas, tr, preZoomAroundLoc) {
|
|
12858
12911
|
if (!deltas.panDelta) return;
|
|
12859
|
-
versorSetLocationAtPoint(tr, preZoomAroundLoc, deltas.around, deltas.panDelta);
|
|
12912
|
+
versorSetLocationAtPoint(tr, preZoomAroundLoc, tr.isPointOnMapSurface(deltas.around) ? deltas.around : tr.centerPoint, deltas.panDelta);
|
|
12860
12913
|
}
|
|
12861
12914
|
cameraForBoxAndBearing(options, padding, bounds, bearing, tr) {
|
|
12862
12915
|
const result = cameraForBoxAndBearing(options, padding, bounds, bearing, tr);
|
|
@@ -17365,17 +17418,17 @@ function drawRaster(painter, tileManager, layer, tileIDs, renderOptions) {
|
|
|
17365
17418
|
const { isRenderingToTexture } = renderOptions;
|
|
17366
17419
|
const source = tileManager.getSource();
|
|
17367
17420
|
const useSubdivision = painter.style.projection.useSubdivision;
|
|
17368
|
-
if (source instanceof ImageSource) drawTiles(painter, tileManager, layer, tileIDs, null, false, false, source.tileCoords, source.
|
|
17421
|
+
if (source instanceof ImageSource) drawTiles(painter, tileManager, layer, tileIDs, null, false, false, source.tileCoords, source.imageWarp, source.flippedWindingOrder, isRenderingToTexture, source.getMesh(painter.context, useSubdivision));
|
|
17369
17422
|
else if (useSubdivision) {
|
|
17370
17423
|
const [stencilBorderless, stencilBorders, coords] = painter.stencilConfigForOverlapTwoPass(tileIDs);
|
|
17371
|
-
drawTiles(painter, tileManager, layer, coords, stencilBorderless, false, true, cornerCoords,
|
|
17372
|
-
drawTiles(painter, tileManager, layer, coords, stencilBorders, true, true, cornerCoords,
|
|
17424
|
+
drawTiles(painter, tileManager, layer, coords, stencilBorderless, false, true, cornerCoords, bilinearImageWarp, false, isRenderingToTexture);
|
|
17425
|
+
drawTiles(painter, tileManager, layer, coords, stencilBorders, true, true, cornerCoords, bilinearImageWarp, false, isRenderingToTexture);
|
|
17373
17426
|
} else {
|
|
17374
17427
|
const [stencil, coords] = painter.getStencilConfigForOverlapAndUpdateStencilID(tileIDs);
|
|
17375
|
-
drawTiles(painter, tileManager, layer, coords, stencil, false, true, cornerCoords,
|
|
17428
|
+
drawTiles(painter, tileManager, layer, coords, stencil, false, true, cornerCoords, bilinearImageWarp, false, isRenderingToTexture);
|
|
17376
17429
|
}
|
|
17377
17430
|
}
|
|
17378
|
-
function drawTiles(painter, tileManager, layer, coords, stencilModes, useBorder, allowPoles, corners,
|
|
17431
|
+
function drawTiles(painter, tileManager, layer, coords, stencilModes, useBorder, allowPoles, corners, imageWarp, flipCullfaceMode = false, isRenderingToTexture = false, sourceMesh = null) {
|
|
17379
17432
|
const minTileZ = coords[coords.length - 1].overscaledZ;
|
|
17380
17433
|
const context = painter.context;
|
|
17381
17434
|
const gl = context.gl;
|
|
@@ -17408,8 +17461,8 @@ function drawTiles(painter, tileManager, layer, coords, stencilModes, useBorder,
|
|
|
17408
17461
|
applyGlobeMatrix: !isRenderingToTexture,
|
|
17409
17462
|
applyTerrainMatrix: true
|
|
17410
17463
|
});
|
|
17411
|
-
const uniformValues = rasterUniformValues(parentTopLeft, parentScaleBy, fadeValues.fadeMix, layer, corners,
|
|
17412
|
-
const mesh = projection.getMeshFromTileID(context, coord.canonical, useBorder, allowPoles, "raster");
|
|
17464
|
+
const uniformValues = rasterUniformValues(parentTopLeft, parentScaleBy, fadeValues.fadeMix, layer, corners, imageWarp);
|
|
17465
|
+
const mesh = sourceMesh ?? projection.getMeshFromTileID(context, coord.canonical, useBorder, allowPoles, "raster");
|
|
17413
17466
|
const stencilMode = stencilModes ? stencilModes[coord.overscaledZ] : StencilMode.disabled;
|
|
17414
17467
|
program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, flipCullfaceMode ? CullFaceMode.frontCCW : CullFaceMode.backCCW, uniformValues, terrainData, projectionData, layer.id, mesh.vertexBuffer, mesh.indexBuffer, mesh.segments);
|
|
17415
17468
|
}
|