maplibre-gl
Version:
BSD licensed community fork of mapbox-gl, a WebGL interactive maps library
67 lines (58 loc) • 2.9 kB
text/typescript
import {Uniform1i, Uniform1f, Uniform2f} from '../uniform_binding';
import {pixelsToTileUnits} from '../../source/pixels_to_tile_units';
import type {Context} from '../../gl/context';
import type {UniformValues, UniformLocations} from '../uniform_binding';
import type {Tile} from '../../source/tile';
import type {CircleStyleLayer} from '../../style/style_layer/circle_style_layer';
import type {Painter} from '../painter';
import {EXTENT} from '../../data/extent';
export type CircleUniformsType = {
'u_camera_to_center_distance': Uniform1f;
'u_scale_with_map': Uniform1i;
'u_pitch_with_map': Uniform1i;
'u_extrude_scale': Uniform2f;
'u_device_pixel_ratio': Uniform1f;
'u_globe_extrude_scale': Uniform1f;
'u_translate': Uniform2f;
};
const circleUniforms = (context: Context, locations: UniformLocations): CircleUniformsType => ({
'u_camera_to_center_distance': new Uniform1f(context, locations.u_camera_to_center_distance),
'u_scale_with_map': new Uniform1i(context, locations.u_scale_with_map),
'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map),
'u_extrude_scale': new Uniform2f(context, locations.u_extrude_scale),
'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio),
'u_globe_extrude_scale': new Uniform1f(context, locations.u_globe_extrude_scale),
'u_translate': new Uniform2f(context, locations.u_translate),
});
const circleUniformValues = (
painter: Painter,
tile: Tile,
layer: CircleStyleLayer,
translate: [number, number],
radiusCorrectionFactor: number
): UniformValues<CircleUniformsType> => {
const transform = painter.transform;
let pitchWithMap: boolean, extrudeScale: [number, number];
let globeExtrudeScale: number = 0;
if (layer.paint.get('circle-pitch-alignment') === 'map') {
const pixelRatio = pixelsToTileUnits(tile, 1, transform.zoom);
pitchWithMap = true;
extrudeScale = [pixelRatio, pixelRatio];
// For globe rendering we need to know how much to extrude the circle as an *angle*.
// The calculation: (one pixel in tile units) / (earth circumference in tile units) * (2PI radians) * radiusCorrectionFactor
globeExtrudeScale = pixelRatio / (EXTENT * Math.pow(2, tile.tileID.overscaledZ)) * 2.0 * Math.PI * radiusCorrectionFactor;
} else {
pitchWithMap = false;
extrudeScale = transform.pixelsToGLUnits;
}
return {
'u_camera_to_center_distance': transform.cameraToCenterDistance,
'u_scale_with_map': +(layer.paint.get('circle-pitch-scale') === 'map'),
'u_pitch_with_map': +(pitchWithMap),
'u_device_pixel_ratio': painter.pixelRatio,
'u_extrude_scale': extrudeScale,
'u_globe_extrude_scale': globeExtrudeScale,
'u_translate': translate,
};
};
export {circleUniforms, circleUniformValues};