"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // dist/index.js var dist_exports = {}; __export(dist_exports, { BrushingExtension: () => brushing_extension_default, ClipExtension: () => clip_extension_default, CollisionFilterExtension: () => collision_filter_extension_default, DataFilterExtension: () => data_filter_extension_default, FillStyleExtension: () => fill_style_extension_default, Fp64Extension: () => fp64_extension_default, MaskExtension: () => mask_extension_default, PathStyleExtension: () => path_style_extension_default, _TerrainExtension: () => terrain_extension_default, project64: () => project64_default }); module.exports = __toCommonJS(dist_exports); // dist/brushing/brushing-extension.js var import_core2 = require("@deck.gl/core"); // dist/brushing/shader-module.js var import_core = require("@deck.gl/core"); var vs = ` uniform bool brushing_enabled; uniform int brushing_target; uniform vec2 brushing_mousePos; uniform float brushing_radius; in vec2 brushingTargets; out float brushing_isVisible; bool brushing_isPointInRange(vec2 position) { if (!brushing_enabled) { return true; } vec2 source_commonspace = project_position(position); vec2 target_commonspace = project_position(brushing_mousePos); float distance = length((target_commonspace - source_commonspace) / project_uCommonUnitsPerMeter.xy); return distance <= brushing_radius; } bool brushing_arePointsInRange(vec2 sourcePos, vec2 targetPos) { return brushing_isPointInRange(sourcePos) || brushing_isPointInRange(targetPos); } void brushing_setVisible(bool visible) { brushing_isVisible = float(visible); } `; var fs = ` uniform bool brushing_enabled; in float brushing_isVisible; `; var TARGET = { source: 0, target: 1, custom: 2, source_target: 3 }; var inject = { "vs:DECKGL_FILTER_GL_POSITION": ` vec2 brushingTarget; vec2 brushingSource; if (brushing_target == 3) { brushingTarget = geometry.worldPositionAlt.xy; brushingSource = geometry.worldPosition.xy; } else if (brushing_target == 0) { brushingTarget = geometry.worldPosition.xy; } else if (brushing_target == 1) { brushingTarget = geometry.worldPositionAlt.xy; } else { brushingTarget = brushingTargets; } bool visible; if (brushing_target == 3) { visible = brushing_arePointsInRange(brushingSource, brushingTarget); } else { visible = brushing_isPointInRange(brushingTarget); } brushing_setVisible(visible); `, "fs:DECKGL_FILTER_COLOR": ` if (brushing_enabled && brushing_isVisible < 0.5) { discard; } ` }; var shader_module_default = { name: "brushing", dependencies: [import_core.project], vs, fs, inject, getUniforms: (opts) => { if (!opts || !("viewport" in opts)) { return {}; } const { brushingEnabled = true, brushingRadius = 1e4, brushingTarget = "source", mousePosition, viewport } = opts; return { brushing_enabled: Boolean(brushingEnabled && mousePosition && viewport.containsPixel(mousePosition)), brushing_radius: brushingRadius, brushing_target: TARGET[brushingTarget] || 0, brushing_mousePos: mousePosition ? viewport.unproject([mousePosition.x - viewport.x, mousePosition.y - viewport.y]) : [0, 0] }; } }; // dist/brushing/brushing-extension.js var defaultProps = { getBrushingTarget: { type: "accessor", value: [0, 0] }, brushingTarget: "source", brushingEnabled: true, brushingRadius: 1e4 }; var BrushingExtension = class extends import_core2.LayerExtension { getShaders() { return { modules: [shader_module_default] }; } initializeState(context, extension) { const attributeManager = this.getAttributeManager(); if (attributeManager) { attributeManager.add({ brushingTargets: { size: 2, stepMode: "dynamic", accessor: "getBrushingTarget" } }); } const onMouseMove = () => { var _a; (_a = this.getCurrentLayer()) == null ? void 0 : _a.setNeedsRedraw(); }; this.state.onMouseMove = onMouseMove; if (context.deck) { context.deck.eventManager.on({ pointermove: onMouseMove, pointerleave: onMouseMove }); } } finalizeState(context, extension) { if (context.deck) { const onMouseMove = this.state.onMouseMove; context.deck.eventManager.off({ pointermove: onMouseMove, pointerleave: onMouseMove }); } } }; BrushingExtension.defaultProps = defaultProps; BrushingExtension.extensionName = "BrushingExtension"; var brushing_extension_default = BrushingExtension; // dist/data-filter/data-filter-extension.js var import_core3 = require("@deck.gl/core"); // dist/data-filter/shader-module.js var vs2 = ` uniform bool filter_useSoftMargin; uniform bool filter_enabled; uniform bool filter_transformSize; uniform ivec4 filter_categoryBitMask; #ifdef DATAFILTER_TYPE uniform DATAFILTER_TYPE filter_min; uniform DATAFILTER_TYPE filter_softMin; uniform DATAFILTER_TYPE filter_softMax; uniform DATAFILTER_TYPE filter_max; in DATAFILTER_TYPE filterValues; #ifdef DATAFILTER_DOUBLE in DATAFILTER_TYPE filterValues64Low; uniform DATAFILTER_TYPE filter_min64High; uniform DATAFILTER_TYPE filter_max64High; #endif #endif #ifdef DATACATEGORY_TYPE in DATACATEGORY_TYPE filterCategoryValues; #endif out float dataFilter_value; float dataFilter_reduceValue(float value) { return value; } float dataFilter_reduceValue(vec2 value) { return min(value.x, value.y); } float dataFilter_reduceValue(vec3 value) { return min(min(value.x, value.y), value.z); } float dataFilter_reduceValue(vec4 value) { return min(min(value.x, value.y), min(value.z, value.w)); } #ifdef DATAFILTER_TYPE void dataFilter_setValue(DATAFILTER_TYPE valueFromMin, DATAFILTER_TYPE valueFromMax) { if (filter_useSoftMargin) { DATAFILTER_TYPE leftInRange = mix( smoothstep(filter_min, filter_softMin, valueFromMin), step(filter_min, valueFromMin), step(filter_softMin, filter_min) ); DATAFILTER_TYPE rightInRange = mix( 1.0 - smoothstep(filter_softMax, filter_max, valueFromMax), step(valueFromMax, filter_max), step(filter_max, filter_softMax) ); dataFilter_value = dataFilter_reduceValue(leftInRange * rightInRange); } else { dataFilter_value = dataFilter_reduceValue( step(filter_min, valueFromMin) * step(valueFromMax, filter_max) ); } } #endif #ifdef DATACATEGORY_TYPE void dataFilter_setCategoryValue(DATACATEGORY_TYPE category) { #if DATACATEGORY_CHANNELS == 1 int dataFilter_masks = filter_categoryBitMask[int(category / 32.0)]; #elif DATACATEGORY_CHANNELS == 2 ivec2 dataFilter_masks = ivec2( filter_categoryBitMask[int(category.x / 32.0)], filter_categoryBitMask[int(category.y / 32.0) + 2] ); #elif DATACATEGORY_CHANNELS == 3 ivec3 dataFilter_masks = filter_categoryBitMask.xyz; #else ivec4 dataFilter_masks = filter_categoryBitMask; #endif DATACATEGORY_TYPE dataFilter_bits = DATACATEGORY_TYPE(dataFilter_masks) / pow(DATACATEGORY_TYPE(2.0), mod(category, 32.0)); dataFilter_bits = mod(floor(dataFilter_bits), 2.0); #if DATACATEGORY_CHANNELS == 1 if(dataFilter_bits == 0.0) dataFilter_value = 0.0; #else if(any(equal(dataFilter_bits, DATACATEGORY_TYPE(0.0)))) dataFilter_value = 0.0; #endif } #endif `; var fs2 = ` uniform bool filter_transformColor; in float dataFilter_value; `; function getUniforms(opts) { if (!opts || !("extensions" in opts)) { return {}; } const { filterRange = [-1, 1], filterEnabled = true, filterTransformSize = true, filterTransformColor = true } = opts; const filterSoftRange = opts.filterSoftRange || filterRange; return { ...Number.isFinite(filterRange[0]) ? { filter_min: filterRange[0], filter_softMin: filterSoftRange[0], filter_softMax: filterSoftRange[1], filter_max: filterRange[1] } : { filter_min: filterRange.map((r) => r[0]), filter_softMin: filterSoftRange.map((r) => r[0]), filter_softMax: filterSoftRange.map((r) => r[1]), filter_max: filterRange.map((r) => r[1]) }, filter_enabled: filterEnabled, filter_useSoftMargin: Boolean(opts.filterSoftRange), filter_transformSize: filterEnabled && filterTransformSize, filter_transformColor: filterEnabled && filterTransformColor }; } function getUniforms64(opts) { if (!opts || !("extensions" in opts)) { return {}; } const uniforms = getUniforms(opts); if (Number.isFinite(uniforms.filter_min)) { const min64High = Math.fround(uniforms.filter_min); uniforms.filter_min -= min64High; uniforms.filter_softMin -= min64High; uniforms.filter_min64High = min64High; const max64High = Math.fround(uniforms.filter_max); uniforms.filter_max -= max64High; uniforms.filter_softMax -= max64High; uniforms.filter_max64High = max64High; } else { const min64High = uniforms.filter_min.map(Math.fround); uniforms.filter_min = uniforms.filter_min.map((x, i) => x - min64High[i]); uniforms.filter_softMin = uniforms.filter_softMin.map((x, i) => x - min64High[i]); uniforms.filter_min64High = min64High; const max64High = uniforms.filter_max.map(Math.fround); uniforms.filter_max = uniforms.filter_max.map((x, i) => x - max64High[i]); uniforms.filter_softMax = uniforms.filter_softMax.map((x, i) => x - max64High[i]); uniforms.filter_max64High = max64High; } return uniforms; } var inject2 = { "vs:#main-start": ` dataFilter_value = 1.0; if (filter_enabled) { #ifdef DATAFILTER_TYPE #ifdef DATAFILTER_DOUBLE dataFilter_setValue( filterValues - filter_min64High + filterValues64Low, filterValues - filter_max64High + filterValues64Low ); #else dataFilter_setValue(filterValues, filterValues); #endif #endif #ifdef DATACATEGORY_TYPE dataFilter_setCategoryValue(filterCategoryValues); #endif } `, "vs:#main-end": ` if (dataFilter_value == 0.0) { gl_Position = vec4(0.); } `, "vs:DECKGL_FILTER_SIZE": ` if (filter_transformSize) { size = size * dataFilter_value; } `, "fs:DECKGL_FILTER_COLOR": ` if (dataFilter_value == 0.0) discard; if (filter_transformColor) { color.a *= dataFilter_value; } ` }; var shaderModule = { name: "data-filter", vs: vs2, fs: fs2, inject: inject2, getUniforms }; var shaderModule64 = { name: "data-filter-fp64", vs: vs2, fs: fs2, inject: inject2, getUniforms: getUniforms64 }; // dist/data-filter/aggregator.js var import_engine = require("@luma.gl/engine"); var import_constants = require("@luma.gl/constants"); var AGGREGATE_VS = `#version 300 es #define SHADER_NAME data-filter-vertex-shader #ifdef FLOAT_TARGET in float filterIndices; in float filterPrevIndices; #else in vec2 filterIndices; in vec2 filterPrevIndices; #endif out vec4 vColor; const float component = 1.0 / 255.0; void main() { #ifdef FLOAT_TARGET dataFilter_value *= float(filterIndices != filterPrevIndices); gl_Position = vec4(0.0, 0.0, 0.0, 1.0); vColor = vec4(0.0, 0.0, 0.0, 1.0); #else // Float texture is not supported: pack result into 4 channels x 256 px x 64px dataFilter_value *= float(filterIndices.x != filterPrevIndices.x); float col = filterIndices.x; float row = filterIndices.y * 4.0; float channel = floor(row); row = fract(row); vColor = component * vec4(bvec4(channel == 0.0, channel == 1.0, channel == 2.0, channel == 3.0)); gl_Position = vec4(col * 2.0 - 1.0, row * 2.0 - 1.0, 0.0, 1.0); #endif gl_PointSize = 1.0; } `; var AGGREGATE_FS = `#version 300 es #define SHADER_NAME data-filter-fragment-shader precision highp float; in vec4 vColor; out vec4 fragColor; void main() { if (dataFilter_value < 0.5) { discard; } fragColor = vColor; } `; var FLOAT_TARGET_FEATURES = [ "float32-renderable-webgl", "texture-blend-float-webgl" ]; function supportsFloatTarget(device) { return FLOAT_TARGET_FEATURES.every((feature) => device.features.has(feature)); } function getFramebuffer(device, useFloatTarget) { if (useFloatTarget) { return device.createFramebuffer({ width: 1, height: 1, colorAttachments: [ device.createTexture({ format: "rgba32float", type: 5126, mipmaps: false }) ] }); } return device.createFramebuffer({ width: 256, height: 64, colorAttachments: [device.createTexture({ format: "rgba8unorm", type: 5126, mipmaps: false })] }); } function getModel(device, shaderOptions, useFloatTarget) { shaderOptions.defines.NON_INSTANCED_MODEL = 1; if (useFloatTarget) { shaderOptions.defines.FLOAT_TARGET = 1; } return new import_engine.Model(device, { id: "data-filter-aggregation-model", vertexCount: 1, isInstanced: false, drawMode: 0, vs: AGGREGATE_VS, fs: AGGREGATE_FS, ...shaderOptions }); } var parameters = { blend: true, blendFunc: [1, 1, 1, 1], blendEquation: [32774, 32774], depthTest: false }; // dist/data-filter/data-filter-extension.js var defaultProps2 = { getFilterValue: { type: "accessor", value: 0 }, getFilterCategory: { type: "accessor", value: 0 }, onFilteredItemsChange: { type: "function", value: null, optional: true }, filterEnabled: true, filterRange: [-1, 1], filterSoftRange: null, filterCategories: [0], filterTransformSize: true, filterTransformColor: true }; var defaultOptions = { categorySize: 0, filterSize: 1, fp64: false, countItems: false }; var DATA_TYPE_FROM_SIZE = { 1: "float", 2: "vec2", 3: "vec3", 4: "vec4" }; var DataFilterExtension = class extends import_core3.LayerExtension { constructor(opts = {}) { super({ ...defaultOptions, ...opts }); } getShaders(extension) { const { categorySize, filterSize, fp64: fp642 } = extension.opts; const defines = {}; if (categorySize) { defines.DATACATEGORY_TYPE = DATA_TYPE_FROM_SIZE[categorySize]; defines.DATACATEGORY_CHANNELS = categorySize; } if (filterSize) { defines.DATAFILTER_TYPE = DATA_TYPE_FROM_SIZE[filterSize]; defines.DATAFILTER_DOUBLE = Boolean(fp642); } return { modules: [fp642 ? shaderModule64 : shaderModule], defines }; } initializeState(context, extension) { const attributeManager = this.getAttributeManager(); const { categorySize, filterSize, fp64: fp642 } = extension.opts; if (attributeManager) { if (filterSize) { attributeManager.add({ filterValues: { size: filterSize, type: fp642 ? "float64" : "float32", stepMode: "dynamic", accessor: "getFilterValue" } }); } if (categorySize) { attributeManager.add({ filterCategoryValues: { size: categorySize, stepMode: "dynamic", accessor: "getFilterCategory", transform: categorySize === 1 ? (d) => extension._getCategoryKey.call(this, d, 0) : (d) => d.map((x, i) => extension._getCategoryKey.call(this, x, i)) } }); } } const { device } = this.context; if (attributeManager && extension.opts.countItems) { const useFloatTarget = supportsFloatTarget(device); attributeManager.add({ filterIndices: { size: useFloatTarget ? 1 : 2, vertexOffset: 1, type: "unorm8", accessor: (object, { index }) => { const i = object && object.__source ? object.__source.index : index; return useFloatTarget ? (i + 1) % 255 : [(i + 1) % 255, Math.floor(i / 255) % 255]; }, shaderAttributes: { filterPrevIndices: { vertexOffset: 0 }, filterIndices: { vertexOffset: 1 } } } }); const filterFBO = getFramebuffer(device, useFloatTarget); const filterModel = getModel(device, extension.getShaders.call(this, extension), useFloatTarget); this.setState({ filterFBO, filterModel }); } } updateState({ props, oldProps, changeFlags }, extension) { var _a, _b; const attributeManager = this.getAttributeManager(); const { categorySize } = extension.opts; if (this.state.filterModel) { const filterNeedsUpdate = ((_a = attributeManager.attributes.filterValues) == null ? void 0 : _a.needsUpdate()) || ((_b = attributeManager.attributes.filterCategoryValues) == null ? void 0 : _b.needsUpdate()) || props.filterEnabled !== oldProps.filterEnabled || props.filterRange !== oldProps.filterRange || props.filterSoftRange !== oldProps.filterSoftRange || props.filterCategories !== oldProps.filterCategories; if (filterNeedsUpdate) { this.setState({ filterNeedsUpdate }); } } if (attributeManager == null ? void 0 : attributeManager.attributes.filterCategoryValues) { const categoryBitMaskNeedsUpdate = attributeManager.attributes.filterCategoryValues.needsUpdate() || !(0, import_core3._deepEqual)(props.filterCategories, oldProps.filterCategories, 2); if (categoryBitMaskNeedsUpdate) { this.setState({ categoryBitMask: null }); } const resetCategories = changeFlags.dataChanged; if (resetCategories) { this.setState({ categoryMap: Array(categorySize).fill(0).map(() => ({})) }); attributeManager.attributes.filterCategoryValues.setNeedsUpdate("categoryMap"); } } } draw(params, extension) { const filterFBO = this.state.filterFBO; const filterModel = this.state.filterModel; const filterNeedsUpdate = this.state.filterNeedsUpdate; const { onFilteredItemsChange } = this.props; if (!this.state.categoryBitMask) { extension._updateCategoryBitMask.call(this, params, extension); } params.uniforms.filter_categoryBitMask = this.state.categoryBitMask; if (filterNeedsUpdate && onFilteredItemsChange && filterModel) { const { attributes: { filterValues, filterCategoryValues, filterIndices } } = this.getAttributeManager(); filterModel.setVertexCount(this.getNumInstances()); this.context.device.clearWebGL({ framebuffer: filterFBO, color: [0, 0, 0, 0] }); filterModel.updateModuleSettings(params.moduleParameters); filterModel.setAttributes({ ...filterValues == null ? void 0 : filterValues.getValue(), ...filterCategoryValues == null ? void 0 : filterCategoryValues.getValue(), ...filterIndices == null ? void 0 : filterIndices.getValue() }); filterModel.setUniforms(params.uniforms); filterModel.device.withParametersWebGL({ framebuffer: filterFBO, ...parameters, viewport: [0, 0, filterFBO.width, filterFBO.height] }, () => { filterModel.draw(this.context.renderPass); }); const color = filterModel.device.readPixelsToArrayWebGL(filterFBO); let count = 0; for (let i = 0; i < color.length; i++) { count += color[i]; } onFilteredItemsChange({ id: this.id, count }); this.state.filterNeedsUpdate = false; } } finalizeState() { const filterFBO = this.state.filterFBO; const filterModel = this.state.filterModel; filterFBO == null ? void 0 : filterFBO.destroy(); filterModel == null ? void 0 : filterModel.destroy(); } _updateCategoryBitMask(params, extension) { const { categorySize } = extension.opts; if (!categorySize) return; const { filterCategories } = this.props; const categoryBitMask = new Uint32Array([0, 0, 0, 0]); const categoryFilters = categorySize === 1 ? [filterCategories] : filterCategories; const maxCategories = categorySize === 1 ? 128 : categorySize === 2 ? 64 : 32; for (let c = 0; c < categoryFilters.length; c++) { const categoryFilter = categoryFilters[c]; for (const category of categoryFilter) { const key = extension._getCategoryKey.call(this, category, c); if (key < maxCategories) { const channel = c * (maxCategories / 32) + Math.floor(key / 32); categoryBitMask[channel] += Math.pow(2, key % 32); } else { import_core3.log.warn(`Exceeded maximum number of categories (${maxCategories})`)(); } } } this.state.categoryBitMask = categoryBitMask; } _getCategoryKey(category, channel) { const categoryMap = this.state.categoryMap[channel]; if (!(category in categoryMap)) { categoryMap[category] = Object.keys(categoryMap).length; } return categoryMap[category]; } }; DataFilterExtension.defaultProps = defaultProps2; DataFilterExtension.extensionName = "DataFilterExtension"; var data_filter_extension_default = DataFilterExtension; // dist/fp64/fp64-extension.js var import_core5 = require("@deck.gl/core"); // dist/fp64/project64.js var import_shadertools = require("@luma.gl/shadertools"); var import_core4 = require("@deck.gl/core"); // dist/fp64/project64.glsl.js var project64_glsl_default = `const vec2 WORLD_SCALE_FP64 = vec2(81.4873275756836, 0.0000032873668232014097); uniform vec2 project_uViewProjectionMatrixFP64[16]; void mercatorProject_fp64(vec4 lnglat_fp64, out vec2 out_val[2]) { #if defined(NVIDIA_FP64_WORKAROUND) out_val[0] = sum_fp64(radians_fp64(lnglat_fp64.xy), PI_FP64 * ONE); #else out_val[0] = sum_fp64(radians_fp64(lnglat_fp64.xy), PI_FP64); #endif out_val[1] = sum_fp64(PI_FP64, log_fp64(tan_fp64(sum_fp64(PI_4_FP64, radians_fp64(lnglat_fp64.zw) / 2.0)))); return; } void project_position_fp64(vec4 position_fp64, out vec2 out_val[2]) { vec2 pos_fp64[2]; mercatorProject_fp64(position_fp64, pos_fp64); out_val[0] = mul_fp64(pos_fp64[0], WORLD_SCALE_FP64); out_val[1] = mul_fp64(pos_fp64[1], WORLD_SCALE_FP64); return; } void project_position_fp64(vec2 position, vec2 position64xyLow, out vec2 out_val[2]) { vec4 position64xy = vec4( position.x, position64xyLow.x, position.y, position64xyLow.y); project_position_fp64(position64xy, out_val); } vec4 project_common_position_to_clipspace_fp64(vec2 vertex_pos_modelspace[4]) { vec2 vertex_pos_clipspace[4]; mat4_vec4_mul_fp64(project_uViewProjectionMatrixFP64, vertex_pos_modelspace, vertex_pos_clipspace); return vec4( vertex_pos_clipspace[0].x, vertex_pos_clipspace[1].x, vertex_pos_clipspace[2].x, vertex_pos_clipspace[3].x ); } vec4 project_position_to_clipspace( vec3 position, vec3 position64xyLow, vec3 offset, out vec4 commonPosition ) { vec2 offset64[4]; vec4_fp64(vec4(offset, 0.0), offset64); float z = project_size(position.z); vec2 projectedPosition64xy[2]; project_position_fp64(position.xy, position64xyLow.xy, projectedPosition64xy); vec2 commonPosition64[4]; commonPosition64[0] = sum_fp64(offset64[0], projectedPosition64xy[0]); commonPosition64[1] = sum_fp64(offset64[1], projectedPosition64xy[1]); commonPosition64[2] = sum_fp64(offset64[2], vec2(z, 0.0)); commonPosition64[3] = vec2(1.0, 0.0); commonPosition = vec4(projectedPosition64xy[0].x, projectedPosition64xy[1].x, z, 1.0); return project_common_position_to_clipspace_fp64(commonPosition64); } vec4 project_position_to_clipspace( vec3 position, vec3 position64xyLow, vec3 offset ) { vec4 commonPosition; return project_position_to_clipspace( position, position64xyLow, offset, commonPosition ); } `; // dist/fp64/project64.js var { fp64ify, fp64ifyMatrix4 } = import_shadertools.fp64; var project64_default = { name: "project64", dependencies: [import_core4.project, import_shadertools.fp64], vs: project64_glsl_default, getUniforms: getUniforms2 }; var getMemoizedUniforms = (0, import_core4._memoize)(calculateUniforms); function getUniforms2(opts) { if (opts && "viewport" in opts) { const { viewProjectionMatrix, scale } = opts.viewport; return getMemoizedUniforms({ viewProjectionMatrix, scale }); } return {}; } function calculateUniforms({ viewProjectionMatrix, scale }) { const glViewProjectionMatrixFP64 = fp64ifyMatrix4(viewProjectionMatrix); const scaleFP64 = fp64ify(scale); return { project_uViewProjectionMatrixFP64: glViewProjectionMatrixFP64, project64_uViewProjectionMatrix: glViewProjectionMatrixFP64, project64_uScale: scaleFP64 }; } // dist/fp64/fp64-extension.js var Fp64Extension = class extends import_core5.LayerExtension { getShaders() { const { coordinateSystem } = this.props; if (coordinateSystem !== import_core5.COORDINATE_SYSTEM.LNGLAT && coordinateSystem !== import_core5.COORDINATE_SYSTEM.DEFAULT) { throw new Error("fp64: coordinateSystem must be LNGLAT"); } return { modules: [project64_default] }; } }; Fp64Extension.extensionName = "Fp64Extension"; var fp64_extension_default = Fp64Extension; // dist/path-style/path-style-extension.js var import_core6 = require("@deck.gl/core"); var import_core7 = require("@math.gl/core"); // dist/path-style/shaders.glsl.js var dashShaders = { inject: { "vs:#decl": ` in vec2 instanceDashArrays; in float instanceDashOffsets; out vec2 vDashArray; out float vDashOffset; `, "vs:#main-end": ` vDashArray = instanceDashArrays; vDashOffset = instanceDashOffsets / width.x; `, "fs:#decl": ` uniform float dashAlignMode; uniform float capType; uniform bool dashGapPickable; in vec2 vDashArray; in float vDashOffset; `, "fs:#main-start": ` float solidLength = vDashArray.x; float gapLength = vDashArray.y; float unitLength = solidLength + gapLength; float offset; if (unitLength > 0.0) { if (dashAlignMode == 0.0) { offset = vDashOffset; } else { unitLength = vPathLength / round(vPathLength / unitLength); offset = solidLength / 2.0; } float unitOffset = mod(vPathPosition.y + offset, unitLength); if (gapLength > 0.0 && unitOffset > solidLength) { if (capType <= 0.5) { if (!(dashGapPickable && bool(picking.isActive))) { discard; } } else { float distToEnd = length(vec2( min(unitOffset - solidLength, unitLength - unitOffset), vPathPosition.x )); if (distToEnd > 1.0) { if (!(dashGapPickable && bool(picking.isActive))) { discard; } } } } } ` } }; var offsetShaders = { inject: { "vs:#decl": ` in float instanceOffsets; `, "vs:DECKGL_FILTER_SIZE": ` float offsetWidth = abs(instanceOffsets * 2.0) + 1.0; size *= offsetWidth; `, "vs:#main-end": ` float offsetWidth = abs(instanceOffsets * 2.0) + 1.0; float offsetDir = sign(instanceOffsets); vPathPosition.x = (vPathPosition.x + offsetDir) * offsetWidth - offsetDir; vPathPosition.y *= offsetWidth; vPathLength *= offsetWidth; `, "fs:#main-start": ` float isInside; isInside = step(-1.0, vPathPosition.x) * step(vPathPosition.x, 1.0); if (isInside == 0.0) { discard; } ` } }; // dist/path-style/path-style-extension.js var defaultProps3 = { getDashArray: { type: "accessor", value: [0, 0] }, getOffset: { type: "accessor", value: 0 }, dashJustified: false, dashGapPickable: false }; var PathStyleExtension = class extends import_core6.LayerExtension { constructor({ dash = false, offset = false, highPrecisionDash = false } = {}) { super({ dash: dash || highPrecisionDash, offset, highPrecisionDash }); } isEnabled(layer) { return "pathTesselator" in layer.state; } getShaders(extension) { if (!extension.isEnabled(this)) { return null; } let result = {}; if (extension.opts.dash) { result = (0, import_core6._mergeShaders)(result, dashShaders); } if (extension.opts.offset) { result = (0, import_core6._mergeShaders)(result, offsetShaders); } return result; } initializeState(context, extension) { const attributeManager = this.getAttributeManager(); if (!attributeManager || !extension.isEnabled(this)) { return; } if (extension.opts.dash) { attributeManager.addInstanced({ instanceDashArrays: { size: 2, accessor: "getDashArray" }, instanceDashOffsets: extension.opts.highPrecisionDash ? { size: 1, accessor: "getPath", transform: extension.getDashOffsets.bind(this) } : { size: 1, update: (attribute) => { attribute.constant = true; attribute.value = [0]; } } }); } if (extension.opts.offset) { attributeManager.addInstanced({ instanceOffsets: { size: 1, accessor: "getOffset" } }); } } updateState(params, extension) { var _a; if (!extension.isEnabled(this)) { return; } const uniforms = {}; if (extension.opts.dash) { uniforms.dashAlignMode = this.props.dashJustified ? 1 : 0; uniforms.dashGapPickable = Boolean(this.props.dashGapPickable); } (_a = this.state.model) == null ? void 0 : _a.setUniforms(uniforms); } getDashOffsets(path) { const result = [0]; const positionSize = this.props.positionFormat === "XY" ? 2 : 3; const isNested = Array.isArray(path[0]); const geometrySize = isNested ? path.length : path.length / positionSize; let p; let prevP; for (let i = 0; i < geometrySize - 1; i++) { p = isNested ? path[i] : path.slice(i * positionSize, i * positionSize + positionSize); p = this.projectPosition(p); if (i > 0) { result[i] = result[i - 1] + import_core7.vec3.dist(prevP, p); } prevP = p; } result[geometrySize - 1] = 0; return result; } }; PathStyleExtension.defaultProps = defaultProps3; PathStyleExtension.extensionName = "PathStyleExtension"; var path_style_extension_default = PathStyleExtension; // dist/fill-style/fill-style-extension.js var import_core9 = require("@deck.gl/core"); // dist/fill-style/shader-module.js var import_core8 = require("@deck.gl/core"); var patternVs = ` in vec4 fillPatternFrames; in float fillPatternScales; in vec2 fillPatternOffsets; uniform bool fill_patternEnabled; uniform vec2 fill_patternTextureSize; out vec2 fill_uv; out vec4 fill_patternBounds; out vec4 fill_patternPlacement; `; var patternFs = ` uniform bool fill_patternEnabled; uniform bool fill_patternMask; uniform sampler2D fill_patternTexture; uniform vec2 fill_uvCoordinateOrigin; uniform vec2 fill_uvCoordinateOrigin64Low; in vec4 fill_patternBounds; in vec4 fill_patternPlacement; in vec2 fill_uv; const float FILL_UV_SCALE = 512.0 / 40000000.0; `; var inject3 = { "vs:DECKGL_FILTER_GL_POSITION": ` fill_uv = geometry.position.xy; `, "vs:DECKGL_FILTER_COLOR": ` if (fill_patternEnabled) { fill_patternBounds = fillPatternFrames / vec4(fill_patternTextureSize, fill_patternTextureSize); fill_patternPlacement.xy = fillPatternOffsets; fill_patternPlacement.zw = fillPatternScales * fillPatternFrames.zw; } `, "fs:DECKGL_FILTER_COLOR": ` if (fill_patternEnabled) { vec2 scale = FILL_UV_SCALE * fill_patternPlacement.zw; vec2 patternUV = mod(mod(fill_uvCoordinateOrigin, scale) + fill_uvCoordinateOrigin64Low + fill_uv, scale) / scale; patternUV = mod(fill_patternPlacement.xy + patternUV, 1.0); vec2 texCoords = fill_patternBounds.xy + fill_patternBounds.zw * patternUV; vec4 patternColor = texture(fill_patternTexture, texCoords); color.a *= patternColor.a; if (!fill_patternMask) { color.rgb = patternColor.rgb; } } ` }; function getPatternUniforms(opts, uniforms) { if (!opts) { return {}; } if ("fillPatternTexture" in opts) { const { fillPatternTexture } = opts; return { fill_patternTexture: fillPatternTexture, fill_patternTextureSize: [fillPatternTexture.width, fillPatternTexture.height] }; } if ("viewport" in opts) { const { fillPatternMask = true, fillPatternEnabled = true } = opts; const { project_uCommonOrigin: coordinateOriginCommon } = uniforms; const coordinateOriginCommon64Low = [ (0, import_core8.fp64LowPart)(coordinateOriginCommon[0]), (0, import_core8.fp64LowPart)(coordinateOriginCommon[1]) ]; return { fill_uvCoordinateOrigin: coordinateOriginCommon.slice(0, 2), fill_uvCoordinateOrigin64Low: coordinateOriginCommon64Low, fill_patternMask: fillPatternMask, fill_patternEnabled: fillPatternEnabled }; } return {}; } var patternShaders = { name: "fill-pattern", vs: patternVs, fs: patternFs, inject: inject3, dependencies: [import_core8.project], getUniforms: getPatternUniforms }; // dist/fill-style/fill-style-extension.js var defaultProps4 = { fillPatternEnabled: true, fillPatternAtlas: { type: "image", value: null, async: true, parameters: { lodMaxClamp: 0 } }, fillPatternMapping: { type: "object", value: {}, async: true }, fillPatternMask: true, getFillPattern: { type: "accessor", value: (d) => d.pattern }, getFillPatternScale: { type: "accessor", value: 1 }, getFillPatternOffset: { type: "accessor", value: [0, 0] } }; var FillStyleExtension = class extends import_core9.LayerExtension { constructor({ pattern = false } = {}) { super({ pattern }); } isEnabled(layer) { return layer.getAttributeManager() !== null && !("pathTesselator" in layer.state); } getShaders(extension) { if (!extension.isEnabled(this)) { return null; } return { modules: [extension.opts.pattern && patternShaders].filter(Boolean) }; } initializeState(context, extension) { if (!extension.isEnabled(this)) { return; } const attributeManager = this.getAttributeManager(); if (extension.opts.pattern) { attributeManager.add({ fillPatternFrames: { size: 4, stepMode: "dynamic", accessor: "getFillPattern", transform: extension.getPatternFrame.bind(this) }, fillPatternScales: { size: 1, stepMode: "dynamic", accessor: "getFillPatternScale", defaultValue: 1 }, fillPatternOffsets: { size: 2, stepMode: "dynamic", accessor: "getFillPatternOffset" } }); } this.setState({ emptyTexture: this.context.device.createTexture({ data: new Uint8Array(4), width: 1, height: 1 }) }); } updateState({ props, oldProps }, extension) { if (!extension.isEnabled(this)) { return; } if (props.fillPatternMapping && props.fillPatternMapping !== oldProps.fillPatternMapping) { this.getAttributeManager().invalidate("getFillPattern"); } } draw(params, extension) { if (!extension.isEnabled(this)) { return; } const { fillPatternAtlas } = this.props; this.setModuleParameters({ fillPatternTexture: fillPatternAtlas || this.state.emptyTexture }); } finalizeState() { const emptyTexture = this.state.emptyTexture; emptyTexture == null ? void 0 : emptyTexture.delete(); } getPatternFrame(name) { const { fillPatternMapping } = this.getCurrentLayer().props; const def = fillPatternMapping && fillPatternMapping[name]; return def ? [def.x, def.y, def.width, def.height] : [0, 0, 0, 0]; } }; FillStyleExtension.defaultProps = defaultProps4; FillStyleExtension.extensionName = "FillStyleExtension"; var fill_style_extension_default = FillStyleExtension; // dist/clip/clip-extension.js var import_core10 = require("@deck.gl/core"); var defaultProps5 = { clipBounds: [0, 0, 1, 1], clipByInstance: void 0 }; var shaderFunction = ` uniform vec4 clip_bounds; bool clip_isInBounds(vec2 position) { return position.x >= clip_bounds[0] && position.y >= clip_bounds[1] && position.x < clip_bounds[2] && position.y < clip_bounds[3]; } `; var shaderModuleVs = { name: "clip-vs", vs: shaderFunction }; var injectionVs = { "vs:#decl": ` out float clip_isVisible; `, "vs:DECKGL_FILTER_GL_POSITION": ` clip_isVisible = float(clip_isInBounds(geometry.worldPosition.xy)); `, "fs:#decl": ` in float clip_isVisible; `, "fs:DECKGL_FILTER_COLOR": ` if (clip_isVisible < 0.5) discard; ` }; var shaderModuleFs = { name: "clip-fs", fs: shaderFunction }; var injectionFs = { "vs:#decl": ` out vec2 clip_commonPosition; `, "vs:DECKGL_FILTER_GL_POSITION": ` clip_commonPosition = geometry.position.xy; `, "fs:#decl": ` in vec2 clip_commonPosition; `, "fs:DECKGL_FILTER_COLOR": ` if (!clip_isInBounds(clip_commonPosition)) discard; ` }; var ClipExtension = class extends import_core10.LayerExtension { getShaders() { let clipByInstance = "instancePositions" in this.getAttributeManager().attributes; if (this.props.clipByInstance !== void 0) { clipByInstance = Boolean(this.props.clipByInstance); } this.state.clipByInstance = clipByInstance; return clipByInstance ? { modules: [shaderModuleVs], inject: injectionVs } : { modules: [shaderModuleFs], inject: injectionFs }; } draw({ uniforms }) { const { clipBounds } = this.props; if (this.state.clipByInstance) { uniforms.clip_bounds = clipBounds; } else { const corner0 = this.projectPosition([clipBounds[0], clipBounds[1], 0]); const corner1 = this.projectPosition([clipBounds[2], clipBounds[3], 0]); uniforms.clip_bounds = [ Math.min(corner0[0], corner1[0]), Math.min(corner0[1], corner1[1]), Math.max(corner0[0], corner1[0]), Math.max(corner0[1], corner1[1]) ]; } } }; ClipExtension.defaultProps = defaultProps5; ClipExtension.extensionName = "ClipExtension"; var clip_extension_default = ClipExtension; // dist/collision-filter/collision-filter-extension.js var import_core15 = require("@deck.gl/core"); // dist/collision-filter/shader-module.js var import_core11 = require("@deck.gl/core"); var vs3 = ` in float collisionPriorities; uniform sampler2D collision_texture; uniform bool collision_sort; uniform bool collision_enabled; vec2 collision_getCoords(vec4 position) { vec4 collision_clipspace = project_common_position_to_clipspace(position); return (1.0 + collision_clipspace.xy / collision_clipspace.w) / 2.0; } float collision_match(vec2 tex, vec3 pickingColor) { vec4 collision_pickingColor = texture(collision_texture, tex); float delta = dot(abs(collision_pickingColor.rgb - pickingColor), vec3(1.0)); float e = 0.001; return step(delta, e); } float collision_isVisible(vec2 texCoords, vec3 pickingColor) { if (!collision_enabled) { return 1.0; } const int N = 2; float accumulator = 0.0; vec2 step = vec2(1.0 / project_uViewportSize); const float floatN = float(N); vec2 delta = -floatN * step; for(int i = -N; i <= N; i++) { delta.x = -step.x * floatN; for(int j = -N; j <= N; j++) { accumulator += collision_match(texCoords + delta, pickingColor); delta.x += step.x; } delta.y += step.y; } float W = 2.0 * floatN + 1.0; return pow(accumulator / (W * W), 2.2); } `; var inject4 = { "vs:#decl": ` float collision_fade = 1.0; `, "vs:DECKGL_FILTER_GL_POSITION": ` if (collision_sort) { float collisionPriority = collisionPriorities; position.z = -0.001 * collisionPriority * position.w; } if (collision_enabled) { vec4 collision_common_position = project_position(vec4(geometry.worldPosition, 1.0)); vec2 collision_texCoords = collision_getCoords(collision_common_position); collision_fade = collision_isVisible(collision_texCoords, geometry.pickingColor / 255.0); if (collision_fade < 0.0001) { position = vec4(0.0, 0.0, 2.0, 1.0); } } `, "vs:DECKGL_FILTER_COLOR": ` color.a *= collision_fade; ` }; var getCollisionUniforms = (opts, uniforms) => { if (!opts || !("dummyCollisionMap" in opts)) { return {}; } const { collisionFBO, drawToCollisionMap, dummyCollisionMap } = opts; return { collision_sort: Boolean(drawToCollisionMap), collision_texture: !drawToCollisionMap && collisionFBO ? collisionFBO.colorAttachments[0] : dummyCollisionMap }; }; var shader_module_default2 = { name: "collision", dependencies: [import_core11.project], vs: vs3, inject: inject4, getUniforms: getCollisionUniforms }; // dist/collision-filter/collision-filter-effect.js var import_core13 = require("@math.gl/core"); var import_core14 = require("@deck.gl/core"); // dist/collision-filter/collision-filter-pass.js var import_core12 = require("@deck.gl/core"); var CollisionFilterPass = class extends import_core12._LayersPass { renderCollisionMap(target, options) { const padding = 1; const clearColor = [0, 0, 0, 0]; const scissorRect = [padding, padding, target.width - 2 * padding, target.height - 2 * padding]; this.render({ ...options, clearColor, scissorRect, target, pass: "collision" }); } getLayerParameters(layer, layerIndex, viewport) { return { ...layer.props.parameters, blend: false, depthRange: [0, 1], depthTest: true }; } getModuleParameters() { return { drawToCollisionMap: true, picking: { isActive: 1, isAttribute: false }, lightSources: {} }; } }; // dist/collision-filter/collision-filter-effect.js var DOWNSCALE = 2; var CollisionFilterEffect = class { constructor() { this.id = "collision-filter-effect"; this.props = null; this.useInPicking = true; this.order = 1; this.channels = {}; this.collisionFBOs = {}; } setup(context) { this.context = context; const { device } = context; this.dummyCollisionMap = device.createTexture({ width: 1, height: 1 }); this.collisionFilterPass = new CollisionFilterPass(device, { id: "default-collision-filter" }); } preRender({ effects: allEffects, layers, layerFilter, viewports, onViewportActive, views, isPicking, preRenderStats = {} }) { var _a; const { device } = this.context; if (isPicking) { return; } const collisionLayers = layers.filter( ({ props: { visible, collisionEnabled } }) => visible && collisionEnabled ); if (collisionLayers.length === 0) { this.channels = {}; return; } const effects = allEffects == null ? void 0 : allEffects.filter((e) => e.useInPicking && preRenderStats[e.id]); const maskEffectRendered = (_a = preRenderStats["mask-effect"]) == null ? void 0 : _a.didRender; const channels = this._groupByCollisionGroup(device, collisionLayers); const viewport = viewports[0]; const viewportChanged = !this.lastViewport || !this.lastViewport.equals(viewport) || maskEffectRendered; for (const collisionGroup in channels) { const collisionFBO = this.collisionFBOs[collisionGroup]; const renderInfo = channels[collisionGroup]; const [width, height] = device.canvasContext.getPixelSize(); collisionFBO.resize({ width: width / DOWNSCALE, height: height / DOWNSCALE }); this._render(renderInfo, { effects, layerFilter, onViewportActive, views, viewport, viewportChanged }); } } _render(renderInfo, { effects, layerFilter, onViewportActive, views, viewport, viewportChanged }) { const { collisionGroup } = renderInfo; const oldRenderInfo = this.channels[collisionGroup]; if (!oldRenderInfo) { return; } const needsRender = viewportChanged || renderInfo === oldRenderInfo || !(0, import_core14._deepEqual)(oldRenderInfo.layers, renderInfo.layers, 1) || renderInfo.layerBounds.some((b, i) => !(0, import_core13.equals)(b, oldRenderInfo.layerBounds[i])) || renderInfo.allLayersLoaded !== oldRenderInfo.allLayersLoaded || renderInfo.layers.some((layer) => layer.props.transitions); this.channels[collisionGroup] = renderInfo; if (needsRender) { this.lastViewport = viewport; const collisionFBO = this.collisionFBOs[collisionGroup]; this.collisionFilterPass.renderCollisionMap(collisionFBO, { pass: "collision-filter", isPicking: true, layers: renderInfo.layers, effects, layerFilter, viewports: viewport ? [viewport] : [], onViewportActive, views, moduleParameters: { dummyCollisionMap: this.dummyCollisionMap, devicePixelRatio: collisionFBO.device.canvasContext.getDevicePixelRatio() / DOWNSCALE } }); } } _groupByCollisionGroup(device, collisionLayers) { const channelMap = {}; for (const layer of collisionLayers) { const { collisionGroup } = layer.props; let channelInfo = channelMap[collisionGroup]; if (!channelInfo) { channelInfo = { collisionGroup, layers: [], layerBounds: [], allLayersLoaded: true }; channelMap[collisionGroup] = channelInfo; } channelInfo.layers.push(layer); channelInfo.layerBounds.push(layer.getBounds()); if (!layer.isLoaded) { channelInfo.allLayersLoaded = false; } } for (const collisionGroup of Object.keys(channelMap)) { if (!this.collisionFBOs[collisionGroup]) { this.createFBO(device, collisionGroup); } if (!this.channels[collisionGroup]) { this.channels[collisionGroup] = channelMap[collisionGroup]; } } for (const collisionGroup of Object.keys(this.collisionFBOs)) { if (!channelMap[collisionGroup]) { this.destroyFBO(collisionGroup); } } return channelMap; } getModuleParameters(layer) { const { collisionGroup } = layer.props; const { collisionFBOs, dummyCollisionMap } = this; return { collisionFBO: collisionFBOs[collisionGroup], dummyCollisionMap }; } cleanup() { if (this.dummyCollisionMap) { this.dummyCollisionMap.delete(); this.dummyCollisionMap = void 0; } this.channels = {}; for (const collisionGroup of Object.keys(this.collisionFBOs)) { this.destroyFBO(collisionGroup); } this.collisionFBOs = {}; this.lastViewport = void 0; } createFBO(device, collisionGroup) { const { width, height } = device.gl.canvas; const collisionMap = device.createTexture({ format: "rgba8unorm", width, height, sampler: { minFilter: "nearest", magFilter: "nearest", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge" } }); const depthStencilAttachment = device.createTexture({ format: "depth16unorm", width, height, mipmaps: false, dataFormat: 6402, type: 5125 }); this.collisionFBOs[collisionGroup] = device.createFramebuffer({ id: `collision-${collisionGroup}`, width, height, colorAttachments: [collisionMap], depthStencilAttachment }); } destroyFBO(collisionGroup) { var _a, _b; const fbo = this.collisionFBOs[collisionGroup]; (_a = fbo.colorAttachments[0]) == null ? void 0 : _a.destroy(); (_b = fbo.depthStencilAttachment) == null ? void 0 : _b.destroy(); fbo.destroy(); delete this.collisionFBOs[collisionGroup]; } }; // dist/collision-filter/collision-filter-extension.js var defaultProps6 = { getCollisionPriority: { type: "accessor", value: 0 }, collisionEnabled: true, collisionGroup: { type: "string", value: "default" }, collisionTestProps: {} }; var CollisionFilterExtension = class extends import_core15.LayerExtension { getShaders() { return { modules: [shader_module_default2] }; } draw({ uniforms, context, moduleParameters }) { const { collisionEnabled } = this.props; const { collisionFBO, drawToCollisionMap } = moduleParameters; const enabled = collisionEnabled && Boolean(collisionFBO); uniforms.collision_enabled = enabled; if (drawToCollisionMap) { this.props = this.clone(this.props.collisionTestProps).props; } } initializeState(context, extension) { var _a; if (this.getAttributeManager() === null) { return; } (_a = this.context.deck) == null ? void 0 : _a._addDefaultEffect(new CollisionFilterEffect()); const attributeManager = this.getAttributeManager(); attributeManager.add({ collisionPriorities: { size: 1, stepMode: "dynamic", accessor: "getCollisionPriority" } }); } getNeedsPickingBuffer() { return this.props.collisionEnabled; } }; CollisionFilterExtension.defaultProps = defaultProps6; CollisionFilterExtension.extensionName = "CollisionFilterExtension"; var collision_filter_extension_default = CollisionFilterExtension; // dist/mask/mask-extension.js var import_core21 = require("@deck.gl/core"); // dist/mask/shader-module.js var import_core16 = require("@deck.gl/core"); var vs4 = ` uniform vec4 mask_bounds; uniform bool mask_maskByInstance; vec2 mask_getCoords(vec4 position) { return (position.xy - mask_bounds.xy) / (mask_bounds.zw - mask_bounds.xy); } `; var fs3 = ` uniform sampler2D mask_texture; uniform int mask_channel; uniform bool mask_enabled; uniform bool mask_inverted; bool mask_isInBounds(vec2 texCoords) { if (!mask_enabled) { return true; } vec4 maskColor = texture(mask_texture, texCoords); float maskValue = 1.0; if (mask_channel == 0) { maskValue = maskColor.r; } else if (mask_channel == 1) { maskValue = maskColor.g; } else if (mask_channel == 2) { maskValue = maskColor.b; } else if (mask_channel == 3) { maskValue = maskColor.a; } if (mask_inverted) { return maskValue >= 0.5; } else { return maskValue < 0.5; } } `; var inject5 = { "vs:#decl": ` out vec2 mask_texCoords; `, "vs:#main-end": ` vec4 mask_common_position; if (mask_maskByInstance) { mask_common_position = project_position(vec4(geometry.worldPosition, 1.0)); } else { mask_common_position = geometry.position; } mask_texCoords = mask_getCoords(mask_common_position); `, "fs:#decl": ` in vec2 mask_texCoords; `, "fs:#main-start": ` if (mask_enabled) { bool mask = mask_isInBounds(mask_texCoords); fragColor = texture(mask_texture, mask_texCoords); if (!mask) discard; } ` }; var getMaskUniforms = (opts) => { if (opts && "maskMap" in opts) { return { mask_texture: opts.maskMap }; } return {}; }; var shader_module_default3 = { name: "mask", dependencies: [import_core16.project], vs: vs4, fs: fs3, inject: inject5, getUniforms: getMaskUniforms }; // dist/mask/mask-effect.js var import_core19 = require("@deck.gl/core"); var import_core20 = require("@math.gl/core"); // dist/mask/mask-pass.js var import_core17 = require("@deck.gl/core"); var MASK_BLENDING = { blendColorOperation: "subtract", blendColorSrcFactor: "zero", blendColorDstFactor: "one", blendAlphaOperation: "subtract", blendAlphaSrcFactor: "zero", blendAlphaDstFactor: "one" }; var MaskPass = class extends import_core17._LayersPass { constructor(device, props) { super(device, props); const { mapSize = 2048 } = props; this.maskMap = device.createTexture({ format: "rgba8unorm", width: mapSize, height: mapSize, sampler: { minFilter: "linear", magFilter: "linear", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge" } }); this.fbo = device.createFramebuffer({ id: "maskmap", width: mapSize, height: mapSize, colorAttachments: [this.maskMap] }); } render(options) { const colorMask = 2 ** options.channel; const clearColor = [255, 255, 255, 255]; super.render({ ...options, clearColor, colorMask, target: this.fbo, pass: "mask" }); } getLayerParameters(layer, layerIndex, viewport) { return { ...layer.props.parameters, blend: true, depthTest: false, ...MASK_BLENDING }; } shouldDrawLayer(layer) { return layer.props.operation.includes("mask"); } delete() { this.fbo.delete(); this.maskMap.delete(); } }; // dist/utils/projection-utils.js var import_core18 = require("@deck.gl/core"); function joinLayerBounds(layers, viewport) { const bounds = [Infinity, Infinity, -Infinity, -Infinity]; for (const layer of layers) { const layerBounds = layer.getBounds(); if (layerBounds) { const bottomLeftCommon = layer.projectPosition(layerBounds[0], { viewport, autoOffset: false }); const topRightCommon = layer.projectPosition(layerBounds[1], { viewport, autoOffset: false }); bounds[0] = Math.min(bounds[0], bottomLeftCommon[0]); bounds[1] = Math.min(bounds[1], bottomLeftCommon[1]); bounds[2] = Math.max(bounds[2], topRightCommon[0]); bounds[3] = Math.max(bounds[3], topRightCommon[1]); } } if (Number.isFinite(bounds[0])) { return bounds; } return null; } var MAX_VIEWPORT_SIZE = 2048; function makeViewport(opts) { const { bounds, viewport, border = 0 } = opts; const { isGeospatial } = viewport; if (bounds[2] <= bounds[0] || bounds[3] <= bounds[1]) { return null; } const centerWorld = viewport.unprojectPosition([ (bounds[0] + bounds[2]) / 2, (bounds[1] + bounds[3]) / 2, 0 ]); let { width, height, zoom } = opts; if (zoom === void 0) { width = width - border * 2; height = height - border * 2; const scale = Math.min(width / (bounds[2] - bounds[0]), height / (bounds[3] - bounds[1])); zoom = Math.min(Math.log2(scale), 20); } else if (!width || !height) { const scale = 2 ** zoom; width = Math.round(Math.abs(bounds[2] - bounds[0]) * scale); height = Math.round(Math.abs(bounds[3] - bounds[1]) * scale); const maxSize = MAX_VIEWPORT_SIZE - border * 2; if (width > maxSize || height > maxSize) { const r = maxSize / Math.max(width, height); width = Math.round(width * r); height = Math.round(height * r); zoom += Math.log2(r); } } return isGeospatial ? new import_core18.WebMercatorViewport({ id: viewport.id, x: border, y: border, width, height, longitude: centerWorld[0], latitude: centerWorld[1], zoom, orthographic: true }) : new import_core18.OrthographicViewport({ id: viewport.id, x: border, y: border, width, height, target: centerWorld, zoom, flipY: false }); } function getViewportBounds(viewport, zRange) { let viewportBoundsWorld; if (zRange && zRange.length === 2) { const [minZ, maxZ] = zRange; const bounds0 = viewport.getBounds({ z: minZ }); const bounds1 = viewport.getBounds({ z: maxZ }); viewportBoundsWorld = [ Math.min(bounds0[0], bounds1[0]), Math.min(bounds0[1], bounds1[1]), Math.max(bounds0[2], bounds1[2]), Math.max(bounds0[3], bounds1[3]) ]; } else { viewportBoundsWorld = viewport.getBounds(); } const viewportBottomLeftCommon = viewport.projectPosition(viewportBoundsWorld.slice(0, 2)); const viewportTopRightCommon = viewport.projectPosition(viewportBoundsWorld.slice(2, 4)); return [ viewportBottomLeftCommon[0], viewportBottomLeftCommon[1], viewportTopRightCommon[0], viewportTopRightCommon[1] ]; } function getRenderBounds(layerBounds, viewport, zRange) { if (!layerBounds) { return [0, 0, 1, 1]; } const viewportBounds = getViewportBounds(viewport, zRange); const paddedBounds = doubleBounds(viewportBounds); if (layerBounds[2] - layerBounds[0] <= paddedBounds[2] - paddedBounds[0] && layerBounds[3] - layerBounds[1] <= paddedBounds[3] - paddedBounds[1]) { return layerBounds; } return [ Math.max(layerBounds[0], paddedBounds[0]), Math.max(layerBounds[1], paddedBounds[1]), Math.min(layerBounds[2], paddedBounds[2]), Math.min(layerBounds[3], paddedBounds[3]) ]; } function doubleBounds(bounds) { const dx = bounds[2] - bounds[0]; const dy = bounds[3] - bounds[1]; const centerX = (bounds[0] + bounds[2]) / 2; const centerY = (bounds[1] + bounds[3]) / 2; return [centerX - dx, centerY - dy, centerX + dx, centerY + dy]; } // dist/mask/mask-effect.js var MaskEffect = class { constructor() { this.id = "mask-effect"; this.props = null; this.useInPicking = true; this.order = 0; this.channels = []; this.masks = null; } setup({ device }) { this.dummyMaskMap = device.createTexture({ width: 1, height: 1 }); this.maskPass = new MaskPass(device, { id: "default-mask" }); this.maskMap = this.maskPass.maskMap; } preRender({ layers, layerFilter, viewports, onViewportActive, views, isPicking }) { let didRender = false; if (isPicking) { return { didRender }; } const maskLayers = layers.filter((l) => l.props.visible && l.props.operation.includes("mask")); if (maskLayers.length === 0) { this.masks = null; this.channels.length = 0; return { didRender }; } this.masks = {}; const channelMap = this._sortMaskChannels(maskLayers); const viewport = viewports[0]; const viewportChanged = !this.lastViewport || !this.lastViewport.equals(viewport); if (viewport.resolution !== void 0) { import_core19.log.warn("MaskExtension is not supported in GlobeView")(); return { didRender }; } for (const maskId in channelMap) { const result = this._renderChannel(channelMap[maskId], { layerFilter, onViewportActive, views, viewport, viewportChanged }); didRender || (didRender = result); } return { didRender }; } _renderChannel(channelInfo, { layerFilter, onViewportActive, views, viewport, viewportChanged }) { let didRender = false; const oldChannelInfo = this.channels[channelInfo.index]; if (!oldChannelInfo) { return didRender; } const maskChanged = channelInfo === oldChannelInfo || channelInfo.layers.length !== oldChannelInfo.layers.length || channelInfo.layers.some((layer, i) => layer !== oldChannelInfo.layers[i] || layer.props.transitions) || channelInfo.layerBounds.some((b, i) => b !== oldChannelInfo.layerBounds[i]); channelInfo.bounds = oldChannelInfo.bounds; channelInfo.maskBounds = oldChannelInfo.maskBounds; this.channels[channelInfo.index] = channelInfo; if (maskChanged || viewportChanged) { this.lastViewport = viewport; const layerBounds = joinLayerBounds(channelInfo.layers, viewport); channelInfo.bounds = layerBounds && getRenderBounds(layerBounds, viewport); if (maskChanged || !(0, import_core20.equals)(channelInfo.bounds, oldChannelInfo.bounds)) { const { maskPass, maskMap } = this; const maskViewport = layerBounds && makeViewport({ bounds: channelInfo.bounds, viewport, width: maskMap.width, height: maskMap.height, border: 1 }); channelInfo.maskBounds = maskViewport ? maskViewport.getBounds() : [0, 0, 1, 1]; maskPass.render({ pass: "mask", channel: channelInfo.index, layers: channelInfo.layers, layerFilter, viewports: maskViewport ? [maskViewport] : [], onViewportActive, views, moduleParameters: { devicePixelRatio: 1 } }); didRender = true; } } this.masks[channelInfo.id] = { index: channelInfo.index, bounds: channelInfo.maskBounds, coordinateOrigin: channelInfo.coordinateOrigin, coordinateSystem: channelInfo.coordinateSystem }; return didRender; } _sortMaskChannels(maskLayers) { const channelMap = {}; let channelCount = 0; for (const layer of maskLayers) { const { id } = layer.root; let channelInfo = channelMap[id]; if (!channelInfo) { if (++channelCount > 4) { import_core19.log.warn("Too many mask layers. The max supported is 4")(); continue; } channelInfo = { id, index: this.channels.findIndex((c) => (c == null ? void 0 : c.id) === id), layers: [], layerBounds: [], coordinateOrigin: layer.root.props.coordinateOrigin, coordinateSystem: layer.root.props.coordinateSystem }; channelMap[id] = channelInfo; } channelInfo.layers.push(layer); channelInfo.layerBounds.push(layer.getBounds()); } for (let i = 0; i < 4; i++) { const channelInfo = this.channels[i]; if (!channelInfo || !(channelInfo.id in channelMap)) { this.channels[i] = null; } } for (const maskId in channelMap) { const channelInfo = channelMap[maskId]; if (channelInfo.index < 0) { channelInfo.index = this.channels.findIndex((c) => !c); this.channels[channelInfo.index] = channelInfo; } } return channelMap; } getModuleParameters() { return { maskMap: this.masks ? this.maskMap : this.dummyMaskMap, maskChannels: this.masks }; } cleanup() { if (this.dummyMaskMap) { this.dummyMaskMap.delete(); this.dummyMaskMap = void 0; } if (this.maskPass) { this.maskPass.delete(); this.maskPass = void 0; this.maskMap = void 0; } this.lastViewport = void 0; this.masks = null; this.channels.length = 0; } }; // dist/mask/mask-extension.js var defaultProps7 = { maskId: "", maskByInstance: void 0, maskInverted: false }; var MaskExtension = class extends import_core21.LayerExtension { initializeState() { var _a; (_a = this.context.deck) == null ? void 0 : _a._addDefaultEffect(new MaskEffect()); } getShaders() { let maskByInstance = "instancePositions" in this.getAttributeManager().attributes; if (this.props.maskByInstance !== void 0) { maskByInstance = Boolean(this.props.maskByInstance); } this.state.maskByInstance = maskByInstance; return { modules: [shader_module_default3] }; } draw({ uniforms, context, moduleParameters }) { uniforms.mask_maskByInstance = this.state.maskByInstance; const { maskId, maskInverted } = this.props; const { maskChannels } = moduleParameters; const { viewport } = context; if (maskChannels && maskChannels[maskId]) { const { index, bounds, coordinateOrigin: fromCoordinateOrigin } = maskChannels[maskId]; let { coordinateSystem: fromCoordinateSystem } = maskChannels[maskId]; uniforms.mask_enabled = true; uniforms.mask_channel = index; uniforms.mask_inverted = maskInverted; if (fromCoordinateSystem === import_core21.COORDINATE_SYSTEM.DEFAULT) { fromCoordinateSystem = viewport.isGeospatial ? import_core21.COORDINATE_SYSTEM.LNGLAT : import_core21.COORDINATE_SYSTEM.CARTESIAN; } const opts = { modelMatrix: null, fromCoordinateOrigin, fromCoordinateSystem }; const bl = this.projectPosition([bounds[0], bounds[1], 0], opts); const tr = this.projectPosition([bounds[2], bounds[3], 0], opts); uniforms.mask_bounds = [bl[0], bl[1], tr[0], tr[1]]; } else { if (maskId) { import_core21.log.warn(`Could not find a mask layer with id: ${maskId}`)(); } uniforms.mask_enabled = false; } } }; MaskExtension.defaultProps = defaultProps7; MaskExtension.extensionName = "MaskExtension"; var mask_extension_default = MaskExtension; // dist/terrain/terrain-extension.js var import_core26 = require("@deck.gl/core"); // dist/terrain/terrain-effect.js var import_core25 = require("@deck.gl/core"); // dist/terrain/shader-module.js var import_core22 = require("@deck.gl/core"); var TERRAIN_MODE = { NONE: 0, WRITE_HEIGHT_MAP: 1, USE_HEIGHT_MAP: 2, USE_COVER: 3, USE_COVER_ONLY: 4, SKIP: 5 }; var TERRAIN_MODE_CONSTANTS = Object.keys(TERRAIN_MODE).map((key) => `const float TERRAIN_MODE_${key} = ${TERRAIN_MODE[key]}.0;`).join("\n"); var terrainModule = { name: "terrain", dependencies: [import_core22.project], inject: { "vs:#decl": ` uniform float terrain_mode; uniform sampler2D terrain_map; uniform vec4 terrain_bounds; out vec3 commonPos; ` + TERRAIN_MODE_CONSTANTS, "vs:#main-start": ` if (terrain_mode == TERRAIN_MODE_SKIP) { gl_Position = vec4(0.0); return; } `, "vs:DECKGL_FILTER_GL_POSITION": ` commonPos = geometry.position.xyz; if (terrain_mode == TERRAIN_MODE_WRITE_HEIGHT_MAP) { vec2 texCoords = (commonPos.xy - terrain_bounds.xy) / terrain_bounds.zw; position = vec4(texCoords * 2.0 - 1.0, 0.0, 1.0); commonPos.z += project_uCommonOrigin.z; } if (terrain_mode == TERRAIN_MODE_USE_HEIGHT_MAP) { vec3 anchor = geometry.worldPosition; anchor.z = 0.0; vec3 anchorCommon = project_position(anchor); vec2 texCoords = (anchorCommon.xy - terrain_bounds.xy) / terrain_bounds.zw; if (texCoords.x >= 0.0 && texCoords.y >= 0.0 && texCoords.x <= 1.0 && texCoords.y <= 1.0) { float terrainZ = texture(terrain_map, texCoords).r; geometry.position.z += terrainZ; position = project_common_position_to_clipspace(geometry.position); } } `, "fs:#decl": ` uniform float terrain_mode; uniform sampler2D terrain_map; uniform vec4 terrain_bounds; in vec3 commonPos; ` + TERRAIN_MODE_CONSTANTS, "fs:#main-start": ` if (terrain_mode == TERRAIN_MODE_WRITE_HEIGHT_MAP) { fragColor = vec4(commonPos.z, 0.0, 0.0, 1.0); return; } `, "fs:DECKGL_FILTER_COLOR": ` if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_USE_COVER_ONLY)) { vec2 texCoords = (commonPos.xy - terrain_bounds.xy) / terrain_bounds.zw; vec4 pixel = texture(terrain_map, texCoords); if (terrain_mode == TERRAIN_MODE_USE_COVER_ONLY) { color = pixel; } else { color = pixel + color * (1.0 - pixel.a); } return; } ` }, getUniforms: (opts = {}, uniforms) => { var _a; if ("dummyHeightMap" in opts) { const { drawToTerrainHeightMap, heightMap, heightMapBounds, dummyHeightMap, terrainCover, useTerrainHeightMap, terrainSkipRender } = opts; const { project_uCommonOrigin } = uniforms; let mode = terrainSkipRender ? TERRAIN_MODE.SKIP : TERRAIN_MODE.NONE; let sampler = dummyHeightMap; let bounds = null; if (drawToTerrainHeightMap) { mode = TERRAIN_MODE.WRITE_HEIGHT_MAP; bounds = heightMapBounds; } else if (useTerrainHeightMap && heightMap) { mode = TERRAIN_MODE.USE_HEIGHT_MAP; sampler = heightMap; bounds = heightMapBounds; } else if (terrainCover) { const isPicking = (_a = opts.picking) == null ? void 0 : _a.isActive; const fbo = isPicking ? terrainCover.getPickingFramebuffer() : terrainCover.getRenderFramebuffer(); sampler = fbo == null ? void 0 : fbo.colorAttachments[0].texture; if (isPicking) { mode = TERRAIN_MODE.SKIP; } if (sampler) { mode = mode === TERRAIN_MODE.SKIP ? TERRAIN_MODE.USE_COVER_ONLY : TERRAIN_MODE.USE_COVER; bounds = terrainCover.bounds; } else { sampler = dummyHeightMap; } } return { terrain_mode: mode, terrain_map: sampler, terrain_bounds: bounds ? [ bounds[0] - project_uCommonOrigin[0], bounds[1] - project_uCommonOrigin[1], bounds[2] - bounds[0], bounds[3] - bounds[1] ] : [0, 0, 0, 0] }; } return null; } }; // dist/terrain/utils.js var import_constants2 = require("@luma.gl/constants"); function createRenderTarget(device, opts) { return device.createFramebuffer({ id: opts.id, colorAttachments: [ device.createTexture({ id: opts.id, ...opts.float && { format: "rgba32float", type: 5126 }, mipmaps: false, sampler: opts.interpolate === false ? { minFilter: "nearest", magFilter: "nearest" } : { minFilter: "linear", magFilter: "linear" } }) ] }); } // dist/terrain/terrain-cover.js var TerrainCover = class { constructor(targetLayer) { this.isDirty = true; this.renderViewport = null; this.bounds = null; this.layers = []; this.targetBounds = null; this.targetBoundsCommon = null; this.targetLayer = targetLayer; this.tile = getTile(targetLayer); } get id() { return this.targetLayer.id; } get isActive() { return Boolean(this.targetLayer.getCurrentLayer()); } shouldUpdate({ targetLayer, viewport, layers, layerNeedsRedraw }) { if (targetLayer) { this.targetLayer = targetLayer; } const sizeChanged = viewport ? this._updateViewport(viewport) : false; let layersChanged = layers ? this._updateLayers(layers) : false; if (layerNeedsRedraw) { for (const id of this.layers) { if (layerNeedsRedraw[id]) { layersChanged = true; break; } } } return layersChanged || sizeChanged; } _updateLayers(layers) { let needsRedraw = false; layers = this.tile ? getIntersectingLayers(this.tile, layers) : layers; if (layers.length !== this.layers.length) { needsRedraw = true; } else { for (let i = 0; i < layers.length; i++) { const id = layers[i].id; if (id !== this.layers[i]) { needsRedraw = true; break; } } } if (needsRedraw) { this.layers = layers.map((layer) => layer.id); } return needsRedraw; } _updateViewport(viewport) { var _a; const targetLayer = this.targetLayer; let shouldRedraw = false; if (this.tile && "boundingBox" in this.tile) { if (!this.targetBounds) { shouldRedraw = true; this.targetBounds = this.tile.boundingBox; const bottomLeftCommon = viewport.projectPosition(this.targetBounds[0]); const topRightCommon = viewport.projectPosition(this.targetBounds[1]); this.targetBoundsCommon = [ bottomLeftCommon[0], bottomLeftCommon[1], topRightCommon[0], topRightCommon[1] ]; } } else if (this.targetBounds !== targetLayer.getBounds()) { shouldRedraw = true; this.targetBounds = targetLayer.getBounds(); this.targetBoundsCommon = joinLayerBounds([targetLayer], viewport); } if (!this.targetBoundsCommon) { return false; } const newZoom = Math.ceil(viewport.zoom + 0.5); if (this.tile) { this.bounds = this.targetBoundsCommon; } else { const oldZoom = (_a = this.renderViewport) == null ? void 0 : _a.zoom; shouldRedraw = shouldRedraw || newZoom !== oldZoom; const newBounds = getRenderBounds(this.targetBoundsCommon, viewport); const oldBounds = this.bounds; shouldRedraw = shouldRedraw || !oldBounds || newBounds.some((x, i) => x !== oldBounds[i]); this.bounds = newBounds; } if (shouldRedraw) { this.renderViewport = makeViewport({ bounds: this.bounds, zoom: newZoom, viewport }); } return shouldRedraw; } getRenderFramebuffer() { if (!this.renderViewport || this.layers.length === 0) { return null; } if (!this.fbo) { this.fbo = createRenderTarget(this.targetLayer.context.device, { id: this.id }); } return this.fbo; } getPickingFramebuffer() { if (!this.renderViewport || this.layers.length === 0 && !this.targetLayer.props.pickable) { return null; } if (!this.pickingFbo) { this.pickingFbo = createRenderTarget(this.targetLayer.context.device, { id: `${this.id}-picking`, interpolate: false }); } return this.pickingFbo; } filterLayers(layers) { return layers.filter(({ id }) => this.layers.includes(id)); } delete() { const { fbo, pickingFbo } = this; if (fbo) { fbo.colorAttachments[0].destroy(); fbo.destroy(); } if (pickingFbo) { pickingFbo.colorAttachments[0].destroy(); pickingFbo.destroy(); } } }; function getIntersectingLayers(sourceTile, layers) { return layers.filter((layer) => { const tile = getTile(layer); if (tile) { return intersect(sourceTile.boundingBox, tile.boundingBox); } return true; }); } function getTile(layer) { while (layer) { const { tile } = layer.props; if (tile) { return tile; } layer = layer.parent; } return null; } function intersect(b1, b2) { if (b1 && b2) { return b1[0][0] < b2[1][0] && b2[0][0] < b1[1][0] && b1[0][1] < b2[1][1] && b2[0][1] < b1[1][1]; } return false; } // dist/terrain/terrain-pass.js var import_core23 = require("@deck.gl/core"); var TERRAIN_BLENDING = { blendColorOperation: "max", blendColorSrcFactor: "one", blendColorDstFactor: "one", blendAlphaOperation: "max", blendAlphaSrcFactor: "one", blendAlphaDstFactor: "one" }; var TerrainPass = class extends import_core23._LayersPass { getRenderableLayers(viewport, opts) { const { layers } = opts; const result = []; const drawParamsByIndex = this._getDrawLayerParams(viewport, opts, true); for (let i = 0; i < layers.length; i++) { const layer = layers[i]; if (!layer.isComposite && drawParamsByIndex[i].shouldDrawLayer) { result.push(layer); } } return result; } renderHeightMap(heightMap, opts) { const target = heightMap.getRenderFramebuffer(); const viewport = heightMap.renderViewport; if (!target || !viewport) { return; } target.resize(viewport); this.render({ ...opts, target, pass: "terrain-height-map", layers: opts.layers, viewports: [viewport], effects: [], clearColor: [0, 0, 0, 0] }); } renderTerrainCover(terrainCover, opts) { const target = terrainCover.getRenderFramebuffer(); const viewport = terrainCover.renderViewport; if (!target || !viewport) { return; } const layers = terrainCover.filterLayers(opts.layers); target.resize(viewport); this.render({ ...opts, target, pass: `terrain-cover-${terrainCover.id}`, layers, effects: [], viewports: [viewport], clearColor: [0, 0, 0, 0] }); } getLayerParameters(layer, layerIndex, viewport) { return { ...layer.props.parameters, blend: true, depthTest: false, ...layer.props.operation.includes("terrain") && TERRAIN_BLENDING }; } }; // dist/terrain/terrain-picking-pass.js var import_core24 = require("@deck.gl/core"); var TerrainPickingPass = class extends import_core24._PickLayersPass { constructor() { super(...arguments); this.drawParameters = {}; } getRenderableLayers(viewport, opts) { const { layers } = opts; const result = []; this.drawParameters = {}; this._resetColorEncoder(opts.pickZ); const drawParamsByIndex = this._getDrawLayerParams(viewport, opts); for (let i = 0; i < layers.length; i++) { const layer = layers[i]; if (!layer.isComposite && drawParamsByIndex[i].shouldDrawLayer) { result.push(layer); this.drawParameters[layer.id] = drawParamsByIndex[i].layerParameters; } } return result; } renderTerrainCover(terrainCover, opts) { const target = terrainCover.getPickingFramebuffer(); const viewport = terrainCover.renderViewport; if (!target || !viewport) { return; } const layers = terrainCover.filterLayers(opts.layers); const terrainLayer = terrainCover.targetLayer; if (terrainLayer.props.pickable) { layers.unshift(terrainLayer); } target.resize(viewport); this.render({ ...opts, pickingFBO: target, pass: `terrain-cover-picking-${terrainCover.id}`, layers, effects: [], viewports: [viewport], cullRect: void 0, deviceRect: viewport, pickZ: false }); } getLayerParameters(layer, layerIndex, viewport) { let parameters2; if (this.drawParameters[layer.id]) { parameters2 = this.drawParameters[layer.id]; } else { parameters2 = super.getLayerParameters(layer, layerIndex, viewport); parameters2.blend = true; } return { ...parameters2, depthTest: false }; } }; // dist/terrain/height-map-builder.js var MAP_MAX_SIZE = 2048; var HeightMapBuilder = class { static isSupported(device) { return device.isTextureFormatRenderable("rgba32float"); } constructor(device) { this.renderViewport = null; this.bounds = null; this.layers = []; this.layersBounds = []; this.layersBoundsCommon = null; this.lastViewport = null; this.device = device; } getRenderFramebuffer() { if (!this.renderViewport) { return null; } if (!this.fbo) { this.fbo = createRenderTarget(this.device, { id: "height-map", float: true }); } return this.fbo; } shouldUpdate({ layers, viewport }) { const layersChanged = layers.length !== this.layers.length || layers.some((layer, i) => layer !== this.layers[i] || layer.props.transitions || layer.getBounds() !== this.layersBounds[i]); if (layersChanged) { this.layers = layers; this.layersBounds = layers.map((layer) => layer.getBounds()); this.layersBoundsCommon = joinLayerBounds(layers, viewport); } const viewportChanged = !this.lastViewport || !viewport.equals(this.lastViewport); if (!this.layersBoundsCommon) { this.renderViewport = null; } else if (layersChanged || viewportChanged) { const bounds = getRenderBounds(this.layersBoundsCommon, viewport); if (bounds[2] <= bounds[0] || bounds[3] <= bounds[1]) { this.renderViewport = null; return false; } this.bounds = bounds; this.lastViewport = viewport; const scale = viewport.scale; const pixelWidth = (bounds[2] - bounds[0]) * scale; const pixelHeight = (bounds[3] - bounds[1]) * scale; this.renderViewport = pixelWidth > 0 || pixelHeight > 0 ? makeViewport({ bounds: [ viewport.center[0] - 1, viewport.center[1] - 1, viewport.center[0] + 1, viewport.center[1] + 1 ], zoom: viewport.zoom, width: Math.min(pixelWidth, MAP_MAX_SIZE), height: Math.min(pixelHeight, MAP_MAX_SIZE), viewport }) : null; return true; } return false; } delete() { if (this.fbo) { this.fbo.colorAttachments[0].delete(); this.fbo.delete(); } } }; // dist/terrain/terrain-effect.js var TerrainEffect = class { constructor() { this.id = "terrain-effect"; this.props = null; this.useInPicking = true; this.isPicking = false; this.isDrapingEnabled = false; this.terrainCovers = /* @__PURE__ */ new Map(); } setup({ device, deck }) { this.dummyHeightMap = device.createTexture({ width: 1, height: 1, data: new Uint8Array([0, 0, 0, 0]) }); this.terrainPass = new TerrainPass(device, { id: "terrain" }); this.terrainPickingPass = new TerrainPickingPass(device, { id: "terrain-picking" }); if (HeightMapBuilder.isSupported(device)) { this.heightMap = new HeightMapBuilder(device); } else { import_core25.log.warn("Terrain offset mode is not supported by this browser")(); } deck._addDefaultShaderModule(terrainModule); } preRender(opts) { if (opts.pickZ) { this.isDrapingEnabled = false; return; } const { viewports } = opts; const isPicking = opts.pass.startsWith("picking"); this.isPicking = isPicking; this.isDrapingEnabled = true; const viewport = viewports[0]; const layers = (isPicking ? this.terrainPickingPass : this.terrainPass).getRenderableLayers(viewport, opts); const terrainLayers = layers.filter((l) => l.props.operation.includes("terrain")); if (terrainLayers.length === 0) { return; } if (!isPicking) { const offsetLayers = layers.filter((l) => l.state.terrainDrawMode === "offset"); if (offsetLayers.length > 0) { this._updateHeightMap(terrainLayers, viewport, opts); } } const drapeLayers = layers.filter((l) => l.state.terrainDrawMode === "drape"); this._updateTerrainCovers(terrainLayers, drapeLayers, viewport, opts); } getModuleParameters(layer) { var _a, _b, _c; const { terrainDrawMode } = layer.state; return { heightMap: ((_b = (_a = this.heightMap) == null ? void 0 : _a.getRenderFramebuffer()) == null ? void 0 : _b.colorAttachments[0].texture) || null, heightMapBounds: (_c = this.heightMap) == null ? void 0 : _c.bounds, dummyHeightMap: this.dummyHeightMap, terrainCover: this.isDrapingEnabled ? this.terrainCovers.get(layer.id) : null, useTerrainHeightMap: terrainDrawMode === "offset", terrainSkipRender: terrainDrawMode === "drape" || !layer.props.operation.includes("draw") }; } cleanup({ deck }) { if (this.dummyHeightMap) { this.dummyHeightMap.delete(); this.dummyHeightMap = void 0; } if (this.heightMap) { this.heightMap.delete(); this.heightMap = void 0; } for (const terrainCover of this.terrainCovers.values()) { terrainCover.delete(); } this.terrainCovers.clear(); deck._removeDefaultShaderModule(terrainModule); } _updateHeightMap(terrainLayers, viewport, opts) { if (!this.heightMap) { return; } const shouldUpdate = this.heightMap.shouldUpdate({ layers: terrainLayers, viewport }); if (!shouldUpdate) { return; } this.terrainPass.renderHeightMap(this.heightMap, { ...opts, layers: terrainLayers, moduleParameters: { heightMapBounds: this.heightMap.bounds, dummyHeightMap: this.dummyHeightMap, devicePixelRatio: 1, drawToTerrainHeightMap: true } }); } _updateTerrainCovers(terrainLayers, drapeLayers, viewport, opts) { const layerNeedsRedraw = {}; for (const layer of drapeLayers) { if (layer.state.terrainCoverNeedsRedraw) { layerNeedsRedraw[layer.id] = true; layer.state.terrainCoverNeedsRedraw = false; } } for (const terrainCover of this.terrainCovers.values()) { terrainCover.isDirty = terrainCover.isDirty || terrainCover.shouldUpdate({ layerNeedsRedraw }); } for (const layer of terrainLayers) { this._updateTerrainCover(layer, drapeLayers, viewport, opts); } if (!this.isPicking) { this._pruneTerrainCovers(); } } _updateTerrainCover(terrainLayer, drapeLayers, viewport, opts) { const renderPass = this.isPicking ? this.terrainPickingPass : this.terrainPass; let terrainCover = this.terrainCovers.get(terrainLayer.id); if (!terrainCover) { terrainCover = new TerrainCover(terrainLayer); this.terrainCovers.set(terrainLayer.id, terrainCover); } try { const isDirty = terrainCover.shouldUpdate({ targetLayer: terrainLayer, viewport, layers: drapeLayers }); if (this.isPicking || terrainCover.isDirty || isDirty) { renderPass.renderTerrainCover(terrainCover, { ...opts, layers: drapeLayers, moduleParameters: { dummyHeightMap: this.dummyHeightMap, terrainSkipRender: false, devicePixelRatio: 1 } }); if (!this.isPicking) { terrainCover.isDirty = false; } } } catch (err) { terrainLayer.raiseError(err, `Error rendering terrain cover ${terrainCover.id}`); } } _pruneTerrainCovers() { const idsToRemove = []; for (const [id, terrainCover] of this.terrainCovers) { if (!terrainCover.isActive) { idsToRemove.push(id); } } for (const id of idsToRemove) { this.terrainCovers.delete(id); } } }; // dist/terrain/terrain-extension.js var defaultProps8 = { terrainDrawMode: void 0 }; var TerrainExtension = class extends import_core26.LayerExtension { getShaders() { return { modules: [terrainModule] }; } initializeState() { var _a; (_a = this.context.deck) == null ? void 0 : _a._addDefaultEffect(new TerrainEffect()); } updateState(params) { var _a; const { props, oldProps } = params; if (this.state.terrainDrawMode && props.terrainDrawMode === oldProps.terrainDrawMode && props.extruded === oldProps.extruded) { return; } let { terrainDrawMode } = props; if (!terrainDrawMode) { const is3d = this.props.extruded; const attributes = (_a = this.getAttributeManager()) == null ? void 0 : _a.attributes; const hasAnchor = attributes && "instancePositions" in attributes; terrainDrawMode = is3d || hasAnchor ? "offset" : "drape"; } this.setState({ terrainDrawMode }); } onNeedsRedraw() { const state = this.state; if (state.terrainDrawMode === "drape") { state.terrainCoverNeedsRedraw = true; } } }; TerrainExtension.defaultProps = defaultProps8; TerrainExtension.extensionName = "TerrainExtension"; var terrain_extension_default = TerrainExtension; //# sourceMappingURL=index.cjs.map