UNPKG

@deck.gl/mesh-layers

Version:

deck.gl layers that loads 3D meshes or scene graphs

1,730 lines (1,685 loc) 513 kB
(function webpackUniversalModuleDefinition(root, factory) { if (typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if (typeof define === 'function' && define.amd) define([], factory); else if (typeof exports === 'object') exports['deck'] = factory(); else root['deck'] = factory();})(globalThis, function () { "use strict"; var __exports__ = (() => { var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name12 in all) __defProp(target, name12, { get: all[name12], 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 __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // external-global-plugin:@deck.gl/core var require_core = __commonJS({ "external-global-plugin:@deck.gl/core"(exports, module) { module.exports = globalThis.deck; } }); // external-global-plugin:@luma.gl/core var require_core2 = __commonJS({ "external-global-plugin:@luma.gl/core"(exports, module) { module.exports = globalThis.luma; } }); // external-global-plugin:@luma.gl/engine var require_engine = __commonJS({ "external-global-plugin:@luma.gl/engine"(exports, module) { module.exports = globalThis.luma; } }); // bundle.ts var bundle_exports = {}; __export(bundle_exports, { ScenegraphLayer: () => ScenegraphLayer, SimpleMeshLayer: () => SimpleMeshLayer }); // ../core/bundle/peer-dependency.ts var peer_dependency_exports = {}; var import_core = __toESM(require_core(), 1); __reExport(peer_dependency_exports, __toESM(require_core(), 1)); if (!import_core.Layer) { throw new Error("@deck.gl/core is not found"); } // bundle.ts __reExport(bundle_exports, peer_dependency_exports); // src/simple-mesh-layer/simple-mesh-layer.ts var import_core3 = __toESM(require_core(), 1); var import_core4 = __toESM(require_core2(), 1); var import_engine = __toESM(require_engine(), 1); // src/utils/matrix.ts var import_core2 = __toESM(require_core(), 1); var RADIAN_PER_DEGREE = Math.PI / 180; var modelMatrix = new Float32Array(16); var valueArray = new Float32Array(12); function calculateTransformMatrix(targetMatrix, orientation, scale5) { const pitch = orientation[0] * RADIAN_PER_DEGREE; const yaw = orientation[1] * RADIAN_PER_DEGREE; const roll = orientation[2] * RADIAN_PER_DEGREE; const sr = Math.sin(roll); const sp = Math.sin(pitch); const sw = Math.sin(yaw); const cr = Math.cos(roll); const cp = Math.cos(pitch); const cw = Math.cos(yaw); const scx = scale5[0]; const scy = scale5[1]; const scz = scale5[2]; targetMatrix[0] = scx * cw * cp; targetMatrix[1] = scx * sw * cp; targetMatrix[2] = scx * -sp; targetMatrix[3] = scy * (-sw * cr + cw * sp * sr); targetMatrix[4] = scy * (cw * cr + sw * sp * sr); targetMatrix[5] = scy * cp * sr; targetMatrix[6] = scz * (sw * sr + cw * sp * cr); targetMatrix[7] = scz * (-cw * sr + sw * sp * cr); targetMatrix[8] = scz * cp * cr; } function getExtendedMat3FromMat4(mat4) { mat4[0] = mat4[0]; mat4[1] = mat4[1]; mat4[2] = mat4[2]; mat4[3] = mat4[4]; mat4[4] = mat4[5]; mat4[5] = mat4[6]; mat4[6] = mat4[8]; mat4[7] = mat4[9]; mat4[8] = mat4[10]; mat4[9] = mat4[12]; mat4[10] = mat4[13]; mat4[11] = mat4[14]; return mat4.subarray(0, 12); } var MATRIX_ATTRIBUTES = { size: 12, accessor: ["getOrientation", "getScale", "getTranslation", "getTransformMatrix"], shaderAttributes: { instanceModelMatrixCol0: { size: 3, elementOffset: 0 }, instanceModelMatrixCol1: { size: 3, elementOffset: 3 }, instanceModelMatrixCol2: { size: 3, elementOffset: 6 }, instanceTranslation: { size: 3, elementOffset: 9 } }, update(attribute, { startRow, endRow }) { const { data, getOrientation, getScale, getTranslation, getTransformMatrix } = this.props; const arrayMatrix = Array.isArray(getTransformMatrix); const constantMatrix = arrayMatrix && getTransformMatrix.length === 16; const constantScale = Array.isArray(getScale); const constantOrientation = Array.isArray(getOrientation); const constantTranslation = Array.isArray(getTranslation); const hasMatrix = constantMatrix || !arrayMatrix && Boolean(getTransformMatrix(data[0])); if (hasMatrix) { attribute.constant = constantMatrix; } else { attribute.constant = constantOrientation && constantScale && constantTranslation; } const instanceModelMatrixData = attribute.value; if (attribute.constant) { let matrix; if (hasMatrix) { modelMatrix.set(getTransformMatrix); matrix = getExtendedMat3FromMat4(modelMatrix); } else { matrix = valueArray; const orientation = getOrientation; const scale5 = getScale; calculateTransformMatrix(matrix, orientation, scale5); matrix.set(getTranslation, 9); } attribute.value = new Float32Array(matrix); } else { let i = startRow * attribute.size; const { iterable, objectInfo } = (0, import_core2.createIterable)(data, startRow, endRow); for (const object of iterable) { objectInfo.index++; let matrix; if (hasMatrix) { modelMatrix.set( constantMatrix ? getTransformMatrix : getTransformMatrix(object, objectInfo) ); matrix = getExtendedMat3FromMat4(modelMatrix); } else { matrix = valueArray; const orientation = constantOrientation ? getOrientation : getOrientation(object, objectInfo); const scale5 = constantScale ? getScale : getScale(object, objectInfo); calculateTransformMatrix(matrix, orientation, scale5); matrix.set(constantTranslation ? getTranslation : getTranslation(object, objectInfo), 9); } instanceModelMatrixData[i++] = matrix[0]; instanceModelMatrixData[i++] = matrix[1]; instanceModelMatrixData[i++] = matrix[2]; instanceModelMatrixData[i++] = matrix[3]; instanceModelMatrixData[i++] = matrix[4]; instanceModelMatrixData[i++] = matrix[5]; instanceModelMatrixData[i++] = matrix[6]; instanceModelMatrixData[i++] = matrix[7]; instanceModelMatrixData[i++] = matrix[8]; instanceModelMatrixData[i++] = matrix[9]; instanceModelMatrixData[i++] = matrix[10]; instanceModelMatrixData[i++] = matrix[11]; } } } }; function shouldComposeModelMatrix(viewport, coordinateSystem) { return coordinateSystem === "cartesian" || coordinateSystem === "meter-offsets" || coordinateSystem === "default" && !viewport.isGeospatial; } // src/simple-mesh-layer/simple-mesh-layer-uniforms.ts var uniformBlock = `layout(std140) uniform simpleMeshUniforms { float sizeScale; bool composeModelMatrix; bool hasTexture; bool flatShading; } simpleMesh; `; var simpleMeshUniforms = { name: "simpleMesh", vs: uniformBlock, fs: uniformBlock, uniformTypes: { sizeScale: "f32", composeModelMatrix: "f32", hasTexture: "f32", flatShading: "f32" } }; // src/simple-mesh-layer/simple-mesh-layer-vertex.glsl.ts var simple_mesh_layer_vertex_glsl_default = `#version 300 es #define SHADER_NAME simple-mesh-layer-vs // Primitive attributes in vec3 positions; in vec3 normals; in vec3 colors; in vec2 texCoords; // Instance attributes in vec3 instancePositions; in vec3 instancePositions64Low; in vec4 instanceColors; in vec3 instancePickingColors; in vec3 instanceModelMatrixCol0; in vec3 instanceModelMatrixCol1; in vec3 instanceModelMatrixCol2; in vec3 instanceTranslation; // Outputs to fragment shader out vec2 vTexCoord; out vec3 cameraPosition; out vec3 normals_commonspace; out vec4 position_commonspace; out vec4 vColor; void main(void) { geometry.worldPosition = instancePositions; geometry.uv = texCoords; geometry.pickingColor = instancePickingColors; vTexCoord = texCoords; cameraPosition = project.cameraPosition; vColor = vec4(colors * instanceColors.rgb, instanceColors.a); mat3 instanceModelMatrix = mat3(instanceModelMatrixCol0, instanceModelMatrixCol1, instanceModelMatrixCol2); vec3 pos = (instanceModelMatrix * positions) * simpleMesh.sizeScale + instanceTranslation; if (simpleMesh.composeModelMatrix) { DECKGL_FILTER_SIZE(pos, geometry); // using instancePositions as world coordinates // when using globe mode, this branch does not re-orient the model to align with the surface of the earth // call project_normal before setting position to avoid rotation normals_commonspace = project_normal(instanceModelMatrix * normals); geometry.worldPosition += pos; gl_Position = project_position_to_clipspace(pos + instancePositions, instancePositions64Low, vec3(0.0), position_commonspace); geometry.position = position_commonspace; } else { pos = project_size(pos); DECKGL_FILTER_SIZE(pos, geometry); gl_Position = project_position_to_clipspace(instancePositions, instancePositions64Low, pos, position_commonspace); geometry.position = position_commonspace; normals_commonspace = project_normal(instanceModelMatrix * normals); } geometry.normal = normals_commonspace; DECKGL_FILTER_GL_POSITION(gl_Position, geometry); DECKGL_FILTER_COLOR(vColor, geometry); } `; // src/simple-mesh-layer/simple-mesh-layer-fragment.glsl.ts var simple_mesh_layer_fragment_glsl_default = `#version 300 es #define SHADER_NAME simple-mesh-layer-fs precision highp float; uniform sampler2D sampler; in vec2 vTexCoord; in vec3 cameraPosition; in vec3 normals_commonspace; in vec4 position_commonspace; in vec4 vColor; out vec4 fragColor; void main(void) { geometry.uv = vTexCoord; vec3 normal; if (simpleMesh.flatShading) { normal = normalize(cross(dFdx(position_commonspace.xyz), dFdy(position_commonspace.xyz))); } else { normal = normals_commonspace; } vec4 color = simpleMesh.hasTexture ? texture(sampler, vTexCoord) : vColor; DECKGL_FILTER_COLOR(color, geometry); vec3 lightColor = lighting_getLightColor(color.rgb, cameraPosition, position_commonspace.xyz, normal); fragColor = vec4(lightColor, color.a * layer.opacity); } `; // ../../node_modules/@loaders.gl/schema/dist/deprecated/mesh-utils.js function getMeshBoundingBox(attributes) { let minX = Infinity; let minY = Infinity; let minZ = Infinity; let maxX = -Infinity; let maxY = -Infinity; let maxZ = -Infinity; const positions = attributes.POSITION ? attributes.POSITION.value : []; const len2 = positions && positions.length; for (let i = 0; i < len2; i += 3) { const x = positions[i]; const y = positions[i + 1]; const z = positions[i + 2]; minX = x < minX ? x : minX; minY = y < minY ? y : minY; minZ = z < minZ ? z : minZ; maxX = x > maxX ? x : maxX; maxY = y > maxY ? y : maxY; maxZ = z > maxZ ? z : maxZ; } return [ [minX, minY, minZ], [maxX, maxY, maxZ] ]; } // src/simple-mesh-layer/simple-mesh-layer.ts function normalizeGeometryAttributes(attributes) { const positionAttribute = attributes.positions || attributes.POSITION; import_core3.log.assert(positionAttribute, 'no "postions" or "POSITION" attribute in mesh'); const vertexCount = positionAttribute.value.length / positionAttribute.size; let colorAttribute = attributes.COLOR_0 || attributes.colors; if (!colorAttribute) { colorAttribute = { size: 3, value: new Float32Array(vertexCount * 3).fill(1) }; } let normalAttribute = attributes.NORMAL || attributes.normals; if (!normalAttribute) { normalAttribute = { size: 3, value: new Float32Array(vertexCount * 3).fill(0) }; } let texCoordAttribute = attributes.TEXCOORD_0 || attributes.texCoords; if (!texCoordAttribute) { texCoordAttribute = { size: 2, value: new Float32Array(vertexCount * 2).fill(0) }; } return { positions: positionAttribute, colors: colorAttribute, normals: normalAttribute, texCoords: texCoordAttribute }; } function getGeometry(data) { if (data instanceof import_engine.Geometry) { data.attributes = normalizeGeometryAttributes(data.attributes); return data; } else if (data.attributes) { return new import_engine.Geometry({ ...data, topology: "triangle-list", attributes: normalizeGeometryAttributes(data.attributes) }); } else { return new import_engine.Geometry({ topology: "triangle-list", attributes: normalizeGeometryAttributes(data) }); } } var DEFAULT_COLOR = [0, 0, 0, 255]; var defaultProps = { mesh: { type: "object", value: null, async: true }, texture: { type: "image", value: null, async: true }, sizeScale: { type: "number", value: 1, min: 0 }, // _instanced is a hack to use world position instead of meter offsets in mesh // TODO - formalize API _instanced: true, // NOTE(Tarek): Quick and dirty wireframe. Just draws // the same mesh with LINE_STRIPS. Won't follow edges // of the original mesh. wireframe: false, // Optional material for 'lighting' shader module material: true, getPosition: { type: "accessor", value: (x) => x.position }, getColor: { type: "accessor", value: DEFAULT_COLOR }, // yaw, pitch and roll are in degrees // https://en.wikipedia.org/wiki/Euler_angles // [pitch, yaw, roll] getOrientation: { type: "accessor", value: [0, 0, 0] }, getScale: { type: "accessor", value: [1, 1, 1] }, getTranslation: { type: "accessor", value: [0, 0, 0] }, // 4x4 matrix getTransformMatrix: { type: "accessor", value: [] }, textureParameters: { type: "object", ignore: true, value: null } }; var SimpleMeshLayer = class extends import_core3.Layer { getShaders() { return super.getShaders({ vs: simple_mesh_layer_vertex_glsl_default, fs: simple_mesh_layer_fragment_glsl_default, modules: [import_core3.project32, import_core3.phongMaterial, import_core3.picking, simpleMeshUniforms] }); } getBounds() { if (this.props._instanced) { return super.getBounds(); } let result = this.state.positionBounds; if (result) { return result; } const { mesh } = this.props; if (!mesh) { return null; } result = mesh.header?.boundingBox; if (!result) { const { attributes } = getGeometry(mesh); attributes.POSITION = attributes.POSITION || attributes.positions; result = getMeshBoundingBox(attributes); } this.state.positionBounds = result; return result; } initializeState() { const attributeManager = this.getAttributeManager(); attributeManager.addInstanced({ instancePositions: { transition: true, type: "float64", fp64: this.use64bitPositions(), size: 3, accessor: "getPosition" }, instanceColors: { type: "unorm8", transition: true, size: this.props.colorFormat.length, accessor: "getColor", defaultValue: [0, 0, 0, 255] }, instanceModelMatrix: MATRIX_ATTRIBUTES }); this.setState({ // Avoid luma.gl's missing uniform warning // TODO - add feature to luma.gl to specify ignored uniforms? emptyTexture: this.context.device.createTexture({ data: new Uint8Array(4), width: 1, height: 1 }) }); } updateState(params) { super.updateState(params); const { props, oldProps, changeFlags } = params; if (props.mesh !== oldProps.mesh || changeFlags.extensionsChanged) { this.state.positionBounds = null; this.state.model?.destroy(); if (props.mesh) { this.state.model = this.getModel(props.mesh); const attributes = props.mesh.attributes || props.mesh; this.setState({ hasNormals: Boolean(attributes.NORMAL || attributes.normals) }); } this.getAttributeManager().invalidateAll(); } if (props.texture !== oldProps.texture && props.texture instanceof import_core4.Texture) { this.setTexture(props.texture); } if (this.state.model) { this.state.model.setTopology(this.props.wireframe ? "line-strip" : "triangle-list"); } } finalizeState(context) { super.finalizeState(context); this.state.emptyTexture.delete(); } draw({ uniforms }) { const { model } = this.state; if (!model) { return; } const { viewport, renderPass } = this.context; const { sizeScale, coordinateSystem, _instanced } = this.props; const simpleMeshProps = { sizeScale, composeModelMatrix: !_instanced || shouldComposeModelMatrix(viewport, coordinateSystem), flatShading: !this.state.hasNormals }; model.shaderInputs.setProps({ simpleMesh: simpleMeshProps }); model.draw(renderPass); } get isLoaded() { return Boolean(this.state?.model && super.isLoaded); } getModel(mesh) { const model = new import_engine.Model(this.context.device, { ...this.getShaders(), id: this.props.id, bufferLayout: this.getAttributeManager().getBufferLayouts(), geometry: getGeometry(mesh), isInstanced: true }); const { texture } = this.props; const { emptyTexture } = this.state; const simpleMeshProps = { sampler: texture || emptyTexture, hasTexture: Boolean(texture) }; model.shaderInputs.setProps({ simpleMesh: simpleMeshProps }); return model; } setTexture(texture) { const { emptyTexture, model } = this.state; if (model) { const simpleMeshProps = { sampler: texture || emptyTexture, hasTexture: Boolean(texture) }; model.shaderInputs.setProps({ simpleMesh: simpleMeshProps }); } } }; SimpleMeshLayer.defaultProps = defaultProps; SimpleMeshLayer.layerName = "SimpleMeshLayer"; // src/scenegraph-layer/scenegraph-layer.ts var import_core16 = __toESM(require_core(), 1); // ../../node_modules/@math.gl/core/dist/lib/common.js var RADIANS_TO_DEGREES = 1 / Math.PI * 180; var DEGREES_TO_RADIANS = 1 / 180 * Math.PI; var DEFAULT_CONFIG = { EPSILON: 1e-12, debug: false, precision: 4, printTypes: false, printDegrees: false, printRowMajor: true, _cartographicRadians: false }; globalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } }; var config = globalThis.mathgl.config; function formatValue(value, { precision = config.precision } = {}) { value = round(value); return `${parseFloat(value.toPrecision(precision))}`; } function isArray(value) { return Array.isArray(value) || ArrayBuffer.isView(value) && !(value instanceof DataView); } function equals(a, b, epsilon) { const oldEpsilon = config.EPSILON; if (epsilon) { config.EPSILON = epsilon; } try { if (a === b) { return true; } if (isArray(a) && isArray(b)) { if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; ++i) { if (!equals(a[i], b[i])) { return false; } } return true; } if (a && a.equals) { return a.equals(b); } if (b && b.equals) { return b.equals(a); } if (typeof a === "number" && typeof b === "number") { return Math.abs(a - b) <= config.EPSILON * Math.max(1, Math.abs(a), Math.abs(b)); } return false; } finally { config.EPSILON = oldEpsilon; } } function round(value) { return Math.round(value / config.EPSILON) * config.EPSILON; } // ../../node_modules/@math.gl/core/dist/classes/base/math-array.js var MathArray = class extends Array { // Common methods /** * Clone the current object * @returns a new copy of this object */ clone() { return new this.constructor().copy(this); } fromArray(array, offset = 0) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = array[i + offset]; } return this.check(); } toArray(targetArray = [], offset = 0) { for (let i = 0; i < this.ELEMENTS; ++i) { targetArray[offset + i] = this[i]; } return targetArray; } toObject(targetObject) { return targetObject; } from(arrayOrObject) { return Array.isArray(arrayOrObject) ? this.copy(arrayOrObject) : ( // @ts-ignore this.fromObject(arrayOrObject) ); } to(arrayOrObject) { if (arrayOrObject === this) { return this; } return isArray(arrayOrObject) ? this.toArray(arrayOrObject) : this.toObject(arrayOrObject); } toTarget(target) { return target ? this.to(target) : this; } /** @deprecated */ toFloat32Array() { return new Float32Array(this); } toString() { return this.formatString(config); } /** Formats string according to options */ formatString(opts) { let string = ""; for (let i = 0; i < this.ELEMENTS; ++i) { string += (i > 0 ? ", " : "") + formatValue(this[i], opts); } return `${opts.printTypes ? this.constructor.name : ""}[${string}]`; } equals(array) { if (!array || this.length !== array.length) { return false; } for (let i = 0; i < this.ELEMENTS; ++i) { if (!equals(this[i], array[i])) { return false; } } return true; } exactEquals(array) { if (!array || this.length !== array.length) { return false; } for (let i = 0; i < this.ELEMENTS; ++i) { if (this[i] !== array[i]) { return false; } } return true; } // Modifiers /** Negates all values in this object */ negate() { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = -this[i]; } return this.check(); } lerp(a, b, t) { if (t === void 0) { return this.lerp(this, a, b); } for (let i = 0; i < this.ELEMENTS; ++i) { const ai = a[i]; const endValue = typeof b === "number" ? b : b[i]; this[i] = ai + t * (endValue - ai); } return this.check(); } /** Minimal */ min(vector) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = Math.min(vector[i], this[i]); } return this.check(); } /** Maximal */ max(vector) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = Math.max(vector[i], this[i]); } return this.check(); } clamp(minVector, maxVector) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = Math.min(Math.max(this[i], minVector[i]), maxVector[i]); } return this.check(); } add(...vectors) { for (const vector of vectors) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] += vector[i]; } } return this.check(); } subtract(...vectors) { for (const vector of vectors) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] -= vector[i]; } } return this.check(); } scale(scale5) { if (typeof scale5 === "number") { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] *= scale5; } } else { for (let i = 0; i < this.ELEMENTS && i < scale5.length; ++i) { this[i] *= scale5[i]; } } return this.check(); } /** * Multiplies all elements by `scale` * Note: `Matrix4.multiplyByScalar` only scales its 3x3 "minor" */ multiplyByScalar(scalar) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] *= scalar; } return this.check(); } // Debug checks /** Throws an error if array length is incorrect or contains illegal values */ check() { if (config.debug && !this.validate()) { throw new Error(`math.gl: ${this.constructor.name} some fields set to invalid numbers'`); } return this; } /** Returns false if the array length is incorrect or contains illegal values */ validate() { let valid = this.length === this.ELEMENTS; for (let i = 0; i < this.ELEMENTS; ++i) { valid = valid && Number.isFinite(this[i]); } return valid; } // three.js compatibility /** @deprecated */ sub(a) { return this.subtract(a); } /** @deprecated */ setScalar(a) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = a; } return this.check(); } /** @deprecated */ addScalar(a) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] += a; } return this.check(); } /** @deprecated */ subScalar(a) { return this.addScalar(-a); } /** @deprecated */ multiplyScalar(scalar) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] *= scalar; } return this.check(); } /** @deprecated */ divideScalar(a) { return this.multiplyByScalar(1 / a); } /** @deprecated */ clampScalar(min, max) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = Math.min(Math.max(this[i], min), max); } return this.check(); } /** @deprecated */ get elements() { return this; } }; // ../../node_modules/@math.gl/core/dist/lib/validators.js function validateVector(v, length4) { if (v.length !== length4) { return false; } for (let i = 0; i < v.length; ++i) { if (!Number.isFinite(v[i])) { return false; } } return true; } function checkNumber(value) { if (!Number.isFinite(value)) { throw new Error(`Invalid number ${JSON.stringify(value)}`); } return value; } function checkVector(v, length4, callerName = "") { if (config.debug && !validateVector(v, length4)) { throw new Error(`math.gl: ${callerName} some fields set to invalid numbers'`); } return v; } // ../../node_modules/@math.gl/core/dist/lib/assert.js function assert(condition, message) { if (!condition) { throw new Error(`math.gl assertion ${message}`); } } // ../../node_modules/@math.gl/core/dist/classes/base/vector.js var Vector = class extends MathArray { // ACCESSORS get x() { return this[0]; } set x(value) { this[0] = checkNumber(value); } get y() { return this[1]; } set y(value) { this[1] = checkNumber(value); } /** * Returns the length of the vector from the origin to the point described by this vector * * @note `length` is a reserved word for Arrays, so `v.length()` will return number of elements * Instead we provide `len` and `magnitude` */ len() { return Math.sqrt(this.lengthSquared()); } /** * Returns the length of the vector from the origin to the point described by this vector */ magnitude() { return this.len(); } /** * Returns the squared length of the vector from the origin to the point described by this vector */ lengthSquared() { let length4 = 0; for (let i = 0; i < this.ELEMENTS; ++i) { length4 += this[i] * this[i]; } return length4; } /** * Returns the squared length of the vector from the origin to the point described by this vector */ magnitudeSquared() { return this.lengthSquared(); } distance(mathArray) { return Math.sqrt(this.distanceSquared(mathArray)); } distanceSquared(mathArray) { let length4 = 0; for (let i = 0; i < this.ELEMENTS; ++i) { const dist = this[i] - mathArray[i]; length4 += dist * dist; } return checkNumber(length4); } dot(mathArray) { let product = 0; for (let i = 0; i < this.ELEMENTS; ++i) { product += this[i] * mathArray[i]; } return checkNumber(product); } // MODIFIERS normalize() { const length4 = this.magnitude(); if (length4 !== 0) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] /= length4; } } return this.check(); } multiply(...vectors) { for (const vector of vectors) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] *= vector[i]; } } return this.check(); } divide(...vectors) { for (const vector of vectors) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] /= vector[i]; } } return this.check(); } // THREE.js compatibility lengthSq() { return this.lengthSquared(); } distanceTo(vector) { return this.distance(vector); } distanceToSquared(vector) { return this.distanceSquared(vector); } getComponent(i) { assert(i >= 0 && i < this.ELEMENTS, "index is out of range"); return checkNumber(this[i]); } setComponent(i, value) { assert(i >= 0 && i < this.ELEMENTS, "index is out of range"); this[i] = value; return this.check(); } addVectors(a, b) { return this.copy(a).add(b); } subVectors(a, b) { return this.copy(a).subtract(b); } multiplyVectors(a, b) { return this.copy(a).multiply(b); } addScaledVector(a, b) { return this.add(new this.constructor(a).multiplyScalar(b)); } }; // ../../node_modules/@math.gl/core/dist/gl-matrix/common.js var EPSILON = 1e-6; var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array; var degree = Math.PI / 180; // ../../node_modules/@math.gl/core/dist/gl-matrix/vec2.js function create() { const out = new ARRAY_TYPE(2); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; } return out; } function transformMat3(out, a, m) { const x = a[0]; const y = a[1]; out[0] = m[0] * x + m[3] * y + m[6]; out[1] = m[1] * x + m[4] * y + m[7]; return out; } function transformMat4(out, a, m) { const x = a[0]; const y = a[1]; out[0] = m[0] * x + m[4] * y + m[12]; out[1] = m[1] * x + m[5] * y + m[13]; return out; } var forEach = function() { const vec = create(); return function(a, stride, offset, count, fn, arg) { let i; let l; if (!stride) { stride = 2; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; } return a; }; }(); // ../../node_modules/@math.gl/core/dist/lib/gl-matrix-extras.js function vec2_transformMat4AsVector(out, a, m) { const x = a[0]; const y = a[1]; const w = m[3] * x + m[7] * y || 1; out[0] = (m[0] * x + m[4] * y) / w; out[1] = (m[1] * x + m[5] * y) / w; return out; } function vec3_transformMat4AsVector(out, a, m) { const x = a[0]; const y = a[1]; const z = a[2]; const w = m[3] * x + m[7] * y + m[11] * z || 1; out[0] = (m[0] * x + m[4] * y + m[8] * z) / w; out[1] = (m[1] * x + m[5] * y + m[9] * z) / w; out[2] = (m[2] * x + m[6] * y + m[10] * z) / w; return out; } function vec3_transformMat2(out, a, m) { const x = a[0]; const y = a[1]; out[0] = m[0] * x + m[2] * y; out[1] = m[1] * x + m[3] * y; out[2] = a[2]; return out; } function vec4_transformMat2(out, a, m) { const x = a[0]; const y = a[1]; out[0] = m[0] * x + m[2] * y; out[1] = m[1] * x + m[3] * y; out[2] = a[2]; out[3] = a[3]; return out; } function vec4_transformMat3(out, a, m) { const x = a[0]; const y = a[1]; const z = a[2]; out[0] = m[0] * x + m[3] * y + m[6] * z; out[1] = m[1] * x + m[4] * y + m[7] * z; out[2] = m[2] * x + m[5] * y + m[8] * z; out[3] = a[3]; return out; } // ../../node_modules/@math.gl/core/dist/gl-matrix/vec3.js function create2() { const out = new ARRAY_TYPE(3); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; } return out; } function length(a) { const x = a[0]; const y = a[1]; const z = a[2]; return Math.sqrt(x * x + y * y + z * z); } function fromValues(x, y, z) { const out = new ARRAY_TYPE(3); out[0] = x; out[1] = y; out[2] = z; return out; } function normalize(out, a) { const x = a[0]; const y = a[1]; const z = a[2]; let len2 = x * x + y * y + z * z; if (len2 > 0) { len2 = 1 / Math.sqrt(len2); } out[0] = a[0] * len2; out[1] = a[1] * len2; out[2] = a[2] * len2; return out; } function dot(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } function cross(out, a, b) { const ax = a[0]; const ay = a[1]; const az = a[2]; const bx = b[0]; const by = b[1]; const bz = b[2]; out[0] = ay * bz - az * by; out[1] = az * bx - ax * bz; out[2] = ax * by - ay * bx; return out; } function transformMat42(out, a, m) { const x = a[0]; const y = a[1]; const z = a[2]; let w = m[3] * x + m[7] * y + m[11] * z + m[15]; w = w || 1; out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; return out; } function transformMat32(out, a, m) { const x = a[0]; const y = a[1]; const z = a[2]; out[0] = x * m[0] + y * m[3] + z * m[6]; out[1] = x * m[1] + y * m[4] + z * m[7]; out[2] = x * m[2] + y * m[5] + z * m[8]; return out; } function transformQuat(out, a, q) { const qx = q[0]; const qy = q[1]; const qz = q[2]; const qw = q[3]; const x = a[0]; const y = a[1]; const z = a[2]; let uvx = qy * z - qz * y; let uvy = qz * x - qx * z; let uvz = qx * y - qy * x; let uuvx = qy * uvz - qz * uvy; let uuvy = qz * uvx - qx * uvz; let uuvz = qx * uvy - qy * uvx; const w2 = qw * 2; uvx *= w2; uvy *= w2; uvz *= w2; uuvx *= 2; uuvy *= 2; uuvz *= 2; out[0] = x + uvx + uuvx; out[1] = y + uvy + uuvy; out[2] = z + uvz + uuvz; return out; } function rotateX(out, a, b, rad) { const p = []; const r = []; p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; r[0] = p[0]; r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad); r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad); out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; } function rotateY(out, a, b, rad) { const p = []; const r = []; p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad); r[1] = p[1]; r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad); out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; } function rotateZ(out, a, b, rad) { const p = []; const r = []; p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad); r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad); r[2] = p[2]; out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; } function angle(a, b) { const ax = a[0]; const ay = a[1]; const az = a[2]; const bx = b[0]; const by = b[1]; const bz = b[2]; const mag = Math.sqrt((ax * ax + ay * ay + az * az) * (bx * bx + by * by + bz * bz)); const cosine = mag && dot(a, b) / mag; return Math.acos(Math.min(Math.max(cosine, -1), 1)); } var len = length; var forEach2 = function() { const vec = create2(); return function(a, stride, offset, count, fn, arg) { let i; let l; if (!stride) { stride = 3; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; vec[2] = a[i + 2]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; a[i + 2] = vec[2]; } return a; }; }(); // ../../node_modules/@math.gl/core/dist/classes/vector3.js var ORIGIN = [0, 0, 0]; var ZERO; var Vector3 = class extends Vector { static get ZERO() { if (!ZERO) { ZERO = new Vector3(0, 0, 0); Object.freeze(ZERO); } return ZERO; } /** * @class * @param x * @param y * @param z */ constructor(x = 0, y = 0, z = 0) { super(-0, -0, -0); if (arguments.length === 1 && isArray(x)) { this.copy(x); } else { if (config.debug) { checkNumber(x); checkNumber(y); checkNumber(z); } this[0] = x; this[1] = y; this[2] = z; } } set(x, y, z) { this[0] = x; this[1] = y; this[2] = z; return this.check(); } copy(array) { this[0] = array[0]; this[1] = array[1]; this[2] = array[2]; return this.check(); } fromObject(object) { if (config.debug) { checkNumber(object.x); checkNumber(object.y); checkNumber(object.z); } this[0] = object.x; this[1] = object.y; this[2] = object.z; return this.check(); } toObject(object) { object.x = this[0]; object.y = this[1]; object.z = this[2]; return object; } // Getters/setters get ELEMENTS() { return 3; } get z() { return this[2]; } set z(value) { this[2] = checkNumber(value); } // ACCESSORS angle(vector) { return angle(this, vector); } // MODIFIERS cross(vector) { cross(this, this, vector); return this.check(); } rotateX({ radians, origin = ORIGIN }) { rotateX(this, this, origin, radians); return this.check(); } rotateY({ radians, origin = ORIGIN }) { rotateY(this, this, origin, radians); return this.check(); } rotateZ({ radians, origin = ORIGIN }) { rotateZ(this, this, origin, radians); return this.check(); } // Transforms // transforms as point (4th component is implicitly 1) transform(matrix4) { return this.transformAsPoint(matrix4); } // transforms as point (4th component is implicitly 1) transformAsPoint(matrix4) { transformMat42(this, this, matrix4); return this.check(); } // transforms as vector (4th component is implicitly 0, ignores translation. slightly faster) transformAsVector(matrix4) { vec3_transformMat4AsVector(this, this, matrix4); return this.check(); } transformByMatrix3(matrix3) { transformMat32(this, this, matrix3); return this.check(); } transformByMatrix2(matrix2) { vec3_transformMat2(this, this, matrix2); return this.check(); } transformByQuaternion(quaternion) { transformQuat(this, this, quaternion); return this.check(); } }; // ../../node_modules/@math.gl/core/dist/classes/vector4.js var ZERO2; var Vector4 = class extends Vector { static get ZERO() { if (!ZERO2) { ZERO2 = new Vector4(0, 0, 0, 0); Object.freeze(ZERO2); } return ZERO2; } constructor(x = 0, y = 0, z = 0, w = 0) { super(-0, -0, -0, -0); if (isArray(x) && arguments.length === 1) { this.copy(x); } else { if (config.debug) { checkNumber(x); checkNumber(y); checkNumber(z); checkNumber(w); } this[0] = x; this[1] = y; this[2] = z; this[3] = w; } } set(x, y, z, w) { this[0] = x; this[1] = y; this[2] = z; this[3] = w; return this.check(); } copy(array) { this[0] = array[0]; this[1] = array[1]; this[2] = array[2]; this[3] = array[3]; return this.check(); } fromObject(object) { if (config.debug) { checkNumber(object.x); checkNumber(object.y); checkNumber(object.z); checkNumber(object.w); } this[0] = object.x; this[1] = object.y; this[2] = object.z; this[3] = object.w; return this; } toObject(object) { object.x = this[0]; object.y = this[1]; object.z = this[2]; object.w = this[3]; return object; } // Getters/setters /* eslint-disable no-multi-spaces, brace-style, no-return-assign */ get ELEMENTS() { return 4; } get z() { return this[2]; } set z(value) { this[2] = checkNumber(value); } get w() { return this[3]; } set w(value) { this[3] = checkNumber(value); } transform(matrix4) { transformMat42(this, this, matrix4); return this.check(); } transformByMatrix3(matrix3) { vec4_transformMat3(this, this, matrix3); return this.check(); } transformByMatrix2(matrix2) { vec4_transformMat2(this, this, matrix2); return this.check(); } transformByQuaternion(quaternion) { transformQuat(this, this, quaternion); return this.check(); } // three.js compatibility applyMatrix4(m) { m.transform(this, this); return this; } }; // ../../node_modules/@math.gl/core/dist/classes/base/matrix.js var Matrix = class extends MathArray { // fromObject(object) { // const array = object.elements; // return this.fromRowMajor(array); // } // toObject(object) { // const array = object.elements; // this.toRowMajor(array); // return object; // } // TODO better override formatString? toString() { let string = "["; if (config.printRowMajor) { string += "row-major:"; for (let row = 0; row < this.RANK; ++row) { for (let col = 0; col < this.RANK; ++col) { string += ` ${this[col * this.RANK + row]}`; } } } else { string += "column-major:"; for (let i = 0; i < this.ELEMENTS; ++i) { string += ` ${this[i]}`; } } string += "]"; return string; } getElementIndex(row, col) { return col * this.RANK + row; } // By default assumes row major indices getElement(row, col) { return this[col * this.RANK + row]; } // By default assumes row major indices setElement(row, col, value) { this[col * this.RANK + row] = checkNumber(value); return this; } getColumn(columnIndex, result = new Array(this.RANK).fill(-0)) { const firstIndex = columnIndex * this.RANK; for (let i = 0; i < this.RANK; ++i) { result[i] = this[firstIndex + i]; } return result; } setColumn(columnIndex, columnVector) { const firstIndex = columnIndex * this.RANK; for (let i = 0; i < this.RANK; ++i) { this[firstIndex + i] = columnVector[i]; } return this; } }; // ../../node_modules/@math.gl/core/dist/gl-matrix/mat3.js function create3() { const out = new ARRAY_TYPE(9); if (ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; out[3] = 0; out[5] = 0; out[6] = 0; out[7] = 0; } out[0] = 1; out[4] = 1; out[8] = 1; return out; } function transpose(out, a) { if (out === a) { const a01 = a[1]; const a02 = a[2]; const a12 = a[5]; out[1] = a[3]; out[2] = a[6]; out[3] = a01; out[5] = a[7]; out[6] = a02; out[7] = a12; } else { out[0] = a[0]; out[1] = a[3]; out[2] = a[6]; out[3] = a[1]; out[4] = a[4]; out[5] = a[7]; out[6] = a[2]; out[7] = a[5]; out[8] = a[8]; } return out; } function invert(out, a) { const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a10 = a[3]; const a11 = a[4]; const a12 = a[5]; const a20 = a[6]; const a21 = a[7]; const a22 = a[8]; const b01 = a22 * a11 - a12 * a21; const b11 = -a22 * a10 + a12 * a20; const b21 = a21 * a10 - a11 * a20; let det = a00 * b01 + a01 * b11 + a02 * b21; if (!det) { return null; } det = 1 / det; out[0] = b01 * det; out[1] = (-a22 * a01 + a02 * a21) * det; out[2] = (a12 * a01 - a02 * a11) * det; out[3] = b11 * det; out[4] = (a22 * a00 - a02 * a20) * det; out[5] = (-a12 * a00 + a02 * a10) * det; out[6] = b21 * det; out[7] = (-a21 * a00 + a01 * a20) * det; out[8] = (a11 * a00 - a01 * a10) * det; return out; } function determinant(a) { const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a10 = a[3]; const a11 = a[4]; const a12 = a[5]; const a20 = a[6]; const a21 = a[7]; const a22 = a[8]; return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); } function multiply(out, a, b) { const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a10 = a[3]; const a11 = a[4]; const a12 = a[5]; const a20 = a[6]; const a21 = a[7]; const a22 = a[8]; const b00 = b[0]; const b01 = b[1]; const b02 = b[2]; const b10 = b[3]; const b11 = b[4]; const b12 = b[5]; const b20 = b[6]; const b21 = b[7]; const b22 = b[8]; out[0] = b00 * a00 + b01 * a10 + b02 * a20; out[1] = b00 * a01 + b01 * a11 + b02 * a21; out[2] = b00 * a02 + b01 * a12 + b02 * a22; out[3] = b10 * a00 + b11 * a10 + b12 * a20; out[4] = b10 * a01 + b11 * a11 + b12 * a21; out[5] = b10 * a02 + b11 * a12 + b12 * a22; out[6] = b20 * a00 + b21 * a10 + b22 * a20; out[7] = b20 * a01 + b21 * a11 + b22 * a21; out[8] = b20 * a02 + b21 * a12 + b22 * a22; return out; } function translate(out, a, v) { const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a10 = a[3]; const a11 = a[4]; const a12 = a[5]; const a20 = a[6]; const a21 = a[7]; const a22 = a[8]; const x = v[0]; const y = v[1]; out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a10; out[4] = a11; out[5] = a12; out[6] = x * a00 + y * a10 + a20; out[7] = x * a01 + y * a11 + a21; out[8] = x * a02 + y * a12 + a22; return out; } function rotate(out, a, rad) { const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a10 = a[3]; const a11 = a[4]; const a12 = a[5]; const a20 = a[6]; const a21 = a[7]; const a22 = a[8]; const s = Math.sin(rad); const c = Math.cos(rad); out[0] = c * a00 + s * a10; out[1] = c * a01 + s * a11; out[2] = c * a02 + s * a12; out[3] = c * a10 - s * a00; out[4] = c * a11 - s * a01; out[5] = c * a12 - s * a02; out[6] = a20; out[7] = a21; out[8] = a22; return out; } function scale(out, a, v) { const x = v[0]; const y = v[1]; out[0] = x * a[0]; out[1] = x * a[1]; out[2] = x * a[2]; out[3] = y * a[3]; out[4] = y * a[4]; out[5] = y * a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; return out; } function fromQuat(out, q) { const x = q[0]; const y = q[1]; const z = q[2]