UNPKG

@deck.gl-community/layers

Version:

Add-on layers for deck.gl

1,414 lines (1,355 loc) 45.7 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; 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); var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // dist/index.js var dist_exports = {}; __export(dist_exports, { DependencyArrowLayer: () => DependencyArrowLayer, PathDirection: () => PathDirection, PathMarkerLayer: () => PathMarkerLayer, PathOutlineLayer: () => PathOutlineLayer, SkyboxLayer: () => SkyboxLayer }); module.exports = __toCommonJS(dist_exports); // dist/path-outline-layer/path-outline-layer.js var import_layers = require("@deck.gl/layers"); // dist/path-outline-layer/outline.js var INITIAL_STATE = { outlineEnabled: false, outlineRenderShadowmap: false, outlineShadowmap: null }; function getUniforms({ outlineEnabled, outlineRenderShadowmap, outlineShadowmap } = INITIAL_STATE) { const uniforms = {}; if (outlineEnabled !== void 0) { uniforms.outline_uEnabled = outlineEnabled; } if (outlineRenderShadowmap !== void 0) { uniforms.outline_uRenderOutlines = outlineRenderShadowmap; } if (outlineShadowmap !== void 0) { uniforms.outline_uShadowmap = outlineShadowmap; } return uniforms; } var vs = `in float instanceZLevel; out float outline_vzLevel; out vec4 outline_vPosition; // Set the z level for the outline shadowmap rendering void outline_setZLevel(float zLevel) { outline_vzLevel = zLevel; } // Store an adjusted position for texture2DProj void outline_setUV(vec4 position) { // mat4( // 0.5, 0.0, 0.0, 0.0, // 0.0, 0.5, 0.0, 0.0, // 0.0, 0.0, 0.5, 0.0, // 0.5, 0.5, 0.5, 1.0 // ) * position; outline_vPosition = vec4(position.xyz * 0.5 + position.w * 0.5, position.w); } `; var fs = `uniform bool outline_uEnabled; uniform bool outline_uRenderOutlines; uniform sampler2D outline_uShadowmap; in float outline_vzLevel; // in vec2 outline_vUV; in vec4 outline_vPosition; const float OUTLINE_Z_LEVEL_ERROR = 0.01; // Return a darker color in shadowmap vec4 outline_filterShadowColor(vec4 color) { return vec4(outline_vzLevel / 255., outline_vzLevel / 255., outline_vzLevel / 255., 1.); } // Return a darker color if in shadowmap vec4 outline_filterDarkenColor(vec4 color) { if (outline_uEnabled) { float maxZLevel; if (outline_vPosition.q > 0.0) { maxZLevel = textureProj(outline_uShadowmap, outline_vPosition).r * 255.; } else { discard; } if (maxZLevel < outline_vzLevel + OUTLINE_Z_LEVEL_ERROR) { return vec4(color.rgb * 0.5, color.a); } else { discard; } } return color; } // if enabled and rendering outlines - Render depth to shadowmap // if enabled and rendering colors - Return a darker color if in shadowmap // if disabled, just return color vec4 outline_filterColor(vec4 color) { if (outline_uEnabled) { return outline_uRenderOutlines ? outline_filterShadowColor(color) : outline_filterDarkenColor(color); } return color; } `; var outline = { name: "outline", vs, fs, getUniforms }; // dist/path-outline-layer/path-outline-layer.js var UNIT = { common: 0, meters: 1, pixels: 2 }; function injectShaderCode({ source, code = "" }) { const INJECT_CODE = /}[^{}]*$/; return source.replace(INJECT_CODE, code.concat("\n}\n")); } var VS_CODE = ` outline_setUV(gl_Position); outline_setZLevel(instanceZLevel); `; var FS_CODE = ` fragColor = outline_filterColor(fragColor); `; var OUTLINE_SHADOWMAP_PARAMETERS = { blend: true, blendColorSrcFactor: "one", blendColorDstFactor: "one", blendColorOperation: "max", blendAlphaSrcFactor: "one", blendAlphaDstFactor: "one", blendAlphaOperation: "max", depthWriteEnabled: false, depthCompare: "always" }; var OUTLINE_RENDER_PARAMETERS = { blend: false, depthWriteEnabled: false, depthCompare: "always" }; var defaultProps = { getZLevel: () => 0 }; var PathOutlineLayer = class extends import_layers.PathLayer { state = void 0; // Override getShaders to inject the outline module getShaders() { const shaders = super.getShaders(); return Object.assign({}, shaders, { modules: shaders.modules.concat([outline]), vs: injectShaderCode({ source: shaders.vs, code: VS_CODE }), fs: injectShaderCode({ source: shaders.fs, code: FS_CODE }) }); } // @ts-expect-error PathLayer is missing LayerContext arg initializeState(context) { super.initializeState(); const attributeManager = this.getAttributeManager(); if (!attributeManager) { throw new Error("PathOutlineLayer requires an attribute manager during initialization."); } const outlineFramebuffer = context.device.createFramebuffer({ colorAttachments: [ context.device.createTexture({ format: "rgba8unorm", width: 1, height: 1, mipLevels: 1 }) ] }); const outlineEmptyTexture = context.device.createTexture({ format: "rgba8unorm", width: 1, height: 1, mipLevels: 1 }); attributeManager.addInstanced({ instanceZLevel: { size: 1, type: "uint8", accessor: "getZLevel" } }); this.setState({ outlineFramebuffer, outlineEmptyTexture, model: this._getModel() }); } finalizeState(context) { var _a, _b; (_a = this.state.outlineFramebuffer) == null ? void 0 : _a.destroy(); (_b = this.state.outlineEmptyTexture) == null ? void 0 : _b.destroy(); super.finalizeState(context); } // Override draw to add render module draw({ parameters = {} }) { const model = this.state.model; const outlineFramebuffer = this.state.outlineFramebuffer; const outlineEmptyTexture = this.state.outlineEmptyTexture; if (!model || !outlineFramebuffer || !outlineEmptyTexture) { return; } const viewport = this.context.viewport; const viewportWidth = Math.max(1, Math.ceil(viewport.width)); const viewportHeight = Math.max(1, Math.ceil(viewport.height)); outlineFramebuffer.resize({ width: viewportWidth, height: viewportHeight }); const shadowmapTexture = getFramebufferTexture(outlineFramebuffer); if (!shadowmapTexture) { return; } const { jointRounded, capRounded, billboard, miterLimit, widthUnits, widthScale, widthMinPixels, widthMaxPixels } = this.props; const basePathProps = { jointType: Number(jointRounded), capType: Number(capRounded), billboard, widthUnits: UNIT[widthUnits], widthScale, miterLimit, widthMinPixels, widthMaxPixels }; this.setShaderModuleProps({ outline: { outlineEnabled: true, outlineRenderShadowmap: true, outlineShadowmap: outlineEmptyTexture } }); model.shaderInputs.setProps({ path: { ...basePathProps, jointType: 0, widthScale: widthScale * 1.3 } }); model.setParameters({ ...parameters, ...OUTLINE_SHADOWMAP_PARAMETERS }); const shadowRenderPass = this.context.device.beginRenderPass({ id: `${this.props.id}-outline-shadowmap`, framebuffer: outlineFramebuffer, parameters: { viewport: [0, 0, viewportWidth, viewportHeight] }, clearColor: [0, 0, 0, 0], clearDepth: 1, clearStencil: 0 }); model.draw(shadowRenderPass); shadowRenderPass.end(); this.setShaderModuleProps({ outline: { outlineEnabled: true, outlineRenderShadowmap: false, outlineShadowmap: shadowmapTexture } }); model.shaderInputs.setProps({ path: basePathProps }); model.setParameters(isPickingPass(parameters) ? parameters : { ...parameters, ...OUTLINE_RENDER_PARAMETERS }); model.draw(this.context.renderPass); } }; __publicField(PathOutlineLayer, "layerName", "PathOutlineLayer"); __publicField(PathOutlineLayer, "defaultProps", defaultProps); function isPickingPass(parameters) { return parameters.blend === true && parameters.blendAlphaSrcFactor === "constant"; } function getFramebufferTexture(framebuffer) { const colorAttachment = framebuffer.colorAttachments[0]; if (!colorAttachment) { return null; } return "texture" in colorAttachment ? colorAttachment.texture : colorAttachment; } // dist/path-marker-layer/path-marker-layer.js var import_core3 = require("@deck.gl/core"); var import_layers2 = require("@deck.gl/layers"); var import_mesh_layers = require("@deck.gl/mesh-layers"); // dist/path-marker-layer/arrow-2d-geometry.js var import_engine = require("@luma.gl/engine"); var Arrow2DGeometry = class extends import_engine.Geometry { constructor(opts = {}) { super(Object.assign({}, opts, { attributes: getArrowAttributes(opts), topology: "triangle-list" })); } }; function getArrowAttributes({ length = 1, headSize = 0.2, tailWidth = 0.05, tailStart = 0.05 }) { const texCoords = [ // HEAD 0.5, 1, 0, 0.5 - headSize / 2, 1 - headSize, 0, 0.5 + headSize / 2, 1 - headSize, 0, 0.5 - tailWidth / 2, tailStart, 0, 0.5 + tailWidth / 2, 1 - headSize, 0, 0.5 + tailWidth / 2, tailStart, 0, 0.5 - tailWidth / 2, tailStart, 0, 0.5 - tailWidth / 2, 1 - headSize, 0, 0.5 + tailWidth / 2, 1 - headSize, 0 ]; const normals = [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]; const positions = new Array(texCoords.length); for (let i = 0; i < texCoords.length / 3; i++) { const i3 = i * 3; positions[i3 + 0] = (texCoords[i3 + 0] - 0.5) * length; positions[i3 + 1] = (texCoords[i3 + 1] - 0.5) * length; positions[i3 + 2] = 0; } return { positions: { size: 3, value: new Float32Array(positions) }, normals: { size: 3, value: new Float32Array(normals) }, texCoords: { size: 2, value: new Float32Array(texCoords) } }; } // dist/path-marker-layer/create-path-markers.js var import_core = require("@math.gl/core"); function getLineLength(vPoints) { let lineLength = 0; for (let i = 0; i < vPoints.length - 1; i++) { lineLength += vPoints[i].distance(vPoints[i + 1]); } return lineLength; } var DEFAULT_COLOR = [0, 0, 0, 255]; var DEFAULT_DIRECTION = { forward: true, backward: false }; function createPathMarkers({ data, getPath = (x, context) => x.path, getDirection = (x) => x.direction, getColor = (_x) => DEFAULT_COLOR, getMarkerPercentages = (x, info) => [0.5], projectFlat }) { const markers = []; for (const object of data) { const path = getPath(object, null); const direction = getDirection(object) || DEFAULT_DIRECTION; const color = getColor(object); const vPoints = path.map((p) => new import_core.Vector2(p)); const vPointsReverse = vPoints.slice(0).reverse(); const lineLength = getLineLength(vPoints); const percentages = getMarkerPercentages(object, { lineLength }); for (const percentage of percentages) { if (direction.forward) { const marker = createMarkerAlongPath({ path: vPoints, percentage, lineLength, color, object, projectFlat }); markers.push(marker); } if (direction.backward) { const marker = createMarkerAlongPath({ path: vPointsReverse, percentage, lineLength, color, object, projectFlat }); markers.push(marker); } } } return markers; } function createMarkerAlongPath({ path, percentage, lineLength, color, object, projectFlat }) { const distanceAlong = lineLength * percentage; let currentDistance = 0; let previousDistance = 0; let i = 0; for (i = 0; i < path.length - 1; i++) { currentDistance += path[i].distance(path[i + 1]); if (currentDistance > distanceAlong) { break; } previousDistance = currentDistance; } if (i === path.length - 1) { i -= 1; } const vDirection = path[i + 1].clone().subtract(path[i]).normalize(); const along = distanceAlong - previousDistance; const vCenter = vDirection.clone().multiply(new import_core.Vector2(along, along)).add(path[i]); const vDirection2 = new import_core.Vector2(projectFlat(path[i + 1])).subtract(projectFlat(path[i])); const angle = vDirection2.verticalAngle() * 180 / Math.PI; return { position: [vCenter.x, vCenter.y, 0], angle, color, object }; } // dist/path-marker-layer/polyline.js var import_core2 = require("@math.gl/core"); function getClosestPointOnLine({ p, p1, p2, clampToLine = true }) { const lineVector = new import_core2.Vector3(p2).subtract(p1); const pointVector = new import_core2.Vector3(p).subtract(p1); let dotProduct = lineVector.dot(pointVector); if (clampToLine) { dotProduct = (0, import_core2.clamp)(dotProduct, 0, 1); } return lineVector.lerp(p1, p2, dotProduct); } function getClosestPointOnPolyline({ p, points }) { p = new import_core2.Vector3(p); let pClosest = null; let distanceSquared = Infinity; let index = -1; for (let i = 0; i < points.length - 1; ++i) { const p1 = points[i]; const p2 = points[i + 1]; const pClosestOnLine = getClosestPointOnLine({ p, p1, p2 }); const distanceToLineSquared = p.distanceSquared(pClosestOnLine); if (distanceToLineSquared < distanceSquared) { distanceSquared = distanceToLineSquared; pClosest = pClosestOnLine; index = i; } } return { point: pClosest, index, p1: points[index], p2: points[index + 1], distanceSquared, distance: Math.sqrt(distanceSquared) }; } // dist/path-marker-layer/path-marker-layer.js var DISTANCE_FOR_MULTI_ARROWS = 0.1; var ARROW_HEAD_SIZE = 0.2; var ARROW_TAIL_WIDTH = 0.05; var DEFAULT_MARKER_LAYER = import_mesh_layers.SimpleMeshLayer; var DEFAULT_MARKER_LAYER_PROPS = { mesh: new Arrow2DGeometry({ headSize: ARROW_HEAD_SIZE, tailWidth: ARROW_TAIL_WIDTH }) }; var defaultProps2 = Object.assign({}, PathOutlineLayer.defaultProps, { MarkerLayer: DEFAULT_MARKER_LAYER, markerLayerProps: DEFAULT_MARKER_LAYER_PROPS, sizeScale: 100, fp64: false, highlightIndex: -1, highlightPoint: null, getPath: (x) => x.path, getColor: (x) => x.color, getMarkerColor: (_x) => [0, 0, 0, 255], getDirection: (x) => x.direction, getMarkerPercentages: (object, { lineLength }) => lineLength > DISTANCE_FOR_MULTI_ARROWS ? [0.25, 0.5, 0.75] : [0.5] }); var PathMarkerLayer = class extends import_core3.CompositeLayer { state = void 0; initializeState() { this.state = { markers: [], mesh: new Arrow2DGeometry({ headSize: ARROW_HEAD_SIZE, tailWidth: ARROW_TAIL_WIDTH }), closestPoint: null, closestPoints: [] }; } projectFlat(xyz, viewport, coordinateSystem, coordinateOrigin) { if (coordinateSystem === import_core3.COORDINATE_SYSTEM.METER_OFFSETS) { const [dx, dy] = viewport.metersToLngLatDelta(xyz); const [x, y] = coordinateOrigin; return viewport.projectFlat([x + dx, dy + y]); } else if (coordinateSystem === import_core3.COORDINATE_SYSTEM.LNGLAT_OFFSETS) { const [dx, dy] = xyz; const [x, y] = coordinateOrigin; return viewport.projectFlat([x + dx, dy + y]); } return viewport.projectFlat(xyz); } updateState({ props, oldProps, changeFlags }) { if (changeFlags.dataChanged || changeFlags.updateTriggersChanged) { const { data, getPath, getDirection, getMarkerColor, getMarkerPercentages, coordinateSystem, coordinateOrigin } = this.props; const { viewport } = this.context; const projectFlat = (o) => this.projectFlat(o, viewport, coordinateSystem, coordinateOrigin); this.state.markers = createPathMarkers({ data, getPath, getDirection, getColor: getMarkerColor, getMarkerPercentages, projectFlat }); this._recalculateClosestPoint(); } if (changeFlags.propsChanged) { if (props.point !== oldProps.point) { this._recalculateClosestPoint(); } } } _recalculateClosestPoint() { const { highlightPoint, highlightIndex } = this.props; if (highlightPoint && highlightIndex >= 0) { const object = this.props.data[highlightIndex]; const points = this.props.getPath(object, null); const { point } = getClosestPointOnPolyline({ points, p: highlightPoint }); this.state.closestPoints = [{ position: point }]; } else { this.state.closestPoints = []; } } getPickingInfo({ info }) { return Object.assign(info, { // override object with picked feature object: info.object && info.object.path || info.object }); } renderLayers() { return [ new PathOutlineLayer(this.props, this.getSubLayerProps({ id: "paths", // Note: data has to be passed explicitly like this to avoid being empty data: this.props.data })), new this.props.MarkerLayer(this.getSubLayerProps(Object.assign({}, this.props.markerLayerProps, { id: "markers", data: this.state.markers, getOrientation: (x) => [0, -x.angle, 0], getColor: (x) => x.color, sizeScale: this.props.sizeScale, fp64: this.props.fp64, pickable: false, parameters: { blend: false, depthTest: false } }))), this.state.closestPoints && new import_layers2.ScatterplotLayer({ id: `${this.props.id}-highlight`, data: this.state.closestPoints, fp64: this.props.fp64 }) ]; } }; __publicField(PathMarkerLayer, "layerName", "PathMarkerLayer"); __publicField(PathMarkerLayer, "defaultProps", defaultProps2); // dist/dependency-arrow-layer/dependency-arrow-layer.js var import_core7 = require("@deck.gl/core"); var import_layers3 = require("@deck.gl/layers"); // dist/dependency-arrow-layer/create-path-markers.js var import_core4 = require("@deck.gl/core"); var import_core5 = require("@math.gl/core"); var PathDirection; (function(PathDirection2) { PathDirection2[PathDirection2["NONE"] = 0] = "NONE"; PathDirection2[PathDirection2["FORWARD"] = 1] = "FORWARD"; PathDirection2[PathDirection2["BACKWARD"] = 2] = "BACKWARD"; PathDirection2[PathDirection2["BOTH"] = 3] = "BOTH"; })(PathDirection || (PathDirection = {})); function createPathMarkers2({ data, getPath, positionSize, getDirection, getMarkerPlacements, mode }) { const markers = []; if (!data || typeof data === "string" || !(Symbol.iterator in Object(data))) { return markers; } const { iterable, objectInfo } = (0, import_core4.createIterable)(data); for (const object of iterable) { objectInfo.index++; const path = normalizePath(getPath(object, objectInfo), positionSize); if (path.length < 2) { continue; } if (mode !== "path") { path.splice(1, path.length - 2); } const direction = typeof getDirection === "function" ? getDirection(object, objectInfo) : getDirection; const lineLength = getLineLength2(path); if (!Number.isFinite(lineLength) || lineLength <= 0) { continue; } objectInfo.lineLength = lineLength; const placements = typeof getMarkerPlacements === "function" ? getMarkerPlacements(object, objectInfo) : getMarkerPlacements; const sourceObject = { object, index: objectInfo.index }; for (const dir of [PathDirection.FORWARD, PathDirection.BACKWARD]) { if (!(direction & dir)) continue; if (dir === PathDirection.BACKWARD) { path.reverse(); } for (const percentage of placements) { const marker = mode === "arc" ? { source: path[0], target: path[1], percentage, __source: sourceObject } : createMarkerAlongPath2({ path, percentage, lineLength, sourceObject }); markers.push(marker); } } } return markers; } function normalizePath(path, size) { if (!path) { return []; } if (Array.isArray(path[0])) { return path.map(([x, y]) => new import_core5.Vector2(x, y)); } const flatPath = path; const length = flatPath.length / size; const points = new Array(length); for (let i = 0; i < length; i++) { points[i] = new import_core5.Vector2(flatPath[i * size], flatPath[i * size + 1]); } return points; } function getLineLength2(vPoints) { let lineLength = 0; for (let i = 0; i < vPoints.length - 1; i++) { lineLength += vPoints[i].distance(vPoints[i + 1]); } return lineLength; } function createMarkerAlongPath2({ path, percentage, lineLength, sourceObject }) { const distanceAlong = lineLength * percentage; let currentDistance = 0; let previousDistance = 0; let i = 0; for (i = 0; i < path.length - 1; i++) { currentDistance += path[i].distance(path[i + 1]); if (currentDistance >= distanceAlong) { break; } previousDistance = currentDistance; } if (i === path.length - 1) { i -= 1; } const along = distanceAlong - previousDistance; const segmentLength = path[i + 1].distance(path[i]); return { source: path[i], target: path[i + 1], percentage: segmentLength > 0 ? along / segmentLength : 0, __source: sourceObject }; } // dist/dependency-arrow-layer/geometry-layer.js var import_core6 = require("@deck.gl/core"); var import_engine2 = require("@luma.gl/engine"); var geometryLayerUniforms = { name: "geometryLayer", vs: `uniform geometryLayerUniforms { float sizeScale; highp int sizeUnits; highp int interpolationMode; } geometryLayer; `, fs: `uniform geometryLayerUniforms { float sizeScale; highp int sizeUnits; highp int interpolationMode; } geometryLayer; `, uniformTypes: { sizeScale: "f32", sizeUnits: "i32", interpolationMode: "i32" } }; var defaultProps3 = { sizeUnits: "common", sizeScale: { type: "number", min: 0, value: 1 }, interpolationMode: "line", getPickingColor: { type: "accessor", value: [0, 0, 0] }, getSourcePosition: { type: "accessor", value: (x) => x.source }, getTargetPosition: { type: "accessor", value: (x) => x.target }, getPositionRatio: { type: "accessor", value: 1 }, getSize: { type: "accessor", value: [1, 1] }, getColor: { type: "accessor", value: [0, 0, 0, 255] }, getArcHeight: { type: "accessor", value: 1 }, getArcTilt: { type: "accessor", value: 0 } }; var vs2 = `#version 300 es #define SHADER_NAME geometry-layer-vertex-shader in vec2 positions; in vec3 instanceSourcePositions; in vec3 instanceSourcePositions64Low; in vec3 instanceTargetPositions; in vec3 instanceTargetPositions64Low; in float instanceRatios; in vec2 instanceSizes; in vec4 instanceColors; in float instanceArcHeights; in float instanceArcTilts; in vec3 instancePickingColors; out vec4 vColor; out vec2 vPosition; flat out vec2 vPixelSize; const int GEOMETRY_LINE = 0; const int GEOMETRY_ARC = 1; // START ARC LAYER VERTEX float paraboloid(float distance, float sourceZ, float targetZ, float ratio) { float deltaZ = targetZ - sourceZ; float dh = distance * instanceArcHeights; if (dh == 0.0) { return sourceZ + deltaZ * ratio; } float unitZ = deltaZ / dh; float p2 = unitZ * unitZ + 1.0; // sqrt does not deal with negative values, manually flip source and target if delta.z < 0 float dir = step(deltaZ, 0.0); float z0 = mix(sourceZ, targetZ, dir); float r = mix(ratio, 1.0 - ratio, dir); return sqrt(r * (p2 - r)) * dh + z0; } vec3 interpolateArc(vec3 source, vec3 target, float ratio) { float distance = length(source.xy - target.xy); float z = paraboloid(distance, source.z, target.z, ratio); float tiltAngle = radians(instanceArcTilts); vec2 tiltDirection = normalize(target.xy - source.xy); vec2 tilt = vec2(-tiltDirection.y, tiltDirection.x) * z * sin(tiltAngle); return vec3( mix(source.xy, target.xy, ratio) + tilt, z * cos(tiltAngle) ); } // END ARC LAYER VERTEX vec3 interplolatePath(vec3 source, vec3 target, float ratio) { if (geometryLayer.interpolationMode == GEOMETRY_ARC) { return interpolateArc(source, target, ratio); } return mix(source, target, ratio); } void main(void) { geometry.worldPosition = instanceSourcePositions; geometry.worldPositionAlt = instanceTargetPositions; vPosition = (positions + 1.0) / 2.0; geometry.uv = vPosition; vec3 source = project_position(instanceSourcePositions, instanceSourcePositions64Low); vec3 target = project_position(instanceTargetPositions, instanceTargetPositions64Low); vec3 curr = interplolatePath(source, target, instanceRatios); vec2 normal; if (instanceRatios < 0.01) { vec3 next = interplolatePath(source, target, instanceRatios + 0.01); normal = next.xy - curr.xy; } else { vec3 prev = interplolatePath(source, target, instanceRatios - 0.01); normal = curr.xy - prev.xy; } vec2 scaledSize = instanceSizes * geometryLayer.sizeScale; // Anchor the marker at the triangle tip, so ratio 1.0 places the arrowhead on the endpoint. vec2 markerPosition = vec2((positions.x - 1.0) / 2.0, positions.y / 2.0); vec2 offset = markerPosition * scaledSize; float angle = atan(normal.y, normal.x); float cosA = cos(angle); float sinA = sin(angle); offset = vec2( offset.x * cosA - offset.y * sinA, offset.x * sinA + offset.y * cosA ); vec3 offsetCommon = vec3(offset, 0.); if (geometryLayer.sizeUnits == UNIT_PIXELS) { offsetCommon.xy = project_pixel_size(offset); vPixelSize = scaledSize; } else { vPixelSize = project_size(scaledSize); } geometry.pickingColor = instancePickingColors; geometry.position = vec4(curr + offsetCommon, 0.1); gl_Position = project_common_position_to_clipspace(geometry.position); DECKGL_FILTER_GL_POSITION(gl_Position, geometry); vColor = vec4(instanceColors.rgb, instanceColors.a * layer.opacity); DECKGL_FILTER_COLOR(vColor, geometry); } `; var fs2 = `#version 300 es #define SHADER_NAME geometry-layer-fragment-shader precision highp float; in vec4 vColor; in vec2 vPosition; flat in vec2 vPixelSize; out vec4 fragColor; float smoothedgeSigned(float signedDistance) { float edgeRadius = fwidth(signedDistance); return smoothstep(-edgeRadius, edgeRadius, signedDistance); } float inTriangle(vec2 bbox, vec2 uv) { float w = max(bbox.x, 1.0); float h = max(bbox.y, 1.0); float d = ((1.0 - abs(1.0 - uv.y * 2.0)) - uv.x) * w; return smoothedgeSigned(d); } void main(void) { geometry.uv = vPosition; float inShape = inTriangle(vPixelSize, vPosition); if (inShape == 0.0) { discard; } fragColor = vColor; fragColor.a *= inShape; DECKGL_FILTER_COLOR(fragColor, geometry); } `; var GeometryLayer = class extends import_core6.Layer { state = {}; getShaders() { return super.getShaders({ vs: vs2, fs: fs2, modules: [import_core6.project32, import_core6.picking, geometryLayerUniforms] }); } initializeState() { this.getAttributeManager().addInstanced({ instanceSourcePositions: { size: 3, type: "float64", fp64: this.use64bitPositions(), transition: true, accessor: "getSourcePosition" }, instanceTargetPositions: { size: 3, type: "float64", fp64: this.use64bitPositions(), transition: true, accessor: "getTargetPosition" }, instanceRatios: { size: 1, transition: true, accessor: "getPositionRatio" }, instanceArcHeights: { size: 1, transition: true, accessor: "getArcHeight" }, instanceArcTilts: { size: 1, transition: true, accessor: "getArcTilt" }, instanceSizes: { size: 2, transition: true, accessor: "getSize" }, instanceColors: { size: 4, transition: true, type: "unorm8", accessor: "getColor", defaultValue: [0, 0, 0, 255] }, instancePickingColors: { size: 3, type: "uint8", accessor: "getPickingColor" } }); } updateState(params) { var _a; super.updateState(params); if (params.changeFlags.extensionsChanged) { (_a = this.state.model) == null ? void 0 : _a.destroy(); this.state.model = this._getModel(); this.getAttributeManager().invalidateAll(); } } draw() { const model = this.state.model; if (!model) { return; } const { sizeScale, sizeUnits, interpolationMode } = this.props; const geometryLayerProps = { sizeScale, sizeUnits: import_core6.UNIT[sizeUnits], interpolationMode: interpolationMode === "line" ? 0 : 1 }; model.shaderInputs.setProps({ geometryLayer: geometryLayerProps }); model.draw(this.context.renderPass); } _getModel() { const positions = [-1, -1, 1, -1, -1, 1, 1, 1]; return new import_engine2.Model(this.context.device, { ...this.getShaders(), id: this.props.id, bufferLayout: this.getAttributeManager().getBufferLayouts(), geometry: new import_engine2.Geometry({ topology: "triangle-strip", attributes: { positions: { size: 2, value: new Float32Array(positions) } } }), isInstanced: true }); } }; __publicField(GeometryLayer, "defaultProps", defaultProps3); __publicField(GeometryLayer, "layerName", "GeometryLayer"); // dist/dependency-arrow-layer/dependency-arrow-layer.js var defaultProps4 = { getPath: import_layers3.PathLayer.defaultProps.getPath, getColor: import_layers3.LineLayer.defaultProps.getColor, getWidth: import_layers3.LineLayer.defaultProps.getWidth, widthUnits: import_layers3.LineLayer.defaultProps.widthUnits, widthScale: import_layers3.LineLayer.defaultProps.widthScale, widthMinPixels: import_layers3.LineLayer.defaultProps.widthMinPixels, widthMaxPixels: import_layers3.LineLayer.defaultProps.widthMaxPixels, arcNumSegments: import_layers3.ArcLayer.defaultProps.numSegments, getArcHeight: import_layers3.ArcLayer.defaultProps.getHeight, getArcTilt: import_layers3.ArcLayer.defaultProps.getTilt, mode: "path", markerSizeScale: 10, highlightIndex: -1, highlightPoint: null, getMarkerColor: { type: "accessor", value: void 0 }, getDirection: { type: "accessor", value: PathDirection.FORWARD }, getMarkerSize: { type: "accessor", value: [1, 1] }, getMarkerPlacements: { type: "accessor", value: [0.5] } }; var DependencyArrowLayer = class extends import_core7.CompositeLayer { state = { markers: [] }; updateState({ props, oldProps, changeFlags }) { const shouldRebuildMarkers = changeFlags.dataChanged || props.mode !== oldProps.mode || props.positionFormat !== oldProps.positionFormat || props.getPath !== oldProps.getPath || props.getDirection !== oldProps.getDirection || props.getMarkerPlacements !== oldProps.getMarkerPlacements || changeFlags.updateTriggersChanged && (changeFlags.updateTriggersChanged["getPath"] || changeFlags.updateTriggersChanged["getDirection"] || changeFlags.updateTriggersChanged["getMarkerPlacements"]); if (shouldRebuildMarkers) { const { data, mode, getPath, getDirection, getMarkerPlacements } = this.props; this.state.markers = createPathMarkers2({ data, positionSize: props.positionFormat.length, getPath, getDirection, getMarkerPlacements, mode }); } } getPickingInfo({ info }) { const pickedObject = info.object; if (pickedObject && pickedObject.__source) { info.object = pickedObject.__source.object; } return info; } renderLayers() { const { mode, getPath, getColor, getMarkerColor, getMarkerSize, markerSizeScale, updateTriggers = {} } = this.props; let pathLayer = null; if (mode === "path") { pathLayer = new import_layers3.PathLayer(this.props, this.getSubLayerProps({ id: "links-path", updateTriggers: { getPath: updateTriggers["getPath"], getColor: updateTriggers["getColor"], getWidth: updateTriggers["getWidth"] } })); } else { const positionSize = this.props.positionFormat.length; const sharedProps = { ...this.props, data: this.props.data, getSourcePosition: (datum, info) => { const path = getPath(datum, info); return getFirstPoint(path, positionSize) ?? [NaN, NaN]; }, getTargetPosition: (datum, info) => { const path = getPath(datum, info); return getLastPoint(path, positionSize) ?? [NaN, NaN]; } }; if (mode === "arc") { pathLayer = new import_layers3.ArcLayer(sharedProps, { getSourceColor: this.props.getColor, getTargetColor: this.props.getColor, numSegments: this.props.arcNumSegments, getHeight: this.props.getArcHeight, getTilt: this.props.getArcTilt }, this.getSubLayerProps({ id: "links-arc", updateTriggers: { getSourcePosition: updateTriggers["getPath"], getTargetPosition: updateTriggers["getPath"], getSourceColor: updateTriggers["getColor"], getTargetColor: updateTriggers["getColor"], getWidth: updateTriggers["getWidth"], getHeight: updateTriggers["getArcHeight"], getTilt: updateTriggers["getArcTilt"] } })); } else { pathLayer = new import_layers3.LineLayer(sharedProps, this.getSubLayerProps({ id: "links-line", updateTriggers: { getSourcePosition: updateTriggers["getPath"], getTargetPosition: updateTriggers["getPath"], getColor: updateTriggers["getColor"], getWidth: updateTriggers["getWidth"] } })); } } return [ pathLayer, new GeometryLayer(this.getSubLayerProps({ id: "arrows", updateTriggers: { getSize: updateTriggers["getMarkerSize"], getColor: getMarkerColor ? updateTriggers["getMarkerColor"] : updateTriggers["getColor"], getArcHeight: updateTriggers["getArcHeight"], getArcTilt: updateTriggers["getArcTilt"] } }), { data: this.state.markers, sizeUnits: "pixels", sizeScale: markerSizeScale, interpolationMode: mode === "arc" ? "arc" : "line", getSourcePosition: (d) => d.source, getTargetPosition: (d) => d.target, getPositionRatio: (d) => d.percentage, getSize: this.getSubLayerAccessor(getMarkerSize), getColor: this.getSubLayerAccessor(getMarkerColor ?? getColor), getArcHeight: this.getSubLayerAccessor(this.props.getArcHeight), getArcTilt: this.getSubLayerAccessor(this.props.getArcTilt), getPickingColor: (d) => this.encodePickingColor(d.__source.index) }) ]; } }; __publicField(DependencyArrowLayer, "layerName", "DependencyArrowLayer"); __publicField(DependencyArrowLayer, "defaultProps", defaultProps4); function getFirstPoint(path, size) { if (!path || path.length === 0) return null; if (Array.isArray(path[0])) { return path[0]; } return path.slice(0, size); } function getLastPoint(path, size) { if (!path || path.length === 0) return null; if (Array.isArray(path[0])) { return path[path.length - 1]; } const len = Math.floor(path.length / size) * size; return path.slice(len - size, len); } // dist/skybox-layer/skybox-layer.js var import_core8 = require("@loaders.gl/core"); var import_textures = require("@loaders.gl/textures"); var import_core9 = require("@deck.gl/core"); var import_core10 = require("@math.gl/core"); var import_engine3 = require("@luma.gl/engine"); // dist/skybox-layer/cubemap-utils.js var CUBE_FACES = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"]; function createCubemapLoadOptions(cubemap, loadOptions) { var _a; if (!loadOptions) { return void 0; } if (typeof cubemap === "string" || ((_a = loadOptions.core) == null ? void 0 : _a.baseUrl) || !loadOptions.baseUrl) { return loadOptions; } return { ...loadOptions, core: { ...loadOptions.core, baseUrl: loadOptions.baseUrl } }; } function convertLoadedCubemapToTextureData(texture) { if (texture.type !== "cube" || !Array.isArray(texture.data) || texture.data.length !== 6) { throw new Error("SkyboxLayer expected a cubemap texture with six faces."); } return Object.fromEntries(CUBE_FACES.map((face, index) => [face, normalizeTextureSlice(texture.data[index], face)])); } function normalizeTextureSlice(faceData, face) { if (Array.isArray(faceData)) { if (faceData.length === 0) { throw new Error(`SkyboxLayer received an empty mip chain for face ${face}.`); } return faceData.map((level, mipLevel) => normalizeTextureLevel(level, face, mipLevel)); } return normalizeTextureLevel(faceData, face, 0); } function normalizeTextureLevel(faceData, face, mipLevel) { if (typeof ImageBitmap !== "undefined" && faceData instanceof ImageBitmap) { return faceData; } const level = faceData; if (level == null ? void 0 : level.imageBitmap) { return level.imageBitmap; } if (level && ArrayBuffer.isView(level.data) && level.width && level.height) { return { data: level.data, width: level.width, height: level.height, format: typeof level.textureFormat === "string" ? level.textureFormat : typeof level.format === "string" ? level.format : "rgba8unorm" }; } throw new Error(`SkyboxLayer could not normalize cubemap face ${face} mip ${mipLevel}.`); } // dist/skybox-layer/skybox-layer.js var app = { name: "app", uniformTypes: { modelMatrix: "mat4x4<f32>", viewMatrix: "mat4x4<f32>", projectionMatrix: "mat4x4<f32>" } }; var SKYBOX_PARAMETERS = { cullMode: "front", depthWriteEnabled: false, depthCompare: "less-equal" }; var SKYBOX_SCALE = new import_core10.Matrix4().scale([2, 2, 2]); var defaultProps5 = { cubemap: null, loadOptions: null, orientation: "default" }; var SkyboxLayer = class extends import_core9.Layer { state = void 0; /** Initializes the cube model and starts loading the cubemap texture. */ initializeState() { const attributeManager = this.getAttributeManager(); attributeManager == null ? void 0 : attributeManager.remove(["instancePickingColors"]); const shaderInputs = new import_engine3.ShaderInputs(createShaderInputModules(this.context.defaultShaderModules), { disableWarnings: true }); const model = this._getModel(shaderInputs); this.setState({ cubemapTexture: null, loadCount: 0, model, shaderInputs }); this._loadCubemap().catch(() => { }); } /** Reloads the cubemap when its source manifest or load options change. */ updateState({ props, oldProps }) { if (props.cubemap !== oldProps.cubemap || props.loadOptions !== oldProps.loadOptions) { this._loadCubemap().catch(() => { }); } } /** Releases GPU resources owned by the layer. */ finalizeState() { var _a, _b; (_a = this.state.cubemapTexture) == null ? void 0 : _a.destroy(); (_b = this.state.model) == null ? void 0 : _b.destroy(); } /** Draws the skybox cube for the current viewport. */ draw() { const { model, cubemapTexture, shaderInputs } = this.state; if (!model || !cubemapTexture || !shaderInputs) { return; } const viewport = this.context.viewport; shaderInputs.setProps({ app: { modelMatrix: getSkyboxModelMatrix(this.props.orientation), viewMatrix: getSkyboxViewMatrix(viewport), projectionMatrix: viewport.projectionMatrix } }); model.draw(this.context.renderPass); } /** Creates the luma.gl model used to render the skybox cube. */ _getModel(shaderInputs) { var _a; return new import_engine3.Model(this.context.device, { ...this.getShaders(), id: this.props.id, bufferLayout: ((_a = this.getAttributeManager()) == null ? void 0 : _a.getBufferLayouts()) || [], geometry: new import_engine3.CubeGeometry({ indices: true }), shaderInputs, isInstanced: false, parameters: SKYBOX_PARAMETERS }); } /** Returns the WGSL/GLSL shader pair used by the layer. */ getShaders() { return { source: SKYBOX_WGSL, vs: SKYBOX_VS, fs: SKYBOX_FS }; } /** Starts an asynchronous cubemap load for the current props. */ async _loadCubemap() { const { cubemap, loadOptions } = this.props; const nextLoadCount = this.state.loadCount + 1; this.setState({ loadCount: nextLoadCount }); if (!cubemap) { this._setCubemapTexture(null); return; } try { const loadedTexture = await loadCubemapSource(cubemap, loadOptions); if (this.state.loadCount !== nextLoadCount || !this.state.model) { return; } const cubemapData = convertLoadedCubemapToTextureData(loadedTexture); this._setCubemapTexture(createCubemapTexture(this.context.device, cubemapData)); } catch (error) { if (this.state.loadCount === nextLoadCount) { this.raiseError(error, "SkyboxLayer failed to load cubemap"); } } } /** Swaps the active GPU cubemap texture and updates model bindings. */ _setCubemapTexture(texture) { const { cubemapTexture, model } = this.state; if (cubemapTexture === texture) { return; } cubemapTexture == null ? void 0 : cubemapTexture.destroy(); this.setState({ cubemapTexture: texture }); if (texture && model) { model.setBindings({ cubeTexture: texture }); } this.setNeedsRedraw(); } }; __publicField(SkyboxLayer, "defaultProps", defaultProps5); __publicField(SkyboxLayer, "layerName", "SkyboxLayer"); async function loadCubemapSource(cubemap, loadOptions) { const normalizedLoadOptions = createCubemapLoadOptions(cubemap, loadOptions); if (typeof cubemap === "string") { return await (0, import_core8.load)(cubemap, import_textures.TextureCubeLoader, normalizedLoadOptions); } return await import_textures.TextureCubeLoader.parseText(JSON.stringify(cubemap), normalizedLoadOptions); } function createCubemapTexture(device, data) { return new import_engine3.DynamicTexture(device, { dimension: "cube", data, mipmaps: true, sampler: { addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge", addressModeW: "clamp-to-edge", magFilter: "linear", minFilter: "linear", mipmapFilter: "linear" } }); } function getSkyboxViewMatrix(viewport) { const viewMatrix = new import_core10.Matrix4(viewport.viewMatrixUncentered || viewport.viewMatrix); viewMatrix[12] = 0; viewMatrix[13] = 0; viewMatrix[14] = 0; return viewMatrix; } function getSkyboxModelMatrix(orientation = "default") { if (orientation === "y-up") { return new import_core10.Matrix4().rotateX(Math.PI / 2).scale([2, 2, 2]); } return new import_core10.Matrix4(SKYBOX_SCALE); } function createShaderInputModules(defaultShaderModules) { return Object.fromEntries([app, ...defaultShaderModules].map((module2) => [module2.name, module2])); } var SKYBOX_WGSL = ( /* wgsl */ ` struct appUniforms { modelMatrix: mat4x4<f32>, viewMatrix: mat4x4<f32>, projectionMatrix: mat4x4<f32>, }; @group(0) @binding(auto) var<uniform> app : appUniforms; @group(0) @binding(auto) var cubeTexture : texture_cube<f32>; @group(0) @binding(auto) var cubeTextureSampler : sampler; struct VertexInputs { @location(0) positions : vec3<f32>, }; struct VertexOutputs { @builtin(position) position : vec4<f32>, @location(0) direction : vec3<f32>, }; @vertex fn vertexMain(inputs: VertexInputs) -> VertexOutputs { var outputs : VertexOutputs; let clipPosition = app.projectionMatrix * app.viewMatrix * app.modelMatrix * vec4<f32>(inputs.positions, 1.0); outputs.position = vec4<f32>(clipPosition.x, clipPosition.y, clipPosition.w, clipPosition.w); outputs.direction = inputs.positions; return outputs; } @fragment fn fragmentMain(inputs: VertexOutputs) -> @location(0) vec4<f32> { return textureSample(cubeTexture, cubeTextureSampler, normalize(inputs.direction)); } ` ); var SKYBOX_VS = ( /* glsl */ `#version 300 es in vec3 positions; uniform appUniforms { mat4 modelMatrix; mat4 viewMatrix; mat4 projectionMatrix; } app; out vec3 vDirection; void main(void) { vec4 clipPosition = app.projectionMatrix * app.viewMatrix * app.modelMatrix * vec4(positions, 1.0); gl_Position = clipPosition.xyww; vDirection = positions; } ` ); var SKYBOX_FS = ( /* glsl */ `#version 300 es precision highp float; uniform samplerCube cubeTexture; in vec3 vDirection; out vec4 fragColor; void main(void) { fragColor = texture(cubeTexture, normalize(vDirection)); } ` ); //# sourceMappingURL=index.cjs.map