diff --git a/convert2xkt_browser.js b/convert2xkt_browser.js new file mode 100755 index 0000000..75770ab --- /dev/null +++ b/convert2xkt_browser.js @@ -0,0 +1,123 @@ +#!/usr/bin/env node + +const commander = require('commander'); +const npmPackage = require('./package.json'); +const {convert2xkt, XKT_INFO} = require("./dist/xeokit-convert.cjs.js"); +const fs = require('fs'); +const defaultConfigs = require(`./convert2xkt.conf.js`); + +const WebIFC = require("web-ifc/web-ifc-api-node.js"); +const path = require("path"); +const {createValidator} = require("@typeonly/validator"); +const { save } = require('@loaders.gl/core'); + +// const validator = createValidator({ +// bundle: require("./types.to.json") +// }); + +const program = new commander.Command(); + +program.version(npmPackage.version, '-v, --version'); + +program + .option('-c, --configs [file]', 'optional path to JSON configs file; overrides convert2xkt.conf.js') + .option('-s, --source [file]', 'path to source file') + .option('-a, --sourcemanifest [file]', 'path to source manifest file (for converting split file output from ifcgltf -s)') + .option('-f, --format [string]', 'source file format (optional); supported formats are gltf, ifc, laz, las, pcd, ply, stl and cityjson') + .option('-m, --metamodel [file]', 'path to source metamodel JSON file (optional)') + .option('-i, --include [types]', 'only convert these types (optional)') + .option('-x, --exclude [types]', 'never convert these types (optional)') + .option('-r, --rotatex', 'rotate model 90 degrees about X axis (for las and cityjson)') + .option('-g, --disablegeoreuse', 'disable geometry reuse (optional)') + .option('-z, --minTileSize [number]', 'minimum diagonal tile size (optional, default 500)') + .option('-t, --disabletextures', 'ignore textures (optional)') + .option('-n, --disablenormals', 'ignore normals (optional)') + .option('-o, --output [file]', 'path to target .xkt file when -s option given, or JSON manifest for multiple .xkt files when source manifest file given with -a; creates directories on path automatically if not existing') + .option('-l, --log', 'enable logging (optional)'); + +program.on('--help', () => { + console.log(`\n\nXKT version: ${XKT_INFO.xktVersion}`); +}); + +program.parse(process.argv); + +const options = program.opts(); + +let configs = defaultConfigs; + +let inputArrayBuffer = null; + +if (options.source === undefined && options.sourcemanifest === undefined) { + console.error('[convert2xkt] [ERROR]: Please specify path to source file or manifest.'); + program.help(); + process.exit(1); +} + +if (options.source !== undefined && options.sourcemanifest !== undefined) { + console.error('[convert2xkt] [ERROR]: Can\'t specify path to source file AND manifest - only one of these params allowed.'); + program.help(); + process.exit(1); +} + +if (options.output === undefined) { + console.error('[convert2xkt] [ERROR]: Please specify target xkt file path.'); + program.help(); + process.exit(1); +} + +function log(msg) { + if (options.log) { + console.log(msg); + } +} + +inputArrayBuffer = fs.readFileSync(options.source); +function saveXKT(arrayBuffer) { + fs.writeFileSync('./output_browser_xkt.xkt', arrayBuffer); + +} +async function main() { + + log(`[convert2xkt] Running convert2xkt v${npmPackage.version}...`); + + if (options.configs !== undefined) { + log(`[convert2xkt] Using JSON configs file: ${options.configs}`); + try { + let configsData = fs.readFileSync(options.configs); + configs = JSON.parse(configsData); + } catch (e) { + console.error(`[convert2xkt] [ERROR]: Failed to load custom configs file (specified with -c or --configs) - ${e}`); + process.exit(1); + } + } else { + log(`[convert2xkt] Using configs in ./convert2xkt.conf.js`); + } + configs.sourceConfigs ||= {}; + + + + log(`[convert2xkt] Converting single input file ${options.source}...`); + + convert2xkt({ + outputXKT: saveXKT, + configs, + sourceData: inputArrayBuffer, + sourceFormat: "", + rotateX: options.rotatex, + reuseGeometries: (options.disablegeoreuse !== true), + log + }).then(() => { + + log(`[convert2xkt] Done.`); + process.exit(0); + }).catch((err) => { + console.error(`[convert2xkt] [ERROR]: ${err}`); + process.exit(1); + }); + +} + +main().catch(err => { + console.error('Error:', err); + process.exit(1); +}); diff --git a/dist/convert2xkt_browser.cjs.js b/dist/convert2xkt_browser.cjs.js new file mode 100644 index 0000000..93ba0bc --- /dev/null +++ b/dist/convert2xkt_browser.cjs.js @@ -0,0 +1,22652 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +// Some temporary vars to help avoid garbage collection +const FloatArrayType = Float64Array ; + +const tempMat1 = new FloatArrayType(16); +const tempMat2 = new FloatArrayType(16); +const tempVec4 = new FloatArrayType(4); + +/** + * @private + */ +const math = { + + MIN_DOUBLE: -Number.MAX_SAFE_INTEGER, + MAX_DOUBLE: Number.MAX_SAFE_INTEGER, + + /** + * The number of radiians in a degree (0.0174532925). + * @property DEGTORAD + * @type {Number} + */ + DEGTORAD: 0.0174532925, + + /** + * The number of degrees in a radian. + * @property RADTODEG + * @type {Number} + */ + RADTODEG: 57.295779513, + + /** + * Returns a new, uninitialized two-element vector. + * @method vec2 + * @param [values] Initial values. + * @static + * @returns {Number[]} + */ + vec2(values) { + return new FloatArrayType(values || 2); + }, + + /** + * Returns a new, uninitialized three-element vector. + * @method vec3 + * @param [values] Initial values. + * @static + * @returns {Number[]} + */ + vec3(values) { + return new FloatArrayType(values || 3); + }, + + /** + * Returns a new, uninitialized four-element vector. + * @method vec4 + * @param [values] Initial values. + * @static + * @returns {Number[]} + */ + vec4(values) { + return new FloatArrayType(values || 4); + }, + + /** + * Returns a new, uninitialized 3x3 matrix. + * @method mat3 + * @param [values] Initial values. + * @static + * @returns {Number[]} + */ + mat3(values) { + return new FloatArrayType(values || 9); + }, + + /** + * Converts a 3x3 matrix to 4x4 + * @method mat3ToMat4 + * @param mat3 3x3 matrix. + * @param mat4 4x4 matrix + * @static + * @returns {Number[]} + */ + mat3ToMat4(mat3, mat4 = new FloatArrayType(16)) { + mat4[0] = mat3[0]; + mat4[1] = mat3[1]; + mat4[2] = mat3[2]; + mat4[3] = 0; + mat4[4] = mat3[3]; + mat4[5] = mat3[4]; + mat4[6] = mat3[5]; + mat4[7] = 0; + mat4[8] = mat3[6]; + mat4[9] = mat3[7]; + mat4[10] = mat3[8]; + mat4[11] = 0; + mat4[12] = 0; + mat4[13] = 0; + mat4[14] = 0; + mat4[15] = 1; + return mat4; + }, + + /** + * Returns a new, uninitialized 4x4 matrix. + * @method mat4 + * @param [values] Initial values. + * @static + * @returns {Number[]} + */ + mat4(values) { + return new FloatArrayType(values || 16); + }, + + /** + * Converts a 4x4 matrix to 3x3 + * @method mat4ToMat3 + * @param mat4 4x4 matrix. + * @param mat3 3x3 matrix + * @static + * @returns {Number[]} + */ + mat4ToMat3(mat4, mat3) { // TODO + //return new FloatArrayType(values || 9); + }, + + /** + * Returns a new UUID. + * @method createUUID + * @static + * @return string The new UUID + */ + createUUID: ((() => { + const lut = []; + for (let i = 0; i < 256; i++) { + lut[i] = (i < 16 ? '0' : '') + (i).toString(16); + } + return () => { + const d0 = Math.random() * 0xffffffff | 0; + const d1 = Math.random() * 0xffffffff | 0; + const d2 = Math.random() * 0xffffffff | 0; + const d3 = Math.random() * 0xffffffff | 0; + return `${lut[d0 & 0xff] + lut[d0 >> 8 & 0xff] + lut[d0 >> 16 & 0xff] + lut[d0 >> 24 & 0xff]}-${lut[d1 & 0xff]}${lut[d1 >> 8 & 0xff]}-${lut[d1 >> 16 & 0x0f | 0x40]}${lut[d1 >> 24 & 0xff]}-${lut[d2 & 0x3f | 0x80]}${lut[d2 >> 8 & 0xff]}-${lut[d2 >> 16 & 0xff]}${lut[d2 >> 24 & 0xff]}${lut[d3 & 0xff]}${lut[d3 >> 8 & 0xff]}${lut[d3 >> 16 & 0xff]}${lut[d3 >> 24 & 0xff]}`; + }; + }))(), + + /** + * Clamps a value to the given range. + * @param {Number} value Value to clamp. + * @param {Number} min Lower bound. + * @param {Number} max Upper bound. + * @returns {Number} Clamped result. + */ + clamp(value, min, max) { + return Math.max(min, Math.min(max, value)); + }, + + /** + * Floating-point modulus + * @method fmod + * @static + * @param {Number} a + * @param {Number} b + * @returns {*} + */ + fmod(a, b) { + if (a < b) { + console.error("math.fmod : Attempting to find modulus within negative range - would be infinite loop - ignoring"); + return a; + } + while (b <= a) { + a -= b; + } + return a; + }, + + /** + * Negates a four-element vector. + * @method negateVec4 + * @static + * @param {Array(Number)} v Vector to negate + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, v otherwise + */ + negateVec4(v, dest) { + if (!dest) { + dest = v; + } + dest[0] = -v[0]; + dest[1] = -v[1]; + dest[2] = -v[2]; + dest[3] = -v[3]; + return dest; + }, + + /** + * Adds one four-element vector to another. + * @method addVec4 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Second vector + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, u otherwise + */ + addVec4(u, v, dest) { + if (!dest) { + dest = u; + } + dest[0] = u[0] + v[0]; + dest[1] = u[1] + v[1]; + dest[2] = u[2] + v[2]; + dest[3] = u[3] + v[3]; + return dest; + }, + + /** + * Adds a scalar value to each element of a four-element vector. + * @method addVec4Scalar + * @static + * @param {Array(Number)} v The vector + * @param {Number} s The scalar + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, v otherwise + */ + addVec4Scalar(v, s, dest) { + if (!dest) { + dest = v; + } + dest[0] = v[0] + s; + dest[1] = v[1] + s; + dest[2] = v[2] + s; + dest[3] = v[3] + s; + return dest; + }, + + /** + * Adds one three-element vector to another. + * @method addVec3 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Second vector + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, u otherwise + */ + addVec3(u, v, dest) { + if (!dest) { + dest = u; + } + dest[0] = u[0] + v[0]; + dest[1] = u[1] + v[1]; + dest[2] = u[2] + v[2]; + return dest; + }, + + /** + * Adds a scalar value to each element of a three-element vector. + * @method addVec4Scalar + * @static + * @param {Array(Number)} v The vector + * @param {Number} s The scalar + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, v otherwise + */ + addVec3Scalar(v, s, dest) { + if (!dest) { + dest = v; + } + dest[0] = v[0] + s; + dest[1] = v[1] + s; + dest[2] = v[2] + s; + return dest; + }, + + /** + * Subtracts one four-element vector from another. + * @method subVec4 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Vector to subtract + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, u otherwise + */ + subVec4(u, v, dest) { + if (!dest) { + dest = u; + } + dest[0] = u[0] - v[0]; + dest[1] = u[1] - v[1]; + dest[2] = u[2] - v[2]; + dest[3] = u[3] - v[3]; + return dest; + }, + + /** + * Subtracts one three-element vector from another. + * @method subVec3 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Vector to subtract + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, u otherwise + */ + subVec3(u, v, dest) { + if (!dest) { + dest = u; + } + dest[0] = u[0] - v[0]; + dest[1] = u[1] - v[1]; + dest[2] = u[2] - v[2]; + return dest; + }, + + /** + * Subtracts one two-element vector from another. + * @method subVec2 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Vector to subtract + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, u otherwise + */ + subVec2(u, v, dest) { + if (!dest) { + dest = u; + } + dest[0] = u[0] - v[0]; + dest[1] = u[1] - v[1]; + return dest; + }, + + /** + * Subtracts a scalar value from each element of a four-element vector. + * @method subVec4Scalar + * @static + * @param {Array(Number)} v The vector + * @param {Number} s The scalar + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, v otherwise + */ + subVec4Scalar(v, s, dest) { + if (!dest) { + dest = v; + } + dest[0] = v[0] - s; + dest[1] = v[1] - s; + dest[2] = v[2] - s; + dest[3] = v[3] - s; + return dest; + }, + + /** + * Sets each element of a 4-element vector to a scalar value minus the value of that element. + * @method subScalarVec4 + * @static + * @param {Array(Number)} v The vector + * @param {Number} s The scalar + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, v otherwise + */ + subScalarVec4(v, s, dest) { + if (!dest) { + dest = v; + } + dest[0] = s - v[0]; + dest[1] = s - v[1]; + dest[2] = s - v[2]; + dest[3] = s - v[3]; + return dest; + }, + + /** + * Multiplies one three-element vector by another. + * @method mulVec3 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Second vector + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, u otherwise + */ + mulVec4(u, v, dest) { + if (!dest) { + dest = u; + } + dest[0] = u[0] * v[0]; + dest[1] = u[1] * v[1]; + dest[2] = u[2] * v[2]; + dest[3] = u[3] * v[3]; + return dest; + }, + + /** + * Multiplies each element of a four-element vector by a scalar. + * @method mulVec34calar + * @static + * @param {Array(Number)} v The vector + * @param {Number} s The scalar + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, v otherwise + */ + mulVec4Scalar(v, s, dest) { + if (!dest) { + dest = v; + } + dest[0] = v[0] * s; + dest[1] = v[1] * s; + dest[2] = v[2] * s; + dest[3] = v[3] * s; + return dest; + }, + + /** + * Multiplies each element of a three-element vector by a scalar. + * @method mulVec3Scalar + * @static + * @param {Array(Number)} v The vector + * @param {Number} s The scalar + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, v otherwise + */ + mulVec3Scalar(v, s, dest) { + if (!dest) { + dest = v; + } + dest[0] = v[0] * s; + dest[1] = v[1] * s; + dest[2] = v[2] * s; + return dest; + }, + + /** + * Multiplies each element of a two-element vector by a scalar. + * @method mulVec2Scalar + * @static + * @param {Array(Number)} v The vector + * @param {Number} s The scalar + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, v otherwise + */ + mulVec2Scalar(v, s, dest) { + if (!dest) { + dest = v; + } + dest[0] = v[0] * s; + dest[1] = v[1] * s; + return dest; + }, + + /** + * Divides one three-element vector by another. + * @method divVec3 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Second vector + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, u otherwise + */ + divVec3(u, v, dest) { + if (!dest) { + dest = u; + } + dest[0] = u[0] / v[0]; + dest[1] = u[1] / v[1]; + dest[2] = u[2] / v[2]; + return dest; + }, + + /** + * Divides one four-element vector by another. + * @method divVec4 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Second vector + * @param {Array(Number)} [dest] Destination vector + * @return {Array(Number)} dest if specified, u otherwise + */ + divVec4(u, v, dest) { + if (!dest) { + dest = u; + } + dest[0] = u[0] / v[0]; + dest[1] = u[1] / v[1]; + dest[2] = u[2] / v[2]; + dest[3] = u[3] / v[3]; + return dest; + }, + + /** + * Divides a scalar by a three-element vector, returning a new vector. + * @method divScalarVec3 + * @static + * @param v vec3 + * @param s scalar + * @param dest vec3 - optional destination + * @return [] dest if specified, v otherwise + */ + divScalarVec3(s, v, dest) { + if (!dest) { + dest = v; + } + dest[0] = s / v[0]; + dest[1] = s / v[1]; + dest[2] = s / v[2]; + return dest; + }, + + /** + * Divides a three-element vector by a scalar. + * @method divVec3Scalar + * @static + * @param v vec3 + * @param s scalar + * @param dest vec3 - optional destination + * @return [] dest if specified, v otherwise + */ + divVec3Scalar(v, s, dest) { + if (!dest) { + dest = v; + } + dest[0] = v[0] / s; + dest[1] = v[1] / s; + dest[2] = v[2] / s; + return dest; + }, + + /** + * Divides a four-element vector by a scalar. + * @method divVec4Scalar + * @static + * @param v vec4 + * @param s scalar + * @param dest vec4 - optional destination + * @return [] dest if specified, v otherwise + */ + divVec4Scalar(v, s, dest) { + if (!dest) { + dest = v; + } + dest[0] = v[0] / s; + dest[1] = v[1] / s; + dest[2] = v[2] / s; + dest[3] = v[3] / s; + return dest; + }, + + + /** + * Divides a scalar by a four-element vector, returning a new vector. + * @method divScalarVec4 + * @static + * @param s scalar + * @param v vec4 + * @param dest vec4 - optional destination + * @return [] dest if specified, v otherwise + */ + divScalarVec4(s, v, dest) { + if (!dest) { + dest = v; + } + dest[0] = s / v[0]; + dest[1] = s / v[1]; + dest[2] = s / v[2]; + dest[3] = s / v[3]; + return dest; + }, + + /** + * Returns the dot product of two four-element vectors. + * @method dotVec4 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Second vector + * @return The dot product + */ + dotVec4(u, v) { + return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2] + u[3] * v[3]); + }, + + /** + * Returns the cross product of two four-element vectors. + * @method cross3Vec4 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Second vector + * @return The cross product + */ + cross3Vec4(u, v) { + const u0 = u[0]; + const u1 = u[1]; + const u2 = u[2]; + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + return [ + u1 * v2 - u2 * v1, + u2 * v0 - u0 * v2, + u0 * v1 - u1 * v0, + 0.0]; + }, + + /** + * Returns the cross product of two three-element vectors. + * @method cross3Vec3 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Second vector + * @return The cross product + */ + cross3Vec3(u, v, dest) { + if (!dest) { + dest = u; + } + const x = u[0]; + const y = u[1]; + const z = u[2]; + const x2 = v[0]; + const y2 = v[1]; + const z2 = v[2]; + dest[0] = y * z2 - z * y2; + dest[1] = z * x2 - x * z2; + dest[2] = x * y2 - y * x2; + return dest; + }, + + + sqLenVec4(v) { // TODO + return math.dotVec4(v, v); + }, + + /** + * Returns the length of a four-element vector. + * @method lenVec4 + * @static + * @param {Array(Number)} v The vector + * @return The length + */ + lenVec4(v) { + return Math.sqrt(math.sqLenVec4(v)); + }, + + /** + * Returns the dot product of two three-element vectors. + * @method dotVec3 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Second vector + * @return The dot product + */ + dotVec3(u, v) { + return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]); + }, + + /** + * Returns the dot product of two two-element vectors. + * @method dotVec4 + * @static + * @param {Array(Number)} u First vector + * @param {Array(Number)} v Second vector + * @return The dot product + */ + dotVec2(u, v) { + return (u[0] * v[0] + u[1] * v[1]); + }, + + + sqLenVec3(v) { + return math.dotVec3(v, v); + }, + + + sqLenVec2(v) { + return math.dotVec2(v, v); + }, + + /** + * Returns the length of a three-element vector. + * @method lenVec3 + * @static + * @param {Array(Number)} v The vector + * @return The length + */ + lenVec3(v) { + return Math.sqrt(math.sqLenVec3(v)); + }, + + distVec3: ((() => { + const vec = new FloatArrayType(3); + return (v, w) => math.lenVec3(math.subVec3(v, w, vec)); + }))(), + + /** + * Returns the length of a two-element vector. + * @method lenVec2 + * @static + * @param {Array(Number)} v The vector + * @return The length + */ + lenVec2(v) { + return Math.sqrt(math.sqLenVec2(v)); + }, + + distVec2: ((() => { + const vec = new FloatArrayType(2); + return (v, w) => math.lenVec2(math.subVec2(v, w, vec)); + }))(), + + /** + * @method rcpVec3 + * @static + * @param v vec3 + * @param dest vec3 - optional destination + * @return [] dest if specified, v otherwise + * + */ + rcpVec3(v, dest) { + return math.divScalarVec3(1.0, v, dest); + }, + + /** + * Normalizes a four-element vector + * @method normalizeVec4 + * @static + * @param v vec4 + * @param dest vec4 - optional destination + * @return [] dest if specified, v otherwise + * + */ + normalizeVec4(v, dest) { + const f = 1.0 / math.lenVec4(v); + return math.mulVec4Scalar(v, f, dest); + }, + + /** + * Normalizes a three-element vector + * @method normalizeVec4 + * @static + */ + normalizeVec3(v, dest) { + const f = 1.0 / math.lenVec3(v); + return math.mulVec3Scalar(v, f, dest); + }, + + /** + * Normalizes a two-element vector + * @method normalizeVec2 + * @static + */ + normalizeVec2(v, dest) { + const f = 1.0 / math.lenVec2(v); + return math.mulVec2Scalar(v, f, dest); + }, + + /** + * Gets the angle between two vectors + * @method angleVec3 + * @param v + * @param w + * @returns {number} + */ + angleVec3(v, w) { + let theta = math.dotVec3(v, w) / (Math.sqrt(math.sqLenVec3(v) * math.sqLenVec3(w))); + theta = theta < -1 ? -1 : (theta > 1 ? 1 : theta); // Clamp to handle numerical problems + return Math.acos(theta); + }, + + /** + * Creates a three-element vector from the rotation part of a sixteen-element matrix. + * @param m + * @param dest + */ + vec3FromMat4Scale: ((() => { + + const tempVec3 = new FloatArrayType(3); + + return (m, dest) => { + + tempVec3[0] = m[0]; + tempVec3[1] = m[1]; + tempVec3[2] = m[2]; + + dest[0] = math.lenVec3(tempVec3); + + tempVec3[0] = m[4]; + tempVec3[1] = m[5]; + tempVec3[2] = m[6]; + + dest[1] = math.lenVec3(tempVec3); + + tempVec3[0] = m[8]; + tempVec3[1] = m[9]; + tempVec3[2] = m[10]; + + dest[2] = math.lenVec3(tempVec3); + + return dest; + }; + }))(), + + /** + * Converts an n-element vector to a JSON-serializable + * array with values rounded to two decimal places. + */ + vecToArray: ((() => { + function trunc(v) { + return Math.round(v * 100000) / 100000 + } + + return v => { + v = Array.prototype.slice.call(v); + for (let i = 0, len = v.length; i < len; i++) { + v[i] = trunc(v[i]); + } + return v; + }; + }))(), + + /** + * Converts a 3-element vector from an array to an object of the form ````{x:999, y:999, z:999}````. + * @param arr + * @returns {{x: *, y: *, z: *}} + */ + xyzArrayToObject(arr) { + return {"x": arr[0], "y": arr[1], "z": arr[2]}; + }, + + /** + * Converts a 3-element vector object of the form ````{x:999, y:999, z:999}```` to an array. + * @param xyz + * @param [arry] + * @returns {*[]} + */ + xyzObjectToArray(xyz, arry) { + arry = arry || new FloatArrayType(3); + arry[0] = xyz.x; + arry[1] = xyz.y; + arry[2] = xyz.z; + return arry; + }, + + /** + * Duplicates a 4x4 identity matrix. + * @method dupMat4 + * @static + */ + dupMat4(m) { + return m.slice(0, 16); + }, + + /** + * Extracts a 3x3 matrix from a 4x4 matrix. + * @method mat4To3 + * @static + */ + mat4To3(m) { + return [ + m[0], m[1], m[2], + m[4], m[5], m[6], + m[8], m[9], m[10] + ]; + }, + + /** + * Returns a 4x4 matrix with each element set to the given scalar value. + * @method m4s + * @static + */ + m4s(s) { + return [ + s, s, s, s, + s, s, s, s, + s, s, s, s, + s, s, s, s + ]; + }, + + /** + * Returns a 4x4 matrix with each element set to zero. + * @method setMat4ToZeroes + * @static + */ + setMat4ToZeroes() { + return math.m4s(0.0); + }, + + /** + * Returns a 4x4 matrix with each element set to 1.0. + * @method setMat4ToOnes + * @static + */ + setMat4ToOnes() { + return math.m4s(1.0); + }, + + /** + * Returns a 4x4 matrix with each element set to 1.0. + * @method setMat4ToOnes + * @static + */ + diagonalMat4v(v) { + return new FloatArrayType([ + v[0], 0.0, 0.0, 0.0, + 0.0, v[1], 0.0, 0.0, + 0.0, 0.0, v[2], 0.0, + 0.0, 0.0, 0.0, v[3] + ]); + }, + + /** + * Returns a 4x4 matrix with diagonal elements set to the given vector. + * @method diagonalMat4c + * @static + */ + diagonalMat4c(x, y, z, w) { + return math.diagonalMat4v([x, y, z, w]); + }, + + /** + * Returns a 4x4 matrix with diagonal elements set to the given scalar. + * @method diagonalMat4s + * @static + */ + diagonalMat4s(s) { + return math.diagonalMat4c(s, s, s, s); + }, + + /** + * Returns a 4x4 identity matrix. + * @method identityMat4 + * @static + */ + identityMat4(mat = new FloatArrayType(16)) { + mat[0] = 1.0; + mat[1] = 0.0; + mat[2] = 0.0; + mat[3] = 0.0; + + mat[4] = 0.0; + mat[5] = 1.0; + mat[6] = 0.0; + mat[7] = 0.0; + + mat[8] = 0.0; + mat[9] = 0.0; + mat[10] = 1.0; + mat[11] = 0.0; + + mat[12] = 0.0; + mat[13] = 0.0; + mat[14] = 0.0; + mat[15] = 1.0; + + return mat; + }, + + /** + * Returns a 3x3 identity matrix. + * @method identityMat3 + * @static + */ + identityMat3(mat = new FloatArrayType(9)) { + mat[0] = 1.0; + mat[1] = 0.0; + mat[2] = 0.0; + + mat[3] = 0.0; + mat[4] = 1.0; + mat[5] = 0.0; + + mat[6] = 0.0; + mat[7] = 0.0; + mat[8] = 1.0; + + return mat; + }, + + /** + * Tests if the given 4x4 matrix is the identity matrix. + * @method isIdentityMat4 + * @static + */ + isIdentityMat4(m) { + if (m[0] !== 1.0 || m[1] !== 0.0 || m[2] !== 0.0 || m[3] !== 0.0 || + m[4] !== 0.0 || m[5] !== 1.0 || m[6] !== 0.0 || m[7] !== 0.0 || + m[8] !== 0.0 || m[9] !== 0.0 || m[10] !== 1.0 || m[11] !== 0.0 || + m[12] !== 0.0 || m[13] !== 0.0 || m[14] !== 0.0 || m[15] !== 1.0) { + return false; + } + return true; + }, + + /** + * Negates the given 4x4 matrix. + * @method negateMat4 + * @static + */ + negateMat4(m, dest) { + if (!dest) { + dest = m; + } + dest[0] = -m[0]; + dest[1] = -m[1]; + dest[2] = -m[2]; + dest[3] = -m[3]; + dest[4] = -m[4]; + dest[5] = -m[5]; + dest[6] = -m[6]; + dest[7] = -m[7]; + dest[8] = -m[8]; + dest[9] = -m[9]; + dest[10] = -m[10]; + dest[11] = -m[11]; + dest[12] = -m[12]; + dest[13] = -m[13]; + dest[14] = -m[14]; + dest[15] = -m[15]; + return dest; + }, + + /** + * Adds the given 4x4 matrices together. + * @method addMat4 + * @static + */ + addMat4(a, b, dest) { + if (!dest) { + dest = a; + } + dest[0] = a[0] + b[0]; + dest[1] = a[1] + b[1]; + dest[2] = a[2] + b[2]; + dest[3] = a[3] + b[3]; + dest[4] = a[4] + b[4]; + dest[5] = a[5] + b[5]; + dest[6] = a[6] + b[6]; + dest[7] = a[7] + b[7]; + dest[8] = a[8] + b[8]; + dest[9] = a[9] + b[9]; + dest[10] = a[10] + b[10]; + dest[11] = a[11] + b[11]; + dest[12] = a[12] + b[12]; + dest[13] = a[13] + b[13]; + dest[14] = a[14] + b[14]; + dest[15] = a[15] + b[15]; + return dest; + }, + + /** + * Adds the given scalar to each element of the given 4x4 matrix. + * @method addMat4Scalar + * @static + */ + addMat4Scalar(m, s, dest) { + if (!dest) { + dest = m; + } + dest[0] = m[0] + s; + dest[1] = m[1] + s; + dest[2] = m[2] + s; + dest[3] = m[3] + s; + dest[4] = m[4] + s; + dest[5] = m[5] + s; + dest[6] = m[6] + s; + dest[7] = m[7] + s; + dest[8] = m[8] + s; + dest[9] = m[9] + s; + dest[10] = m[10] + s; + dest[11] = m[11] + s; + dest[12] = m[12] + s; + dest[13] = m[13] + s; + dest[14] = m[14] + s; + dest[15] = m[15] + s; + return dest; + }, + + /** + * Adds the given scalar to each element of the given 4x4 matrix. + * @method addScalarMat4 + * @static + */ + addScalarMat4(s, m, dest) { + return math.addMat4Scalar(m, s, dest); + }, + + /** + * Subtracts the second 4x4 matrix from the first. + * @method subMat4 + * @static + */ + subMat4(a, b, dest) { + if (!dest) { + dest = a; + } + dest[0] = a[0] - b[0]; + dest[1] = a[1] - b[1]; + dest[2] = a[2] - b[2]; + dest[3] = a[3] - b[3]; + dest[4] = a[4] - b[4]; + dest[5] = a[5] - b[5]; + dest[6] = a[6] - b[6]; + dest[7] = a[7] - b[7]; + dest[8] = a[8] - b[8]; + dest[9] = a[9] - b[9]; + dest[10] = a[10] - b[10]; + dest[11] = a[11] - b[11]; + dest[12] = a[12] - b[12]; + dest[13] = a[13] - b[13]; + dest[14] = a[14] - b[14]; + dest[15] = a[15] - b[15]; + return dest; + }, + + /** + * Subtracts the given scalar from each element of the given 4x4 matrix. + * @method subMat4Scalar + * @static + */ + subMat4Scalar(m, s, dest) { + if (!dest) { + dest = m; + } + dest[0] = m[0] - s; + dest[1] = m[1] - s; + dest[2] = m[2] - s; + dest[3] = m[3] - s; + dest[4] = m[4] - s; + dest[5] = m[5] - s; + dest[6] = m[6] - s; + dest[7] = m[7] - s; + dest[8] = m[8] - s; + dest[9] = m[9] - s; + dest[10] = m[10] - s; + dest[11] = m[11] - s; + dest[12] = m[12] - s; + dest[13] = m[13] - s; + dest[14] = m[14] - s; + dest[15] = m[15] - s; + return dest; + }, + + /** + * Subtracts the given scalar from each element of the given 4x4 matrix. + * @method subScalarMat4 + * @static + */ + subScalarMat4(s, m, dest) { + if (!dest) { + dest = m; + } + dest[0] = s - m[0]; + dest[1] = s - m[1]; + dest[2] = s - m[2]; + dest[3] = s - m[3]; + dest[4] = s - m[4]; + dest[5] = s - m[5]; + dest[6] = s - m[6]; + dest[7] = s - m[7]; + dest[8] = s - m[8]; + dest[9] = s - m[9]; + dest[10] = s - m[10]; + dest[11] = s - m[11]; + dest[12] = s - m[12]; + dest[13] = s - m[13]; + dest[14] = s - m[14]; + dest[15] = s - m[15]; + return dest; + }, + + /** + * Multiplies the two given 4x4 matrix by each other. + * @method mulMat4 + * @static + */ + mulMat4(a, b, dest) { + if (!dest) { + dest = a; + } + + // Cache the matrix values (makes for huge speed increases!) + const a00 = a[0]; + + const a01 = a[1]; + const a02 = a[2]; + const a03 = a[3]; + const a10 = a[4]; + const a11 = a[5]; + const a12 = a[6]; + const a13 = a[7]; + const a20 = a[8]; + const a21 = a[9]; + const a22 = a[10]; + const a23 = a[11]; + const a30 = a[12]; + const a31 = a[13]; + const a32 = a[14]; + const a33 = a[15]; + const b00 = b[0]; + const b01 = b[1]; + const b02 = b[2]; + const b03 = b[3]; + const b10 = b[4]; + const b11 = b[5]; + const b12 = b[6]; + const b13 = b[7]; + const b20 = b[8]; + const b21 = b[9]; + const b22 = b[10]; + const b23 = b[11]; + const b30 = b[12]; + const b31 = b[13]; + const b32 = b[14]; + const b33 = b[15]; + + dest[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30; + dest[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31; + dest[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32; + dest[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33; + dest[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30; + dest[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31; + dest[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32; + dest[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33; + dest[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30; + dest[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31; + dest[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32; + dest[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33; + dest[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30; + dest[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31; + dest[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32; + dest[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33; + + return dest; + }, + + /** + * Multiplies the two given 3x3 matrices by each other. + * @method mulMat4 + * @static + */ + mulMat3(a, b, dest) { + if (!dest) { + dest = new FloatArrayType(9); + } + + const a11 = a[0]; + const a12 = a[3]; + const a13 = a[6]; + const a21 = a[1]; + const a22 = a[4]; + const a23 = a[7]; + const a31 = a[2]; + const a32 = a[5]; + const a33 = a[8]; + const b11 = b[0]; + const b12 = b[3]; + const b13 = b[6]; + const b21 = b[1]; + const b22 = b[4]; + const b23 = b[7]; + const b31 = b[2]; + const b32 = b[5]; + const b33 = b[8]; + + dest[0] = a11 * b11 + a12 * b21 + a13 * b31; + dest[3] = a11 * b12 + a12 * b22 + a13 * b32; + dest[6] = a11 * b13 + a12 * b23 + a13 * b33; + + dest[1] = a21 * b11 + a22 * b21 + a23 * b31; + dest[4] = a21 * b12 + a22 * b22 + a23 * b32; + dest[7] = a21 * b13 + a22 * b23 + a23 * b33; + + dest[2] = a31 * b11 + a32 * b21 + a33 * b31; + dest[5] = a31 * b12 + a32 * b22 + a33 * b32; + dest[8] = a31 * b13 + a32 * b23 + a33 * b33; + + return dest; + }, + + /** + * Multiplies each element of the given 4x4 matrix by the given scalar. + * @method mulMat4Scalar + * @static + */ + mulMat4Scalar(m, s, dest) { + if (!dest) { + dest = m; + } + dest[0] = m[0] * s; + dest[1] = m[1] * s; + dest[2] = m[2] * s; + dest[3] = m[3] * s; + dest[4] = m[4] * s; + dest[5] = m[5] * s; + dest[6] = m[6] * s; + dest[7] = m[7] * s; + dest[8] = m[8] * s; + dest[9] = m[9] * s; + dest[10] = m[10] * s; + dest[11] = m[11] * s; + dest[12] = m[12] * s; + dest[13] = m[13] * s; + dest[14] = m[14] * s; + dest[15] = m[15] * s; + return dest; + }, + + /** + * Multiplies the given 4x4 matrix by the given four-element vector. + * @method mulMat4v4 + * @static + */ + mulMat4v4(m, v, dest = math.vec4()) { + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + const v3 = v[3]; + dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3; + dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3; + dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3; + dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3; + return dest; + }, + + /** + * Transposes the given 4x4 matrix. + * @method transposeMat4 + * @static + */ + transposeMat4(mat, dest) { + // If we are transposing ourselves we can skip a few steps but have to cache some values + const m4 = mat[4]; + + const m14 = mat[14]; + const m8 = mat[8]; + const m13 = mat[13]; + const m12 = mat[12]; + const m9 = mat[9]; + if (!dest || mat === dest) { + const a01 = mat[1]; + const a02 = mat[2]; + const a03 = mat[3]; + const a12 = mat[6]; + const a13 = mat[7]; + const a23 = mat[11]; + mat[1] = m4; + mat[2] = m8; + mat[3] = m12; + mat[4] = a01; + mat[6] = m9; + mat[7] = m13; + mat[8] = a02; + mat[9] = a12; + mat[11] = m14; + mat[12] = a03; + mat[13] = a13; + mat[14] = a23; + return mat; + } + dest[0] = mat[0]; + dest[1] = m4; + dest[2] = m8; + dest[3] = m12; + dest[4] = mat[1]; + dest[5] = mat[5]; + dest[6] = m9; + dest[7] = m13; + dest[8] = mat[2]; + dest[9] = mat[6]; + dest[10] = mat[10]; + dest[11] = m14; + dest[12] = mat[3]; + dest[13] = mat[7]; + dest[14] = mat[11]; + dest[15] = mat[15]; + return dest; + }, + + /** + * Transposes the given 3x3 matrix. + * + * @method transposeMat3 + * @static + */ + transposeMat3(mat, dest) { + if (dest === mat) { + const a01 = mat[1]; + const a02 = mat[2]; + const a12 = mat[5]; + dest[1] = mat[3]; + dest[2] = mat[6]; + dest[3] = a01; + dest[5] = mat[7]; + dest[6] = a02; + dest[7] = a12; + } else { + dest[0] = mat[0]; + dest[1] = mat[3]; + dest[2] = mat[6]; + dest[3] = mat[1]; + dest[4] = mat[4]; + dest[5] = mat[7]; + dest[6] = mat[2]; + dest[7] = mat[5]; + dest[8] = mat[8]; + } + return dest; + }, + + /** + * Returns the determinant of the given 4x4 matrix. + * @method determinantMat4 + * @static + */ + determinantMat4(mat) { + // Cache the matrix values (makes for huge speed increases!) + const a00 = mat[0]; + + const a01 = mat[1]; + const a02 = mat[2]; + const a03 = mat[3]; + const a10 = mat[4]; + const a11 = mat[5]; + const a12 = mat[6]; + const a13 = mat[7]; + const a20 = mat[8]; + const a21 = mat[9]; + const a22 = mat[10]; + const a23 = mat[11]; + const a30 = mat[12]; + const a31 = mat[13]; + const a32 = mat[14]; + const a33 = mat[15]; + return a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 + + a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 + + a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 + + a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 + + a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 + + a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33; + }, + + /** + * Returns the inverse of the given 4x4 matrix. + * @method inverseMat4 + * @static + */ + inverseMat4(mat, dest) { + if (!dest) { + dest = mat; + } + + // Cache the matrix values (makes for huge speed increases!) + const a00 = mat[0]; + + const a01 = mat[1]; + const a02 = mat[2]; + const a03 = mat[3]; + const a10 = mat[4]; + const a11 = mat[5]; + const a12 = mat[6]; + const a13 = mat[7]; + const a20 = mat[8]; + const a21 = mat[9]; + const a22 = mat[10]; + const a23 = mat[11]; + const a30 = mat[12]; + const a31 = mat[13]; + const a32 = mat[14]; + const a33 = mat[15]; + const b00 = a00 * a11 - a01 * a10; + const b01 = a00 * a12 - a02 * a10; + const b02 = a00 * a13 - a03 * a10; + const b03 = a01 * a12 - a02 * a11; + const b04 = a01 * a13 - a03 * a11; + const b05 = a02 * a13 - a03 * a12; + const b06 = a20 * a31 - a21 * a30; + const b07 = a20 * a32 - a22 * a30; + const b08 = a20 * a33 - a23 * a30; + const b09 = a21 * a32 - a22 * a31; + const b10 = a21 * a33 - a23 * a31; + const b11 = a22 * a33 - a23 * a32; + + // Calculate the determinant (inlined to avoid double-caching) + const invDet = 1 / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06); + + dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet; + dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet; + dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet; + dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet; + dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet; + dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet; + dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet; + dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet; + dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet; + dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet; + dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet; + dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet; + dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet; + dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet; + dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet; + dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet; + + return dest; + }, + + /** + * Returns the trace of the given 4x4 matrix. + * @method traceMat4 + * @static + */ + traceMat4(m) { + return (m[0] + m[5] + m[10] + m[15]); + }, + + /** + * Returns 4x4 translation matrix. + * @method translationMat4 + * @static + */ + translationMat4v(v, dest) { + const m = dest || math.identityMat4(); + m[12] = v[0]; + m[13] = v[1]; + m[14] = v[2]; + return m; + }, + + /** + * Returns 3x3 translation matrix. + * @method translationMat3 + * @static + */ + translationMat3v(v, dest) { + const m = dest || math.identityMat3(); + m[6] = v[0]; + m[7] = v[1]; + return m; + }, + + /** + * Returns 4x4 translation matrix. + * @method translationMat4c + * @static + */ + translationMat4c: ((() => { + const xyz = new FloatArrayType(3); + return (x, y, z, dest) => { + xyz[0] = x; + xyz[1] = y; + xyz[2] = z; + return math.translationMat4v(xyz, dest); + }; + }))(), + + /** + * Returns 4x4 translation matrix. + * @method translationMat4s + * @static + */ + translationMat4s(s, dest) { + return math.translationMat4c(s, s, s, dest); + }, + + /** + * Efficiently post-concatenates a translation to the given matrix. + * @param v + * @param m + */ + translateMat4v(xyz, m) { + return math.translateMat4c(xyz[0], xyz[1], xyz[2], m); + }, + + /** + * Efficiently post-concatenates a translation to the given matrix. + * @param x + * @param y + * @param z + * @param m + */ + OLDtranslateMat4c(x, y, z, m) { + + const m12 = m[12]; + m[0] += m12 * x; + m[4] += m12 * y; + m[8] += m12 * z; + + const m13 = m[13]; + m[1] += m13 * x; + m[5] += m13 * y; + m[9] += m13 * z; + + const m14 = m[14]; + m[2] += m14 * x; + m[6] += m14 * y; + m[10] += m14 * z; + + const m15 = m[15]; + m[3] += m15 * x; + m[7] += m15 * y; + m[11] += m15 * z; + + return m; + }, + + translateMat4c(x, y, z, m) { + + const m3 = m[3]; + m[0] += m3 * x; + m[1] += m3 * y; + m[2] += m3 * z; + + const m7 = m[7]; + m[4] += m7 * x; + m[5] += m7 * y; + m[6] += m7 * z; + + const m11 = m[11]; + m[8] += m11 * x; + m[9] += m11 * y; + m[10] += m11 * z; + + const m15 = m[15]; + m[12] += m15 * x; + m[13] += m15 * y; + m[14] += m15 * z; + + return m; + }, + /** + * Returns 4x4 rotation matrix. + * @method rotationMat4v + * @static + */ + rotationMat4v(anglerad, axis, m) { + const ax = math.normalizeVec4([axis[0], axis[1], axis[2], 0.0], []); + const s = Math.sin(anglerad); + const c = Math.cos(anglerad); + const q = 1.0 - c; + + const x = ax[0]; + const y = ax[1]; + const z = ax[2]; + + let xy; + let yz; + let zx; + let xs; + let ys; + let zs; + + //xx = x * x; used once + //yy = y * y; used once + //zz = z * z; used once + xy = x * y; + yz = y * z; + zx = z * x; + xs = x * s; + ys = y * s; + zs = z * s; + + m = m || math.mat4(); + + m[0] = (q * x * x) + c; + m[1] = (q * xy) + zs; + m[2] = (q * zx) - ys; + m[3] = 0.0; + + m[4] = (q * xy) - zs; + m[5] = (q * y * y) + c; + m[6] = (q * yz) + xs; + m[7] = 0.0; + + m[8] = (q * zx) + ys; + m[9] = (q * yz) - xs; + m[10] = (q * z * z) + c; + m[11] = 0.0; + + m[12] = 0.0; + m[13] = 0.0; + m[14] = 0.0; + m[15] = 1.0; + + return m; + }, + + /** + * Returns 4x4 rotation matrix. + * @method rotationMat4c + * @static + */ + rotationMat4c(anglerad, x, y, z, mat) { + return math.rotationMat4v(anglerad, [x, y, z], mat); + }, + + /** + * Returns 4x4 scale matrix. + * @method scalingMat4v + * @static + */ + scalingMat4v(v, m = math.identityMat4()) { + m[0] = v[0]; + m[5] = v[1]; + m[10] = v[2]; + return m; + }, + + /** + * Returns 3x3 scale matrix. + * @method scalingMat3v + * @static + */ + scalingMat3v(v, m = math.identityMat3()) { + m[0] = v[0]; + m[4] = v[1]; + return m; + }, + + /** + * Returns 4x4 scale matrix. + * @method scalingMat4c + * @static + */ + scalingMat4c: ((() => { + const xyz = new FloatArrayType(3); + return (x, y, z, dest) => { + xyz[0] = x; + xyz[1] = y; + xyz[2] = z; + return math.scalingMat4v(xyz, dest); + }; + }))(), + + /** + * Efficiently post-concatenates a scaling to the given matrix. + * @method scaleMat4c + * @param x + * @param y + * @param z + * @param m + */ + scaleMat4c(x, y, z, m) { + + m[0] *= x; + m[4] *= y; + m[8] *= z; + + m[1] *= x; + m[5] *= y; + m[9] *= z; + + m[2] *= x; + m[6] *= y; + m[10] *= z; + + m[3] *= x; + m[7] *= y; + m[11] *= z; + return m; + }, + + /** + * Efficiently post-concatenates a scaling to the given matrix. + * @method scaleMat4c + * @param xyz + * @param m + */ + scaleMat4v(xyz, m) { + + const x = xyz[0]; + const y = xyz[1]; + const z = xyz[2]; + + m[0] *= x; + m[4] *= y; + m[8] *= z; + m[1] *= x; + m[5] *= y; + m[9] *= z; + m[2] *= x; + m[6] *= y; + m[10] *= z; + m[3] *= x; + m[7] *= y; + m[11] *= z; + + return m; + }, + + /** + * Returns 4x4 scale matrix. + * @method scalingMat4s + * @static + */ + scalingMat4s(s) { + return math.scalingMat4c(s, s, s); + }, + + /** + * Creates a matrix from a quaternion rotation and vector translation + * + * @param {Number[]} q Rotation quaternion + * @param {Number[]} v Translation vector + * @param {Number[]} dest Destination matrix + * @returns {Number[]} dest + */ + rotationTranslationMat4(q, v, dest = math.mat4()) { + const x = q[0]; + const y = q[1]; + const z = q[2]; + const w = q[3]; + + const x2 = x + x; + const y2 = y + y; + const z2 = z + z; + const xx = x * x2; + const xy = x * y2; + const xz = x * z2; + const yy = y * y2; + const yz = y * z2; + const zz = z * z2; + const wx = w * x2; + const wy = w * y2; + const wz = w * z2; + + dest[0] = 1 - (yy + zz); + dest[1] = xy + wz; + dest[2] = xz - wy; + dest[3] = 0; + dest[4] = xy - wz; + dest[5] = 1 - (xx + zz); + dest[6] = yz + wx; + dest[7] = 0; + dest[8] = xz + wy; + dest[9] = yz - wx; + dest[10] = 1 - (xx + yy); + dest[11] = 0; + dest[12] = v[0]; + dest[13] = v[1]; + dest[14] = v[2]; + dest[15] = 1; + + return dest; + }, + + /** + * Gets Euler angles from a 4x4 matrix. + * + * @param {Number[]} mat The 4x4 matrix. + * @param {String} order Desired Euler angle order: "XYZ", "YXZ", "ZXY" etc. + * @param {Number[]} [dest] Destination Euler angles, created by default. + * @returns {Number[]} The Euler angles. + */ + mat4ToEuler(mat, order, dest = math.vec4()) { + const clamp = math.clamp; + + // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + + const m11 = mat[0]; + + const m12 = mat[4]; + const m13 = mat[8]; + const m21 = mat[1]; + const m22 = mat[5]; + const m23 = mat[9]; + const m31 = mat[2]; + const m32 = mat[6]; + const m33 = mat[10]; + + if (order === 'XYZ') { + + dest[1] = Math.asin(clamp(m13, -1, 1)); + + if (Math.abs(m13) < 0.99999) { + dest[0] = Math.atan2(-m23, m33); + dest[2] = Math.atan2(-m12, m11); + } else { + dest[0] = Math.atan2(m32, m22); + dest[2] = 0; + + } + + } else if (order === 'YXZ') { + + dest[0] = Math.asin(-clamp(m23, -1, 1)); + + if (Math.abs(m23) < 0.99999) { + dest[1] = Math.atan2(m13, m33); + dest[2] = Math.atan2(m21, m22); + } else { + dest[1] = Math.atan2(-m31, m11); + dest[2] = 0; + } + + } else if (order === 'ZXY') { + + dest[0] = Math.asin(clamp(m32, -1, 1)); + + if (Math.abs(m32) < 0.99999) { + dest[1] = Math.atan2(-m31, m33); + dest[2] = Math.atan2(-m12, m22); + } else { + dest[1] = 0; + dest[2] = Math.atan2(m21, m11); + } + + } else if (order === 'ZYX') { + + dest[1] = Math.asin(-clamp(m31, -1, 1)); + + if (Math.abs(m31) < 0.99999) { + dest[0] = Math.atan2(m32, m33); + dest[2] = Math.atan2(m21, m11); + } else { + dest[0] = 0; + dest[2] = Math.atan2(-m12, m22); + } + + } else if (order === 'YZX') { + + dest[2] = Math.asin(clamp(m21, -1, 1)); + + if (Math.abs(m21) < 0.99999) { + dest[0] = Math.atan2(-m23, m22); + dest[1] = Math.atan2(-m31, m11); + } else { + dest[0] = 0; + dest[1] = Math.atan2(m13, m33); + } + + } else if (order === 'XZY') { + + dest[2] = Math.asin(-clamp(m12, -1, 1)); + + if (Math.abs(m12) < 0.99999) { + dest[0] = Math.atan2(m32, m22); + dest[1] = Math.atan2(m13, m11); + } else { + dest[0] = Math.atan2(-m23, m33); + dest[1] = 0; + } + } + + return dest; + }, + + composeMat4(position, quaternion, scale, mat = math.mat4()) { + math.quaternionToRotationMat4(quaternion, mat); + math.scaleMat4v(scale, mat); + math.translateMat4v(position, mat); + + return mat; + }, + + decomposeMat4: (() => { + + const vec = new FloatArrayType(3); + const matrix = new FloatArrayType(16); + + return function decompose(mat, position, quaternion, scale) { + + vec[0] = mat[0]; + vec[1] = mat[1]; + vec[2] = mat[2]; + + let sx = math.lenVec3(vec); + + vec[0] = mat[4]; + vec[1] = mat[5]; + vec[2] = mat[6]; + + const sy = math.lenVec3(vec); + + vec[8] = mat[8]; + vec[9] = mat[9]; + vec[10] = mat[10]; + + const sz = math.lenVec3(vec); + + // if determine is negative, we need to invert one scale + const det = math.determinantMat4(mat); + + if (det < 0) { + sx = -sx; + } + + position[0] = mat[12]; + position[1] = mat[13]; + position[2] = mat[14]; + + // scale the rotation part + matrix.set(mat); + + const invSX = 1 / sx; + const invSY = 1 / sy; + const invSZ = 1 / sz; + + matrix[0] *= invSX; + matrix[1] *= invSX; + matrix[2] *= invSX; + + matrix[4] *= invSY; + matrix[5] *= invSY; + matrix[6] *= invSY; + + matrix[8] *= invSZ; + matrix[9] *= invSZ; + matrix[10] *= invSZ; + + math.mat4ToQuaternion(matrix, quaternion); + + scale[0] = sx; + scale[1] = sy; + scale[2] = sz; + + return this; + + }; + + })(), + + /** + * Returns a 4x4 'lookat' viewing transform matrix. + * @method lookAtMat4v + * @param pos vec3 position of the viewer + * @param target vec3 point the viewer is looking at + * @param up vec3 pointing "up" + * @param dest mat4 Optional, mat4 matrix will be written into + * + * @return {mat4} dest if specified, a new mat4 otherwise + */ + lookAtMat4v(pos, target, up, dest) { + if (!dest) { + dest = math.mat4(); + } + + const posx = pos[0]; + const posy = pos[1]; + const posz = pos[2]; + const upx = up[0]; + const upy = up[1]; + const upz = up[2]; + const targetx = target[0]; + const targety = target[1]; + const targetz = target[2]; + + if (posx === targetx && posy === targety && posz === targetz) { + return math.identityMat4(); + } + + let z0; + let z1; + let z2; + let x0; + let x1; + let x2; + let y0; + let y1; + let y2; + let len; + + //vec3.direction(eye, center, z); + z0 = posx - targetx; + z1 = posy - targety; + z2 = posz - targetz; + + // normalize (no check needed for 0 because of early return) + len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2); + z0 *= len; + z1 *= len; + z2 *= len; + + //vec3.normalize(vec3.cross(up, z, x)); + x0 = upy * z2 - upz * z1; + x1 = upz * z0 - upx * z2; + x2 = upx * z1 - upy * z0; + len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2); + if (!len) { + x0 = 0; + x1 = 0; + x2 = 0; + } else { + len = 1 / len; + x0 *= len; + x1 *= len; + x2 *= len; + } + + //vec3.normalize(vec3.cross(z, x, y)); + y0 = z1 * x2 - z2 * x1; + y1 = z2 * x0 - z0 * x2; + y2 = z0 * x1 - z1 * x0; + + len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2); + if (!len) { + y0 = 0; + y1 = 0; + y2 = 0; + } else { + len = 1 / len; + y0 *= len; + y1 *= len; + y2 *= len; + } + + dest[0] = x0; + dest[1] = y0; + dest[2] = z0; + dest[3] = 0; + dest[4] = x1; + dest[5] = y1; + dest[6] = z1; + dest[7] = 0; + dest[8] = x2; + dest[9] = y2; + dest[10] = z2; + dest[11] = 0; + dest[12] = -(x0 * posx + x1 * posy + x2 * posz); + dest[13] = -(y0 * posx + y1 * posy + y2 * posz); + dest[14] = -(z0 * posx + z1 * posy + z2 * posz); + dest[15] = 1; + + return dest; + }, + + /** + * Returns a 4x4 'lookat' viewing transform matrix. + * @method lookAtMat4c + * @static + */ + lookAtMat4c(posx, posy, posz, targetx, targety, targetz, upx, upy, upz) { + return math.lookAtMat4v([posx, posy, posz], [targetx, targety, targetz], [upx, upy, upz], []); + }, + + /** + * Returns a 4x4 orthographic projection matrix. + * @method orthoMat4c + * @static + */ + orthoMat4c(left, right, bottom, top, near, far, dest) { + if (!dest) { + dest = math.mat4(); + } + const rl = (right - left); + const tb = (top - bottom); + const fn = (far - near); + + dest[0] = 2.0 / rl; + dest[1] = 0.0; + dest[2] = 0.0; + dest[3] = 0.0; + + dest[4] = 0.0; + dest[5] = 2.0 / tb; + dest[6] = 0.0; + dest[7] = 0.0; + + dest[8] = 0.0; + dest[9] = 0.0; + dest[10] = -2.0 / fn; + dest[11] = 0.0; + + dest[12] = -(left + right) / rl; + dest[13] = -(top + bottom) / tb; + dest[14] = -(far + near) / fn; + dest[15] = 1.0; + + return dest; + }, + + /** + * Returns a 4x4 perspective projection matrix. + * @method frustumMat4v + * @static + */ + frustumMat4v(fmin, fmax, m) { + if (!m) { + m = math.mat4(); + } + + const fmin4 = [fmin[0], fmin[1], fmin[2], 0.0]; + const fmax4 = [fmax[0], fmax[1], fmax[2], 0.0]; + + math.addVec4(fmax4, fmin4, tempMat1); + math.subVec4(fmax4, fmin4, tempMat2); + + const t = 2.0 * fmin4[2]; + + const tempMat20 = tempMat2[0]; + const tempMat21 = tempMat2[1]; + const tempMat22 = tempMat2[2]; + + m[0] = t / tempMat20; + m[1] = 0.0; + m[2] = 0.0; + m[3] = 0.0; + + m[4] = 0.0; + m[5] = t / tempMat21; + m[6] = 0.0; + m[7] = 0.0; + + m[8] = tempMat1[0] / tempMat20; + m[9] = tempMat1[1] / tempMat21; + m[10] = -tempMat1[2] / tempMat22; + m[11] = -1.0; + + m[12] = 0.0; + m[13] = 0.0; + m[14] = -t * fmax4[2] / tempMat22; + m[15] = 0.0; + + return m; + }, + + /** + * Returns a 4x4 perspective projection matrix. + * @method frustumMat4v + * @static + */ + frustumMat4(left, right, bottom, top, near, far, dest) { + if (!dest) { + dest = math.mat4(); + } + const rl = (right - left); + const tb = (top - bottom); + const fn = (far - near); + dest[0] = (near * 2) / rl; + dest[1] = 0; + dest[2] = 0; + dest[3] = 0; + dest[4] = 0; + dest[5] = (near * 2) / tb; + dest[6] = 0; + dest[7] = 0; + dest[8] = (right + left) / rl; + dest[9] = (top + bottom) / tb; + dest[10] = -(far + near) / fn; + dest[11] = -1; + dest[12] = 0; + dest[13] = 0; + dest[14] = -(far * near * 2) / fn; + dest[15] = 0; + return dest; + }, + + /** + * Returns a 4x4 perspective projection matrix. + * @method perspectiveMat4v + * @static + */ + perspectiveMat4(fovyrad, aspectratio, znear, zfar, m) { + const pmin = []; + const pmax = []; + + pmin[2] = znear; + pmax[2] = zfar; + + pmax[1] = pmin[2] * Math.tan(fovyrad / 2.0); + pmin[1] = -pmax[1]; + + pmax[0] = pmax[1] * aspectratio; + pmin[0] = -pmax[0]; + + return math.frustumMat4v(pmin, pmax, m); + }, + + /** + * Transforms a three-element position by a 4x4 matrix. + * @method transformPoint3 + * @static + */ + transformPoint3(m, p, dest = math.vec3()) { + + const x = p[0]; + const y = p[1]; + const z = p[2]; + + dest[0] = (m[0] * x) + (m[4] * y) + (m[8] * z) + m[12]; + dest[1] = (m[1] * x) + (m[5] * y) + (m[9] * z) + m[13]; + dest[2] = (m[2] * x) + (m[6] * y) + (m[10] * z) + m[14]; + + return dest; + }, + + /** + * Transforms a homogeneous coordinate by a 4x4 matrix. + * @method transformPoint3 + * @static + */ + transformPoint4(m, v, dest = math.vec4()) { + dest[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3]; + dest[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3]; + dest[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3]; + dest[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3]; + + return dest; + }, + + + /** + * Transforms an array of three-element positions by a 4x4 matrix. + * @method transformPoints3 + * @static + */ + transformPoints3(m, points, points2) { + const result = points2 || []; + const len = points.length; + let p0; + let p1; + let p2; + let pi; + + // cache values + const m0 = m[0]; + + const m1 = m[1]; + const m2 = m[2]; + const m3 = m[3]; + const m4 = m[4]; + const m5 = m[5]; + const m6 = m[6]; + const m7 = m[7]; + const m8 = m[8]; + const m9 = m[9]; + const m10 = m[10]; + const m11 = m[11]; + const m12 = m[12]; + const m13 = m[13]; + const m14 = m[14]; + const m15 = m[15]; + + let r; + + for (let i = 0; i < len; ++i) { + + // cache values + pi = points[i]; + + p0 = pi[0]; + p1 = pi[1]; + p2 = pi[2]; + + r = result[i] || (result[i] = [0, 0, 0]); + + r[0] = (m0 * p0) + (m4 * p1) + (m8 * p2) + m12; + r[1] = (m1 * p0) + (m5 * p1) + (m9 * p2) + m13; + r[2] = (m2 * p0) + (m6 * p1) + (m10 * p2) + m14; + r[3] = (m3 * p0) + (m7 * p1) + (m11 * p2) + m15; + } + + result.length = len; + + return result; + }, + + /** + * Transforms an array of positions by a 4x4 matrix. + * @method transformPositions3 + * @static + */ + transformPositions3(m, p, p2 = p) { + let i; + const len = p.length; + + let x; + let y; + let z; + + const m0 = m[0]; + const m1 = m[1]; + const m2 = m[2]; + const m3 = m[3]; + const m4 = m[4]; + const m5 = m[5]; + const m6 = m[6]; + const m7 = m[7]; + const m8 = m[8]; + const m9 = m[9]; + const m10 = m[10]; + const m11 = m[11]; + const m12 = m[12]; + const m13 = m[13]; + const m14 = m[14]; + const m15 = m[15]; + + for (i = 0; i < len; i += 3) { + + x = p[i + 0]; + y = p[i + 1]; + z = p[i + 2]; + + p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12; + p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13; + p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14; + p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15; + } + + return p2; + }, + + /** + * Transforms an array of positions by a 4x4 matrix. + * @method transformPositions4 + * @static + */ + transformPositions4(m, p, p2 = p) { + let i; + const len = p.length; + + let x; + let y; + let z; + + const m0 = m[0]; + const m1 = m[1]; + const m2 = m[2]; + const m3 = m[3]; + const m4 = m[4]; + const m5 = m[5]; + const m6 = m[6]; + const m7 = m[7]; + const m8 = m[8]; + const m9 = m[9]; + const m10 = m[10]; + const m11 = m[11]; + const m12 = m[12]; + const m13 = m[13]; + const m14 = m[14]; + const m15 = m[15]; + + for (i = 0; i < len; i += 4) { + + x = p[i + 0]; + y = p[i + 1]; + z = p[i + 2]; + + p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12; + p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13; + p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14; + p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15; + } + + return p2; + }, + + /** + * Transforms a three-element vector by a 4x4 matrix. + * @method transformVec3 + * @static + */ + transformVec3(m, v, dest) { + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + dest = dest || this.vec3(); + dest[0] = (m[0] * v0) + (m[4] * v1) + (m[8] * v2); + dest[1] = (m[1] * v0) + (m[5] * v1) + (m[9] * v2); + dest[2] = (m[2] * v0) + (m[6] * v1) + (m[10] * v2); + return dest; + }, + + /** + * Transforms a four-element vector by a 4x4 matrix. + * @method transformVec4 + * @static + */ + transformVec4(m, v, dest) { + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + const v3 = v[3]; + dest = dest || math.vec4(); + dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3; + dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3; + dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3; + dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3; + return dest; + }, + + /** + * Rotate a 3D vector around the x-axis + * + * @method rotateVec3X + * @param {Number[]} a The vec3 point to rotate + * @param {Number[]} b The origin of the rotation + * @param {Number} c The angle of rotation + * @param {Number[]} dest The receiving vec3 + * @returns {Number[]} dest + * @static + */ + rotateVec3X(a, b, c, dest) { + const p = []; + const r = []; + + //Translate point to the origin + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; + + //perform rotation + r[0] = p[0]; + r[1] = p[1] * Math.cos(c) - p[2] * Math.sin(c); + r[2] = p[1] * Math.sin(c) + p[2] * Math.cos(c); + + //translate to correct position + dest[0] = r[0] + b[0]; + dest[1] = r[1] + b[1]; + dest[2] = r[2] + b[2]; + + return dest; + }, + + /** + * Rotate a 3D vector around the y-axis + * + * @method rotateVec3Y + * @param {Number[]} a The vec3 point to rotate + * @param {Number[]} b The origin of the rotation + * @param {Number} c The angle of rotation + * @param {Number[]} dest The receiving vec3 + * @returns {Number[]} dest + * @static + */ + rotateVec3Y(a, b, c, dest) { + const p = []; + const r = []; + + //Translate point to the origin + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; + + //perform rotation + r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c); + r[1] = p[1]; + r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c); + + //translate to correct position + dest[0] = r[0] + b[0]; + dest[1] = r[1] + b[1]; + dest[2] = r[2] + b[2]; + + return dest; + }, + + /** + * Rotate a 3D vector around the z-axis + * + * @method rotateVec3Z + * @param {Number[]} a The vec3 point to rotate + * @param {Number[]} b The origin of the rotation + * @param {Number} c The angle of rotation + * @param {Number[]} dest The receiving vec3 + * @returns {Number[]} dest + * @static + */ + rotateVec3Z(a, b, c, dest) { + const p = []; + const r = []; + + //Translate point to the origin + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; + + //perform rotation + r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c); + r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c); + r[2] = p[2]; + + //translate to correct position + dest[0] = r[0] + b[0]; + dest[1] = r[1] + b[1]; + dest[2] = r[2] + b[2]; + + return dest; + }, + + /** + * Transforms a four-element vector by a 4x4 projection matrix. + * + * @method projectVec4 + * @param {Number[]} p 3D View-space coordinate + * @param {Number[]} q 2D Projected coordinate + * @returns {Number[]} 2D Projected coordinate + * @static + */ + projectVec4(p, q) { + const f = 1.0 / p[3]; + q = q || math.vec2(); + q[0] = v[0] * f; + q[1] = v[1] * f; + return q; + }, + + /** + * Unprojects a three-element vector. + * + * @method unprojectVec3 + * @param {Number[]} p 3D Projected coordinate + * @param {Number[]} viewMat View matrix + * @returns {Number[]} projMat Projection matrix + * @static + */ + unprojectVec3: ((() => { + const mat = new FloatArrayType(16); + const mat2 = new FloatArrayType(16); + const mat3 = new FloatArrayType(16); + return function (p, viewMat, projMat, q) { + return this.transformVec3(this.mulMat4(this.inverseMat4(viewMat, mat), this.inverseMat4(projMat, mat2), mat3), p, q) + }; + }))(), + + /** + * Linearly interpolates between two 3D vectors. + * @method lerpVec3 + * @static + */ + lerpVec3(t, t1, t2, p1, p2, dest) { + const result = dest || math.vec3(); + const f = (t - t1) / (t2 - t1); + result[0] = p1[0] + (f * (p2[0] - p1[0])); + result[1] = p1[1] + (f * (p2[1] - p1[1])); + result[2] = p1[2] + (f * (p2[2] - p1[2])); + return result; + }, + + + /** + * Flattens a two-dimensional array into a one-dimensional array. + * + * @method flatten + * @static + * @param {Array of Arrays} a A 2D array + * @returns Flattened 1D array + */ + flatten(a) { + + const result = []; + + let i; + let leni; + let j; + let lenj; + let item; + + for (i = 0, leni = a.length; i < leni; i++) { + item = a[i]; + for (j = 0, lenj = item.length; j < lenj; j++) { + result.push(item[j]); + } + } + + return result; + }, + + + identityQuaternion(dest = math.vec4()) { + dest[0] = 0.0; + dest[1] = 0.0; + dest[2] = 0.0; + dest[3] = 1.0; + return dest; + }, + + /** + * Initializes a quaternion from Euler angles. + * + * @param {Number[]} euler The Euler angles. + * @param {String} order Euler angle order: "XYZ", "YXZ", "ZXY" etc. + * @param {Number[]} [dest] Destination quaternion, created by default. + * @returns {Number[]} The quaternion. + */ + eulerToQuaternion(euler, order, dest = math.vec4()) { + // http://www.mathworks.com/matlabcentral/fileexchange/ + // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ + // content/SpinCalc.m + + const a = (euler[0] * math.DEGTORAD) / 2; + const b = (euler[1] * math.DEGTORAD) / 2; + const c = (euler[2] * math.DEGTORAD) / 2; + + const c1 = Math.cos(a); + const c2 = Math.cos(b); + const c3 = Math.cos(c); + const s1 = Math.sin(a); + const s2 = Math.sin(b); + const s3 = Math.sin(c); + + if (order === 'XYZ') { + + dest[0] = s1 * c2 * c3 + c1 * s2 * s3; + dest[1] = c1 * s2 * c3 - s1 * c2 * s3; + dest[2] = c1 * c2 * s3 + s1 * s2 * c3; + dest[3] = c1 * c2 * c3 - s1 * s2 * s3; + + } else if (order === 'YXZ') { + + dest[0] = s1 * c2 * c3 + c1 * s2 * s3; + dest[1] = c1 * s2 * c3 - s1 * c2 * s3; + dest[2] = c1 * c2 * s3 - s1 * s2 * c3; + dest[3] = c1 * c2 * c3 + s1 * s2 * s3; + + } else if (order === 'ZXY') { + + dest[0] = s1 * c2 * c3 - c1 * s2 * s3; + dest[1] = c1 * s2 * c3 + s1 * c2 * s3; + dest[2] = c1 * c2 * s3 + s1 * s2 * c3; + dest[3] = c1 * c2 * c3 - s1 * s2 * s3; + + } else if (order === 'ZYX') { + + dest[0] = s1 * c2 * c3 - c1 * s2 * s3; + dest[1] = c1 * s2 * c3 + s1 * c2 * s3; + dest[2] = c1 * c2 * s3 - s1 * s2 * c3; + dest[3] = c1 * c2 * c3 + s1 * s2 * s3; + + } else if (order === 'YZX') { + + dest[0] = s1 * c2 * c3 + c1 * s2 * s3; + dest[1] = c1 * s2 * c3 + s1 * c2 * s3; + dest[2] = c1 * c2 * s3 - s1 * s2 * c3; + dest[3] = c1 * c2 * c3 - s1 * s2 * s3; + + } else if (order === 'XZY') { + + dest[0] = s1 * c2 * c3 - c1 * s2 * s3; + dest[1] = c1 * s2 * c3 - s1 * c2 * s3; + dest[2] = c1 * c2 * s3 + s1 * s2 * c3; + dest[3] = c1 * c2 * c3 + s1 * s2 * s3; + } + + return dest; + }, + + mat4ToQuaternion(m, dest = math.vec4()) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + + // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + + const m11 = m[0]; + const m12 = m[4]; + const m13 = m[8]; + const m21 = m[1]; + const m22 = m[5]; + const m23 = m[9]; + const m31 = m[2]; + const m32 = m[6]; + const m33 = m[10]; + let s; + + const trace = m11 + m22 + m33; + + if (trace > 0) { + + s = 0.5 / Math.sqrt(trace + 1.0); + + dest[3] = 0.25 / s; + dest[0] = (m32 - m23) * s; + dest[1] = (m13 - m31) * s; + dest[2] = (m21 - m12) * s; + + } else if (m11 > m22 && m11 > m33) { + + s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33); + + dest[3] = (m32 - m23) / s; + dest[0] = 0.25 * s; + dest[1] = (m12 + m21) / s; + dest[2] = (m13 + m31) / s; + + } else if (m22 > m33) { + + s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33); + + dest[3] = (m13 - m31) / s; + dest[0] = (m12 + m21) / s; + dest[1] = 0.25 * s; + dest[2] = (m23 + m32) / s; + + } else { + + s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22); + + dest[3] = (m21 - m12) / s; + dest[0] = (m13 + m31) / s; + dest[1] = (m23 + m32) / s; + dest[2] = 0.25 * s; + } + + return dest; + }, + + vec3PairToQuaternion(u, v, dest = math.vec4()) { + const norm_u_norm_v = Math.sqrt(math.dotVec3(u, u) * math.dotVec3(v, v)); + let real_part = norm_u_norm_v + math.dotVec3(u, v); + + if (real_part < 0.00000001 * norm_u_norm_v) { + + // If u and v are exactly opposite, rotate 180 degrees + // around an arbitrary orthogonal axis. Axis normalisation + // can happen later, when we normalise the quaternion. + + real_part = 0.0; + + if (Math.abs(u[0]) > Math.abs(u[2])) { + + dest[0] = -u[1]; + dest[1] = u[0]; + dest[2] = 0; + + } else { + dest[0] = 0; + dest[1] = -u[2]; + dest[2] = u[1]; + } + + } else { + + // Otherwise, build quaternion the standard way. + math.cross3Vec3(u, v, dest); + } + + dest[3] = real_part; + + return math.normalizeQuaternion(dest); + }, + + angleAxisToQuaternion(angleAxis, dest = math.vec4()) { + const halfAngle = angleAxis[3] / 2.0; + const fsin = Math.sin(halfAngle); + dest[0] = fsin * angleAxis[0]; + dest[1] = fsin * angleAxis[1]; + dest[2] = fsin * angleAxis[2]; + dest[3] = Math.cos(halfAngle); + return dest; + }, + + quaternionToEuler: ((() => { + const mat = new FloatArrayType(16); + return (q, order, dest) => { + dest = dest || math.vec3(); + math.quaternionToRotationMat4(q, mat); + math.mat4ToEuler(mat, order, dest); + return dest; + }; + }))(), + + mulQuaternions(p, q, dest = math.vec4()) { + const p0 = p[0]; + const p1 = p[1]; + const p2 = p[2]; + const p3 = p[3]; + const q0 = q[0]; + const q1 = q[1]; + const q2 = q[2]; + const q3 = q[3]; + dest[0] = p3 * q0 + p0 * q3 + p1 * q2 - p2 * q1; + dest[1] = p3 * q1 + p1 * q3 + p2 * q0 - p0 * q2; + dest[2] = p3 * q2 + p2 * q3 + p0 * q1 - p1 * q0; + dest[3] = p3 * q3 - p0 * q0 - p1 * q1 - p2 * q2; + return dest; + }, + + vec3ApplyQuaternion(q, vec, dest = math.vec3()) { + const x = vec[0]; + const y = vec[1]; + const z = vec[2]; + + const qx = q[0]; + const qy = q[1]; + const qz = q[2]; + const qw = q[3]; + + // calculate quat * vector + + const ix = qw * x + qy * z - qz * y; + const iy = qw * y + qz * x - qx * z; + const iz = qw * z + qx * y - qy * x; + const iw = -qx * x - qy * y - qz * z; + + // calculate result * inverse quat + + dest[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; + dest[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; + dest[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; + + return dest; + }, + + quaternionToMat4(q, dest) { + + dest = math.identityMat4(dest); + + const q0 = q[0]; //x + const q1 = q[1]; //y + const q2 = q[2]; //z + const q3 = q[3]; //w + + const tx = 2.0 * q0; + const ty = 2.0 * q1; + const tz = 2.0 * q2; + + const twx = tx * q3; + const twy = ty * q3; + const twz = tz * q3; + + const txx = tx * q0; + const txy = ty * q0; + const txz = tz * q0; + + const tyy = ty * q1; + const tyz = tz * q1; + const tzz = tz * q2; + + dest[0] = 1.0 - (tyy + tzz); + dest[1] = txy + twz; + dest[2] = txz - twy; + + dest[4] = txy - twz; + dest[5] = 1.0 - (txx + tzz); + dest[6] = tyz + twx; + + dest[8] = txz + twy; + dest[9] = tyz - twx; + + dest[10] = 1.0 - (txx + tyy); + + return dest; + }, + + quaternionToRotationMat4(q, m) { + const x = q[0]; + const y = q[1]; + const z = q[2]; + const w = q[3]; + + const x2 = x + x; + const y2 = y + y; + const z2 = z + z; + const xx = x * x2; + const xy = x * y2; + const xz = x * z2; + const yy = y * y2; + const yz = y * z2; + const zz = z * z2; + const wx = w * x2; + const wy = w * y2; + const wz = w * z2; + + m[0] = 1 - (yy + zz); + m[4] = xy - wz; + m[8] = xz + wy; + + m[1] = xy + wz; + m[5] = 1 - (xx + zz); + m[9] = yz - wx; + + m[2] = xz - wy; + m[6] = yz + wx; + m[10] = 1 - (xx + yy); + + // last column + m[3] = 0; + m[7] = 0; + m[11] = 0; + + // bottom row + m[12] = 0; + m[13] = 0; + m[14] = 0; + m[15] = 1; + + return m; + }, + + normalizeQuaternion(q, dest = q) { + const len = math.lenVec4([q[0], q[1], q[2], q[3]]); + dest[0] = q[0] / len; + dest[1] = q[1] / len; + dest[2] = q[2] / len; + dest[3] = q[3] / len; + return dest; + }, + + conjugateQuaternion(q, dest = q) { + dest[0] = -q[0]; + dest[1] = -q[1]; + dest[2] = -q[2]; + dest[3] = q[3]; + return dest; + }, + + inverseQuaternion(q, dest) { + return math.normalizeQuaternion(math.conjugateQuaternion(q, dest)); + }, + + quaternionToAngleAxis(q, angleAxis = math.vec4()) { + q = math.normalizeQuaternion(q, tempVec4); + const q3 = q[3]; + const angle = 2 * Math.acos(q3); + const s = Math.sqrt(1 - q3 * q3); + if (s < 0.001) { // test to avoid divide by zero, s is always positive due to sqrt + angleAxis[0] = q[0]; + angleAxis[1] = q[1]; + angleAxis[2] = q[2]; + } else { + angleAxis[0] = q[0] / s; + angleAxis[1] = q[1] / s; + angleAxis[2] = q[2] / s; + } + angleAxis[3] = angle; // * 57.295779579; + return angleAxis; + }, + + //------------------------------------------------------------------------------------------------------------------ + // Boundaries + //------------------------------------------------------------------------------------------------------------------ + + /** + * Returns a new, uninitialized 3D axis-aligned bounding box. + * + * @private + */ + AABB3(values) { + return new FloatArrayType(values || 6); + }, + + /** + * Returns a new, uninitialized 2D axis-aligned bounding box. + * + * @private + */ + AABB2(values) { + return new FloatArrayType(values || 4); + }, + + /** + * Returns a new, uninitialized 3D oriented bounding box (OBB). + * + * @private + */ + OBB3(values) { + return new FloatArrayType(values || 32); + }, + + /** + * Returns a new, uninitialized 2D oriented bounding box (OBB). + * + * @private + */ + OBB2(values) { + return new FloatArrayType(values || 16); + }, + + /** Returns a new 3D bounding sphere */ + Sphere3(x, y, z, r) { + return new FloatArrayType([x, y, z, r]); + }, + + /** + * Transforms an OBB3 by a 4x4 matrix. + * + * @private + */ + transformOBB3(m, p, p2 = p) { + let i; + const len = p.length; + + let x; + let y; + let z; + + const m0 = m[0]; + const m1 = m[1]; + const m2 = m[2]; + const m3 = m[3]; + const m4 = m[4]; + const m5 = m[5]; + const m6 = m[6]; + const m7 = m[7]; + const m8 = m[8]; + const m9 = m[9]; + const m10 = m[10]; + const m11 = m[11]; + const m12 = m[12]; + const m13 = m[13]; + const m14 = m[14]; + const m15 = m[15]; + + for (i = 0; i < len; i += 4) { + + x = p[i + 0]; + y = p[i + 1]; + z = p[i + 2]; + + p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12; + p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13; + p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14; + p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15; + } + + return p2; + }, + + /** Returns true if the first AABB contains the second AABB. + * @param aabb1 + * @param aabb2 + * @returns {boolean} + */ + containsAABB3: function (aabb1, aabb2) { + const result = ( + aabb1[0] <= aabb2[0] && aabb2[3] <= aabb1[3] && + aabb1[1] <= aabb2[1] && aabb2[4] <= aabb1[4] && + aabb1[2] <= aabb2[2] && aabb2[5] <= aabb1[5]); + return result; + }, + + /** + * Gets the diagonal size of an AABB3 given as minima and maxima. + * + * @private + */ + getAABB3Diag: ((() => { + + const min = new FloatArrayType(3); + const max = new FloatArrayType(3); + const tempVec3 = new FloatArrayType(3); + + return aabb => { + + min[0] = aabb[0]; + min[1] = aabb[1]; + min[2] = aabb[2]; + + max[0] = aabb[3]; + max[1] = aabb[4]; + max[2] = aabb[5]; + + math.subVec3(max, min, tempVec3); + + return Math.abs(math.lenVec3(tempVec3)); + }; + }))(), + + /** + * Get a diagonal boundary size that is symmetrical about the given point. + * + * @private + */ + getAABB3DiagPoint: ((() => { + + const min = new FloatArrayType(3); + const max = new FloatArrayType(3); + const tempVec3 = new FloatArrayType(3); + + return (aabb, p) => { + + min[0] = aabb[0]; + min[1] = aabb[1]; + min[2] = aabb[2]; + + max[0] = aabb[3]; + max[1] = aabb[4]; + max[2] = aabb[5]; + + const diagVec = math.subVec3(max, min, tempVec3); + + const xneg = p[0] - aabb[0]; + const xpos = aabb[3] - p[0]; + const yneg = p[1] - aabb[1]; + const ypos = aabb[4] - p[1]; + const zneg = p[2] - aabb[2]; + const zpos = aabb[5] - p[2]; + + diagVec[0] += (xneg > xpos) ? xneg : xpos; + diagVec[1] += (yneg > ypos) ? yneg : ypos; + diagVec[2] += (zneg > zpos) ? zneg : zpos; + + return Math.abs(math.lenVec3(diagVec)); + }; + }))(), + + /** + * Gets the center of an AABB. + * + * @private + */ + getAABB3Center(aabb, dest) { + const r = dest || math.vec3(); + + r[0] = (aabb[0] + aabb[3]) / 2; + r[1] = (aabb[1] + aabb[4]) / 2; + r[2] = (aabb[2] + aabb[5]) / 2; + + return r; + }, + + /** + * Gets the center of a 2D AABB. + * + * @private + */ + getAABB2Center(aabb, dest) { + const r = dest || math.vec2(); + + r[0] = (aabb[2] + aabb[0]) / 2; + r[1] = (aabb[3] + aabb[1]) / 2; + + return r; + }, + + /** + * Collapses a 3D axis-aligned boundary, ready to expand to fit 3D points. + * Creates new AABB if none supplied. + * + * @private + */ + collapseAABB3(aabb = math.AABB3()) { + aabb[0] = math.MAX_DOUBLE; + aabb[1] = math.MAX_DOUBLE; + aabb[2] = math.MAX_DOUBLE; + aabb[3] = -math.MAX_DOUBLE; + aabb[4] = -math.MAX_DOUBLE; + aabb[5] = -math.MAX_DOUBLE; + + return aabb; + }, + + /** + * Converts an axis-aligned 3D boundary into an oriented boundary consisting of + * an array of eight 3D positions, one for each corner of the boundary. + * + * @private + */ + AABB3ToOBB3(aabb, obb = math.OBB3()) { + obb[0] = aabb[0]; + obb[1] = aabb[1]; + obb[2] = aabb[2]; + obb[3] = 1; + + obb[4] = aabb[3]; + obb[5] = aabb[1]; + obb[6] = aabb[2]; + obb[7] = 1; + + obb[8] = aabb[3]; + obb[9] = aabb[4]; + obb[10] = aabb[2]; + obb[11] = 1; + + obb[12] = aabb[0]; + obb[13] = aabb[4]; + obb[14] = aabb[2]; + obb[15] = 1; + + obb[16] = aabb[0]; + obb[17] = aabb[1]; + obb[18] = aabb[5]; + obb[19] = 1; + + obb[20] = aabb[3]; + obb[21] = aabb[1]; + obb[22] = aabb[5]; + obb[23] = 1; + + obb[24] = aabb[3]; + obb[25] = aabb[4]; + obb[26] = aabb[5]; + obb[27] = 1; + + obb[28] = aabb[0]; + obb[29] = aabb[4]; + obb[30] = aabb[5]; + obb[31] = 1; + + return obb; + }, + + /** + * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array. + * + * @private + */ + positions3ToAABB3: ((() => { + + const p = new FloatArrayType(3); + + return (positions, aabb, positionsDecodeMatrix) => { + aabb = aabb || math.AABB3(); + + let xmin = math.MAX_DOUBLE; + let ymin = math.MAX_DOUBLE; + let zmin = math.MAX_DOUBLE; + let xmax = -math.MAX_DOUBLE; + let ymax = -math.MAX_DOUBLE; + let zmax = -math.MAX_DOUBLE; + + let x; + let y; + let z; + + for (let i = 0, len = positions.length; i < len; i += 3) { + + if (positionsDecodeMatrix) { + + p[0] = positions[i + 0]; + p[1] = positions[i + 1]; + p[2] = positions[i + 2]; + + math.decompressPosition(p, positionsDecodeMatrix, p); + + x = p[0]; + y = p[1]; + z = p[2]; + + } else { + x = positions[i + 0]; + y = positions[i + 1]; + z = positions[i + 2]; + } + + if (x < xmin) { + xmin = x; + } + + if (y < ymin) { + ymin = y; + } + + if (z < zmin) { + zmin = z; + } + + if (x > xmax) { + xmax = x; + } + + if (y > ymax) { + ymax = y; + } + + if (z > zmax) { + zmax = z; + } + } + + aabb[0] = xmin; + aabb[1] = ymin; + aabb[2] = zmin; + aabb[3] = xmax; + aabb[4] = ymax; + aabb[5] = zmax; + + return aabb; + }; + }))(), + + /** + * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array. + * + * @private + */ + OBB3ToAABB3(obb, aabb = math.AABB3()) { + let xmin = math.MAX_DOUBLE; + let ymin = math.MAX_DOUBLE; + let zmin = math.MAX_DOUBLE; + let xmax = -math.MAX_DOUBLE; + let ymax = -math.MAX_DOUBLE; + let zmax = -math.MAX_DOUBLE; + + let x; + let y; + let z; + + for (let i = 0, len = obb.length; i < len; i += 4) { + + x = obb[i + 0]; + y = obb[i + 1]; + z = obb[i + 2]; + + if (x < xmin) { + xmin = x; + } + + if (y < ymin) { + ymin = y; + } + + if (z < zmin) { + zmin = z; + } + + if (x > xmax) { + xmax = x; + } + + if (y > ymax) { + ymax = y; + } + + if (z > zmax) { + zmax = z; + } + } + + aabb[0] = xmin; + aabb[1] = ymin; + aabb[2] = zmin; + aabb[3] = xmax; + aabb[4] = ymax; + aabb[5] = zmax; + + return aabb; + }, + + /** + * Finds the minimum axis-aligned 3D boundary enclosing the given 3D points. + * + * @private + */ + points3ToAABB3(points, aabb = math.AABB3()) { + let xmin = math.MAX_DOUBLE; + let ymin = math.MAX_DOUBLE; + let zmin = math.MAX_DOUBLE; + let xmax = -math.MAX_DOUBLE; + let ymax = -math.MAX_DOUBLE; + let zmax = -math.MAX_DOUBLE; + + let x; + let y; + let z; + + for (let i = 0, len = points.length; i < len; i++) { + + x = points[i][0]; + y = points[i][1]; + z = points[i][2]; + + if (x < xmin) { + xmin = x; + } + + if (y < ymin) { + ymin = y; + } + + if (z < zmin) { + zmin = z; + } + + if (x > xmax) { + xmax = x; + } + + if (y > ymax) { + ymax = y; + } + + if (z > zmax) { + zmax = z; + } + } + + aabb[0] = xmin; + aabb[1] = ymin; + aabb[2] = zmin; + aabb[3] = xmax; + aabb[4] = ymax; + aabb[5] = zmax; + + return aabb; + }, + + /** + * Finds the minimum boundary sphere enclosing the given 3D points. + * + * @private + */ + points3ToSphere3: ((() => { + + const tempVec3 = new FloatArrayType(3); + + return (points, sphere) => { + + sphere = sphere || math.vec4(); + + let x = 0; + let y = 0; + let z = 0; + + let i; + const numPoints = points.length; + + for (i = 0; i < numPoints; i++) { + x += points[i][0]; + y += points[i][1]; + z += points[i][2]; + } + + sphere[0] = x / numPoints; + sphere[1] = y / numPoints; + sphere[2] = z / numPoints; + + let radius = 0; + let dist; + + for (i = 0; i < numPoints; i++) { + + dist = Math.abs(math.lenVec3(math.subVec3(points[i], sphere, tempVec3))); + + if (dist > radius) { + radius = dist; + } + } + + sphere[3] = radius; + + return sphere; + }; + }))(), + + /** + * Finds the minimum boundary sphere enclosing the given 3D positions. + * + * @private + */ + positions3ToSphere3: ((() => { + + const tempVec3a = new FloatArrayType(3); + const tempVec3b = new FloatArrayType(3); + + return (positions, sphere) => { + + sphere = sphere || math.vec4(); + + let x = 0; + let y = 0; + let z = 0; + + let i; + const lenPositions = positions.length; + let radius = 0; + + for (i = 0; i < lenPositions; i += 3) { + x += positions[i]; + y += positions[i + 1]; + z += positions[i + 2]; + } + + const numPositions = lenPositions / 3; + + sphere[0] = x / numPositions; + sphere[1] = y / numPositions; + sphere[2] = z / numPositions; + + let dist; + + for (i = 0; i < lenPositions; i += 3) { + + tempVec3a[0] = positions[i]; + tempVec3a[1] = positions[i + 1]; + tempVec3a[2] = positions[i + 2]; + + dist = Math.abs(math.lenVec3(math.subVec3(tempVec3a, sphere, tempVec3b))); + + if (dist > radius) { + radius = dist; + } + } + + sphere[3] = radius; + + return sphere; + }; + }))(), + + /** + * Finds the minimum boundary sphere enclosing the given 3D points. + * + * @private + */ + OBB3ToSphere3: ((() => { + + const point = new FloatArrayType(3); + const tempVec3 = new FloatArrayType(3); + + return (points, sphere) => { + + sphere = sphere || math.vec4(); + + let x = 0; + let y = 0; + let z = 0; + + let i; + const lenPoints = points.length; + const numPoints = lenPoints / 4; + + for (i = 0; i < lenPoints; i += 4) { + x += points[i + 0]; + y += points[i + 1]; + z += points[i + 2]; + } + + sphere[0] = x / numPoints; + sphere[1] = y / numPoints; + sphere[2] = z / numPoints; + + let radius = 0; + let dist; + + for (i = 0; i < lenPoints; i += 4) { + + point[0] = points[i + 0]; + point[1] = points[i + 1]; + point[2] = points[i + 2]; + + dist = Math.abs(math.lenVec3(math.subVec3(point, sphere, tempVec3))); + + if (dist > radius) { + radius = dist; + } + } + + sphere[3] = radius; + + return sphere; + }; + }))(), + + /** + * Gets the center of a bounding sphere. + * + * @private + */ + getSphere3Center(sphere, dest = math.vec3()) { + dest[0] = sphere[0]; + dest[1] = sphere[1]; + dest[2] = sphere[2]; + + return dest; + }, + + /** + * Expands the first axis-aligned 3D boundary to enclose the second, if required. + * + * @private + */ + expandAABB3(aabb1, aabb2) { + + if (aabb1[0] > aabb2[0]) { + aabb1[0] = aabb2[0]; + } + + if (aabb1[1] > aabb2[1]) { + aabb1[1] = aabb2[1]; + } + + if (aabb1[2] > aabb2[2]) { + aabb1[2] = aabb2[2]; + } + + if (aabb1[3] < aabb2[3]) { + aabb1[3] = aabb2[3]; + } + + if (aabb1[4] < aabb2[4]) { + aabb1[4] = aabb2[4]; + } + + if (aabb1[5] < aabb2[5]) { + aabb1[5] = aabb2[5]; + } + + return aabb1; + }, + + /** + * Expands an axis-aligned 3D boundary to enclose the given point, if needed. + * + * @private + */ + expandAABB3Point3(aabb, p) { + + if (aabb[0] > p[0]) { + aabb[0] = p[0]; + } + + if (aabb[1] > p[1]) { + aabb[1] = p[1]; + } + + if (aabb[2] > p[2]) { + aabb[2] = p[2]; + } + + if (aabb[3] < p[0]) { + aabb[3] = p[0]; + } + + if (aabb[4] < p[1]) { + aabb[4] = p[1]; + } + + if (aabb[5] < p[2]) { + aabb[5] = p[2]; + } + + return aabb; + }, + + /** + * Calculates the normal vector of a triangle. + * + * @private + */ + triangleNormal(a, b, c, normal = math.vec3()) { + const p1x = b[0] - a[0]; + const p1y = b[1] - a[1]; + const p1z = b[2] - a[2]; + + const p2x = c[0] - a[0]; + const p2y = c[1] - a[1]; + const p2z = c[2] - a[2]; + + const p3x = p1y * p2z - p1z * p2y; + const p3y = p1z * p2x - p1x * p2z; + const p3z = p1x * p2y - p1y * p2x; + + const mag = Math.sqrt(p3x * p3x + p3y * p3y + p3z * p3z); + if (mag === 0) { + normal[0] = 0; + normal[1] = 0; + normal[2] = 0; + } else { + normal[0] = p3x / mag; + normal[1] = p3y / mag; + normal[2] = p3z / mag; + } + + return normal + } +}; + +function quantizePositions (positions, lenPositions, aabb, quantizedPositions) { + const xmin = aabb[0]; + const ymin = aabb[1]; + const zmin = aabb[2]; + const xwid = aabb[3] - xmin; + const ywid = aabb[4] - ymin; + const zwid = aabb[5] - zmin; + const maxInt = 65535; + const xMultiplier = maxInt / xwid; + const yMultiplier = maxInt / ywid; + const zMultiplier = maxInt / zwid; + const verify = (num) => num >= 0 ? num : 0; + for (let i = 0; i < lenPositions; i += 3) { + quantizedPositions[i + 0] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 0] - xmin) * xMultiplier))); + quantizedPositions[i + 1] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 1] - ymin) * yMultiplier))); + quantizedPositions[i + 2] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 2] - zmin) * zMultiplier))); + } +} + +function compressPosition(p, aabb, q) { + const multiplier = new Float32Array([ + aabb[3] !== aabb[0] ? 65535 / (aabb[3] - aabb[0]) : 0, + aabb[4] !== aabb[1] ? 65535 / (aabb[4] - aabb[1]) : 0, + aabb[5] !== aabb[2] ? 65535 / (aabb[5] - aabb[2]) : 0 + ]); + q[0] = Math.max(0, Math.min(65535, Math.floor((p[0] - aabb[0]) * multiplier[0]))); + q[1] = Math.max(0, Math.min(65535, Math.floor((p[1] - aabb[1]) * multiplier[1]))); + q[2] = Math.max(0, Math.min(65535, Math.floor((p[2] - aabb[2]) * multiplier[2]))); +} + +var createPositionsDecodeMatrix = (function () { + const translate = math.mat4(); + const scale = math.mat4(); + return function (aabb, positionsDecodeMatrix) { + positionsDecodeMatrix = positionsDecodeMatrix || math.mat4(); + const xmin = aabb[0]; + const ymin = aabb[1]; + const zmin = aabb[2]; + const xwid = aabb[3] - xmin; + const ywid = aabb[4] - ymin; + const zwid = aabb[5] - zmin; + const maxInt = 65535; + math.identityMat4(translate); + math.translationMat4v(aabb, translate); + math.identityMat4(scale); + math.scalingMat4v([xwid / maxInt, ywid / maxInt, zwid / maxInt], scale); + math.mulMat4(translate, scale, positionsDecodeMatrix); + return positionsDecodeMatrix; + }; +})(); + +function transformAndOctEncodeNormals(modelNormalMatrix, normals, lenNormals, compressedNormals, lenCompressedNormals) { + // http://jcgt.org/published/0003/02/01/ + let oct, dec, best, currentCos, bestCos; + let i; + let localNormal = math.vec3(); + let worldNormal = math.vec3(); + for (i = 0; i < lenNormals; i += 3) { + localNormal[0] = normals[i]; + localNormal[1] = normals[i + 1]; + localNormal[2] = normals[i + 2]; + + math.transformVec3(modelNormalMatrix, localNormal, worldNormal); + math.normalizeVec3(worldNormal, worldNormal); + + // Test various combinations of ceil and floor to minimize rounding errors + best = oct = octEncodeVec3(worldNormal, 0, "floor", "floor"); + dec = octDecodeVec2(oct); + currentCos = bestCos = dot$1(worldNormal, 0, dec); + oct = octEncodeVec3(worldNormal, 0, "ceil", "floor"); + dec = octDecodeVec2(oct); + currentCos = dot$1(worldNormal, 0, dec); + if (currentCos > bestCos) { + best = oct; + bestCos = currentCos; + } + oct = octEncodeVec3(worldNormal, 0, "floor", "ceil"); + dec = octDecodeVec2(oct); + currentCos = dot$1(worldNormal, 0, dec); + if (currentCos > bestCos) { + best = oct; + bestCos = currentCos; + } + oct = octEncodeVec3(worldNormal, 0, "ceil", "ceil"); + dec = octDecodeVec2(oct); + currentCos = dot$1(worldNormal, 0, dec); + if (currentCos > bestCos) { + best = oct; + bestCos = currentCos; + } + compressedNormals[lenCompressedNormals + i + 0] = best[0]; + compressedNormals[lenCompressedNormals + i + 1] = best[1]; + compressedNormals[lenCompressedNormals + i + 2] = 0.0; // Unused + } + lenCompressedNormals += lenNormals; + return lenCompressedNormals; +} + +function octEncodeNormals(normals, lenNormals, compressedNormals, lenCompressedNormals) { // http://jcgt.org/published/0003/02/01/ + let oct, dec, best, currentCos, bestCos; + for (let i = 0; i < lenNormals; i += 3) { + // Test various combinations of ceil and floor to minimize rounding errors + best = oct = octEncodeVec3(normals, i, "floor", "floor"); + dec = octDecodeVec2(oct); + currentCos = bestCos = dot$1(normals, i, dec); + oct = octEncodeVec3(normals, i, "ceil", "floor"); + dec = octDecodeVec2(oct); + currentCos = dot$1(normals, i, dec); + if (currentCos > bestCos) { + best = oct; + bestCos = currentCos; + } + oct = octEncodeVec3(normals, i, "floor", "ceil"); + dec = octDecodeVec2(oct); + currentCos = dot$1(normals, i, dec); + if (currentCos > bestCos) { + best = oct; + bestCos = currentCos; + } + oct = octEncodeVec3(normals, i, "ceil", "ceil"); + dec = octDecodeVec2(oct); + currentCos = dot$1(normals, i, dec); + if (currentCos > bestCos) { + best = oct; + bestCos = currentCos; + } + compressedNormals[lenCompressedNormals + i + 0] = best[0]; + compressedNormals[lenCompressedNormals + i + 1] = best[1]; + compressedNormals[lenCompressedNormals + i + 2] = 0.0; // Unused + } + lenCompressedNormals += lenNormals; + return lenCompressedNormals; +} + +/** + * @private + */ +function octEncodeVec3(array, i, xfunc, yfunc) { // Oct-encode single normal vector in 2 bytes + let x = array[i] / (Math.abs(array[i]) + Math.abs(array[i + 1]) + Math.abs(array[i + 2])); + let y = array[i + 1] / (Math.abs(array[i]) + Math.abs(array[i + 1]) + Math.abs(array[i + 2])); + if (array[i + 2] < 0) { + let tempx = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1); + let tempy = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1); + x = tempx; + y = tempy; + } + return new Int8Array([ + Math[xfunc](x * 127.5 + (x < 0 ? -1 : 0)), + Math[yfunc](y * 127.5 + (y < 0 ? -1 : 0)) + ]); +} + +/** + * Decode an oct-encoded normal + */ +function octDecodeVec2(oct) { + let x = oct[0]; + let y = oct[1]; + x /= x < 0 ? 127 : 128; + y /= y < 0 ? 127 : 128; + const z = 1 - Math.abs(x) - Math.abs(y); + if (z < 0) { + x = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1); + y = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1); + } + const length = Math.sqrt(x * x + y * y + z * z); + return [ + x / length, + y / length, + z / length + ]; +} + +/** + * Dot product of a normal in an array against a candidate decoding + * @private + */ +function dot$1(array, i, vec3) { + return array[i] * vec3[0] + array[i + 1] * vec3[1] + array[i + 2] * vec3[2]; +} + +/** + * @private + */ +const geometryCompression = { + quantizePositions, + compressPosition, + createPositionsDecodeMatrix, + transformAndOctEncodeNormals, + octEncodeNormals, +}; + +/** + * @private + */ +const buildEdgeIndices = (function () { + + const uniquePositions = []; + const indicesLookup = []; + const indicesReverseLookup = []; + const weldedIndices = []; + +// TODO: Optimize with caching, but need to cater to both compressed and uncompressed positions + + const faces = []; + let numFaces = 0; + const compa = new Uint16Array(3); + const compb = new Uint16Array(3); + const compc = new Uint16Array(3); + const a = math.vec3(); + const b = math.vec3(); + const c = math.vec3(); + const cb = math.vec3(); + const ab = math.vec3(); + const cross = math.vec3(); + const normal = math.vec3(); + const inverseNormal = math.vec3(); + + function weldVertices(positions, indices) { + const positionsMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique) + let vx; + let vy; + let vz; + let key; + const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001 + const precision = Math.pow(10, precisionPoints); + let i; + let len; + let lenUniquePositions = 0; + for (i = 0, len = positions.length; i < len; i += 3) { + vx = positions[i]; + vy = positions[i + 1]; + vz = positions[i + 2]; + key = Math.round(vx * precision) + '_' + Math.round(vy * precision) + '_' + Math.round(vz * precision); + if (positionsMap[key] === undefined) { + positionsMap[key] = lenUniquePositions / 3; + uniquePositions[lenUniquePositions++] = vx; + uniquePositions[lenUniquePositions++] = vy; + uniquePositions[lenUniquePositions++] = vz; + } + indicesLookup[i / 3] = positionsMap[key]; + } + for (i = 0, len = indices.length; i < len; i++) { + weldedIndices[i] = indicesLookup[indices[i]]; + indicesReverseLookup[weldedIndices[i]] = indices[i]; + } + } + + function buildFaces(numIndices, positionsDecodeMatrix) { + numFaces = 0; + for (let i = 0, len = numIndices; i < len; i += 3) { + const ia = ((weldedIndices[i]) * 3); + const ib = ((weldedIndices[i + 1]) * 3); + const ic = ((weldedIndices[i + 2]) * 3); + if (positionsDecodeMatrix) { + compa[0] = uniquePositions[ia]; + compa[1] = uniquePositions[ia + 1]; + compa[2] = uniquePositions[ia + 2]; + compb[0] = uniquePositions[ib]; + compb[1] = uniquePositions[ib + 1]; + compb[2] = uniquePositions[ib + 2]; + compc[0] = uniquePositions[ic]; + compc[1] = uniquePositions[ic + 1]; + compc[2] = uniquePositions[ic + 2]; + // Decode + math.decompressPosition(compa, positionsDecodeMatrix, a); + math.decompressPosition(compb, positionsDecodeMatrix, b); + math.decompressPosition(compc, positionsDecodeMatrix, c); + } else { + a[0] = uniquePositions[ia]; + a[1] = uniquePositions[ia + 1]; + a[2] = uniquePositions[ia + 2]; + b[0] = uniquePositions[ib]; + b[1] = uniquePositions[ib + 1]; + b[2] = uniquePositions[ib + 2]; + c[0] = uniquePositions[ic]; + c[1] = uniquePositions[ic + 1]; + c[2] = uniquePositions[ic + 2]; + } + math.subVec3(c, b, cb); + math.subVec3(a, b, ab); + math.cross3Vec3(cb, ab, cross); + math.normalizeVec3(cross, normal); + const face = faces[numFaces] || (faces[numFaces] = {normal: math.vec3()}); + face.normal[0] = normal[0]; + face.normal[1] = normal[1]; + face.normal[2] = normal[2]; + numFaces++; + } + } + + return function (positions, indices, positionsDecodeMatrix, edgeThreshold) { + weldVertices(positions, indices); + buildFaces(indices.length, positionsDecodeMatrix); + const edgeIndices = []; + const thresholdDot = Math.cos(math.DEGTORAD * edgeThreshold); + const edges = {}; + let edge1; + let edge2; + let index1; + let index2; + let key; + let largeIndex = false; + let edge; + let normal1; + let normal2; + let dot; + let ia; + let ib; + for (let i = 0, len = indices.length; i < len; i += 3) { + const faceIndex = i / 3; + for (let j = 0; j < 3; j++) { + edge1 = weldedIndices[i + j]; + edge2 = weldedIndices[i + ((j + 1) % 3)]; + index1 = Math.min(edge1, edge2); + index2 = Math.max(edge1, edge2); + key = index1 + ',' + index2; + if (edges[key] === undefined) { + edges[key] = { + index1: index1, + index2: index2, + face1: faceIndex, + face2: undefined, + }; + } else { + edges[key].face2 = faceIndex; + } + } + } + for (key in edges) { + edge = edges[key]; + // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree. + if (edge.face2 !== undefined) { + normal1 = faces[edge.face1].normal; + normal2 = faces[edge.face2].normal; + inverseNormal[0] = -normal2[0]; + inverseNormal[1] = -normal2[1]; + inverseNormal[2] = -normal2[2]; + dot = Math.abs(math.dotVec3(normal1, normal2)); + const dot2 = Math.abs(math.dotVec3(normal1, inverseNormal)); + if (dot > thresholdDot && dot2 > thresholdDot) { + continue; + } + } + ia = indicesReverseLookup[edge.index1]; + ib = indicesReverseLookup[edge.index2]; + if (!largeIndex && ia > 65535 || ib > 65535) { + largeIndex = true; + } + edgeIndices.push(ia); + edgeIndices.push(ib); + } + return (largeIndex) ? new Uint32Array(edgeIndices) : new Uint16Array(edgeIndices); + }; +})(); + +/** + * Uses edge adjacency counts to identify if the given triangle mesh can be rendered with backface culling enabled. + * + * If all edges are connected to exactly two triangles, then the mesh will likely be a closed solid, and we can safely + * render it with backface culling enabled. + * + * Otherwise, the mesh is a surface, and we must render it with backface culling disabled. + * + * @private + */ +const isTriangleMeshSolid = (indices, positions, vertexIndexMapping, edges) => { + + function compareIndexPositions(a, b) + { + let posA, posB; + + for (let i = 0; i < 3; i++) { + posA = positions [a*3+i]; + posB = positions [b*3+i]; + + if (posA !== posB) { + return posB - posA; + } + } + + return 0; + } + // Group together indices corresponding to same position coordinates + let newIndices = indices.slice ().sort (compareIndexPositions); + + // Calculate the mapping: + // - from original index in indices array + // - to indices-for-unique-positions + let uniqueVertexIndex = null; + + for (let i = 0, len = newIndices.length; i < len; i++) { + if (i == 0 || 0 != compareIndexPositions ( + newIndices[i], + newIndices[i-1], + )) { + // different position + uniqueVertexIndex = newIndices [i]; + } + + vertexIndexMapping [ + newIndices[i] + ] = uniqueVertexIndex; + } + + // Generate the list of edges + for (let i = 0, len = indices.length; i < len; i += 3) { + + const a = vertexIndexMapping[indices[i]]; + const b = vertexIndexMapping[indices[i+1]]; + const c = vertexIndexMapping[indices[i+2]]; + + let a2 = a; + let b2 = b; + let c2 = c; + + if (a > b && a > c) { + if (b > c) { + a2 = a; + b2 = b; + c2 = c; + } else { + a2 = a; + b2 = c; + c2 = b; + } + } else if (b > a && b > c) { + if (a > c) { + a2 = b; + b2 = a; + c2 = c; + } else { + a2 = b; + b2 = c; + c2 = a; + } + } else if (c > a && c > b) { + if (a > b) { + a2 = c; + b2 = a; + c2 = b; + } else { + a2 = c; + b2 = b; + c2 = a; + } + } + + edges[i+0] = [ + a2, b2 + ]; + edges[i+1] = [ + b2, c2 + ]; + + if (a2 > c2) { + const temp = c2; + c2 = a2; + a2 = temp; + } + + edges[i+2] = [ + c2, a2 + ]; + } + + // Group semantically equivalent edgdes together + function compareEdges (e1, e2) { + let a, b; + + for (let i = 0; i < 2; i++) { + a = e1[i]; + b = e2[i]; + + if (b !== a) { + return b - a; + } + } + + return 0; + } + + edges = edges.slice(0, indices.length); + + edges.sort (compareEdges); + + // Make sure each edge is used exactly twice + let sameEdgeCount = 0; + + for (let i = 0; i < edges.length; i++) + { + if (i === 0 || 0 !== compareEdges ( + edges[i], edges[i-1] + )) { + // different edge + if (0 !== i && sameEdgeCount !== 2) + { + return false; + } + + sameEdgeCount = 1; + } + else + { + // same edge + sameEdgeCount++; + } + } + + if (edges.length > 0 && sameEdgeCount !== 2) + { + return false; + } + + // Each edge is used exactly twice, this is a + // watertight surface and hence a solid geometry. + return true; +}; + +/** + * Represents the usage of a {@link XKTGeometry} by an {@link XKTEntity}. + * + * * Created by {@link XKTModel#createEntity} + * * Stored in {@link XKTEntity#meshes} and {@link XKTModel#meshesList} + * * Has an {@link XKTGeometry}, and an optional {@link XKTTextureSet}, both of which it can share with other {@link XKTMesh}es + * * Has {@link XKTMesh#color}, {@link XKTMesh#opacity}, {@link XKTMesh#metallic} and {@link XKTMesh#roughness} PBR attributes + * @class XKTMesh + */ +class XKTMesh { + + /** + * @private + */ + constructor(cfg) { + + /** + * Unique ID of this XKTMesh in {@link XKTModel#meshes}. + * + * @type {Number} + */ + this.meshId = cfg.meshId; + + /** + * Index of this XKTMesh in {@link XKTModel#meshesList}; + * + * @type {Number} + */ + this.meshIndex = cfg.meshIndex; + + /** + * The 4x4 modeling transform matrix. + * + * Transform is relative to the center of the {@link XKTTile} that contains this XKTMesh's {@link XKTEntity}, + * which is given in {@link XKTMesh#entity}. + * + * When the ````XKTEntity```` shares its {@link XKTGeometry}s with other ````XKTEntity````s, this matrix is used + * to transform this XKTMesh's XKTGeometry into World-space. When this XKTMesh does not share its ````XKTGeometry````, + * then this matrix is ignored. + * + * @type {Number[]} + */ + this.matrix = cfg.matrix; + + /** + * The instanced {@link XKTGeometry}. + * + * @type {XKTGeometry} + */ + this.geometry = cfg.geometry; + + /** + * RGB color of this XKTMesh. + * + * @type {Float32Array} + */ + this.color = cfg.color || new Float32Array([1, 1, 1]); + + /** + * PBR metallness of this XKTMesh. + * + * @type {Number} + */ + this.metallic = (cfg.metallic !== null && cfg.metallic !== undefined) ? cfg.metallic : 0; + + /** + * PBR roughness of this XKTMesh. + * The {@link XKTTextureSet} that defines the appearance of this XKTMesh. + * + * @type {Number} + * @type {XKTTextureSet} + */ + this.roughness = (cfg.roughness !== null && cfg.roughness !== undefined) ? cfg.roughness : 1; + + /** + * Opacity of this XKTMesh. + * + * @type {Number} + */ + this.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? cfg.opacity : 1.0; + + /** + * The {@link XKTTextureSet} that defines the appearance of this XKTMesh. + * + * @type {XKTTextureSet} + */ + this.textureSet = cfg.textureSet; + + /** + * The owner {@link XKTEntity}. + * + * Set by {@link XKTModel#createEntity}. + * + * @type {XKTEntity} + */ + this.entity = null; // Set after instantiation, when the Entity is known + } +} + +/** + * An element of reusable geometry within an {@link XKTModel}. + * + * * Created by {@link XKTModel#createGeometry} + * * Stored in {@link XKTModel#geometries} and {@link XKTModel#geometriesList} + * * Referenced by {@link XKTMesh}s, which belong to {@link XKTEntity}s + * + * @class XKTGeometry + */ +class XKTGeometry { + + /** + * @private + * @param {*} cfg Configuration for the XKTGeometry. + * @param {Number} cfg.geometryId Unique ID of the geometry in {@link XKTModel#geometries}. + * @param {String} cfg.primitiveType Type of this geometry - "triangles", "points" or "lines" so far. + * @param {Number} cfg.geometryIndex Index of this XKTGeometry in {@link XKTModel#geometriesList}. + * @param {Float64Array} cfg.positions Non-quantized 3D vertex positions. + * @param {Float32Array} cfg.normals Non-compressed vertex normals. + * @param {Uint8Array} cfg.colorsCompressed Unsigned 8-bit integer RGBA vertex colors. + * @param {Float32Array} cfg.uvs Non-compressed vertex UV coordinates. + * @param {Uint32Array} cfg.indices Indices to organize the vertex positions and normals into triangles. + * @param {Uint32Array} cfg.edgeIndices Indices to organize the vertex positions into edges. + */ + constructor(cfg) { + + /** + * Unique ID of this XKTGeometry in {@link XKTModel#geometries}. + * + * @type {Number} + */ + this.geometryId = cfg.geometryId; + + /** + * The type of primitive - "triangles" | "points" | "lines". + * + * @type {String} + */ + this.primitiveType = cfg.primitiveType; + + /** + * Index of this XKTGeometry in {@link XKTModel#geometriesList}. + * + * @type {Number} + */ + this.geometryIndex = cfg.geometryIndex; + + /** + * The number of {@link XKTMesh}s that reference this XKTGeometry. + * + * @type {Number} + */ + this.numInstances = 0; + + /** + * Non-quantized 3D vertex positions. + * + * Defined for all primitive types. + * + * @type {Float64Array} + */ + this.positions = cfg.positions; + + /** + * Quantized vertex positions. + * + * Defined for all primitive types. + * + * This array is later created from {@link XKTGeometry#positions} by {@link XKTModel#finalize}. + * + * @type {Uint16Array} + */ + this.positionsQuantized = new Uint16Array(cfg.positions.length); + + /** + * Non-compressed 3D vertex normals. + * + * Defined only for triangle primitives. Can be null if we want xeokit to auto-generate them. Ignored for points and lines. + * + * @type {Float32Array} + */ + this.normals = cfg.normals; + + /** + * Compressed vertex normals. + * + * Defined only for triangle primitives. Ignored for points and lines. + * + * This array is later created from {@link XKTGeometry#normals} by {@link XKTModel#finalize}. + * + * Will be null if {@link XKTGeometry#normals} is also null. + * + * @type {Int8Array} + */ + this.normalsOctEncoded = null; + + /** + * Compressed RGBA vertex colors. + * + * Defined only for point primitives. Ignored for triangles and lines. + * + * @type {Uint8Array} + */ + this.colorsCompressed = cfg.colorsCompressed; + + /** + * Non-compressed vertex UVs. + * + * @type {Float32Array} + */ + this.uvs = cfg.uvs; + + /** + * Compressed vertex UVs. + * + * @type {Uint16Array} + */ + this.uvsCompressed = cfg.uvsCompressed; + + /** + * Indices that organize the vertex positions and normals as triangles. + * + * Defined only for triangle and lines primitives. Ignored for points. + * + * @type {Uint32Array} + */ + this.indices = cfg.indices; + + /** + * Indices that organize the vertex positions as edges. + * + * Defined only for triangle primitives. Ignored for points and lines. + * + * @type {Uint32Array} + */ + this.edgeIndices = cfg.edgeIndices; + + /** + * When {@link XKTGeometry#primitiveType} is "triangles", this is ````true```` when this geometry is a watertight mesh. + * + * Defined only for triangle primitives. Ignored for points and lines. + * + * Set by {@link XKTModel#finalize}. + * + * @type {boolean} + */ + this.solid = false; + } + + /** + * Convenience property that is ````true```` when {@link XKTGeometry#numInstances} is greater that one. + * @returns {boolean} + */ + get reused() { + return (this.numInstances > 1); + } +} + +/** + * An object within an {@link XKTModel}. + * + * * Created by {@link XKTModel#createEntity} + * * Stored in {@link XKTModel#entities} and {@link XKTModel#entitiesList} + * * Has one or more {@link XKTMesh}s, each having an {@link XKTGeometry} + * + * @class XKTEntity + */ +class XKTEntity { + + /** + * @private + * @param entityId + * @param meshes + */ + constructor(entityId, meshes) { + + /** + * Unique ID of this ````XKTEntity```` in {@link XKTModel#entities}. + * + * For a BIM model, this will be an IFC product ID. + * + * We can also use {@link XKTModel#createMetaObject} to create an {@link XKTMetaObject} to specify metadata for + * this ````XKTEntity````. To associate the {@link XKTMetaObject} with our {@link XKTEntity}, we give + * {@link XKTMetaObject#metaObjectId} the same value as {@link XKTEntity#entityId}. + * + * @type {String} + */ + this.entityId = entityId; + + /** + * Index of this ````XKTEntity```` in {@link XKTModel#entitiesList}. + * + * Set by {@link XKTModel#finalize}. + * + * @type {Number} + */ + this.entityIndex = null; + + /** + * A list of {@link XKTMesh}s that indicate which {@link XKTGeometry}s are used by this Entity. + * + * @type {XKTMesh[]} + */ + this.meshes = meshes; + + /** + * World-space axis-aligned bounding box (AABB) that encloses the {@link XKTGeometry#positions} of + * the {@link XKTGeometry}s that are used by this ````XKTEntity````. + * + * Set by {@link XKTModel#finalize}. + * + * @type {Float32Array} + */ + this.aabb = math.AABB3(); + + /** + * Indicates if this ````XKTEntity```` shares {@link XKTGeometry}s with other {@link XKTEntity}'s. + * + * Set by {@link XKTModel#finalize}. + * + * Note that when an ````XKTEntity```` shares ````XKTGeometrys````, it shares **all** of its ````XKTGeometrys````. An ````XKTEntity```` + * never shares only some of its ````XKTGeometrys```` - it always shares either the whole set or none at all. + * + * @type {Boolean} + */ + this.hasReusedGeometries = false; + } +} + +/** + * @desc A box-shaped 3D region within an {@link XKTModel} that contains {@link XKTEntity}s. + * + * * Created by {@link XKTModel#finalize} + * * Stored in {@link XKTModel#tilesList} + * + * @class XKTTile + */ +class XKTTile { + + /** + * Creates a new XKTTile. + * + * @private + * @param aabb + * @param entities + */ + constructor(aabb, entities) { + + /** + * Axis-aligned World-space bounding box that encloses the {@link XKTEntity}'s within this Tile. + * + * @type {Float64Array} + */ + this.aabb = aabb; + + /** + * The {@link XKTEntity}'s within this XKTTile. + * + * @type {XKTEntity[]} + */ + this.entities = entities; + } +} + +/** + * A kd-Tree node, used internally by {@link XKTModel}. + * + * @private + */ +class KDNode { + + /** + * Create a KDNode with an axis-aligned 3D World-space boundary. + */ + constructor(aabb) { + + /** + * The axis-aligned 3D World-space boundary of this KDNode. + * + * @type {Float64Array} + */ + this.aabb = aabb; + + /** + * The {@link XKTEntity}s within this KDNode. + */ + this.entities = null; + + /** + * The left child KDNode. + */ + this.left = null; + + /** + * The right child KDNode. + */ + this.right = null; + } +} + +/** + * A meta object within an {@link XKTModel}. + * + * These are plugged together into a parent-child hierarchy to represent structural + * metadata for the {@link XKTModel}. + * + * The leaf XKTMetaObjects are usually associated with + * an {@link XKTEntity}, which they do so by sharing the same ID, + * ie. where {@link XKTMetaObject#metaObjectId} == {@link XKTEntity#entityId}. + * + * * Created by {@link XKTModel#createMetaObject} + * * Stored in {@link XKTModel#metaObjects} and {@link XKTModel#metaObjectsList} + * * Has an ID, a type, and a human-readable name + * * May have a parent {@link XKTMetaObject} + * * When no children, is usually associated with an {@link XKTEntity} + * + * @class XKTMetaObject + */ +class XKTMetaObject { + + /** + * @private + * @param metaObjectId + * @param propertySetIds + * @param metaObjectType + * @param metaObjectName + * @param parentMetaObjectId + */ + constructor(metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId) { + + /** + * Unique ID of this ````XKTMetaObject```` in {@link XKTModel#metaObjects}. + * + * For a BIM model, this will be an IFC product ID. + * + * If this is a leaf XKTMetaObject, where it is not a parent to any other XKTMetaObject, + * then this will be equal to the ID of an {@link XKTEntity} in {@link XKTModel#entities}, + * ie. where {@link XKTMetaObject#metaObjectId} == {@link XKTEntity#entityId}. + * + * @type {String} + */ + this.metaObjectId = metaObjectId; + + /** + * Unique ID of one or more property sets that contains additional metadata about this + * {@link XKTMetaObject}. The property sets can be stored in an external system, or + * within the {@link XKTModel}, as {@link XKTPropertySet}s within {@link XKTModel#propertySets}. + * + * @type {String[]} + */ + this.propertySetIds = propertySetIds; + + /** + * Indicates the XKTMetaObject meta object type. + * + * This defaults to "default". + * + * @type {string} + */ + this.metaObjectType = metaObjectType; + + /** + * Indicates the XKTMetaObject meta object name. + * + * This defaults to {@link XKTMetaObject#metaObjectId}. + * + * @type {string} + */ + this.metaObjectName = metaObjectName; + + /** + * The parent XKTMetaObject, if any. + * + * Will be null if there is no parent. + * + * @type {String} + */ + this.parentMetaObjectId = parentMetaObjectId; + } +} + +/** + * A property set within an {@link XKTModel}. + * + * These are shared among {@link XKTMetaObject}s. + * + * * Created by {@link XKTModel#createPropertySet} + * * Stored in {@link XKTModel#propertySets} and {@link XKTModel#propertySetsList} + * * Has an ID, a type, and a human-readable name + * + * @class XKTPropertySet + */ +class XKTPropertySet { + + /** + * @private + */ + constructor(propertySetId, propertySetType, propertySetName, properties) { + + /** + * Unique ID of this ````XKTPropertySet```` in {@link XKTModel#propertySets}. + * + * @type {String} + */ + this.propertySetId = propertySetId; + + /** + * Indicates the ````XKTPropertySet````'s type. + * + * This defaults to "default". + * + * @type {string} + */ + this.propertySetType = propertySetType; + + /** + * Indicates the XKTPropertySet meta object name. + * + * This defaults to {@link XKTPropertySet#propertySetId}. + * + * @type {string} + */ + this.propertySetName = propertySetName; + + /** + * The properties within this ````XKTPropertySet````. + * + * @type {*[]} + */ + this.properties = properties; + } +} + +/** + * Given geometry defined as an array of positions, optional normals, option uv and an array of indices, returns + * modified arrays that have duplicate vertices removed. + * + * @private + */ +function mergeVertices(positions, indices, mergedPositions, mergedIndices) { + const positionsMap = {}; + const indicesLookup = []; + const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001 + const precision = 10 ** precisionPoints; + for (let i = 0, len = positions.length; i < len; i += 3) { + const vx = positions[i]; + const vy = positions[i + 1]; + const vz = positions[i + 2]; + const key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`; + if (positionsMap[key] === undefined) { + positionsMap[key] = mergedPositions.length / 3; + mergedPositions.push(vx); + mergedPositions.push(vy); + mergedPositions.push(vz); + } + indicesLookup[i / 3] = positionsMap[key]; + } + for (let i = 0, len = indices.length; i < len; i++) { + mergedIndices[i] = indicesLookup[indices[i]]; + } +} + +/** + * @desc Provides info on the XKT generated by xeokit-convert. + */ +const XKT_INFO = { + + /** + * The XKT version generated by xeokit-convert. + * + * This is the XKT version that's modeled by {@link XKTModel}, serialized + * by {@link writeXKTModelToArrayBuffer}, and written by {@link convert2xkt}. + * + * * Current XKT version: **10** + * * [XKT format specs](https://github.com/xeokit/xeokit-convert/blob/main/specs/index.md) + * + * @property xktVersion + * @type {number} + */ + xktVersion: 10 +}; + +/*---------------------------------------------------------------------------------------------------------------------- + * NOTE: The values of these constants must match those within xeokit-sdk + *--------------------------------------------------------------------------------------------------------------------*/ + +/** + * Texture wrapping mode in which the texture repeats to infinity. + */ +const RepeatWrapping = 1000; + +/** + * Texture wrapping mode in which the last pixel of the texture stretches to the edge of the mesh. + */ +const ClampToEdgeWrapping = 1001; + +/** + * Texture wrapping mode in which the texture repeats to infinity, mirroring on each repeat. + */ +const MirroredRepeatWrapping = 1002; + +/** + * Texture magnification and minification filter that returns the nearest texel to the given sample coordinates. + */ +const NearestFilter = 1003; + +/** + * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and returns the nearest texel to the given sample coordinates. + */ +const NearestMipMapNearestFilter = 1004; + +/** + * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured + * and returns the nearest texel to the center of the pixel at the given sample coordinates. + */ +const NearestMipMapLinearFilter = 1005; + +/** + * Texture magnification and minification filter that returns the weighted average of the four nearest texels to the given sample coordinates. + */ +const LinearFilter = 1006; + +/** + * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and + * returns the weighted average of the four nearest texels to the given sample coordinates. + */ +const LinearMipMapNearestFilter = 1007; + +/** + * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured, + * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the + * weighted average of those two values. + */ +const LinearMipMapLinearFilter = 1008; + +/** + * A texture shared by {@link XKTTextureSet}s. + * + * * Created by {@link XKTModel#createTexture} + * * Stored in {@link XKTTextureSet#textures}, {@link XKTModel#textures} and {@link XKTModel#texturesList} + * + * @class XKTTexture + */ + +class XKTTexture { + + /** + * @private + */ + constructor(cfg) { + + /** + * Unique ID of this XKTTexture in {@link XKTModel#textures}. + * + * @type {Number} + */ + this.textureId = cfg.textureId; + + /** + * Index of this XKTTexture in {@link XKTModel#texturesList}; + * + * @type {Number} + */ + this.textureIndex = cfg.textureIndex; + + /** + * Texture image data. + * + * @type {Buffer} + */ + this.imageData = cfg.imageData; + + /** + * Which material channel this texture is applied to, as determined by its {@link XKTTextureSet}s. + * + * @type {Number} + */ + this.channel = null; + + /** + * Width of this XKTTexture. + * + * @type {Number} + */ + this.width = cfg.width; + + /** + * Height of this XKTTexture. + * + * @type {Number} + */ + this.height = cfg.height; + + /** + * Texture file source. + * + * @type {String} + */ + this.src = cfg.src; + + /** + * Whether this XKTTexture is to be compressed. + * + * @type {Boolean} + */ + this.compressed = (!!cfg.compressed); + + /** + * Media type of this XKTTexture. + * + * Supported values are {@link GIFMediaType}, {@link PNGMediaType} and {@link JPEGMediaType}. + * + * Ignored for compressed textures. + * + * @type {Number} + */ + this.mediaType = cfg.mediaType; + + /** + * How the texture is sampled when a texel covers less than one pixel. Supported values + * are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, + * {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter} + * and {@link LinearMipMapLinearFilter}. + * + * Ignored for compressed textures. + * + * @type {Number} + */ + this.minFilter = cfg.minFilter || LinearMipMapNearestFilter; + + /** + * How the texture is sampled when a texel covers more than one pixel. Supported values + * are {@link LinearFilter} and {@link NearestFilter}. + * + * Ignored for compressed textures. + * + * @type {Number} + */ + this.magFilter = cfg.magFilter || LinearMipMapNearestFilter; + + /** + * S wrapping mode. + * + * Supported values are {@link ClampToEdgeWrapping}, + * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. + * + * Ignored for compressed textures. + * + * @type {Number} + */ + this.wrapS = cfg.wrapS || RepeatWrapping; + + /** + * T wrapping mode. + * + * Supported values are {@link ClampToEdgeWrapping}, + * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. + * + * Ignored for compressed textures. + * + * @type {Number} + */ + this.wrapT = cfg.wrapT || RepeatWrapping; + + /** + * R wrapping mode. + * + * Ignored for compressed textures. + * + * Supported values are {@link ClampToEdgeWrapping}, + * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. + * + * @type {*|number} + */ + this.wrapR = cfg.wrapR || RepeatWrapping; + } +} + +/** + * A set of textures shared by {@link XKTMesh}es. + * + * * Created by {@link XKTModel#createTextureSet} + * * Registered in {@link XKTMesh#material}, {@link XKTModel#materials} and {@link XKTModel#.textureSetsList} + * + * @class XKTMetalRoughMaterial + */ +class XKTTextureSet { + + /** + * @private + */ + constructor(cfg) { + + /** + * Unique ID of this XKTTextureSet in {@link XKTModel#materials}. + * + * @type {Number} + */ + this.textureSetId = cfg.textureSetId; + + /** + * Index of this XKTTexture in {@link XKTModel#texturesList}; + * + * @type {Number} + */ + this.textureSetIndex = cfg.textureSetIndex; + + /** + * Identifies the material type. + * + * @type {Number} + */ + this.materialType = cfg.materialType; + + /** + * Index of this XKTTextureSet in {@link XKTModel#meshesList}; + * + * @type {Number} + */ + this.materialIndex = cfg.materialIndex; + + /** + * The number of {@link XKTMesh}s that reference this XKTTextureSet. + * + * @type {Number} + */ + this.numInstances = 0; + + /** + * RGBA {@link XKTTexture} containing base color in RGB and opacity in A. + * + * @type {XKTTexture} + */ + this.colorTexture = cfg.colorTexture; + + /** + * RGBA {@link XKTTexture} containing metallic and roughness factors in R and G. + * + * @type {XKTTexture} + */ + this.metallicRoughnessTexture = cfg.metallicRoughnessTexture; + + /** + * RGBA {@link XKTTexture} with surface normals in RGB. + * + * @type {XKTTexture} + */ + this.normalsTexture = cfg.normalsTexture; + + /** + * RGBA {@link XKTTexture} with emissive color in RGB. + * + * @type {XKTTexture} + */ + this.emissiveTexture = cfg.emissiveTexture; + + /** + * RGBA {@link XKTTexture} with ambient occlusion factors in RGB. + * + * @type {XKTTexture} + */ + this.occlusionTexture = cfg.occlusionTexture; + } +} + +function assert$5(condition, message) { + if (!condition) { + throw new Error(message || 'loader assertion failed.'); + } +} + +const isBrowser$2 = Boolean(typeof process !== 'object' || String(process) !== '[object process]' || process.browser); +const matches$1 = typeof process !== 'undefined' && process.version && /v([0-9]*)/.exec(process.version); +matches$1 && parseFloat(matches$1[1]) || 0; + +const VERSION$8 = "3.4.14" ; + +function assert$4(condition, message) { + if (!condition) { + throw new Error(message || 'loaders.gl assertion failed.'); + } +} + +const globals = { + self: typeof self !== 'undefined' && self, + window: typeof window !== 'undefined' && window, + global: typeof global !== 'undefined' && global, + document: typeof document !== 'undefined' && document +}; +const global_ = globals.global || globals.self || globals.window || {}; +const isBrowser$1 = typeof process !== 'object' || String(process) !== '[object process]' || process.browser; +const isWorker = typeof importScripts === 'function'; +const isMobile = typeof window !== 'undefined' && typeof window.orientation !== 'undefined'; +const matches = typeof process !== 'undefined' && process.version && /v([0-9]*)/.exec(process.version); +matches && parseFloat(matches[1]) || 0; + +function _typeof(obj) { + "@babel/helpers - typeof"; + + return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }, _typeof(obj); +} + +function _toPrimitive(input, hint) { + if (_typeof(input) !== "object" || input === null) return input; + var prim = input[Symbol.toPrimitive]; + if (prim !== undefined) { + var res = prim.call(input, hint || "default"); + if (_typeof(res) !== "object") return res; + throw new TypeError("@@toPrimitive must return a primitive value."); + } + return (hint === "string" ? String : Number)(input); +} + +function _toPropertyKey(arg) { + var key = _toPrimitive(arg, "string"); + return _typeof(key) === "symbol" ? key : String(key); +} + +function _defineProperty(obj, key, value) { + key = _toPropertyKey(key); + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; +} + +class WorkerJob { + constructor(jobName, workerThread) { + _defineProperty(this, "name", void 0); + _defineProperty(this, "workerThread", void 0); + _defineProperty(this, "isRunning", true); + _defineProperty(this, "result", void 0); + _defineProperty(this, "_resolve", () => {}); + _defineProperty(this, "_reject", () => {}); + this.name = jobName; + this.workerThread = workerThread; + this.result = new Promise((resolve, reject) => { + this._resolve = resolve; + this._reject = reject; + }); + } + postMessage(type, payload) { + this.workerThread.postMessage({ + source: 'loaders.gl', + type, + payload + }); + } + done(value) { + assert$4(this.isRunning); + this.isRunning = false; + this._resolve(value); + } + error(error) { + assert$4(this.isRunning); + this.isRunning = false; + this._reject(error); + } +} + +class Worker$1 { + terminate() {} +} + +const workerURLCache = new Map(); +function getLoadableWorkerURL(props) { + assert$4(props.source && !props.url || !props.source && props.url); + let workerURL = workerURLCache.get(props.source || props.url); + if (!workerURL) { + if (props.url) { + workerURL = getLoadableWorkerURLFromURL(props.url); + workerURLCache.set(props.url, workerURL); + } + if (props.source) { + workerURL = getLoadableWorkerURLFromSource(props.source); + workerURLCache.set(props.source, workerURL); + } + } + assert$4(workerURL); + return workerURL; +} +function getLoadableWorkerURLFromURL(url) { + if (!url.startsWith('http')) { + return url; + } + const workerSource = buildScriptSource(url); + return getLoadableWorkerURLFromSource(workerSource); +} +function getLoadableWorkerURLFromSource(workerSource) { + const blob = new Blob([workerSource], { + type: 'application/javascript' + }); + return URL.createObjectURL(blob); +} +function buildScriptSource(workerUrl) { + return "try {\n importScripts('".concat(workerUrl, "');\n} catch (error) {\n console.error(error);\n throw error;\n}"); +} + +function getTransferList(object) { + let recursive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + let transfers = arguments.length > 2 ? arguments[2] : undefined; + const transfersSet = transfers || new Set(); + if (!object) ; else if (isTransferable(object)) { + transfersSet.add(object); + } else if (isTransferable(object.buffer)) { + transfersSet.add(object.buffer); + } else if (ArrayBuffer.isView(object)) ; else if (recursive && typeof object === 'object') { + for (const key in object) { + getTransferList(object[key], recursive, transfersSet); + } + } + return transfers === undefined ? Array.from(transfersSet) : []; +} +function isTransferable(object) { + if (!object) { + return false; + } + if (object instanceof ArrayBuffer) { + return true; + } + if (typeof MessagePort !== 'undefined' && object instanceof MessagePort) { + return true; + } + if (typeof ImageBitmap !== 'undefined' && object instanceof ImageBitmap) { + return true; + } + if (typeof OffscreenCanvas !== 'undefined' && object instanceof OffscreenCanvas) { + return true; + } + return false; +} +function getTransferListForWriter(object) { + if (object === null) { + return {}; + } + const clone = Object.assign({}, object); + Object.keys(clone).forEach(key => { + if (typeof object[key] === 'object' && !ArrayBuffer.isView(object[key]) && !(object[key] instanceof Array)) { + clone[key] = getTransferListForWriter(object[key]); + } else if (typeof clone[key] === 'function' || clone[key] instanceof RegExp) { + clone[key] = {}; + } else { + clone[key] = object[key]; + } + }); + return clone; +} + +const NOOP = () => {}; +class WorkerThread { + static isSupported() { + return typeof Worker !== 'undefined' && isBrowser$1 || typeof Worker$1 !== 'undefined' && !isBrowser$1; + } + constructor(props) { + _defineProperty(this, "name", void 0); + _defineProperty(this, "source", void 0); + _defineProperty(this, "url", void 0); + _defineProperty(this, "terminated", false); + _defineProperty(this, "worker", void 0); + _defineProperty(this, "onMessage", void 0); + _defineProperty(this, "onError", void 0); + _defineProperty(this, "_loadableURL", ''); + const { + name, + source, + url + } = props; + assert$4(source || url); + this.name = name; + this.source = source; + this.url = url; + this.onMessage = NOOP; + this.onError = error => console.log(error); + this.worker = isBrowser$1 ? this._createBrowserWorker() : this._createNodeWorker(); + } + destroy() { + this.onMessage = NOOP; + this.onError = NOOP; + this.worker.terminate(); + this.terminated = true; + } + get isRunning() { + return Boolean(this.onMessage); + } + postMessage(data, transferList) { + transferList = transferList || getTransferList(data); + this.worker.postMessage(data, transferList); + } + _getErrorFromErrorEvent(event) { + let message = 'Failed to load '; + message += "worker ".concat(this.name, " from ").concat(this.url, ". "); + if (event.message) { + message += "".concat(event.message, " in "); + } + if (event.lineno) { + message += ":".concat(event.lineno, ":").concat(event.colno); + } + return new Error(message); + } + _createBrowserWorker() { + this._loadableURL = getLoadableWorkerURL({ + source: this.source, + url: this.url + }); + const worker = new Worker(this._loadableURL, { + name: this.name + }); + worker.onmessage = event => { + if (!event.data) { + this.onError(new Error('No data received')); + } else { + this.onMessage(event.data); + } + }; + worker.onerror = error => { + this.onError(this._getErrorFromErrorEvent(error)); + this.terminated = true; + }; + worker.onmessageerror = event => console.error(event); + return worker; + } + _createNodeWorker() { + let worker; + if (this.url) { + const absolute = this.url.includes(':/') || this.url.startsWith('/'); + const url = absolute ? this.url : "./".concat(this.url); + worker = new Worker$1(url, { + eval: false + }); + } else if (this.source) { + worker = new Worker$1(this.source, { + eval: true + }); + } else { + throw new Error('no worker'); + } + worker.on('message', data => { + this.onMessage(data); + }); + worker.on('error', error => { + this.onError(error); + }); + worker.on('exit', code => {}); + return worker; + } +} + +class WorkerPool { + static isSupported() { + return WorkerThread.isSupported(); + } + constructor(props) { + _defineProperty(this, "name", 'unnamed'); + _defineProperty(this, "source", void 0); + _defineProperty(this, "url", void 0); + _defineProperty(this, "maxConcurrency", 1); + _defineProperty(this, "maxMobileConcurrency", 1); + _defineProperty(this, "onDebug", () => {}); + _defineProperty(this, "reuseWorkers", true); + _defineProperty(this, "props", {}); + _defineProperty(this, "jobQueue", []); + _defineProperty(this, "idleQueue", []); + _defineProperty(this, "count", 0); + _defineProperty(this, "isDestroyed", false); + this.source = props.source; + this.url = props.url; + this.setProps(props); + } + destroy() { + this.idleQueue.forEach(worker => worker.destroy()); + this.isDestroyed = true; + } + setProps(props) { + this.props = { + ...this.props, + ...props + }; + if (props.name !== undefined) { + this.name = props.name; + } + if (props.maxConcurrency !== undefined) { + this.maxConcurrency = props.maxConcurrency; + } + if (props.maxMobileConcurrency !== undefined) { + this.maxMobileConcurrency = props.maxMobileConcurrency; + } + if (props.reuseWorkers !== undefined) { + this.reuseWorkers = props.reuseWorkers; + } + if (props.onDebug !== undefined) { + this.onDebug = props.onDebug; + } + } + async startJob(name) { + let onMessage = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (job, type, data) => job.done(data); + let onError = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : (job, error) => job.error(error); + const startPromise = new Promise(onStart => { + this.jobQueue.push({ + name, + onMessage, + onError, + onStart + }); + return this; + }); + this._startQueuedJob(); + return await startPromise; + } + async _startQueuedJob() { + if (!this.jobQueue.length) { + return; + } + const workerThread = this._getAvailableWorker(); + if (!workerThread) { + return; + } + const queuedJob = this.jobQueue.shift(); + if (queuedJob) { + this.onDebug({ + message: 'Starting job', + name: queuedJob.name, + workerThread, + backlog: this.jobQueue.length + }); + const job = new WorkerJob(queuedJob.name, workerThread); + workerThread.onMessage = data => queuedJob.onMessage(job, data.type, data.payload); + workerThread.onError = error => queuedJob.onError(job, error); + queuedJob.onStart(job); + try { + await job.result; + } finally { + this.returnWorkerToQueue(workerThread); + } + } + } + returnWorkerToQueue(worker) { + const shouldDestroyWorker = this.isDestroyed || !this.reuseWorkers || this.count > this._getMaxConcurrency(); + if (shouldDestroyWorker) { + worker.destroy(); + this.count--; + } else { + this.idleQueue.push(worker); + } + if (!this.isDestroyed) { + this._startQueuedJob(); + } + } + _getAvailableWorker() { + if (this.idleQueue.length > 0) { + return this.idleQueue.shift() || null; + } + if (this.count < this._getMaxConcurrency()) { + this.count++; + const name = "".concat(this.name.toLowerCase(), " (#").concat(this.count, " of ").concat(this.maxConcurrency, ")"); + return new WorkerThread({ + name, + source: this.source, + url: this.url + }); + } + return null; + } + _getMaxConcurrency() { + return isMobile ? this.maxMobileConcurrency : this.maxConcurrency; + } +} + +const DEFAULT_PROPS = { + maxConcurrency: 3, + maxMobileConcurrency: 1, + reuseWorkers: true, + onDebug: () => {} +}; +class WorkerFarm { + static isSupported() { + return WorkerThread.isSupported(); + } + static getWorkerFarm() { + let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + WorkerFarm._workerFarm = WorkerFarm._workerFarm || new WorkerFarm({}); + WorkerFarm._workerFarm.setProps(props); + return WorkerFarm._workerFarm; + } + constructor(props) { + _defineProperty(this, "props", void 0); + _defineProperty(this, "workerPools", new Map()); + this.props = { + ...DEFAULT_PROPS + }; + this.setProps(props); + this.workerPools = new Map(); + } + destroy() { + for (const workerPool of this.workerPools.values()) { + workerPool.destroy(); + } + this.workerPools = new Map(); + } + setProps(props) { + this.props = { + ...this.props, + ...props + }; + for (const workerPool of this.workerPools.values()) { + workerPool.setProps(this._getWorkerPoolProps()); + } + } + getWorkerPool(options) { + const { + name, + source, + url + } = options; + let workerPool = this.workerPools.get(name); + if (!workerPool) { + workerPool = new WorkerPool({ + name, + source, + url + }); + workerPool.setProps(this._getWorkerPoolProps()); + this.workerPools.set(name, workerPool); + } + return workerPool; + } + _getWorkerPoolProps() { + return { + maxConcurrency: this.props.maxConcurrency, + maxMobileConcurrency: this.props.maxMobileConcurrency, + reuseWorkers: this.props.reuseWorkers, + onDebug: this.props.onDebug + }; + } +} +_defineProperty(WorkerFarm, "_workerFarm", void 0); + +const NPM_TAG = 'latest'; +const VERSION$7 = "3.4.14" ; +function getWorkerName(worker) { + const warning = worker.version !== VERSION$7 ? " (worker-utils@".concat(VERSION$7, ")") : ''; + return "".concat(worker.name, "@").concat(worker.version).concat(warning); +} +function getWorkerURL(worker) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const workerOptions = options[worker.id] || {}; + const workerFile = "".concat(worker.id, "-worker.js"); + let url = workerOptions.workerUrl; + if (!url && worker.id === 'compression') { + url = options.workerUrl; + } + if (options._workerType === 'test') { + url = "modules/".concat(worker.module, "/dist/").concat(workerFile); + } + if (!url) { + let version = worker.version; + if (version === 'latest') { + version = NPM_TAG; + } + const versionTag = version ? "@".concat(version) : ''; + url = "https://unpkg.com/@loaders.gl/".concat(worker.module).concat(versionTag, "/dist/").concat(workerFile); + } + assert$4(url); + return url; +} + +async function processOnWorker(worker, data) { + let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + let context = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + const name = getWorkerName(worker); + const workerFarm = WorkerFarm.getWorkerFarm(options); + const { + source + } = options; + const workerPoolProps = { + name, + source + }; + if (!source) { + workerPoolProps.url = getWorkerURL(worker, options); + } + const workerPool = workerFarm.getWorkerPool(workerPoolProps); + const jobName = options.jobName || worker.name; + const job = await workerPool.startJob(jobName, onMessage$1.bind(null, context)); + const transferableOptions = getTransferListForWriter(options); + job.postMessage('process', { + input: data, + options: transferableOptions + }); + const result = await job.result; + return result.result; +} +async function onMessage$1(context, job, type, payload) { + switch (type) { + case 'done': + job.done(payload); + break; + case 'error': + job.error(new Error(payload.error)); + break; + case 'process': + const { + id, + input, + options + } = payload; + try { + if (!context.process) { + job.postMessage('error', { + id, + error: 'Worker not set up to process on main thread' + }); + return; + } + const result = await context.process(input, options); + job.postMessage('done', { + id, + result + }); + } catch (error) { + const message = error instanceof Error ? error.message : 'unknown error'; + job.postMessage('error', { + id, + error: message + }); + } + break; + default: + console.warn("process-on-worker: unknown message ".concat(type)); + } +} + +function validateWorkerVersion(worker) { + let coreVersion = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : VERSION$8; + assert$4(worker, 'no worker provided'); + const workerVersion = worker.version; + if (!coreVersion || !workerVersion) { + return false; + } + return true; +} + +const readFileAsArrayBuffer = null; +const readFileAsText = null; +const requireFromFile = null; +const requireFromString = null; + +var node = /*#__PURE__*/Object.freeze({ + __proto__: null, + readFileAsArrayBuffer: readFileAsArrayBuffer, + readFileAsText: readFileAsText, + requireFromFile: requireFromFile, + requireFromString: requireFromString +}); + +const VERSION$6 = "3.4.14" ; +const loadLibraryPromises = {}; +async function loadLibrary(libraryUrl) { + let moduleName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + if (moduleName) { + libraryUrl = getLibraryUrl(libraryUrl, moduleName, options); + } + loadLibraryPromises[libraryUrl] = loadLibraryPromises[libraryUrl] || loadLibraryFromFile(libraryUrl); + return await loadLibraryPromises[libraryUrl]; +} +function getLibraryUrl(library, moduleName, options) { + if (library.startsWith('http')) { + return library; + } + const modules = options.modules || {}; + if (modules[library]) { + return modules[library]; + } + if (!isBrowser$1) { + return "modules/".concat(moduleName, "/dist/libs/").concat(library); + } + if (options.CDN) { + assert$4(options.CDN.startsWith('http')); + return "".concat(options.CDN, "/").concat(moduleName, "@").concat(VERSION$6, "/dist/libs/").concat(library); + } + if (isWorker) { + return "../src/libs/".concat(library); + } + return "modules/".concat(moduleName, "/src/libs/").concat(library); +} +async function loadLibraryFromFile(libraryUrl) { + if (libraryUrl.endsWith('wasm')) { + const response = await fetch(libraryUrl); + return await response.arrayBuffer(); + } + if (!isBrowser$1) { + try { + return node && requireFromFile && (await requireFromFile(libraryUrl)); + } catch { + return null; + } + } + if (isWorker) { + return importScripts(libraryUrl); + } + const response = await fetch(libraryUrl); + const scriptSource = await response.text(); + return loadLibraryFromString(scriptSource, libraryUrl); +} +function loadLibraryFromString(scriptSource, id) { + if (!isBrowser$1) { + return requireFromString ; + } + if (isWorker) { + eval.call(global_, scriptSource); + return null; + } + const script = document.createElement('script'); + script.id = id; + try { + script.appendChild(document.createTextNode(scriptSource)); + } catch (e) { + script.text = scriptSource; + } + document.body.appendChild(script); + return null; +} + +function canParseWithWorker(loader, options) { + if (!WorkerFarm.isSupported()) { + return false; + } + if (!isBrowser$1 && !(options !== null && options !== void 0 && options._nodeWorkers)) { + return false; + } + return loader.worker && (options === null || options === void 0 ? void 0 : options.worker); +} +async function parseWithWorker(loader, data, options, context, parseOnMainThread) { + const name = loader.id; + const url = getWorkerURL(loader, options); + const workerFarm = WorkerFarm.getWorkerFarm(options); + const workerPool = workerFarm.getWorkerPool({ + name, + url + }); + options = JSON.parse(JSON.stringify(options)); + context = JSON.parse(JSON.stringify(context || {})); + const job = await workerPool.startJob('process-on-worker', onMessage.bind(null, parseOnMainThread)); + job.postMessage('process', { + input: data, + options, + context + }); + const result = await job.result; + return await result.result; +} +async function onMessage(parseOnMainThread, job, type, payload) { + switch (type) { + case 'done': + job.done(payload); + break; + case 'error': + job.error(new Error(payload.error)); + break; + case 'process': + const { + id, + input, + options + } = payload; + try { + const result = await parseOnMainThread(input, options); + job.postMessage('done', { + id, + result + }); + } catch (error) { + const message = error instanceof Error ? error.message : 'unknown error'; + job.postMessage('error', { + id, + error: message + }); + } + break; + default: + console.warn("parse-with-worker unknown message ".concat(type)); + } +} + +function canEncodeWithWorker(writer, options) { + if (!WorkerFarm.isSupported()) { + return false; + } + if (!isBrowser$2 && !(options !== null && options !== void 0 && options._nodeWorkers)) { + return false; + } + return writer.worker && (options === null || options === void 0 ? void 0 : options.worker); +} + +function getFirstCharacters$1(data) { + let length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5; + if (typeof data === 'string') { + return data.slice(0, length); + } else if (ArrayBuffer.isView(data)) { + return getMagicString$2(data.buffer, data.byteOffset, length); + } else if (data instanceof ArrayBuffer) { + const byteOffset = 0; + return getMagicString$2(data, byteOffset, length); + } + return ''; +} +function getMagicString$2(arrayBuffer, byteOffset, length) { + if (arrayBuffer.byteLength <= byteOffset + length) { + return ''; + } + const dataView = new DataView(arrayBuffer); + let magic = ''; + for (let i = 0; i < length; i++) { + magic += String.fromCharCode(dataView.getUint8(byteOffset + i)); + } + return magic; +} + +function parseJSON(string) { + try { + return JSON.parse(string); + } catch (_) { + throw new Error("Failed to parse JSON from data starting with \"".concat(getFirstCharacters$1(string), "\"")); + } +} + +function compareArrayBuffers(arrayBuffer1, arrayBuffer2, byteLength) { + byteLength = byteLength || arrayBuffer1.byteLength; + if (arrayBuffer1.byteLength < byteLength || arrayBuffer2.byteLength < byteLength) { + return false; + } + const array1 = new Uint8Array(arrayBuffer1); + const array2 = new Uint8Array(arrayBuffer2); + for (let i = 0; i < array1.length; ++i) { + if (array1[i] !== array2[i]) { + return false; + } + } + return true; +} +function concatenateArrayBuffers() { + for (var _len = arguments.length, sources = new Array(_len), _key = 0; _key < _len; _key++) { + sources[_key] = arguments[_key]; + } + const sourceArrays = sources.map(source2 => source2 instanceof ArrayBuffer ? new Uint8Array(source2) : source2); + const byteLength = sourceArrays.reduce((length, typedArray) => length + typedArray.byteLength, 0); + const result = new Uint8Array(byteLength); + let offset = 0; + for (const sourceArray of sourceArrays) { + result.set(sourceArray, offset); + offset += sourceArray.byteLength; + } + return result.buffer; +} +function sliceArrayBuffer(arrayBuffer, byteOffset, byteLength) { + const subArray = byteLength !== undefined ? new Uint8Array(arrayBuffer).subarray(byteOffset, byteOffset + byteLength) : new Uint8Array(arrayBuffer).subarray(byteOffset); + const arrayCopy = new Uint8Array(subArray); + return arrayCopy.buffer; +} + +function padToNBytes(byteLength, padding) { + assert$5(byteLength >= 0); + assert$5(padding > 0); + return byteLength + (padding - 1) & ~(padding - 1); +} +function copyToArray(source, target, targetOffset) { + let sourceArray; + if (source instanceof ArrayBuffer) { + sourceArray = new Uint8Array(source); + } else { + const srcByteOffset = source.byteOffset; + const srcByteLength = source.byteLength; + sourceArray = new Uint8Array(source.buffer || source.arrayBuffer, srcByteOffset, srcByteLength); + } + target.set(sourceArray, targetOffset); + return targetOffset + padToNBytes(sourceArray.byteLength, 4); +} + +async function concatenateArrayBuffersAsync(asyncIterator) { + const arrayBuffers = []; + for await (const chunk of asyncIterator) { + arrayBuffers.push(chunk); + } + return concatenateArrayBuffers(...arrayBuffers); +} + +let pathPrefix = ''; +const fileAliases = {}; +function resolvePath(filename) { + for (const alias in fileAliases) { + if (filename.startsWith(alias)) { + const replacement = fileAliases[alias]; + filename = filename.replace(alias, replacement); + } + } + if (!filename.startsWith('http://') && !filename.startsWith('https://')) { + filename = "".concat(pathPrefix).concat(filename); + } + return filename; +} + +function toArrayBuffer$3(buffer) { + return buffer; +} +function toBuffer$1(binaryData) { + throw new Error('Buffer not supported in browser'); +} + +function isBuffer$1(value) { + return value && typeof value === 'object' && value.isBuffer; +} +function toBuffer(data) { + return toBuffer$1 ? toBuffer$1() : data; +} +function toArrayBuffer$2(data) { + if (isBuffer$1(data)) { + return toArrayBuffer$3(data); + } + if (data instanceof ArrayBuffer) { + return data; + } + if (ArrayBuffer.isView(data)) { + if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) { + return data.buffer; + } + return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength); + } + if (typeof data === 'string') { + const text = data; + const uint8Array = new TextEncoder().encode(text); + return uint8Array.buffer; + } + if (data && typeof data === 'object' && data._toArrayBuffer) { + return data._toArrayBuffer(); + } + throw new Error('toArrayBuffer'); +} + +function filename(url) { + const slashIndex = url ? url.lastIndexOf('/') : -1; + return slashIndex >= 0 ? url.substr(slashIndex + 1) : ''; +} +function dirname(url) { + const slashIndex = url ? url.lastIndexOf('/') : -1; + return slashIndex >= 0 ? url.substr(0, slashIndex) : ''; +} + +const writeFile$1 = null; + +const isBoolean = x => typeof x === 'boolean'; +const isFunction = x => typeof x === 'function'; +const isObject = x => x !== null && typeof x === 'object'; +const isPureObject = x => isObject(x) && x.constructor === {}.constructor; +const isIterable = x => x && typeof x[Symbol.iterator] === 'function'; +const isAsyncIterable = x => x && typeof x[Symbol.asyncIterator] === 'function'; +const isResponse = x => typeof Response !== 'undefined' && x instanceof Response || x && x.arrayBuffer && x.text && x.json; +const isBlob = x => typeof Blob !== 'undefined' && x instanceof Blob; +const isBuffer = x => x && typeof x === 'object' && x.isBuffer; +const isReadableDOMStream = x => typeof ReadableStream !== 'undefined' && x instanceof ReadableStream || isObject(x) && isFunction(x.tee) && isFunction(x.cancel) && isFunction(x.getReader); +const isReadableNodeStream = x => isObject(x) && isFunction(x.read) && isFunction(x.pipe) && isBoolean(x.readable); +const isReadableStream = x => isReadableDOMStream(x) || isReadableNodeStream(x); + +const DATA_URL_PATTERN = /^data:([-\w.]+\/[-\w.+]+)(;|,)/; +const MIME_TYPE_PATTERN = /^([-\w.]+\/[-\w.+]+)/; +function parseMIMEType(mimeString) { + const matches = MIME_TYPE_PATTERN.exec(mimeString); + if (matches) { + return matches[1]; + } + return mimeString; +} +function parseMIMETypeFromURL(url) { + const matches = DATA_URL_PATTERN.exec(url); + if (matches) { + return matches[1]; + } + return ''; +} + +const QUERY_STRING_PATTERN = /\?.*/; +function extractQueryString(url) { + const matches = url.match(QUERY_STRING_PATTERN); + return matches && matches[0]; +} +function stripQueryString(url) { + return url.replace(QUERY_STRING_PATTERN, ''); +} + +function getResourceUrl(resource) { + if (isResponse(resource)) { + const response = resource; + return response.url; + } + if (isBlob(resource)) { + const blob = resource; + return blob.name || ''; + } + if (typeof resource === 'string') { + return resource; + } + return ''; +} +function getResourceMIMEType(resource) { + if (isResponse(resource)) { + const response = resource; + const contentTypeHeader = response.headers.get('content-type') || ''; + const noQueryUrl = stripQueryString(response.url); + return parseMIMEType(contentTypeHeader) || parseMIMETypeFromURL(noQueryUrl); + } + if (isBlob(resource)) { + const blob = resource; + return blob.type || ''; + } + if (typeof resource === 'string') { + return parseMIMETypeFromURL(resource); + } + return ''; +} +function getResourceContentLength(resource) { + if (isResponse(resource)) { + const response = resource; + return response.headers['content-length'] || -1; + } + if (isBlob(resource)) { + const blob = resource; + return blob.size; + } + if (typeof resource === 'string') { + return resource.length; + } + if (resource instanceof ArrayBuffer) { + return resource.byteLength; + } + if (ArrayBuffer.isView(resource)) { + return resource.byteLength; + } + return -1; +} + +async function makeResponse(resource) { + if (isResponse(resource)) { + return resource; + } + const headers = {}; + const contentLength = getResourceContentLength(resource); + if (contentLength >= 0) { + headers['content-length'] = String(contentLength); + } + const url = getResourceUrl(resource); + const type = getResourceMIMEType(resource); + if (type) { + headers['content-type'] = type; + } + const initialDataUrl = await getInitialDataUrl(resource); + if (initialDataUrl) { + headers['x-first-bytes'] = initialDataUrl; + } + if (typeof resource === 'string') { + resource = new TextEncoder().encode(resource); + } + const response = new Response(resource, { + headers + }); + Object.defineProperty(response, 'url', { + value: url + }); + return response; +} +async function checkResponse(response) { + if (!response.ok) { + const message = await getResponseError(response); + throw new Error(message); + } +} +async function getResponseError(response) { + let message = "Failed to fetch resource ".concat(response.url, " (").concat(response.status, "): "); + try { + const contentType = response.headers.get('Content-Type'); + let text = response.statusText; + if (contentType.includes('application/json')) { + text += " ".concat(await response.text()); + } + message += text; + message = message.length > 60 ? "".concat(message.slice(0, 60), "...") : message; + } catch (error) {} + return message; +} +async function getInitialDataUrl(resource) { + const INITIAL_DATA_LENGTH = 5; + if (typeof resource === 'string') { + return "data:,".concat(resource.slice(0, INITIAL_DATA_LENGTH)); + } + if (resource instanceof Blob) { + const blobSlice = resource.slice(0, 5); + return await new Promise(resolve => { + const reader = new FileReader(); + reader.onload = event => { + var _event$target; + return resolve(event === null || event === void 0 ? void 0 : (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.result); + }; + reader.readAsDataURL(blobSlice); + }); + } + if (resource instanceof ArrayBuffer) { + const slice = resource.slice(0, INITIAL_DATA_LENGTH); + const base64 = arrayBufferToBase64(slice); + return "data:base64,".concat(base64); + } + return null; +} +function arrayBufferToBase64(buffer) { + let binary = ''; + const bytes = new Uint8Array(buffer); + for (let i = 0; i < bytes.byteLength; i++) { + binary += String.fromCharCode(bytes[i]); + } + return btoa(binary); +} + +async function fetchFile(url, options) { + if (typeof url === 'string') { + url = resolvePath(url); + let fetchOptions = options; + if (options !== null && options !== void 0 && options.fetch && typeof (options === null || options === void 0 ? void 0 : options.fetch) !== 'function') { + fetchOptions = options.fetch; + } + return await fetch(url, fetchOptions); + } + return await makeResponse(url); +} + +async function writeFile(filePath, arrayBufferOrString, options) { + filePath = resolvePath(filePath); + if (!isBrowser$2) { + await writeFile$1(filePath, toBuffer(arrayBufferOrString), { + flag: 'w' + }); + } + assert$5(false); +} + +function isElectron(mockUserAgent) { + if (typeof window !== 'undefined' && typeof window.process === 'object' && window.process.type === 'renderer') { + return true; + } + + if (typeof process !== 'undefined' && typeof process.versions === 'object' && Boolean(process.versions['electron'])) { + return true; + } + + const realUserAgent = typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent; + const userAgent = mockUserAgent || realUserAgent; + + if (userAgent && userAgent.indexOf('Electron') >= 0) { + return true; + } + + return false; +} + +function isBrowser() { + const isNode = typeof process === 'object' && String(process) === '[object process]' && !process.browser; + return !isNode || isElectron(); +} + +const window_ = globalThis.window || globalThis.self || globalThis.global; +const process_ = globalThis.process || {}; + +const VERSION$5 = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'untranspiled source'; +isBrowser(); + +function getStorage(type) { + try { + const storage = window[type]; + const x = '__storage_test__'; + storage.setItem(x, x); + storage.removeItem(x); + return storage; + } catch (e) { + return null; + } +} + +class LocalStorage { + constructor(id, defaultConfig) { + let type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'sessionStorage'; + this.storage = void 0; + this.id = void 0; + this.config = void 0; + this.storage = getStorage(type); + this.id = id; + this.config = defaultConfig; + + this._loadConfiguration(); + } + + getConfiguration() { + return this.config; + } + + setConfiguration(configuration) { + Object.assign(this.config, configuration); + + if (this.storage) { + const serialized = JSON.stringify(this.config); + this.storage.setItem(this.id, serialized); + } + } + + _loadConfiguration() { + let configuration = {}; + + if (this.storage) { + const serializedConfiguration = this.storage.getItem(this.id); + configuration = serializedConfiguration ? JSON.parse(serializedConfiguration) : {}; + } + + Object.assign(this.config, configuration); + return this; + } + +} + +function formatTime(ms) { + let formatted; + + if (ms < 10) { + formatted = "".concat(ms.toFixed(2), "ms"); + } else if (ms < 100) { + formatted = "".concat(ms.toFixed(1), "ms"); + } else if (ms < 1000) { + formatted = "".concat(ms.toFixed(0), "ms"); + } else { + formatted = "".concat((ms / 1000).toFixed(2), "s"); + } + + return formatted; +} +function leftPad(string) { + let length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 8; + const padLength = Math.max(length - string.length, 0); + return "".concat(' '.repeat(padLength)).concat(string); +} + +function formatImage(image, message, scale) { + let maxWidth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 600; + const imageUrl = image.src.replace(/\(/g, '%28').replace(/\)/g, '%29'); + + if (image.width > maxWidth) { + scale = Math.min(scale, maxWidth / image.width); + } + + const width = image.width * scale; + const height = image.height * scale; + const style = ['font-size:1px;', "padding:".concat(Math.floor(height / 2), "px ").concat(Math.floor(width / 2), "px;"), "line-height:".concat(height, "px;"), "background:url(".concat(imageUrl, ");"), "background-size:".concat(width, "px ").concat(height, "px;"), 'color:transparent;'].join(''); + return ["".concat(message, " %c+"), style]; +} + +let COLOR; + +(function (COLOR) { + COLOR[COLOR["BLACK"] = 30] = "BLACK"; + COLOR[COLOR["RED"] = 31] = "RED"; + COLOR[COLOR["GREEN"] = 32] = "GREEN"; + COLOR[COLOR["YELLOW"] = 33] = "YELLOW"; + COLOR[COLOR["BLUE"] = 34] = "BLUE"; + COLOR[COLOR["MAGENTA"] = 35] = "MAGENTA"; + COLOR[COLOR["CYAN"] = 36] = "CYAN"; + COLOR[COLOR["WHITE"] = 37] = "WHITE"; + COLOR[COLOR["BRIGHT_BLACK"] = 90] = "BRIGHT_BLACK"; + COLOR[COLOR["BRIGHT_RED"] = 91] = "BRIGHT_RED"; + COLOR[COLOR["BRIGHT_GREEN"] = 92] = "BRIGHT_GREEN"; + COLOR[COLOR["BRIGHT_YELLOW"] = 93] = "BRIGHT_YELLOW"; + COLOR[COLOR["BRIGHT_BLUE"] = 94] = "BRIGHT_BLUE"; + COLOR[COLOR["BRIGHT_MAGENTA"] = 95] = "BRIGHT_MAGENTA"; + COLOR[COLOR["BRIGHT_CYAN"] = 96] = "BRIGHT_CYAN"; + COLOR[COLOR["BRIGHT_WHITE"] = 97] = "BRIGHT_WHITE"; +})(COLOR || (COLOR = {})); + +const BACKGROUND_INCREMENT = 10; + +function getColor(color) { + if (typeof color !== 'string') { + return color; + } + + color = color.toUpperCase(); + return COLOR[color] || COLOR.WHITE; +} + +function addColor(string, color, background) { + if (!isBrowser && typeof string === 'string') { + if (color) { + const colorCode = getColor(color); + string = "\x1B[".concat(colorCode, "m").concat(string, "\x1B[39m"); + } + + if (background) { + const colorCode = getColor(background); + string = "\x1B[".concat(colorCode + BACKGROUND_INCREMENT, "m").concat(string, "\x1B[49m"); + } + } + + return string; +} + +function autobind(obj) { + let predefined = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['constructor']; + const proto = Object.getPrototypeOf(obj); + const propNames = Object.getOwnPropertyNames(proto); + const object = obj; + + for (const key of propNames) { + const value = object[key]; + + if (typeof value === 'function') { + if (!predefined.find(name => key === name)) { + object[key] = value.bind(obj); + } + } + } +} + +function assert$3(condition, message) { + if (!condition) { + throw new Error(message || 'Assertion failed'); + } +} + +function getHiResTimestamp() { + let timestamp; + + if (isBrowser() && window_.performance) { + var _window$performance, _window$performance$n; + + timestamp = window_ === null || window_ === void 0 ? void 0 : (_window$performance = window_.performance) === null || _window$performance === void 0 ? void 0 : (_window$performance$n = _window$performance.now) === null || _window$performance$n === void 0 ? void 0 : _window$performance$n.call(_window$performance); + } else if ('hrtime' in process_) { + var _process$hrtime; + + const timeParts = process_ === null || process_ === void 0 ? void 0 : (_process$hrtime = process_.hrtime) === null || _process$hrtime === void 0 ? void 0 : _process$hrtime.call(process_); + timestamp = timeParts[0] * 1000 + timeParts[1] / 1e6; + } else { + timestamp = Date.now(); + } + + return timestamp; +} + +const originalConsole = { + debug: isBrowser() ? console.debug || console.log : console.log, + log: console.log, + info: console.info, + warn: console.warn, + error: console.error +}; +const DEFAULT_LOG_CONFIGURATION = { + enabled: true, + level: 0 +}; + +function noop() {} + +const cache = {}; +const ONCE = { + once: true +}; +class Log { + constructor() { + let { + id + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { + id: '' + }; + this.id = void 0; + this.VERSION = VERSION$5; + this._startTs = getHiResTimestamp(); + this._deltaTs = getHiResTimestamp(); + this._storage = void 0; + this.userData = {}; + this.LOG_THROTTLE_TIMEOUT = 0; + this.id = id; + this.userData = {}; + this._storage = new LocalStorage("__probe-".concat(this.id, "__"), DEFAULT_LOG_CONFIGURATION); + this.timeStamp("".concat(this.id, " started")); + autobind(this); + Object.seal(this); + } + + set level(newLevel) { + this.setLevel(newLevel); + } + + get level() { + return this.getLevel(); + } + + isEnabled() { + return this._storage.config.enabled; + } + + getLevel() { + return this._storage.config.level; + } + + getTotal() { + return Number((getHiResTimestamp() - this._startTs).toPrecision(10)); + } + + getDelta() { + return Number((getHiResTimestamp() - this._deltaTs).toPrecision(10)); + } + + set priority(newPriority) { + this.level = newPriority; + } + + get priority() { + return this.level; + } + + getPriority() { + return this.level; + } + + enable() { + let enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + + this._storage.setConfiguration({ + enabled + }); + + return this; + } + + setLevel(level) { + this._storage.setConfiguration({ + level + }); + + return this; + } + + get(setting) { + return this._storage.config[setting]; + } + + set(setting, value) { + this._storage.setConfiguration({ + [setting]: value + }); + } + + settings() { + if (console.table) { + console.table(this._storage.config); + } else { + console.log(this._storage.config); + } + } + + assert(condition, message) { + assert$3(condition, message); + } + + warn(message) { + return this._getLogFunction(0, message, originalConsole.warn, arguments, ONCE); + } + + error(message) { + return this._getLogFunction(0, message, originalConsole.error, arguments); + } + + deprecated(oldUsage, newUsage) { + return this.warn("`".concat(oldUsage, "` is deprecated and will be removed in a later version. Use `").concat(newUsage, "` instead")); + } + + removed(oldUsage, newUsage) { + return this.error("`".concat(oldUsage, "` has been removed. Use `").concat(newUsage, "` instead")); + } + + probe(logLevel, message) { + return this._getLogFunction(logLevel, message, originalConsole.log, arguments, { + time: true, + once: true + }); + } + + log(logLevel, message) { + return this._getLogFunction(logLevel, message, originalConsole.debug, arguments); + } + + info(logLevel, message) { + return this._getLogFunction(logLevel, message, console.info, arguments); + } + + once(logLevel, message) { + return this._getLogFunction(logLevel, message, originalConsole.debug || originalConsole.info, arguments, ONCE); + } + + table(logLevel, table, columns) { + if (table) { + return this._getLogFunction(logLevel, table, console.table || noop, columns && [columns], { + tag: getTableHeader(table) + }); + } + + return noop; + } + + image(_ref) { + let { + logLevel, + priority, + image, + message = '', + scale = 1 + } = _ref; + + if (!this._shouldLog(logLevel || priority)) { + return noop; + } + + return isBrowser() ? logImageInBrowser({ + image, + message, + scale + }) : logImageInNode(); + } + + time(logLevel, message) { + return this._getLogFunction(logLevel, message, console.time ? console.time : console.info); + } + + timeEnd(logLevel, message) { + return this._getLogFunction(logLevel, message, console.timeEnd ? console.timeEnd : console.info); + } + + timeStamp(logLevel, message) { + return this._getLogFunction(logLevel, message, console.timeStamp || noop); + } + + group(logLevel, message) { + let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { + collapsed: false + }; + const options = normalizeArguments({ + logLevel, + message, + opts + }); + const { + collapsed + } = opts; + options.method = (collapsed ? console.groupCollapsed : console.group) || console.info; + return this._getLogFunction(options); + } + + groupCollapsed(logLevel, message) { + let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return this.group(logLevel, message, Object.assign({}, opts, { + collapsed: true + })); + } + + groupEnd(logLevel) { + return this._getLogFunction(logLevel, '', console.groupEnd || noop); + } + + withGroup(logLevel, message, func) { + this.group(logLevel, message)(); + + try { + func(); + } finally { + this.groupEnd(logLevel)(); + } + } + + trace() { + if (console.trace) { + console.trace(); + } + } + + _shouldLog(logLevel) { + return this.isEnabled() && this.getLevel() >= normalizeLogLevel(logLevel); + } + + _getLogFunction(logLevel, message, method, args, opts) { + if (this._shouldLog(logLevel)) { + opts = normalizeArguments({ + logLevel, + message, + args, + opts + }); + method = method || opts.method; + assert$3(method); + opts.total = this.getTotal(); + opts.delta = this.getDelta(); + this._deltaTs = getHiResTimestamp(); + const tag = opts.tag || opts.message; + + if (opts.once && tag) { + if (!cache[tag]) { + cache[tag] = getHiResTimestamp(); + } else { + return noop; + } + } + + message = decorateMessage(this.id, opts.message, opts); + return method.bind(console, message, ...opts.args); + } + + return noop; + } + +} +Log.VERSION = VERSION$5; + +function normalizeLogLevel(logLevel) { + if (!logLevel) { + return 0; + } + + let resolvedLevel; + + switch (typeof logLevel) { + case 'number': + resolvedLevel = logLevel; + break; + + case 'object': + resolvedLevel = logLevel.logLevel || logLevel.priority || 0; + break; + + default: + return 0; + } + + assert$3(Number.isFinite(resolvedLevel) && resolvedLevel >= 0); + return resolvedLevel; +} + +function normalizeArguments(opts) { + const { + logLevel, + message + } = opts; + opts.logLevel = normalizeLogLevel(logLevel); + const args = opts.args ? Array.from(opts.args) : []; + + while (args.length && args.shift() !== message) {} + + switch (typeof logLevel) { + case 'string': + case 'function': + if (message !== undefined) { + args.unshift(message); + } + + opts.message = logLevel; + break; + + case 'object': + Object.assign(opts, logLevel); + break; + } + + if (typeof opts.message === 'function') { + opts.message = opts.message(); + } + + const messageType = typeof opts.message; + assert$3(messageType === 'string' || messageType === 'object'); + return Object.assign(opts, { + args + }, opts.opts); +} + +function decorateMessage(id, message, opts) { + if (typeof message === 'string') { + const time = opts.time ? leftPad(formatTime(opts.total)) : ''; + message = opts.time ? "".concat(id, ": ").concat(time, " ").concat(message) : "".concat(id, ": ").concat(message); + message = addColor(message, opts.color, opts.background); + } + + return message; +} + +function logImageInNode(_ref2) { + console.warn('removed'); + return noop; +} + +function logImageInBrowser(_ref3) { + let { + image, + message = '', + scale = 1 + } = _ref3; + + if (typeof image === 'string') { + const img = new Image(); + + img.onload = () => { + const args = formatImage(img, message, scale); + console.log(...args); + }; + + img.src = image; + return noop; + } + + const element = image.nodeName || ''; + + if (element.toLowerCase() === 'img') { + console.log(...formatImage(image, message, scale)); + return noop; + } + + if (element.toLowerCase() === 'canvas') { + const img = new Image(); + + img.onload = () => console.log(...formatImage(img, message, scale)); + + img.src = image.toDataURL(); + return noop; + } + + return noop; +} + +function getTableHeader(table) { + for (const key in table) { + for (const title in table[key]) { + return title || 'untitled'; + } + } + + return 'empty'; +} + +const probeLog = new Log({ + id: 'loaders.gl' +}); +class NullLog { + log() { + return () => {}; + } + info() { + return () => {}; + } + warn() { + return () => {}; + } + error() { + return () => {}; + } +} +class ConsoleLog { + constructor() { + _defineProperty(this, "console", void 0); + this.console = console; + } + log() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + return this.console.log.bind(this.console, ...args); + } + info() { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + return this.console.info.bind(this.console, ...args); + } + warn() { + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + return this.console.warn.bind(this.console, ...args); + } + error() { + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + return this.console.error.bind(this.console, ...args); + } +} + +const DEFAULT_LOADER_OPTIONS = { + fetch: null, + mimeType: undefined, + nothrow: false, + log: new ConsoleLog(), + CDN: 'https://unpkg.com/@loaders.gl', + worker: true, + maxConcurrency: 3, + maxMobileConcurrency: 1, + reuseWorkers: isBrowser$2, + _nodeWorkers: false, + _workerType: '', + limit: 0, + _limitMB: 0, + batchSize: 'auto', + batchDebounceMs: 0, + metadata: false, + transforms: [] +}; +const REMOVED_LOADER_OPTIONS = { + throws: 'nothrow', + dataType: '(no longer used)', + uri: 'baseUri', + method: 'fetch.method', + headers: 'fetch.headers', + body: 'fetch.body', + mode: 'fetch.mode', + credentials: 'fetch.credentials', + cache: 'fetch.cache', + redirect: 'fetch.redirect', + referrer: 'fetch.referrer', + referrerPolicy: 'fetch.referrerPolicy', + integrity: 'fetch.integrity', + keepalive: 'fetch.keepalive', + signal: 'fetch.signal' +}; + +function getGlobalLoaderState() { + globalThis.loaders = globalThis.loaders || {}; + const { + loaders + } = globalThis; + loaders._state = loaders._state || {}; + return loaders._state; +} +const getGlobalLoaderOptions = () => { + const state = getGlobalLoaderState(); + state.globalOptions = state.globalOptions || { + ...DEFAULT_LOADER_OPTIONS + }; + return state.globalOptions; +}; +function normalizeOptions(options, loader, loaders, url) { + loaders = loaders || []; + loaders = Array.isArray(loaders) ? loaders : [loaders]; + validateOptions(options, loaders); + return normalizeOptionsInternal(loader, options, url); +} +function validateOptions(options, loaders) { + validateOptionsObject(options, null, DEFAULT_LOADER_OPTIONS, REMOVED_LOADER_OPTIONS, loaders); + for (const loader of loaders) { + const idOptions = options && options[loader.id] || {}; + const loaderOptions = loader.options && loader.options[loader.id] || {}; + const deprecatedOptions = loader.deprecatedOptions && loader.deprecatedOptions[loader.id] || {}; + validateOptionsObject(idOptions, loader.id, loaderOptions, deprecatedOptions, loaders); + } +} +function validateOptionsObject(options, id, defaultOptions, deprecatedOptions, loaders) { + const loaderName = id || 'Top level'; + const prefix = id ? "".concat(id, ".") : ''; + for (const key in options) { + const isSubOptions = !id && isObject(options[key]); + const isBaseUriOption = key === 'baseUri' && !id; + const isWorkerUrlOption = key === 'workerUrl' && id; + if (!(key in defaultOptions) && !isBaseUriOption && !isWorkerUrlOption) { + if (key in deprecatedOptions) { + probeLog.warn("".concat(loaderName, " loader option '").concat(prefix).concat(key, "' no longer supported, use '").concat(deprecatedOptions[key], "'"))(); + } else if (!isSubOptions) { + const suggestion = findSimilarOption(key, loaders); + probeLog.warn("".concat(loaderName, " loader option '").concat(prefix).concat(key, "' not recognized. ").concat(suggestion))(); + } + } + } +} +function findSimilarOption(optionKey, loaders) { + const lowerCaseOptionKey = optionKey.toLowerCase(); + let bestSuggestion = ''; + for (const loader of loaders) { + for (const key in loader.options) { + if (optionKey === key) { + return "Did you mean '".concat(loader.id, ".").concat(key, "'?"); + } + const lowerCaseKey = key.toLowerCase(); + const isPartialMatch = lowerCaseOptionKey.startsWith(lowerCaseKey) || lowerCaseKey.startsWith(lowerCaseOptionKey); + if (isPartialMatch) { + bestSuggestion = bestSuggestion || "Did you mean '".concat(loader.id, ".").concat(key, "'?"); + } + } + } + return bestSuggestion; +} +function normalizeOptionsInternal(loader, options, url) { + const loaderDefaultOptions = loader.options || {}; + const mergedOptions = { + ...loaderDefaultOptions + }; + addUrlOptions(mergedOptions, url); + if (mergedOptions.log === null) { + mergedOptions.log = new NullLog(); + } + mergeNestedFields(mergedOptions, getGlobalLoaderOptions()); + mergeNestedFields(mergedOptions, options); + return mergedOptions; +} +function mergeNestedFields(mergedOptions, options) { + for (const key in options) { + if (key in options) { + const value = options[key]; + if (isPureObject(value) && isPureObject(mergedOptions[key])) { + mergedOptions[key] = { + ...mergedOptions[key], + ...options[key] + }; + } else { + mergedOptions[key] = options[key]; + } + } + } +} +function addUrlOptions(options, url) { + if (url && !('baseUri' in options)) { + options.baseUri = url; + } +} + +function isLoaderObject(loader) { + var _loader; + if (!loader) { + return false; + } + if (Array.isArray(loader)) { + loader = loader[0]; + } + const hasExtensions = Array.isArray((_loader = loader) === null || _loader === void 0 ? void 0 : _loader.extensions); + return hasExtensions; +} +function normalizeLoader(loader) { + var _loader2, _loader3; + assert$5(loader, 'null loader'); + assert$5(isLoaderObject(loader), 'invalid loader'); + let options; + if (Array.isArray(loader)) { + options = loader[1]; + loader = loader[0]; + loader = { + ...loader, + options: { + ...loader.options, + ...options + } + }; + } + if ((_loader2 = loader) !== null && _loader2 !== void 0 && _loader2.parseTextSync || (_loader3 = loader) !== null && _loader3 !== void 0 && _loader3.parseText) { + loader.text = true; + } + if (!loader.text) { + loader.binary = true; + } + return loader; +} + +const getGlobalLoaderRegistry = () => { + const state = getGlobalLoaderState(); + state.loaderRegistry = state.loaderRegistry || []; + return state.loaderRegistry; +}; +function getRegisteredLoaders() { + return getGlobalLoaderRegistry(); +} + +const log = new Log({ + id: 'loaders.gl' +}); + +const EXT_PATTERN = /\.([^.]+)$/; +async function selectLoader(data) { + let loaders = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + let options = arguments.length > 2 ? arguments[2] : undefined; + let context = arguments.length > 3 ? arguments[3] : undefined; + if (!validHTTPResponse(data)) { + return null; + } + let loader = selectLoaderSync(data, loaders, { + ...options, + nothrow: true + }, context); + if (loader) { + return loader; + } + if (isBlob(data)) { + data = await data.slice(0, 10).arrayBuffer(); + loader = selectLoaderSync(data, loaders, options, context); + } + if (!loader && !(options !== null && options !== void 0 && options.nothrow)) { + throw new Error(getNoValidLoaderMessage(data)); + } + return loader; +} +function selectLoaderSync(data) { + let loaders = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + let options = arguments.length > 2 ? arguments[2] : undefined; + let context = arguments.length > 3 ? arguments[3] : undefined; + if (!validHTTPResponse(data)) { + return null; + } + if (loaders && !Array.isArray(loaders)) { + return normalizeLoader(loaders); + } + let candidateLoaders = []; + if (loaders) { + candidateLoaders = candidateLoaders.concat(loaders); + } + if (!(options !== null && options !== void 0 && options.ignoreRegisteredLoaders)) { + candidateLoaders.push(...getRegisteredLoaders()); + } + normalizeLoaders(candidateLoaders); + const loader = selectLoaderInternal(data, candidateLoaders, options, context); + if (!loader && !(options !== null && options !== void 0 && options.nothrow)) { + throw new Error(getNoValidLoaderMessage(data)); + } + return loader; +} +function selectLoaderInternal(data, loaders, options, context) { + const url = getResourceUrl(data); + const type = getResourceMIMEType(data); + const testUrl = stripQueryString(url) || (context === null || context === void 0 ? void 0 : context.url); + let loader = null; + let reason = ''; + if (options !== null && options !== void 0 && options.mimeType) { + loader = findLoaderByMIMEType(loaders, options === null || options === void 0 ? void 0 : options.mimeType); + reason = "match forced by supplied MIME type ".concat(options === null || options === void 0 ? void 0 : options.mimeType); + } + loader = loader || findLoaderByUrl(loaders, testUrl); + reason = reason || (loader ? "matched url ".concat(testUrl) : ''); + loader = loader || findLoaderByMIMEType(loaders, type); + reason = reason || (loader ? "matched MIME type ".concat(type) : ''); + loader = loader || findLoaderByInitialBytes(loaders, data); + reason = reason || (loader ? "matched initial data ".concat(getFirstCharacters(data)) : ''); + loader = loader || findLoaderByMIMEType(loaders, options === null || options === void 0 ? void 0 : options.fallbackMimeType); + reason = reason || (loader ? "matched fallback MIME type ".concat(type) : ''); + if (reason) { + var _loader; + log.log(1, "selectLoader selected ".concat((_loader = loader) === null || _loader === void 0 ? void 0 : _loader.name, ": ").concat(reason, ".")); + } + return loader; +} +function validHTTPResponse(data) { + if (data instanceof Response) { + if (data.status === 204) { + return false; + } + } + return true; +} +function getNoValidLoaderMessage(data) { + const url = getResourceUrl(data); + const type = getResourceMIMEType(data); + let message = 'No valid loader found ('; + message += url ? "".concat(filename(url), ", ") : 'no url provided, '; + message += "MIME type: ".concat(type ? "\"".concat(type, "\"") : 'not provided', ", "); + const firstCharacters = data ? getFirstCharacters(data) : ''; + message += firstCharacters ? " first bytes: \"".concat(firstCharacters, "\"") : 'first bytes: not available'; + message += ')'; + return message; +} +function normalizeLoaders(loaders) { + for (const loader of loaders) { + normalizeLoader(loader); + } +} +function findLoaderByUrl(loaders, url) { + const match = url && EXT_PATTERN.exec(url); + const extension = match && match[1]; + return extension ? findLoaderByExtension(loaders, extension) : null; +} +function findLoaderByExtension(loaders, extension) { + extension = extension.toLowerCase(); + for (const loader of loaders) { + for (const loaderExtension of loader.extensions) { + if (loaderExtension.toLowerCase() === extension) { + return loader; + } + } + } + return null; +} +function findLoaderByMIMEType(loaders, mimeType) { + for (const loader of loaders) { + if (loader.mimeTypes && loader.mimeTypes.includes(mimeType)) { + return loader; + } + if (mimeType === "application/x.".concat(loader.id)) { + return loader; + } + } + return null; +} +function findLoaderByInitialBytes(loaders, data) { + if (!data) { + return null; + } + for (const loader of loaders) { + if (typeof data === 'string') { + if (testDataAgainstText(data, loader)) { + return loader; + } + } else if (ArrayBuffer.isView(data)) { + if (testDataAgainstBinary(data.buffer, data.byteOffset, loader)) { + return loader; + } + } else if (data instanceof ArrayBuffer) { + const byteOffset = 0; + if (testDataAgainstBinary(data, byteOffset, loader)) { + return loader; + } + } + } + return null; +} +function testDataAgainstText(data, loader) { + if (loader.testText) { + return loader.testText(data); + } + const tests = Array.isArray(loader.tests) ? loader.tests : [loader.tests]; + return tests.some(test => data.startsWith(test)); +} +function testDataAgainstBinary(data, byteOffset, loader) { + const tests = Array.isArray(loader.tests) ? loader.tests : [loader.tests]; + return tests.some(test => testBinary(data, byteOffset, loader, test)); +} +function testBinary(data, byteOffset, loader, test) { + if (test instanceof ArrayBuffer) { + return compareArrayBuffers(test, data, test.byteLength); + } + switch (typeof test) { + case 'function': + return test(data, loader); + case 'string': + const magic = getMagicString$1(data, byteOffset, test.length); + return test === magic; + default: + return false; + } +} +function getFirstCharacters(data) { + let length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5; + if (typeof data === 'string') { + return data.slice(0, length); + } else if (ArrayBuffer.isView(data)) { + return getMagicString$1(data.buffer, data.byteOffset, length); + } else if (data instanceof ArrayBuffer) { + const byteOffset = 0; + return getMagicString$1(data, byteOffset, length); + } + return ''; +} +function getMagicString$1(arrayBuffer, byteOffset, length) { + if (arrayBuffer.byteLength < byteOffset + length) { + return ''; + } + const dataView = new DataView(arrayBuffer); + let magic = ''; + for (let i = 0; i < length; i++) { + magic += String.fromCharCode(dataView.getUint8(byteOffset + i)); + } + return magic; +} + +const DEFAULT_CHUNK_SIZE$2 = 256 * 1024; +function* makeStringIterator(string, options) { + const chunkSize = (options === null || options === void 0 ? void 0 : options.chunkSize) || DEFAULT_CHUNK_SIZE$2; + let offset = 0; + const textEncoder = new TextEncoder(); + while (offset < string.length) { + const chunkLength = Math.min(string.length - offset, chunkSize); + const chunk = string.slice(offset, offset + chunkLength); + offset += chunkLength; + yield textEncoder.encode(chunk); + } +} + +const DEFAULT_CHUNK_SIZE$1 = 256 * 1024; +function makeArrayBufferIterator(arrayBuffer) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return function* () { + const { + chunkSize = DEFAULT_CHUNK_SIZE$1 + } = options; + let byteOffset = 0; + while (byteOffset < arrayBuffer.byteLength) { + const chunkByteLength = Math.min(arrayBuffer.byteLength - byteOffset, chunkSize); + const chunk = new ArrayBuffer(chunkByteLength); + const sourceArray = new Uint8Array(arrayBuffer, byteOffset, chunkByteLength); + const chunkArray = new Uint8Array(chunk); + chunkArray.set(sourceArray); + byteOffset += chunkByteLength; + yield chunk; + } + }(); +} + +const DEFAULT_CHUNK_SIZE = 1024 * 1024; +async function* makeBlobIterator(blob, options) { + const chunkSize = (options === null || options === void 0 ? void 0 : options.chunkSize) || DEFAULT_CHUNK_SIZE; + let offset = 0; + while (offset < blob.size) { + const end = offset + chunkSize; + const chunk = await blob.slice(offset, end).arrayBuffer(); + offset = end; + yield chunk; + } +} + +function makeStreamIterator(stream, options) { + return isBrowser$2 ? makeBrowserStreamIterator(stream, options) : makeNodeStreamIterator(stream); +} +async function* makeBrowserStreamIterator(stream, options) { + const reader = stream.getReader(); + let nextBatchPromise; + try { + while (true) { + const currentBatchPromise = nextBatchPromise || reader.read(); + if (options !== null && options !== void 0 && options._streamReadAhead) { + nextBatchPromise = reader.read(); + } + const { + done, + value + } = await currentBatchPromise; + if (done) { + return; + } + yield toArrayBuffer$2(value); + } + } catch (error) { + reader.releaseLock(); + } +} +async function* makeNodeStreamIterator(stream, options) { + for await (const chunk of stream) { + yield toArrayBuffer$2(chunk); + } +} + +function makeIterator(data, options) { + if (typeof data === 'string') { + return makeStringIterator(data, options); + } + if (data instanceof ArrayBuffer) { + return makeArrayBufferIterator(data, options); + } + if (isBlob(data)) { + return makeBlobIterator(data, options); + } + if (isReadableStream(data)) { + return makeStreamIterator(data, options); + } + if (isResponse(data)) { + const response = data; + return makeStreamIterator(response.body, options); + } + throw new Error('makeIterator'); +} + +const ERR_DATA = 'Cannot convert supplied data type'; +function getArrayBufferOrStringFromDataSync(data, loader, options) { + if (loader.text && typeof data === 'string') { + return data; + } + if (isBuffer(data)) { + data = data.buffer; + } + if (data instanceof ArrayBuffer) { + const arrayBuffer = data; + if (loader.text && !loader.binary) { + const textDecoder = new TextDecoder('utf8'); + return textDecoder.decode(arrayBuffer); + } + return arrayBuffer; + } + if (ArrayBuffer.isView(data)) { + if (loader.text && !loader.binary) { + const textDecoder = new TextDecoder('utf8'); + return textDecoder.decode(data); + } + let arrayBuffer = data.buffer; + const byteLength = data.byteLength || data.length; + if (data.byteOffset !== 0 || byteLength !== arrayBuffer.byteLength) { + arrayBuffer = arrayBuffer.slice(data.byteOffset, data.byteOffset + byteLength); + } + return arrayBuffer; + } + throw new Error(ERR_DATA); +} +async function getArrayBufferOrStringFromData(data, loader, options) { + const isArrayBuffer = data instanceof ArrayBuffer || ArrayBuffer.isView(data); + if (typeof data === 'string' || isArrayBuffer) { + return getArrayBufferOrStringFromDataSync(data, loader); + } + if (isBlob(data)) { + data = await makeResponse(data); + } + if (isResponse(data)) { + const response = data; + await checkResponse(response); + return loader.binary ? await response.arrayBuffer() : await response.text(); + } + if (isReadableStream(data)) { + data = makeIterator(data, options); + } + if (isIterable(data) || isAsyncIterable(data)) { + return concatenateArrayBuffersAsync(data); + } + throw new Error(ERR_DATA); +} + +function getFetchFunction(options, context) { + const globalOptions = getGlobalLoaderOptions(); + const fetchOptions = options || globalOptions; + if (typeof fetchOptions.fetch === 'function') { + return fetchOptions.fetch; + } + if (isObject(fetchOptions.fetch)) { + return url => fetchFile(url, fetchOptions); + } + if (context !== null && context !== void 0 && context.fetch) { + return context === null || context === void 0 ? void 0 : context.fetch; + } + return fetchFile; +} + +function getLoaderContext(context, options, parentContext) { + if (parentContext) { + return parentContext; + } + const newContext = { + fetch: getFetchFunction(options, context), + ...context + }; + if (newContext.url) { + const baseUrl = stripQueryString(newContext.url); + newContext.baseUrl = baseUrl; + newContext.queryString = extractQueryString(newContext.url); + newContext.filename = filename(baseUrl); + newContext.baseUrl = dirname(baseUrl); + } + if (!Array.isArray(newContext.loaders)) { + newContext.loaders = null; + } + return newContext; +} +function getLoadersFromContext(loaders, context) { + if (!context && loaders && !Array.isArray(loaders)) { + return loaders; + } + let candidateLoaders; + if (loaders) { + candidateLoaders = Array.isArray(loaders) ? loaders : [loaders]; + } + if (context && context.loaders) { + const contextLoaders = Array.isArray(context.loaders) ? context.loaders : [context.loaders]; + candidateLoaders = candidateLoaders ? [...candidateLoaders, ...contextLoaders] : contextLoaders; + } + return candidateLoaders && candidateLoaders.length ? candidateLoaders : null; +} + +async function parse$2(data, loaders, options, context) { + assert$4(!context || typeof context === 'object'); + if (loaders && !Array.isArray(loaders) && !isLoaderObject(loaders)) { + context = undefined; + options = loaders; + loaders = undefined; + } + data = await data; + options = options || {}; + const url = getResourceUrl(data); + const typedLoaders = loaders; + const candidateLoaders = getLoadersFromContext(typedLoaders, context); + const loader = await selectLoader(data, candidateLoaders, options); + if (!loader) { + return null; + } + options = normalizeOptions(options, loader, candidateLoaders, url); + context = getLoaderContext({ + url, + parse: parse$2, + loaders: candidateLoaders + }, options, context || null); + return await parseWithLoader(loader, data, options, context); +} +async function parseWithLoader(loader, data, options, context) { + validateWorkerVersion(loader); + if (isResponse(data)) { + const response = data; + const { + ok, + redirected, + status, + statusText, + type, + url + } = response; + const headers = Object.fromEntries(response.headers.entries()); + context.response = { + headers, + ok, + redirected, + status, + statusText, + type, + url + }; + } + data = await getArrayBufferOrStringFromData(data, loader, options); + if (loader.parseTextSync && typeof data === 'string') { + options.dataType = 'text'; + return loader.parseTextSync(data, options, context, loader); + } + if (canParseWithWorker(loader, options)) { + return await parseWithWorker(loader, data, options, context, parse$2); + } + if (loader.parseText && typeof data === 'string') { + return await loader.parseText(data, options, context, loader); + } + if (loader.parse) { + return await loader.parse(data, options, context, loader); + } + assert$4(!loader.parseSync); + throw new Error("".concat(loader.id, " loader - no parser found and worker is disabled")); +} + +async function load(url, loaders, options, context) { + if (!Array.isArray(loaders) && !isLoaderObject(loaders)) { + options = loaders; + loaders = undefined; + } + const fetch = getFetchFunction(options); + let data = url; + if (typeof url === 'string') { + data = await fetch(url); + } + if (isBlob(url)) { + data = await fetch(url); + } + return await parse$2(data, loaders, options); +} + +async function encode$4(data, writer, options) { + const globalOptions = getGlobalLoaderOptions(); + options = { + ...globalOptions, + ...options + }; + if (canEncodeWithWorker(writer, options)) { + return await processOnWorker(writer, data, options); + } + if (writer.encode) { + return await writer.encode(data, options); + } + if (writer.encodeSync) { + return writer.encodeSync(data, options); + } + if (writer.encodeText) { + return new TextEncoder().encode(await writer.encodeText(data, options)); + } + if (writer.encodeInBatches) { + const batches = encodeInBatches(data, writer, options); + const chunks = []; + for await (const batch of batches) { + chunks.push(batch); + } + return concatenateArrayBuffers(...chunks); + } + if (!isBrowser$2 && writer.encodeURLtoURL) { + const tmpInputFilename = getTemporaryFilename('input'); + await writeFile(tmpInputFilename, data); + const tmpOutputFilename = getTemporaryFilename('output'); + const outputFilename = await encodeURLtoURL(tmpInputFilename, tmpOutputFilename, writer, options); + const response = await fetchFile(outputFilename); + return response.arrayBuffer(); + } + throw new Error('Writer could not encode data'); +} +function encodeInBatches(data, writer, options) { + if (writer.encodeInBatches) { + const dataIterator = getIterator(data); + return writer.encodeInBatches(dataIterator, options); + } + throw new Error('Writer could not encode data in batches'); +} +async function encodeURLtoURL(inputUrl, outputUrl, writer, options) { + inputUrl = resolvePath(inputUrl); + outputUrl = resolvePath(outputUrl); + if (isBrowser$2 || !writer.encodeURLtoURL) { + throw new Error(); + } + const outputFilename = await writer.encodeURLtoURL(inputUrl, outputUrl, options); + return outputFilename; +} +function getIterator(data) { + const dataIterator = [{ + table: data, + start: 0, + end: data.length + }]; + return dataIterator; +} +function getTemporaryFilename(filename) { + return "/tmp/".concat(filename); +} + +const VERSION$4 = "3.4.14" ; + +const VERSION$3 = "3.4.14" ; +const BASIS_CDN_ENCODER_WASM = "https://unpkg.com/@loaders.gl/textures@".concat(VERSION$3, "/dist/libs/basis_encoder.wasm"); +const BASIS_CDN_ENCODER_JS = "https://unpkg.com/@loaders.gl/textures@".concat(VERSION$3, "/dist/libs/basis_encoder.js"); +let loadBasisTranscoderPromise; +async function loadBasisTrascoderModule(options) { + const modules = options.modules || {}; + if (modules.basis) { + return modules.basis; + } + loadBasisTranscoderPromise = loadBasisTranscoderPromise || loadBasisTrascoder(options); + return await loadBasisTranscoderPromise; +} +async function loadBasisTrascoder(options) { + let BASIS = null; + let wasmBinary = null; + [BASIS, wasmBinary] = await Promise.all([await loadLibrary('basis_transcoder.js', 'textures', options), await loadLibrary('basis_transcoder.wasm', 'textures', options)]); + BASIS = BASIS || globalThis.BASIS; + return await initializeBasisTrascoderModule(BASIS, wasmBinary); +} +function initializeBasisTrascoderModule(BasisModule, wasmBinary) { + const options = {}; + if (wasmBinary) { + options.wasmBinary = wasmBinary; + } + return new Promise(resolve => { + BasisModule(options).then(module => { + const { + BasisFile, + initializeBasis + } = module; + initializeBasis(); + resolve({ + BasisFile + }); + }); + }); +} +let loadBasisEncoderPromise; +async function loadBasisEncoderModule(options) { + const modules = options.modules || {}; + if (modules.basisEncoder) { + return modules.basisEncoder; + } + loadBasisEncoderPromise = loadBasisEncoderPromise || loadBasisEncoder(options); + return await loadBasisEncoderPromise; +} +async function loadBasisEncoder(options) { + let BASIS_ENCODER = null; + let wasmBinary = null; + [BASIS_ENCODER, wasmBinary] = await Promise.all([await loadLibrary(BASIS_CDN_ENCODER_JS, 'textures', options), await loadLibrary(BASIS_CDN_ENCODER_WASM, 'textures', options)]); + BASIS_ENCODER = BASIS_ENCODER || globalThis.BASIS; + return await initializeBasisEncoderModule(BASIS_ENCODER, wasmBinary); +} +function initializeBasisEncoderModule(BasisEncoderModule, wasmBinary) { + const options = {}; + if (wasmBinary) { + options.wasmBinary = wasmBinary; + } + return new Promise(resolve => { + BasisEncoderModule(options).then(module => { + const { + BasisFile, + KTX2File, + initializeBasis, + BasisEncoder + } = module; + initializeBasis(); + resolve({ + BasisFile, + KTX2File, + BasisEncoder + }); + }); + }); +} + +const GL_EXTENSIONS_CONSTANTS = { + COMPRESSED_RGB_S3TC_DXT1_EXT: 0x83f0, + COMPRESSED_RGBA_S3TC_DXT1_EXT: 0x83f1, + COMPRESSED_RGBA_S3TC_DXT3_EXT: 0x83f2, + COMPRESSED_RGBA_S3TC_DXT5_EXT: 0x83f3, + COMPRESSED_R11_EAC: 0x9270, + COMPRESSED_SIGNED_R11_EAC: 0x9271, + COMPRESSED_RG11_EAC: 0x9272, + COMPRESSED_SIGNED_RG11_EAC: 0x9273, + COMPRESSED_RGB8_ETC2: 0x9274, + COMPRESSED_RGBA8_ETC2_EAC: 0x9275, + COMPRESSED_SRGB8_ETC2: 0x9276, + COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 0x9277, + COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 0x9278, + COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 0x9279, + COMPRESSED_RGB_PVRTC_4BPPV1_IMG: 0x8c00, + COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: 0x8c02, + COMPRESSED_RGB_PVRTC_2BPPV1_IMG: 0x8c01, + COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: 0x8c03, + COMPRESSED_RGB_ETC1_WEBGL: 0x8d64, + COMPRESSED_RGB_ATC_WEBGL: 0x8c92, + COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL: 0x8c93, + COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL: 0x87ee, + COMPRESSED_RGBA_ASTC_4X4_KHR: 0x93b0, + COMPRESSED_RGBA_ASTC_5X4_KHR: 0x93b1, + COMPRESSED_RGBA_ASTC_5X5_KHR: 0x93b2, + COMPRESSED_RGBA_ASTC_6X5_KHR: 0x93b3, + COMPRESSED_RGBA_ASTC_6X6_KHR: 0x93b4, + COMPRESSED_RGBA_ASTC_8X5_KHR: 0x93b5, + COMPRESSED_RGBA_ASTC_8X6_KHR: 0x93b6, + COMPRESSED_RGBA_ASTC_8X8_KHR: 0x93b7, + COMPRESSED_RGBA_ASTC_10X5_KHR: 0x93b8, + COMPRESSED_RGBA_ASTC_10X6_KHR: 0x93b9, + COMPRESSED_RGBA_ASTC_10X8_KHR: 0x93ba, + COMPRESSED_RGBA_ASTC_10X10_KHR: 0x93bb, + COMPRESSED_RGBA_ASTC_12X10_KHR: 0x93bc, + COMPRESSED_RGBA_ASTC_12X12_KHR: 0x93bd, + COMPRESSED_SRGB8_ALPHA8_ASTC_4X4_KHR: 0x93d0, + COMPRESSED_SRGB8_ALPHA8_ASTC_5X4_KHR: 0x93d1, + COMPRESSED_SRGB8_ALPHA8_ASTC_5X5_KHR: 0x93d2, + COMPRESSED_SRGB8_ALPHA8_ASTC_6X5_KHR: 0x93d3, + COMPRESSED_SRGB8_ALPHA8_ASTC_6X6_KHR: 0x93d4, + COMPRESSED_SRGB8_ALPHA8_ASTC_8X5_KHR: 0x93d5, + COMPRESSED_SRGB8_ALPHA8_ASTC_8X6_KHR: 0x93d6, + COMPRESSED_SRGB8_ALPHA8_ASTC_8X8_KHR: 0x93d7, + COMPRESSED_SRGB8_ALPHA8_ASTC_10X5_KHR: 0x93d8, + COMPRESSED_SRGB8_ALPHA8_ASTC_10X6_KHR: 0x93d9, + COMPRESSED_SRGB8_ALPHA8_ASTC_10X8_KHR: 0x93da, + COMPRESSED_SRGB8_ALPHA8_ASTC_10X10_KHR: 0x93db, + COMPRESSED_SRGB8_ALPHA8_ASTC_12X10_KHR: 0x93dc, + COMPRESSED_SRGB8_ALPHA8_ASTC_12X12_KHR: 0x93dd, + COMPRESSED_RED_RGTC1_EXT: 0x8dbb, + COMPRESSED_SIGNED_RED_RGTC1_EXT: 0x8dbc, + COMPRESSED_RED_GREEN_RGTC2_EXT: 0x8dbd, + COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: 0x8dbe, + COMPRESSED_SRGB_S3TC_DXT1_EXT: 0x8c4c, + COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 0x8c4d, + COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 0x8c4e, + COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 0x8c4f +}; + +const BROWSER_PREFIXES = ['', 'WEBKIT_', 'MOZ_']; +const WEBGL_EXTENSIONS = { + WEBGL_compressed_texture_s3tc: 'dxt', + WEBGL_compressed_texture_s3tc_srgb: 'dxt-srgb', + WEBGL_compressed_texture_etc1: 'etc1', + WEBGL_compressed_texture_etc: 'etc2', + WEBGL_compressed_texture_pvrtc: 'pvrtc', + WEBGL_compressed_texture_atc: 'atc', + WEBGL_compressed_texture_astc: 'astc', + EXT_texture_compression_rgtc: 'rgtc' +}; +let formats = null; +function getSupportedGPUTextureFormats(gl) { + if (!formats) { + gl = gl || getWebGLContext() || undefined; + formats = new Set(); + for (const prefix of BROWSER_PREFIXES) { + for (const extension in WEBGL_EXTENSIONS) { + if (gl && gl.getExtension("".concat(prefix).concat(extension))) { + const gpuTextureFormat = WEBGL_EXTENSIONS[extension]; + formats.add(gpuTextureFormat); + } + } + } + } + return formats; +} +function getWebGLContext() { + try { + const canvas = document.createElement('canvas'); + return canvas.getContext('webgl'); + } catch (error) { + return null; + } +} + +var n,i,s,a,r,o,l,f;!function(t){t[t.NONE=0]="NONE",t[t.BASISLZ=1]="BASISLZ",t[t.ZSTD=2]="ZSTD",t[t.ZLIB=3]="ZLIB";}(n||(n={})),function(t){t[t.BASICFORMAT=0]="BASICFORMAT";}(i||(i={})),function(t){t[t.UNSPECIFIED=0]="UNSPECIFIED",t[t.ETC1S=163]="ETC1S",t[t.UASTC=166]="UASTC";}(s||(s={})),function(t){t[t.UNSPECIFIED=0]="UNSPECIFIED",t[t.SRGB=1]="SRGB";}(a||(a={})),function(t){t[t.UNSPECIFIED=0]="UNSPECIFIED",t[t.LINEAR=1]="LINEAR",t[t.SRGB=2]="SRGB",t[t.ITU=3]="ITU",t[t.NTSC=4]="NTSC",t[t.SLOG=5]="SLOG",t[t.SLOG2=6]="SLOG2";}(r||(r={})),function(t){t[t.ALPHA_STRAIGHT=0]="ALPHA_STRAIGHT",t[t.ALPHA_PREMULTIPLIED=1]="ALPHA_PREMULTIPLIED";}(o||(o={})),function(t){t[t.RGB=0]="RGB",t[t.RRR=3]="RRR",t[t.GGG=4]="GGG",t[t.AAA=15]="AAA";}(l||(l={})),function(t){t[t.RGB=0]="RGB",t[t.RGBA=3]="RGBA",t[t.RRR=4]="RRR",t[t.RRRG=5]="RRRG";}(f||(f={})); + +const KTX2_ID = [0xab, 0x4b, 0x54, 0x58, 0x20, 0x32, 0x30, 0xbb, 0x0d, 0x0a, 0x1a, 0x0a]; +function isKTX(data) { + const id = new Uint8Array(data); + const notKTX = id.byteLength < KTX2_ID.length || id[0] !== KTX2_ID[0] || id[1] !== KTX2_ID[1] || id[2] !== KTX2_ID[2] || id[3] !== KTX2_ID[3] || id[4] !== KTX2_ID[4] || id[5] !== KTX2_ID[5] || id[6] !== KTX2_ID[6] || id[7] !== KTX2_ID[7] || id[8] !== KTX2_ID[8] || id[9] !== KTX2_ID[9] || id[10] !== KTX2_ID[10] || id[11] !== KTX2_ID[11]; + return !notKTX; +} + +const OutputFormat = { + etc1: { + basisFormat: 0, + compressed: true, + format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_ETC1_WEBGL + }, + etc2: { + basisFormat: 1, + compressed: true + }, + bc1: { + basisFormat: 2, + compressed: true, + format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_S3TC_DXT1_EXT + }, + bc3: { + basisFormat: 3, + compressed: true, + format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT5_EXT + }, + bc4: { + basisFormat: 4, + compressed: true + }, + bc5: { + basisFormat: 5, + compressed: true + }, + 'bc7-m6-opaque-only': { + basisFormat: 6, + compressed: true + }, + 'bc7-m5': { + basisFormat: 7, + compressed: true + }, + 'pvrtc1-4-rgb': { + basisFormat: 8, + compressed: true, + format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_PVRTC_4BPPV1_IMG + }, + 'pvrtc1-4-rgba': { + basisFormat: 9, + compressed: true, + format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG + }, + 'astc-4x4': { + basisFormat: 10, + compressed: true, + format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_4X4_KHR + }, + 'atc-rgb': { + basisFormat: 11, + compressed: true + }, + 'atc-rgba-interpolated-alpha': { + basisFormat: 12, + compressed: true + }, + rgba32: { + basisFormat: 13, + compressed: false + }, + rgb565: { + basisFormat: 14, + compressed: false + }, + bgr565: { + basisFormat: 15, + compressed: false + }, + rgba4444: { + basisFormat: 16, + compressed: false + } +}; +async function parseBasis(data, options) { + if (options.basis.containerFormat === 'auto') { + if (isKTX(data)) { + const fileConstructors = await loadBasisEncoderModule(options); + return parseKTX2File(fileConstructors.KTX2File, data, options); + } + const { + BasisFile + } = await loadBasisTrascoderModule(options); + return parseBasisFile(BasisFile, data, options); + } + switch (options.basis.module) { + case 'encoder': + const fileConstructors = await loadBasisEncoderModule(options); + switch (options.basis.containerFormat) { + case 'ktx2': + return parseKTX2File(fileConstructors.KTX2File, data, options); + case 'basis': + default: + return parseBasisFile(fileConstructors.BasisFile, data, options); + } + case 'transcoder': + default: + const { + BasisFile + } = await loadBasisTrascoderModule(options); + return parseBasisFile(BasisFile, data, options); + } +} +function parseBasisFile(BasisFile, data, options) { + const basisFile = new BasisFile(new Uint8Array(data)); + try { + if (!basisFile.startTranscoding()) { + throw new Error('Failed to start basis transcoding'); + } + const imageCount = basisFile.getNumImages(); + const images = []; + for (let imageIndex = 0; imageIndex < imageCount; imageIndex++) { + const levelsCount = basisFile.getNumLevels(imageIndex); + const levels = []; + for (let levelIndex = 0; levelIndex < levelsCount; levelIndex++) { + levels.push(transcodeImage(basisFile, imageIndex, levelIndex, options)); + } + images.push(levels); + } + return images; + } finally { + basisFile.close(); + basisFile.delete(); + } +} +function transcodeImage(basisFile, imageIndex, levelIndex, options) { + const width = basisFile.getImageWidth(imageIndex, levelIndex); + const height = basisFile.getImageHeight(imageIndex, levelIndex); + const hasAlpha = basisFile.getHasAlpha(); + const { + compressed, + format, + basisFormat + } = getBasisOptions(options, hasAlpha); + const decodedSize = basisFile.getImageTranscodedSizeInBytes(imageIndex, levelIndex, basisFormat); + const decodedData = new Uint8Array(decodedSize); + if (!basisFile.transcodeImage(decodedData, imageIndex, levelIndex, basisFormat, 0, 0)) { + throw new Error('failed to start Basis transcoding'); + } + return { + width, + height, + data: decodedData, + compressed, + format, + hasAlpha + }; +} +function parseKTX2File(KTX2File, data, options) { + const ktx2File = new KTX2File(new Uint8Array(data)); + try { + if (!ktx2File.startTranscoding()) { + throw new Error('failed to start KTX2 transcoding'); + } + const levelsCount = ktx2File.getLevels(); + const levels = []; + for (let levelIndex = 0; levelIndex < levelsCount; levelIndex++) { + levels.push(transcodeKTX2Image(ktx2File, levelIndex, options)); + break; + } + return [levels]; + } finally { + ktx2File.close(); + ktx2File.delete(); + } +} +function transcodeKTX2Image(ktx2File, levelIndex, options) { + const { + alphaFlag, + height, + width + } = ktx2File.getImageLevelInfo(levelIndex, 0, 0); + const { + compressed, + format, + basisFormat + } = getBasisOptions(options, alphaFlag); + const decodedSize = ktx2File.getImageTranscodedSizeInBytes(levelIndex, 0, 0, basisFormat); + const decodedData = new Uint8Array(decodedSize); + if (!ktx2File.transcodeImage(decodedData, levelIndex, 0, 0, basisFormat, 0, -1, -1)) { + throw new Error('Failed to transcode KTX2 image'); + } + return { + width, + height, + data: decodedData, + compressed, + levelSize: decodedSize, + hasAlpha: alphaFlag, + format + }; +} +function getBasisOptions(options, hasAlpha) { + let format = options && options.basis && options.basis.format; + if (format === 'auto') { + format = selectSupportedBasisFormat(); + } + if (typeof format === 'object') { + format = hasAlpha ? format.alpha : format.noAlpha; + } + format = format.toLowerCase(); + return OutputFormat[format]; +} +function selectSupportedBasisFormat() { + const supportedFormats = getSupportedGPUTextureFormats(); + if (supportedFormats.has('astc')) { + return 'astc-4x4'; + } else if (supportedFormats.has('dxt')) { + return { + alpha: 'bc3', + noAlpha: 'bc1' + }; + } else if (supportedFormats.has('pvrtc')) { + return { + alpha: 'pvrtc1-4-rgba', + noAlpha: 'pvrtc1-4-rgb' + }; + } else if (supportedFormats.has('etc1')) { + return 'etc1'; + } else if (supportedFormats.has('etc2')) { + return 'etc2'; + } + return 'rgb565'; +} + +const BasisWorkerLoader = { + name: 'Basis', + id: isBrowser$1 ? 'basis' : 'basis-nodejs', + module: 'textures', + version: VERSION$4, + worker: true, + extensions: ['basis', 'ktx2'], + mimeTypes: ['application/octet-stream', 'image/ktx2'], + tests: ['sB'], + binary: true, + options: { + basis: { + format: 'auto', + libraryPath: 'libs/', + containerFormat: 'auto', + module: 'transcoder' + } + } +}; +const BasisLoader = { + ...BasisWorkerLoader, + parse: parseBasis +}; + +async function encodeKTX2BasisTexture(image) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const { + useSRGB = false, + qualityLevel = 10, + encodeUASTC = false, + mipmaps = false + } = options; + const { + BasisEncoder + } = await loadBasisEncoderModule(options); + const basisEncoder = new BasisEncoder(); + try { + const basisFileData = new Uint8Array(image.width * image.height * 4); + basisEncoder.setCreateKTX2File(true); + basisEncoder.setKTX2UASTCSupercompression(true); + basisEncoder.setKTX2SRGBTransferFunc(true); + basisEncoder.setSliceSourceImage(0, image.data, image.width, image.height, false); + basisEncoder.setPerceptual(useSRGB); + basisEncoder.setMipSRGB(useSRGB); + basisEncoder.setQualityLevel(qualityLevel); + basisEncoder.setUASTC(encodeUASTC); + basisEncoder.setMipGen(mipmaps); + const numOutputBytes = basisEncoder.encode(basisFileData); + const actualKTX2FileData = basisFileData.subarray(0, numOutputBytes).buffer; + return actualKTX2FileData; + } catch (error) { + console.error('Basis Universal Supercompressed GPU Texture encoder Error: ', error); + throw error; + } finally { + basisEncoder.delete(); + } +} + +const KTX2BasisWriter = { + name: 'Basis Universal Supercompressed GPU Texture', + id: 'ktx2-basis-writer', + module: 'textures', + version: VERSION$4, + extensions: ['ktx2'], + options: { + useSRGB: false, + qualityLevel: 10, + encodeUASTC: false, + mipmaps: false + }, + encode: encodeKTX2BasisTexture +}; + +const VERSION$2 = "3.4.14" ; + +const { + _parseImageNode +} = globalThis; +const IMAGE_SUPPORTED = typeof Image !== 'undefined'; +const IMAGE_BITMAP_SUPPORTED = typeof ImageBitmap !== 'undefined'; +const NODE_IMAGE_SUPPORTED = Boolean(_parseImageNode); +const DATA_SUPPORTED = isBrowser$2 ? true : NODE_IMAGE_SUPPORTED; +function isImageTypeSupported(type) { + switch (type) { + case 'auto': + return IMAGE_BITMAP_SUPPORTED || IMAGE_SUPPORTED || DATA_SUPPORTED; + case 'imagebitmap': + return IMAGE_BITMAP_SUPPORTED; + case 'image': + return IMAGE_SUPPORTED; + case 'data': + return DATA_SUPPORTED; + default: + throw new Error("@loaders.gl/images: image ".concat(type, " not supported in this environment")); + } +} +function getDefaultImageType() { + if (IMAGE_BITMAP_SUPPORTED) { + return 'imagebitmap'; + } + if (IMAGE_SUPPORTED) { + return 'image'; + } + if (DATA_SUPPORTED) { + return 'data'; + } + throw new Error('Install \'@loaders.gl/polyfills\' to parse images under Node.js'); +} + +function getImageType(image) { + const format = getImageTypeOrNull(image); + if (!format) { + throw new Error('Not an image'); + } + return format; +} +function getImageData(image) { + switch (getImageType(image)) { + case 'data': + return image; + case 'image': + case 'imagebitmap': + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + if (!context) { + throw new Error('getImageData'); + } + canvas.width = image.width; + canvas.height = image.height; + context.drawImage(image, 0, 0); + return context.getImageData(0, 0, image.width, image.height); + default: + throw new Error('getImageData'); + } +} +function getImageTypeOrNull(image) { + if (typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) { + return 'imagebitmap'; + } + if (typeof Image !== 'undefined' && image instanceof Image) { + return 'image'; + } + if (image && typeof image === 'object' && image.data && image.width && image.height) { + return 'data'; + } + return null; +} + +const SVG_DATA_URL_PATTERN = /^data:image\/svg\+xml/; +const SVG_URL_PATTERN = /\.svg((\?|#).*)?$/; +function isSVG(url) { + return url && (SVG_DATA_URL_PATTERN.test(url) || SVG_URL_PATTERN.test(url)); +} +function getBlobOrSVGDataUrl(arrayBuffer, url) { + if (isSVG(url)) { + const textDecoder = new TextDecoder(); + let xmlText = textDecoder.decode(arrayBuffer); + try { + if (typeof unescape === 'function' && typeof encodeURIComponent === 'function') { + xmlText = unescape(encodeURIComponent(xmlText)); + } + } catch (error) { + throw new Error(error.message); + } + const src = "data:image/svg+xml;base64,".concat(btoa(xmlText)); + return src; + } + return getBlob(arrayBuffer, url); +} +function getBlob(arrayBuffer, url) { + if (isSVG(url)) { + throw new Error('SVG cannot be parsed directly to imagebitmap'); + } + return new Blob([new Uint8Array(arrayBuffer)]); +} + +async function parseToImage(arrayBuffer, options, url) { + const blobOrDataUrl = getBlobOrSVGDataUrl(arrayBuffer, url); + const URL = self.URL || self.webkitURL; + const objectUrl = typeof blobOrDataUrl !== 'string' && URL.createObjectURL(blobOrDataUrl); + try { + return await loadToImage(objectUrl || blobOrDataUrl, options); + } finally { + if (objectUrl) { + URL.revokeObjectURL(objectUrl); + } + } +} +async function loadToImage(url, options) { + const image = new Image(); + image.src = url; + if (options.image && options.image.decode && image.decode) { + await image.decode(); + return image; + } + return await new Promise((resolve, reject) => { + try { + image.onload = () => resolve(image); + image.onerror = err => reject(new Error("Could not load image ".concat(url, ": ").concat(err))); + } catch (error) { + reject(error); + } + }); +} + +const EMPTY_OBJECT = {}; +let imagebitmapOptionsSupported = true; +async function parseToImageBitmap(arrayBuffer, options, url) { + let blob; + if (isSVG(url)) { + const image = await parseToImage(arrayBuffer, options, url); + blob = image; + } else { + blob = getBlob(arrayBuffer, url); + } + const imagebitmapOptions = options && options.imagebitmap; + return await safeCreateImageBitmap(blob, imagebitmapOptions); +} +async function safeCreateImageBitmap(blob) { + let imagebitmapOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + if (isEmptyObject(imagebitmapOptions) || !imagebitmapOptionsSupported) { + imagebitmapOptions = null; + } + if (imagebitmapOptions) { + try { + return await createImageBitmap(blob, imagebitmapOptions); + } catch (error) { + console.warn(error); + imagebitmapOptionsSupported = false; + } + } + return await createImageBitmap(blob); +} +function isEmptyObject(object) { + for (const key in object || EMPTY_OBJECT) { + return false; + } + return true; +} + +function getISOBMFFMediaType(buffer) { + if (!checkString(buffer, 'ftyp', 4)) { + return null; + } + if ((buffer[8] & 0x60) === 0x00) { + return null; + } + return decodeMajorBrand(buffer); +} +function decodeMajorBrand(buffer) { + const brandMajor = getUTF8String(buffer, 8, 12).replace('\0', ' ').trim(); + switch (brandMajor) { + case 'avif': + case 'avis': + return { + extension: 'avif', + mimeType: 'image/avif' + }; + default: + return null; + } +} +function getUTF8String(array, start, end) { + return String.fromCharCode(...array.slice(start, end)); +} +function stringToBytes(string) { + return [...string].map(character => character.charCodeAt(0)); +} +function checkString(buffer, header) { + let offset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + const headerBytes = stringToBytes(header); + for (let i = 0; i < headerBytes.length; ++i) { + if (headerBytes[i] !== buffer[i + offset]) { + return false; + } + } + return true; +} + +const BIG_ENDIAN = false; +const LITTLE_ENDIAN = true; +function getBinaryImageMetadata(binaryData) { + const dataView = toDataView(binaryData); + return getPngMetadata(dataView) || getJpegMetadata(dataView) || getGifMetadata(dataView) || getBmpMetadata(dataView) || getISOBMFFMetadata(dataView); +} +function getISOBMFFMetadata(binaryData) { + const buffer = new Uint8Array(binaryData instanceof DataView ? binaryData.buffer : binaryData); + const mediaType = getISOBMFFMediaType(buffer); + if (!mediaType) { + return null; + } + return { + mimeType: mediaType.mimeType, + width: 0, + height: 0 + }; +} +function getPngMetadata(binaryData) { + const dataView = toDataView(binaryData); + const isPng = dataView.byteLength >= 24 && dataView.getUint32(0, BIG_ENDIAN) === 0x89504e47; + if (!isPng) { + return null; + } + return { + mimeType: 'image/png', + width: dataView.getUint32(16, BIG_ENDIAN), + height: dataView.getUint32(20, BIG_ENDIAN) + }; +} +function getGifMetadata(binaryData) { + const dataView = toDataView(binaryData); + const isGif = dataView.byteLength >= 10 && dataView.getUint32(0, BIG_ENDIAN) === 0x47494638; + if (!isGif) { + return null; + } + return { + mimeType: 'image/gif', + width: dataView.getUint16(6, LITTLE_ENDIAN), + height: dataView.getUint16(8, LITTLE_ENDIAN) + }; +} +function getBmpMetadata(binaryData) { + const dataView = toDataView(binaryData); + const isBmp = dataView.byteLength >= 14 && dataView.getUint16(0, BIG_ENDIAN) === 0x424d && dataView.getUint32(2, LITTLE_ENDIAN) === dataView.byteLength; + if (!isBmp) { + return null; + } + return { + mimeType: 'image/bmp', + width: dataView.getUint32(18, LITTLE_ENDIAN), + height: dataView.getUint32(22, LITTLE_ENDIAN) + }; +} +function getJpegMetadata(binaryData) { + const dataView = toDataView(binaryData); + const isJpeg = dataView.byteLength >= 3 && dataView.getUint16(0, BIG_ENDIAN) === 0xffd8 && dataView.getUint8(2) === 0xff; + if (!isJpeg) { + return null; + } + const { + tableMarkers, + sofMarkers + } = getJpegMarkers(); + let i = 2; + while (i + 9 < dataView.byteLength) { + const marker = dataView.getUint16(i, BIG_ENDIAN); + if (sofMarkers.has(marker)) { + return { + mimeType: 'image/jpeg', + height: dataView.getUint16(i + 5, BIG_ENDIAN), + width: dataView.getUint16(i + 7, BIG_ENDIAN) + }; + } + if (!tableMarkers.has(marker)) { + return null; + } + i += 2; + i += dataView.getUint16(i, BIG_ENDIAN); + } + return null; +} +function getJpegMarkers() { + const tableMarkers = new Set([0xffdb, 0xffc4, 0xffcc, 0xffdd, 0xfffe]); + for (let i = 0xffe0; i < 0xfff0; ++i) { + tableMarkers.add(i); + } + const sofMarkers = new Set([0xffc0, 0xffc1, 0xffc2, 0xffc3, 0xffc5, 0xffc6, 0xffc7, 0xffc9, 0xffca, 0xffcb, 0xffcd, 0xffce, 0xffcf, 0xffde]); + return { + tableMarkers, + sofMarkers + }; +} +function toDataView(data) { + if (data instanceof DataView) { + return data; + } + if (ArrayBuffer.isView(data)) { + return new DataView(data.buffer); + } + if (data instanceof ArrayBuffer) { + return new DataView(data); + } + throw new Error('toDataView'); +} + +async function parseToNodeImage(arrayBuffer, options) { + const { + mimeType + } = getBinaryImageMetadata(arrayBuffer) || {}; + const _parseImageNode = globalThis._parseImageNode; + assert$5(_parseImageNode); + return await _parseImageNode(arrayBuffer, mimeType); +} + +async function parseImage(arrayBuffer, options, context) { + options = options || {}; + const imageOptions = options.image || {}; + const imageType = imageOptions.type || 'auto'; + const { + url + } = context || {}; + const loadType = getLoadableImageType(imageType); + let image; + switch (loadType) { + case 'imagebitmap': + image = await parseToImageBitmap(arrayBuffer, options, url); + break; + case 'image': + image = await parseToImage(arrayBuffer, options, url); + break; + case 'data': + image = await parseToNodeImage(arrayBuffer); + break; + default: + assert$5(false); + } + if (imageType === 'data') { + image = getImageData(image); + } + return image; +} +function getLoadableImageType(type) { + switch (type) { + case 'auto': + case 'data': + return getDefaultImageType(); + default: + isImageTypeSupported(type); + return type; + } +} + +const EXTENSIONS$1 = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'ico', 'svg', 'avif']; +const MIME_TYPES = ['image/png', 'image/jpeg', 'image/gif', 'image/webp', 'image/avif', 'image/bmp', 'image/vnd.microsoft.icon', 'image/svg+xml']; +const DEFAULT_IMAGE_LOADER_OPTIONS = { + image: { + type: 'auto', + decode: true + } +}; +const ImageLoader = { + id: 'image', + module: 'images', + name: 'Images', + version: VERSION$2, + mimeTypes: MIME_TYPES, + extensions: EXTENSIONS$1, + parse: parseImage, + tests: [arrayBuffer => Boolean(getBinaryImageMetadata(new DataView(arrayBuffer)))], + options: DEFAULT_IMAGE_LOADER_OPTIONS +}; + +const mimeTypeSupportedSync = {}; +function isImageFormatSupported(mimeType) { + if (mimeTypeSupportedSync[mimeType] === undefined) { + const supported = isBrowser$2 ? checkBrowserImageFormatSupport(mimeType) : checkNodeImageFormatSupport(mimeType); + mimeTypeSupportedSync[mimeType] = supported; + } + return mimeTypeSupportedSync[mimeType]; +} +function checkNodeImageFormatSupport(mimeType) { + const NODE_FORMAT_SUPPORT = ['image/png', 'image/jpeg', 'image/gif']; + const { + _parseImageNode, + _imageFormatsNode = NODE_FORMAT_SUPPORT + } = globalThis; + return Boolean(_parseImageNode) && _imageFormatsNode.includes(mimeType); +} +function checkBrowserImageFormatSupport(mimeType) { + switch (mimeType) { + case 'image/avif': + case 'image/webp': + return testBrowserImageFormatSupport(mimeType); + default: + return true; + } +} +function testBrowserImageFormatSupport(mimeType) { + try { + const element = document.createElement('canvas'); + const dataURL = element.toDataURL(mimeType); + return dataURL.indexOf("data:".concat(mimeType)) === 0; + } catch { + return false; + } +} + +const tempVec4a = math.vec4([0, 0, 0, 1]); +const tempVec4b = math.vec4([0, 0, 0, 1]); + +const tempMat4 = math.mat4(); +const tempMat4b = math.mat4(); + +const kdTreeDimLength = new Float64Array(3); + +// XKT texture types + +const COLOR_TEXTURE = 0; +const METALLIC_ROUGHNESS_TEXTURE = 1; +const NORMALS_TEXTURE = 2; +const EMISSIVE_TEXTURE = 3; +const OCCLUSION_TEXTURE = 4; + +// KTX2 encoding options for each texture type + +const TEXTURE_ENCODING_OPTIONS = {}; +TEXTURE_ENCODING_OPTIONS[COLOR_TEXTURE] = { + useSRGB: true, + qualityLevel: 50, + encodeUASTC: true, + mipmaps: true +}; +TEXTURE_ENCODING_OPTIONS[EMISSIVE_TEXTURE] = { + useSRGB: true, + encodeUASTC: true, + qualityLevel: 10, + mipmaps: false +}; +TEXTURE_ENCODING_OPTIONS[METALLIC_ROUGHNESS_TEXTURE] = { + useSRGB: false, + encodeUASTC: true, + qualityLevel: 50, + mipmaps: true // Needed for GGX roughness shading +}; +TEXTURE_ENCODING_OPTIONS[NORMALS_TEXTURE] = { + useSRGB: false, + encodeUASTC: true, + qualityLevel: 10, + mipmaps: false +}; +TEXTURE_ENCODING_OPTIONS[OCCLUSION_TEXTURE] = { + useSRGB: false, + encodeUASTC: true, + qualityLevel: 10, + mipmaps: false +}; + +/** + * A document model that represents the contents of an .XKT file. + * + * * An XKTModel contains {@link XKTTile}s, which spatially subdivide the model into axis-aligned, box-shaped regions. + * * Each {@link XKTTile} contains {@link XKTEntity}s, which represent the objects within its region. + * * Each {@link XKTEntity} has {@link XKTMesh}s, which each have a {@link XKTGeometry}. Each {@link XKTGeometry} can be shared by multiple {@link XKTMesh}s. + * * Import models into an XKTModel using {@link parseGLTFJSONIntoXKTModel}, {@link parseIFCIntoXKTModel}, {@link parseCityJSONIntoXKTModel} etc. + * * Build an XKTModel programmatically using {@link XKTModel#createGeometry}, {@link XKTModel#createMesh} and {@link XKTModel#createEntity}. + * * Serialize an XKTModel to an ArrayBuffer using {@link writeXKTModelToArrayBuffer}. + * + * ## Usage + * + * See [main docs page](/docs/#javascript-api) for usage examples. + * + * @class XKTModel + */ +class XKTModel { + + /** + * Constructs a new XKTModel. + * + * @param {*} [cfg] Configuration + * @param {Number} [cfg.edgeThreshold=10] + * @param {Number} [cfg.minTileSize=500] + */ + constructor(cfg = {}) { + + /** + * The model's ID, if available. + * + * Will be "default" by default. + * + * @type {String} + */ + this.modelId = cfg.modelId || "default"; + + /** + * The project ID, if available. + * + * Will be an empty string by default. + * + * @type {String} + */ + this.projectId = cfg.projectId || ""; + + /** + * The revision ID, if available. + * + * Will be an empty string by default. + * + * @type {String} + */ + this.revisionId = cfg.revisionId || ""; + + /** + * The model author, if available. + * + * Will be an empty string by default. + * + * @property author + * @type {String} + */ + this.author = cfg.author || ""; + + /** + * The date the model was created, if available. + * + * Will be an empty string by default. + * + * @property createdAt + * @type {String} + */ + this.createdAt = cfg.createdAt || ""; + + /** + * The application that created the model, if available. + * + * Will be an empty string by default. + * + * @property creatingApplication + * @type {String} + */ + this.creatingApplication = cfg.creatingApplication || ""; + + /** + * The model schema version, if available. + * + * In the case of IFC, this could be "IFC2x3" or "IFC4", for example. + * + * Will be an empty string by default. + * + * @property schema + * @type {String} + */ + this.schema = cfg.schema || ""; + + /** + * The XKT format version. + * + * @property xktVersion; + * @type {number} + */ + this.xktVersion = XKT_INFO.xktVersion; + + /** + * + * @type {Number|number} + */ + this.edgeThreshold = cfg.edgeThreshold || 10; + + /** + * Minimum diagonal size of the boundary of an {@link XKTTile}. + * + * @type {Number|number} + */ + this.minTileSize = cfg.minTileSize || 500; + + /** + * Optional overall AABB that contains all the {@link XKTEntity}s we'll create in this model, if previously known. + * + * This is the AABB of a complete set of input files that are provided as a split-model set for conversion. + * + * This is used to help the {@link XKTTile.aabb}s within split models align neatly with each other, as we + * build them with a k-d tree in {@link XKTModel#finalize}. Without this, the AABBs of the different parts + * tend to misalign slightly, resulting in excess number of {@link XKTTile}s, which degrades memory and rendering + * performance when the XKT is viewer in the xeokit Viewer. + */ + this.modelAABB = cfg.modelAABB; + + /** + * Map of {@link XKTPropertySet}s within this XKTModel, each mapped to {@link XKTPropertySet#propertySetId}. + * + * Created by {@link XKTModel#createPropertySet}. + * + * @type {{String:XKTPropertySet}} + */ + this.propertySets = {}; + + /** + * {@link XKTPropertySet}s within this XKTModel. + * + * Each XKTPropertySet holds its position in this list in {@link XKTPropertySet#propertySetIndex}. + * + * Created by {@link XKTModel#finalize}. + * + * @type {XKTPropertySet[]} + */ + this.propertySetsList = []; + + /** + * Map of {@link XKTMetaObject}s within this XKTModel, each mapped to {@link XKTMetaObject#metaObjectId}. + * + * Created by {@link XKTModel#createMetaObject}. + * + * @type {{String:XKTMetaObject}} + */ + this.metaObjects = {}; + + /** + * {@link XKTMetaObject}s within this XKTModel. + * + * Each XKTMetaObject holds its position in this list in {@link XKTMetaObject#metaObjectIndex}. + * + * Created by {@link XKTModel#finalize}. + * + * @type {XKTMetaObject[]} + */ + this.metaObjectsList = []; + + /** + * The positions of all shared {@link XKTGeometry}s are de-quantized using this singular + * de-quantization matrix. + * + * This de-quantization matrix is generated from the collective Local-space boundary of the + * positions of all shared {@link XKTGeometry}s. + * + * @type {Float32Array} + */ + this.reusedGeometriesDecodeMatrix = new Float32Array(16); + + /** + * Map of {@link XKTGeometry}s within this XKTModel, each mapped to {@link XKTGeometry#geometryId}. + * + * Created by {@link XKTModel#createGeometry}. + * + * @type {{Number:XKTGeometry}} + */ + this.geometries = {}; + + /** + * List of {@link XKTGeometry}s within this XKTModel, in the order they were created. + * + * Each XKTGeometry holds its position in this list in {@link XKTGeometry#geometryIndex}. + * + * Created by {@link XKTModel#finalize}. + * + * @type {XKTGeometry[]} + */ + this.geometriesList = []; + + /** + * Map of {@link XKTTexture}s within this XKTModel, each mapped to {@link XKTTexture#textureId}. + * + * Created by {@link XKTModel#createTexture}. + * + * @type {{Number:XKTTexture}} + */ + this.textures = {}; + + /** + * List of {@link XKTTexture}s within this XKTModel, in the order they were created. + * + * Each XKTTexture holds its position in this list in {@link XKTTexture#textureIndex}. + * + * Created by {@link XKTModel#finalize}. + * + * @type {XKTTexture[]} + */ + this.texturesList = []; + + /** + * Map of {@link XKTTextureSet}s within this XKTModel, each mapped to {@link XKTTextureSet#textureSetId}. + * + * Created by {@link XKTModel#createTextureSet}. + * + * @type {{Number:XKTTextureSet}} + */ + this.textureSets = {}; + + /** + * List of {@link XKTTextureSet}s within this XKTModel, in the order they were created. + * + * Each XKTTextureSet holds its position in this list in {@link XKTTextureSet#textureSetIndex}. + * + * Created by {@link XKTModel#finalize}. + * + * @type {XKTTextureSet[]} + */ + this.textureSetsList = []; + + /** + * Map of {@link XKTMesh}s within this XKTModel, each mapped to {@link XKTMesh#meshId}. + * + * Created by {@link XKTModel#createMesh}. + * + * @type {{Number:XKTMesh}} + */ + this.meshes = {}; + + /** + * List of {@link XKTMesh}s within this XKTModel, in the order they were created. + * + * Each XKTMesh holds its position in this list in {@link XKTMesh#meshIndex}. + * + * Created by {@link XKTModel#finalize}. + * + * @type {XKTMesh[]} + */ + this.meshesList = []; + + /** + * Map of {@link XKTEntity}s within this XKTModel, each mapped to {@link XKTEntity#entityId}. + * + * Created by {@link XKTModel#createEntity}. + * + * @type {{String:XKTEntity}} + */ + this.entities = {}; + + /** + * {@link XKTEntity}s within this XKTModel. + * + * Each XKTEntity holds its position in this list in {@link XKTEntity#entityIndex}. + * + * Created by {@link XKTModel#finalize}. + * + * @type {XKTEntity[]} + */ + this.entitiesList = []; + + /** + * {@link XKTTile}s within this XKTModel. + * + * Created by {@link XKTModel#finalize}. + * + * @type {XKTTile[]} + */ + this.tilesList = []; + + /** + * The axis-aligned 3D World-space boundary of this XKTModel. + * + * Created by {@link XKTModel#finalize}. + * + * @type {Float64Array} + */ + this.aabb = math.AABB3(); + + /** + * Indicates if this XKTModel has been finalized. + * + * Set ````true```` by {@link XKTModel#finalize}. + * + * @type {boolean} + */ + this.finalized = false; + } + + /** + * Creates an {@link XKTPropertySet} within this XKTModel. + * + * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}). + * + * @param {*} params Method parameters. + * @param {String} params.propertySetId Unique ID for the {@link XKTPropertySet}. + * @param {String} [params.propertySetType="default"] A meta type for the {@link XKTPropertySet}. + * @param {String} [params.propertySetName] Human-readable name for the {@link XKTPropertySet}. Defaults to the ````propertySetId```` parameter. + * @param {String[]} params.properties Properties for the {@link XKTPropertySet}. + * @returns {XKTPropertySet} The new {@link XKTPropertySet}. + */ + createPropertySet(params) { + + if (!params) { + throw "Parameters expected: params"; + } + + if (params.propertySetId === null || params.propertySetId === undefined) { + throw "Parameter expected: params.propertySetId"; + } + + if (params.properties === null || params.properties === undefined) { + throw "Parameter expected: params.properties"; + } + + if (this.finalized) { + console.error("XKTModel has been finalized, can't add more property sets"); + return; + } + + if (this.propertySets[params.propertySetId]) { + // console.error("XKTPropertySet already exists with this ID: " + params.propertySetId); + return; + } + + const propertySetId = params.propertySetId; + const propertySetType = params.propertySetType || "Default"; + const propertySetName = params.propertySetName || params.propertySetId; + const properties = params.properties || []; + + const propertySet = new XKTPropertySet(propertySetId, propertySetType, propertySetName, properties); + + this.propertySets[propertySetId] = propertySet; + this.propertySetsList.push(propertySet); + + return propertySet; + } + + /** + * Creates an {@link XKTMetaObject} within this XKTModel. + * + * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}). + * + * @param {*} params Method parameters. + * @param {String} params.metaObjectId Unique ID for the {@link XKTMetaObject}. + * @param {String} params.propertySetIds ID of one or more property sets that contains additional metadata about + * this {@link XKTMetaObject}. The property sets could be stored externally (ie not managed at all by the XKT file), + * or could be {@link XKTPropertySet}s within {@link XKTModel#propertySets}. + * @param {String} [params.metaObjectType="default"] A meta type for the {@link XKTMetaObject}. Can be anything, + * but is usually an IFC type, such as "IfcSite" or "IfcWall". + * @param {String} [params.metaObjectName] Human-readable name for the {@link XKTMetaObject}. Defaults to the ````metaObjectId```` parameter. + * @param {String} [params.parentMetaObjectId] ID of the parent {@link XKTMetaObject}, if any. Defaults to the ````metaObjectId```` parameter. + * @returns {XKTMetaObject} The new {@link XKTMetaObject}. + */ + createMetaObject(params) { + + if (!params) { + throw "Parameters expected: params"; + } + + if (params.metaObjectId === null || params.metaObjectId === undefined) { + throw "Parameter expected: params.metaObjectId"; + } + + if (this.finalized) { + console.error("XKTModel has been finalized, can't add more meta objects"); + return; + } + + if (this.metaObjects[params.metaObjectId]) { + // console.error("XKTMetaObject already exists with this ID: " + params.metaObjectId); + return; + } + + const metaObjectId = params.metaObjectId; + const propertySetIds = params.propertySetIds; + const metaObjectType = params.metaObjectType || "Default"; + const metaObjectName = params.metaObjectName || params.metaObjectId; + const parentMetaObjectId = params.parentMetaObjectId; + + const metaObject = new XKTMetaObject(metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId); + + this.metaObjects[metaObjectId] = metaObject; + this.metaObjectsList.push(metaObject); + + if (!parentMetaObjectId) { + if (!this._rootMetaObject) { + this._rootMetaObject = metaObject; + } + } + + return metaObject; + } + + /** + * Creates an {@link XKTTexture} within this XKTModel. + * + * Registers the new {@link XKTTexture} in {@link XKTModel#textures} and {@link XKTModel#texturesList}. + * + * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}). + * + * @param {*} params Method parameters. + * @param {Number} params.textureId Unique ID for the {@link XKTTexture}. + * @param {String} [params.src] Source of an image file for the texture. + * @param {Buffer} [params.imageData] Image data for the texture. + * @param {Number} [params.mediaType] Media type (ie. MIME type) of ````imageData````. Supported values are {@link GIFMediaType}, {@link PNGMediaType} and {@link JPEGMediaType}. + * @param {Number} [params.width] Texture width, used with ````imageData````. Ignored for compressed textures. + * @param {Number} [params.height] Texture height, used with ````imageData````. Ignored for compressed textures. + * @param {Boolean} [params.compressed=true] Whether to compress the texture. + * @param {Number} [params.minFilter=LinearMipMapNearestFilter] How the texture is sampled when a texel covers less than one pixel. Supported + * values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter}, + * {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}. Ignored for compressed textures. + * @param {Number} [params.magFilter=LinearMipMapNearestFilter] How the texture is sampled when a texel covers more than one pixel. Supported values + * are {@link LinearFilter} and {@link NearestFilter}. Ignored for compressed textures. + * @param {Number} [params.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping}, + * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures. + * @param {Number} [params.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping}, + * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures. + * {@param {Number} [params.wrapR=RepeatWrapping] Wrap parameter for texture coordinate *R*. Supported values are {@link ClampToEdgeWrapping}, + * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures. + * @returns {XKTTexture} The new {@link XKTTexture}. + */ + createTexture(params) { + + if (!params) { + throw "Parameters expected: params"; + } + + if (params.textureId === null || params.textureId === undefined) { + throw "Parameter expected: params.textureId"; + } + + if (!params.imageData && !params.src) { + throw "Parameter expected: params.imageData or params.src"; + } + + if (this.finalized) { + console.error("XKTModel has been finalized, can't add more textures"); + return; + } + + if (this.textures[params.textureId]) { + console.error("XKTTexture already exists with this ID: " + params.textureId); + return; + } + + if (params.src) { + const fileExt = params.src.split('.').pop(); + if (fileExt !== "jpg" && fileExt !== "jpeg" && fileExt !== "png") { + console.error(`XKTModel does not support image files with extension '${fileExt}' - won't create texture '${params.textureId}`); + return; + } + } + + const textureId = params.textureId; + + const texture = new XKTTexture({ + textureId, + imageData: params.imageData, + mediaType: params.mediaType, + minFilter: params.minFilter, + magFilter: params.magFilter, + wrapS: params.wrapS, + wrapT: params.wrapT, + wrapR: params.wrapR, + width: params.width, + height: params.height, + compressed: (params.compressed !== false), + src: params.src + }); + + this.textures[textureId] = texture; + this.texturesList.push(texture); + + return texture; + } + + /** + * Creates an {@link XKTTextureSet} within this XKTModel. + * + * Registers the new {@link XKTTextureSet} in {@link XKTModel#textureSets} and {@link XKTModel#.textureSetsList}. + * + * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}). + * + * @param {*} params Method parameters. + * @param {Number} params.textureSetId Unique ID for the {@link XKTTextureSet}. + * @param {*} [params.colorTextureId] ID of *RGBA* base color {@link XKTTexture}, with color in *RGB* and alpha in *A*. + * @param {*} [params.metallicRoughnessTextureId] ID of *RGBA* metal-roughness {@link XKTTexture}, with the metallic factor in *R*, and roughness factor in *G*. + * @param {*} [params.normalsTextureId] ID of *RGBA* normal {@link XKTTexture}, with normal map vectors in *RGB*. + * @param {*} [params.emissiveTextureId] ID of *RGBA* emissive {@link XKTTexture}, with emissive color in *RGB*. + * @param {*} [params.occlusionTextureId] ID of *RGBA* occlusion {@link XKTTexture}, with occlusion factor in *R*. + * @returns {XKTTextureSet} The new {@link XKTTextureSet}. + */ + createTextureSet(params) { + + if (!params) { + throw "Parameters expected: params"; + } + + if (params.textureSetId === null || params.textureSetId === undefined) { + throw "Parameter expected: params.textureSetId"; + } + + if (this.finalized) { + console.error("XKTModel has been finalized, can't add more textureSets"); + return; + } + + if (this.textureSets[params.textureSetId]) { + console.error("XKTTextureSet already exists with this ID: " + params.textureSetId); + return; + } + + let colorTexture; + if (params.colorTextureId !== undefined && params.colorTextureId !== null) { + colorTexture = this.textures[params.colorTextureId]; + if (!colorTexture) { + console.error(`Texture not found: ${params.colorTextureId} - ensure that you create it first with createTexture()`); + return; + } + colorTexture.channel = COLOR_TEXTURE; + } + + let metallicRoughnessTexture; + if (params.metallicRoughnessTextureId !== undefined && params.metallicRoughnessTextureId !== null) { + metallicRoughnessTexture = this.textures[params.metallicRoughnessTextureId]; + if (!metallicRoughnessTexture) { + console.error(`Texture not found: ${params.metallicRoughnessTextureId} - ensure that you create it first with createTexture()`); + return; + } + metallicRoughnessTexture.channel = METALLIC_ROUGHNESS_TEXTURE; + } + + let normalsTexture; + if (params.normalsTextureId !== undefined && params.normalsTextureId !== null) { + normalsTexture = this.textures[params.normalsTextureId]; + if (!normalsTexture) { + console.error(`Texture not found: ${params.normalsTextureId} - ensure that you create it first with createTexture()`); + return; + } + normalsTexture.channel = NORMALS_TEXTURE; + } + + let emissiveTexture; + if (params.emissiveTextureId !== undefined && params.emissiveTextureId !== null) { + emissiveTexture = this.textures[params.emissiveTextureId]; + if (!emissiveTexture) { + console.error(`Texture not found: ${params.emissiveTextureId} - ensure that you create it first with createTexture()`); + return; + } + emissiveTexture.channel = EMISSIVE_TEXTURE; + } + + let occlusionTexture; + if (params.occlusionTextureId !== undefined && params.occlusionTextureId !== null) { + occlusionTexture = this.textures[params.occlusionTextureId]; + if (!occlusionTexture) { + console.error(`Texture not found: ${params.occlusionTextureId} - ensure that you create it first with createTexture()`); + return; + } + occlusionTexture.channel = OCCLUSION_TEXTURE; + } + + const textureSet = new XKTTextureSet({ + textureSetId: params.textureSetId, + textureSetIndex: this.textureSetsList.length, + colorTexture, + metallicRoughnessTexture, + normalsTexture, + emissiveTexture, + occlusionTexture + }); + + this.textureSets[params.textureSetId] = textureSet; + this.textureSetsList.push(textureSet); + + return textureSet; + } + + /** + * Creates an {@link XKTGeometry} within this XKTModel. + * + * Registers the new {@link XKTGeometry} in {@link XKTModel#geometries} and {@link XKTModel#geometriesList}. + * + * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}). + * + * @param {*} params Method parameters. + * @param {Number} params.geometryId Unique ID for the {@link XKTGeometry}. + * @param {String} params.primitiveType The type of {@link XKTGeometry}: "triangles", "lines" or "points". + * @param {Float64Array} params.positions Floating-point Local-space vertex positions for the {@link XKTGeometry}. Required for all primitive types. + * @param {Number[]} [params.normals] Floating-point vertex normals for the {@link XKTGeometry}. Only used with triangles primitives. Ignored for points and lines. + * @param {Number[]} [params.colors] Floating-point RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles. + * @param {Number[]} [params.colorsCompressed] Integer RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles. + * @param {Number[]} [params.uvs] Floating-point vertex UV coordinates for the {@link XKTGeometry}. Alias for ````uv````. + * @param {Number[]} [params.uv] Floating-point vertex UV coordinates for the {@link XKTGeometry}. Alias for ````uvs````. + * @param {Number[]} [params.colorsCompressed] Integer RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles. + * @param {Uint32Array} [params.indices] Indices for the {@link XKTGeometry}. Required for triangles and lines primitives. Ignored for points. + * @param {Number} [params.edgeThreshold=10] + * @returns {XKTGeometry} The new {@link XKTGeometry}. + */ + createGeometry(params) { + + if (!params) { + throw "Parameters expected: params"; + } + + if (params.geometryId === null || params.geometryId === undefined) { + throw "Parameter expected: params.geometryId"; + } + + if (!params.primitiveType) { + throw "Parameter expected: params.primitiveType"; + } + + if (!params.positions) { + throw "Parameter expected: params.positions"; + } + + const triangles = params.primitiveType === "triangles"; + const points = params.primitiveType === "points"; + const lines = params.primitiveType === "lines"; + const line_strip = params.primitiveType === "line-strip"; + const line_loop = params.primitiveType === "line-loop"; + params.primitiveType === "triangle-strip"; + params.primitiveType === "triangle-fan"; + + if (!triangles && !points && !lines && !line_strip && !line_loop) { + throw "Unsupported value for params.primitiveType: " + + params.primitiveType + + "' - supported values are 'triangles', 'points', 'lines', 'line-strip', 'triangle-strip' and 'triangle-fan"; + } + + if (triangles) { + if (!params.indices) { + params.indices = this._createDefaultIndices(); + throw "Parameter expected for 'triangles' primitive: params.indices"; + } + } + + if (points) { + if (!params.colors && !params.colorsCompressed) { + throw "Parameter expected for 'points' primitive: params.colors or params.colorsCompressed"; + } + } + + if (lines) { + if (!params.indices) { + throw "Parameter expected for 'lines' primitive: params.indices"; + } + } + + if (this.finalized) { + console.error("XKTModel has been finalized, can't add more geometries"); + return; + } + + if (this.geometries[params.geometryId]) { + console.error("XKTGeometry already exists with this ID: " + params.geometryId); + return; + } + + const geometryId = params.geometryId; + const primitiveType = params.primitiveType; + const positions = new Float64Array(params.positions); // May modify in #finalize + + const xktGeometryCfg = { + geometryId: geometryId, + geometryIndex: this.geometriesList.length, + primitiveType: primitiveType, + positions: positions, + uvs: params.uvs || params.uv + }; + + if (triangles) { + if (params.normals) { + xktGeometryCfg.normals = new Float32Array(params.normals); + } + if (params.indices) { + xktGeometryCfg.indices = params.indices; + } else { + xktGeometryCfg.indices = this._createDefaultIndices(positions.length / 3); + } + } + + if (points) { + if (params.colorsCompressed) { + xktGeometryCfg.colorsCompressed = new Uint8Array(params.colorsCompressed); + + } else { + const colors = params.colors; + const colorsCompressed = new Uint8Array(colors.length); + for (let i = 0, len = colors.length; i < len; i++) { + colorsCompressed[i] = Math.floor(colors[i] * 255); + } + xktGeometryCfg.colorsCompressed = colorsCompressed; + } + } + + if (lines) { + xktGeometryCfg.indices = params.indices; + } + + if (triangles) { + + if (!params.normals && !params.uv && !params.uvs) { + + // Building models often duplicate positions to allow face-aligned vertex normals; when we're not + // providing normals for a geometry, it becomes possible to merge duplicate vertex positions within it. + + // TODO: Make vertex merging also merge normals? + + const mergedPositions = []; + const mergedIndices = []; + mergeVertices(xktGeometryCfg.positions, xktGeometryCfg.indices, mergedPositions, mergedIndices); + xktGeometryCfg.positions = new Float64Array(mergedPositions); + xktGeometryCfg.indices = mergedIndices; + } + + xktGeometryCfg.edgeIndices = buildEdgeIndices(xktGeometryCfg.positions, xktGeometryCfg.indices, null, params.edgeThreshold || this.edgeThreshold || 10); + } + + const geometry = new XKTGeometry(xktGeometryCfg); + + this.geometries[geometryId] = geometry; + this.geometriesList.push(geometry); + + return geometry; + } + + _createDefaultIndices(numIndices) { + const indices = []; + for (let i = 0; i < numIndices; i++) { + indices.push(i); + } + return indices; + } + + /** + * Creates an {@link XKTMesh} within this XKTModel. + * + * An {@link XKTMesh} can be owned by one {@link XKTEntity}, which can own multiple {@link XKTMesh}es. + * + * Registers the new {@link XKTMesh} in {@link XKTModel#meshes} and {@link XKTModel#meshesList}. + * + * @param {*} params Method parameters. + * @param {Number} params.meshId Unique ID for the {@link XKTMesh}. + * @param {Number} params.geometryId ID of an existing {@link XKTGeometry} in {@link XKTModel#geometries}. + * @param {Number} [params.textureSetId] Unique ID of an {@link XKTTextureSet} in {@link XKTModel#textureSets}. + * @param {Float32Array} params.color RGB color for the {@link XKTMesh}, with each color component in range [0..1]. + * @param {Number} [params.metallic=0] How metallic the {@link XKTMesh} is, in range [0..1]. A value of ````0```` indicates fully dielectric material, while ````1```` indicates fully metallic. + * @param {Number} [params.roughness=1] How rough the {@link XKTMesh} is, in range [0..1]. A value of ````0```` indicates fully smooth, while ````1```` indicates fully rough. + * @param {Number} params.opacity Opacity factor for the {@link XKTMesh}, in range [0..1]. + * @param {Float64Array} [params.matrix] Modeling matrix for the {@link XKTMesh}. Overrides ````position````, ````scale```` and ````rotation```` parameters. + * @param {Number[]} [params.position=[0,0,0]] Position of the {@link XKTMesh}. Overridden by the ````matrix```` parameter. + * @param {Number[]} [params.scale=[1,1,1]] Scale of the {@link XKTMesh}. Overridden by the ````matrix```` parameter. + * @param {Number[]} [params.rotation=[0,0,0]] Rotation of the {@link XKTMesh} as Euler angles given in degrees, for each of the X, Y and Z axis. Overridden by the ````matrix```` parameter. + * @returns {XKTMesh} The new {@link XKTMesh}. + */ + createMesh(params) { + + if (params.meshId === null || params.meshId === undefined) { + throw "Parameter expected: params.meshId"; + } + + if (params.geometryId === null || params.geometryId === undefined) { + throw "Parameter expected: params.geometryId"; + } + + if (this.finalized) { + throw "XKTModel has been finalized, can't add more meshes"; + } + + if (this.meshes[params.meshId]) { + console.error("XKTMesh already exists with this ID: " + params.meshId); + return; + } + + const geometry = this.geometries[params.geometryId]; + + if (!geometry) { + console.error("XKTGeometry not found: " + params.geometryId); + return; + } + + geometry.numInstances++; + + let textureSet = null; + if (params.textureSetId) { + textureSet = this.textureSets[params.textureSetId]; + if (!textureSet) { + console.error("XKTTextureSet not found: " + params.textureSetId); + return; + } + textureSet.numInstances++; + } + + let matrix = params.matrix; + + if (!matrix) { + + const position = params.position; + const scale = params.scale; + const rotation = params.rotation; + + if (position || scale || rotation) { + matrix = math.identityMat4(); + const quaternion = math.eulerToQuaternion(rotation || [0, 0, 0], "XYZ", math.identityQuaternion()); + math.composeMat4(position || [0, 0, 0], quaternion, scale || [1, 1, 1], matrix); + + } else { + matrix = math.identityMat4(); + } + } + + const meshIndex = this.meshesList.length; + + const mesh = new XKTMesh({ + meshId: params.meshId, + meshIndex, + matrix, + geometry, + color: params.color, + metallic: params.metallic, + roughness: params.roughness, + opacity: params.opacity, + textureSet + }); + + this.meshes[mesh.meshId] = mesh; + this.meshesList.push(mesh); + + return mesh; + } + + /** + * Creates an {@link XKTEntity} within this XKTModel. + * + * Registers the new {@link XKTEntity} in {@link XKTModel#entities} and {@link XKTModel#entitiesList}. + * + * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}). + * + * @param {*} params Method parameters. + * @param {String} params.entityId Unique ID for the {@link XKTEntity}. + * @param {String[]} params.meshIds IDs of {@link XKTMesh}es used by the {@link XKTEntity}. Note that each {@link XKTMesh} can only be used by one {@link XKTEntity}. + * @returns {XKTEntity} The new {@link XKTEntity}. + */ + createEntity(params) { + + if (!params) { + throw "Parameters expected: params"; + } + + if (params.entityId === null || params.entityId === undefined) { + throw "Parameter expected: params.entityId"; + } + + if (!params.meshIds) { + throw "Parameter expected: params.meshIds"; + } + + if (this.finalized) { + console.error("XKTModel has been finalized, can't add more entities"); + return; + } + + if (params.meshIds.length === 0) { + console.warn("XKTEntity has no meshes - won't create: " + params.entityId); + return; + } + + let entityId = params.entityId; + + if (this.entities[entityId]) { + while (this.entities[entityId]) { + entityId = math.createUUID(); + } + console.error("XKTEntity already exists with this ID: " + params.entityId + " - substituting random ID instead: " + entityId); + } + + const meshIds = params.meshIds; + const meshes = []; + + for (let meshIdIdx = 0, meshIdLen = meshIds.length; meshIdIdx < meshIdLen; meshIdIdx++) { + + const meshId = meshIds[meshIdIdx]; + const mesh = this.meshes[meshId]; + + if (!mesh) { + console.error("XKTMesh found: " + meshId); + continue; + } + + if (mesh.entity) { + console.error("XKTMesh " + meshId + " already used by XKTEntity " + mesh.entity.entityId); + continue; + } + + meshes.push(mesh); + } + + const entity = new XKTEntity(entityId, meshes); + + for (let i = 0, len = meshes.length; i < len; i++) { + const mesh = meshes[i]; + mesh.entity = entity; + } + + this.entities[entityId] = entity; + this.entitiesList.push(entity); + + return entity; + } + + /** + * Creates a default {@link XKTMetaObject} for each {@link XKTEntity} that does not already have one. + */ + createDefaultMetaObjects() { + + for (let i = 0, len = this.entitiesList.length; i < len; i++) { + + const entity = this.entitiesList[i]; + const metaObjectId = entity.entityId; + const metaObject = this.metaObjects[metaObjectId]; + + if (!metaObject) { + + if (!this._rootMetaObject) { + this._rootMetaObject = this.createMetaObject({ + metaObjectId: this.modelId, + metaObjectType: "Default", + metaObjectName: this.modelId + }); + } + + this.createMetaObject({ + metaObjectId: metaObjectId, + metaObjectType: "Default", + metaObjectName: "" + metaObjectId, + parentMetaObjectId: this._rootMetaObject.metaObjectId + }); + } + } + } + + /** + * Finalizes this XKTModel. + * + * After finalizing, we may then serialize the model to an array buffer using {@link writeXKTModelToArrayBuffer}. + * + * Logs error and does nothing if this XKTModel has already been finalized. + * + * Internally, this method: + * + * * for each {@link XKTEntity} that doesn't already have a {@link XKTMetaObject}, creates one with {@link XKTMetaObject#metaObjectType} set to "default" + * * sets each {@link XKTEntity}'s {@link XKTEntity#hasReusedGeometries} true if it shares its {@link XKTGeometry}s with other {@link XKTEntity}s, + * * creates each {@link XKTEntity}'s {@link XKTEntity#aabb}, + * * creates {@link XKTTile}s in {@link XKTModel#tilesList}, and + * * sets {@link XKTModel#finalized} ````true````. + */ + async finalize() { + + if (this.finalized) { + console.log("XKTModel already finalized"); + return; + } + + this._removeUnusedTextures(); + + await this._compressTextures(); + + this._bakeSingleUseGeometryPositions(); + + this._bakeAndOctEncodeNormals(); + + this._createEntityAABBs(); + + const rootKDNode = this._createKDTree(); + + this.entitiesList = []; + + this._createTilesFromKDTree(rootKDNode); + + this._createReusedGeometriesDecodeMatrix(); + + this._flagSolidGeometries(); + + this.aabb.set(rootKDNode.aabb); + + this.finalized = true; + } + + _removeUnusedTextures() { + let texturesList = []; + const textures = {}; + for (let i = 0, leni = this.texturesList.length; i < leni; i++) { + const texture = this.texturesList[i]; + if (texture.channel !== null) { + texture.textureIndex = texturesList.length; + texturesList.push(texture); + textures[texture.textureId] = texture; + } + } + this.texturesList = texturesList; + this.textures = textures; + } + + _compressTextures() { + let countTextures = this.texturesList.length; + return new Promise((resolve) => { + if (countTextures === 0) { + resolve(); + return; + } + for (let i = 0, leni = this.texturesList.length; i < leni; i++) { + const texture = this.texturesList[i]; + const encodingOptions = TEXTURE_ENCODING_OPTIONS[texture.channel] || {}; + + if (texture.src) { + + // XKTTexture created with XKTModel#createTexture({ src: ... }) + + const src = texture.src; + const fileExt = src.split('.').pop(); + switch (fileExt) { + case "jpeg": + case "jpg": + case "png": + load(src, ImageLoader, { + image: { + type: "data" + } + }).then((imageData) => { + if (texture.compressed) { + encode$4(imageData, KTX2BasisWriter, encodingOptions).then((encodedData) => { + const encodedImageData = new Uint8Array(encodedData); + texture.imageData = encodedImageData; + if (--countTextures <= 0) { + resolve(); + } + }).catch((err) => { + console.error("[XKTModel.finalize] Failed to encode image: " + err); + if (--countTextures <= 0) { + resolve(); + } + }); + } else { + texture.imageData = new Uint8Array(1); + if (--countTextures <= 0) { + resolve(); + } + } + }).catch((err) => { + console.error("[XKTModel.finalize] Failed to load image: " + err); + if (--countTextures <= 0) { + resolve(); + } + }); + break; + default: + if (--countTextures <= 0) { + resolve(); + } + break; + } + } + + if (texture.imageData) { + + // XKTTexture created with XKTModel#createTexture({ imageData: ... }) + + if (texture.compressed) { + encode$4(texture.imageData, KTX2BasisWriter, encodingOptions) + .then((encodedImageData) => { + texture.imageData = new Uint8Array(encodedImageData); + if (--countTextures <= 0) { + resolve(); + } + }).catch((err) => { + console.error("[XKTModel.finalize] Failed to encode image: " + err); + if (--countTextures <= 0) { + resolve(); + } + }); + } else { + texture.imageData = new Uint8Array(1); + if (--countTextures <= 0) { + resolve(); + } + } + } + } + }); + } + + _bakeSingleUseGeometryPositions() { + + for (let j = 0, lenj = this.meshesList.length; j < lenj; j++) { + + const mesh = this.meshesList[j]; + + const geometry = mesh.geometry; + + if (geometry.numInstances === 1) { + + const matrix = mesh.matrix; + + if (matrix && (!math.isIdentityMat4(matrix))) { + + const positions = geometry.positions; + + for (let i = 0, len = positions.length; i < len; i += 3) { + + tempVec4a[0] = positions[i + 0]; + tempVec4a[1] = positions[i + 1]; + tempVec4a[2] = positions[i + 2]; + tempVec4a[3] = 1; + + math.transformPoint4(matrix, tempVec4a, tempVec4b); + + positions[i + 0] = tempVec4b[0]; + positions[i + 1] = tempVec4b[1]; + positions[i + 2] = tempVec4b[2]; + } + } + } + } + } + + _bakeAndOctEncodeNormals() { + + for (let i = 0, len = this.meshesList.length; i < len; i++) { + + const mesh = this.meshesList[i]; + const geometry = mesh.geometry; + + if (geometry.normals && !geometry.normalsOctEncoded) { + + geometry.normalsOctEncoded = new Int8Array(geometry.normals.length); + + if (geometry.numInstances > 1) { + geometryCompression.octEncodeNormals(geometry.normals, geometry.normals.length, geometry.normalsOctEncoded, 0); + + } else { + const modelNormalMatrix = math.inverseMat4(math.transposeMat4(mesh.matrix, tempMat4), tempMat4b); + geometryCompression.transformAndOctEncodeNormals(modelNormalMatrix, geometry.normals, geometry.normals.length, geometry.normalsOctEncoded, 0); + } + } + } + } + + _createEntityAABBs() { + + for (let i = 0, len = this.entitiesList.length; i < len; i++) { + + const entity = this.entitiesList[i]; + const entityAABB = entity.aabb; + const meshes = entity.meshes; + + math.collapseAABB3(entityAABB); + + for (let j = 0, lenj = meshes.length; j < lenj; j++) { + + const mesh = meshes[j]; + const geometry = mesh.geometry; + const matrix = mesh.matrix; + + if (geometry.numInstances > 1) { + + const positions = geometry.positions; + for (let i = 0, len = positions.length; i < len; i += 3) { + tempVec4a[0] = positions[i + 0]; + tempVec4a[1] = positions[i + 1]; + tempVec4a[2] = positions[i + 2]; + tempVec4a[3] = 1; + math.transformPoint4(matrix, tempVec4a, tempVec4b); + math.expandAABB3Point3(entityAABB, tempVec4b); + } + + } else { + + const positions = geometry.positions; + for (let i = 0, len = positions.length; i < len; i += 3) { + tempVec4a[0] = positions[i + 0]; + tempVec4a[1] = positions[i + 1]; + tempVec4a[2] = positions[i + 2]; + math.expandAABB3Point3(entityAABB, tempVec4a); + } + } + } + } + } + + _createKDTree() { + + let aabb; + if (this.modelAABB) { + aabb = this.modelAABB; // Pre-known uber AABB + } else { + aabb = math.collapseAABB3(); + for (let i = 0, len = this.entitiesList.length; i < len; i++) { + const entity = this.entitiesList[i]; + math.expandAABB3(aabb, entity.aabb); + } + } + + const rootKDNode = new KDNode(aabb); + + for (let i = 0, len = this.entitiesList.length; i < len; i++) { + const entity = this.entitiesList[i]; + this._insertEntityIntoKDTree(rootKDNode, entity); + } + + return rootKDNode; + } + + _insertEntityIntoKDTree(kdNode, entity) { + + const nodeAABB = kdNode.aabb; + const entityAABB = entity.aabb; + + const nodeAABBDiag = math.getAABB3Diag(nodeAABB); + + if (nodeAABBDiag < this.minTileSize) { + kdNode.entities = kdNode.entities || []; + kdNode.entities.push(entity); + math.expandAABB3(nodeAABB, entityAABB); + return; + } + + if (kdNode.left) { + if (math.containsAABB3(kdNode.left.aabb, entityAABB)) { + this._insertEntityIntoKDTree(kdNode.left, entity); + return; + } + } + + if (kdNode.right) { + if (math.containsAABB3(kdNode.right.aabb, entityAABB)) { + this._insertEntityIntoKDTree(kdNode.right, entity); + return; + } + } + + kdTreeDimLength[0] = nodeAABB[3] - nodeAABB[0]; + kdTreeDimLength[1] = nodeAABB[4] - nodeAABB[1]; + kdTreeDimLength[2] = nodeAABB[5] - nodeAABB[2]; + + let dim = 0; + + if (kdTreeDimLength[1] > kdTreeDimLength[dim]) { + dim = 1; + } + + if (kdTreeDimLength[2] > kdTreeDimLength[dim]) { + dim = 2; + } + + if (!kdNode.left) { + const aabbLeft = nodeAABB.slice(); + aabbLeft[dim + 3] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0); + kdNode.left = new KDNode(aabbLeft); + if (math.containsAABB3(aabbLeft, entityAABB)) { + this._insertEntityIntoKDTree(kdNode.left, entity); + return; + } + } + + if (!kdNode.right) { + const aabbRight = nodeAABB.slice(); + aabbRight[dim] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0); + kdNode.right = new KDNode(aabbRight); + if (math.containsAABB3(aabbRight, entityAABB)) { + this._insertEntityIntoKDTree(kdNode.right, entity); + return; + } + } + + kdNode.entities = kdNode.entities || []; + kdNode.entities.push(entity); + + math.expandAABB3(nodeAABB, entityAABB); + } + + _createTilesFromKDTree(rootKDNode) { + this._createTilesFromKDNode(rootKDNode); + } + + _createTilesFromKDNode(kdNode) { + if (kdNode.entities && kdNode.entities.length > 0) { + this._createTileFromEntities(kdNode); + } + if (kdNode.left) { + this._createTilesFromKDNode(kdNode.left); + } + if (kdNode.right) { + this._createTilesFromKDNode(kdNode.right); + } + } + + /** + * Creates a tile from the given entities. + * + * For each single-use {@link XKTGeometry}, this method centers {@link XKTGeometry#positions} to make them relative to the + * tile's center, then quantizes the positions to unsigned 16-bit integers, relative to the tile's boundary. + * + * @param kdNode + */ + _createTileFromEntities(kdNode) { + + const tileAABB = kdNode.aabb; + const entities = kdNode.entities; + + const tileCenter = math.getAABB3Center(tileAABB); + const tileCenterNeg = math.mulVec3Scalar(tileCenter, -1, math.vec3()); + + const rtcAABB = math.AABB3(); // AABB centered at the RTC origin + + rtcAABB[0] = tileAABB[0] - tileCenter[0]; + rtcAABB[1] = tileAABB[1] - tileCenter[1]; + rtcAABB[2] = tileAABB[2] - tileCenter[2]; + rtcAABB[3] = tileAABB[3] - tileCenter[0]; + rtcAABB[4] = tileAABB[4] - tileCenter[1]; + rtcAABB[5] = tileAABB[5] - tileCenter[2]; + + for (let i = 0; i < entities.length; i++) { + + const entity = entities [i]; + + const meshes = entity.meshes; + + for (let j = 0, lenj = meshes.length; j < lenj; j++) { + + const mesh = meshes[j]; + const geometry = mesh.geometry; + + if (!geometry.reused) { // Batched geometry + + const positions = geometry.positions; + + // Center positions relative to their tile's World-space center + + for (let k = 0, lenk = positions.length; k < lenk; k += 3) { + + positions[k + 0] -= tileCenter[0]; + positions[k + 1] -= tileCenter[1]; + positions[k + 2] -= tileCenter[2]; + } + + // Quantize positions relative to tile's RTC-space boundary + + geometryCompression.quantizePositions(positions, positions.length, rtcAABB, geometry.positionsQuantized); + + } else { // Instanced geometry + + // Post-multiply a translation to the mesh's modeling matrix + // to center the entity's geometry instances to the tile RTC center + + ////////////////////////////// + // Why do we do this? + // Seems to break various models + ///////////////////////////////// + + math.translateMat4v(tileCenterNeg, mesh.matrix); + } + } + + entity.entityIndex = this.entitiesList.length; + + this.entitiesList.push(entity); + } + + const tile = new XKTTile(tileAABB, entities); + + this.tilesList.push(tile); + } + + _createReusedGeometriesDecodeMatrix() { + + const tempVec3a = math.vec3(); + const reusedGeometriesAABB = math.collapseAABB3(math.AABB3()); + let countReusedGeometries = 0; + + for (let geometryIndex = 0, numGeometries = this.geometriesList.length; geometryIndex < numGeometries; geometryIndex++) { + + const geometry = this.geometriesList [geometryIndex]; + + if (geometry.reused) { // Instanced geometry + + const positions = geometry.positions; + + for (let i = 0, len = positions.length; i < len; i += 3) { + + tempVec3a[0] = positions[i]; + tempVec3a[1] = positions[i + 1]; + tempVec3a[2] = positions[i + 2]; + + math.expandAABB3Point3(reusedGeometriesAABB, tempVec3a); + } + + countReusedGeometries++; + } + } + + if (countReusedGeometries > 0) { + + geometryCompression.createPositionsDecodeMatrix(reusedGeometriesAABB, this.reusedGeometriesDecodeMatrix); + + for (let geometryIndex = 0, numGeometries = this.geometriesList.length; geometryIndex < numGeometries; geometryIndex++) { + + const geometry = this.geometriesList [geometryIndex]; + + if (geometry.reused) { + geometryCompression.quantizePositions(geometry.positions, geometry.positions.length, reusedGeometriesAABB, geometry.positionsQuantized); + } + } + + } else { + math.identityMat4(this.reusedGeometriesDecodeMatrix); // No need for this matrix, but we'll be tidy and set it to identity + } + } + + _flagSolidGeometries() { + let maxNumPositions = 0; + let maxNumIndices = 0; + for (let i = 0, len = this.geometriesList.length; i < len; i++) { + const geometry = this.geometriesList[i]; + if (geometry.primitiveType === "triangles") { + if (geometry.positionsQuantized.length > maxNumPositions) { + maxNumPositions = geometry.positionsQuantized.length; + } + if (geometry.indices.length > maxNumIndices) { + maxNumIndices = geometry.indices.length; + } + } + } + let vertexIndexMapping = new Array(maxNumPositions / 3); + let edges = new Array(maxNumIndices); + for (let i = 0, len = this.geometriesList.length; i < len; i++) { + const geometry = this.geometriesList[i]; + if (geometry.primitiveType === "triangles") { + geometry.solid = isTriangleMeshSolid(geometry.indices, geometry.positionsQuantized, vertexIndexMapping, edges); + } + } + } +} + +function isString(value) { + return (typeof value === 'string' || value instanceof String); +} + +function apply(o, o2) { + for (const name in o) { + if (o.hasOwnProperty(name)) { + o2[name] = o[name]; + } + } + return o2; +} + +/** + * @private + */ +const utils = { + isString, + apply +}; + +const VERSION$1 = "3.4.14" ; + +function assert$2(condition, message) { + if (!condition) { + throw new Error(message || 'assert failed: gltf'); + } +} + +function resolveUrl(url, options) { + const absolute = url.startsWith('data:') || url.startsWith('http:') || url.startsWith('https:'); + if (absolute) { + return url; + } + const baseUrl = options.baseUri || options.uri; + if (!baseUrl) { + throw new Error("'baseUri' must be provided to resolve relative url ".concat(url)); + } + return baseUrl.substr(0, baseUrl.lastIndexOf('/') + 1) + url; +} + +function getTypedArrayForBufferView(json, buffers, bufferViewIndex) { + const bufferView = json.bufferViews[bufferViewIndex]; + assert$2(bufferView); + const bufferIndex = bufferView.buffer; + const binChunk = buffers[bufferIndex]; + assert$2(binChunk); + const byteOffset = (bufferView.byteOffset || 0) + binChunk.byteOffset; + return new Uint8Array(binChunk.arrayBuffer, byteOffset, bufferView.byteLength); +} + +const TYPES = ['SCALAR', 'VEC2', 'VEC3', 'VEC4']; +const ARRAY_CONSTRUCTOR_TO_WEBGL_CONSTANT = [[Int8Array, 5120], [Uint8Array, 5121], [Int16Array, 5122], [Uint16Array, 5123], [Uint32Array, 5125], [Float32Array, 5126], [Float64Array, 5130]]; +const ARRAY_TO_COMPONENT_TYPE = new Map(ARRAY_CONSTRUCTOR_TO_WEBGL_CONSTANT); +const ATTRIBUTE_TYPE_TO_COMPONENTS = { + SCALAR: 1, + VEC2: 2, + VEC3: 3, + VEC4: 4, + MAT2: 4, + MAT3: 9, + MAT4: 16 +}; +const ATTRIBUTE_COMPONENT_TYPE_TO_BYTE_SIZE = { + 5120: 1, + 5121: 1, + 5122: 2, + 5123: 2, + 5125: 4, + 5126: 4 +}; +const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY = { + 5120: Int8Array, + 5121: Uint8Array, + 5122: Int16Array, + 5123: Uint16Array, + 5125: Uint32Array, + 5126: Float32Array +}; +function getAccessorTypeFromSize(size) { + const type = TYPES[size - 1]; + return type || TYPES[0]; +} +function getComponentTypeFromArray(typedArray) { + const componentType = ARRAY_TO_COMPONENT_TYPE.get(typedArray.constructor); + if (!componentType) { + throw new Error('Illegal typed array'); + } + return componentType; +} +function getAccessorArrayTypeAndLength(accessor, bufferView) { + const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType]; + const components = ATTRIBUTE_TYPE_TO_COMPONENTS[accessor.type]; + const bytesPerComponent = ATTRIBUTE_COMPONENT_TYPE_TO_BYTE_SIZE[accessor.componentType]; + const length = accessor.count * components; + const byteLength = accessor.count * components * bytesPerComponent; + assert$2(byteLength >= 0 && byteLength <= bufferView.byteLength); + return { + ArrayType, + length, + byteLength + }; +} + +const DEFAULT_GLTF_JSON = { + asset: { + version: '2.0', + generator: 'loaders.gl' + }, + buffers: [] +}; +class GLTFScenegraph { + constructor(gltf) { + _defineProperty(this, "gltf", void 0); + _defineProperty(this, "sourceBuffers", void 0); + _defineProperty(this, "byteLength", void 0); + this.gltf = gltf || { + json: { + ...DEFAULT_GLTF_JSON + }, + buffers: [] + }; + this.sourceBuffers = []; + this.byteLength = 0; + if (this.gltf.buffers && this.gltf.buffers[0]) { + this.byteLength = this.gltf.buffers[0].byteLength; + this.sourceBuffers = [this.gltf.buffers[0]]; + } + } + get json() { + return this.gltf.json; + } + getApplicationData(key) { + const data = this.json[key]; + return data; + } + getExtraData(key) { + const extras = this.json.extras || {}; + return extras[key]; + } + getExtension(extensionName) { + const isExtension = this.getUsedExtensions().find(name => name === extensionName); + const extensions = this.json.extensions || {}; + return isExtension ? extensions[extensionName] || true : null; + } + getRequiredExtension(extensionName) { + const isRequired = this.getRequiredExtensions().find(name => name === extensionName); + return isRequired ? this.getExtension(extensionName) : null; + } + getRequiredExtensions() { + return this.json.extensionsRequired || []; + } + getUsedExtensions() { + return this.json.extensionsUsed || []; + } + getRemovedExtensions() { + return this.json.extensionsRemoved || []; + } + getObjectExtension(object, extensionName) { + const extensions = object.extensions || {}; + return extensions[extensionName]; + } + getScene(index) { + return this.getObject('scenes', index); + } + getNode(index) { + return this.getObject('nodes', index); + } + getSkin(index) { + return this.getObject('skins', index); + } + getMesh(index) { + return this.getObject('meshes', index); + } + getMaterial(index) { + return this.getObject('materials', index); + } + getAccessor(index) { + return this.getObject('accessors', index); + } + getTexture(index) { + return this.getObject('textures', index); + } + getSampler(index) { + return this.getObject('samplers', index); + } + getImage(index) { + return this.getObject('images', index); + } + getBufferView(index) { + return this.getObject('bufferViews', index); + } + getBuffer(index) { + return this.getObject('buffers', index); + } + getObject(array, index) { + if (typeof index === 'object') { + return index; + } + const object = this.json[array] && this.json[array][index]; + if (!object) { + throw new Error("glTF file error: Could not find ".concat(array, "[").concat(index, "]")); + } + return object; + } + getTypedArrayForBufferView(bufferView) { + bufferView = this.getBufferView(bufferView); + const bufferIndex = bufferView.buffer; + const binChunk = this.gltf.buffers[bufferIndex]; + assert$2(binChunk); + const byteOffset = (bufferView.byteOffset || 0) + binChunk.byteOffset; + return new Uint8Array(binChunk.arrayBuffer, byteOffset, bufferView.byteLength); + } + getTypedArrayForAccessor(accessor) { + accessor = this.getAccessor(accessor); + const bufferView = this.getBufferView(accessor.bufferView); + const buffer = this.getBuffer(bufferView.buffer); + const arrayBuffer = buffer.data; + const { + ArrayType, + length + } = getAccessorArrayTypeAndLength(accessor, bufferView); + const byteOffset = bufferView.byteOffset + accessor.byteOffset; + return new ArrayType(arrayBuffer, byteOffset, length); + } + getTypedArrayForImageData(image) { + image = this.getAccessor(image); + const bufferView = this.getBufferView(image.bufferView); + const buffer = this.getBuffer(bufferView.buffer); + const arrayBuffer = buffer.data; + const byteOffset = bufferView.byteOffset || 0; + return new Uint8Array(arrayBuffer, byteOffset, bufferView.byteLength); + } + addApplicationData(key, data) { + this.json[key] = data; + return this; + } + addExtraData(key, data) { + this.json.extras = this.json.extras || {}; + this.json.extras[key] = data; + return this; + } + addObjectExtension(object, extensionName, data) { + object.extensions = object.extensions || {}; + object.extensions[extensionName] = data; + this.registerUsedExtension(extensionName); + return this; + } + setObjectExtension(object, extensionName, data) { + const extensions = object.extensions || {}; + extensions[extensionName] = data; + } + removeObjectExtension(object, extensionName) { + const extensions = object.extensions || {}; + const extension = extensions[extensionName]; + delete extensions[extensionName]; + return extension; + } + addExtension(extensionName) { + let extensionData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + assert$2(extensionData); + this.json.extensions = this.json.extensions || {}; + this.json.extensions[extensionName] = extensionData; + this.registerUsedExtension(extensionName); + return extensionData; + } + addRequiredExtension(extensionName) { + let extensionData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + assert$2(extensionData); + this.addExtension(extensionName, extensionData); + this.registerRequiredExtension(extensionName); + return extensionData; + } + registerUsedExtension(extensionName) { + this.json.extensionsUsed = this.json.extensionsUsed || []; + if (!this.json.extensionsUsed.find(ext => ext === extensionName)) { + this.json.extensionsUsed.push(extensionName); + } + } + registerRequiredExtension(extensionName) { + this.registerUsedExtension(extensionName); + this.json.extensionsRequired = this.json.extensionsRequired || []; + if (!this.json.extensionsRequired.find(ext => ext === extensionName)) { + this.json.extensionsRequired.push(extensionName); + } + } + removeExtension(extensionName) { + if (!this.getExtension(extensionName)) { + return; + } + if (this.json.extensionsRequired) { + this._removeStringFromArray(this.json.extensionsRequired, extensionName); + } + if (this.json.extensionsUsed) { + this._removeStringFromArray(this.json.extensionsUsed, extensionName); + } + if (this.json.extensions) { + delete this.json.extensions[extensionName]; + } + if (!Array.isArray(this.json.extensionsRemoved)) { + this.json.extensionsRemoved = []; + } + const extensionsRemoved = this.json.extensionsRemoved; + if (!extensionsRemoved.includes(extensionName)) { + extensionsRemoved.push(extensionName); + } + } + setDefaultScene(sceneIndex) { + this.json.scene = sceneIndex; + } + addScene(scene) { + const { + nodeIndices + } = scene; + this.json.scenes = this.json.scenes || []; + this.json.scenes.push({ + nodes: nodeIndices + }); + return this.json.scenes.length - 1; + } + addNode(node) { + const { + meshIndex, + matrix + } = node; + this.json.nodes = this.json.nodes || []; + const nodeData = { + mesh: meshIndex + }; + if (matrix) { + nodeData.matrix = matrix; + } + this.json.nodes.push(nodeData); + return this.json.nodes.length - 1; + } + addMesh(mesh) { + const { + attributes, + indices, + material, + mode = 4 + } = mesh; + const accessors = this._addAttributes(attributes); + const glTFMesh = { + primitives: [{ + attributes: accessors, + mode + }] + }; + if (indices) { + const indicesAccessor = this._addIndices(indices); + glTFMesh.primitives[0].indices = indicesAccessor; + } + if (Number.isFinite(material)) { + glTFMesh.primitives[0].material = material; + } + this.json.meshes = this.json.meshes || []; + this.json.meshes.push(glTFMesh); + return this.json.meshes.length - 1; + } + addPointCloud(attributes) { + const accessorIndices = this._addAttributes(attributes); + const glTFMesh = { + primitives: [{ + attributes: accessorIndices, + mode: 0 + }] + }; + this.json.meshes = this.json.meshes || []; + this.json.meshes.push(glTFMesh); + return this.json.meshes.length - 1; + } + addImage(imageData, mimeTypeOpt) { + const metadata = getBinaryImageMetadata(imageData); + const mimeType = mimeTypeOpt || (metadata === null || metadata === void 0 ? void 0 : metadata.mimeType); + const bufferViewIndex = this.addBufferView(imageData); + const glTFImage = { + bufferView: bufferViewIndex, + mimeType + }; + this.json.images = this.json.images || []; + this.json.images.push(glTFImage); + return this.json.images.length - 1; + } + addBufferView(buffer) { + const byteLength = buffer.byteLength; + assert$2(Number.isFinite(byteLength)); + this.sourceBuffers = this.sourceBuffers || []; + this.sourceBuffers.push(buffer); + const glTFBufferView = { + buffer: 0, + byteOffset: this.byteLength, + byteLength + }; + this.byteLength += padToNBytes(byteLength, 4); + this.json.bufferViews = this.json.bufferViews || []; + this.json.bufferViews.push(glTFBufferView); + return this.json.bufferViews.length - 1; + } + addAccessor(bufferViewIndex, accessor) { + const glTFAccessor = { + bufferView: bufferViewIndex, + type: getAccessorTypeFromSize(accessor.size), + componentType: accessor.componentType, + count: accessor.count, + max: accessor.max, + min: accessor.min + }; + this.json.accessors = this.json.accessors || []; + this.json.accessors.push(glTFAccessor); + return this.json.accessors.length - 1; + } + addBinaryBuffer(sourceBuffer) { + let accessor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { + size: 3 + }; + const bufferViewIndex = this.addBufferView(sourceBuffer); + let minMax = { + min: accessor.min, + max: accessor.max + }; + if (!minMax.min || !minMax.max) { + minMax = this._getAccessorMinMax(sourceBuffer, accessor.size); + } + const accessorDefaults = { + size: accessor.size, + componentType: getComponentTypeFromArray(sourceBuffer), + count: Math.round(sourceBuffer.length / accessor.size), + min: minMax.min, + max: minMax.max + }; + return this.addAccessor(bufferViewIndex, Object.assign(accessorDefaults, accessor)); + } + addTexture(texture) { + const { + imageIndex + } = texture; + const glTFTexture = { + source: imageIndex + }; + this.json.textures = this.json.textures || []; + this.json.textures.push(glTFTexture); + return this.json.textures.length - 1; + } + addMaterial(pbrMaterialInfo) { + this.json.materials = this.json.materials || []; + this.json.materials.push(pbrMaterialInfo); + return this.json.materials.length - 1; + } + createBinaryChunk() { + var _this$json, _this$json$buffers; + this.gltf.buffers = []; + const totalByteLength = this.byteLength; + const arrayBuffer = new ArrayBuffer(totalByteLength); + const targetArray = new Uint8Array(arrayBuffer); + let dstByteOffset = 0; + for (const sourceBuffer of this.sourceBuffers || []) { + dstByteOffset = copyToArray(sourceBuffer, targetArray, dstByteOffset); + } + if ((_this$json = this.json) !== null && _this$json !== void 0 && (_this$json$buffers = _this$json.buffers) !== null && _this$json$buffers !== void 0 && _this$json$buffers[0]) { + this.json.buffers[0].byteLength = totalByteLength; + } else { + this.json.buffers = [{ + byteLength: totalByteLength + }]; + } + this.gltf.binary = arrayBuffer; + this.sourceBuffers = [arrayBuffer]; + } + _removeStringFromArray(array, string) { + let found = true; + while (found) { + const index = array.indexOf(string); + if (index > -1) { + array.splice(index, 1); + } else { + found = false; + } + } + } + _addAttributes() { + let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const result = {}; + for (const attributeKey in attributes) { + const attributeData = attributes[attributeKey]; + const attrName = this._getGltfAttributeName(attributeKey); + const accessor = this.addBinaryBuffer(attributeData.value, attributeData); + result[attrName] = accessor; + } + return result; + } + _addIndices(indices) { + return this.addBinaryBuffer(indices, { + size: 1 + }); + } + _getGltfAttributeName(attributeName) { + switch (attributeName.toLowerCase()) { + case 'position': + case 'positions': + case 'vertices': + return 'POSITION'; + case 'normal': + case 'normals': + return 'NORMAL'; + case 'color': + case 'colors': + return 'COLOR_0'; + case 'texcoord': + case 'texcoords': + return 'TEXCOORD_0'; + default: + return attributeName; + } + } + _getAccessorMinMax(buffer, size) { + const result = { + min: null, + max: null + }; + if (buffer.length < size) { + return result; + } + result.min = []; + result.max = []; + const initValues = buffer.subarray(0, size); + for (const value of initValues) { + result.min.push(value); + result.max.push(value); + } + for (let index = size; index < buffer.length; index += size) { + for (let componentIndex = 0; componentIndex < size; componentIndex++) { + result.min[0 + componentIndex] = Math.min(result.min[0 + componentIndex], buffer[index + componentIndex]); + result.max[0 + componentIndex] = Math.max(result.max[0 + componentIndex], buffer[index + componentIndex]); + } + } + return result; + } +} + +const wasm_base = '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'; +const wasm_simd = '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'; +const detector = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 3, 2, 0, 0, 5, 3, 1, 0, 1, 12, 1, 0, 10, 22, 2, 12, 0, 65, 0, 65, 0, 65, 0, 252, 10, 0, 0, 11, 7, 0, 65, 0, 253, 15, 26, 11]); +const wasmpack = new Uint8Array([32, 0, 65, 253, 3, 1, 2, 34, 4, 106, 6, 5, 11, 8, 7, 20, 13, 33, 12, 16, 128, 9, 116, 64, 19, 113, 127, 15, 10, 21, 22, 14, 255, 66, 24, 54, 136, 107, 18, 23, 192, 26, 114, 118, 132, 17, 77, 101, 130, 144, 27, 87, 131, 44, 45, 74, 156, 154, 70, 167]); +const FILTERS = { + 0: '', + 1: 'meshopt_decodeFilterOct', + 2: 'meshopt_decodeFilterQuat', + 3: 'meshopt_decodeFilterExp', + NONE: '', + OCTAHEDRAL: 'meshopt_decodeFilterOct', + QUATERNION: 'meshopt_decodeFilterQuat', + EXPONENTIAL: 'meshopt_decodeFilterExp' +}; +const DECODERS = { + 0: 'meshopt_decodeVertexBuffer', + 1: 'meshopt_decodeIndexBuffer', + 2: 'meshopt_decodeIndexSequence', + ATTRIBUTES: 'meshopt_decodeVertexBuffer', + TRIANGLES: 'meshopt_decodeIndexBuffer', + INDICES: 'meshopt_decodeIndexSequence' +}; +async function meshoptDecodeGltfBuffer(target, count, size, source, mode) { + let filter = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'NONE'; + const instance = await loadWasmInstance(); + decode$7(instance, instance.exports[DECODERS[mode]], target, count, size, source, instance.exports[FILTERS[filter || 'NONE']]); +} +let wasmPromise; +async function loadWasmInstance() { + if (!wasmPromise) { + wasmPromise = loadWasmModule(); + } + return wasmPromise; +} +async function loadWasmModule() { + let wasm = wasm_base; + if (WebAssembly.validate(detector)) { + wasm = wasm_simd; + console.log('Warning: meshopt_decoder is using experimental SIMD support'); + } + const result = await WebAssembly.instantiate(unpack(wasm), {}); + await result.instance.exports.__wasm_call_ctors(); + return result.instance; +} +function unpack(data) { + const result = new Uint8Array(data.length); + for (let i = 0; i < data.length; ++i) { + const ch = data.charCodeAt(i); + result[i] = ch > 96 ? ch - 71 : ch > 64 ? ch - 65 : ch > 47 ? ch + 4 : ch > 46 ? 63 : 62; + } + let write = 0; + for (let i = 0; i < data.length; ++i) { + result[write++] = result[i] < 60 ? wasmpack[result[i]] : (result[i] - 60) * 64 + result[++i]; + } + return result.buffer.slice(0, write); +} +function decode$7(instance, fun, target, count, size, source, filter) { + const sbrk = instance.exports.sbrk; + const count4 = count + 3 & ~3; + const tp = sbrk(count4 * size); + const sp = sbrk(source.length); + const heap = new Uint8Array(instance.exports.memory.buffer); + heap.set(source, sp); + const res = fun(tp, count, size, sp, source.length); + if (res === 0 && filter) { + filter(tp, count4, size); + } + target.set(heap.subarray(tp, tp + count * size)); + sbrk(tp - sbrk(0)); + if (res !== 0) { + throw new Error("Malformed buffer data: ".concat(res)); + } +} + +const EXT_MESHOPT_COMPRESSION = 'EXT_meshopt_compression'; +const name$8 = EXT_MESHOPT_COMPRESSION; +async function decode$6(gltfData, options) { + var _options$gltf; + const scenegraph = new GLTFScenegraph(gltfData); + if (!(options !== null && options !== void 0 && (_options$gltf = options.gltf) !== null && _options$gltf !== void 0 && _options$gltf.decompressMeshes)) { + return; + } + const promises = []; + for (const bufferViewIndex of gltfData.json.bufferViews || []) { + promises.push(decodeMeshoptBufferView(scenegraph, bufferViewIndex)); + } + await Promise.all(promises); + scenegraph.removeExtension(EXT_MESHOPT_COMPRESSION); +} +async function decodeMeshoptBufferView(scenegraph, bufferView) { + const meshoptExtension = scenegraph.getObjectExtension(bufferView, EXT_MESHOPT_COMPRESSION); + if (meshoptExtension) { + const { + byteOffset = 0, + byteLength = 0, + byteStride, + count, + mode, + filter = 'NONE', + buffer: bufferIndex + } = meshoptExtension; + const buffer = scenegraph.gltf.buffers[bufferIndex]; + const source = new Uint8Array(buffer.arrayBuffer, buffer.byteOffset + byteOffset, byteLength); + const result = new Uint8Array(scenegraph.gltf.buffers[bufferView.buffer].arrayBuffer, bufferView.byteOffset, bufferView.byteLength); + await meshoptDecodeGltfBuffer(result, count, byteStride, source, mode, filter); + return result; + } + return null; +} + +var EXT_meshopt_compression = /*#__PURE__*/Object.freeze({ + __proto__: null, + name: name$8, + decode: decode$6 +}); + +const EXT_TEXTURE_WEBP = 'EXT_texture_webp'; +const name$7 = EXT_TEXTURE_WEBP; +function preprocess$3(gltfData, options) { + const scenegraph = new GLTFScenegraph(gltfData); + if (!isImageFormatSupported('image/webp')) { + if (scenegraph.getRequiredExtensions().includes(EXT_TEXTURE_WEBP)) { + throw new Error("gltf: Required extension ".concat(EXT_TEXTURE_WEBP, " not supported by browser")); + } + return; + } + const { + json + } = scenegraph; + for (const texture of json.textures || []) { + const extension = scenegraph.getObjectExtension(texture, EXT_TEXTURE_WEBP); + if (extension) { + texture.source = extension.source; + } + scenegraph.removeObjectExtension(texture, EXT_TEXTURE_WEBP); + } + scenegraph.removeExtension(EXT_TEXTURE_WEBP); +} + +var EXT_texture_webp = /*#__PURE__*/Object.freeze({ + __proto__: null, + name: name$7, + preprocess: preprocess$3 +}); + +const KHR_TEXTURE_BASISU = 'KHR_texture_basisu'; +const name$6 = KHR_TEXTURE_BASISU; +function preprocess$2(gltfData, options) { + const scene = new GLTFScenegraph(gltfData); + const { + json + } = scene; + for (const texture of json.textures || []) { + const extension = scene.getObjectExtension(texture, KHR_TEXTURE_BASISU); + if (extension) { + texture.source = extension.source; + } + scene.removeObjectExtension(texture, KHR_TEXTURE_BASISU); + } + scene.removeExtension(KHR_TEXTURE_BASISU); +} + +var KHR_texture_basisu = /*#__PURE__*/Object.freeze({ + __proto__: null, + name: name$6, + preprocess: preprocess$2 +}); + +const VERSION = "3.4.14" ; + +const DEFAULT_DRACO_OPTIONS = { + draco: { + decoderType: typeof WebAssembly === 'object' ? 'wasm' : 'js', + libraryPath: 'libs/', + extraAttributes: {}, + attributeNameEntry: undefined + } +}; +const DracoLoader$1 = { + name: 'Draco', + id: isBrowser$1 ? 'draco' : 'draco-nodejs', + module: 'draco', + shapes: ['mesh'], + version: VERSION, + worker: true, + extensions: ['drc'], + mimeTypes: ['application/octet-stream'], + binary: true, + tests: ['DRACO'], + options: DEFAULT_DRACO_OPTIONS +}; + +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 len = positions && positions.length; + for (let i = 0; i < len; 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]]; +} + +function assert$1(condition, message) { + if (!condition) { + throw new Error(message || 'loader assertion failed.'); + } +} + +class Schema { + constructor(fields, metadata) { + _defineProperty(this, "fields", void 0); + _defineProperty(this, "metadata", void 0); + assert$1(Array.isArray(fields)); + checkNames(fields); + this.fields = fields; + this.metadata = metadata || new Map(); + } + compareTo(other) { + if (this.metadata !== other.metadata) { + return false; + } + if (this.fields.length !== other.fields.length) { + return false; + } + for (let i = 0; i < this.fields.length; ++i) { + if (!this.fields[i].compareTo(other.fields[i])) { + return false; + } + } + return true; + } + select() { + const nameMap = Object.create(null); + for (var _len = arguments.length, columnNames = new Array(_len), _key = 0; _key < _len; _key++) { + columnNames[_key] = arguments[_key]; + } + for (const name of columnNames) { + nameMap[name] = true; + } + const selectedFields = this.fields.filter(field => nameMap[field.name]); + return new Schema(selectedFields, this.metadata); + } + selectAt() { + for (var _len2 = arguments.length, columnIndices = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + columnIndices[_key2] = arguments[_key2]; + } + const selectedFields = columnIndices.map(index => this.fields[index]).filter(Boolean); + return new Schema(selectedFields, this.metadata); + } + assign(schemaOrFields) { + let fields; + let metadata = this.metadata; + if (schemaOrFields instanceof Schema) { + const otherSchema = schemaOrFields; + fields = otherSchema.fields; + metadata = mergeMaps(mergeMaps(new Map(), this.metadata), otherSchema.metadata); + } else { + fields = schemaOrFields; + } + const fieldMap = Object.create(null); + for (const field of this.fields) { + fieldMap[field.name] = field; + } + for (const field of fields) { + fieldMap[field.name] = field; + } + const mergedFields = Object.values(fieldMap); + return new Schema(mergedFields, metadata); + } +} +function checkNames(fields) { + const usedNames = {}; + for (const field of fields) { + if (usedNames[field.name]) { + console.warn('Schema: duplicated field name', field.name, field); + } + usedNames[field.name] = true; + } +} +function mergeMaps(m1, m2) { + return new Map([...(m1 || new Map()), ...(m2 || new Map())]); +} + +class Field { + constructor(name, type) { + let nullable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + let metadata = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new Map(); + _defineProperty(this, "name", void 0); + _defineProperty(this, "type", void 0); + _defineProperty(this, "nullable", void 0); + _defineProperty(this, "metadata", void 0); + this.name = name; + this.type = type; + this.nullable = nullable; + this.metadata = metadata; + } + get typeId() { + return this.type && this.type.typeId; + } + clone() { + return new Field(this.name, this.type, this.nullable, this.metadata); + } + compareTo(other) { + return this.name === other.name && this.type === other.type && this.nullable === other.nullable && this.metadata === other.metadata; + } + toString() { + return "".concat(this.type).concat(this.nullable ? ', nullable' : '').concat(this.metadata ? ", metadata: ".concat(this.metadata) : ''); + } +} + +let Type = function (Type) { + Type[Type["NONE"] = 0] = "NONE"; + Type[Type["Null"] = 1] = "Null"; + Type[Type["Int"] = 2] = "Int"; + Type[Type["Float"] = 3] = "Float"; + Type[Type["Binary"] = 4] = "Binary"; + Type[Type["Utf8"] = 5] = "Utf8"; + Type[Type["Bool"] = 6] = "Bool"; + Type[Type["Decimal"] = 7] = "Decimal"; + Type[Type["Date"] = 8] = "Date"; + Type[Type["Time"] = 9] = "Time"; + Type[Type["Timestamp"] = 10] = "Timestamp"; + Type[Type["Interval"] = 11] = "Interval"; + Type[Type["List"] = 12] = "List"; + Type[Type["Struct"] = 13] = "Struct"; + Type[Type["Union"] = 14] = "Union"; + Type[Type["FixedSizeBinary"] = 15] = "FixedSizeBinary"; + Type[Type["FixedSizeList"] = 16] = "FixedSizeList"; + Type[Type["Map"] = 17] = "Map"; + Type[Type["Dictionary"] = -1] = "Dictionary"; + Type[Type["Int8"] = -2] = "Int8"; + Type[Type["Int16"] = -3] = "Int16"; + Type[Type["Int32"] = -4] = "Int32"; + Type[Type["Int64"] = -5] = "Int64"; + Type[Type["Uint8"] = -6] = "Uint8"; + Type[Type["Uint16"] = -7] = "Uint16"; + Type[Type["Uint32"] = -8] = "Uint32"; + Type[Type["Uint64"] = -9] = "Uint64"; + Type[Type["Float16"] = -10] = "Float16"; + Type[Type["Float32"] = -11] = "Float32"; + Type[Type["Float64"] = -12] = "Float64"; + Type[Type["DateDay"] = -13] = "DateDay"; + Type[Type["DateMillisecond"] = -14] = "DateMillisecond"; + Type[Type["TimestampSecond"] = -15] = "TimestampSecond"; + Type[Type["TimestampMillisecond"] = -16] = "TimestampMillisecond"; + Type[Type["TimestampMicrosecond"] = -17] = "TimestampMicrosecond"; + Type[Type["TimestampNanosecond"] = -18] = "TimestampNanosecond"; + Type[Type["TimeSecond"] = -19] = "TimeSecond"; + Type[Type["TimeMillisecond"] = -20] = "TimeMillisecond"; + Type[Type["TimeMicrosecond"] = -21] = "TimeMicrosecond"; + Type[Type["TimeNanosecond"] = -22] = "TimeNanosecond"; + Type[Type["DenseUnion"] = -23] = "DenseUnion"; + Type[Type["SparseUnion"] = -24] = "SparseUnion"; + Type[Type["IntervalDayTime"] = -25] = "IntervalDayTime"; + Type[Type["IntervalYearMonth"] = -26] = "IntervalYearMonth"; + return Type; +}({}); + +let _Symbol$toStringTag, _Symbol$toStringTag2, _Symbol$toStringTag7; +class DataType { + static isNull(x) { + return x && x.typeId === Type.Null; + } + static isInt(x) { + return x && x.typeId === Type.Int; + } + static isFloat(x) { + return x && x.typeId === Type.Float; + } + static isBinary(x) { + return x && x.typeId === Type.Binary; + } + static isUtf8(x) { + return x && x.typeId === Type.Utf8; + } + static isBool(x) { + return x && x.typeId === Type.Bool; + } + static isDecimal(x) { + return x && x.typeId === Type.Decimal; + } + static isDate(x) { + return x && x.typeId === Type.Date; + } + static isTime(x) { + return x && x.typeId === Type.Time; + } + static isTimestamp(x) { + return x && x.typeId === Type.Timestamp; + } + static isInterval(x) { + return x && x.typeId === Type.Interval; + } + static isList(x) { + return x && x.typeId === Type.List; + } + static isStruct(x) { + return x && x.typeId === Type.Struct; + } + static isUnion(x) { + return x && x.typeId === Type.Union; + } + static isFixedSizeBinary(x) { + return x && x.typeId === Type.FixedSizeBinary; + } + static isFixedSizeList(x) { + return x && x.typeId === Type.FixedSizeList; + } + static isMap(x) { + return x && x.typeId === Type.Map; + } + static isDictionary(x) { + return x && x.typeId === Type.Dictionary; + } + get typeId() { + return Type.NONE; + } + compareTo(other) { + return this === other; + } +} +_Symbol$toStringTag = Symbol.toStringTag; +class Int extends DataType { + constructor(isSigned, bitWidth) { + super(); + _defineProperty(this, "isSigned", void 0); + _defineProperty(this, "bitWidth", void 0); + this.isSigned = isSigned; + this.bitWidth = bitWidth; + } + get typeId() { + return Type.Int; + } + get [_Symbol$toStringTag]() { + return 'Int'; + } + toString() { + return "".concat(this.isSigned ? 'I' : 'Ui', "nt").concat(this.bitWidth); + } +} +class Int8 extends Int { + constructor() { + super(true, 8); + } +} +class Int16 extends Int { + constructor() { + super(true, 16); + } +} +class Int32 extends Int { + constructor() { + super(true, 32); + } +} +class Uint8 extends Int { + constructor() { + super(false, 8); + } +} +class Uint16 extends Int { + constructor() { + super(false, 16); + } +} +class Uint32 extends Int { + constructor() { + super(false, 32); + } +} +const Precision = { + HALF: 16, + SINGLE: 32, + DOUBLE: 64 +}; +_Symbol$toStringTag2 = Symbol.toStringTag; +class Float extends DataType { + constructor(precision) { + super(); + _defineProperty(this, "precision", void 0); + this.precision = precision; + } + get typeId() { + return Type.Float; + } + get [_Symbol$toStringTag2]() { + return 'Float'; + } + toString() { + return "Float".concat(this.precision); + } +} +class Float32 extends Float { + constructor() { + super(Precision.SINGLE); + } +} +class Float64 extends Float { + constructor() { + super(Precision.DOUBLE); + } +} +_Symbol$toStringTag7 = Symbol.toStringTag; +class FixedSizeList extends DataType { + constructor(listSize, child) { + super(); + _defineProperty(this, "listSize", void 0); + _defineProperty(this, "children", void 0); + this.listSize = listSize; + this.children = [child]; + } + get typeId() { + return Type.FixedSizeList; + } + get valueType() { + return this.children[0].type; + } + get valueField() { + return this.children[0]; + } + get [_Symbol$toStringTag7]() { + return 'FixedSizeList'; + } + toString() { + return "FixedSizeList[".concat(this.listSize, "]<").concat(this.valueType, ">"); + } +} + +function getArrowTypeFromTypedArray(array) { + switch (array.constructor) { + case Int8Array: + return new Int8(); + case Uint8Array: + return new Uint8(); + case Int16Array: + return new Int16(); + case Uint16Array: + return new Uint16(); + case Int32Array: + return new Int32(); + case Uint32Array: + return new Uint32(); + case Float32Array: + return new Float32(); + case Float64Array: + return new Float64(); + default: + throw new Error('array type not supported'); + } +} + +function deduceMeshField(attributeName, attribute, optionalMetadata) { + const type = getArrowTypeFromTypedArray(attribute.value); + const metadata = optionalMetadata ? optionalMetadata : makeMeshAttributeMetadata(attribute); + const field = new Field(attributeName, new FixedSizeList(attribute.size, new Field('value', type)), false, metadata); + return field; +} +function makeMeshAttributeMetadata(attribute) { + const result = new Map(); + if ('byteOffset' in attribute) { + result.set('byteOffset', attribute.byteOffset.toString(10)); + } + if ('byteStride' in attribute) { + result.set('byteStride', attribute.byteStride.toString(10)); + } + if ('normalized' in attribute) { + result.set('normalized', attribute.normalized.toString()); + } + return result; +} + +function getDracoSchema(attributes, loaderData, indices) { + const metadataMap = makeMetadata(loaderData.metadata); + const fields = []; + const namedLoaderDataAttributes = transformAttributesLoaderData(loaderData.attributes); + for (const attributeName in attributes) { + const attribute = attributes[attributeName]; + const field = getArrowFieldFromAttribute(attributeName, attribute, namedLoaderDataAttributes[attributeName]); + fields.push(field); + } + if (indices) { + const indicesField = getArrowFieldFromAttribute('indices', indices); + fields.push(indicesField); + } + return new Schema(fields, metadataMap); +} +function transformAttributesLoaderData(loaderData) { + const result = {}; + for (const key in loaderData) { + const dracoAttribute = loaderData[key]; + result[dracoAttribute.name || 'undefined'] = dracoAttribute; + } + return result; +} +function getArrowFieldFromAttribute(attributeName, attribute, loaderData) { + const metadataMap = loaderData ? makeMetadata(loaderData.metadata) : undefined; + const field = deduceMeshField(attributeName, attribute, metadataMap); + return field; +} +function makeMetadata(metadata) { + const metadataMap = new Map(); + for (const key in metadata) { + metadataMap.set("".concat(key, ".string"), JSON.stringify(metadata[key])); + } + return metadataMap; +} + +const DRACO_TO_GLTF_ATTRIBUTE_NAME_MAP = { + POSITION: 'POSITION', + NORMAL: 'NORMAL', + COLOR: 'COLOR_0', + TEX_COORD: 'TEXCOORD_0' +}; +const DRACO_DATA_TYPE_TO_TYPED_ARRAY_MAP = { + 1: Int8Array, + 2: Uint8Array, + 3: Int16Array, + 4: Uint16Array, + 5: Int32Array, + 6: Uint32Array, + 9: Float32Array +}; +const INDEX_ITEM_SIZE = 4; +class DracoParser { + constructor(draco) { + _defineProperty(this, "draco", void 0); + _defineProperty(this, "decoder", void 0); + _defineProperty(this, "metadataQuerier", void 0); + this.draco = draco; + this.decoder = new this.draco.Decoder(); + this.metadataQuerier = new this.draco.MetadataQuerier(); + } + destroy() { + this.draco.destroy(this.decoder); + this.draco.destroy(this.metadataQuerier); + } + parseSync(arrayBuffer) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const buffer = new this.draco.DecoderBuffer(); + buffer.Init(new Int8Array(arrayBuffer), arrayBuffer.byteLength); + this._disableAttributeTransforms(options); + const geometry_type = this.decoder.GetEncodedGeometryType(buffer); + const dracoGeometry = geometry_type === this.draco.TRIANGULAR_MESH ? new this.draco.Mesh() : new this.draco.PointCloud(); + try { + let dracoStatus; + switch (geometry_type) { + case this.draco.TRIANGULAR_MESH: + dracoStatus = this.decoder.DecodeBufferToMesh(buffer, dracoGeometry); + break; + case this.draco.POINT_CLOUD: + dracoStatus = this.decoder.DecodeBufferToPointCloud(buffer, dracoGeometry); + break; + default: + throw new Error('DRACO: Unknown geometry type.'); + } + if (!dracoStatus.ok() || !dracoGeometry.ptr) { + const message = "DRACO decompression failed: ".concat(dracoStatus.error_msg()); + throw new Error(message); + } + const loaderData = this._getDracoLoaderData(dracoGeometry, geometry_type, options); + const geometry = this._getMeshData(dracoGeometry, loaderData, options); + const boundingBox = getMeshBoundingBox(geometry.attributes); + const schema = getDracoSchema(geometry.attributes, loaderData, geometry.indices); + const data = { + loader: 'draco', + loaderData, + header: { + vertexCount: dracoGeometry.num_points(), + boundingBox + }, + ...geometry, + schema + }; + return data; + } finally { + this.draco.destroy(buffer); + if (dracoGeometry) { + this.draco.destroy(dracoGeometry); + } + } + } + _getDracoLoaderData(dracoGeometry, geometry_type, options) { + const metadata = this._getTopLevelMetadata(dracoGeometry); + const attributes = this._getDracoAttributes(dracoGeometry, options); + return { + geometry_type, + num_attributes: dracoGeometry.num_attributes(), + num_points: dracoGeometry.num_points(), + num_faces: dracoGeometry instanceof this.draco.Mesh ? dracoGeometry.num_faces() : 0, + metadata, + attributes + }; + } + _getDracoAttributes(dracoGeometry, options) { + const dracoAttributes = {}; + for (let attributeId = 0; attributeId < dracoGeometry.num_attributes(); attributeId++) { + const dracoAttribute = this.decoder.GetAttribute(dracoGeometry, attributeId); + const metadata = this._getAttributeMetadata(dracoGeometry, attributeId); + dracoAttributes[dracoAttribute.unique_id()] = { + unique_id: dracoAttribute.unique_id(), + attribute_type: dracoAttribute.attribute_type(), + data_type: dracoAttribute.data_type(), + num_components: dracoAttribute.num_components(), + byte_offset: dracoAttribute.byte_offset(), + byte_stride: dracoAttribute.byte_stride(), + normalized: dracoAttribute.normalized(), + attribute_index: attributeId, + metadata + }; + const quantization = this._getQuantizationTransform(dracoAttribute, options); + if (quantization) { + dracoAttributes[dracoAttribute.unique_id()].quantization_transform = quantization; + } + const octahedron = this._getOctahedronTransform(dracoAttribute, options); + if (octahedron) { + dracoAttributes[dracoAttribute.unique_id()].octahedron_transform = octahedron; + } + } + return dracoAttributes; + } + _getMeshData(dracoGeometry, loaderData, options) { + const attributes = this._getMeshAttributes(loaderData, dracoGeometry, options); + const positionAttribute = attributes.POSITION; + if (!positionAttribute) { + throw new Error('DRACO: No position attribute found.'); + } + if (dracoGeometry instanceof this.draco.Mesh) { + switch (options.topology) { + case 'triangle-strip': + return { + topology: 'triangle-strip', + mode: 4, + attributes, + indices: { + value: this._getTriangleStripIndices(dracoGeometry), + size: 1 + } + }; + case 'triangle-list': + default: + return { + topology: 'triangle-list', + mode: 5, + attributes, + indices: { + value: this._getTriangleListIndices(dracoGeometry), + size: 1 + } + }; + } + } + return { + topology: 'point-list', + mode: 0, + attributes + }; + } + _getMeshAttributes(loaderData, dracoGeometry, options) { + const attributes = {}; + for (const loaderAttribute of Object.values(loaderData.attributes)) { + const attributeName = this._deduceAttributeName(loaderAttribute, options); + loaderAttribute.name = attributeName; + const { + value, + size + } = this._getAttributeValues(dracoGeometry, loaderAttribute); + attributes[attributeName] = { + value, + size, + byteOffset: loaderAttribute.byte_offset, + byteStride: loaderAttribute.byte_stride, + normalized: loaderAttribute.normalized + }; + } + return attributes; + } + _getTriangleListIndices(dracoGeometry) { + const numFaces = dracoGeometry.num_faces(); + const numIndices = numFaces * 3; + const byteLength = numIndices * INDEX_ITEM_SIZE; + const ptr = this.draco._malloc(byteLength); + try { + this.decoder.GetTrianglesUInt32Array(dracoGeometry, byteLength, ptr); + return new Uint32Array(this.draco.HEAPF32.buffer, ptr, numIndices).slice(); + } finally { + this.draco._free(ptr); + } + } + _getTriangleStripIndices(dracoGeometry) { + const dracoArray = new this.draco.DracoInt32Array(); + try { + this.decoder.GetTriangleStripsFromMesh(dracoGeometry, dracoArray); + return getUint32Array(dracoArray); + } finally { + this.draco.destroy(dracoArray); + } + } + _getAttributeValues(dracoGeometry, attribute) { + const TypedArrayCtor = DRACO_DATA_TYPE_TO_TYPED_ARRAY_MAP[attribute.data_type]; + const numComponents = attribute.num_components; + const numPoints = dracoGeometry.num_points(); + const numValues = numPoints * numComponents; + const byteLength = numValues * TypedArrayCtor.BYTES_PER_ELEMENT; + const dataType = getDracoDataType(this.draco, TypedArrayCtor); + let value; + const ptr = this.draco._malloc(byteLength); + try { + const dracoAttribute = this.decoder.GetAttribute(dracoGeometry, attribute.attribute_index); + this.decoder.GetAttributeDataArrayForAllPoints(dracoGeometry, dracoAttribute, dataType, byteLength, ptr); + value = new TypedArrayCtor(this.draco.HEAPF32.buffer, ptr, numValues).slice(); + } finally { + this.draco._free(ptr); + } + return { + value, + size: numComponents + }; + } + _deduceAttributeName(attribute, options) { + const uniqueId = attribute.unique_id; + for (const [attributeName, attributeUniqueId] of Object.entries(options.extraAttributes || {})) { + if (attributeUniqueId === uniqueId) { + return attributeName; + } + } + const thisAttributeType = attribute.attribute_type; + for (const dracoAttributeConstant in DRACO_TO_GLTF_ATTRIBUTE_NAME_MAP) { + const attributeType = this.draco[dracoAttributeConstant]; + if (attributeType === thisAttributeType) { + return DRACO_TO_GLTF_ATTRIBUTE_NAME_MAP[dracoAttributeConstant]; + } + } + const entryName = options.attributeNameEntry || 'name'; + if (attribute.metadata[entryName]) { + return attribute.metadata[entryName].string; + } + return "CUSTOM_ATTRIBUTE_".concat(uniqueId); + } + _getTopLevelMetadata(dracoGeometry) { + const dracoMetadata = this.decoder.GetMetadata(dracoGeometry); + return this._getDracoMetadata(dracoMetadata); + } + _getAttributeMetadata(dracoGeometry, attributeId) { + const dracoMetadata = this.decoder.GetAttributeMetadata(dracoGeometry, attributeId); + return this._getDracoMetadata(dracoMetadata); + } + _getDracoMetadata(dracoMetadata) { + if (!dracoMetadata || !dracoMetadata.ptr) { + return {}; + } + const result = {}; + const numEntries = this.metadataQuerier.NumEntries(dracoMetadata); + for (let entryIndex = 0; entryIndex < numEntries; entryIndex++) { + const entryName = this.metadataQuerier.GetEntryName(dracoMetadata, entryIndex); + result[entryName] = this._getDracoMetadataField(dracoMetadata, entryName); + } + return result; + } + _getDracoMetadataField(dracoMetadata, entryName) { + const dracoArray = new this.draco.DracoInt32Array(); + try { + this.metadataQuerier.GetIntEntryArray(dracoMetadata, entryName, dracoArray); + const intArray = getInt32Array(dracoArray); + return { + int: this.metadataQuerier.GetIntEntry(dracoMetadata, entryName), + string: this.metadataQuerier.GetStringEntry(dracoMetadata, entryName), + double: this.metadataQuerier.GetDoubleEntry(dracoMetadata, entryName), + intArray + }; + } finally { + this.draco.destroy(dracoArray); + } + } + _disableAttributeTransforms(options) { + const { + quantizedAttributes = [], + octahedronAttributes = [] + } = options; + const skipAttributes = [...quantizedAttributes, ...octahedronAttributes]; + for (const dracoAttributeName of skipAttributes) { + this.decoder.SkipAttributeTransform(this.draco[dracoAttributeName]); + } + } + _getQuantizationTransform(dracoAttribute, options) { + const { + quantizedAttributes = [] + } = options; + const attribute_type = dracoAttribute.attribute_type(); + const skip = quantizedAttributes.map(type => this.decoder[type]).includes(attribute_type); + if (skip) { + const transform = new this.draco.AttributeQuantizationTransform(); + try { + if (transform.InitFromAttribute(dracoAttribute)) { + return { + quantization_bits: transform.quantization_bits(), + range: transform.range(), + min_values: new Float32Array([1, 2, 3]).map(i => transform.min_value(i)) + }; + } + } finally { + this.draco.destroy(transform); + } + } + return null; + } + _getOctahedronTransform(dracoAttribute, options) { + const { + octahedronAttributes = [] + } = options; + const attribute_type = dracoAttribute.attribute_type(); + const octahedron = octahedronAttributes.map(type => this.decoder[type]).includes(attribute_type); + if (octahedron) { + const transform = new this.draco.AttributeQuantizationTransform(); + try { + if (transform.InitFromAttribute(dracoAttribute)) { + return { + quantization_bits: transform.quantization_bits() + }; + } + } finally { + this.draco.destroy(transform); + } + } + return null; + } +} +function getDracoDataType(draco, attributeType) { + switch (attributeType) { + case Float32Array: + return draco.DT_FLOAT32; + case Int8Array: + return draco.DT_INT8; + case Int16Array: + return draco.DT_INT16; + case Int32Array: + return draco.DT_INT32; + case Uint8Array: + return draco.DT_UINT8; + case Uint16Array: + return draco.DT_UINT16; + case Uint32Array: + return draco.DT_UINT32; + default: + return draco.DT_INVALID; + } +} +function getInt32Array(dracoArray) { + const numValues = dracoArray.size(); + const intArray = new Int32Array(numValues); + for (let i = 0; i < numValues; i++) { + intArray[i] = dracoArray.GetValue(i); + } + return intArray; +} +function getUint32Array(dracoArray) { + const numValues = dracoArray.size(); + const intArray = new Int32Array(numValues); + for (let i = 0; i < numValues; i++) { + intArray[i] = dracoArray.GetValue(i); + } + return intArray; +} + +const DRACO_DECODER_VERSION = '1.5.5'; +const STATIC_DECODER_URL = "https://www.gstatic.com/draco/versioned/decoders/".concat(DRACO_DECODER_VERSION); +const DRACO_JS_DECODER_URL = "".concat(STATIC_DECODER_URL, "/draco_decoder.js"); +const DRACO_WASM_WRAPPER_URL = "".concat(STATIC_DECODER_URL, "/draco_wasm_wrapper.js"); +const DRACO_WASM_DECODER_URL = "".concat(STATIC_DECODER_URL, "/draco_decoder.wasm"); +let loadDecoderPromise; +async function loadDracoDecoderModule(options) { + const modules = options.modules || {}; + if (modules.draco3d) { + loadDecoderPromise = loadDecoderPromise || modules.draco3d.createDecoderModule({}).then(draco => { + return { + draco + }; + }); + } else { + loadDecoderPromise = loadDecoderPromise || loadDracoDecoder(options); + } + return await loadDecoderPromise; +} +async function loadDracoDecoder(options) { + let DracoDecoderModule; + let wasmBinary; + switch (options.draco && options.draco.decoderType) { + case 'js': + DracoDecoderModule = await loadLibrary(DRACO_JS_DECODER_URL, 'draco', options); + break; + case 'wasm': + default: + [DracoDecoderModule, wasmBinary] = await Promise.all([await loadLibrary(DRACO_WASM_WRAPPER_URL, 'draco', options), await loadLibrary(DRACO_WASM_DECODER_URL, 'draco', options)]); + } + DracoDecoderModule = DracoDecoderModule || globalThis.DracoDecoderModule; + return await initializeDracoDecoder(DracoDecoderModule, wasmBinary); +} +function initializeDracoDecoder(DracoDecoderModule, wasmBinary) { + const options = {}; + if (wasmBinary) { + options.wasmBinary = wasmBinary; + } + return new Promise(resolve => { + DracoDecoderModule({ + ...options, + onModuleLoaded: draco => resolve({ + draco + }) + }); + }); +} + +({ + id: isBrowser$1 ? 'draco-writer' : 'draco-writer-nodejs', + name: 'Draco compressed geometry writer', + module: 'draco', + version: VERSION, + worker: true, + options: { + draco: {}, + source: null + } +}); +const DracoLoader = { + ...DracoLoader$1, + parse: parse$1 +}; +async function parse$1(arrayBuffer, options) { + const { + draco + } = await loadDracoDecoderModule(options); + const dracoParser = new DracoParser(draco); + try { + return dracoParser.parseSync(arrayBuffer, options === null || options === void 0 ? void 0 : options.draco); + } finally { + dracoParser.destroy(); + } +} + +function getGLTFAccessors(attributes) { + const accessors = {}; + for (const name in attributes) { + const attribute = attributes[name]; + if (name !== 'indices') { + const glTFAccessor = getGLTFAccessor(attribute); + accessors[name] = glTFAccessor; + } + } + return accessors; +} +function getGLTFAccessor(attribute) { + const { + buffer, + size, + count + } = getAccessorData(attribute); + const glTFAccessor = { + value: buffer, + size, + byteOffset: 0, + count, + type: getAccessorTypeFromSize(size), + componentType: getComponentTypeFromArray(buffer) + }; + return glTFAccessor; +} +function getAccessorData(attribute) { + let buffer = attribute; + let size = 1; + let count = 0; + if (attribute && attribute.value) { + buffer = attribute.value; + size = attribute.size || 1; + } + if (buffer) { + if (!ArrayBuffer.isView(buffer)) { + buffer = toTypedArray(buffer, Float32Array); + } + count = buffer.length / size; + } + return { + buffer, + size, + count + }; +} +function toTypedArray(array, ArrayType) { + let convertTypedArrays = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + if (!array) { + return null; + } + if (Array.isArray(array)) { + return new ArrayType(array); + } + if (convertTypedArrays && !(array instanceof ArrayType)) { + return new ArrayType(array); + } + return array; +} + +const KHR_DRACO_MESH_COMPRESSION = 'KHR_draco_mesh_compression'; +const name$5 = KHR_DRACO_MESH_COMPRESSION; +function preprocess$1(gltfData, options, context) { + const scenegraph = new GLTFScenegraph(gltfData); + for (const primitive of makeMeshPrimitiveIterator(scenegraph)) { + if (scenegraph.getObjectExtension(primitive, KHR_DRACO_MESH_COMPRESSION)) ; + } +} +async function decode$5(gltfData, options, context) { + var _options$gltf; + if (!(options !== null && options !== void 0 && (_options$gltf = options.gltf) !== null && _options$gltf !== void 0 && _options$gltf.decompressMeshes)) { + return; + } + const scenegraph = new GLTFScenegraph(gltfData); + const promises = []; + for (const primitive of makeMeshPrimitiveIterator(scenegraph)) { + if (scenegraph.getObjectExtension(primitive, KHR_DRACO_MESH_COMPRESSION)) { + promises.push(decompressPrimitive(scenegraph, primitive, options, context)); + } + } + await Promise.all(promises); + scenegraph.removeExtension(KHR_DRACO_MESH_COMPRESSION); +} +function encode$3(gltfData) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const scenegraph = new GLTFScenegraph(gltfData); + for (const mesh of scenegraph.json.meshes || []) { + compressMesh(mesh, options); + scenegraph.addRequiredExtension(KHR_DRACO_MESH_COMPRESSION); + } +} +async function decompressPrimitive(scenegraph, primitive, options, context) { + const dracoExtension = scenegraph.getObjectExtension(primitive, KHR_DRACO_MESH_COMPRESSION); + if (!dracoExtension) { + return; + } + const buffer = scenegraph.getTypedArrayForBufferView(dracoExtension.bufferView); + const bufferCopy = sliceArrayBuffer(buffer.buffer, buffer.byteOffset); + const { + parse + } = context; + const dracoOptions = { + ...options + }; + delete dracoOptions['3d-tiles']; + const decodedData = await parse(bufferCopy, DracoLoader, dracoOptions, context); + const decodedAttributes = getGLTFAccessors(decodedData.attributes); + for (const [attributeName, decodedAttribute] of Object.entries(decodedAttributes)) { + if (attributeName in primitive.attributes) { + const accessorIndex = primitive.attributes[attributeName]; + const accessor = scenegraph.getAccessor(accessorIndex); + if (accessor !== null && accessor !== void 0 && accessor.min && accessor !== null && accessor !== void 0 && accessor.max) { + decodedAttribute.min = accessor.min; + decodedAttribute.max = accessor.max; + } + } + } + primitive.attributes = decodedAttributes; + if (decodedData.indices) { + primitive.indices = getGLTFAccessor(decodedData.indices); + } + checkPrimitive(primitive); +} +function compressMesh(attributes, indices) { + var _context$parseSync; + let mode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4; + let options = arguments.length > 3 ? arguments[3] : undefined; + let context = arguments.length > 4 ? arguments[4] : undefined; + if (!options.DracoWriter) { + throw new Error('options.gltf.DracoWriter not provided'); + } + const compressedData = options.DracoWriter.encodeSync({ + attributes + }); + const decodedData = context === null || context === void 0 ? void 0 : (_context$parseSync = context.parseSync) === null || _context$parseSync === void 0 ? void 0 : _context$parseSync.call(context, { + attributes + }); + const fauxAccessors = options._addFauxAttributes(decodedData.attributes); + const bufferViewIndex = options.addBufferView(compressedData); + const glTFMesh = { + primitives: [{ + attributes: fauxAccessors, + mode, + extensions: { + [KHR_DRACO_MESH_COMPRESSION]: { + bufferView: bufferViewIndex, + attributes: fauxAccessors + } + } + }] + }; + return glTFMesh; +} +function checkPrimitive(primitive) { + if (!primitive.attributes && Object.keys(primitive.attributes).length > 0) { + throw new Error('glTF: Empty primitive detected: Draco decompression failure?'); + } +} +function* makeMeshPrimitiveIterator(scenegraph) { + for (const mesh of scenegraph.json.meshes || []) { + for (const primitive of mesh.primitives) { + yield primitive; + } + } +} + +var KHR_draco_mesh_compression = /*#__PURE__*/Object.freeze({ + __proto__: null, + name: name$5, + preprocess: preprocess$1, + decode: decode$5, + encode: encode$3 +}); + +function assert(condition, message) { + if (!condition) { + throw new Error("math.gl assertion ".concat(message)); + } +} + +const config = { + EPSILON: 1e-12, + debug: false, + precision: 4, + printTypes: false, + printDegrees: false, + printRowMajor: true +}; +function formatValue(value, { + precision = config.precision +} = {}) { + value = round(value); + return "".concat(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; +} + +function _extendableBuiltin(cls) { + function ExtendableBuiltin() { + var instance = Reflect.construct(cls, Array.from(arguments)); + Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); + return instance; + } + + ExtendableBuiltin.prototype = Object.create(cls.prototype, { + constructor: { + value: cls, + enumerable: false, + writable: true, + configurable: true + } + }); + + if (Object.setPrototypeOf) { + Object.setPrototypeOf(ExtendableBuiltin, cls); + } else { + ExtendableBuiltin.__proto__ = cls; + } + + return ExtendableBuiltin; +} +class MathArray extends _extendableBuiltin(Array) { + 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; + } + + from(arrayOrObject) { + return Array.isArray(arrayOrObject) ? this.copy(arrayOrObject) : 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; + } + + toFloat32Array() { + return new Float32Array(this); + } + + toString() { + return this.formatString(config); + } + + formatString(opts) { + let string = ''; + + for (let i = 0; i < this.ELEMENTS; ++i) { + string += (i > 0 ? ', ' : '') + formatValue(this[i], opts); + } + + return "".concat(opts.printTypes ? this.constructor.name : '', "[").concat(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; + } + + negate() { + for (let i = 0; i < this.ELEMENTS; ++i) { + this[i] = -this[i]; + } + + return this.check(); + } + + lerp(a, b, t) { + if (t === undefined) { + return this.lerp(this, a, b); + } + + for (let i = 0; i < this.ELEMENTS; ++i) { + const ai = a[i]; + this[i] = ai + t * (b[i] - ai); + } + + return this.check(); + } + + min(vector) { + for (let i = 0; i < this.ELEMENTS; ++i) { + this[i] = Math.min(vector[i], this[i]); + } + + return this.check(); + } + + 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(scale) { + if (typeof scale === 'number') { + for (let i = 0; i < this.ELEMENTS; ++i) { + this[i] *= scale; + } + } else { + for (let i = 0; i < this.ELEMENTS && i < scale.length; ++i) { + this[i] *= scale[i]; + } + } + + return this.check(); + } + + multiplyByScalar(scalar) { + for (let i = 0; i < this.ELEMENTS; ++i) { + this[i] *= scalar; + } + + return this.check(); + } + + check() { + if (config.debug && !this.validate()) { + throw new Error("math.gl: ".concat(this.constructor.name, " some fields set to invalid numbers'")); + } + + return this; + } + + validate() { + let valid = this.length === this.ELEMENTS; + + for (let i = 0; i < this.ELEMENTS; ++i) { + valid = valid && Number.isFinite(this[i]); + } + + return valid; + } + + sub(a) { + return this.subtract(a); + } + + setScalar(a) { + for (let i = 0; i < this.ELEMENTS; ++i) { + this[i] = a; + } + + return this.check(); + } + + addScalar(a) { + for (let i = 0; i < this.ELEMENTS; ++i) { + this[i] += a; + } + + return this.check(); + } + + subScalar(a) { + return this.addScalar(-a); + } + + multiplyScalar(scalar) { + for (let i = 0; i < this.ELEMENTS; ++i) { + this[i] *= scalar; + } + + return this.check(); + } + + divideScalar(a) { + return this.multiplyByScalar(1 / a); + } + + clampScalar(min, max) { + for (let i = 0; i < this.ELEMENTS; ++i) { + this[i] = Math.min(Math.max(this[i], min), max); + } + + return this.check(); + } + + get elements() { + return this; + } + +} + +function validateVector(v, length) { + if (v.length !== length) { + 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 ".concat(value)); + } + + return value; +} +function checkVector(v, length, callerName = '') { + if (config.debug && !validateVector(v, length)) { + throw new Error("math.gl: ".concat(callerName, " some fields set to invalid numbers'")); + } + + return v; +} + +class Vector extends MathArray { + get x() { + return this[0]; + } + + set x(value) { + this[0] = checkNumber(value); + } + + get y() { + return this[1]; + } + + set y(value) { + this[1] = checkNumber(value); + } + + len() { + return Math.sqrt(this.lengthSquared()); + } + + magnitude() { + return this.len(); + } + + lengthSquared() { + let length = 0; + + for (let i = 0; i < this.ELEMENTS; ++i) { + length += this[i] * this[i]; + } + + return length; + } + + magnitudeSquared() { + return this.lengthSquared(); + } + + distance(mathArray) { + return Math.sqrt(this.distanceSquared(mathArray)); + } + + distanceSquared(mathArray) { + let length = 0; + + for (let i = 0; i < this.ELEMENTS; ++i) { + const dist = this[i] - mathArray[i]; + length += dist * dist; + } + + return checkNumber(length); + } + + dot(mathArray) { + let product = 0; + + for (let i = 0; i < this.ELEMENTS; ++i) { + product += this[i] * mathArray[i]; + } + + return checkNumber(product); + } + + normalize() { + const length = this.magnitude(); + + if (length !== 0) { + for (let i = 0; i < this.ELEMENTS; ++i) { + this[i] /= length; + } + } + + 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(); + } + + 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)); + } + +} + +/** + * Common utilities + * @module glMatrix + */ +var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; +if (!Math.hypot) Math.hypot = function () { + var y = 0, + i = arguments.length; + + while (i--) { + y += arguments[i] * arguments[i]; + } + + return Math.sqrt(y); +}; + +/** + * 2 Dimensional Vector + * @module vec2 + */ + +/** + * Creates a new, empty vec2 + * + * @returns {vec2} a new 2D vector + */ + +function create$1() { + var out = new ARRAY_TYPE(2); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + } + + return out; +} +/** + * Transforms the vec2 with a mat3 + * 3rd vector component is implicitly '1' + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat3} m matrix to transform with + * @returns {vec2} out + */ + +function transformMat3$1(out, a, m) { + var x = a[0], + 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; +} +/** + * Perform some operation over an array of vec2s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + +(function () { + var vec = create$1(); + return function (a, stride, offset, count, fn, arg) { + var i, 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; + }; +})(); + +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.0; + 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_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; +} + +/** + * 3 Dimensional Vector + * @module vec3 + */ + +/** + * Creates a new, empty vec3 + * + * @returns {vec3} a new 3D vector + */ + +function create() { + var out = new ARRAY_TYPE(3); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + return out; +} +/** + * Calculates the dot product of two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} dot product of a and b + */ + +function dot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} +/** + * Computes the cross product of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + +function cross(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2]; + var bx = b[0], + by = b[1], + bz = b[2]; + out[0] = ay * bz - az * by; + out[1] = az * bx - ax * bz; + out[2] = ax * by - ay * bx; + return out; +} +/** + * Transforms the vec3 with a mat4. + * 4th vector component is implicitly '1' + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with + * @returns {vec3} out + */ + +function transformMat4(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + var w = m[3] * x + m[7] * y + m[11] * z + m[15]; + w = w || 1.0; + 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; +} +/** + * Transforms the vec3 with a mat3. + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat3} m the 3x3 matrix to transform with + * @returns {vec3} out + */ + +function transformMat3(out, a, m) { + var x = a[0], + y = a[1], + 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; +} +/** + * Transforms the vec3 with a quat + * Can also be used for dual quaternions. (Multiply it with the real part) + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with + * @returns {vec3} out + */ + +function transformQuat(out, a, q) { + // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; + var x = a[0], + y = a[1], + z = a[2]; // var qvec = [qx, qy, qz]; + // var uv = vec3.cross([], qvec, a); + + var uvx = qy * z - qz * y, + uvy = qz * x - qx * z, + uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv); + + var uuvx = qy * uvz - qz * uvy, + uuvy = qz * uvx - qx * uvz, + uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w); + + var w2 = qw * 2; + uvx *= w2; + uvy *= w2; + uvz *= w2; // vec3.scale(uuv, uuv, 2); + + uuvx *= 2; + uuvy *= 2; + uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv)); + + out[0] = x + uvx + uuvx; + out[1] = y + uvy + uuvy; + out[2] = z + uvz + uuvz; + return out; +} +/** + * Rotate a 3D vector around the x-axis + * @param {vec3} out The receiving vec3 + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec3} out + */ + +function rotateX(out, a, b, rad) { + var p = [], + r = []; //Translate point to the origin + + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; //perform rotation + + 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); //translate to correct position + + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; +} +/** + * Rotate a 3D vector around the y-axis + * @param {vec3} out The receiving vec3 + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec3} out + */ + +function rotateY(out, a, b, rad) { + var p = [], + r = []; //Translate point to the origin + + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; //perform rotation + + 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); //translate to correct position + + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; +} +/** + * Rotate a 3D vector around the z-axis + * @param {vec3} out The receiving vec3 + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec3} out + */ + +function rotateZ(out, a, b, rad) { + var p = [], + r = []; //Translate point to the origin + + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; //perform rotation + + 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]; //translate to correct position + + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; +} +/** + * Get the angle between two 3D vectors + * @param {ReadonlyVec3} a The first operand + * @param {ReadonlyVec3} b The second operand + * @returns {Number} The angle in radians + */ + +function angle(a, b) { + var ax = a[0], + ay = a[1], + az = a[2], + bx = b[0], + by = b[1], + bz = b[2], + mag1 = Math.sqrt(ax * ax + ay * ay + az * az), + mag2 = Math.sqrt(bx * bx + by * by + bz * bz), + mag = mag1 * mag2, + cosine = mag && dot(a, b) / mag; + return Math.acos(Math.min(Math.max(cosine, -1), 1)); +} +/** + * Perform some operation over an array of vec3s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + +(function () { + var vec = create(); + return function (a, stride, offset, count, fn, arg) { + var i, 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; + }; +})(); + +const ORIGIN = [0, 0, 0]; +let ZERO; +class Vector3 extends Vector { + static get ZERO() { + if (!ZERO) { + ZERO = new Vector3(0, 0, 0); + Object.freeze(ZERO); + } + + return ZERO; + } + + 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; + } + + get ELEMENTS() { + return 3; + } + + get z() { + return this[2]; + } + + set z(value) { + this[2] = checkNumber(value); + } + + angle(vector) { + return angle(this, vector); + } + + 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(); + } + + transform(matrix4) { + return this.transformAsPoint(matrix4); + } + + transformAsPoint(matrix4) { + transformMat4(this, this, matrix4); + return this.check(); + } + + transformAsVector(matrix4) { + vec3_transformMat4AsVector(this, this, matrix4); + return this.check(); + } + + transformByMatrix3(matrix3) { + transformMat3(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(); + } + +} + +class Matrix extends MathArray { + 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 += " ".concat(this[col * this.RANK + row]); + } + } + } else { + string += 'column-major:'; + + for (let i = 0; i < this.ELEMENTS; ++i) { + string += " ".concat(this[i]); + } + } + + string += ']'; + return string; + } + + getElementIndex(row, col) { + return col * this.RANK + row; + } + + getElement(row, col) { + return this[col * this.RANK + row]; + } + + 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; + } + +} + +/** + * Transpose the values of a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + +function transpose(out, a) { + // If we are transposing ourselves we can skip a few steps but have to cache some values + if (out === a) { + var a01 = a[1], + a02 = a[2], + 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; +} +/** + * Inverts a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + +function invert(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + var b01 = a22 * a11 - a12 * a21; + var b11 = -a22 * a10 + a12 * a20; + var b21 = a21 * a10 - a11 * a20; // Calculate the determinant + + var det = a00 * b01 + a01 * b11 + a02 * b21; + + if (!det) { + return null; + } + + det = 1.0 / 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; +} +/** + * Calculates the determinant of a mat3 + * + * @param {ReadonlyMat3} a the source matrix + * @returns {Number} determinant of a + */ + +function determinant(a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); +} +/** + * Multiplies two mat3's + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the first operand + * @param {ReadonlyMat3} b the second operand + * @returns {mat3} out + */ + +function multiply(out, a, b) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + var b00 = b[0], + b01 = b[1], + b02 = b[2]; + var b10 = b[3], + b11 = b[4], + b12 = b[5]; + var b20 = b[6], + b21 = b[7], + 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; +} +/** + * Translate a mat3 by the given vector + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to translate + * @param {ReadonlyVec2} v vector to translate by + * @returns {mat3} out + */ + +function translate(out, a, v) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a10 = a[3], + a11 = a[4], + a12 = a[5], + a20 = a[6], + a21 = a[7], + a22 = a[8], + x = v[0], + 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; +} +/** + * Rotates a mat3 by the given angle + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat3} out + */ + +function rotate(out, a, rad) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a10 = a[3], + a11 = a[4], + a12 = a[5], + a20 = a[6], + a21 = a[7], + a22 = a[8], + s = Math.sin(rad), + 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; +} +/** + * Scales the mat3 by the dimensions in the given vec2 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to rotate + * @param {ReadonlyVec2} v the vec2 to scale the matrix by + * @returns {mat3} out + **/ + +function scale(out, a, v) { + var x = v[0], + 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; +} +/** + * Calculates a 3x3 matrix from the given quaternion + * + * @param {mat3} out mat3 receiving operation result + * @param {ReadonlyQuat} q Quaternion to create matrix from + * + * @returns {mat3} out + */ + +function fromQuat(out, q) { + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var yx = y * x2; + var yy = y * y2; + var zx = z * x2; + var zy = z * y2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - yy - zz; + out[3] = yx - wz; + out[6] = zx + wy; + out[1] = yx + wz; + out[4] = 1 - xx - zz; + out[7] = zy - wx; + out[2] = zx - wy; + out[5] = zy + wx; + out[8] = 1 - xx - yy; + return out; +} + +var INDICES; + +(function (INDICES) { + INDICES[INDICES["COL0ROW0"] = 0] = "COL0ROW0"; + INDICES[INDICES["COL0ROW1"] = 1] = "COL0ROW1"; + INDICES[INDICES["COL0ROW2"] = 2] = "COL0ROW2"; + INDICES[INDICES["COL1ROW0"] = 3] = "COL1ROW0"; + INDICES[INDICES["COL1ROW1"] = 4] = "COL1ROW1"; + INDICES[INDICES["COL1ROW2"] = 5] = "COL1ROW2"; + INDICES[INDICES["COL2ROW0"] = 6] = "COL2ROW0"; + INDICES[INDICES["COL2ROW1"] = 7] = "COL2ROW1"; + INDICES[INDICES["COL2ROW2"] = 8] = "COL2ROW2"; +})(INDICES || (INDICES = {})); + +const IDENTITY_MATRIX = Object.freeze([1, 0, 0, 0, 1, 0, 0, 0, 1]); +class Matrix3 extends Matrix { + static get IDENTITY() { + return getIdentityMatrix(); + } + + static get ZERO() { + return getZeroMatrix(); + } + + get ELEMENTS() { + return 9; + } + + get RANK() { + return 3; + } + + get INDICES() { + return INDICES; + } + + constructor(array, ...args) { + super(-0, -0, -0, -0, -0, -0, -0, -0, -0); + + if (arguments.length === 1 && Array.isArray(array)) { + this.copy(array); + } else if (args.length > 0) { + this.copy([array, ...args]); + } else { + this.identity(); + } + } + + copy(array) { + this[0] = array[0]; + this[1] = array[1]; + this[2] = array[2]; + this[3] = array[3]; + this[4] = array[4]; + this[5] = array[5]; + this[6] = array[6]; + this[7] = array[7]; + this[8] = array[8]; + return this.check(); + } + + identity() { + return this.copy(IDENTITY_MATRIX); + } + + fromObject(object) { + return this.check(); + } + + fromQuaternion(q) { + fromQuat(this, q); + return this.check(); + } + + set(m00, m10, m20, m01, m11, m21, m02, m12, m22) { + this[0] = m00; + this[1] = m10; + this[2] = m20; + this[3] = m01; + this[4] = m11; + this[5] = m21; + this[6] = m02; + this[7] = m12; + this[8] = m22; + return this.check(); + } + + setRowMajor(m00, m01, m02, m10, m11, m12, m20, m21, m22) { + this[0] = m00; + this[1] = m10; + this[2] = m20; + this[3] = m01; + this[4] = m11; + this[5] = m21; + this[6] = m02; + this[7] = m12; + this[8] = m22; + return this.check(); + } + + determinant() { + return determinant(this); + } + + transpose() { + transpose(this, this); + return this.check(); + } + + invert() { + invert(this, this); + return this.check(); + } + + multiplyLeft(a) { + multiply(this, a, this); + return this.check(); + } + + multiplyRight(a) { + multiply(this, this, a); + return this.check(); + } + + rotate(radians) { + rotate(this, this, radians); + return this.check(); + } + + scale(factor) { + if (Array.isArray(factor)) { + scale(this, this, factor); + } else { + scale(this, this, [factor, factor]); + } + + return this.check(); + } + + translate(vec) { + translate(this, this, vec); + return this.check(); + } + + transform(vector, result) { + let out; + + switch (vector.length) { + case 2: + out = transformMat3$1(result || [-0, -0], vector, this); + break; + + case 3: + out = transformMat3(result || [-0, -0, -0], vector, this); + break; + + case 4: + out = vec4_transformMat3(result || [-0, -0, -0, -0], vector, this); + break; + + default: + throw new Error('Illegal vector'); + } + + checkVector(out, vector.length); + return out; + } + + transformVector(vector, result) { + return this.transform(vector, result); + } + + transformVector2(vector, result) { + return this.transform(vector, result); + } + + transformVector3(vector, result) { + return this.transform(vector, result); + } + +} +let ZERO_MATRIX3; +let IDENTITY_MATRIX3; + +function getZeroMatrix() { + if (!ZERO_MATRIX3) { + ZERO_MATRIX3 = new Matrix3([0, 0, 0, 0, 0, 0, 0, 0, 0]); + Object.freeze(ZERO_MATRIX3); + } + + return ZERO_MATRIX3; +} + +function getIdentityMatrix() { + if (!IDENTITY_MATRIX3) { + IDENTITY_MATRIX3 = new Matrix3(); + Object.freeze(IDENTITY_MATRIX3); + } + + return IDENTITY_MATRIX3; +} + +const COMPONENTS$1 = { + SCALAR: 1, + VEC2: 2, + VEC3: 3, + VEC4: 4, + MAT2: 4, + MAT3: 9, + MAT4: 16 +}; +const BYTES$1 = { + 5120: 1, + 5121: 1, + 5122: 2, + 5123: 2, + 5125: 4, + 5126: 4 +}; + +const EXT_MESHOPT_TRANSFORM = 'KHR_texture_transform'; +const name$4 = EXT_MESHOPT_TRANSFORM; +const scratchVector = new Vector3(); +const scratchRotationMatrix = new Matrix3(); +const scratchScaleMatrix = new Matrix3(); +async function decode$4(gltfData, options) { + const gltfScenegraph = new GLTFScenegraph(gltfData); + const extension = gltfScenegraph.getExtension(EXT_MESHOPT_TRANSFORM); + if (!extension) { + return; + } + const materials = gltfData.json.materials || []; + for (let i = 0; i < materials.length; i++) { + transformTexCoords(i, gltfData); + } +} +function transformTexCoords(materialIndex, gltfData) { + var _gltfData$json$materi, _material$pbrMetallic, _material$pbrMetallic2; + const processedTexCoords = []; + const material = (_gltfData$json$materi = gltfData.json.materials) === null || _gltfData$json$materi === void 0 ? void 0 : _gltfData$json$materi[materialIndex]; + const baseColorTexture = material === null || material === void 0 ? void 0 : (_material$pbrMetallic = material.pbrMetallicRoughness) === null || _material$pbrMetallic === void 0 ? void 0 : _material$pbrMetallic.baseColorTexture; + if (baseColorTexture) { + transformPrimitives(gltfData, materialIndex, baseColorTexture, processedTexCoords); + } + const emisiveTexture = material === null || material === void 0 ? void 0 : material.emissiveTexture; + if (emisiveTexture) { + transformPrimitives(gltfData, materialIndex, emisiveTexture, processedTexCoords); + } + const normalTexture = material === null || material === void 0 ? void 0 : material.normalTexture; + if (normalTexture) { + transformPrimitives(gltfData, materialIndex, normalTexture, processedTexCoords); + } + const occlusionTexture = material === null || material === void 0 ? void 0 : material.occlusionTexture; + if (occlusionTexture) { + transformPrimitives(gltfData, materialIndex, occlusionTexture, processedTexCoords); + } + const metallicRoughnessTexture = material === null || material === void 0 ? void 0 : (_material$pbrMetallic2 = material.pbrMetallicRoughness) === null || _material$pbrMetallic2 === void 0 ? void 0 : _material$pbrMetallic2.metallicRoughnessTexture; + if (metallicRoughnessTexture) { + transformPrimitives(gltfData, materialIndex, metallicRoughnessTexture, processedTexCoords); + } +} +function transformPrimitives(gltfData, materialIndex, texture, processedTexCoords) { + const transformParameters = getTransformParameters(texture, processedTexCoords); + if (!transformParameters) { + return; + } + const meshes = gltfData.json.meshes || []; + for (const mesh of meshes) { + for (const primitive of mesh.primitives) { + const material = primitive.material; + if (Number.isFinite(material) && materialIndex === material) { + transformPrimitive(gltfData, primitive, transformParameters); + } + } + } +} +function getTransformParameters(texture, processedTexCoords) { + var _texture$extensions; + const textureInfo = (_texture$extensions = texture.extensions) === null || _texture$extensions === void 0 ? void 0 : _texture$extensions[EXT_MESHOPT_TRANSFORM]; + const { + texCoord: originalTexCoord = 0 + } = texture; + const { + texCoord = originalTexCoord + } = textureInfo; + const isProcessed = processedTexCoords.findIndex(_ref => { + let [original, newTexCoord] = _ref; + return original === originalTexCoord && newTexCoord === texCoord; + }) !== -1; + if (!isProcessed) { + const matrix = makeTransformationMatrix(textureInfo); + if (originalTexCoord !== texCoord) { + texture.texCoord = texCoord; + } + processedTexCoords.push([originalTexCoord, texCoord]); + return { + originalTexCoord, + texCoord, + matrix + }; + } + return null; +} +function transformPrimitive(gltfData, primitive, transformParameters) { + const { + originalTexCoord, + texCoord, + matrix + } = transformParameters; + const texCoordAccessor = primitive.attributes["TEXCOORD_".concat(originalTexCoord)]; + if (Number.isFinite(texCoordAccessor)) { + var _gltfData$json$access; + const accessor = (_gltfData$json$access = gltfData.json.accessors) === null || _gltfData$json$access === void 0 ? void 0 : _gltfData$json$access[texCoordAccessor]; + if (accessor && accessor.bufferView) { + var _gltfData$json$buffer; + const bufferView = (_gltfData$json$buffer = gltfData.json.bufferViews) === null || _gltfData$json$buffer === void 0 ? void 0 : _gltfData$json$buffer[accessor.bufferView]; + if (bufferView) { + const { + arrayBuffer, + byteOffset: bufferByteOffset + } = gltfData.buffers[bufferView.buffer]; + const byteOffset = (bufferByteOffset || 0) + (accessor.byteOffset || 0) + (bufferView.byteOffset || 0); + const { + ArrayType, + length + } = getAccessorArrayTypeAndLength(accessor, bufferView); + const bytes = BYTES$1[accessor.componentType]; + const components = COMPONENTS$1[accessor.type]; + const elementAddressScale = bufferView.byteStride || bytes * components; + const result = new Float32Array(length); + for (let i = 0; i < accessor.count; i++) { + const uv = new ArrayType(arrayBuffer, byteOffset + i * elementAddressScale, 2); + scratchVector.set(uv[0], uv[1], 1); + scratchVector.transformByMatrix3(matrix); + result.set([scratchVector[0], scratchVector[1]], i * components); + } + if (originalTexCoord === texCoord) { + updateGltf(accessor, bufferView, gltfData.buffers, result); + } else { + createAttribute(texCoord, accessor, primitive, gltfData, result); + } + } + } + } +} +function updateGltf(accessor, bufferView, buffers, newTexCoordArray) { + accessor.componentType = 5126; + buffers.push({ + arrayBuffer: newTexCoordArray.buffer, + byteOffset: 0, + byteLength: newTexCoordArray.buffer.byteLength + }); + bufferView.buffer = buffers.length - 1; + bufferView.byteLength = newTexCoordArray.buffer.byteLength; + bufferView.byteOffset = 0; + delete bufferView.byteStride; +} +function createAttribute(newTexCoord, originalAccessor, primitive, gltfData, newTexCoordArray) { + gltfData.buffers.push({ + arrayBuffer: newTexCoordArray.buffer, + byteOffset: 0, + byteLength: newTexCoordArray.buffer.byteLength + }); + const bufferViews = gltfData.json.bufferViews; + if (!bufferViews) { + return; + } + bufferViews.push({ + buffer: gltfData.buffers.length - 1, + byteLength: newTexCoordArray.buffer.byteLength, + byteOffset: 0 + }); + const accessors = gltfData.json.accessors; + if (!accessors) { + return; + } + accessors.push({ + bufferView: (bufferViews === null || bufferViews === void 0 ? void 0 : bufferViews.length) - 1, + byteOffset: 0, + componentType: 5126, + count: originalAccessor.count, + type: 'VEC2' + }); + primitive.attributes["TEXCOORD_".concat(newTexCoord)] = accessors.length - 1; +} +function makeTransformationMatrix(extensionData) { + const { + offset = [0, 0], + rotation = 0, + scale = [1, 1] + } = extensionData; + const translationMatirx = new Matrix3().set(1, 0, 0, 0, 1, 0, offset[0], offset[1], 1); + const rotationMatirx = scratchRotationMatrix.set(Math.cos(rotation), Math.sin(rotation), 0, -Math.sin(rotation), Math.cos(rotation), 0, 0, 0, 1); + const scaleMatrix = scratchScaleMatrix.set(scale[0], 0, 0, 0, scale[1], 0, 0, 0, 1); + return translationMatirx.multiplyRight(rotationMatirx).multiplyRight(scaleMatrix); +} + +var KHR_texture_transform = /*#__PURE__*/Object.freeze({ + __proto__: null, + name: name$4, + decode: decode$4 +}); + +const KHR_LIGHTS_PUNCTUAL = 'KHR_lights_punctual'; +const name$3 = KHR_LIGHTS_PUNCTUAL; +async function decode$3(gltfData) { + const gltfScenegraph = new GLTFScenegraph(gltfData); + const { + json + } = gltfScenegraph; + const extension = gltfScenegraph.getExtension(KHR_LIGHTS_PUNCTUAL); + if (extension) { + gltfScenegraph.json.lights = extension.lights; + gltfScenegraph.removeExtension(KHR_LIGHTS_PUNCTUAL); + } + for (const node of json.nodes || []) { + const nodeExtension = gltfScenegraph.getObjectExtension(node, KHR_LIGHTS_PUNCTUAL); + if (nodeExtension) { + node.light = nodeExtension.light; + } + gltfScenegraph.removeObjectExtension(node, KHR_LIGHTS_PUNCTUAL); + } +} +async function encode$2(gltfData) { + const gltfScenegraph = new GLTFScenegraph(gltfData); + const { + json + } = gltfScenegraph; + if (json.lights) { + const extension = gltfScenegraph.addExtension(KHR_LIGHTS_PUNCTUAL); + assert$2(!extension.lights); + extension.lights = json.lights; + delete json.lights; + } + if (gltfScenegraph.json.lights) { + for (const light of gltfScenegraph.json.lights) { + const node = light.node; + gltfScenegraph.addObjectExtension(node, KHR_LIGHTS_PUNCTUAL, light); + } + delete gltfScenegraph.json.lights; + } +} + +var KHR_lights_punctual = /*#__PURE__*/Object.freeze({ + __proto__: null, + name: name$3, + decode: decode$3, + encode: encode$2 +}); + +const KHR_MATERIALS_UNLIT = 'KHR_materials_unlit'; +const name$2 = KHR_MATERIALS_UNLIT; +async function decode$2(gltfData) { + const gltfScenegraph = new GLTFScenegraph(gltfData); + const { + json + } = gltfScenegraph; + for (const material of json.materials || []) { + const extension = material.extensions && material.extensions.KHR_materials_unlit; + if (extension) { + material.unlit = true; + } + gltfScenegraph.removeObjectExtension(material, KHR_MATERIALS_UNLIT); + } + gltfScenegraph.removeExtension(KHR_MATERIALS_UNLIT); +} +function encode$1(gltfData) { + const gltfScenegraph = new GLTFScenegraph(gltfData); + const { + json + } = gltfScenegraph; + if (gltfScenegraph.materials) { + for (const material of json.materials || []) { + if (material.unlit) { + delete material.unlit; + gltfScenegraph.addObjectExtension(material, KHR_MATERIALS_UNLIT, {}); + gltfScenegraph.addExtension(KHR_MATERIALS_UNLIT); + } + } + } +} + +var KHR_materials_unlit = /*#__PURE__*/Object.freeze({ + __proto__: null, + name: name$2, + decode: decode$2, + encode: encode$1 +}); + +const KHR_TECHNIQUES_WEBGL = 'KHR_techniques_webgl'; +const name$1 = KHR_TECHNIQUES_WEBGL; +async function decode$1(gltfData) { + const gltfScenegraph = new GLTFScenegraph(gltfData); + const { + json + } = gltfScenegraph; + const extension = gltfScenegraph.getExtension(KHR_TECHNIQUES_WEBGL); + if (extension) { + const techniques = resolveTechniques(extension, gltfScenegraph); + for (const material of json.materials || []) { + const materialExtension = gltfScenegraph.getObjectExtension(material, KHR_TECHNIQUES_WEBGL); + if (materialExtension) { + material.technique = Object.assign({}, materialExtension, techniques[materialExtension.technique]); + material.technique.values = resolveValues(material.technique, gltfScenegraph); + } + gltfScenegraph.removeObjectExtension(material, KHR_TECHNIQUES_WEBGL); + } + gltfScenegraph.removeExtension(KHR_TECHNIQUES_WEBGL); + } +} +async function encode(gltfData, options) {} +function resolveTechniques(techniquesExtension, gltfScenegraph) { + const { + programs = [], + shaders = [], + techniques = [] + } = techniquesExtension; + const textDecoder = new TextDecoder(); + shaders.forEach(shader => { + if (Number.isFinite(shader.bufferView)) { + shader.code = textDecoder.decode(gltfScenegraph.getTypedArrayForBufferView(shader.bufferView)); + } else { + throw new Error('KHR_techniques_webgl: no shader code'); + } + }); + programs.forEach(program => { + program.fragmentShader = shaders[program.fragmentShader]; + program.vertexShader = shaders[program.vertexShader]; + }); + techniques.forEach(technique => { + technique.program = programs[technique.program]; + }); + return techniques; +} +function resolveValues(technique, gltfScenegraph) { + const values = Object.assign({}, technique.values); + Object.keys(technique.uniforms || {}).forEach(uniform => { + if (technique.uniforms[uniform].value && !(uniform in values)) { + values[uniform] = technique.uniforms[uniform].value; + } + }); + Object.keys(values).forEach(uniform => { + if (typeof values[uniform] === 'object' && values[uniform].index !== undefined) { + values[uniform].texture = gltfScenegraph.getTexture(values[uniform].index); + } + }); + return values; +} + +var KHR_techniques_webgl = /*#__PURE__*/Object.freeze({ + __proto__: null, + name: name$1, + decode: decode$1, + encode: encode +}); + +const EXT_FEATURE_METADATA = 'EXT_feature_metadata'; +const name = EXT_FEATURE_METADATA; +async function decode(gltfData) { + const scenegraph = new GLTFScenegraph(gltfData); + decodeExtFeatureMetadata(scenegraph); +} +function decodeExtFeatureMetadata(scenegraph) { + var _extension$schema; + const extension = scenegraph.getExtension(EXT_FEATURE_METADATA); + const schemaClasses = extension === null || extension === void 0 ? void 0 : (_extension$schema = extension.schema) === null || _extension$schema === void 0 ? void 0 : _extension$schema.classes; + const featureTables = extension === null || extension === void 0 ? void 0 : extension.featureTables; + const featureTextures = extension === null || extension === void 0 ? void 0 : extension.featureTextures; + if (featureTextures) { + console.warn('featureTextures is not yet supported in the "EXT_feature_metadata" extension.'); + } + if (schemaClasses && featureTables) { + for (const schemaName in schemaClasses) { + const schemaClass = schemaClasses[schemaName]; + const featureTable = findFeatureTableByName(featureTables, schemaName); + if (featureTable) { + handleFeatureTableProperties(scenegraph, featureTable, schemaClass); + } + } + } +} +function handleFeatureTableProperties(scenegraph, featureTable, schemaClass) { + for (const propertyName in schemaClass.properties) { + var _featureTable$propert; + const schemaProperty = schemaClass.properties[propertyName]; + const featureTableProperty = featureTable === null || featureTable === void 0 ? void 0 : (_featureTable$propert = featureTable.properties) === null || _featureTable$propert === void 0 ? void 0 : _featureTable$propert[propertyName]; + const numberOfFeatures = featureTable.count; + if (featureTableProperty) { + const data = getPropertyDataFromBinarySource(scenegraph, schemaProperty, numberOfFeatures, featureTableProperty); + featureTableProperty.data = data; + } + } +} +function getPropertyDataFromBinarySource(scenegraph, schemaProperty, numberOfFeatures, featureTableProperty) { + const bufferView = featureTableProperty.bufferView; + let data = scenegraph.getTypedArrayForBufferView(bufferView); + switch (schemaProperty.type) { + case 'STRING': + { + const stringOffsetBufferView = featureTableProperty.stringOffsetBufferView; + const offsetsData = scenegraph.getTypedArrayForBufferView(stringOffsetBufferView); + data = getStringAttributes(data, offsetsData, numberOfFeatures); + break; + } + } + return data; +} +function findFeatureTableByName(featureTables, schemaClassName) { + for (const featureTableName in featureTables) { + const featureTable = featureTables[featureTableName]; + if (featureTable.class === schemaClassName) { + return featureTable; + } + } + return null; +} +function getStringAttributes(data, offsetsData, stringsCount) { + const stringsArray = []; + const textDecoder = new TextDecoder('utf8'); + let stringOffset = 0; + const bytesPerStringSize = 4; + for (let index = 0; index < stringsCount; index++) { + const stringByteSize = offsetsData[(index + 1) * bytesPerStringSize] - offsetsData[index * bytesPerStringSize]; + const stringData = data.subarray(stringOffset, stringByteSize + stringOffset); + const stringAttribute = textDecoder.decode(stringData); + stringsArray.push(stringAttribute); + stringOffset += stringByteSize; + } + return stringsArray; +} + +var EXT_feature_metadata = /*#__PURE__*/Object.freeze({ + __proto__: null, + name: name, + decode: decode +}); + +const EXTENSIONS = [EXT_meshopt_compression, EXT_texture_webp, KHR_texture_basisu, KHR_draco_mesh_compression, KHR_lights_punctual, KHR_materials_unlit, KHR_techniques_webgl, KHR_texture_transform, EXT_feature_metadata]; +function preprocessExtensions(gltf) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let context = arguments.length > 2 ? arguments[2] : undefined; + const extensions = EXTENSIONS.filter(extension => useExtension(extension.name, options)); + for (const extension of extensions) { + var _extension$preprocess; + (_extension$preprocess = extension.preprocess) === null || _extension$preprocess === void 0 ? void 0 : _extension$preprocess.call(extension, gltf, options, context); + } +} +async function decodeExtensions(gltf) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let context = arguments.length > 2 ? arguments[2] : undefined; + const extensions = EXTENSIONS.filter(extension => useExtension(extension.name, options)); + for (const extension of extensions) { + var _extension$decode; + await ((_extension$decode = extension.decode) === null || _extension$decode === void 0 ? void 0 : _extension$decode.call(extension, gltf, options, context)); + } +} +function useExtension(extensionName, options) { + var _options$gltf; + const excludes = (options === null || options === void 0 ? void 0 : (_options$gltf = options.gltf) === null || _options$gltf === void 0 ? void 0 : _options$gltf.excludeExtensions) || {}; + const exclude = extensionName in excludes && !excludes[extensionName]; + return !exclude; +} + +const KHR_BINARY_GLTF = 'KHR_binary_glTF'; +function preprocess(gltfData) { + const gltfScenegraph = new GLTFScenegraph(gltfData); + const { + json + } = gltfScenegraph; + for (const image of json.images || []) { + const extension = gltfScenegraph.getObjectExtension(image, KHR_BINARY_GLTF); + if (extension) { + Object.assign(image, extension); + } + gltfScenegraph.removeObjectExtension(image, KHR_BINARY_GLTF); + } + if (json.buffers && json.buffers[0]) { + delete json.buffers[0].uri; + } + gltfScenegraph.removeExtension(KHR_BINARY_GLTF); +} + +const GLTF_ARRAYS = { + accessors: 'accessor', + animations: 'animation', + buffers: 'buffer', + bufferViews: 'bufferView', + images: 'image', + materials: 'material', + meshes: 'mesh', + nodes: 'node', + samplers: 'sampler', + scenes: 'scene', + skins: 'skin', + textures: 'texture' +}; +const GLTF_KEYS = { + accessor: 'accessors', + animations: 'animation', + buffer: 'buffers', + bufferView: 'bufferViews', + image: 'images', + material: 'materials', + mesh: 'meshes', + node: 'nodes', + sampler: 'samplers', + scene: 'scenes', + skin: 'skins', + texture: 'textures' +}; +class GLTFV1Normalizer { + constructor() { + _defineProperty(this, "idToIndexMap", { + animations: {}, + accessors: {}, + buffers: {}, + bufferViews: {}, + images: {}, + materials: {}, + meshes: {}, + nodes: {}, + samplers: {}, + scenes: {}, + skins: {}, + textures: {} + }); + _defineProperty(this, "json", void 0); + } + normalize(gltf, options) { + this.json = gltf.json; + const json = gltf.json; + switch (json.asset && json.asset.version) { + case '2.0': + return; + case undefined: + case '1.0': + break; + default: + console.warn("glTF: Unknown version ".concat(json.asset.version)); + return; + } + if (!options.normalize) { + throw new Error('glTF v1 is not supported.'); + } + console.warn('Converting glTF v1 to glTF v2 format. This is experimental and may fail.'); + this._addAsset(json); + this._convertTopLevelObjectsToArrays(json); + preprocess(gltf); + this._convertObjectIdsToArrayIndices(json); + this._updateObjects(json); + this._updateMaterial(json); + } + _addAsset(json) { + json.asset = json.asset || {}; + json.asset.version = '2.0'; + json.asset.generator = json.asset.generator || 'Normalized to glTF 2.0 by loaders.gl'; + } + _convertTopLevelObjectsToArrays(json) { + for (const arrayName in GLTF_ARRAYS) { + this._convertTopLevelObjectToArray(json, arrayName); + } + } + _convertTopLevelObjectToArray(json, mapName) { + const objectMap = json[mapName]; + if (!objectMap || Array.isArray(objectMap)) { + return; + } + json[mapName] = []; + for (const id in objectMap) { + const object = objectMap[id]; + object.id = object.id || id; + const index = json[mapName].length; + json[mapName].push(object); + this.idToIndexMap[mapName][id] = index; + } + } + _convertObjectIdsToArrayIndices(json) { + for (const arrayName in GLTF_ARRAYS) { + this._convertIdsToIndices(json, arrayName); + } + if ('scene' in json) { + json.scene = this._convertIdToIndex(json.scene, 'scene'); + } + for (const texture of json.textures) { + this._convertTextureIds(texture); + } + for (const mesh of json.meshes) { + this._convertMeshIds(mesh); + } + for (const node of json.nodes) { + this._convertNodeIds(node); + } + for (const node of json.scenes) { + this._convertSceneIds(node); + } + } + _convertTextureIds(texture) { + if (texture.source) { + texture.source = this._convertIdToIndex(texture.source, 'image'); + } + } + _convertMeshIds(mesh) { + for (const primitive of mesh.primitives) { + const { + attributes, + indices, + material + } = primitive; + for (const attributeName in attributes) { + attributes[attributeName] = this._convertIdToIndex(attributes[attributeName], 'accessor'); + } + if (indices) { + primitive.indices = this._convertIdToIndex(indices, 'accessor'); + } + if (material) { + primitive.material = this._convertIdToIndex(material, 'material'); + } + } + } + _convertNodeIds(node) { + if (node.children) { + node.children = node.children.map(child => this._convertIdToIndex(child, 'node')); + } + if (node.meshes) { + node.meshes = node.meshes.map(mesh => this._convertIdToIndex(mesh, 'mesh')); + } + } + _convertSceneIds(scene) { + if (scene.nodes) { + scene.nodes = scene.nodes.map(node => this._convertIdToIndex(node, 'node')); + } + } + _convertIdsToIndices(json, topLevelArrayName) { + if (!json[topLevelArrayName]) { + console.warn("gltf v1: json doesn't contain attribute ".concat(topLevelArrayName)); + json[topLevelArrayName] = []; + } + for (const object of json[topLevelArrayName]) { + for (const key in object) { + const id = object[key]; + const index = this._convertIdToIndex(id, key); + object[key] = index; + } + } + } + _convertIdToIndex(id, key) { + const arrayName = GLTF_KEYS[key]; + if (arrayName in this.idToIndexMap) { + const index = this.idToIndexMap[arrayName][id]; + if (!Number.isFinite(index)) { + throw new Error("gltf v1: failed to resolve ".concat(key, " with id ").concat(id)); + } + return index; + } + return id; + } + _updateObjects(json) { + for (const buffer of this.json.buffers) { + delete buffer.type; + } + } + _updateMaterial(json) { + for (const material of json.materials) { + var _material$values, _material$values2, _material$values3; + material.pbrMetallicRoughness = { + baseColorFactor: [1, 1, 1, 1], + metallicFactor: 1, + roughnessFactor: 1 + }; + const textureId = ((_material$values = material.values) === null || _material$values === void 0 ? void 0 : _material$values.tex) || ((_material$values2 = material.values) === null || _material$values2 === void 0 ? void 0 : _material$values2.texture2d_0) || ((_material$values3 = material.values) === null || _material$values3 === void 0 ? void 0 : _material$values3.diffuseTex); + const textureIndex = json.textures.findIndex(texture => texture.id === textureId); + if (textureIndex !== -1) { + material.pbrMetallicRoughness.baseColorTexture = { + index: textureIndex + }; + } + } + } +} +function normalizeGLTFV1(gltf) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return new GLTFV1Normalizer().normalize(gltf, options); +} + +const COMPONENTS = { + SCALAR: 1, + VEC2: 2, + VEC3: 3, + VEC4: 4, + MAT2: 4, + MAT3: 9, + MAT4: 16 +}; +const BYTES = { + 5120: 1, + 5121: 1, + 5122: 2, + 5123: 2, + 5125: 4, + 5126: 4 +}; +const GL_SAMPLER = { + TEXTURE_MAG_FILTER: 0x2800, + TEXTURE_MIN_FILTER: 0x2801, + TEXTURE_WRAP_S: 0x2802, + TEXTURE_WRAP_T: 0x2803, + REPEAT: 0x2901, + LINEAR: 0x2601, + NEAREST_MIPMAP_LINEAR: 0x2702 +}; +const SAMPLER_PARAMETER_GLTF_TO_GL = { + magFilter: GL_SAMPLER.TEXTURE_MAG_FILTER, + minFilter: GL_SAMPLER.TEXTURE_MIN_FILTER, + wrapS: GL_SAMPLER.TEXTURE_WRAP_S, + wrapT: GL_SAMPLER.TEXTURE_WRAP_T +}; +const DEFAULT_SAMPLER = { + [GL_SAMPLER.TEXTURE_MAG_FILTER]: GL_SAMPLER.LINEAR, + [GL_SAMPLER.TEXTURE_MIN_FILTER]: GL_SAMPLER.NEAREST_MIPMAP_LINEAR, + [GL_SAMPLER.TEXTURE_WRAP_S]: GL_SAMPLER.REPEAT, + [GL_SAMPLER.TEXTURE_WRAP_T]: GL_SAMPLER.REPEAT +}; +function getBytesFromComponentType(componentType) { + return BYTES[componentType]; +} +function getSizeFromAccessorType(type) { + return COMPONENTS[type]; +} +class GLTFPostProcessor { + constructor() { + _defineProperty(this, "baseUri", ''); + _defineProperty(this, "json", {}); + _defineProperty(this, "buffers", []); + _defineProperty(this, "images", []); + } + postProcess(gltf) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const { + json, + buffers = [], + images = [], + baseUri = '' + } = gltf; + assert$2(json); + this.baseUri = baseUri; + this.json = json; + this.buffers = buffers; + this.images = images; + this._resolveTree(this.json, options); + return this.json; + } + _resolveTree(json) { + if (json.bufferViews) { + json.bufferViews = json.bufferViews.map((bufView, i) => this._resolveBufferView(bufView, i)); + } + if (json.images) { + json.images = json.images.map((image, i) => this._resolveImage(image, i)); + } + if (json.samplers) { + json.samplers = json.samplers.map((sampler, i) => this._resolveSampler(sampler, i)); + } + if (json.textures) { + json.textures = json.textures.map((texture, i) => this._resolveTexture(texture, i)); + } + if (json.accessors) { + json.accessors = json.accessors.map((accessor, i) => this._resolveAccessor(accessor, i)); + } + if (json.materials) { + json.materials = json.materials.map((material, i) => this._resolveMaterial(material, i)); + } + if (json.meshes) { + json.meshes = json.meshes.map((mesh, i) => this._resolveMesh(mesh, i)); + } + if (json.nodes) { + json.nodes = json.nodes.map((node, i) => this._resolveNode(node, i)); + } + if (json.skins) { + json.skins = json.skins.map((skin, i) => this._resolveSkin(skin, i)); + } + if (json.scenes) { + json.scenes = json.scenes.map((scene, i) => this._resolveScene(scene, i)); + } + if (json.scene !== undefined) { + json.scene = json.scenes[this.json.scene]; + } + } + getScene(index) { + return this._get('scenes', index); + } + getNode(index) { + return this._get('nodes', index); + } + getSkin(index) { + return this._get('skins', index); + } + getMesh(index) { + return this._get('meshes', index); + } + getMaterial(index) { + return this._get('materials', index); + } + getAccessor(index) { + return this._get('accessors', index); + } + getCamera(index) { + return null; + } + getTexture(index) { + return this._get('textures', index); + } + getSampler(index) { + return this._get('samplers', index); + } + getImage(index) { + return this._get('images', index); + } + getBufferView(index) { + return this._get('bufferViews', index); + } + getBuffer(index) { + return this._get('buffers', index); + } + _get(array, index) { + if (typeof index === 'object') { + return index; + } + const object = this.json[array] && this.json[array][index]; + if (!object) { + console.warn("glTF file error: Could not find ".concat(array, "[").concat(index, "]")); + } + return object; + } + _resolveScene(scene, index) { + scene.id = scene.id || "scene-".concat(index); + scene.nodes = (scene.nodes || []).map(node => this.getNode(node)); + return scene; + } + _resolveNode(node, index) { + node.id = node.id || "node-".concat(index); + if (node.children) { + node.children = node.children.map(child => this.getNode(child)); + } + if (node.mesh !== undefined) { + node.mesh = this.getMesh(node.mesh); + } else if (node.meshes !== undefined && node.meshes.length) { + node.mesh = node.meshes.reduce((accum, meshIndex) => { + const mesh = this.getMesh(meshIndex); + accum.id = mesh.id; + accum.primitives = accum.primitives.concat(mesh.primitives); + return accum; + }, { + primitives: [] + }); + } + if (node.camera !== undefined) { + node.camera = this.getCamera(node.camera); + } + if (node.skin !== undefined) { + node.skin = this.getSkin(node.skin); + } + return node; + } + _resolveSkin(skin, index) { + skin.id = skin.id || "skin-".concat(index); + skin.inverseBindMatrices = this.getAccessor(skin.inverseBindMatrices); + return skin; + } + _resolveMesh(mesh, index) { + mesh.id = mesh.id || "mesh-".concat(index); + if (mesh.primitives) { + mesh.primitives = mesh.primitives.map(primitive => { + primitive = { + ...primitive + }; + const attributes = primitive.attributes; + primitive.attributes = {}; + for (const attribute in attributes) { + primitive.attributes[attribute] = this.getAccessor(attributes[attribute]); + } + if (primitive.indices !== undefined) { + primitive.indices = this.getAccessor(primitive.indices); + } + if (primitive.material !== undefined) { + primitive.material = this.getMaterial(primitive.material); + } + return primitive; + }); + } + return mesh; + } + _resolveMaterial(material, index) { + material.id = material.id || "material-".concat(index); + if (material.normalTexture) { + material.normalTexture = { + ...material.normalTexture + }; + material.normalTexture.texture = this.getTexture(material.normalTexture.index); + } + if (material.occlusionTexture) { + material.occlustionTexture = { + ...material.occlustionTexture + }; + material.occlusionTexture.texture = this.getTexture(material.occlusionTexture.index); + } + if (material.emissiveTexture) { + material.emmisiveTexture = { + ...material.emmisiveTexture + }; + material.emissiveTexture.texture = this.getTexture(material.emissiveTexture.index); + } + if (!material.emissiveFactor) { + material.emissiveFactor = material.emmisiveTexture ? [1, 1, 1] : [0, 0, 0]; + } + if (material.pbrMetallicRoughness) { + material.pbrMetallicRoughness = { + ...material.pbrMetallicRoughness + }; + const mr = material.pbrMetallicRoughness; + if (mr.baseColorTexture) { + mr.baseColorTexture = { + ...mr.baseColorTexture + }; + mr.baseColorTexture.texture = this.getTexture(mr.baseColorTexture.index); + } + if (mr.metallicRoughnessTexture) { + mr.metallicRoughnessTexture = { + ...mr.metallicRoughnessTexture + }; + mr.metallicRoughnessTexture.texture = this.getTexture(mr.metallicRoughnessTexture.index); + } + } + return material; + } + _resolveAccessor(accessor, index) { + accessor.id = accessor.id || "accessor-".concat(index); + if (accessor.bufferView !== undefined) { + accessor.bufferView = this.getBufferView(accessor.bufferView); + } + accessor.bytesPerComponent = getBytesFromComponentType(accessor.componentType); + accessor.components = getSizeFromAccessorType(accessor.type); + accessor.bytesPerElement = accessor.bytesPerComponent * accessor.components; + if (accessor.bufferView) { + const buffer = accessor.bufferView.buffer; + const { + ArrayType, + byteLength + } = getAccessorArrayTypeAndLength(accessor, accessor.bufferView); + const byteOffset = (accessor.bufferView.byteOffset || 0) + (accessor.byteOffset || 0) + buffer.byteOffset; + let cutBuffer = buffer.arrayBuffer.slice(byteOffset, byteOffset + byteLength); + if (accessor.bufferView.byteStride) { + cutBuffer = this._getValueFromInterleavedBuffer(buffer, byteOffset, accessor.bufferView.byteStride, accessor.bytesPerElement, accessor.count); + } + accessor.value = new ArrayType(cutBuffer); + } + return accessor; + } + _getValueFromInterleavedBuffer(buffer, byteOffset, byteStride, bytesPerElement, count) { + const result = new Uint8Array(count * bytesPerElement); + for (let i = 0; i < count; i++) { + const elementOffset = byteOffset + i * byteStride; + result.set(new Uint8Array(buffer.arrayBuffer.slice(elementOffset, elementOffset + bytesPerElement)), i * bytesPerElement); + } + return result.buffer; + } + _resolveTexture(texture, index) { + texture.id = texture.id || "texture-".concat(index); + texture.sampler = 'sampler' in texture ? this.getSampler(texture.sampler) : DEFAULT_SAMPLER; + texture.source = this.getImage(texture.source); + return texture; + } + _resolveSampler(sampler, index) { + sampler.id = sampler.id || "sampler-".concat(index); + sampler.parameters = {}; + for (const key in sampler) { + const glEnum = this._enumSamplerParameter(key); + if (glEnum !== undefined) { + sampler.parameters[glEnum] = sampler[key]; + } + } + return sampler; + } + _enumSamplerParameter(key) { + return SAMPLER_PARAMETER_GLTF_TO_GL[key]; + } + _resolveImage(image, index) { + image.id = image.id || "image-".concat(index); + if (image.bufferView !== undefined) { + image.bufferView = this.getBufferView(image.bufferView); + } + const preloadedImage = this.images[index]; + if (preloadedImage) { + image.image = preloadedImage; + } + return image; + } + _resolveBufferView(bufferView, index) { + const bufferIndex = bufferView.buffer; + const result = { + id: "bufferView-".concat(index), + ...bufferView, + buffer: this.buffers[bufferIndex] + }; + const arrayBuffer = this.buffers[bufferIndex].arrayBuffer; + let byteOffset = this.buffers[bufferIndex].byteOffset || 0; + if ('byteOffset' in bufferView) { + byteOffset += bufferView.byteOffset; + } + result.data = new Uint8Array(arrayBuffer, byteOffset, bufferView.byteLength); + return result; + } + _resolveCamera(camera, index) { + camera.id = camera.id || "camera-".concat(index); + if (camera.perspective) ; + if (camera.orthographic) ; + return camera; + } +} +function postProcessGLTF(gltf, options) { + return new GLTFPostProcessor().postProcess(gltf, options); +} + +const MAGIC_glTF = 0x676c5446; +const GLB_FILE_HEADER_SIZE = 12; +const GLB_CHUNK_HEADER_SIZE = 8; +const GLB_CHUNK_TYPE_JSON = 0x4e4f534a; +const GLB_CHUNK_TYPE_BIN = 0x004e4942; +const GLB_CHUNK_TYPE_JSON_XVIZ_DEPRECATED = 0; +const GLB_CHUNK_TYPE_BIX_XVIZ_DEPRECATED = 1; +const GLB_V1_CONTENT_FORMAT_JSON = 0x0; +const LE = true; +function getMagicString(dataView) { + let byteOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return "".concat(String.fromCharCode(dataView.getUint8(byteOffset + 0))).concat(String.fromCharCode(dataView.getUint8(byteOffset + 1))).concat(String.fromCharCode(dataView.getUint8(byteOffset + 2))).concat(String.fromCharCode(dataView.getUint8(byteOffset + 3))); +} +function isGLB(arrayBuffer) { + let byteOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + const dataView = new DataView(arrayBuffer); + const { + magic = MAGIC_glTF + } = options; + const magic1 = dataView.getUint32(byteOffset, false); + return magic1 === magic || magic1 === MAGIC_glTF; +} +function parseGLBSync(glb, arrayBuffer) { + let byteOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + const dataView = new DataView(arrayBuffer); + const type = getMagicString(dataView, byteOffset + 0); + const version = dataView.getUint32(byteOffset + 4, LE); + const byteLength = dataView.getUint32(byteOffset + 8, LE); + Object.assign(glb, { + header: { + byteOffset, + byteLength, + hasBinChunk: false + }, + type, + version, + json: {}, + binChunks: [] + }); + byteOffset += GLB_FILE_HEADER_SIZE; + switch (glb.version) { + case 1: + return parseGLBV1(glb, dataView, byteOffset); + case 2: + return parseGLBV2(glb, dataView, byteOffset, {}); + default: + throw new Error("Invalid GLB version ".concat(glb.version, ". Only supports v1 and v2.")); + } +} +function parseGLBV1(glb, dataView, byteOffset) { + assert$5(glb.header.byteLength > GLB_FILE_HEADER_SIZE + GLB_CHUNK_HEADER_SIZE); + const contentLength = dataView.getUint32(byteOffset + 0, LE); + const contentFormat = dataView.getUint32(byteOffset + 4, LE); + byteOffset += GLB_CHUNK_HEADER_SIZE; + assert$5(contentFormat === GLB_V1_CONTENT_FORMAT_JSON); + parseJSONChunk(glb, dataView, byteOffset, contentLength); + byteOffset += contentLength; + byteOffset += parseBINChunk(glb, dataView, byteOffset, glb.header.byteLength); + return byteOffset; +} +function parseGLBV2(glb, dataView, byteOffset, options) { + assert$5(glb.header.byteLength > GLB_FILE_HEADER_SIZE + GLB_CHUNK_HEADER_SIZE); + parseGLBChunksSync(glb, dataView, byteOffset, options); + return byteOffset + glb.header.byteLength; +} +function parseGLBChunksSync(glb, dataView, byteOffset, options) { + while (byteOffset + 8 <= glb.header.byteLength) { + const chunkLength = dataView.getUint32(byteOffset + 0, LE); + const chunkFormat = dataView.getUint32(byteOffset + 4, LE); + byteOffset += GLB_CHUNK_HEADER_SIZE; + switch (chunkFormat) { + case GLB_CHUNK_TYPE_JSON: + parseJSONChunk(glb, dataView, byteOffset, chunkLength); + break; + case GLB_CHUNK_TYPE_BIN: + parseBINChunk(glb, dataView, byteOffset, chunkLength); + break; + case GLB_CHUNK_TYPE_JSON_XVIZ_DEPRECATED: + if (!options.strict) { + parseJSONChunk(glb, dataView, byteOffset, chunkLength); + } + break; + case GLB_CHUNK_TYPE_BIX_XVIZ_DEPRECATED: + if (!options.strict) { + parseBINChunk(glb, dataView, byteOffset, chunkLength); + } + break; + } + byteOffset += padToNBytes(chunkLength, 4); + } + return byteOffset; +} +function parseJSONChunk(glb, dataView, byteOffset, chunkLength) { + const jsonChunk = new Uint8Array(dataView.buffer, byteOffset, chunkLength); + const textDecoder = new TextDecoder('utf8'); + const jsonText = textDecoder.decode(jsonChunk); + glb.json = JSON.parse(jsonText); + return padToNBytes(chunkLength, 4); +} +function parseBINChunk(glb, dataView, byteOffset, chunkLength) { + glb.header.hasBinChunk = true; + glb.binChunks.push({ + byteOffset, + byteLength: chunkLength, + arrayBuffer: dataView.buffer + }); + return padToNBytes(chunkLength, 4); +} + +async function parseGLTF(gltf, arrayBufferOrString) { + var _options$gltf, _options$gltf2, _options$gltf3, _options$gltf4; + let byteOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + let options = arguments.length > 3 ? arguments[3] : undefined; + let context = arguments.length > 4 ? arguments[4] : undefined; + parseGLTFContainerSync(gltf, arrayBufferOrString, byteOffset, options); + normalizeGLTFV1(gltf, { + normalize: options === null || options === void 0 ? void 0 : (_options$gltf = options.gltf) === null || _options$gltf === void 0 ? void 0 : _options$gltf.normalize + }); + preprocessExtensions(gltf, options, context); + const promises = []; + if (options !== null && options !== void 0 && (_options$gltf2 = options.gltf) !== null && _options$gltf2 !== void 0 && _options$gltf2.loadBuffers && gltf.json.buffers) { + await loadBuffers(gltf, options, context); + } + if (options !== null && options !== void 0 && (_options$gltf3 = options.gltf) !== null && _options$gltf3 !== void 0 && _options$gltf3.loadImages) { + const promise = loadImages(gltf, options, context); + promises.push(promise); + } + const promise = decodeExtensions(gltf, options, context); + promises.push(promise); + await Promise.all(promises); + return options !== null && options !== void 0 && (_options$gltf4 = options.gltf) !== null && _options$gltf4 !== void 0 && _options$gltf4.postProcess ? postProcessGLTF(gltf, options) : gltf; +} +function parseGLTFContainerSync(gltf, data, byteOffset, options) { + if (options.uri) { + gltf.baseUri = options.uri; + } + if (data instanceof ArrayBuffer && !isGLB(data, byteOffset, options)) { + const textDecoder = new TextDecoder(); + data = textDecoder.decode(data); + } + if (typeof data === 'string') { + gltf.json = parseJSON(data); + } else if (data instanceof ArrayBuffer) { + const glb = {}; + byteOffset = parseGLBSync(glb, data, byteOffset, options.glb); + assert$2(glb.type === 'glTF', "Invalid GLB magic string ".concat(glb.type)); + gltf._glb = glb; + gltf.json = glb.json; + } else { + assert$2(false, 'GLTF: must be ArrayBuffer or string'); + } + const buffers = gltf.json.buffers || []; + gltf.buffers = new Array(buffers.length).fill(null); + if (gltf._glb && gltf._glb.header.hasBinChunk) { + const { + binChunks + } = gltf._glb; + gltf.buffers[0] = { + arrayBuffer: binChunks[0].arrayBuffer, + byteOffset: binChunks[0].byteOffset, + byteLength: binChunks[0].byteLength + }; + } + const images = gltf.json.images || []; + gltf.images = new Array(images.length).fill({}); +} +async function loadBuffers(gltf, options, context) { + const buffers = gltf.json.buffers || []; + for (let i = 0; i < buffers.length; ++i) { + const buffer = buffers[i]; + if (buffer.uri) { + var _context$fetch, _response$arrayBuffer; + const { + fetch + } = context; + assert$2(fetch); + const uri = resolveUrl(buffer.uri, options); + const response = await (context === null || context === void 0 ? void 0 : (_context$fetch = context.fetch) === null || _context$fetch === void 0 ? void 0 : _context$fetch.call(context, uri)); + const arrayBuffer = await (response === null || response === void 0 ? void 0 : (_response$arrayBuffer = response.arrayBuffer) === null || _response$arrayBuffer === void 0 ? void 0 : _response$arrayBuffer.call(response)); + gltf.buffers[i] = { + arrayBuffer, + byteOffset: 0, + byteLength: arrayBuffer.byteLength + }; + delete buffer.uri; + } else if (gltf.buffers[i] === null) { + gltf.buffers[i] = { + arrayBuffer: new ArrayBuffer(buffer.byteLength), + byteOffset: 0, + byteLength: buffer.byteLength + }; + } + } +} +async function loadImages(gltf, options, context) { + const imageIndices = getReferencesImageIndices(gltf); + const images = gltf.json.images || []; + const promises = []; + for (const imageIndex of imageIndices) { + promises.push(loadImage(gltf, images[imageIndex], imageIndex, options, context)); + } + return await Promise.all(promises); +} +function getReferencesImageIndices(gltf) { + const imageIndices = new Set(); + const textures = gltf.json.textures || []; + for (const texture of textures) { + if (texture.source !== undefined) { + imageIndices.add(texture.source); + } + } + return Array.from(imageIndices).sort(); +} +async function loadImage(gltf, image, index, options, context) { + const { + fetch, + parse + } = context; + let arrayBuffer; + if (image.uri && !image.hasOwnProperty('bufferView')) { + const uri = resolveUrl(image.uri, options); + const response = await fetch(uri); + arrayBuffer = await response.arrayBuffer(); + image.bufferView = { + data: arrayBuffer + }; + } + if (Number.isFinite(image.bufferView)) { + const array = getTypedArrayForBufferView(gltf.json, gltf.buffers, image.bufferView); + arrayBuffer = sliceArrayBuffer(array.buffer, array.byteOffset, array.byteLength); + } + assert$2(arrayBuffer, 'glTF image has no data'); + let parsedImage = await parse(arrayBuffer, [ImageLoader, BasisLoader], { + mimeType: image.mimeType, + basis: options.basis || { + format: selectSupportedBasisFormat() + } + }, context); + if (parsedImage && parsedImage[0]) { + parsedImage = { + compressed: true, + mipmaps: false, + width: parsedImage[0].width, + height: parsedImage[0].height, + data: parsedImage[0] + }; + } + gltf.images = gltf.images || []; + gltf.images[index] = parsedImage; +} + +const GLTFLoader = { + name: 'glTF', + id: 'gltf', + module: 'gltf', + version: VERSION$1, + extensions: ['gltf', 'glb'], + mimeTypes: ['model/gltf+json', 'model/gltf-binary'], + text: true, + binary: true, + tests: ['glTF'], + parse, + options: { + gltf: { + normalize: true, + loadBuffers: true, + loadImages: true, + decompressMeshes: true, + postProcess: true + }, + log: console + }, + deprecatedOptions: { + fetchImages: 'gltf.loadImages', + createImages: 'gltf.loadImages', + decompress: 'gltf.decompressMeshes', + postProcess: 'gltf.postProcess', + gltf: { + decompress: 'gltf.decompressMeshes' + } + } +}; +async function parse(arrayBuffer) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let context = arguments.length > 2 ? arguments[2] : undefined; + options = { + ...GLTFLoader.options, + ...options + }; + options.gltf = { + ...GLTFLoader.options.gltf, + ...options.gltf + }; + const { + byteOffset = 0 + } = options; + const gltf = {}; + return await parseGLTF(gltf, arrayBuffer, byteOffset, options, context); +} + +/** + * @desc Parses glTF into an {@link XKTModel}, supporting ````.glb```` and textures. + * + * * Supports ````.glb```` and textures + * * For a lightweight glTF JSON parser that ignores textures, see {@link parseGLTFJSONIntoXKTModel}. + * + * ## Usage + * + * In the example below we'll create an {@link XKTModel}, then load a binary glTF model into it. + * + * ````javascript + * utils.loadArraybuffer("../assets/models/gltf/HousePlan/glTF-Binary/HousePlan.glb", async (data) => { + * + * const xktModel = new XKTModel(); + * + * parseGLTFIntoXKTModel({ + * data, + * xktModel, + * log: (msg) => { console.log(msg); } + * }).then(()=>{ + * xktModel.finalize(); + * }, + * (msg) => { + * console.error(msg); + * }); + * }); + * ```` + * + * @param {Object} params Parsing parameters. + * @param {ArrayBuffer} params.data The glTF. + * @param {String} [params.baseUri] The base URI used to load this glTF, if any. For resolving relative uris to linked resources. + * @param {Object} [params.metaModelData] Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly. + * @param {XKTModel} params.xktModel XKTModel to parse into. + * @param {Boolean} [params.includeTextures=true] Whether to parse textures. + * @param {Boolean} [params.includeNormals=true] Whether to parse normals. When false, the parser will ignore the glTF + * geometry normals, and the glTF data will rely on the xeokit ````Viewer```` to automatically generate them. This has + * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render + * a flat-shaded non-PBR representation of the glTF. + * @param {Object} [params.stats] Collects statistics. + * @param {function} [params.log] Logging callback. + @returns {Promise} Resolves when glTF has been parsed. + */ +function parseGLTFIntoXKTModel({ + data, + baseUri, + xktModel, + metaModelData, + includeTextures = true, + includeNormals = true, + getAttachment, + stats = {}, + log + }) { + + return new Promise(function (resolve, reject) { + + if (!data) { + reject("Argument expected: data"); + return; + } + + if (!xktModel) { + reject("Argument expected: xktModel"); + return; + } + + stats.sourceFormat = "glTF"; + stats.schemaVersion = "2.0"; + stats.title = ""; + stats.author = ""; + stats.created = ""; + stats.numTriangles = 0; + stats.numVertices = 0; + stats.numNormals = 0; + stats.numUVs = 0; + stats.numTextures = 0; + stats.numObjects = 0; + stats.numGeometries = 0; + + parse$2(data, GLTFLoader, { + baseUri + }).then((gltfData) => { + + const ctx = { + gltfData, + metaModelCorrections: metaModelData, + getAttachment: getAttachment || (() => { + throw new Error('You must define getAttachment() method to convert glTF with external resources') + }), + log: (log || function (msg) { + }), + error: function (msg) { + console.error(msg); + }, + xktModel, + includeNormals: (includeNormals !== false), + includeTextures: (includeTextures !== false), + geometryCreated: {}, + nextId: 0, + stats + }; + + ctx.log("Using parser: parseGLTFIntoXKTModel"); + ctx.log(`Parsing normals: ${ctx.includeNormals ? "enabled" : "disabled"}`); + ctx.log(`Parsing textures: ${ctx.includeTextures ? "enabled" : "disabled"}`); + + if (ctx.includeTextures) { + parseTextures(ctx); + } + parseMaterials(ctx); + parseDefaultScene(ctx); + + resolve(); + + }, (errMsg) => { + reject(`[parseGLTFIntoXKTModel] ${errMsg}`); + }); + }); +} + +function parseTextures(ctx) { + const gltfData = ctx.gltfData; + const textures = gltfData.textures; + if (textures) { + for (let i = 0, len = textures.length; i < len; i++) { + parseTexture(ctx, textures[i]); + ctx.stats.numTextures++; + } + } +} + +function parseTexture(ctx, texture) { + if (!texture.source || !texture.source.image) { + return; + } + const textureId = `texture-${ctx.nextId++}`; + + let minFilter = NearestMipMapLinearFilter; + switch (texture.sampler.minFilter) { + case 9728: + minFilter = NearestFilter; + break; + case 9729: + minFilter = LinearFilter; + break; + case 9984: + minFilter = NearestMipMapNearestFilter; + break; + case 9985: + minFilter = LinearMipMapNearestFilter; + break; + case 9986: + minFilter = NearestMipMapLinearFilter; + break; + case 9987: + minFilter = LinearMipMapLinearFilter; + break; + } + + let magFilter = LinearFilter; + switch (texture.sampler.magFilter) { + case 9728: + magFilter = NearestFilter; + break; + case 9729: + magFilter = LinearFilter; + break; + } + + let wrapS = RepeatWrapping; + switch (texture.sampler.wrapS) { + case 33071: + wrapS = ClampToEdgeWrapping; + break; + case 33648: + wrapS = MirroredRepeatWrapping; + break; + case 10497: + wrapS = RepeatWrapping; + break; + } + + let wrapT = RepeatWrapping; + switch (texture.sampler.wrapT) { + case 33071: + wrapT = ClampToEdgeWrapping; + break; + case 33648: + wrapT = MirroredRepeatWrapping; + break; + case 10497: + wrapT = RepeatWrapping; + break; + } + + let wrapR = RepeatWrapping; + switch (texture.sampler.wrapR) { + case 33071: + wrapR = ClampToEdgeWrapping; + break; + case 33648: + wrapR = MirroredRepeatWrapping; + break; + case 10497: + wrapR = RepeatWrapping; + break; + } + + ctx.xktModel.createTexture({ + textureId: textureId, + imageData: texture.source.image, + mediaType: texture.source.mediaType, + compressed: true, + width: texture.source.image.width, + height: texture.source.image.height, + minFilter, + magFilter, + wrapS, + wrapT, + wrapR, + flipY: !!texture.flipY, + // encoding: "sRGB" + }); + texture._textureId = textureId; +} + +function parseMaterials(ctx) { + const gltfData = ctx.gltfData; + const materials = gltfData.materials; + if (materials) { + for (let i = 0, len = materials.length; i < len; i++) { + const material = materials[i]; + material._textureSetId = ctx.includeTextures ? parseTextureSet(ctx, material) : null; + material._attributes = parseMaterialAttributes(ctx, material); + } + } +} + +function parseTextureSet(ctx, material) { + const textureSetCfg = {}; + if (material.normalTexture) { + textureSetCfg.normalTextureId = material.normalTexture.texture._textureId; + } + if (material.occlusionTexture) { + textureSetCfg.occlusionTextureId = material.occlusionTexture.texture._textureId; + } + if (material.emissiveTexture) { + textureSetCfg.emissiveTextureId = material.emissiveTexture.texture._textureId; + } + // const alphaMode = material.alphaMode; + // switch (alphaMode) { + // case "NORMAL_OPAQUE": + // materialCfg.alphaMode = "opaque"; + // break; + // case "MASK": + // materialCfg.alphaMode = "mask"; + // break; + // case "BLEND": + // materialCfg.alphaMode = "blend"; + // break; + // default: + // } + // const alphaCutoff = material.alphaCutoff; + // if (alphaCutoff !== undefined) { + // materialCfg.alphaCutoff = alphaCutoff; + // } + const metallicPBR = material.pbrMetallicRoughness; + if (material.pbrMetallicRoughness) { + const pbrMetallicRoughness = material.pbrMetallicRoughness; + const baseColorTexture = pbrMetallicRoughness.baseColorTexture || pbrMetallicRoughness.colorTexture; + if (baseColorTexture) { + if (baseColorTexture.texture) { + textureSetCfg.colorTextureId = baseColorTexture.texture._textureId; + } else { + textureSetCfg.colorTextureId = ctx.gltfData.textures[baseColorTexture.index]._textureId; + } + } + if (metallicPBR.metallicRoughnessTexture) { + textureSetCfg.metallicRoughnessTextureId = metallicPBR.metallicRoughnessTexture.texture._textureId; + } + } + const extensions = material.extensions; + if (extensions) { + const specularPBR = extensions["KHR_materials_pbrSpecularGlossiness"]; + if (specularPBR) { + specularPBR.specularTexture; + const specularColorTexture = specularPBR.specularColorTexture; + if (specularColorTexture !== null && specularColorTexture !== undefined) { + textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId; + } + } + } + if (textureSetCfg.normalTextureId !== undefined || + textureSetCfg.occlusionTextureId !== undefined || + textureSetCfg.emissiveTextureId !== undefined || + textureSetCfg.colorTextureId !== undefined || + textureSetCfg.metallicRoughnessTextureId !== undefined) { + textureSetCfg.textureSetId = `textureSet-${ctx.nextId++};`; + ctx.xktModel.createTextureSet(textureSetCfg); + ctx.stats.numTextureSets++; + return textureSetCfg.textureSetId; + } + return null; +} + +function parseMaterialAttributes(ctx, material) { // Substitute RGBA for material, to use fast flat shading instead + const extensions = material.extensions; + const materialAttributes = { + color: new Float32Array([1, 1, 1, 1]), + opacity: 1, + metallic: 0, + roughness: 1 + }; + if (extensions) { + const specularPBR = extensions["KHR_materials_pbrSpecularGlossiness"]; + if (specularPBR) { + const diffuseFactor = specularPBR.diffuseFactor; + if (diffuseFactor !== null && diffuseFactor !== undefined) { + materialAttributes.color.set(diffuseFactor); + } + } + const common = extensions["KHR_materials_common"]; + if (common) { + const technique = common.technique; + const values = common.values || {}; + const blinn = technique === "BLINN"; + const phong = technique === "PHONG"; + const lambert = technique === "LAMBERT"; + const diffuse = values.diffuse; + if (diffuse && (blinn || phong || lambert)) { + if (!utils.isString(diffuse)) { + materialAttributes.color.set(diffuse); + } + } + const transparency = values.transparency; + if (transparency !== null && transparency !== undefined) { + materialAttributes.opacity = transparency; + } + const transparent = values.transparent; + if (transparent !== null && transparent !== undefined) { + materialAttributes.opacity = transparent; + } + } + } + const metallicPBR = material.pbrMetallicRoughness; + if (metallicPBR) { + const baseColorFactor = metallicPBR.baseColorFactor; + if (baseColorFactor) { + materialAttributes.color[0] = baseColorFactor[0]; + materialAttributes.color[1] = baseColorFactor[1]; + materialAttributes.color[2] = baseColorFactor[2]; + materialAttributes.opacity = baseColorFactor[3]; + } + const metallicFactor = metallicPBR.metallicFactor; + if (metallicFactor !== null && metallicFactor !== undefined) { + materialAttributes.metallic = metallicFactor; + } + const roughnessFactor = metallicPBR.roughnessFactor; + if (roughnessFactor !== null && roughnessFactor !== undefined) { + materialAttributes.roughness = roughnessFactor; + } + } + return materialAttributes; +} + +function parseDefaultScene(ctx) { + const gltfData = ctx.gltfData; + const scene = gltfData.scene || gltfData.scenes[0]; + if (!scene) { + ctx.error("glTF has no default scene"); + return; + } + parseScene(ctx, scene); +} + +function parseScene(ctx, scene) { + const nodes = scene.nodes; + if (!nodes) { + return; + } + for (let i = 0, len = nodes.length; i < len; i++) { + const node = nodes[i]; + countMeshUsage(ctx, node); + } + for (let i = 0, len = nodes.length; i < len; i++) { + const node = nodes[i]; + parseNode(ctx, node, 0, null); + } +} + +function countMeshUsage(ctx, node) { + const mesh = node.mesh; + if (mesh) { + mesh.instances = mesh.instances ? mesh.instances + 1 : 1; + } + if (node.children) { + const children = node.children; + for (let i = 0, len = children.length; i < len; i++) { + const childNode = children[i]; + if (!childNode) { + ctx.error("Node not found: " + i); + continue; + } + countMeshUsage(ctx, childNode); + } + } +} + +const objectIdStack = []; +const meshIdsStack = []; + +let meshIds = null; + +function parseNode(ctx, node, depth, matrix) { + + const xktModel = ctx.xktModel; + + // Pre-order visit scene node + + let localMatrix; + if (node.matrix) { + localMatrix = node.matrix; + if (matrix) { + matrix = math.mulMat4(matrix, localMatrix, math.mat4()); + } else { + matrix = localMatrix; + } + } + if (node.translation) { + localMatrix = math.translationMat4v(node.translation); + if (matrix) { + matrix = math.mulMat4(matrix, localMatrix, math.mat4()); + } else { + matrix = localMatrix; + } + } + if (node.rotation) { + localMatrix = math.quaternionToMat4(node.rotation); + if (matrix) { + matrix = math.mulMat4(matrix, localMatrix, math.mat4()); + } else { + matrix = localMatrix; + } + } + if (node.scale) { + localMatrix = math.scalingMat4v(node.scale); + if (matrix) { + matrix = math.mulMat4(matrix, localMatrix, math.mat4()); + } else { + matrix = localMatrix; + } + } + + if (node.name) { + meshIds = []; + let xktEntityId = node.name; + if (!!xktEntityId && xktModel.entities[xktEntityId]) { + ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${xktEntityId} - will randomly-generating an object ID in XKT`); + } + while (!xktEntityId || xktModel.entities[xktEntityId]) { + xktEntityId = "entity-" + ctx.nextId++; + } + objectIdStack.push(xktEntityId); + meshIdsStack.push(meshIds); + } + + if (meshIds && node.mesh) { + + const mesh = node.mesh; + const numPrimitives = mesh.primitives.length; + + if (numPrimitives > 0) { + for (let i = 0; i < numPrimitives; i++) { + const primitive = mesh.primitives[i]; + if (!primitive._xktGeometryId) { + const xktGeometryId = "geometry-" + ctx.nextId++; + const geometryCfg = { + geometryId: xktGeometryId + }; + switch (primitive.mode) { + case 0: // POINTS + geometryCfg.primitiveType = "points"; + break; + case 1: // LINES + geometryCfg.primitiveType = "lines"; + break; + case 2: // LINE_LOOP + geometryCfg.primitiveType = "line-loop"; + break; + case 3: // LINE_STRIP + geometryCfg.primitiveType = "line-strip"; + break; + case 4: // TRIANGLES + geometryCfg.primitiveType = "triangles"; + break; + case 5: // TRIANGLE_STRIP + geometryCfg.primitiveType = "triangle-strip"; + break; + case 6: // TRIANGLE_FAN + geometryCfg.primitiveType = "triangle-fan"; + break; + default: + geometryCfg.primitiveType = "triangles"; + } + const POSITION = primitive.attributes.POSITION; + if (!POSITION) { + continue; + } + geometryCfg.positions = primitive.attributes.POSITION.value; + ctx.stats.numVertices += geometryCfg.positions.length / 3; + if (ctx.includeNormals) { + if (primitive.attributes.NORMAL) { + geometryCfg.normals = primitive.attributes.NORMAL.value; + ctx.stats.numNormals += geometryCfg.normals.length / 3; + } + } + if (primitive.attributes.COLOR_0) { + geometryCfg.colorsCompressed = primitive.attributes.COLOR_0.value; + } + if (ctx.includeTextures) { + if (primitive.attributes.TEXCOORD_0) { + geometryCfg.uvs = primitive.attributes.TEXCOORD_0.value; + ctx.stats.numUVs += geometryCfg.uvs.length / 2; + } + } + if (primitive.indices) { + geometryCfg.indices = primitive.indices.value; + if (primitive.mode === 4) { + ctx.stats.numTriangles += geometryCfg.indices.length / 3; + } + } + xktModel.createGeometry(geometryCfg); + primitive._xktGeometryId = xktGeometryId; + ctx.stats.numGeometries++; + } + + const xktMeshId = ctx.nextId++; + const meshCfg = { + meshId: xktMeshId, + geometryId: primitive._xktGeometryId, + matrix: matrix ? matrix.slice() : math.identityMat4() + }; + const material = primitive.material; + if (material) { + meshCfg.textureSetId = material._textureSetId; + meshCfg.color = material._attributes.color; + meshCfg.opacity = material._attributes.opacity; + meshCfg.metallic = material._attributes.metallic; + meshCfg.roughness = material._attributes.roughness; + } else { + meshCfg.color = [1.0, 1.0, 1.0]; + meshCfg.opacity = 1.0; + } + xktModel.createMesh(meshCfg); + meshIds.push(xktMeshId); + } + } + } + + // Visit child scene nodes + + if (node.children) { + const children = node.children; + for (let i = 0, len = children.length; i < len; i++) { + const childNode = children[i]; + parseNode(ctx, childNode, depth + 1, matrix); + } + } + + // Post-order visit scene node + + const nodeName = node.name; + if ((nodeName !== undefined && nodeName !== null) || depth === 0) { + if (nodeName === undefined || nodeName === null) { + ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`); + } + let xktEntityId = objectIdStack.pop(); + if (!xktEntityId) { // For when there are no nodes with names + xktEntityId = "entity-" + ctx.nextId++; + } + let entityMeshIds = meshIdsStack.pop(); + if (meshIds && meshIds.length > 0) { + xktModel.createEntity({ + entityId: xktEntityId, + meshIds: entityMeshIds + }); + } + ctx.stats.numObjects++; + meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null; + } +} + +/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */ +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +/* eslint-disable space-unary-ops */ + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +//const Z_FILTERED = 1; +//const Z_HUFFMAN_ONLY = 2; +//const Z_RLE = 3; +const Z_FIXED$1 = 4; +//const Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +const Z_BINARY = 0; +const Z_TEXT = 1; +//const Z_ASCII = 1; // = Z_TEXT +const Z_UNKNOWN$1 = 2; + +/*============================================================================*/ + + +function zero$1(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } } + +// From zutil.h + +const STORED_BLOCK = 0; +const STATIC_TREES = 1; +const DYN_TREES = 2; +/* The three kinds of block type */ + +const MIN_MATCH$1 = 3; +const MAX_MATCH$1 = 258; +/* The minimum and maximum match lengths */ + +// From deflate.h +/* =========================================================================== + * Internal compression state. + */ + +const LENGTH_CODES$1 = 29; +/* number of length codes, not counting the special END_BLOCK code */ + +const LITERALS$1 = 256; +/* number of literal bytes 0..255 */ + +const L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1; +/* number of Literal or Length codes, including the END_BLOCK code */ + +const D_CODES$1 = 30; +/* number of distance codes */ + +const BL_CODES$1 = 19; +/* number of codes used to transfer the bit lengths */ + +const HEAP_SIZE$1 = 2 * L_CODES$1 + 1; +/* maximum heap size */ + +const MAX_BITS$1 = 15; +/* All codes must not exceed MAX_BITS bits */ + +const Buf_size = 16; +/* size of bit buffer in bi_buf */ + + +/* =========================================================================== + * Constants + */ + +const MAX_BL_BITS = 7; +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +const END_BLOCK = 256; +/* end of block literal code */ + +const REP_3_6 = 16; +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +const REPZ_3_10 = 17; +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +const REPZ_11_138 = 18; +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +/* eslint-disable comma-spacing,array-bracket-spacing */ +const extra_lbits = /* extra bits for each length code */ + new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]); + +const extra_dbits = /* extra bits for each distance code */ + new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]); + +const extra_blbits = /* extra bits for each bit length code */ + new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]); + +const bl_order = + new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]); +/* eslint-enable comma-spacing,array-bracket-spacing */ + +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +// We pre-fill arrays with 0 to avoid uninitialized gaps + +const DIST_CODE_LEN = 512; /* see definition of array dist_code below */ + +// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1 +const static_ltree = new Array((L_CODES$1 + 2) * 2); +zero$1(static_ltree); +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +const static_dtree = new Array(D_CODES$1 * 2); +zero$1(static_dtree); +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +const _dist_code = new Array(DIST_CODE_LEN); +zero$1(_dist_code); +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +const _length_code = new Array(MAX_MATCH$1 - MIN_MATCH$1 + 1); +zero$1(_length_code); +/* length code for each normalized match length (0 == MIN_MATCH) */ + +const base_length = new Array(LENGTH_CODES$1); +zero$1(base_length); +/* First normalized length for each code (0 = MIN_MATCH) */ + +const base_dist = new Array(D_CODES$1); +zero$1(base_dist); +/* First normalized distance for each code (0 = distance of 1) */ + + +function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { + + this.static_tree = static_tree; /* static tree or NULL */ + this.extra_bits = extra_bits; /* extra bits for each code or NULL */ + this.extra_base = extra_base; /* base index for extra_bits */ + this.elems = elems; /* max number of elements in the tree */ + this.max_length = max_length; /* max bit length for the codes */ + + // show if `static_tree` has data or dummy - needed for monomorphic objects + this.has_stree = static_tree && static_tree.length; +} + + +let static_l_desc; +let static_d_desc; +let static_bl_desc; + + +function TreeDesc(dyn_tree, stat_desc) { + this.dyn_tree = dyn_tree; /* the dynamic tree */ + this.max_code = 0; /* largest code with non zero frequency */ + this.stat_desc = stat_desc; /* the corresponding static tree */ +} + + + +const d_code = (dist) => { + + return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; +}; + + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +const put_short = (s, w) => { +// put_byte(s, (uch)((w) & 0xff)); +// put_byte(s, (uch)((ush)(w) >> 8)); + s.pending_buf[s.pending++] = (w) & 0xff; + s.pending_buf[s.pending++] = (w >>> 8) & 0xff; +}; + + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +const send_bits = (s, value, length) => { + + if (s.bi_valid > (Buf_size - length)) { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + put_short(s, s.bi_buf); + s.bi_buf = value >> (Buf_size - s.bi_valid); + s.bi_valid += length - Buf_size; + } else { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + s.bi_valid += length; + } +}; + + +const send_code = (s, c, tree) => { + + send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); +}; + + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +const bi_reverse = (code, len) => { + + let res = 0; + do { + res |= code & 1; + code >>>= 1; + res <<= 1; + } while (--len > 0); + return res >>> 1; +}; + + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +const bi_flush = (s) => { + + if (s.bi_valid === 16) { + put_short(s, s.bi_buf); + s.bi_buf = 0; + s.bi_valid = 0; + + } else if (s.bi_valid >= 8) { + s.pending_buf[s.pending++] = s.bi_buf & 0xff; + s.bi_buf >>= 8; + s.bi_valid -= 8; + } +}; + + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +const gen_bitlen = (s, desc) => { +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ + + const tree = desc.dyn_tree; + const max_code = desc.max_code; + const stree = desc.stat_desc.static_tree; + const has_stree = desc.stat_desc.has_stree; + const extra = desc.stat_desc.extra_bits; + const base = desc.stat_desc.extra_base; + const max_length = desc.stat_desc.max_length; + let h; /* heap index */ + let n, m; /* iterate over the tree elements */ + let bits; /* bit length */ + let xbits; /* extra bits */ + let f; /* frequency */ + let overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS$1; bits++) { + s.bl_count[bits] = 0; + } + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ + + for (h = s.heap_max + 1; h < HEAP_SIZE$1; h++) { + n = s.heap[h]; + bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n * 2 + 1]/*.Len*/ = bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) { continue; } /* not a leaf node */ + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) { + xbits = extra[n - base]; + } + f = tree[n * 2]/*.Freq*/; + s.opt_len += f * (bits + xbits); + if (has_stree) { + s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); + } + } + if (overflow === 0) { return; } + + // Tracev((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s.bl_count[bits] === 0) { bits--; } + s.bl_count[bits]--; /* move one leaf down the tree */ + s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ + s.bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits !== 0; bits--) { + n = s.bl_count[bits]; + while (n !== 0) { + m = s.heap[--h]; + if (m > max_code) { continue; } + if (tree[m * 2 + 1]/*.Len*/ !== bits) { + // Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; + tree[m * 2 + 1]/*.Len*/ = bits; + } + n--; + } + } +}; + + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +const gen_codes = (tree, max_code, bl_count) => { +// ct_data *tree; /* the tree to decorate */ +// int max_code; /* largest code with non zero frequency */ +// ushf *bl_count; /* number of codes at each bit length */ + + const next_code = new Array(MAX_BITS$1 + 1); /* next code value for each bit length */ + let code = 0; /* running code value */ + let bits; /* bit index */ + let n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS$1; bits++) { + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + //Assert (code + bl_count[MAX_BITS]-1 == (1< { + + let n; /* iterates over tree elements */ + let bits; /* bit counter */ + let length; /* length value */ + let code; /* code value */ + let dist; /* distance index */ + const bl_count = new Array(MAX_BITS$1 + 1); + /* number of codes at each bit length for an optimal tree */ + + // do check in _tr_init() + //if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +/*#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif*/ + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES$1 - 1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + _length_code[length++] = code; + } + } + //Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length - 1] = code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + _dist_code[dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for (; code < D_CODES$1; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { + _dist_code[256 + dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS$1; bits++) { + bl_count[bits] = 0; + } + + n = 0; + while (n <= 143) { + static_ltree[n * 2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + while (n <= 255) { + static_ltree[n * 2 + 1]/*.Len*/ = 9; + n++; + bl_count[9]++; + } + while (n <= 279) { + static_ltree[n * 2 + 1]/*.Len*/ = 7; + n++; + bl_count[7]++; + } + while (n <= 287) { + static_ltree[n * 2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes(static_ltree, L_CODES$1 + 1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES$1; n++) { + static_dtree[n * 2 + 1]/*.Len*/ = 5; + static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5); + } + + // Now data ready and we can init static trees + static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS$1 + 1, L_CODES$1, MAX_BITS$1); + static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES$1, MAX_BITS$1); + static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES$1, MAX_BL_BITS); + + //static_init_done = true; +}; + + +/* =========================================================================== + * Initialize a new block. + */ +const init_block = (s) => { + + let n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES$1; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } + for (n = 0; n < D_CODES$1; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } + for (n = 0; n < BL_CODES$1; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } + + s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1; + s.opt_len = s.static_len = 0; + s.sym_next = s.matches = 0; +}; + + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +const bi_windup = (s) => +{ + if (s.bi_valid > 8) { + put_short(s, s.bi_buf); + } else if (s.bi_valid > 0) { + //put_byte(s, (Byte)s->bi_buf); + s.pending_buf[s.pending++] = s.bi_buf; + } + s.bi_buf = 0; + s.bi_valid = 0; +}; + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +const smaller = (tree, n, m, depth) => { + + const _n2 = n * 2; + const _m2 = m * 2; + return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || + (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); +}; + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +const pqdownheap = (s, tree, k) => { +// deflate_state *s; +// ct_data *tree; /* the tree to restore */ +// int k; /* node to move down */ + + const v = s.heap[k]; + let j = k << 1; /* left son of k */ + while (j <= s.heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s.heap_len && + smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s.heap[j], s.depth)) { break; } + + /* Exchange v with the smallest son */ + s.heap[k] = s.heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s.heap[k] = v; +}; + + +// inlined manually +// const SMALLEST = 1; + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +const compress_block = (s, ltree, dtree) => { +// deflate_state *s; +// const ct_data *ltree; /* literal tree */ +// const ct_data *dtree; /* distance tree */ + + let dist; /* distance of matched string */ + let lc; /* match length or unmatched char (if dist == 0) */ + let sx = 0; /* running index in sym_buf */ + let code; /* the code to send */ + let extra; /* number of extra bits to send */ + + if (s.sym_next !== 0) { + do { + dist = s.pending_buf[s.sym_buf + sx++] & 0xff; + dist += (s.pending_buf[s.sym_buf + sx++] & 0xff) << 8; + lc = s.pending_buf[s.sym_buf + sx++]; + if (dist === 0) { + send_code(s, lc, ltree); /* send a literal byte */ + //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS$1 + 1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra !== 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + //Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra !== 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and sym_buf is ok: */ + //Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); + + } while (sx < s.sym_next); + } + + send_code(s, END_BLOCK, ltree); +}; + + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +const build_tree = (s, desc) => { +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ + + const tree = desc.dyn_tree; + const stree = desc.stat_desc.static_tree; + const has_stree = desc.stat_desc.has_stree; + const elems = desc.stat_desc.elems; + let n, m; /* iterate over heap elements */ + let max_code = -1; /* largest code with non zero frequency */ + let node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s.heap_len = 0; + s.heap_max = HEAP_SIZE$1; + + for (n = 0; n < elems; n++) { + if (tree[n * 2]/*.Freq*/ !== 0) { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + + } else { + tree[n * 2 + 1]/*.Len*/ = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s.heap_len < 2) { + node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); + tree[node * 2]/*.Freq*/ = 1; + s.depth[node] = 0; + s.opt_len--; + + if (has_stree) { + s.static_len -= stree[node * 2 + 1]/*.Len*/; + } + /* node is 0 or 1 so it does not have extra bits */ + } + desc.max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + //pqremove(s, tree, n); /* n = node of least frequency */ + /*** pqremove ***/ + n = s.heap[1/*SMALLEST*/]; + s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; + pqdownheap(s, tree, 1/*SMALLEST*/); + /***/ + + m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ + + s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ + s.heap[--s.heap_max] = m; + + /* Create a new node father of n and m */ + tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; + s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; + tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; + + /* and insert the new node in the heap */ + s.heap[1/*SMALLEST*/] = node++; + pqdownheap(s, tree, 1/*SMALLEST*/); + + } while (s.heap_len >= 2); + + s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes(tree, max_code, s.bl_count); +}; + + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +const scan_tree = (s, tree, max_code) => { +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ + + let n; /* iterates over all tree elements */ + let prevlen = -1; /* last emitted length */ + let curlen; /* length of current code */ + + let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ + + let count = 0; /* repeat count of the current code */ + let max_count = 7; /* max repeat count */ + let min_count = 4; /* min repeat count */ + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + s.bl_tree[curlen * 2]/*.Freq*/ += count; + + } else if (curlen !== 0) { + + if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } + s.bl_tree[REP_3_6 * 2]/*.Freq*/++; + + } else if (count <= 10) { + s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++; + + } else { + s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++; + } + + count = 0; + prevlen = curlen; + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +}; + + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +const send_tree = (s, tree, max_code) => { +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ + + let n; /* iterates over all tree elements */ + let prevlen = -1; /* last emitted length */ + let curlen; /* length of current code */ + + let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ + + let count = 0; /* repeat count of the current code */ + let max_count = 7; /* max repeat count */ + let min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); + + } else if (curlen !== 0) { + if (curlen !== prevlen) { + send_code(s, curlen, s.bl_tree); + count--; + } + //Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s.bl_tree); + send_bits(s, count - 3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s.bl_tree); + send_bits(s, count - 3, 3); + + } else { + send_code(s, REPZ_11_138, s.bl_tree); + send_bits(s, count - 11, 7); + } + + count = 0; + prevlen = curlen; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +}; + + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +const build_bl_tree = (s) => { + + let max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, s.dyn_ltree, s.l_desc.max_code); + scan_tree(s, s.dyn_dtree, s.d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, s.bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES$1 - 1; max_blindex >= 3; max_blindex--) { + if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) { + break; + } + } + /* Update opt_len to include the bit length tree and counts */ + s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + // s->opt_len, s->static_len)); + + return max_blindex; +}; + + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +const send_all_trees = (s, lcodes, dcodes, blcodes) => { +// deflate_state *s; +// int lcodes, dcodes, blcodes; /* number of codes for each tree */ + + let rank; /* index in bl_order */ + + //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + // "too many codes"); + //Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes - 1, 5); + send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3); + } + //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ + //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ + //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +}; + + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "block list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +const detect_data_type = (s) => { + /* block_mask is the bit mask of block-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + let block_mask = 0xf3ffc07f; + let n; + + /* Check for non-textual ("block-listed") bytes. */ + for (n = 0; n <= 31; n++, block_mask >>>= 1) { + if ((block_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { + return Z_BINARY; + } + } + + /* Check for textual ("allow-listed") bytes. */ + if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || + s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + for (n = 32; n < LITERALS$1; n++) { + if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + } + + /* There are no "block-listed" or "allow-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +}; + + +let static_init_done = false; + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +const _tr_init$1 = (s) => +{ + + if (!static_init_done) { + tr_static_init(); + static_init_done = true; + } + + s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); + s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); + s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); + + s.bi_buf = 0; + s.bi_valid = 0; + + /* Initialize the first block of the first file: */ + init_block(s); +}; + + +/* =========================================================================== + * Send a stored block + */ +const _tr_stored_block$1 = (s, buf, stored_len, last) => { +//DeflateState *s; +//charf *buf; /* input block */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ + + send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ + bi_windup(s); /* align on byte boundary */ + put_short(s, stored_len); + put_short(s, ~stored_len); + if (stored_len) { + s.pending_buf.set(s.window.subarray(buf, buf + stored_len), s.pending); + } + s.pending += stored_len; +}; + + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +const _tr_align$1 = (s) => { + send_bits(s, STATIC_TREES << 1, 3); + send_code(s, END_BLOCK, static_ltree); + bi_flush(s); +}; + + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and write out the encoded block. + */ +const _tr_flush_block$1 = (s, buf, stored_len, last) => { +//DeflateState *s; +//charf *buf; /* input block, or NULL if too old */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ + + let opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + let max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s.level > 0) { + + /* Check if the file is binary or text */ + if (s.strm.data_type === Z_UNKNOWN$1) { + s.strm.data_type = detect_data_type(s); + } + + /* Construct the literal and distance trees */ + build_tree(s, s.l_desc); + // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + + build_tree(s, s.d_desc); + // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s.opt_len + 3 + 7) >>> 3; + static_lenb = (s.static_len + 3 + 7) >>> 3; + + // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + // s->sym_next / 3)); + + if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } + + } else { + // Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { + /* 4: two words for the lengths */ + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block$1(s, buf, stored_len, last); + + } else if (s.strategy === Z_FIXED$1 || static_lenb === opt_lenb) { + + send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3); + compress_block(s, static_ltree, static_dtree); + + } else { + send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); + send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); + compress_block(s, s.dyn_ltree, s.dyn_dtree); + } + // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); + } + // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + // s->compressed_len-7*last)); +}; + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +const _tr_tally$1 = (s, dist, lc) => { +// deflate_state *s; +// unsigned dist; /* distance of matched string */ +// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ + + s.pending_buf[s.sym_buf + s.sym_next++] = dist; + s.pending_buf[s.sym_buf + s.sym_next++] = dist >> 8; + s.pending_buf[s.sym_buf + s.sym_next++] = lc; + if (dist === 0) { + /* lc is the unmatched char */ + s.dyn_ltree[lc * 2]/*.Freq*/++; + } else { + s.matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + //Assert((ush)dist < (ush)MAX_DIST(s) && + // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s.dyn_ltree[(_length_code[lc] + LITERALS$1 + 1) * 2]/*.Freq*/++; + s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; + } + + return (s.sym_next === s.sym_end); +}; + +var _tr_init_1 = _tr_init$1; +var _tr_stored_block_1 = _tr_stored_block$1; +var _tr_flush_block_1 = _tr_flush_block$1; +var _tr_tally_1 = _tr_tally$1; +var _tr_align_1 = _tr_align$1; + +var trees = { + _tr_init: _tr_init_1, + _tr_stored_block: _tr_stored_block_1, + _tr_flush_block: _tr_flush_block_1, + _tr_tally: _tr_tally_1, + _tr_align: _tr_align_1 +}; + +// Note: adler32 takes 12% for level 0 and 2% for level 6. +// It isn't worth it to make additional optimizations as in original. +// Small size is preferable. + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +const adler32 = (adler, buf, len, pos) => { + let s1 = (adler & 0xffff) |0, + s2 = ((adler >>> 16) & 0xffff) |0, + n = 0; + + while (len !== 0) { + // Set limit ~ twice less than 5552, to keep + // s2 in 31-bits, because we force signed ints. + // in other case %= will fail. + n = len > 2000 ? 2000 : len; + len -= n; + + do { + s1 = (s1 + buf[pos++]) |0; + s2 = (s2 + s1) |0; + } while (--n); + + s1 %= 65521; + s2 %= 65521; + } + + return (s1 | (s2 << 16)) |0; +}; + + +var adler32_1 = adler32; + +// Note: we can't get significant speed boost here. +// So write code to minimize size - no pregenerated tables +// and array tools dependencies. + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +// Use ordinary array, since untyped makes no boost here +const makeTable = () => { + let c, table = []; + + for (var n = 0; n < 256; n++) { + c = n; + for (var k = 0; k < 8; k++) { + c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; + } + + return table; +}; + +// Create table on load. Just 255 signed longs. Not a problem. +const crcTable = new Uint32Array(makeTable()); + + +const crc32 = (crc, buf, len, pos) => { + const t = crcTable; + const end = pos + len; + + crc ^= -1; + + for (let i = pos; i < end; i++) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +}; + + +var crc32_1 = crc32; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +var messages = { + 2: 'need dictionary', /* Z_NEED_DICT 2 */ + 1: 'stream end', /* Z_STREAM_END 1 */ + 0: '', /* Z_OK 0 */ + '-1': 'file error', /* Z_ERRNO (-1) */ + '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ + '-3': 'data error', /* Z_DATA_ERROR (-3) */ + '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ + '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ + '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +var constants$2 = { + + /* Allowed flush values; see deflate() and inflate() below for details */ + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_TREES: 6, + + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + //Z_VERSION_ERROR: -6, + + /* compression levels */ + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + + + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + + /* Possible values of the data_type field (though see inflate()) */ + Z_BINARY: 0, + Z_TEXT: 1, + //Z_ASCII: 1, // = Z_TEXT (deprecated) + Z_UNKNOWN: 2, + + /* The deflate compression method */ + Z_DEFLATED: 8 + //Z_NULL: null // Use -1 or null inline, depending on var type +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +const { _tr_init, _tr_stored_block, _tr_flush_block, _tr_tally, _tr_align } = trees; + + + + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + +const { + Z_NO_FLUSH: Z_NO_FLUSH$2, Z_PARTIAL_FLUSH, Z_FULL_FLUSH: Z_FULL_FLUSH$1, Z_FINISH: Z_FINISH$3, Z_BLOCK: Z_BLOCK$1, + Z_OK: Z_OK$3, Z_STREAM_END: Z_STREAM_END$3, Z_STREAM_ERROR: Z_STREAM_ERROR$2, Z_DATA_ERROR: Z_DATA_ERROR$2, Z_BUF_ERROR: Z_BUF_ERROR$1, + Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$1, + Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE, Z_FIXED, Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$1, + Z_UNKNOWN, + Z_DEFLATED: Z_DEFLATED$2 +} = constants$2; + +/*============================================================================*/ + + +const MAX_MEM_LEVEL = 9; +/* Maximum value for memLevel in deflateInit2 */ +const MAX_WBITS$1 = 15; +/* 32K LZ77 window */ +const DEF_MEM_LEVEL = 8; + + +const LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ +const LITERALS = 256; +/* number of literal bytes 0..255 */ +const L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ +const D_CODES = 30; +/* number of distance codes */ +const BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ +const HEAP_SIZE = 2 * L_CODES + 1; +/* maximum heap size */ +const MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +const MIN_MATCH = 3; +const MAX_MATCH = 258; +const MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); + +const PRESET_DICT = 0x20; + +const INIT_STATE = 42; /* zlib header -> BUSY_STATE */ +//#ifdef GZIP +const GZIP_STATE = 57; /* gzip header -> BUSY_STATE | EXTRA_STATE */ +//#endif +const EXTRA_STATE = 69; /* gzip extra block -> NAME_STATE */ +const NAME_STATE = 73; /* gzip file name -> COMMENT_STATE */ +const COMMENT_STATE = 91; /* gzip comment -> HCRC_STATE */ +const HCRC_STATE = 103; /* gzip header CRC -> BUSY_STATE */ +const BUSY_STATE = 113; /* deflate -> FINISH_STATE */ +const FINISH_STATE = 666; /* stream complete */ + +const BS_NEED_MORE = 1; /* block not completed, need more input or more output */ +const BS_BLOCK_DONE = 2; /* block flush performed */ +const BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ +const BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ + +const OS_CODE = 0x03; // Unix :) . Don't detect, use this default. + +const err = (strm, errorCode) => { + strm.msg = messages[errorCode]; + return errorCode; +}; + +const rank = (f) => { + return ((f) * 2) - ((f) > 4 ? 9 : 0); +}; + +const zero = (buf) => { + let len = buf.length; while (--len >= 0) { buf[len] = 0; } +}; + +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +const slide_hash = (s) => { + let n, m; + let p; + let wsize = s.w_size; + + n = s.hash_size; + p = n; + do { + m = s.head[--p]; + s.head[p] = (m >= wsize ? m - wsize : 0); + } while (--n); + n = wsize; +//#ifndef FASTEST + p = n; + do { + m = s.prev[--p]; + s.prev[p] = (m >= wsize ? m - wsize : 0); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +//#endif +}; + +/* eslint-disable new-cap */ +let HASH_ZLIB = (s, prev, data) => ((prev << s.hash_shift) ^ data) & s.hash_mask; +// This hash causes less collisions, https://github.com/nodeca/pako/issues/135 +// But breaks binary compatibility +//let HASH_FAST = (s, prev, data) => ((prev << 8) + (prev >> 8) + (data << 4)) & s.hash_mask; +let HASH = HASH_ZLIB; + + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). + */ +const flush_pending = (strm) => { + const s = strm.state; + + //_tr_flush_bits(s); + let len = s.pending; + if (len > strm.avail_out) { + len = strm.avail_out; + } + if (len === 0) { return; } + + strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len), strm.next_out); + strm.next_out += len; + s.pending_out += len; + strm.total_out += len; + strm.avail_out -= len; + s.pending -= len; + if (s.pending === 0) { + s.pending_out = 0; + } +}; + + +const flush_block_only = (s, last) => { + _tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); + s.block_start = s.strstart; + flush_pending(s.strm); +}; + + +const put_byte = (s, b) => { + s.pending_buf[s.pending++] = b; +}; + + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +const putShortMSB = (s, b) => { + + // put_byte(s, (Byte)(b >> 8)); +// put_byte(s, (Byte)(b & 0xff)); + s.pending_buf[s.pending++] = (b >>> 8) & 0xff; + s.pending_buf[s.pending++] = b & 0xff; +}; + + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->input buffer and copying from it. + * (See also flush_pending()). + */ +const read_buf = (strm, buf, start, size) => { + + let len = strm.avail_in; + + if (len > size) { len = size; } + if (len === 0) { return 0; } + + strm.avail_in -= len; + + // zmemcpy(buf, strm->next_in, len); + buf.set(strm.input.subarray(strm.next_in, strm.next_in + len), start); + if (strm.state.wrap === 1) { + strm.adler = adler32_1(strm.adler, buf, len, start); + } + + else if (strm.state.wrap === 2) { + strm.adler = crc32_1(strm.adler, buf, len, start); + } + + strm.next_in += len; + strm.total_in += len; + + return len; +}; + + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +const longest_match = (s, cur_match) => { + + let chain_length = s.max_chain_length; /* max hash chain length */ + let scan = s.strstart; /* current string */ + let match; /* matched string */ + let len; /* length of current match */ + let best_len = s.prev_length; /* best match length so far */ + let nice_match = s.nice_match; /* stop if match long enough */ + const limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? + s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; + + const _win = s.window; // shortcut + + const wmask = s.w_mask; + const prev = s.prev; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + + const strend = s.strstart + MAX_MATCH; + let scan_end1 = _win[scan + best_len - 1]; + let scan_end = _win[scan + best_len]; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s.prev_length >= s.good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if (nice_match > s.lookahead) { nice_match = s.lookahead; } + + // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + // Assert(cur_match < s->strstart, "no future"); + match = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ + + if (_win[match + best_len] !== scan_end || + _win[match + best_len - 1] !== scan_end1 || + _win[match] !== _win[scan] || + _win[++match] !== _win[scan + 1]) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2; + match++; + // Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + /*jshint noempty:false*/ + } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + scan < strend); + + // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (strend - scan); + scan = strend - MAX_MATCH; + + if (len > best_len) { + s.match_start = cur_match; + best_len = len; + if (len >= nice_match) { + break; + } + scan_end1 = _win[scan + best_len - 1]; + scan_end = _win[scan + best_len]; + } + } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); + + if (best_len <= s.lookahead) { + return best_len; + } + return s.lookahead; +}; + + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +const fill_window = (s) => { + + const _w_size = s.w_size; + let n, more, str; + + //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s.window_size - s.lookahead - s.strstart; + + // JS ints have 32 bit, block below not needed + /* Deal with !@#$% 64K limit: */ + //if (sizeof(int) <= 2) { + // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + // more = wsize; + // + // } else if (more == (unsigned)(-1)) { + // /* Very unlikely, but possible on 16 bit machine if + // * strstart == 0 && lookahead == 1 (input done a byte at time) + // */ + // more--; + // } + //} + + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { + + s.window.set(s.window.subarray(_w_size, _w_size + _w_size - more), 0); + s.match_start -= _w_size; + s.strstart -= _w_size; + /* we now have strstart >= MAX_DIST */ + s.block_start -= _w_size; + if (s.insert > s.strstart) { + s.insert = s.strstart; + } + slide_hash(s); + more += _w_size; + } + if (s.strm.avail_in === 0) { + break; + } + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + //Assert(more >= 2, "more < 2"); + n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); + s.lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s.lookahead + s.insert >= MIN_MATCH) { + str = s.strstart - s.insert; + s.ins_h = s.window[str]; + + /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ + s.ins_h = HASH(s, s.ins_h, s.window[str + 1]); +//#if MIN_MATCH != 3 +// Call update_hash() MIN_MATCH-3 more times +//#endif + while (s.insert) { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]); + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = str; + str++; + s.insert--; + if (s.lookahead + s.insert < MIN_MATCH) { + break; + } + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ +// if (s.high_water < s.window_size) { +// const curr = s.strstart + s.lookahead; +// let init = 0; +// +// if (s.high_water < curr) { +// /* Previous high water mark below current data -- zero WIN_INIT +// * bytes or up to end of window, whichever is less. +// */ +// init = s.window_size - curr; +// if (init > WIN_INIT) +// init = WIN_INIT; +// zmemzero(s->window + curr, (unsigned)init); +// s->high_water = curr + init; +// } +// else if (s->high_water < (ulg)curr + WIN_INIT) { +// /* High water mark at or above current data, but below current data +// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up +// * to end of window, whichever is less. +// */ +// init = (ulg)curr + WIN_INIT - s->high_water; +// if (init > s->window_size - s->high_water) +// init = s->window_size - s->high_water; +// zmemzero(s->window + s->high_water, (unsigned)init); +// s->high_water += init; +// } +// } +// +// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, +// "not enough room for search"); +}; + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunites to have a single copy from next_in to next_out. + */ +const deflate_stored = (s, flush) => { + + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. + */ + let min_block = s.pending_buf_size - 5 > s.w_size ? s.w_size : s.pending_buf_size - 5; + + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + let len, left, have, last = 0; + let used = s.strm.avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. + */ + len = 65535/* MAX_STORED */; /* maximum deflate stored block length */ + have = (s.bi_valid + 42) >> 3; /* number of header bytes */ + if (s.strm.avail_out < have) { /* need room for header */ + break; + } + /* maximum stored block length that will fit in avail_out: */ + have = s.strm.avail_out - have; + left = s.strstart - s.block_start; /* bytes left in window */ + if (len > left + s.strm.avail_in) { + len = left + s.strm.avail_in; /* limit len to the input */ + } + if (len > have) { + len = have; /* limit len to the output */ + } + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len === 0 && flush !== Z_FINISH$3) || + flush === Z_NO_FLUSH$2 || + len !== left + s.strm.avail_in)) { + break; + } + + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush === Z_FINISH$3 && len === left + s.strm.avail_in ? 1 : 0; + _tr_stored_block(s, 0, 0, last); + + /* Replace the lengths in the dummy stored block with len. */ + s.pending_buf[s.pending - 4] = len; + s.pending_buf[s.pending - 3] = len >> 8; + s.pending_buf[s.pending - 2] = ~len; + s.pending_buf[s.pending - 1] = ~len >> 8; + + /* Write the stored block header bytes. */ + flush_pending(s.strm); + +//#ifdef ZLIB_DEBUG +// /* Update debugging counts for the data about to be copied. */ +// s->compressed_len += len << 3; +// s->bits_sent += len << 3; +//#endif + + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + if (left > len) { + left = len; + } + //zmemcpy(s->strm->next_out, s->window + s->block_start, left); + s.strm.output.set(s.window.subarray(s.block_start, s.block_start + left), s.strm.next_out); + s.strm.next_out += left; + s.strm.avail_out -= left; + s.strm.total_out += left; + s.block_start += left; + len -= left; + } + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + read_buf(s.strm, s.strm.output, s.strm.next_out, len); + s.strm.next_out += len; + s.strm.avail_out -= len; + s.strm.total_out += len; + } + } while (last === 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s.strm.avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. + */ + if (used >= s.w_size) { /* supplant the previous history */ + s.matches = 2; /* clear hash */ + //zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s.window.set(s.strm.input.subarray(s.strm.next_in - s.w_size, s.strm.next_in), 0); + s.strstart = s.w_size; + s.insert = s.strstart; + } + else { + if (s.window_size - s.strstart <= used) { + /* Slide the window down. */ + s.strstart -= s.w_size; + //zmemcpy(s->window, s->window + s->w_size, s->strstart); + s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); + if (s.matches < 2) { + s.matches++; /* add a pending slide_hash() */ + } + if (s.insert > s.strstart) { + s.insert = s.strstart; + } + } + //zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); + s.window.set(s.strm.input.subarray(s.strm.next_in - used, s.strm.next_in), s.strstart); + s.strstart += used; + s.insert += used > s.w_size - s.insert ? s.w_size - s.insert : used; + } + s.block_start = s.strstart; + } + if (s.high_water < s.strstart) { + s.high_water = s.strstart; + } + + /* If the last block was written to next_out, then done. */ + if (last) { + return BS_FINISH_DONE; + } + + /* If flushing and all input has been consumed, then done. */ + if (flush !== Z_NO_FLUSH$2 && flush !== Z_FINISH$3 && + s.strm.avail_in === 0 && s.strstart === s.block_start) { + return BS_BLOCK_DONE; + } + + /* Fill the window with any remaining input. */ + have = s.window_size - s.strstart; + if (s.strm.avail_in > have && s.block_start >= s.w_size) { + /* Slide the window down. */ + s.block_start -= s.w_size; + s.strstart -= s.w_size; + //zmemcpy(s->window, s->window + s->w_size, s->strstart); + s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); + if (s.matches < 2) { + s.matches++; /* add a pending slide_hash() */ + } + have += s.w_size; /* more space now */ + if (s.insert > s.strstart) { + s.insert = s.strstart; + } + } + if (have > s.strm.avail_in) { + have = s.strm.avail_in; + } + if (have) { + read_buf(s.strm, s.window, s.strstart, have); + s.strstart += have; + s.insert += have > s.w_size - s.insert ? s.w_size - s.insert : have; + } + if (s.high_water < s.strstart) { + s.high_water = s.strstart; + } + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s.bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = s.pending_buf_size - have > 65535/* MAX_STORED */ ? 65535/* MAX_STORED */ : s.pending_buf_size - have; + min_block = have > s.w_size ? s.w_size : have; + left = s.strstart - s.block_start; + if (left >= min_block || + ((left || flush === Z_FINISH$3) && flush !== Z_NO_FLUSH$2 && + s.strm.avail_in === 0 && left <= have)) { + len = left > have ? have : left; + last = flush === Z_FINISH$3 && s.strm.avail_in === 0 && + len === left ? 1 : 0; + _tr_stored_block(s, s.block_start, len, last); + s.block_start += len; + flush_pending(s.strm); + } + + /* We've done all we can with the available input and output. */ + return last ? BS_FINISH_STARTED : BS_NEED_MORE; +}; + + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +const deflate_fast = (s, flush) => { + + let hash_head; /* head of the hash chain */ + let bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; /* flush the current block */ + } + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + if (s.match_length >= MIN_MATCH) { + // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only + + /*** _tr_tally_dist(s, s.strstart - s.match_start, + s.match_length - MIN_MATCH, bflush); ***/ + bflush = _tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { + s.match_length--; /* string at strstart already in table */ + do { + s.strstart++; + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s.match_length !== 0); + s.strstart++; + } else + { + s.strstart += s.match_length; + s.match_length = 0; + s.ins_h = s.window[s.strstart]; + /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ + s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + 1]); + +//#if MIN_MATCH != 3 +// Call UPDATE_HASH() MIN_MATCH-3 more times +//#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s.window[s.strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = _tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1); + if (flush === Z_FINISH$3) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.sym_next) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +}; + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +const deflate_slow = (s, flush) => { + + let hash_head; /* head of hash chain */ + let bflush; /* set if current block must be flushed */ + + let max_insert; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + */ + s.prev_length = s.match_length; + s.prev_match = s.match_start; + s.match_length = MIN_MATCH - 1; + + if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && + s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + + if (s.match_length <= 5 && + (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s.match_length = MIN_MATCH - 1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { + max_insert = s.strstart + s.lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + //check_match(s, s.strstart-1, s.prev_match, s.prev_length); + + /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, + s.prev_length - MIN_MATCH, bflush);***/ + bflush = _tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s.lookahead -= s.prev_length - 1; + s.prev_length -= 2; + do { + if (++s.strstart <= max_insert) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + } while (--s.prev_length !== 0); + s.match_available = 0; + s.match_length = MIN_MATCH - 1; + s.strstart++; + + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + } else if (s.match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = _tr_tally(s, 0, s.window[s.strstart - 1]); + + if (bflush) { + /*** FLUSH_BLOCK_ONLY(s, 0) ***/ + flush_block_only(s, false); + /***/ + } + s.strstart++; + s.lookahead--; + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s.match_available = 1; + s.strstart++; + s.lookahead--; + } + } + //Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s.match_available) { + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = _tr_tally(s, 0, s.window[s.strstart - 1]); + + s.match_available = 0; + } + s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; + if (flush === Z_FINISH$3) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.sym_next) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_BLOCK_DONE; +}; + + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +const deflate_rle = (s, flush) => { + + let bflush; /* set if current block must be flushed */ + let prev; /* byte at distance one to match */ + let scan, strend; /* scan goes up to strend for length of run */ + + const _win = s.window; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s.lookahead <= MAX_MATCH) { + fill_window(s); + if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH$2) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s.match_length = 0; + if (s.lookahead >= MIN_MATCH && s.strstart > 0) { + scan = s.strstart - 1; + prev = _win[scan]; + if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { + strend = s.strstart + MAX_MATCH; + do { + /*jshint noempty:false*/ + } while (prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + scan < strend); + s.match_length = MAX_MATCH - (strend - scan); + if (s.match_length > s.lookahead) { + s.match_length = s.lookahead; + } + } + //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s.match_length >= MIN_MATCH) { + //check_match(s, s.strstart, s.strstart - 1, s.match_length); + + /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ + bflush = _tr_tally(s, 1, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + s.strstart += s.match_length; + s.match_length = 0; + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = _tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH$3) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.sym_next) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +}; + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +const deflate_huff = (s, flush) => { + + let bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s.lookahead === 0) { + fill_window(s); + if (s.lookahead === 0) { + if (flush === Z_NO_FLUSH$2) { + return BS_NEED_MORE; + } + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s.match_length = 0; + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = _tr_tally(s, 0, s.window[s.strstart]); + s.lookahead--; + s.strstart++; + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH$3) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.sym_next) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +}; + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +function Config(good_length, max_lazy, nice_length, max_chain, func) { + + this.good_length = good_length; + this.max_lazy = max_lazy; + this.nice_length = nice_length; + this.max_chain = max_chain; + this.func = func; +} + +const configuration_table = [ + /* good lazy nice chain */ + new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ + new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ + new Config(4, 5, 16, 8, deflate_fast), /* 2 */ + new Config(4, 6, 32, 32, deflate_fast), /* 3 */ + + new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ + new Config(8, 16, 32, 32, deflate_slow), /* 5 */ + new Config(8, 16, 128, 128, deflate_slow), /* 6 */ + new Config(8, 32, 128, 256, deflate_slow), /* 7 */ + new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ + new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ +]; + + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +const lm_init = (s) => { + + s.window_size = 2 * s.w_size; + + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + + /* Set the default configuration parameters: + */ + s.max_lazy_match = configuration_table[s.level].max_lazy; + s.good_match = configuration_table[s.level].good_length; + s.nice_match = configuration_table[s.level].nice_length; + s.max_chain_length = configuration_table[s.level].max_chain; + + s.strstart = 0; + s.block_start = 0; + s.lookahead = 0; + s.insert = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + s.ins_h = 0; +}; + + +function DeflateState() { + this.strm = null; /* pointer back to this zlib stream */ + this.status = 0; /* as the name implies */ + this.pending_buf = null; /* output still pending */ + this.pending_buf_size = 0; /* size of pending_buf */ + this.pending_out = 0; /* next pending byte to output to the stream */ + this.pending = 0; /* nb of bytes in the pending buffer */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.gzhead = null; /* gzip header information to write */ + this.gzindex = 0; /* where in extra, name, or comment */ + this.method = Z_DEFLATED$2; /* can only be DEFLATED */ + this.last_flush = -1; /* value of flush param for previous deflate call */ + + this.w_size = 0; /* LZ77 window size (32K by default) */ + this.w_bits = 0; /* log2(w_size) (8..16) */ + this.w_mask = 0; /* w_size - 1 */ + + this.window = null; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. + */ + + this.window_size = 0; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + this.prev = null; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + this.head = null; /* Heads of the hash chains or NIL. */ + + this.ins_h = 0; /* hash index of string to be inserted */ + this.hash_size = 0; /* number of elements in hash table */ + this.hash_bits = 0; /* log2(hash_size) */ + this.hash_mask = 0; /* hash_size-1 */ + + this.hash_shift = 0; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + this.block_start = 0; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + this.match_length = 0; /* length of best match */ + this.prev_match = 0; /* previous match */ + this.match_available = 0; /* set if previous match exists */ + this.strstart = 0; /* start of string to insert */ + this.match_start = 0; /* start of matching string */ + this.lookahead = 0; /* number of valid bytes ahead in window */ + + this.prev_length = 0; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + this.max_chain_length = 0; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + this.max_lazy_match = 0; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ + // That's alias to max_lazy_match, don't use directly + //this.max_insert_length = 0; + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + this.level = 0; /* compression level (1..9) */ + this.strategy = 0; /* favor or force Huffman coding*/ + + this.good_match = 0; + /* Use a faster search when the previous match is longer than this */ + + this.nice_match = 0; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + + /* Didn't use ct_data typedef below to suppress compiler warning */ + + // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + // Use flat array of DOUBLE size, with interleaved fata, + // because JS does not support effective + this.dyn_ltree = new Uint16Array(HEAP_SIZE * 2); + this.dyn_dtree = new Uint16Array((2 * D_CODES + 1) * 2); + this.bl_tree = new Uint16Array((2 * BL_CODES + 1) * 2); + zero(this.dyn_ltree); + zero(this.dyn_dtree); + zero(this.bl_tree); + + this.l_desc = null; /* desc. for literal tree */ + this.d_desc = null; /* desc. for distance tree */ + this.bl_desc = null; /* desc. for bit length tree */ + + //ush bl_count[MAX_BITS+1]; + this.bl_count = new Uint16Array(MAX_BITS + 1); + /* number of codes at each bit length for an optimal tree */ + + //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + this.heap = new Uint16Array(2 * L_CODES + 1); /* heap used to build the Huffman trees */ + zero(this.heap); + + this.heap_len = 0; /* number of elements in the heap */ + this.heap_max = 0; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + this.depth = new Uint16Array(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; + zero(this.depth); + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + this.sym_buf = 0; /* buffer for distances and literals/lengths */ + + this.lit_bufsize = 0; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + this.sym_next = 0; /* running index in sym_buf */ + this.sym_end = 0; /* symbol table full when sym_next reaches this */ + + this.opt_len = 0; /* bit length of current block with optimal trees */ + this.static_len = 0; /* bit length of current block with static trees */ + this.matches = 0; /* number of string matches in current block */ + this.insert = 0; /* bytes at end of window left to insert */ + + + this.bi_buf = 0; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + this.bi_valid = 0; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + // Used for window memory init. We safely ignore it for JS. That makes + // sense only for pointers and memory check tools. + //this.high_water = 0; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ +} + + +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +const deflateStateCheck = (strm) => { + + if (!strm) { + return 1; + } + const s = strm.state; + if (!s || s.strm !== strm || (s.status !== INIT_STATE && +//#ifdef GZIP + s.status !== GZIP_STATE && +//#endif + s.status !== EXTRA_STATE && + s.status !== NAME_STATE && + s.status !== COMMENT_STATE && + s.status !== HCRC_STATE && + s.status !== BUSY_STATE && + s.status !== FINISH_STATE)) { + return 1; + } + return 0; +}; + + +const deflateResetKeep = (strm) => { + + if (deflateStateCheck(strm)) { + return err(strm, Z_STREAM_ERROR$2); + } + + strm.total_in = strm.total_out = 0; + strm.data_type = Z_UNKNOWN; + + const s = strm.state; + s.pending = 0; + s.pending_out = 0; + + if (s.wrap < 0) { + s.wrap = -s.wrap; + /* was made negative by deflate(..., Z_FINISH); */ + } + s.status = +//#ifdef GZIP + s.wrap === 2 ? GZIP_STATE : +//#endif + s.wrap ? INIT_STATE : BUSY_STATE; + strm.adler = (s.wrap === 2) ? + 0 // crc32(0, Z_NULL, 0) + : + 1; // adler32(0, Z_NULL, 0) + s.last_flush = -2; + _tr_init(s); + return Z_OK$3; +}; + + +const deflateReset = (strm) => { + + const ret = deflateResetKeep(strm); + if (ret === Z_OK$3) { + lm_init(strm.state); + } + return ret; +}; + + +const deflateSetHeader = (strm, head) => { + + if (deflateStateCheck(strm) || strm.state.wrap !== 2) { + return Z_STREAM_ERROR$2; + } + strm.state.gzhead = head; + return Z_OK$3; +}; + + +const deflateInit2 = (strm, level, method, windowBits, memLevel, strategy) => { + + if (!strm) { // === Z_NULL + return Z_STREAM_ERROR$2; + } + let wrap = 1; + + if (level === Z_DEFAULT_COMPRESSION$1) { + level = 6; + } + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } + + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } + + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED$2 || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED || (windowBits === 8 && wrap !== 1)) { + return err(strm, Z_STREAM_ERROR$2); + } + + + if (windowBits === 8) { + windowBits = 9; + } + /* until 256-byte window bug fixed */ + + const s = new DeflateState(); + + strm.state = s; + s.strm = strm; + s.status = INIT_STATE; /* to pass state test in deflateReset() */ + + s.wrap = wrap; + s.gzhead = null; + s.w_bits = windowBits; + s.w_size = 1 << s.w_bits; + s.w_mask = s.w_size - 1; + + s.hash_bits = memLevel + 7; + s.hash_size = 1 << s.hash_bits; + s.hash_mask = s.hash_size - 1; + s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); + + s.window = new Uint8Array(s.w_size * 2); + s.head = new Uint16Array(s.hash_size); + s.prev = new Uint16Array(s.w_size); + + // Don't need mem init magic for JS. + //s.high_water = 0; /* nothing written to s->window yet */ + + s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + /* We overlay pending_buf and sym_buf. This works since the average size + * for length/distance pairs over any compressed block is assured to be 31 + * bits or less. + * + * Analysis: The longest fixed codes are a length code of 8 bits plus 5 + * extra bits, for lengths 131 to 257. The longest fixed distance codes are + * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest + * possible fixed-codes length/distance pair is then 31 bits total. + * + * sym_buf starts one-fourth of the way into pending_buf. So there are + * three bytes in sym_buf for every four bytes in pending_buf. Each symbol + * in sym_buf is three bytes -- two for the distance and one for the + * literal/length. As each symbol is consumed, the pointer to the next + * sym_buf value to read moves forward three bytes. From that symbol, up to + * 31 bits are written to pending_buf. The closest the written pending_buf + * bits gets to the next sym_buf symbol to read is just before the last + * code is written. At that time, 31*(n-2) bits have been written, just + * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at + * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 + * symbols are written.) The closest the writing gets to what is unread is + * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and + * can range from 128 to 32768. + * + * Therefore, at a minimum, there are 142 bits of space between what is + * written and what is read in the overlain buffers, so the symbols cannot + * be overwritten by the compressed data. That space is actually 139 bits, + * due to the three-bit fixed-code block header. + * + * That covers the case where either Z_FIXED is specified, forcing fixed + * codes, or when the use of fixed codes is chosen, because that choice + * results in a smaller compressed block than dynamic codes. That latter + * condition then assures that the above analysis also covers all dynamic + * blocks. A dynamic-code block will only be chosen to be emitted if it has + * fewer bits than a fixed-code block would for the same set of symbols. + * Therefore its average symbol length is assured to be less than 31. So + * the compressed data for a dynamic block also cannot overwrite the + * symbols from which it is being constructed. + */ + + s.pending_buf_size = s.lit_bufsize * 4; + s.pending_buf = new Uint8Array(s.pending_buf_size); + + // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) + //s->sym_buf = s->pending_buf + s->lit_bufsize; + s.sym_buf = s.lit_bufsize; + + //s->sym_end = (s->lit_bufsize - 1) * 3; + s.sym_end = (s.lit_bufsize - 1) * 3; + /* We avoid equality with lit_bufsize*3 because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + + s.level = level; + s.strategy = strategy; + s.method = method; + + return deflateReset(strm); +}; + +const deflateInit = (strm, level) => { + + return deflateInit2(strm, level, Z_DEFLATED$2, MAX_WBITS$1, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY$1); +}; + + +/* ========================================================================= */ +const deflate$2 = (strm, flush) => { + + if (deflateStateCheck(strm) || flush > Z_BLOCK$1 || flush < 0) { + return strm ? err(strm, Z_STREAM_ERROR$2) : Z_STREAM_ERROR$2; + } + + const s = strm.state; + + if (!strm.output || + (strm.avail_in !== 0 && !strm.input) || + (s.status === FINISH_STATE && flush !== Z_FINISH$3)) { + return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR$1 : Z_STREAM_ERROR$2); + } + + const old_flush = s.last_flush; + s.last_flush = flush; + + /* Flush as much pending output as possible */ + if (s.pending !== 0) { + flush_pending(strm); + if (strm.avail_out === 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s.last_flush = -1; + return Z_OK$3; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && + flush !== Z_FINISH$3) { + return err(strm, Z_BUF_ERROR$1); + } + + /* User must not provide more input after the first FINISH: */ + if (s.status === FINISH_STATE && strm.avail_in !== 0) { + return err(strm, Z_BUF_ERROR$1); + } + + /* Write the header */ + if (s.status === INIT_STATE && s.wrap === 0) { + s.status = BUSY_STATE; + } + if (s.status === INIT_STATE) { + /* zlib header */ + let header = (Z_DEFLATED$2 + ((s.w_bits - 8) << 4)) << 8; + let level_flags = -1; + + if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { + level_flags = 0; + } else if (s.level < 6) { + level_flags = 1; + } else if (s.level === 6) { + level_flags = 2; + } else { + level_flags = 3; + } + header |= (level_flags << 6); + if (s.strstart !== 0) { header |= PRESET_DICT; } + header += 31 - (header % 31); + + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s.strstart !== 0) { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + strm.adler = 1; // adler32(0L, Z_NULL, 0); + s.status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s.pending !== 0) { + s.last_flush = -1; + return Z_OK$3; + } + } +//#ifdef GZIP + if (s.status === GZIP_STATE) { + /* gzip header */ + strm.adler = 0; //crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (!s.gzhead) { // s->gzhead == Z_NULL + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s.status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s.pending !== 0) { + s.last_flush = -1; + return Z_OK$3; + } + } + else { + put_byte(s, (s.gzhead.text ? 1 : 0) + + (s.gzhead.hcrc ? 2 : 0) + + (!s.gzhead.extra ? 0 : 4) + + (!s.gzhead.name ? 0 : 8) + + (!s.gzhead.comment ? 0 : 16) + ); + put_byte(s, s.gzhead.time & 0xff); + put_byte(s, (s.gzhead.time >> 8) & 0xff); + put_byte(s, (s.gzhead.time >> 16) & 0xff); + put_byte(s, (s.gzhead.time >> 24) & 0xff); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, s.gzhead.os & 0xff); + if (s.gzhead.extra && s.gzhead.extra.length) { + put_byte(s, s.gzhead.extra.length & 0xff); + put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); + } + if (s.gzhead.hcrc) { + strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending, 0); + } + s.gzindex = 0; + s.status = EXTRA_STATE; + } + } + if (s.status === EXTRA_STATE) { + if (s.gzhead.extra/* != Z_NULL*/) { + let beg = s.pending; /* start of bytes to update crc */ + let left = (s.gzhead.extra.length & 0xffff) - s.gzindex; + while (s.pending + left > s.pending_buf_size) { + let copy = s.pending_buf_size - s.pending; + // zmemcpy(s.pending_buf + s.pending, + // s.gzhead.extra + s.gzindex, copy); + s.pending_buf.set(s.gzhead.extra.subarray(s.gzindex, s.gzindex + copy), s.pending); + s.pending = s.pending_buf_size; + //--- HCRC_UPDATE(beg) ---// + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); + } + //---// + s.gzindex += copy; + flush_pending(strm); + if (s.pending !== 0) { + s.last_flush = -1; + return Z_OK$3; + } + beg = 0; + left -= copy; + } + // JS specific: s.gzhead.extra may be TypedArray or Array for backward compatibility + // TypedArray.slice and TypedArray.from don't exist in IE10-IE11 + let gzhead_extra = new Uint8Array(s.gzhead.extra); + // zmemcpy(s->pending_buf + s->pending, + // s->gzhead->extra + s->gzindex, left); + s.pending_buf.set(gzhead_extra.subarray(s.gzindex, s.gzindex + left), s.pending); + s.pending += left; + //--- HCRC_UPDATE(beg) ---// + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); + } + //---// + s.gzindex = 0; + } + s.status = NAME_STATE; + } + if (s.status === NAME_STATE) { + if (s.gzhead.name/* != Z_NULL*/) { + let beg = s.pending; /* start of bytes to update crc */ + let val; + do { + if (s.pending === s.pending_buf_size) { + //--- HCRC_UPDATE(beg) ---// + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); + } + //---// + flush_pending(strm); + if (s.pending !== 0) { + s.last_flush = -1; + return Z_OK$3; + } + beg = 0; + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.name.length) { + val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + //--- HCRC_UPDATE(beg) ---// + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); + } + //---// + s.gzindex = 0; + } + s.status = COMMENT_STATE; + } + if (s.status === COMMENT_STATE) { + if (s.gzhead.comment/* != Z_NULL*/) { + let beg = s.pending; /* start of bytes to update crc */ + let val; + do { + if (s.pending === s.pending_buf_size) { + //--- HCRC_UPDATE(beg) ---// + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); + } + //---// + flush_pending(strm); + if (s.pending !== 0) { + s.last_flush = -1; + return Z_OK$3; + } + beg = 0; + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.comment.length) { + val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + //--- HCRC_UPDATE(beg) ---// + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); + } + //---// + } + s.status = HCRC_STATE; + } + if (s.status === HCRC_STATE) { + if (s.gzhead.hcrc) { + if (s.pending + 2 > s.pending_buf_size) { + flush_pending(strm); + if (s.pending !== 0) { + s.last_flush = -1; + return Z_OK$3; + } + } + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + strm.adler = 0; //crc32(0L, Z_NULL, 0); + } + s.status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s.pending !== 0) { + s.last_flush = -1; + return Z_OK$3; + } + } +//#endif + + /* Start a new block or continue the current one. + */ + if (strm.avail_in !== 0 || s.lookahead !== 0 || + (flush !== Z_NO_FLUSH$2 && s.status !== FINISH_STATE)) { + let bstate = s.level === 0 ? deflate_stored(s, flush) : + s.strategy === Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s.strategy === Z_RLE ? deflate_rle(s, flush) : + configuration_table[s.level].func(s, flush); + + if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { + s.status = FINISH_STATE; + } + if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { + if (strm.avail_out === 0) { + s.last_flush = -1; + /* avoid BUF_ERROR next call, see above */ + } + return Z_OK$3; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate === BS_BLOCK_DONE) { + if (flush === Z_PARTIAL_FLUSH) { + _tr_align(s); + } + else if (flush !== Z_BLOCK$1) { /* FULL_FLUSH or SYNC_FLUSH */ + + _tr_stored_block(s, 0, 0, false); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush === Z_FULL_FLUSH$1) { + /*** CLEAR_HASH(s); ***/ /* forget history */ + zero(s.head); // Fill with NIL (= 0); + + if (s.lookahead === 0) { + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + } + } + flush_pending(strm); + if (strm.avail_out === 0) { + s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK$3; + } + } + } + + if (flush !== Z_FINISH$3) { return Z_OK$3; } + if (s.wrap <= 0) { return Z_STREAM_END$3; } + + /* Write the trailer */ + if (s.wrap === 2) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + put_byte(s, (strm.adler >> 16) & 0xff); + put_byte(s, (strm.adler >> 24) & 0xff); + put_byte(s, strm.total_in & 0xff); + put_byte(s, (strm.total_in >> 8) & 0xff); + put_byte(s, (strm.total_in >> 16) & 0xff); + put_byte(s, (strm.total_in >> 24) & 0xff); + } + else + { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s.wrap > 0) { s.wrap = -s.wrap; } + /* write the trailer only once! */ + return s.pending !== 0 ? Z_OK$3 : Z_STREAM_END$3; +}; + + +const deflateEnd = (strm) => { + + if (deflateStateCheck(strm)) { + return Z_STREAM_ERROR$2; + } + + const status = strm.state.status; + + strm.state = null; + + return status === BUSY_STATE ? err(strm, Z_DATA_ERROR$2) : Z_OK$3; +}; + + +/* ========================================================================= + * Initializes the compression dictionary from the given byte + * sequence without producing any compressed output. + */ +const deflateSetDictionary = (strm, dictionary) => { + + let dictLength = dictionary.length; + + if (deflateStateCheck(strm)) { + return Z_STREAM_ERROR$2; + } + + const s = strm.state; + const wrap = s.wrap; + + if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) { + return Z_STREAM_ERROR$2; + } + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap === 1) { + /* adler32(strm->adler, dictionary, dictLength); */ + strm.adler = adler32_1(strm.adler, dictionary, dictLength, 0); + } + + s.wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s.w_size) { + if (wrap === 0) { /* already empty otherwise */ + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + /* use the tail */ + // dictionary = dictionary.slice(dictLength - s.w_size); + let tmpDict = new Uint8Array(s.w_size); + tmpDict.set(dictionary.subarray(dictLength - s.w_size, dictLength), 0); + dictionary = tmpDict; + dictLength = s.w_size; + } + /* insert dictionary into window and hash */ + const avail = strm.avail_in; + const next = strm.next_in; + const input = strm.input; + strm.avail_in = dictLength; + strm.next_in = 0; + strm.input = dictionary; + fill_window(s); + while (s.lookahead >= MIN_MATCH) { + let str = s.strstart; + let n = s.lookahead - (MIN_MATCH - 1); + do { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]); + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + + s.head[s.ins_h] = str; + str++; + } while (--n); + s.strstart = str; + s.lookahead = MIN_MATCH - 1; + fill_window(s); + } + s.strstart += s.lookahead; + s.block_start = s.strstart; + s.insert = s.lookahead; + s.lookahead = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + strm.next_in = next; + strm.input = input; + strm.avail_in = avail; + s.wrap = wrap; + return Z_OK$3; +}; + + +var deflateInit_1 = deflateInit; +var deflateInit2_1 = deflateInit2; +var deflateReset_1 = deflateReset; +var deflateResetKeep_1 = deflateResetKeep; +var deflateSetHeader_1 = deflateSetHeader; +var deflate_2$1 = deflate$2; +var deflateEnd_1 = deflateEnd; +var deflateSetDictionary_1 = deflateSetDictionary; +var deflateInfo = 'pako deflate (from Nodeca project)'; + +/* Not implemented +module.exports.deflateBound = deflateBound; +module.exports.deflateCopy = deflateCopy; +module.exports.deflateGetDictionary = deflateGetDictionary; +module.exports.deflateParams = deflateParams; +module.exports.deflatePending = deflatePending; +module.exports.deflatePrime = deflatePrime; +module.exports.deflateTune = deflateTune; +*/ + +var deflate_1$2 = { + deflateInit: deflateInit_1, + deflateInit2: deflateInit2_1, + deflateReset: deflateReset_1, + deflateResetKeep: deflateResetKeep_1, + deflateSetHeader: deflateSetHeader_1, + deflate: deflate_2$1, + deflateEnd: deflateEnd_1, + deflateSetDictionary: deflateSetDictionary_1, + deflateInfo: deflateInfo +}; + +const _has = (obj, key) => { + return Object.prototype.hasOwnProperty.call(obj, key); +}; + +var assign = function (obj /*from1, from2, from3, ...*/) { + const sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + const source = sources.shift(); + if (!source) { continue; } + + if (typeof source !== 'object') { + throw new TypeError(source + 'must be non-object'); + } + + for (const p in source) { + if (_has(source, p)) { + obj[p] = source[p]; + } + } + } + + return obj; +}; + + +// Join array of chunks to single array. +var flattenChunks = (chunks) => { + // calculate data length + let len = 0; + + for (let i = 0, l = chunks.length; i < l; i++) { + len += chunks[i].length; + } + + // join chunks + const result = new Uint8Array(len); + + for (let i = 0, pos = 0, l = chunks.length; i < l; i++) { + let chunk = chunks[i]; + result.set(chunk, pos); + pos += chunk.length; + } + + return result; +}; + +var common = { + assign: assign, + flattenChunks: flattenChunks +}; + +// String encode/decode helpers + + +// Quick check if we can use fast array to bin string conversion +// +// - apply(Array) can fail on Android 2.2 +// - apply(Uint8Array) can fail on iOS 5.1 Safari +// +let STR_APPLY_UIA_OK = true; + +try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; } + + +// Table with utf8 lengths (calculated by first byte of sequence) +// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, +// because max possible codepoint is 0x10ffff +const _utf8len = new Uint8Array(256); +for (let q = 0; q < 256; q++) { + _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1); +} +_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start + + +// convert string to array (typed, when possible) +var string2buf = (str) => { + if (typeof TextEncoder === 'function' && TextEncoder.prototype.encode) { + return new TextEncoder().encode(str); + } + + let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { + c2 = str.charCodeAt(m_pos + 1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } + + // allocate buffer + buf = new Uint8Array(buf_len); + + // convert + for (i = 0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { + c2 = str.charCodeAt(m_pos + 1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; +}; + +// Helper +const buf2binstring = (buf, len) => { + // On Chrome, the arguments in a function call that are allowed is `65534`. + // If the length of the buffer is smaller than that, we can use this optimization, + // otherwise we will take a slower path. + if (len < 65534) { + if (buf.subarray && STR_APPLY_UIA_OK) { + return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len)); + } + } + + let result = ''; + for (let i = 0; i < len; i++) { + result += String.fromCharCode(buf[i]); + } + return result; +}; + + +// convert array to string +var buf2string = (buf, max) => { + const len = max || buf.length; + + if (typeof TextDecoder === 'function' && TextDecoder.prototype.decode) { + return new TextDecoder().decode(buf.subarray(0, max)); + } + + let i, out; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + const utf16buf = new Array(len * 2); + + for (out = 0, i = 0; i < len;) { + let c = buf[i++]; + // quick process ascii + if (c < 0x80) { utf16buf[out++] = c; continue; } + + let c_len = _utf8len[c]; + // skip 5 & 6 byte codes + if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + return buf2binstring(utf16buf, out); +}; + + +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +var utf8border = (buf, max) => { + + max = max || buf.length; + if (max > buf.length) { max = buf.length; } + + // go back from last position, until start of sequence found + let pos = max - 1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } + + // Very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } + + // If we came to start of buffer - that means buffer is too small, + // return max too. + if (pos === 0) { return max; } + + return (pos + _utf8len[buf[pos]] > max) ? pos : max; +}; + +var strings = { + string2buf: string2buf, + buf2string: buf2string, + utf8border: utf8border +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +function ZStream() { + /* next input byte */ + this.input = null; // JS specific, because we have no pointers + this.next_in = 0; + /* number of bytes available at input */ + this.avail_in = 0; + /* total number of input bytes read so far */ + this.total_in = 0; + /* next output byte should be put there */ + this.output = null; // JS specific, because we have no pointers + this.next_out = 0; + /* remaining free space at output */ + this.avail_out = 0; + /* total number of bytes output so far */ + this.total_out = 0; + /* last error message, NULL if no error */ + this.msg = ''/*Z_NULL*/; + /* not visible by applications */ + this.state = null; + /* best guess about the data type: binary or text */ + this.data_type = 2/*Z_UNKNOWN*/; + /* adler32 value of the uncompressed data */ + this.adler = 0; +} + +var zstream = ZStream; + +const toString$1 = Object.prototype.toString; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + +const { + Z_NO_FLUSH: Z_NO_FLUSH$1, Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH: Z_FINISH$2, + Z_OK: Z_OK$2, Z_STREAM_END: Z_STREAM_END$2, + Z_DEFAULT_COMPRESSION, + Z_DEFAULT_STRATEGY, + Z_DEFLATED: Z_DEFLATED$1 +} = constants$2; + +/* ===========================================================================*/ + + +/** + * class Deflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[deflate]], + * [[deflateRaw]] and [[gzip]]. + **/ + +/* internal + * Deflate.chunks -> Array + * + * Chunks of output data, if [[Deflate#onData]] not overridden. + **/ + +/** + * Deflate.result -> Uint8Array + * + * Compressed result, generated by default [[Deflate#onData]] + * and [[Deflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Deflate#push]] with `Z_FINISH` / `true` param). + **/ + +/** + * Deflate.err -> Number + * + * Error code after deflate finished. 0 (Z_OK) on success. + * You will not need it in real life, because deflate errors + * are possible only on wrong options or bad `onData` / `onEnd` + * custom handlers. + **/ + +/** + * Deflate.msg -> String + * + * Error message, if [[Deflate.err]] != 0 + **/ + + +/** + * new Deflate(options) + * - options (Object): zlib deflate options. + * + * Creates new deflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `level` + * - `windowBits` + * - `memLevel` + * - `strategy` + * - `dictionary` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw deflate + * - `gzip` (Boolean) - create gzip wrapper + * - `header` (Object) - custom header for gzip + * - `text` (Boolean) - true if compressed data believed to be text + * - `time` (Number) - modification time, unix timestamp + * - `os` (Number) - operation system code + * - `extra` (Array) - array of bytes with extra data (max 65536) + * - `name` (String) - file name (binary string) + * - `comment` (String) - comment (binary string) + * - `hcrc` (Boolean) - true if header crc should be added + * + * ##### Example: + * + * ```javascript + * const pako = require('pako') + * , chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * const deflate = new pako.Deflate({ level: 3}); + * + * deflate.push(chunk1, false); + * deflate.push(chunk2, true); // true -> last chunk + * + * if (deflate.err) { throw new Error(deflate.err); } + * + * console.log(deflate.result); + * ``` + **/ +function Deflate$1(options) { + this.options = common.assign({ + level: Z_DEFAULT_COMPRESSION, + method: Z_DEFLATED$1, + chunkSize: 16384, + windowBits: 15, + memLevel: 8, + strategy: Z_DEFAULT_STRATEGY + }, options || {}); + + let opt = this.options; + + if (opt.raw && (opt.windowBits > 0)) { + opt.windowBits = -opt.windowBits; + } + + else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { + opt.windowBits += 16; + } + + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ''; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new zstream(); + this.strm.avail_out = 0; + + let status = deflate_1$2.deflateInit2( + this.strm, + opt.level, + opt.method, + opt.windowBits, + opt.memLevel, + opt.strategy + ); + + if (status !== Z_OK$2) { + throw new Error(messages[status]); + } + + if (opt.header) { + deflate_1$2.deflateSetHeader(this.strm, opt.header); + } + + if (opt.dictionary) { + let dict; + // Convert data if needed + if (typeof opt.dictionary === 'string') { + // If we need to compress text, change encoding to utf8. + dict = strings.string2buf(opt.dictionary); + } else if (toString$1.call(opt.dictionary) === '[object ArrayBuffer]') { + dict = new Uint8Array(opt.dictionary); + } else { + dict = opt.dictionary; + } + + status = deflate_1$2.deflateSetDictionary(this.strm, dict); + + if (status !== Z_OK$2) { + throw new Error(messages[status]); + } + + this._dict_set = true; + } +} + +/** + * Deflate#push(data[, flush_mode]) -> Boolean + * - data (Uint8Array|ArrayBuffer|String): input data. Strings will be + * converted to utf8 byte sequence. + * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. + * + * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with + * new compressed chunks. Returns `true` on success. The last data block must + * have `flush_mode` Z_FINISH (or `true`). That will flush internal pending + * buffers and call [[Deflate#onEnd]]. + * + * On fail call [[Deflate#onEnd]] with error code and return false. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ +Deflate$1.prototype.push = function (data, flush_mode) { + const strm = this.strm; + const chunkSize = this.options.chunkSize; + let status, _flush_mode; + + if (this.ended) { return false; } + + if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; + else _flush_mode = flush_mode === true ? Z_FINISH$2 : Z_NO_FLUSH$1; + + // Convert data if needed + if (typeof data === 'string') { + // If we need to compress text, change encoding to utf8. + strm.input = strings.string2buf(data); + } else if (toString$1.call(data) === '[object ArrayBuffer]') { + strm.input = new Uint8Array(data); + } else { + strm.input = data; + } + + strm.next_in = 0; + strm.avail_in = strm.input.length; + + for (;;) { + if (strm.avail_out === 0) { + strm.output = new Uint8Array(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + + // Make sure avail_out > 6 to avoid repeating markers + if ((_flush_mode === Z_SYNC_FLUSH || _flush_mode === Z_FULL_FLUSH) && strm.avail_out <= 6) { + this.onData(strm.output.subarray(0, strm.next_out)); + strm.avail_out = 0; + continue; + } + + status = deflate_1$2.deflate(strm, _flush_mode); + + // Ended => flush and finish + if (status === Z_STREAM_END$2) { + if (strm.next_out > 0) { + this.onData(strm.output.subarray(0, strm.next_out)); + } + status = deflate_1$2.deflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === Z_OK$2; + } + + // Flush if out buffer full + if (strm.avail_out === 0) { + this.onData(strm.output); + continue; + } + + // Flush if requested and has data + if (_flush_mode > 0 && strm.next_out > 0) { + this.onData(strm.output.subarray(0, strm.next_out)); + strm.avail_out = 0; + continue; + } + + if (strm.avail_in === 0) break; + } + + return true; +}; + + +/** + * Deflate#onData(chunk) -> Void + * - chunk (Uint8Array): output data. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ +Deflate$1.prototype.onData = function (chunk) { + this.chunks.push(chunk); +}; + + +/** + * Deflate#onEnd(status) -> Void + * - status (Number): deflate status. 0 (Z_OK) on success, + * other if not. + * + * Called once after you tell deflate that the input stream is + * complete (Z_FINISH). By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ +Deflate$1.prototype.onEnd = function (status) { + // On success - join + if (status === Z_OK$2) { + this.result = common.flattenChunks(this.chunks); + } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; +}; + + +/** + * deflate(data[, options]) -> Uint8Array + * - data (Uint8Array|ArrayBuffer|String): input data to compress. + * - options (Object): zlib deflate options. + * + * Compress `data` with deflate algorithm and `options`. + * + * Supported options are: + * + * - level + * - windowBits + * - memLevel + * - strategy + * - dictionary + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * + * ##### Example: + * + * ```javascript + * const pako = require('pako') + * const data = new Uint8Array([1,2,3,4,5,6,7,8,9]); + * + * console.log(pako.deflate(data)); + * ``` + **/ +function deflate$1(input, options) { + const deflator = new Deflate$1(options); + + deflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (deflator.err) { throw deflator.msg || messages[deflator.err]; } + + return deflator.result; +} + + +/** + * deflateRaw(data[, options]) -> Uint8Array + * - data (Uint8Array|ArrayBuffer|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ +function deflateRaw$1(input, options) { + options = options || {}; + options.raw = true; + return deflate$1(input, options); +} + + +/** + * gzip(data[, options]) -> Uint8Array + * - data (Uint8Array|ArrayBuffer|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but create gzip wrapper instead of + * deflate one. + **/ +function gzip$1(input, options) { + options = options || {}; + options.gzip = true; + return deflate$1(input, options); +} + + +var Deflate_1$1 = Deflate$1; +var deflate_2 = deflate$1; +var deflateRaw_1$1 = deflateRaw$1; +var gzip_1$1 = gzip$1; +var constants$1 = constants$2; + +var deflate_1$1 = { + Deflate: Deflate_1$1, + deflate: deflate_2, + deflateRaw: deflateRaw_1$1, + gzip: gzip_1$1, + constants: constants$1 +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +// See state defs from inflate.js +const BAD$1 = 16209; /* got a data error -- remain here until reset */ +const TYPE$1 = 16191; /* i: waiting for type bits, including last-flag bit */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state.mode === LEN + strm.avail_in >= 6 + strm.avail_out >= 258 + start >= strm.avail_out + state.bits < 8 + + On return, state.mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm.avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm.avail_out >= 258 for each loop to avoid checking for + output space. + */ +var inffast = function inflate_fast(strm, start) { + let _in; /* local strm.input */ + let last; /* have enough input while in < last */ + let _out; /* local strm.output */ + let beg; /* inflate()'s initial strm.output */ + let end; /* while out < end, enough space available */ +//#ifdef INFLATE_STRICT + let dmax; /* maximum distance from zlib header */ +//#endif + let wsize; /* window size or zero if not using window */ + let whave; /* valid bytes in the window */ + let wnext; /* window write index */ + // Use `s_window` instead `window`, avoid conflict with instrumentation tools + let s_window; /* allocated sliding window, if wsize != 0 */ + let hold; /* local strm.hold */ + let bits; /* local strm.bits */ + let lcode; /* local strm.lencode */ + let dcode; /* local strm.distcode */ + let lmask; /* mask for first level of length codes */ + let dmask; /* mask for first level of distance codes */ + let here; /* retrieved table entry */ + let op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + let len; /* match length, unused bytes */ + let dist; /* match distance */ + let from; /* where to copy match from */ + let from_source; + + + let input, output; // JS specific, because we have no pointers + + /* copy state to local variables */ + const state = strm.state; + //here = state.here; + _in = strm.next_in; + input = strm.input; + last = _in + (strm.avail_in - 5); + _out = strm.next_out; + output = strm.output; + beg = _out - (start - strm.avail_out); + end = _out + (strm.avail_out - 257); +//#ifdef INFLATE_STRICT + dmax = state.dmax; +//#endif + wsize = state.wsize; + whave = state.whave; + wnext = state.wnext; + s_window = state.window; + hold = state.hold; + bits = state.bits; + lcode = state.lencode; + dcode = state.distcode; + lmask = (1 << state.lenbits) - 1; + dmask = (1 << state.distbits) - 1; + + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + top: + do { + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + + here = lcode[hold & lmask]; + + dolen: + for (;;) { // Goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + if (op === 0) { /* literal */ + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + output[_out++] = here & 0xffff/*here.val*/; + } + else if (op & 16) { /* length base */ + len = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + len += hold & ((1 << op) - 1); + hold >>>= op; + bits -= op; + } + //Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = dcode[hold & dmask]; + + dodist: + for (;;) { // goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + + if (op & 16) { /* distance base */ + dist = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + } + dist += hold & ((1 << op) - 1); +//#ifdef INFLATE_STRICT + if (dist > dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD$1; + break top; + } +//#endif + hold >>>= op; + bits -= op; + //Tracevv((stderr, "inflate: distance %u\n", dist)); + op = _out - beg; /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD$1; + break top; + } + +// (!) This block is disabled in zlib defaults, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// if (len <= op - whave) { +// do { +// output[_out++] = 0; +// } while (--len); +// continue top; +// } +// len -= op - whave; +// do { +// output[_out++] = 0; +// } while (--op > whave); +// if (op === 0) { +// from = _out - dist; +// do { +// output[_out++] = output[from++]; +// } while (--len); +// continue top; +// } +//#endif + } + from = 0; // window index + from_source = s_window; + if (wnext === 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = 0; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + while (len > 2) { + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + len -= 3; + } + if (len) { + output[_out++] = from_source[from++]; + if (len > 1) { + output[_out++] = from_source[from++]; + } + } + } + else { + from = _out - dist; /* copy direct from output */ + do { /* minimum length is three */ + output[_out++] = output[from++]; + output[_out++] = output[from++]; + output[_out++] = output[from++]; + len -= 3; + } while (len > 2); + if (len) { + output[_out++] = output[from++]; + if (len > 1) { + output[_out++] = output[from++]; + } + } + } + } + else if ((op & 64) === 0) { /* 2nd level distance code */ + here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dodist; + } + else { + strm.msg = 'invalid distance code'; + state.mode = BAD$1; + break top; + } + + break; // need to emulate goto via "continue" + } + } + else if ((op & 64) === 0) { /* 2nd level length code */ + here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dolen; + } + else if (op & 32) { /* end-of-block */ + //Tracevv((stderr, "inflate: end of block\n")); + state.mode = TYPE$1; + break top; + } + else { + strm.msg = 'invalid literal/length code'; + state.mode = BAD$1; + break top; + } + + break; // need to emulate goto via "continue" + } + } while (_in < last && _out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + _in -= len; + bits -= len << 3; + hold &= (1 << bits) - 1; + + /* update state and return */ + strm.next_in = _in; + strm.next_out = _out; + strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); + strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); + state.hold = hold; + state.bits = bits; + return; +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +const MAXBITS = 15; +const ENOUGH_LENS$1 = 852; +const ENOUGH_DISTS$1 = 592; +//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +const CODES$1 = 0; +const LENS$1 = 1; +const DISTS$1 = 2; + +const lbase = new Uint16Array([ /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 +]); + +const lext = new Uint8Array([ /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 +]); + +const dbase = new Uint16Array([ /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0 +]); + +const dext = new Uint8Array([ /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64 +]); + +const inflate_table = (type, lens, lens_index, codes, table, table_index, work, opts) => +{ + const bits = opts.bits; + //here = opts.here; /* table entry for duplication */ + + let len = 0; /* a code's length in bits */ + let sym = 0; /* index of code symbols */ + let min = 0, max = 0; /* minimum and maximum code lengths */ + let root = 0; /* number of index bits for root table */ + let curr = 0; /* number of index bits for current table */ + let drop = 0; /* code bits to drop for sub-table */ + let left = 0; /* number of prefix codes available */ + let used = 0; /* code entries in table used */ + let huff = 0; /* Huffman code */ + let incr; /* for incrementing code, index */ + let fill; /* index for replicating entries */ + let low; /* low bits for current root entry */ + let mask; /* mask for low root bits */ + let next; /* next available space in table */ + let base = null; /* base value table to use */ +// let shoextra; /* extra bits table to use */ + let match; /* use base and extra for symbol >= match */ + const count = new Uint16Array(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ + const offs = new Uint16Array(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ + let extra = null; + + let here_bits, here_op, here_val; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) { + count[len] = 0; + } + for (sym = 0; sym < codes; sym++) { + count[lens[lens_index + sym]]++; + } + + /* bound code lengths, force root to be within code lengths */ + root = bits; + for (max = MAXBITS; max >= 1; max--) { + if (count[max] !== 0) { break; } + } + if (root > max) { + root = max; + } + if (max === 0) { /* no symbols to code at all */ + //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ + //table.bits[opts.table_index] = 1; //here.bits = (var char)1; + //table.val[opts.table_index++] = 0; //here.val = (var short)0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + + //table.op[opts.table_index] = 64; + //table.bits[opts.table_index] = 1; + //table.val[opts.table_index++] = 0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + opts.bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) { + if (count[min] !== 0) { break; } + } + if (root < min) { + root = min; + } + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) { + return -1; + } /* over-subscribed */ + } + if (left > 0 && (type === CODES$1 || max !== 1)) { + return -1; /* incomplete set */ + } + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) { + offs[len + 1] = offs[len] + count[len]; + } + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) { + if (lens[lens_index + sym] !== 0) { + work[offs[lens[lens_index + sym]]++] = sym; + } + } + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + // poor man optimization - use if-else instead of switch, + // to avoid deopts in old v8 + if (type === CODES$1) { + base = extra = work; /* dummy value--not used */ + match = 20; + + } else if (type === LENS$1) { + base = lbase; + extra = lext; + match = 257; + + } else { /* DISTS */ + base = dbase; + extra = dext; + match = 0; + } + + /* initialize opts for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = table_index; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = -1; /* trigger new sub-table when len > root */ + used = 1 << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type === LENS$1 && used > ENOUGH_LENS$1) || + (type === DISTS$1 && used > ENOUGH_DISTS$1)) { + return 1; + } + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here_bits = len - drop; + if (work[sym] + 1 < match) { + here_op = 0; + here_val = work[sym]; + } + else if (work[sym] >= match) { + here_op = extra[work[sym] - match]; + here_val = base[work[sym] - match]; + } + else { + here_op = 32 + 64; /* end of block */ + here_val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1 << (len - drop); + fill = 1 << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; + } while (fill !== 0); + + /* backwards increment the len-bit code huff */ + incr = 1 << (len - 1); + while (huff & incr) { + incr >>= 1; + } + if (incr !== 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--count[len] === 0) { + if (len === max) { break; } + len = lens[lens_index + work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) !== low) { + /* if first time, transition to sub-tables */ + if (drop === 0) { + drop = root; + } + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = 1 << curr; + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) { break; } + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1 << curr; + if ((type === LENS$1 && used > ENOUGH_LENS$1) || + (type === DISTS$1 && used > ENOUGH_DISTS$1)) { + return 1; + } + + /* point entry in root table to sub-table */ + low = huff & mask; + /*table.op[low] = curr; + table.bits[low] = root; + table.val[low] = next - opts.table_index;*/ + table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff !== 0) { + //table.op[next + huff] = 64; /* invalid code marker */ + //table.bits[next + huff] = len - drop; + //table.val[next + huff] = 0; + table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; + } + + /* set return parameters */ + //opts.table_index += used; + opts.bits = root; + return 0; +}; + + +var inftrees = inflate_table; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + + + + + + +const CODES = 0; +const LENS = 1; +const DISTS = 2; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + +const { + Z_FINISH: Z_FINISH$1, Z_BLOCK, Z_TREES, + Z_OK: Z_OK$1, Z_STREAM_END: Z_STREAM_END$1, Z_NEED_DICT: Z_NEED_DICT$1, Z_STREAM_ERROR: Z_STREAM_ERROR$1, Z_DATA_ERROR: Z_DATA_ERROR$1, Z_MEM_ERROR: Z_MEM_ERROR$1, Z_BUF_ERROR, + Z_DEFLATED +} = constants$2; + + +/* STATES ====================================================================*/ +/* ===========================================================================*/ + + +const HEAD = 16180; /* i: waiting for magic header */ +const FLAGS = 16181; /* i: waiting for method and flags (gzip) */ +const TIME = 16182; /* i: waiting for modification time (gzip) */ +const OS = 16183; /* i: waiting for extra flags and operating system (gzip) */ +const EXLEN = 16184; /* i: waiting for extra length (gzip) */ +const EXTRA = 16185; /* i: waiting for extra bytes (gzip) */ +const NAME = 16186; /* i: waiting for end of file name (gzip) */ +const COMMENT = 16187; /* i: waiting for end of comment (gzip) */ +const HCRC = 16188; /* i: waiting for header crc (gzip) */ +const DICTID = 16189; /* i: waiting for dictionary check value */ +const DICT = 16190; /* waiting for inflateSetDictionary() call */ +const TYPE = 16191; /* i: waiting for type bits, including last-flag bit */ +const TYPEDO = 16192; /* i: same, but skip check to exit inflate on new block */ +const STORED = 16193; /* i: waiting for stored size (length and complement) */ +const COPY_ = 16194; /* i/o: same as COPY below, but only first time in */ +const COPY = 16195; /* i/o: waiting for input or output to copy stored block */ +const TABLE = 16196; /* i: waiting for dynamic block table lengths */ +const LENLENS = 16197; /* i: waiting for code length code lengths */ +const CODELENS = 16198; /* i: waiting for length/lit and distance code lengths */ +const LEN_ = 16199; /* i: same as LEN below, but only first time in */ +const LEN = 16200; /* i: waiting for length/lit/eob code */ +const LENEXT = 16201; /* i: waiting for length extra bits */ +const DIST = 16202; /* i: waiting for distance code */ +const DISTEXT = 16203; /* i: waiting for distance extra bits */ +const MATCH = 16204; /* o: waiting for output space to copy string */ +const LIT = 16205; /* o: waiting for output space to write literal */ +const CHECK = 16206; /* i: waiting for 32-bit check value */ +const LENGTH = 16207; /* i: waiting for 32-bit length (gzip) */ +const DONE = 16208; /* finished check, done -- remain here until reset */ +const BAD = 16209; /* got a data error -- remain here until reset */ +const MEM = 16210; /* got an inflate() memory error -- remain here until reset */ +const SYNC = 16211; /* looking for synchronization bytes to restart inflate() */ + +/* ===========================================================================*/ + + + +const ENOUGH_LENS = 852; +const ENOUGH_DISTS = 592; +//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +const MAX_WBITS = 15; +/* 32K LZ77 window */ +const DEF_WBITS = MAX_WBITS; + + +const zswap32 = (q) => { + + return (((q >>> 24) & 0xff) + + ((q >>> 8) & 0xff00) + + ((q & 0xff00) << 8) + + ((q & 0xff) << 24)); +}; + + +function InflateState() { + this.strm = null; /* pointer back to this zlib stream */ + this.mode = 0; /* current inflate mode */ + this.last = false; /* true if processing last block */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ + this.havedict = false; /* true if dictionary provided */ + this.flags = 0; /* gzip header method and flags (0 if zlib), or + -1 if raw or no header yet */ + this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ + this.check = 0; /* protected copy of check value */ + this.total = 0; /* protected copy of output count */ + // TODO: may be {} + this.head = null; /* where to save gzip header information */ + + /* sliding window */ + this.wbits = 0; /* log base 2 of requested window size */ + this.wsize = 0; /* window size or zero if not using window */ + this.whave = 0; /* valid bytes in the window */ + this.wnext = 0; /* window write index */ + this.window = null; /* allocated sliding window, if needed */ + + /* bit accumulator */ + this.hold = 0; /* input bit accumulator */ + this.bits = 0; /* number of bits in "in" */ + + /* for string and stored block copying */ + this.length = 0; /* literal or length of data to copy */ + this.offset = 0; /* distance back to copy string from */ + + /* for table and code decoding */ + this.extra = 0; /* extra bits needed */ + + /* fixed and dynamic code tables */ + this.lencode = null; /* starting table for length/literal codes */ + this.distcode = null; /* starting table for distance codes */ + this.lenbits = 0; /* index bits for lencode */ + this.distbits = 0; /* index bits for distcode */ + + /* dynamic table building */ + this.ncode = 0; /* number of code length code lengths */ + this.nlen = 0; /* number of length code lengths */ + this.ndist = 0; /* number of distance code lengths */ + this.have = 0; /* number of code lengths in lens[] */ + this.next = null; /* next available space in codes[] */ + + this.lens = new Uint16Array(320); /* temporary storage for code lengths */ + this.work = new Uint16Array(288); /* work area for code table building */ + + /* + because we don't have pointers in js, we use lencode and distcode directly + as buffers so we don't need codes + */ + //this.codes = new Int32Array(ENOUGH); /* space for code tables */ + this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ + this.distdyn = null; /* dynamic table for distance codes (JS specific) */ + this.sane = 0; /* if false, allow invalid distance too far */ + this.back = 0; /* bits back of last unprocessed length/lit */ + this.was = 0; /* initial length of match */ +} + + +const inflateStateCheck = (strm) => { + + if (!strm) { + return 1; + } + const state = strm.state; + if (!state || state.strm !== strm || + state.mode < HEAD || state.mode > SYNC) { + return 1; + } + return 0; +}; + + +const inflateResetKeep = (strm) => { + + if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; } + const state = strm.state; + strm.total_in = strm.total_out = state.total = 0; + strm.msg = ''; /*Z_NULL*/ + if (state.wrap) { /* to support ill-conceived Java test suite */ + strm.adler = state.wrap & 1; + } + state.mode = HEAD; + state.last = 0; + state.havedict = 0; + state.flags = -1; + state.dmax = 32768; + state.head = null/*Z_NULL*/; + state.hold = 0; + state.bits = 0; + //state.lencode = state.distcode = state.next = state.codes; + state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS); + state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS); + + state.sane = 1; + state.back = -1; + //Tracev((stderr, "inflate: reset\n")); + return Z_OK$1; +}; + + +const inflateReset = (strm) => { + + if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; } + const state = strm.state; + state.wsize = 0; + state.whave = 0; + state.wnext = 0; + return inflateResetKeep(strm); + +}; + + +const inflateReset2 = (strm, windowBits) => { + let wrap; + + /* get the state */ + if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; } + const state = strm.state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 5; + if (windowBits < 48) { + windowBits &= 15; + } + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) { + return Z_STREAM_ERROR$1; + } + if (state.window !== null && state.wbits !== windowBits) { + state.window = null; + } + + /* update state and reset the rest of it */ + state.wrap = wrap; + state.wbits = windowBits; + return inflateReset(strm); +}; + + +const inflateInit2 = (strm, windowBits) => { + + if (!strm) { return Z_STREAM_ERROR$1; } + //strm.msg = Z_NULL; /* in case we return an error */ + + const state = new InflateState(); + + //if (state === Z_NULL) return Z_MEM_ERROR; + //Tracev((stderr, "inflate: allocated\n")); + strm.state = state; + state.strm = strm; + state.window = null/*Z_NULL*/; + state.mode = HEAD; /* to pass state test in inflateReset2() */ + const ret = inflateReset2(strm, windowBits); + if (ret !== Z_OK$1) { + strm.state = null/*Z_NULL*/; + } + return ret; +}; + + +const inflateInit = (strm) => { + + return inflateInit2(strm, DEF_WBITS); +}; + + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +let virgin = true; + +let lenfix, distfix; // We have no pointers in JS, so keep tables separate + + +const fixedtables = (state) => { + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + lenfix = new Int32Array(512); + distfix = new Int32Array(32); + + /* literal/length table */ + let sym = 0; + while (sym < 144) { state.lens[sym++] = 8; } + while (sym < 256) { state.lens[sym++] = 9; } + while (sym < 280) { state.lens[sym++] = 7; } + while (sym < 288) { state.lens[sym++] = 8; } + + inftrees(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); + + /* distance table */ + sym = 0; + while (sym < 32) { state.lens[sym++] = 5; } + + inftrees(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); + + /* do this just once */ + virgin = false; + } + + state.lencode = lenfix; + state.lenbits = 9; + state.distcode = distfix; + state.distbits = 5; +}; + + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +const updatewindow = (strm, src, end, copy) => { + + let dist; + const state = strm.state; + + /* if it hasn't been done already, allocate space for the window */ + if (state.window === null) { + state.wsize = 1 << state.wbits; + state.wnext = 0; + state.whave = 0; + + state.window = new Uint8Array(state.wsize); + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state.wsize) { + state.window.set(src.subarray(end - state.wsize, end), 0); + state.wnext = 0; + state.whave = state.wsize; + } + else { + dist = state.wsize - state.wnext; + if (dist > copy) { + dist = copy; + } + //zmemcpy(state->window + state->wnext, end - copy, dist); + state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext); + copy -= dist; + if (copy) { + //zmemcpy(state->window, end - copy, copy); + state.window.set(src.subarray(end - copy, end), 0); + state.wnext = copy; + state.whave = state.wsize; + } + else { + state.wnext += dist; + if (state.wnext === state.wsize) { state.wnext = 0; } + if (state.whave < state.wsize) { state.whave += dist; } + } + } + return 0; +}; + + +const inflate$2 = (strm, flush) => { + + let state; + let input, output; // input/output buffers + let next; /* next input INDEX */ + let put; /* next output INDEX */ + let have, left; /* available input and output */ + let hold; /* bit buffer */ + let bits; /* bits in bit buffer */ + let _in, _out; /* save starting available input and output */ + let copy; /* number of stored or match bytes to copy */ + let from; /* where to copy match bytes from */ + let from_source; + let here = 0; /* current decoding table entry */ + let here_bits, here_op, here_val; // paked "here" denormalized (JS specific) + //let last; /* parent table entry */ + let last_bits, last_op, last_val; // paked "last" denormalized (JS specific) + let len; /* length to copy for repeats, bits to drop */ + let ret; /* return code */ + const hbuf = new Uint8Array(4); /* buffer for gzip header crc calculation */ + let opts; + + let n; // temporary variable for NEED_BITS + + const order = /* permutation of code lengths */ + new Uint8Array([ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]); + + + if (inflateStateCheck(strm) || !strm.output || + (!strm.input && strm.avail_in !== 0)) { + return Z_STREAM_ERROR$1; + } + + state = strm.state; + if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ + + + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + _in = have; + _out = left; + ret = Z_OK$1; + + inf_leave: // goto emulation + for (;;) { + switch (state.mode) { + case HEAD: + if (state.wrap === 0) { + state.mode = TYPEDO; + break; + } + //=== NEEDBITS(16); + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ + if (state.wbits === 0) { + state.wbits = 15; + } + state.check = 0/*crc32(0L, Z_NULL, 0)*/; + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32_1(state.check, hbuf, 2, 0); + //===// + + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = FLAGS; + break; + } + if (state.head) { + state.head.done = false; + } + if (!(state.wrap & 1) || /* check if zlib header allowed */ + (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { + strm.msg = 'incorrect header check'; + state.mode = BAD; + break; + } + if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// + len = (hold & 0x0f)/*BITS(4)*/ + 8; + if (state.wbits === 0) { + state.wbits = len; + } + if (len > 15 || len > state.wbits) { + strm.msg = 'invalid window size'; + state.mode = BAD; + break; + } + + // !!! pako patch. Force use `options.windowBits` if passed. + // Required to always use max window size by default. + state.dmax = 1 << state.wbits; + //state.dmax = 1 << len; + + state.flags = 0; /* indicate zlib header */ + //Tracev((stderr, "inflate: zlib header ok\n")); + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = hold & 0x200 ? DICTID : TYPE; + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + break; + case FLAGS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.flags = hold; + if ((state.flags & 0xff) !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + if (state.flags & 0xe000) { + strm.msg = 'unknown header flags set'; + state.mode = BAD; + break; + } + if (state.head) { + state.head.text = ((hold >> 8) & 1); + } + if ((state.flags & 0x0200) && (state.wrap & 4)) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32_1(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = TIME; + /* falls through */ + case TIME: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.time = hold; + } + if ((state.flags & 0x0200) && (state.wrap & 4)) { + //=== CRC4(state.check, hold) + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + hbuf[2] = (hold >>> 16) & 0xff; + hbuf[3] = (hold >>> 24) & 0xff; + state.check = crc32_1(state.check, hbuf, 4, 0); + //=== + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = OS; + /* falls through */ + case OS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.xflags = (hold & 0xff); + state.head.os = (hold >> 8); + } + if ((state.flags & 0x0200) && (state.wrap & 4)) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32_1(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = EXLEN; + /* falls through */ + case EXLEN: + if (state.flags & 0x0400) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length = hold; + if (state.head) { + state.head.extra_len = hold; + } + if ((state.flags & 0x0200) && (state.wrap & 4)) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32_1(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + else if (state.head) { + state.head.extra = null/*Z_NULL*/; + } + state.mode = EXTRA; + /* falls through */ + case EXTRA: + if (state.flags & 0x0400) { + copy = state.length; + if (copy > have) { copy = have; } + if (copy) { + if (state.head) { + len = state.head.extra_len - state.length; + if (!state.head.extra) { + // Use untyped array for more convenient processing later + state.head.extra = new Uint8Array(state.head.extra_len); + } + state.head.extra.set( + input.subarray( + next, + // extra field is limited to 65536 bytes + // - no need for additional size check + next + copy + ), + /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ + len + ); + //zmemcpy(state.head.extra + len, next, + // len + copy > state.head.extra_max ? + // state.head.extra_max - len : copy); + } + if ((state.flags & 0x0200) && (state.wrap & 4)) { + state.check = crc32_1(state.check, input, copy, next); + } + have -= copy; + next += copy; + state.length -= copy; + } + if (state.length) { break inf_leave; } + } + state.length = 0; + state.mode = NAME; + /* falls through */ + case NAME: + if (state.flags & 0x0800) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + // TODO: 2 or 1 bytes? + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.name_max*/)) { + state.head.name += String.fromCharCode(len); + } + } while (len && copy < have); + + if ((state.flags & 0x0200) && (state.wrap & 4)) { + state.check = crc32_1(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.name = null; + } + state.length = 0; + state.mode = COMMENT; + /* falls through */ + case COMMENT: + if (state.flags & 0x1000) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.comm_max*/)) { + state.head.comment += String.fromCharCode(len); + } + } while (len && copy < have); + if ((state.flags & 0x0200) && (state.wrap & 4)) { + state.check = crc32_1(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.comment = null; + } + state.mode = HCRC; + /* falls through */ + case HCRC: + if (state.flags & 0x0200) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((state.wrap & 4) && hold !== (state.check & 0xffff)) { + strm.msg = 'header crc mismatch'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + if (state.head) { + state.head.hcrc = ((state.flags >> 9) & 1); + state.head.done = true; + } + strm.adler = state.check = 0; + state.mode = TYPE; + break; + case DICTID: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + strm.adler = state.check = zswap32(hold); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = DICT; + /* falls through */ + case DICT: + if (state.havedict === 0) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + return Z_NEED_DICT$1; + } + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + /* falls through */ + case TYPE: + if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } + /* falls through */ + case TYPEDO: + if (state.last) { + //--- BYTEBITS() ---// + hold >>>= bits & 7; + bits -= bits & 7; + //---// + state.mode = CHECK; + break; + } + //=== NEEDBITS(3); */ + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.last = (hold & 0x01)/*BITS(1)*/; + //--- DROPBITS(1) ---// + hold >>>= 1; + bits -= 1; + //---// + + switch ((hold & 0x03)/*BITS(2)*/) { + case 0: /* stored block */ + //Tracev((stderr, "inflate: stored block%s\n", + // state.last ? " (last)" : "")); + state.mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + //Tracev((stderr, "inflate: fixed codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = LEN_; /* decode codes */ + if (flush === Z_TREES) { + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break inf_leave; + } + break; + case 2: /* dynamic block */ + //Tracev((stderr, "inflate: dynamic codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = TABLE; + break; + case 3: + strm.msg = 'invalid block type'; + state.mode = BAD; + } + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break; + case STORED: + //--- BYTEBITS() ---// /* go to byte boundary */ + hold >>>= bits & 7; + bits -= bits & 7; + //---// + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { + strm.msg = 'invalid stored block lengths'; + state.mode = BAD; + break; + } + state.length = hold & 0xffff; + //Tracev((stderr, "inflate: stored length %u\n", + // state.length)); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = COPY_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case COPY_: + state.mode = COPY; + /* falls through */ + case COPY: + copy = state.length; + if (copy) { + if (copy > have) { copy = have; } + if (copy > left) { copy = left; } + if (copy === 0) { break inf_leave; } + //--- zmemcpy(put, next, copy); --- + output.set(input.subarray(next, next + copy), put); + //---// + have -= copy; + next += copy; + left -= copy; + put += copy; + state.length -= copy; + break; + } + //Tracev((stderr, "inflate: stored end\n")); + state.mode = TYPE; + break; + case TABLE: + //=== NEEDBITS(14); */ + while (bits < 14) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// +//#ifndef PKZIP_BUG_WORKAROUND + if (state.nlen > 286 || state.ndist > 30) { + strm.msg = 'too many length or distance symbols'; + state.mode = BAD; + break; + } +//#endif + //Tracev((stderr, "inflate: table sizes ok\n")); + state.have = 0; + state.mode = LENLENS; + /* falls through */ + case LENLENS: + while (state.have < state.ncode) { + //=== NEEDBITS(3); + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + while (state.have < 19) { + state.lens[order[state.have++]] = 0; + } + // We have separate tables & no pointers. 2 commented lines below not needed. + //state.next = state.codes; + //state.lencode = state.next; + // Switch to use dynamic table + state.lencode = state.lendyn; + state.lenbits = 7; + + opts = { bits: state.lenbits }; + ret = inftrees(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); + state.lenbits = opts.bits; + + if (ret) { + strm.msg = 'invalid code lengths set'; + state.mode = BAD; + break; + } + //Tracev((stderr, "inflate: code lengths ok\n")); + state.have = 0; + state.mode = CODELENS; + /* falls through */ + case CODELENS: + while (state.have < state.nlen + state.ndist) { + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_val < 16) { + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.lens[state.have++] = here_val; + } + else { + if (here_val === 16) { + //=== NEEDBITS(here.bits + 2); + n = here_bits + 2; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + if (state.have === 0) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + len = state.lens[state.have - 1]; + copy = 3 + (hold & 0x03);//BITS(2); + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + } + else if (here_val === 17) { + //=== NEEDBITS(here.bits + 3); + n = here_bits + 3; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 3 + (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + else { + //=== NEEDBITS(here.bits + 7); + n = here_bits + 7; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 11 + (hold & 0x7f);//BITS(7); + //--- DROPBITS(7) ---// + hold >>>= 7; + bits -= 7; + //---// + } + if (state.have + copy > state.nlen + state.ndist) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + while (copy--) { + state.lens[state.have++] = len; + } + } + } + + /* handle error breaks in while */ + if (state.mode === BAD) { break; } + + /* check for end-of-block code (better have one) */ + if (state.lens[256] === 0) { + strm.msg = 'invalid code -- missing end-of-block'; + state.mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state.lenbits = 9; + + opts = { bits: state.lenbits }; + ret = inftrees(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.lenbits = opts.bits; + // state.lencode = state.next; + + if (ret) { + strm.msg = 'invalid literal/lengths set'; + state.mode = BAD; + break; + } + + state.distbits = 6; + //state.distcode.copy(state.codes); + // Switch to use dynamic table + state.distcode = state.distdyn; + opts = { bits: state.distbits }; + ret = inftrees(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.distbits = opts.bits; + // state.distcode = state.next; + + if (ret) { + strm.msg = 'invalid distances set'; + state.mode = BAD; + break; + } + //Tracev((stderr, 'inflate: codes ok\n')); + state.mode = LEN_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case LEN_: + state.mode = LEN; + /* falls through */ + case LEN: + if (have >= 6 && left >= 258) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + inffast(strm, _out); + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + if (state.mode === TYPE) { + state.back = -1; + } + break; + } + state.back = 0; + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_op && (here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.lencode[last_val + + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + state.length = here_val; + if (here_op === 0) { + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + state.mode = LIT; + break; + } + if (here_op & 32) { + //Tracevv((stderr, "inflate: end of block\n")); + state.back = -1; + state.mode = TYPE; + break; + } + if (here_op & 64) { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break; + } + state.extra = here_op & 15; + state.mode = LENEXT; + /* falls through */ + case LENEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } + //Tracevv((stderr, "inflate: length %u\n", state.length)); + state.was = state.length; + state.mode = DIST; + /* falls through */ + case DIST: + for (;;) { + here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if ((here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.distcode[last_val + + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + if (here_op & 64) { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break; + } + state.offset = here_val; + state.extra = (here_op) & 15; + state.mode = DISTEXT; + /* falls through */ + case DISTEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } +//#ifdef INFLATE_STRICT + if (state.offset > state.dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +//#endif + //Tracevv((stderr, "inflate: distance %u\n", state.offset)); + state.mode = MATCH; + /* falls through */ + case MATCH: + if (left === 0) { break inf_leave; } + copy = _out - left; + if (state.offset > copy) { /* copy from window */ + copy = state.offset - copy; + if (copy > state.whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +// (!) This block is disabled in zlib defaults, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// Trace((stderr, "inflate.c too far\n")); +// copy -= state.whave; +// if (copy > state.length) { copy = state.length; } +// if (copy > left) { copy = left; } +// left -= copy; +// state.length -= copy; +// do { +// output[put++] = 0; +// } while (--copy); +// if (state.length === 0) { state.mode = LEN; } +// break; +//#endif + } + if (copy > state.wnext) { + copy -= state.wnext; + from = state.wsize - copy; + } + else { + from = state.wnext - copy; + } + if (copy > state.length) { copy = state.length; } + from_source = state.window; + } + else { /* copy from output */ + from_source = output; + from = put - state.offset; + copy = state.length; + } + if (copy > left) { copy = left; } + left -= copy; + state.length -= copy; + do { + output[put++] = from_source[from++]; + } while (--copy); + if (state.length === 0) { state.mode = LEN; } + break; + case LIT: + if (left === 0) { break inf_leave; } + output[put++] = state.length; + left--; + state.mode = LEN; + break; + case CHECK: + if (state.wrap) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + // Use '|' instead of '+' to make sure that result is signed + hold |= input[next++] << bits; + bits += 8; + } + //===// + _out -= left; + strm.total_out += _out; + state.total += _out; + if ((state.wrap & 4) && _out) { + strm.adler = state.check = + /*UPDATE_CHECK(state.check, put - _out, _out);*/ + (state.flags ? crc32_1(state.check, output, _out, put - _out) : adler32_1(state.check, output, _out, put - _out)); + + } + _out = left; + // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too + if ((state.wrap & 4) && (state.flags ? hold : zswap32(hold)) !== state.check) { + strm.msg = 'incorrect data check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: check matches trailer\n")); + } + state.mode = LENGTH; + /* falls through */ + case LENGTH: + if (state.wrap && state.flags) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((state.wrap & 4) && hold !== (state.total & 0xffffffff)) { + strm.msg = 'incorrect length check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: length matches trailer\n")); + } + state.mode = DONE; + /* falls through */ + case DONE: + ret = Z_STREAM_END$1; + break inf_leave; + case BAD: + ret = Z_DATA_ERROR$1; + break inf_leave; + case MEM: + return Z_MEM_ERROR$1; + case SYNC: + /* falls through */ + default: + return Z_STREAM_ERROR$1; + } + } + + // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + + if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && + (state.mode < CHECK || flush !== Z_FINISH$1))) { + if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) ; + } + _in -= strm.avail_in; + _out -= strm.avail_out; + strm.total_in += _in; + strm.total_out += _out; + state.total += _out; + if ((state.wrap & 4) && _out) { + strm.adler = state.check = /*UPDATE_CHECK(state.check, strm.next_out - _out, _out);*/ + (state.flags ? crc32_1(state.check, output, _out, strm.next_out - _out) : adler32_1(state.check, output, _out, strm.next_out - _out)); + } + strm.data_type = state.bits + (state.last ? 64 : 0) + + (state.mode === TYPE ? 128 : 0) + + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); + if (((_in === 0 && _out === 0) || flush === Z_FINISH$1) && ret === Z_OK$1) { + ret = Z_BUF_ERROR; + } + return ret; +}; + + +const inflateEnd = (strm) => { + + if (inflateStateCheck(strm)) { + return Z_STREAM_ERROR$1; + } + + let state = strm.state; + if (state.window) { + state.window = null; + } + strm.state = null; + return Z_OK$1; +}; + + +const inflateGetHeader = (strm, head) => { + + /* check state */ + if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; } + const state = strm.state; + if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR$1; } + + /* save header structure */ + state.head = head; + head.done = false; + return Z_OK$1; +}; + + +const inflateSetDictionary = (strm, dictionary) => { + const dictLength = dictionary.length; + + let state; + let dictid; + let ret; + + /* check state */ + if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; } + state = strm.state; + + if (state.wrap !== 0 && state.mode !== DICT) { + return Z_STREAM_ERROR$1; + } + + /* check for correct dictionary identifier */ + if (state.mode === DICT) { + dictid = 1; /* adler32(0, null, 0)*/ + /* dictid = adler32(dictid, dictionary, dictLength); */ + dictid = adler32_1(dictid, dictionary, dictLength, 0); + if (dictid !== state.check) { + return Z_DATA_ERROR$1; + } + } + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary, dictLength, dictLength); + if (ret) { + state.mode = MEM; + return Z_MEM_ERROR$1; + } + state.havedict = 1; + // Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK$1; +}; + + +var inflateReset_1 = inflateReset; +var inflateReset2_1 = inflateReset2; +var inflateResetKeep_1 = inflateResetKeep; +var inflateInit_1 = inflateInit; +var inflateInit2_1 = inflateInit2; +var inflate_2$1 = inflate$2; +var inflateEnd_1 = inflateEnd; +var inflateGetHeader_1 = inflateGetHeader; +var inflateSetDictionary_1 = inflateSetDictionary; +var inflateInfo = 'pako inflate (from Nodeca project)'; + +/* Not implemented +module.exports.inflateCodesUsed = inflateCodesUsed; +module.exports.inflateCopy = inflateCopy; +module.exports.inflateGetDictionary = inflateGetDictionary; +module.exports.inflateMark = inflateMark; +module.exports.inflatePrime = inflatePrime; +module.exports.inflateSync = inflateSync; +module.exports.inflateSyncPoint = inflateSyncPoint; +module.exports.inflateUndermine = inflateUndermine; +module.exports.inflateValidate = inflateValidate; +*/ + +var inflate_1$2 = { + inflateReset: inflateReset_1, + inflateReset2: inflateReset2_1, + inflateResetKeep: inflateResetKeep_1, + inflateInit: inflateInit_1, + inflateInit2: inflateInit2_1, + inflate: inflate_2$1, + inflateEnd: inflateEnd_1, + inflateGetHeader: inflateGetHeader_1, + inflateSetDictionary: inflateSetDictionary_1, + inflateInfo: inflateInfo +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +function GZheader() { + /* true if compressed data believed to be text */ + this.text = 0; + /* modification time */ + this.time = 0; + /* extra flags (not used when writing a gzip file) */ + this.xflags = 0; + /* operating system */ + this.os = 0; + /* pointer to extra field or Z_NULL if none */ + this.extra = null; + /* extra field length (valid if extra != Z_NULL) */ + this.extra_len = 0; // Actually, we don't need it in JS, + // but leave for few code modifications + + // + // Setup limits is not necessary because in js we should not preallocate memory + // for inflate use constant limit in 65536 bytes + // + + /* space at extra (only when reading header) */ + // this.extra_max = 0; + /* pointer to zero-terminated file name or Z_NULL */ + this.name = ''; + /* space at name (only when reading header) */ + // this.name_max = 0; + /* pointer to zero-terminated comment or Z_NULL */ + this.comment = ''; + /* space at comment (only when reading header) */ + // this.comm_max = 0; + /* true if there was or will be a header crc */ + this.hcrc = 0; + /* true when done reading gzip header (not used when writing a gzip file) */ + this.done = false; +} + +var gzheader = GZheader; + +const toString = Object.prototype.toString; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + +const { + Z_NO_FLUSH, Z_FINISH, + Z_OK, Z_STREAM_END, Z_NEED_DICT, Z_STREAM_ERROR, Z_DATA_ERROR, Z_MEM_ERROR +} = constants$2; + +/* ===========================================================================*/ + + +/** + * class Inflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[inflate]] + * and [[inflateRaw]]. + **/ + +/* internal + * inflate.chunks -> Array + * + * Chunks of output data, if [[Inflate#onData]] not overridden. + **/ + +/** + * Inflate.result -> Uint8Array|String + * + * Uncompressed result, generated by default [[Inflate#onData]] + * and [[Inflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Inflate#push]] with `Z_FINISH` / `true` param). + **/ + +/** + * Inflate.err -> Number + * + * Error code after inflate finished. 0 (Z_OK) on success. + * Should be checked if broken data possible. + **/ + +/** + * Inflate.msg -> String + * + * Error message, if [[Inflate.err]] != 0 + **/ + + +/** + * new Inflate(options) + * - options (Object): zlib inflate options. + * + * Creates new inflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `windowBits` + * - `dictionary` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw inflate + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * By default, when no options set, autodetect deflate/gzip data format via + * wrapper header. + * + * ##### Example: + * + * ```javascript + * const pako = require('pako') + * const chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) + * const chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * const inflate = new pako.Inflate({ level: 3}); + * + * inflate.push(chunk1, false); + * inflate.push(chunk2, true); // true -> last chunk + * + * if (inflate.err) { throw new Error(inflate.err); } + * + * console.log(inflate.result); + * ``` + **/ +function Inflate$1(options) { + this.options = common.assign({ + chunkSize: 1024 * 64, + windowBits: 15, + to: '' + }, options || {}); + + const opt = this.options; + + // Force window size for `raw` data, if not set directly, + // because we have no header for autodetect. + if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { + opt.windowBits = -opt.windowBits; + if (opt.windowBits === 0) { opt.windowBits = -15; } + } + + // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate + if ((opt.windowBits >= 0) && (opt.windowBits < 16) && + !(options && options.windowBits)) { + opt.windowBits += 32; + } + + // Gzip header has no info about windows size, we can do autodetect only + // for deflate. So, if window size not set, force it to max when gzip possible + if ((opt.windowBits > 15) && (opt.windowBits < 48)) { + // bit 3 (16) -> gzipped data + // bit 4 (32) -> autodetect gzip/deflate + if ((opt.windowBits & 15) === 0) { + opt.windowBits |= 15; + } + } + + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ''; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new zstream(); + this.strm.avail_out = 0; + + let status = inflate_1$2.inflateInit2( + this.strm, + opt.windowBits + ); + + if (status !== Z_OK) { + throw new Error(messages[status]); + } + + this.header = new gzheader(); + + inflate_1$2.inflateGetHeader(this.strm, this.header); + + // Setup dictionary + if (opt.dictionary) { + // Convert data if needed + if (typeof opt.dictionary === 'string') { + opt.dictionary = strings.string2buf(opt.dictionary); + } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') { + opt.dictionary = new Uint8Array(opt.dictionary); + } + if (opt.raw) { //In raw mode we need to set the dictionary early + status = inflate_1$2.inflateSetDictionary(this.strm, opt.dictionary); + if (status !== Z_OK) { + throw new Error(messages[status]); + } + } + } +} + +/** + * Inflate#push(data[, flush_mode]) -> Boolean + * - data (Uint8Array|ArrayBuffer): input data + * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE + * flush modes. See constants. Skipped or `false` means Z_NO_FLUSH, + * `true` means Z_FINISH. + * + * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with + * new output chunks. Returns `true` on success. If end of stream detected, + * [[Inflate#onEnd]] will be called. + * + * `flush_mode` is not needed for normal operation, because end of stream + * detected automatically. You may try to use it for advanced things, but + * this functionality was not tested. + * + * On fail call [[Inflate#onEnd]] with error code and return false. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ +Inflate$1.prototype.push = function (data, flush_mode) { + const strm = this.strm; + const chunkSize = this.options.chunkSize; + const dictionary = this.options.dictionary; + let status, _flush_mode, last_avail_out; + + if (this.ended) return false; + + if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; + else _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH; + + // Convert data if needed + if (toString.call(data) === '[object ArrayBuffer]') { + strm.input = new Uint8Array(data); + } else { + strm.input = data; + } + + strm.next_in = 0; + strm.avail_in = strm.input.length; + + for (;;) { + if (strm.avail_out === 0) { + strm.output = new Uint8Array(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + + status = inflate_1$2.inflate(strm, _flush_mode); + + if (status === Z_NEED_DICT && dictionary) { + status = inflate_1$2.inflateSetDictionary(strm, dictionary); + + if (status === Z_OK) { + status = inflate_1$2.inflate(strm, _flush_mode); + } else if (status === Z_DATA_ERROR) { + // Replace code with more verbose + status = Z_NEED_DICT; + } + } + + // Skip snyc markers if more data follows and not raw mode + while (strm.avail_in > 0 && + status === Z_STREAM_END && + strm.state.wrap > 0 && + data[strm.next_in] !== 0) + { + inflate_1$2.inflateReset(strm); + status = inflate_1$2.inflate(strm, _flush_mode); + } + + switch (status) { + case Z_STREAM_ERROR: + case Z_DATA_ERROR: + case Z_NEED_DICT: + case Z_MEM_ERROR: + this.onEnd(status); + this.ended = true; + return false; + } + + // Remember real `avail_out` value, because we may patch out buffer content + // to align utf8 strings boundaries. + last_avail_out = strm.avail_out; + + if (strm.next_out) { + if (strm.avail_out === 0 || status === Z_STREAM_END) { + + if (this.options.to === 'string') { + + let next_out_utf8 = strings.utf8border(strm.output, strm.next_out); + + let tail = strm.next_out - next_out_utf8; + let utf8str = strings.buf2string(strm.output, next_out_utf8); + + // move tail & realign counters + strm.next_out = tail; + strm.avail_out = chunkSize - tail; + if (tail) strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0); + + this.onData(utf8str); + + } else { + this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out)); + } + } + } + + // Must repeat iteration if out buffer is full + if (status === Z_OK && last_avail_out === 0) continue; + + // Finalize if end of stream reached. + if (status === Z_STREAM_END) { + status = inflate_1$2.inflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return true; + } + + if (strm.avail_in === 0) break; + } + + return true; +}; + + +/** + * Inflate#onData(chunk) -> Void + * - chunk (Uint8Array|String): output data. When string output requested, + * each chunk will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ +Inflate$1.prototype.onData = function (chunk) { + this.chunks.push(chunk); +}; + + +/** + * Inflate#onEnd(status) -> Void + * - status (Number): inflate status. 0 (Z_OK) on success, + * other if not. + * + * Called either after you tell inflate that the input stream is + * complete (Z_FINISH). By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ +Inflate$1.prototype.onEnd = function (status) { + // On success - join + if (status === Z_OK) { + if (this.options.to === 'string') { + this.result = this.chunks.join(''); + } else { + this.result = common.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; +}; + +const { Deflate, deflate, deflateRaw, gzip } = deflate_1$1; +var deflate_1 = deflate; + +const XKT_VERSION = XKT_INFO.xktVersion; +const NUM_TEXTURE_ATTRIBUTES = 9; +const NUM_MATERIAL_ATTRIBUTES = 6; + +/** + * Writes an {@link XKTModel} to an {@link ArrayBuffer}. + * + * @param {XKTModel} xktModel The {@link XKTModel}. + * @param {String} metaModelJSON The metamodel JSON in a string. + * @param {Object} [stats] Collects statistics. + * @param {Object} options Options for how the XKT is written. + * @param {Boolean} [options.zip=true] ZIP the contents? + * @returns {ArrayBuffer} The {@link ArrayBuffer}. + */ +function writeXKTModelToArrayBuffer(xktModel, metaModelJSON, stats, options) { + const data = getModelData(xktModel, metaModelJSON, stats); + const deflatedData = deflateData(data, metaModelJSON, options); + stats.texturesSize += deflatedData.textureData.byteLength; + const arrayBuffer = createArrayBuffer(deflatedData); + return arrayBuffer; +} + +function getModelData(xktModel, metaModelDataStr, stats) { + + //------------------------------------------------------------------------------------------------------------------ + // Allocate data + //------------------------------------------------------------------------------------------------------------------ + + const propertySetsList = xktModel.propertySetsList; + const metaObjectsList = xktModel.metaObjectsList; + const geometriesList = xktModel.geometriesList; + const texturesList = xktModel.texturesList; + const textureSetsList = xktModel.textureSetsList; + const meshesList = xktModel.meshesList; + const entitiesList = xktModel.entitiesList; + const tilesList = xktModel.tilesList; + + const numPropertySets = propertySetsList.length; + const numMetaObjects = metaObjectsList.length; + const numGeometries = geometriesList.length; + const numTextures = texturesList.length; + const numTextureSets = textureSetsList.length; + const numMeshes = meshesList.length; + const numEntities = entitiesList.length; + const numTiles = tilesList.length; + + let lenPositions = 0; + let lenNormals = 0; + let lenColors = 0; + let lenUVs = 0; + let lenIndices = 0; + let lenEdgeIndices = 0; + let lenMatrices = 0; + let lenTextures = 0; + + for (let geometryIndex = 0; geometryIndex < numGeometries; geometryIndex++) { + const geometry = geometriesList [geometryIndex]; + if (geometry.positionsQuantized) { + lenPositions += geometry.positionsQuantized.length; + } + if (geometry.normalsOctEncoded) { + lenNormals += geometry.normalsOctEncoded.length; + } + if (geometry.colorsCompressed) { + lenColors += geometry.colorsCompressed.length; + } + if (geometry.uvs) { + lenUVs += geometry.uvs.length; + } + if (geometry.indices) { + lenIndices += geometry.indices.length; + } + if (geometry.edgeIndices) { + lenEdgeIndices += geometry.edgeIndices.length; + } + } + + for (let textureIndex = 0; textureIndex < numTextures; textureIndex++) { + const xktTexture = texturesList[textureIndex]; + const imageData = xktTexture.imageData; + lenTextures += imageData.byteLength; + + if (xktTexture.compressed) { + stats.numCompressedTextures++; + } + } + + for (let meshIndex = 0; meshIndex < numMeshes; meshIndex++) { + const mesh = meshesList[meshIndex]; + if (mesh.geometry.numInstances > 1) { + lenMatrices += 16; + } + } + + const data = { + metadata: {}, + textureData: new Uint8Array(lenTextures), // All textures + eachTextureDataPortion: new Uint32Array(numTextures), // For each texture, an index to its first element in textureData + eachTextureAttributes: new Uint16Array(numTextures * NUM_TEXTURE_ATTRIBUTES), + positions: new Uint16Array(lenPositions), // All geometry arrays + normals: new Int8Array(lenNormals), + colors: new Uint8Array(lenColors), + uvs: new Float32Array(lenUVs), + indices: new Uint32Array(lenIndices), + edgeIndices: new Uint32Array(lenEdgeIndices), + eachTextureSetTextures: new Int32Array(numTextureSets * 5), // For each texture set, a set of five Texture indices [color, metal/roughness,normals,emissive,occlusion]; each index has value -1 if no texture + matrices: new Float32Array(lenMatrices), // Modeling matrices for entities that share geometries. Each entity either shares all it's geometries, or owns all its geometries exclusively. Exclusively-owned geometries are pre-transformed into World-space, and so their entities don't have modeling matrices in this array. + reusedGeometriesDecodeMatrix: new Float32Array(xktModel.reusedGeometriesDecodeMatrix), // A single, global vertex position de-quantization matrix for all reused geometries. Reused geometries are quantized to their collective Local-space AABB, and this matrix is derived from that AABB. + eachGeometryPrimitiveType: new Uint8Array(numGeometries), // Primitive type for each geometry (0=solid triangles, 1=surface triangles, 2=lines, 3=points, 4=line-strip) + eachGeometryPositionsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.positions. Every primitive type has positions. + eachGeometryNormalsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.normals. If the next geometry has the same index, then this geometry has no normals. + eachGeometryColorsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.colors. If the next geometry has the same index, then this geometry has no colors. + eachGeometryUVsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.uvs. If the next geometry has the same index, then this geometry has no UVs. + eachGeometryIndicesPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.indices. If the next geometry has the same index, then this geometry has no indices. + eachGeometryEdgeIndicesPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.edgeIndices. If the next geometry has the same index, then this geometry has no edge indices. + eachMeshGeometriesPortion: new Uint32Array(numMeshes), // For each mesh, an index into the eachGeometry* arrays + eachMeshMatricesPortion: new Uint32Array(numMeshes), // For each mesh that shares its geometry, an index to its first element in data.matrices, to indicate the modeling matrix that transforms the shared geometry Local-space vertex positions. This is ignored for meshes that don't share geometries, because the vertex positions of non-shared geometries are pre-transformed into World-space. + eachMeshTextureSet: new Int32Array(numMeshes), // For each mesh, the index of its texture set in data.eachTextureSetTextures; this array contains signed integers so that we can use -1 to indicate when a mesh has no texture set + eachMeshMaterialAttributes: new Uint8Array(numMeshes * NUM_MATERIAL_ATTRIBUTES), // For each mesh, an RGBA integer color of format [0..255, 0..255, 0..255, 0..255], and PBR metallic and roughness factors, of format [0..255, 0..255] + eachEntityId: [], // For each entity, an ID string + eachEntityMeshesPortion: new Uint32Array(numEntities), // For each entity, the index of the first element of meshes used by the entity + eachTileAABB: new Float64Array(numTiles * 6), // For each tile, an axis-aligned bounding box + eachTileEntitiesPortion: new Uint32Array(numTiles) // For each tile, the index of the first element of eachEntityId, eachEntityMeshesPortion and eachEntityMatricesPortion used by the tile + }; + + let countPositions = 0; + let countNormals = 0; + let countColors = 0; + let countUVs = 0; + let countIndices = 0; + let countEdgeIndices = 0; + + // Metadata + + data.metadata = { + id: xktModel.modelId, + projectId: xktModel.projectId, + revisionId: xktModel.revisionId, + author: xktModel.author, + createdAt: xktModel.createdAt, + creatingApplication: xktModel.creatingApplication, + schema: xktModel.schema, + propertySets: [], + metaObjects: [] + }; + + // Property sets + + for (let propertySetsIndex = 0; propertySetsIndex < numPropertySets; propertySetsIndex++) { + const propertySet = propertySetsList[propertySetsIndex]; + const propertySetJSON = { + id: "" + propertySet.propertySetId, + name: propertySet.propertySetName, + type: propertySet.propertySetType, + properties: propertySet.properties + }; + data.metadata.propertySets.push(propertySetJSON); + } + + // Metaobjects + + if (!metaModelDataStr) { + for (let metaObjectsIndex = 0; metaObjectsIndex < numMetaObjects; metaObjectsIndex++) { + const metaObject = metaObjectsList[metaObjectsIndex]; + const metaObjectJSON = { + name: metaObject.metaObjectName, + type: metaObject.metaObjectType, + id: "" + metaObject.metaObjectId + }; + if (metaObject.parentMetaObjectId !== undefined && metaObject.parentMetaObjectId !== null) { + metaObjectJSON.parent = "" + metaObject.parentMetaObjectId; + } + if (metaObject.propertySetIds && metaObject.propertySetIds.length > 0) { + metaObjectJSON.propertySetIds = metaObject.propertySetIds; + } + if (metaObject.external) { + metaObjectJSON.external = metaObject.external; + } + data.metadata.metaObjects.push(metaObjectJSON); + } + } + + // Geometries + + for (let geometryIndex = 0; geometryIndex < numGeometries; geometryIndex++) { + const geometry = geometriesList [geometryIndex]; + let primitiveType = 1; + switch (geometry.primitiveType) { + case "triangles": + primitiveType = geometry.solid ? 0 : 1; + break; + case "points": + primitiveType = 2; + break; + case "lines": + primitiveType = 3; + break; + case "line-strip": + case "line-loop": + primitiveType = 4; + break; + case "triangle-strip": + primitiveType = 5; + break; + case "triangle-fan": + primitiveType = 6; + break; + default: + primitiveType = 1; + } + data.eachGeometryPrimitiveType [geometryIndex] = primitiveType; + data.eachGeometryPositionsPortion [geometryIndex] = countPositions; + data.eachGeometryNormalsPortion [geometryIndex] = countNormals; + data.eachGeometryColorsPortion [geometryIndex] = countColors; + data.eachGeometryUVsPortion [geometryIndex] = countUVs; + data.eachGeometryIndicesPortion [geometryIndex] = countIndices; + data.eachGeometryEdgeIndicesPortion [geometryIndex] = countEdgeIndices; + if (geometry.positionsQuantized) { + data.positions.set(geometry.positionsQuantized, countPositions); + countPositions += geometry.positionsQuantized.length; + } + if (geometry.normalsOctEncoded) { + data.normals.set(geometry.normalsOctEncoded, countNormals); + countNormals += geometry.normalsOctEncoded.length; + } + if (geometry.colorsCompressed) { + data.colors.set(geometry.colorsCompressed, countColors); + countColors += geometry.colorsCompressed.length; + } + if (geometry.uvs) { + data.uvs.set(geometry.uvs, countUVs); + countUVs += geometry.uvs.length; + } + if (geometry.indices) { + data.indices.set(geometry.indices, countIndices); + countIndices += geometry.indices.length; + } + if (geometry.edgeIndices) { + data.edgeIndices.set(geometry.edgeIndices, countEdgeIndices); + countEdgeIndices += geometry.edgeIndices.length; + } + } + + // Textures + + for (let textureIndex = 0, numTextures = xktModel.texturesList.length, portionIdx = 0; textureIndex < numTextures; textureIndex++) { + const xktTexture = xktModel.texturesList[textureIndex]; + const imageData = xktTexture.imageData; + data.textureData.set(imageData, portionIdx); + data.eachTextureDataPortion[textureIndex] = portionIdx; + + portionIdx += imageData.byteLength; + + let textureAttrIdx = textureIndex * NUM_TEXTURE_ATTRIBUTES; + data.eachTextureAttributes[textureAttrIdx++] = xktTexture.compressed ? 1 : 0; + data.eachTextureAttributes[textureAttrIdx++] = xktTexture.mediaType; // GIFMediaType | PNGMediaType | JPEGMediaType + data.eachTextureAttributes[textureAttrIdx++] = xktTexture.width; + data.eachTextureAttributes[textureAttrIdx++] = xktTexture.height; + data.eachTextureAttributes[textureAttrIdx++] = xktTexture.minFilter; // LinearMipmapLinearFilter | LinearMipMapNearestFilter | NearestMipMapNearestFilter | NearestMipMapLinearFilter | LinearMipMapLinearFilter + data.eachTextureAttributes[textureAttrIdx++] = xktTexture.magFilter; // LinearFilter | NearestFilter + data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapS; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping + data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapT; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping + data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapR; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping + } + + // Texture sets + + for (let textureSetIndex = 0, numTextureSets = xktModel.textureSetsList.length, eachTextureSetTexturesIndex = 0; textureSetIndex < numTextureSets; textureSetIndex++) { + const textureSet = textureSetsList[textureSetIndex]; + data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.colorTexture ? textureSet.colorTexture.textureIndex : -1; // Color map + data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.metallicRoughnessTexture ? textureSet.metallicRoughnessTexture.textureIndex : -1; // Metal/rough map + data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.normalsTexture ? textureSet.normalsTexture.textureIndex : -1; // Normal map + data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.emissiveTexture ? textureSet.emissiveTexture.textureIndex : -1; // Emissive map + data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.occlusionTexture ? textureSet.occlusionTexture.textureIndex : -1; // Occlusion map + } + + // Tiles -> Entities -> Meshes + + let entityIndex = 0; + let countEntityMeshesPortion = 0; + let eachMeshMaterialAttributesIndex = 0; + let matricesIndex = 0; + let meshIndex = 0; + + for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) { + + const tile = tilesList [tileIndex]; + const tileEntities = tile.entities; + const numTileEntities = tileEntities.length; + + if (numTileEntities === 0) { + continue; + } + + data.eachTileEntitiesPortion[tileIndex] = entityIndex; + + const tileAABB = tile.aabb; + + for (let j = 0; j < numTileEntities; j++) { + + const entity = tileEntities[j]; + const entityMeshes = entity.meshes; + const numEntityMeshes = entityMeshes.length; + + for (let k = 0; k < numEntityMeshes; k++) { + + const mesh = entityMeshes[k]; + const geometry = mesh.geometry; + const geometryIndex = geometry.geometryIndex; + + data.eachMeshGeometriesPortion [countEntityMeshesPortion + k] = geometryIndex; + + if (mesh.geometry.numInstances > 1) { + data.matrices.set(mesh.matrix, matricesIndex); + data.eachMeshMatricesPortion [meshIndex] = matricesIndex; + matricesIndex += 16; + } + + data.eachMeshTextureSet[meshIndex] = mesh.textureSet ? mesh.textureSet.textureSetIndex : -1; + + data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[0] * 255); // Color RGB + data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[1] * 255); + data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[2] * 255); + data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.opacity * 255); // Opacity + data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.metallic * 255); // Metallic + data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.roughness * 255); // Roughness + + meshIndex++; + } + + data.eachEntityId [entityIndex] = entity.entityId; + data.eachEntityMeshesPortion[entityIndex] = countEntityMeshesPortion; // <<<<<<<<<<<<<<<<<<<< Error here? Order/value of countEntityMeshesPortion correct? + + entityIndex++; + countEntityMeshesPortion += numEntityMeshes; + } + + const tileAABBIndex = tileIndex * 6; + + data.eachTileAABB.set(tileAABB, tileAABBIndex); + } + + return data; +} + +function deflateData(data, metaModelJSON, options) { + + function deflate(buffer) { + return (options.zip !== false) ? deflate_1(buffer) : buffer; + } + + let metaModelBytes; + if (metaModelJSON) { + const deflatedJSON = deflateJSON(metaModelJSON); + metaModelBytes = deflate(deflatedJSON); + } else { + const deflatedJSON = deflateJSON(data.metadata); + metaModelBytes = deflate(deflatedJSON); + } + + return { + metadata: metaModelBytes, + textureData: deflate(data.textureData.buffer), + eachTextureDataPortion: deflate(data.eachTextureDataPortion.buffer), + eachTextureAttributes: deflate(data.eachTextureAttributes.buffer), + positions: deflate(data.positions.buffer), + normals: deflate(data.normals.buffer), + colors: deflate(data.colors.buffer), + uvs: deflate(data.uvs.buffer), + indices: deflate(data.indices.buffer), + edgeIndices: deflate(data.edgeIndices.buffer), + eachTextureSetTextures: deflate(data.eachTextureSetTextures.buffer), + matrices: deflate(data.matrices.buffer), + reusedGeometriesDecodeMatrix: deflate(data.reusedGeometriesDecodeMatrix.buffer), + eachGeometryPrimitiveType: deflate(data.eachGeometryPrimitiveType.buffer), + eachGeometryPositionsPortion: deflate(data.eachGeometryPositionsPortion.buffer), + eachGeometryNormalsPortion: deflate(data.eachGeometryNormalsPortion.buffer), + eachGeometryColorsPortion: deflate(data.eachGeometryColorsPortion.buffer), + eachGeometryUVsPortion: deflate(data.eachGeometryUVsPortion.buffer), + eachGeometryIndicesPortion: deflate(data.eachGeometryIndicesPortion.buffer), + eachGeometryEdgeIndicesPortion: deflate(data.eachGeometryEdgeIndicesPortion.buffer), + eachMeshGeometriesPortion: deflate(data.eachMeshGeometriesPortion.buffer), + eachMeshMatricesPortion: deflate(data.eachMeshMatricesPortion.buffer), + eachMeshTextureSet: deflate(data.eachMeshTextureSet.buffer), + eachMeshMaterialAttributes: deflate(data.eachMeshMaterialAttributes.buffer), + eachEntityId: deflate(JSON.stringify(data.eachEntityId) + .replace(/[\u007F-\uFFFF]/g, function (chr) { // Produce only ASCII-chars, so that the data can be inflated later + return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4) + })), + eachEntityMeshesPortion: deflate(data.eachEntityMeshesPortion.buffer), + eachTileAABB: deflate(data.eachTileAABB.buffer), + eachTileEntitiesPortion: deflate(data.eachTileEntitiesPortion.buffer) + }; +} + +function deflateJSON(strings) { + return JSON.stringify(strings) + .replace(/[\u007F-\uFFFF]/g, function (chr) { // Produce only ASCII-chars, so that the data can be inflated later + return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4) + }); +} + +function createArrayBuffer(deflatedData) { + return toArrayBuffer$1([ + deflatedData.metadata, + deflatedData.textureData, + deflatedData.eachTextureDataPortion, + deflatedData.eachTextureAttributes, + deflatedData.positions, + deflatedData.normals, + deflatedData.colors, + deflatedData.uvs, + deflatedData.indices, + deflatedData.edgeIndices, + deflatedData.eachTextureSetTextures, + deflatedData.matrices, + deflatedData.reusedGeometriesDecodeMatrix, + deflatedData.eachGeometryPrimitiveType, + deflatedData.eachGeometryPositionsPortion, + deflatedData.eachGeometryNormalsPortion, + deflatedData.eachGeometryColorsPortion, + deflatedData.eachGeometryUVsPortion, + deflatedData.eachGeometryIndicesPortion, + deflatedData.eachGeometryEdgeIndicesPortion, + deflatedData.eachMeshGeometriesPortion, + deflatedData.eachMeshMatricesPortion, + deflatedData.eachMeshTextureSet, + deflatedData.eachMeshMaterialAttributes, + deflatedData.eachEntityId, + deflatedData.eachEntityMeshesPortion, + deflatedData.eachTileAABB, + deflatedData.eachTileEntitiesPortion + ]); +} + +function toArrayBuffer$1(elements) { + const indexData = new Uint32Array(elements.length + 2); + indexData[0] = XKT_VERSION; + indexData [1] = elements.length; // Stored Data 1.1: number of stored elements + let dataLen = 0; // Stored Data 1.2: length of stored elements + for (let i = 0, len = elements.length; i < len; i++) { + const element = elements[i]; + const elementsize = element.length; + indexData[i + 2] = elementsize; + dataLen += elementsize; + } + const indexBuf = new Uint8Array(indexData.buffer); + const dataArray = new Uint8Array(indexBuf.length + dataLen); + dataArray.set(indexBuf); + let offset = indexBuf.length; + for (let i = 0, len = elements.length; i < len; i++) { // Stored Data 2: the elements themselves + const element = elements[i]; + dataArray.set(element, offset); + offset += element.length; + } + return dataArray.buffer; +} + +/** + * @private + * @param buf + * @returns {ArrayBuffer} + */ +function toArrayBuffer(buf) { + const ab = new ArrayBuffer(buf.length); + const view = new Uint8Array(ab); + for (let i = 0; i < buf.length; ++i) { + view[i] = buf[i]; + } + return ab; +} + +/** + * Converts model files into xeokit's native XKT format. + * + * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS. + * + * **Only bundled in xeokit-convert.cjs.js.** + * + * ## Usage + * + ```` + * @param {Object} params Conversion parameters. + * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the + * caller the choice of whether to use the Browser or NodeJS version. + * @param {*} [params.configs] Configurations. + * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````. + * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method. + * @param {Function} [params.outputXKT] Callback to collect XKT file data. + * @param {String[]} [params.includeTypes] Option to only convert objects of these types. + * @param {String[]} [params.excludeTypes] Option to never convert objects of these types. + * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided. + * @param {Function} [params.outputStats] Callback to collect statistics. + * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis "up", if necessary. Applies to CityJSON and LAS/LAZ models. + * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false, + * will automatically "expand" all reused geometries into duplicate copies. This has the drawback of increasing the XKT + * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model + * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are + * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a + * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc). + * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models. + * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore + * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has + * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render + * a flat-shaded non-PBR representation of the model. + * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000, + * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close + * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger. + * @param {Function} [params.log] Logging callback. + * @return {Promise} + */ +function convert2xkt({ + configs = {}, + sourceData, + modelAABB, + outputXKTModel, + outputXKT, + includeTypes, + excludeTypes, + reuseGeometries = true, + minTileSize = 200, + stats = {}, + rotateX = false, + includeTextures = true, + includeNormals = true, + log = function (msg) { + } + }) { + + stats.schemaVersion = ""; + stats.title = ""; + stats.author = ""; + stats.created = ""; + stats.numMetaObjects = 0; + stats.numPropertySets = 0; + stats.numTriangles = 0; + stats.numVertices = 0; + stats.numNormals = 0; + stats.numUVs = 0; + stats.numTextures = 0; + stats.numTextureSets = 0; + stats.numObjects = 0; + stats.numGeometries = 0; + stats.sourceSize = 0; + stats.xktSize = 0; + stats.texturesSize = 0; + stats.xktVersion = ""; + stats.compressionRatio = 0; + stats.conversionTime = 0; + stats.aabb = null; + + return new Promise(function (resolve, reject) { + const _log = log; + log = (msg) => { + _log(`[convert2xkt] ${msg}`); + }; + + if (!sourceData) { + reject("Argument expected: source or sourceData"); + return; + } + + if (!outputXKTModel && !outputXKT) { + reject("Argument expected: output, outputXKTModel or outputXKT"); + return; + } + + const sourceConfigs = configs.sourceConfigs || {}; + const ext = 'glb'; + + log(`Input file extension: "${ext}"`); + + let fileTypeConfigs = sourceConfigs[ext]; + + if (!fileTypeConfigs) { + log(`[WARNING] Could not find configs sourceConfigs entry for source format "${ext}". This is derived from the source file name extension. Will use internal default configs.`); + fileTypeConfigs = {}; + } + + function overrideOption(option1, option2) { + if (option1 !== undefined) { + return option1; + } + return option2; + } + + + const sourceFileSizeBytes = sourceData.byteLength; + + log("Input file size: " + (sourceFileSizeBytes / 1000).toFixed(2) + " kB"); + + + + minTileSize = overrideOption(fileTypeConfigs.minTileSize, minTileSize); + rotateX = overrideOption(fileTypeConfigs.rotateX, rotateX); + reuseGeometries = overrideOption(fileTypeConfigs.reuseGeometries, reuseGeometries); + includeTextures = overrideOption(fileTypeConfigs.includeTextures, includeTextures); + includeNormals = overrideOption(fileTypeConfigs.includeNormals, includeNormals); + includeTypes = overrideOption(fileTypeConfigs.includeTypes, includeTypes); + excludeTypes = overrideOption(fileTypeConfigs.excludeTypes, excludeTypes); + + if (reuseGeometries === false) { + log("Geometry reuse is disabled"); + } + + const xktModel = new XKTModel({ + minTileSize, + modelAABB + }); + + + + sourceData = toArrayBuffer(sourceData); + convert(parseGLTFIntoXKTModel, { + data: sourceData, + reuseGeometries, + includeTextures: true, + includeNormals, + xktModel, + stats, + log + }); + + + function convert(parser, converterParams) { + + parser(converterParams).then(() => { + + + log("Input file parsed OK. Building XKT document..."); + + xktModel.finalize().then(() => { + + log("XKT document built OK. Writing to XKT file..."); + + const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel, null, stats, {zip: true}); + + const xktContent = Buffer.from(xktArrayBuffer); + + + if (outputXKT) { + outputXKT(xktContent); + } + + resolve(); + }); + }, (err) => { + reject(err); + }); + } + }); +} + +exports.convert2xkt = convert2xkt; diff --git a/dist/xeokit-convert.cjs.js b/dist/xeokit-convert.cjs.js index 427a549..f0e283c 100644 --- a/dist/xeokit-convert.cjs.js +++ b/dist/xeokit-convert.cjs.js @@ -1,3 +1,3 @@ /*! For license information please see xeokit-convert.cjs.js.LICENSE.txt */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.convert2xkt=t():e.convert2xkt=t()}(global,(()=>(()=>{"use strict";var e={231:e=>{e.exports=require("fs")},423:e=>{e.exports=require("path")}},t={};function r(n){var i=t[n];if(void 0!==i)return i.exports;var o=t[n]={exports:{}};return e[n](o,o.exports,r),o.exports}r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};return(()=>{r.r(n),r.d(n,{ClampToEdgeWrapping:()=>p,GIFMediaType:()=>O,JPEGMediaType:()=>P,LinearFilter:()=>M,LinearMipMapLinearFilter:()=>A,LinearMipMapNearestFilter:()=>I,LinearMipmapLinearFilter:()=>S,LinearMipmapNearestFilter:()=>T,MirroredRepeatWrapping:()=>m,NearestFilter:()=>y,NearestMipMapLinearFilter:()=>w,NearestMipMapNearestFilter:()=>g,NearestMipmapLinearFilter:()=>b,NearestMipmapNearestFilter:()=>x,PNGMediaType:()=>L,RepeatWrapping:()=>d,XKTModel:()=>He,XKT_INFO:()=>f,buildBoxGeometry:()=>Ur,buildBoxLinesGeometry:()=>Xr,buildCylinderGeometry:()=>Rr,buildGridGeometry:()=>Kr,buildPlaneGeometry:()=>qr,buildSphereGeometry:()=>Zr,buildTorusGeometry:()=>Yr,buildVectorTextGeometry:()=>Qr,convert2xkt:()=>en,parseCityJSONIntoXKTModel:()=>Nt,parseGLTFIntoXKTModel:()=>Wt,parseGLTFJSONIntoXKTModel:()=>sr,parseIFCIntoXKTModel:()=>vr,parseLASIntoXKTModel:()=>Mr,parseMetaModelIntoXKTModel:()=>Tr,parsePCDIntoXKTModel:()=>Ir,parsePLYIntoXKTModel:()=>Lr,parseSTLIntoXKTModel:()=>kr,writeXKTModelToArrayBuffer:()=>nt});const e=require("@loaders.gl/polyfills");var t,i,o,a,s,u,c,l,h,f={xktVersion:10},d=1e3,p=1001,m=1002,y=1003,g=1004,x=1004,b=1005,w=1005,M=1006,T=1007,I=1007,S=1008,A=1008,O=1e4,P=10001,L=10002,E=Float64Array,j=new E(16),D=new E(16),G=new E(4),k={MIN_DOUBLE:-Number.MAX_SAFE_INTEGER,MAX_DOUBLE:Number.MAX_SAFE_INTEGER,DEGTORAD:.0174532925,RADTODEG:57.295779513,vec2:function(e){return new E(e||2)},vec3:function(e){return new E(e||3)},vec4:function(e){return new E(e||4)},mat3:function(e){return new E(e||9)},mat3ToMat4:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new E(16);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=0,t[4]=e[3],t[5]=e[4],t[6]=e[5],t[7]=0,t[8]=e[6],t[9]=e[7],t[10]=e[8],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},mat4:function(e){return new E(e||16)},mat4ToMat3:function(e,t){},createUUID:function(){for(var e=[],t=0;t<256;t++)e[t]=(t<16?"0":"")+t.toString(16);return function(){var t=4294967295*Math.random()|0,r=4294967295*Math.random()|0,n=4294967295*Math.random()|0,i=4294967295*Math.random()|0;return"".concat(e[255&t]+e[t>>8&255]+e[t>>16&255]+e[t>>24&255],"-").concat(e[255&r]).concat(e[r>>8&255],"-").concat(e[r>>16&15|64]).concat(e[r>>24&255],"-").concat(e[63&n|128]).concat(e[n>>8&255],"-").concat(e[n>>16&255]).concat(e[n>>24&255]).concat(e[255&i]).concat(e[i>>8&255]).concat(e[i>>16&255]).concat(e[i>>24&255])}}(),clamp:function(e,t,r){return Math.max(t,Math.min(r,e))},fmod:function(e,t){if(e1?1:r,Math.acos(r)},vec3FromMat4Scale:(u=new E(3),function(e,t){return u[0]=e[0],u[1]=e[1],u[2]=e[2],t[0]=k.lenVec3(u),u[0]=e[4],u[1]=e[5],u[2]=e[6],t[1]=k.lenVec3(u),u[0]=e[8],u[1]=e[9],u[2]=e[10],t[2]=k.lenVec3(u),t}),vecToArray:function(){function e(e){return Math.round(1e5*e)/1e5}return function(t){for(var r=0,n=(t=Array.prototype.slice.call(t)).length;r0&&void 0!==arguments[0]?arguments[0]:new E(16);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},identityMat3:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:new E(9);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},isIdentityMat4:function(e){return 1===e[0]&&0===e[1]&&0===e[2]&&0===e[3]&&0===e[4]&&1===e[5]&&0===e[6]&&0===e[7]&&0===e[8]&&0===e[9]&&1===e[10]&&0===e[11]&&0===e[12]&&0===e[13]&&0===e[14]&&1===e[15]},negateMat4:function(e,t){return t||(t=e),t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},addMat4:function(e,t,r){return r||(r=e),r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},addMat4Scalar:function(e,t,r){return r||(r=e),r[0]=e[0]+t,r[1]=e[1]+t,r[2]=e[2]+t,r[3]=e[3]+t,r[4]=e[4]+t,r[5]=e[5]+t,r[6]=e[6]+t,r[7]=e[7]+t,r[8]=e[8]+t,r[9]=e[9]+t,r[10]=e[10]+t,r[11]=e[11]+t,r[12]=e[12]+t,r[13]=e[13]+t,r[14]=e[14]+t,r[15]=e[15]+t,r},addScalarMat4:function(e,t,r){return k.addMat4Scalar(t,e,r)},subMat4:function(e,t,r){return r||(r=e),r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},subMat4Scalar:function(e,t,r){return r||(r=e),r[0]=e[0]-t,r[1]=e[1]-t,r[2]=e[2]-t,r[3]=e[3]-t,r[4]=e[4]-t,r[5]=e[5]-t,r[6]=e[6]-t,r[7]=e[7]-t,r[8]=e[8]-t,r[9]=e[9]-t,r[10]=e[10]-t,r[11]=e[11]-t,r[12]=e[12]-t,r[13]=e[13]-t,r[14]=e[14]-t,r[15]=e[15]-t,r},subScalarMat4:function(e,t,r){return r||(r=t),r[0]=e-t[0],r[1]=e-t[1],r[2]=e-t[2],r[3]=e-t[3],r[4]=e-t[4],r[5]=e-t[5],r[6]=e-t[6],r[7]=e-t[7],r[8]=e-t[8],r[9]=e-t[9],r[10]=e-t[10],r[11]=e-t[11],r[12]=e-t[12],r[13]=e-t[13],r[14]=e-t[14],r[15]=e-t[15],r},mulMat4:function(e,t,r){r||(r=e);var n=e[0],i=e[1],o=e[2],a=e[3],s=e[4],u=e[5],c=e[6],l=e[7],h=e[8],f=e[9],d=e[10],p=e[11],m=e[12],v=e[13],y=e[14],g=e[15],x=t[0],b=t[1],w=t[2],M=t[3],T=t[4],I=t[5],S=t[6],A=t[7],O=t[8],P=t[9],L=t[10],E=t[11],j=t[12],D=t[13],G=t[14],k=t[15];return r[0]=x*n+b*s+w*h+M*m,r[1]=x*i+b*u+w*f+M*v,r[2]=x*o+b*c+w*d+M*y,r[3]=x*a+b*l+w*p+M*g,r[4]=T*n+I*s+S*h+A*m,r[5]=T*i+I*u+S*f+A*v,r[6]=T*o+I*c+S*d+A*y,r[7]=T*a+I*l+S*p+A*g,r[8]=O*n+P*s+L*h+E*m,r[9]=O*i+P*u+L*f+E*v,r[10]=O*o+P*c+L*d+E*y,r[11]=O*a+P*l+L*p+E*g,r[12]=j*n+D*s+G*h+k*m,r[13]=j*i+D*u+G*f+k*v,r[14]=j*o+D*c+G*d+k*y,r[15]=j*a+D*l+G*p+k*g,r},mulMat3:function(e,t,r){r||(r=new E(9));var n=e[0],i=e[3],o=e[6],a=e[1],s=e[4],u=e[7],c=e[2],l=e[5],h=e[8],f=t[0],d=t[3],p=t[6],m=t[1],v=t[4],y=t[7],g=t[2],x=t[5],b=t[8];return r[0]=n*f+i*m+o*g,r[3]=n*d+i*v+o*x,r[6]=n*p+i*y+o*b,r[1]=a*f+s*m+u*g,r[4]=a*d+s*v+u*x,r[7]=a*p+s*y+u*b,r[2]=c*f+l*m+h*g,r[5]=c*d+l*v+h*x,r[8]=c*p+l*y+h*b,r},mulMat4Scalar:function(e,t,r){return r||(r=e),r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},mulMat4v4:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:k.vec4(),n=t[0],i=t[1],o=t[2],a=t[3];return r[0]=e[0]*n+e[4]*i+e[8]*o+e[12]*a,r[1]=e[1]*n+e[5]*i+e[9]*o+e[13]*a,r[2]=e[2]*n+e[6]*i+e[10]*o+e[14]*a,r[3]=e[3]*n+e[7]*i+e[11]*o+e[15]*a,r},transposeMat4:function(e,t){var r=e[4],n=e[14],i=e[8],o=e[13],a=e[12],s=e[9];if(!t||e===t){var u=e[1],c=e[2],l=e[3],h=e[6],f=e[7],d=e[11];return e[1]=r,e[2]=i,e[3]=a,e[4]=u,e[6]=s,e[7]=o,e[8]=c,e[9]=h,e[11]=n,e[12]=l,e[13]=f,e[14]=d,e}return t[0]=e[0],t[1]=r,t[2]=i,t[3]=a,t[4]=e[1],t[5]=e[5],t[6]=s,t[7]=o,t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=n,t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t},transposeMat3:function(e,t){if(t===e){var r=e[1],n=e[2],i=e[5];t[1]=e[3],t[2]=e[6],t[3]=r,t[5]=e[7],t[6]=n,t[7]=i}else t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8];return t},determinantMat4:function(e){var t=e[0],r=e[1],n=e[2],i=e[3],o=e[4],a=e[5],s=e[6],u=e[7],c=e[8],l=e[9],h=e[10],f=e[11],d=e[12],p=e[13],m=e[14],v=e[15];return d*l*s*i-c*p*s*i-d*a*h*i+o*p*h*i+c*a*m*i-o*l*m*i-d*l*n*u+c*p*n*u+d*r*h*u-t*p*h*u-c*r*m*u+t*l*m*u+d*a*n*f-o*p*n*f-d*r*s*f+t*p*s*f+o*r*m*f-t*a*m*f-c*a*n*v+o*l*n*v+c*r*s*v-t*l*s*v-o*r*h*v+t*a*h*v},inverseMat4:function(e,t){t||(t=e);var r=e[0],n=e[1],i=e[2],o=e[3],a=e[4],s=e[5],u=e[6],c=e[7],l=e[8],h=e[9],f=e[10],d=e[11],p=e[12],m=e[13],v=e[14],y=e[15],g=r*s-n*a,x=r*u-i*a,b=r*c-o*a,w=n*u-i*s,M=n*c-o*s,T=i*c-o*u,I=l*m-h*p,S=l*v-f*p,A=l*y-d*p,O=h*v-f*m,P=h*y-d*m,L=f*y-d*v,E=1/(g*L-x*P+b*O+w*A-M*S+T*I);return t[0]=(s*L-u*P+c*O)*E,t[1]=(-n*L+i*P-o*O)*E,t[2]=(m*T-v*M+y*w)*E,t[3]=(-h*T+f*M-d*w)*E,t[4]=(-a*L+u*A-c*S)*E,t[5]=(r*L-i*A+o*S)*E,t[6]=(-p*T+v*b-y*x)*E,t[7]=(l*T-f*b+d*x)*E,t[8]=(a*P-s*A+c*I)*E,t[9]=(-r*P+n*A-o*I)*E,t[10]=(p*M-m*b+y*g)*E,t[11]=(-l*M+h*b-d*g)*E,t[12]=(-a*O+s*S-u*I)*E,t[13]=(r*O-n*S+i*I)*E,t[14]=(-p*w+m*x-v*g)*E,t[15]=(l*w-h*x+f*g)*E,t},traceMat4:function(e){return e[0]+e[5]+e[10]+e[15]},translationMat4v:function(e,t){var r=t||k.identityMat4();return r[12]=e[0],r[13]=e[1],r[14]=e[2],r},translationMat3v:function(e,t){var r=t||k.identityMat3();return r[6]=e[0],r[7]=e[1],r},translationMat4c:(s=new E(3),function(e,t,r,n){return s[0]=e,s[1]=t,s[2]=r,k.translationMat4v(s,n)}),translationMat4s:function(e,t){return k.translationMat4c(e,e,e,t)},translateMat4v:function(e,t){return k.translateMat4c(e[0],e[1],e[2],t)},OLDtranslateMat4c:function(e,t,r,n){var i=n[12];n[0]+=i*e,n[4]+=i*t,n[8]+=i*r;var o=n[13];n[1]+=o*e,n[5]+=o*t,n[9]+=o*r;var a=n[14];n[2]+=a*e,n[6]+=a*t,n[10]+=a*r;var s=n[15];return n[3]+=s*e,n[7]+=s*t,n[11]+=s*r,n},translateMat4c:function(e,t,r,n){var i=n[3];n[0]+=i*e,n[1]+=i*t,n[2]+=i*r;var o=n[7];n[4]+=o*e,n[5]+=o*t,n[6]+=o*r;var a=n[11];n[8]+=a*e,n[9]+=a*t,n[10]+=a*r;var s=n[15];return n[12]+=s*e,n[13]+=s*t,n[14]+=s*r,n},rotationMat4v:function(e,t,r){var n,i,o,a,s,u,c=k.normalizeVec4([t[0],t[1],t[2],0],[]),l=Math.sin(e),h=Math.cos(e),f=1-h,d=c[0],p=c[1],m=c[2];return n=d*p,i=p*m,o=m*d,a=d*l,s=p*l,u=m*l,(r=r||k.mat4())[0]=f*d*d+h,r[1]=f*n+u,r[2]=f*o-s,r[3]=0,r[4]=f*n-u,r[5]=f*p*p+h,r[6]=f*i+a,r[7]=0,r[8]=f*o+s,r[9]=f*i-a,r[10]=f*m*m+h,r[11]=0,r[12]=0,r[13]=0,r[14]=0,r[15]=1,r},rotationMat4c:function(e,t,r,n,i){return k.rotationMat4v(e,[t,r,n],i)},scalingMat4v:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:k.identityMat4();return t[0]=e[0],t[5]=e[1],t[10]=e[2],t},scalingMat3v:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:k.identityMat3();return t[0]=e[0],t[4]=e[1],t},scalingMat4c:function(){var e=new E(3);return function(t,r,n,i){return e[0]=t,e[1]=r,e[2]=n,k.scalingMat4v(e,i)}}(),scaleMat4c:function(e,t,r,n){return n[0]*=e,n[4]*=t,n[8]*=r,n[1]*=e,n[5]*=t,n[9]*=r,n[2]*=e,n[6]*=t,n[10]*=r,n[3]*=e,n[7]*=t,n[11]*=r,n},scaleMat4v:function(e,t){var r=e[0],n=e[1],i=e[2];return t[0]*=r,t[4]*=n,t[8]*=i,t[1]*=r,t[5]*=n,t[9]*=i,t[2]*=r,t[6]*=n,t[10]*=i,t[3]*=r,t[7]*=n,t[11]*=i,t},scalingMat4s:function(e){return k.scalingMat4c(e,e,e)},rotationTranslationMat4:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:k.mat4(),n=e[0],i=e[1],o=e[2],a=e[3],s=n+n,u=i+i,c=o+o,l=n*s,h=n*u,f=n*c,d=i*u,p=i*c,m=o*c,v=a*s,y=a*u,g=a*c;return r[0]=1-(d+m),r[1]=h+g,r[2]=f-y,r[3]=0,r[4]=h-g,r[5]=1-(l+m),r[6]=p+v,r[7]=0,r[8]=f+y,r[9]=p-v,r[10]=1-(l+d),r[11]=0,r[12]=t[0],r[13]=t[1],r[14]=t[2],r[15]=1,r},mat4ToEuler:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:k.vec4(),n=k.clamp,i=e[0],o=e[4],a=e[8],s=e[1],u=e[5],c=e[9],l=e[2],h=e[6],f=e[10];return"XYZ"===t?(r[1]=Math.asin(n(a,-1,1)),Math.abs(a)<.99999?(r[0]=Math.atan2(-c,f),r[2]=Math.atan2(-o,i)):(r[0]=Math.atan2(h,u),r[2]=0)):"YXZ"===t?(r[0]=Math.asin(-n(c,-1,1)),Math.abs(c)<.99999?(r[1]=Math.atan2(a,f),r[2]=Math.atan2(s,u)):(r[1]=Math.atan2(-l,i),r[2]=0)):"ZXY"===t?(r[0]=Math.asin(n(h,-1,1)),Math.abs(h)<.99999?(r[1]=Math.atan2(-l,f),r[2]=Math.atan2(-o,u)):(r[1]=0,r[2]=Math.atan2(s,i))):"ZYX"===t?(r[1]=Math.asin(-n(l,-1,1)),Math.abs(l)<.99999?(r[0]=Math.atan2(h,f),r[2]=Math.atan2(s,i)):(r[0]=0,r[2]=Math.atan2(-o,u))):"YZX"===t?(r[2]=Math.asin(n(s,-1,1)),Math.abs(s)<.99999?(r[0]=Math.atan2(-c,u),r[1]=Math.atan2(-l,i)):(r[0]=0,r[1]=Math.atan2(a,f))):"XZY"===t&&(r[2]=Math.asin(-n(o,-1,1)),Math.abs(o)<.99999?(r[0]=Math.atan2(h,u),r[1]=Math.atan2(a,i)):(r[0]=Math.atan2(-c,f),r[1]=0)),r},composeMat4:function(e,t,r){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:k.mat4();return k.quaternionToRotationMat4(t,n),k.scaleMat4v(r,n),k.translateMat4v(e,n),n},decomposeMat4:function(){var e=new E(3),t=new E(16);return function(r,n,i,o){e[0]=r[0],e[1]=r[1],e[2]=r[2];var a=k.lenVec3(e);e[0]=r[4],e[1]=r[5],e[2]=r[6];var s=k.lenVec3(e);e[8]=r[8],e[9]=r[9],e[10]=r[10];var u=k.lenVec3(e);k.determinantMat4(r)<0&&(a=-a),n[0]=r[12],n[1]=r[13],n[2]=r[14],t.set(r);var c=1/a,l=1/s,h=1/u;return t[0]*=c,t[1]*=c,t[2]*=c,t[4]*=l,t[5]*=l,t[6]*=l,t[8]*=h,t[9]*=h,t[10]*=h,k.mat4ToQuaternion(t,i),o[0]=a,o[1]=s,o[2]=u,this}}(),lookAtMat4v:function(e,t,r,n){n||(n=k.mat4());var i,o,a,s,u,c,l,h,f,d,p=e[0],m=e[1],v=e[2],y=r[0],g=r[1],x=r[2],b=t[0],w=t[1],M=t[2];return p===b&&m===w&&v===M?k.identityMat4():(i=p-b,o=m-w,a=v-M,s=g*(a*=d=1/Math.sqrt(i*i+o*o+a*a))-x*(o*=d),u=x*(i*=d)-y*a,c=y*o-g*i,(d=Math.sqrt(s*s+u*u+c*c))?(s*=d=1/d,u*=d,c*=d):(s=0,u=0,c=0),l=o*c-a*u,h=a*s-i*c,f=i*u-o*s,(d=Math.sqrt(l*l+h*h+f*f))?(l*=d=1/d,h*=d,f*=d):(l=0,h=0,f=0),n[0]=s,n[1]=l,n[2]=i,n[3]=0,n[4]=u,n[5]=h,n[6]=o,n[7]=0,n[8]=c,n[9]=f,n[10]=a,n[11]=0,n[12]=-(s*p+u*m+c*v),n[13]=-(l*p+h*m+f*v),n[14]=-(i*p+o*m+a*v),n[15]=1,n)},lookAtMat4c:function(e,t,r,n,i,o,a,s,u){return k.lookAtMat4v([e,t,r],[n,i,o],[a,s,u],[])},orthoMat4c:function(e,t,r,n,i,o,a){a||(a=k.mat4());var s=t-e,u=n-r,c=o-i;return a[0]=2/s,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=2/u,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=-2/c,a[11]=0,a[12]=-(e+t)/s,a[13]=-(n+r)/u,a[14]=-(o+i)/c,a[15]=1,a},frustumMat4v:function(e,t,r){r||(r=k.mat4());var n=[e[0],e[1],e[2],0],i=[t[0],t[1],t[2],0];k.addVec4(i,n,j),k.subVec4(i,n,D);var o=2*n[2],a=D[0],s=D[1],u=D[2];return r[0]=o/a,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=o/s,r[6]=0,r[7]=0,r[8]=j[0]/a,r[9]=j[1]/s,r[10]=-j[2]/u,r[11]=-1,r[12]=0,r[13]=0,r[14]=-o*i[2]/u,r[15]=0,r},frustumMat4:function(e,t,r,n,i,o,a){a||(a=k.mat4());var s=t-e,u=n-r,c=o-i;return a[0]=2*i/s,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=2*i/u,a[6]=0,a[7]=0,a[8]=(t+e)/s,a[9]=(n+r)/u,a[10]=-(o+i)/c,a[11]=-1,a[12]=0,a[13]=0,a[14]=-o*i*2/c,a[15]=0,a},perspectiveMat4:function(e,t,r,n,i){var o=[],a=[];return o[2]=r,a[2]=n,a[1]=o[2]*Math.tan(e/2),o[1]=-a[1],a[0]=a[1]*t,o[0]=-a[0],k.frustumMat4v(o,a,i)},transformPoint3:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:k.vec3(),n=t[0],i=t[1],o=t[2];return r[0]=e[0]*n+e[4]*i+e[8]*o+e[12],r[1]=e[1]*n+e[5]*i+e[9]*o+e[13],r[2]=e[2]*n+e[6]*i+e[10]*o+e[14],r},transformPoint4:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:k.vec4();return r[0]=e[0]*t[0]+e[4]*t[1]+e[8]*t[2]+e[12]*t[3],r[1]=e[1]*t[0]+e[5]*t[1]+e[9]*t[2]+e[13]*t[3],r[2]=e[2]*t[0]+e[6]*t[1]+e[10]*t[2]+e[14]*t[3],r[3]=e[3]*t[0]+e[7]*t[1]+e[11]*t[2]+e[15]*t[3],r},transformPoints3:function(e,t,r){for(var n,i,o,a,s,u=r||[],c=t.length,l=e[0],h=e[1],f=e[2],d=e[3],p=e[4],m=e[5],v=e[6],y=e[7],g=e[8],x=e[9],b=e[10],w=e[11],M=e[12],T=e[13],I=e[14],S=e[15],A=0;A2&&void 0!==arguments[2]?arguments[2]:t,s=t.length,u=e[0],c=e[1],l=e[2],h=e[3],f=e[4],d=e[5],p=e[6],m=e[7],v=e[8],y=e[9],g=e[10],x=e[11],b=e[12],w=e[13],M=e[14],T=e[15];for(r=0;r2&&void 0!==arguments[2]?arguments[2]:t,s=t.length,u=e[0],c=e[1],l=e[2],h=e[3],f=e[4],d=e[5],p=e[6],m=e[7],v=e[8],y=e[9],g=e[10],x=e[11],b=e[12],w=e[13],M=e[14],T=e[15];for(r=0;r0&&void 0!==arguments[0]?arguments[0]:k.vec4();return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e},eulerToQuaternion:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:k.vec4(),n=e[0]*k.DEGTORAD/2,i=e[1]*k.DEGTORAD/2,o=e[2]*k.DEGTORAD/2,a=Math.cos(n),s=Math.cos(i),u=Math.cos(o),c=Math.sin(n),l=Math.sin(i),h=Math.sin(o);return"XYZ"===t?(r[0]=c*s*u+a*l*h,r[1]=a*l*u-c*s*h,r[2]=a*s*h+c*l*u,r[3]=a*s*u-c*l*h):"YXZ"===t?(r[0]=c*s*u+a*l*h,r[1]=a*l*u-c*s*h,r[2]=a*s*h-c*l*u,r[3]=a*s*u+c*l*h):"ZXY"===t?(r[0]=c*s*u-a*l*h,r[1]=a*l*u+c*s*h,r[2]=a*s*h+c*l*u,r[3]=a*s*u-c*l*h):"ZYX"===t?(r[0]=c*s*u-a*l*h,r[1]=a*l*u+c*s*h,r[2]=a*s*h-c*l*u,r[3]=a*s*u+c*l*h):"YZX"===t?(r[0]=c*s*u+a*l*h,r[1]=a*l*u+c*s*h,r[2]=a*s*h-c*l*u,r[3]=a*s*u-c*l*h):"XZY"===t&&(r[0]=c*s*u-a*l*h,r[1]=a*l*u-c*s*h,r[2]=a*s*h+c*l*u,r[3]=a*s*u+c*l*h),r},mat4ToQuaternion:function(e){var t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:k.vec4(),n=e[0],i=e[4],o=e[8],a=e[1],s=e[5],u=e[9],c=e[2],l=e[6],h=e[10],f=n+s+h;return f>0?(t=.5/Math.sqrt(f+1),r[3]=.25/t,r[0]=(l-u)*t,r[1]=(o-c)*t,r[2]=(a-i)*t):n>s&&n>h?(t=2*Math.sqrt(1+n-s-h),r[3]=(l-u)/t,r[0]=.25*t,r[1]=(i+a)/t,r[2]=(o+c)/t):s>h?(t=2*Math.sqrt(1+s-n-h),r[3]=(o-c)/t,r[0]=(i+a)/t,r[1]=.25*t,r[2]=(u+l)/t):(t=2*Math.sqrt(1+h-n-s),r[3]=(a-i)/t,r[0]=(o+c)/t,r[1]=(u+l)/t,r[2]=.25*t),r},vec3PairToQuaternion:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:k.vec4(),n=Math.sqrt(k.dotVec3(e,e)*k.dotVec3(t,t)),i=n+k.dotVec3(e,t);return i<1e-8*n?(i=0,Math.abs(e[0])>Math.abs(e[2])?(r[0]=-e[1],r[1]=e[0],r[2]=0):(r[0]=0,r[1]=-e[2],r[2]=e[1])):k.cross3Vec3(e,t,r),r[3]=i,k.normalizeQuaternion(r)},angleAxisToQuaternion:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:k.vec4(),r=e[3]/2,n=Math.sin(r);return t[0]=n*e[0],t[1]=n*e[1],t[2]=n*e[2],t[3]=Math.cos(r),t},quaternionToEuler:function(){var e=new E(16);return function(t,r,n){return n=n||k.vec3(),k.quaternionToRotationMat4(t,e),k.mat4ToEuler(e,r,n),n}}(),mulQuaternions:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:k.vec4(),n=e[0],i=e[1],o=e[2],a=e[3],s=t[0],u=t[1],c=t[2],l=t[3];return r[0]=a*s+n*l+i*c-o*u,r[1]=a*u+i*l+o*s-n*c,r[2]=a*c+o*l+n*u-i*s,r[3]=a*l-n*s-i*u-o*c,r},vec3ApplyQuaternion:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:k.vec3(),n=t[0],i=t[1],o=t[2],a=e[0],s=e[1],u=e[2],c=e[3],l=c*n+s*o-u*i,h=c*i+u*n-a*o,f=c*o+a*i-s*n,d=-a*n-s*i-u*o;return r[0]=l*c+d*-a+h*-u-f*-s,r[1]=h*c+d*-s+f*-a-l*-u,r[2]=f*c+d*-u+l*-s-h*-a,r},quaternionToMat4:function(e,t){t=k.identityMat4(t);var r=e[0],n=e[1],i=e[2],o=e[3],a=2*r,s=2*n,u=2*i,c=a*o,l=s*o,h=u*o,f=a*r,d=s*r,p=u*r,m=s*n,v=u*n,y=u*i;return t[0]=1-(m+y),t[1]=d+h,t[2]=p-l,t[4]=d-h,t[5]=1-(f+y),t[6]=v+c,t[8]=p+l,t[9]=v-c,t[10]=1-(f+m),t},quaternionToRotationMat4:function(e,t){var r=e[0],n=e[1],i=e[2],o=e[3],a=r+r,s=n+n,u=i+i,c=r*a,l=r*s,h=r*u,f=n*s,d=n*u,p=i*u,m=o*a,v=o*s,y=o*u;return t[0]=1-(f+p),t[4]=l-y,t[8]=h+v,t[1]=l+y,t[5]=1-(c+p),t[9]=d-m,t[2]=h-v,t[6]=d+m,t[10]=1-(c+f),t[3]=0,t[7]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},normalizeQuaternion:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:e,r=k.lenVec4([e[0],e[1],e[2],e[3]]);return t[0]=e[0]/r,t[1]=e[1]/r,t[2]=e[2]/r,t[3]=e[3]/r,t},conjugateQuaternion:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:e;return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=e[3],t},inverseQuaternion:function(e,t){return k.normalizeQuaternion(k.conjugateQuaternion(e,t))},quaternionToAngleAxis:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:k.vec4(),r=(e=k.normalizeQuaternion(e,G))[3],n=2*Math.acos(r),i=Math.sqrt(1-r*r);return i<.001?(t[0]=e[0],t[1]=e[1],t[2]=e[2]):(t[0]=e[0]/i,t[1]=e[1]/i,t[2]=e[2]/i),t[3]=n,t},AABB3:function(e){return new E(e||6)},AABB2:function(e){return new E(e||4)},OBB3:function(e){return new E(e||32)},OBB2:function(e){return new E(e||16)},Sphere3:function(e,t,r,n){return new E([e,t,r,n])},transformOBB3:function(e,t){var r,n,i,o,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t,s=t.length,u=e[0],c=e[1],l=e[2],h=e[3],f=e[4],d=e[5],p=e[6],m=e[7],v=e[8],y=e[9],g=e[10],x=e[11],b=e[12],w=e[13],M=e[14],T=e[15];for(r=0;rs?a:s,o[1]+=u>c?u:c,o[2]+=l>h?l:h,Math.abs(k.lenVec3(o))}}(),getAABB3Center:function(e,t){var r=t||k.vec3();return r[0]=(e[0]+e[3])/2,r[1]=(e[1]+e[4])/2,r[2]=(e[2]+e[5])/2,r},getAABB2Center:function(e,t){var r=t||k.vec2();return r[0]=(e[2]+e[0])/2,r[1]=(e[3]+e[1])/2,r},collapseAABB3:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:k.AABB3();return e[0]=k.MAX_DOUBLE,e[1]=k.MAX_DOUBLE,e[2]=k.MAX_DOUBLE,e[3]=-k.MAX_DOUBLE,e[4]=-k.MAX_DOUBLE,e[5]=-k.MAX_DOUBLE,e},AABB3ToOBB3:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:k.OBB3();return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=1,t[4]=e[3],t[5]=e[1],t[6]=e[2],t[7]=1,t[8]=e[3],t[9]=e[4],t[10]=e[2],t[11]=1,t[12]=e[0],t[13]=e[4],t[14]=e[2],t[15]=1,t[16]=e[0],t[17]=e[1],t[18]=e[5],t[19]=1,t[20]=e[3],t[21]=e[1],t[22]=e[5],t[23]=1,t[24]=e[3],t[25]=e[4],t[26]=e[5],t[27]=1,t[28]=e[0],t[29]=e[4],t[30]=e[5],t[31]=1,t},positions3ToAABB3:(t=new E(3),function(e,r,n){r=r||k.AABB3();for(var i,o,a,s=k.MAX_DOUBLE,u=k.MAX_DOUBLE,c=k.MAX_DOUBLE,l=-k.MAX_DOUBLE,h=-k.MAX_DOUBLE,f=-k.MAX_DOUBLE,d=0,p=e.length;dl&&(l=i),o>h&&(h=o),a>f&&(f=a);return r[0]=s,r[1]=u,r[2]=c,r[3]=l,r[4]=h,r[5]=f,r}),OBB3ToAABB3:function(e){for(var t,r,n,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:k.AABB3(),o=k.MAX_DOUBLE,a=k.MAX_DOUBLE,s=k.MAX_DOUBLE,u=-k.MAX_DOUBLE,c=-k.MAX_DOUBLE,l=-k.MAX_DOUBLE,h=0,f=e.length;hu&&(u=t),r>c&&(c=r),n>l&&(l=n);return i[0]=o,i[1]=a,i[2]=s,i[3]=u,i[4]=c,i[5]=l,i},points3ToAABB3:function(e){for(var t,r,n,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:k.AABB3(),o=k.MAX_DOUBLE,a=k.MAX_DOUBLE,s=k.MAX_DOUBLE,u=-k.MAX_DOUBLE,c=-k.MAX_DOUBLE,l=-k.MAX_DOUBLE,h=0,f=e.length;hu&&(u=t),r>c&&(c=r),n>l&&(l=n);return i[0]=o,i[1]=a,i[2]=s,i[3]=u,i[4]=c,i[5]=l,i},points3ToSphere3:function(){var e=new E(3);return function(t,r){r=r||k.vec4();var n,i=0,o=0,a=0,s=t.length;for(n=0;nc&&(c=u);return r[3]=c,r}}(),positions3ToSphere3:function(){var e=new E(3),t=new E(3);return function(r,n){n=n||k.vec4();var i,o=0,a=0,s=0,u=r.length,c=0;for(i=0;ic&&(c=l);return n[3]=c,n}}(),OBB3ToSphere3:function(){var e=new E(3),t=new E(3);return function(r,n){n=n||k.vec4();var i,o=0,a=0,s=0,u=r.length,c=u/4;for(i=0;ih&&(h=l);return n[3]=h,n}}(),getSphere3Center:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:k.vec3();return t[0]=e[0],t[1]=e[1],t[2]=e[2],t},expandAABB3:function(e,t){return e[0]>t[0]&&(e[0]=t[0]),e[1]>t[1]&&(e[1]=t[1]),e[2]>t[2]&&(e[2]=t[2]),e[3]t[0]&&(e[0]=t[0]),e[1]>t[1]&&(e[1]=t[1]),e[2]>t[2]&&(e[2]=t[2]),e[3]3&&void 0!==arguments[3]?arguments[3]:k.vec3(),i=t[0]-e[0],o=t[1]-e[1],a=t[2]-e[2],s=r[0]-e[0],u=r[1]-e[1],c=r[2]-e[2],l=o*c-a*u,h=a*s-i*c,f=i*u-o*s,d=Math.sqrt(l*l+h*h+f*f);return 0===d?(n[0]=0,n[1]=0,n[2]=0):(n[0]=l/d,n[1]=h/d,n[2]=f/d),n}};function _(e,t,r,n){var i=e[t]/(Math.abs(e[t])+Math.abs(e[t+1])+Math.abs(e[t+2])),o=e[t+1]/(Math.abs(e[t])+Math.abs(e[t+1])+Math.abs(e[t+2]));if(e[t+2]<0){var a=(1-Math.abs(o))*(i>=0?1:-1),s=(1-Math.abs(i))*(o>=0?1:-1);i=a,o=s}return new Int8Array([Math[r](127.5*i+(i<0?-1:0)),Math[n](127.5*o+(o<0?-1:0))])}function F(e){var t=e[0],r=e[1];t/=t<0?127:128,r/=r<0?127:128;var n=1-Math.abs(t)-Math.abs(r);n<0&&(t=(1-Math.abs(r))*(t>=0?1:-1),r=(1-Math.abs(t))*(r>=0?1:-1));var i=Math.sqrt(t*t+r*r+n*n);return[t/i,r/i,n/i]}function N(e,t,r){return e[t]*r[0]+e[t+1]*r[1]+e[t+2]*r[2]}var V,B,C,z,U,X,R,K,q,Z,Y,W,Q,J,H,$,ee,te={quantizePositions:function(e,t,r,n){for(var i=r[0],o=r[1],a=r[2],s=65535,u=s/(r[3]-i),c=s/(r[4]-o),l=s/(r[5]-a),h=function(e){return e>=0?e:0},f=0;fu&&(a=o,u=s),(s=N(h,0,F(o=_(h,0,"floor","ceil"))))>u&&(a=o,u=s),(s=N(h,0,F(o=_(h,0,"ceil","ceil"))))>u&&(a=o,u=s),n[i+c+0]=a[0],n[i+c+1]=a[1],n[i+c+2]=0;return i+r},octEncodeNormals:function(e,t,r,n){for(var i,o,a,s,u=0;us&&(o=i,s=a),(a=N(e,u,F(i=_(e,u,"floor","ceil"))))>s&&(o=i,s=a),(a=N(e,u,F(i=_(e,u,"ceil","ceil"))))>s&&(o=i,s=a),r[n+u+0]=o[0],r[n+u+1]=o[1],r[n+u+2]=0;return n+t}},re=(V=[],B=[],C=[],z=[],U=[],X=0,R=new Uint16Array(3),K=new Uint16Array(3),q=new Uint16Array(3),Z=k.vec3(),Y=k.vec3(),W=k.vec3(),Q=k.vec3(),J=k.vec3(),H=k.vec3(),$=k.vec3(),ee=k.vec3(),function(e,t,r,n){!function(e,t){var r,n,i,o,a,s,u={},c=Math.pow(10,4),l=0;for(a=0,s=e.length;av&&T>v)continue}d=C[c.index1],p=C[c.index2],(!g&&d>65535||p>65535)&&(g=!0),m.push(d),m.push(p)}return g?new Uint32Array(m):new Uint16Array(m)}),ne=function(e,t,r,n){function i(e,r){for(var n,i,o=0;o<3;o++)if((n=t[3*e+o])!==(i=t[3*r+o]))return i-n;return 0}for(var o=e.slice().sort(i),a=null,s=0,u=o.length;sf&&h>d?f>d?(p=h,m=f,v=d):(p=h,m=d,v=f):f>h&&f>d?h>d?(p=f,m=h,v=d):(p=f,m=d,v=h):d>h&&d>f&&(h>f?(p=d,m=h,v=f):(p=d,m=f,v=h)),n[c+0]=[p,m],n[c+1]=[m,v],p>v){var y=v;v=p,p=y}n[c+2]=[v,p]}function g(e,t){for(var r,n,i=0;i<2;i++)if(r=e[i],(n=t[i])!==r)return n-r;return 0}(n=n.slice(0,e.length)).sort(g);for(var x=0,b=0;b0&&2!==x)};function ie(e){return ie="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ie(e)}function oe(e,t){for(var r=0;r1}}])&&ce(t.prototype,r),Object.defineProperty(t,"prototype",{writable:!1}),e}();function he(e){return he="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},he(e)}function fe(e,t){for(var r=0;r=0;--i){var o=this.tryEntries[i],a=o.completion;if("root"===o.tryLoc)return n("end");if(o.tryLoc<=this.prev){var s=r.call(o,"catchLoc"),u=r.call(o,"finallyLoc");if(s&&u){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),I(r),h}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var i=n.arg;I(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,r){return this.delegate={iterator:A(e),resultName:t,nextLoc:r},"next"===this.method&&(this.arg=void 0),h}},e}function Re(e,t,r,n,i,o,a){try{var s=e[o](a),u=s.value}catch(e){return void r(e)}s.done?t(u):Promise.resolve(u).then(n,i)}function Ke(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.modelId=t.modelId||"default",this.projectId=t.projectId||"",this.revisionId=t.revisionId||"",this.author=t.author||"",this.createdAt=t.createdAt||"",this.creatingApplication=t.creatingApplication||"",this.schema=t.schema||"",this.xktVersion=f.xktVersion,this.edgeThreshold=t.edgeThreshold||10,this.minTileSize=t.minTileSize||500,this.modelAABB=t.modelAABB,this.propertySets={},this.propertySetsList=[],this.metaObjects={},this.metaObjectsList=[],this.reusedGeometriesDecodeMatrix=new Float32Array(16),this.geometries={},this.geometriesList=[],this.textures={},this.texturesList=[],this.textureSets={},this.textureSetsList=[],this.meshes={},this.meshesList=[],this.entities={},this.entitiesList=[],this.tilesList=[],this.aabb=k.AABB3(),this.finalized=!1}var t,r,n,i;return t=e,r=[{key:"createPropertySet",value:function(e){if(!e)throw"Parameters expected: params";if(null===e.propertySetId||void 0===e.propertySetId)throw"Parameter expected: params.propertySetId";if(null===e.properties||void 0===e.properties)throw"Parameter expected: params.properties";if(this.finalized)console.error("XKTModel has been finalized, can't add more property sets");else if(!this.propertySets[e.propertySetId]){var t=e.propertySetId,r=e.propertySetType||"Default",n=e.propertySetName||e.propertySetId,i=e.properties||[],o=new Ee(t,r,n,i);return this.propertySets[t]=o,this.propertySetsList.push(o),o}}},{key:"createMetaObject",value:function(e){if(!e)throw"Parameters expected: params";if(null===e.metaObjectId||void 0===e.metaObjectId)throw"Parameter expected: params.metaObjectId";if(this.finalized)console.error("XKTModel has been finalized, can't add more meta objects");else if(!this.metaObjects[e.metaObjectId]){var t=e.metaObjectId,r=e.propertySetIds,n=e.metaObjectType||"Default",i=e.metaObjectName||e.metaObjectId,o=e.parentMetaObjectId,a=new Ae(t,r,n,i,o);return this.metaObjects[t]=a,this.metaObjectsList.push(a),o||this._rootMetaObject||(this._rootMetaObject=a),a}}},{key:"createTexture",value:function(e){if(!e)throw"Parameters expected: params";if(null===e.textureId||void 0===e.textureId)throw"Parameter expected: params.textureId";if(!e.imageData&&!e.src)throw"Parameter expected: params.imageData or params.src";if(this.finalized)console.error("XKTModel has been finalized, can't add more textures");else{if(!this.textures[e.textureId]){if(e.src){var t=e.src.split(".").pop();if("jpg"!==t&&"jpeg"!==t&&"png"!==t)return void console.error("XKTModel does not support image files with extension '".concat(t,"' - won't create texture '").concat(e.textureId))}var r=e.textureId,n=new ke({textureId:r,imageData:e.imageData,mediaType:e.mediaType,minFilter:e.minFilter,magFilter:e.magFilter,wrapS:e.wrapS,wrapT:e.wrapT,wrapR:e.wrapR,width:e.width,height:e.height,compressed:!1!==e.compressed,src:e.src});return this.textures[r]=n,this.texturesList.push(n),n}console.error("XKTTexture already exists with this ID: "+e.textureId)}}},{key:"createTextureSet",value:function(e){if(!e)throw"Parameters expected: params";if(null===e.textureSetId||void 0===e.textureSetId)throw"Parameter expected: params.textureSetId";if(this.finalized)console.error("XKTModel has been finalized, can't add more textureSets");else{if(!this.textureSets[e.textureSetId]){var t,r,n,i,o;if(void 0!==e.colorTextureId&&null!==e.colorTextureId){if(!(t=this.textures[e.colorTextureId]))return void console.error("Texture not found: ".concat(e.colorTextureId," - ensure that you create it first with createTexture()"));t.channel=0}if(void 0!==e.metallicRoughnessTextureId&&null!==e.metallicRoughnessTextureId){if(!(r=this.textures[e.metallicRoughnessTextureId]))return void console.error("Texture not found: ".concat(e.metallicRoughnessTextureId," - ensure that you create it first with createTexture()"));r.channel=1}if(void 0!==e.normalsTextureId&&null!==e.normalsTextureId){if(!(n=this.textures[e.normalsTextureId]))return void console.error("Texture not found: ".concat(e.normalsTextureId," - ensure that you create it first with createTexture()"));n.channel=2}if(void 0!==e.emissiveTextureId&&null!==e.emissiveTextureId){if(!(i=this.textures[e.emissiveTextureId]))return void console.error("Texture not found: ".concat(e.emissiveTextureId," - ensure that you create it first with createTexture()"));i.channel=3}if(void 0!==e.occlusionTextureId&&null!==e.occlusionTextureId){if(!(o=this.textures[e.occlusionTextureId]))return void console.error("Texture not found: ".concat(e.occlusionTextureId," - ensure that you create it first with createTexture()"));o.channel=4}var a=new Ve({textureSetId:e.textureSetId,textureSetIndex:this.textureSetsList.length,colorTexture:t,metallicRoughnessTexture:r,normalsTexture:n,emissiveTexture:i,occlusionTexture:o});return this.textureSets[e.textureSetId]=a,this.textureSetsList.push(a),a}console.error("XKTTextureSet already exists with this ID: "+e.textureSetId)}}},{key:"createGeometry",value:function(e){if(!e)throw"Parameters expected: params";if(null===e.geometryId||void 0===e.geometryId)throw"Parameter expected: params.geometryId";if(!e.primitiveType)throw"Parameter expected: params.primitiveType";if(!e.positions)throw"Parameter expected: params.positions";var t="triangles"===e.primitiveType,r="points"===e.primitiveType,n="lines"===e.primitiveType,i="line-strip"===e.primitiveType,o="line-loop"===e.primitiveType;if(e.primitiveType,e.primitiveType,!(t||r||n||i||o))throw"Unsupported value for params.primitiveType: "+e.primitiveType+"' - supported values are 'triangles', 'points', 'lines', 'line-strip', 'triangle-strip' and 'triangle-fan";if(t&&!e.indices)throw e.indices=this._createDefaultIndices(),"Parameter expected for 'triangles' primitive: params.indices";if(r&&!e.colors&&!e.colorsCompressed)throw"Parameter expected for 'points' primitive: params.colors or params.colorsCompressed";if(n&&!e.indices)throw"Parameter expected for 'lines' primitive: params.indices";if(this.finalized)console.error("XKTModel has been finalized, can't add more geometries");else{if(!this.geometries[e.geometryId]){var a=e.geometryId,s=e.primitiveType,u=new Float64Array(e.positions),c={geometryId:a,geometryIndex:this.geometriesList.length,primitiveType:s,positions:u,uvs:e.uvs||e.uv};if(t&&(e.normals&&(c.normals=new Float32Array(e.normals)),e.indices?c.indices=e.indices:c.indices=this._createDefaultIndices(u.length/3)),r)if(e.colorsCompressed)c.colorsCompressed=new Uint8Array(e.colorsCompressed);else{for(var l=e.colors,h=new Uint8Array(l.length),f=0,d=l.length;f1)te.octEncodeNormals(n.normals,n.normals.length,n.normalsOctEncoded,0);else{var i=k.inverseMat4(k.transposeMat4(r.matrix,Ye),We);te.transformAndOctEncodeNormals(i,n.normals,n.normals.length,n.normalsOctEncoded,0)}}}},{key:"_createEntityAABBs",value:function(){for(var e=0,t=this.entitiesList.length;e1)for(var l=u.positions,h=0,f=l.length;hQe[i]&&(i=1),Qe[2]>Qe[i]&&(i=2),!e.left){var o=r.slice();if(o[i+3]=(r[i]+r[i+3])/2,e.left=new Me(o),k.containsAABB3(o,n))return void this._insertEntityIntoKDTree(e.left,t)}if(!e.right){var a=r.slice();if(a[i]=(r[i]+r[i+3])/2,e.right=new Me(a),k.containsAABB3(a,n))return void this._insertEntityIntoKDTree(e.right,t)}e.entities=e.entities||[],e.entities.push(t),k.expandAABB3(r,n)}}},{key:"_createTilesFromKDTree",value:function(e){this._createTilesFromKDNode(e)}},{key:"_createTilesFromKDNode",value:function(e){e.entities&&e.entities.length>0&&this._createTileFromEntities(e),e.left&&this._createTilesFromKDNode(e.left),e.right&&this._createTilesFromKDNode(e.right)}},{key:"_createTileFromEntities",value:function(e){var t=e.aabb,r=e.entities,n=k.getAABB3Center(t),i=k.mulVec3Scalar(n,-1,k.vec3()),o=k.AABB3();o[0]=t[0]-n[0],o[1]=t[1]-n[1],o[2]=t[2]-n[2],o[3]=t[3]-n[0],o[4]=t[4]-n[1],o[5]=t[5]-n[2];for(var a=0;a0){te.createPositionsDecodeMatrix(t,this.reusedGeometriesDecodeMatrix);for(var c=0,l=this.geometriesList.length;ce&&(e=i.positionsQuantized.length),i.indices.length>t&&(t=i.indices.length))}for(var o=new Array(e/3),a=new Array(t),s=0,u=this.geometriesList.length;s1&&(S+=16);var D={metadata:{},textureData:new Uint8Array(A),eachTextureDataPortion:new Uint32Array(p),eachTextureAttributes:new Uint16Array(p*tt),positions:new Uint16Array(x),normals:new Int8Array(b),colors:new Uint8Array(w),uvs:new Float32Array(M),indices:new Uint32Array(T),edgeIndices:new Uint32Array(I),eachTextureSetTextures:new Int32Array(5*m),matrices:new Float32Array(S),reusedGeometriesDecodeMatrix:new Float32Array(e.reusedGeometriesDecodeMatrix),eachGeometryPrimitiveType:new Uint8Array(d),eachGeometryPositionsPortion:new Uint32Array(d),eachGeometryNormalsPortion:new Uint32Array(d),eachGeometryColorsPortion:new Uint32Array(d),eachGeometryUVsPortion:new Uint32Array(d),eachGeometryIndicesPortion:new Uint32Array(d),eachGeometryEdgeIndicesPortion:new Uint32Array(d),eachMeshGeometriesPortion:new Uint32Array(v),eachMeshMatricesPortion:new Uint32Array(v),eachMeshTextureSet:new Int32Array(v),eachMeshMaterialAttributes:new Uint8Array(v*rt),eachEntityId:[],eachEntityMeshesPortion:new Uint32Array(y),eachTileAABB:new Float64Array(6*g),eachTileEntitiesPortion:new Uint32Array(g)},G=0,k=0,_=0,F=0,N=0,V=0;D.metadata={id:e.modelId,projectId:e.projectId,revisionId:e.revisionId,author:e.author,createdAt:e.createdAt,creatingApplication:e.creatingApplication,schema:e.schema,propertySets:[],metaObjects:[]};for(var B=0;B0&&(R.propertySetIds=X.propertySetIds),X.external&&(R.external=X.external),D.metadata.metaObjects.push(R)}for(var K=0;K1&&(D.matrices.set(xe.matrix,se),D.eachMeshMatricesPortion[ue]=se,se+=16),D.eachMeshTextureSet[ue]=xe.textureSet?xe.textureSet.textureSetIndex:-1,D.eachMeshMaterialAttributes[ae++]=255*xe.color[0],D.eachMeshMaterialAttributes[ae++]=255*xe.color[1],D.eachMeshMaterialAttributes[ae++]=255*xe.color[2],D.eachMeshMaterialAttributes[ae++]=255*xe.opacity,D.eachMeshMaterialAttributes[ae++]=255*xe.metallic,D.eachMeshMaterialAttributes[ae++]=255*xe.roughness,ue++}D.eachEntityId[ie]=me.entityId,D.eachEntityMeshesPortion[ie]=oe,ie++,oe+=ye}var we=6*ce;D.eachTileAABB.set(de,we)}}return D}(e,t,r),o=function(e,t,r){function n(e){return!1!==r.zip?$e.deflate(e):e}return{metadata:n(it(t||e.metadata)),textureData:n(e.textureData.buffer),eachTextureDataPortion:n(e.eachTextureDataPortion.buffer),eachTextureAttributes:n(e.eachTextureAttributes.buffer),positions:n(e.positions.buffer),normals:n(e.normals.buffer),colors:n(e.colors.buffer),uvs:n(e.uvs.buffer),indices:n(e.indices.buffer),edgeIndices:n(e.edgeIndices.buffer),eachTextureSetTextures:n(e.eachTextureSetTextures.buffer),matrices:n(e.matrices.buffer),reusedGeometriesDecodeMatrix:n(e.reusedGeometriesDecodeMatrix.buffer),eachGeometryPrimitiveType:n(e.eachGeometryPrimitiveType.buffer),eachGeometryPositionsPortion:n(e.eachGeometryPositionsPortion.buffer),eachGeometryNormalsPortion:n(e.eachGeometryNormalsPortion.buffer),eachGeometryColorsPortion:n(e.eachGeometryColorsPortion.buffer),eachGeometryUVsPortion:n(e.eachGeometryUVsPortion.buffer),eachGeometryIndicesPortion:n(e.eachGeometryIndicesPortion.buffer),eachGeometryEdgeIndicesPortion:n(e.eachGeometryEdgeIndicesPortion.buffer),eachMeshGeometriesPortion:n(e.eachMeshGeometriesPortion.buffer),eachMeshMatricesPortion:n(e.eachMeshMatricesPortion.buffer),eachMeshTextureSet:n(e.eachMeshTextureSet.buffer),eachMeshMaterialAttributes:n(e.eachMeshMaterialAttributes.buffer),eachEntityId:n(JSON.stringify(e.eachEntityId).replace(/[\u007F-\uFFFF]/g,(function(e){return"\\u"+("0000"+e.charCodeAt(0).toString(16)).substr(-4)}))),eachEntityMeshesPortion:n(e.eachEntityMeshesPortion.buffer),eachTileAABB:n(e.eachTileAABB.buffer),eachTileEntitiesPortion:n(e.eachTileEntitiesPortion.buffer)}}(i,t,n);r.texturesSize+=o.textureData.byteLength;var a=function(e){return function(e){var t=new Uint32Array(e.length+2);t[0]=et,t[1]=e.length;for(var r=0,n=0,i=e.length;n80*r){n=o=e[0],i=a=e[1];for(var p=r;po&&(o=s),u>a&&(a=u);c=0!==(c=Math.max(o-n,a-i))?1/c:0}return ut(f,d,r,n,i,c),d}function at(e,t,r,n,i){var o,a;if(i===Et(e,t,r,n)>0)for(o=t;o=t;o-=n)a=Ot(o,e[o],e[o+1],a);return a&&wt(a,a.next)&&(Pt(a),a=a.next),a}function st(e,t){if(!e)return e;t||(t=e);var r,n=e;do{if(r=!1,n.steiner||!wt(n,n.next)&&0!==bt(n.prev,n,n.next))n=n.next;else{if(Pt(n),(n=t=n.prev)===n.next)break;r=!0}}while(r||n!==t);return t}function ut(e,t,r,n,i,o,a){if(e){!a&&o&&function(e,t,r,n){var i=e;do{null===i.z&&(i.z=vt(i.x,i.y,t,r,n)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,function(e){var t,r,n,i,o,a,s,u,c=1;do{for(r=e,e=null,o=null,a=0;r;){for(a++,n=r,s=0,t=0;t0||u>0&&n;)0!==s&&(0===u||!n||r.z<=n.z)?(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,u--),o?o.nextZ=i:e=i,i.prevZ=o,o=i;r=n}o.nextZ=null,c*=2}while(a>1)}(i)}(e,n,i,o);for(var s,u,c=e;e.prev!==e.next;)if(s=e.prev,u=e.next,o?lt(e,n,i,o):ct(e))t.push(s.i/r),t.push(e.i/r),t.push(u.i/r),Pt(e),e=u.next,c=u.next;else if((e=u)===c){a?1===a?ut(e=ht(st(e),t,r),t,r,n,i,o,2):2===a&&ft(e,t,r,n,i,o):ut(st(e),t,r,n,i,o,1);break}}}function ct(e){var t=e.prev,r=e,n=e.next;if(bt(t,r,n)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(gt(t.x,t.y,r.x,r.y,n.x,n.y,i.x,i.y)&&bt(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function lt(e,t,r,n){var i=e.prev,o=e,a=e.next;if(bt(i,o,a)>=0)return!1;for(var s=i.xo.x?i.x>a.x?i.x:a.x:o.x>a.x?o.x:a.x,l=i.y>o.y?i.y>a.y?i.y:a.y:o.y>a.y?o.y:a.y,h=vt(s,u,t,r,n),f=vt(c,l,t,r,n),d=e.prevZ,p=e.nextZ;d&&d.z>=h&&p&&p.z<=f;){if(d!==e.prev&&d!==e.next&>(i.x,i.y,o.x,o.y,a.x,a.y,d.x,d.y)&&bt(d.prev,d,d.next)>=0)return!1;if(d=d.prevZ,p!==e.prev&&p!==e.next&>(i.x,i.y,o.x,o.y,a.x,a.y,p.x,p.y)&&bt(p.prev,p,p.next)>=0)return!1;p=p.nextZ}for(;d&&d.z>=h;){if(d!==e.prev&&d!==e.next&>(i.x,i.y,o.x,o.y,a.x,a.y,d.x,d.y)&&bt(d.prev,d,d.next)>=0)return!1;d=d.prevZ}for(;p&&p.z<=f;){if(p!==e.prev&&p!==e.next&>(i.x,i.y,o.x,o.y,a.x,a.y,p.x,p.y)&&bt(p.prev,p,p.next)>=0)return!1;p=p.nextZ}return!0}function ht(e,t,r){var n=e;do{var i=n.prev,o=n.next.next;!wt(i,o)&&Mt(i,n,n.next,o)&&St(i,o)&&St(o,i)&&(t.push(i.i/r),t.push(n.i/r),t.push(o.i/r),Pt(n),Pt(n.next),n=e=o),n=n.next}while(n!==e);return st(n)}function ft(e,t,r,n,i,o){var a=e;do{for(var s=a.next.next;s!==a.prev;){if(a.i!==s.i&&xt(a,s)){var u=At(a,s);return a=st(a,a.next),u=st(u,u.next),ut(a,t,r,n,i,o),void ut(u,t,r,n,i,o)}s=s.next}a=a.next}while(a!==e)}function dt(e,t){return e.x-t.x}function pt(e,t){if(t=function(e,t){var r,n=t,i=e.x,o=e.y,a=-1/0;do{if(o<=n.y&&o>=n.next.y&&n.next.y!==n.y){var s=n.x+(o-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(s<=i&&s>a){if(a=s,s===i){if(o===n.y)return n;if(o===n.next.y)return n.next}r=n.x=n.x&&n.x>=l&&i!==n.x&>(or.x||n.x===r.x&&mt(r,n)))&&(r=n,f=u)),n=n.next}while(n!==c);return r}(e,t),t){var r=At(t,e);st(t,t.next),st(r,r.next)}}function mt(e,t){return bt(e.prev,e,t.prev)<0&&bt(t.next,e,e.next)<0}function vt(e,t,r,n,i){return(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=32767*(e-r)*i)|e<<8))|e<<4))|e<<2))|e<<1))|(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=32767*(t-n)*i)|t<<8))|t<<4))|t<<2))|t<<1))<<1}function yt(e){var t=e,r=e;do{(t.x=0&&(e-a)*(n-s)-(r-a)*(t-s)>=0&&(r-a)*(o-s)-(i-a)*(n-s)>=0}function xt(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!function(e,t){var r=e;do{if(r.i!==e.i&&r.next.i!==e.i&&r.i!==t.i&&r.next.i!==t.i&&Mt(r,r.next,e,t))return!0;r=r.next}while(r!==e);return!1}(e,t)&&(St(e,t)&&St(t,e)&&function(e,t){var r=e,n=!1,i=(e.x+t.x)/2,o=(e.y+t.y)/2;do{r.y>o!=r.next.y>o&&r.next.y!==r.y&&i<(r.next.x-r.x)*(o-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next}while(r!==e);return n}(e,t)&&(bt(e.prev,e,t.prev)||bt(e,t.prev,t))||wt(e,t)&&bt(e.prev,e,e.next)>0&&bt(t.prev,t,t.next)>0)}function bt(e,t,r){return(t.y-e.y)*(r.x-t.x)-(t.x-e.x)*(r.y-t.y)}function wt(e,t){return e.x===t.x&&e.y===t.y}function Mt(e,t,r,n){var i=It(bt(e,t,r)),o=It(bt(e,t,n)),a=It(bt(r,n,e)),s=It(bt(r,n,t));return i!==o&&a!==s||!(0!==i||!Tt(e,r,t))||!(0!==o||!Tt(e,n,t))||!(0!==a||!Tt(r,e,n))||!(0!==s||!Tt(r,t,n))}function Tt(e,t,r){return t.x<=Math.max(e.x,r.x)&&t.x>=Math.min(e.x,r.x)&&t.y<=Math.max(e.y,r.y)&&t.y>=Math.min(e.y,r.y)}function It(e){return e>0?1:e<0?-1:0}function St(e,t){return bt(e.prev,e,e.next)<0?bt(e,t,e.next)>=0&&bt(e,e.prev,t)>=0:bt(e,t,e.prev)<0||bt(e,e.next,t)<0}function At(e,t){var r=new Lt(e.i,e.x,e.y),n=new Lt(t.i,t.x,t.y),i=e.next,o=t.prev;return e.next=t,t.prev=e,r.next=i,i.prev=r,n.next=r,r.prev=n,o.next=n,n.prev=o,n}function Ot(e,t,r,n){var i=new Lt(e,t,r);return n?(i.next=n.next,i.prev=n,n.next.prev=i,n.next=i):(i.prev=i,i.next=i),i}function Pt(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function Lt(e,t,r){this.i=e,this.x=t,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function Et(e,t,r,n){for(var i=0,o=t,a=r-n;oe.length)&&(t=e.length);for(var r=0,n=new Array(t);r0&&(n+=e[i-1].length,r.holes.push(n))}return r};var Gt=k.vec2(),kt=k.vec3(),_t=k.vec3(),Ft=k.vec3();function Nt(e){var t=e.data,r=e.xktModel,n=e.center,i=void 0!==n&&n,o=e.transform,a=void 0===o?null:o,s=e.stats,u=void 0===s?{}:s,c=e.log;return new Promise((function(e,n){if(t)if("CityJSON"===t.type)if(r){var o;c("Using parser: parseCityJSONIntoXKTModel"),c("center: ".concat(i)),a&&c("transform: [".concat(a,"]")),t.transform||i||a?(o=function(e){for(var t=[],r=0,n=0;r0){for(var c=[],l=0,h=t.geometry.length;l0){var x=y[g[0]];if(void 0!==x.value)d=v[x.value];else{var b=x.values;if(b){p=[];for(var w=0,M=b.length;w0&&(n.createEntity({entityId:r,meshIds:c}),e.stats.numObjects++)}}function Ct(e,t,r,n){switch(t.type){case"MultiPoint":case"MultiLineString":case"GeometryInstance":break;case"MultiSurface":case"CompositeSurface":zt(e,r,t.boundaries,n);break;case"Solid":for(var i=t.boundaries,o=0;o0&&l.push(c.length);var p=Rt(e,s[d],h,f);c.push.apply(c,jt(p))}if(3===c.length)f.indices.push(c[0]),f.indices.push(c[1]),f.indices.push(c[2]);else if(c.length>3){for(var m=[],v=0;v0&&s.push(a.length);var c=Rt(e,t[o][u],r,n);a.push.apply(a,jt(c))}if(3===a.length)n.indices.push(a[0]),n.indices.push(a[1]),n.indices.push(a[2]);else if(a.length>3){for(var l=[],h=0;h0)for(var c=0;c0&&o.createEntity({entityId:b,meshIds:w}),e.stats.numObjects++,rr=tr.length>0?tr[tr.length-1]:null}}var ir="undefined"!=typeof atob?atob:function(e){return Buffer.from(e,"base64").toString("binary")},or={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},ar={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16};function sr(e){var t=e.data,r=e.xktModel,n=e.metaModelData,i=e.includeNormals,o=e.reuseGeometries,a=e.getAttachment,s=e.stats,u=void 0===s?{}:s,c=e.log;return c&&c("Using parser: parseGLTFJSONIntoXKTModel"),new Promise((function(e,s){if(t)if(r){u.sourceFormat="glTF",u.schemaVersion="2.0",u.title="",u.author="",u.created="",u.numTriangles=0,u.numVertices=0,u.numNormals=0,u.numObjects=0,u.numGeometries=0;var l={gltf:t,metaModelCorrections:n?ur(n):null,getAttachment:a||function(){throw new Error("You must define getAttachment() method to convert glTF with external resources")},log:c||function(e){},xktModel:r,includeNormals:i,createXKTGeometryIds:{},nextMeshId:0,reuseGeometries:!1!==o,stats:u};l.log("Parsing normals: ".concat(l.includeNormals?"enabled":"disabled")),function(e){var t=e.gltf.buffers;return t?Promise.all(t.map((function(t){return function(e,t){return new Promise((function(r,n){if(t._arrayBuffer)return t._buffer=t._arrayBuffer,void r(t);var i=t.uri;i?function(e,t){return new Promise((function(r,n){var i=t.match(/^data:(.*?)(;base64)?,(.*)$/);if(i){var o=!!i[2],a=i[3];a=decodeURIComponent(a),o&&(a=ir(a));for(var s=new ArrayBuffer(a.length),u=new Uint8Array(s),c=0;c0)for(var l=0;l0){null==j&&e.log("[parseGLTFJSONIntoXKTModel] Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT");var D=j;if(null==D)for(a.entities[D]&&e.error("Two or more glTF nodes found with same 'name' attribute: '"+j+"'");!D||a.entities[D];)D="entity-"+e.nextId++;if(e.metaModelCorrections){var G=e.metaModelCorrections.eachChildRoot[D];if(G){var _=e.metaModelCorrections.eachRootStats[G.id];_.countChildren++,_.countChildren>=_.numChildren&&(a.createEntity({entityId:G.id,meshIds:hr}),e.stats.numObjects++,hr=[])}else e.metaModelCorrections.metaObjectsMap[D]&&(a.createEntity({entityId:D,meshIds:hr}),e.stats.numObjects++,hr=[])}else a.createEntity({entityId:D,meshIds:hr}),e.stats.numObjects++,hr=[]}}function dr(e){if(!e.attributes)return"empty";var t=e.mode,r=(e.material,e.indices),n=e.attributes.POSITION,i=e.attributes.NORMAL,o=e.attributes.COLOR_0,a=e.attributes.TEXCOORD_0;return[t,null!=r?r:"-",null!=n?n:"-",null!=i?i:"-",null!=o?o:"-",null!=a?a:"-"].join(";")}function pr(e,t,r){var n=t.attributes;if(n){switch(t.mode){case 0:r.primitive="points";break;case 1:case 2:case 3:r.primitive="lines";break;case 4:default:r.primitive="triangles";break;case 5:console.log("TRIANGLE_STRIP"),r.primitive="triangles";break;case 6:console.log("TRIANGLE_FAN"),r.primitive="triangles"}var i=e.gltf.accessors,o=t.indices;if(null!=o){var a=i[o];r.indices=mr(e,a)}var s=n.POSITION;if(null!=s){var u=i[s];r.positions=mr(e,u)}var c=n.NORMAL;if(null!=c){var l=i[c];r.normals=mr(e,l)}var h=n.COLOR_0;if(null!=h){var f=i[h];r.colors=mr(e,f)}}}function mr(e,t){var r=e.gltf.bufferViews[t.bufferView],n=ar[t.type],i=or[t.componentType],o=i.BYTES_PER_ELEMENT*n;if(t.byteStride&&t.byteStride!==o)throw new Error("interleaved buffer!");return new i(r._buffer,t.byteOffset||0,t.count*n)}function vr(e){var t=e.WebIFC,r=e.data,n=e.xktModel,i=e.autoNormals,o=void 0===i||i,a=e.includeTypes,s=e.excludeTypes,u=e.wasmPath,c=e.stats,l=void 0===c?{}:c,h=e.log;return h&&h("Using parser: parseIFCIntoXKTModel"),new Promise((function(e,i){if(r)if(n)if(u){var c=new t.IfcAPI;u&&c.SetWasmPath(u),c.Init().then((function(){var i=new Uint8Array(r),u=c.OpenModel(i);l.sourceFormat="IFC",l.schemaVersion="",l.title="",l.author="",l.created="",l.numMetaObjects=0,l.numPropertySets=0,l.numObjects=0,l.numGeometries=0,l.numTriangles=0,l.numVertices=0;var f={WebIFC:t,modelID:u,ifcAPI:c,xktModel:n,autoNormals:o,log:h||function(e){},nextId:0,stats:l};if(a){f.includeTypes={};for(var d=0,p=a.length;d0){for(var d=o.Name.value,p=[],m=0,v=f.length;m0&&(e.xktModel.createEntity({entityId:o,meshIds:i}),e.stats.numObjects++)}else console.log("excluding: "+a)}const br=require("@loaders.gl/las");var wr=5e5;function Mr(e){var t=e.data,r=e.xktModel,n=e.center,i=void 0!==n&&n,o=e.transform,a=void 0===o?null:o,s=e.colorDepth,u=void 0===s?"auto":s,c=e.fp64,l=void 0!==c&&c,h=e.skip,f=void 0===h?1:h,d=e.stats,p=e.log,m=void 0===p?function(){}:p;return m&&m("Using parser: parseLASIntoXKTModel"),new Promise((function(e,n){t?r?(m("Converting LAZ/LAS"),m("center: ".concat(i)),a&&m("transform: [".concat(a,"]")),m("colorDepth: ".concat(u)),m("fp64: ".concat(l)),m("skip: ".concat(f)),(0,Be.parse)(t,br.LASLoader,{las:{colorDepth:u,fp64:l}}).then((function(t){var n=t.attributes,o=t.loaderData,s=void 0!==o.pointsFormatId?o.pointsFormatId:-1;if(n.POSITION){var u={};switch(s){case 0:if(!n.intensity)return void m("No intensities found in file (expected for LAS point format 0)");u=y(n.POSITION,n.intensity);break;case 1:if(!n.intensity)return void m("No intensities found in file (expected for LAS point format 1)");u=y(n.POSITION,n.intensity);break;case 2:if(!n.intensity)return void m("No intensities found in file (expected for LAS point format 2)");u=v(n.POSITION,n.COLOR_0,n.intensity);break;case 3:if(!n.intensity)return void m("No intensities found in file (expected for LAS point format 3)");u=v(n.POSITION,n.COLOR_0,n.intensity)}for(var c=g(function(e){if(e){if(i){for(var t=k.vec3(),r=e.length,n=0,o=e.length;n=e.length)return[e];for(var r=[],n=0;n0?P:null}),M++}}o&&o("Converted meta objects: "+M),e()}))}function Ir(e){var t=e.data,r=e.xktModel,n=e.littleEndian,i=void 0===n||n,o=e.stats,a=e.log;return a&&a("Using parser: parsePCDIntoXKTModel"),new Promise((function(e,n){var s=function(e){if("undefined"!=typeof TextDecoder)return(new TextDecoder).decode(e);for(var t="",r=0,n=e.length;r>16&255,g=v>>8&255,x=v>>0&255;l.push(y,g,x,255)}else l.push(255),l.push(255),l.push(255)}if("binary_compressed"===u.data)for(var b=new Uint32Array(t.slice(u.headerLen,u.headerLen+8)),w=b[0],M=b[1],T=function(e,t){var r,n,i,o=e.length,a=new Uint8Array(t),s=0,u=0;do{if((r=e[s++])<32){if(u+ ++r>t)throw new Error("Output buffer is not large enough");if(s+r>o)throw new Error("Invalid compressed data");do{a[u++]=e[s++]}while(--r)}else{if(n=r>>5,i=u-((31&r)<<8)-1,s>=o)throw new Error("Invalid compressed data");if(7===n&&(n+=e[s++],s>=o))throw new Error("Invalid compressed data");if(i-=e[s++],u+n+2>t)throw new Error("Output buffer is not large enough");if(i<0)throw new Error("Invalid compressed data");if(i>=u)throw new Error("Invalid compressed data");do{a[u++]=a[i++]}while(2+--n)}}while(s0?l:null}),r.createMesh({meshId:"pointsMesh",geometryId:"pointsGeometry"}),r.createEntity({entityId:"geometries",meshIds:["pointsMesh"]}),a&&(a("Converted drawable objects: 1"),a("Converted geometries: 1"),a("Converted vertices: "+c.length/3)),o&&(o.sourceFormat="PCD",o.schemaVersion="",o.title="",o.author="",o.created="",o.numObjects=1,o.numGeometries=1,o.numVertices=c.length/3),e()}))}const Sr=require("@loaders.gl/ply");function Ar(e){return Ar="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ar(e)}function Or(){Or=function(){return e};var e={},t=Object.prototype,r=t.hasOwnProperty,n=Object.defineProperty||function(e,t,r){e[t]=r.value},i="function"==typeof Symbol?Symbol:{},o=i.iterator||"@@iterator",a=i.asyncIterator||"@@asyncIterator",s=i.toStringTag||"@@toStringTag";function u(e,t,r){return Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{u({},"")}catch(e){u=function(e,t,r){return e[t]=r}}function c(e,t,r,i){var o=t&&t.prototype instanceof f?t:f,a=Object.create(o.prototype),s=new S(i||[]);return n(a,"_invoke",{value:w(e,r,s)}),a}function l(e,t,r){try{return{type:"normal",arg:e.call(t,r)}}catch(e){return{type:"throw",arg:e}}}e.wrap=c;var h={};function f(){}function d(){}function p(){}var m={};u(m,o,(function(){return this}));var v=Object.getPrototypeOf,y=v&&v(v(A([])));y&&y!==t&&r.call(y,o)&&(m=y);var g=p.prototype=f.prototype=Object.create(m);function x(e){["next","throw","return"].forEach((function(t){u(e,t,(function(e){return this._invoke(t,e)}))}))}function b(e,t){function i(n,o,a,s){var u=l(e[n],e,o);if("throw"!==u.type){var c=u.arg,h=c.value;return h&&"object"==Ar(h)&&r.call(h,"__await")?t.resolve(h.__await).then((function(e){i("next",e,a,s)}),(function(e){i("throw",e,a,s)})):t.resolve(h).then((function(e){c.value=e,a(c)}),(function(e){return i("throw",e,a,s)}))}s(u.arg)}var o;n(this,"_invoke",{value:function(e,r){function n(){return new t((function(t,n){i(e,r,t,n)}))}return o=o?o.then(n,n):n()}})}function w(e,t,r){var n="suspendedStart";return function(i,o){if("executing"===n)throw new Error("Generator is already running");if("completed"===n){if("throw"===i)throw o;return{value:void 0,done:!0}}for(r.method=i,r.arg=o;;){var a=r.delegate;if(a){var s=M(a,r);if(s){if(s===h)continue;return s}}if("next"===r.method)r.sent=r._sent=r.arg;else if("throw"===r.method){if("suspendedStart"===n)throw n="completed",r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);n="executing";var u=l(e,t,r);if("normal"===u.type){if(n=r.done?"completed":"suspendedYield",u.arg===h)continue;return{value:u.arg,done:r.done}}"throw"===u.type&&(n="completed",r.method="throw",r.arg=u.arg)}}}function M(e,t){var r=t.method,n=e.iterator[r];if(void 0===n)return t.delegate=null,"throw"===r&&e.iterator.return&&(t.method="return",t.arg=void 0,M(e,t),"throw"===t.method)||"return"!==r&&(t.method="throw",t.arg=new TypeError("The iterator does not provide a '"+r+"' method")),h;var i=l(n,e.iterator,t.arg);if("throw"===i.type)return t.method="throw",t.arg=i.arg,t.delegate=null,h;var o=i.arg;return o?o.done?(t[e.resultName]=o.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=void 0),t.delegate=null,h):o:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,h)}function T(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function I(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function S(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(T,this),this.reset(!0)}function A(e){if(e){var t=e[o];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var n=-1,i=function t(){for(;++n=0;--i){var o=this.tryEntries[i],a=o.completion;if("root"===o.tryLoc)return n("end");if(o.tryLoc<=this.prev){var s=r.call(o,"catchLoc"),u=r.call(o,"finallyLoc");if(s&&u){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),I(r),h}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var i=n.arg;I(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,r){return this.delegate={iterator:A(e),resultName:t,nextLoc:r},"next"===this.method&&(this.arg=void 0),h}},e}function Pr(e,t,r,n,i,o,a){try{var s=e[o](a),u=s.value}catch(e){return void r(e)}s.done?t(u):Promise.resolve(u).then(n,i)}function Lr(e){return Er.apply(this,arguments)}function Er(){var e;return e=Or().mark((function e(t){var r,n,i,o,a,s,u,c,l,h,f;return Or().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=t.data,n=t.xktModel,i=t.stats,(o=t.log)&&o("Using parser: parsePLYIntoXKTModel"),r){e.next=4;break}throw"Argument expected: data";case 4:if(n){e.next=6;break}throw"Argument expected: xktModel";case 6:return e.prev=6,e.next=9,(0,Be.parse)(r,Sr.PLYLoader);case 9:a=e.sent,e.next=16;break;case 12:return e.prev=12,e.t0=e.catch(6),o&&o("Error: "+e.t0),e.abrupt("return");case 16:if(s=a.attributes,u=!!s.COLOR_0){for(c=u?s.COLOR_0.value:null,l=[],h=0,f=c.length;h=0;--i){var o=this.tryEntries[i],a=o.completion;if("root"===o.tryLoc)return n("end");if(o.tryLoc<=this.prev){var s=r.call(o,"catchLoc"),u=r.call(o,"finallyLoc");if(s&&u){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),I(r),h}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var i=n.arg;I(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,r){return this.delegate={iterator:A(e),resultName:t,nextLoc:r},"next"===this.method&&(this.arg=void 0),h}},e}function Gr(e,t,r,n,i,o,a){try{var s=e[o](a),u=s.value}catch(e){return void r(e)}s.done?t(u):Promise.resolve(u).then(n,i)}function kr(e){return _r.apply(this,arguments)}function _r(){var e;return e=Dr().mark((function e(t){var r,n,i,o,a,s,u,c;return Dr().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=t.data,n=t.splitMeshes,i=t.autoNormals,o=t.smoothNormals,a=t.smoothNormalsAngleThreshold,s=t.xktModel,u=t.stats,(c=t.log)&&c("Using parser: parseSTLIntoXKTModel"),e.abrupt("return",new Promise((function(e,t){if(r)if(s){var l=k.createUUID(),h=s.createMetaObject({metaObjectId:l,metaObjectType:"Model",metaObjectName:"Model"}),f={data:r,splitMeshes:n,autoNormals:i,smoothNormals:o,smoothNormalsAngleThreshold:a,xktModel:s,rootMetaObject:h,nextId:0,log:c||function(e){},stats:{numObjects:0,numGeometries:0,numTriangles:0,numVertices:0}},d=zr(r);Fr(d)?Nr(f,d):Vr(f,"string"!=typeof(p=r)?function(e){if("undefined"!=typeof TextDecoder)return(new TextDecoder).decode(e);for(var t="",r=0,n=e.length;r>5&31)/31,i=(S>>10&31)/31):(r=a,n=s,i=u),(x&&r!==f||n!==d||i!==p)&&(null!==f&&(m=!0),f=r,d=n,p=i)}for(var A=1;A<=3;A++){var O=w+12*A;y.push(c.getFloat32(O,!0)),y.push(c.getFloat32(O+4,!0)),y.push(c.getFloat32(O+8,!0)),e.autoNormals||g.push(M,T,I),h&&o.push(r,n,i,1)}x&&m&&(Cr(e,y,g,o),y=[],g=[],o=o?[]:null,m=!1)}y.length>0&&Cr(e,y,g,o)}function Vr(e,t){for(var r,n,i,o,a,s,u,c=/facet([\s\S]*?)endfacet/g,l=0,h=/[\s]+([+-]?(?:\d+.\d+|\d+.|\d+|.\d+)(?:[eE][+-]?\d+)?)/.source,f=new RegExp("vertex"+h+h+h,"g"),d=new RegExp("normal"+h+h+h,"g"),p=[],m=[];null!==(o=c.exec(t));){for(a=0,s=0,u=o[0];null!==(o=d.exec(u));)r=parseFloat(o[1]),n=parseFloat(o[2]),i=parseFloat(o[3]),s++;for(;null!==(o=f.exec(u));)p.push(parseFloat(o[1]),parseFloat(o[2]),parseFloat(o[3])),m.push(r,n,i),a++;if(1!==s)return e.log("Error in normal of face "+l),-1;if(3!==a)return e.log("Error in positions of face "+l),-1;l++}Cr(e,p,m,null)}var Br=0;function Cr(e,t,r,n){for(var i=new Int32Array(t.length/3),o=0,a=i.length;o0?r:null,n=n&&n.length>0?n:null,!e.autoNormals&&e.smoothNormals&&function(e,t){var r,n,i,o,a,s,u,c,l,h,f,d=(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).smoothNormalsAngleThreshold||20,p={},m=[],v={},y=Math.pow(10,4);for(u=0,l=e.length;u0&&void 0!==arguments[0]?arguments[0]:{},t=e.xSize||1;t<0&&(console.error("negative xSize not allowed - will invert"),t*=-1);var r=e.ySize||1;r<0&&(console.error("negative ySize not allowed - will invert"),r*=-1);var n=e.zSize||1;n<0&&(console.error("negative zSize not allowed - will invert"),n*=-1);var i=e.center,o=i?i[0]:0,a=i?i[1]:0,s=i?i[2]:0,u=-t+o,c=-r+a,l=-n+s,h=t+o,f=r+a,d=n+s;return{primitiveType:"triangles",positions:[h,f,d,u,f,d,u,c,d,h,c,d,h,f,d,h,c,d,h,c,l,h,f,l,h,f,d,h,f,l,u,f,l,u,f,d,u,f,d,u,f,l,u,c,l,u,c,d,u,c,l,h,c,l,h,c,d,u,c,d,h,c,l,u,c,l,u,f,l,h,f,l],normals:[0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1],uv:[1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0],indices:[0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,12,13,14,12,14,15,16,17,18,16,18,19,20,21,22,20,22,23]}}function Xr(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.xSize||1;t<0&&(console.error("negative xSize not allowed - will invert"),t*=-1);var r=e.ySize||1;r<0&&(console.error("negative ySize not allowed - will invert"),r*=-1);var n=e.zSize||1;n<0&&(console.error("negative zSize not allowed - will invert"),n*=-1);var i=e.center,o=i?i[0]:0,a=i?i[1]:0,s=i?i[2]:0,u=-t+o,c=-r+a,l=-n+s,h=t+o,f=r+a,d=n+s;return{primitiveType:"lines",positions:[u,c,l,u,c,d,u,f,l,u,f,d,h,c,l,h,c,d,h,f,l,h,f,d],indices:[0,1,1,3,3,2,2,0,4,5,5,7,7,6,6,4,0,4,1,5,2,6,3,7]}}function Rr(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.radiusTop||1;t<0&&(console.error("negative radiusTop not allowed - will invert"),t*=-1);var r=e.radiusBottom||1;r<0&&(console.error("negative radiusBottom not allowed - will invert"),r*=-1);var n=e.height||1;n<0&&(console.error("negative height not allowed - will invert"),n*=-1);var i=e.radialSegments||32;i<0&&(console.error("negative radialSegments not allowed - will invert"),i*=-1),i<3&&(i=3);var o=e.heightSegments||1;o<0&&(console.error("negative heightSegments not allowed - will invert"),o*=-1),o<1&&(o=1);var a,s,u,c,l,h,f,d,p,m,v,y=!!e.openEnded,g=e.center,x=g?g[0]:0,b=g?g[1]:0,w=g?g[2]:0,M=n/2,T=n/o,I=2*Math.PI/i,S=1/i,A=(t-r)/o,O=[],P=[],L=[],E=[],j=(90-180*Math.atan(n/(r-t))/Math.PI)/90;for(a=0;a<=o;a++)for(l=t-a*A,h=M-a*T,s=0;s<=i;s++)u=Math.sin(s*I),c=Math.cos(s*I),P.push(l*u),P.push(j),P.push(l*c),L.push(s*S),L.push(1*a/o),O.push(l*u+x),O.push(h+b),O.push(l*c+w);for(a=0;a0){for(p=O.length/3,P.push(0),P.push(1),P.push(0),L.push(.5),L.push(.5),O.push(0+x),O.push(M+b),O.push(0+w),s=0;s<=i;s++)u=Math.sin(s*I),c=Math.cos(s*I),m=.5*Math.sin(s*I)+.5,v=.5*Math.cos(s*I)+.5,P.push(t*u),P.push(1),P.push(t*c),L.push(m),L.push(v),O.push(t*u+x),O.push(M+b),O.push(t*c+w);for(s=0;s0){for(p=O.length/3,P.push(0),P.push(-1),P.push(0),L.push(.5),L.push(.5),O.push(0+x),O.push(0-M+b),O.push(0+w),s=0;s<=i;s++)u=Math.sin(s*I),c=Math.cos(s*I),m=.5*Math.sin(s*I)+.5,v=.5*Math.cos(s*I)+.5,P.push(r*u),P.push(-1),P.push(r*c),L.push(m),L.push(v),O.push(r*u+x),O.push(0-M+b),O.push(r*c+w);for(s=0;s0&&void 0!==arguments[0]?arguments[0]:{},t=e.size||1;t<0&&(console.error("negative size not allowed - will invert"),t*=-1);var r=e.divisions||1;r<0&&(console.error("negative divisions not allowed - will invert"),r*=-1),r<1&&(r=1);for(var n=(t=t||10)/(r=r||10),i=t/2,o=[],a=[],s=0,u=0,c=-i;u<=r;u++,c+=n)o.push(-i),o.push(0),o.push(c),o.push(i),o.push(0),o.push(c),o.push(c),o.push(0),o.push(-i),o.push(c),o.push(0),o.push(i),a.push(s++),a.push(s++),a.push(s++),a.push(s++);return{primitiveType:"lines",positions:o,indices:a}}function qr(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.xSize||1;t<0&&(console.error("negative xSize not allowed - will invert"),t*=-1);var r=e.zSize||1;r<0&&(console.error("negative zSize not allowed - will invert"),r*=-1);var n=e.xSegments||1;n<0&&(console.error("negative xSegments not allowed - will invert"),n*=-1),n<1&&(n=1);var i=e.xSegments||1;i<0&&(console.error("negative zSegments not allowed - will invert"),i*=-1),i<1&&(i=1);var o,a,s,u,c,l,h,f=e.center,d=f?f[0]:0,p=f?f[1]:0,m=f?f[2]:0,v=t/2,y=r/2,g=Math.floor(n)||1,x=Math.floor(i)||1,b=g+1,w=x+1,M=t/g,T=r/x,I=new Float32Array(b*w*3),S=new Float32Array(b*w*3),A=new Float32Array(b*w*2),O=0,P=0;for(o=0;o65535?Uint32Array:Uint16Array)(g*x*6);for(o=0;o0&&void 0!==arguments[0]?arguments[0]:{},t=e.lod||1,r=e.center?e.center[0]:0,n=e.center?e.center[1]:0,i=e.center?e.center[2]:0,o=e.radius||1;o<0&&(console.error("negative radius not allowed - will invert"),o*=-1);var a=e.heightSegments||18;a<0&&(console.error("negative heightSegments not allowed - will invert"),a*=-1),(a=Math.floor(t*a))<18&&(a=18);var s=e.widthSegments||18;s<0&&(console.error("negative widthSegments not allowed - will invert"),s*=-1),(s=Math.floor(t*s))<18&&(s=18);var u,c,l,h,f,d,p,m,v,y,g,x,b,w,M=[],T=[],I=[],S=[];for(u=0;u<=a;u++)for(l=u*Math.PI/a,h=Math.sin(l),f=Math.cos(l),c=0;c<=s;c++)d=2*c*Math.PI/s,p=Math.sin(d),m=Math.cos(d)*h,v=f,y=p*h,g=1-c/s,x=u/a,T.push(m),T.push(v),T.push(y),I.push(g),I.push(x),M.push(r+o*m),M.push(n+o*v),M.push(i+o*y);for(u=0;u0&&void 0!==arguments[0]?arguments[0]:{},t=e.radius||1;t<0&&(console.error("negative radius not allowed - will invert"),t*=-1),t*=.5;var r=e.tube||.3;r<0&&(console.error("negative tube not allowed - will invert"),r*=-1);var n=e.radialSegments||32;n<0&&(console.error("negative radialSegments not allowed - will invert"),n*=-1),n<4&&(n=4);var i=e.tubeSegments||24;i<0&&(console.error("negative tubeSegments not allowed - will invert"),i*=-1),i<4&&(i=4);var o=e.arc||2*Math.PI;o<0&&(console.warn("negative arc not allowed - will invert"),o*=-1),o>360&&(o=360);var a,s,u,c,l,h,f,d,p,m,v,y,g=e.center,x=g?g[0]:0,b=g?g[1]:0,w=g?g[2]:0,M=[],T=[],I=[],S=[];for(d=0;d<=i;d++)for(f=0;f<=n;f++)a=f/n*o,s=.785398+d/i*Math.PI*2,x=t*Math.cos(a),b=t*Math.sin(a),u=(t+r*Math.cos(s))*Math.cos(a),c=(t+r*Math.cos(s))*Math.sin(a),l=r*Math.sin(s),M.push(u+x),M.push(c+b),M.push(l+w),I.push(1-f/n),I.push(d/i),h=k.normalizeVec3(k.subVec3([u,c,l],[x,b,w],[]),[]),T.push(h[0]),T.push(h[1]),T.push(h[2]);for(d=1;d<=i;d++)for(f=1;f<=n;f++)p=(n+1)*d+f-1,m=(n+1)*(d-1)+f-1,v=(n+1)*(d-1)+f,y=(n+1)*d+f,S.push(p),S.push(m),S.push(v),S.push(v),S.push(y),S.push(p);return{primitiveType:"triangles",positions:M,normals:T,uv:I,uvs:I,indices:S}}var Wr={" ":{width:16,points:[]},"!":{width:10,points:[[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},'"':{width:16,points:[[4,21],[4,14],[-1,-1],[12,21],[12,14]]},"#":{width:21,points:[[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]]},$:{width:20,points:[[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},"%":{width:24,points:[[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]]},"&":{width:26,points:[[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]]},"'":{width:10,points:[[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]]},"(":{width:14,points:[[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]]},")":{width:14,points:[[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]]},"*":{width:16,points:[[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]]},"+":{width:26,points:[[13,18],[13,0],[-1,-1],[4,9],[22,9]]},",":{width:10,points:[[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"-":{width:26,points:[[4,9],[22,9]]},".":{width:10,points:[[5,2],[4,1],[5,0],[6,1],[5,2]]},"/":{width:22,points:[[20,25],[2,-7]]},0:{width:20,points:[[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]]},1:{width:20,points:[[6,17],[8,18],[11,21],[11,0]]},2:{width:20,points:[[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]]},3:{width:20,points:[[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},4:{width:20,points:[[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]]},5:{width:20,points:[[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},6:{width:20,points:[[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]]},7:{width:20,points:[[17,21],[7,0],[-1,-1],[3,21],[17,21]]},8:{width:20,points:[[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]]},9:{width:20,points:[[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]]},":":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},";":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"<":{width:24,points:[[20,18],[4,9],[20,0]]},"=":{width:26,points:[[4,12],[22,12],[-1,-1],[4,6],[22,6]]},">":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};function Qr(){for(var e,t,r,n,i,o,a,s,u,c=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},l=c.origin||[0,0,0],h=l[0],f=l[1],d=l[2],p=c.size||1,m=[],v=[],y=((""+c.text).trim()||"").split("\n"),g=0,x=0,b=.04,w=0;w(()=>{"use strict";var e={d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{ClampToEdgeWrapping:()=>p,GIFMediaType:()=>O,JPEGMediaType:()=>P,LinearFilter:()=>M,LinearMipMapLinearFilter:()=>A,LinearMipMapNearestFilter:()=>I,LinearMipmapLinearFilter:()=>S,LinearMipmapNearestFilter:()=>T,MirroredRepeatWrapping:()=>m,NearestFilter:()=>y,NearestMipMapLinearFilter:()=>w,NearestMipMapNearestFilter:()=>g,NearestMipmapLinearFilter:()=>b,NearestMipmapNearestFilter:()=>x,PNGMediaType:()=>L,RepeatWrapping:()=>d,XKTModel:()=>He,XKT_INFO:()=>f,buildBoxGeometry:()=>zr,buildBoxLinesGeometry:()=>Xr,buildCylinderGeometry:()=>Rr,buildGridGeometry:()=>Kr,buildPlaneGeometry:()=>qr,buildSphereGeometry:()=>Zr,buildTorusGeometry:()=>Yr,buildVectorTextGeometry:()=>Wr,convert2xkt:()=>Jr,parseCityJSONIntoXKTModel:()=>Vt,parseGLTFIntoXKTModel:()=>Qt,parseGLTFJSONIntoXKTModel:()=>sr,parseIFCIntoXKTModel:()=>vr,parseLASIntoXKTModel:()=>Mr,parseMetaModelIntoXKTModel:()=>Tr,parsePCDIntoXKTModel:()=>Ir,parsePLYIntoXKTModel:()=>Lr,parseSTLIntoXKTModel:()=>_r,writeXKTModelToArrayBuffer:()=>nt});const r=require("@loaders.gl/polyfills");var n,i,o,a,s,u,c,l,h,f={xktVersion:10},d=1e3,p=1001,m=1002,y=1003,g=1004,x=1004,b=1005,w=1005,M=1006,T=1007,I=1007,S=1008,A=1008,O=1e4,P=10001,L=10002,E=Float64Array,j=new E(16),G=new E(16),D=new E(4),_={MIN_DOUBLE:-Number.MAX_SAFE_INTEGER,MAX_DOUBLE:Number.MAX_SAFE_INTEGER,DEGTORAD:.0174532925,RADTODEG:57.295779513,vec2:function(e){return new E(e||2)},vec3:function(e){return new E(e||3)},vec4:function(e){return new E(e||4)},mat3:function(e){return new E(e||9)},mat3ToMat4:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new E(16);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=0,t[4]=e[3],t[5]=e[4],t[6]=e[5],t[7]=0,t[8]=e[6],t[9]=e[7],t[10]=e[8],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},mat4:function(e){return new E(e||16)},mat4ToMat3:function(e,t){},createUUID:function(){for(var e=[],t=0;t<256;t++)e[t]=(t<16?"0":"")+t.toString(16);return function(){var t=4294967295*Math.random()|0,r=4294967295*Math.random()|0,n=4294967295*Math.random()|0,i=4294967295*Math.random()|0;return"".concat(e[255&t]+e[t>>8&255]+e[t>>16&255]+e[t>>24&255],"-").concat(e[255&r]).concat(e[r>>8&255],"-").concat(e[r>>16&15|64]).concat(e[r>>24&255],"-").concat(e[63&n|128]).concat(e[n>>8&255],"-").concat(e[n>>16&255]).concat(e[n>>24&255]).concat(e[255&i]).concat(e[i>>8&255]).concat(e[i>>16&255]).concat(e[i>>24&255])}}(),clamp:function(e,t,r){return Math.max(t,Math.min(r,e))},fmod:function(e,t){if(e1?1:r,Math.acos(r)},vec3FromMat4Scale:(u=new E(3),function(e,t){return u[0]=e[0],u[1]=e[1],u[2]=e[2],t[0]=_.lenVec3(u),u[0]=e[4],u[1]=e[5],u[2]=e[6],t[1]=_.lenVec3(u),u[0]=e[8],u[1]=e[9],u[2]=e[10],t[2]=_.lenVec3(u),t}),vecToArray:function(){function e(e){return Math.round(1e5*e)/1e5}return function(t){for(var r=0,n=(t=Array.prototype.slice.call(t)).length;r0&&void 0!==arguments[0]?arguments[0]:new E(16);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},identityMat3:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:new E(9);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},isIdentityMat4:function(e){return 1===e[0]&&0===e[1]&&0===e[2]&&0===e[3]&&0===e[4]&&1===e[5]&&0===e[6]&&0===e[7]&&0===e[8]&&0===e[9]&&1===e[10]&&0===e[11]&&0===e[12]&&0===e[13]&&0===e[14]&&1===e[15]},negateMat4:function(e,t){return t||(t=e),t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t[4]=-e[4],t[5]=-e[5],t[6]=-e[6],t[7]=-e[7],t[8]=-e[8],t[9]=-e[9],t[10]=-e[10],t[11]=-e[11],t[12]=-e[12],t[13]=-e[13],t[14]=-e[14],t[15]=-e[15],t},addMat4:function(e,t,r){return r||(r=e),r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r[3]=e[3]+t[3],r[4]=e[4]+t[4],r[5]=e[5]+t[5],r[6]=e[6]+t[6],r[7]=e[7]+t[7],r[8]=e[8]+t[8],r[9]=e[9]+t[9],r[10]=e[10]+t[10],r[11]=e[11]+t[11],r[12]=e[12]+t[12],r[13]=e[13]+t[13],r[14]=e[14]+t[14],r[15]=e[15]+t[15],r},addMat4Scalar:function(e,t,r){return r||(r=e),r[0]=e[0]+t,r[1]=e[1]+t,r[2]=e[2]+t,r[3]=e[3]+t,r[4]=e[4]+t,r[5]=e[5]+t,r[6]=e[6]+t,r[7]=e[7]+t,r[8]=e[8]+t,r[9]=e[9]+t,r[10]=e[10]+t,r[11]=e[11]+t,r[12]=e[12]+t,r[13]=e[13]+t,r[14]=e[14]+t,r[15]=e[15]+t,r},addScalarMat4:function(e,t,r){return _.addMat4Scalar(t,e,r)},subMat4:function(e,t,r){return r||(r=e),r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r[3]=e[3]-t[3],r[4]=e[4]-t[4],r[5]=e[5]-t[5],r[6]=e[6]-t[6],r[7]=e[7]-t[7],r[8]=e[8]-t[8],r[9]=e[9]-t[9],r[10]=e[10]-t[10],r[11]=e[11]-t[11],r[12]=e[12]-t[12],r[13]=e[13]-t[13],r[14]=e[14]-t[14],r[15]=e[15]-t[15],r},subMat4Scalar:function(e,t,r){return r||(r=e),r[0]=e[0]-t,r[1]=e[1]-t,r[2]=e[2]-t,r[3]=e[3]-t,r[4]=e[4]-t,r[5]=e[5]-t,r[6]=e[6]-t,r[7]=e[7]-t,r[8]=e[8]-t,r[9]=e[9]-t,r[10]=e[10]-t,r[11]=e[11]-t,r[12]=e[12]-t,r[13]=e[13]-t,r[14]=e[14]-t,r[15]=e[15]-t,r},subScalarMat4:function(e,t,r){return r||(r=t),r[0]=e-t[0],r[1]=e-t[1],r[2]=e-t[2],r[3]=e-t[3],r[4]=e-t[4],r[5]=e-t[5],r[6]=e-t[6],r[7]=e-t[7],r[8]=e-t[8],r[9]=e-t[9],r[10]=e-t[10],r[11]=e-t[11],r[12]=e-t[12],r[13]=e-t[13],r[14]=e-t[14],r[15]=e-t[15],r},mulMat4:function(e,t,r){r||(r=e);var n=e[0],i=e[1],o=e[2],a=e[3],s=e[4],u=e[5],c=e[6],l=e[7],h=e[8],f=e[9],d=e[10],p=e[11],m=e[12],v=e[13],y=e[14],g=e[15],x=t[0],b=t[1],w=t[2],M=t[3],T=t[4],I=t[5],S=t[6],A=t[7],O=t[8],P=t[9],L=t[10],E=t[11],j=t[12],G=t[13],D=t[14],_=t[15];return r[0]=x*n+b*s+w*h+M*m,r[1]=x*i+b*u+w*f+M*v,r[2]=x*o+b*c+w*d+M*y,r[3]=x*a+b*l+w*p+M*g,r[4]=T*n+I*s+S*h+A*m,r[5]=T*i+I*u+S*f+A*v,r[6]=T*o+I*c+S*d+A*y,r[7]=T*a+I*l+S*p+A*g,r[8]=O*n+P*s+L*h+E*m,r[9]=O*i+P*u+L*f+E*v,r[10]=O*o+P*c+L*d+E*y,r[11]=O*a+P*l+L*p+E*g,r[12]=j*n+G*s+D*h+_*m,r[13]=j*i+G*u+D*f+_*v,r[14]=j*o+G*c+D*d+_*y,r[15]=j*a+G*l+D*p+_*g,r},mulMat3:function(e,t,r){r||(r=new E(9));var n=e[0],i=e[3],o=e[6],a=e[1],s=e[4],u=e[7],c=e[2],l=e[5],h=e[8],f=t[0],d=t[3],p=t[6],m=t[1],v=t[4],y=t[7],g=t[2],x=t[5],b=t[8];return r[0]=n*f+i*m+o*g,r[3]=n*d+i*v+o*x,r[6]=n*p+i*y+o*b,r[1]=a*f+s*m+u*g,r[4]=a*d+s*v+u*x,r[7]=a*p+s*y+u*b,r[2]=c*f+l*m+h*g,r[5]=c*d+l*v+h*x,r[8]=c*p+l*y+h*b,r},mulMat4Scalar:function(e,t,r){return r||(r=e),r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r[3]=e[3]*t,r[4]=e[4]*t,r[5]=e[5]*t,r[6]=e[6]*t,r[7]=e[7]*t,r[8]=e[8]*t,r[9]=e[9]*t,r[10]=e[10]*t,r[11]=e[11]*t,r[12]=e[12]*t,r[13]=e[13]*t,r[14]=e[14]*t,r[15]=e[15]*t,r},mulMat4v4:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:_.vec4(),n=t[0],i=t[1],o=t[2],a=t[3];return r[0]=e[0]*n+e[4]*i+e[8]*o+e[12]*a,r[1]=e[1]*n+e[5]*i+e[9]*o+e[13]*a,r[2]=e[2]*n+e[6]*i+e[10]*o+e[14]*a,r[3]=e[3]*n+e[7]*i+e[11]*o+e[15]*a,r},transposeMat4:function(e,t){var r=e[4],n=e[14],i=e[8],o=e[13],a=e[12],s=e[9];if(!t||e===t){var u=e[1],c=e[2],l=e[3],h=e[6],f=e[7],d=e[11];return e[1]=r,e[2]=i,e[3]=a,e[4]=u,e[6]=s,e[7]=o,e[8]=c,e[9]=h,e[11]=n,e[12]=l,e[13]=f,e[14]=d,e}return t[0]=e[0],t[1]=r,t[2]=i,t[3]=a,t[4]=e[1],t[5]=e[5],t[6]=s,t[7]=o,t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=n,t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15],t},transposeMat3:function(e,t){if(t===e){var r=e[1],n=e[2],i=e[5];t[1]=e[3],t[2]=e[6],t[3]=r,t[5]=e[7],t[6]=n,t[7]=i}else t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8];return t},determinantMat4:function(e){var t=e[0],r=e[1],n=e[2],i=e[3],o=e[4],a=e[5],s=e[6],u=e[7],c=e[8],l=e[9],h=e[10],f=e[11],d=e[12],p=e[13],m=e[14],v=e[15];return d*l*s*i-c*p*s*i-d*a*h*i+o*p*h*i+c*a*m*i-o*l*m*i-d*l*n*u+c*p*n*u+d*r*h*u-t*p*h*u-c*r*m*u+t*l*m*u+d*a*n*f-o*p*n*f-d*r*s*f+t*p*s*f+o*r*m*f-t*a*m*f-c*a*n*v+o*l*n*v+c*r*s*v-t*l*s*v-o*r*h*v+t*a*h*v},inverseMat4:function(e,t){t||(t=e);var r=e[0],n=e[1],i=e[2],o=e[3],a=e[4],s=e[5],u=e[6],c=e[7],l=e[8],h=e[9],f=e[10],d=e[11],p=e[12],m=e[13],v=e[14],y=e[15],g=r*s-n*a,x=r*u-i*a,b=r*c-o*a,w=n*u-i*s,M=n*c-o*s,T=i*c-o*u,I=l*m-h*p,S=l*v-f*p,A=l*y-d*p,O=h*v-f*m,P=h*y-d*m,L=f*y-d*v,E=1/(g*L-x*P+b*O+w*A-M*S+T*I);return t[0]=(s*L-u*P+c*O)*E,t[1]=(-n*L+i*P-o*O)*E,t[2]=(m*T-v*M+y*w)*E,t[3]=(-h*T+f*M-d*w)*E,t[4]=(-a*L+u*A-c*S)*E,t[5]=(r*L-i*A+o*S)*E,t[6]=(-p*T+v*b-y*x)*E,t[7]=(l*T-f*b+d*x)*E,t[8]=(a*P-s*A+c*I)*E,t[9]=(-r*P+n*A-o*I)*E,t[10]=(p*M-m*b+y*g)*E,t[11]=(-l*M+h*b-d*g)*E,t[12]=(-a*O+s*S-u*I)*E,t[13]=(r*O-n*S+i*I)*E,t[14]=(-p*w+m*x-v*g)*E,t[15]=(l*w-h*x+f*g)*E,t},traceMat4:function(e){return e[0]+e[5]+e[10]+e[15]},translationMat4v:function(e,t){var r=t||_.identityMat4();return r[12]=e[0],r[13]=e[1],r[14]=e[2],r},translationMat3v:function(e,t){var r=t||_.identityMat3();return r[6]=e[0],r[7]=e[1],r},translationMat4c:(s=new E(3),function(e,t,r,n){return s[0]=e,s[1]=t,s[2]=r,_.translationMat4v(s,n)}),translationMat4s:function(e,t){return _.translationMat4c(e,e,e,t)},translateMat4v:function(e,t){return _.translateMat4c(e[0],e[1],e[2],t)},OLDtranslateMat4c:function(e,t,r,n){var i=n[12];n[0]+=i*e,n[4]+=i*t,n[8]+=i*r;var o=n[13];n[1]+=o*e,n[5]+=o*t,n[9]+=o*r;var a=n[14];n[2]+=a*e,n[6]+=a*t,n[10]+=a*r;var s=n[15];return n[3]+=s*e,n[7]+=s*t,n[11]+=s*r,n},translateMat4c:function(e,t,r,n){var i=n[3];n[0]+=i*e,n[1]+=i*t,n[2]+=i*r;var o=n[7];n[4]+=o*e,n[5]+=o*t,n[6]+=o*r;var a=n[11];n[8]+=a*e,n[9]+=a*t,n[10]+=a*r;var s=n[15];return n[12]+=s*e,n[13]+=s*t,n[14]+=s*r,n},rotationMat4v:function(e,t,r){var n,i,o,a,s,u,c=_.normalizeVec4([t[0],t[1],t[2],0],[]),l=Math.sin(e),h=Math.cos(e),f=1-h,d=c[0],p=c[1],m=c[2];return n=d*p,i=p*m,o=m*d,a=d*l,s=p*l,u=m*l,(r=r||_.mat4())[0]=f*d*d+h,r[1]=f*n+u,r[2]=f*o-s,r[3]=0,r[4]=f*n-u,r[5]=f*p*p+h,r[6]=f*i+a,r[7]=0,r[8]=f*o+s,r[9]=f*i-a,r[10]=f*m*m+h,r[11]=0,r[12]=0,r[13]=0,r[14]=0,r[15]=1,r},rotationMat4c:function(e,t,r,n,i){return _.rotationMat4v(e,[t,r,n],i)},scalingMat4v:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_.identityMat4();return t[0]=e[0],t[5]=e[1],t[10]=e[2],t},scalingMat3v:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_.identityMat3();return t[0]=e[0],t[4]=e[1],t},scalingMat4c:function(){var e=new E(3);return function(t,r,n,i){return e[0]=t,e[1]=r,e[2]=n,_.scalingMat4v(e,i)}}(),scaleMat4c:function(e,t,r,n){return n[0]*=e,n[4]*=t,n[8]*=r,n[1]*=e,n[5]*=t,n[9]*=r,n[2]*=e,n[6]*=t,n[10]*=r,n[3]*=e,n[7]*=t,n[11]*=r,n},scaleMat4v:function(e,t){var r=e[0],n=e[1],i=e[2];return t[0]*=r,t[4]*=n,t[8]*=i,t[1]*=r,t[5]*=n,t[9]*=i,t[2]*=r,t[6]*=n,t[10]*=i,t[3]*=r,t[7]*=n,t[11]*=i,t},scalingMat4s:function(e){return _.scalingMat4c(e,e,e)},rotationTranslationMat4:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:_.mat4(),n=e[0],i=e[1],o=e[2],a=e[3],s=n+n,u=i+i,c=o+o,l=n*s,h=n*u,f=n*c,d=i*u,p=i*c,m=o*c,v=a*s,y=a*u,g=a*c;return r[0]=1-(d+m),r[1]=h+g,r[2]=f-y,r[3]=0,r[4]=h-g,r[5]=1-(l+m),r[6]=p+v,r[7]=0,r[8]=f+y,r[9]=p-v,r[10]=1-(l+d),r[11]=0,r[12]=t[0],r[13]=t[1],r[14]=t[2],r[15]=1,r},mat4ToEuler:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:_.vec4(),n=_.clamp,i=e[0],o=e[4],a=e[8],s=e[1],u=e[5],c=e[9],l=e[2],h=e[6],f=e[10];return"XYZ"===t?(r[1]=Math.asin(n(a,-1,1)),Math.abs(a)<.99999?(r[0]=Math.atan2(-c,f),r[2]=Math.atan2(-o,i)):(r[0]=Math.atan2(h,u),r[2]=0)):"YXZ"===t?(r[0]=Math.asin(-n(c,-1,1)),Math.abs(c)<.99999?(r[1]=Math.atan2(a,f),r[2]=Math.atan2(s,u)):(r[1]=Math.atan2(-l,i),r[2]=0)):"ZXY"===t?(r[0]=Math.asin(n(h,-1,1)),Math.abs(h)<.99999?(r[1]=Math.atan2(-l,f),r[2]=Math.atan2(-o,u)):(r[1]=0,r[2]=Math.atan2(s,i))):"ZYX"===t?(r[1]=Math.asin(-n(l,-1,1)),Math.abs(l)<.99999?(r[0]=Math.atan2(h,f),r[2]=Math.atan2(s,i)):(r[0]=0,r[2]=Math.atan2(-o,u))):"YZX"===t?(r[2]=Math.asin(n(s,-1,1)),Math.abs(s)<.99999?(r[0]=Math.atan2(-c,u),r[1]=Math.atan2(-l,i)):(r[0]=0,r[1]=Math.atan2(a,f))):"XZY"===t&&(r[2]=Math.asin(-n(o,-1,1)),Math.abs(o)<.99999?(r[0]=Math.atan2(h,u),r[1]=Math.atan2(a,i)):(r[0]=Math.atan2(-c,f),r[1]=0)),r},composeMat4:function(e,t,r){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:_.mat4();return _.quaternionToRotationMat4(t,n),_.scaleMat4v(r,n),_.translateMat4v(e,n),n},decomposeMat4:function(){var e=new E(3),t=new E(16);return function(r,n,i,o){e[0]=r[0],e[1]=r[1],e[2]=r[2];var a=_.lenVec3(e);e[0]=r[4],e[1]=r[5],e[2]=r[6];var s=_.lenVec3(e);e[8]=r[8],e[9]=r[9],e[10]=r[10];var u=_.lenVec3(e);_.determinantMat4(r)<0&&(a=-a),n[0]=r[12],n[1]=r[13],n[2]=r[14],t.set(r);var c=1/a,l=1/s,h=1/u;return t[0]*=c,t[1]*=c,t[2]*=c,t[4]*=l,t[5]*=l,t[6]*=l,t[8]*=h,t[9]*=h,t[10]*=h,_.mat4ToQuaternion(t,i),o[0]=a,o[1]=s,o[2]=u,this}}(),lookAtMat4v:function(e,t,r,n){n||(n=_.mat4());var i,o,a,s,u,c,l,h,f,d,p=e[0],m=e[1],v=e[2],y=r[0],g=r[1],x=r[2],b=t[0],w=t[1],M=t[2];return p===b&&m===w&&v===M?_.identityMat4():(i=p-b,o=m-w,a=v-M,s=g*(a*=d=1/Math.sqrt(i*i+o*o+a*a))-x*(o*=d),u=x*(i*=d)-y*a,c=y*o-g*i,(d=Math.sqrt(s*s+u*u+c*c))?(s*=d=1/d,u*=d,c*=d):(s=0,u=0,c=0),l=o*c-a*u,h=a*s-i*c,f=i*u-o*s,(d=Math.sqrt(l*l+h*h+f*f))?(l*=d=1/d,h*=d,f*=d):(l=0,h=0,f=0),n[0]=s,n[1]=l,n[2]=i,n[3]=0,n[4]=u,n[5]=h,n[6]=o,n[7]=0,n[8]=c,n[9]=f,n[10]=a,n[11]=0,n[12]=-(s*p+u*m+c*v),n[13]=-(l*p+h*m+f*v),n[14]=-(i*p+o*m+a*v),n[15]=1,n)},lookAtMat4c:function(e,t,r,n,i,o,a,s,u){return _.lookAtMat4v([e,t,r],[n,i,o],[a,s,u],[])},orthoMat4c:function(e,t,r,n,i,o,a){a||(a=_.mat4());var s=t-e,u=n-r,c=o-i;return a[0]=2/s,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=2/u,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=-2/c,a[11]=0,a[12]=-(e+t)/s,a[13]=-(n+r)/u,a[14]=-(o+i)/c,a[15]=1,a},frustumMat4v:function(e,t,r){r||(r=_.mat4());var n=[e[0],e[1],e[2],0],i=[t[0],t[1],t[2],0];_.addVec4(i,n,j),_.subVec4(i,n,G);var o=2*n[2],a=G[0],s=G[1],u=G[2];return r[0]=o/a,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=o/s,r[6]=0,r[7]=0,r[8]=j[0]/a,r[9]=j[1]/s,r[10]=-j[2]/u,r[11]=-1,r[12]=0,r[13]=0,r[14]=-o*i[2]/u,r[15]=0,r},frustumMat4:function(e,t,r,n,i,o,a){a||(a=_.mat4());var s=t-e,u=n-r,c=o-i;return a[0]=2*i/s,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=2*i/u,a[6]=0,a[7]=0,a[8]=(t+e)/s,a[9]=(n+r)/u,a[10]=-(o+i)/c,a[11]=-1,a[12]=0,a[13]=0,a[14]=-o*i*2/c,a[15]=0,a},perspectiveMat4:function(e,t,r,n,i){var o=[],a=[];return o[2]=r,a[2]=n,a[1]=o[2]*Math.tan(e/2),o[1]=-a[1],a[0]=a[1]*t,o[0]=-a[0],_.frustumMat4v(o,a,i)},transformPoint3:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:_.vec3(),n=t[0],i=t[1],o=t[2];return r[0]=e[0]*n+e[4]*i+e[8]*o+e[12],r[1]=e[1]*n+e[5]*i+e[9]*o+e[13],r[2]=e[2]*n+e[6]*i+e[10]*o+e[14],r},transformPoint4:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:_.vec4();return r[0]=e[0]*t[0]+e[4]*t[1]+e[8]*t[2]+e[12]*t[3],r[1]=e[1]*t[0]+e[5]*t[1]+e[9]*t[2]+e[13]*t[3],r[2]=e[2]*t[0]+e[6]*t[1]+e[10]*t[2]+e[14]*t[3],r[3]=e[3]*t[0]+e[7]*t[1]+e[11]*t[2]+e[15]*t[3],r},transformPoints3:function(e,t,r){for(var n,i,o,a,s,u=r||[],c=t.length,l=e[0],h=e[1],f=e[2],d=e[3],p=e[4],m=e[5],v=e[6],y=e[7],g=e[8],x=e[9],b=e[10],w=e[11],M=e[12],T=e[13],I=e[14],S=e[15],A=0;A2&&void 0!==arguments[2]?arguments[2]:t,s=t.length,u=e[0],c=e[1],l=e[2],h=e[3],f=e[4],d=e[5],p=e[6],m=e[7],v=e[8],y=e[9],g=e[10],x=e[11],b=e[12],w=e[13],M=e[14],T=e[15];for(r=0;r2&&void 0!==arguments[2]?arguments[2]:t,s=t.length,u=e[0],c=e[1],l=e[2],h=e[3],f=e[4],d=e[5],p=e[6],m=e[7],v=e[8],y=e[9],g=e[10],x=e[11],b=e[12],w=e[13],M=e[14],T=e[15];for(r=0;r0&&void 0!==arguments[0]?arguments[0]:_.vec4();return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e},eulerToQuaternion:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:_.vec4(),n=e[0]*_.DEGTORAD/2,i=e[1]*_.DEGTORAD/2,o=e[2]*_.DEGTORAD/2,a=Math.cos(n),s=Math.cos(i),u=Math.cos(o),c=Math.sin(n),l=Math.sin(i),h=Math.sin(o);return"XYZ"===t?(r[0]=c*s*u+a*l*h,r[1]=a*l*u-c*s*h,r[2]=a*s*h+c*l*u,r[3]=a*s*u-c*l*h):"YXZ"===t?(r[0]=c*s*u+a*l*h,r[1]=a*l*u-c*s*h,r[2]=a*s*h-c*l*u,r[3]=a*s*u+c*l*h):"ZXY"===t?(r[0]=c*s*u-a*l*h,r[1]=a*l*u+c*s*h,r[2]=a*s*h+c*l*u,r[3]=a*s*u-c*l*h):"ZYX"===t?(r[0]=c*s*u-a*l*h,r[1]=a*l*u+c*s*h,r[2]=a*s*h-c*l*u,r[3]=a*s*u+c*l*h):"YZX"===t?(r[0]=c*s*u+a*l*h,r[1]=a*l*u+c*s*h,r[2]=a*s*h-c*l*u,r[3]=a*s*u-c*l*h):"XZY"===t&&(r[0]=c*s*u-a*l*h,r[1]=a*l*u-c*s*h,r[2]=a*s*h+c*l*u,r[3]=a*s*u+c*l*h),r},mat4ToQuaternion:function(e){var t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_.vec4(),n=e[0],i=e[4],o=e[8],a=e[1],s=e[5],u=e[9],c=e[2],l=e[6],h=e[10],f=n+s+h;return f>0?(t=.5/Math.sqrt(f+1),r[3]=.25/t,r[0]=(l-u)*t,r[1]=(o-c)*t,r[2]=(a-i)*t):n>s&&n>h?(t=2*Math.sqrt(1+n-s-h),r[3]=(l-u)/t,r[0]=.25*t,r[1]=(i+a)/t,r[2]=(o+c)/t):s>h?(t=2*Math.sqrt(1+s-n-h),r[3]=(o-c)/t,r[0]=(i+a)/t,r[1]=.25*t,r[2]=(u+l)/t):(t=2*Math.sqrt(1+h-n-s),r[3]=(a-i)/t,r[0]=(o+c)/t,r[1]=(u+l)/t,r[2]=.25*t),r},vec3PairToQuaternion:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:_.vec4(),n=Math.sqrt(_.dotVec3(e,e)*_.dotVec3(t,t)),i=n+_.dotVec3(e,t);return i<1e-8*n?(i=0,Math.abs(e[0])>Math.abs(e[2])?(r[0]=-e[1],r[1]=e[0],r[2]=0):(r[0]=0,r[1]=-e[2],r[2]=e[1])):_.cross3Vec3(e,t,r),r[3]=i,_.normalizeQuaternion(r)},angleAxisToQuaternion:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_.vec4(),r=e[3]/2,n=Math.sin(r);return t[0]=n*e[0],t[1]=n*e[1],t[2]=n*e[2],t[3]=Math.cos(r),t},quaternionToEuler:function(){var e=new E(16);return function(t,r,n){return n=n||_.vec3(),_.quaternionToRotationMat4(t,e),_.mat4ToEuler(e,r,n),n}}(),mulQuaternions:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:_.vec4(),n=e[0],i=e[1],o=e[2],a=e[3],s=t[0],u=t[1],c=t[2],l=t[3];return r[0]=a*s+n*l+i*c-o*u,r[1]=a*u+i*l+o*s-n*c,r[2]=a*c+o*l+n*u-i*s,r[3]=a*l-n*s-i*u-o*c,r},vec3ApplyQuaternion:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:_.vec3(),n=t[0],i=t[1],o=t[2],a=e[0],s=e[1],u=e[2],c=e[3],l=c*n+s*o-u*i,h=c*i+u*n-a*o,f=c*o+a*i-s*n,d=-a*n-s*i-u*o;return r[0]=l*c+d*-a+h*-u-f*-s,r[1]=h*c+d*-s+f*-a-l*-u,r[2]=f*c+d*-u+l*-s-h*-a,r},quaternionToMat4:function(e,t){t=_.identityMat4(t);var r=e[0],n=e[1],i=e[2],o=e[3],a=2*r,s=2*n,u=2*i,c=a*o,l=s*o,h=u*o,f=a*r,d=s*r,p=u*r,m=s*n,v=u*n,y=u*i;return t[0]=1-(m+y),t[1]=d+h,t[2]=p-l,t[4]=d-h,t[5]=1-(f+y),t[6]=v+c,t[8]=p+l,t[9]=v-c,t[10]=1-(f+m),t},quaternionToRotationMat4:function(e,t){var r=e[0],n=e[1],i=e[2],o=e[3],a=r+r,s=n+n,u=i+i,c=r*a,l=r*s,h=r*u,f=n*s,d=n*u,p=i*u,m=o*a,v=o*s,y=o*u;return t[0]=1-(f+p),t[4]=l-y,t[8]=h+v,t[1]=l+y,t[5]=1-(c+p),t[9]=d-m,t[2]=h-v,t[6]=d+m,t[10]=1-(c+f),t[3]=0,t[7]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},normalizeQuaternion:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:e,r=_.lenVec4([e[0],e[1],e[2],e[3]]);return t[0]=e[0]/r,t[1]=e[1]/r,t[2]=e[2]/r,t[3]=e[3]/r,t},conjugateQuaternion:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:e;return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=e[3],t},inverseQuaternion:function(e,t){return _.normalizeQuaternion(_.conjugateQuaternion(e,t))},quaternionToAngleAxis:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_.vec4(),r=(e=_.normalizeQuaternion(e,D))[3],n=2*Math.acos(r),i=Math.sqrt(1-r*r);return i<.001?(t[0]=e[0],t[1]=e[1],t[2]=e[2]):(t[0]=e[0]/i,t[1]=e[1]/i,t[2]=e[2]/i),t[3]=n,t},AABB3:function(e){return new E(e||6)},AABB2:function(e){return new E(e||4)},OBB3:function(e){return new E(e||32)},OBB2:function(e){return new E(e||16)},Sphere3:function(e,t,r,n){return new E([e,t,r,n])},transformOBB3:function(e,t){var r,n,i,o,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t,s=t.length,u=e[0],c=e[1],l=e[2],h=e[3],f=e[4],d=e[5],p=e[6],m=e[7],v=e[8],y=e[9],g=e[10],x=e[11],b=e[12],w=e[13],M=e[14],T=e[15];for(r=0;rs?a:s,o[1]+=u>c?u:c,o[2]+=l>h?l:h,Math.abs(_.lenVec3(o))}}(),getAABB3Center:function(e,t){var r=t||_.vec3();return r[0]=(e[0]+e[3])/2,r[1]=(e[1]+e[4])/2,r[2]=(e[2]+e[5])/2,r},getAABB2Center:function(e,t){var r=t||_.vec2();return r[0]=(e[2]+e[0])/2,r[1]=(e[3]+e[1])/2,r},collapseAABB3:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:_.AABB3();return e[0]=_.MAX_DOUBLE,e[1]=_.MAX_DOUBLE,e[2]=_.MAX_DOUBLE,e[3]=-_.MAX_DOUBLE,e[4]=-_.MAX_DOUBLE,e[5]=-_.MAX_DOUBLE,e},AABB3ToOBB3:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_.OBB3();return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=1,t[4]=e[3],t[5]=e[1],t[6]=e[2],t[7]=1,t[8]=e[3],t[9]=e[4],t[10]=e[2],t[11]=1,t[12]=e[0],t[13]=e[4],t[14]=e[2],t[15]=1,t[16]=e[0],t[17]=e[1],t[18]=e[5],t[19]=1,t[20]=e[3],t[21]=e[1],t[22]=e[5],t[23]=1,t[24]=e[3],t[25]=e[4],t[26]=e[5],t[27]=1,t[28]=e[0],t[29]=e[4],t[30]=e[5],t[31]=1,t},positions3ToAABB3:(n=new E(3),function(e,t,r){t=t||_.AABB3();for(var i,o,a,s=_.MAX_DOUBLE,u=_.MAX_DOUBLE,c=_.MAX_DOUBLE,l=-_.MAX_DOUBLE,h=-_.MAX_DOUBLE,f=-_.MAX_DOUBLE,d=0,p=e.length;dl&&(l=i),o>h&&(h=o),a>f&&(f=a);return t[0]=s,t[1]=u,t[2]=c,t[3]=l,t[4]=h,t[5]=f,t}),OBB3ToAABB3:function(e){for(var t,r,n,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_.AABB3(),o=_.MAX_DOUBLE,a=_.MAX_DOUBLE,s=_.MAX_DOUBLE,u=-_.MAX_DOUBLE,c=-_.MAX_DOUBLE,l=-_.MAX_DOUBLE,h=0,f=e.length;hu&&(u=t),r>c&&(c=r),n>l&&(l=n);return i[0]=o,i[1]=a,i[2]=s,i[3]=u,i[4]=c,i[5]=l,i},points3ToAABB3:function(e){for(var t,r,n,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_.AABB3(),o=_.MAX_DOUBLE,a=_.MAX_DOUBLE,s=_.MAX_DOUBLE,u=-_.MAX_DOUBLE,c=-_.MAX_DOUBLE,l=-_.MAX_DOUBLE,h=0,f=e.length;hu&&(u=t),r>c&&(c=r),n>l&&(l=n);return i[0]=o,i[1]=a,i[2]=s,i[3]=u,i[4]=c,i[5]=l,i},points3ToSphere3:function(){var e=new E(3);return function(t,r){r=r||_.vec4();var n,i=0,o=0,a=0,s=t.length;for(n=0;nc&&(c=u);return r[3]=c,r}}(),positions3ToSphere3:function(){var e=new E(3),t=new E(3);return function(r,n){n=n||_.vec4();var i,o=0,a=0,s=0,u=r.length,c=0;for(i=0;ic&&(c=l);return n[3]=c,n}}(),OBB3ToSphere3:function(){var e=new E(3),t=new E(3);return function(r,n){n=n||_.vec4();var i,o=0,a=0,s=0,u=r.length,c=u/4;for(i=0;ih&&(h=l);return n[3]=h,n}}(),getSphere3Center:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_.vec3();return t[0]=e[0],t[1]=e[1],t[2]=e[2],t},expandAABB3:function(e,t){return e[0]>t[0]&&(e[0]=t[0]),e[1]>t[1]&&(e[1]=t[1]),e[2]>t[2]&&(e[2]=t[2]),e[3]t[0]&&(e[0]=t[0]),e[1]>t[1]&&(e[1]=t[1]),e[2]>t[2]&&(e[2]=t[2]),e[3]3&&void 0!==arguments[3]?arguments[3]:_.vec3(),i=t[0]-e[0],o=t[1]-e[1],a=t[2]-e[2],s=r[0]-e[0],u=r[1]-e[1],c=r[2]-e[2],l=o*c-a*u,h=a*s-i*c,f=i*u-o*s,d=Math.sqrt(l*l+h*h+f*f);return 0===d?(n[0]=0,n[1]=0,n[2]=0):(n[0]=l/d,n[1]=h/d,n[2]=f/d),n}};function k(e,t,r,n){var i=e[t]/(Math.abs(e[t])+Math.abs(e[t+1])+Math.abs(e[t+2])),o=e[t+1]/(Math.abs(e[t])+Math.abs(e[t+1])+Math.abs(e[t+2]));if(e[t+2]<0){var a=(1-Math.abs(o))*(i>=0?1:-1),s=(1-Math.abs(i))*(o>=0?1:-1);i=a,o=s}return new Int8Array([Math[r](127.5*i+(i<0?-1:0)),Math[n](127.5*o+(o<0?-1:0))])}function N(e){var t=e[0],r=e[1];t/=t<0?127:128,r/=r<0?127:128;var n=1-Math.abs(t)-Math.abs(r);n<0&&(t=(1-Math.abs(r))*(t>=0?1:-1),r=(1-Math.abs(t))*(r>=0?1:-1));var i=Math.sqrt(t*t+r*r+n*n);return[t/i,r/i,n/i]}function V(e,t,r){return e[t]*r[0]+e[t+1]*r[1]+e[t+2]*r[2]}var B,F,C,U,z,X,R,K,q,Z,Y,Q,W,J,H,$,ee,te={quantizePositions:function(e,t,r,n){for(var i=r[0],o=r[1],a=r[2],s=65535,u=s/(r[3]-i),c=s/(r[4]-o),l=s/(r[5]-a),h=function(e){return e>=0?e:0},f=0;fu&&(a=o,u=s),(s=V(h,0,N(o=k(h,0,"floor","ceil"))))>u&&(a=o,u=s),(s=V(h,0,N(o=k(h,0,"ceil","ceil"))))>u&&(a=o,u=s),n[i+c+0]=a[0],n[i+c+1]=a[1],n[i+c+2]=0;return i+r},octEncodeNormals:function(e,t,r,n){for(var i,o,a,s,u=0;us&&(o=i,s=a),(a=V(e,u,N(i=k(e,u,"floor","ceil"))))>s&&(o=i,s=a),(a=V(e,u,N(i=k(e,u,"ceil","ceil"))))>s&&(o=i,s=a),r[n+u+0]=o[0],r[n+u+1]=o[1],r[n+u+2]=0;return n+t}},re=(B=[],F=[],C=[],U=[],z=[],X=0,R=new Uint16Array(3),K=new Uint16Array(3),q=new Uint16Array(3),Z=_.vec3(),Y=_.vec3(),Q=_.vec3(),W=_.vec3(),J=_.vec3(),H=_.vec3(),$=_.vec3(),ee=_.vec3(),function(e,t,r,n){!function(e,t){var r,n,i,o,a,s,u={},c=Math.pow(10,4),l=0;for(a=0,s=e.length;av&&T>v)continue}d=C[c.index1],p=C[c.index2],(!g&&d>65535||p>65535)&&(g=!0),m.push(d),m.push(p)}return g?new Uint32Array(m):new Uint16Array(m)}),ne=function(e,t,r,n){function i(e,r){for(var n,i,o=0;o<3;o++)if((n=t[3*e+o])!==(i=t[3*r+o]))return i-n;return 0}for(var o=e.slice().sort(i),a=null,s=0,u=o.length;sf&&h>d?f>d?(p=h,m=f,v=d):(p=h,m=d,v=f):f>h&&f>d?h>d?(p=f,m=h,v=d):(p=f,m=d,v=h):d>h&&d>f&&(h>f?(p=d,m=h,v=f):(p=d,m=f,v=h)),n[c+0]=[p,m],n[c+1]=[m,v],p>v){var y=v;v=p,p=y}n[c+2]=[v,p]}function g(e,t){for(var r,n,i=0;i<2;i++)if(r=e[i],(n=t[i])!==r)return n-r;return 0}(n=n.slice(0,e.length)).sort(g);for(var x=0,b=0;b0&&2!==x)};function ie(e){return ie="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ie(e)}function oe(e,t){for(var r=0;r1}}])&&ce(t.prototype,r),Object.defineProperty(t,"prototype",{writable:!1}),e}();function he(e){return he="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},he(e)}function fe(e,t){for(var r=0;r=0;--i){var o=this.tryEntries[i],a=o.completion;if("root"===o.tryLoc)return n("end");if(o.tryLoc<=this.prev){var s=r.call(o,"catchLoc"),u=r.call(o,"finallyLoc");if(s&&u){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),I(r),h}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var i=n.arg;I(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,r){return this.delegate={iterator:A(e),resultName:t,nextLoc:r},"next"===this.method&&(this.arg=void 0),h}},e}function Re(e,t,r,n,i,o,a){try{var s=e[o](a),u=s.value}catch(e){return void r(e)}s.done?t(u):Promise.resolve(u).then(n,i)}function Ke(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.modelId=t.modelId||"default",this.projectId=t.projectId||"",this.revisionId=t.revisionId||"",this.author=t.author||"",this.createdAt=t.createdAt||"",this.creatingApplication=t.creatingApplication||"",this.schema=t.schema||"",this.xktVersion=f.xktVersion,this.edgeThreshold=t.edgeThreshold||10,this.minTileSize=t.minTileSize||500,this.modelAABB=t.modelAABB,this.propertySets={},this.propertySetsList=[],this.metaObjects={},this.metaObjectsList=[],this.reusedGeometriesDecodeMatrix=new Float32Array(16),this.geometries={},this.geometriesList=[],this.textures={},this.texturesList=[],this.textureSets={},this.textureSetsList=[],this.meshes={},this.meshesList=[],this.entities={},this.entitiesList=[],this.tilesList=[],this.aabb=_.AABB3(),this.finalized=!1}var t,r,n,i;return t=e,r=[{key:"createPropertySet",value:function(e){if(!e)throw"Parameters expected: params";if(null===e.propertySetId||void 0===e.propertySetId)throw"Parameter expected: params.propertySetId";if(null===e.properties||void 0===e.properties)throw"Parameter expected: params.properties";if(this.finalized)console.error("XKTModel has been finalized, can't add more property sets");else if(!this.propertySets[e.propertySetId]){var t=e.propertySetId,r=e.propertySetType||"Default",n=e.propertySetName||e.propertySetId,i=e.properties||[],o=new Ee(t,r,n,i);return this.propertySets[t]=o,this.propertySetsList.push(o),o}}},{key:"createMetaObject",value:function(e){if(!e)throw"Parameters expected: params";if(null===e.metaObjectId||void 0===e.metaObjectId)throw"Parameter expected: params.metaObjectId";if(this.finalized)console.error("XKTModel has been finalized, can't add more meta objects");else if(!this.metaObjects[e.metaObjectId]){var t=e.metaObjectId,r=e.propertySetIds,n=e.metaObjectType||"Default",i=e.metaObjectName||e.metaObjectId,o=e.parentMetaObjectId,a=new Ae(t,r,n,i,o);return this.metaObjects[t]=a,this.metaObjectsList.push(a),o||this._rootMetaObject||(this._rootMetaObject=a),a}}},{key:"createTexture",value:function(e){if(!e)throw"Parameters expected: params";if(null===e.textureId||void 0===e.textureId)throw"Parameter expected: params.textureId";if(!e.imageData&&!e.src)throw"Parameter expected: params.imageData or params.src";if(this.finalized)console.error("XKTModel has been finalized, can't add more textures");else{if(!this.textures[e.textureId]){if(e.src){var t=e.src.split(".").pop();if("jpg"!==t&&"jpeg"!==t&&"png"!==t)return void console.error("XKTModel does not support image files with extension '".concat(t,"' - won't create texture '").concat(e.textureId))}var r=e.textureId,n=new _e({textureId:r,imageData:e.imageData,mediaType:e.mediaType,minFilter:e.minFilter,magFilter:e.magFilter,wrapS:e.wrapS,wrapT:e.wrapT,wrapR:e.wrapR,width:e.width,height:e.height,compressed:!1!==e.compressed,src:e.src});return this.textures[r]=n,this.texturesList.push(n),n}console.error("XKTTexture already exists with this ID: "+e.textureId)}}},{key:"createTextureSet",value:function(e){if(!e)throw"Parameters expected: params";if(null===e.textureSetId||void 0===e.textureSetId)throw"Parameter expected: params.textureSetId";if(this.finalized)console.error("XKTModel has been finalized, can't add more textureSets");else{if(!this.textureSets[e.textureSetId]){var t,r,n,i,o;if(void 0!==e.colorTextureId&&null!==e.colorTextureId){if(!(t=this.textures[e.colorTextureId]))return void console.error("Texture not found: ".concat(e.colorTextureId," - ensure that you create it first with createTexture()"));t.channel=0}if(void 0!==e.metallicRoughnessTextureId&&null!==e.metallicRoughnessTextureId){if(!(r=this.textures[e.metallicRoughnessTextureId]))return void console.error("Texture not found: ".concat(e.metallicRoughnessTextureId," - ensure that you create it first with createTexture()"));r.channel=1}if(void 0!==e.normalsTextureId&&null!==e.normalsTextureId){if(!(n=this.textures[e.normalsTextureId]))return void console.error("Texture not found: ".concat(e.normalsTextureId," - ensure that you create it first with createTexture()"));n.channel=2}if(void 0!==e.emissiveTextureId&&null!==e.emissiveTextureId){if(!(i=this.textures[e.emissiveTextureId]))return void console.error("Texture not found: ".concat(e.emissiveTextureId," - ensure that you create it first with createTexture()"));i.channel=3}if(void 0!==e.occlusionTextureId&&null!==e.occlusionTextureId){if(!(o=this.textures[e.occlusionTextureId]))return void console.error("Texture not found: ".concat(e.occlusionTextureId," - ensure that you create it first with createTexture()"));o.channel=4}var a=new Be({textureSetId:e.textureSetId,textureSetIndex:this.textureSetsList.length,colorTexture:t,metallicRoughnessTexture:r,normalsTexture:n,emissiveTexture:i,occlusionTexture:o});return this.textureSets[e.textureSetId]=a,this.textureSetsList.push(a),a}console.error("XKTTextureSet already exists with this ID: "+e.textureSetId)}}},{key:"createGeometry",value:function(e){if(!e)throw"Parameters expected: params";if(null===e.geometryId||void 0===e.geometryId)throw"Parameter expected: params.geometryId";if(!e.primitiveType)throw"Parameter expected: params.primitiveType";if(!e.positions)throw"Parameter expected: params.positions";var t="triangles"===e.primitiveType,r="points"===e.primitiveType,n="lines"===e.primitiveType,i="line-strip"===e.primitiveType,o="line-loop"===e.primitiveType;if(e.primitiveType,e.primitiveType,!(t||r||n||i||o))throw"Unsupported value for params.primitiveType: "+e.primitiveType+"' - supported values are 'triangles', 'points', 'lines', 'line-strip', 'triangle-strip' and 'triangle-fan";if(t&&!e.indices)throw e.indices=this._createDefaultIndices(),"Parameter expected for 'triangles' primitive: params.indices";if(r&&!e.colors&&!e.colorsCompressed)throw"Parameter expected for 'points' primitive: params.colors or params.colorsCompressed";if(n&&!e.indices)throw"Parameter expected for 'lines' primitive: params.indices";if(this.finalized)console.error("XKTModel has been finalized, can't add more geometries");else{if(!this.geometries[e.geometryId]){var a=e.geometryId,s=e.primitiveType,u=new Float64Array(e.positions),c={geometryId:a,geometryIndex:this.geometriesList.length,primitiveType:s,positions:u,uvs:e.uvs||e.uv};if(t&&(e.normals&&(c.normals=new Float32Array(e.normals)),e.indices?c.indices=e.indices:c.indices=this._createDefaultIndices(u.length/3)),r)if(e.colorsCompressed)c.colorsCompressed=new Uint8Array(e.colorsCompressed);else{for(var l=e.colors,h=new Uint8Array(l.length),f=0,d=l.length;f1)te.octEncodeNormals(n.normals,n.normals.length,n.normalsOctEncoded,0);else{var i=_.inverseMat4(_.transposeMat4(r.matrix,Ye),Qe);te.transformAndOctEncodeNormals(i,n.normals,n.normals.length,n.normalsOctEncoded,0)}}}},{key:"_createEntityAABBs",value:function(){for(var e=0,t=this.entitiesList.length;e1)for(var l=u.positions,h=0,f=l.length;hWe[i]&&(i=1),We[2]>We[i]&&(i=2),!e.left){var o=r.slice();if(o[i+3]=(r[i]+r[i+3])/2,e.left=new Me(o),_.containsAABB3(o,n))return void this._insertEntityIntoKDTree(e.left,t)}if(!e.right){var a=r.slice();if(a[i]=(r[i]+r[i+3])/2,e.right=new Me(a),_.containsAABB3(a,n))return void this._insertEntityIntoKDTree(e.right,t)}e.entities=e.entities||[],e.entities.push(t),_.expandAABB3(r,n)}}},{key:"_createTilesFromKDTree",value:function(e){this._createTilesFromKDNode(e)}},{key:"_createTilesFromKDNode",value:function(e){e.entities&&e.entities.length>0&&this._createTileFromEntities(e),e.left&&this._createTilesFromKDNode(e.left),e.right&&this._createTilesFromKDNode(e.right)}},{key:"_createTileFromEntities",value:function(e){var t=e.aabb,r=e.entities,n=_.getAABB3Center(t),i=_.mulVec3Scalar(n,-1,_.vec3()),o=_.AABB3();o[0]=t[0]-n[0],o[1]=t[1]-n[1],o[2]=t[2]-n[2],o[3]=t[3]-n[0],o[4]=t[4]-n[1],o[5]=t[5]-n[2];for(var a=0;a0){te.createPositionsDecodeMatrix(t,this.reusedGeometriesDecodeMatrix);for(var c=0,l=this.geometriesList.length;ce&&(e=i.positionsQuantized.length),i.indices.length>t&&(t=i.indices.length))}for(var o=new Array(e/3),a=new Array(t),s=0,u=this.geometriesList.length;s1&&(S+=16);var G={metadata:{},textureData:new Uint8Array(A),eachTextureDataPortion:new Uint32Array(p),eachTextureAttributes:new Uint16Array(p*tt),positions:new Uint16Array(x),normals:new Int8Array(b),colors:new Uint8Array(w),uvs:new Float32Array(M),indices:new Uint32Array(T),edgeIndices:new Uint32Array(I),eachTextureSetTextures:new Int32Array(5*m),matrices:new Float32Array(S),reusedGeometriesDecodeMatrix:new Float32Array(e.reusedGeometriesDecodeMatrix),eachGeometryPrimitiveType:new Uint8Array(d),eachGeometryPositionsPortion:new Uint32Array(d),eachGeometryNormalsPortion:new Uint32Array(d),eachGeometryColorsPortion:new Uint32Array(d),eachGeometryUVsPortion:new Uint32Array(d),eachGeometryIndicesPortion:new Uint32Array(d),eachGeometryEdgeIndicesPortion:new Uint32Array(d),eachMeshGeometriesPortion:new Uint32Array(v),eachMeshMatricesPortion:new Uint32Array(v),eachMeshTextureSet:new Int32Array(v),eachMeshMaterialAttributes:new Uint8Array(v*rt),eachEntityId:[],eachEntityMeshesPortion:new Uint32Array(y),eachTileAABB:new Float64Array(6*g),eachTileEntitiesPortion:new Uint32Array(g)},D=0,_=0,k=0,N=0,V=0,B=0;G.metadata={id:e.modelId,projectId:e.projectId,revisionId:e.revisionId,author:e.author,createdAt:e.createdAt,creatingApplication:e.creatingApplication,schema:e.schema,propertySets:[],metaObjects:[]};for(var F=0;F0&&(R.propertySetIds=X.propertySetIds),X.external&&(R.external=X.external),G.metadata.metaObjects.push(R)}for(var K=0;K1&&(G.matrices.set(xe.matrix,se),G.eachMeshMatricesPortion[ue]=se,se+=16),G.eachMeshTextureSet[ue]=xe.textureSet?xe.textureSet.textureSetIndex:-1,G.eachMeshMaterialAttributes[ae++]=255*xe.color[0],G.eachMeshMaterialAttributes[ae++]=255*xe.color[1],G.eachMeshMaterialAttributes[ae++]=255*xe.color[2],G.eachMeshMaterialAttributes[ae++]=255*xe.opacity,G.eachMeshMaterialAttributes[ae++]=255*xe.metallic,G.eachMeshMaterialAttributes[ae++]=255*xe.roughness,ue++}G.eachEntityId[ie]=me.entityId,G.eachEntityMeshesPortion[ie]=oe,ie++,oe+=ye}var we=6*ce;G.eachTileAABB.set(de,we)}}return G}(e,t,r),o=function(e,t,r){function n(e){return!1!==r.zip?$e.deflate(e):e}return{metadata:n(it(t||e.metadata)),textureData:n(e.textureData.buffer),eachTextureDataPortion:n(e.eachTextureDataPortion.buffer),eachTextureAttributes:n(e.eachTextureAttributes.buffer),positions:n(e.positions.buffer),normals:n(e.normals.buffer),colors:n(e.colors.buffer),uvs:n(e.uvs.buffer),indices:n(e.indices.buffer),edgeIndices:n(e.edgeIndices.buffer),eachTextureSetTextures:n(e.eachTextureSetTextures.buffer),matrices:n(e.matrices.buffer),reusedGeometriesDecodeMatrix:n(e.reusedGeometriesDecodeMatrix.buffer),eachGeometryPrimitiveType:n(e.eachGeometryPrimitiveType.buffer),eachGeometryPositionsPortion:n(e.eachGeometryPositionsPortion.buffer),eachGeometryNormalsPortion:n(e.eachGeometryNormalsPortion.buffer),eachGeometryColorsPortion:n(e.eachGeometryColorsPortion.buffer),eachGeometryUVsPortion:n(e.eachGeometryUVsPortion.buffer),eachGeometryIndicesPortion:n(e.eachGeometryIndicesPortion.buffer),eachGeometryEdgeIndicesPortion:n(e.eachGeometryEdgeIndicesPortion.buffer),eachMeshGeometriesPortion:n(e.eachMeshGeometriesPortion.buffer),eachMeshMatricesPortion:n(e.eachMeshMatricesPortion.buffer),eachMeshTextureSet:n(e.eachMeshTextureSet.buffer),eachMeshMaterialAttributes:n(e.eachMeshMaterialAttributes.buffer),eachEntityId:n(JSON.stringify(e.eachEntityId).replace(/[\u007F-\uFFFF]/g,(function(e){return"\\u"+("0000"+e.charCodeAt(0).toString(16)).substr(-4)}))),eachEntityMeshesPortion:n(e.eachEntityMeshesPortion.buffer),eachTileAABB:n(e.eachTileAABB.buffer),eachTileEntitiesPortion:n(e.eachTileEntitiesPortion.buffer)}}(i,t,n);r.texturesSize+=o.textureData.byteLength;var a=function(e){return function(e){var t=new Uint32Array(e.length+2);t[0]=et,t[1]=e.length;for(var r=0,n=0,i=e.length;n80*r){n=o=e[0],i=a=e[1];for(var p=r;po&&(o=s),u>a&&(a=u);c=0!==(c=Math.max(o-n,a-i))?1/c:0}return ut(f,d,r,n,i,c),d}function at(e,t,r,n,i){var o,a;if(i===Et(e,t,r,n)>0)for(o=t;o=t;o-=n)a=Ot(o,e[o],e[o+1],a);return a&&wt(a,a.next)&&(Pt(a),a=a.next),a}function st(e,t){if(!e)return e;t||(t=e);var r,n=e;do{if(r=!1,n.steiner||!wt(n,n.next)&&0!==bt(n.prev,n,n.next))n=n.next;else{if(Pt(n),(n=t=n.prev)===n.next)break;r=!0}}while(r||n!==t);return t}function ut(e,t,r,n,i,o,a){if(e){!a&&o&&function(e,t,r,n){var i=e;do{null===i.z&&(i.z=vt(i.x,i.y,t,r,n)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next}while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,function(e){var t,r,n,i,o,a,s,u,c=1;do{for(r=e,e=null,o=null,a=0;r;){for(a++,n=r,s=0,t=0;t0||u>0&&n;)0!==s&&(0===u||!n||r.z<=n.z)?(i=r,r=r.nextZ,s--):(i=n,n=n.nextZ,u--),o?o.nextZ=i:e=i,i.prevZ=o,o=i;r=n}o.nextZ=null,c*=2}while(a>1)}(i)}(e,n,i,o);for(var s,u,c=e;e.prev!==e.next;)if(s=e.prev,u=e.next,o?lt(e,n,i,o):ct(e))t.push(s.i/r),t.push(e.i/r),t.push(u.i/r),Pt(e),e=u.next,c=u.next;else if((e=u)===c){a?1===a?ut(e=ht(st(e),t,r),t,r,n,i,o,2):2===a&&ft(e,t,r,n,i,o):ut(st(e),t,r,n,i,o,1);break}}}function ct(e){var t=e.prev,r=e,n=e.next;if(bt(t,r,n)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(gt(t.x,t.y,r.x,r.y,n.x,n.y,i.x,i.y)&&bt(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function lt(e,t,r,n){var i=e.prev,o=e,a=e.next;if(bt(i,o,a)>=0)return!1;for(var s=i.xo.x?i.x>a.x?i.x:a.x:o.x>a.x?o.x:a.x,l=i.y>o.y?i.y>a.y?i.y:a.y:o.y>a.y?o.y:a.y,h=vt(s,u,t,r,n),f=vt(c,l,t,r,n),d=e.prevZ,p=e.nextZ;d&&d.z>=h&&p&&p.z<=f;){if(d!==e.prev&&d!==e.next&>(i.x,i.y,o.x,o.y,a.x,a.y,d.x,d.y)&&bt(d.prev,d,d.next)>=0)return!1;if(d=d.prevZ,p!==e.prev&&p!==e.next&>(i.x,i.y,o.x,o.y,a.x,a.y,p.x,p.y)&&bt(p.prev,p,p.next)>=0)return!1;p=p.nextZ}for(;d&&d.z>=h;){if(d!==e.prev&&d!==e.next&>(i.x,i.y,o.x,o.y,a.x,a.y,d.x,d.y)&&bt(d.prev,d,d.next)>=0)return!1;d=d.prevZ}for(;p&&p.z<=f;){if(p!==e.prev&&p!==e.next&>(i.x,i.y,o.x,o.y,a.x,a.y,p.x,p.y)&&bt(p.prev,p,p.next)>=0)return!1;p=p.nextZ}return!0}function ht(e,t,r){var n=e;do{var i=n.prev,o=n.next.next;!wt(i,o)&&Mt(i,n,n.next,o)&&St(i,o)&&St(o,i)&&(t.push(i.i/r),t.push(n.i/r),t.push(o.i/r),Pt(n),Pt(n.next),n=e=o),n=n.next}while(n!==e);return st(n)}function ft(e,t,r,n,i,o){var a=e;do{for(var s=a.next.next;s!==a.prev;){if(a.i!==s.i&&xt(a,s)){var u=At(a,s);return a=st(a,a.next),u=st(u,u.next),ut(a,t,r,n,i,o),void ut(u,t,r,n,i,o)}s=s.next}a=a.next}while(a!==e)}function dt(e,t){return e.x-t.x}function pt(e,t){if(t=function(e,t){var r,n=t,i=e.x,o=e.y,a=-1/0;do{if(o<=n.y&&o>=n.next.y&&n.next.y!==n.y){var s=n.x+(o-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(s<=i&&s>a){if(a=s,s===i){if(o===n.y)return n;if(o===n.next.y)return n.next}r=n.x=n.x&&n.x>=l&&i!==n.x&>(or.x||n.x===r.x&&mt(r,n)))&&(r=n,f=u)),n=n.next}while(n!==c);return r}(e,t),t){var r=At(t,e);st(t,t.next),st(r,r.next)}}function mt(e,t){return bt(e.prev,e,t.prev)<0&&bt(t.next,e,e.next)<0}function vt(e,t,r,n,i){return(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=32767*(e-r)*i)|e<<8))|e<<4))|e<<2))|e<<1))|(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=32767*(t-n)*i)|t<<8))|t<<4))|t<<2))|t<<1))<<1}function yt(e){var t=e,r=e;do{(t.x=0&&(e-a)*(n-s)-(r-a)*(t-s)>=0&&(r-a)*(o-s)-(i-a)*(n-s)>=0}function xt(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!function(e,t){var r=e;do{if(r.i!==e.i&&r.next.i!==e.i&&r.i!==t.i&&r.next.i!==t.i&&Mt(r,r.next,e,t))return!0;r=r.next}while(r!==e);return!1}(e,t)&&(St(e,t)&&St(t,e)&&function(e,t){var r=e,n=!1,i=(e.x+t.x)/2,o=(e.y+t.y)/2;do{r.y>o!=r.next.y>o&&r.next.y!==r.y&&i<(r.next.x-r.x)*(o-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next}while(r!==e);return n}(e,t)&&(bt(e.prev,e,t.prev)||bt(e,t.prev,t))||wt(e,t)&&bt(e.prev,e,e.next)>0&&bt(t.prev,t,t.next)>0)}function bt(e,t,r){return(t.y-e.y)*(r.x-t.x)-(t.x-e.x)*(r.y-t.y)}function wt(e,t){return e.x===t.x&&e.y===t.y}function Mt(e,t,r,n){var i=It(bt(e,t,r)),o=It(bt(e,t,n)),a=It(bt(r,n,e)),s=It(bt(r,n,t));return i!==o&&a!==s||!(0!==i||!Tt(e,r,t))||!(0!==o||!Tt(e,n,t))||!(0!==a||!Tt(r,e,n))||!(0!==s||!Tt(r,t,n))}function Tt(e,t,r){return t.x<=Math.max(e.x,r.x)&&t.x>=Math.min(e.x,r.x)&&t.y<=Math.max(e.y,r.y)&&t.y>=Math.min(e.y,r.y)}function It(e){return e>0?1:e<0?-1:0}function St(e,t){return bt(e.prev,e,e.next)<0?bt(e,t,e.next)>=0&&bt(e,e.prev,t)>=0:bt(e,t,e.prev)<0||bt(e,e.next,t)<0}function At(e,t){var r=new Lt(e.i,e.x,e.y),n=new Lt(t.i,t.x,t.y),i=e.next,o=t.prev;return e.next=t,t.prev=e,r.next=i,i.prev=r,n.next=r,r.prev=n,o.next=n,n.prev=o,n}function Ot(e,t,r,n){var i=new Lt(e,t,r);return n?(i.next=n.next,i.prev=n,n.next.prev=i,n.next=i):(i.prev=i,i.next=i),i}function Pt(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function Lt(e,t,r){this.i=e,this.x=t,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function Et(e,t,r,n){for(var i=0,o=t,a=r-n;oe.length)&&(t=e.length);for(var r=0,n=new Array(t);r0&&(n+=e[i-1].length,r.holes.push(n))}return r};var Dt=_.vec2(),_t=_.vec3(),kt=_.vec3(),Nt=_.vec3();function Vt(e){var t=e.data,r=e.xktModel,n=e.center,i=void 0!==n&&n,o=e.transform,a=void 0===o?null:o,s=e.stats,u=void 0===s?{}:s,c=e.log;return new Promise((function(e,n){if(t)if("CityJSON"===t.type)if(r){var o;c("Using parser: parseCityJSONIntoXKTModel"),c("center: ".concat(i)),a&&c("transform: [".concat(a,"]")),t.transform||i||a?(o=function(e){for(var t=[],r=0,n=0;r0){for(var c=[],l=0,h=t.geometry.length;l0){var x=y[g[0]];if(void 0!==x.value)d=v[x.value];else{var b=x.values;if(b){p=[];for(var w=0,M=b.length;w0&&(n.createEntity({entityId:r,meshIds:c}),e.stats.numObjects++)}}function Ct(e,t,r,n){switch(t.type){case"MultiPoint":case"MultiLineString":case"GeometryInstance":break;case"MultiSurface":case"CompositeSurface":Ut(e,r,t.boundaries,n);break;case"Solid":for(var i=t.boundaries,o=0;o0&&l.push(c.length);var p=Rt(e,s[d],h,f);c.push.apply(c,jt(p))}if(3===c.length)f.indices.push(c[0]),f.indices.push(c[1]),f.indices.push(c[2]);else if(c.length>3){for(var m=[],v=0;v0&&s.push(a.length);var c=Rt(e,t[o][u],r,n);a.push.apply(a,jt(c))}if(3===a.length)n.indices.push(a[0]),n.indices.push(a[1]),n.indices.push(a[2]);else if(a.length>3){for(var l=[],h=0;h0)for(var c=0;c0&&o.createEntity({entityId:b,meshIds:w}),e.stats.numObjects++,rr=tr.length>0?tr[tr.length-1]:null}}var ir="undefined"!=typeof atob?atob:function(e){return Buffer.from(e,"base64").toString("binary")},or={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},ar={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16};function sr(e){var t=e.data,r=e.xktModel,n=e.metaModelData,i=e.includeNormals,o=e.reuseGeometries,a=e.getAttachment,s=e.stats,u=void 0===s?{}:s,c=e.log;return c&&c("Using parser: parseGLTFJSONIntoXKTModel"),new Promise((function(e,s){if(t)if(r){u.sourceFormat="glTF",u.schemaVersion="2.0",u.title="",u.author="",u.created="",u.numTriangles=0,u.numVertices=0,u.numNormals=0,u.numObjects=0,u.numGeometries=0;var l={gltf:t,metaModelCorrections:n?ur(n):null,getAttachment:a||function(){throw new Error("You must define getAttachment() method to convert glTF with external resources")},log:c||function(e){},xktModel:r,includeNormals:i,createXKTGeometryIds:{},nextMeshId:0,reuseGeometries:!1!==o,stats:u};l.log("Parsing normals: ".concat(l.includeNormals?"enabled":"disabled")),function(e){var t=e.gltf.buffers;return t?Promise.all(t.map((function(t){return function(e,t){return new Promise((function(r,n){if(t._arrayBuffer)return t._buffer=t._arrayBuffer,void r(t);var i=t.uri;i?function(e,t){return new Promise((function(r,n){var i=t.match(/^data:(.*?)(;base64)?,(.*)$/);if(i){var o=!!i[2],a=i[3];a=decodeURIComponent(a),o&&(a=ir(a));for(var s=new ArrayBuffer(a.length),u=new Uint8Array(s),c=0;c0)for(var l=0;l0){null==j&&e.log("[parseGLTFJSONIntoXKTModel] Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT");var G=j;if(null==G)for(a.entities[G]&&e.error("Two or more glTF nodes found with same 'name' attribute: '"+j+"'");!G||a.entities[G];)G="entity-"+e.nextId++;if(e.metaModelCorrections){var D=e.metaModelCorrections.eachChildRoot[G];if(D){var k=e.metaModelCorrections.eachRootStats[D.id];k.countChildren++,k.countChildren>=k.numChildren&&(a.createEntity({entityId:D.id,meshIds:hr}),e.stats.numObjects++,hr=[])}else e.metaModelCorrections.metaObjectsMap[G]&&(a.createEntity({entityId:G,meshIds:hr}),e.stats.numObjects++,hr=[])}else a.createEntity({entityId:G,meshIds:hr}),e.stats.numObjects++,hr=[]}}function dr(e){if(!e.attributes)return"empty";var t=e.mode,r=(e.material,e.indices),n=e.attributes.POSITION,i=e.attributes.NORMAL,o=e.attributes.COLOR_0,a=e.attributes.TEXCOORD_0;return[t,null!=r?r:"-",null!=n?n:"-",null!=i?i:"-",null!=o?o:"-",null!=a?a:"-"].join(";")}function pr(e,t,r){var n=t.attributes;if(n){switch(t.mode){case 0:r.primitive="points";break;case 1:case 2:case 3:r.primitive="lines";break;case 4:default:r.primitive="triangles";break;case 5:console.log("TRIANGLE_STRIP"),r.primitive="triangles";break;case 6:console.log("TRIANGLE_FAN"),r.primitive="triangles"}var i=e.gltf.accessors,o=t.indices;if(null!=o){var a=i[o];r.indices=mr(e,a)}var s=n.POSITION;if(null!=s){var u=i[s];r.positions=mr(e,u)}var c=n.NORMAL;if(null!=c){var l=i[c];r.normals=mr(e,l)}var h=n.COLOR_0;if(null!=h){var f=i[h];r.colors=mr(e,f)}}}function mr(e,t){var r=e.gltf.bufferViews[t.bufferView],n=ar[t.type],i=or[t.componentType],o=i.BYTES_PER_ELEMENT*n;if(t.byteStride&&t.byteStride!==o)throw new Error("interleaved buffer!");return new i(r._buffer,t.byteOffset||0,t.count*n)}function vr(e){var t=e.WebIFC,r=e.data,n=e.xktModel,i=e.autoNormals,o=void 0===i||i,a=e.includeTypes,s=e.excludeTypes,u=e.wasmPath,c=e.stats,l=void 0===c?{}:c,h=e.log;return h&&h("Using parser: parseIFCIntoXKTModel"),new Promise((function(e,i){if(r)if(n)if(u){var c=new t.IfcAPI;u&&c.SetWasmPath(u),c.Init().then((function(){var i=new Uint8Array(r),u=c.OpenModel(i);l.sourceFormat="IFC",l.schemaVersion="",l.title="",l.author="",l.created="",l.numMetaObjects=0,l.numPropertySets=0,l.numObjects=0,l.numGeometries=0,l.numTriangles=0,l.numVertices=0;var f={WebIFC:t,modelID:u,ifcAPI:c,xktModel:n,autoNormals:o,log:h||function(e){},nextId:0,stats:l};if(a){f.includeTypes={};for(var d=0,p=a.length;d0){for(var d=o.Name.value,p=[],m=0,v=f.length;m0&&(e.xktModel.createEntity({entityId:o,meshIds:i}),e.stats.numObjects++)}else console.log("excluding: "+a)}const br=require("@loaders.gl/las");var wr=5e5;function Mr(e){var t=e.data,r=e.xktModel,n=e.center,i=void 0!==n&&n,o=e.transform,a=void 0===o?null:o,s=e.colorDepth,u=void 0===s?"auto":s,c=e.fp64,l=void 0!==c&&c,h=e.skip,f=void 0===h?1:h,d=e.stats,p=e.log,m=void 0===p?function(){}:p;return m&&m("Using parser: parseLASIntoXKTModel"),new Promise((function(e,n){t?r?(m("Converting LAZ/LAS"),m("center: ".concat(i)),a&&m("transform: [".concat(a,"]")),m("colorDepth: ".concat(u)),m("fp64: ".concat(l)),m("skip: ".concat(f)),(0,Fe.parse)(t,br.LASLoader,{las:{colorDepth:u,fp64:l}}).then((function(t){var n=t.attributes,o=t.loaderData,s=void 0!==o.pointsFormatId?o.pointsFormatId:-1;if(n.POSITION){var u={};switch(s){case 0:if(!n.intensity)return void m("No intensities found in file (expected for LAS point format 0)");u=y(n.POSITION,n.intensity);break;case 1:if(!n.intensity)return void m("No intensities found in file (expected for LAS point format 1)");u=y(n.POSITION,n.intensity);break;case 2:if(!n.intensity)return void m("No intensities found in file (expected for LAS point format 2)");u=v(n.POSITION,n.COLOR_0,n.intensity);break;case 3:if(!n.intensity)return void m("No intensities found in file (expected for LAS point format 3)");u=v(n.POSITION,n.COLOR_0,n.intensity)}for(var c=g(function(e){if(e){if(i){for(var t=_.vec3(),r=e.length,n=0,o=e.length;n=e.length)return[e];for(var r=[],n=0;n0?P:null}),M++}}o&&o("Converted meta objects: "+M),e()}))}function Ir(e){var t=e.data,r=e.xktModel,n=e.littleEndian,i=void 0===n||n,o=e.stats,a=e.log;return a&&a("Using parser: parsePCDIntoXKTModel"),new Promise((function(e,n){var s=function(e){if("undefined"!=typeof TextDecoder)return(new TextDecoder).decode(e);for(var t="",r=0,n=e.length;r>16&255,g=v>>8&255,x=v>>0&255;l.push(y,g,x,255)}else l.push(255),l.push(255),l.push(255)}if("binary_compressed"===u.data)for(var b=new Uint32Array(t.slice(u.headerLen,u.headerLen+8)),w=b[0],M=b[1],T=function(e,t){var r,n,i,o=e.length,a=new Uint8Array(t),s=0,u=0;do{if((r=e[s++])<32){if(u+ ++r>t)throw new Error("Output buffer is not large enough");if(s+r>o)throw new Error("Invalid compressed data");do{a[u++]=e[s++]}while(--r)}else{if(n=r>>5,i=u-((31&r)<<8)-1,s>=o)throw new Error("Invalid compressed data");if(7===n&&(n+=e[s++],s>=o))throw new Error("Invalid compressed data");if(i-=e[s++],u+n+2>t)throw new Error("Output buffer is not large enough");if(i<0)throw new Error("Invalid compressed data");if(i>=u)throw new Error("Invalid compressed data");do{a[u++]=a[i++]}while(2+--n)}}while(s0?l:null}),r.createMesh({meshId:"pointsMesh",geometryId:"pointsGeometry"}),r.createEntity({entityId:"geometries",meshIds:["pointsMesh"]}),a&&(a("Converted drawable objects: 1"),a("Converted geometries: 1"),a("Converted vertices: "+c.length/3)),o&&(o.sourceFormat="PCD",o.schemaVersion="",o.title="",o.author="",o.created="",o.numObjects=1,o.numGeometries=1,o.numVertices=c.length/3),e()}))}const Sr=require("@loaders.gl/ply");function Ar(e){return Ar="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ar(e)}function Or(){Or=function(){return e};var e={},t=Object.prototype,r=t.hasOwnProperty,n=Object.defineProperty||function(e,t,r){e[t]=r.value},i="function"==typeof Symbol?Symbol:{},o=i.iterator||"@@iterator",a=i.asyncIterator||"@@asyncIterator",s=i.toStringTag||"@@toStringTag";function u(e,t,r){return Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{u({},"")}catch(e){u=function(e,t,r){return e[t]=r}}function c(e,t,r,i){var o=t&&t.prototype instanceof f?t:f,a=Object.create(o.prototype),s=new S(i||[]);return n(a,"_invoke",{value:w(e,r,s)}),a}function l(e,t,r){try{return{type:"normal",arg:e.call(t,r)}}catch(e){return{type:"throw",arg:e}}}e.wrap=c;var h={};function f(){}function d(){}function p(){}var m={};u(m,o,(function(){return this}));var v=Object.getPrototypeOf,y=v&&v(v(A([])));y&&y!==t&&r.call(y,o)&&(m=y);var g=p.prototype=f.prototype=Object.create(m);function x(e){["next","throw","return"].forEach((function(t){u(e,t,(function(e){return this._invoke(t,e)}))}))}function b(e,t){function i(n,o,a,s){var u=l(e[n],e,o);if("throw"!==u.type){var c=u.arg,h=c.value;return h&&"object"==Ar(h)&&r.call(h,"__await")?t.resolve(h.__await).then((function(e){i("next",e,a,s)}),(function(e){i("throw",e,a,s)})):t.resolve(h).then((function(e){c.value=e,a(c)}),(function(e){return i("throw",e,a,s)}))}s(u.arg)}var o;n(this,"_invoke",{value:function(e,r){function n(){return new t((function(t,n){i(e,r,t,n)}))}return o=o?o.then(n,n):n()}})}function w(e,t,r){var n="suspendedStart";return function(i,o){if("executing"===n)throw new Error("Generator is already running");if("completed"===n){if("throw"===i)throw o;return{value:void 0,done:!0}}for(r.method=i,r.arg=o;;){var a=r.delegate;if(a){var s=M(a,r);if(s){if(s===h)continue;return s}}if("next"===r.method)r.sent=r._sent=r.arg;else if("throw"===r.method){if("suspendedStart"===n)throw n="completed",r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);n="executing";var u=l(e,t,r);if("normal"===u.type){if(n=r.done?"completed":"suspendedYield",u.arg===h)continue;return{value:u.arg,done:r.done}}"throw"===u.type&&(n="completed",r.method="throw",r.arg=u.arg)}}}function M(e,t){var r=t.method,n=e.iterator[r];if(void 0===n)return t.delegate=null,"throw"===r&&e.iterator.return&&(t.method="return",t.arg=void 0,M(e,t),"throw"===t.method)||"return"!==r&&(t.method="throw",t.arg=new TypeError("The iterator does not provide a '"+r+"' method")),h;var i=l(n,e.iterator,t.arg);if("throw"===i.type)return t.method="throw",t.arg=i.arg,t.delegate=null,h;var o=i.arg;return o?o.done?(t[e.resultName]=o.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=void 0),t.delegate=null,h):o:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,h)}function T(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function I(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function S(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(T,this),this.reset(!0)}function A(e){if(e){var t=e[o];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var n=-1,i=function t(){for(;++n=0;--i){var o=this.tryEntries[i],a=o.completion;if("root"===o.tryLoc)return n("end");if(o.tryLoc<=this.prev){var s=r.call(o,"catchLoc"),u=r.call(o,"finallyLoc");if(s&&u){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),I(r),h}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var i=n.arg;I(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,r){return this.delegate={iterator:A(e),resultName:t,nextLoc:r},"next"===this.method&&(this.arg=void 0),h}},e}function Pr(e,t,r,n,i,o,a){try{var s=e[o](a),u=s.value}catch(e){return void r(e)}s.done?t(u):Promise.resolve(u).then(n,i)}function Lr(e){return Er.apply(this,arguments)}function Er(){var e;return e=Or().mark((function e(t){var r,n,i,o,a,s,u,c,l,h,f;return Or().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=t.data,n=t.xktModel,i=t.stats,(o=t.log)&&o("Using parser: parsePLYIntoXKTModel"),r){e.next=4;break}throw"Argument expected: data";case 4:if(n){e.next=6;break}throw"Argument expected: xktModel";case 6:return e.prev=6,e.next=9,(0,Fe.parse)(r,Sr.PLYLoader);case 9:a=e.sent,e.next=16;break;case 12:return e.prev=12,e.t0=e.catch(6),o&&o("Error: "+e.t0),e.abrupt("return");case 16:if(s=a.attributes,u=!!s.COLOR_0){for(c=u?s.COLOR_0.value:null,l=[],h=0,f=c.length;h=0;--i){var o=this.tryEntries[i],a=o.completion;if("root"===o.tryLoc)return n("end");if(o.tryLoc<=this.prev){var s=r.call(o,"catchLoc"),u=r.call(o,"finallyLoc");if(s&&u){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),I(r),h}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var i=n.arg;I(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,r){return this.delegate={iterator:A(e),resultName:t,nextLoc:r},"next"===this.method&&(this.arg=void 0),h}},e}function Dr(e,t,r,n,i,o,a){try{var s=e[o](a),u=s.value}catch(e){return void r(e)}s.done?t(u):Promise.resolve(u).then(n,i)}function _r(e){return kr.apply(this,arguments)}function kr(){var e;return e=Gr().mark((function e(t){var r,n,i,o,a,s,u,c;return Gr().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=t.data,n=t.splitMeshes,i=t.autoNormals,o=t.smoothNormals,a=t.smoothNormalsAngleThreshold,s=t.xktModel,u=t.stats,(c=t.log)&&c("Using parser: parseSTLIntoXKTModel"),e.abrupt("return",new Promise((function(e,t){if(r)if(s){var l=_.createUUID(),h=s.createMetaObject({metaObjectId:l,metaObjectType:"Model",metaObjectName:"Model"}),f={data:r,splitMeshes:n,autoNormals:i,smoothNormals:o,smoothNormalsAngleThreshold:a,xktModel:s,rootMetaObject:h,nextId:0,log:c||function(e){},stats:{numObjects:0,numGeometries:0,numTriangles:0,numVertices:0}},d=Ur(r);Nr(d)?Vr(f,d):Br(f,"string"!=typeof(p=r)?function(e){if("undefined"!=typeof TextDecoder)return(new TextDecoder).decode(e);for(var t="",r=0,n=e.length;r>5&31)/31,i=(S>>10&31)/31):(r=a,n=s,i=u),(x&&r!==f||n!==d||i!==p)&&(null!==f&&(m=!0),f=r,d=n,p=i)}for(var A=1;A<=3;A++){var O=w+12*A;y.push(c.getFloat32(O,!0)),y.push(c.getFloat32(O+4,!0)),y.push(c.getFloat32(O+8,!0)),e.autoNormals||g.push(M,T,I),h&&o.push(r,n,i,1)}x&&m&&(Cr(e,y,g,o),y=[],g=[],o=o?[]:null,m=!1)}y.length>0&&Cr(e,y,g,o)}function Br(e,t){for(var r,n,i,o,a,s,u,c=/facet([\s\S]*?)endfacet/g,l=0,h=/[\s]+([+-]?(?:\d+.\d+|\d+.|\d+|.\d+)(?:[eE][+-]?\d+)?)/.source,f=new RegExp("vertex"+h+h+h,"g"),d=new RegExp("normal"+h+h+h,"g"),p=[],m=[];null!==(o=c.exec(t));){for(a=0,s=0,u=o[0];null!==(o=d.exec(u));)r=parseFloat(o[1]),n=parseFloat(o[2]),i=parseFloat(o[3]),s++;for(;null!==(o=f.exec(u));)p.push(parseFloat(o[1]),parseFloat(o[2]),parseFloat(o[3])),m.push(r,n,i),a++;if(1!==s)return e.log("Error in normal of face "+l),-1;if(3!==a)return e.log("Error in positions of face "+l),-1;l++}Cr(e,p,m,null)}var Fr=0;function Cr(e,t,r,n){for(var i=new Int32Array(t.length/3),o=0,a=i.length;o0?r:null,n=n&&n.length>0?n:null,!e.autoNormals&&e.smoothNormals&&function(e,t){var r,n,i,o,a,s,u,c,l,h,f,d=(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).smoothNormalsAngleThreshold||20,p={},m=[],v={},y=Math.pow(10,4);for(u=0,l=e.length;u0&&void 0!==arguments[0]?arguments[0]:{},t=e.xSize||1;t<0&&(console.error("negative xSize not allowed - will invert"),t*=-1);var r=e.ySize||1;r<0&&(console.error("negative ySize not allowed - will invert"),r*=-1);var n=e.zSize||1;n<0&&(console.error("negative zSize not allowed - will invert"),n*=-1);var i=e.center,o=i?i[0]:0,a=i?i[1]:0,s=i?i[2]:0,u=-t+o,c=-r+a,l=-n+s,h=t+o,f=r+a,d=n+s;return{primitiveType:"triangles",positions:[h,f,d,u,f,d,u,c,d,h,c,d,h,f,d,h,c,d,h,c,l,h,f,l,h,f,d,h,f,l,u,f,l,u,f,d,u,f,d,u,f,l,u,c,l,u,c,d,u,c,l,h,c,l,h,c,d,u,c,d,h,c,l,u,c,l,u,f,l,h,f,l],normals:[0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1],uv:[1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0],indices:[0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,12,13,14,12,14,15,16,17,18,16,18,19,20,21,22,20,22,23]}}function Xr(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.xSize||1;t<0&&(console.error("negative xSize not allowed - will invert"),t*=-1);var r=e.ySize||1;r<0&&(console.error("negative ySize not allowed - will invert"),r*=-1);var n=e.zSize||1;n<0&&(console.error("negative zSize not allowed - will invert"),n*=-1);var i=e.center,o=i?i[0]:0,a=i?i[1]:0,s=i?i[2]:0,u=-t+o,c=-r+a,l=-n+s,h=t+o,f=r+a,d=n+s;return{primitiveType:"lines",positions:[u,c,l,u,c,d,u,f,l,u,f,d,h,c,l,h,c,d,h,f,l,h,f,d],indices:[0,1,1,3,3,2,2,0,4,5,5,7,7,6,6,4,0,4,1,5,2,6,3,7]}}function Rr(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.radiusTop||1;t<0&&(console.error("negative radiusTop not allowed - will invert"),t*=-1);var r=e.radiusBottom||1;r<0&&(console.error("negative radiusBottom not allowed - will invert"),r*=-1);var n=e.height||1;n<0&&(console.error("negative height not allowed - will invert"),n*=-1);var i=e.radialSegments||32;i<0&&(console.error("negative radialSegments not allowed - will invert"),i*=-1),i<3&&(i=3);var o=e.heightSegments||1;o<0&&(console.error("negative heightSegments not allowed - will invert"),o*=-1),o<1&&(o=1);var a,s,u,c,l,h,f,d,p,m,v,y=!!e.openEnded,g=e.center,x=g?g[0]:0,b=g?g[1]:0,w=g?g[2]:0,M=n/2,T=n/o,I=2*Math.PI/i,S=1/i,A=(t-r)/o,O=[],P=[],L=[],E=[],j=(90-180*Math.atan(n/(r-t))/Math.PI)/90;for(a=0;a<=o;a++)for(l=t-a*A,h=M-a*T,s=0;s<=i;s++)u=Math.sin(s*I),c=Math.cos(s*I),P.push(l*u),P.push(j),P.push(l*c),L.push(s*S),L.push(1*a/o),O.push(l*u+x),O.push(h+b),O.push(l*c+w);for(a=0;a0){for(p=O.length/3,P.push(0),P.push(1),P.push(0),L.push(.5),L.push(.5),O.push(0+x),O.push(M+b),O.push(0+w),s=0;s<=i;s++)u=Math.sin(s*I),c=Math.cos(s*I),m=.5*Math.sin(s*I)+.5,v=.5*Math.cos(s*I)+.5,P.push(t*u),P.push(1),P.push(t*c),L.push(m),L.push(v),O.push(t*u+x),O.push(M+b),O.push(t*c+w);for(s=0;s0){for(p=O.length/3,P.push(0),P.push(-1),P.push(0),L.push(.5),L.push(.5),O.push(0+x),O.push(0-M+b),O.push(0+w),s=0;s<=i;s++)u=Math.sin(s*I),c=Math.cos(s*I),m=.5*Math.sin(s*I)+.5,v=.5*Math.cos(s*I)+.5,P.push(r*u),P.push(-1),P.push(r*c),L.push(m),L.push(v),O.push(r*u+x),O.push(0-M+b),O.push(r*c+w);for(s=0;s0&&void 0!==arguments[0]?arguments[0]:{},t=e.size||1;t<0&&(console.error("negative size not allowed - will invert"),t*=-1);var r=e.divisions||1;r<0&&(console.error("negative divisions not allowed - will invert"),r*=-1),r<1&&(r=1);for(var n=(t=t||10)/(r=r||10),i=t/2,o=[],a=[],s=0,u=0,c=-i;u<=r;u++,c+=n)o.push(-i),o.push(0),o.push(c),o.push(i),o.push(0),o.push(c),o.push(c),o.push(0),o.push(-i),o.push(c),o.push(0),o.push(i),a.push(s++),a.push(s++),a.push(s++),a.push(s++);return{primitiveType:"lines",positions:o,indices:a}}function qr(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.xSize||1;t<0&&(console.error("negative xSize not allowed - will invert"),t*=-1);var r=e.zSize||1;r<0&&(console.error("negative zSize not allowed - will invert"),r*=-1);var n=e.xSegments||1;n<0&&(console.error("negative xSegments not allowed - will invert"),n*=-1),n<1&&(n=1);var i=e.xSegments||1;i<0&&(console.error("negative zSegments not allowed - will invert"),i*=-1),i<1&&(i=1);var o,a,s,u,c,l,h,f=e.center,d=f?f[0]:0,p=f?f[1]:0,m=f?f[2]:0,v=t/2,y=r/2,g=Math.floor(n)||1,x=Math.floor(i)||1,b=g+1,w=x+1,M=t/g,T=r/x,I=new Float32Array(b*w*3),S=new Float32Array(b*w*3),A=new Float32Array(b*w*2),O=0,P=0;for(o=0;o65535?Uint32Array:Uint16Array)(g*x*6);for(o=0;o0&&void 0!==arguments[0]?arguments[0]:{},t=e.lod||1,r=e.center?e.center[0]:0,n=e.center?e.center[1]:0,i=e.center?e.center[2]:0,o=e.radius||1;o<0&&(console.error("negative radius not allowed - will invert"),o*=-1);var a=e.heightSegments||18;a<0&&(console.error("negative heightSegments not allowed - will invert"),a*=-1),(a=Math.floor(t*a))<18&&(a=18);var s=e.widthSegments||18;s<0&&(console.error("negative widthSegments not allowed - will invert"),s*=-1),(s=Math.floor(t*s))<18&&(s=18);var u,c,l,h,f,d,p,m,v,y,g,x,b,w,M=[],T=[],I=[],S=[];for(u=0;u<=a;u++)for(l=u*Math.PI/a,h=Math.sin(l),f=Math.cos(l),c=0;c<=s;c++)d=2*c*Math.PI/s,p=Math.sin(d),m=Math.cos(d)*h,v=f,y=p*h,g=1-c/s,x=u/a,T.push(m),T.push(v),T.push(y),I.push(g),I.push(x),M.push(r+o*m),M.push(n+o*v),M.push(i+o*y);for(u=0;u0&&void 0!==arguments[0]?arguments[0]:{},t=e.radius||1;t<0&&(console.error("negative radius not allowed - will invert"),t*=-1),t*=.5;var r=e.tube||.3;r<0&&(console.error("negative tube not allowed - will invert"),r*=-1);var n=e.radialSegments||32;n<0&&(console.error("negative radialSegments not allowed - will invert"),n*=-1),n<4&&(n=4);var i=e.tubeSegments||24;i<0&&(console.error("negative tubeSegments not allowed - will invert"),i*=-1),i<4&&(i=4);var o=e.arc||2*Math.PI;o<0&&(console.warn("negative arc not allowed - will invert"),o*=-1),o>360&&(o=360);var a,s,u,c,l,h,f,d,p,m,v,y,g=e.center,x=g?g[0]:0,b=g?g[1]:0,w=g?g[2]:0,M=[],T=[],I=[],S=[];for(d=0;d<=i;d++)for(f=0;f<=n;f++)a=f/n*o,s=.785398+d/i*Math.PI*2,x=t*Math.cos(a),b=t*Math.sin(a),u=(t+r*Math.cos(s))*Math.cos(a),c=(t+r*Math.cos(s))*Math.sin(a),l=r*Math.sin(s),M.push(u+x),M.push(c+b),M.push(l+w),I.push(1-f/n),I.push(d/i),h=_.normalizeVec3(_.subVec3([u,c,l],[x,b,w],[]),[]),T.push(h[0]),T.push(h[1]),T.push(h[2]);for(d=1;d<=i;d++)for(f=1;f<=n;f++)p=(n+1)*d+f-1,m=(n+1)*(d-1)+f-1,v=(n+1)*(d-1)+f,y=(n+1)*d+f,S.push(p),S.push(m),S.push(v),S.push(v),S.push(y),S.push(p);return{primitiveType:"triangles",positions:M,normals:T,uv:I,uvs:I,indices:S}}var Qr={" ":{width:16,points:[]},"!":{width:10,points:[[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},'"':{width:16,points:[[4,21],[4,14],[-1,-1],[12,21],[12,14]]},"#":{width:21,points:[[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]]},$:{width:20,points:[[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},"%":{width:24,points:[[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]]},"&":{width:26,points:[[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]]},"'":{width:10,points:[[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]]},"(":{width:14,points:[[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]]},")":{width:14,points:[[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]]},"*":{width:16,points:[[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]]},"+":{width:26,points:[[13,18],[13,0],[-1,-1],[4,9],[22,9]]},",":{width:10,points:[[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"-":{width:26,points:[[4,9],[22,9]]},".":{width:10,points:[[5,2],[4,1],[5,0],[6,1],[5,2]]},"/":{width:22,points:[[20,25],[2,-7]]},0:{width:20,points:[[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]]},1:{width:20,points:[[6,17],[8,18],[11,21],[11,0]]},2:{width:20,points:[[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]]},3:{width:20,points:[[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},4:{width:20,points:[[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]]},5:{width:20,points:[[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},6:{width:20,points:[[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]]},7:{width:20,points:[[17,21],[7,0],[-1,-1],[3,21],[17,21]]},8:{width:20,points:[[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]]},9:{width:20,points:[[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]]},":":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},";":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"<":{width:24,points:[[20,18],[4,9],[20,0]]},"=":{width:26,points:[[4,12],[22,12],[-1,-1],[4,6],[22,6]]},">":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};function Wr(){for(var e,t,r,n,i,o,a,s,u,c=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},l=c.origin||[0,0,0],h=l[0],f=l[1],d=l[2],p=c.size||1,m=[],v=[],y=((""+c.text).trim()||"").split("\n"),g=0,x=0,b=.04,w=0;w {\nreturn ","module.exports = require(\"fs\");","module.exports = require(\"path\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/polyfills\");","/**\n * @desc Provides info on the XKT generated by xeokit-convert.\n */\nconst XKT_INFO = {\n\n /**\n * The XKT version generated by xeokit-convert.\n *\n * This is the XKT version that's modeled by {@link XKTModel}, serialized\n * by {@link writeXKTModelToArrayBuffer}, and written by {@link convert2xkt}.\n *\n * * Current XKT version: **10**\n * * [XKT format specs](https://github.com/xeokit/xeokit-convert/blob/main/specs/index.md)\n *\n * @property xktVersion\n * @type {number}\n */\n xktVersion: 10\n};\n\nexport {XKT_INFO};","// Some temporary vars to help avoid garbage collection\n\nconst doublePrecision = true;\nconst FloatArrayType = doublePrecision ? Float64Array : Float32Array;\n\nconst tempMat1 = new FloatArrayType(16);\nconst tempMat2 = new FloatArrayType(16);\nconst tempVec4 = new FloatArrayType(4);\n\n/**\n * @private\n */\nconst math = {\n\n MIN_DOUBLE: -Number.MAX_SAFE_INTEGER,\n MAX_DOUBLE: Number.MAX_SAFE_INTEGER,\n\n /**\n * The number of radiians in a degree (0.0174532925).\n * @property DEGTORAD\n * @type {Number}\n */\n DEGTORAD: 0.0174532925,\n\n /**\n * The number of degrees in a radian.\n * @property RADTODEG\n * @type {Number}\n */\n RADTODEG: 57.295779513,\n\n /**\n * Returns a new, uninitialized two-element vector.\n * @method vec2\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec2(values) {\n return new FloatArrayType(values || 2);\n },\n\n /**\n * Returns a new, uninitialized three-element vector.\n * @method vec3\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec3(values) {\n return new FloatArrayType(values || 3);\n },\n\n /**\n * Returns a new, uninitialized four-element vector.\n * @method vec4\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec4(values) {\n return new FloatArrayType(values || 4);\n },\n\n /**\n * Returns a new, uninitialized 3x3 matrix.\n * @method mat3\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n mat3(values) {\n return new FloatArrayType(values || 9);\n },\n\n /**\n * Converts a 3x3 matrix to 4x4\n * @method mat3ToMat4\n * @param mat3 3x3 matrix.\n * @param mat4 4x4 matrix\n * @static\n * @returns {Number[]}\n */\n mat3ToMat4(mat3, mat4 = new FloatArrayType(16)) {\n mat4[0] = mat3[0];\n mat4[1] = mat3[1];\n mat4[2] = mat3[2];\n mat4[3] = 0;\n mat4[4] = mat3[3];\n mat4[5] = mat3[4];\n mat4[6] = mat3[5];\n mat4[7] = 0;\n mat4[8] = mat3[6];\n mat4[9] = mat3[7];\n mat4[10] = mat3[8];\n mat4[11] = 0;\n mat4[12] = 0;\n mat4[13] = 0;\n mat4[14] = 0;\n mat4[15] = 1;\n return mat4;\n },\n\n /**\n * Returns a new, uninitialized 4x4 matrix.\n * @method mat4\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n mat4(values) {\n return new FloatArrayType(values || 16);\n },\n\n /**\n * Converts a 4x4 matrix to 3x3\n * @method mat4ToMat3\n * @param mat4 4x4 matrix.\n * @param mat3 3x3 matrix\n * @static\n * @returns {Number[]}\n */\n mat4ToMat3(mat4, mat3) { // TODO\n //return new FloatArrayType(values || 9);\n },\n\n /**\n * Returns a new UUID.\n * @method createUUID\n * @static\n * @return string The new UUID\n */\n createUUID: ((() => {\n const self = {};\n const lut = [];\n for (let i = 0; i < 256; i++) {\n lut[i] = (i < 16 ? '0' : '') + (i).toString(16);\n }\n return () => {\n const d0 = Math.random() * 0xffffffff | 0;\n const d1 = Math.random() * 0xffffffff | 0;\n const d2 = Math.random() * 0xffffffff | 0;\n const d3 = Math.random() * 0xffffffff | 0;\n return `${lut[d0 & 0xff] + lut[d0 >> 8 & 0xff] + lut[d0 >> 16 & 0xff] + lut[d0 >> 24 & 0xff]}-${lut[d1 & 0xff]}${lut[d1 >> 8 & 0xff]}-${lut[d1 >> 16 & 0x0f | 0x40]}${lut[d1 >> 24 & 0xff]}-${lut[d2 & 0x3f | 0x80]}${lut[d2 >> 8 & 0xff]}-${lut[d2 >> 16 & 0xff]}${lut[d2 >> 24 & 0xff]}${lut[d3 & 0xff]}${lut[d3 >> 8 & 0xff]}${lut[d3 >> 16 & 0xff]}${lut[d3 >> 24 & 0xff]}`;\n };\n }))(),\n\n /**\n * Clamps a value to the given range.\n * @param {Number} value Value to clamp.\n * @param {Number} min Lower bound.\n * @param {Number} max Upper bound.\n * @returns {Number} Clamped result.\n */\n clamp(value, min, max) {\n return Math.max(min, Math.min(max, value));\n },\n\n /**\n * Floating-point modulus\n * @method fmod\n * @static\n * @param {Number} a\n * @param {Number} b\n * @returns {*}\n */\n fmod(a, b) {\n if (a < b) {\n console.error(\"math.fmod : Attempting to find modulus within negative range - would be infinite loop - ignoring\");\n return a;\n }\n while (b <= a) {\n a -= b;\n }\n return a;\n },\n\n /**\n * Negates a four-element vector.\n * @method negateVec4\n * @static\n * @param {Array(Number)} v Vector to negate\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n negateVec4(v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = -v[0];\n dest[1] = -v[1];\n dest[2] = -v[2];\n dest[3] = -v[3];\n return dest;\n },\n\n /**\n * Adds one four-element vector to another.\n * @method addVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n addVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] + v[0];\n dest[1] = u[1] + v[1];\n dest[2] = u[2] + v[2];\n dest[3] = u[3] + v[3];\n return dest;\n },\n\n /**\n * Adds a scalar value to each element of a four-element vector.\n * @method addVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n addVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] + s;\n dest[1] = v[1] + s;\n dest[2] = v[2] + s;\n dest[3] = v[3] + s;\n return dest;\n },\n\n /**\n * Adds one three-element vector to another.\n * @method addVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n addVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] + v[0];\n dest[1] = u[1] + v[1];\n dest[2] = u[2] + v[2];\n return dest;\n },\n\n /**\n * Adds a scalar value to each element of a three-element vector.\n * @method addVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n addVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] + s;\n dest[1] = v[1] + s;\n dest[2] = v[2] + s;\n return dest;\n },\n\n /**\n * Subtracts one four-element vector from another.\n * @method subVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n dest[2] = u[2] - v[2];\n dest[3] = u[3] - v[3];\n return dest;\n },\n\n /**\n * Subtracts one three-element vector from another.\n * @method subVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n dest[2] = u[2] - v[2];\n return dest;\n },\n\n /**\n * Subtracts one two-element vector from another.\n * @method subVec2\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec2(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n return dest;\n },\n\n /**\n * Subtracts a scalar value from each element of a four-element vector.\n * @method subVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n subVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] - s;\n dest[1] = v[1] - s;\n dest[2] = v[2] - s;\n dest[3] = v[3] - s;\n return dest;\n },\n\n /**\n * Sets each element of a 4-element vector to a scalar value minus the value of that element.\n * @method subScalarVec4\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n subScalarVec4(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s - v[0];\n dest[1] = s - v[1];\n dest[2] = s - v[2];\n dest[3] = s - v[3];\n return dest;\n },\n\n /**\n * Multiplies one three-element vector by another.\n * @method mulVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n mulVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] * v[0];\n dest[1] = u[1] * v[1];\n dest[2] = u[2] * v[2];\n dest[3] = u[3] * v[3];\n return dest;\n },\n\n /**\n * Multiplies each element of a four-element vector by a scalar.\n * @method mulVec34calar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n dest[2] = v[2] * s;\n dest[3] = v[3] * s;\n return dest;\n },\n\n /**\n * Multiplies each element of a three-element vector by a scalar.\n * @method mulVec3Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n dest[2] = v[2] * s;\n return dest;\n },\n\n /**\n * Multiplies each element of a two-element vector by a scalar.\n * @method mulVec2Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec2Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n return dest;\n },\n\n /**\n * Divides one three-element vector by another.\n * @method divVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n divVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] / v[0];\n dest[1] = u[1] / v[1];\n dest[2] = u[2] / v[2];\n return dest;\n },\n\n /**\n * Divides one four-element vector by another.\n * @method divVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n divVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] / v[0];\n dest[1] = u[1] / v[1];\n dest[2] = u[2] / v[2];\n dest[3] = u[3] / v[3];\n return dest;\n },\n\n /**\n * Divides a scalar by a three-element vector, returning a new vector.\n * @method divScalarVec3\n * @static\n * @param v vec3\n * @param s scalar\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divScalarVec3(s, v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s / v[0];\n dest[1] = s / v[1];\n dest[2] = s / v[2];\n return dest;\n },\n\n /**\n * Divides a three-element vector by a scalar.\n * @method divVec3Scalar\n * @static\n * @param v vec3\n * @param s scalar\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] / s;\n dest[1] = v[1] / s;\n dest[2] = v[2] / s;\n return dest;\n },\n\n /**\n * Divides a four-element vector by a scalar.\n * @method divVec4Scalar\n * @static\n * @param v vec4\n * @param s scalar\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] / s;\n dest[1] = v[1] / s;\n dest[2] = v[2] / s;\n dest[3] = v[3] / s;\n return dest;\n },\n\n\n /**\n * Divides a scalar by a four-element vector, returning a new vector.\n * @method divScalarVec4\n * @static\n * @param s scalar\n * @param v vec4\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divScalarVec4(s, v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s / v[0];\n dest[1] = s / v[1];\n dest[2] = s / v[2];\n dest[3] = s / v[3];\n return dest;\n },\n\n /**\n * Returns the dot product of two four-element vectors.\n * @method dotVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec4(u, v) {\n return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2] + u[3] * v[3]);\n },\n\n /**\n * Returns the cross product of two four-element vectors.\n * @method cross3Vec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The cross product\n */\n cross3Vec4(u, v) {\n const u0 = u[0];\n const u1 = u[1];\n const u2 = u[2];\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n return [\n u1 * v2 - u2 * v1,\n u2 * v0 - u0 * v2,\n u0 * v1 - u1 * v0,\n 0.0];\n },\n\n /**\n * Returns the cross product of two three-element vectors.\n * @method cross3Vec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The cross product\n */\n cross3Vec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n const x = u[0];\n const y = u[1];\n const z = u[2];\n const x2 = v[0];\n const y2 = v[1];\n const z2 = v[2];\n dest[0] = y * z2 - z * y2;\n dest[1] = z * x2 - x * z2;\n dest[2] = x * y2 - y * x2;\n return dest;\n },\n\n\n sqLenVec4(v) { // TODO\n return math.dotVec4(v, v);\n },\n\n /**\n * Returns the length of a four-element vector.\n * @method lenVec4\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec4(v) {\n return Math.sqrt(math.sqLenVec4(v));\n },\n\n /**\n * Returns the dot product of two three-element vectors.\n * @method dotVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec3(u, v) {\n return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]);\n },\n\n /**\n * Returns the dot product of two two-element vectors.\n * @method dotVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec2(u, v) {\n return (u[0] * v[0] + u[1] * v[1]);\n },\n\n\n sqLenVec3(v) {\n return math.dotVec3(v, v);\n },\n\n\n sqLenVec2(v) {\n return math.dotVec2(v, v);\n },\n\n /**\n * Returns the length of a three-element vector.\n * @method lenVec3\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec3(v) {\n return Math.sqrt(math.sqLenVec3(v));\n },\n\n distVec3: ((() => {\n const vec = new FloatArrayType(3);\n return (v, w) => math.lenVec3(math.subVec3(v, w, vec));\n }))(),\n\n /**\n * Returns the length of a two-element vector.\n * @method lenVec2\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec2(v) {\n return Math.sqrt(math.sqLenVec2(v));\n },\n\n distVec2: ((() => {\n const vec = new FloatArrayType(2);\n return (v, w) => math.lenVec2(math.subVec2(v, w, vec));\n }))(),\n\n /**\n * @method rcpVec3\n * @static\n * @param v vec3\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n *\n */\n rcpVec3(v, dest) {\n return math.divScalarVec3(1.0, v, dest);\n },\n\n /**\n * Normalizes a four-element vector\n * @method normalizeVec4\n * @static\n * @param v vec4\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n *\n */\n normalizeVec4(v, dest) {\n const f = 1.0 / math.lenVec4(v);\n return math.mulVec4Scalar(v, f, dest);\n },\n\n /**\n * Normalizes a three-element vector\n * @method normalizeVec4\n * @static\n */\n normalizeVec3(v, dest) {\n const f = 1.0 / math.lenVec3(v);\n return math.mulVec3Scalar(v, f, dest);\n },\n\n /**\n * Normalizes a two-element vector\n * @method normalizeVec2\n * @static\n */\n normalizeVec2(v, dest) {\n const f = 1.0 / math.lenVec2(v);\n return math.mulVec2Scalar(v, f, dest);\n },\n\n /**\n * Gets the angle between two vectors\n * @method angleVec3\n * @param v\n * @param w\n * @returns {number}\n */\n angleVec3(v, w) {\n let theta = math.dotVec3(v, w) / (Math.sqrt(math.sqLenVec3(v) * math.sqLenVec3(w)));\n theta = theta < -1 ? -1 : (theta > 1 ? 1 : theta); // Clamp to handle numerical problems\n return Math.acos(theta);\n },\n\n /**\n * Creates a three-element vector from the rotation part of a sixteen-element matrix.\n * @param m\n * @param dest\n */\n vec3FromMat4Scale: ((() => {\n\n const tempVec3 = new FloatArrayType(3);\n\n return (m, dest) => {\n\n tempVec3[0] = m[0];\n tempVec3[1] = m[1];\n tempVec3[2] = m[2];\n\n dest[0] = math.lenVec3(tempVec3);\n\n tempVec3[0] = m[4];\n tempVec3[1] = m[5];\n tempVec3[2] = m[6];\n\n dest[1] = math.lenVec3(tempVec3);\n\n tempVec3[0] = m[8];\n tempVec3[1] = m[9];\n tempVec3[2] = m[10];\n\n dest[2] = math.lenVec3(tempVec3);\n\n return dest;\n };\n }))(),\n\n /**\n * Converts an n-element vector to a JSON-serializable\n * array with values rounded to two decimal places.\n */\n vecToArray: ((() => {\n function trunc(v) {\n return Math.round(v * 100000) / 100000\n }\n\n return v => {\n v = Array.prototype.slice.call(v);\n for (let i = 0, len = v.length; i < len; i++) {\n v[i] = trunc(v[i]);\n }\n return v;\n };\n }))(),\n\n /**\n * Converts a 3-element vector from an array to an object of the form ````{x:999, y:999, z:999}````.\n * @param arr\n * @returns {{x: *, y: *, z: *}}\n */\n xyzArrayToObject(arr) {\n return {\"x\": arr[0], \"y\": arr[1], \"z\": arr[2]};\n },\n\n /**\n * Converts a 3-element vector object of the form ````{x:999, y:999, z:999}```` to an array.\n * @param xyz\n * @param [arry]\n * @returns {*[]}\n */\n xyzObjectToArray(xyz, arry) {\n arry = arry || new FloatArrayType(3);\n arry[0] = xyz.x;\n arry[1] = xyz.y;\n arry[2] = xyz.z;\n return arry;\n },\n\n /**\n * Duplicates a 4x4 identity matrix.\n * @method dupMat4\n * @static\n */\n dupMat4(m) {\n return m.slice(0, 16);\n },\n\n /**\n * Extracts a 3x3 matrix from a 4x4 matrix.\n * @method mat4To3\n * @static\n */\n mat4To3(m) {\n return [\n m[0], m[1], m[2],\n m[4], m[5], m[6],\n m[8], m[9], m[10]\n ];\n },\n\n /**\n * Returns a 4x4 matrix with each element set to the given scalar value.\n * @method m4s\n * @static\n */\n m4s(s) {\n return [\n s, s, s, s,\n s, s, s, s,\n s, s, s, s,\n s, s, s, s\n ];\n },\n\n /**\n * Returns a 4x4 matrix with each element set to zero.\n * @method setMat4ToZeroes\n * @static\n */\n setMat4ToZeroes() {\n return math.m4s(0.0);\n },\n\n /**\n * Returns a 4x4 matrix with each element set to 1.0.\n * @method setMat4ToOnes\n * @static\n */\n setMat4ToOnes() {\n return math.m4s(1.0);\n },\n\n /**\n * Returns a 4x4 matrix with each element set to 1.0.\n * @method setMat4ToOnes\n * @static\n */\n diagonalMat4v(v) {\n return new FloatArrayType([\n v[0], 0.0, 0.0, 0.0,\n 0.0, v[1], 0.0, 0.0,\n 0.0, 0.0, v[2], 0.0,\n 0.0, 0.0, 0.0, v[3]\n ]);\n },\n\n /**\n * Returns a 4x4 matrix with diagonal elements set to the given vector.\n * @method diagonalMat4c\n * @static\n */\n diagonalMat4c(x, y, z, w) {\n return math.diagonalMat4v([x, y, z, w]);\n },\n\n /**\n * Returns a 4x4 matrix with diagonal elements set to the given scalar.\n * @method diagonalMat4s\n * @static\n */\n diagonalMat4s(s) {\n return math.diagonalMat4c(s, s, s, s);\n },\n\n /**\n * Returns a 4x4 identity matrix.\n * @method identityMat4\n * @static\n */\n identityMat4(mat = new FloatArrayType(16)) {\n mat[0] = 1.0;\n mat[1] = 0.0;\n mat[2] = 0.0;\n mat[3] = 0.0;\n\n mat[4] = 0.0;\n mat[5] = 1.0;\n mat[6] = 0.0;\n mat[7] = 0.0;\n\n mat[8] = 0.0;\n mat[9] = 0.0;\n mat[10] = 1.0;\n mat[11] = 0.0;\n\n mat[12] = 0.0;\n mat[13] = 0.0;\n mat[14] = 0.0;\n mat[15] = 1.0;\n\n return mat;\n },\n\n /**\n * Returns a 3x3 identity matrix.\n * @method identityMat3\n * @static\n */\n identityMat3(mat = new FloatArrayType(9)) {\n mat[0] = 1.0;\n mat[1] = 0.0;\n mat[2] = 0.0;\n\n mat[3] = 0.0;\n mat[4] = 1.0;\n mat[5] = 0.0;\n\n mat[6] = 0.0;\n mat[7] = 0.0;\n mat[8] = 1.0;\n\n return mat;\n },\n\n /**\n * Tests if the given 4x4 matrix is the identity matrix.\n * @method isIdentityMat4\n * @static\n */\n isIdentityMat4(m) {\n if (m[0] !== 1.0 || m[1] !== 0.0 || m[2] !== 0.0 || m[3] !== 0.0 ||\n m[4] !== 0.0 || m[5] !== 1.0 || m[6] !== 0.0 || m[7] !== 0.0 ||\n m[8] !== 0.0 || m[9] !== 0.0 || m[10] !== 1.0 || m[11] !== 0.0 ||\n m[12] !== 0.0 || m[13] !== 0.0 || m[14] !== 0.0 || m[15] !== 1.0) {\n return false;\n }\n return true;\n },\n\n /**\n * Negates the given 4x4 matrix.\n * @method negateMat4\n * @static\n */\n negateMat4(m, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = -m[0];\n dest[1] = -m[1];\n dest[2] = -m[2];\n dest[3] = -m[3];\n dest[4] = -m[4];\n dest[5] = -m[5];\n dest[6] = -m[6];\n dest[7] = -m[7];\n dest[8] = -m[8];\n dest[9] = -m[9];\n dest[10] = -m[10];\n dest[11] = -m[11];\n dest[12] = -m[12];\n dest[13] = -m[13];\n dest[14] = -m[14];\n dest[15] = -m[15];\n return dest;\n },\n\n /**\n * Adds the given 4x4 matrices together.\n * @method addMat4\n * @static\n */\n addMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n dest[0] = a[0] + b[0];\n dest[1] = a[1] + b[1];\n dest[2] = a[2] + b[2];\n dest[3] = a[3] + b[3];\n dest[4] = a[4] + b[4];\n dest[5] = a[5] + b[5];\n dest[6] = a[6] + b[6];\n dest[7] = a[7] + b[7];\n dest[8] = a[8] + b[8];\n dest[9] = a[9] + b[9];\n dest[10] = a[10] + b[10];\n dest[11] = a[11] + b[11];\n dest[12] = a[12] + b[12];\n dest[13] = a[13] + b[13];\n dest[14] = a[14] + b[14];\n dest[15] = a[15] + b[15];\n return dest;\n },\n\n /**\n * Adds the given scalar to each element of the given 4x4 matrix.\n * @method addMat4Scalar\n * @static\n */\n addMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] + s;\n dest[1] = m[1] + s;\n dest[2] = m[2] + s;\n dest[3] = m[3] + s;\n dest[4] = m[4] + s;\n dest[5] = m[5] + s;\n dest[6] = m[6] + s;\n dest[7] = m[7] + s;\n dest[8] = m[8] + s;\n dest[9] = m[9] + s;\n dest[10] = m[10] + s;\n dest[11] = m[11] + s;\n dest[12] = m[12] + s;\n dest[13] = m[13] + s;\n dest[14] = m[14] + s;\n dest[15] = m[15] + s;\n return dest;\n },\n\n /**\n * Adds the given scalar to each element of the given 4x4 matrix.\n * @method addScalarMat4\n * @static\n */\n addScalarMat4(s, m, dest) {\n return math.addMat4Scalar(m, s, dest);\n },\n\n /**\n * Subtracts the second 4x4 matrix from the first.\n * @method subMat4\n * @static\n */\n subMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n dest[0] = a[0] - b[0];\n dest[1] = a[1] - b[1];\n dest[2] = a[2] - b[2];\n dest[3] = a[3] - b[3];\n dest[4] = a[4] - b[4];\n dest[5] = a[5] - b[5];\n dest[6] = a[6] - b[6];\n dest[7] = a[7] - b[7];\n dest[8] = a[8] - b[8];\n dest[9] = a[9] - b[9];\n dest[10] = a[10] - b[10];\n dest[11] = a[11] - b[11];\n dest[12] = a[12] - b[12];\n dest[13] = a[13] - b[13];\n dest[14] = a[14] - b[14];\n dest[15] = a[15] - b[15];\n return dest;\n },\n\n /**\n * Subtracts the given scalar from each element of the given 4x4 matrix.\n * @method subMat4Scalar\n * @static\n */\n subMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] - s;\n dest[1] = m[1] - s;\n dest[2] = m[2] - s;\n dest[3] = m[3] - s;\n dest[4] = m[4] - s;\n dest[5] = m[5] - s;\n dest[6] = m[6] - s;\n dest[7] = m[7] - s;\n dest[8] = m[8] - s;\n dest[9] = m[9] - s;\n dest[10] = m[10] - s;\n dest[11] = m[11] - s;\n dest[12] = m[12] - s;\n dest[13] = m[13] - s;\n dest[14] = m[14] - s;\n dest[15] = m[15] - s;\n return dest;\n },\n\n /**\n * Subtracts the given scalar from each element of the given 4x4 matrix.\n * @method subScalarMat4\n * @static\n */\n subScalarMat4(s, m, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = s - m[0];\n dest[1] = s - m[1];\n dest[2] = s - m[2];\n dest[3] = s - m[3];\n dest[4] = s - m[4];\n dest[5] = s - m[5];\n dest[6] = s - m[6];\n dest[7] = s - m[7];\n dest[8] = s - m[8];\n dest[9] = s - m[9];\n dest[10] = s - m[10];\n dest[11] = s - m[11];\n dest[12] = s - m[12];\n dest[13] = s - m[13];\n dest[14] = s - m[14];\n dest[15] = s - m[15];\n return dest;\n },\n\n /**\n * Multiplies the two given 4x4 matrix by each other.\n * @method mulMat4\n * @static\n */\n mulMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = a[0];\n\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n const b00 = b[0];\n const b01 = b[1];\n const b02 = b[2];\n const b03 = b[3];\n const b10 = b[4];\n const b11 = b[5];\n const b12 = b[6];\n const b13 = b[7];\n const b20 = b[8];\n const b21 = b[9];\n const b22 = b[10];\n const b23 = b[11];\n const b30 = b[12];\n const b31 = b[13];\n const b32 = b[14];\n const b33 = b[15];\n\n dest[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;\n dest[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;\n dest[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;\n dest[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;\n dest[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;\n dest[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;\n dest[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;\n dest[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;\n dest[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;\n dest[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;\n dest[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;\n dest[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;\n dest[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;\n dest[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;\n dest[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;\n dest[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;\n\n return dest;\n },\n\n /**\n * Multiplies the two given 3x3 matrices by each other.\n * @method mulMat4\n * @static\n */\n mulMat3(a, b, dest) {\n if (!dest) {\n dest = new FloatArrayType(9);\n }\n\n const a11 = a[0];\n const a12 = a[3];\n const a13 = a[6];\n const a21 = a[1];\n const a22 = a[4];\n const a23 = a[7];\n const a31 = a[2];\n const a32 = a[5];\n const a33 = a[8];\n const b11 = b[0];\n const b12 = b[3];\n const b13 = b[6];\n const b21 = b[1];\n const b22 = b[4];\n const b23 = b[7];\n const b31 = b[2];\n const b32 = b[5];\n const b33 = b[8];\n\n dest[0] = a11 * b11 + a12 * b21 + a13 * b31;\n dest[3] = a11 * b12 + a12 * b22 + a13 * b32;\n dest[6] = a11 * b13 + a12 * b23 + a13 * b33;\n\n dest[1] = a21 * b11 + a22 * b21 + a23 * b31;\n dest[4] = a21 * b12 + a22 * b22 + a23 * b32;\n dest[7] = a21 * b13 + a22 * b23 + a23 * b33;\n\n dest[2] = a31 * b11 + a32 * b21 + a33 * b31;\n dest[5] = a31 * b12 + a32 * b22 + a33 * b32;\n dest[8] = a31 * b13 + a32 * b23 + a33 * b33;\n\n return dest;\n },\n\n /**\n * Multiplies each element of the given 4x4 matrix by the given scalar.\n * @method mulMat4Scalar\n * @static\n */\n mulMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] * s;\n dest[1] = m[1] * s;\n dest[2] = m[2] * s;\n dest[3] = m[3] * s;\n dest[4] = m[4] * s;\n dest[5] = m[5] * s;\n dest[6] = m[6] * s;\n dest[7] = m[7] * s;\n dest[8] = m[8] * s;\n dest[9] = m[9] * s;\n dest[10] = m[10] * s;\n dest[11] = m[11] * s;\n dest[12] = m[12] * s;\n dest[13] = m[13] * s;\n dest[14] = m[14] * s;\n dest[15] = m[15] * s;\n return dest;\n },\n\n /**\n * Multiplies the given 4x4 matrix by the given four-element vector.\n * @method mulMat4v4\n * @static\n */\n mulMat4v4(m, v, dest = math.vec4()) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n const v3 = v[3];\n dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3;\n dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3;\n dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3;\n dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3;\n return dest;\n },\n\n /**\n * Transposes the given 4x4 matrix.\n * @method transposeMat4\n * @static\n */\n transposeMat4(mat, dest) {\n // If we are transposing ourselves we can skip a few steps but have to cache some values\n const m4 = mat[4];\n\n const m14 = mat[14];\n const m8 = mat[8];\n const m13 = mat[13];\n const m12 = mat[12];\n const m9 = mat[9];\n if (!dest || mat === dest) {\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a12 = mat[6];\n const a13 = mat[7];\n const a23 = mat[11];\n mat[1] = m4;\n mat[2] = m8;\n mat[3] = m12;\n mat[4] = a01;\n mat[6] = m9;\n mat[7] = m13;\n mat[8] = a02;\n mat[9] = a12;\n mat[11] = m14;\n mat[12] = a03;\n mat[13] = a13;\n mat[14] = a23;\n return mat;\n }\n dest[0] = mat[0];\n dest[1] = m4;\n dest[2] = m8;\n dest[3] = m12;\n dest[4] = mat[1];\n dest[5] = mat[5];\n dest[6] = m9;\n dest[7] = m13;\n dest[8] = mat[2];\n dest[9] = mat[6];\n dest[10] = mat[10];\n dest[11] = m14;\n dest[12] = mat[3];\n dest[13] = mat[7];\n dest[14] = mat[11];\n dest[15] = mat[15];\n return dest;\n },\n\n /**\n * Transposes the given 3x3 matrix.\n *\n * @method transposeMat3\n * @static\n */\n transposeMat3(mat, dest) {\n if (dest === mat) {\n const a01 = mat[1];\n const a02 = mat[2];\n const a12 = mat[5];\n dest[1] = mat[3];\n dest[2] = mat[6];\n dest[3] = a01;\n dest[5] = mat[7];\n dest[6] = a02;\n dest[7] = a12;\n } else {\n dest[0] = mat[0];\n dest[1] = mat[3];\n dest[2] = mat[6];\n dest[3] = mat[1];\n dest[4] = mat[4];\n dest[5] = mat[7];\n dest[6] = mat[2];\n dest[7] = mat[5];\n dest[8] = mat[8];\n }\n return dest;\n },\n\n /**\n * Returns the determinant of the given 4x4 matrix.\n * @method determinantMat4\n * @static\n */\n determinantMat4(mat) {\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = mat[0];\n\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a10 = mat[4];\n const a11 = mat[5];\n const a12 = mat[6];\n const a13 = mat[7];\n const a20 = mat[8];\n const a21 = mat[9];\n const a22 = mat[10];\n const a23 = mat[11];\n const a30 = mat[12];\n const a31 = mat[13];\n const a32 = mat[14];\n const a33 = mat[15];\n return a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 +\n a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 +\n a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 +\n a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 +\n a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 +\n a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33;\n },\n\n /**\n * Returns the inverse of the given 4x4 matrix.\n * @method inverseMat4\n * @static\n */\n inverseMat4(mat, dest) {\n if (!dest) {\n dest = mat;\n }\n\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = mat[0];\n\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a10 = mat[4];\n const a11 = mat[5];\n const a12 = mat[6];\n const a13 = mat[7];\n const a20 = mat[8];\n const a21 = mat[9];\n const a22 = mat[10];\n const a23 = mat[11];\n const a30 = mat[12];\n const a31 = mat[13];\n const a32 = mat[14];\n const a33 = mat[15];\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant (inlined to avoid double-caching)\n const invDet = 1 / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06);\n\n dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;\n dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;\n dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;\n dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;\n dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;\n dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;\n dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;\n dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;\n dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;\n dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;\n dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;\n dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;\n dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;\n dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;\n dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;\n dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;\n\n return dest;\n },\n\n /**\n * Returns the trace of the given 4x4 matrix.\n * @method traceMat4\n * @static\n */\n traceMat4(m) {\n return (m[0] + m[5] + m[10] + m[15]);\n },\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4\n * @static\n */\n translationMat4v(v, dest) {\n const m = dest || math.identityMat4();\n m[12] = v[0];\n m[13] = v[1];\n m[14] = v[2];\n return m;\n },\n\n /**\n * Returns 3x3 translation matrix.\n * @method translationMat3\n * @static\n */\n translationMat3v(v, dest) {\n const m = dest || math.identityMat3();\n m[6] = v[0];\n m[7] = v[1];\n return m;\n },\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4c\n * @static\n */\n translationMat4c: ((() => {\n const xyz = new FloatArrayType(3);\n return (x, y, z, dest) => {\n xyz[0] = x;\n xyz[1] = y;\n xyz[2] = z;\n return math.translationMat4v(xyz, dest);\n };\n }))(),\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4s\n * @static\n */\n translationMat4s(s, dest) {\n return math.translationMat4c(s, s, s, dest);\n },\n\n /**\n * Efficiently post-concatenates a translation to the given matrix.\n * @param v\n * @param m\n */\n translateMat4v(xyz, m) {\n return math.translateMat4c(xyz[0], xyz[1], xyz[2], m);\n },\n\n /**\n * Efficiently post-concatenates a translation to the given matrix.\n * @param x\n * @param y\n * @param z\n * @param m\n */\n OLDtranslateMat4c(x, y, z, m) {\n\n const m12 = m[12];\n m[0] += m12 * x;\n m[4] += m12 * y;\n m[8] += m12 * z;\n\n const m13 = m[13];\n m[1] += m13 * x;\n m[5] += m13 * y;\n m[9] += m13 * z;\n\n const m14 = m[14];\n m[2] += m14 * x;\n m[6] += m14 * y;\n m[10] += m14 * z;\n\n const m15 = m[15];\n m[3] += m15 * x;\n m[7] += m15 * y;\n m[11] += m15 * z;\n\n return m;\n },\n\n translateMat4c(x, y, z, m) {\n\n const m3 = m[3];\n m[0] += m3 * x;\n m[1] += m3 * y;\n m[2] += m3 * z;\n\n const m7 = m[7];\n m[4] += m7 * x;\n m[5] += m7 * y;\n m[6] += m7 * z;\n\n const m11 = m[11];\n m[8] += m11 * x;\n m[9] += m11 * y;\n m[10] += m11 * z;\n\n const m15 = m[15];\n m[12] += m15 * x;\n m[13] += m15 * y;\n m[14] += m15 * z;\n\n return m;\n },\n /**\n * Returns 4x4 rotation matrix.\n * @method rotationMat4v\n * @static\n */\n rotationMat4v(anglerad, axis, m) {\n const ax = math.normalizeVec4([axis[0], axis[1], axis[2], 0.0], []);\n const s = Math.sin(anglerad);\n const c = Math.cos(anglerad);\n const q = 1.0 - c;\n\n const x = ax[0];\n const y = ax[1];\n const z = ax[2];\n\n let xy;\n let yz;\n let zx;\n let xs;\n let ys;\n let zs;\n\n //xx = x * x; used once\n //yy = y * y; used once\n //zz = z * z; used once\n xy = x * y;\n yz = y * z;\n zx = z * x;\n xs = x * s;\n ys = y * s;\n zs = z * s;\n\n m = m || math.mat4();\n\n m[0] = (q * x * x) + c;\n m[1] = (q * xy) + zs;\n m[2] = (q * zx) - ys;\n m[3] = 0.0;\n\n m[4] = (q * xy) - zs;\n m[5] = (q * y * y) + c;\n m[6] = (q * yz) + xs;\n m[7] = 0.0;\n\n m[8] = (q * zx) + ys;\n m[9] = (q * yz) - xs;\n m[10] = (q * z * z) + c;\n m[11] = 0.0;\n\n m[12] = 0.0;\n m[13] = 0.0;\n m[14] = 0.0;\n m[15] = 1.0;\n\n return m;\n },\n\n /**\n * Returns 4x4 rotation matrix.\n * @method rotationMat4c\n * @static\n */\n rotationMat4c(anglerad, x, y, z, mat) {\n return math.rotationMat4v(anglerad, [x, y, z], mat);\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4v\n * @static\n */\n scalingMat4v(v, m = math.identityMat4()) {\n m[0] = v[0];\n m[5] = v[1];\n m[10] = v[2];\n return m;\n },\n\n /**\n * Returns 3x3 scale matrix.\n * @method scalingMat3v\n * @static\n */\n scalingMat3v(v, m = math.identityMat3()) {\n m[0] = v[0];\n m[4] = v[1];\n return m;\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4c\n * @static\n */\n scalingMat4c: ((() => {\n const xyz = new FloatArrayType(3);\n return (x, y, z, dest) => {\n xyz[0] = x;\n xyz[1] = y;\n xyz[2] = z;\n return math.scalingMat4v(xyz, dest);\n };\n }))(),\n\n /**\n * Efficiently post-concatenates a scaling to the given matrix.\n * @method scaleMat4c\n * @param x\n * @param y\n * @param z\n * @param m\n */\n scaleMat4c(x, y, z, m) {\n\n m[0] *= x;\n m[4] *= y;\n m[8] *= z;\n\n m[1] *= x;\n m[5] *= y;\n m[9] *= z;\n\n m[2] *= x;\n m[6] *= y;\n m[10] *= z;\n\n m[3] *= x;\n m[7] *= y;\n m[11] *= z;\n return m;\n },\n\n /**\n * Efficiently post-concatenates a scaling to the given matrix.\n * @method scaleMat4c\n * @param xyz\n * @param m\n */\n scaleMat4v(xyz, m) {\n\n const x = xyz[0];\n const y = xyz[1];\n const z = xyz[2];\n\n m[0] *= x;\n m[4] *= y;\n m[8] *= z;\n m[1] *= x;\n m[5] *= y;\n m[9] *= z;\n m[2] *= x;\n m[6] *= y;\n m[10] *= z;\n m[3] *= x;\n m[7] *= y;\n m[11] *= z;\n\n return m;\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4s\n * @static\n */\n scalingMat4s(s) {\n return math.scalingMat4c(s, s, s);\n },\n\n /**\n * Creates a matrix from a quaternion rotation and vector translation\n *\n * @param {Number[]} q Rotation quaternion\n * @param {Number[]} v Translation vector\n * @param {Number[]} dest Destination matrix\n * @returns {Number[]} dest\n */\n rotationTranslationMat4(q, v, dest = math.mat4()) {\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n dest[0] = 1 - (yy + zz);\n dest[1] = xy + wz;\n dest[2] = xz - wy;\n dest[3] = 0;\n dest[4] = xy - wz;\n dest[5] = 1 - (xx + zz);\n dest[6] = yz + wx;\n dest[7] = 0;\n dest[8] = xz + wy;\n dest[9] = yz - wx;\n dest[10] = 1 - (xx + yy);\n dest[11] = 0;\n dest[12] = v[0];\n dest[13] = v[1];\n dest[14] = v[2];\n dest[15] = 1;\n\n return dest;\n },\n\n /**\n * Gets Euler angles from a 4x4 matrix.\n *\n * @param {Number[]} mat The 4x4 matrix.\n * @param {String} order Desired Euler angle order: \"XYZ\", \"YXZ\", \"ZXY\" etc.\n * @param {Number[]} [dest] Destination Euler angles, created by default.\n * @returns {Number[]} The Euler angles.\n */\n mat4ToEuler(mat, order, dest = math.vec4()) {\n const clamp = math.clamp;\n\n // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n const m11 = mat[0];\n\n const m12 = mat[4];\n const m13 = mat[8];\n const m21 = mat[1];\n const m22 = mat[5];\n const m23 = mat[9];\n const m31 = mat[2];\n const m32 = mat[6];\n const m33 = mat[10];\n\n if (order === 'XYZ') {\n\n dest[1] = Math.asin(clamp(m13, -1, 1));\n\n if (Math.abs(m13) < 0.99999) {\n dest[0] = Math.atan2(-m23, m33);\n dest[2] = Math.atan2(-m12, m11);\n } else {\n dest[0] = Math.atan2(m32, m22);\n dest[2] = 0;\n\n }\n\n } else if (order === 'YXZ') {\n\n dest[0] = Math.asin(-clamp(m23, -1, 1));\n\n if (Math.abs(m23) < 0.99999) {\n dest[1] = Math.atan2(m13, m33);\n dest[2] = Math.atan2(m21, m22);\n } else {\n dest[1] = Math.atan2(-m31, m11);\n dest[2] = 0;\n }\n\n } else if (order === 'ZXY') {\n\n dest[0] = Math.asin(clamp(m32, -1, 1));\n\n if (Math.abs(m32) < 0.99999) {\n dest[1] = Math.atan2(-m31, m33);\n dest[2] = Math.atan2(-m12, m22);\n } else {\n dest[1] = 0;\n dest[2] = Math.atan2(m21, m11);\n }\n\n } else if (order === 'ZYX') {\n\n dest[1] = Math.asin(-clamp(m31, -1, 1));\n\n if (Math.abs(m31) < 0.99999) {\n dest[0] = Math.atan2(m32, m33);\n dest[2] = Math.atan2(m21, m11);\n } else {\n dest[0] = 0;\n dest[2] = Math.atan2(-m12, m22);\n }\n\n } else if (order === 'YZX') {\n\n dest[2] = Math.asin(clamp(m21, -1, 1));\n\n if (Math.abs(m21) < 0.99999) {\n dest[0] = Math.atan2(-m23, m22);\n dest[1] = Math.atan2(-m31, m11);\n } else {\n dest[0] = 0;\n dest[1] = Math.atan2(m13, m33);\n }\n\n } else if (order === 'XZY') {\n\n dest[2] = Math.asin(-clamp(m12, -1, 1));\n\n if (Math.abs(m12) < 0.99999) {\n dest[0] = Math.atan2(m32, m22);\n dest[1] = Math.atan2(m13, m11);\n } else {\n dest[0] = Math.atan2(-m23, m33);\n dest[1] = 0;\n }\n }\n\n return dest;\n },\n\n composeMat4(position, quaternion, scale, mat = math.mat4()) {\n math.quaternionToRotationMat4(quaternion, mat);\n math.scaleMat4v(scale, mat);\n math.translateMat4v(position, mat);\n\n return mat;\n },\n\n decomposeMat4: (() => {\n\n const vec = new FloatArrayType(3);\n const matrix = new FloatArrayType(16);\n\n return function decompose(mat, position, quaternion, scale) {\n\n vec[0] = mat[0];\n vec[1] = mat[1];\n vec[2] = mat[2];\n\n let sx = math.lenVec3(vec);\n\n vec[0] = mat[4];\n vec[1] = mat[5];\n vec[2] = mat[6];\n\n const sy = math.lenVec3(vec);\n\n vec[8] = mat[8];\n vec[9] = mat[9];\n vec[10] = mat[10];\n\n const sz = math.lenVec3(vec);\n\n // if determine is negative, we need to invert one scale\n const det = math.determinantMat4(mat);\n\n if (det < 0) {\n sx = -sx;\n }\n\n position[0] = mat[12];\n position[1] = mat[13];\n position[2] = mat[14];\n\n // scale the rotation part\n matrix.set(mat);\n\n const invSX = 1 / sx;\n const invSY = 1 / sy;\n const invSZ = 1 / sz;\n\n matrix[0] *= invSX;\n matrix[1] *= invSX;\n matrix[2] *= invSX;\n\n matrix[4] *= invSY;\n matrix[5] *= invSY;\n matrix[6] *= invSY;\n\n matrix[8] *= invSZ;\n matrix[9] *= invSZ;\n matrix[10] *= invSZ;\n\n math.mat4ToQuaternion(matrix, quaternion);\n\n scale[0] = sx;\n scale[1] = sy;\n scale[2] = sz;\n\n return this;\n\n };\n\n })(),\n\n /**\n * Returns a 4x4 'lookat' viewing transform matrix.\n * @method lookAtMat4v\n * @param pos vec3 position of the viewer\n * @param target vec3 point the viewer is looking at\n * @param up vec3 pointing \"up\"\n * @param dest mat4 Optional, mat4 matrix will be written into\n *\n * @return {mat4} dest if specified, a new mat4 otherwise\n */\n lookAtMat4v(pos, target, up, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n\n const posx = pos[0];\n const posy = pos[1];\n const posz = pos[2];\n const upx = up[0];\n const upy = up[1];\n const upz = up[2];\n const targetx = target[0];\n const targety = target[1];\n const targetz = target[2];\n\n if (posx === targetx && posy === targety && posz === targetz) {\n return math.identityMat4();\n }\n\n let z0;\n let z1;\n let z2;\n let x0;\n let x1;\n let x2;\n let y0;\n let y1;\n let y2;\n let len;\n\n //vec3.direction(eye, center, z);\n z0 = posx - targetx;\n z1 = posy - targety;\n z2 = posz - targetz;\n\n // normalize (no check needed for 0 because of early return)\n len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);\n z0 *= len;\n z1 *= len;\n z2 *= len;\n\n //vec3.normalize(vec3.cross(up, z, x));\n x0 = upy * z2 - upz * z1;\n x1 = upz * z0 - upx * z2;\n x2 = upx * z1 - upy * z0;\n len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);\n if (!len) {\n x0 = 0;\n x1 = 0;\n x2 = 0;\n } else {\n len = 1 / len;\n x0 *= len;\n x1 *= len;\n x2 *= len;\n }\n\n //vec3.normalize(vec3.cross(z, x, y));\n y0 = z1 * x2 - z2 * x1;\n y1 = z2 * x0 - z0 * x2;\n y2 = z0 * x1 - z1 * x0;\n\n len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);\n if (!len) {\n y0 = 0;\n y1 = 0;\n y2 = 0;\n } else {\n len = 1 / len;\n y0 *= len;\n y1 *= len;\n y2 *= len;\n }\n\n dest[0] = x0;\n dest[1] = y0;\n dest[2] = z0;\n dest[3] = 0;\n dest[4] = x1;\n dest[5] = y1;\n dest[6] = z1;\n dest[7] = 0;\n dest[8] = x2;\n dest[9] = y2;\n dest[10] = z2;\n dest[11] = 0;\n dest[12] = -(x0 * posx + x1 * posy + x2 * posz);\n dest[13] = -(y0 * posx + y1 * posy + y2 * posz);\n dest[14] = -(z0 * posx + z1 * posy + z2 * posz);\n dest[15] = 1;\n\n return dest;\n },\n\n /**\n * Returns a 4x4 'lookat' viewing transform matrix.\n * @method lookAtMat4c\n * @static\n */\n lookAtMat4c(posx, posy, posz, targetx, targety, targetz, upx, upy, upz) {\n return math.lookAtMat4v([posx, posy, posz], [targetx, targety, targetz], [upx, upy, upz], []);\n },\n\n /**\n * Returns a 4x4 orthographic projection matrix.\n * @method orthoMat4c\n * @static\n */\n orthoMat4c(left, right, bottom, top, near, far, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n const rl = (right - left);\n const tb = (top - bottom);\n const fn = (far - near);\n\n dest[0] = 2.0 / rl;\n dest[1] = 0.0;\n dest[2] = 0.0;\n dest[3] = 0.0;\n\n dest[4] = 0.0;\n dest[5] = 2.0 / tb;\n dest[6] = 0.0;\n dest[7] = 0.0;\n\n dest[8] = 0.0;\n dest[9] = 0.0;\n dest[10] = -2.0 / fn;\n dest[11] = 0.0;\n\n dest[12] = -(left + right) / rl;\n dest[13] = -(top + bottom) / tb;\n dest[14] = -(far + near) / fn;\n dest[15] = 1.0;\n\n return dest;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method frustumMat4v\n * @static\n */\n frustumMat4v(fmin, fmax, m) {\n if (!m) {\n m = math.mat4();\n }\n\n const fmin4 = [fmin[0], fmin[1], fmin[2], 0.0];\n const fmax4 = [fmax[0], fmax[1], fmax[2], 0.0];\n\n math.addVec4(fmax4, fmin4, tempMat1);\n math.subVec4(fmax4, fmin4, tempMat2);\n\n const t = 2.0 * fmin4[2];\n\n const tempMat20 = tempMat2[0];\n const tempMat21 = tempMat2[1];\n const tempMat22 = tempMat2[2];\n\n m[0] = t / tempMat20;\n m[1] = 0.0;\n m[2] = 0.0;\n m[3] = 0.0;\n\n m[4] = 0.0;\n m[5] = t / tempMat21;\n m[6] = 0.0;\n m[7] = 0.0;\n\n m[8] = tempMat1[0] / tempMat20;\n m[9] = tempMat1[1] / tempMat21;\n m[10] = -tempMat1[2] / tempMat22;\n m[11] = -1.0;\n\n m[12] = 0.0;\n m[13] = 0.0;\n m[14] = -t * fmax4[2] / tempMat22;\n m[15] = 0.0;\n\n return m;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method frustumMat4v\n * @static\n */\n frustumMat4(left, right, bottom, top, near, far, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n const rl = (right - left);\n const tb = (top - bottom);\n const fn = (far - near);\n dest[0] = (near * 2) / rl;\n dest[1] = 0;\n dest[2] = 0;\n dest[3] = 0;\n dest[4] = 0;\n dest[5] = (near * 2) / tb;\n dest[6] = 0;\n dest[7] = 0;\n dest[8] = (right + left) / rl;\n dest[9] = (top + bottom) / tb;\n dest[10] = -(far + near) / fn;\n dest[11] = -1;\n dest[12] = 0;\n dest[13] = 0;\n dest[14] = -(far * near * 2) / fn;\n dest[15] = 0;\n return dest;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method perspectiveMat4v\n * @static\n */\n perspectiveMat4(fovyrad, aspectratio, znear, zfar, m) {\n const pmin = [];\n const pmax = [];\n\n pmin[2] = znear;\n pmax[2] = zfar;\n\n pmax[1] = pmin[2] * Math.tan(fovyrad / 2.0);\n pmin[1] = -pmax[1];\n\n pmax[0] = pmax[1] * aspectratio;\n pmin[0] = -pmax[0];\n\n return math.frustumMat4v(pmin, pmax, m);\n },\n\n /**\n * Transforms a three-element position by a 4x4 matrix.\n * @method transformPoint3\n * @static\n */\n transformPoint3(m, p, dest = math.vec3()) {\n\n const x = p[0];\n const y = p[1];\n const z = p[2];\n\n dest[0] = (m[0] * x) + (m[4] * y) + (m[8] * z) + m[12];\n dest[1] = (m[1] * x) + (m[5] * y) + (m[9] * z) + m[13];\n dest[2] = (m[2] * x) + (m[6] * y) + (m[10] * z) + m[14];\n\n return dest;\n },\n\n /**\n * Transforms a homogeneous coordinate by a 4x4 matrix.\n * @method transformPoint3\n * @static\n */\n transformPoint4(m, v, dest = math.vec4()) {\n dest[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];\n dest[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];\n dest[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];\n dest[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];\n\n return dest;\n },\n\n\n /**\n * Transforms an array of three-element positions by a 4x4 matrix.\n * @method transformPoints3\n * @static\n */\n transformPoints3(m, points, points2) {\n const result = points2 || [];\n const len = points.length;\n let p0;\n let p1;\n let p2;\n let pi;\n\n // cache values\n const m0 = m[0];\n\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n let r;\n\n for (let i = 0; i < len; ++i) {\n\n // cache values\n pi = points[i];\n\n p0 = pi[0];\n p1 = pi[1];\n p2 = pi[2];\n\n r = result[i] || (result[i] = [0, 0, 0]);\n\n r[0] = (m0 * p0) + (m4 * p1) + (m8 * p2) + m12;\n r[1] = (m1 * p0) + (m5 * p1) + (m9 * p2) + m13;\n r[2] = (m2 * p0) + (m6 * p1) + (m10 * p2) + m14;\n r[3] = (m3 * p0) + (m7 * p1) + (m11 * p2) + m15;\n }\n\n result.length = len;\n\n return result;\n },\n\n /**\n * Transforms an array of positions by a 4x4 matrix.\n * @method transformPositions3\n * @static\n */\n transformPositions3(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 3) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /**\n * Transforms an array of positions by a 4x4 matrix.\n * @method transformPositions4\n * @static\n */\n transformPositions4(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 4) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /**\n * Transforms a three-element vector by a 4x4 matrix.\n * @method transformVec3\n * @static\n */\n transformVec3(m, v, dest) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n dest = dest || this.vec3();\n dest[0] = (m[0] * v0) + (m[4] * v1) + (m[8] * v2);\n dest[1] = (m[1] * v0) + (m[5] * v1) + (m[9] * v2);\n dest[2] = (m[2] * v0) + (m[6] * v1) + (m[10] * v2);\n return dest;\n },\n\n /**\n * Transforms a four-element vector by a 4x4 matrix.\n * @method transformVec4\n * @static\n */\n transformVec4(m, v, dest) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n const v3 = v[3];\n dest = dest || math.vec4();\n dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3;\n dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3;\n dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3;\n dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3;\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the x-axis\n *\n * @method rotateVec3X\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3X(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[0];\n r[1] = p[1] * Math.cos(c) - p[2] * Math.sin(c);\n r[2] = p[1] * Math.sin(c) + p[2] * Math.cos(c);\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the y-axis\n *\n * @method rotateVec3Y\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3Y(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c);\n r[1] = p[1];\n r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c);\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the z-axis\n *\n * @method rotateVec3Z\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3Z(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c);\n r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c);\n r[2] = p[2];\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Transforms a four-element vector by a 4x4 projection matrix.\n *\n * @method projectVec4\n * @param {Number[]} p 3D View-space coordinate\n * @param {Number[]} q 2D Projected coordinate\n * @returns {Number[]} 2D Projected coordinate\n * @static\n */\n projectVec4(p, q) {\n const f = 1.0 / p[3];\n q = q || math.vec2();\n q[0] = v[0] * f;\n q[1] = v[1] * f;\n return q;\n },\n\n /**\n * Unprojects a three-element vector.\n *\n * @method unprojectVec3\n * @param {Number[]} p 3D Projected coordinate\n * @param {Number[]} viewMat View matrix\n * @returns {Number[]} projMat Projection matrix\n * @static\n */\n unprojectVec3: ((() => {\n const mat = new FloatArrayType(16);\n const mat2 = new FloatArrayType(16);\n const mat3 = new FloatArrayType(16);\n return function (p, viewMat, projMat, q) {\n return this.transformVec3(this.mulMat4(this.inverseMat4(viewMat, mat), this.inverseMat4(projMat, mat2), mat3), p, q)\n };\n }))(),\n\n /**\n * Linearly interpolates between two 3D vectors.\n * @method lerpVec3\n * @static\n */\n lerpVec3(t, t1, t2, p1, p2, dest) {\n const result = dest || math.vec3();\n const f = (t - t1) / (t2 - t1);\n result[0] = p1[0] + (f * (p2[0] - p1[0]));\n result[1] = p1[1] + (f * (p2[1] - p1[1]));\n result[2] = p1[2] + (f * (p2[2] - p1[2]));\n return result;\n },\n\n\n /**\n * Flattens a two-dimensional array into a one-dimensional array.\n *\n * @method flatten\n * @static\n * @param {Array of Arrays} a A 2D array\n * @returns Flattened 1D array\n */\n flatten(a) {\n\n const result = [];\n\n let i;\n let leni;\n let j;\n let lenj;\n let item;\n\n for (i = 0, leni = a.length; i < leni; i++) {\n item = a[i];\n for (j = 0, lenj = item.length; j < lenj; j++) {\n result.push(item[j]);\n }\n }\n\n return result;\n },\n\n\n identityQuaternion(dest = math.vec4()) {\n dest[0] = 0.0;\n dest[1] = 0.0;\n dest[2] = 0.0;\n dest[3] = 1.0;\n return dest;\n },\n\n /**\n * Initializes a quaternion from Euler angles.\n *\n * @param {Number[]} euler The Euler angles.\n * @param {String} order Euler angle order: \"XYZ\", \"YXZ\", \"ZXY\" etc.\n * @param {Number[]} [dest] Destination quaternion, created by default.\n * @returns {Number[]} The quaternion.\n */\n eulerToQuaternion(euler, order, dest = math.vec4()) {\n // http://www.mathworks.com/matlabcentral/fileexchange/\n // \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n //\tcontent/SpinCalc.m\n\n const a = (euler[0] * math.DEGTORAD) / 2;\n const b = (euler[1] * math.DEGTORAD) / 2;\n const c = (euler[2] * math.DEGTORAD) / 2;\n\n const c1 = Math.cos(a);\n const c2 = Math.cos(b);\n const c3 = Math.cos(c);\n const s1 = Math.sin(a);\n const s2 = Math.sin(b);\n const s3 = Math.sin(c);\n\n if (order === 'XYZ') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'YXZ') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n\n } else if (order === 'ZXY') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'ZYX') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n\n } else if (order === 'YZX') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'XZY') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n }\n\n return dest;\n },\n\n mat4ToQuaternion(m, dest = math.vec4()) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n const m11 = m[0];\n const m12 = m[4];\n const m13 = m[8];\n const m21 = m[1];\n const m22 = m[5];\n const m23 = m[9];\n const m31 = m[2];\n const m32 = m[6];\n const m33 = m[10];\n let s;\n\n const trace = m11 + m22 + m33;\n\n if (trace > 0) {\n\n s = 0.5 / Math.sqrt(trace + 1.0);\n\n dest[3] = 0.25 / s;\n dest[0] = (m32 - m23) * s;\n dest[1] = (m13 - m31) * s;\n dest[2] = (m21 - m12) * s;\n\n } else if (m11 > m22 && m11 > m33) {\n\n s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);\n\n dest[3] = (m32 - m23) / s;\n dest[0] = 0.25 * s;\n dest[1] = (m12 + m21) / s;\n dest[2] = (m13 + m31) / s;\n\n } else if (m22 > m33) {\n\n s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);\n\n dest[3] = (m13 - m31) / s;\n dest[0] = (m12 + m21) / s;\n dest[1] = 0.25 * s;\n dest[2] = (m23 + m32) / s;\n\n } else {\n\n s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);\n\n dest[3] = (m21 - m12) / s;\n dest[0] = (m13 + m31) / s;\n dest[1] = (m23 + m32) / s;\n dest[2] = 0.25 * s;\n }\n\n return dest;\n },\n\n vec3PairToQuaternion(u, v, dest = math.vec4()) {\n const norm_u_norm_v = Math.sqrt(math.dotVec3(u, u) * math.dotVec3(v, v));\n let real_part = norm_u_norm_v + math.dotVec3(u, v);\n\n if (real_part < 0.00000001 * norm_u_norm_v) {\n\n // If u and v are exactly opposite, rotate 180 degrees\n // around an arbitrary orthogonal axis. Axis normalisation\n // can happen later, when we normalise the quaternion.\n\n real_part = 0.0;\n\n if (Math.abs(u[0]) > Math.abs(u[2])) {\n\n dest[0] = -u[1];\n dest[1] = u[0];\n dest[2] = 0;\n\n } else {\n dest[0] = 0;\n dest[1] = -u[2];\n dest[2] = u[1]\n }\n\n } else {\n\n // Otherwise, build quaternion the standard way.\n math.cross3Vec3(u, v, dest);\n }\n\n dest[3] = real_part;\n\n return math.normalizeQuaternion(dest);\n },\n\n angleAxisToQuaternion(angleAxis, dest = math.vec4()) {\n const halfAngle = angleAxis[3] / 2.0;\n const fsin = Math.sin(halfAngle);\n dest[0] = fsin * angleAxis[0];\n dest[1] = fsin * angleAxis[1];\n dest[2] = fsin * angleAxis[2];\n dest[3] = Math.cos(halfAngle);\n return dest;\n },\n\n quaternionToEuler: ((() => {\n const mat = new FloatArrayType(16);\n return (q, order, dest) => {\n dest = dest || math.vec3();\n math.quaternionToRotationMat4(q, mat);\n math.mat4ToEuler(mat, order, dest);\n return dest;\n };\n }))(),\n\n mulQuaternions(p, q, dest = math.vec4()) {\n const p0 = p[0];\n const p1 = p[1];\n const p2 = p[2];\n const p3 = p[3];\n const q0 = q[0];\n const q1 = q[1];\n const q2 = q[2];\n const q3 = q[3];\n dest[0] = p3 * q0 + p0 * q3 + p1 * q2 - p2 * q1;\n dest[1] = p3 * q1 + p1 * q3 + p2 * q0 - p0 * q2;\n dest[2] = p3 * q2 + p2 * q3 + p0 * q1 - p1 * q0;\n dest[3] = p3 * q3 - p0 * q0 - p1 * q1 - p2 * q2;\n return dest;\n },\n\n vec3ApplyQuaternion(q, vec, dest = math.vec3()) {\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n const qx = q[0];\n const qy = q[1];\n const qz = q[2];\n const qw = q[3];\n\n // calculate quat * vector\n\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = -qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n\n dest[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;\n dest[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;\n dest[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;\n\n return dest;\n },\n\n quaternionToMat4(q, dest) {\n\n dest = math.identityMat4(dest);\n\n const q0 = q[0]; //x\n const q1 = q[1]; //y\n const q2 = q[2]; //z\n const q3 = q[3]; //w\n\n const tx = 2.0 * q0;\n const ty = 2.0 * q1;\n const tz = 2.0 * q2;\n\n const twx = tx * q3;\n const twy = ty * q3;\n const twz = tz * q3;\n\n const txx = tx * q0;\n const txy = ty * q0;\n const txz = tz * q0;\n\n const tyy = ty * q1;\n const tyz = tz * q1;\n const tzz = tz * q2;\n\n dest[0] = 1.0 - (tyy + tzz);\n dest[1] = txy + twz;\n dest[2] = txz - twy;\n\n dest[4] = txy - twz;\n dest[5] = 1.0 - (txx + tzz);\n dest[6] = tyz + twx;\n\n dest[8] = txz + twy;\n dest[9] = tyz - twx;\n\n dest[10] = 1.0 - (txx + tyy);\n\n return dest;\n },\n\n quaternionToRotationMat4(q, m) {\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n m[0] = 1 - (yy + zz);\n m[4] = xy - wz;\n m[8] = xz + wy;\n\n m[1] = xy + wz;\n m[5] = 1 - (xx + zz);\n m[9] = yz - wx;\n\n m[2] = xz - wy;\n m[6] = yz + wx;\n m[10] = 1 - (xx + yy);\n\n // last column\n m[3] = 0;\n m[7] = 0;\n m[11] = 0;\n\n // bottom row\n m[12] = 0;\n m[13] = 0;\n m[14] = 0;\n m[15] = 1;\n\n return m;\n },\n\n normalizeQuaternion(q, dest = q) {\n const len = math.lenVec4([q[0], q[1], q[2], q[3]]);\n dest[0] = q[0] / len;\n dest[1] = q[1] / len;\n dest[2] = q[2] / len;\n dest[3] = q[3] / len;\n return dest;\n },\n\n conjugateQuaternion(q, dest = q) {\n dest[0] = -q[0];\n dest[1] = -q[1];\n dest[2] = -q[2];\n dest[3] = q[3];\n return dest;\n },\n\n inverseQuaternion(q, dest) {\n return math.normalizeQuaternion(math.conjugateQuaternion(q, dest));\n },\n\n quaternionToAngleAxis(q, angleAxis = math.vec4()) {\n q = math.normalizeQuaternion(q, tempVec4);\n const q3 = q[3];\n const angle = 2 * Math.acos(q3);\n const s = Math.sqrt(1 - q3 * q3);\n if (s < 0.001) { // test to avoid divide by zero, s is always positive due to sqrt\n angleAxis[0] = q[0];\n angleAxis[1] = q[1];\n angleAxis[2] = q[2];\n } else {\n angleAxis[0] = q[0] / s;\n angleAxis[1] = q[1] / s;\n angleAxis[2] = q[2] / s;\n }\n angleAxis[3] = angle; // * 57.295779579;\n return angleAxis;\n },\n\n //------------------------------------------------------------------------------------------------------------------\n // Boundaries\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Returns a new, uninitialized 3D axis-aligned bounding box.\n *\n * @private\n */\n AABB3(values) {\n return new FloatArrayType(values || 6);\n },\n\n /**\n * Returns a new, uninitialized 2D axis-aligned bounding box.\n *\n * @private\n */\n AABB2(values) {\n return new FloatArrayType(values || 4);\n },\n\n /**\n * Returns a new, uninitialized 3D oriented bounding box (OBB).\n *\n * @private\n */\n OBB3(values) {\n return new FloatArrayType(values || 32);\n },\n\n /**\n * Returns a new, uninitialized 2D oriented bounding box (OBB).\n *\n * @private\n */\n OBB2(values) {\n return new FloatArrayType(values || 16);\n },\n\n /** Returns a new 3D bounding sphere */\n Sphere3(x, y, z, r) {\n return new FloatArrayType([x, y, z, r]);\n },\n\n /**\n * Transforms an OBB3 by a 4x4 matrix.\n *\n * @private\n */\n transformOBB3(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 4) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /** Returns true if the first AABB contains the second AABB.\n * @param aabb1\n * @param aabb2\n * @returns {boolean}\n */\n containsAABB3: function (aabb1, aabb2) {\n const result = (\n aabb1[0] <= aabb2[0] && aabb2[3] <= aabb1[3] &&\n aabb1[1] <= aabb2[1] && aabb2[4] <= aabb1[4] &&\n aabb1[2] <= aabb2[2] && aabb2[5] <= aabb1[5]);\n return result;\n },\n\n /**\n * Gets the diagonal size of an AABB3 given as minima and maxima.\n *\n * @private\n */\n getAABB3Diag: ((() => {\n\n const min = new FloatArrayType(3);\n const max = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return aabb => {\n\n min[0] = aabb[0];\n min[1] = aabb[1];\n min[2] = aabb[2];\n\n max[0] = aabb[3];\n max[1] = aabb[4];\n max[2] = aabb[5];\n\n math.subVec3(max, min, tempVec3);\n\n return Math.abs(math.lenVec3(tempVec3));\n };\n }))(),\n\n /**\n * Get a diagonal boundary size that is symmetrical about the given point.\n *\n * @private\n */\n getAABB3DiagPoint: ((() => {\n\n const min = new FloatArrayType(3);\n const max = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return (aabb, p) => {\n\n min[0] = aabb[0];\n min[1] = aabb[1];\n min[2] = aabb[2];\n\n max[0] = aabb[3];\n max[1] = aabb[4];\n max[2] = aabb[5];\n\n const diagVec = math.subVec3(max, min, tempVec3);\n\n const xneg = p[0] - aabb[0];\n const xpos = aabb[3] - p[0];\n const yneg = p[1] - aabb[1];\n const ypos = aabb[4] - p[1];\n const zneg = p[2] - aabb[2];\n const zpos = aabb[5] - p[2];\n\n diagVec[0] += (xneg > xpos) ? xneg : xpos;\n diagVec[1] += (yneg > ypos) ? yneg : ypos;\n diagVec[2] += (zneg > zpos) ? zneg : zpos;\n\n return Math.abs(math.lenVec3(diagVec));\n };\n }))(),\n\n /**\n * Gets the center of an AABB.\n *\n * @private\n */\n getAABB3Center(aabb, dest) {\n const r = dest || math.vec3();\n\n r[0] = (aabb[0] + aabb[3]) / 2;\n r[1] = (aabb[1] + aabb[4]) / 2;\n r[2] = (aabb[2] + aabb[5]) / 2;\n\n return r;\n },\n\n /**\n * Gets the center of a 2D AABB.\n *\n * @private\n */\n getAABB2Center(aabb, dest) {\n const r = dest || math.vec2();\n\n r[0] = (aabb[2] + aabb[0]) / 2;\n r[1] = (aabb[3] + aabb[1]) / 2;\n\n return r;\n },\n\n /**\n * Collapses a 3D axis-aligned boundary, ready to expand to fit 3D points.\n * Creates new AABB if none supplied.\n *\n * @private\n */\n collapseAABB3(aabb = math.AABB3()) {\n aabb[0] = math.MAX_DOUBLE;\n aabb[1] = math.MAX_DOUBLE;\n aabb[2] = math.MAX_DOUBLE;\n aabb[3] = -math.MAX_DOUBLE;\n aabb[4] = -math.MAX_DOUBLE;\n aabb[5] = -math.MAX_DOUBLE;\n\n return aabb;\n },\n\n /**\n * Converts an axis-aligned 3D boundary into an oriented boundary consisting of\n * an array of eight 3D positions, one for each corner of the boundary.\n *\n * @private\n */\n AABB3ToOBB3(aabb, obb = math.OBB3()) {\n obb[0] = aabb[0];\n obb[1] = aabb[1];\n obb[2] = aabb[2];\n obb[3] = 1;\n\n obb[4] = aabb[3];\n obb[5] = aabb[1];\n obb[6] = aabb[2];\n obb[7] = 1;\n\n obb[8] = aabb[3];\n obb[9] = aabb[4];\n obb[10] = aabb[2];\n obb[11] = 1;\n\n obb[12] = aabb[0];\n obb[13] = aabb[4];\n obb[14] = aabb[2];\n obb[15] = 1;\n\n obb[16] = aabb[0];\n obb[17] = aabb[1];\n obb[18] = aabb[5];\n obb[19] = 1;\n\n obb[20] = aabb[3];\n obb[21] = aabb[1];\n obb[22] = aabb[5];\n obb[23] = 1;\n\n obb[24] = aabb[3];\n obb[25] = aabb[4];\n obb[26] = aabb[5];\n obb[27] = 1;\n\n obb[28] = aabb[0];\n obb[29] = aabb[4];\n obb[30] = aabb[5];\n obb[31] = 1;\n\n return obb;\n },\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array.\n *\n * @private\n */\n positions3ToAABB3: ((() => {\n\n const p = new FloatArrayType(3);\n\n return (positions, aabb, positionsDecodeMatrix) => {\n aabb = aabb || math.AABB3();\n\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n if (positionsDecodeMatrix) {\n\n p[0] = positions[i + 0];\n p[1] = positions[i + 1];\n p[2] = positions[i + 2];\n\n math.decompressPosition(p, positionsDecodeMatrix, p);\n\n x = p[0];\n y = p[1];\n z = p[2];\n\n } else {\n x = positions[i + 0];\n y = positions[i + 1];\n z = positions[i + 2];\n }\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n };\n }))(),\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array.\n *\n * @private\n */\n OBB3ToAABB3(obb, aabb = math.AABB3()) {\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = obb.length; i < len; i += 4) {\n\n x = obb[i + 0];\n y = obb[i + 1];\n z = obb[i + 2];\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n },\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the given 3D points.\n *\n * @private\n */\n points3ToAABB3(points, aabb = math.AABB3()) {\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = points.length; i < len; i++) {\n\n x = points[i][0];\n y = points[i][1];\n z = points[i][2];\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n },\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D points.\n *\n * @private\n */\n points3ToSphere3: ((() => {\n\n const tempVec3 = new FloatArrayType(3);\n\n return (points, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const numPoints = points.length;\n\n for (i = 0; i < numPoints; i++) {\n x += points[i][0];\n y += points[i][1];\n z += points[i][2];\n }\n\n sphere[0] = x / numPoints;\n sphere[1] = y / numPoints;\n sphere[2] = z / numPoints;\n\n let radius = 0;\n let dist;\n\n for (i = 0; i < numPoints; i++) {\n\n dist = Math.abs(math.lenVec3(math.subVec3(points[i], sphere, tempVec3)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D positions.\n *\n * @private\n */\n positions3ToSphere3: ((() => {\n\n const tempVec3a = new FloatArrayType(3);\n const tempVec3b = new FloatArrayType(3);\n\n return (positions, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const lenPositions = positions.length;\n let radius = 0;\n\n for (i = 0; i < lenPositions; i += 3) {\n x += positions[i];\n y += positions[i + 1];\n z += positions[i + 2];\n }\n\n const numPositions = lenPositions / 3;\n\n sphere[0] = x / numPositions;\n sphere[1] = y / numPositions;\n sphere[2] = z / numPositions;\n\n let dist;\n\n for (i = 0; i < lenPositions; i += 3) {\n\n tempVec3a[0] = positions[i];\n tempVec3a[1] = positions[i + 1];\n tempVec3a[2] = positions[i + 2];\n\n dist = Math.abs(math.lenVec3(math.subVec3(tempVec3a, sphere, tempVec3b)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D points.\n *\n * @private\n */\n OBB3ToSphere3: ((() => {\n\n const point = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return (points, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const lenPoints = points.length;\n const numPoints = lenPoints / 4;\n\n for (i = 0; i < lenPoints; i += 4) {\n x += points[i + 0];\n y += points[i + 1];\n z += points[i + 2];\n }\n\n sphere[0] = x / numPoints;\n sphere[1] = y / numPoints;\n sphere[2] = z / numPoints;\n\n let radius = 0;\n let dist;\n\n for (i = 0; i < lenPoints; i += 4) {\n\n point[0] = points[i + 0];\n point[1] = points[i + 1];\n point[2] = points[i + 2];\n\n dist = Math.abs(math.lenVec3(math.subVec3(point, sphere, tempVec3)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Gets the center of a bounding sphere.\n *\n * @private\n */\n getSphere3Center(sphere, dest = math.vec3()) {\n dest[0] = sphere[0];\n dest[1] = sphere[1];\n dest[2] = sphere[2];\n\n return dest;\n },\n\n /**\n * Expands the first axis-aligned 3D boundary to enclose the second, if required.\n *\n * @private\n */\n expandAABB3(aabb1, aabb2) {\n\n if (aabb1[0] > aabb2[0]) {\n aabb1[0] = aabb2[0];\n }\n\n if (aabb1[1] > aabb2[1]) {\n aabb1[1] = aabb2[1];\n }\n\n if (aabb1[2] > aabb2[2]) {\n aabb1[2] = aabb2[2];\n }\n\n if (aabb1[3] < aabb2[3]) {\n aabb1[3] = aabb2[3];\n }\n\n if (aabb1[4] < aabb2[4]) {\n aabb1[4] = aabb2[4];\n }\n\n if (aabb1[5] < aabb2[5]) {\n aabb1[5] = aabb2[5];\n }\n\n return aabb1;\n },\n\n /**\n * Expands an axis-aligned 3D boundary to enclose the given point, if needed.\n *\n * @private\n */\n expandAABB3Point3(aabb, p) {\n\n if (aabb[0] > p[0]) {\n aabb[0] = p[0];\n }\n\n if (aabb[1] > p[1]) {\n aabb[1] = p[1];\n }\n\n if (aabb[2] > p[2]) {\n aabb[2] = p[2];\n }\n\n if (aabb[3] < p[0]) {\n aabb[3] = p[0];\n }\n\n if (aabb[4] < p[1]) {\n aabb[4] = p[1];\n }\n\n if (aabb[5] < p[2]) {\n aabb[5] = p[2];\n }\n\n return aabb;\n },\n\n /**\n * Calculates the normal vector of a triangle.\n *\n * @private\n */\n triangleNormal(a, b, c, normal = math.vec3()) {\n const p1x = b[0] - a[0];\n const p1y = b[1] - a[1];\n const p1z = b[2] - a[2];\n\n const p2x = c[0] - a[0];\n const p2y = c[1] - a[1];\n const p2z = c[2] - a[2];\n\n const p3x = p1y * p2z - p1z * p2y;\n const p3y = p1z * p2x - p1x * p2z;\n const p3z = p1x * p2y - p1y * p2x;\n\n const mag = Math.sqrt(p3x * p3x + p3y * p3y + p3z * p3z);\n if (mag === 0) {\n normal[0] = 0;\n normal[1] = 0;\n normal[2] = 0;\n } else {\n normal[0] = p3x / mag;\n normal[1] = p3y / mag;\n normal[2] = p3z / mag;\n }\n\n return normal\n }\n};\n\nexport {math};","import {math} from \"../../lib/math.js\";\n\nfunction quantizePositions (positions, lenPositions, aabb, quantizedPositions) {\n const xmin = aabb[0];\n const ymin = aabb[1];\n const zmin = aabb[2];\n const xwid = aabb[3] - xmin;\n const ywid = aabb[4] - ymin;\n const zwid = aabb[5] - zmin;\n const maxInt = 65535;\n const xMultiplier = maxInt / xwid;\n const yMultiplier = maxInt / ywid;\n const zMultiplier = maxInt / zwid;\n const verify = (num) => num >= 0 ? num : 0;\n for (let i = 0; i < lenPositions; i += 3) {\n quantizedPositions[i + 0] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 0] - xmin) * xMultiplier)));\n quantizedPositions[i + 1] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 1] - ymin) * yMultiplier)));\n quantizedPositions[i + 2] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 2] - zmin) * zMultiplier)));\n }\n}\n\nfunction compressPosition(p, aabb, q) {\n const multiplier = new Float32Array([\n aabb[3] !== aabb[0] ? 65535 / (aabb[3] - aabb[0]) : 0,\n aabb[4] !== aabb[1] ? 65535 / (aabb[4] - aabb[1]) : 0,\n aabb[5] !== aabb[2] ? 65535 / (aabb[5] - aabb[2]) : 0\n ]);\n q[0] = Math.max(0, Math.min(65535, Math.floor((p[0] - aabb[0]) * multiplier[0])));\n q[1] = Math.max(0, Math.min(65535, Math.floor((p[1] - aabb[1]) * multiplier[1])));\n q[2] = Math.max(0, Math.min(65535, Math.floor((p[2] - aabb[2]) * multiplier[2])));\n}\n\nvar createPositionsDecodeMatrix = (function () {\n const translate = math.mat4();\n const scale = math.mat4();\n return function (aabb, positionsDecodeMatrix) {\n positionsDecodeMatrix = positionsDecodeMatrix || math.mat4();\n const xmin = aabb[0];\n const ymin = aabb[1];\n const zmin = aabb[2];\n const xwid = aabb[3] - xmin;\n const ywid = aabb[4] - ymin;\n const zwid = aabb[5] - zmin;\n const maxInt = 65535;\n math.identityMat4(translate);\n math.translationMat4v(aabb, translate);\n math.identityMat4(scale);\n math.scalingMat4v([xwid / maxInt, ywid / maxInt, zwid / maxInt], scale);\n math.mulMat4(translate, scale, positionsDecodeMatrix);\n return positionsDecodeMatrix;\n };\n})();\n\nfunction transformAndOctEncodeNormals(modelNormalMatrix, normals, lenNormals, compressedNormals, lenCompressedNormals) {\n // http://jcgt.org/published/0003/02/01/\n let oct, dec, best, currentCos, bestCos;\n let i, ei;\n let localNormal = math.vec3();\n let worldNormal = math.vec3();\n for (i = 0; i < lenNormals; i += 3) {\n localNormal[0] = normals[i];\n localNormal[1] = normals[i + 1];\n localNormal[2] = normals[i + 2];\n\n math.transformVec3(modelNormalMatrix, localNormal, worldNormal);\n math.normalizeVec3(worldNormal, worldNormal);\n\n // Test various combinations of ceil and floor to minimize rounding errors\n best = oct = octEncodeVec3(worldNormal, 0, \"floor\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = bestCos = dot(worldNormal, 0, dec);\n oct = octEncodeVec3(worldNormal, 0, \"ceil\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = dot(worldNormal, 0, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(worldNormal, 0, \"floor\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(worldNormal, 0, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(worldNormal, 0, \"ceil\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(worldNormal, 0, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n compressedNormals[lenCompressedNormals + i + 0] = best[0];\n compressedNormals[lenCompressedNormals + i + 1] = best[1];\n compressedNormals[lenCompressedNormals + i + 2] = 0.0; // Unused\n }\n lenCompressedNormals += lenNormals;\n return lenCompressedNormals;\n}\n\nfunction octEncodeNormals(normals, lenNormals, compressedNormals, lenCompressedNormals) { // http://jcgt.org/published/0003/02/01/\n let oct, dec, best, currentCos, bestCos;\n for (let i = 0; i < lenNormals; i += 3) {\n // Test various combinations of ceil and floor to minimize rounding errors\n best = oct = octEncodeVec3(normals, i, \"floor\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = bestCos = dot(normals, i, dec);\n oct = octEncodeVec3(normals, i, \"ceil\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = dot(normals, i, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(normals, i, \"floor\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(normals, i, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(normals, i, \"ceil\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(normals, i, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n compressedNormals[lenCompressedNormals + i + 0] = best[0];\n compressedNormals[lenCompressedNormals + i + 1] = best[1];\n compressedNormals[lenCompressedNormals + i + 2] = 0.0; // Unused\n }\n lenCompressedNormals += lenNormals;\n return lenCompressedNormals;\n}\n\n/**\n * @private\n */\nfunction octEncodeVec3(array, i, xfunc, yfunc) { // Oct-encode single normal vector in 2 bytes\n let x = array[i] / (Math.abs(array[i]) + Math.abs(array[i + 1]) + Math.abs(array[i + 2]));\n let y = array[i + 1] / (Math.abs(array[i]) + Math.abs(array[i + 1]) + Math.abs(array[i + 2]));\n if (array[i + 2] < 0) {\n let tempx = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n let tempy = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n x = tempx;\n y = tempy;\n }\n return new Int8Array([\n Math[xfunc](x * 127.5 + (x < 0 ? -1 : 0)),\n Math[yfunc](y * 127.5 + (y < 0 ? -1 : 0))\n ]);\n}\n\n/**\n * Decode an oct-encoded normal\n */\nfunction octDecodeVec2(oct) {\n let x = oct[0];\n let y = oct[1];\n x /= x < 0 ? 127 : 128;\n y /= y < 0 ? 127 : 128;\n const z = 1 - Math.abs(x) - Math.abs(y);\n if (z < 0) {\n x = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n y = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n }\n const length = Math.sqrt(x * x + y * y + z * z);\n return [\n x / length,\n y / length,\n z / length\n ];\n}\n\n/**\n * Dot product of a normal in an array against a candidate decoding\n * @private\n */\nfunction dot(array, i, vec3) {\n return array[i] * vec3[0] + array[i + 1] * vec3[1] + array[i + 2] * vec3[2];\n}\n\n/**\n * @private\n */\nconst geometryCompression = {\n quantizePositions,\n compressPosition,\n createPositionsDecodeMatrix,\n transformAndOctEncodeNormals,\n octEncodeNormals,\n};\n\nexport {geometryCompression}","/*----------------------------------------------------------------------------------------------------------------------\n * NOTE: The values of these constants must match those within xeokit-sdk\n *--------------------------------------------------------------------------------------------------------------------*/\n\n/**\n * Texture wrapping mode in which the texture repeats to infinity.\n */\nexport const RepeatWrapping = 1000;\n\n/**\n * Texture wrapping mode in which the last pixel of the texture stretches to the edge of the mesh.\n */\nexport const ClampToEdgeWrapping = 1001;\n\n/**\n * Texture wrapping mode in which the texture repeats to infinity, mirroring on each repeat.\n */\nexport const MirroredRepeatWrapping = 1002;\n\n/**\n * Texture magnification and minification filter that returns the nearest texel to the given sample coordinates.\n */\nexport const NearestFilter = 1003;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and returns the nearest texel to the given sample coordinates.\n */\nexport const NearestMipMapNearestFilter = 1004;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured\n * and returns the nearest texel to the given sample coordinates.\n */\nexport const NearestMipmapNearestFilter = 1004;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\n */\nexport const NearestMipmapLinearFilter = 1005;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\n */\nexport const NearestMipMapLinearFilter = 1005;\n\n/**\n * Texture magnification and minification filter that returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nexport const LinearFilter = 1006;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\n * returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nexport const LinearMipmapNearestFilter = 1007;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\n * returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nexport const LinearMipMapNearestFilter = 1007;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\n * weighted average of those two values.\n */\nexport const LinearMipmapLinearFilter = 1008;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\n * weighted average of those two values.\n */\nexport const LinearMipMapLinearFilter = 1008;\n\n/**\n * Media type for GIF images.\n */\nexport const GIFMediaType = 10000;\n\n/**\n * Media type for JPEG images.\n */\nexport const JPEGMediaType = 10001;\n\n/**\n * Media type for PNG images.\n */\nexport const PNGMediaType = 10002;","import {math} from \"../../lib/math.js\";\n\n/**\n * @private\n */\nconst buildEdgeIndices = (function () {\n\n const uniquePositions = [];\n const indicesLookup = [];\n const indicesReverseLookup = [];\n const weldedIndices = [];\n\n// TODO: Optimize with caching, but need to cater to both compressed and uncompressed positions\n\n const faces = [];\n let numFaces = 0;\n const compa = new Uint16Array(3);\n const compb = new Uint16Array(3);\n const compc = new Uint16Array(3);\n const a = math.vec3();\n const b = math.vec3();\n const c = math.vec3();\n const cb = math.vec3();\n const ab = math.vec3();\n const cross = math.vec3();\n const normal = math.vec3();\n const inverseNormal = math.vec3();\n\n function weldVertices(positions, indices) {\n const positionsMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n let vx;\n let vy;\n let vz;\n let key;\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = Math.pow(10, precisionPoints);\n let i;\n let len;\n let lenUniquePositions = 0;\n for (i = 0, len = positions.length; i < len; i += 3) {\n vx = positions[i];\n vy = positions[i + 1];\n vz = positions[i + 2];\n key = Math.round(vx * precision) + '_' + Math.round(vy * precision) + '_' + Math.round(vz * precision);\n if (positionsMap[key] === undefined) {\n positionsMap[key] = lenUniquePositions / 3;\n uniquePositions[lenUniquePositions++] = vx;\n uniquePositions[lenUniquePositions++] = vy;\n uniquePositions[lenUniquePositions++] = vz;\n }\n indicesLookup[i / 3] = positionsMap[key];\n }\n for (i = 0, len = indices.length; i < len; i++) {\n weldedIndices[i] = indicesLookup[indices[i]];\n indicesReverseLookup[weldedIndices[i]] = indices[i];\n }\n }\n\n function buildFaces(numIndices, positionsDecodeMatrix) {\n numFaces = 0;\n for (let i = 0, len = numIndices; i < len; i += 3) {\n const ia = ((weldedIndices[i]) * 3);\n const ib = ((weldedIndices[i + 1]) * 3);\n const ic = ((weldedIndices[i + 2]) * 3);\n if (positionsDecodeMatrix) {\n compa[0] = uniquePositions[ia];\n compa[1] = uniquePositions[ia + 1];\n compa[2] = uniquePositions[ia + 2];\n compb[0] = uniquePositions[ib];\n compb[1] = uniquePositions[ib + 1];\n compb[2] = uniquePositions[ib + 2];\n compc[0] = uniquePositions[ic];\n compc[1] = uniquePositions[ic + 1];\n compc[2] = uniquePositions[ic + 2];\n // Decode\n math.decompressPosition(compa, positionsDecodeMatrix, a);\n math.decompressPosition(compb, positionsDecodeMatrix, b);\n math.decompressPosition(compc, positionsDecodeMatrix, c);\n } else {\n a[0] = uniquePositions[ia];\n a[1] = uniquePositions[ia + 1];\n a[2] = uniquePositions[ia + 2];\n b[0] = uniquePositions[ib];\n b[1] = uniquePositions[ib + 1];\n b[2] = uniquePositions[ib + 2];\n c[0] = uniquePositions[ic];\n c[1] = uniquePositions[ic + 1];\n c[2] = uniquePositions[ic + 2];\n }\n math.subVec3(c, b, cb);\n math.subVec3(a, b, ab);\n math.cross3Vec3(cb, ab, cross);\n math.normalizeVec3(cross, normal);\n const face = faces[numFaces] || (faces[numFaces] = {normal: math.vec3()});\n face.normal[0] = normal[0];\n face.normal[1] = normal[1];\n face.normal[2] = normal[2];\n numFaces++;\n }\n }\n\n return function (positions, indices, positionsDecodeMatrix, edgeThreshold) {\n weldVertices(positions, indices);\n buildFaces(indices.length, positionsDecodeMatrix);\n const edgeIndices = [];\n const thresholdDot = Math.cos(math.DEGTORAD * edgeThreshold);\n const edges = {};\n let edge1;\n let edge2;\n let index1;\n let index2;\n let key;\n let largeIndex = false;\n let edge;\n let normal1;\n let normal2;\n let dot;\n let ia;\n let ib;\n for (let i = 0, len = indices.length; i < len; i += 3) {\n const faceIndex = i / 3;\n for (let j = 0; j < 3; j++) {\n edge1 = weldedIndices[i + j];\n edge2 = weldedIndices[i + ((j + 1) % 3)];\n index1 = Math.min(edge1, edge2);\n index2 = Math.max(edge1, edge2);\n key = index1 + ',' + index2;\n if (edges[key] === undefined) {\n edges[key] = {\n index1: index1,\n index2: index2,\n face1: faceIndex,\n face2: undefined,\n };\n } else {\n edges[key].face2 = faceIndex;\n }\n }\n }\n for (key in edges) {\n edge = edges[key];\n // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n if (edge.face2 !== undefined) {\n normal1 = faces[edge.face1].normal;\n normal2 = faces[edge.face2].normal;\n inverseNormal[0] = -normal2[0];\n inverseNormal[1] = -normal2[1];\n inverseNormal[2] = -normal2[2];\n dot = Math.abs(math.dotVec3(normal1, normal2));\n const dot2 = Math.abs(math.dotVec3(normal1, inverseNormal));\n if (dot > thresholdDot && dot2 > thresholdDot) {\n continue;\n }\n }\n ia = indicesReverseLookup[edge.index1];\n ib = indicesReverseLookup[edge.index2];\n if (!largeIndex && ia > 65535 || ib > 65535) {\n largeIndex = true;\n }\n edgeIndices.push(ia);\n edgeIndices.push(ib);\n }\n return (largeIndex) ? new Uint32Array(edgeIndices) : new Uint16Array(edgeIndices);\n };\n})();\n\n\nexport {buildEdgeIndices};","/**\n * Uses edge adjacency counts to identify if the given triangle mesh can be rendered with backface culling enabled.\n *\n * If all edges are connected to exactly two triangles, then the mesh will likely be a closed solid, and we can safely\n * render it with backface culling enabled.\n *\n * Otherwise, the mesh is a surface, and we must render it with backface culling disabled.\n *\n * @private\n */\nconst isTriangleMeshSolid = (indices, positions, vertexIndexMapping, edges) => {\n\n function compareIndexPositions(a, b)\n {\n let posA, posB;\n\n for (let i = 0; i < 3; i++) {\n posA = positions [a*3+i];\n posB = positions [b*3+i];\n\n if (posA !== posB) {\n return posB - posA;\n }\n }\n\n return 0;\n };\n\n // Group together indices corresponding to same position coordinates\n let newIndices = indices.slice ().sort (compareIndexPositions);\n\n // Calculate the mapping:\n // - from original index in indices array\n // - to indices-for-unique-positions\n let uniqueVertexIndex = null;\n\n for (let i = 0, len = newIndices.length; i < len; i++) {\n if (i == 0 || 0 != compareIndexPositions (\n newIndices[i],\n newIndices[i-1],\n )) {\n // different position\n uniqueVertexIndex = newIndices [i];\n }\n\n vertexIndexMapping [\n newIndices[i]\n ] = uniqueVertexIndex;\n }\n\n // Generate the list of edges\n for (let i = 0, len = indices.length; i < len; i += 3) {\n\n const a = vertexIndexMapping[indices[i]];\n const b = vertexIndexMapping[indices[i+1]];\n const c = vertexIndexMapping[indices[i+2]];\n\n let a2 = a;\n let b2 = b;\n let c2 = c;\n\n if (a > b && a > c) {\n if (b > c) {\n a2 = a;\n b2 = b;\n c2 = c;\n } else {\n a2 = a;\n b2 = c;\n c2 = b;\n }\n } else if (b > a && b > c) {\n if (a > c) {\n a2 = b;\n b2 = a;\n c2 = c;\n } else {\n a2 = b;\n b2 = c;\n c2 = a;\n }\n } else if (c > a && c > b) {\n if (a > b) {\n a2 = c;\n b2 = a;\n c2 = b;\n } else {\n a2 = c;\n b2 = b;\n c2 = a;\n }\n }\n\n edges[i+0] = [\n a2, b2\n ];\n edges[i+1] = [\n b2, c2\n ];\n\n if (a2 > c2) {\n const temp = c2;\n c2 = a2;\n a2 = temp;\n }\n\n edges[i+2] = [\n c2, a2\n ];\n }\n\n // Group semantically equivalent edgdes together\n function compareEdges (e1, e2) {\n let a, b;\n\n for (let i = 0; i < 2; i++) {\n a = e1[i];\n b = e2[i];\n\n if (b !== a) {\n return b - a;\n }\n }\n\n return 0;\n }\n\n edges = edges.slice(0, indices.length);\n\n edges.sort (compareEdges);\n\n // Make sure each edge is used exactly twice\n let sameEdgeCount = 0;\n\n for (let i = 0; i < edges.length; i++)\n {\n if (i === 0 || 0 !== compareEdges (\n edges[i], edges[i-1]\n )) {\n // different edge\n if (0 !== i && sameEdgeCount !== 2)\n {\n return false;\n }\n\n sameEdgeCount = 1;\n }\n else\n {\n // same edge\n sameEdgeCount++;\n }\n }\n\n if (edges.length > 0 && sameEdgeCount !== 2)\n {\n return false;\n }\n\n // Each edge is used exactly twice, this is a\n // watertight surface and hence a solid geometry.\n return true;\n};\n\nexport {isTriangleMeshSolid};","/**\n * Represents the usage of a {@link XKTGeometry} by an {@link XKTEntity}.\n *\n * * Created by {@link XKTModel#createEntity}\n * * Stored in {@link XKTEntity#meshes} and {@link XKTModel#meshesList}\n * * Has an {@link XKTGeometry}, and an optional {@link XKTTextureSet}, both of which it can share with other {@link XKTMesh}es\n * * Has {@link XKTMesh#color}, {@link XKTMesh#opacity}, {@link XKTMesh#metallic} and {@link XKTMesh#roughness} PBR attributes\n * @class XKTMesh\n */\nclass XKTMesh {\n\n /**\n * @private\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTMesh in {@link XKTModel#meshes}.\n *\n * @type {Number}\n */\n this.meshId = cfg.meshId;\n\n /**\n * Index of this XKTMesh in {@link XKTModel#meshesList};\n *\n * @type {Number}\n */\n this.meshIndex = cfg.meshIndex;\n\n /**\n * The 4x4 modeling transform matrix.\n *\n * Transform is relative to the center of the {@link XKTTile} that contains this XKTMesh's {@link XKTEntity},\n * which is given in {@link XKTMesh#entity}.\n *\n * When the ````XKTEntity```` shares its {@link XKTGeometry}s with other ````XKTEntity````s, this matrix is used\n * to transform this XKTMesh's XKTGeometry into World-space. When this XKTMesh does not share its ````XKTGeometry````,\n * then this matrix is ignored.\n *\n * @type {Number[]}\n */\n this.matrix = cfg.matrix;\n\n /**\n * The instanced {@link XKTGeometry}.\n *\n * @type {XKTGeometry}\n */\n this.geometry = cfg.geometry;\n\n /**\n * RGB color of this XKTMesh.\n *\n * @type {Float32Array}\n */\n this.color = cfg.color || new Float32Array([1, 1, 1]);\n\n /**\n * PBR metallness of this XKTMesh.\n *\n * @type {Number}\n */\n this.metallic = (cfg.metallic !== null && cfg.metallic !== undefined) ? cfg.metallic : 0;\n\n /**\n * PBR roughness of this XKTMesh.\n * The {@link XKTTextureSet} that defines the appearance of this XKTMesh.\n *\n * @type {Number}\n * @type {XKTTextureSet}\n */\n this.roughness = (cfg.roughness !== null && cfg.roughness !== undefined) ? cfg.roughness : 1;\n\n /**\n * Opacity of this XKTMesh.\n *\n * @type {Number}\n */\n this.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? cfg.opacity : 1.0;\n\n /**\n * The {@link XKTTextureSet} that defines the appearance of this XKTMesh.\n *\n * @type {XKTTextureSet}\n */\n this.textureSet = cfg.textureSet;\n\n /**\n * The owner {@link XKTEntity}.\n *\n * Set by {@link XKTModel#createEntity}.\n *\n * @type {XKTEntity}\n */\n this.entity = null; // Set after instantiation, when the Entity is known\n }\n}\n\nexport {XKTMesh};","/**\n * An element of reusable geometry within an {@link XKTModel}.\n *\n * * Created by {@link XKTModel#createGeometry}\n * * Stored in {@link XKTModel#geometries} and {@link XKTModel#geometriesList}\n * * Referenced by {@link XKTMesh}s, which belong to {@link XKTEntity}s\n *\n * @class XKTGeometry\n */\nclass XKTGeometry {\n\n /**\n * @private\n * @param {*} cfg Configuration for the XKTGeometry.\n * @param {Number} cfg.geometryId Unique ID of the geometry in {@link XKTModel#geometries}.\n * @param {String} cfg.primitiveType Type of this geometry - \"triangles\", \"points\" or \"lines\" so far.\n * @param {Number} cfg.geometryIndex Index of this XKTGeometry in {@link XKTModel#geometriesList}.\n * @param {Float64Array} cfg.positions Non-quantized 3D vertex positions.\n * @param {Float32Array} cfg.normals Non-compressed vertex normals.\n * @param {Uint8Array} cfg.colorsCompressed Unsigned 8-bit integer RGBA vertex colors.\n * @param {Float32Array} cfg.uvs Non-compressed vertex UV coordinates.\n * @param {Uint32Array} cfg.indices Indices to organize the vertex positions and normals into triangles.\n * @param {Uint32Array} cfg.edgeIndices Indices to organize the vertex positions into edges.\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTGeometry in {@link XKTModel#geometries}.\n *\n * @type {Number}\n */\n this.geometryId = cfg.geometryId;\n\n /**\n * The type of primitive - \"triangles\" | \"points\" | \"lines\".\n *\n * @type {String}\n */\n this.primitiveType = cfg.primitiveType;\n\n /**\n * Index of this XKTGeometry in {@link XKTModel#geometriesList}.\n *\n * @type {Number}\n */\n this.geometryIndex = cfg.geometryIndex;\n\n /**\n * The number of {@link XKTMesh}s that reference this XKTGeometry.\n *\n * @type {Number}\n */\n this.numInstances = 0;\n\n /**\n * Non-quantized 3D vertex positions.\n *\n * Defined for all primitive types.\n *\n * @type {Float64Array}\n */\n this.positions = cfg.positions;\n\n /**\n * Quantized vertex positions.\n *\n * Defined for all primitive types.\n *\n * This array is later created from {@link XKTGeometry#positions} by {@link XKTModel#finalize}.\n *\n * @type {Uint16Array}\n */\n this.positionsQuantized = new Uint16Array(cfg.positions.length);\n\n /**\n * Non-compressed 3D vertex normals.\n *\n * Defined only for triangle primitives. Can be null if we want xeokit to auto-generate them. Ignored for points and lines.\n *\n * @type {Float32Array}\n */\n this.normals = cfg.normals;\n\n /**\n * Compressed vertex normals.\n *\n * Defined only for triangle primitives. Ignored for points and lines.\n *\n * This array is later created from {@link XKTGeometry#normals} by {@link XKTModel#finalize}.\n *\n * Will be null if {@link XKTGeometry#normals} is also null.\n *\n * @type {Int8Array}\n */\n this.normalsOctEncoded = null;\n\n /**\n * Compressed RGBA vertex colors.\n *\n * Defined only for point primitives. Ignored for triangles and lines.\n *\n * @type {Uint8Array}\n */\n this.colorsCompressed = cfg.colorsCompressed;\n\n /**\n * Non-compressed vertex UVs.\n *\n * @type {Float32Array}\n */\n this.uvs = cfg.uvs;\n\n /**\n * Compressed vertex UVs.\n *\n * @type {Uint16Array}\n */\n this.uvsCompressed = cfg.uvsCompressed;\n\n /**\n * Indices that organize the vertex positions and normals as triangles.\n *\n * Defined only for triangle and lines primitives. Ignored for points.\n *\n * @type {Uint32Array}\n */\n this.indices = cfg.indices;\n\n /**\n * Indices that organize the vertex positions as edges.\n *\n * Defined only for triangle primitives. Ignored for points and lines.\n *\n * @type {Uint32Array}\n */\n this.edgeIndices = cfg.edgeIndices;\n\n /**\n * When {@link XKTGeometry#primitiveType} is \"triangles\", this is ````true```` when this geometry is a watertight mesh.\n *\n * Defined only for triangle primitives. Ignored for points and lines.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * @type {boolean}\n */\n this.solid = false;\n }\n\n /**\n * Convenience property that is ````true```` when {@link XKTGeometry#numInstances} is greater that one.\n * @returns {boolean}\n */\n get reused() {\n return (this.numInstances > 1);\n }\n}\n\nexport {XKTGeometry};","import {math} from \"../lib/math.js\";\n\n/**\n * An object within an {@link XKTModel}.\n *\n * * Created by {@link XKTModel#createEntity}\n * * Stored in {@link XKTModel#entities} and {@link XKTModel#entitiesList}\n * * Has one or more {@link XKTMesh}s, each having an {@link XKTGeometry}\n *\n * @class XKTEntity\n */\nclass XKTEntity {\n\n /**\n * @private\n * @param entityId\n * @param meshes\n */\n constructor(entityId, meshes) {\n\n /**\n * Unique ID of this ````XKTEntity```` in {@link XKTModel#entities}.\n *\n * For a BIM model, this will be an IFC product ID.\n *\n * We can also use {@link XKTModel#createMetaObject} to create an {@link XKTMetaObject} to specify metadata for\n * this ````XKTEntity````. To associate the {@link XKTMetaObject} with our {@link XKTEntity}, we give\n * {@link XKTMetaObject#metaObjectId} the same value as {@link XKTEntity#entityId}.\n *\n * @type {String}\n */\n this.entityId = entityId;\n\n /**\n * Index of this ````XKTEntity```` in {@link XKTModel#entitiesList}.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * @type {Number}\n */\n this.entityIndex = null;\n\n /**\n * A list of {@link XKTMesh}s that indicate which {@link XKTGeometry}s are used by this Entity.\n *\n * @type {XKTMesh[]}\n */\n this.meshes = meshes;\n\n /**\n * World-space axis-aligned bounding box (AABB) that encloses the {@link XKTGeometry#positions} of\n * the {@link XKTGeometry}s that are used by this ````XKTEntity````.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * @type {Float32Array}\n */\n this.aabb = math.AABB3();\n\n /**\n * Indicates if this ````XKTEntity```` shares {@link XKTGeometry}s with other {@link XKTEntity}'s.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * Note that when an ````XKTEntity```` shares ````XKTGeometrys````, it shares **all** of its ````XKTGeometrys````. An ````XKTEntity````\n * never shares only some of its ````XKTGeometrys```` - it always shares either the whole set or none at all.\n *\n * @type {Boolean}\n */\n this.hasReusedGeometries = false;\n }\n}\n\nexport {XKTEntity};","/**\n * @desc A box-shaped 3D region within an {@link XKTModel} that contains {@link XKTEntity}s.\n *\n * * Created by {@link XKTModel#finalize}\n * * Stored in {@link XKTModel#tilesList}\n *\n * @class XKTTile\n */\nclass XKTTile {\n\n /**\n * Creates a new XKTTile.\n *\n * @private\n * @param aabb\n * @param entities\n */\n constructor(aabb, entities) {\n\n /**\n * Axis-aligned World-space bounding box that encloses the {@link XKTEntity}'s within this Tile.\n *\n * @type {Float64Array}\n */\n this.aabb = aabb;\n\n /**\n * The {@link XKTEntity}'s within this XKTTile.\n *\n * @type {XKTEntity[]}\n */\n this.entities = entities;\n }\n}\n\nexport {XKTTile};","/**\n * A kd-Tree node, used internally by {@link XKTModel}.\n *\n * @private\n */\nclass KDNode {\n\n /**\n * Create a KDNode with an axis-aligned 3D World-space boundary.\n */\n constructor(aabb) {\n\n /**\n * The axis-aligned 3D World-space boundary of this KDNode.\n *\n * @type {Float64Array}\n */\n this.aabb = aabb;\n\n /**\n * The {@link XKTEntity}s within this KDNode.\n */\n this.entities = null;\n\n /**\n * The left child KDNode.\n */\n this.left = null;\n\n /**\n * The right child KDNode.\n */\n this.right = null;\n }\n}\n\nexport {KDNode};","/**\n * A meta object within an {@link XKTModel}.\n *\n * These are plugged together into a parent-child hierarchy to represent structural\n * metadata for the {@link XKTModel}.\n *\n * The leaf XKTMetaObjects are usually associated with\n * an {@link XKTEntity}, which they do so by sharing the same ID,\n * ie. where {@link XKTMetaObject#metaObjectId} == {@link XKTEntity#entityId}.\n *\n * * Created by {@link XKTModel#createMetaObject}\n * * Stored in {@link XKTModel#metaObjects} and {@link XKTModel#metaObjectsList}\n * * Has an ID, a type, and a human-readable name\n * * May have a parent {@link XKTMetaObject}\n * * When no children, is usually associated with an {@link XKTEntity}\n *\n * @class XKTMetaObject\n */\nclass XKTMetaObject {\n\n /**\n * @private\n * @param metaObjectId\n * @param propertySetIds\n * @param metaObjectType\n * @param metaObjectName\n * @param parentMetaObjectId\n */\n constructor(metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId) {\n\n /**\n * Unique ID of this ````XKTMetaObject```` in {@link XKTModel#metaObjects}.\n *\n * For a BIM model, this will be an IFC product ID.\n *\n * If this is a leaf XKTMetaObject, where it is not a parent to any other XKTMetaObject,\n * then this will be equal to the ID of an {@link XKTEntity} in {@link XKTModel#entities},\n * ie. where {@link XKTMetaObject#metaObjectId} == {@link XKTEntity#entityId}.\n *\n * @type {String}\n */\n this.metaObjectId = metaObjectId;\n\n /**\n * Unique ID of one or more property sets that contains additional metadata about this\n * {@link XKTMetaObject}. The property sets can be stored in an external system, or\n * within the {@link XKTModel}, as {@link XKTPropertySet}s within {@link XKTModel#propertySets}.\n *\n * @type {String[]}\n */\n this.propertySetIds = propertySetIds;\n\n /**\n * Indicates the XKTMetaObject meta object type.\n *\n * This defaults to \"default\".\n *\n * @type {string}\n */\n this.metaObjectType = metaObjectType;\n\n /**\n * Indicates the XKTMetaObject meta object name.\n *\n * This defaults to {@link XKTMetaObject#metaObjectId}.\n *\n * @type {string}\n */\n this.metaObjectName = metaObjectName;\n\n /**\n * The parent XKTMetaObject, if any.\n *\n * Will be null if there is no parent.\n *\n * @type {String}\n */\n this.parentMetaObjectId = parentMetaObjectId;\n }\n}\n\nexport {XKTMetaObject};","/**\n * A property set within an {@link XKTModel}.\n *\n * These are shared among {@link XKTMetaObject}s.\n *\n * * Created by {@link XKTModel#createPropertySet}\n * * Stored in {@link XKTModel#propertySets} and {@link XKTModel#propertySetsList}\n * * Has an ID, a type, and a human-readable name\n *\n * @class XKTPropertySet\n */\nclass XKTPropertySet {\n\n /**\n * @private\n */\n constructor(propertySetId, propertySetType, propertySetName, properties) {\n\n /**\n * Unique ID of this ````XKTPropertySet```` in {@link XKTModel#propertySets}.\n *\n * @type {String}\n */\n this.propertySetId = propertySetId;\n\n /**\n * Indicates the ````XKTPropertySet````'s type.\n *\n * This defaults to \"default\".\n *\n * @type {string}\n */\n this.propertySetType = propertySetType;\n\n /**\n * Indicates the XKTPropertySet meta object name.\n *\n * This defaults to {@link XKTPropertySet#propertySetId}.\n *\n * @type {string}\n */\n this.propertySetName = propertySetName;\n\n /**\n * The properties within this ````XKTPropertySet````.\n *\n * @type {*[]}\n */\n this.properties = properties;\n }\n}\n\nexport {XKTPropertySet};","/**\n * A texture shared by {@link XKTTextureSet}s.\n *\n * * Created by {@link XKTModel#createTexture}\n * * Stored in {@link XKTTextureSet#textures}, {@link XKTModel#textures} and {@link XKTModel#texturesList}\n *\n * @class XKTTexture\n */\nimport {RepeatWrapping, LinearMipMapNearestFilter} from \"../constants\";\n\nclass XKTTexture {\n\n /**\n * @private\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTTexture in {@link XKTModel#textures}.\n *\n * @type {Number}\n */\n this.textureId = cfg.textureId;\n\n /**\n * Index of this XKTTexture in {@link XKTModel#texturesList};\n *\n * @type {Number}\n */\n this.textureIndex = cfg.textureIndex;\n\n /**\n * Texture image data.\n *\n * @type {Buffer}\n */\n this.imageData = cfg.imageData;\n\n /**\n * Which material channel this texture is applied to, as determined by its {@link XKTTextureSet}s.\n *\n * @type {Number}\n */\n this.channel = null;\n\n /**\n * Width of this XKTTexture.\n *\n * @type {Number}\n */\n this.width = cfg.width;\n\n /**\n * Height of this XKTTexture.\n *\n * @type {Number}\n */\n this.height = cfg.height;\n\n /**\n * Texture file source.\n *\n * @type {String}\n */\n this.src = cfg.src;\n\n /**\n * Whether this XKTTexture is to be compressed.\n *\n * @type {Boolean}\n */\n this.compressed = (!!cfg.compressed);\n\n /**\n * Media type of this XKTTexture.\n *\n * Supported values are {@link GIFMediaType}, {@link PNGMediaType} and {@link JPEGMediaType}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.mediaType = cfg.mediaType;\n\n /**\n * How the texture is sampled when a texel covers less than one pixel. Supported values\n * are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter},\n * {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter}\n * and {@link LinearMipMapLinearFilter}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.minFilter = cfg.minFilter || LinearMipMapNearestFilter;\n\n /**\n * How the texture is sampled when a texel covers more than one pixel. Supported values\n * are {@link LinearFilter} and {@link NearestFilter}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.magFilter = cfg.magFilter || LinearMipMapNearestFilter;\n\n /**\n * S wrapping mode.\n *\n * Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.wrapS = cfg.wrapS || RepeatWrapping;\n\n /**\n * T wrapping mode.\n *\n * Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.wrapT = cfg.wrapT || RepeatWrapping;\n\n /**\n * R wrapping mode.\n *\n * Ignored for compressed textures.\n *\n * Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n *\n * @type {*|number}\n */\n this.wrapR = cfg.wrapR || RepeatWrapping\n }\n}\n\nexport {XKTTexture};","/**\n * A set of textures shared by {@link XKTMesh}es.\n *\n * * Created by {@link XKTModel#createTextureSet}\n * * Registered in {@link XKTMesh#material}, {@link XKTModel#materials} and {@link XKTModel#.textureSetsList}\n *\n * @class XKTMetalRoughMaterial\n */\nclass XKTTextureSet {\n\n /**\n * @private\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTTextureSet in {@link XKTModel#materials}.\n *\n * @type {Number}\n */\n this.textureSetId = cfg.textureSetId;\n\n /**\n * Index of this XKTTexture in {@link XKTModel#texturesList};\n *\n * @type {Number}\n */\n this.textureSetIndex = cfg.textureSetIndex;\n\n /**\n * Identifies the material type.\n *\n * @type {Number}\n */\n this.materialType = cfg.materialType;\n\n /**\n * Index of this XKTTextureSet in {@link XKTModel#meshesList};\n *\n * @type {Number}\n */\n this.materialIndex = cfg.materialIndex;\n\n /**\n * The number of {@link XKTMesh}s that reference this XKTTextureSet.\n *\n * @type {Number}\n */\n this.numInstances = 0;\n\n /**\n * RGBA {@link XKTTexture} containing base color in RGB and opacity in A.\n *\n * @type {XKTTexture}\n */\n this.colorTexture = cfg.colorTexture;\n\n /**\n * RGBA {@link XKTTexture} containing metallic and roughness factors in R and G.\n *\n * @type {XKTTexture}\n */\n this.metallicRoughnessTexture = cfg.metallicRoughnessTexture;\n\n /**\n * RGBA {@link XKTTexture} with surface normals in RGB.\n *\n * @type {XKTTexture}\n */\n this.normalsTexture = cfg.normalsTexture;\n\n /**\n * RGBA {@link XKTTexture} with emissive color in RGB.\n *\n * @type {XKTTexture}\n */\n this.emissiveTexture = cfg.emissiveTexture;\n\n /**\n * RGBA {@link XKTTexture} with ambient occlusion factors in RGB.\n *\n * @type {XKTTexture}\n */\n this.occlusionTexture = cfg.occlusionTexture;\n }\n}\n\nexport {XKTTextureSet};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/core\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/textures\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/images\");","import {math} from \"../lib/math.js\";\nimport {geometryCompression} from \"./lib/geometryCompression.js\";\nimport {buildEdgeIndices} from \"./lib/buildEdgeIndices.js\";\nimport {isTriangleMeshSolid} from \"./lib/isTriangleMeshSolid.js\";\n\nimport {XKTMesh} from './XKTMesh.js';\nimport {XKTGeometry} from './XKTGeometry.js';\nimport {XKTEntity} from './XKTEntity.js';\nimport {XKTTile} from './XKTTile.js';\nimport {KDNode} from \"./KDNode.js\";\nimport {XKTMetaObject} from \"./XKTMetaObject.js\";\nimport {XKTPropertySet} from \"./XKTPropertySet.js\";\nimport {mergeVertices} from \"../lib/mergeVertices.js\";\nimport {XKT_INFO} from \"../XKT_INFO.js\";\nimport {XKTTexture} from \"./XKTTexture\";\nimport {XKTTextureSet} from \"./XKTTextureSet\";\nimport {encode, load} from \"@loaders.gl/core\";\nimport {KTX2BasisWriter} from \"@loaders.gl/textures\";\nimport {ImageLoader} from '@loaders.gl/images';\n\nconst tempVec4a = math.vec4([0, 0, 0, 1]);\nconst tempVec4b = math.vec4([0, 0, 0, 1]);\n\nconst tempMat4 = math.mat4();\nconst tempMat4b = math.mat4();\n\nconst kdTreeDimLength = new Float64Array(3);\n\n// XKT texture types\n\nconst COLOR_TEXTURE = 0;\nconst METALLIC_ROUGHNESS_TEXTURE = 1;\nconst NORMALS_TEXTURE = 2;\nconst EMISSIVE_TEXTURE = 3;\nconst OCCLUSION_TEXTURE = 4;\n\n// KTX2 encoding options for each texture type\n\nconst TEXTURE_ENCODING_OPTIONS = {}\nTEXTURE_ENCODING_OPTIONS[COLOR_TEXTURE] = {\n useSRGB: true,\n qualityLevel: 50,\n encodeUASTC: true,\n mipmaps: true\n};\nTEXTURE_ENCODING_OPTIONS[EMISSIVE_TEXTURE] = {\n useSRGB: true,\n encodeUASTC: true,\n qualityLevel: 10,\n mipmaps: false\n};\nTEXTURE_ENCODING_OPTIONS[METALLIC_ROUGHNESS_TEXTURE] = {\n useSRGB: false,\n encodeUASTC: true,\n qualityLevel: 50,\n mipmaps: true // Needed for GGX roughness shading\n};\nTEXTURE_ENCODING_OPTIONS[NORMALS_TEXTURE] = {\n useSRGB: false,\n encodeUASTC: true,\n qualityLevel: 10,\n mipmaps: false\n};\nTEXTURE_ENCODING_OPTIONS[OCCLUSION_TEXTURE] = {\n useSRGB: false,\n encodeUASTC: true,\n qualityLevel: 10,\n mipmaps: false\n};\n\n/**\n * A document model that represents the contents of an .XKT file.\n *\n * * An XKTModel contains {@link XKTTile}s, which spatially subdivide the model into axis-aligned, box-shaped regions.\n * * Each {@link XKTTile} contains {@link XKTEntity}s, which represent the objects within its region.\n * * Each {@link XKTEntity} has {@link XKTMesh}s, which each have a {@link XKTGeometry}. Each {@link XKTGeometry} can be shared by multiple {@link XKTMesh}s.\n * * Import models into an XKTModel using {@link parseGLTFJSONIntoXKTModel}, {@link parseIFCIntoXKTModel}, {@link parseCityJSONIntoXKTModel} etc.\n * * Build an XKTModel programmatically using {@link XKTModel#createGeometry}, {@link XKTModel#createMesh} and {@link XKTModel#createEntity}.\n * * Serialize an XKTModel to an ArrayBuffer using {@link writeXKTModelToArrayBuffer}.\n *\n * ## Usage\n *\n * See [main docs page](/docs/#javascript-api) for usage examples.\n *\n * @class XKTModel\n */\nclass XKTModel {\n\n /**\n * Constructs a new XKTModel.\n *\n * @param {*} [cfg] Configuration\n * @param {Number} [cfg.edgeThreshold=10]\n * @param {Number} [cfg.minTileSize=500]\n */\n constructor(cfg = {}) {\n\n /**\n * The model's ID, if available.\n *\n * Will be \"default\" by default.\n *\n * @type {String}\n */\n this.modelId = cfg.modelId || \"default\";\n\n /**\n * The project ID, if available.\n *\n * Will be an empty string by default.\n *\n * @type {String}\n */\n this.projectId = cfg.projectId || \"\";\n\n /**\n * The revision ID, if available.\n *\n * Will be an empty string by default.\n *\n * @type {String}\n */\n this.revisionId = cfg.revisionId || \"\";\n\n /**\n * The model author, if available.\n *\n * Will be an empty string by default.\n *\n * @property author\n * @type {String}\n */\n this.author = cfg.author || \"\";\n\n /**\n * The date the model was created, if available.\n *\n * Will be an empty string by default.\n *\n * @property createdAt\n * @type {String}\n */\n this.createdAt = cfg.createdAt || \"\";\n\n /**\n * The application that created the model, if available.\n *\n * Will be an empty string by default.\n *\n * @property creatingApplication\n * @type {String}\n */\n this.creatingApplication = cfg.creatingApplication || \"\";\n\n /**\n * The model schema version, if available.\n *\n * In the case of IFC, this could be \"IFC2x3\" or \"IFC4\", for example.\n *\n * Will be an empty string by default.\n *\n * @property schema\n * @type {String}\n */\n this.schema = cfg.schema || \"\";\n\n /**\n * The XKT format version.\n *\n * @property xktVersion;\n * @type {number}\n */\n this.xktVersion = XKT_INFO.xktVersion;\n\n /**\n *\n * @type {Number|number}\n */\n this.edgeThreshold = cfg.edgeThreshold || 10;\n\n /**\n * Minimum diagonal size of the boundary of an {@link XKTTile}.\n *\n * @type {Number|number}\n */\n this.minTileSize = cfg.minTileSize || 500;\n\n /**\n * Optional overall AABB that contains all the {@link XKTEntity}s we'll create in this model, if previously known.\n *\n * This is the AABB of a complete set of input files that are provided as a split-model set for conversion.\n *\n * This is used to help the {@link XKTTile.aabb}s within split models align neatly with each other, as we\n * build them with a k-d tree in {@link XKTModel#finalize}. Without this, the AABBs of the different parts\n * tend to misalign slightly, resulting in excess number of {@link XKTTile}s, which degrades memory and rendering\n * performance when the XKT is viewer in the xeokit Viewer.\n */\n this.modelAABB = cfg.modelAABB;\n\n /**\n * Map of {@link XKTPropertySet}s within this XKTModel, each mapped to {@link XKTPropertySet#propertySetId}.\n *\n * Created by {@link XKTModel#createPropertySet}.\n *\n * @type {{String:XKTPropertySet}}\n */\n this.propertySets = {};\n\n /**\n * {@link XKTPropertySet}s within this XKTModel.\n *\n * Each XKTPropertySet holds its position in this list in {@link XKTPropertySet#propertySetIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTPropertySet[]}\n */\n this.propertySetsList = [];\n\n /**\n * Map of {@link XKTMetaObject}s within this XKTModel, each mapped to {@link XKTMetaObject#metaObjectId}.\n *\n * Created by {@link XKTModel#createMetaObject}.\n *\n * @type {{String:XKTMetaObject}}\n */\n this.metaObjects = {};\n\n /**\n * {@link XKTMetaObject}s within this XKTModel.\n *\n * Each XKTMetaObject holds its position in this list in {@link XKTMetaObject#metaObjectIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTMetaObject[]}\n */\n this.metaObjectsList = [];\n\n /**\n * The positions of all shared {@link XKTGeometry}s are de-quantized using this singular\n * de-quantization matrix.\n *\n * This de-quantization matrix is generated from the collective Local-space boundary of the\n * positions of all shared {@link XKTGeometry}s.\n *\n * @type {Float32Array}\n */\n this.reusedGeometriesDecodeMatrix = new Float32Array(16);\n\n /**\n * Map of {@link XKTGeometry}s within this XKTModel, each mapped to {@link XKTGeometry#geometryId}.\n *\n * Created by {@link XKTModel#createGeometry}.\n *\n * @type {{Number:XKTGeometry}}\n */\n this.geometries = {};\n\n /**\n * List of {@link XKTGeometry}s within this XKTModel, in the order they were created.\n *\n * Each XKTGeometry holds its position in this list in {@link XKTGeometry#geometryIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTGeometry[]}\n */\n this.geometriesList = [];\n\n /**\n * Map of {@link XKTTexture}s within this XKTModel, each mapped to {@link XKTTexture#textureId}.\n *\n * Created by {@link XKTModel#createTexture}.\n *\n * @type {{Number:XKTTexture}}\n */\n this.textures = {};\n\n /**\n * List of {@link XKTTexture}s within this XKTModel, in the order they were created.\n *\n * Each XKTTexture holds its position in this list in {@link XKTTexture#textureIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTTexture[]}\n */\n this.texturesList = [];\n\n /**\n * Map of {@link XKTTextureSet}s within this XKTModel, each mapped to {@link XKTTextureSet#textureSetId}.\n *\n * Created by {@link XKTModel#createTextureSet}.\n *\n * @type {{Number:XKTTextureSet}}\n */\n this.textureSets = {};\n\n /**\n * List of {@link XKTTextureSet}s within this XKTModel, in the order they were created.\n *\n * Each XKTTextureSet holds its position in this list in {@link XKTTextureSet#textureSetIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTTextureSet[]}\n */\n this.textureSetsList = [];\n\n /**\n * Map of {@link XKTMesh}s within this XKTModel, each mapped to {@link XKTMesh#meshId}.\n *\n * Created by {@link XKTModel#createMesh}.\n *\n * @type {{Number:XKTMesh}}\n */\n this.meshes = {};\n\n /**\n * List of {@link XKTMesh}s within this XKTModel, in the order they were created.\n *\n * Each XKTMesh holds its position in this list in {@link XKTMesh#meshIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTMesh[]}\n */\n this.meshesList = [];\n\n /**\n * Map of {@link XKTEntity}s within this XKTModel, each mapped to {@link XKTEntity#entityId}.\n *\n * Created by {@link XKTModel#createEntity}.\n *\n * @type {{String:XKTEntity}}\n */\n this.entities = {};\n\n /**\n * {@link XKTEntity}s within this XKTModel.\n *\n * Each XKTEntity holds its position in this list in {@link XKTEntity#entityIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTEntity[]}\n */\n this.entitiesList = [];\n\n /**\n * {@link XKTTile}s within this XKTModel.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTTile[]}\n */\n this.tilesList = [];\n\n /**\n * The axis-aligned 3D World-space boundary of this XKTModel.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {Float64Array}\n */\n this.aabb = math.AABB3();\n\n /**\n * Indicates if this XKTModel has been finalized.\n *\n * Set ````true```` by {@link XKTModel#finalize}.\n *\n * @type {boolean}\n */\n this.finalized = false;\n }\n\n /**\n * Creates an {@link XKTPropertySet} within this XKTModel.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {String} params.propertySetId Unique ID for the {@link XKTPropertySet}.\n * @param {String} [params.propertySetType=\"default\"] A meta type for the {@link XKTPropertySet}.\n * @param {String} [params.propertySetName] Human-readable name for the {@link XKTPropertySet}. Defaults to the ````propertySetId```` parameter.\n * @param {String[]} params.properties Properties for the {@link XKTPropertySet}.\n * @returns {XKTPropertySet} The new {@link XKTPropertySet}.\n */\n createPropertySet(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.propertySetId === null || params.propertySetId === undefined) {\n throw \"Parameter expected: params.propertySetId\";\n }\n\n if (params.properties === null || params.properties === undefined) {\n throw \"Parameter expected: params.properties\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more property sets\");\n return;\n }\n\n if (this.propertySets[params.propertySetId]) {\n // console.error(\"XKTPropertySet already exists with this ID: \" + params.propertySetId);\n return;\n }\n\n const propertySetId = params.propertySetId;\n const propertySetType = params.propertySetType || \"Default\";\n const propertySetName = params.propertySetName || params.propertySetId;\n const properties = params.properties || [];\n\n const propertySet = new XKTPropertySet(propertySetId, propertySetType, propertySetName, properties);\n\n this.propertySets[propertySetId] = propertySet;\n this.propertySetsList.push(propertySet);\n\n return propertySet;\n }\n\n /**\n * Creates an {@link XKTMetaObject} within this XKTModel.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {String} params.metaObjectId Unique ID for the {@link XKTMetaObject}.\n * @param {String} params.propertySetIds ID of one or more property sets that contains additional metadata about\n * this {@link XKTMetaObject}. The property sets could be stored externally (ie not managed at all by the XKT file),\n * or could be {@link XKTPropertySet}s within {@link XKTModel#propertySets}.\n * @param {String} [params.metaObjectType=\"default\"] A meta type for the {@link XKTMetaObject}. Can be anything,\n * but is usually an IFC type, such as \"IfcSite\" or \"IfcWall\".\n * @param {String} [params.metaObjectName] Human-readable name for the {@link XKTMetaObject}. Defaults to the ````metaObjectId```` parameter.\n * @param {String} [params.parentMetaObjectId] ID of the parent {@link XKTMetaObject}, if any. Defaults to the ````metaObjectId```` parameter.\n * @returns {XKTMetaObject} The new {@link XKTMetaObject}.\n */\n createMetaObject(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.metaObjectId === null || params.metaObjectId === undefined) {\n throw \"Parameter expected: params.metaObjectId\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more meta objects\");\n return;\n }\n\n if (this.metaObjects[params.metaObjectId]) {\n // console.error(\"XKTMetaObject already exists with this ID: \" + params.metaObjectId);\n return;\n }\n\n const metaObjectId = params.metaObjectId;\n const propertySetIds = params.propertySetIds;\n const metaObjectType = params.metaObjectType || \"Default\";\n const metaObjectName = params.metaObjectName || params.metaObjectId;\n const parentMetaObjectId = params.parentMetaObjectId;\n\n const metaObject = new XKTMetaObject(metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId);\n\n this.metaObjects[metaObjectId] = metaObject;\n this.metaObjectsList.push(metaObject);\n\n if (!parentMetaObjectId) {\n if (!this._rootMetaObject) {\n this._rootMetaObject = metaObject;\n }\n }\n\n return metaObject;\n }\n\n /**\n * Creates an {@link XKTTexture} within this XKTModel.\n *\n * Registers the new {@link XKTTexture} in {@link XKTModel#textures} and {@link XKTModel#texturesList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {Number} params.textureId Unique ID for the {@link XKTTexture}.\n * @param {String} [params.src] Source of an image file for the texture.\n * @param {Buffer} [params.imageData] Image data for the texture.\n * @param {Number} [params.mediaType] Media type (ie. MIME type) of ````imageData````. Supported values are {@link GIFMediaType}, {@link PNGMediaType} and {@link JPEGMediaType}.\n * @param {Number} [params.width] Texture width, used with ````imageData````. Ignored for compressed textures.\n * @param {Number} [params.height] Texture height, used with ````imageData````. Ignored for compressed textures.\n * @param {Boolean} [params.compressed=true] Whether to compress the texture.\n * @param {Number} [params.minFilter=LinearMipMapNearestFilter] How the texture is sampled when a texel covers less than one pixel. Supported\n * values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter},\n * {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}. Ignored for compressed textures.\n * @param {Number} [params.magFilter=LinearMipMapNearestFilter] How the texture is sampled when a texel covers more than one pixel. Supported values\n * are {@link LinearFilter} and {@link NearestFilter}. Ignored for compressed textures.\n * @param {Number} [params.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures.\n * @param {Number} [params.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures.\n * {@param {Number} [params.wrapR=RepeatWrapping] Wrap parameter for texture coordinate *R*. Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures.\n * @returns {XKTTexture} The new {@link XKTTexture}.\n */\n createTexture(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.textureId === null || params.textureId === undefined) {\n throw \"Parameter expected: params.textureId\";\n }\n\n if (!params.imageData && !params.src) {\n throw \"Parameter expected: params.imageData or params.src\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more textures\");\n return;\n }\n\n if (this.textures[params.textureId]) {\n console.error(\"XKTTexture already exists with this ID: \" + params.textureId);\n return;\n }\n\n if (params.src) {\n const fileExt = params.src.split('.').pop();\n if (fileExt !== \"jpg\" && fileExt !== \"jpeg\" && fileExt !== \"png\") {\n console.error(`XKTModel does not support image files with extension '${fileExt}' - won't create texture '${params.textureId}`);\n return;\n }\n }\n\n const textureId = params.textureId;\n\n const texture = new XKTTexture({\n textureId,\n imageData: params.imageData,\n mediaType: params.mediaType,\n minFilter: params.minFilter,\n magFilter: params.magFilter,\n wrapS: params.wrapS,\n wrapT: params.wrapT,\n wrapR: params.wrapR,\n width: params.width,\n height: params.height,\n compressed: (params.compressed !== false),\n src: params.src\n });\n\n this.textures[textureId] = texture;\n this.texturesList.push(texture);\n\n return texture;\n }\n\n /**\n * Creates an {@link XKTTextureSet} within this XKTModel.\n *\n * Registers the new {@link XKTTextureSet} in {@link XKTModel#textureSets} and {@link XKTModel#.textureSetsList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {Number} params.textureSetId Unique ID for the {@link XKTTextureSet}.\n * @param {*} [params.colorTextureId] ID of *RGBA* base color {@link XKTTexture}, with color in *RGB* and alpha in *A*.\n * @param {*} [params.metallicRoughnessTextureId] ID of *RGBA* metal-roughness {@link XKTTexture}, with the metallic factor in *R*, and roughness factor in *G*.\n * @param {*} [params.normalsTextureId] ID of *RGBA* normal {@link XKTTexture}, with normal map vectors in *RGB*.\n * @param {*} [params.emissiveTextureId] ID of *RGBA* emissive {@link XKTTexture}, with emissive color in *RGB*.\n * @param {*} [params.occlusionTextureId] ID of *RGBA* occlusion {@link XKTTexture}, with occlusion factor in *R*.\n * @returns {XKTTextureSet} The new {@link XKTTextureSet}.\n */\n createTextureSet(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.textureSetId === null || params.textureSetId === undefined) {\n throw \"Parameter expected: params.textureSetId\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more textureSets\");\n return;\n }\n\n if (this.textureSets[params.textureSetId]) {\n console.error(\"XKTTextureSet already exists with this ID: \" + params.textureSetId);\n return;\n }\n\n let colorTexture;\n if (params.colorTextureId !== undefined && params.colorTextureId !== null) {\n colorTexture = this.textures[params.colorTextureId];\n if (!colorTexture) {\n console.error(`Texture not found: ${params.colorTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n colorTexture.channel = COLOR_TEXTURE;\n }\n\n let metallicRoughnessTexture;\n if (params.metallicRoughnessTextureId !== undefined && params.metallicRoughnessTextureId !== null) {\n metallicRoughnessTexture = this.textures[params.metallicRoughnessTextureId];\n if (!metallicRoughnessTexture) {\n console.error(`Texture not found: ${params.metallicRoughnessTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n metallicRoughnessTexture.channel = METALLIC_ROUGHNESS_TEXTURE;\n }\n\n let normalsTexture;\n if (params.normalsTextureId !== undefined && params.normalsTextureId !== null) {\n normalsTexture = this.textures[params.normalsTextureId];\n if (!normalsTexture) {\n console.error(`Texture not found: ${params.normalsTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n normalsTexture.channel = NORMALS_TEXTURE;\n }\n\n let emissiveTexture;\n if (params.emissiveTextureId !== undefined && params.emissiveTextureId !== null) {\n emissiveTexture = this.textures[params.emissiveTextureId];\n if (!emissiveTexture) {\n console.error(`Texture not found: ${params.emissiveTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n emissiveTexture.channel = EMISSIVE_TEXTURE;\n }\n\n let occlusionTexture;\n if (params.occlusionTextureId !== undefined && params.occlusionTextureId !== null) {\n occlusionTexture = this.textures[params.occlusionTextureId];\n if (!occlusionTexture) {\n console.error(`Texture not found: ${params.occlusionTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n occlusionTexture.channel = OCCLUSION_TEXTURE;\n }\n\n const textureSet = new XKTTextureSet({\n textureSetId: params.textureSetId,\n textureSetIndex: this.textureSetsList.length,\n colorTexture,\n metallicRoughnessTexture,\n normalsTexture,\n emissiveTexture,\n occlusionTexture\n });\n\n this.textureSets[params.textureSetId] = textureSet;\n this.textureSetsList.push(textureSet);\n\n return textureSet;\n }\n\n /**\n * Creates an {@link XKTGeometry} within this XKTModel.\n *\n * Registers the new {@link XKTGeometry} in {@link XKTModel#geometries} and {@link XKTModel#geometriesList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {Number} params.geometryId Unique ID for the {@link XKTGeometry}.\n * @param {String} params.primitiveType The type of {@link XKTGeometry}: \"triangles\", \"lines\" or \"points\".\n * @param {Float64Array} params.positions Floating-point Local-space vertex positions for the {@link XKTGeometry}. Required for all primitive types.\n * @param {Number[]} [params.normals] Floating-point vertex normals for the {@link XKTGeometry}. Only used with triangles primitives. Ignored for points and lines.\n * @param {Number[]} [params.colors] Floating-point RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.\n * @param {Number[]} [params.colorsCompressed] Integer RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.\n * @param {Number[]} [params.uvs] Floating-point vertex UV coordinates for the {@link XKTGeometry}. Alias for ````uv````.\n * @param {Number[]} [params.uv] Floating-point vertex UV coordinates for the {@link XKTGeometry}. Alias for ````uvs````.\n * @param {Number[]} [params.colorsCompressed] Integer RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.\n * @param {Uint32Array} [params.indices] Indices for the {@link XKTGeometry}. Required for triangles and lines primitives. Ignored for points.\n * @param {Number} [params.edgeThreshold=10]\n * @returns {XKTGeometry} The new {@link XKTGeometry}.\n */\n createGeometry(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.geometryId === null || params.geometryId === undefined) {\n throw \"Parameter expected: params.geometryId\";\n }\n\n if (!params.primitiveType) {\n throw \"Parameter expected: params.primitiveType\";\n }\n\n if (!params.positions) {\n throw \"Parameter expected: params.positions\";\n }\n\n const triangles = params.primitiveType === \"triangles\";\n const points = params.primitiveType === \"points\";\n const lines = params.primitiveType === \"lines\";\n const line_strip = params.primitiveType === \"line-strip\";\n const line_loop = params.primitiveType === \"line-loop\";\n const triangle_strip = params.primitiveType === \"triangle-strip\";\n const triangle_fan = params.primitiveType === \"triangle-fan\";\n\n if (!triangles && !points && !lines && !line_strip && !line_loop) {\n throw \"Unsupported value for params.primitiveType: \"\n + params.primitiveType\n + \"' - supported values are 'triangles', 'points', 'lines', 'line-strip', 'triangle-strip' and 'triangle-fan\";\n }\n\n if (triangles) {\n if (!params.indices) {\n params.indices = this._createDefaultIndices()\n throw \"Parameter expected for 'triangles' primitive: params.indices\";\n }\n }\n\n if (points) {\n if (!params.colors && !params.colorsCompressed) {\n throw \"Parameter expected for 'points' primitive: params.colors or params.colorsCompressed\";\n }\n }\n\n if (lines) {\n if (!params.indices) {\n throw \"Parameter expected for 'lines' primitive: params.indices\";\n }\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more geometries\");\n return;\n }\n\n if (this.geometries[params.geometryId]) {\n console.error(\"XKTGeometry already exists with this ID: \" + params.geometryId);\n return;\n }\n\n const geometryId = params.geometryId;\n const primitiveType = params.primitiveType;\n const positions = new Float64Array(params.positions); // May modify in #finalize\n\n const xktGeometryCfg = {\n geometryId: geometryId,\n geometryIndex: this.geometriesList.length,\n primitiveType: primitiveType,\n positions: positions,\n uvs: params.uvs || params.uv\n }\n\n if (triangles) {\n if (params.normals) {\n xktGeometryCfg.normals = new Float32Array(params.normals);\n }\n if (params.indices) {\n xktGeometryCfg.indices = params.indices;\n } else {\n xktGeometryCfg.indices = this._createDefaultIndices(positions.length / 3);\n }\n }\n\n if (points) {\n if (params.colorsCompressed) {\n xktGeometryCfg.colorsCompressed = new Uint8Array(params.colorsCompressed);\n\n } else {\n const colors = params.colors;\n const colorsCompressed = new Uint8Array(colors.length);\n for (let i = 0, len = colors.length; i < len; i++) {\n colorsCompressed[i] = Math.floor(colors[i] * 255);\n }\n xktGeometryCfg.colorsCompressed = colorsCompressed;\n }\n }\n\n if (lines) {\n xktGeometryCfg.indices = params.indices;\n }\n\n if (triangles) {\n\n if (!params.normals && !params.uv && !params.uvs) {\n\n // Building models often duplicate positions to allow face-aligned vertex normals; when we're not\n // providing normals for a geometry, it becomes possible to merge duplicate vertex positions within it.\n\n // TODO: Make vertex merging also merge normals?\n\n const mergedPositions = [];\n const mergedIndices = [];\n mergeVertices(xktGeometryCfg.positions, xktGeometryCfg.indices, mergedPositions, mergedIndices);\n xktGeometryCfg.positions = new Float64Array(mergedPositions);\n xktGeometryCfg.indices = mergedIndices;\n }\n\n xktGeometryCfg.edgeIndices = buildEdgeIndices(xktGeometryCfg.positions, xktGeometryCfg.indices, null, params.edgeThreshold || this.edgeThreshold || 10);\n }\n\n const geometry = new XKTGeometry(xktGeometryCfg);\n\n this.geometries[geometryId] = geometry;\n this.geometriesList.push(geometry);\n\n return geometry;\n }\n\n _createDefaultIndices(numIndices) {\n const indices = [];\n for (let i = 0; i < numIndices; i++) {\n indices.push(i);\n }\n return indices;\n }\n\n /**\n * Creates an {@link XKTMesh} within this XKTModel.\n *\n * An {@link XKTMesh} can be owned by one {@link XKTEntity}, which can own multiple {@link XKTMesh}es.\n *\n * Registers the new {@link XKTMesh} in {@link XKTModel#meshes} and {@link XKTModel#meshesList}.\n *\n * @param {*} params Method parameters.\n * @param {Number} params.meshId Unique ID for the {@link XKTMesh}.\n * @param {Number} params.geometryId ID of an existing {@link XKTGeometry} in {@link XKTModel#geometries}.\n * @param {Number} [params.textureSetId] Unique ID of an {@link XKTTextureSet} in {@link XKTModel#textureSets}.\n * @param {Float32Array} params.color RGB color for the {@link XKTMesh}, with each color component in range [0..1].\n * @param {Number} [params.metallic=0] How metallic the {@link XKTMesh} is, in range [0..1]. A value of ````0```` indicates fully dielectric material, while ````1```` indicates fully metallic.\n * @param {Number} [params.roughness=1] How rough the {@link XKTMesh} is, in range [0..1]. A value of ````0```` indicates fully smooth, while ````1```` indicates fully rough.\n * @param {Number} params.opacity Opacity factor for the {@link XKTMesh}, in range [0..1].\n * @param {Float64Array} [params.matrix] Modeling matrix for the {@link XKTMesh}. Overrides ````position````, ````scale```` and ````rotation```` parameters.\n * @param {Number[]} [params.position=[0,0,0]] Position of the {@link XKTMesh}. Overridden by the ````matrix```` parameter.\n * @param {Number[]} [params.scale=[1,1,1]] Scale of the {@link XKTMesh}. Overridden by the ````matrix```` parameter.\n * @param {Number[]} [params.rotation=[0,0,0]] Rotation of the {@link XKTMesh} as Euler angles given in degrees, for each of the X, Y and Z axis. Overridden by the ````matrix```` parameter.\n * @returns {XKTMesh} The new {@link XKTMesh}.\n */\n createMesh(params) {\n\n if (params.meshId === null || params.meshId === undefined) {\n throw \"Parameter expected: params.meshId\";\n }\n\n if (params.geometryId === null || params.geometryId === undefined) {\n throw \"Parameter expected: params.geometryId\";\n }\n\n if (this.finalized) {\n throw \"XKTModel has been finalized, can't add more meshes\";\n }\n\n if (this.meshes[params.meshId]) {\n console.error(\"XKTMesh already exists with this ID: \" + params.meshId);\n return;\n }\n\n const geometry = this.geometries[params.geometryId];\n\n if (!geometry) {\n console.error(\"XKTGeometry not found: \" + params.geometryId);\n return;\n }\n\n geometry.numInstances++;\n\n let textureSet = null;\n if (params.textureSetId) {\n textureSet = this.textureSets[params.textureSetId];\n if (!textureSet) {\n console.error(\"XKTTextureSet not found: \" + params.textureSetId);\n return;\n }\n textureSet.numInstances++;\n }\n\n let matrix = params.matrix;\n\n if (!matrix) {\n\n const position = params.position;\n const scale = params.scale;\n const rotation = params.rotation;\n\n if (position || scale || rotation) {\n matrix = math.identityMat4();\n const quaternion = math.eulerToQuaternion(rotation || [0, 0, 0], \"XYZ\", math.identityQuaternion());\n math.composeMat4(position || [0, 0, 0], quaternion, scale || [1, 1, 1], matrix)\n\n } else {\n matrix = math.identityMat4();\n }\n }\n\n const meshIndex = this.meshesList.length;\n\n const mesh = new XKTMesh({\n meshId: params.meshId,\n meshIndex,\n matrix,\n geometry,\n color: params.color,\n metallic: params.metallic,\n roughness: params.roughness,\n opacity: params.opacity,\n textureSet\n });\n\n this.meshes[mesh.meshId] = mesh;\n this.meshesList.push(mesh);\n\n return mesh;\n }\n\n /**\n * Creates an {@link XKTEntity} within this XKTModel.\n *\n * Registers the new {@link XKTEntity} in {@link XKTModel#entities} and {@link XKTModel#entitiesList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {String} params.entityId Unique ID for the {@link XKTEntity}.\n * @param {String[]} params.meshIds IDs of {@link XKTMesh}es used by the {@link XKTEntity}. Note that each {@link XKTMesh} can only be used by one {@link XKTEntity}.\n * @returns {XKTEntity} The new {@link XKTEntity}.\n */\n createEntity(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.entityId === null || params.entityId === undefined) {\n throw \"Parameter expected: params.entityId\";\n }\n\n if (!params.meshIds) {\n throw \"Parameter expected: params.meshIds\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more entities\");\n return;\n }\n\n if (params.meshIds.length === 0) {\n console.warn(\"XKTEntity has no meshes - won't create: \" + params.entityId);\n return;\n }\n\n let entityId = params.entityId;\n\n if (this.entities[entityId]) {\n while (this.entities[entityId]) {\n entityId = math.createUUID();\n }\n console.error(\"XKTEntity already exists with this ID: \" + params.entityId + \" - substituting random ID instead: \" + entityId);\n }\n\n const meshIds = params.meshIds;\n const meshes = [];\n\n for (let meshIdIdx = 0, meshIdLen = meshIds.length; meshIdIdx < meshIdLen; meshIdIdx++) {\n\n const meshId = meshIds[meshIdIdx];\n const mesh = this.meshes[meshId];\n\n if (!mesh) {\n console.error(\"XKTMesh found: \" + meshId);\n continue;\n }\n\n if (mesh.entity) {\n console.error(\"XKTMesh \" + meshId + \" already used by XKTEntity \" + mesh.entity.entityId);\n continue;\n }\n\n meshes.push(mesh);\n }\n\n const entity = new XKTEntity(entityId, meshes);\n\n for (let i = 0, len = meshes.length; i < len; i++) {\n const mesh = meshes[i];\n mesh.entity = entity;\n }\n\n this.entities[entityId] = entity;\n this.entitiesList.push(entity);\n\n return entity;\n }\n\n /**\n * Creates a default {@link XKTMetaObject} for each {@link XKTEntity} that does not already have one.\n */\n createDefaultMetaObjects() {\n\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n\n const entity = this.entitiesList[i];\n const metaObjectId = entity.entityId;\n const metaObject = this.metaObjects[metaObjectId];\n\n if (!metaObject) {\n\n if (!this._rootMetaObject) {\n this._rootMetaObject = this.createMetaObject({\n metaObjectId: this.modelId,\n metaObjectType: \"Default\",\n metaObjectName: this.modelId\n });\n }\n\n this.createMetaObject({\n metaObjectId: metaObjectId,\n metaObjectType: \"Default\",\n metaObjectName: \"\" + metaObjectId,\n parentMetaObjectId: this._rootMetaObject.metaObjectId\n });\n }\n }\n }\n\n /**\n * Finalizes this XKTModel.\n *\n * After finalizing, we may then serialize the model to an array buffer using {@link writeXKTModelToArrayBuffer}.\n *\n * Logs error and does nothing if this XKTModel has already been finalized.\n *\n * Internally, this method:\n *\n * * for each {@link XKTEntity} that doesn't already have a {@link XKTMetaObject}, creates one with {@link XKTMetaObject#metaObjectType} set to \"default\"\n * * sets each {@link XKTEntity}'s {@link XKTEntity#hasReusedGeometries} true if it shares its {@link XKTGeometry}s with other {@link XKTEntity}s,\n * * creates each {@link XKTEntity}'s {@link XKTEntity#aabb},\n * * creates {@link XKTTile}s in {@link XKTModel#tilesList}, and\n * * sets {@link XKTModel#finalized} ````true````.\n */\n async finalize() {\n\n if (this.finalized) {\n console.log(\"XKTModel already finalized\");\n return;\n }\n\n this._removeUnusedTextures();\n\n await this._compressTextures();\n\n this._bakeSingleUseGeometryPositions();\n\n this._bakeAndOctEncodeNormals();\n\n this._createEntityAABBs();\n\n const rootKDNode = this._createKDTree();\n\n this.entitiesList = [];\n\n this._createTilesFromKDTree(rootKDNode);\n\n this._createReusedGeometriesDecodeMatrix();\n\n this._flagSolidGeometries();\n\n this.aabb.set(rootKDNode.aabb);\n\n this.finalized = true;\n }\n\n _removeUnusedTextures() {\n let texturesList = [];\n const textures = {};\n for (let i = 0, leni = this.texturesList.length; i < leni; i++) {\n const texture = this.texturesList[i];\n if (texture.channel !== null) {\n texture.textureIndex = texturesList.length;\n texturesList.push(texture);\n textures[texture.textureId] = texture;\n }\n }\n this.texturesList = texturesList;\n this.textures = textures;\n }\n\n _compressTextures() {\n let countTextures = this.texturesList.length;\n return new Promise((resolve) => {\n if (countTextures === 0) {\n resolve();\n return;\n }\n for (let i = 0, leni = this.texturesList.length; i < leni; i++) {\n const texture = this.texturesList[i];\n const encodingOptions = TEXTURE_ENCODING_OPTIONS[texture.channel] || {};\n\n if (texture.src) {\n\n // XKTTexture created with XKTModel#createTexture({ src: ... })\n\n const src = texture.src;\n const fileExt = src.split('.').pop();\n switch (fileExt) {\n case \"jpeg\":\n case \"jpg\":\n case \"png\":\n load(src, ImageLoader, {\n image: {\n type: \"data\"\n }\n }).then((imageData) => {\n if (texture.compressed) {\n encode(imageData, KTX2BasisWriter, encodingOptions).then((encodedData) => {\n const encodedImageData = new Uint8Array(encodedData);\n texture.imageData = encodedImageData;\n if (--countTextures <= 0) {\n resolve();\n }\n }).catch((err) => {\n console.error(\"[XKTModel.finalize] Failed to encode image: \" + err);\n if (--countTextures <= 0) {\n resolve();\n }\n });\n } else {\n texture.imageData = new Uint8Array(1);\n if (--countTextures <= 0) {\n resolve();\n }\n }\n }).catch((err) => {\n console.error(\"[XKTModel.finalize] Failed to load image: \" + err);\n if (--countTextures <= 0) {\n resolve();\n }\n });\n break;\n default:\n if (--countTextures <= 0) {\n resolve();\n }\n break;\n }\n }\n\n if (texture.imageData) {\n\n // XKTTexture created with XKTModel#createTexture({ imageData: ... })\n\n if (texture.compressed) {\n encode(texture.imageData, KTX2BasisWriter, encodingOptions)\n .then((encodedImageData) => {\n texture.imageData = new Uint8Array(encodedImageData);\n if (--countTextures <= 0) {\n resolve();\n }\n }).catch((err) => {\n console.error(\"[XKTModel.finalize] Failed to encode image: \" + err);\n if (--countTextures <= 0) {\n resolve();\n }\n });\n } else {\n texture.imageData = new Uint8Array(1);\n if (--countTextures <= 0) {\n resolve();\n }\n }\n }\n }\n });\n }\n\n _bakeSingleUseGeometryPositions() {\n\n for (let j = 0, lenj = this.meshesList.length; j < lenj; j++) {\n\n const mesh = this.meshesList[j];\n\n const geometry = mesh.geometry;\n\n if (geometry.numInstances === 1) {\n\n const matrix = mesh.matrix;\n\n if (matrix && (!math.isIdentityMat4(matrix))) {\n\n const positions = geometry.positions;\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n tempVec4a[0] = positions[i + 0];\n tempVec4a[1] = positions[i + 1];\n tempVec4a[2] = positions[i + 2];\n tempVec4a[3] = 1;\n\n math.transformPoint4(matrix, tempVec4a, tempVec4b);\n\n positions[i + 0] = tempVec4b[0];\n positions[i + 1] = tempVec4b[1];\n positions[i + 2] = tempVec4b[2];\n }\n }\n }\n }\n }\n\n _bakeAndOctEncodeNormals() {\n\n for (let i = 0, len = this.meshesList.length; i < len; i++) {\n\n const mesh = this.meshesList[i];\n const geometry = mesh.geometry;\n\n if (geometry.normals && !geometry.normalsOctEncoded) {\n\n geometry.normalsOctEncoded = new Int8Array(geometry.normals.length);\n\n if (geometry.numInstances > 1) {\n geometryCompression.octEncodeNormals(geometry.normals, geometry.normals.length, geometry.normalsOctEncoded, 0);\n\n } else {\n const modelNormalMatrix = math.inverseMat4(math.transposeMat4(mesh.matrix, tempMat4), tempMat4b);\n geometryCompression.transformAndOctEncodeNormals(modelNormalMatrix, geometry.normals, geometry.normals.length, geometry.normalsOctEncoded, 0);\n }\n }\n }\n }\n\n _createEntityAABBs() {\n\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n\n const entity = this.entitiesList[i];\n const entityAABB = entity.aabb;\n const meshes = entity.meshes;\n\n math.collapseAABB3(entityAABB);\n\n for (let j = 0, lenj = meshes.length; j < lenj; j++) {\n\n const mesh = meshes[j];\n const geometry = mesh.geometry;\n const matrix = mesh.matrix;\n\n if (geometry.numInstances > 1) {\n\n const positions = geometry.positions;\n for (let i = 0, len = positions.length; i < len; i += 3) {\n tempVec4a[0] = positions[i + 0];\n tempVec4a[1] = positions[i + 1];\n tempVec4a[2] = positions[i + 2];\n tempVec4a[3] = 1;\n math.transformPoint4(matrix, tempVec4a, tempVec4b);\n math.expandAABB3Point3(entityAABB, tempVec4b);\n }\n\n } else {\n\n const positions = geometry.positions;\n for (let i = 0, len = positions.length; i < len; i += 3) {\n tempVec4a[0] = positions[i + 0];\n tempVec4a[1] = positions[i + 1];\n tempVec4a[2] = positions[i + 2];\n math.expandAABB3Point3(entityAABB, tempVec4a);\n }\n }\n }\n }\n }\n\n _createKDTree() {\n\n let aabb;\n if (this.modelAABB) {\n aabb = this.modelAABB; // Pre-known uber AABB\n } else {\n aabb = math.collapseAABB3();\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n const entity = this.entitiesList[i];\n math.expandAABB3(aabb, entity.aabb);\n }\n }\n\n const rootKDNode = new KDNode(aabb);\n\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n const entity = this.entitiesList[i];\n this._insertEntityIntoKDTree(rootKDNode, entity);\n }\n\n return rootKDNode;\n }\n\n _insertEntityIntoKDTree(kdNode, entity) {\n\n const nodeAABB = kdNode.aabb;\n const entityAABB = entity.aabb;\n\n const nodeAABBDiag = math.getAABB3Diag(nodeAABB);\n\n if (nodeAABBDiag < this.minTileSize) {\n kdNode.entities = kdNode.entities || [];\n kdNode.entities.push(entity);\n math.expandAABB3(nodeAABB, entityAABB);\n return;\n }\n\n if (kdNode.left) {\n if (math.containsAABB3(kdNode.left.aabb, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.left, entity);\n return;\n }\n }\n\n if (kdNode.right) {\n if (math.containsAABB3(kdNode.right.aabb, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.right, entity);\n return;\n }\n }\n\n kdTreeDimLength[0] = nodeAABB[3] - nodeAABB[0];\n kdTreeDimLength[1] = nodeAABB[4] - nodeAABB[1];\n kdTreeDimLength[2] = nodeAABB[5] - nodeAABB[2];\n\n let dim = 0;\n\n if (kdTreeDimLength[1] > kdTreeDimLength[dim]) {\n dim = 1;\n }\n\n if (kdTreeDimLength[2] > kdTreeDimLength[dim]) {\n dim = 2;\n }\n\n if (!kdNode.left) {\n const aabbLeft = nodeAABB.slice();\n aabbLeft[dim + 3] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0);\n kdNode.left = new KDNode(aabbLeft);\n if (math.containsAABB3(aabbLeft, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.left, entity);\n return;\n }\n }\n\n if (!kdNode.right) {\n const aabbRight = nodeAABB.slice();\n aabbRight[dim] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0);\n kdNode.right = new KDNode(aabbRight);\n if (math.containsAABB3(aabbRight, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.right, entity);\n return;\n }\n }\n\n kdNode.entities = kdNode.entities || [];\n kdNode.entities.push(entity);\n\n math.expandAABB3(nodeAABB, entityAABB);\n }\n\n _createTilesFromKDTree(rootKDNode) {\n this._createTilesFromKDNode(rootKDNode);\n }\n\n _createTilesFromKDNode(kdNode) {\n if (kdNode.entities && kdNode.entities.length > 0) {\n this._createTileFromEntities(kdNode);\n }\n if (kdNode.left) {\n this._createTilesFromKDNode(kdNode.left);\n }\n if (kdNode.right) {\n this._createTilesFromKDNode(kdNode.right);\n }\n }\n\n /**\n * Creates a tile from the given entities.\n *\n * For each single-use {@link XKTGeometry}, this method centers {@link XKTGeometry#positions} to make them relative to the\n * tile's center, then quantizes the positions to unsigned 16-bit integers, relative to the tile's boundary.\n *\n * @param kdNode\n */\n _createTileFromEntities(kdNode) {\n\n const tileAABB = kdNode.aabb;\n const entities = kdNode.entities;\n\n const tileCenter = math.getAABB3Center(tileAABB);\n const tileCenterNeg = math.mulVec3Scalar(tileCenter, -1, math.vec3());\n\n const rtcAABB = math.AABB3(); // AABB centered at the RTC origin\n\n rtcAABB[0] = tileAABB[0] - tileCenter[0];\n rtcAABB[1] = tileAABB[1] - tileCenter[1];\n rtcAABB[2] = tileAABB[2] - tileCenter[2];\n rtcAABB[3] = tileAABB[3] - tileCenter[0];\n rtcAABB[4] = tileAABB[4] - tileCenter[1];\n rtcAABB[5] = tileAABB[5] - tileCenter[2];\n\n for (let i = 0; i < entities.length; i++) {\n\n const entity = entities [i];\n\n const meshes = entity.meshes;\n\n for (let j = 0, lenj = meshes.length; j < lenj; j++) {\n\n const mesh = meshes[j];\n const geometry = mesh.geometry;\n\n if (!geometry.reused) { // Batched geometry\n\n const positions = geometry.positions;\n\n // Center positions relative to their tile's World-space center\n\n for (let k = 0, lenk = positions.length; k < lenk; k += 3) {\n\n positions[k + 0] -= tileCenter[0];\n positions[k + 1] -= tileCenter[1];\n positions[k + 2] -= tileCenter[2];\n }\n\n // Quantize positions relative to tile's RTC-space boundary\n\n geometryCompression.quantizePositions(positions, positions.length, rtcAABB, geometry.positionsQuantized);\n\n } else { // Instanced geometry\n\n // Post-multiply a translation to the mesh's modeling matrix\n // to center the entity's geometry instances to the tile RTC center\n\n //////////////////////////////\n // Why do we do this?\n // Seems to break various models\n /////////////////////////////////\n\n math.translateMat4v(tileCenterNeg, mesh.matrix);\n }\n }\n\n entity.entityIndex = this.entitiesList.length;\n\n this.entitiesList.push(entity);\n }\n\n const tile = new XKTTile(tileAABB, entities);\n\n this.tilesList.push(tile);\n }\n\n _createReusedGeometriesDecodeMatrix() {\n\n const tempVec3a = math.vec3();\n const reusedGeometriesAABB = math.collapseAABB3(math.AABB3());\n let countReusedGeometries = 0;\n\n for (let geometryIndex = 0, numGeometries = this.geometriesList.length; geometryIndex < numGeometries; geometryIndex++) {\n\n const geometry = this.geometriesList [geometryIndex];\n\n if (geometry.reused) { // Instanced geometry\n\n const positions = geometry.positions;\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n tempVec3a[0] = positions[i];\n tempVec3a[1] = positions[i + 1];\n tempVec3a[2] = positions[i + 2];\n\n math.expandAABB3Point3(reusedGeometriesAABB, tempVec3a);\n }\n\n countReusedGeometries++;\n }\n }\n\n if (countReusedGeometries > 0) {\n\n geometryCompression.createPositionsDecodeMatrix(reusedGeometriesAABB, this.reusedGeometriesDecodeMatrix);\n\n for (let geometryIndex = 0, numGeometries = this.geometriesList.length; geometryIndex < numGeometries; geometryIndex++) {\n\n const geometry = this.geometriesList [geometryIndex];\n\n if (geometry.reused) {\n geometryCompression.quantizePositions(geometry.positions, geometry.positions.length, reusedGeometriesAABB, geometry.positionsQuantized);\n }\n }\n\n } else {\n math.identityMat4(this.reusedGeometriesDecodeMatrix); // No need for this matrix, but we'll be tidy and set it to identity\n }\n }\n\n _flagSolidGeometries() {\n let maxNumPositions = 0;\n let maxNumIndices = 0;\n for (let i = 0, len = this.geometriesList.length; i < len; i++) {\n const geometry = this.geometriesList[i];\n if (geometry.primitiveType === \"triangles\") {\n if (geometry.positionsQuantized.length > maxNumPositions) {\n maxNumPositions = geometry.positionsQuantized.length;\n }\n if (geometry.indices.length > maxNumIndices) {\n maxNumIndices = geometry.indices.length;\n }\n }\n }\n let vertexIndexMapping = new Array(maxNumPositions / 3);\n let edges = new Array(maxNumIndices);\n for (let i = 0, len = this.geometriesList.length; i < len; i++) {\n const geometry = this.geometriesList[i];\n if (geometry.primitiveType === \"triangles\") {\n geometry.solid = isTriangleMeshSolid(geometry.indices, geometry.positionsQuantized, vertexIndexMapping, edges);\n }\n }\n }\n}\n\nexport {\n XKTModel\n}","/**\n * Given geometry defined as an array of positions, optional normals, option uv and an array of indices, returns\n * modified arrays that have duplicate vertices removed.\n *\n * @private\n */\nfunction mergeVertices(positions, indices, mergedPositions, mergedIndices) {\n const positionsMap = {};\n const indicesLookup = [];\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = 10 ** precisionPoints;\n let uvi = 0;\n for (let i = 0, len = positions.length; i < len; i += 3) {\n const vx = positions[i];\n const vy = positions[i + 1];\n const vz = positions[i + 2];\n const key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`;\n if (positionsMap[key] === undefined) {\n positionsMap[key] = mergedPositions.length / 3;\n mergedPositions.push(vx);\n mergedPositions.push(vy);\n mergedPositions.push(vz);\n }\n indicesLookup[i / 3] = positionsMap[key];\n uvi += 2;\n }\n for (let i = 0, len = indices.length; i < len; i++) {\n mergedIndices[i] = indicesLookup[indices[i]];\n }\n}\n\nexport {mergeVertices};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"pako\");","import {XKT_INFO} from \"../XKT_INFO.js\";\nimport * as pako from 'pako';\n\nconst XKT_VERSION = XKT_INFO.xktVersion;\nconst NUM_TEXTURE_ATTRIBUTES = 9;\nconst NUM_MATERIAL_ATTRIBUTES = 6;\n\n/**\n * Writes an {@link XKTModel} to an {@link ArrayBuffer}.\n *\n * @param {XKTModel} xktModel The {@link XKTModel}.\n * @param {String} metaModelJSON The metamodel JSON in a string.\n * @param {Object} [stats] Collects statistics.\n * @param {Object} options Options for how the XKT is written.\n * @param {Boolean} [options.zip=true] ZIP the contents?\n * @returns {ArrayBuffer} The {@link ArrayBuffer}.\n */\nfunction writeXKTModelToArrayBuffer(xktModel, metaModelJSON, stats, options) {\n const data = getModelData(xktModel, metaModelJSON, stats);\n const deflatedData = deflateData(data, metaModelJSON, options);\n stats.texturesSize += deflatedData.textureData.byteLength;\n const arrayBuffer = createArrayBuffer(deflatedData);\n return arrayBuffer;\n}\n\nfunction getModelData(xktModel, metaModelDataStr, stats) {\n\n //------------------------------------------------------------------------------------------------------------------\n // Allocate data\n //------------------------------------------------------------------------------------------------------------------\n\n const propertySetsList = xktModel.propertySetsList;\n const metaObjectsList = xktModel.metaObjectsList;\n const geometriesList = xktModel.geometriesList;\n const texturesList = xktModel.texturesList;\n const textureSetsList = xktModel.textureSetsList;\n const meshesList = xktModel.meshesList;\n const entitiesList = xktModel.entitiesList;\n const tilesList = xktModel.tilesList;\n\n const numPropertySets = propertySetsList.length;\n const numMetaObjects = metaObjectsList.length;\n const numGeometries = geometriesList.length;\n const numTextures = texturesList.length;\n const numTextureSets = textureSetsList.length;\n const numMeshes = meshesList.length;\n const numEntities = entitiesList.length;\n const numTiles = tilesList.length;\n\n let lenPositions = 0;\n let lenNormals = 0;\n let lenColors = 0;\n let lenUVs = 0;\n let lenIndices = 0;\n let lenEdgeIndices = 0;\n let lenMatrices = 0;\n let lenTextures = 0;\n\n for (let geometryIndex = 0; geometryIndex < numGeometries; geometryIndex++) {\n const geometry = geometriesList [geometryIndex];\n if (geometry.positionsQuantized) {\n lenPositions += geometry.positionsQuantized.length;\n }\n if (geometry.normalsOctEncoded) {\n lenNormals += geometry.normalsOctEncoded.length;\n }\n if (geometry.colorsCompressed) {\n lenColors += geometry.colorsCompressed.length;\n }\n if (geometry.uvs) {\n lenUVs += geometry.uvs.length;\n }\n if (geometry.indices) {\n lenIndices += geometry.indices.length;\n }\n if (geometry.edgeIndices) {\n lenEdgeIndices += geometry.edgeIndices.length;\n }\n }\n\n for (let textureIndex = 0; textureIndex < numTextures; textureIndex++) {\n const xktTexture = texturesList[textureIndex];\n const imageData = xktTexture.imageData;\n lenTextures += imageData.byteLength;\n\n if (xktTexture.compressed) {\n stats.numCompressedTextures++;\n }\n }\n\n for (let meshIndex = 0; meshIndex < numMeshes; meshIndex++) {\n const mesh = meshesList[meshIndex];\n if (mesh.geometry.numInstances > 1) {\n lenMatrices += 16;\n }\n }\n\n const data = {\n metadata: {},\n textureData: new Uint8Array(lenTextures), // All textures\n eachTextureDataPortion: new Uint32Array(numTextures), // For each texture, an index to its first element in textureData\n eachTextureAttributes: new Uint16Array(numTextures * NUM_TEXTURE_ATTRIBUTES),\n positions: new Uint16Array(lenPositions), // All geometry arrays\n normals: new Int8Array(lenNormals),\n colors: new Uint8Array(lenColors),\n uvs: new Float32Array(lenUVs),\n indices: new Uint32Array(lenIndices),\n edgeIndices: new Uint32Array(lenEdgeIndices),\n eachTextureSetTextures: new Int32Array(numTextureSets * 5), // For each texture set, a set of five Texture indices [color, metal/roughness,normals,emissive,occlusion]; each index has value -1 if no texture\n matrices: new Float32Array(lenMatrices), // Modeling matrices for entities that share geometries. Each entity either shares all it's geometries, or owns all its geometries exclusively. Exclusively-owned geometries are pre-transformed into World-space, and so their entities don't have modeling matrices in this array.\n reusedGeometriesDecodeMatrix: new Float32Array(xktModel.reusedGeometriesDecodeMatrix), // A single, global vertex position de-quantization matrix for all reused geometries. Reused geometries are quantized to their collective Local-space AABB, and this matrix is derived from that AABB.\n eachGeometryPrimitiveType: new Uint8Array(numGeometries), // Primitive type for each geometry (0=solid triangles, 1=surface triangles, 2=lines, 3=points, 4=line-strip)\n eachGeometryPositionsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.positions. Every primitive type has positions.\n eachGeometryNormalsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.normals. If the next geometry has the same index, then this geometry has no normals.\n eachGeometryColorsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.colors. If the next geometry has the same index, then this geometry has no colors.\n eachGeometryUVsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.uvs. If the next geometry has the same index, then this geometry has no UVs.\n eachGeometryIndicesPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.indices. If the next geometry has the same index, then this geometry has no indices.\n eachGeometryEdgeIndicesPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.edgeIndices. If the next geometry has the same index, then this geometry has no edge indices.\n eachMeshGeometriesPortion: new Uint32Array(numMeshes), // For each mesh, an index into the eachGeometry* arrays\n eachMeshMatricesPortion: new Uint32Array(numMeshes), // For each mesh that shares its geometry, an index to its first element in data.matrices, to indicate the modeling matrix that transforms the shared geometry Local-space vertex positions. This is ignored for meshes that don't share geometries, because the vertex positions of non-shared geometries are pre-transformed into World-space.\n eachMeshTextureSet: new Int32Array(numMeshes), // For each mesh, the index of its texture set in data.eachTextureSetTextures; this array contains signed integers so that we can use -1 to indicate when a mesh has no texture set\n eachMeshMaterialAttributes: new Uint8Array(numMeshes * NUM_MATERIAL_ATTRIBUTES), // For each mesh, an RGBA integer color of format [0..255, 0..255, 0..255, 0..255], and PBR metallic and roughness factors, of format [0..255, 0..255]\n eachEntityId: [], // For each entity, an ID string\n eachEntityMeshesPortion: new Uint32Array(numEntities), // For each entity, the index of the first element of meshes used by the entity\n eachTileAABB: new Float64Array(numTiles * 6), // For each tile, an axis-aligned bounding box\n eachTileEntitiesPortion: new Uint32Array(numTiles) // For each tile, the index of the first element of eachEntityId, eachEntityMeshesPortion and eachEntityMatricesPortion used by the tile\n };\n\n let countPositions = 0;\n let countNormals = 0;\n let countColors = 0;\n let countUVs = 0;\n let countIndices = 0;\n let countEdgeIndices = 0;\n\n // Metadata\n\n data.metadata = {\n id: xktModel.modelId,\n projectId: xktModel.projectId,\n revisionId: xktModel.revisionId,\n author: xktModel.author,\n createdAt: xktModel.createdAt,\n creatingApplication: xktModel.creatingApplication,\n schema: xktModel.schema,\n propertySets: [],\n metaObjects: []\n };\n\n // Property sets\n\n for (let propertySetsIndex = 0; propertySetsIndex < numPropertySets; propertySetsIndex++) {\n const propertySet = propertySetsList[propertySetsIndex];\n const propertySetJSON = {\n id: \"\" + propertySet.propertySetId,\n name: propertySet.propertySetName,\n type: propertySet.propertySetType,\n properties: propertySet.properties\n };\n data.metadata.propertySets.push(propertySetJSON);\n }\n\n // Metaobjects\n\n if (!metaModelDataStr) {\n for (let metaObjectsIndex = 0; metaObjectsIndex < numMetaObjects; metaObjectsIndex++) {\n const metaObject = metaObjectsList[metaObjectsIndex];\n const metaObjectJSON = {\n name: metaObject.metaObjectName,\n type: metaObject.metaObjectType,\n id: \"\" + metaObject.metaObjectId\n };\n if (metaObject.parentMetaObjectId !== undefined && metaObject.parentMetaObjectId !== null) {\n metaObjectJSON.parent = \"\" + metaObject.parentMetaObjectId;\n }\n if (metaObject.propertySetIds && metaObject.propertySetIds.length > 0) {\n metaObjectJSON.propertySetIds = metaObject.propertySetIds;\n }\n if (metaObject.external) {\n metaObjectJSON.external = metaObject.external;\n }\n data.metadata.metaObjects.push(metaObjectJSON);\n }\n }\n\n // Geometries\n\n for (let geometryIndex = 0; geometryIndex < numGeometries; geometryIndex++) {\n const geometry = geometriesList [geometryIndex];\n let primitiveType = 1;\n switch (geometry.primitiveType) {\n case \"triangles\":\n primitiveType = geometry.solid ? 0 : 1;\n break;\n case \"points\":\n primitiveType = 2;\n break;\n case \"lines\":\n primitiveType = 3;\n break;\n case \"line-strip\":\n case \"line-loop\":\n primitiveType = 4;\n break;\n case \"triangle-strip\":\n primitiveType = 5;\n break;\n case \"triangle-fan\":\n primitiveType = 6;\n break;\n default:\n primitiveType = 1\n }\n data.eachGeometryPrimitiveType [geometryIndex] = primitiveType;\n data.eachGeometryPositionsPortion [geometryIndex] = countPositions;\n data.eachGeometryNormalsPortion [geometryIndex] = countNormals;\n data.eachGeometryColorsPortion [geometryIndex] = countColors;\n data.eachGeometryUVsPortion [geometryIndex] = countUVs;\n data.eachGeometryIndicesPortion [geometryIndex] = countIndices;\n data.eachGeometryEdgeIndicesPortion [geometryIndex] = countEdgeIndices;\n if (geometry.positionsQuantized) {\n data.positions.set(geometry.positionsQuantized, countPositions);\n countPositions += geometry.positionsQuantized.length;\n }\n if (geometry.normalsOctEncoded) {\n data.normals.set(geometry.normalsOctEncoded, countNormals);\n countNormals += geometry.normalsOctEncoded.length;\n }\n if (geometry.colorsCompressed) {\n data.colors.set(geometry.colorsCompressed, countColors);\n countColors += geometry.colorsCompressed.length;\n }\n if (geometry.uvs) {\n data.uvs.set(geometry.uvs, countUVs);\n countUVs += geometry.uvs.length;\n }\n if (geometry.indices) {\n data.indices.set(geometry.indices, countIndices);\n countIndices += geometry.indices.length;\n }\n if (geometry.edgeIndices) {\n data.edgeIndices.set(geometry.edgeIndices, countEdgeIndices);\n countEdgeIndices += geometry.edgeIndices.length;\n }\n }\n\n // Textures\n\n for (let textureIndex = 0, numTextures = xktModel.texturesList.length, portionIdx = 0; textureIndex < numTextures; textureIndex++) {\n const xktTexture = xktModel.texturesList[textureIndex];\n const imageData = xktTexture.imageData;\n data.textureData.set(imageData, portionIdx);\n data.eachTextureDataPortion[textureIndex] = portionIdx;\n\n portionIdx += imageData.byteLength;\n\n let textureAttrIdx = textureIndex * NUM_TEXTURE_ATTRIBUTES;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.compressed ? 1 : 0;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.mediaType; // GIFMediaType | PNGMediaType | JPEGMediaType\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.width;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.height;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.minFilter; // LinearMipmapLinearFilter | LinearMipMapNearestFilter | NearestMipMapNearestFilter | NearestMipMapLinearFilter | LinearMipMapLinearFilter\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.magFilter; // LinearFilter | NearestFilter\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapS; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapT; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapR; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n }\n\n // Texture sets\n\n for (let textureSetIndex = 0, numTextureSets = xktModel.textureSetsList.length, eachTextureSetTexturesIndex = 0; textureSetIndex < numTextureSets; textureSetIndex++) {\n const textureSet = textureSetsList[textureSetIndex];\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.colorTexture ? textureSet.colorTexture.textureIndex : -1; // Color map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.metallicRoughnessTexture ? textureSet.metallicRoughnessTexture.textureIndex : -1; // Metal/rough map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.normalsTexture ? textureSet.normalsTexture.textureIndex : -1; // Normal map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.emissiveTexture ? textureSet.emissiveTexture.textureIndex : -1; // Emissive map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.occlusionTexture ? textureSet.occlusionTexture.textureIndex : -1; // Occlusion map\n }\n\n // Tiles -> Entities -> Meshes\n\n let entityIndex = 0;\n let countEntityMeshesPortion = 0;\n let eachMeshMaterialAttributesIndex = 0;\n let matricesIndex = 0;\n let meshIndex = 0;\n\n for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {\n\n const tile = tilesList [tileIndex];\n const tileEntities = tile.entities;\n const numTileEntities = tileEntities.length;\n\n if (numTileEntities === 0) {\n continue;\n }\n\n data.eachTileEntitiesPortion[tileIndex] = entityIndex;\n\n const tileAABB = tile.aabb;\n\n for (let j = 0; j < numTileEntities; j++) {\n\n const entity = tileEntities[j];\n const entityMeshes = entity.meshes;\n const numEntityMeshes = entityMeshes.length;\n\n for (let k = 0; k < numEntityMeshes; k++) {\n\n const mesh = entityMeshes[k];\n const geometry = mesh.geometry;\n const geometryIndex = geometry.geometryIndex;\n\n data.eachMeshGeometriesPortion [countEntityMeshesPortion + k] = geometryIndex;\n\n if (mesh.geometry.numInstances > 1) {\n data.matrices.set(mesh.matrix, matricesIndex);\n data.eachMeshMatricesPortion [meshIndex] = matricesIndex;\n matricesIndex += 16;\n }\n\n data.eachMeshTextureSet[meshIndex] = mesh.textureSet ? mesh.textureSet.textureSetIndex : -1;\n\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[0] * 255); // Color RGB\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[1] * 255);\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[2] * 255);\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.opacity * 255); // Opacity\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.metallic * 255); // Metallic\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.roughness * 255); // Roughness\n\n meshIndex++;\n }\n\n data.eachEntityId [entityIndex] = entity.entityId;\n data.eachEntityMeshesPortion[entityIndex] = countEntityMeshesPortion; // <<<<<<<<<<<<<<<<<<<< Error here? Order/value of countEntityMeshesPortion correct?\n\n entityIndex++;\n countEntityMeshesPortion += numEntityMeshes;\n }\n\n const tileAABBIndex = tileIndex * 6;\n\n data.eachTileAABB.set(tileAABB, tileAABBIndex);\n }\n\n return data;\n}\n\nfunction deflateData(data, metaModelJSON, options) {\n\n function deflate(buffer) {\n return (options.zip !== false) ? pako.deflate(buffer) : buffer;\n }\n\n let metaModelBytes;\n if (metaModelJSON) {\n const deflatedJSON = deflateJSON(metaModelJSON);\n metaModelBytes = deflate(deflatedJSON)\n } else {\n const deflatedJSON = deflateJSON(data.metadata);\n metaModelBytes = deflate(deflatedJSON)\n }\n\n return {\n metadata: metaModelBytes,\n textureData: deflate(data.textureData.buffer),\n eachTextureDataPortion: deflate(data.eachTextureDataPortion.buffer),\n eachTextureAttributes: deflate(data.eachTextureAttributes.buffer),\n positions: deflate(data.positions.buffer),\n normals: deflate(data.normals.buffer),\n colors: deflate(data.colors.buffer),\n uvs: deflate(data.uvs.buffer),\n indices: deflate(data.indices.buffer),\n edgeIndices: deflate(data.edgeIndices.buffer),\n eachTextureSetTextures: deflate(data.eachTextureSetTextures.buffer),\n matrices: deflate(data.matrices.buffer),\n reusedGeometriesDecodeMatrix: deflate(data.reusedGeometriesDecodeMatrix.buffer),\n eachGeometryPrimitiveType: deflate(data.eachGeometryPrimitiveType.buffer),\n eachGeometryPositionsPortion: deflate(data.eachGeometryPositionsPortion.buffer),\n eachGeometryNormalsPortion: deflate(data.eachGeometryNormalsPortion.buffer),\n eachGeometryColorsPortion: deflate(data.eachGeometryColorsPortion.buffer),\n eachGeometryUVsPortion: deflate(data.eachGeometryUVsPortion.buffer),\n eachGeometryIndicesPortion: deflate(data.eachGeometryIndicesPortion.buffer),\n eachGeometryEdgeIndicesPortion: deflate(data.eachGeometryEdgeIndicesPortion.buffer),\n eachMeshGeometriesPortion: deflate(data.eachMeshGeometriesPortion.buffer),\n eachMeshMatricesPortion: deflate(data.eachMeshMatricesPortion.buffer),\n eachMeshTextureSet: deflate(data.eachMeshTextureSet.buffer),\n eachMeshMaterialAttributes: deflate(data.eachMeshMaterialAttributes.buffer),\n eachEntityId: deflate(JSON.stringify(data.eachEntityId)\n .replace(/[\\u007F-\\uFFFF]/g, function (chr) { // Produce only ASCII-chars, so that the data can be inflated later\n return \"\\\\u\" + (\"0000\" + chr.charCodeAt(0).toString(16)).substr(-4)\n })),\n eachEntityMeshesPortion: deflate(data.eachEntityMeshesPortion.buffer),\n eachTileAABB: deflate(data.eachTileAABB.buffer),\n eachTileEntitiesPortion: deflate(data.eachTileEntitiesPortion.buffer)\n };\n}\n\nfunction deflateJSON(strings) {\n return JSON.stringify(strings)\n .replace(/[\\u007F-\\uFFFF]/g, function (chr) { // Produce only ASCII-chars, so that the data can be inflated later\n return \"\\\\u\" + (\"0000\" + chr.charCodeAt(0).toString(16)).substr(-4)\n });\n}\n\nfunction createArrayBuffer(deflatedData) {\n return toArrayBuffer([\n deflatedData.metadata,\n deflatedData.textureData,\n deflatedData.eachTextureDataPortion,\n deflatedData.eachTextureAttributes,\n deflatedData.positions,\n deflatedData.normals,\n deflatedData.colors,\n deflatedData.uvs,\n deflatedData.indices,\n deflatedData.edgeIndices,\n deflatedData.eachTextureSetTextures,\n deflatedData.matrices,\n deflatedData.reusedGeometriesDecodeMatrix,\n deflatedData.eachGeometryPrimitiveType,\n deflatedData.eachGeometryPositionsPortion,\n deflatedData.eachGeometryNormalsPortion,\n deflatedData.eachGeometryColorsPortion,\n deflatedData.eachGeometryUVsPortion,\n deflatedData.eachGeometryIndicesPortion,\n deflatedData.eachGeometryEdgeIndicesPortion,\n deflatedData.eachMeshGeometriesPortion,\n deflatedData.eachMeshMatricesPortion,\n deflatedData.eachMeshTextureSet,\n deflatedData.eachMeshMaterialAttributes,\n deflatedData.eachEntityId,\n deflatedData.eachEntityMeshesPortion,\n deflatedData.eachTileAABB,\n deflatedData.eachTileEntitiesPortion\n ]);\n}\n\nfunction toArrayBuffer(elements) {\n const indexData = new Uint32Array(elements.length + 2);\n indexData[0] = XKT_VERSION;\n indexData [1] = elements.length; // Stored Data 1.1: number of stored elements\n let dataLen = 0; // Stored Data 1.2: length of stored elements\n for (let i = 0, len = elements.length; i < len; i++) {\n const element = elements[i];\n const elementsize = element.length;\n indexData[i + 2] = elementsize;\n dataLen += elementsize;\n }\n const indexBuf = new Uint8Array(indexData.buffer);\n const dataArray = new Uint8Array(indexBuf.length + dataLen);\n dataArray.set(indexBuf);\n let offset = indexBuf.length;\n for (let i = 0, len = elements.length; i < len; i++) { // Stored Data 2: the elements themselves\n const element = elements[i];\n dataArray.set(element, offset);\n offset += element.length;\n }\n return dataArray.buffer;\n}\n\nexport {writeXKTModelToArrayBuffer};","/** @private */\nfunction earcut(data, holeIndices, dim) {\n\n dim = dim || 2;\n\n var hasHoles = holeIndices && holeIndices.length,\n outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n outerNode = linkedList(data, 0, outerLen, dim, true),\n triangles = [];\n\n if (!outerNode || outerNode.next === outerNode.prev) return triangles;\n\n var minX, minY, maxX, maxY, x, y, invSize;\n\n if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n if (data.length > 80 * dim) {\n minX = maxX = data[0];\n minY = maxY = data[1];\n\n for (var i = dim; i < outerLen; i += dim) {\n x = data[i];\n y = data[i + 1];\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n }\n\n // minX, minY and invSize are later used to transform coords into integers for z-order calculation\n invSize = Math.max(maxX - minX, maxY - minY);\n invSize = invSize !== 0 ? 1 / invSize : 0;\n }\n\n earcutLinked(outerNode, triangles, dim, minX, minY, invSize);\n\n return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList(data, start, end, dim, clockwise) {\n var i, last;\n\n if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n } else {\n for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n }\n\n if (last && equals(last, last.next)) {\n removeNode(last);\n last = last.next;\n }\n\n return last;\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints(start, end) {\n if (!start) return start;\n if (!end) end = start;\n\n var p = start,\n again;\n do {\n again = false;\n\n if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n removeNode(p);\n p = end = p.prev;\n if (p === p.next) break;\n again = true;\n\n } else {\n p = p.next;\n }\n } while (again || p !== end);\n\n return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {\n if (!ear) return;\n\n // interlink polygon nodes in z-order\n if (!pass && invSize) indexCurve(ear, minX, minY, invSize);\n\n var stop = ear,\n prev, next;\n\n // iterate through ears, slicing them one by one\n while (ear.prev !== ear.next) {\n prev = ear.prev;\n next = ear.next;\n\n if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {\n // cut off the triangle\n triangles.push(prev.i / dim);\n triangles.push(ear.i / dim);\n triangles.push(next.i / dim);\n\n removeNode(ear);\n\n // skipping the next vertex leads to less sliver triangles\n ear = next.next;\n stop = next.next;\n\n continue;\n }\n\n ear = next;\n\n // if we looped through the whole remaining polygon and can't find any more ears\n if (ear === stop) {\n // try filtering points and slicing again\n if (!pass) {\n earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);\n\n // if this didn't work, try curing all small self-intersections locally\n } else if (pass === 1) {\n ear = cureLocalIntersections(filterPoints(ear), triangles, dim);\n earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);\n\n // as a last resort, try splitting the remaining polygon into two\n } else if (pass === 2) {\n splitEarcut(ear, triangles, dim, minX, minY, invSize);\n }\n\n break;\n }\n }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar(ear) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // now make sure we don't have other points inside the potential ear\n var p = ear.next.next;\n\n while (p !== ear.prev) {\n if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.next;\n }\n\n return true;\n}\n\nfunction isEarHashed(ear, minX, minY, invSize) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // triangle bbox; min & max are calculated like this for speed\n var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\n // z-order range for the current triangle bbox;\n var minZ = zOrder(minTX, minTY, minX, minY, invSize),\n maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);\n\n var p = ear.prevZ,\n n = ear.nextZ;\n\n // look for points inside the triangle in both directions\n while (p && p.z >= minZ && n && n.z <= maxZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n\n if (n !== ear.prev && n !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&\n area(n.prev, n, n.next) >= 0) return false;\n n = n.nextZ;\n }\n\n // look for remaining points in decreasing z-order\n while (p && p.z >= minZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n }\n\n // look for remaining points in increasing z-order\n while (n && n.z <= maxZ) {\n if (n !== ear.prev && n !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&\n area(n.prev, n, n.next) >= 0) return false;\n n = n.nextZ;\n }\n\n return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections(start, triangles, dim) {\n var p = start;\n do {\n var a = p.prev,\n b = p.next.next;\n\n if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\n triangles.push(a.i / dim);\n triangles.push(p.i / dim);\n triangles.push(b.i / dim);\n\n // remove two nodes involved\n removeNode(p);\n removeNode(p.next);\n\n p = start = b;\n }\n p = p.next;\n } while (p !== start);\n\n return filterPoints(p);\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut(start, triangles, dim, minX, minY, invSize) {\n // look for a valid diagonal that divides the polygon into two\n var a = start;\n do {\n var b = a.next.next;\n while (b !== a.prev) {\n if (a.i !== b.i && isValidDiagonal(a, b)) {\n // split the polygon in two by the diagonal\n var c = splitPolygon(a, b);\n\n // filter colinear points around the cuts\n a = filterPoints(a, a.next);\n c = filterPoints(c, c.next);\n\n // run earcut on each half\n earcutLinked(a, triangles, dim, minX, minY, invSize);\n earcutLinked(c, triangles, dim, minX, minY, invSize);\n return;\n }\n b = b.next;\n }\n a = a.next;\n } while (a !== start);\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n var queue = [],\n i, len, start, end, list;\n\n for (i = 0, len = holeIndices.length; i < len; i++) {\n start = holeIndices[i] * dim;\n end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n list = linkedList(data, start, end, dim, false);\n if (list === list.next) list.steiner = true;\n queue.push(getLeftmost(list));\n }\n\n queue.sort(compareX);\n\n // process holes from left to right\n for (i = 0; i < queue.length; i++) {\n eliminateHole(queue[i], outerNode);\n outerNode = filterPoints(outerNode, outerNode.next);\n }\n\n return outerNode;\n}\n\nfunction compareX(a, b) {\n return a.x - b.x;\n}\n\n// find a bridge between vertices that connects hole with an outer ring and and link it\nfunction eliminateHole(hole, outerNode) {\n outerNode = findHoleBridge(hole, outerNode);\n if (outerNode) {\n var b = splitPolygon(outerNode, hole);\n\n // filter collinear points around the cuts\n filterPoints(outerNode, outerNode.next);\n filterPoints(b, b.next);\n }\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge(hole, outerNode) {\n var p = outerNode,\n hx = hole.x,\n hy = hole.y,\n qx = -Infinity,\n m;\n\n // find a segment intersected by a ray from the hole's leftmost point to the left;\n // segment's endpoint with lesser x will be potential connection point\n do {\n if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {\n var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n if (x <= hx && x > qx) {\n qx = x;\n if (x === hx) {\n if (hy === p.y) return p;\n if (hy === p.next.y) return p.next;\n }\n m = p.x < p.next.x ? p : p.next;\n }\n }\n p = p.next;\n } while (p !== outerNode);\n\n if (!m) return null;\n\n if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint\n\n // look for points inside the triangle of hole point, segment intersection and endpoint;\n // if there are no points found, we have a valid connection;\n // otherwise choose the point of the minimum angle with the ray as connection point\n\n var stop = m,\n mx = m.x,\n my = m.y,\n tanMin = Infinity,\n tan;\n\n p = m;\n\n do {\n if (hx >= p.x && p.x >= mx && hx !== p.x &&\n pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\n tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n if (locallyInside(p, hole) &&\n (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {\n m = p;\n tanMin = tan;\n }\n }\n\n p = p.next;\n } while (p !== stop);\n\n return m;\n}\n\n// whether sector in vertex m contains sector in vertex p in the same coordinates\nfunction sectorContainsSector(m, p) {\n return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve(start, minX, minY, invSize) {\n var p = start;\n do {\n if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize);\n p.prevZ = p.prev;\n p.nextZ = p.next;\n p = p.next;\n } while (p !== start);\n\n p.prevZ.nextZ = null;\n p.prevZ = null;\n\n sortLinked(p);\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked(list) {\n var i, p, q, e, tail, numMerges, pSize, qSize,\n inSize = 1;\n\n do {\n p = list;\n list = null;\n tail = null;\n numMerges = 0;\n\n while (p) {\n numMerges++;\n q = p;\n pSize = 0;\n for (i = 0; i < inSize; i++) {\n pSize++;\n q = q.nextZ;\n if (!q) break;\n }\n qSize = inSize;\n\n while (pSize > 0 || (qSize > 0 && q)) {\n\n if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else {\n e = q;\n q = q.nextZ;\n qSize--;\n }\n\n if (tail) tail.nextZ = e;\n else list = e;\n\n e.prevZ = tail;\n tail = e;\n }\n\n p = q;\n }\n\n tail.nextZ = null;\n inSize *= 2;\n\n } while (numMerges > 1);\n\n return list;\n}\n\n// z-order of a point given coords and inverse of the longer side of data bbox\nfunction zOrder(x, y, minX, minY, invSize) {\n // coords are transformed into non-negative 15-bit integer range\n x = 32767 * (x - minX) * invSize;\n y = 32767 * (y - minY) * invSize;\n\n x = (x | (x << 8)) & 0x00FF00FF;\n x = (x | (x << 4)) & 0x0F0F0F0F;\n x = (x | (x << 2)) & 0x33333333;\n x = (x | (x << 1)) & 0x55555555;\n\n y = (y | (y << 8)) & 0x00FF00FF;\n y = (y | (y << 4)) & 0x0F0F0F0F;\n y = (y | (y << 2)) & 0x33333333;\n y = (y | (y << 1)) & 0x55555555;\n\n return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost(start) {\n var p = start,\n leftmost = start;\n do {\n if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;\n p = p.next;\n } while (p !== start);\n\n return leftmost;\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal(a, b) {\n return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges\n (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible\n (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors\n equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case\n}\n\n// signed area of a triangle\nfunction area(p, q, r) {\n return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\nfunction equals(p1, p2) {\n return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect\nfunction intersects(p1, q1, p2, q2) {\n var o1 = sign(area(p1, q1, p2));\n var o2 = sign(area(p1, q1, q2));\n var o3 = sign(area(p2, q2, p1));\n var o4 = sign(area(p2, q2, q1));\n\n if (o1 !== o2 && o3 !== o4) return true; // general case\n\n if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1\n if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1\n if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2\n if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2\n\n return false;\n}\n\n// for collinear points p, q, r, check if point q lies on segment pr\nfunction onSegment(p, q, r) {\n return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);\n}\n\nfunction sign(num) {\n return num > 0 ? 1 : num < 0 ? -1 : 0;\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon(a, b) {\n var p = a;\n do {\n if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n intersects(p, p.next, a, b)) return true;\n p = p.next;\n } while (p !== a);\n\n return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside(a, b) {\n return area(a.prev, a, a.next) < 0 ?\n area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside(a, b) {\n var p = a,\n inside = false,\n px = (a.x + b.x) / 2,\n py = (a.y + b.y) / 2;\n do {\n if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&\n (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n inside = !inside;\n p = p.next;\n } while (p !== a);\n\n return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon(a, b) {\n var a2 = new Node(a.i, a.x, a.y),\n b2 = new Node(b.i, b.x, b.y),\n an = a.next,\n bp = b.prev;\n\n a.next = b;\n b.prev = a;\n\n a2.next = an;\n an.prev = a2;\n\n b2.next = a2;\n a2.prev = b2;\n\n bp.next = b2;\n b2.prev = bp;\n\n return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode(i, x, y, last) {\n var p = new Node(i, x, y);\n\n if (!last) {\n p.prev = p;\n p.next = p;\n\n } else {\n p.next = last.next;\n p.prev = last;\n last.next.prev = p;\n last.next = p;\n }\n return p;\n}\n\nfunction removeNode(p) {\n p.next.prev = p.prev;\n p.prev.next = p.next;\n\n if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n}\n\nfunction Node(i, x, y) {\n // vertex index in coordinates array\n this.i = i;\n\n // vertex coordinates\n this.x = x;\n this.y = y;\n\n // previous and next vertex nodes in a polygon ring\n this.prev = null;\n this.next = null;\n\n // z-order curve value\n this.z = null;\n\n // previous and next nodes in z-order\n this.prevZ = null;\n this.nextZ = null;\n\n // indicates whether this is a steiner point\n this.steiner = false;\n}\n\n// return a percentage difference between the polygon area and its triangulation area;\n// used to verify correctness of triangulation\nearcut.deviation = function (data, holeIndices, dim, triangles) {\n var hasHoles = holeIndices && holeIndices.length;\n var outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\n var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n if (hasHoles) {\n for (var i = 0, len = holeIndices.length; i < len; i++) {\n var start = holeIndices[i] * dim;\n var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n polygonArea -= Math.abs(signedArea(data, start, end, dim));\n }\n }\n\n var trianglesArea = 0;\n for (i = 0; i < triangles.length; i += 3) {\n var a = triangles[i] * dim;\n var b = triangles[i + 1] * dim;\n var c = triangles[i + 2] * dim;\n trianglesArea += Math.abs(\n (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n }\n\n return polygonArea === 0 && trianglesArea === 0 ? 0 :\n Math.abs((trianglesArea - polygonArea) / polygonArea);\n};\n\nfunction signedArea(data, start, end, dim) {\n var sum = 0;\n for (var i = start, j = end - dim; i < end; i += dim) {\n sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n j = i;\n }\n return sum;\n}\n\n// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\nearcut.flatten = function (data) {\n var dim = data[0][0].length,\n result = {vertices: [], holes: [], dimensions: dim},\n holeIndex = 0;\n\n for (var i = 0; i < data.length; i++) {\n for (var j = 0; j < data[i].length; j++) {\n for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);\n }\n if (i > 0) {\n holeIndex += data[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n return result;\n};\n\nexport {earcut};","import {earcut} from './../lib/earcut';\nimport {math} from \"./../lib/math.js\";\n\nconst tempVec2a = math.vec2();\nconst tempVec3a = math.vec3();\nconst tempVec3b = math.vec3();\nconst tempVec3c = math.vec3();\n\n/**\n * @desc Parses a CityJSON model into an {@link XKTModel}.\n *\n * [CityJSON](https://www.cityjson.org) is a JSON-based encoding for a subset of the CityGML data model (version 2.0.0),\n * which is an open standardised data model and exchange format to store digital 3D models of cities and\n * landscapes. CityGML is an official standard of the [Open Geospatial Consortium](https://www.ogc.org/).\n *\n * This converter function supports most of the [CityJSON 1.0.2 Specification](https://www.cityjson.org/specs/1.0.2),\n * with the following limitations:\n *\n * * Does not (yet) support CityJSON semantics for geometry primitives.\n * * Does not (yet) support textured geometries.\n * * Does not (yet) support geometry templates.\n * * When the CityJSON file provides multiple *themes* for a geometry, then we parse only the first of the provided themes for that geometry.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a CityJSON model into it.\n *\n * ````javascript\n * utils.loadJSON(\"./models/cityjson/DenHaag.json\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseCityJSONIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {Object} params.data CityJSON data.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {boolean} [params.center=false] Set true to center the CityJSON vertex positions to [0,0,0]. This is applied before the transformation matrix, if specified.\n * @param {Boolean} [params.transform] 4x4 transformation matrix to transform CityJSON vertex positions. Use this to rotate, translate and scale them if neccessary.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when CityJSON has been parsed.\n */\nfunction parseCityJSONIntoXKTModel({\n data,\n xktModel,\n center = false,\n transform = null,\n stats = {}, log\n }) {\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (data.type !== \"CityJSON\") {\n reject(\"Invalid argument: data is not a CityJSON file\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n let vertices;\n\n log(\"Using parser: parseCityJSONIntoXKTModel\");\n\n log(`center: ${center}`);\n if (transform) {\n log(`transform: [${transform}]`);\n }\n\n if (data.transform || center || transform) {\n vertices = copyVertices(data.vertices);\n if (data.transform) {\n transformVertices(vertices, data.transform)\n }\n if (center) {\n centerVertices(vertices);\n }\n if (transform) {\n customTransformVertices(vertices, transform);\n }\n } else {\n vertices = data.vertices;\n }\n\n stats.sourceFormat = data.type || \"\";\n stats.schemaVersion = data.version || \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 0;\n stats.numPropertySets = 0;\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n const rootMetaObjectId = math.createUUID();\n\n xktModel.createMetaObject({\n metaObjectId: rootMetaObjectId,\n metaObjectType: \"Model\",\n metaObjectName: \"Model\"\n });\n\n stats.numMetaObjects++;\n\n const modelMetaObjectId = math.createUUID();\n\n xktModel.createMetaObject({\n metaObjectId: modelMetaObjectId,\n metaObjectType: \"CityJSON\",\n metaObjectName: \"CityJSON\",\n parentMetaObjectId: rootMetaObjectId\n });\n\n stats.numMetaObjects++;\n\n const ctx = {\n data,\n vertices,\n xktModel,\n rootMetaObjectId: modelMetaObjectId,\n log: (log || function (msg) {\n }),\n nextId: 0,\n stats\n };\n\n ctx.xktModel.schema = data.type + \" \" + data.version;\n\n ctx.log(\"Converting \" + ctx.xktModel.schema);\n\n parseCityJSON(ctx);\n\n resolve();\n });\n}\n\nfunction copyVertices(vertices) {\n const vertices2 = [];\n for (let i = 0, j = 0; i < vertices.length; i++, j += 3) {\n const x = vertices[i][0];\n const y = vertices[i][1];\n const z = vertices[i][2];\n vertices2.push([x, y, z]);\n }\n return vertices2;\n}\n\nfunction transformVertices(vertices, cityJSONTransform) {\n const scale = cityJSONTransform.scale || math.vec3([1, 1, 1]);\n const translate = cityJSONTransform.translate || math.vec3([0, 0, 0]);\n for (let i = 0; i < vertices.length; i++) {\n const vertex = vertices[i];\n vertex[0] = (vertex[0] * scale[0]) + translate[0];\n vertex[1] = (vertex[1] * scale[1]) + translate[1];\n vertex[2] = (vertex[2] * scale[2]) + translate[2];\n }\n}\n\nfunction centerVertices(vertices) {\n if (center) {\n const centerPos = math.vec3();\n const numPoints = vertices.length;\n for (let i = 0, len = vertices.length; i < len; i++) {\n const vertex = vertices[i];\n centerPos[0] += vertex[0];\n centerPos[1] += vertex[1];\n centerPos[2] += vertex[2];\n }\n centerPos[0] /= numPoints;\n centerPos[1] /= numPoints;\n centerPos[2] /= numPoints;\n for (let i = 0, len = vertices.length; i < len; i++) {\n const vertex = vertices[i];\n vertex[0] -= centerPos[0];\n vertex[1] -= centerPos[1];\n vertex[2] -= centerPos[2];\n }\n }\n}\n\nfunction customTransformVertices(vertices, transform) {\n if (transform) {\n const mat = math.mat4(transform);\n for (let i = 0, len = vertices.length; i < len; i++) {\n const vertex = vertices[i];\n math.transformPoint3(mat, vertex, vertex);\n }\n }\n}\n\nfunction parseCityJSON(ctx) {\n\n const data = ctx.data;\n const cityObjects = data.CityObjects;\n\n for (const objectId in cityObjects) {\n if (cityObjects.hasOwnProperty(objectId)) {\n const cityObject = cityObjects[objectId];\n parseCityObject(ctx, cityObject, objectId);\n }\n }\n}\n\nfunction parseCityObject(ctx, cityObject, objectId) {\n\n const xktModel = ctx.xktModel;\n const data = ctx.data;\n const metaObjectId = objectId;\n const metaObjectType = cityObject.type;\n const metaObjectName = metaObjectType + \" : \" + objectId;\n\n const parentMetaObjectId = cityObject.parents ? cityObject.parents[0] : ctx.rootMetaObjectId;\n\n xktModel.createMetaObject({\n metaObjectId,\n metaObjectName,\n metaObjectType,\n parentMetaObjectId\n });\n\n ctx.stats.numMetaObjects++;\n\n if (!(cityObject.geometry && cityObject.geometry.length > 0)) {\n return;\n }\n\n const meshIds = [];\n\n for (let i = 0, len = cityObject.geometry.length; i < len; i++) {\n\n const geometry = cityObject.geometry[i];\n\n let objectMaterial;\n let surfaceMaterials;\n\n const appearance = data.appearance;\n if (appearance) {\n const materials = appearance.materials;\n if (materials) {\n const geometryMaterial = geometry.material;\n if (geometryMaterial) {\n const themeIds = Object.keys(geometryMaterial);\n if (themeIds.length > 0) {\n const themeId = themeIds[0];\n const theme = geometryMaterial[themeId];\n if (theme.value !== undefined) {\n objectMaterial = materials[theme.value];\n } else {\n const values = theme.values;\n if (values) {\n surfaceMaterials = [];\n for (let j = 0, lenj = values.length; j < lenj; j++) {\n const value = values[i];\n const surfaceMaterial = materials[value];\n surfaceMaterials.push(surfaceMaterial);\n }\n }\n }\n }\n }\n }\n }\n\n if (surfaceMaterials) {\n parseGeometrySurfacesWithOwnMaterials(ctx, geometry, surfaceMaterials, meshIds);\n\n } else {\n parseGeometrySurfacesWithSharedMaterial(ctx, geometry, objectMaterial, meshIds);\n }\n }\n\n if (meshIds.length > 0) {\n xktModel.createEntity({\n entityId: objectId,\n meshIds: meshIds\n });\n\n ctx.stats.numObjects++;\n }\n}\n\nfunction parseGeometrySurfacesWithOwnMaterials(ctx, geometry, surfaceMaterials, meshIds) {\n\n const geomType = geometry.type;\n\n switch (geomType) {\n\n case \"MultiPoint\":\n break;\n\n case \"MultiLineString\":\n break;\n\n case \"MultiSurface\":\n\n case \"CompositeSurface\":\n const surfaces = geometry.boundaries;\n parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n break;\n\n case \"Solid\":\n const shells = geometry.boundaries;\n for (let j = 0; j < shells.length; j++) {\n const surfaces = shells[j];\n parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n }\n break;\n\n case \"MultiSolid\":\n\n case \"CompositeSolid\":\n const solids = geometry.boundaries;\n for (let j = 0; j < solids.length; j++) {\n for (let k = 0; k < solids[j].length; k++) {\n const surfaces = solids[j][k];\n parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n }\n }\n break;\n\n case \"GeometryInstance\":\n break;\n }\n}\n\nfunction parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds) {\n\n const vertices = ctx.vertices;\n const xktModel = ctx.xktModel;\n\n for (let i = 0; i < surfaces.length; i++) {\n\n const surface = surfaces[i];\n const surfaceMaterial = surfaceMaterials[i] || {diffuseColor: [0.8, 0.8, 0.8], transparency: 1.0};\n\n const face = [];\n const holes = [];\n\n const sharedIndices = [];\n\n const geometryCfg = {\n positions: [],\n indices: []\n };\n\n for (let j = 0; j < surface.length; j++) {\n\n if (face.length > 0) {\n holes.push(face.length);\n }\n\n const newFace = extractLocalIndices(ctx, surface[j], sharedIndices, geometryCfg);\n\n face.push(...newFace);\n }\n\n if (face.length === 3) { // Triangle\n\n geometryCfg.indices.push(face[0]);\n geometryCfg.indices.push(face[1]);\n geometryCfg.indices.push(face[2]);\n\n } else if (face.length > 3) { // Polygon\n\n // Prepare to triangulate\n\n const pList = [];\n\n for (let k = 0; k < face.length; k++) {\n pList.push({\n x: vertices[sharedIndices[face[k]]][0],\n y: vertices[sharedIndices[face[k]]][1],\n z: vertices[sharedIndices[face[k]]][2]\n });\n }\n\n const normal = getNormalOfPositions(pList, math.vec3());\n\n // Convert to 2D\n\n let pv = [];\n\n for (let k = 0; k < pList.length; k++) {\n\n to2D(pList[k], normal, tempVec2a);\n\n pv.unshift(tempVec2a[0]);\n pv.unshift(tempVec2a[1]);\n }\n\n // Triangulate\n\n const tr = earcut(pv, holes, 2);\n\n // Create triangles\n\n for (let k = 0; k < tr.length; k += 3) {\n geometryCfg.indices.unshift(face[tr[k]]);\n geometryCfg.indices.unshift(face[tr[k + 1]]);\n geometryCfg.indices.unshift(face[tr[k + 2]]);\n }\n }\n\n const geometryId = \"\" + ctx.nextId++;\n const meshId = \"\" + ctx.nextId++;\n\n xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: geometryCfg.positions,\n indices: geometryCfg.indices\n });\n\n xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n color: (surfaceMaterial && surfaceMaterial.diffuseColor) ? surfaceMaterial.diffuseColor : [0.8, 0.8, 0.8],\n opacity: 1.0\n //opacity: (surfaceMaterial && surfaceMaterial.transparency !== undefined) ? (1.0 - surfaceMaterial.transparency) : 1.0\n });\n\n meshIds.push(meshId);\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n }\n}\n\nfunction parseGeometrySurfacesWithSharedMaterial(ctx, geometry, objectMaterial, meshIds) {\n\n const xktModel = ctx.xktModel;\n const sharedIndices = [];\n const geometryCfg = {\n positions: [],\n indices: []\n };\n\n const geomType = geometry.type;\n\n switch (geomType) {\n case \"MultiPoint\":\n break;\n\n case \"MultiLineString\":\n break;\n\n case \"MultiSurface\":\n case \"CompositeSurface\":\n const surfaces = geometry.boundaries;\n parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n break;\n\n case \"Solid\":\n const shells = geometry.boundaries;\n for (let j = 0; j < shells.length; j++) {\n const surfaces = shells[j];\n parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n }\n break;\n\n case \"MultiSolid\":\n case \"CompositeSolid\":\n const solids = geometry.boundaries;\n for (let j = 0; j < solids.length; j++) {\n for (let k = 0; k < solids[j].length; k++) {\n const surfaces = solids[j][k];\n parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n }\n }\n break;\n\n case \"GeometryInstance\":\n break;\n }\n\n const geometryId = \"\" + ctx.nextId++;\n const meshId = \"\" + ctx.nextId++;\n\n xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: geometryCfg.positions,\n indices: geometryCfg.indices\n });\n\n xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n color: (objectMaterial && objectMaterial.diffuseColor) ? objectMaterial.diffuseColor : [0.8, 0.8, 0.8],\n opacity: 1.0\n //opacity: (objectMaterial && objectMaterial.transparency !== undefined) ? (1.0 - objectMaterial.transparency) : 1.0\n });\n\n meshIds.push(meshId);\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n}\n\nfunction parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, primitiveCfg) {\n\n const vertices = ctx.vertices;\n\n for (let i = 0; i < surfaces.length; i++) {\n\n let boundary = [];\n let holes = [];\n\n for (let j = 0; j < surfaces[i].length; j++) {\n if (boundary.length > 0) {\n holes.push(boundary.length);\n }\n const newBoundary = extractLocalIndices(ctx, surfaces[i][j], sharedIndices, primitiveCfg);\n boundary.push(...newBoundary);\n }\n\n if (boundary.length === 3) { // Triangle\n\n primitiveCfg.indices.push(boundary[0]);\n primitiveCfg.indices.push(boundary[1]);\n primitiveCfg.indices.push(boundary[2]);\n\n } else if (boundary.length > 3) { // Polygon\n\n let pList = [];\n\n for (let k = 0; k < boundary.length; k++) {\n pList.push({\n x: vertices[sharedIndices[boundary[k]]][0],\n y: vertices[sharedIndices[boundary[k]]][1],\n z: vertices[sharedIndices[boundary[k]]][2]\n });\n }\n\n const normal = getNormalOfPositions(pList, math.vec3());\n let pv = [];\n\n for (let k = 0; k < pList.length; k++) {\n to2D(pList[k], normal, tempVec2a);\n pv.unshift(tempVec2a[0]);\n pv.unshift(tempVec2a[1]);\n }\n\n const tr = earcut(pv, holes, 2);\n\n for (let k = 0; k < tr.length; k += 3) {\n primitiveCfg.indices.unshift(boundary[tr[k]]);\n primitiveCfg.indices.unshift(boundary[tr[k + 1]]);\n primitiveCfg.indices.unshift(boundary[tr[k + 2]]);\n }\n }\n }\n}\n\nfunction extractLocalIndices(ctx, boundary, sharedIndices, geometryCfg) {\n\n const vertices = ctx.vertices;\n const newBoundary = []\n\n for (let i = 0, len = boundary.length; i < len; i++) {\n\n const index = boundary[i];\n\n if (sharedIndices.includes(index)) {\n const vertexIndex = sharedIndices.indexOf(index);\n newBoundary.push(vertexIndex);\n\n } else {\n geometryCfg.positions.push(vertices[index][0]);\n geometryCfg.positions.push(vertices[index][1]);\n geometryCfg.positions.push(vertices[index][2]);\n\n newBoundary.push(sharedIndices.length);\n\n sharedIndices.push(index);\n }\n }\n\n return newBoundary\n}\n\nfunction getNormalOfPositions(positions, normal) {\n\n for (let i = 0; i < positions.length; i++) {\n\n let nexti = i + 1;\n if (nexti === positions.length) {\n nexti = 0;\n }\n\n normal[0] += ((positions[i].y - positions[nexti].y) * (positions[i].z + positions[nexti].z));\n normal[1] += ((positions[i].z - positions[nexti].z) * (positions[i].x + positions[nexti].x));\n normal[2] += ((positions[i].x - positions[nexti].x) * (positions[i].y + positions[nexti].y));\n }\n\n return math.normalizeVec3(normal);\n}\n\nfunction to2D(_p, _n, re) {\n\n const p = tempVec3a;\n const n = tempVec3b;\n const x3 = tempVec3c;\n\n p[0] = _p.x;\n p[1] = _p.y;\n p[2] = _p.z;\n\n n[0] = _n.x;\n n[1] = _n.y;\n n[2] = _n.z;\n\n x3[0] = 1.1;\n x3[1] = 1.1;\n x3[2] = 1.1;\n\n const dist = math.lenVec3(math.subVec3(x3, n));\n\n if (dist < 0.01) {\n x3[0] += 1.0;\n x3[1] += 2.0;\n x3[2] += 3.0;\n }\n\n const dot = math.dotVec3(x3, n);\n const tmp2 = math.mulVec3Scalar(n, dot, math.vec3());\n\n x3[0] -= tmp2[0];\n x3[1] -= tmp2[1];\n x3[2] -= tmp2[2];\n\n math.normalizeVec3(x3);\n\n const y3 = math.cross3Vec3(n, x3, math.vec3());\n const x = math.dotVec3(p, x3);\n const y = math.dotVec3(p, y3);\n\n re[0] = x;\n re[1] = y;\n}\n\nexport {parseCityJSONIntoXKTModel};","function isString(value) {\n return (typeof value === 'string' || value instanceof String);\n}\n\nfunction apply(o, o2) {\n for (const name in o) {\n if (o.hasOwnProperty(name)) {\n o2[name] = o[name];\n }\n }\n return o2;\n}\n\n/**\n * @private\n */\nconst utils = {\n isString,\n apply\n};\n\nexport {utils};\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/gltf\");","import {utils} from \"../XKTModel/lib/utils.js\";\nimport {math} from \"../lib/math.js\";\n\nimport {parse} from '@loaders.gl/core';\nimport {GLTFLoader} from '@loaders.gl/gltf';\nimport {\n ClampToEdgeWrapping,\n LinearFilter,\n LinearMipMapLinearFilter,\n LinearMipMapNearestFilter,\n MirroredRepeatWrapping,\n NearestFilter,\n NearestMipMapLinearFilter,\n NearestMipMapNearestFilter,\n RepeatWrapping\n} from \"../constants.js\";\n\n/**\n * @desc Parses glTF into an {@link XKTModel}, supporting ````.glb```` and textures.\n *\n * * Supports ````.glb```` and textures\n * * For a lightweight glTF JSON parser that ignores textures, see {@link parseGLTFJSONIntoXKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a binary glTF model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"../assets/models/gltf/HousePlan/glTF-Binary/HousePlan.glb\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseGLTFIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing parameters.\n * @param {ArrayBuffer} params.data The glTF.\n * @param {String} [params.baseUri] The base URI used to load this glTF, if any. For resolving relative uris to linked resources.\n * @param {Object} [params.metaModelData] Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Boolean} [params.includeTextures=true] Whether to parse textures.\n * @param {Boolean} [params.includeNormals=true] Whether to parse normals. When false, the parser will ignore the glTF\n * geometry normals, and the glTF data will rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the glTF.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when glTF has been parsed.\n */\nfunction parseGLTFIntoXKTModel({\n data,\n baseUri,\n xktModel,\n metaModelData,\n includeTextures = true,\n includeNormals = true,\n getAttachment,\n stats = {},\n log\n }) {\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n stats.sourceFormat = \"glTF\";\n stats.schemaVersion = \"2.0\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numUVs = 0;\n stats.numTextures = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n parse(data, GLTFLoader, {\n baseUri\n }).then((gltfData) => {\n\n const ctx = {\n gltfData,\n metaModelCorrections: metaModelData,\n getAttachment: getAttachment || (() => {\n throw new Error('You must define getAttachment() method to convert glTF with external resources')\n }),\n log: (log || function (msg) {\n }),\n error: function (msg) {\n console.error(msg);\n },\n xktModel,\n includeNormals: (includeNormals !== false),\n includeTextures: (includeTextures !== false),\n geometryCreated: {},\n nextId: 0,\n stats\n };\n\n ctx.log(\"Using parser: parseGLTFIntoXKTModel\");\n ctx.log(`Parsing normals: ${ctx.includeNormals ? \"enabled\" : \"disabled\"}`);\n ctx.log(`Parsing textures: ${ctx.includeTextures ? \"enabled\" : \"disabled\"}`);\n\n if (ctx.includeTextures) {\n parseTextures(ctx);\n }\n parseMaterials(ctx);\n parseDefaultScene(ctx);\n\n resolve();\n\n }, (errMsg) => {\n reject(`[parseGLTFIntoXKTModel] ${errMsg}`);\n });\n });\n}\n\nfunction parseTextures(ctx) {\n const gltfData = ctx.gltfData;\n const textures = gltfData.textures;\n if (textures) {\n for (let i = 0, len = textures.length; i < len; i++) {\n parseTexture(ctx, textures[i]);\n ctx.stats.numTextures++;\n }\n }\n}\n\nfunction parseTexture(ctx, texture) {\n if (!texture.source || !texture.source.image) {\n return;\n }\n const textureId = `texture-${ctx.nextId++}`;\n\n let minFilter = NearestMipMapLinearFilter;\n switch (texture.sampler.minFilter) {\n case 9728:\n minFilter = NearestFilter;\n break;\n case 9729:\n minFilter = LinearFilter;\n break;\n case 9984:\n minFilter = NearestMipMapNearestFilter;\n break;\n case 9985:\n minFilter = LinearMipMapNearestFilter;\n break;\n case 9986:\n minFilter = NearestMipMapLinearFilter;\n break;\n case 9987:\n minFilter = LinearMipMapLinearFilter;\n break;\n }\n\n let magFilter = LinearFilter;\n switch (texture.sampler.magFilter) {\n case 9728:\n magFilter = NearestFilter;\n break;\n case 9729:\n magFilter = LinearFilter;\n break;\n }\n\n let wrapS = RepeatWrapping;\n switch (texture.sampler.wrapS) {\n case 33071:\n wrapS = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapS = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapS = RepeatWrapping;\n break;\n }\n\n let wrapT = RepeatWrapping;\n switch (texture.sampler.wrapT) {\n case 33071:\n wrapT = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapT = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapT = RepeatWrapping;\n break;\n }\n\n let wrapR = RepeatWrapping;\n switch (texture.sampler.wrapR) {\n case 33071:\n wrapR = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapR = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapR = RepeatWrapping;\n break;\n }\n\n ctx.xktModel.createTexture({\n textureId: textureId,\n imageData: texture.source.image,\n mediaType: texture.source.mediaType,\n compressed: true,\n width: texture.source.image.width,\n height: texture.source.image.height,\n minFilter,\n magFilter,\n wrapS,\n wrapT,\n wrapR,\n flipY: !!texture.flipY,\n // encoding: \"sRGB\"\n });\n texture._textureId = textureId;\n}\n\nfunction parseMaterials(ctx) {\n const gltfData = ctx.gltfData;\n const materials = gltfData.materials;\n if (materials) {\n for (let i = 0, len = materials.length; i < len; i++) {\n const material = materials[i];\n material._textureSetId = ctx.includeTextures ? parseTextureSet(ctx, material) : null;\n material._attributes = parseMaterialAttributes(ctx, material);\n }\n }\n}\n\nfunction parseTextureSet(ctx, material) {\n const textureSetCfg = {};\n if (material.normalTexture) {\n textureSetCfg.normalTextureId = material.normalTexture.texture._textureId;\n }\n if (material.occlusionTexture) {\n textureSetCfg.occlusionTextureId = material.occlusionTexture.texture._textureId;\n }\n if (material.emissiveTexture) {\n textureSetCfg.emissiveTextureId = material.emissiveTexture.texture._textureId;\n }\n // const alphaMode = material.alphaMode;\n // switch (alphaMode) {\n // case \"NORMAL_OPAQUE\":\n // materialCfg.alphaMode = \"opaque\";\n // break;\n // case \"MASK\":\n // materialCfg.alphaMode = \"mask\";\n // break;\n // case \"BLEND\":\n // materialCfg.alphaMode = \"blend\";\n // break;\n // default:\n // }\n // const alphaCutoff = material.alphaCutoff;\n // if (alphaCutoff !== undefined) {\n // materialCfg.alphaCutoff = alphaCutoff;\n // }\n const metallicPBR = material.pbrMetallicRoughness;\n if (material.pbrMetallicRoughness) {\n const pbrMetallicRoughness = material.pbrMetallicRoughness;\n const baseColorTexture = pbrMetallicRoughness.baseColorTexture || pbrMetallicRoughness.colorTexture;\n if (baseColorTexture) {\n if (baseColorTexture.texture) {\n textureSetCfg.colorTextureId = baseColorTexture.texture._textureId;\n } else {\n textureSetCfg.colorTextureId = ctx.gltfData.textures[baseColorTexture.index]._textureId;\n }\n }\n if (metallicPBR.metallicRoughnessTexture) {\n textureSetCfg.metallicRoughnessTextureId = metallicPBR.metallicRoughnessTexture.texture._textureId;\n }\n }\n const extensions = material.extensions;\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const specularTexture = specularPBR.specularTexture;\n if (specularTexture !== null && specularTexture !== undefined) {\n // textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n }\n const specularColorTexture = specularPBR.specularColorTexture;\n if (specularColorTexture !== null && specularColorTexture !== undefined) {\n textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n }\n }\n }\n if (textureSetCfg.normalTextureId !== undefined ||\n textureSetCfg.occlusionTextureId !== undefined ||\n textureSetCfg.emissiveTextureId !== undefined ||\n textureSetCfg.colorTextureId !== undefined ||\n textureSetCfg.metallicRoughnessTextureId !== undefined) {\n textureSetCfg.textureSetId = `textureSet-${ctx.nextId++};`\n ctx.xktModel.createTextureSet(textureSetCfg);\n ctx.stats.numTextureSets++;\n return textureSetCfg.textureSetId;\n }\n return null;\n}\n\nfunction parseMaterialAttributes(ctx, material) { // Substitute RGBA for material, to use fast flat shading instead\n const extensions = material.extensions;\n const materialAttributes = {\n color: new Float32Array([1, 1, 1, 1]),\n opacity: 1,\n metallic: 0,\n roughness: 1\n };\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const diffuseFactor = specularPBR.diffuseFactor;\n if (diffuseFactor !== null && diffuseFactor !== undefined) {\n materialAttributes.color.set(diffuseFactor);\n }\n }\n const common = extensions[\"KHR_materials_common\"];\n if (common) {\n const technique = common.technique;\n const values = common.values || {};\n const blinn = technique === \"BLINN\";\n const phong = technique === \"PHONG\";\n const lambert = technique === \"LAMBERT\";\n const diffuse = values.diffuse;\n if (diffuse && (blinn || phong || lambert)) {\n if (!utils.isString(diffuse)) {\n materialAttributes.color.set(diffuse);\n }\n }\n const transparency = values.transparency;\n if (transparency !== null && transparency !== undefined) {\n materialAttributes.opacity = transparency;\n }\n const transparent = values.transparent;\n if (transparent !== null && transparent !== undefined) {\n materialAttributes.opacity = transparent;\n }\n }\n }\n const metallicPBR = material.pbrMetallicRoughness;\n if (metallicPBR) {\n const baseColorFactor = metallicPBR.baseColorFactor;\n if (baseColorFactor) {\n materialAttributes.color[0] = baseColorFactor[0];\n materialAttributes.color[1] = baseColorFactor[1];\n materialAttributes.color[2] = baseColorFactor[2];\n materialAttributes.opacity = baseColorFactor[3];\n }\n const metallicFactor = metallicPBR.metallicFactor;\n if (metallicFactor !== null && metallicFactor !== undefined) {\n materialAttributes.metallic = metallicFactor;\n }\n const roughnessFactor = metallicPBR.roughnessFactor;\n if (roughnessFactor !== null && roughnessFactor !== undefined) {\n materialAttributes.roughness = roughnessFactor;\n }\n }\n return materialAttributes;\n}\n\nfunction parseDefaultScene(ctx) {\n const gltfData = ctx.gltfData;\n const scene = gltfData.scene || gltfData.scenes[0];\n if (!scene) {\n ctx.error(\"glTF has no default scene\");\n return;\n }\n parseScene(ctx, scene);\n}\n\nfunction parseScene(ctx, scene) {\n const nodes = scene.nodes;\n if (!nodes) {\n return;\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const node = nodes[i];\n countMeshUsage(ctx, node);\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const node = nodes[i];\n parseNode(ctx, node, 0, null);\n }\n}\n\nfunction countMeshUsage(ctx, node) {\n const mesh = node.mesh;\n if (mesh) {\n mesh.instances = mesh.instances ? mesh.instances + 1 : 1;\n }\n if (node.children) {\n const children = node.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNode = children[i];\n if (!childNode) {\n ctx.error(\"Node not found: \" + i);\n continue;\n }\n countMeshUsage(ctx, childNode);\n }\n }\n}\n\nconst objectIdStack = [];\nconst meshIdsStack = [];\n\nlet meshIds = null;\n\nfunction parseNode(ctx, node, depth, matrix) {\n\n const xktModel = ctx.xktModel;\n\n // Pre-order visit scene node\n\n let localMatrix;\n if (node.matrix) {\n localMatrix = node.matrix;\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.translation) {\n localMatrix = math.translationMat4v(node.translation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.rotation) {\n localMatrix = math.quaternionToMat4(node.rotation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.scale) {\n localMatrix = math.scalingMat4v(node.scale);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n\n if (node.name) {\n meshIds = [];\n let xktEntityId = node.name;\n if (!!xktEntityId && xktModel.entities[xktEntityId]) {\n ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${xktEntityId} - will randomly-generating an object ID in XKT`);\n }\n while (!xktEntityId || xktModel.entities[xktEntityId]) {\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n objectIdStack.push(xktEntityId);\n meshIdsStack.push(meshIds);\n }\n\n if (meshIds && node.mesh) {\n\n const mesh = node.mesh;\n const numPrimitives = mesh.primitives.length;\n\n if (numPrimitives > 0) {\n for (let i = 0; i < numPrimitives; i++) {\n const primitive = mesh.primitives[i];\n if (!primitive._xktGeometryId) {\n const xktGeometryId = \"geometry-\" + ctx.nextId++;\n const geometryCfg = {\n geometryId: xktGeometryId\n };\n switch (primitive.mode) {\n case 0: // POINTS\n geometryCfg.primitiveType = \"points\";\n break;\n case 1: // LINES\n geometryCfg.primitiveType = \"lines\";\n break;\n case 2: // LINE_LOOP\n geometryCfg.primitiveType = \"line-loop\";\n break;\n case 3: // LINE_STRIP\n geometryCfg.primitiveType = \"line-strip\";\n break;\n case 4: // TRIANGLES\n geometryCfg.primitiveType = \"triangles\";\n break;\n case 5: // TRIANGLE_STRIP\n geometryCfg.primitiveType = \"triangle-strip\";\n break;\n case 6: // TRIANGLE_FAN\n geometryCfg.primitiveType = \"triangle-fan\";\n break;\n default:\n geometryCfg.primitiveType = \"triangles\";\n }\n const POSITION = primitive.attributes.POSITION;\n if (!POSITION) {\n continue;\n }\n geometryCfg.positions = primitive.attributes.POSITION.value;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n if (ctx.includeNormals) {\n if (primitive.attributes.NORMAL) {\n geometryCfg.normals = primitive.attributes.NORMAL.value;\n ctx.stats.numNormals += geometryCfg.normals.length / 3;\n }\n }\n if (primitive.attributes.COLOR_0) {\n geometryCfg.colorsCompressed = primitive.attributes.COLOR_0.value;\n }\n if (ctx.includeTextures) {\n if (primitive.attributes.TEXCOORD_0) {\n geometryCfg.uvs = primitive.attributes.TEXCOORD_0.value;\n ctx.stats.numUVs += geometryCfg.uvs.length / 2;\n }\n }\n if (primitive.indices) {\n geometryCfg.indices = primitive.indices.value;\n if (primitive.mode === 4) {\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n }\n }\n xktModel.createGeometry(geometryCfg);\n primitive._xktGeometryId = xktGeometryId;\n ctx.stats.numGeometries++;\n }\n\n const xktMeshId = ctx.nextId++;\n const meshCfg = {\n meshId: xktMeshId,\n geometryId: primitive._xktGeometryId,\n matrix: matrix ? matrix.slice() : math.identityMat4()\n };\n const material = primitive.material;\n if (material) {\n meshCfg.textureSetId = material._textureSetId;\n meshCfg.color = material._attributes.color;\n meshCfg.opacity = material._attributes.opacity;\n meshCfg.metallic = material._attributes.metallic;\n meshCfg.roughness = material._attributes.roughness;\n } else {\n meshCfg.color = [1.0, 1.0, 1.0];\n meshCfg.opacity = 1.0;\n }\n xktModel.createMesh(meshCfg);\n meshIds.push(xktMeshId);\n }\n }\n }\n\n // Visit child scene nodes\n\n if (node.children) {\n const children = node.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNode = children[i];\n parseNode(ctx, childNode, depth + 1, matrix);\n }\n }\n\n // Post-order visit scene node\n\n const nodeName = node.name;\n if ((nodeName !== undefined && nodeName !== null) || depth === 0) {\n if (nodeName === undefined || nodeName === null) {\n ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);\n }\n let xktEntityId = objectIdStack.pop();\n if (!xktEntityId) { // For when there are no nodes with names\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n let entityMeshIds = meshIdsStack.pop();\n if (meshIds && meshIds.length > 0) {\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: entityMeshIds\n });\n }\n ctx.stats.numObjects++;\n meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null;\n }\n}\n\nexport {parseGLTFIntoXKTModel};","import {utils} from \"../XKTModel/lib/utils.js\";\nimport {math} from \"../lib/math.js\";\n\nconst atob2 = (typeof atob !== 'undefined') ? atob : a => Buffer.from(a, 'base64').toString('binary');\n\nconst WEBGL_COMPONENT_TYPES = {\n 5120: Int8Array,\n 5121: Uint8Array,\n 5122: Int16Array,\n 5123: Uint16Array,\n 5125: Uint32Array,\n 5126: Float32Array\n};\n\nconst WEBGL_TYPE_SIZES = {\n 'SCALAR': 1,\n 'VEC2': 2,\n 'VEC3': 3,\n 'VEC4': 4,\n 'MAT2': 4,\n 'MAT3': 9,\n 'MAT4': 16\n};\n\n/**\n * @desc Parses glTF JSON into an {@link XKTModel}, without ````.glb```` and textures.\n *\n * * Lightweight JSON-based glTF parser which ignores textures\n * * For texture and ````.glb```` support, see {@link parseGLTFIntoXKTModel}\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a glTF model into it.\n *\n * ````javascript\n * utils.loadJSON(\"./models/gltf/duplex/scene.gltf\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseGLTFJSONIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing parameters.\n * @param {Object} params.data The glTF JSON.\n * @param {Object} [params.metaModelData] Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Boolean} [params.includeNormals=false] Whether to parse normals. When false, the parser will ignore the glTF\n * geometry normals, and the glTF data will rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded representation of the glTF.\n * @param {Boolean} [params.reuseGeometries=true] When true, the parser will enable geometry reuse within the XKTModel. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be if we have 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {function} [params.getAttachment] Callback through which to fetch attachments, if the glTF has them.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n * @returns {Promise}\n */\nfunction parseGLTFJSONIntoXKTModel({\n data,\n xktModel,\n metaModelData,\n includeNormals,\n reuseGeometries,\n getAttachment,\n stats = {},\n log\n }) {\n\n if (log) {\n log(\"Using parser: parseGLTFJSONIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n stats.sourceFormat = \"glTF\";\n stats.schemaVersion = \"2.0\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n const ctx = {\n gltf: data,\n metaModelCorrections: metaModelData ? getMetaModelCorrections(metaModelData) : null,\n getAttachment: getAttachment || (() => {\n throw new Error('You must define getAttachment() method to convert glTF with external resources')\n }),\n log: (log || function (msg) {\n }),\n xktModel,\n includeNormals,\n createXKTGeometryIds: {},\n nextMeshId: 0,\n reuseGeometries: (reuseGeometries !== false),\n stats\n };\n\n ctx.log(`Parsing normals: ${ctx.includeNormals ? \"enabled\" : \"disabled\"}`);\n\n parseBuffers(ctx).then(() => {\n\n parseBufferViews(ctx);\n freeBuffers(ctx);\n parseMaterials(ctx);\n parseDefaultScene(ctx);\n\n resolve();\n\n }, (errMsg) => {\n reject(errMsg);\n });\n });\n}\n\nfunction getMetaModelCorrections(metaModelData) {\n const eachRootStats = {};\n const eachChildRoot = {};\n const metaObjects = metaModelData.metaObjects || [];\n const metaObjectsMap = {};\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n const metaObject = metaObjects[i];\n metaObjectsMap[metaObject.id] = metaObject;\n }\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n const metaObject = metaObjects[i];\n if (metaObject.parent !== undefined && metaObject.parent !== null) {\n const metaObjectParent = metaObjectsMap[metaObject.parent];\n if (metaObject.type === metaObjectParent.type) {\n let rootMetaObject = metaObjectParent;\n while (rootMetaObject.parent && metaObjectsMap[rootMetaObject.parent].type === rootMetaObject.type) {\n rootMetaObject = metaObjectsMap[rootMetaObject.parent];\n }\n const rootStats = eachRootStats[rootMetaObject.id] || (eachRootStats[rootMetaObject.id] = {\n numChildren: 0,\n countChildren: 0\n });\n rootStats.numChildren++;\n eachChildRoot[metaObject.id] = rootMetaObject;\n } else {\n\n }\n }\n }\n const metaModelCorrections = {\n metaObjectsMap,\n eachRootStats,\n eachChildRoot\n };\n return metaModelCorrections;\n}\n\nfunction parseBuffers(ctx) { // Parses geometry buffers into temporary \"_buffer\" Unit8Array properties on the glTF \"buffer\" elements\n const buffers = ctx.gltf.buffers;\n if (buffers) {\n return Promise.all(buffers.map(buffer => parseBuffer(ctx, buffer)));\n } else {\n return new Promise(function (resolve, reject) {\n resolve();\n });\n }\n}\n\nfunction parseBuffer(ctx, bufferInfo) {\n return new Promise(function (resolve, reject) {\n // Allow a shortcut where the glTF buffer is \"enrichened\" with direct\n // access to the data-arrayBuffer, w/out needing to either:\n // - read the file indicated by the \".uri\" component of the buffer\n // - base64-decode the encoded data in the \".uri\" component\n if (bufferInfo._arrayBuffer) {\n bufferInfo._buffer = bufferInfo._arrayBuffer;\n resolve(bufferInfo);\n return;\n }\n // Otherwise, proceed with \"standard-glTF\" .uri component.\n const uri = bufferInfo.uri;\n if (!uri) {\n reject('gltf/handleBuffer missing uri in ' + JSON.stringify(bufferInfo));\n return;\n }\n parseArrayBuffer(ctx, uri).then((arrayBuffer) => {\n bufferInfo._buffer = arrayBuffer;\n resolve(arrayBuffer);\n }, (errMsg) => {\n reject(errMsg);\n })\n });\n}\n\nfunction parseArrayBuffer(ctx, uri) {\n return new Promise(function (resolve, reject) {\n const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; // Check for data: URI\n const dataUriRegexResult = uri.match(dataUriRegex);\n if (dataUriRegexResult) { // Safari can't handle data URIs through XMLHttpRequest\n const isBase64 = !!dataUriRegexResult[2];\n let data = dataUriRegexResult[3];\n data = decodeURIComponent(data);\n if (isBase64) {\n data = atob2(data);\n }\n const buffer = new ArrayBuffer(data.length);\n const view = new Uint8Array(buffer);\n for (let i = 0; i < data.length; i++) {\n view[i] = data.charCodeAt(i);\n }\n resolve(buffer);\n } else { // Uri is a path to a file\n ctx.getAttachment(uri).then(\n (arrayBuffer) => {\n resolve(arrayBuffer);\n },\n (errMsg) => {\n reject(errMsg);\n });\n }\n });\n}\n\nfunction parseBufferViews(ctx) { // Parses our temporary \"_buffer\" properties into \"_buffer\" properties on glTF \"bufferView\" elements\n const bufferViewsInfo = ctx.gltf.bufferViews;\n if (bufferViewsInfo) {\n for (let i = 0, len = bufferViewsInfo.length; i < len; i++) {\n parseBufferView(ctx, bufferViewsInfo[i]);\n }\n }\n}\n\nfunction parseBufferView(ctx, bufferViewInfo) {\n const buffer = ctx.gltf.buffers[bufferViewInfo.buffer];\n bufferViewInfo._typedArray = null;\n const byteLength = bufferViewInfo.byteLength || 0;\n const byteOffset = bufferViewInfo.byteOffset || 0;\n bufferViewInfo._buffer = buffer._buffer.slice(byteOffset, byteOffset + byteLength);\n}\n\nfunction freeBuffers(ctx) { // Deletes the \"_buffer\" properties from the glTF \"buffer\" elements, to save memory\n const buffers = ctx.gltf.buffers;\n if (buffers) {\n for (let i = 0, len = buffers.length; i < len; i++) {\n buffers[i]._buffer = null;\n }\n }\n}\n\nfunction parseMaterials(ctx) {\n const materialsInfo = ctx.gltf.materials;\n if (materialsInfo) {\n for (let i = 0, len = materialsInfo.length; i < len; i++) {\n const materialInfo = materialsInfo[i];\n const material = parseMaterial(ctx, materialInfo);\n materialInfo._materialData = material;\n }\n }\n}\n\nfunction parseMaterial(ctx, materialInfo) { // Attempts to extract an RGBA color for a glTF material\n const material = {\n color: new Float32Array([1, 1, 1]),\n opacity: 1.0,\n metallic: 0,\n roughness: 1\n };\n const extensions = materialInfo.extensions;\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const diffuseFactor = specularPBR.diffuseFactor;\n if (diffuseFactor !== null && diffuseFactor !== undefined) {\n material.color[0] = diffuseFactor[0];\n material.color[1] = diffuseFactor[1];\n material.color[2] = diffuseFactor[2];\n }\n }\n const common = extensions[\"KHR_materials_common\"];\n if (common) {\n const technique = common.technique;\n const values = common.values || {};\n const blinn = technique === \"BLINN\";\n const phong = technique === \"PHONG\";\n const lambert = technique === \"LAMBERT\";\n const diffuse = values.diffuse;\n if (diffuse && (blinn || phong || lambert)) {\n if (!utils.isString(diffuse)) {\n material.color[0] = diffuse[0];\n material.color[1] = diffuse[1];\n material.color[2] = diffuse[2];\n }\n }\n const transparency = values.transparency;\n if (transparency !== null && transparency !== undefined) {\n material.opacity = transparency;\n }\n const transparent = values.transparent;\n if (transparent !== null && transparent !== undefined) {\n material.opacity = transparent;\n }\n }\n }\n const metallicPBR = materialInfo.pbrMetallicRoughness;\n if (metallicPBR) {\n const baseColorFactor = metallicPBR.baseColorFactor;\n if (baseColorFactor) {\n material.color[0] = baseColorFactor[0];\n material.color[1] = baseColorFactor[1];\n material.color[2] = baseColorFactor[2];\n material.opacity = baseColorFactor[3];\n }\n const metallicFactor = metallicPBR.metallicFactor;\n if (metallicFactor !== null && metallicFactor !== undefined) {\n material.metallic = metallicFactor;\n }\n const roughnessFactor = metallicPBR.roughnessFactor;\n if (roughnessFactor !== null && roughnessFactor !== undefined) {\n material.roughness = roughnessFactor;\n }\n }\n return material;\n}\n\nfunction parseDefaultScene(ctx) {\n const scene = ctx.gltf.scene || 0;\n const defaultSceneInfo = ctx.gltf.scenes[scene];\n if (!defaultSceneInfo) {\n throw new Error(\"glTF has no default scene\");\n }\n parseScene(ctx, defaultSceneInfo);\n}\n\n\nfunction parseScene(ctx, sceneInfo) {\n const nodes = sceneInfo.nodes;\n if (!nodes) {\n return;\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const glTFNode = ctx.gltf.nodes[nodes[i]];\n if (glTFNode) {\n parseNode(ctx, glTFNode, 0, null);\n }\n }\n}\n\nlet deferredMeshIds = [];\n\nfunction parseNode(ctx, glTFNode, depth, matrix) {\n\n const gltf = ctx.gltf;\n const xktModel = ctx.xktModel;\n\n let localMatrix;\n\n if (glTFNode.matrix) {\n localMatrix = glTFNode.matrix;\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n\n if (glTFNode.translation) {\n localMatrix = math.translationMat4v(glTFNode.translation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, localMatrix);\n } else {\n matrix = localMatrix;\n }\n }\n\n if (glTFNode.rotation) {\n localMatrix = math.quaternionToMat4(glTFNode.rotation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, localMatrix);\n } else {\n matrix = localMatrix;\n }\n }\n\n if (glTFNode.scale) {\n localMatrix = math.scalingMat4v(glTFNode.scale);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, localMatrix);\n } else {\n matrix = localMatrix;\n }\n }\n\n const gltfMeshId = glTFNode.mesh;\n\n if (gltfMeshId !== undefined) {\n\n const meshInfo = gltf.meshes[gltfMeshId];\n\n if (meshInfo) {\n\n const numPrimitivesInMesh = meshInfo.primitives.length;\n\n if (numPrimitivesInMesh > 0) {\n\n for (let i = 0; i < numPrimitivesInMesh; i++) {\n\n const primitiveInfo = meshInfo.primitives[i];\n\n const geometryHash = createPrimitiveGeometryHash(primitiveInfo);\n\n let xktGeometryId = ctx.createXKTGeometryIds[geometryHash];\n\n if ((!ctx.reuseGeometries) || !xktGeometryId) {\n\n xktGeometryId = \"geometry-\" + ctx.nextMeshId++\n\n const geometryArrays = {};\n\n parsePrimitiveGeometry(ctx, primitiveInfo, geometryArrays);\n\n const colors = geometryArrays.colors;\n\n let colorsCompressed;\n\n if (geometryArrays.colors) {\n colorsCompressed = [];\n for (let j = 0, lenj = colors.length; j < lenj; j += 4) {\n colorsCompressed.push(colors[j + 0]);\n colorsCompressed.push(colors[j + 1]);\n colorsCompressed.push(colors[j + 2]);\n colorsCompressed.push(255);\n }\n }\n\n xktModel.createGeometry({\n geometryId: xktGeometryId,\n primitiveType: geometryArrays.primitive,\n positions: geometryArrays.positions,\n normals: ctx.includeNormals ? geometryArrays.normals : null,\n colorsCompressed: colorsCompressed,\n indices: geometryArrays.indices\n });\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += geometryArrays.positions ? geometryArrays.positions.length / 3 : 0;\n ctx.stats.numNormals += (ctx.includeNormals && geometryArrays.normals) ? geometryArrays.normals.length / 3 : 0;\n ctx.stats.numTriangles += geometryArrays.indices ? geometryArrays.indices.length / 3 : 0;\n\n ctx.createXKTGeometryIds[geometryHash] = xktGeometryId;\n } else {\n// Geometry reused\n }\n\n const materialIndex = primitiveInfo.material;\n const materialInfo = (materialIndex !== null && materialIndex !== undefined) ? gltf.materials[materialIndex] : null;\n const color = materialInfo ? materialInfo._materialData.color : new Float32Array([1.0, 1.0, 1.0, 1.0]);\n const opacity = materialInfo ? materialInfo._materialData.opacity : 1.0;\n const metallic = materialInfo ? materialInfo._materialData.metallic : 0.0;\n const roughness = materialInfo ? materialInfo._materialData.roughness : 1.0;\n\n const xktMeshId = \"mesh-\" + ctx.nextMeshId++;\n\n xktModel.createMesh({\n meshId: xktMeshId,\n geometryId: xktGeometryId,\n matrix: matrix ? matrix.slice() : math.identityMat4(),\n color: color,\n opacity: opacity,\n metallic: metallic,\n roughness: roughness\n });\n\n deferredMeshIds.push(xktMeshId);\n }\n }\n }\n }\n\n\n if (glTFNode.children) {\n const children = glTFNode.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNodeIdx = children[i];\n const childGLTFNode = gltf.nodes[childNodeIdx];\n if (!childGLTFNode) {\n console.warn('Node not found: ' + i);\n continue;\n }\n parseNode(ctx, childGLTFNode, depth + 1, matrix);\n }\n }\n\n // Post-order visit scene node\n\n const nodeName = glTFNode.name;\n if (((nodeName !== undefined && nodeName !== null) || depth === 0) && deferredMeshIds.length > 0) {\n if (nodeName === undefined || nodeName === null) {\n ctx.log(`[parseGLTFJSONIntoXKTModel] Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);\n }\n let xktEntityId = nodeName; // Fall back on generated ID when `name` not found on glTF scene node(s)\n if (xktEntityId === undefined || xktEntityId === null) {\n if (xktModel.entities[xktEntityId]) {\n ctx.error(\"Two or more glTF nodes found with same 'name' attribute: '\" + nodeName + \"'\");\n }\n while (!xktEntityId || xktModel.entities[xktEntityId]) {\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n }\n if (ctx.metaModelCorrections) { // Merging meshes into XKTObjects that map to metaobjects\n const rootMetaObject = ctx.metaModelCorrections.eachChildRoot[xktEntityId];\n if (rootMetaObject) {\n const rootMetaObjectStats = ctx.metaModelCorrections.eachRootStats[rootMetaObject.id];\n rootMetaObjectStats.countChildren++;\n if (rootMetaObjectStats.countChildren >= rootMetaObjectStats.numChildren) {\n xktModel.createEntity({\n entityId: rootMetaObject.id,\n meshIds: deferredMeshIds\n });\n ctx.stats.numObjects++;\n deferredMeshIds = [];\n }\n } else {\n const metaObject = ctx.metaModelCorrections.metaObjectsMap[xktEntityId];\n if (metaObject) {\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: deferredMeshIds\n });\n ctx.stats.numObjects++;\n deferredMeshIds = [];\n }\n }\n } else { // Create an XKTObject from the meshes at each named glTF node, don't care about metaobjects\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: deferredMeshIds\n });\n ctx.stats.numObjects++;\n deferredMeshIds = [];\n }\n }\n}\n\nfunction createPrimitiveGeometryHash(primitiveInfo) {\n const attributes = primitiveInfo.attributes;\n if (!attributes) {\n return \"empty\";\n }\n const mode = primitiveInfo.mode;\n const material = primitiveInfo.material;\n const indices = primitiveInfo.indices;\n const positions = primitiveInfo.attributes.POSITION;\n const normals = primitiveInfo.attributes.NORMAL;\n const colors = primitiveInfo.attributes.COLOR_0;\n const uv = primitiveInfo.attributes.TEXCOORD_0;\n return [\n mode,\n // material,\n (indices !== null && indices !== undefined) ? indices : \"-\",\n (positions !== null && positions !== undefined) ? positions : \"-\",\n (normals !== null && normals !== undefined) ? normals : \"-\",\n (colors !== null && colors !== undefined) ? colors : \"-\",\n (uv !== null && uv !== undefined) ? uv : \"-\"\n ].join(\";\");\n}\n\nfunction parsePrimitiveGeometry(ctx, primitiveInfo, geometryArrays) {\n const attributes = primitiveInfo.attributes;\n if (!attributes) {\n return;\n }\n switch (primitiveInfo.mode) {\n case 0: // POINTS\n geometryArrays.primitive = \"points\";\n break;\n case 1: // LINES\n geometryArrays.primitive = \"lines\";\n break;\n case 2: // LINE_LOOP\n // TODO: convert\n geometryArrays.primitive = \"lines\";\n break;\n case 3: // LINE_STRIP\n // TODO: convert\n geometryArrays.primitive = \"lines\";\n break;\n case 4: // TRIANGLES\n geometryArrays.primitive = \"triangles\";\n break;\n case 5: // TRIANGLE_STRIP\n // TODO: convert\n console.log(\"TRIANGLE_STRIP\");\n geometryArrays.primitive = \"triangles\";\n break;\n case 6: // TRIANGLE_FAN\n // TODO: convert\n console.log(\"TRIANGLE_FAN\");\n geometryArrays.primitive = \"triangles\";\n break;\n default:\n geometryArrays.primitive = \"triangles\";\n }\n const accessors = ctx.gltf.accessors;\n const indicesIndex = primitiveInfo.indices;\n if (indicesIndex !== null && indicesIndex !== undefined) {\n const accessorInfo = accessors[indicesIndex];\n geometryArrays.indices = parseAccessorTypedArray(ctx, accessorInfo);\n }\n const positionsIndex = attributes.POSITION;\n if (positionsIndex !== null && positionsIndex !== undefined) {\n const accessorInfo = accessors[positionsIndex];\n geometryArrays.positions = parseAccessorTypedArray(ctx, accessorInfo);\n }\n const normalsIndex = attributes.NORMAL;\n if (normalsIndex !== null && normalsIndex !== undefined) {\n const accessorInfo = accessors[normalsIndex];\n geometryArrays.normals = parseAccessorTypedArray(ctx, accessorInfo);\n }\n const colorsIndex = attributes.COLOR_0;\n if (colorsIndex !== null && colorsIndex !== undefined) {\n const accessorInfo = accessors[colorsIndex];\n geometryArrays.colors = parseAccessorTypedArray(ctx, accessorInfo);\n }\n}\n\nfunction parseAccessorTypedArray(ctx, accessorInfo) {\n const bufferView = ctx.gltf.bufferViews[accessorInfo.bufferView];\n const itemSize = WEBGL_TYPE_SIZES[accessorInfo.type];\n const TypedArray = WEBGL_COMPONENT_TYPES[accessorInfo.componentType];\n const elementBytes = TypedArray.BYTES_PER_ELEMENT; // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.\n const itemBytes = elementBytes * itemSize;\n if (accessorInfo.byteStride && accessorInfo.byteStride !== itemBytes) { // The buffer is not interleaved if the stride is the item size in bytes.\n throw new Error(\"interleaved buffer!\"); // TODO\n } else {\n return new TypedArray(bufferView._buffer, accessorInfo.byteOffset || 0, accessorInfo.count * itemSize);\n }\n}\n\nexport {parseGLTFJSONIntoXKTModel};\n","/**\n * @desc Parses IFC STEP file data into an {@link XKTModel}.\n *\n * This function uses [web-ifc](https://github.com/tomvandig/web-ifc) to parse the IFC, which relies on a\n * WASM file to do the parsing.\n *\n * Depending on how we use this function, we may need to provide it with a path to the directory where that WASM file is stored.\n *\n * This function is tested with web-ifc version 0.0.34.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an IFC model into it.\n *\n * ````javascript\n * import {XKTModel, parseIFCIntoXKTModel, writeXKTModelToArrayBuffer} from \"xeokit-convert.es.js\";\n *\n * import * as WebIFC from \"web-ifc-api.js\";\n *\n * utils.loadArraybuffer(\"rac_advanced_sample_project.ifc\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseIFCIntoXKTModel({\n * WebIFC,\n * data,\n * xktModel,\n * wasmPath: \"../dist/\",\n * autoNormals: true,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {ArrayBuffer} [params.data] IFC file data.\n * @param {XKTModel} [params.xktModel] XKTModel to parse into.\n * @param {Boolean} [params.autoNormals=true] When true, the parser will ignore the IFC geometry normals, and the IFC\n * data will rely on the xeokit ````Viewer```` to automatically generate them. This has the limitation that the\n * normals will be face-aligned, and therefore the ````Viewer```` will only be able to render a flat-shaded representation\n * of the IFC model. This is ````true```` by default, because IFC models tend to look acceptable with flat-shading,\n * and we always want to minimize IFC model size wherever possible.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {String} params.wasmPath Path to ````web-ifc.wasm````, required by this function.\n * @param {Object} [params.stats={}] Collects statistics.\n * @param {function} [params.log] Logging callback.\n * @returns {Promise} Resolves when IFC has been parsed.\n */\nfunction parseIFCIntoXKTModel({\n WebIFC,\n data,\n xktModel,\n autoNormals = true,\n includeTypes,\n excludeTypes,\n wasmPath,\n stats = {},\n log\n }) {\n\n if (log) {\n log(\"Using parser: parseIFCIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n if (!wasmPath) {\n reject(\"Argument expected: wasmPath\");\n return;\n }\n\n const ifcAPI = new WebIFC.IfcAPI();\n\n if (wasmPath) {\n ifcAPI.SetWasmPath(wasmPath);\n }\n\n ifcAPI.Init().then(() => {\n\n const dataArray = new Uint8Array(data);\n\n const modelID = ifcAPI.OpenModel(dataArray);\n\n stats.sourceFormat = \"IFC\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 0;\n stats.numPropertySets = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n stats.numTriangles = 0;\n stats.numVertices = 0;\n\n const ctx = {\n WebIFC,\n modelID,\n ifcAPI,\n xktModel,\n autoNormals,\n log: (log || function (msg) {\n }),\n nextId: 0,\n stats\n };\n\n if (includeTypes) {\n ctx.includeTypes = {};\n for (let i = 0, len = includeTypes.length; i < len; i++) {\n ctx.includeTypes[includeTypes[i]] = true;\n }\n }\n\n if (excludeTypes) {\n ctx.excludeTypes = {};\n for (let i = 0, len = excludeTypes.length; i < len; i++) {\n ctx.excludeTypes[excludeTypes[i]] = true;\n }\n }\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(modelID, WebIFC.IFCPROJECT);\n const ifcProjectId = lines.get(0);\n const ifcProject = ctx.ifcAPI.GetLine(modelID, ifcProjectId);\n\n ctx.xktModel.schema = \"\";\n ctx.xktModel.modelId = \"\" + modelID;\n ctx.xktModel.projectId = \"\" + ifcProjectId;\n\n parseMetadata(ctx);\n parseGeometry(ctx);\n parsePropertySets(ctx);\n\n resolve();\n\n }).catch((e) => {\n\n reject(e);\n })\n });\n}\n\nfunction parsePropertySets(ctx) {\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, ctx.WebIFC.IFCRELDEFINESBYPROPERTIES);\n\n for (let i = 0; i < lines.size(); i++) {\n\n let relID = lines.get(i);\n\n let rel = ctx.ifcAPI.GetLine(ctx.modelID, relID, true);\n\n if (rel) {\n\n const relatingPropertyDefinition = rel.RelatingPropertyDefinition;\n if (!relatingPropertyDefinition) {\n continue;\n }\n\n const propertySetId = relatingPropertyDefinition.GlobalId.value;\n\n const relatedObjects = rel.RelatedObjects;\n if (relatedObjects) {\n for (let i = 0, len = relatedObjects.length; i < len; i++) {\n const relatedObject = relatedObjects[i];\n const metaObjectId = relatedObject.GlobalId.value;\n const metaObject = ctx.xktModel.metaObjects[metaObjectId];\n if (metaObject) {\n if (!metaObject.propertySetIds) {\n metaObject.propertySetIds = [];\n }\n metaObject.propertySetIds.push(propertySetId);\n }\n }\n }\n\n const props = relatingPropertyDefinition.HasProperties;\n if (props && props.length > 0) {\n const propertySetType = \"Default\";\n const propertySetName = relatingPropertyDefinition.Name.value;\n const properties = [];\n for (let i = 0, len = props.length; i < len; i++) {\n const prop = props[i];\n const name = prop.Name;\n const nominalValue = prop.NominalValue;\n if (name && nominalValue) {\n const property = {\n name: name.value,\n type: nominalValue.type,\n value: nominalValue.value,\n valueType: nominalValue.valueType\n };\n if (prop.Description) {\n property.description = prop.Description.value;\n } else if (nominalValue.description) {\n property.description = nominalValue.description;\n }\n properties.push(property);\n }\n }\n ctx.xktModel.createPropertySet({propertySetId, propertySetType, propertySetName, properties});\n ctx.stats.numPropertySets++;\n }\n }\n }\n}\n\nfunction parseMetadata(ctx) {\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, ctx.WebIFC.IFCPROJECT);\n const ifcProjectId = lines.get(0);\n const ifcProject = ctx.ifcAPI.GetLine(ctx.modelID, ifcProjectId);\n\n parseSpatialChildren(ctx, ifcProject);\n}\n\nfunction parseSpatialChildren(ctx, ifcElement, parentMetaObjectId) {\n\n const metaObjectType = ifcElement.__proto__.constructor.name;\n\n if (ctx.includeTypes && (!ctx.includeTypes[metaObjectType])) {\n return;\n }\n\n if (ctx.excludeTypes && ctx.excludeTypes[metaObjectType]) {\n return;\n }\n\n createMetaObject(ctx, ifcElement, parentMetaObjectId);\n\n const metaObjectId = ifcElement.GlobalId.value;\n\n parseRelatedItemsOfType(\n ctx,\n ifcElement.expressID,\n 'RelatingObject',\n 'RelatedObjects',\n ctx.WebIFC.IFCRELAGGREGATES,\n metaObjectId);\n\n parseRelatedItemsOfType(\n ctx,\n ifcElement.expressID,\n 'RelatingStructure',\n 'RelatedElements',\n ctx.WebIFC.IFCRELCONTAINEDINSPATIALSTRUCTURE,\n metaObjectId);\n}\n\nfunction createMetaObject(ctx, ifcElement, parentMetaObjectId) {\n\n const metaObjectId = ifcElement.GlobalId.value;\n const propertySetIds = null;\n const metaObjectType = ifcElement.__proto__.constructor.name;\n const metaObjectName = (ifcElement.Name && ifcElement.Name.value !== \"\") ? ifcElement.Name.value : metaObjectType;\n\n ctx.xktModel.createMetaObject({metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId});\n ctx.stats.numMetaObjects++;\n}\n\nfunction parseRelatedItemsOfType(ctx, id, relation, related, type, parentMetaObjectId) {\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, type);\n\n for (let i = 0; i < lines.size(); i++) {\n\n const relID = lines.get(i);\n const rel = ctx.ifcAPI.GetLine(ctx.modelID, relID);\n const relatedItems = rel[relation];\n\n let foundElement = false;\n\n if (Array.isArray(relatedItems)) {\n const values = relatedItems.map((item) => item.value);\n foundElement = values.includes(id);\n\n } else {\n foundElement = (relatedItems.value === id);\n }\n\n if (foundElement) {\n\n const element = rel[related];\n\n if (!Array.isArray(element)) {\n\n const ifcElement = ctx.ifcAPI.GetLine(ctx.modelID, element.value);\n\n parseSpatialChildren(ctx, ifcElement, parentMetaObjectId);\n\n } else {\n\n element.forEach((element2) => {\n\n const ifcElement = ctx.ifcAPI.GetLine(ctx.modelID, element2.value);\n\n parseSpatialChildren(ctx, ifcElement, parentMetaObjectId);\n });\n }\n }\n }\n}\n\nfunction parseGeometry(ctx) {\n\n // Parses the geometry and materials in the IFC, creates\n // XKTEntity, XKTMesh and XKTGeometry components within the XKTModel.\n\n const flatMeshes = ctx.ifcAPI.LoadAllGeometry(ctx.modelID);\n\n for (let i = 0, len = flatMeshes.size(); i < len; i++) {\n const flatMesh = flatMeshes.get(i);\n createObject(ctx, flatMesh);\n }\n\n // LoadAllGeometry does not return IFCSpace meshes\n // here is a workaround\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, ctx.WebIFC.IFCSPACE);\n for (let j = 0, len = lines.size(); j < len; j++) {\n const ifcSpaceId = lines.get(j);\n const flatMesh = ctx.ifcAPI.GetFlatMesh(ctx.modelID, ifcSpaceId);\n createObject(ctx, flatMesh);\n }\n}\n\nfunction createObject(ctx, flatMesh) {\n\n const flatMeshExpressID = flatMesh.expressID;\n const placedGeometries = flatMesh.geometries;\n\n const meshIds = [];\n\n const properties = ctx.ifcAPI.GetLine(ctx.modelID, flatMeshExpressID);\n const entityId = properties.GlobalId.value;\n\n const metaObjectId = entityId;\n const metaObject = ctx.xktModel.metaObjects[metaObjectId];\n\n if (ctx.includeTypes && (!metaObject || (!ctx.includeTypes[metaObject.metaObjectType]))) {\n return;\n }\n\n if (ctx.excludeTypes && (!metaObject || ctx.excludeTypes[metaObject.metaObjectType])) {\n console.log(\"excluding: \" + metaObjectId)\n return;\n }\n\n for (let j = 0, lenj = placedGeometries.size(); j < lenj; j++) {\n\n const placedGeometry = placedGeometries.get(j);\n const geometryId = \"\" + placedGeometry.geometryExpressID;\n\n if (!ctx.xktModel.geometries[geometryId]) {\n\n const geometry = ctx.ifcAPI.GetGeometry(ctx.modelID, placedGeometry.geometryExpressID);\n const vertexData = ctx.ifcAPI.GetVertexArray(geometry.GetVertexData(), geometry.GetVertexDataSize());\n const indices = ctx.ifcAPI.GetIndexArray(geometry.GetIndexData(), geometry.GetIndexDataSize());\n\n // De-interleave vertex arrays\n\n const positions = [];\n const normals = [];\n\n for (let k = 0, lenk = vertexData.length / 6; k < lenk; k++) {\n positions.push(vertexData[k * 6 + 0]);\n positions.push(vertexData[k * 6 + 1]);\n positions.push(vertexData[k * 6 + 2]);\n }\n\n if (!ctx.autoNormals) {\n for (let k = 0, lenk = vertexData.length / 6; k < lenk; k++) {\n normals.push(vertexData[k * 6 + 3]);\n normals.push(vertexData[k * 6 + 4]);\n normals.push(vertexData[k * 6 + 5]);\n }\n }\n\n ctx.xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: positions,\n normals: ctx.autoNormals ? null : normals,\n indices: indices\n });\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += (positions.length / 3);\n ctx.stats.numTriangles += (indices.length / 3);\n }\n\n const meshId = (\"mesh\" + ctx.nextId++);\n\n ctx.xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n matrix: placedGeometry.flatTransformation,\n color: [placedGeometry.color.x, placedGeometry.color.y, placedGeometry.color.z],\n opacity: placedGeometry.color.w\n });\n\n meshIds.push(meshId);\n }\n\n if (meshIds.length > 0) {\n ctx.xktModel.createEntity({\n entityId: entityId,\n meshIds: meshIds\n });\n ctx.stats.numObjects++;\n }\n}\n\nexport {parseIFCIntoXKTModel};\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/las\");","import {parse} from '@loaders.gl/core';\nimport {LASLoader} from '@loaders.gl/las';\n\nimport {math} from \"../lib/math.js\";\n\nconst MAX_VERTICES = 500000; // TODO: Rough estimate\n\n/**\n * @desc Parses LAS and LAZ point cloud data into an {@link XKTModel}.\n *\n * This parser handles both the LASER file format (LAS) and its compressed version (LAZ),\n * a public format for the interchange of 3-dimensional point cloud data data, developed\n * for LIDAR mapping purposes.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an LAZ point cloud model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"./models/laz/autzen.laz\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * await parseLASIntoXKTModel({\n * data,\n * xktModel,\n * rotateX: true,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer} params.data LAS/LAZ file data.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {boolean} [params.center=false] Set true to center the LAS point positions to [0,0,0]. This is applied before the transformation matrix, if specified.\n * @param {Boolean} [params.transform] 4x4 transformation matrix to transform point positions. Use this to rotate, translate and scale them if neccessary.\n * @param {Number|String} [params.colorDepth=8] Whether colors encoded using 8 or 16 bits. Can be set to 'auto'. LAS specification recommends 16 bits.\n * @param {Boolean} [params.fp64=false] Configures if LASLoaderPlugin assumes that LAS positions are stored in 64-bit floats instead of 32-bit.\n * @param {Number} [params.skip=1] Read one from every n points.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n * @returns {Promise} Resolves when LAS has been parsed.\n */\nfunction parseLASIntoXKTModel({\n data,\n xktModel,\n center = false,\n transform = null,\n colorDepth = \"auto\",\n fp64 = false,\n skip = 1,\n stats,\n log = () => {\n }\n }) {\n\n if (log) {\n log(\"Using parser: parseLASIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n log(\"Converting LAZ/LAS\");\n\n log(`center: ${center}`);\n if (transform) {\n log(`transform: [${transform}]`);\n }\n log(`colorDepth: ${colorDepth}`);\n log(`fp64: ${fp64}`);\n log(`skip: ${skip}`);\n\n parse(data, LASLoader, {\n las: {\n colorDepth,\n fp64\n }\n }).then((parsedData) => {\n\n const attributes = parsedData.attributes;\n\n const loaderData = parsedData.loaderData;\n const pointsFormatId = loaderData.pointsFormatId !== undefined ? loaderData.pointsFormatId : -1;\n\n if (!attributes.POSITION) {\n log(\"No positions found in file (expected for all LAS point formats)\");\n return;\n }\n\n let readAttributes = {};\n\n switch (pointsFormatId) {\n case 0:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 0)\");\n return;\n }\n\n readAttributes = readIntensities(attributes.POSITION, attributes.intensity);\n break;\n case 1:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 1)\");\n return;\n }\n readAttributes = readIntensities(attributes.POSITION, attributes.intensity);\n break;\n case 2:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 2)\");\n return;\n }\n\n readAttributes = readColorsAndIntensities(attributes.POSITION, attributes.COLOR_0, attributes.intensity);\n break;\n case 3:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 3)\");\n return;\n }\n readAttributes = readColorsAndIntensities(attributes.POSITION, attributes.COLOR_0, attributes.intensity);\n break;\n }\n\n const pointsChunks = chunkArray(readPositions(readAttributes.positions), MAX_VERTICES * 3);\n const colorsChunks = chunkArray(readAttributes.colors, MAX_VERTICES * 4);\n\n const meshIds = [];\n\n for (let j = 0, lenj = pointsChunks.length; j < lenj; j++) {\n\n const geometryId = `geometry-${j}`;\n const meshId = `mesh-${j}`;\n\n meshIds.push(meshId);\n\n xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"points\",\n positions: pointsChunks[j],\n colorsCompressed: colorsChunks[j]\n });\n\n xktModel.createMesh({\n meshId,\n geometryId\n });\n }\n\n const entityId = math.createUUID();\n\n xktModel.createEntity({\n entityId,\n meshIds\n });\n\n const rootMetaObjectId = math.createUUID();\n\n xktModel.createMetaObject({\n metaObjectId: rootMetaObjectId,\n metaObjectType: \"Model\",\n metaObjectName: \"Model\"\n });\n\n xktModel.createMetaObject({\n metaObjectId: entityId,\n metaObjectType: \"PointCloud\",\n metaObjectName: \"PointCloud (LAZ)\",\n parentMetaObjectId: rootMetaObjectId\n });\n\n if (stats) {\n stats.sourceFormat = \"LAS\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 2;\n stats.numPropertySets = 0;\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numVertices = readAttributes.positions.length / 3;\n }\n\n resolve();\n\n }, (errMsg) => {\n reject(errMsg);\n });\n });\n\n function readPositions(positionsValue) {\n if (positionsValue) {\n if (center) {\n const centerPos = math.vec3();\n const numPoints = positionsValue.length;\n for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n centerPos[0] += positionsValue[i + 0];\n centerPos[1] += positionsValue[i + 1];\n centerPos[2] += positionsValue[i + 2];\n }\n centerPos[0] /= numPoints;\n centerPos[1] /= numPoints;\n centerPos[2] /= numPoints;\n for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n positionsValue[i + 0] -= centerPos[0];\n positionsValue[i + 1] -= centerPos[1];\n positionsValue[i + 2] -= centerPos[2];\n }\n }\n if (transform) {\n const mat = math.mat4(transform);\n const pos = math.vec3();\n for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n pos[0] = positionsValue[i + 0];\n pos[1] = positionsValue[i + 1];\n pos[2] = positionsValue[i + 2];\n math.transformPoint3(mat, pos, pos);\n positionsValue[i + 0] = pos[0];\n positionsValue[i + 1] = pos[1];\n positionsValue[i + 2] = pos[2];\n }\n }\n }\n return positionsValue;\n }\n\n function readColorsAndIntensities(attributesPosition, attributesColor, attributesIntensity) {\n const positionsValue = attributesPosition.value;\n const colors = attributesColor.value;\n const colorSize = attributesColor.size;\n const intensities = attributesIntensity.value;\n const colorsCompressedSize = intensities.length * 4;\n const positions = [];\n const colorsCompressed = new Uint8Array(colorsCompressedSize / skip);\n let count = skip;\n for (let i = 0, j = 0, k = 0, l = 0, m = 0, n=0,len = intensities.length; i < len; i++, k += colorSize, j += 4, l += 3) {\n if (count <= 0) {\n colorsCompressed[m++] = colors[k + 0];\n colorsCompressed[m++] = colors[k + 1];\n colorsCompressed[m++] = colors[k + 2];\n colorsCompressed[m++] = Math.round((intensities[i] / 65536) * 255);\n positions[n++] = positionsValue[l + 0];\n positions[n++] = positionsValue[l + 1];\n positions[n++] = positionsValue[l + 2];\n count = skip;\n } else {\n count--;\n }\n }\n return {\n positions,\n colors: colorsCompressed\n };\n }\n\n function readIntensities(attributesPosition, attributesIntensity) {\n const positionsValue = attributesPosition.value;\n const intensities = attributesIntensity.value;\n const colorsCompressedSize = intensities.length * 4;\n const positions = [];\n const colorsCompressed = new Uint8Array(colorsCompressedSize / skip);\n let count = skip;\n for (let i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, len = intensities.length; i < len; i++, k += 3, j += 4, l += 3) {\n if (count <= 0) {\n colorsCompressed[m++] = 0;\n colorsCompressed[m++] = 0;\n colorsCompressed[m++] = 0;\n colorsCompressed[m++] = Math.round((intensities[i] / 65536) * 255);\n positions[n++] = positionsValue[l + 0];\n positions[n++] = positionsValue[l + 1];\n positions[n++] = positionsValue[l + 2];\n count = skip;\n } else {\n count--;\n }\n }\n return {\n positions,\n colors: colorsCompressed\n };\n }\n\n function chunkArray(array, chunkSize) {\n if (chunkSize >= array.length) {\n return [array]; // One chunk\n }\n let result = [];\n for (let i = 0; i < array.length; i += chunkSize) {\n result.push(array.slice(i, i + chunkSize));\n }\n return result;\n }\n\n}\n\nexport {parseLASIntoXKTModel};","/**\n * @desc Parses JSON metamodel into an {@link XKTModel}.\n *\n * @param {Object} params Parsing parameters.\n * @param {JSON} params.metaModelData Metamodel data.\n * @param {String[]} [params.excludeTypes] Types to exclude from parsing.\n * @param {String[]} [params.includeTypes] Types to include in parsing.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when JSON has been parsed.\n */\nfunction parseMetaModelIntoXKTModel({metaModelData, xktModel, includeTypes, excludeTypes, log}) {\n\n if (log) {\n log(\"Using parser: parseMetaModelIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n const metaObjects = metaModelData.metaObjects || [];\n const propertySets = metaModelData.propertySets || [];\n\n xktModel.modelId = metaModelData.revisionId || \"\"; // HACK\n xktModel.projectId = metaModelData.projectId || \"\";\n xktModel.revisionId = metaModelData.revisionId || \"\";\n xktModel.author = metaModelData.author || \"\";\n xktModel.createdAt = metaModelData.createdAt || \"\";\n xktModel.creatingApplication = metaModelData.creatingApplication || \"\";\n xktModel.schema = metaModelData.schema || \"\";\n\n for (let i = 0, len = propertySets.length; i < len; i++) {\n\n const propertySet = propertySets[i];\n\n xktModel.createPropertySet({\n propertySetId: propertySet.id,\n propertySetName: propertySet.name,\n propertySetType: propertySet.type,\n properties: propertySet.properties\n });\n }\n\n let includeTypesMap;\n if (includeTypes) {\n includeTypesMap = {};\n for (let i = 0, len = includeTypes.length; i < len; i++) {\n includeTypesMap[includeTypes[i]] = true;\n }\n }\n\n let excludeTypesMap;\n if (excludeTypes) {\n excludeTypesMap = {};\n for (let i = 0, len = excludeTypes.length; i < len; i++) {\n excludeTypesMap[excludeTypes[i]] = true;\n }\n }\n\n const metaObjectsMap = {};\n\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n const newObject = metaObjects[i];\n metaObjectsMap[newObject.id] = newObject;\n }\n\n let countMetaObjects = 0;\n\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n\n const metaObject = metaObjects[i];\n const type = metaObject.type;\n\n if (excludeTypesMap && excludeTypesMap[type]) {\n continue;\n }\n\n if (includeTypesMap && !includeTypesMap[type]) {\n continue;\n }\n\n if (metaObject.parent !== undefined && metaObject.parent !== null) {\n const metaObjectParent = metaObjectsMap[metaObject.parent];\n if (metaObject.type === metaObjectParent.type) { // Don't create redundant sub-objects\n continue\n }\n }\n\n const propertySetIds = [];\n if (metaObject.propertySetIds) {\n for (let j = 0, lenj = metaObject.propertySetIds.length; j < lenj; j++) {\n const propertySetId = metaObject.propertySetIds[j];\n if (propertySetId !== undefined && propertySetId !== null && propertySetId !== \"\") {\n propertySetIds.push(propertySetId);\n }\n }\n }\n if (metaObject.propertySetId !== undefined && metaObject.propertySetId !== null && metaObject.propertySetId !== \"\") {\n propertySetIds.push(metaObject.propertySetId);\n }\n\n xktModel.createMetaObject({\n metaObjectId: metaObject.id,\n metaObjectType: metaObject.type,\n metaObjectName: metaObject.name,\n parentMetaObjectId: metaObject.parent,\n propertySetIds: propertySetIds.length > 0 ? propertySetIds : null\n });\n\n countMetaObjects++;\n }\n\n if (log) {\n log(\"Converted meta objects: \" + countMetaObjects);\n }\n\n resolve();\n });\n}\n\nexport {parseMetaModelIntoXKTModel};\n","/**\n * @desc Parses PCD point cloud data into an {@link XKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an LAZ point cloud model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"\"./models/pcd/ism_test_cat.pcd\"\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * await parsePCDIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer} params.data PCD file data.\n * @param {Boolean} [params.littleEndian=true] Whether PCD binary data is Little-Endian or Big-Endian.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when PCD has been parsed.\n */\nfunction parsePCDIntoXKTModel({data, xktModel, littleEndian = true, stats, log}) {\n\n if (log) {\n log(\"Using parser: parsePCDIntoXKTModel\");\n }\n\n return new Promise(function(resolve, reject) {\n\n const textData = decodeText(new Uint8Array(data));\n\n const header = parseHeader(textData);\n\n const positions = [];\n const normals = [];\n const colors = [];\n\n if (header.data === 'ascii') {\n\n const offset = header.offset;\n const data = textData.substr(header.headerLen);\n const lines = data.split('\\n');\n\n for (let i = 0, l = lines.length; i < l; i++) {\n\n if (lines[i] === '') {\n continue;\n }\n\n const line = lines[i].split(' ');\n\n if (offset.x !== undefined) {\n positions.push(parseFloat(line[offset.x]));\n positions.push(parseFloat(line[offset.y]));\n positions.push(parseFloat(line[offset.z]));\n }\n\n if (offset.rgb !== undefined) {\n const rgb = parseFloat(line[offset.rgb]);\n const r = (rgb >> 16) & 0x0000ff;\n const g = (rgb >> 8) & 0x0000ff;\n const b = (rgb >> 0) & 0x0000ff;\n colors.push(r, g, b, 255);\n } else {\n colors.push(255);\n colors.push(255);\n colors.push(255);\n }\n }\n }\n\n if (header.data === 'binary_compressed') {\n\n const sizes = new Uint32Array(data.slice(header.headerLen, header.headerLen + 8));\n const compressedSize = sizes[0];\n const decompressedSize = sizes[1];\n const decompressed = decompressLZF(new Uint8Array(data, header.headerLen + 8, compressedSize), decompressedSize);\n const dataview = new DataView(decompressed.buffer);\n const offset = header.offset;\n\n for (let i = 0; i < header.points; i++) {\n\n if (offset.x !== undefined) {\n positions.push(dataview.getFloat32((header.points * offset.x) + header.size[0] * i, littleEndian));\n positions.push(dataview.getFloat32((header.points * offset.y) + header.size[1] * i, littleEndian));\n positions.push(dataview.getFloat32((header.points * offset.z) + header.size[2] * i, littleEndian));\n }\n\n if (offset.rgb !== undefined) {\n colors.push(dataview.getUint8((header.points * offset.rgb) + header.size[3] * i + 0));\n colors.push(dataview.getUint8((header.points * offset.rgb) + header.size[3] * i + 1));\n colors.push(dataview.getUint8((header.points * offset.rgb) + header.size[3] * i + 2));\n // colors.push(255);\n } else {\n colors.push(1);\n colors.push(1);\n colors.push(1);\n }\n }\n }\n\n if (header.data === 'binary') {\n\n const dataview = new DataView(data, header.headerLen);\n const offset = header.offset;\n\n for (let i = 0, row = 0; i < header.points; i++, row += header.rowSize) {\n if (offset.x !== undefined) {\n positions.push(dataview.getFloat32(row + offset.x, littleEndian));\n positions.push(dataview.getFloat32(row + offset.y, littleEndian));\n positions.push(dataview.getFloat32(row + offset.z, littleEndian));\n }\n\n if (offset.rgb !== undefined) {\n colors.push(dataview.getUint8(row + offset.rgb + 2));\n colors.push(dataview.getUint8(row + offset.rgb + 1));\n colors.push(dataview.getUint8(row + offset.rgb + 0));\n } else {\n colors.push(255);\n colors.push(255);\n colors.push(255);\n }\n }\n }\n\n xktModel.createGeometry({\n geometryId: \"pointsGeometry\",\n primitiveType: \"points\",\n positions: positions,\n colors: colors && colors.length > 0 ? colors : null\n });\n\n xktModel.createMesh({\n meshId: \"pointsMesh\",\n geometryId: \"pointsGeometry\"\n });\n\n xktModel.createEntity({\n entityId: \"geometries\",\n meshIds: [\"pointsMesh\"]\n });\n\n if (log) {\n log(\"Converted drawable objects: 1\");\n log(\"Converted geometries: 1\");\n log(\"Converted vertices: \" + positions.length / 3);\n }\n\n if (stats) {\n stats.sourceFormat = \"PCD\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numVertices = positions.length / 3;\n }\n\n resolve();\n });\n}\n\nfunction parseHeader(data) {\n const header = {};\n const result1 = data.search(/[\\r\\n]DATA\\s(\\S*)\\s/i);\n const result2 = /[\\r\\n]DATA\\s(\\S*)\\s/i.exec(data.substr(result1 - 1));\n header.data = result2[1];\n header.headerLen = result2[0].length + result1;\n header.str = data.substr(0, header.headerLen);\n header.str = header.str.replace(/\\#.*/gi, ''); // Strip comments\n header.version = /VERSION (.*)/i.exec(header.str); // Parse\n header.fields = /FIELDS (.*)/i.exec(header.str);\n header.size = /SIZE (.*)/i.exec(header.str);\n header.type = /TYPE (.*)/i.exec(header.str);\n header.count = /COUNT (.*)/i.exec(header.str);\n header.width = /WIDTH (.*)/i.exec(header.str);\n header.height = /HEIGHT (.*)/i.exec(header.str);\n header.viewpoint = /VIEWPOINT (.*)/i.exec(header.str);\n header.points = /POINTS (.*)/i.exec(header.str);\n if (header.version !== null) {\n header.version = parseFloat(header.version[1]);\n }\n if (header.fields !== null) {\n header.fields = header.fields[1].split(' ');\n }\n if (header.type !== null) {\n header.type = header.type[1].split(' ');\n }\n if (header.width !== null) {\n header.width = parseInt(header.width[1]);\n }\n if (header.height !== null) {\n header.height = parseInt(header.height[1]);\n }\n if (header.viewpoint !== null) {\n header.viewpoint = header.viewpoint[1];\n }\n if (header.points !== null) {\n header.points = parseInt(header.points[1], 10);\n }\n if (header.points === null) {\n header.points = header.width * header.height;\n }\n if (header.size !== null) {\n header.size = header.size[1].split(' ').map(function (x) {\n return parseInt(x, 10);\n });\n }\n if (header.count !== null) {\n header.count = header.count[1].split(' ').map(function (x) {\n return parseInt(x, 10);\n });\n } else {\n header.count = [];\n for (let i = 0, l = header.fields.length; i < l; i++) {\n header.count.push(1);\n }\n }\n header.offset = {};\n let sizeSum = 0;\n for (let i = 0, l = header.fields.length; i < l; i++) {\n if (header.data === 'ascii') {\n header.offset[header.fields[i]] = i;\n } else {\n header.offset[header.fields[i]] = sizeSum;\n sizeSum += header.size[i] * header.count[i];\n }\n }\n header.rowSize = sizeSum; // For binary only\n return header;\n}\n\nfunction decodeText(array) {\n if (typeof TextDecoder !== 'undefined') {\n return new TextDecoder().decode(array);\n }\n let s = '';\n for (let i = 0, il = array.length; i < il; i++) {\n s += String.fromCharCode(array[i]);\n }\n try {\n return decodeURIComponent(escape(s));\n } catch (e) {\n return s;\n }\n}\n\nfunction decompressLZF(inData, outLength) { // https://gitlab.com/taketwo/three-pcd-loader/blob/master/decompress-lzf.js\n const inLength = inData.length;\n const outData = new Uint8Array(outLength);\n let inPtr = 0;\n let outPtr = 0;\n let ctrl;\n let len;\n let ref;\n do {\n ctrl = inData[inPtr++];\n if (ctrl < (1 << 5)) {\n ctrl++;\n if (outPtr + ctrl > outLength) throw new Error('Output buffer is not large enough');\n if (inPtr + ctrl > inLength) throw new Error('Invalid compressed data');\n do {\n outData[outPtr++] = inData[inPtr++];\n } while (--ctrl);\n } else {\n len = ctrl >> 5;\n ref = outPtr - ((ctrl & 0x1f) << 8) - 1;\n if (inPtr >= inLength) throw new Error('Invalid compressed data');\n if (len === 7) {\n len += inData[inPtr++];\n if (inPtr >= inLength) throw new Error('Invalid compressed data');\n }\n ref -= inData[inPtr++];\n if (outPtr + len + 2 > outLength) throw new Error('Output buffer is not large enough');\n if (ref < 0) throw new Error('Invalid compressed data');\n if (ref >= outPtr) throw new Error('Invalid compressed data');\n do {\n outData[outPtr++] = outData[ref++];\n } while (--len + 2);\n }\n } while (inPtr < inLength);\n return outData;\n}\n\nexport {parsePCDIntoXKTModel};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/ply\");","import {parse} from '@loaders.gl/core';\nimport {PLYLoader} from '@loaders.gl/ply';\n\n/**\n * @desc Parses PLY file data into an {@link XKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a PLY model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"./models/ply/test.ply\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parsePLYIntoXKTModel({data, xktModel}).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer} params.data PLY file data.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when PLY has been parsed.\n */\nasync function parsePLYIntoXKTModel({data, xktModel, stats, log}) {\n\n if (log) {\n log(\"Using parser: parsePLYIntoXKTModel\");\n }\n\n if (!data) {\n throw \"Argument expected: data\";\n }\n\n if (!xktModel) {\n throw \"Argument expected: xktModel\";\n }\n\n let parsedData;\n try {\n parsedData = await parse(data, PLYLoader);\n } catch (e) {\n if (log) {\n log(\"Error: \" + e);\n }\n return;\n }\n\n const attributes = parsedData.attributes;\n const hasColors = !!attributes.COLOR_0;\n\n if (hasColors) {\n const colorsValue = hasColors ? attributes.COLOR_0.value : null;\n const colorsCompressed = [];\n for (let i = 0, len = colorsValue.length; i < len; i += 4) {\n colorsCompressed.push(colorsValue[i]);\n colorsCompressed.push(colorsValue[i + 1]);\n colorsCompressed.push(colorsValue[i + 2]);\n }\n xktModel.createGeometry({\n geometryId: \"plyGeometry\",\n primitiveType: \"triangles\",\n positions: attributes.POSITION.value,\n indices: parsedData.indices ? parsedData.indices.value : [],\n colorsCompressed: colorsCompressed\n });\n } else {\n xktModel.createGeometry({\n geometryId: \"plyGeometry\",\n primitiveType: \"triangles\",\n positions: attributes.POSITION.value,\n indices: parsedData.indices ? parsedData.indices.value : []\n });\n }\n\n xktModel.createMesh({\n meshId: \"plyMesh\",\n geometryId: \"plyGeometry\",\n color: (!hasColors) ? [1, 1, 1] : null\n });\n\n xktModel.createEntity({\n entityId: \"ply\",\n meshIds: [\"plyMesh\"]\n });\n\n if (stats) {\n stats.sourceFormat = \"PLY\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 2;\n stats.numPropertySets = 0;\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numVertices = attributes.POSITION.value.length / 3;\n }\n}\n\nexport {parsePLYIntoXKTModel};\n","import {faceToVertexNormals} from \"../lib/faceToVertexNormals.js\";\nimport {math} from \"../lib/math.js\";\n\n/**\n * @desc Parses STL file data into an {@link XKTModel}.\n *\n * * Supports binary and ASCII STL formats.\n * * Option to create a separate {@link XKTEntity} for each group of faces that share the same vertex colors.\n * * Option to smooth face-aligned normals loaded from STL.\n * * Option to reduce XKT file size by ignoring STL normals and relying on xeokit to auto-generate them.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an STL model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"./models/stl/binary/spurGear.stl\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseSTLIntoXKTModel({data, xktModel});\n *\n * xktModel.finalize();\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer|String} [params.data] STL file data. Can be binary or string.\n * @param {Boolean} [params.autoNormals=false] When true, the parser will ignore the STL geometry normals, and the STL\n * data will rely on the xeokit ````Viewer```` to automatically generate them. This has the limitation that the\n * normals will be face-aligned, and therefore the ````Viewer```` will only be able to render a flat-shaded representation\n * of the STL.\n * Overrides ````smoothNormals```` when ````true````. This ignores the normals in the STL, and loads no\n * normals from the STL into the {@link XKTModel}, resulting in the XKT file storing no normals for the STL model. The\n * xeokit-sdk will then automatically generate the normals within its shaders. The disadvantages are that auto-normals\n * may slow rendering down a little bit, and that the normals can only be face-aligned (and thus rendered using flat\n * shading). The advantages, however, are a smaller XKT file size, and the ability to apply certain geometry optimizations\n * during parsing, such as removing duplicated STL vertex positions, that are not possible when normals are loaded\n * for the STL vertices.\n * @param {Boolean} [params.smoothNormals=true] When true, automatically converts face-oriented STL normals to vertex normals, for a smooth appearance. Ignored if ````autoNormals```` is ````true````.\n * @param {Number} [params.smoothNormalsAngleThreshold=20] This is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n * @param {Boolean} [params.splitMeshes=true] When true, creates a separate {@link XKTEntity} for each group of faces that share the same vertex colors. Only works with binary STL (ie. when ````data```` is an ArrayBuffer).\n * @param {XKTModel} [params.xktModel] XKTModel to parse into.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when STL has been parsed.\n */\nasync function parseSTLIntoXKTModel({\n data,\n splitMeshes,\n autoNormals,\n smoothNormals,\n smoothNormalsAngleThreshold,\n xktModel,\n stats,\n log\n }) {\n\n if (log) {\n log(\"Using parser: parseSTLIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n const rootMetaObjectId = math.createUUID();\n\n const rootMetaObject = xktModel.createMetaObject({\n metaObjectId: rootMetaObjectId,\n metaObjectType: \"Model\",\n metaObjectName: \"Model\"\n });\n\n const ctx = {\n data,\n splitMeshes,\n autoNormals,\n smoothNormals,\n smoothNormalsAngleThreshold,\n xktModel,\n rootMetaObject,\n nextId: 0,\n log: (log || function (msg) {\n }),\n stats: {\n numObjects: 0,\n numGeometries: 0,\n numTriangles: 0,\n numVertices: 0\n }\n };\n\n const binData = ensureBinary(data);\n\n if (isBinary(binData)) {\n parseBinary(ctx, binData);\n } else {\n parseASCII(ctx, ensureString(data));\n }\n\n if (stats) {\n stats.sourceFormat = \"STL\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 2;\n stats.numPropertySets = 0;\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numTriangles = ctx.stats.numTriangles;\n stats.numVertices = ctx.stats.numVertices;\n }\n\n resolve();\n });\n}\n\nfunction isBinary(data) {\n const reader = new DataView(data);\n const numFaces = reader.getUint32(80, true);\n const faceSize = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);\n const numExpectedBytes = 80 + (32 / 8) + (numFaces * faceSize);\n if (numExpectedBytes === reader.byteLength) {\n return true;\n }\n const solid = [115, 111, 108, 105, 100];\n for (let i = 0; i < 5; i++) {\n if (solid[i] !== reader.getUint8(i, false)) {\n return true;\n }\n }\n return false;\n}\n\nfunction parseBinary(ctx, data) {\n const reader = new DataView(data);\n const faces = reader.getUint32(80, true);\n let r;\n let g;\n let b;\n let hasColors = false;\n let colors;\n let defaultR;\n let defaultG;\n let defaultB;\n let lastR = null;\n let lastG = null;\n let lastB = null;\n let newMesh = false;\n let alpha;\n for (let index = 0; index < 80 - 10; index++) {\n if ((reader.getUint32(index, false) === 0x434F4C4F /*COLO*/) &&\n (reader.getUint8(index + 4) === 0x52 /*'R'*/) &&\n (reader.getUint8(index + 5) === 0x3D /*'='*/)) {\n hasColors = true;\n colors = [];\n defaultR = reader.getUint8(index + 6) / 255;\n defaultG = reader.getUint8(index + 7) / 255;\n defaultB = reader.getUint8(index + 8) / 255;\n alpha = reader.getUint8(index + 9) / 255;\n }\n }\n let dataOffset = 84;\n let faceLength = 12 * 4 + 2;\n let positions = [];\n let normals = [];\n let splitMeshes = ctx.splitMeshes;\n for (let face = 0; face < faces; face++) {\n let start = dataOffset + face * faceLength;\n let normalX = reader.getFloat32(start, true);\n let normalY = reader.getFloat32(start + 4, true);\n let normalZ = reader.getFloat32(start + 8, true);\n if (hasColors) {\n let packedColor = reader.getUint16(start + 48, true);\n if ((packedColor & 0x8000) === 0) {\n r = (packedColor & 0x1F) / 31;\n g = ((packedColor >> 5) & 0x1F) / 31;\n b = ((packedColor >> 10) & 0x1F) / 31;\n } else {\n r = defaultR;\n g = defaultG;\n b = defaultB;\n }\n if (splitMeshes && r !== lastR || g !== lastG || b !== lastB) {\n if (lastR !== null) {\n newMesh = true;\n }\n lastR = r;\n lastG = g;\n lastB = b;\n }\n }\n for (let i = 1; i <= 3; i++) {\n let vertexstart = start + i * 12;\n positions.push(reader.getFloat32(vertexstart, true));\n positions.push(reader.getFloat32(vertexstart + 4, true));\n positions.push(reader.getFloat32(vertexstart + 8, true));\n if (!ctx.autoNormals) {\n normals.push(normalX, normalY, normalZ);\n }\n if (hasColors) {\n colors.push(r, g, b, 1); // TODO: handle alpha\n }\n }\n if (splitMeshes && newMesh) {\n addMesh(ctx, positions, normals, colors);\n positions = [];\n normals = [];\n colors = colors ? [] : null;\n newMesh = false;\n }\n }\n if (positions.length > 0) {\n addMesh(ctx, positions, normals, colors);\n }\n}\n\nfunction parseASCII(ctx, data) {\n const faceRegex = /facet([\\s\\S]*?)endfacet/g;\n let faceCounter = 0;\n const floatRegex = /[\\s]+([+-]?(?:\\d+.\\d+|\\d+.|\\d+|.\\d+)(?:[eE][+-]?\\d+)?)/.source;\n const vertexRegex = new RegExp('vertex' + floatRegex + floatRegex + floatRegex, 'g');\n const normalRegex = new RegExp('normal' + floatRegex + floatRegex + floatRegex, 'g');\n const positions = [];\n const normals = [];\n const colors = null;\n let normalx;\n let normaly;\n let normalz;\n let result;\n let verticesPerFace;\n let normalsPerFace;\n let text;\n while ((result = faceRegex.exec(data)) !== null) {\n verticesPerFace = 0;\n normalsPerFace = 0;\n text = result[0];\n while ((result = normalRegex.exec(text)) !== null) {\n normalx = parseFloat(result[1]);\n normaly = parseFloat(result[2]);\n normalz = parseFloat(result[3]);\n normalsPerFace++;\n }\n while ((result = vertexRegex.exec(text)) !== null) {\n positions.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n normals.push(normalx, normaly, normalz);\n verticesPerFace++;\n }\n if (normalsPerFace !== 1) {\n ctx.log(\"Error in normal of face \" + faceCounter);\n return -1;\n }\n if (verticesPerFace !== 3) {\n ctx.log(\"Error in positions of face \" + faceCounter);\n return -1;\n }\n faceCounter++;\n }\n addMesh(ctx, positions, normals, colors);\n}\n\nlet nextGeometryId = 0;\n\nfunction addMesh(ctx, positions, normals, colors) {\n\n const indices = new Int32Array(positions.length / 3);\n for (let ni = 0, len = indices.length; ni < len; ni++) {\n indices[ni] = ni;\n }\n\n normals = normals && normals.length > 0 ? normals : null;\n colors = colors && colors.length > 0 ? colors : null;\n\n if (!ctx.autoNormals && ctx.smoothNormals) {\n faceToVertexNormals(positions, normals, {smoothNormalsAngleThreshold: ctx.smoothNormalsAngleThreshold});\n }\n\n const geometryId = \"\" + nextGeometryId++;\n const meshId = \"\" + nextGeometryId++;\n const entityId = \"\" + nextGeometryId++;\n\n ctx.xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: positions,\n normals: (!ctx.autoNormals) ? normals : null,\n colors: colors,\n indices: indices\n });\n\n ctx.xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n color: colors ? null : [1, 1, 1],\n metallic: 0.9,\n roughness: 0.1\n });\n\n ctx.xktModel.createEntity({\n entityId: entityId,\n meshIds: [meshId]\n });\n\n ctx.xktModel.createMetaObject({\n metaObjectId: entityId,\n metaObjectType: \"Default\",\n metaObjectName: \"STL Mesh\",\n parentMetaObjectId: ctx.rootMetaObject.metaObjectId\n });\n\n ctx.stats.numGeometries++;\n ctx.stats.numObjects++;\n ctx.stats.numVertices += positions.length / 3;\n ctx.stats.numTriangles += indices.length / 3;\n}\n\nfunction ensureString(buffer) {\n if (typeof buffer !== 'string') {\n return decodeText(new Uint8Array(buffer));\n }\n return buffer;\n}\n\nfunction ensureBinary(buffer) {\n if (typeof buffer === 'string') {\n const arrayBuffer = new Uint8Array(buffer.length);\n for (let i = 0; i < buffer.length; i++) {\n arrayBuffer[i] = buffer.charCodeAt(i) & 0xff; // implicitly assumes little-endian\n }\n return arrayBuffer.buffer || arrayBuffer;\n } else {\n return buffer;\n }\n}\n\nfunction decodeText(array) {\n if (typeof TextDecoder !== 'undefined') {\n return new TextDecoder().decode(array);\n }\n let s = '';\n for (let i = 0, il = array.length; i < il; i++) {\n s += String.fromCharCode(array[i]); // Implicitly assumes little-endian.\n }\n return decodeURIComponent(escape(s));\n}\n\nexport {parseSTLIntoXKTModel};\n","import {math} from \"./math.js\";\n\n/**\n * Converts surface-perpendicular face normals to vertex normals. Assumes that the mesh contains disjoint triangles\n * that don't share vertex array elements. Works by finding groups of vertices that have the same location and\n * averaging their normal vectors.\n *\n * @returns {{positions: Array, normals: *}}\n * @private\n */\nfunction faceToVertexNormals(positions, normals, options = {}) {\n const smoothNormalsAngleThreshold = options.smoothNormalsAngleThreshold || 20;\n const vertexMap = {};\n const vertexNormals = [];\n const vertexNormalAccum = {};\n let acc;\n let vx;\n let vy;\n let vz;\n let key;\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = 10 ** precisionPoints;\n let posi;\n let i;\n let j;\n let len;\n let a;\n let b;\n let c;\n\n for (i = 0, len = positions.length; i < len; i += 3) {\n\n posi = i / 3;\n\n vx = positions[i];\n vy = positions[i + 1];\n vz = positions[i + 2];\n\n key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`;\n\n if (vertexMap[key] === undefined) {\n vertexMap[key] = [posi];\n } else {\n vertexMap[key].push(posi);\n }\n\n const normal = math.normalizeVec3([normals[i], normals[i + 1], normals[i + 2]]);\n\n vertexNormals[posi] = normal;\n\n acc = math.vec4([normal[0], normal[1], normal[2], 1]);\n\n vertexNormalAccum[posi] = acc;\n }\n\n for (key in vertexMap) {\n\n if (vertexMap.hasOwnProperty(key)) {\n\n const vertices = vertexMap[key];\n const numVerts = vertices.length;\n\n for (i = 0; i < numVerts; i++) {\n\n const ii = vertices[i];\n\n acc = vertexNormalAccum[ii];\n\n for (j = 0; j < numVerts; j++) {\n\n if (i === j) {\n continue;\n }\n\n const jj = vertices[j];\n\n a = vertexNormals[ii];\n b = vertexNormals[jj];\n\n const angle = Math.abs(math.angleVec3(a, b) / math.DEGTORAD);\n\n if (angle < smoothNormalsAngleThreshold) {\n\n acc[0] += b[0];\n acc[1] += b[1];\n acc[2] += b[2];\n acc[3] += 1.0;\n }\n }\n }\n }\n }\n\n for (i = 0, len = normals.length; i < len; i += 3) {\n\n acc = vertexNormalAccum[i / 3];\n\n normals[i + 0] = acc[0] / acc[3];\n normals[i + 1] = acc[1] / acc[3];\n normals[i + 2] = acc[2] / acc[3];\n\n }\n}\n\nexport {faceToVertexNormals};","/**\n * @desc Creates box-shaped triangle mesh geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a box-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildBoxGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const box = buildBoxGeometry({\n * primitiveType: \"triangles\" // or \"lines\"\n * center: [0,0,0],\n * xSize: 1, // Half-size on each axis\n * ySize: 1,\n * zSize: 1\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"boxGeometry\",\n * primitiveType: box.primitiveType,\n * positions: box.positions,\n * normals: box.normals,\n * indices: box.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redBoxMesh\",\n * geometryId: \"boxGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redBox\",\n * meshIds: [\"redBoxMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildBoxGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.xSize=1.0] Half-size on the X-axis.\n * @param {Number} [cfg.ySize=1.0] Half-size on the Y-axis.\n * @param {Number} [cfg.zSize=1.0] Half-size on the Z-axis.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildBoxGeometry(cfg = {}) {\n\n let xSize = cfg.xSize || 1;\n if (xSize < 0) {\n console.error(\"negative xSize not allowed - will invert\");\n xSize *= -1;\n }\n\n let ySize = cfg.ySize || 1;\n if (ySize < 0) {\n console.error(\"negative ySize not allowed - will invert\");\n ySize *= -1;\n }\n\n let zSize = cfg.zSize || 1;\n if (zSize < 0) {\n console.error(\"negative zSize not allowed - will invert\");\n zSize *= -1;\n }\n\n const center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const xmin = -xSize + centerX;\n const ymin = -ySize + centerY;\n const zmin = -zSize + centerZ;\n const xmax = xSize + centerX;\n const ymax = ySize + centerY;\n const zmax = zSize + centerZ;\n\n return {\n\n primitiveType: \"triangles\",\n\n // The vertices - eight for our cube, each\n // one spanning three array elements for X,Y and Z\n\n positions: [\n\n // v0-v1-v2-v3 front\n xmax, ymax, zmax,\n xmin, ymax, zmax,\n xmin, ymin, zmax,\n xmax, ymin, zmax,\n\n // v0-v3-v4-v1 right\n xmax, ymax, zmax,\n xmax, ymin, zmax,\n xmax, ymin, zmin,\n xmax, ymax, zmin,\n\n // v0-v1-v6-v1 top\n xmax, ymax, zmax,\n xmax, ymax, zmin,\n xmin, ymax, zmin,\n xmin, ymax, zmax,\n\n // v1-v6-v7-v2 left\n xmin, ymax, zmax,\n xmin, ymax, zmin,\n xmin, ymin, zmin,\n xmin, ymin, zmax,\n\n // v7-v4-v3-v2 bottom\n xmin, ymin, zmin,\n xmax, ymin, zmin,\n xmax, ymin, zmax,\n xmin, ymin, zmax,\n\n // v4-v7-v6-v1 back\n xmax, ymin, zmin,\n xmin, ymin, zmin,\n xmin, ymax, zmin,\n xmax, ymax, zmin\n ],\n\n // Normal vectors, one for each vertex\n normals: [\n\n // v0-v1-v2-v3 front\n 0, 0, 1,\n 0, 0, 1,\n 0, 0, 1,\n 0, 0, 1,\n\n // v0-v3-v4-v5 right\n 1, 0, 0,\n 1, 0, 0,\n 1, 0, 0,\n 1, 0, 0,\n\n // v0-v5-v6-v1 top\n 0, 1, 0,\n 0, 1, 0,\n 0, 1, 0,\n 0, 1, 0,\n\n // v1-v6-v7-v2 left\n -1, 0, 0,\n -1, 0, 0,\n -1, 0, 0,\n -1, 0, 0,\n\n // v7-v4-v3-v2 bottom\n 0, -1, 0,\n 0, -1, 0,\n 0, -1, 0,\n 0, -1, 0,\n\n // v4-v7-v6-v5 back\n 0, 0, -1,\n 0, 0, -1,\n 0, 0, -1,\n 0, 0, -1\n ],\n\n // UV coords\n uv: [\n\n // v0-v1-v2-v3 front\n 1, 0,\n 0, 0,\n 0, 1,\n 1, 1,\n\n // v0-v3-v4-v1 right\n 0, 0,\n 0, 1,\n 1, 1,\n 1, 0,\n\n // v0-v1-v6-v1 top\n 1, 1,\n 1, 0,\n 0, 0,\n 0, 1,\n\n // v1-v6-v7-v2 left\n 1, 0,\n 0, 0,\n 0, 1,\n 1, 1,\n\n // v7-v4-v3-v2 bottom\n 0, 1,\n 1, 1,\n 1, 0,\n 0, 0,\n\n // v4-v7-v6-v1 back\n 0, 1,\n 1, 1,\n 1, 0,\n 0, 0\n ],\n\n // Indices - these organise the\n // positions and uv texture coordinates\n // into geometric primitives in accordance\n // with the \"primitive\" parameter,\n // in this case a set of three indices\n // for each triangle.\n //\n // Note that each triangle is specified\n // in counter-clockwise winding order.\n //\n // You can specify them in clockwise\n // order if you configure the Modes\n // node's frontFace flag as \"cw\", instead of\n // the default \"ccw\".\n indices: [\n 0, 1, 2,\n 0, 2, 3,\n // front\n 4, 5, 6,\n 4, 6, 7,\n // right\n 8, 9, 10,\n 8, 10, 11,\n // top\n 12, 13, 14,\n 12, 14, 15,\n // left\n 16, 17, 18,\n 16, 18, 19,\n // bottom\n 20, 21, 22,\n 20, 22, 23\n ]\n };\n}\n\nexport {buildBoxGeometry};\n","/**\n * @desc Creates box-shaped line segment geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a box-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildBoxLinesGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const box = buildBoxLinesGeometry({\n * center: [0,0,0],\n * xSize: 1, // Half-size on each axis\n * ySize: 1,\n * zSize: 1\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"boxGeometry\",\n * primitiveType: box.primitiveType, // \"lines\"\n * positions: box.positions,\n * normals: box.normals,\n * indices: box.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redBoxMesh\",\n * geometryId: \"boxGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redBox\",\n * meshIds: [\"redBoxMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildBoxLinesGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.xSize=1.0] Half-size on the X-axis.\n * @param {Number} [cfg.ySize=1.0] Half-size on the Y-axis.\n * @param {Number} [cfg.zSize=1.0] Half-size on the Z-axis.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildBoxLinesGeometry(cfg = {}) {\n\n let xSize = cfg.xSize || 1;\n if (xSize < 0) {\n console.error(\"negative xSize not allowed - will invert\");\n xSize *= -1;\n }\n\n let ySize = cfg.ySize || 1;\n if (ySize < 0) {\n console.error(\"negative ySize not allowed - will invert\");\n ySize *= -1;\n }\n\n let zSize = cfg.zSize || 1;\n if (zSize < 0) {\n console.error(\"negative zSize not allowed - will invert\");\n zSize *= -1;\n }\n\n const center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const xmin = -xSize + centerX;\n const ymin = -ySize + centerY;\n const zmin = -zSize + centerZ;\n const xmax = xSize + centerX;\n const ymax = ySize + centerY;\n const zmax = zSize + centerZ;\n\n return {\n primitiveType: \"lines\",\n positions: [\n xmin, ymin, zmin,\n xmin, ymin, zmax,\n xmin, ymax, zmin,\n xmin, ymax, zmax,\n xmax, ymin, zmin,\n xmax, ymin, zmax,\n xmax, ymax, zmin,\n xmax, ymax, zmax\n ],\n indices: [\n 0, 1,\n 1, 3,\n 3, 2,\n 2, 0,\n 4, 5,\n 5, 7,\n 7, 6,\n 6, 4,\n 0, 4,\n 1, 5,\n 2, 6,\n 3, 7\n ]\n }\n}\n\nexport {buildBoxLinesGeometry};\n","/**\n * @desc Creates cylinder-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a cylinder-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildCylinderGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const cylinder = buildCylinderGeometry({\n * center: [0,0,0],\n * radiusTop: 2.0,\n * radiusBottom: 2.0,\n * height: 5.0,\n * radialSegments: 20,\n * heightSegments: 1,\n * openEnded: false\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"cylinderGeometry\",\n * primitiveType: cylinder.primitiveType,\n * positions: cylinder.positions,\n * normals: cylinder.normals,\n * indices: cylinder.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redCylinderMesh\",\n * geometryId: \"cylinderGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redCylinder\",\n * meshIds: [\"redCylinderMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildCylinderGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.radiusTop=1] Radius of top.\n * @param {Number} [cfg.radiusBottom=1] Radius of bottom.\n * @param {Number} [cfg.height=1] Height.\n * @param {Number} [cfg.radialSegments=60] Number of horizontal segments.\n * @param {Number} [cfg.heightSegments=1] Number of vertical segments.\n * @param {Boolean} [cfg.openEnded=false] Whether or not the cylinder has solid caps on the ends.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildCylinderGeometry(cfg = {}) {\n\n let radiusTop = cfg.radiusTop || 1;\n if (radiusTop < 0) {\n console.error(\"negative radiusTop not allowed - will invert\");\n radiusTop *= -1;\n }\n\n let radiusBottom = cfg.radiusBottom || 1;\n if (radiusBottom < 0) {\n console.error(\"negative radiusBottom not allowed - will invert\");\n radiusBottom *= -1;\n }\n\n let height = cfg.height || 1;\n if (height < 0) {\n console.error(\"negative height not allowed - will invert\");\n height *= -1;\n }\n\n let radialSegments = cfg.radialSegments || 32;\n if (radialSegments < 0) {\n console.error(\"negative radialSegments not allowed - will invert\");\n radialSegments *= -1;\n }\n if (radialSegments < 3) {\n radialSegments = 3;\n }\n\n let heightSegments = cfg.heightSegments || 1;\n if (heightSegments < 0) {\n console.error(\"negative heightSegments not allowed - will invert\");\n heightSegments *= -1;\n }\n if (heightSegments < 1) {\n heightSegments = 1;\n }\n\n const openEnded = !!cfg.openEnded;\n\n let center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const heightHalf = height / 2;\n const heightLength = height / heightSegments;\n const radialAngle = (2.0 * Math.PI / radialSegments);\n const radialLength = 1.0 / radialSegments;\n //var nextRadius = this._radiusBottom;\n const radiusChange = (radiusTop - radiusBottom) / heightSegments;\n\n const positions = [];\n const normals = [];\n const uvs = [];\n const indices = [];\n\n let h;\n let i;\n\n let x;\n let z;\n\n let currentRadius;\n let currentHeight;\n\n let first;\n let second;\n\n let startIndex;\n let tu;\n let tv;\n\n // create vertices\n const normalY = (90.0 - (Math.atan(height / (radiusBottom - radiusTop))) * 180 / Math.PI) / 90.0;\n\n for (h = 0; h <= heightSegments; h++) {\n currentRadius = radiusTop - h * radiusChange;\n currentHeight = heightHalf - h * heightLength;\n\n for (i = 0; i <= radialSegments; i++) {\n x = Math.sin(i * radialAngle);\n z = Math.cos(i * radialAngle);\n\n normals.push(currentRadius * x);\n normals.push(normalY); //todo\n normals.push(currentRadius * z);\n\n uvs.push((i * radialLength));\n uvs.push(h * 1 / heightSegments);\n\n positions.push((currentRadius * x) + centerX);\n positions.push((currentHeight) + centerY);\n positions.push((currentRadius * z) + centerZ);\n }\n }\n\n // create faces\n for (h = 0; h < heightSegments; h++) {\n for (i = 0; i <= radialSegments; i++) {\n\n first = h * (radialSegments + 1) + i;\n second = first + radialSegments;\n\n indices.push(first);\n indices.push(second);\n indices.push(second + 1);\n\n indices.push(first);\n indices.push(second + 1);\n indices.push(first + 1);\n }\n }\n\n // create top cap\n if (!openEnded && radiusTop > 0) {\n startIndex = (positions.length / 3);\n\n // top center\n normals.push(0.0);\n normals.push(1.0);\n normals.push(0.0);\n\n uvs.push(0.5);\n uvs.push(0.5);\n\n positions.push(0 + centerX);\n positions.push(heightHalf + centerY);\n positions.push(0 + centerZ);\n\n // top triangle fan\n for (i = 0; i <= radialSegments; i++) {\n x = Math.sin(i * radialAngle);\n z = Math.cos(i * radialAngle);\n tu = (0.5 * Math.sin(i * radialAngle)) + 0.5;\n tv = (0.5 * Math.cos(i * radialAngle)) + 0.5;\n\n normals.push(radiusTop * x);\n normals.push(1.0);\n normals.push(radiusTop * z);\n\n uvs.push(tu);\n uvs.push(tv);\n\n positions.push((radiusTop * x) + centerX);\n positions.push((heightHalf) + centerY);\n positions.push((radiusTop * z) + centerZ);\n }\n\n for (i = 0; i < radialSegments; i++) {\n center = startIndex;\n first = startIndex + 1 + i;\n\n indices.push(first);\n indices.push(first + 1);\n indices.push(center);\n }\n }\n\n // create bottom cap\n if (!openEnded && radiusBottom > 0) {\n\n startIndex = (positions.length / 3);\n\n // top center\n normals.push(0.0);\n normals.push(-1.0);\n normals.push(0.0);\n\n uvs.push(0.5);\n uvs.push(0.5);\n\n positions.push(0 + centerX);\n positions.push(0 - heightHalf + centerY);\n positions.push(0 + centerZ);\n\n // top triangle fan\n for (i = 0; i <= radialSegments; i++) {\n\n x = Math.sin(i * radialAngle);\n z = Math.cos(i * radialAngle);\n\n tu = (0.5 * Math.sin(i * radialAngle)) + 0.5;\n tv = (0.5 * Math.cos(i * radialAngle)) + 0.5;\n\n normals.push(radiusBottom * x);\n normals.push(-1.0);\n normals.push(radiusBottom * z);\n\n uvs.push(tu);\n uvs.push(tv);\n\n positions.push((radiusBottom * x) + centerX);\n positions.push((0 - heightHalf) + centerY);\n positions.push((radiusBottom * z) + centerZ);\n }\n\n for (i = 0; i < radialSegments; i++) {\n\n center = startIndex;\n first = startIndex + 1 + i;\n\n indices.push(center);\n indices.push(first + 1);\n indices.push(first);\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\n\nexport {buildCylinderGeometry};\n","/**\n * @desc Creates grid-shaped geometry arrays..\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a grid-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildGridGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const grid = buildGridGeometry({\n * size: 1000,\n * divisions: 500\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"gridGeometry\",\n * primitiveType: grid.primitiveType, // Will be \"lines\"\n * positions: grid.positions,\n * indices: grid.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redGridMesh\",\n * geometryId: \"gridGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redGrid\",\n * meshIds: [\"redGridMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildGridGeometry\n * @param {*} [cfg] Configs\n * @param {Number} [cfg.size=1] Dimension on the X and Z-axis.\n * @param {Number} [cfg.divisions=1] Number of divisions on X and Z axis..\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildGridGeometry(cfg = {}) {\n\n let size = cfg.size || 1;\n if (size < 0) {\n console.error(\"negative size not allowed - will invert\");\n size *= -1;\n }\n\n let divisions = cfg.divisions || 1;\n if (divisions < 0) {\n console.error(\"negative divisions not allowed - will invert\");\n divisions *= -1;\n }\n if (divisions < 1) {\n divisions = 1;\n }\n\n size = size || 10;\n divisions = divisions || 10;\n\n const step = size / divisions;\n const halfSize = size / 2;\n\n const positions = [];\n const indices = [];\n let l = 0;\n\n for (let i = 0, j = 0, k = -halfSize; i <= divisions; i++, k += step) {\n\n positions.push(-halfSize);\n positions.push(0);\n positions.push(k);\n\n positions.push(halfSize);\n positions.push(0);\n positions.push(k);\n\n positions.push(k);\n positions.push(0);\n positions.push(-halfSize);\n\n positions.push(k);\n positions.push(0);\n positions.push(halfSize);\n\n indices.push(l++);\n indices.push(l++);\n indices.push(l++);\n indices.push(l++);\n }\n\n return {\n primitiveType: \"lines\",\n positions: positions,\n indices: indices\n };\n}\n\n\nexport {buildGridGeometry};\n","/**\n * @desc Creates plane-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a plane-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildPlaneGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const plane = buildPlaneGeometry({\n * center: [0,0,0],\n * xSize: 2,\n * zSize: 2,\n * xSegments: 10,\n * zSegments: 10\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"planeGeometry\",\n * primitiveType: plane.primitiveType, // Will be \"triangles\"\n * positions: plane.positions,\n * normals: plane.normals,\n * indices: plane.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redPlaneMesh\",\n * geometryId: \"planeGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redPlane\",\n * meshIds: [\"redPlaneMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildPlaneGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.xSize=1] Dimension on the X-axis.\n * @param {Number} [cfg.zSize=1] Dimension on the Z-axis.\n * @param {Number} [cfg.xSegments=1] Number of segments on the X-axis.\n * @param {Number} [cfg.zSegments=1] Number of segments on the Z-axis.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildPlaneGeometry(cfg = {}) {\n\n let xSize = cfg.xSize || 1;\n if (xSize < 0) {\n console.error(\"negative xSize not allowed - will invert\");\n xSize *= -1;\n }\n\n let zSize = cfg.zSize || 1;\n if (zSize < 0) {\n console.error(\"negative zSize not allowed - will invert\");\n zSize *= -1;\n }\n\n let xSegments = cfg.xSegments || 1;\n if (xSegments < 0) {\n console.error(\"negative xSegments not allowed - will invert\");\n xSegments *= -1;\n }\n if (xSegments < 1) {\n xSegments = 1;\n }\n\n let zSegments = cfg.xSegments || 1;\n if (zSegments < 0) {\n console.error(\"negative zSegments not allowed - will invert\");\n zSegments *= -1;\n }\n if (zSegments < 1) {\n zSegments = 1;\n }\n\n const center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const halfWidth = xSize / 2;\n const halfHeight = zSize / 2;\n\n const planeX = Math.floor(xSegments) || 1;\n const planeZ = Math.floor(zSegments) || 1;\n\n const planeX1 = planeX + 1;\n const planeZ1 = planeZ + 1;\n\n const segmentWidth = xSize / planeX;\n const segmentHeight = zSize / planeZ;\n\n const positions = new Float32Array(planeX1 * planeZ1 * 3);\n const normals = new Float32Array(planeX1 * planeZ1 * 3);\n const uvs = new Float32Array(planeX1 * planeZ1 * 2);\n\n let offset = 0;\n let offset2 = 0;\n\n let iz;\n let ix;\n let x;\n let a;\n let b;\n let c;\n let d;\n\n for (iz = 0; iz < planeZ1; iz++) {\n\n const z = iz * segmentHeight - halfHeight;\n\n for (ix = 0; ix < planeX1; ix++) {\n\n x = ix * segmentWidth - halfWidth;\n\n positions[offset] = x + centerX;\n positions[offset + 1] = centerY;\n positions[offset + 2] = -z + centerZ;\n\n normals[offset + 2] = -1;\n\n uvs[offset2] = (ix) / planeX;\n uvs[offset2 + 1] = ((planeZ - iz) / planeZ);\n\n offset += 3;\n offset2 += 2;\n }\n }\n\n offset = 0;\n\n const indices = new ((positions.length / 3) > 65535 ? Uint32Array : Uint16Array)(planeX * planeZ * 6);\n\n for (iz = 0; iz < planeZ; iz++) {\n\n for (ix = 0; ix < planeX; ix++) {\n\n a = ix + planeX1 * iz;\n b = ix + planeX1 * (iz + 1);\n c = (ix + 1) + planeX1 * (iz + 1);\n d = (ix + 1) + planeX1 * iz;\n\n indices[offset] = d;\n indices[offset + 1] = b;\n indices[offset + 2] = a;\n\n indices[offset + 3] = d;\n indices[offset + 4] = c;\n indices[offset + 5] = b;\n\n offset += 6;\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\nexport {buildPlaneGeometry};\n","/**\n * @desc Creates sphere-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a sphere-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildSphereGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const sphere = buildSphereGeometry({\n * center: [0,0,0],\n * radius: 1.5,\n * heightSegments: 60,\n * widthSegments: 60\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"sphereGeometry\",\n * primitiveType: sphere.primitiveType, // Will be \"triangles\"\n * positions: sphere.positions,\n * normals: sphere.normals,\n * indices: sphere.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redSphereMesh\",\n * geometryId: \"sphereGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n *const xktEntity = xktModel.createEntity({\n * entityId: \"redSphere\",\n * meshIds: [\"redSphereMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildSphereGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.radius=1] Radius.\n * @param {Number} [cfg.heightSegments=24] Number of latitudinal bands.\n * @param {Number} [cfg.widthSegments=18] Number of longitudinal bands.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildSphereGeometry(cfg = {}) {\n\n const lod = cfg.lod || 1;\n\n const centerX = cfg.center ? cfg.center[0] : 0;\n const centerY = cfg.center ? cfg.center[1] : 0;\n const centerZ = cfg.center ? cfg.center[2] : 0;\n\n let radius = cfg.radius || 1;\n if (radius < 0) {\n console.error(\"negative radius not allowed - will invert\");\n radius *= -1;\n }\n\n let heightSegments = cfg.heightSegments || 18;\n if (heightSegments < 0) {\n console.error(\"negative heightSegments not allowed - will invert\");\n heightSegments *= -1;\n }\n heightSegments = Math.floor(lod * heightSegments);\n if (heightSegments < 18) {\n heightSegments = 18;\n }\n\n let widthSegments = cfg.widthSegments || 18;\n if (widthSegments < 0) {\n console.error(\"negative widthSegments not allowed - will invert\");\n widthSegments *= -1;\n }\n widthSegments = Math.floor(lod * widthSegments);\n if (widthSegments < 18) {\n widthSegments = 18;\n }\n\n const positions = [];\n const normals = [];\n const uvs = [];\n const indices = [];\n\n let i;\n let j;\n\n let theta;\n let sinTheta;\n let cosTheta;\n\n let phi;\n let sinPhi;\n let cosPhi;\n\n let x;\n let y;\n let z;\n\n let u;\n let v;\n\n let first;\n let second;\n\n for (i = 0; i <= heightSegments; i++) {\n\n theta = i * Math.PI / heightSegments;\n sinTheta = Math.sin(theta);\n cosTheta = Math.cos(theta);\n\n for (j = 0; j <= widthSegments; j++) {\n\n phi = j * 2 * Math.PI / widthSegments;\n sinPhi = Math.sin(phi);\n cosPhi = Math.cos(phi);\n\n x = cosPhi * sinTheta;\n y = cosTheta;\n z = sinPhi * sinTheta;\n u = 1.0 - j / widthSegments;\n v = i / heightSegments;\n\n normals.push(x);\n normals.push(y);\n normals.push(z);\n\n uvs.push(u);\n uvs.push(v);\n\n positions.push(centerX + radius * x);\n positions.push(centerY + radius * y);\n positions.push(centerZ + radius * z);\n }\n }\n\n for (i = 0; i < heightSegments; i++) {\n for (j = 0; j < widthSegments; j++) {\n\n first = (i * (widthSegments + 1)) + j;\n second = first + widthSegments + 1;\n\n indices.push(first + 1);\n indices.push(second + 1);\n indices.push(second);\n indices.push(first + 1);\n indices.push(second);\n indices.push(first);\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\nexport {buildSphereGeometry};\n","import {math} from '../lib/math.js';\n\n/**\n * @desc Creates torus-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a torus-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildTorusGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const torus = buildTorusGeometry({\n * center: [0,0,0],\n * radius: 1.0,\n * tube: 0.5,\n * radialSegments: 32,\n * tubeSegments: 24,\n * arc: Math.PI * 2.0\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"torusGeometry\",\n * primitiveType: torus.primitiveType, // Will be \"triangles\"\n * positions: torus.positions,\n * normals: torus.normals,\n * indices: torus.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redTorusMesh\",\n * geometryId: \"torusGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redTorus\",\n * meshIds: [\"redTorusMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildTorusGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.radius=1] The overall radius.\n * @param {Number} [cfg.tube=0.3] The tube radius.\n * @param {Number} [cfg.radialSegments=32] The number of radial segments.\n * @param {Number} [cfg.tubeSegments=24] The number of tubular segments.\n * @param {Number} [cfg.arc=Math.PI*0.5] The length of the arc in radians, where Math.PI*2 is a closed torus.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildTorusGeometry(cfg = {}) {\n\n let radius = cfg.radius || 1;\n if (radius < 0) {\n console.error(\"negative radius not allowed - will invert\");\n radius *= -1;\n }\n radius *= 0.5;\n\n let tube = cfg.tube || 0.3;\n if (tube < 0) {\n console.error(\"negative tube not allowed - will invert\");\n tube *= -1;\n }\n\n let radialSegments = cfg.radialSegments || 32;\n if (radialSegments < 0) {\n console.error(\"negative radialSegments not allowed - will invert\");\n radialSegments *= -1;\n }\n if (radialSegments < 4) {\n radialSegments = 4;\n }\n\n let tubeSegments = cfg.tubeSegments || 24;\n if (tubeSegments < 0) {\n console.error(\"negative tubeSegments not allowed - will invert\");\n tubeSegments *= -1;\n }\n if (tubeSegments < 4) {\n tubeSegments = 4;\n }\n\n let arc = cfg.arc || Math.PI * 2;\n if (arc < 0) {\n console.warn(\"negative arc not allowed - will invert\");\n arc *= -1;\n }\n if (arc > 360) {\n arc = 360;\n }\n\n const center = cfg.center;\n let centerX = center ? center[0] : 0;\n let centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const positions = [];\n const normals = [];\n const uvs = [];\n const indices = [];\n\n let u;\n let v;\n let x;\n let y;\n let z;\n let vec;\n\n let i;\n let j;\n\n for (j = 0; j <= tubeSegments; j++) {\n for (i = 0; i <= radialSegments; i++) {\n\n u = i / radialSegments * arc;\n v = 0.785398 + (j / tubeSegments * Math.PI * 2);\n\n centerX = radius * Math.cos(u);\n centerY = radius * Math.sin(u);\n\n x = (radius + tube * Math.cos(v)) * Math.cos(u);\n y = (radius + tube * Math.cos(v)) * Math.sin(u);\n z = tube * Math.sin(v);\n\n positions.push(x + centerX);\n positions.push(y + centerY);\n positions.push(z + centerZ);\n\n uvs.push(1 - (i / radialSegments));\n uvs.push((j / tubeSegments));\n\n vec = math.normalizeVec3(math.subVec3([x, y, z], [centerX, centerY, centerZ], []), []);\n\n normals.push(vec[0]);\n normals.push(vec[1]);\n normals.push(vec[2]);\n }\n }\n\n let a;\n let b;\n let c;\n let d;\n\n for (j = 1; j <= tubeSegments; j++) {\n for (i = 1; i <= radialSegments; i++) {\n\n a = (radialSegments + 1) * j + i - 1;\n b = (radialSegments + 1) * (j - 1) + i - 1;\n c = (radialSegments + 1) * (j - 1) + i;\n d = (radialSegments + 1) * j + i;\n\n indices.push(a);\n indices.push(b);\n indices.push(c);\n\n indices.push(c);\n indices.push(d);\n indices.push(a);\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\nexport {buildTorusGeometry};\n","const letters = {\n ' ': {width: 16, points: []},\n '!': {\n width: 10, points: [\n [5, 21],\n [5, 7],\n [-1, -1],\n [5, 2],\n [4, 1],\n [5, 0],\n [6, 1],\n [5, 2]\n ]\n },\n '\"': {\n width: 16, points: [\n [4, 21],\n [4, 14],\n [-1, -1],\n [12, 21],\n [12, 14]\n ]\n },\n '#': {\n width: 21, points: [\n [11, 25],\n [4, -7],\n [-1, -1],\n [17, 25],\n [10, -7],\n [-1, -1],\n [4, 12],\n [18, 12],\n [-1, -1],\n [3, 6],\n [17, 6]\n ]\n },\n '$': {\n width: 20, points: [\n [8, 25],\n [8, -4],\n [-1, -1],\n [12, 25],\n [12, -4],\n [-1, -1],\n [17, 18],\n [15, 20],\n [12, 21],\n [8, 21],\n [5, 20],\n [3, 18],\n [3, 16],\n [4, 14],\n [5, 13],\n [7, 12],\n [13, 10],\n [15, 9],\n [16, 8],\n [17, 6],\n [17, 3],\n [15, 1],\n [12, 0],\n [8, 0],\n [5, 1],\n [3, 3]\n ]\n },\n '%': {\n width: 24, points: [\n [21, 21],\n [3, 0],\n [-1, -1],\n [8, 21],\n [10, 19],\n [10, 17],\n [9, 15],\n [7, 14],\n [5, 14],\n [3, 16],\n [3, 18],\n [4, 20],\n [6, 21],\n [8, 21],\n [10, 20],\n [13, 19],\n [16, 19],\n [19, 20],\n [21, 21],\n [-1, -1],\n [17, 7],\n [15, 6],\n [14, 4],\n [14, 2],\n [16, 0],\n [18, 0],\n [20, 1],\n [21, 3],\n [21, 5],\n [19, 7],\n [17, 7]\n ]\n },\n '&': {\n width: 26, points: [\n [23, 12],\n [23, 13],\n [22, 14],\n [21, 14],\n [20, 13],\n [19, 11],\n [17, 6],\n [15, 3],\n [13, 1],\n [11, 0],\n [7, 0],\n [5, 1],\n [4, 2],\n [3, 4],\n [3, 6],\n [4, 8],\n [5, 9],\n [12, 13],\n [13, 14],\n [14, 16],\n [14, 18],\n [13, 20],\n [11, 21],\n [9, 20],\n [8, 18],\n [8, 16],\n [9, 13],\n [11, 10],\n [16, 3],\n [18, 1],\n [20, 0],\n [22, 0],\n [23, 1],\n [23, 2]\n ]\n },\n '\\'': {\n width: 10, points: [\n [5, 19],\n [4, 20],\n [5, 21],\n [6, 20],\n [6, 18],\n [5, 16],\n [4, 15]\n ]\n },\n '(': {\n width: 14, points: [\n [11, 25],\n [9, 23],\n [7, 20],\n [5, 16],\n [4, 11],\n [4, 7],\n [5, 2],\n [7, -2],\n [9, -5],\n [11, -7]\n ]\n },\n ')': {\n width: 14, points: [\n [3, 25],\n [5, 23],\n [7, 20],\n [9, 16],\n [10, 11],\n [10, 7],\n [9, 2],\n [7, -2],\n [5, -5],\n [3, -7]\n ]\n },\n '*': {\n width: 16, points: [\n [8, 21],\n [8, 9],\n [-1, -1],\n [3, 18],\n [13, 12],\n [-1, -1],\n [13, 18],\n [3, 12]\n ]\n },\n '+': {\n width: 26, points: [\n [13, 18],\n [13, 0],\n [-1, -1],\n [4, 9],\n [22, 9]\n ]\n },\n ',': {\n width: 10, points: [\n [6, 1],\n [5, 0],\n [4, 1],\n [5, 2],\n [6, 1],\n [6, -1],\n [5, -3],\n [4, -4]\n ]\n },\n '-': {\n width: 26, points: [\n [4, 9],\n [22, 9]\n ]\n },\n '.': {\n width: 10, points: [\n [5, 2],\n [4, 1],\n [5, 0],\n [6, 1],\n [5, 2]\n ]\n },\n '/': {\n width: 22, points: [\n [20, 25],\n [2, -7]\n ]\n },\n '0': {\n width: 20, points: [\n [9, 21],\n [6, 20],\n [4, 17],\n [3, 12],\n [3, 9],\n [4, 4],\n [6, 1],\n [9, 0],\n [11, 0],\n [14, 1],\n [16, 4],\n [17, 9],\n [17, 12],\n [16, 17],\n [14, 20],\n [11, 21],\n [9, 21]\n ]\n },\n '1': {\n width: 20, points: [\n [6, 17],\n [8, 18],\n [11, 21],\n [11, 0]\n ]\n },\n '2': {\n width: 20, points: [\n [4, 16],\n [4, 17],\n [5, 19],\n [6, 20],\n [8, 21],\n [12, 21],\n [14, 20],\n [15, 19],\n [16, 17],\n [16, 15],\n [15, 13],\n [13, 10],\n [3, 0],\n [17, 0]\n ]\n },\n '3': {\n width: 20, points: [\n [5, 21],\n [16, 21],\n [10, 13],\n [13, 13],\n [15, 12],\n [16, 11],\n [17, 8],\n [17, 6],\n [16, 3],\n [14, 1],\n [11, 0],\n [8, 0],\n [5, 1],\n [4, 2],\n [3, 4]\n ]\n },\n '4': {\n width: 20, points: [\n [13, 21],\n [3, 7],\n [18, 7],\n [-1, -1],\n [13, 21],\n [13, 0]\n ]\n },\n '5': {\n width: 20, points: [\n [15, 21],\n [5, 21],\n [4, 12],\n [5, 13],\n [8, 14],\n [11, 14],\n [14, 13],\n [16, 11],\n [17, 8],\n [17, 6],\n [16, 3],\n [14, 1],\n [11, 0],\n [8, 0],\n [5, 1],\n [4, 2],\n [3, 4]\n ]\n },\n '6': {\n width: 20, points: [\n [16, 18],\n [15, 20],\n [12, 21],\n [10, 21],\n [7, 20],\n [5, 17],\n [4, 12],\n [4, 7],\n [5, 3],\n [7, 1],\n [10, 0],\n [11, 0],\n [14, 1],\n [16, 3],\n [17, 6],\n [17, 7],\n [16, 10],\n [14, 12],\n [11, 13],\n [10, 13],\n [7, 12],\n [5, 10],\n [4, 7]\n ]\n },\n '7': {\n width: 20, points: [\n [17, 21],\n [7, 0],\n [-1, -1],\n [3, 21],\n [17, 21]\n ]\n },\n '8': {\n width: 20, points: [\n [8, 21],\n [5, 20],\n [4, 18],\n [4, 16],\n [5, 14],\n [7, 13],\n [11, 12],\n [14, 11],\n [16, 9],\n [17, 7],\n [17, 4],\n [16, 2],\n [15, 1],\n [12, 0],\n [8, 0],\n [5, 1],\n [4, 2],\n [3, 4],\n [3, 7],\n [4, 9],\n [6, 11],\n [9, 12],\n [13, 13],\n [15, 14],\n [16, 16],\n [16, 18],\n [15, 20],\n [12, 21],\n [8, 21]\n ]\n },\n '9': {\n width: 20, points: [\n [16, 14],\n [15, 11],\n [13, 9],\n [10, 8],\n [9, 8],\n [6, 9],\n [4, 11],\n [3, 14],\n [3, 15],\n [4, 18],\n [6, 20],\n [9, 21],\n [10, 21],\n [13, 20],\n [15, 18],\n [16, 14],\n [16, 9],\n [15, 4],\n [13, 1],\n [10, 0],\n [8, 0],\n [5, 1],\n [4, 3]\n ]\n },\n ':': {\n width: 10, points: [\n [5, 14],\n [4, 13],\n [5, 12],\n [6, 13],\n [5, 14],\n [-1, -1],\n [5, 2],\n [4, 1],\n [5, 0],\n [6, 1],\n [5, 2]\n ]\n },\n ';': {\n width: 10, points: [\n [5, 14],\n [4, 13],\n [5, 12],\n [6, 13],\n [5, 14],\n [-1, -1],\n [6, 1],\n [5, 0],\n [4, 1],\n [5, 2],\n [6, 1],\n [6, -1],\n [5, -3],\n [4, -4]\n ]\n },\n '<': {\n width: 24, points: [\n [20, 18],\n [4, 9],\n [20, 0]\n ]\n },\n '=': {\n width: 26, points: [\n [4, 12],\n [22, 12],\n [-1, -1],\n [4, 6],\n [22, 6]\n ]\n },\n '>': {\n width: 24, points: [\n [4, 18],\n [20, 9],\n [4, 0]\n ]\n },\n '?': {\n width: 18, points: [\n [3, 16],\n [3, 17],\n [4, 19],\n [5, 20],\n [7, 21],\n [11, 21],\n [13, 20],\n [14, 19],\n [15, 17],\n [15, 15],\n [14, 13],\n [13, 12],\n [9, 10],\n [9, 7],\n [-1, -1],\n [9, 2],\n [8, 1],\n [9, 0],\n [10, 1],\n [9, 2]\n ]\n },\n '@': {\n width: 27, points: [\n [18, 13],\n [17, 15],\n [15, 16],\n [12, 16],\n [10, 15],\n [9, 14],\n [8, 11],\n [8, 8],\n [9, 6],\n [11, 5],\n [14, 5],\n [16, 6],\n [17, 8],\n [-1, -1],\n [12, 16],\n [10, 14],\n [9, 11],\n [9, 8],\n [10, 6],\n [11, 5],\n [-1, -1],\n [18, 16],\n [17, 8],\n [17, 6],\n [19, 5],\n [21, 5],\n [23, 7],\n [24, 10],\n [24, 12],\n [23, 15],\n [22, 17],\n [20, 19],\n [18, 20],\n [15, 21],\n [12, 21],\n [9, 20],\n [7, 19],\n [5, 17],\n [4, 15],\n [3, 12],\n [3, 9],\n [4, 6],\n [5, 4],\n [7, 2],\n [9, 1],\n [12, 0],\n [15, 0],\n [18, 1],\n [20, 2],\n [21, 3],\n [-1, -1],\n [19, 16],\n [18, 8],\n [18, 6],\n [19, 5]\n ]\n },\n 'A': {\n width: 18, points: [\n [9, 21],\n [1, 0],\n [-1, -1],\n [9, 21],\n [17, 0],\n [-1, -1],\n [4, 7],\n [14, 7]\n ]\n },\n 'B': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [13, 21],\n [16, 20],\n [17, 19],\n [18, 17],\n [18, 15],\n [17, 13],\n [16, 12],\n [13, 11],\n [-1, -1],\n [4, 11],\n [13, 11],\n [16, 10],\n [17, 9],\n [18, 7],\n [18, 4],\n [17, 2],\n [16, 1],\n [13, 0],\n [4, 0]\n ]\n },\n 'C': {\n width: 21, points: [\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5]\n ]\n },\n 'D': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [11, 21],\n [14, 20],\n [16, 18],\n [17, 16],\n [18, 13],\n [18, 8],\n [17, 5],\n [16, 3],\n [14, 1],\n [11, 0],\n [4, 0]\n ]\n },\n 'E': {\n width: 19, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [17, 21],\n [-1, -1],\n [4, 11],\n [12, 11],\n [-1, -1],\n [4, 0],\n [17, 0]\n ]\n },\n 'F': {\n width: 18, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [17, 21],\n [-1, -1],\n [4, 11],\n [12, 11]\n ]\n },\n 'G': {\n width: 21, points: [\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5],\n [18, 8],\n [-1, -1],\n [13, 8],\n [18, 8]\n ]\n },\n 'H': {\n width: 22, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [18, 21],\n [18, 0],\n [-1, -1],\n [4, 11],\n [18, 11]\n ]\n },\n 'I': {\n width: 8, points: [\n [4, 21],\n [4, 0]\n ]\n },\n 'J': {\n width: 16, points: [\n [12, 21],\n [12, 5],\n [11, 2],\n [10, 1],\n [8, 0],\n [6, 0],\n [4, 1],\n [3, 2],\n [2, 5],\n [2, 7]\n ]\n },\n 'K': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [18, 21],\n [4, 7],\n [-1, -1],\n [9, 12],\n [18, 0]\n ]\n },\n 'L': {\n width: 17, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 0],\n [16, 0]\n ]\n },\n 'M': {\n width: 24, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [12, 0],\n [-1, -1],\n [20, 21],\n [12, 0],\n [-1, -1],\n [20, 21],\n [20, 0]\n ]\n },\n 'N': {\n width: 22, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [18, 0],\n [-1, -1],\n [18, 21],\n [18, 0]\n ]\n },\n 'O': {\n width: 22, points: [\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5],\n [19, 8],\n [19, 13],\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21]\n ]\n },\n 'P': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [13, 21],\n [16, 20],\n [17, 19],\n [18, 17],\n [18, 14],\n [17, 12],\n [16, 11],\n [13, 10],\n [4, 10]\n ]\n },\n 'Q': {\n width: 22, points: [\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5],\n [19, 8],\n [19, 13],\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21],\n [-1, -1],\n [12, 4],\n [18, -2]\n ]\n },\n 'R': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [13, 21],\n [16, 20],\n [17, 19],\n [18, 17],\n [18, 15],\n [17, 13],\n [16, 12],\n [13, 11],\n [4, 11],\n [-1, -1],\n [11, 11],\n [18, 0]\n ]\n },\n 'S': {\n width: 20, points: [\n [17, 18],\n [15, 20],\n [12, 21],\n [8, 21],\n [5, 20],\n [3, 18],\n [3, 16],\n [4, 14],\n [5, 13],\n [7, 12],\n [13, 10],\n [15, 9],\n [16, 8],\n [17, 6],\n [17, 3],\n [15, 1],\n [12, 0],\n [8, 0],\n [5, 1],\n [3, 3]\n ]\n },\n 'T': {\n width: 16, points: [\n [8, 21],\n [8, 0],\n [-1, -1],\n [1, 21],\n [15, 21]\n ]\n },\n 'U': {\n width: 22, points: [\n [4, 21],\n [4, 6],\n [5, 3],\n [7, 1],\n [10, 0],\n [12, 0],\n [15, 1],\n [17, 3],\n [18, 6],\n [18, 21]\n ]\n },\n 'V': {\n width: 18, points: [\n [1, 21],\n [9, 0],\n [-1, -1],\n [17, 21],\n [9, 0]\n ]\n },\n 'W': {\n width: 24, points: [\n [2, 21],\n [7, 0],\n [-1, -1],\n [12, 21],\n [7, 0],\n [-1, -1],\n [12, 21],\n [17, 0],\n [-1, -1],\n [22, 21],\n [17, 0]\n ]\n },\n 'X': {\n width: 20, points: [\n [3, 21],\n [17, 0],\n [-1, -1],\n [17, 21],\n [3, 0]\n ]\n },\n 'Y': {\n width: 18, points: [\n [1, 21],\n [9, 11],\n [9, 0],\n [-1, -1],\n [17, 21],\n [9, 11]\n ]\n },\n 'Z': {\n width: 20, points: [\n [17, 21],\n [3, 0],\n [-1, -1],\n [3, 21],\n [17, 21],\n [-1, -1],\n [3, 0],\n [17, 0]\n ]\n },\n '[': {\n width: 14, points: [\n [4, 25],\n [4, -7],\n [-1, -1],\n [5, 25],\n [5, -7],\n [-1, -1],\n [4, 25],\n [11, 25],\n [-1, -1],\n [4, -7],\n [11, -7]\n ]\n },\n '\\\\': {\n width: 14, points: [\n [0, 21],\n [14, -3]\n ]\n },\n ']': {\n width: 14, points: [\n [9, 25],\n [9, -7],\n [-1, -1],\n [10, 25],\n [10, -7],\n [-1, -1],\n [3, 25],\n [10, 25],\n [-1, -1],\n [3, -7],\n [10, -7]\n ]\n },\n '^': {\n width: 16, points: [\n [6, 15],\n [8, 18],\n [10, 15],\n [-1, -1],\n [3, 12],\n [8, 17],\n [13, 12],\n [-1, -1],\n [8, 17],\n [8, 0]\n ]\n },\n '_': {\n width: 16, points: [\n [0, -2],\n [16, -2]\n ]\n },\n '`': {\n width: 10, points: [\n [6, 21],\n [5, 20],\n [4, 18],\n [4, 16],\n [5, 15],\n [6, 16],\n [5, 17]\n ]\n },\n 'a': {\n width: 19, points: [\n [15, 14],\n [15, 0],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'b': {\n width: 19, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 11],\n [6, 13],\n [8, 14],\n [11, 14],\n [13, 13],\n [15, 11],\n [16, 8],\n [16, 6],\n [15, 3],\n [13, 1],\n [11, 0],\n [8, 0],\n [6, 1],\n [4, 3]\n ]\n },\n 'c': {\n width: 18, points: [\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'd': {\n width: 19, points: [\n [15, 21],\n [15, 0],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'e': {\n width: 18, points: [\n [3, 8],\n [15, 8],\n [15, 10],\n [14, 12],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'f': {\n width: 12, points: [\n [10, 21],\n [8, 21],\n [6, 20],\n [5, 17],\n [5, 0],\n [-1, -1],\n [2, 14],\n [9, 14]\n ]\n },\n 'g': {\n width: 19, points: [\n [15, 14],\n [15, -2],\n [14, -5],\n [13, -6],\n [11, -7],\n [8, -7],\n [6, -6],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'h': {\n width: 19, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 10],\n [7, 13],\n [9, 14],\n [12, 14],\n [14, 13],\n [15, 10],\n [15, 0]\n ]\n },\n 'i': {\n width: 8, points: [\n [3, 21],\n [4, 20],\n [5, 21],\n [4, 22],\n [3, 21],\n [-1, -1],\n [4, 14],\n [4, 0]\n ]\n },\n 'j': {\n width: 10, points: [\n [5, 21],\n [6, 20],\n [7, 21],\n [6, 22],\n [5, 21],\n [-1, -1],\n [6, 14],\n [6, -3],\n [5, -6],\n [3, -7],\n [1, -7]\n ]\n },\n 'k': {\n width: 17, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [14, 14],\n [4, 4],\n [-1, -1],\n [8, 8],\n [15, 0]\n ]\n },\n 'l': {\n width: 8, points: [\n [4, 21],\n [4, 0]\n ]\n },\n 'm': {\n width: 30, points: [\n [4, 14],\n [4, 0],\n [-1, -1],\n [4, 10],\n [7, 13],\n [9, 14],\n [12, 14],\n [14, 13],\n [15, 10],\n [15, 0],\n [-1, -1],\n [15, 10],\n [18, 13],\n [20, 14],\n [23, 14],\n [25, 13],\n [26, 10],\n [26, 0]\n ]\n },\n 'n': {\n width: 19, points: [\n [4, 14],\n [4, 0],\n [-1, -1],\n [4, 10],\n [7, 13],\n [9, 14],\n [12, 14],\n [14, 13],\n [15, 10],\n [15, 0]\n ]\n },\n 'o': {\n width: 19, points: [\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3],\n [16, 6],\n [16, 8],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14]\n ]\n },\n 'p': {\n width: 19, points: [\n [4, 14],\n [4, -7],\n [-1, -1],\n [4, 11],\n [6, 13],\n [8, 14],\n [11, 14],\n [13, 13],\n [15, 11],\n [16, 8],\n [16, 6],\n [15, 3],\n [13, 1],\n [11, 0],\n [8, 0],\n [6, 1],\n [4, 3]\n ]\n },\n 'q': {\n width: 19, points: [\n [15, 14],\n [15, -7],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'r': {\n width: 13, points: [\n [4, 14],\n [4, 0],\n [-1, -1],\n [4, 8],\n [5, 11],\n [7, 13],\n [9, 14],\n [12, 14]\n ]\n },\n 's': {\n width: 17, points: [\n [14, 11],\n [13, 13],\n [10, 14],\n [7, 14],\n [4, 13],\n [3, 11],\n [4, 9],\n [6, 8],\n [11, 7],\n [13, 6],\n [14, 4],\n [14, 3],\n [13, 1],\n [10, 0],\n [7, 0],\n [4, 1],\n [3, 3]\n ]\n },\n 't': {\n width: 12, points: [\n [5, 21],\n [5, 4],\n [6, 1],\n [8, 0],\n [10, 0],\n [-1, -1],\n [2, 14],\n [9, 14]\n ]\n },\n 'u': {\n width: 19, points: [\n [4, 14],\n [4, 4],\n [5, 1],\n [7, 0],\n [10, 0],\n [12, 1],\n [15, 4],\n [-1, -1],\n [15, 14],\n [15, 0]\n ]\n },\n 'v': {\n width: 16, points: [\n [2, 14],\n [8, 0],\n [-1, -1],\n [14, 14],\n [8, 0]\n ]\n },\n 'w': {\n width: 22, points: [\n [3, 14],\n [7, 0],\n [-1, -1],\n [11, 14],\n [7, 0],\n [-1, -1],\n [11, 14],\n [15, 0],\n [-1, -1],\n [19, 14],\n [15, 0]\n ]\n },\n 'x': {\n width: 17, points: [\n [3, 14],\n [14, 0],\n [-1, -1],\n [14, 14],\n [3, 0]\n ]\n },\n 'y': {\n width: 16, points: [\n [2, 14],\n [8, 0],\n [-1, -1],\n [14, 14],\n [8, 0],\n [6, -4],\n [4, -6],\n [2, -7],\n [1, -7]\n ]\n },\n 'z': {\n width: 17, points: [\n [14, 14],\n [3, 0],\n [-1, -1],\n [3, 14],\n [14, 14],\n [-1, -1],\n [3, 0],\n [14, 0]\n ]\n },\n '{': {\n width: 14, points: [\n [9, 25],\n [7, 24],\n [6, 23],\n [5, 21],\n [5, 19],\n [6, 17],\n [7, 16],\n [8, 14],\n [8, 12],\n [6, 10],\n [-1, -1],\n [7, 24],\n [6, 22],\n [6, 20],\n [7, 18],\n [8, 17],\n [9, 15],\n [9, 13],\n [8, 11],\n [4, 9],\n [8, 7],\n [9, 5],\n [9, 3],\n [8, 1],\n [7, 0],\n [6, -2],\n [6, -4],\n [7, -6],\n [-1, -1],\n [6, 8],\n [8, 6],\n [8, 4],\n [7, 2],\n [6, 1],\n [5, -1],\n [5, -3],\n [6, -5],\n [7, -6],\n [9, -7]\n ]\n },\n '|': {\n width: 8, points: [\n [4, 25],\n [4, -7]\n ]\n },\n '}': {\n width: 14, points: [\n [5, 25],\n [7, 24],\n [8, 23],\n [9, 21],\n [9, 19],\n [8, 17],\n [7, 16],\n [6, 14],\n [6, 12],\n [8, 10],\n [-1, -1],\n [7, 24],\n [8, 22],\n [8, 20],\n [7, 18],\n [6, 17],\n [5, 15],\n [5, 13],\n [6, 11],\n [10, 9],\n [6, 7],\n [5, 5],\n [5, 3],\n [6, 1],\n [7, 0],\n [8, -2],\n [8, -4],\n [7, -6],\n [-1, -1],\n [8, 8],\n [6, 6],\n [6, 4],\n [7, 2],\n [8, 1],\n [9, -1],\n [9, -3],\n [8, -5],\n [7, -6],\n [5, -7]\n ]\n },\n '~': {\n width: 24, points: [\n [3, 6],\n [3, 8],\n [4, 11],\n [6, 12],\n [8, 12],\n [10, 11],\n [14, 8],\n [16, 7],\n [18, 7],\n [20, 8],\n [21, 10],\n [-1, -1],\n [3, 8],\n [4, 10],\n [6, 11],\n [8, 11],\n [10, 10],\n [14, 7],\n [16, 6],\n [18, 6],\n [20, 7],\n [21, 10],\n [21, 12]\n ]\n }\n};\n\n/**\n * @desc Creates wireframe text-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a text-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildVectorTextGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const text = buildVectorTextGeometry({\n * origin: [0,0,0],\n * text: \"On the other side of the screen, it all looked so easy\"\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"textGeometry\",\n * primitiveType: text.primitiveType, // Will be \"lines\"\n * positions: text.positions,\n * indices: text.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redTextMesh\",\n * geometryId: \"textGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redText\",\n * meshIds: [\"redTextMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildVectorTextGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number[]} [cfg.origin] 3D point indicating the top left corner.\n * @param {Number} [cfg.size=1] Size of each character.\n * @param {String} [cfg.text=\"\"] The text.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildVectorTextGeometry(cfg = {}) {\n\n var origin = cfg.origin || [0, 0, 0];\n var xOrigin = origin[0];\n var yOrigin = origin[1];\n var zOrigin = origin[2];\n var size = cfg.size || 1;\n\n var positions = [];\n var indices = [];\n var text = (\"\" + cfg.text).trim();\n var lines = (text || \"\").split(\"\\n\");\n var countVerts = 0;\n var y = 0;\n var x;\n var str;\n var len;\n var c;\n var mag = 1.0 / 25.0;\n var penUp;\n var p1;\n var p2;\n var needLine;\n var pointsLen;\n var a;\n\n for (var iLine = 0; iLine < lines.length; iLine++) {\n\n x = 0;\n str = lines[iLine];\n len = str.length;\n\n for (var i = 0; i < len; i++) {\n\n c = letters[str.charAt(i)];\n\n if (c === '\\n') {\n //alert(\"newline\");\n }\n\n if (!c) {\n continue;\n }\n\n penUp = 1;\n p1 = -1;\n p2 = -1;\n needLine = false;\n\n pointsLen = c.points.length;\n\n for (var j = 0; j < pointsLen; j++) {\n a = c.points[j];\n\n if (a[0] === -1 && a[1] === -1) {\n penUp = 1;\n needLine = false;\n continue;\n }\n\n positions.push((x + (a[0] * size) * mag) + xOrigin);\n positions.push((y + (a[1] * size) * mag) + yOrigin);\n positions.push(0 + zOrigin);\n\n if (p1 === -1) {\n p1 = countVerts;\n } else if (p2 === -1) {\n p2 = countVerts;\n } else {\n p1 = p2;\n p2 = countVerts;\n }\n countVerts++;\n\n if (penUp) {\n penUp = false;\n\n } else {\n indices.push(p1);\n indices.push(p2);\n }\n\n needLine = true;\n }\n x += c.width * mag * size;\n\n }\n y -= 35 * mag * size;\n }\n\n return {\n primitiveType: \"lines\",\n positions: positions,\n indices: indices\n };\n}\n\n\nexport {buildVectorTextGeometry}\n","/**\n * @private\n * @param buf\n * @returns {ArrayBuffer}\n */\nexport function toArrayBuffer(buf) {\n const ab = new ArrayBuffer(buf.length);\n const view = new Uint8Array(ab);\n for (let i = 0; i < buf.length; ++i) {\n view[i] = buf[i];\n }\n return ab;\n}","import {XKT_INFO} from \"./XKT_INFO.js\";\nimport {XKTModel} from \"./XKTModel/XKTModel.js\";\nimport {parseCityJSONIntoXKTModel} from \"./parsers/parseCityJSONIntoXKTModel.js\";\nimport {parseGLTFIntoXKTModel} from \"./parsers/parseGLTFIntoXKTModel.js\";\nimport {parseIFCIntoXKTModel} from \"./parsers/parseIFCIntoXKTModel.js\";\nimport {parseLASIntoXKTModel} from \"./parsers/parseLASIntoXKTModel.js\";\nimport {parsePCDIntoXKTModel} from \"./parsers/parsePCDIntoXKTModel.js\";\nimport {parsePLYIntoXKTModel} from \"./parsers/parsePLYIntoXKTModel.js\";\nimport {parseSTLIntoXKTModel} from \"./parsers/parseSTLIntoXKTModel.js\";\nimport {writeXKTModelToArrayBuffer} from \"./XKTModel/writeXKTModelToArrayBuffer.js\";\n\nimport {toArrayBuffer} from \"./XKTModel/lib/toArraybuffer\";\n\nconst fs = require('fs');\nconst path = require(\"path\");\n\n/**\n * Converts model files into xeokit's native XKT format.\n *\n * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.\n *\n * **Only bundled in xeokit-convert.cjs.js.**\n *\n * ## Usage\n *\n * ````javascript\n * const convert2xkt = require(\"@xeokit/xeokit-convert/dist/convert2xkt.cjs.js\");\n * const fs = require('fs');\n *\n * convert2xkt({\n * sourceData: fs.readFileSync(\"rme_advanced_sample_project.ifc\"),\n * outputXKT: (xtkArrayBuffer) => {\n * fs.writeFileSync(\"rme_advanced_sample_project.ifc.xkt\", xtkArrayBuffer);\n * }\n * }).then(() => {\n * console.log(\"Converted.\");\n * }, (errMsg) => {\n * console.error(\"Conversion failed: \" + errMsg)\n * });\n ````\n * @param {Object} params Conversion parameters.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {*} [params.configs] Configurations.\n * @param {String} [params.source] Path to source file. Alternative to ````sourceData````.\n * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````.\n * @param {String} [params.sourceFormat] Format of source file/data. Always needed with ````sourceData````, but not normally needed with ````source````, because convert2xkt will determine the format automatically from the file extension of ````source````.\n * @param {String} [params.metaModelDataStr] Source file data. Overrides metadata from ````metaModelSource````, ````sourceData```` and ````source````.\n * @param {String} [params.metaModelSource] Path to source metaModel file. Overrides metadata from ````sourceData```` and ````source````. Overridden by ````metaModelData````.\n * @param {String} [params.output] Path to destination XKT file. Directories on this path are automatically created if not existing.\n * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method.\n * @param {Function} [params.outputXKT] Callback to collect XKT file data.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided.\n * @param {Function} [params.outputStats] Callback to collect statistics.\n * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis \"up\", if necessary. Applies to CityJSON and LAS/LAZ models.\n * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models.\n * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore\n * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the model.\n * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000,\n * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close\n * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger.\n * @param {Function} [params.log] Logging callback.\n * @return {Promise}\n */\nfunction convert2xkt({\n WebIFC,\n configs = {},\n source,\n sourceData,\n sourceFormat,\n metaModelSource,\n metaModelDataStr,\n modelAABB,\n output,\n outputXKTModel,\n outputXKT,\n includeTypes,\n excludeTypes,\n reuseGeometries = true,\n minTileSize = 200,\n stats = {},\n outputStats,\n rotateX = false,\n includeTextures = true,\n includeNormals = true,\n log = function (msg) {\n }\n }) {\n\n stats.sourceFormat = \"\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 0;\n stats.numPropertySets = 0;\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numUVs = 0;\n stats.numTextures = 0;\n stats.numTextureSets = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n stats.sourceSize = 0;\n stats.xktSize = 0;\n stats.texturesSize = 0;\n stats.xktVersion = \"\";\n stats.compressionRatio = 0;\n stats.conversionTime = 0;\n stats.aabb = null;\n\n function getFileExtension(fileName) {\n let ext = path.extname(fileName);\n if (ext.charAt(0) === \".\") {\n ext = ext.substring(1);\n }\n return ext;\n }\n\n return new Promise(function (resolve, reject) {\n const _log = log;\n log = (msg) => {\n _log(`[convert2xkt] ${msg}`)\n }\n\n if (!source && !sourceData) {\n reject(\"Argument expected: source or sourceData\");\n return;\n }\n\n if (!sourceFormat && sourceData) {\n reject(\"Argument expected: sourceFormat is required with sourceData\");\n return;\n }\n\n if (!output && !outputXKTModel && !outputXKT) {\n reject(\"Argument expected: output, outputXKTModel or outputXKT\");\n return;\n }\n\n if (source) {\n log('Reading input file: ' + source);\n }\n\n const startTime = new Date();\n\n const sourceConfigs = configs.sourceConfigs || {};\n const ext = sourceFormat || getFileExtension(source);\n\n log(`Input file extension: \"${ext}\"`);\n\n let fileTypeConfigs = sourceConfigs[ext];\n\n if (!fileTypeConfigs) {\n log(`[WARNING] Could not find configs sourceConfigs entry for source format \"${ext}\". This is derived from the source file name extension. Will use internal default configs.`);\n fileTypeConfigs = {};\n }\n\n function overrideOption(option1, option2) {\n if (option1 !== undefined) {\n return option1;\n }\n return option2;\n }\n\n if (!sourceData) {\n try {\n sourceData = fs.readFileSync(source);\n } catch (err) {\n reject(err);\n return;\n }\n }\n\n const sourceFileSizeBytes = sourceData.byteLength;\n\n log(\"Input file size: \" + (sourceFileSizeBytes / 1000).toFixed(2) + \" kB\");\n\n if (!metaModelDataStr && metaModelSource) {\n log('Reading input metadata file: ' + metaModelSource);\n try {\n metaModelDataStr = fs.readFileSync(metaModelSource);\n } catch (err) {\n reject(err);\n return;\n }\n } else {\n log(`Not embedding metadata in XKT`);\n }\n\n let metaModelJSON;\n\n if (metaModelDataStr) {\n try {\n metaModelJSON = JSON.parse(metaModelDataStr);\n } catch (e) {\n metaModelJSON = {};\n log(`Error parsing metadata JSON: ${e}`);\n }\n }\n\n minTileSize = overrideOption(fileTypeConfigs.minTileSize, minTileSize);\n rotateX = overrideOption(fileTypeConfigs.rotateX, rotateX);\n reuseGeometries = overrideOption(fileTypeConfigs.reuseGeometries, reuseGeometries);\n includeTextures = overrideOption(fileTypeConfigs.includeTextures, includeTextures);\n includeNormals = overrideOption(fileTypeConfigs.includeNormals, includeNormals);\n includeTypes = overrideOption(fileTypeConfigs.includeTypes, includeTypes);\n excludeTypes = overrideOption(fileTypeConfigs.excludeTypes, excludeTypes);\n\n if (reuseGeometries === false) {\n log(\"Geometry reuse is disabled\");\n }\n\n const xktModel = new XKTModel({\n minTileSize,\n modelAABB\n });\n\n switch (ext) {\n case \"json\":\n convert(parseCityJSONIntoXKTModel, {\n data: JSON.parse(sourceData),\n xktModel,\n stats,\n rotateX,\n center: fileTypeConfigs.center,\n transform: fileTypeConfigs.transform,\n log\n });\n break;\n\n case \"glb\":\n sourceData = toArrayBuffer(sourceData);\n convert(parseGLTFIntoXKTModel, {\n data: sourceData,\n reuseGeometries,\n includeTextures: true,\n includeNormals,\n metaModelData: metaModelJSON,\n xktModel,\n stats,\n log\n });\n break;\n\n case \"gltf\":\n sourceData = toArrayBuffer(sourceData);\n const gltfBasePath = source ? path.dirname(source) : \"\";\n convert(parseGLTFIntoXKTModel, {\n baseUri: gltfBasePath,\n data: sourceData,\n reuseGeometries,\n includeTextures: true,\n includeNormals,\n metaModelData: metaModelJSON,\n xktModel,\n stats,\n log\n });\n break;\n\n // case \"gltf\":\n // const gltfJSON = JSON.parse(sourceData);\n // const gltfBasePath = source ? getBasePath(source) : \"\";\n // convert(parseGLTFIntoXKTModel, {\n // baseUri: gltfBasePath,\n // data: gltfJSON,\n // reuseGeometries,\n // includeTextures,\n // includeNormals,\n // metaModelData: metaModelJSON,\n // xktModel,\n // getAttachment: async (name) => {\n // const filePath = gltfBasePath + name;\n // log(`Reading attachment file: ${filePath}`);\n // const buffer = fs.readFileSync(filePath);\n // const arrayBuf = toArrayBuffer(buffer);\n // return arrayBuf;\n // },\n // stats,\n // log\n // });\n // break;\n\n case \"ifc\":\n convert(parseIFCIntoXKTModel, {\n WebIFC,\n data: sourceData,\n xktModel,\n wasmPath: \"./\",\n includeTypes,\n excludeTypes,\n stats,\n log\n });\n break;\n\n case \"laz\":\n convert(parseLASIntoXKTModel, {\n data: sourceData,\n xktModel,\n stats,\n fp64: fileTypeConfigs.fp64,\n colorDepth: fileTypeConfigs.colorDepth,\n center: fileTypeConfigs.center,\n transform: fileTypeConfigs.transform,\n skip: overrideOption(fileTypeConfigs.skip, 1),\n log\n });\n break;\n\n case \"las\":\n convert(parseLASIntoXKTModel, {\n data: sourceData,\n xktModel,\n stats,\n fp64: fileTypeConfigs.fp64,\n colorDepth: fileTypeConfigs.colorDepth,\n center: fileTypeConfigs.center,\n transform: fileTypeConfigs.transform,\n skip: overrideOption(fileTypeConfigs.skip, 1),\n log\n });\n break;\n\n case \"pcd\":\n convert(parsePCDIntoXKTModel, {\n data: sourceData,\n xktModel,\n stats,\n log\n });\n break;\n\n case \"ply\":\n convert(parsePLYIntoXKTModel, {\n data: sourceData,\n xktModel,\n stats,\n log\n });\n break;\n\n case \"stl\":\n convert(parseSTLIntoXKTModel, {\n data: sourceData,\n xktModel,\n stats,\n log\n });\n break;\n\n default:\n reject(`Error: unsupported source format: \"${ext}\".`);\n return;\n }\n\n function convert(parser, converterParams) {\n\n parser(converterParams).then(() => {\n\n if (!metaModelJSON) {\n log(\"Creating default metamodel in XKT\");\n xktModel.createDefaultMetaObjects();\n }\n\n log(\"Input file parsed OK. Building XKT document...\");\n\n xktModel.finalize().then(() => {\n\n log(\"XKT document built OK. Writing to XKT file...\");\n\n const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel, metaModelJSON, stats, {zip: true});\n\n const xktContent = Buffer.from(xktArrayBuffer);\n\n const targetFileSizeBytes = xktArrayBuffer.byteLength;\n\n stats.minTileSize = minTileSize || 200;\n stats.sourceSize = (sourceFileSizeBytes / 1000).toFixed(2);\n stats.xktSize = (targetFileSizeBytes / 1000).toFixed(2);\n stats.xktVersion = XKT_INFO.xktVersion;\n stats.compressionRatio = (sourceFileSizeBytes / targetFileSizeBytes).toFixed(2);\n stats.conversionTime = ((new Date() - startTime) / 1000.0).toFixed(2);\n stats.aabb = xktModel.aabb;\n log(`Converted to: XKT v${stats.xktVersion}`);\n if (includeTypes) {\n log(\"Include types: \" + (includeTypes ? includeTypes : \"(include all)\"));\n }\n if (excludeTypes) {\n log(\"Exclude types: \" + (excludeTypes ? excludeTypes : \"(exclude none)\"));\n }\n log(\"XKT size: \" + stats.xktSize + \" kB\");\n log(\"XKT textures size: \" + (stats.texturesSize / 1000).toFixed(2) + \"kB\");\n log(\"Compression ratio: \" + stats.compressionRatio);\n log(\"Conversion time: \" + stats.conversionTime + \" s\");\n log(\"Converted metaobjects: \" + stats.numMetaObjects);\n log(\"Converted property sets: \" + stats.numPropertySets);\n log(\"Converted drawable objects: \" + stats.numObjects);\n log(\"Converted geometries: \" + stats.numGeometries);\n log(\"Converted textures: \" + stats.numTextures);\n log(\"Converted textureSets: \" + stats.numTextureSets);\n log(\"Converted triangles: \" + stats.numTriangles);\n log(\"Converted vertices: \" + stats.numVertices);\n log(\"Converted UVs: \" + stats.numUVs);\n log(\"Converted normals: \" + stats.numNormals);\n log(\"Converted tiles: \" + xktModel.tilesList.length);\n log(\"minTileSize: \" + stats.minTileSize);\n\n if (output) {\n const outputDir = path.dirname(output);\n if (outputDir !== \"\" && !fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, {recursive: true});\n }\n log('Writing XKT file: ' + output);\n fs.writeFileSync(output, xktContent);\n }\n\n if (outputXKTModel) {\n outputXKTModel(xktModel);\n }\n\n if (outputXKT) {\n outputXKT(xktContent);\n }\n\n if (outputStats) {\n outputStats(stats);\n }\n\n resolve();\n });\n }, (err) => {\n reject(err);\n });\n }\n });\n}\n\nexport {convert2xkt};","import '@loaders.gl/polyfills';\nimport {installFilePolyfills} from '@loaders.gl/polyfills';\n\ninstallFilePolyfills();\n\nexport * from \"./src/index.js\";\nexport {convert2xkt} from \"./src/convert2xkt.js\"; // convert2xkt is only bundled for Node.js\n"],"names":["root","factory","exports","module","define","amd","global","require","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","d","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","p","mat","mat2","mat3","xyz","tempVec3","vec","translate","scale","XKT_INFO","xktVersion","RepeatWrapping","ClampToEdgeWrapping","MirroredRepeatWrapping","NearestFilter","NearestMipMapNearestFilter","NearestMipmapNearestFilter","NearestMipmapLinearFilter","NearestMipMapLinearFilter","LinearFilter","LinearMipmapNearestFilter","LinearMipMapNearestFilter","LinearMipmapLinearFilter","LinearMipMapLinearFilter","GIFMediaType","JPEGMediaType","PNGMediaType","FloatArrayType","Float64Array","tempMat1","tempMat2","tempVec4","math","MIN_DOUBLE","Number","MAX_SAFE_INTEGER","MAX_DOUBLE","DEGTORAD","RADTODEG","vec2","values","vec3","vec4","mat3ToMat4","mat4","arguments","length","mat4ToMat3","createUUID","lut","i","toString","d0","Math","random","d1","d2","d3","concat","clamp","min","max","fmod","a","b","console","error","negateVec4","v","dest","addVec4","u","addVec4Scalar","s","addVec3","addVec3Scalar","subVec4","subVec3","subVec2","subVec4Scalar","subScalarVec4","mulVec4","mulVec4Scalar","mulVec3Scalar","mulVec2Scalar","divVec3","divVec4","divScalarVec3","divVec3Scalar","divVec4Scalar","divScalarVec4","dotVec4","cross3Vec4","u0","u1","u2","v0","v1","v2","cross3Vec3","x","y","z","x2","y2","z2","sqLenVec4","lenVec4","sqrt","dotVec3","dotVec2","sqLenVec3","sqLenVec2","lenVec3","distVec3","w","lenVec2","distVec2","rcpVec3","normalizeVec4","f","normalizeVec3","normalizeVec2","angleVec3","theta","acos","vec3FromMat4Scale","m","vecToArray","trunc","round","len","Array","slice","xyzArrayToObject","arr","xyzObjectToArray","arry","dupMat4","mat4To3","m4s","setMat4ToZeroes","setMat4ToOnes","diagonalMat4v","diagonalMat4c","diagonalMat4s","identityMat4","identityMat3","isIdentityMat4","negateMat4","addMat4","addMat4Scalar","addScalarMat4","subMat4","subMat4Scalar","subScalarMat4","mulMat4","a00","a01","a02","a03","a10","a11","a12","a13","a20","a21","a22","a23","a30","a31","a32","a33","b00","b01","b02","b03","b10","b11","b12","b13","b20","b21","b22","b23","b30","b31","b32","b33","mulMat3","mulMat4Scalar","mulMat4v4","v3","transposeMat4","m4","m14","m8","m13","m12","m9","transposeMat3","determinantMat4","inverseMat4","b04","b05","b06","b07","b08","b09","invDet","traceMat4","translationMat4v","translationMat3v","translationMat4c","translationMat4s","translateMat4v","translateMat4c","OLDtranslateMat4c","m15","m3","m7","m11","rotationMat4v","anglerad","axis","xy","yz","zx","xs","ys","zs","ax","sin","c","cos","q","rotationMat4c","scalingMat4v","scalingMat3v","scalingMat4c","scaleMat4c","scaleMat4v","scalingMat4s","rotationTranslationMat4","xx","xz","yy","zz","wx","wy","wz","mat4ToEuler","order","m21","m22","m23","m31","m32","m33","asin","abs","atan2","composeMat4","position","quaternion","quaternionToRotationMat4","decomposeMat4","matrix","sx","sy","sz","set","invSX","invSY","invSZ","mat4ToQuaternion","this","lookAtMat4v","pos","target","up","z0","z1","x0","x1","y0","y1","posx","posy","posz","upx","upy","upz","targetx","targety","targetz","lookAtMat4c","orthoMat4c","left","right","bottom","top","near","far","rl","tb","fn","frustumMat4v","fmin","fmax","fmin4","fmax4","t","tempMat20","tempMat21","tempMat22","frustumMat4","perspectiveMat4","fovyrad","aspectratio","znear","zfar","pmin","pmax","tan","transformPoint3","transformPoint4","transformPoints3","points","points2","p0","p1","p2","pi","result","m0","m1","m2","m5","m6","m10","transformPositions3","transformPositions4","transformVec3","transformVec4","rotateVec3X","rotateVec3Y","rotateVec3Z","projectVec4","unprojectVec3","viewMat","projMat","lerpVec3","t1","t2","flatten","leni","j","lenj","item","push","identityQuaternion","eulerToQuaternion","euler","c1","c2","c3","s1","s2","s3","trace","vec3PairToQuaternion","norm_u_norm_v","real_part","normalizeQuaternion","angleAxisToQuaternion","angleAxis","halfAngle","fsin","quaternionToEuler","mulQuaternions","p3","q0","q1","q2","q3","vec3ApplyQuaternion","qx","qy","qz","qw","ix","iy","iz","iw","quaternionToMat4","tx","ty","tz","twx","twy","twz","txx","txy","txz","tyy","tyz","tzz","conjugateQuaternion","inverseQuaternion","quaternionToAngleAxis","angle","AABB3","AABB2","OBB3","OBB2","Sphere3","transformOBB3","containsAABB3","aabb1","aabb2","getAABB3Diag","aabb","getAABB3DiagPoint","diagVec","xneg","xpos","yneg","ypos","zneg","zpos","getAABB3Center","getAABB2Center","collapseAABB3","AABB3ToOBB3","obb","positions3ToAABB3","positions","positionsDecodeMatrix","xmin","ymin","zmin","xmax","ymax","zmax","decompressPosition","OBB3ToAABB3","points3ToAABB3","points3ToSphere3","sphere","numPoints","dist","radius","positions3ToSphere3","tempVec3a","tempVec3b","lenPositions","numPositions","OBB3ToSphere3","point","lenPoints","getSphere3Center","expandAABB3","expandAABB3Point3","triangleNormal","normal","p1x","p1y","p1z","p2x","p2y","p2z","p3x","p3y","p3z","mag","octEncodeVec3","array","xfunc","yfunc","tempx","tempy","Int8Array","octDecodeVec2","oct","dot","uniquePositions","indicesLookup","indicesReverseLookup","weldedIndices","faces","numFaces","compa","compb","compc","cb","ab","cross","inverseNormal","geometryCompression","quantizePositions","quantizedPositions","maxInt","xMultiplier","yMultiplier","zMultiplier","verify","num","floor","compressPosition","multiplier","Float32Array","createPositionsDecodeMatrix","xwid","ywid","zwid","transformAndOctEncodeNormals","modelNormalMatrix","normals","lenNormals","compressedNormals","lenCompressedNormals","best","currentCos","bestCos","localNormal","worldNormal","octEncodeNormals","buildEdgeIndices","Uint16Array","indices","edgeThreshold","vx","vy","vz","positionsMap","precision","pow","lenUniquePositions","weldVertices","numIndices","ia","ib","ic","face","buildFaces","edge1","edge2","index1","index2","edge","normal1","normal2","edgeIndices","thresholdDot","edges","largeIndex","faceIndex","face1","face2","dot2","Uint32Array","isTriangleMeshSolid","vertexIndexMapping","compareIndexPositions","posA","posB","newIndices","sort","uniqueVertexIndex","a2","b2","temp","compareEdges","e1","e2","sameEdgeCount","XKTMesh","_createClass","cfg","_classCallCheck","meshId","meshIndex","geometry","color","metallic","roughness","opacity","textureSet","entity","XKTGeometry","geometryId","primitiveType","geometryIndex","numInstances","positionsQuantized","normalsOctEncoded","colorsCompressed","uvs","uvsCompressed","solid","XKTEntity","entityId","meshes","entityIndex","hasReusedGeometries","XKTTile","entities","KDNode","XKTMetaObject","metaObjectId","propertySetIds","metaObjectType","metaObjectName","parentMetaObjectId","XKTPropertySet","propertySetId","propertySetType","propertySetName","properties","XKTTexture","textureId","textureIndex","imageData","channel","width","height","src","compressed","mediaType","minFilter","magFilter","wrapS","wrapT","wrapR","XKTTextureSet","textureSetId","textureSetIndex","materialType","materialIndex","colorTexture","metallicRoughnessTexture","normalsTexture","emissiveTexture","occlusionTexture","_regeneratorRuntime","Op","hasOwn","desc","$Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","configurable","writable","err","wrap","innerFn","outerFn","self","tryLocsList","protoGenerator","Generator","generator","create","context","Context","makeInvokeMethod","tryCatch","arg","type","ContinueSentinel","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","getProto","getPrototypeOf","NativeIteratorPrototype","Gp","defineIteratorMethods","forEach","method","_invoke","AsyncIterator","PromiseImpl","invoke","resolve","reject","record","_typeof","__await","then","unwrapped","previousPromise","callInvokeWithMethodAndArg","state","Error","done","delegate","delegateResult","maybeInvokeDelegate","sent","_sent","dispatchException","abrupt","methodName","TypeError","info","resultName","next","nextLoc","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","reset","iterable","iteratorMethod","isNaN","doneResult","displayName","isGeneratorFunction","genFun","ctor","constructor","name","mark","setPrototypeOf","__proto__","awrap","async","Promise","iter","keys","val","object","reverse","pop","skipTempReset","prev","charAt","stop","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","finish","thrown","delegateYield","asyncGeneratorStep","gen","_next","_throw","_defineProperties","props","descriptor","input","hint","prim","toPrimitive","res","String","_toPrimitive","tempVec4a","tempVec4b","tempMat4","tempMat4b","kdTreeDimLength","TEXTURE_ENCODING_OPTIONS","useSRGB","qualityLevel","encodeUASTC","mipmaps","XKTModel","instance","Constructor","modelId","projectId","revisionId","author","createdAt","creatingApplication","schema","minTileSize","modelAABB","propertySets","propertySetsList","metaObjects","metaObjectsList","reusedGeometriesDecodeMatrix","geometries","geometriesList","textures","texturesList","textureSets","textureSetsList","meshesList","entitiesList","tilesList","finalized","protoProps","_finalize","params","propertySet","metaObject","_rootMetaObject","fileExt","split","texture","colorTextureId","metallicRoughnessTextureId","normalsTextureId","emissiveTextureId","occlusionTextureId","triangles","lines","line_strip","line_loop","_createDefaultIndices","colors","xktGeometryCfg","uv","Uint8Array","mergedPositions","mergedIndices","mergeVertices","rotation","mesh","meshIds","meshIdIdx","meshIdLen","warn","createMetaObject","_callee","rootKDNode","_context","log","_removeUnusedTextures","_compressTextures","_bakeSingleUseGeometryPositions","_bakeAndOctEncodeNormals","_createEntityAABBs","_createKDTree","_createTilesFromKDTree","_createReusedGeometriesDecodeMatrix","_flagSolidGeometries","args","apply","_this","countTextures","_loop","encodingOptions","load","ImageLoader","image","encode","KTX2BasisWriter","encodedData","encodedImageData","entityAABB","_insertEntityIntoKDTree","kdNode","nodeAABB","dim","aabbLeft","aabbRight","_createTilesFromKDNode","_createTileFromEntities","tileAABB","tileCenter","tileCenterNeg","rtcAABB","reused","k","lenk","tile","reusedGeometriesAABB","countReusedGeometries","numGeometries","maxNumPositions","maxNumIndices","XKT_VERSION","NUM_TEXTURE_ATTRIBUTES","NUM_MATERIAL_ATTRIBUTES","writeXKTModelToArrayBuffer","xktModel","metaModelJSON","stats","options","data","metaModelDataStr","numPropertySets","numMetaObjects","numTextures","numTextureSets","numMeshes","numEntities","numTiles","lenColors","lenUVs","lenIndices","lenEdgeIndices","lenMatrices","lenTextures","xktTexture","byteLength","numCompressedTextures","metadata","textureData","eachTextureDataPortion","eachTextureAttributes","eachTextureSetTextures","Int32Array","matrices","eachGeometryPrimitiveType","eachGeometryPositionsPortion","eachGeometryNormalsPortion","eachGeometryColorsPortion","eachGeometryUVsPortion","eachGeometryIndicesPortion","eachGeometryEdgeIndicesPortion","eachMeshGeometriesPortion","eachMeshMatricesPortion","eachMeshTextureSet","eachMeshMaterialAttributes","eachEntityId","eachEntityMeshesPortion","eachTileAABB","eachTileEntitiesPortion","countPositions","countNormals","countColors","countUVs","countIndices","countEdgeIndices","id","propertySetsIndex","propertySetJSON","metaObjectsIndex","metaObjectJSON","parent","external","portionIdx","textureAttrIdx","eachTextureSetTexturesIndex","countEntityMeshesPortion","eachMeshMaterialAttributesIndex","matricesIndex","tileIndex","tileEntities","numTileEntities","entityMeshes","numEntityMeshes","tileAABBIndex","getModelData","deflatedData","deflate","buffer","zip","pako","deflateJSON","JSON","stringify","replace","chr","charCodeAt","substr","deflateData","texturesSize","arrayBuffer","elements","indexData","dataLen","elementsize","indexBuf","dataArray","offset","element","toArrayBuffer","createArrayBuffer","strings","earcut","holeIndices","minX","minY","maxX","maxY","invSize","hasHoles","outerLen","outerNode","linkedList","list","queue","steiner","getLeftmost","compareX","eliminateHole","filterPoints","eliminateHoles","earcutLinked","start","end","clockwise","last","signedArea","insertNode","equals","removeNode","again","area","ear","pass","zOrder","prevZ","nextZ","e","tail","numMerges","pSize","qSize","inSize","sortLinked","indexCurve","isEarHashed","isEar","cureLocalIntersections","splitEarcut","pointInTriangle","minTX","minTY","maxTX","maxTY","minZ","maxZ","n","intersects","locallyInside","isValidDiagonal","splitPolygon","hole","hx","hy","mx","my","tanMin","Infinity","sectorContainsSector","findHoleBridge","leftmost","ay","bx","by","cx","cy","px","py","intersectsPolygon","inside","middleInside","o1","sign","o2","o3","o4","onSegment","Node","an","bp","sum","deviation","polygonArea","trianglesArea","vertices","holes","dimensions","holeIndex","tempVec2a","tempVec3c","parseCityJSONIntoXKTModel","_ref","_ref$center","center","_ref$transform","transform","_ref$stats","vertices2","copyVertices","cityJSONTransform","vertex","transformVertices","centerVertices","customTransformVertices","sourceFormat","schemaVersion","version","title","created","numTriangles","numVertices","numObjects","rootMetaObjectId","modelMetaObjectId","ctx","msg","nextId","cityObjects","CityObjects","objectId","parseCityObject","parseCityJSON","centerPos","cityObject","parents","objectMaterial","surfaceMaterials","appearance","materials","geometryMaterial","material","themeIds","theme","surfaceMaterial","parseGeometrySurfacesWithOwnMaterials","parseGeometrySurfacesWithSharedMaterial","createEntity","parseSurfacesWithOwnMaterials","boundaries","shells","solids","surfaces","surface","diffuseColor","transparency","sharedIndices","geometryCfg","newFace","extractLocalIndices","_toConsumableArray","pList","getNormalOfPositions","pv","to2D","unshift","tr","createGeometry","createMesh","parseSurfacesWithSharedMaterial","primitiveCfg","boundary","newBoundary","index","includes","vertexIndex","indexOf","nexti","_p","_n","re","x3","tmp2","y3","utils","isString","parseGLTFIntoXKTModel","baseUri","metaModelData","_ref$includeTextures","includeTextures","_ref$includeNormals","includeNormals","getAttachment","numNormals","numUVs","parse","GLTFLoader","gltfData","metaModelCorrections","geometryCreated","parseTexture","parseTextures","_textureSetId","parseTextureSet","_attributes","parseMaterialAttributes","parseMaterials","scene","scenes","nodes","countMeshUsage","parseNode","parseScene","parseDefaultScene","errMsg","source","sampler","createTexture","flipY","_textureId","textureSetCfg","normalTexture","normalTextureId","metallicPBR","pbrMetallicRoughness","baseColorTexture","extensions","specularPBR","specularTexture","specularColorTexture","createTextureSet","materialAttributes","diffuseFactor","common","technique","blinn","phong","lambert","diffuse","transparent","baseColorFactor","metallicFactor","roughnessFactor","node","instances","children","childNode","objectIdStack","meshIdsStack","depth","localMatrix","translation","xktEntityId","numPrimitives","primitives","primitive","_xktGeometryId","xktGeometryId","mode","attributes","POSITION","NORMAL","COLOR_0","TEXCOORD_0","xktMeshId","meshCfg","nodeName","entityMeshIds","atob2","atob","Buffer","from","WEBGL_COMPONENT_TYPES","Int16Array","WEBGL_TYPE_SIZES","parseGLTFJSONIntoXKTModel","reuseGeometries","gltf","getMetaModelCorrections","createXKTGeometryIds","nextMeshId","buffers","all","map","bufferInfo","_arrayBuffer","_buffer","uri","dataUriRegexResult","match","isBase64","decodeURIComponent","ArrayBuffer","view","parseArrayBuffer","parseBuffer","parseBuffers","bufferViewsInfo","bufferViews","parseBufferView","parseBufferViews","freeBuffers","materialsInfo","materialInfo","parseMaterial","_materialData","defaultSceneInfo","sceneInfo","glTFNode","eachRootStats","eachChildRoot","metaObjectsMap","metaObjectParent","rootMetaObject","numChildren","countChildren","bufferViewInfo","_typedArray","byteOffset","deferredMeshIds","gltfMeshId","meshInfo","numPrimitivesInMesh","primitiveInfo","geometryHash","createPrimitiveGeometryHash","geometryArrays","parsePrimitiveGeometry","childNodeIdx","childGLTFNode","rootMetaObjectStats","join","accessors","indicesIndex","accessorInfo","parseAccessorTypedArray","positionsIndex","normalsIndex","colorsIndex","bufferView","itemSize","TypedArray","componentType","itemBytes","BYTES_PER_ELEMENT","byteStride","count","parseIFCIntoXKTModel","WebIFC","_ref$autoNormals","autoNormals","includeTypes","excludeTypes","wasmPath","ifcAPI","IfcAPI","SetWasmPath","Init","modelID","OpenModel","ifcProjectId","GetLineIDsWithType","IFCPROJECT","GetLine","ifcProject","parseSpatialChildren","parseMetadata","flatMeshes","LoadAllGeometry","size","createObject","IFCSPACE","ifcSpaceId","flatMesh","GetFlatMesh","parseGeometry","IFCRELDEFINESBYPROPERTIES","relID","rel","relatingPropertyDefinition","RelatingPropertyDefinition","GlobalId","relatedObjects","RelatedObjects","HasProperties","Name","nominalValue","NominalValue","property","valueType","Description","description","createPropertySet","parsePropertySets","ifcElement","parseRelatedItemsOfType","expressID","IFCRELAGGREGATES","IFCRELCONTAINEDINSPATIALSTRUCTURE","relation","related","relatedItems","isArray","element2","flatMeshExpressID","placedGeometries","placedGeometry","geometryExpressID","GetGeometry","vertexData","GetVertexArray","GetVertexData","GetVertexDataSize","GetIndexArray","GetIndexData","GetIndexDataSize","flatTransformation","MAX_VERTICES","parseLASIntoXKTModel","_ref$colorDepth","colorDepth","_ref$fp","fp64","_ref$skip","skip","_ref$log","LASLoader","las","parsedData","loaderData","pointsFormatId","readAttributes","intensity","readIntensities","readColorsAndIntensities","pointsChunks","chunkArray","positionsValue","readPositions","colorsChunks","attributesPosition","attributesColor","attributesIntensity","colorSize","intensities","colorsCompressedSize","l","chunkSize","parseMetaModelIntoXKTModel","includeTypesMap","excludeTypesMap","newObject","countMetaObjects","parsePCDIntoXKTModel","_ref$littleEndian","littleEndian","textData","TextDecoder","decode","il","fromCharCode","escape","decodeText","header","result1","search","result2","exec","headerLen","str","fields","viewpoint","parseFloat","parseInt","sizeSum","rowSize","parseHeader","line","rgb","g","sizes","compressedSize","decompressedSize","decompressed","inData","outLength","ctrl","ref","inLength","outData","inPtr","outPtr","decompressLZF","dataview","DataView","getFloat32","getUint8","row","parsePLYIntoXKTModel","_x","_parsePLYIntoXKTModel","hasColors","colorsValue","PLYLoader","t0","parseSTLIntoXKTModel","_parseSTLIntoXKTModel","splitMeshes","smoothNormals","smoothNormalsAngleThreshold","binData","ensureBinary","isBinary","parseBinary","parseASCII","reader","getUint32","defaultR","defaultG","defaultB","lastR","lastG","lastB","newMesh","normalX","normalY","normalZ","packedColor","getUint16","vertexstart","addMesh","normalx","normaly","normalz","verticesPerFace","normalsPerFace","text","faceRegex","faceCounter","floatRegex","vertexRegex","RegExp","normalRegex","nextGeometryId","ni","acc","posi","vertexMap","vertexNormals","vertexNormalAccum","numVerts","ii","jj","faceToVertexNormals","buildBoxGeometry","xSize","ySize","zSize","centerX","centerY","centerZ","buildBoxLinesGeometry","buildCylinderGeometry","radiusTop","radiusBottom","radialSegments","heightSegments","h","currentRadius","currentHeight","first","second","startIndex","tu","tv","openEnded","heightHalf","heightLength","radialAngle","PI","radialLength","radiusChange","atan","buildGridGeometry","divisions","step","halfSize","buildPlaneGeometry","xSegments","zSegments","halfWidth","halfHeight","planeX","planeZ","planeX1","planeZ1","segmentWidth","segmentHeight","offset2","buildSphereGeometry","lod","widthSegments","sinTheta","cosTheta","phi","sinPhi","buildTorusGeometry","tube","tubeSegments","arc","letters","buildVectorTextGeometry","penUp","pointsLen","origin","xOrigin","yOrigin","zOrigin","trim","countVerts","iLine","buf","fs","path","convert2xkt","_ref$configs","configs","sourceData","metaModelSource","output","outputXKTModel","outputXKT","_ref$reuseGeometries","_ref$minTileSize","outputStats","_ref$rotateX","rotateX","sourceSize","xktSize","compressionRatio","conversionTime","_log","startTime","Date","sourceConfigs","ext","fileName","extname","substring","getFileExtension","fileTypeConfigs","readFileSync","sourceFileSizeBytes","toFixed","overrideOption","convert","dirname","option1","option2","parser","converterParams","createDefaultMetaObjects","finalize","xktArrayBuffer","xktContent","targetFileSizeBytes","outputDir","existsSync","mkdirSync","recursive","writeFileSync","installFilePolyfills"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"xeokit-convert.cjs.js","mappings":"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","sources":["webpack://convert2xkt/webpack/universalModuleDefinition","webpack://convert2xkt/webpack/bootstrap","webpack://convert2xkt/webpack/runtime/define property getters","webpack://convert2xkt/webpack/runtime/hasOwnProperty shorthand","webpack://convert2xkt/webpack/runtime/make namespace object","webpack://convert2xkt/external commonjs \"@loaders.gl/polyfills\"","webpack://convert2xkt/./src/XKT_INFO.js","webpack://convert2xkt/./src/lib/math.js","webpack://convert2xkt/./src/XKTModel/lib/geometryCompression.js","webpack://convert2xkt/./src/constants.js","webpack://convert2xkt/./src/XKTModel/lib/buildEdgeIndices.js","webpack://convert2xkt/./src/XKTModel/lib/isTriangleMeshSolid.js","webpack://convert2xkt/./src/XKTModel/XKTMesh.js","webpack://convert2xkt/./src/XKTModel/XKTGeometry.js","webpack://convert2xkt/./src/XKTModel/XKTEntity.js","webpack://convert2xkt/./src/XKTModel/XKTTile.js","webpack://convert2xkt/./src/XKTModel/KDNode.js","webpack://convert2xkt/./src/XKTModel/XKTMetaObject.js","webpack://convert2xkt/./src/XKTModel/XKTPropertySet.js","webpack://convert2xkt/./src/XKTModel/XKTTexture.js","webpack://convert2xkt/./src/XKTModel/XKTTextureSet.js","webpack://convert2xkt/external commonjs \"@loaders.gl/core\"","webpack://convert2xkt/external commonjs \"@loaders.gl/textures\"","webpack://convert2xkt/external commonjs \"@loaders.gl/images\"","webpack://convert2xkt/./src/XKTModel/XKTModel.js","webpack://convert2xkt/./src/lib/mergeVertices.js","webpack://convert2xkt/external commonjs \"pako\"","webpack://convert2xkt/./src/XKTModel/writeXKTModelToArrayBuffer.js","webpack://convert2xkt/./src/lib/earcut.js","webpack://convert2xkt/./src/parsers/parseCityJSONIntoXKTModel.js","webpack://convert2xkt/./src/XKTModel/lib/utils.js","webpack://convert2xkt/external commonjs \"@loaders.gl/gltf\"","webpack://convert2xkt/./src/parsers/parseGLTFIntoXKTModel.js","webpack://convert2xkt/./src/parsers/parseGLTFJSONIntoXKTModel.js","webpack://convert2xkt/./src/parsers/parseIFCIntoXKTModel.js","webpack://convert2xkt/external commonjs \"@loaders.gl/las\"","webpack://convert2xkt/./src/parsers/parseLASIntoXKTModel.js","webpack://convert2xkt/./src/parsers/parseMetaModelIntoXKTModel.js","webpack://convert2xkt/./src/parsers/parsePCDIntoXKTModel.js","webpack://convert2xkt/external commonjs \"@loaders.gl/ply\"","webpack://convert2xkt/./src/parsers/parsePLYIntoXKTModel.js","webpack://convert2xkt/./src/parsers/parseSTLIntoXKTModel.js","webpack://convert2xkt/./src/lib/faceToVertexNormals.js","webpack://convert2xkt/./src/geometryBuilders/buildBoxGeometry.js","webpack://convert2xkt/./src/geometryBuilders/buildBoxLinesGeometry.js","webpack://convert2xkt/./src/geometryBuilders/buildCylinderGeometry.js","webpack://convert2xkt/./src/geometryBuilders/buildGridGeometry.js","webpack://convert2xkt/./src/geometryBuilders/buildPlaneGeometry.js","webpack://convert2xkt/./src/geometryBuilders/buildSphereGeometry.js","webpack://convert2xkt/./src/geometryBuilders/buildTorusGeometry.js","webpack://convert2xkt/./src/geometryBuilders/buildVectorTextGeometry.js","webpack://convert2xkt/./src/convert2xkt_browser.js","webpack://convert2xkt/./src/XKTModel/lib/toArraybuffer.js","webpack://convert2xkt/./index.dist.node.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"convert2xkt\"] = factory();\n\telse\n\t\troot[\"convert2xkt\"] = factory();\n})(global, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/polyfills\");","/**\n * @desc Provides info on the XKT generated by xeokit-convert.\n */\nconst XKT_INFO = {\n\n /**\n * The XKT version generated by xeokit-convert.\n *\n * This is the XKT version that's modeled by {@link XKTModel}, serialized\n * by {@link writeXKTModelToArrayBuffer}, and written by {@link convert2xkt}.\n *\n * * Current XKT version: **10**\n * * [XKT format specs](https://github.com/xeokit/xeokit-convert/blob/main/specs/index.md)\n *\n * @property xktVersion\n * @type {number}\n */\n xktVersion: 10\n};\n\nexport {XKT_INFO};","// Some temporary vars to help avoid garbage collection\n\nconst doublePrecision = true;\nconst FloatArrayType = doublePrecision ? Float64Array : Float32Array;\n\nconst tempMat1 = new FloatArrayType(16);\nconst tempMat2 = new FloatArrayType(16);\nconst tempVec4 = new FloatArrayType(4);\n\n/**\n * @private\n */\nconst math = {\n\n MIN_DOUBLE: -Number.MAX_SAFE_INTEGER,\n MAX_DOUBLE: Number.MAX_SAFE_INTEGER,\n\n /**\n * The number of radiians in a degree (0.0174532925).\n * @property DEGTORAD\n * @type {Number}\n */\n DEGTORAD: 0.0174532925,\n\n /**\n * The number of degrees in a radian.\n * @property RADTODEG\n * @type {Number}\n */\n RADTODEG: 57.295779513,\n\n /**\n * Returns a new, uninitialized two-element vector.\n * @method vec2\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec2(values) {\n return new FloatArrayType(values || 2);\n },\n\n /**\n * Returns a new, uninitialized three-element vector.\n * @method vec3\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec3(values) {\n return new FloatArrayType(values || 3);\n },\n\n /**\n * Returns a new, uninitialized four-element vector.\n * @method vec4\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec4(values) {\n return new FloatArrayType(values || 4);\n },\n\n /**\n * Returns a new, uninitialized 3x3 matrix.\n * @method mat3\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n mat3(values) {\n return new FloatArrayType(values || 9);\n },\n\n /**\n * Converts a 3x3 matrix to 4x4\n * @method mat3ToMat4\n * @param mat3 3x3 matrix.\n * @param mat4 4x4 matrix\n * @static\n * @returns {Number[]}\n */\n mat3ToMat4(mat3, mat4 = new FloatArrayType(16)) {\n mat4[0] = mat3[0];\n mat4[1] = mat3[1];\n mat4[2] = mat3[2];\n mat4[3] = 0;\n mat4[4] = mat3[3];\n mat4[5] = mat3[4];\n mat4[6] = mat3[5];\n mat4[7] = 0;\n mat4[8] = mat3[6];\n mat4[9] = mat3[7];\n mat4[10] = mat3[8];\n mat4[11] = 0;\n mat4[12] = 0;\n mat4[13] = 0;\n mat4[14] = 0;\n mat4[15] = 1;\n return mat4;\n },\n\n /**\n * Returns a new, uninitialized 4x4 matrix.\n * @method mat4\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n mat4(values) {\n return new FloatArrayType(values || 16);\n },\n\n /**\n * Converts a 4x4 matrix to 3x3\n * @method mat4ToMat3\n * @param mat4 4x4 matrix.\n * @param mat3 3x3 matrix\n * @static\n * @returns {Number[]}\n */\n mat4ToMat3(mat4, mat3) { // TODO\n //return new FloatArrayType(values || 9);\n },\n\n /**\n * Returns a new UUID.\n * @method createUUID\n * @static\n * @return string The new UUID\n */\n createUUID: ((() => {\n const self = {};\n const lut = [];\n for (let i = 0; i < 256; i++) {\n lut[i] = (i < 16 ? '0' : '') + (i).toString(16);\n }\n return () => {\n const d0 = Math.random() * 0xffffffff | 0;\n const d1 = Math.random() * 0xffffffff | 0;\n const d2 = Math.random() * 0xffffffff | 0;\n const d3 = Math.random() * 0xffffffff | 0;\n return `${lut[d0 & 0xff] + lut[d0 >> 8 & 0xff] + lut[d0 >> 16 & 0xff] + lut[d0 >> 24 & 0xff]}-${lut[d1 & 0xff]}${lut[d1 >> 8 & 0xff]}-${lut[d1 >> 16 & 0x0f | 0x40]}${lut[d1 >> 24 & 0xff]}-${lut[d2 & 0x3f | 0x80]}${lut[d2 >> 8 & 0xff]}-${lut[d2 >> 16 & 0xff]}${lut[d2 >> 24 & 0xff]}${lut[d3 & 0xff]}${lut[d3 >> 8 & 0xff]}${lut[d3 >> 16 & 0xff]}${lut[d3 >> 24 & 0xff]}`;\n };\n }))(),\n\n /**\n * Clamps a value to the given range.\n * @param {Number} value Value to clamp.\n * @param {Number} min Lower bound.\n * @param {Number} max Upper bound.\n * @returns {Number} Clamped result.\n */\n clamp(value, min, max) {\n return Math.max(min, Math.min(max, value));\n },\n\n /**\n * Floating-point modulus\n * @method fmod\n * @static\n * @param {Number} a\n * @param {Number} b\n * @returns {*}\n */\n fmod(a, b) {\n if (a < b) {\n console.error(\"math.fmod : Attempting to find modulus within negative range - would be infinite loop - ignoring\");\n return a;\n }\n while (b <= a) {\n a -= b;\n }\n return a;\n },\n\n /**\n * Negates a four-element vector.\n * @method negateVec4\n * @static\n * @param {Array(Number)} v Vector to negate\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n negateVec4(v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = -v[0];\n dest[1] = -v[1];\n dest[2] = -v[2];\n dest[3] = -v[3];\n return dest;\n },\n\n /**\n * Adds one four-element vector to another.\n * @method addVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n addVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] + v[0];\n dest[1] = u[1] + v[1];\n dest[2] = u[2] + v[2];\n dest[3] = u[3] + v[3];\n return dest;\n },\n\n /**\n * Adds a scalar value to each element of a four-element vector.\n * @method addVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n addVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] + s;\n dest[1] = v[1] + s;\n dest[2] = v[2] + s;\n dest[3] = v[3] + s;\n return dest;\n },\n\n /**\n * Adds one three-element vector to another.\n * @method addVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n addVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] + v[0];\n dest[1] = u[1] + v[1];\n dest[2] = u[2] + v[2];\n return dest;\n },\n\n /**\n * Adds a scalar value to each element of a three-element vector.\n * @method addVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n addVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] + s;\n dest[1] = v[1] + s;\n dest[2] = v[2] + s;\n return dest;\n },\n\n /**\n * Subtracts one four-element vector from another.\n * @method subVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n dest[2] = u[2] - v[2];\n dest[3] = u[3] - v[3];\n return dest;\n },\n\n /**\n * Subtracts one three-element vector from another.\n * @method subVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n dest[2] = u[2] - v[2];\n return dest;\n },\n\n /**\n * Subtracts one two-element vector from another.\n * @method subVec2\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec2(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n return dest;\n },\n\n /**\n * Subtracts a scalar value from each element of a four-element vector.\n * @method subVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n subVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] - s;\n dest[1] = v[1] - s;\n dest[2] = v[2] - s;\n dest[3] = v[3] - s;\n return dest;\n },\n\n /**\n * Sets each element of a 4-element vector to a scalar value minus the value of that element.\n * @method subScalarVec4\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n subScalarVec4(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s - v[0];\n dest[1] = s - v[1];\n dest[2] = s - v[2];\n dest[3] = s - v[3];\n return dest;\n },\n\n /**\n * Multiplies one three-element vector by another.\n * @method mulVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n mulVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] * v[0];\n dest[1] = u[1] * v[1];\n dest[2] = u[2] * v[2];\n dest[3] = u[3] * v[3];\n return dest;\n },\n\n /**\n * Multiplies each element of a four-element vector by a scalar.\n * @method mulVec34calar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n dest[2] = v[2] * s;\n dest[3] = v[3] * s;\n return dest;\n },\n\n /**\n * Multiplies each element of a three-element vector by a scalar.\n * @method mulVec3Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n dest[2] = v[2] * s;\n return dest;\n },\n\n /**\n * Multiplies each element of a two-element vector by a scalar.\n * @method mulVec2Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec2Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n return dest;\n },\n\n /**\n * Divides one three-element vector by another.\n * @method divVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n divVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] / v[0];\n dest[1] = u[1] / v[1];\n dest[2] = u[2] / v[2];\n return dest;\n },\n\n /**\n * Divides one four-element vector by another.\n * @method divVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n divVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] / v[0];\n dest[1] = u[1] / v[1];\n dest[2] = u[2] / v[2];\n dest[3] = u[3] / v[3];\n return dest;\n },\n\n /**\n * Divides a scalar by a three-element vector, returning a new vector.\n * @method divScalarVec3\n * @static\n * @param v vec3\n * @param s scalar\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divScalarVec3(s, v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s / v[0];\n dest[1] = s / v[1];\n dest[2] = s / v[2];\n return dest;\n },\n\n /**\n * Divides a three-element vector by a scalar.\n * @method divVec3Scalar\n * @static\n * @param v vec3\n * @param s scalar\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] / s;\n dest[1] = v[1] / s;\n dest[2] = v[2] / s;\n return dest;\n },\n\n /**\n * Divides a four-element vector by a scalar.\n * @method divVec4Scalar\n * @static\n * @param v vec4\n * @param s scalar\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] / s;\n dest[1] = v[1] / s;\n dest[2] = v[2] / s;\n dest[3] = v[3] / s;\n return dest;\n },\n\n\n /**\n * Divides a scalar by a four-element vector, returning a new vector.\n * @method divScalarVec4\n * @static\n * @param s scalar\n * @param v vec4\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divScalarVec4(s, v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s / v[0];\n dest[1] = s / v[1];\n dest[2] = s / v[2];\n dest[3] = s / v[3];\n return dest;\n },\n\n /**\n * Returns the dot product of two four-element vectors.\n * @method dotVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec4(u, v) {\n return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2] + u[3] * v[3]);\n },\n\n /**\n * Returns the cross product of two four-element vectors.\n * @method cross3Vec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The cross product\n */\n cross3Vec4(u, v) {\n const u0 = u[0];\n const u1 = u[1];\n const u2 = u[2];\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n return [\n u1 * v2 - u2 * v1,\n u2 * v0 - u0 * v2,\n u0 * v1 - u1 * v0,\n 0.0];\n },\n\n /**\n * Returns the cross product of two three-element vectors.\n * @method cross3Vec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The cross product\n */\n cross3Vec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n const x = u[0];\n const y = u[1];\n const z = u[2];\n const x2 = v[0];\n const y2 = v[1];\n const z2 = v[2];\n dest[0] = y * z2 - z * y2;\n dest[1] = z * x2 - x * z2;\n dest[2] = x * y2 - y * x2;\n return dest;\n },\n\n\n sqLenVec4(v) { // TODO\n return math.dotVec4(v, v);\n },\n\n /**\n * Returns the length of a four-element vector.\n * @method lenVec4\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec4(v) {\n return Math.sqrt(math.sqLenVec4(v));\n },\n\n /**\n * Returns the dot product of two three-element vectors.\n * @method dotVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec3(u, v) {\n return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]);\n },\n\n /**\n * Returns the dot product of two two-element vectors.\n * @method dotVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec2(u, v) {\n return (u[0] * v[0] + u[1] * v[1]);\n },\n\n\n sqLenVec3(v) {\n return math.dotVec3(v, v);\n },\n\n\n sqLenVec2(v) {\n return math.dotVec2(v, v);\n },\n\n /**\n * Returns the length of a three-element vector.\n * @method lenVec3\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec3(v) {\n return Math.sqrt(math.sqLenVec3(v));\n },\n\n distVec3: ((() => {\n const vec = new FloatArrayType(3);\n return (v, w) => math.lenVec3(math.subVec3(v, w, vec));\n }))(),\n\n /**\n * Returns the length of a two-element vector.\n * @method lenVec2\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec2(v) {\n return Math.sqrt(math.sqLenVec2(v));\n },\n\n distVec2: ((() => {\n const vec = new FloatArrayType(2);\n return (v, w) => math.lenVec2(math.subVec2(v, w, vec));\n }))(),\n\n /**\n * @method rcpVec3\n * @static\n * @param v vec3\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n *\n */\n rcpVec3(v, dest) {\n return math.divScalarVec3(1.0, v, dest);\n },\n\n /**\n * Normalizes a four-element vector\n * @method normalizeVec4\n * @static\n * @param v vec4\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n *\n */\n normalizeVec4(v, dest) {\n const f = 1.0 / math.lenVec4(v);\n return math.mulVec4Scalar(v, f, dest);\n },\n\n /**\n * Normalizes a three-element vector\n * @method normalizeVec4\n * @static\n */\n normalizeVec3(v, dest) {\n const f = 1.0 / math.lenVec3(v);\n return math.mulVec3Scalar(v, f, dest);\n },\n\n /**\n * Normalizes a two-element vector\n * @method normalizeVec2\n * @static\n */\n normalizeVec2(v, dest) {\n const f = 1.0 / math.lenVec2(v);\n return math.mulVec2Scalar(v, f, dest);\n },\n\n /**\n * Gets the angle between two vectors\n * @method angleVec3\n * @param v\n * @param w\n * @returns {number}\n */\n angleVec3(v, w) {\n let theta = math.dotVec3(v, w) / (Math.sqrt(math.sqLenVec3(v) * math.sqLenVec3(w)));\n theta = theta < -1 ? -1 : (theta > 1 ? 1 : theta); // Clamp to handle numerical problems\n return Math.acos(theta);\n },\n\n /**\n * Creates a three-element vector from the rotation part of a sixteen-element matrix.\n * @param m\n * @param dest\n */\n vec3FromMat4Scale: ((() => {\n\n const tempVec3 = new FloatArrayType(3);\n\n return (m, dest) => {\n\n tempVec3[0] = m[0];\n tempVec3[1] = m[1];\n tempVec3[2] = m[2];\n\n dest[0] = math.lenVec3(tempVec3);\n\n tempVec3[0] = m[4];\n tempVec3[1] = m[5];\n tempVec3[2] = m[6];\n\n dest[1] = math.lenVec3(tempVec3);\n\n tempVec3[0] = m[8];\n tempVec3[1] = m[9];\n tempVec3[2] = m[10];\n\n dest[2] = math.lenVec3(tempVec3);\n\n return dest;\n };\n }))(),\n\n /**\n * Converts an n-element vector to a JSON-serializable\n * array with values rounded to two decimal places.\n */\n vecToArray: ((() => {\n function trunc(v) {\n return Math.round(v * 100000) / 100000\n }\n\n return v => {\n v = Array.prototype.slice.call(v);\n for (let i = 0, len = v.length; i < len; i++) {\n v[i] = trunc(v[i]);\n }\n return v;\n };\n }))(),\n\n /**\n * Converts a 3-element vector from an array to an object of the form ````{x:999, y:999, z:999}````.\n * @param arr\n * @returns {{x: *, y: *, z: *}}\n */\n xyzArrayToObject(arr) {\n return {\"x\": arr[0], \"y\": arr[1], \"z\": arr[2]};\n },\n\n /**\n * Converts a 3-element vector object of the form ````{x:999, y:999, z:999}```` to an array.\n * @param xyz\n * @param [arry]\n * @returns {*[]}\n */\n xyzObjectToArray(xyz, arry) {\n arry = arry || new FloatArrayType(3);\n arry[0] = xyz.x;\n arry[1] = xyz.y;\n arry[2] = xyz.z;\n return arry;\n },\n\n /**\n * Duplicates a 4x4 identity matrix.\n * @method dupMat4\n * @static\n */\n dupMat4(m) {\n return m.slice(0, 16);\n },\n\n /**\n * Extracts a 3x3 matrix from a 4x4 matrix.\n * @method mat4To3\n * @static\n */\n mat4To3(m) {\n return [\n m[0], m[1], m[2],\n m[4], m[5], m[6],\n m[8], m[9], m[10]\n ];\n },\n\n /**\n * Returns a 4x4 matrix with each element set to the given scalar value.\n * @method m4s\n * @static\n */\n m4s(s) {\n return [\n s, s, s, s,\n s, s, s, s,\n s, s, s, s,\n s, s, s, s\n ];\n },\n\n /**\n * Returns a 4x4 matrix with each element set to zero.\n * @method setMat4ToZeroes\n * @static\n */\n setMat4ToZeroes() {\n return math.m4s(0.0);\n },\n\n /**\n * Returns a 4x4 matrix with each element set to 1.0.\n * @method setMat4ToOnes\n * @static\n */\n setMat4ToOnes() {\n return math.m4s(1.0);\n },\n\n /**\n * Returns a 4x4 matrix with each element set to 1.0.\n * @method setMat4ToOnes\n * @static\n */\n diagonalMat4v(v) {\n return new FloatArrayType([\n v[0], 0.0, 0.0, 0.0,\n 0.0, v[1], 0.0, 0.0,\n 0.0, 0.0, v[2], 0.0,\n 0.0, 0.0, 0.0, v[3]\n ]);\n },\n\n /**\n * Returns a 4x4 matrix with diagonal elements set to the given vector.\n * @method diagonalMat4c\n * @static\n */\n diagonalMat4c(x, y, z, w) {\n return math.diagonalMat4v([x, y, z, w]);\n },\n\n /**\n * Returns a 4x4 matrix with diagonal elements set to the given scalar.\n * @method diagonalMat4s\n * @static\n */\n diagonalMat4s(s) {\n return math.diagonalMat4c(s, s, s, s);\n },\n\n /**\n * Returns a 4x4 identity matrix.\n * @method identityMat4\n * @static\n */\n identityMat4(mat = new FloatArrayType(16)) {\n mat[0] = 1.0;\n mat[1] = 0.0;\n mat[2] = 0.0;\n mat[3] = 0.0;\n\n mat[4] = 0.0;\n mat[5] = 1.0;\n mat[6] = 0.0;\n mat[7] = 0.0;\n\n mat[8] = 0.0;\n mat[9] = 0.0;\n mat[10] = 1.0;\n mat[11] = 0.0;\n\n mat[12] = 0.0;\n mat[13] = 0.0;\n mat[14] = 0.0;\n mat[15] = 1.0;\n\n return mat;\n },\n\n /**\n * Returns a 3x3 identity matrix.\n * @method identityMat3\n * @static\n */\n identityMat3(mat = new FloatArrayType(9)) {\n mat[0] = 1.0;\n mat[1] = 0.0;\n mat[2] = 0.0;\n\n mat[3] = 0.0;\n mat[4] = 1.0;\n mat[5] = 0.0;\n\n mat[6] = 0.0;\n mat[7] = 0.0;\n mat[8] = 1.0;\n\n return mat;\n },\n\n /**\n * Tests if the given 4x4 matrix is the identity matrix.\n * @method isIdentityMat4\n * @static\n */\n isIdentityMat4(m) {\n if (m[0] !== 1.0 || m[1] !== 0.0 || m[2] !== 0.0 || m[3] !== 0.0 ||\n m[4] !== 0.0 || m[5] !== 1.0 || m[6] !== 0.0 || m[7] !== 0.0 ||\n m[8] !== 0.0 || m[9] !== 0.0 || m[10] !== 1.0 || m[11] !== 0.0 ||\n m[12] !== 0.0 || m[13] !== 0.0 || m[14] !== 0.0 || m[15] !== 1.0) {\n return false;\n }\n return true;\n },\n\n /**\n * Negates the given 4x4 matrix.\n * @method negateMat4\n * @static\n */\n negateMat4(m, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = -m[0];\n dest[1] = -m[1];\n dest[2] = -m[2];\n dest[3] = -m[3];\n dest[4] = -m[4];\n dest[5] = -m[5];\n dest[6] = -m[6];\n dest[7] = -m[7];\n dest[8] = -m[8];\n dest[9] = -m[9];\n dest[10] = -m[10];\n dest[11] = -m[11];\n dest[12] = -m[12];\n dest[13] = -m[13];\n dest[14] = -m[14];\n dest[15] = -m[15];\n return dest;\n },\n\n /**\n * Adds the given 4x4 matrices together.\n * @method addMat4\n * @static\n */\n addMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n dest[0] = a[0] + b[0];\n dest[1] = a[1] + b[1];\n dest[2] = a[2] + b[2];\n dest[3] = a[3] + b[3];\n dest[4] = a[4] + b[4];\n dest[5] = a[5] + b[5];\n dest[6] = a[6] + b[6];\n dest[7] = a[7] + b[7];\n dest[8] = a[8] + b[8];\n dest[9] = a[9] + b[9];\n dest[10] = a[10] + b[10];\n dest[11] = a[11] + b[11];\n dest[12] = a[12] + b[12];\n dest[13] = a[13] + b[13];\n dest[14] = a[14] + b[14];\n dest[15] = a[15] + b[15];\n return dest;\n },\n\n /**\n * Adds the given scalar to each element of the given 4x4 matrix.\n * @method addMat4Scalar\n * @static\n */\n addMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] + s;\n dest[1] = m[1] + s;\n dest[2] = m[2] + s;\n dest[3] = m[3] + s;\n dest[4] = m[4] + s;\n dest[5] = m[5] + s;\n dest[6] = m[6] + s;\n dest[7] = m[7] + s;\n dest[8] = m[8] + s;\n dest[9] = m[9] + s;\n dest[10] = m[10] + s;\n dest[11] = m[11] + s;\n dest[12] = m[12] + s;\n dest[13] = m[13] + s;\n dest[14] = m[14] + s;\n dest[15] = m[15] + s;\n return dest;\n },\n\n /**\n * Adds the given scalar to each element of the given 4x4 matrix.\n * @method addScalarMat4\n * @static\n */\n addScalarMat4(s, m, dest) {\n return math.addMat4Scalar(m, s, dest);\n },\n\n /**\n * Subtracts the second 4x4 matrix from the first.\n * @method subMat4\n * @static\n */\n subMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n dest[0] = a[0] - b[0];\n dest[1] = a[1] - b[1];\n dest[2] = a[2] - b[2];\n dest[3] = a[3] - b[3];\n dest[4] = a[4] - b[4];\n dest[5] = a[5] - b[5];\n dest[6] = a[6] - b[6];\n dest[7] = a[7] - b[7];\n dest[8] = a[8] - b[8];\n dest[9] = a[9] - b[9];\n dest[10] = a[10] - b[10];\n dest[11] = a[11] - b[11];\n dest[12] = a[12] - b[12];\n dest[13] = a[13] - b[13];\n dest[14] = a[14] - b[14];\n dest[15] = a[15] - b[15];\n return dest;\n },\n\n /**\n * Subtracts the given scalar from each element of the given 4x4 matrix.\n * @method subMat4Scalar\n * @static\n */\n subMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] - s;\n dest[1] = m[1] - s;\n dest[2] = m[2] - s;\n dest[3] = m[3] - s;\n dest[4] = m[4] - s;\n dest[5] = m[5] - s;\n dest[6] = m[6] - s;\n dest[7] = m[7] - s;\n dest[8] = m[8] - s;\n dest[9] = m[9] - s;\n dest[10] = m[10] - s;\n dest[11] = m[11] - s;\n dest[12] = m[12] - s;\n dest[13] = m[13] - s;\n dest[14] = m[14] - s;\n dest[15] = m[15] - s;\n return dest;\n },\n\n /**\n * Subtracts the given scalar from each element of the given 4x4 matrix.\n * @method subScalarMat4\n * @static\n */\n subScalarMat4(s, m, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = s - m[0];\n dest[1] = s - m[1];\n dest[2] = s - m[2];\n dest[3] = s - m[3];\n dest[4] = s - m[4];\n dest[5] = s - m[5];\n dest[6] = s - m[6];\n dest[7] = s - m[7];\n dest[8] = s - m[8];\n dest[9] = s - m[9];\n dest[10] = s - m[10];\n dest[11] = s - m[11];\n dest[12] = s - m[12];\n dest[13] = s - m[13];\n dest[14] = s - m[14];\n dest[15] = s - m[15];\n return dest;\n },\n\n /**\n * Multiplies the two given 4x4 matrix by each other.\n * @method mulMat4\n * @static\n */\n mulMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = a[0];\n\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n const b00 = b[0];\n const b01 = b[1];\n const b02 = b[2];\n const b03 = b[3];\n const b10 = b[4];\n const b11 = b[5];\n const b12 = b[6];\n const b13 = b[7];\n const b20 = b[8];\n const b21 = b[9];\n const b22 = b[10];\n const b23 = b[11];\n const b30 = b[12];\n const b31 = b[13];\n const b32 = b[14];\n const b33 = b[15];\n\n dest[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;\n dest[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;\n dest[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;\n dest[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;\n dest[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;\n dest[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;\n dest[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;\n dest[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;\n dest[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;\n dest[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;\n dest[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;\n dest[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;\n dest[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;\n dest[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;\n dest[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;\n dest[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;\n\n return dest;\n },\n\n /**\n * Multiplies the two given 3x3 matrices by each other.\n * @method mulMat4\n * @static\n */\n mulMat3(a, b, dest) {\n if (!dest) {\n dest = new FloatArrayType(9);\n }\n\n const a11 = a[0];\n const a12 = a[3];\n const a13 = a[6];\n const a21 = a[1];\n const a22 = a[4];\n const a23 = a[7];\n const a31 = a[2];\n const a32 = a[5];\n const a33 = a[8];\n const b11 = b[0];\n const b12 = b[3];\n const b13 = b[6];\n const b21 = b[1];\n const b22 = b[4];\n const b23 = b[7];\n const b31 = b[2];\n const b32 = b[5];\n const b33 = b[8];\n\n dest[0] = a11 * b11 + a12 * b21 + a13 * b31;\n dest[3] = a11 * b12 + a12 * b22 + a13 * b32;\n dest[6] = a11 * b13 + a12 * b23 + a13 * b33;\n\n dest[1] = a21 * b11 + a22 * b21 + a23 * b31;\n dest[4] = a21 * b12 + a22 * b22 + a23 * b32;\n dest[7] = a21 * b13 + a22 * b23 + a23 * b33;\n\n dest[2] = a31 * b11 + a32 * b21 + a33 * b31;\n dest[5] = a31 * b12 + a32 * b22 + a33 * b32;\n dest[8] = a31 * b13 + a32 * b23 + a33 * b33;\n\n return dest;\n },\n\n /**\n * Multiplies each element of the given 4x4 matrix by the given scalar.\n * @method mulMat4Scalar\n * @static\n */\n mulMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] * s;\n dest[1] = m[1] * s;\n dest[2] = m[2] * s;\n dest[3] = m[3] * s;\n dest[4] = m[4] * s;\n dest[5] = m[5] * s;\n dest[6] = m[6] * s;\n dest[7] = m[7] * s;\n dest[8] = m[8] * s;\n dest[9] = m[9] * s;\n dest[10] = m[10] * s;\n dest[11] = m[11] * s;\n dest[12] = m[12] * s;\n dest[13] = m[13] * s;\n dest[14] = m[14] * s;\n dest[15] = m[15] * s;\n return dest;\n },\n\n /**\n * Multiplies the given 4x4 matrix by the given four-element vector.\n * @method mulMat4v4\n * @static\n */\n mulMat4v4(m, v, dest = math.vec4()) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n const v3 = v[3];\n dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3;\n dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3;\n dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3;\n dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3;\n return dest;\n },\n\n /**\n * Transposes the given 4x4 matrix.\n * @method transposeMat4\n * @static\n */\n transposeMat4(mat, dest) {\n // If we are transposing ourselves we can skip a few steps but have to cache some values\n const m4 = mat[4];\n\n const m14 = mat[14];\n const m8 = mat[8];\n const m13 = mat[13];\n const m12 = mat[12];\n const m9 = mat[9];\n if (!dest || mat === dest) {\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a12 = mat[6];\n const a13 = mat[7];\n const a23 = mat[11];\n mat[1] = m4;\n mat[2] = m8;\n mat[3] = m12;\n mat[4] = a01;\n mat[6] = m9;\n mat[7] = m13;\n mat[8] = a02;\n mat[9] = a12;\n mat[11] = m14;\n mat[12] = a03;\n mat[13] = a13;\n mat[14] = a23;\n return mat;\n }\n dest[0] = mat[0];\n dest[1] = m4;\n dest[2] = m8;\n dest[3] = m12;\n dest[4] = mat[1];\n dest[5] = mat[5];\n dest[6] = m9;\n dest[7] = m13;\n dest[8] = mat[2];\n dest[9] = mat[6];\n dest[10] = mat[10];\n dest[11] = m14;\n dest[12] = mat[3];\n dest[13] = mat[7];\n dest[14] = mat[11];\n dest[15] = mat[15];\n return dest;\n },\n\n /**\n * Transposes the given 3x3 matrix.\n *\n * @method transposeMat3\n * @static\n */\n transposeMat3(mat, dest) {\n if (dest === mat) {\n const a01 = mat[1];\n const a02 = mat[2];\n const a12 = mat[5];\n dest[1] = mat[3];\n dest[2] = mat[6];\n dest[3] = a01;\n dest[5] = mat[7];\n dest[6] = a02;\n dest[7] = a12;\n } else {\n dest[0] = mat[0];\n dest[1] = mat[3];\n dest[2] = mat[6];\n dest[3] = mat[1];\n dest[4] = mat[4];\n dest[5] = mat[7];\n dest[6] = mat[2];\n dest[7] = mat[5];\n dest[8] = mat[8];\n }\n return dest;\n },\n\n /**\n * Returns the determinant of the given 4x4 matrix.\n * @method determinantMat4\n * @static\n */\n determinantMat4(mat) {\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = mat[0];\n\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a10 = mat[4];\n const a11 = mat[5];\n const a12 = mat[6];\n const a13 = mat[7];\n const a20 = mat[8];\n const a21 = mat[9];\n const a22 = mat[10];\n const a23 = mat[11];\n const a30 = mat[12];\n const a31 = mat[13];\n const a32 = mat[14];\n const a33 = mat[15];\n return a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 +\n a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 +\n a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 +\n a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 +\n a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 +\n a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33;\n },\n\n /**\n * Returns the inverse of the given 4x4 matrix.\n * @method inverseMat4\n * @static\n */\n inverseMat4(mat, dest) {\n if (!dest) {\n dest = mat;\n }\n\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = mat[0];\n\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a10 = mat[4];\n const a11 = mat[5];\n const a12 = mat[6];\n const a13 = mat[7];\n const a20 = mat[8];\n const a21 = mat[9];\n const a22 = mat[10];\n const a23 = mat[11];\n const a30 = mat[12];\n const a31 = mat[13];\n const a32 = mat[14];\n const a33 = mat[15];\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant (inlined to avoid double-caching)\n const invDet = 1 / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06);\n\n dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;\n dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;\n dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;\n dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;\n dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;\n dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;\n dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;\n dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;\n dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;\n dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;\n dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;\n dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;\n dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;\n dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;\n dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;\n dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;\n\n return dest;\n },\n\n /**\n * Returns the trace of the given 4x4 matrix.\n * @method traceMat4\n * @static\n */\n traceMat4(m) {\n return (m[0] + m[5] + m[10] + m[15]);\n },\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4\n * @static\n */\n translationMat4v(v, dest) {\n const m = dest || math.identityMat4();\n m[12] = v[0];\n m[13] = v[1];\n m[14] = v[2];\n return m;\n },\n\n /**\n * Returns 3x3 translation matrix.\n * @method translationMat3\n * @static\n */\n translationMat3v(v, dest) {\n const m = dest || math.identityMat3();\n m[6] = v[0];\n m[7] = v[1];\n return m;\n },\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4c\n * @static\n */\n translationMat4c: ((() => {\n const xyz = new FloatArrayType(3);\n return (x, y, z, dest) => {\n xyz[0] = x;\n xyz[1] = y;\n xyz[2] = z;\n return math.translationMat4v(xyz, dest);\n };\n }))(),\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4s\n * @static\n */\n translationMat4s(s, dest) {\n return math.translationMat4c(s, s, s, dest);\n },\n\n /**\n * Efficiently post-concatenates a translation to the given matrix.\n * @param v\n * @param m\n */\n translateMat4v(xyz, m) {\n return math.translateMat4c(xyz[0], xyz[1], xyz[2], m);\n },\n\n /**\n * Efficiently post-concatenates a translation to the given matrix.\n * @param x\n * @param y\n * @param z\n * @param m\n */\n OLDtranslateMat4c(x, y, z, m) {\n\n const m12 = m[12];\n m[0] += m12 * x;\n m[4] += m12 * y;\n m[8] += m12 * z;\n\n const m13 = m[13];\n m[1] += m13 * x;\n m[5] += m13 * y;\n m[9] += m13 * z;\n\n const m14 = m[14];\n m[2] += m14 * x;\n m[6] += m14 * y;\n m[10] += m14 * z;\n\n const m15 = m[15];\n m[3] += m15 * x;\n m[7] += m15 * y;\n m[11] += m15 * z;\n\n return m;\n },\n\n translateMat4c(x, y, z, m) {\n\n const m3 = m[3];\n m[0] += m3 * x;\n m[1] += m3 * y;\n m[2] += m3 * z;\n\n const m7 = m[7];\n m[4] += m7 * x;\n m[5] += m7 * y;\n m[6] += m7 * z;\n\n const m11 = m[11];\n m[8] += m11 * x;\n m[9] += m11 * y;\n m[10] += m11 * z;\n\n const m15 = m[15];\n m[12] += m15 * x;\n m[13] += m15 * y;\n m[14] += m15 * z;\n\n return m;\n },\n /**\n * Returns 4x4 rotation matrix.\n * @method rotationMat4v\n * @static\n */\n rotationMat4v(anglerad, axis, m) {\n const ax = math.normalizeVec4([axis[0], axis[1], axis[2], 0.0], []);\n const s = Math.sin(anglerad);\n const c = Math.cos(anglerad);\n const q = 1.0 - c;\n\n const x = ax[0];\n const y = ax[1];\n const z = ax[2];\n\n let xy;\n let yz;\n let zx;\n let xs;\n let ys;\n let zs;\n\n //xx = x * x; used once\n //yy = y * y; used once\n //zz = z * z; used once\n xy = x * y;\n yz = y * z;\n zx = z * x;\n xs = x * s;\n ys = y * s;\n zs = z * s;\n\n m = m || math.mat4();\n\n m[0] = (q * x * x) + c;\n m[1] = (q * xy) + zs;\n m[2] = (q * zx) - ys;\n m[3] = 0.0;\n\n m[4] = (q * xy) - zs;\n m[5] = (q * y * y) + c;\n m[6] = (q * yz) + xs;\n m[7] = 0.0;\n\n m[8] = (q * zx) + ys;\n m[9] = (q * yz) - xs;\n m[10] = (q * z * z) + c;\n m[11] = 0.0;\n\n m[12] = 0.0;\n m[13] = 0.0;\n m[14] = 0.0;\n m[15] = 1.0;\n\n return m;\n },\n\n /**\n * Returns 4x4 rotation matrix.\n * @method rotationMat4c\n * @static\n */\n rotationMat4c(anglerad, x, y, z, mat) {\n return math.rotationMat4v(anglerad, [x, y, z], mat);\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4v\n * @static\n */\n scalingMat4v(v, m = math.identityMat4()) {\n m[0] = v[0];\n m[5] = v[1];\n m[10] = v[2];\n return m;\n },\n\n /**\n * Returns 3x3 scale matrix.\n * @method scalingMat3v\n * @static\n */\n scalingMat3v(v, m = math.identityMat3()) {\n m[0] = v[0];\n m[4] = v[1];\n return m;\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4c\n * @static\n */\n scalingMat4c: ((() => {\n const xyz = new FloatArrayType(3);\n return (x, y, z, dest) => {\n xyz[0] = x;\n xyz[1] = y;\n xyz[2] = z;\n return math.scalingMat4v(xyz, dest);\n };\n }))(),\n\n /**\n * Efficiently post-concatenates a scaling to the given matrix.\n * @method scaleMat4c\n * @param x\n * @param y\n * @param z\n * @param m\n */\n scaleMat4c(x, y, z, m) {\n\n m[0] *= x;\n m[4] *= y;\n m[8] *= z;\n\n m[1] *= x;\n m[5] *= y;\n m[9] *= z;\n\n m[2] *= x;\n m[6] *= y;\n m[10] *= z;\n\n m[3] *= x;\n m[7] *= y;\n m[11] *= z;\n return m;\n },\n\n /**\n * Efficiently post-concatenates a scaling to the given matrix.\n * @method scaleMat4c\n * @param xyz\n * @param m\n */\n scaleMat4v(xyz, m) {\n\n const x = xyz[0];\n const y = xyz[1];\n const z = xyz[2];\n\n m[0] *= x;\n m[4] *= y;\n m[8] *= z;\n m[1] *= x;\n m[5] *= y;\n m[9] *= z;\n m[2] *= x;\n m[6] *= y;\n m[10] *= z;\n m[3] *= x;\n m[7] *= y;\n m[11] *= z;\n\n return m;\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4s\n * @static\n */\n scalingMat4s(s) {\n return math.scalingMat4c(s, s, s);\n },\n\n /**\n * Creates a matrix from a quaternion rotation and vector translation\n *\n * @param {Number[]} q Rotation quaternion\n * @param {Number[]} v Translation vector\n * @param {Number[]} dest Destination matrix\n * @returns {Number[]} dest\n */\n rotationTranslationMat4(q, v, dest = math.mat4()) {\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n dest[0] = 1 - (yy + zz);\n dest[1] = xy + wz;\n dest[2] = xz - wy;\n dest[3] = 0;\n dest[4] = xy - wz;\n dest[5] = 1 - (xx + zz);\n dest[6] = yz + wx;\n dest[7] = 0;\n dest[8] = xz + wy;\n dest[9] = yz - wx;\n dest[10] = 1 - (xx + yy);\n dest[11] = 0;\n dest[12] = v[0];\n dest[13] = v[1];\n dest[14] = v[2];\n dest[15] = 1;\n\n return dest;\n },\n\n /**\n * Gets Euler angles from a 4x4 matrix.\n *\n * @param {Number[]} mat The 4x4 matrix.\n * @param {String} order Desired Euler angle order: \"XYZ\", \"YXZ\", \"ZXY\" etc.\n * @param {Number[]} [dest] Destination Euler angles, created by default.\n * @returns {Number[]} The Euler angles.\n */\n mat4ToEuler(mat, order, dest = math.vec4()) {\n const clamp = math.clamp;\n\n // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n const m11 = mat[0];\n\n const m12 = mat[4];\n const m13 = mat[8];\n const m21 = mat[1];\n const m22 = mat[5];\n const m23 = mat[9];\n const m31 = mat[2];\n const m32 = mat[6];\n const m33 = mat[10];\n\n if (order === 'XYZ') {\n\n dest[1] = Math.asin(clamp(m13, -1, 1));\n\n if (Math.abs(m13) < 0.99999) {\n dest[0] = Math.atan2(-m23, m33);\n dest[2] = Math.atan2(-m12, m11);\n } else {\n dest[0] = Math.atan2(m32, m22);\n dest[2] = 0;\n\n }\n\n } else if (order === 'YXZ') {\n\n dest[0] = Math.asin(-clamp(m23, -1, 1));\n\n if (Math.abs(m23) < 0.99999) {\n dest[1] = Math.atan2(m13, m33);\n dest[2] = Math.atan2(m21, m22);\n } else {\n dest[1] = Math.atan2(-m31, m11);\n dest[2] = 0;\n }\n\n } else if (order === 'ZXY') {\n\n dest[0] = Math.asin(clamp(m32, -1, 1));\n\n if (Math.abs(m32) < 0.99999) {\n dest[1] = Math.atan2(-m31, m33);\n dest[2] = Math.atan2(-m12, m22);\n } else {\n dest[1] = 0;\n dest[2] = Math.atan2(m21, m11);\n }\n\n } else if (order === 'ZYX') {\n\n dest[1] = Math.asin(-clamp(m31, -1, 1));\n\n if (Math.abs(m31) < 0.99999) {\n dest[0] = Math.atan2(m32, m33);\n dest[2] = Math.atan2(m21, m11);\n } else {\n dest[0] = 0;\n dest[2] = Math.atan2(-m12, m22);\n }\n\n } else if (order === 'YZX') {\n\n dest[2] = Math.asin(clamp(m21, -1, 1));\n\n if (Math.abs(m21) < 0.99999) {\n dest[0] = Math.atan2(-m23, m22);\n dest[1] = Math.atan2(-m31, m11);\n } else {\n dest[0] = 0;\n dest[1] = Math.atan2(m13, m33);\n }\n\n } else if (order === 'XZY') {\n\n dest[2] = Math.asin(-clamp(m12, -1, 1));\n\n if (Math.abs(m12) < 0.99999) {\n dest[0] = Math.atan2(m32, m22);\n dest[1] = Math.atan2(m13, m11);\n } else {\n dest[0] = Math.atan2(-m23, m33);\n dest[1] = 0;\n }\n }\n\n return dest;\n },\n\n composeMat4(position, quaternion, scale, mat = math.mat4()) {\n math.quaternionToRotationMat4(quaternion, mat);\n math.scaleMat4v(scale, mat);\n math.translateMat4v(position, mat);\n\n return mat;\n },\n\n decomposeMat4: (() => {\n\n const vec = new FloatArrayType(3);\n const matrix = new FloatArrayType(16);\n\n return function decompose(mat, position, quaternion, scale) {\n\n vec[0] = mat[0];\n vec[1] = mat[1];\n vec[2] = mat[2];\n\n let sx = math.lenVec3(vec);\n\n vec[0] = mat[4];\n vec[1] = mat[5];\n vec[2] = mat[6];\n\n const sy = math.lenVec3(vec);\n\n vec[8] = mat[8];\n vec[9] = mat[9];\n vec[10] = mat[10];\n\n const sz = math.lenVec3(vec);\n\n // if determine is negative, we need to invert one scale\n const det = math.determinantMat4(mat);\n\n if (det < 0) {\n sx = -sx;\n }\n\n position[0] = mat[12];\n position[1] = mat[13];\n position[2] = mat[14];\n\n // scale the rotation part\n matrix.set(mat);\n\n const invSX = 1 / sx;\n const invSY = 1 / sy;\n const invSZ = 1 / sz;\n\n matrix[0] *= invSX;\n matrix[1] *= invSX;\n matrix[2] *= invSX;\n\n matrix[4] *= invSY;\n matrix[5] *= invSY;\n matrix[6] *= invSY;\n\n matrix[8] *= invSZ;\n matrix[9] *= invSZ;\n matrix[10] *= invSZ;\n\n math.mat4ToQuaternion(matrix, quaternion);\n\n scale[0] = sx;\n scale[1] = sy;\n scale[2] = sz;\n\n return this;\n\n };\n\n })(),\n\n /**\n * Returns a 4x4 'lookat' viewing transform matrix.\n * @method lookAtMat4v\n * @param pos vec3 position of the viewer\n * @param target vec3 point the viewer is looking at\n * @param up vec3 pointing \"up\"\n * @param dest mat4 Optional, mat4 matrix will be written into\n *\n * @return {mat4} dest if specified, a new mat4 otherwise\n */\n lookAtMat4v(pos, target, up, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n\n const posx = pos[0];\n const posy = pos[1];\n const posz = pos[2];\n const upx = up[0];\n const upy = up[1];\n const upz = up[2];\n const targetx = target[0];\n const targety = target[1];\n const targetz = target[2];\n\n if (posx === targetx && posy === targety && posz === targetz) {\n return math.identityMat4();\n }\n\n let z0;\n let z1;\n let z2;\n let x0;\n let x1;\n let x2;\n let y0;\n let y1;\n let y2;\n let len;\n\n //vec3.direction(eye, center, z);\n z0 = posx - targetx;\n z1 = posy - targety;\n z2 = posz - targetz;\n\n // normalize (no check needed for 0 because of early return)\n len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);\n z0 *= len;\n z1 *= len;\n z2 *= len;\n\n //vec3.normalize(vec3.cross(up, z, x));\n x0 = upy * z2 - upz * z1;\n x1 = upz * z0 - upx * z2;\n x2 = upx * z1 - upy * z0;\n len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);\n if (!len) {\n x0 = 0;\n x1 = 0;\n x2 = 0;\n } else {\n len = 1 / len;\n x0 *= len;\n x1 *= len;\n x2 *= len;\n }\n\n //vec3.normalize(vec3.cross(z, x, y));\n y0 = z1 * x2 - z2 * x1;\n y1 = z2 * x0 - z0 * x2;\n y2 = z0 * x1 - z1 * x0;\n\n len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);\n if (!len) {\n y0 = 0;\n y1 = 0;\n y2 = 0;\n } else {\n len = 1 / len;\n y0 *= len;\n y1 *= len;\n y2 *= len;\n }\n\n dest[0] = x0;\n dest[1] = y0;\n dest[2] = z0;\n dest[3] = 0;\n dest[4] = x1;\n dest[5] = y1;\n dest[6] = z1;\n dest[7] = 0;\n dest[8] = x2;\n dest[9] = y2;\n dest[10] = z2;\n dest[11] = 0;\n dest[12] = -(x0 * posx + x1 * posy + x2 * posz);\n dest[13] = -(y0 * posx + y1 * posy + y2 * posz);\n dest[14] = -(z0 * posx + z1 * posy + z2 * posz);\n dest[15] = 1;\n\n return dest;\n },\n\n /**\n * Returns a 4x4 'lookat' viewing transform matrix.\n * @method lookAtMat4c\n * @static\n */\n lookAtMat4c(posx, posy, posz, targetx, targety, targetz, upx, upy, upz) {\n return math.lookAtMat4v([posx, posy, posz], [targetx, targety, targetz], [upx, upy, upz], []);\n },\n\n /**\n * Returns a 4x4 orthographic projection matrix.\n * @method orthoMat4c\n * @static\n */\n orthoMat4c(left, right, bottom, top, near, far, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n const rl = (right - left);\n const tb = (top - bottom);\n const fn = (far - near);\n\n dest[0] = 2.0 / rl;\n dest[1] = 0.0;\n dest[2] = 0.0;\n dest[3] = 0.0;\n\n dest[4] = 0.0;\n dest[5] = 2.0 / tb;\n dest[6] = 0.0;\n dest[7] = 0.0;\n\n dest[8] = 0.0;\n dest[9] = 0.0;\n dest[10] = -2.0 / fn;\n dest[11] = 0.0;\n\n dest[12] = -(left + right) / rl;\n dest[13] = -(top + bottom) / tb;\n dest[14] = -(far + near) / fn;\n dest[15] = 1.0;\n\n return dest;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method frustumMat4v\n * @static\n */\n frustumMat4v(fmin, fmax, m) {\n if (!m) {\n m = math.mat4();\n }\n\n const fmin4 = [fmin[0], fmin[1], fmin[2], 0.0];\n const fmax4 = [fmax[0], fmax[1], fmax[2], 0.0];\n\n math.addVec4(fmax4, fmin4, tempMat1);\n math.subVec4(fmax4, fmin4, tempMat2);\n\n const t = 2.0 * fmin4[2];\n\n const tempMat20 = tempMat2[0];\n const tempMat21 = tempMat2[1];\n const tempMat22 = tempMat2[2];\n\n m[0] = t / tempMat20;\n m[1] = 0.0;\n m[2] = 0.0;\n m[3] = 0.0;\n\n m[4] = 0.0;\n m[5] = t / tempMat21;\n m[6] = 0.0;\n m[7] = 0.0;\n\n m[8] = tempMat1[0] / tempMat20;\n m[9] = tempMat1[1] / tempMat21;\n m[10] = -tempMat1[2] / tempMat22;\n m[11] = -1.0;\n\n m[12] = 0.0;\n m[13] = 0.0;\n m[14] = -t * fmax4[2] / tempMat22;\n m[15] = 0.0;\n\n return m;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method frustumMat4v\n * @static\n */\n frustumMat4(left, right, bottom, top, near, far, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n const rl = (right - left);\n const tb = (top - bottom);\n const fn = (far - near);\n dest[0] = (near * 2) / rl;\n dest[1] = 0;\n dest[2] = 0;\n dest[3] = 0;\n dest[4] = 0;\n dest[5] = (near * 2) / tb;\n dest[6] = 0;\n dest[7] = 0;\n dest[8] = (right + left) / rl;\n dest[9] = (top + bottom) / tb;\n dest[10] = -(far + near) / fn;\n dest[11] = -1;\n dest[12] = 0;\n dest[13] = 0;\n dest[14] = -(far * near * 2) / fn;\n dest[15] = 0;\n return dest;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method perspectiveMat4v\n * @static\n */\n perspectiveMat4(fovyrad, aspectratio, znear, zfar, m) {\n const pmin = [];\n const pmax = [];\n\n pmin[2] = znear;\n pmax[2] = zfar;\n\n pmax[1] = pmin[2] * Math.tan(fovyrad / 2.0);\n pmin[1] = -pmax[1];\n\n pmax[0] = pmax[1] * aspectratio;\n pmin[0] = -pmax[0];\n\n return math.frustumMat4v(pmin, pmax, m);\n },\n\n /**\n * Transforms a three-element position by a 4x4 matrix.\n * @method transformPoint3\n * @static\n */\n transformPoint3(m, p, dest = math.vec3()) {\n\n const x = p[0];\n const y = p[1];\n const z = p[2];\n\n dest[0] = (m[0] * x) + (m[4] * y) + (m[8] * z) + m[12];\n dest[1] = (m[1] * x) + (m[5] * y) + (m[9] * z) + m[13];\n dest[2] = (m[2] * x) + (m[6] * y) + (m[10] * z) + m[14];\n\n return dest;\n },\n\n /**\n * Transforms a homogeneous coordinate by a 4x4 matrix.\n * @method transformPoint3\n * @static\n */\n transformPoint4(m, v, dest = math.vec4()) {\n dest[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];\n dest[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];\n dest[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];\n dest[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];\n\n return dest;\n },\n\n\n /**\n * Transforms an array of three-element positions by a 4x4 matrix.\n * @method transformPoints3\n * @static\n */\n transformPoints3(m, points, points2) {\n const result = points2 || [];\n const len = points.length;\n let p0;\n let p1;\n let p2;\n let pi;\n\n // cache values\n const m0 = m[0];\n\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n let r;\n\n for (let i = 0; i < len; ++i) {\n\n // cache values\n pi = points[i];\n\n p0 = pi[0];\n p1 = pi[1];\n p2 = pi[2];\n\n r = result[i] || (result[i] = [0, 0, 0]);\n\n r[0] = (m0 * p0) + (m4 * p1) + (m8 * p2) + m12;\n r[1] = (m1 * p0) + (m5 * p1) + (m9 * p2) + m13;\n r[2] = (m2 * p0) + (m6 * p1) + (m10 * p2) + m14;\n r[3] = (m3 * p0) + (m7 * p1) + (m11 * p2) + m15;\n }\n\n result.length = len;\n\n return result;\n },\n\n /**\n * Transforms an array of positions by a 4x4 matrix.\n * @method transformPositions3\n * @static\n */\n transformPositions3(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 3) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /**\n * Transforms an array of positions by a 4x4 matrix.\n * @method transformPositions4\n * @static\n */\n transformPositions4(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 4) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /**\n * Transforms a three-element vector by a 4x4 matrix.\n * @method transformVec3\n * @static\n */\n transformVec3(m, v, dest) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n dest = dest || this.vec3();\n dest[0] = (m[0] * v0) + (m[4] * v1) + (m[8] * v2);\n dest[1] = (m[1] * v0) + (m[5] * v1) + (m[9] * v2);\n dest[2] = (m[2] * v0) + (m[6] * v1) + (m[10] * v2);\n return dest;\n },\n\n /**\n * Transforms a four-element vector by a 4x4 matrix.\n * @method transformVec4\n * @static\n */\n transformVec4(m, v, dest) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n const v3 = v[3];\n dest = dest || math.vec4();\n dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3;\n dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3;\n dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3;\n dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3;\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the x-axis\n *\n * @method rotateVec3X\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3X(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[0];\n r[1] = p[1] * Math.cos(c) - p[2] * Math.sin(c);\n r[2] = p[1] * Math.sin(c) + p[2] * Math.cos(c);\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the y-axis\n *\n * @method rotateVec3Y\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3Y(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c);\n r[1] = p[1];\n r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c);\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the z-axis\n *\n * @method rotateVec3Z\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3Z(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c);\n r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c);\n r[2] = p[2];\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Transforms a four-element vector by a 4x4 projection matrix.\n *\n * @method projectVec4\n * @param {Number[]} p 3D View-space coordinate\n * @param {Number[]} q 2D Projected coordinate\n * @returns {Number[]} 2D Projected coordinate\n * @static\n */\n projectVec4(p, q) {\n const f = 1.0 / p[3];\n q = q || math.vec2();\n q[0] = v[0] * f;\n q[1] = v[1] * f;\n return q;\n },\n\n /**\n * Unprojects a three-element vector.\n *\n * @method unprojectVec3\n * @param {Number[]} p 3D Projected coordinate\n * @param {Number[]} viewMat View matrix\n * @returns {Number[]} projMat Projection matrix\n * @static\n */\n unprojectVec3: ((() => {\n const mat = new FloatArrayType(16);\n const mat2 = new FloatArrayType(16);\n const mat3 = new FloatArrayType(16);\n return function (p, viewMat, projMat, q) {\n return this.transformVec3(this.mulMat4(this.inverseMat4(viewMat, mat), this.inverseMat4(projMat, mat2), mat3), p, q)\n };\n }))(),\n\n /**\n * Linearly interpolates between two 3D vectors.\n * @method lerpVec3\n * @static\n */\n lerpVec3(t, t1, t2, p1, p2, dest) {\n const result = dest || math.vec3();\n const f = (t - t1) / (t2 - t1);\n result[0] = p1[0] + (f * (p2[0] - p1[0]));\n result[1] = p1[1] + (f * (p2[1] - p1[1]));\n result[2] = p1[2] + (f * (p2[2] - p1[2]));\n return result;\n },\n\n\n /**\n * Flattens a two-dimensional array into a one-dimensional array.\n *\n * @method flatten\n * @static\n * @param {Array of Arrays} a A 2D array\n * @returns Flattened 1D array\n */\n flatten(a) {\n\n const result = [];\n\n let i;\n let leni;\n let j;\n let lenj;\n let item;\n\n for (i = 0, leni = a.length; i < leni; i++) {\n item = a[i];\n for (j = 0, lenj = item.length; j < lenj; j++) {\n result.push(item[j]);\n }\n }\n\n return result;\n },\n\n\n identityQuaternion(dest = math.vec4()) {\n dest[0] = 0.0;\n dest[1] = 0.0;\n dest[2] = 0.0;\n dest[3] = 1.0;\n return dest;\n },\n\n /**\n * Initializes a quaternion from Euler angles.\n *\n * @param {Number[]} euler The Euler angles.\n * @param {String} order Euler angle order: \"XYZ\", \"YXZ\", \"ZXY\" etc.\n * @param {Number[]} [dest] Destination quaternion, created by default.\n * @returns {Number[]} The quaternion.\n */\n eulerToQuaternion(euler, order, dest = math.vec4()) {\n // http://www.mathworks.com/matlabcentral/fileexchange/\n // \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n //\tcontent/SpinCalc.m\n\n const a = (euler[0] * math.DEGTORAD) / 2;\n const b = (euler[1] * math.DEGTORAD) / 2;\n const c = (euler[2] * math.DEGTORAD) / 2;\n\n const c1 = Math.cos(a);\n const c2 = Math.cos(b);\n const c3 = Math.cos(c);\n const s1 = Math.sin(a);\n const s2 = Math.sin(b);\n const s3 = Math.sin(c);\n\n if (order === 'XYZ') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'YXZ') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n\n } else if (order === 'ZXY') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'ZYX') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n\n } else if (order === 'YZX') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'XZY') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n }\n\n return dest;\n },\n\n mat4ToQuaternion(m, dest = math.vec4()) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n const m11 = m[0];\n const m12 = m[4];\n const m13 = m[8];\n const m21 = m[1];\n const m22 = m[5];\n const m23 = m[9];\n const m31 = m[2];\n const m32 = m[6];\n const m33 = m[10];\n let s;\n\n const trace = m11 + m22 + m33;\n\n if (trace > 0) {\n\n s = 0.5 / Math.sqrt(trace + 1.0);\n\n dest[3] = 0.25 / s;\n dest[0] = (m32 - m23) * s;\n dest[1] = (m13 - m31) * s;\n dest[2] = (m21 - m12) * s;\n\n } else if (m11 > m22 && m11 > m33) {\n\n s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);\n\n dest[3] = (m32 - m23) / s;\n dest[0] = 0.25 * s;\n dest[1] = (m12 + m21) / s;\n dest[2] = (m13 + m31) / s;\n\n } else if (m22 > m33) {\n\n s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);\n\n dest[3] = (m13 - m31) / s;\n dest[0] = (m12 + m21) / s;\n dest[1] = 0.25 * s;\n dest[2] = (m23 + m32) / s;\n\n } else {\n\n s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);\n\n dest[3] = (m21 - m12) / s;\n dest[0] = (m13 + m31) / s;\n dest[1] = (m23 + m32) / s;\n dest[2] = 0.25 * s;\n }\n\n return dest;\n },\n\n vec3PairToQuaternion(u, v, dest = math.vec4()) {\n const norm_u_norm_v = Math.sqrt(math.dotVec3(u, u) * math.dotVec3(v, v));\n let real_part = norm_u_norm_v + math.dotVec3(u, v);\n\n if (real_part < 0.00000001 * norm_u_norm_v) {\n\n // If u and v are exactly opposite, rotate 180 degrees\n // around an arbitrary orthogonal axis. Axis normalisation\n // can happen later, when we normalise the quaternion.\n\n real_part = 0.0;\n\n if (Math.abs(u[0]) > Math.abs(u[2])) {\n\n dest[0] = -u[1];\n dest[1] = u[0];\n dest[2] = 0;\n\n } else {\n dest[0] = 0;\n dest[1] = -u[2];\n dest[2] = u[1]\n }\n\n } else {\n\n // Otherwise, build quaternion the standard way.\n math.cross3Vec3(u, v, dest);\n }\n\n dest[3] = real_part;\n\n return math.normalizeQuaternion(dest);\n },\n\n angleAxisToQuaternion(angleAxis, dest = math.vec4()) {\n const halfAngle = angleAxis[3] / 2.0;\n const fsin = Math.sin(halfAngle);\n dest[0] = fsin * angleAxis[0];\n dest[1] = fsin * angleAxis[1];\n dest[2] = fsin * angleAxis[2];\n dest[3] = Math.cos(halfAngle);\n return dest;\n },\n\n quaternionToEuler: ((() => {\n const mat = new FloatArrayType(16);\n return (q, order, dest) => {\n dest = dest || math.vec3();\n math.quaternionToRotationMat4(q, mat);\n math.mat4ToEuler(mat, order, dest);\n return dest;\n };\n }))(),\n\n mulQuaternions(p, q, dest = math.vec4()) {\n const p0 = p[0];\n const p1 = p[1];\n const p2 = p[2];\n const p3 = p[3];\n const q0 = q[0];\n const q1 = q[1];\n const q2 = q[2];\n const q3 = q[3];\n dest[0] = p3 * q0 + p0 * q3 + p1 * q2 - p2 * q1;\n dest[1] = p3 * q1 + p1 * q3 + p2 * q0 - p0 * q2;\n dest[2] = p3 * q2 + p2 * q3 + p0 * q1 - p1 * q0;\n dest[3] = p3 * q3 - p0 * q0 - p1 * q1 - p2 * q2;\n return dest;\n },\n\n vec3ApplyQuaternion(q, vec, dest = math.vec3()) {\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n const qx = q[0];\n const qy = q[1];\n const qz = q[2];\n const qw = q[3];\n\n // calculate quat * vector\n\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = -qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n\n dest[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;\n dest[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;\n dest[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;\n\n return dest;\n },\n\n quaternionToMat4(q, dest) {\n\n dest = math.identityMat4(dest);\n\n const q0 = q[0]; //x\n const q1 = q[1]; //y\n const q2 = q[2]; //z\n const q3 = q[3]; //w\n\n const tx = 2.0 * q0;\n const ty = 2.0 * q1;\n const tz = 2.0 * q2;\n\n const twx = tx * q3;\n const twy = ty * q3;\n const twz = tz * q3;\n\n const txx = tx * q0;\n const txy = ty * q0;\n const txz = tz * q0;\n\n const tyy = ty * q1;\n const tyz = tz * q1;\n const tzz = tz * q2;\n\n dest[0] = 1.0 - (tyy + tzz);\n dest[1] = txy + twz;\n dest[2] = txz - twy;\n\n dest[4] = txy - twz;\n dest[5] = 1.0 - (txx + tzz);\n dest[6] = tyz + twx;\n\n dest[8] = txz + twy;\n dest[9] = tyz - twx;\n\n dest[10] = 1.0 - (txx + tyy);\n\n return dest;\n },\n\n quaternionToRotationMat4(q, m) {\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n m[0] = 1 - (yy + zz);\n m[4] = xy - wz;\n m[8] = xz + wy;\n\n m[1] = xy + wz;\n m[5] = 1 - (xx + zz);\n m[9] = yz - wx;\n\n m[2] = xz - wy;\n m[6] = yz + wx;\n m[10] = 1 - (xx + yy);\n\n // last column\n m[3] = 0;\n m[7] = 0;\n m[11] = 0;\n\n // bottom row\n m[12] = 0;\n m[13] = 0;\n m[14] = 0;\n m[15] = 1;\n\n return m;\n },\n\n normalizeQuaternion(q, dest = q) {\n const len = math.lenVec4([q[0], q[1], q[2], q[3]]);\n dest[0] = q[0] / len;\n dest[1] = q[1] / len;\n dest[2] = q[2] / len;\n dest[3] = q[3] / len;\n return dest;\n },\n\n conjugateQuaternion(q, dest = q) {\n dest[0] = -q[0];\n dest[1] = -q[1];\n dest[2] = -q[2];\n dest[3] = q[3];\n return dest;\n },\n\n inverseQuaternion(q, dest) {\n return math.normalizeQuaternion(math.conjugateQuaternion(q, dest));\n },\n\n quaternionToAngleAxis(q, angleAxis = math.vec4()) {\n q = math.normalizeQuaternion(q, tempVec4);\n const q3 = q[3];\n const angle = 2 * Math.acos(q3);\n const s = Math.sqrt(1 - q3 * q3);\n if (s < 0.001) { // test to avoid divide by zero, s is always positive due to sqrt\n angleAxis[0] = q[0];\n angleAxis[1] = q[1];\n angleAxis[2] = q[2];\n } else {\n angleAxis[0] = q[0] / s;\n angleAxis[1] = q[1] / s;\n angleAxis[2] = q[2] / s;\n }\n angleAxis[3] = angle; // * 57.295779579;\n return angleAxis;\n },\n\n //------------------------------------------------------------------------------------------------------------------\n // Boundaries\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Returns a new, uninitialized 3D axis-aligned bounding box.\n *\n * @private\n */\n AABB3(values) {\n return new FloatArrayType(values || 6);\n },\n\n /**\n * Returns a new, uninitialized 2D axis-aligned bounding box.\n *\n * @private\n */\n AABB2(values) {\n return new FloatArrayType(values || 4);\n },\n\n /**\n * Returns a new, uninitialized 3D oriented bounding box (OBB).\n *\n * @private\n */\n OBB3(values) {\n return new FloatArrayType(values || 32);\n },\n\n /**\n * Returns a new, uninitialized 2D oriented bounding box (OBB).\n *\n * @private\n */\n OBB2(values) {\n return new FloatArrayType(values || 16);\n },\n\n /** Returns a new 3D bounding sphere */\n Sphere3(x, y, z, r) {\n return new FloatArrayType([x, y, z, r]);\n },\n\n /**\n * Transforms an OBB3 by a 4x4 matrix.\n *\n * @private\n */\n transformOBB3(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 4) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /** Returns true if the first AABB contains the second AABB.\n * @param aabb1\n * @param aabb2\n * @returns {boolean}\n */\n containsAABB3: function (aabb1, aabb2) {\n const result = (\n aabb1[0] <= aabb2[0] && aabb2[3] <= aabb1[3] &&\n aabb1[1] <= aabb2[1] && aabb2[4] <= aabb1[4] &&\n aabb1[2] <= aabb2[2] && aabb2[5] <= aabb1[5]);\n return result;\n },\n\n /**\n * Gets the diagonal size of an AABB3 given as minima and maxima.\n *\n * @private\n */\n getAABB3Diag: ((() => {\n\n const min = new FloatArrayType(3);\n const max = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return aabb => {\n\n min[0] = aabb[0];\n min[1] = aabb[1];\n min[2] = aabb[2];\n\n max[0] = aabb[3];\n max[1] = aabb[4];\n max[2] = aabb[5];\n\n math.subVec3(max, min, tempVec3);\n\n return Math.abs(math.lenVec3(tempVec3));\n };\n }))(),\n\n /**\n * Get a diagonal boundary size that is symmetrical about the given point.\n *\n * @private\n */\n getAABB3DiagPoint: ((() => {\n\n const min = new FloatArrayType(3);\n const max = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return (aabb, p) => {\n\n min[0] = aabb[0];\n min[1] = aabb[1];\n min[2] = aabb[2];\n\n max[0] = aabb[3];\n max[1] = aabb[4];\n max[2] = aabb[5];\n\n const diagVec = math.subVec3(max, min, tempVec3);\n\n const xneg = p[0] - aabb[0];\n const xpos = aabb[3] - p[0];\n const yneg = p[1] - aabb[1];\n const ypos = aabb[4] - p[1];\n const zneg = p[2] - aabb[2];\n const zpos = aabb[5] - p[2];\n\n diagVec[0] += (xneg > xpos) ? xneg : xpos;\n diagVec[1] += (yneg > ypos) ? yneg : ypos;\n diagVec[2] += (zneg > zpos) ? zneg : zpos;\n\n return Math.abs(math.lenVec3(diagVec));\n };\n }))(),\n\n /**\n * Gets the center of an AABB.\n *\n * @private\n */\n getAABB3Center(aabb, dest) {\n const r = dest || math.vec3();\n\n r[0] = (aabb[0] + aabb[3]) / 2;\n r[1] = (aabb[1] + aabb[4]) / 2;\n r[2] = (aabb[2] + aabb[5]) / 2;\n\n return r;\n },\n\n /**\n * Gets the center of a 2D AABB.\n *\n * @private\n */\n getAABB2Center(aabb, dest) {\n const r = dest || math.vec2();\n\n r[0] = (aabb[2] + aabb[0]) / 2;\n r[1] = (aabb[3] + aabb[1]) / 2;\n\n return r;\n },\n\n /**\n * Collapses a 3D axis-aligned boundary, ready to expand to fit 3D points.\n * Creates new AABB if none supplied.\n *\n * @private\n */\n collapseAABB3(aabb = math.AABB3()) {\n aabb[0] = math.MAX_DOUBLE;\n aabb[1] = math.MAX_DOUBLE;\n aabb[2] = math.MAX_DOUBLE;\n aabb[3] = -math.MAX_DOUBLE;\n aabb[4] = -math.MAX_DOUBLE;\n aabb[5] = -math.MAX_DOUBLE;\n\n return aabb;\n },\n\n /**\n * Converts an axis-aligned 3D boundary into an oriented boundary consisting of\n * an array of eight 3D positions, one for each corner of the boundary.\n *\n * @private\n */\n AABB3ToOBB3(aabb, obb = math.OBB3()) {\n obb[0] = aabb[0];\n obb[1] = aabb[1];\n obb[2] = aabb[2];\n obb[3] = 1;\n\n obb[4] = aabb[3];\n obb[5] = aabb[1];\n obb[6] = aabb[2];\n obb[7] = 1;\n\n obb[8] = aabb[3];\n obb[9] = aabb[4];\n obb[10] = aabb[2];\n obb[11] = 1;\n\n obb[12] = aabb[0];\n obb[13] = aabb[4];\n obb[14] = aabb[2];\n obb[15] = 1;\n\n obb[16] = aabb[0];\n obb[17] = aabb[1];\n obb[18] = aabb[5];\n obb[19] = 1;\n\n obb[20] = aabb[3];\n obb[21] = aabb[1];\n obb[22] = aabb[5];\n obb[23] = 1;\n\n obb[24] = aabb[3];\n obb[25] = aabb[4];\n obb[26] = aabb[5];\n obb[27] = 1;\n\n obb[28] = aabb[0];\n obb[29] = aabb[4];\n obb[30] = aabb[5];\n obb[31] = 1;\n\n return obb;\n },\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array.\n *\n * @private\n */\n positions3ToAABB3: ((() => {\n\n const p = new FloatArrayType(3);\n\n return (positions, aabb, positionsDecodeMatrix) => {\n aabb = aabb || math.AABB3();\n\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n if (positionsDecodeMatrix) {\n\n p[0] = positions[i + 0];\n p[1] = positions[i + 1];\n p[2] = positions[i + 2];\n\n math.decompressPosition(p, positionsDecodeMatrix, p);\n\n x = p[0];\n y = p[1];\n z = p[2];\n\n } else {\n x = positions[i + 0];\n y = positions[i + 1];\n z = positions[i + 2];\n }\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n };\n }))(),\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array.\n *\n * @private\n */\n OBB3ToAABB3(obb, aabb = math.AABB3()) {\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = obb.length; i < len; i += 4) {\n\n x = obb[i + 0];\n y = obb[i + 1];\n z = obb[i + 2];\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n },\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the given 3D points.\n *\n * @private\n */\n points3ToAABB3(points, aabb = math.AABB3()) {\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = points.length; i < len; i++) {\n\n x = points[i][0];\n y = points[i][1];\n z = points[i][2];\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n },\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D points.\n *\n * @private\n */\n points3ToSphere3: ((() => {\n\n const tempVec3 = new FloatArrayType(3);\n\n return (points, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const numPoints = points.length;\n\n for (i = 0; i < numPoints; i++) {\n x += points[i][0];\n y += points[i][1];\n z += points[i][2];\n }\n\n sphere[0] = x / numPoints;\n sphere[1] = y / numPoints;\n sphere[2] = z / numPoints;\n\n let radius = 0;\n let dist;\n\n for (i = 0; i < numPoints; i++) {\n\n dist = Math.abs(math.lenVec3(math.subVec3(points[i], sphere, tempVec3)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D positions.\n *\n * @private\n */\n positions3ToSphere3: ((() => {\n\n const tempVec3a = new FloatArrayType(3);\n const tempVec3b = new FloatArrayType(3);\n\n return (positions, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const lenPositions = positions.length;\n let radius = 0;\n\n for (i = 0; i < lenPositions; i += 3) {\n x += positions[i];\n y += positions[i + 1];\n z += positions[i + 2];\n }\n\n const numPositions = lenPositions / 3;\n\n sphere[0] = x / numPositions;\n sphere[1] = y / numPositions;\n sphere[2] = z / numPositions;\n\n let dist;\n\n for (i = 0; i < lenPositions; i += 3) {\n\n tempVec3a[0] = positions[i];\n tempVec3a[1] = positions[i + 1];\n tempVec3a[2] = positions[i + 2];\n\n dist = Math.abs(math.lenVec3(math.subVec3(tempVec3a, sphere, tempVec3b)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D points.\n *\n * @private\n */\n OBB3ToSphere3: ((() => {\n\n const point = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return (points, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const lenPoints = points.length;\n const numPoints = lenPoints / 4;\n\n for (i = 0; i < lenPoints; i += 4) {\n x += points[i + 0];\n y += points[i + 1];\n z += points[i + 2];\n }\n\n sphere[0] = x / numPoints;\n sphere[1] = y / numPoints;\n sphere[2] = z / numPoints;\n\n let radius = 0;\n let dist;\n\n for (i = 0; i < lenPoints; i += 4) {\n\n point[0] = points[i + 0];\n point[1] = points[i + 1];\n point[2] = points[i + 2];\n\n dist = Math.abs(math.lenVec3(math.subVec3(point, sphere, tempVec3)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Gets the center of a bounding sphere.\n *\n * @private\n */\n getSphere3Center(sphere, dest = math.vec3()) {\n dest[0] = sphere[0];\n dest[1] = sphere[1];\n dest[2] = sphere[2];\n\n return dest;\n },\n\n /**\n * Expands the first axis-aligned 3D boundary to enclose the second, if required.\n *\n * @private\n */\n expandAABB3(aabb1, aabb2) {\n\n if (aabb1[0] > aabb2[0]) {\n aabb1[0] = aabb2[0];\n }\n\n if (aabb1[1] > aabb2[1]) {\n aabb1[1] = aabb2[1];\n }\n\n if (aabb1[2] > aabb2[2]) {\n aabb1[2] = aabb2[2];\n }\n\n if (aabb1[3] < aabb2[3]) {\n aabb1[3] = aabb2[3];\n }\n\n if (aabb1[4] < aabb2[4]) {\n aabb1[4] = aabb2[4];\n }\n\n if (aabb1[5] < aabb2[5]) {\n aabb1[5] = aabb2[5];\n }\n\n return aabb1;\n },\n\n /**\n * Expands an axis-aligned 3D boundary to enclose the given point, if needed.\n *\n * @private\n */\n expandAABB3Point3(aabb, p) {\n\n if (aabb[0] > p[0]) {\n aabb[0] = p[0];\n }\n\n if (aabb[1] > p[1]) {\n aabb[1] = p[1];\n }\n\n if (aabb[2] > p[2]) {\n aabb[2] = p[2];\n }\n\n if (aabb[3] < p[0]) {\n aabb[3] = p[0];\n }\n\n if (aabb[4] < p[1]) {\n aabb[4] = p[1];\n }\n\n if (aabb[5] < p[2]) {\n aabb[5] = p[2];\n }\n\n return aabb;\n },\n\n /**\n * Calculates the normal vector of a triangle.\n *\n * @private\n */\n triangleNormal(a, b, c, normal = math.vec3()) {\n const p1x = b[0] - a[0];\n const p1y = b[1] - a[1];\n const p1z = b[2] - a[2];\n\n const p2x = c[0] - a[0];\n const p2y = c[1] - a[1];\n const p2z = c[2] - a[2];\n\n const p3x = p1y * p2z - p1z * p2y;\n const p3y = p1z * p2x - p1x * p2z;\n const p3z = p1x * p2y - p1y * p2x;\n\n const mag = Math.sqrt(p3x * p3x + p3y * p3y + p3z * p3z);\n if (mag === 0) {\n normal[0] = 0;\n normal[1] = 0;\n normal[2] = 0;\n } else {\n normal[0] = p3x / mag;\n normal[1] = p3y / mag;\n normal[2] = p3z / mag;\n }\n\n return normal\n }\n};\n\nexport {math};","import {math} from \"../../lib/math.js\";\n\nfunction quantizePositions (positions, lenPositions, aabb, quantizedPositions) {\n const xmin = aabb[0];\n const ymin = aabb[1];\n const zmin = aabb[2];\n const xwid = aabb[3] - xmin;\n const ywid = aabb[4] - ymin;\n const zwid = aabb[5] - zmin;\n const maxInt = 65535;\n const xMultiplier = maxInt / xwid;\n const yMultiplier = maxInt / ywid;\n const zMultiplier = maxInt / zwid;\n const verify = (num) => num >= 0 ? num : 0;\n for (let i = 0; i < lenPositions; i += 3) {\n quantizedPositions[i + 0] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 0] - xmin) * xMultiplier)));\n quantizedPositions[i + 1] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 1] - ymin) * yMultiplier)));\n quantizedPositions[i + 2] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 2] - zmin) * zMultiplier)));\n }\n}\n\nfunction compressPosition(p, aabb, q) {\n const multiplier = new Float32Array([\n aabb[3] !== aabb[0] ? 65535 / (aabb[3] - aabb[0]) : 0,\n aabb[4] !== aabb[1] ? 65535 / (aabb[4] - aabb[1]) : 0,\n aabb[5] !== aabb[2] ? 65535 / (aabb[5] - aabb[2]) : 0\n ]);\n q[0] = Math.max(0, Math.min(65535, Math.floor((p[0] - aabb[0]) * multiplier[0])));\n q[1] = Math.max(0, Math.min(65535, Math.floor((p[1] - aabb[1]) * multiplier[1])));\n q[2] = Math.max(0, Math.min(65535, Math.floor((p[2] - aabb[2]) * multiplier[2])));\n}\n\nvar createPositionsDecodeMatrix = (function () {\n const translate = math.mat4();\n const scale = math.mat4();\n return function (aabb, positionsDecodeMatrix) {\n positionsDecodeMatrix = positionsDecodeMatrix || math.mat4();\n const xmin = aabb[0];\n const ymin = aabb[1];\n const zmin = aabb[2];\n const xwid = aabb[3] - xmin;\n const ywid = aabb[4] - ymin;\n const zwid = aabb[5] - zmin;\n const maxInt = 65535;\n math.identityMat4(translate);\n math.translationMat4v(aabb, translate);\n math.identityMat4(scale);\n math.scalingMat4v([xwid / maxInt, ywid / maxInt, zwid / maxInt], scale);\n math.mulMat4(translate, scale, positionsDecodeMatrix);\n return positionsDecodeMatrix;\n };\n})();\n\nfunction transformAndOctEncodeNormals(modelNormalMatrix, normals, lenNormals, compressedNormals, lenCompressedNormals) {\n // http://jcgt.org/published/0003/02/01/\n let oct, dec, best, currentCos, bestCos;\n let i, ei;\n let localNormal = math.vec3();\n let worldNormal = math.vec3();\n for (i = 0; i < lenNormals; i += 3) {\n localNormal[0] = normals[i];\n localNormal[1] = normals[i + 1];\n localNormal[2] = normals[i + 2];\n\n math.transformVec3(modelNormalMatrix, localNormal, worldNormal);\n math.normalizeVec3(worldNormal, worldNormal);\n\n // Test various combinations of ceil and floor to minimize rounding errors\n best = oct = octEncodeVec3(worldNormal, 0, \"floor\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = bestCos = dot(worldNormal, 0, dec);\n oct = octEncodeVec3(worldNormal, 0, \"ceil\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = dot(worldNormal, 0, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(worldNormal, 0, \"floor\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(worldNormal, 0, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(worldNormal, 0, \"ceil\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(worldNormal, 0, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n compressedNormals[lenCompressedNormals + i + 0] = best[0];\n compressedNormals[lenCompressedNormals + i + 1] = best[1];\n compressedNormals[lenCompressedNormals + i + 2] = 0.0; // Unused\n }\n lenCompressedNormals += lenNormals;\n return lenCompressedNormals;\n}\n\nfunction octEncodeNormals(normals, lenNormals, compressedNormals, lenCompressedNormals) { // http://jcgt.org/published/0003/02/01/\n let oct, dec, best, currentCos, bestCos;\n for (let i = 0; i < lenNormals; i += 3) {\n // Test various combinations of ceil and floor to minimize rounding errors\n best = oct = octEncodeVec3(normals, i, \"floor\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = bestCos = dot(normals, i, dec);\n oct = octEncodeVec3(normals, i, \"ceil\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = dot(normals, i, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(normals, i, \"floor\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(normals, i, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(normals, i, \"ceil\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(normals, i, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n compressedNormals[lenCompressedNormals + i + 0] = best[0];\n compressedNormals[lenCompressedNormals + i + 1] = best[1];\n compressedNormals[lenCompressedNormals + i + 2] = 0.0; // Unused\n }\n lenCompressedNormals += lenNormals;\n return lenCompressedNormals;\n}\n\n/**\n * @private\n */\nfunction octEncodeVec3(array, i, xfunc, yfunc) { // Oct-encode single normal vector in 2 bytes\n let x = array[i] / (Math.abs(array[i]) + Math.abs(array[i + 1]) + Math.abs(array[i + 2]));\n let y = array[i + 1] / (Math.abs(array[i]) + Math.abs(array[i + 1]) + Math.abs(array[i + 2]));\n if (array[i + 2] < 0) {\n let tempx = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n let tempy = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n x = tempx;\n y = tempy;\n }\n return new Int8Array([\n Math[xfunc](x * 127.5 + (x < 0 ? -1 : 0)),\n Math[yfunc](y * 127.5 + (y < 0 ? -1 : 0))\n ]);\n}\n\n/**\n * Decode an oct-encoded normal\n */\nfunction octDecodeVec2(oct) {\n let x = oct[0];\n let y = oct[1];\n x /= x < 0 ? 127 : 128;\n y /= y < 0 ? 127 : 128;\n const z = 1 - Math.abs(x) - Math.abs(y);\n if (z < 0) {\n x = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n y = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n }\n const length = Math.sqrt(x * x + y * y + z * z);\n return [\n x / length,\n y / length,\n z / length\n ];\n}\n\n/**\n * Dot product of a normal in an array against a candidate decoding\n * @private\n */\nfunction dot(array, i, vec3) {\n return array[i] * vec3[0] + array[i + 1] * vec3[1] + array[i + 2] * vec3[2];\n}\n\n/**\n * @private\n */\nconst geometryCompression = {\n quantizePositions,\n compressPosition,\n createPositionsDecodeMatrix,\n transformAndOctEncodeNormals,\n octEncodeNormals,\n};\n\nexport {geometryCompression}","/*----------------------------------------------------------------------------------------------------------------------\n * NOTE: The values of these constants must match those within xeokit-sdk\n *--------------------------------------------------------------------------------------------------------------------*/\n\n/**\n * Texture wrapping mode in which the texture repeats to infinity.\n */\nexport const RepeatWrapping = 1000;\n\n/**\n * Texture wrapping mode in which the last pixel of the texture stretches to the edge of the mesh.\n */\nexport const ClampToEdgeWrapping = 1001;\n\n/**\n * Texture wrapping mode in which the texture repeats to infinity, mirroring on each repeat.\n */\nexport const MirroredRepeatWrapping = 1002;\n\n/**\n * Texture magnification and minification filter that returns the nearest texel to the given sample coordinates.\n */\nexport const NearestFilter = 1003;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and returns the nearest texel to the given sample coordinates.\n */\nexport const NearestMipMapNearestFilter = 1004;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured\n * and returns the nearest texel to the given sample coordinates.\n */\nexport const NearestMipmapNearestFilter = 1004;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\n */\nexport const NearestMipmapLinearFilter = 1005;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\n */\nexport const NearestMipMapLinearFilter = 1005;\n\n/**\n * Texture magnification and minification filter that returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nexport const LinearFilter = 1006;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\n * returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nexport const LinearMipmapNearestFilter = 1007;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\n * returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nexport const LinearMipMapNearestFilter = 1007;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\n * weighted average of those two values.\n */\nexport const LinearMipmapLinearFilter = 1008;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\n * weighted average of those two values.\n */\nexport const LinearMipMapLinearFilter = 1008;\n\n/**\n * Media type for GIF images.\n */\nexport const GIFMediaType = 10000;\n\n/**\n * Media type for JPEG images.\n */\nexport const JPEGMediaType = 10001;\n\n/**\n * Media type for PNG images.\n */\nexport const PNGMediaType = 10002;","import {math} from \"../../lib/math.js\";\n\n/**\n * @private\n */\nconst buildEdgeIndices = (function () {\n\n const uniquePositions = [];\n const indicesLookup = [];\n const indicesReverseLookup = [];\n const weldedIndices = [];\n\n// TODO: Optimize with caching, but need to cater to both compressed and uncompressed positions\n\n const faces = [];\n let numFaces = 0;\n const compa = new Uint16Array(3);\n const compb = new Uint16Array(3);\n const compc = new Uint16Array(3);\n const a = math.vec3();\n const b = math.vec3();\n const c = math.vec3();\n const cb = math.vec3();\n const ab = math.vec3();\n const cross = math.vec3();\n const normal = math.vec3();\n const inverseNormal = math.vec3();\n\n function weldVertices(positions, indices) {\n const positionsMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n let vx;\n let vy;\n let vz;\n let key;\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = Math.pow(10, precisionPoints);\n let i;\n let len;\n let lenUniquePositions = 0;\n for (i = 0, len = positions.length; i < len; i += 3) {\n vx = positions[i];\n vy = positions[i + 1];\n vz = positions[i + 2];\n key = Math.round(vx * precision) + '_' + Math.round(vy * precision) + '_' + Math.round(vz * precision);\n if (positionsMap[key] === undefined) {\n positionsMap[key] = lenUniquePositions / 3;\n uniquePositions[lenUniquePositions++] = vx;\n uniquePositions[lenUniquePositions++] = vy;\n uniquePositions[lenUniquePositions++] = vz;\n }\n indicesLookup[i / 3] = positionsMap[key];\n }\n for (i = 0, len = indices.length; i < len; i++) {\n weldedIndices[i] = indicesLookup[indices[i]];\n indicesReverseLookup[weldedIndices[i]] = indices[i];\n }\n }\n\n function buildFaces(numIndices, positionsDecodeMatrix) {\n numFaces = 0;\n for (let i = 0, len = numIndices; i < len; i += 3) {\n const ia = ((weldedIndices[i]) * 3);\n const ib = ((weldedIndices[i + 1]) * 3);\n const ic = ((weldedIndices[i + 2]) * 3);\n if (positionsDecodeMatrix) {\n compa[0] = uniquePositions[ia];\n compa[1] = uniquePositions[ia + 1];\n compa[2] = uniquePositions[ia + 2];\n compb[0] = uniquePositions[ib];\n compb[1] = uniquePositions[ib + 1];\n compb[2] = uniquePositions[ib + 2];\n compc[0] = uniquePositions[ic];\n compc[1] = uniquePositions[ic + 1];\n compc[2] = uniquePositions[ic + 2];\n // Decode\n math.decompressPosition(compa, positionsDecodeMatrix, a);\n math.decompressPosition(compb, positionsDecodeMatrix, b);\n math.decompressPosition(compc, positionsDecodeMatrix, c);\n } else {\n a[0] = uniquePositions[ia];\n a[1] = uniquePositions[ia + 1];\n a[2] = uniquePositions[ia + 2];\n b[0] = uniquePositions[ib];\n b[1] = uniquePositions[ib + 1];\n b[2] = uniquePositions[ib + 2];\n c[0] = uniquePositions[ic];\n c[1] = uniquePositions[ic + 1];\n c[2] = uniquePositions[ic + 2];\n }\n math.subVec3(c, b, cb);\n math.subVec3(a, b, ab);\n math.cross3Vec3(cb, ab, cross);\n math.normalizeVec3(cross, normal);\n const face = faces[numFaces] || (faces[numFaces] = {normal: math.vec3()});\n face.normal[0] = normal[0];\n face.normal[1] = normal[1];\n face.normal[2] = normal[2];\n numFaces++;\n }\n }\n\n return function (positions, indices, positionsDecodeMatrix, edgeThreshold) {\n weldVertices(positions, indices);\n buildFaces(indices.length, positionsDecodeMatrix);\n const edgeIndices = [];\n const thresholdDot = Math.cos(math.DEGTORAD * edgeThreshold);\n const edges = {};\n let edge1;\n let edge2;\n let index1;\n let index2;\n let key;\n let largeIndex = false;\n let edge;\n let normal1;\n let normal2;\n let dot;\n let ia;\n let ib;\n for (let i = 0, len = indices.length; i < len; i += 3) {\n const faceIndex = i / 3;\n for (let j = 0; j < 3; j++) {\n edge1 = weldedIndices[i + j];\n edge2 = weldedIndices[i + ((j + 1) % 3)];\n index1 = Math.min(edge1, edge2);\n index2 = Math.max(edge1, edge2);\n key = index1 + ',' + index2;\n if (edges[key] === undefined) {\n edges[key] = {\n index1: index1,\n index2: index2,\n face1: faceIndex,\n face2: undefined,\n };\n } else {\n edges[key].face2 = faceIndex;\n }\n }\n }\n for (key in edges) {\n edge = edges[key];\n // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n if (edge.face2 !== undefined) {\n normal1 = faces[edge.face1].normal;\n normal2 = faces[edge.face2].normal;\n inverseNormal[0] = -normal2[0];\n inverseNormal[1] = -normal2[1];\n inverseNormal[2] = -normal2[2];\n dot = Math.abs(math.dotVec3(normal1, normal2));\n const dot2 = Math.abs(math.dotVec3(normal1, inverseNormal));\n if (dot > thresholdDot && dot2 > thresholdDot) {\n continue;\n }\n }\n ia = indicesReverseLookup[edge.index1];\n ib = indicesReverseLookup[edge.index2];\n if (!largeIndex && ia > 65535 || ib > 65535) {\n largeIndex = true;\n }\n edgeIndices.push(ia);\n edgeIndices.push(ib);\n }\n return (largeIndex) ? new Uint32Array(edgeIndices) : new Uint16Array(edgeIndices);\n };\n})();\n\n\nexport {buildEdgeIndices};","/**\n * Uses edge adjacency counts to identify if the given triangle mesh can be rendered with backface culling enabled.\n *\n * If all edges are connected to exactly two triangles, then the mesh will likely be a closed solid, and we can safely\n * render it with backface culling enabled.\n *\n * Otherwise, the mesh is a surface, and we must render it with backface culling disabled.\n *\n * @private\n */\nconst isTriangleMeshSolid = (indices, positions, vertexIndexMapping, edges) => {\n\n function compareIndexPositions(a, b)\n {\n let posA, posB;\n\n for (let i = 0; i < 3; i++) {\n posA = positions [a*3+i];\n posB = positions [b*3+i];\n\n if (posA !== posB) {\n return posB - posA;\n }\n }\n\n return 0;\n };\n\n // Group together indices corresponding to same position coordinates\n let newIndices = indices.slice ().sort (compareIndexPositions);\n\n // Calculate the mapping:\n // - from original index in indices array\n // - to indices-for-unique-positions\n let uniqueVertexIndex = null;\n\n for (let i = 0, len = newIndices.length; i < len; i++) {\n if (i == 0 || 0 != compareIndexPositions (\n newIndices[i],\n newIndices[i-1],\n )) {\n // different position\n uniqueVertexIndex = newIndices [i];\n }\n\n vertexIndexMapping [\n newIndices[i]\n ] = uniqueVertexIndex;\n }\n\n // Generate the list of edges\n for (let i = 0, len = indices.length; i < len; i += 3) {\n\n const a = vertexIndexMapping[indices[i]];\n const b = vertexIndexMapping[indices[i+1]];\n const c = vertexIndexMapping[indices[i+2]];\n\n let a2 = a;\n let b2 = b;\n let c2 = c;\n\n if (a > b && a > c) {\n if (b > c) {\n a2 = a;\n b2 = b;\n c2 = c;\n } else {\n a2 = a;\n b2 = c;\n c2 = b;\n }\n } else if (b > a && b > c) {\n if (a > c) {\n a2 = b;\n b2 = a;\n c2 = c;\n } else {\n a2 = b;\n b2 = c;\n c2 = a;\n }\n } else if (c > a && c > b) {\n if (a > b) {\n a2 = c;\n b2 = a;\n c2 = b;\n } else {\n a2 = c;\n b2 = b;\n c2 = a;\n }\n }\n\n edges[i+0] = [\n a2, b2\n ];\n edges[i+1] = [\n b2, c2\n ];\n\n if (a2 > c2) {\n const temp = c2;\n c2 = a2;\n a2 = temp;\n }\n\n edges[i+2] = [\n c2, a2\n ];\n }\n\n // Group semantically equivalent edgdes together\n function compareEdges (e1, e2) {\n let a, b;\n\n for (let i = 0; i < 2; i++) {\n a = e1[i];\n b = e2[i];\n\n if (b !== a) {\n return b - a;\n }\n }\n\n return 0;\n }\n\n edges = edges.slice(0, indices.length);\n\n edges.sort (compareEdges);\n\n // Make sure each edge is used exactly twice\n let sameEdgeCount = 0;\n\n for (let i = 0; i < edges.length; i++)\n {\n if (i === 0 || 0 !== compareEdges (\n edges[i], edges[i-1]\n )) {\n // different edge\n if (0 !== i && sameEdgeCount !== 2)\n {\n return false;\n }\n\n sameEdgeCount = 1;\n }\n else\n {\n // same edge\n sameEdgeCount++;\n }\n }\n\n if (edges.length > 0 && sameEdgeCount !== 2)\n {\n return false;\n }\n\n // Each edge is used exactly twice, this is a\n // watertight surface and hence a solid geometry.\n return true;\n};\n\nexport {isTriangleMeshSolid};","/**\n * Represents the usage of a {@link XKTGeometry} by an {@link XKTEntity}.\n *\n * * Created by {@link XKTModel#createEntity}\n * * Stored in {@link XKTEntity#meshes} and {@link XKTModel#meshesList}\n * * Has an {@link XKTGeometry}, and an optional {@link XKTTextureSet}, both of which it can share with other {@link XKTMesh}es\n * * Has {@link XKTMesh#color}, {@link XKTMesh#opacity}, {@link XKTMesh#metallic} and {@link XKTMesh#roughness} PBR attributes\n * @class XKTMesh\n */\nclass XKTMesh {\n\n /**\n * @private\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTMesh in {@link XKTModel#meshes}.\n *\n * @type {Number}\n */\n this.meshId = cfg.meshId;\n\n /**\n * Index of this XKTMesh in {@link XKTModel#meshesList};\n *\n * @type {Number}\n */\n this.meshIndex = cfg.meshIndex;\n\n /**\n * The 4x4 modeling transform matrix.\n *\n * Transform is relative to the center of the {@link XKTTile} that contains this XKTMesh's {@link XKTEntity},\n * which is given in {@link XKTMesh#entity}.\n *\n * When the ````XKTEntity```` shares its {@link XKTGeometry}s with other ````XKTEntity````s, this matrix is used\n * to transform this XKTMesh's XKTGeometry into World-space. When this XKTMesh does not share its ````XKTGeometry````,\n * then this matrix is ignored.\n *\n * @type {Number[]}\n */\n this.matrix = cfg.matrix;\n\n /**\n * The instanced {@link XKTGeometry}.\n *\n * @type {XKTGeometry}\n */\n this.geometry = cfg.geometry;\n\n /**\n * RGB color of this XKTMesh.\n *\n * @type {Float32Array}\n */\n this.color = cfg.color || new Float32Array([1, 1, 1]);\n\n /**\n * PBR metallness of this XKTMesh.\n *\n * @type {Number}\n */\n this.metallic = (cfg.metallic !== null && cfg.metallic !== undefined) ? cfg.metallic : 0;\n\n /**\n * PBR roughness of this XKTMesh.\n * The {@link XKTTextureSet} that defines the appearance of this XKTMesh.\n *\n * @type {Number}\n * @type {XKTTextureSet}\n */\n this.roughness = (cfg.roughness !== null && cfg.roughness !== undefined) ? cfg.roughness : 1;\n\n /**\n * Opacity of this XKTMesh.\n *\n * @type {Number}\n */\n this.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? cfg.opacity : 1.0;\n\n /**\n * The {@link XKTTextureSet} that defines the appearance of this XKTMesh.\n *\n * @type {XKTTextureSet}\n */\n this.textureSet = cfg.textureSet;\n\n /**\n * The owner {@link XKTEntity}.\n *\n * Set by {@link XKTModel#createEntity}.\n *\n * @type {XKTEntity}\n */\n this.entity = null; // Set after instantiation, when the Entity is known\n }\n}\n\nexport {XKTMesh};","/**\n * An element of reusable geometry within an {@link XKTModel}.\n *\n * * Created by {@link XKTModel#createGeometry}\n * * Stored in {@link XKTModel#geometries} and {@link XKTModel#geometriesList}\n * * Referenced by {@link XKTMesh}s, which belong to {@link XKTEntity}s\n *\n * @class XKTGeometry\n */\nclass XKTGeometry {\n\n /**\n * @private\n * @param {*} cfg Configuration for the XKTGeometry.\n * @param {Number} cfg.geometryId Unique ID of the geometry in {@link XKTModel#geometries}.\n * @param {String} cfg.primitiveType Type of this geometry - \"triangles\", \"points\" or \"lines\" so far.\n * @param {Number} cfg.geometryIndex Index of this XKTGeometry in {@link XKTModel#geometriesList}.\n * @param {Float64Array} cfg.positions Non-quantized 3D vertex positions.\n * @param {Float32Array} cfg.normals Non-compressed vertex normals.\n * @param {Uint8Array} cfg.colorsCompressed Unsigned 8-bit integer RGBA vertex colors.\n * @param {Float32Array} cfg.uvs Non-compressed vertex UV coordinates.\n * @param {Uint32Array} cfg.indices Indices to organize the vertex positions and normals into triangles.\n * @param {Uint32Array} cfg.edgeIndices Indices to organize the vertex positions into edges.\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTGeometry in {@link XKTModel#geometries}.\n *\n * @type {Number}\n */\n this.geometryId = cfg.geometryId;\n\n /**\n * The type of primitive - \"triangles\" | \"points\" | \"lines\".\n *\n * @type {String}\n */\n this.primitiveType = cfg.primitiveType;\n\n /**\n * Index of this XKTGeometry in {@link XKTModel#geometriesList}.\n *\n * @type {Number}\n */\n this.geometryIndex = cfg.geometryIndex;\n\n /**\n * The number of {@link XKTMesh}s that reference this XKTGeometry.\n *\n * @type {Number}\n */\n this.numInstances = 0;\n\n /**\n * Non-quantized 3D vertex positions.\n *\n * Defined for all primitive types.\n *\n * @type {Float64Array}\n */\n this.positions = cfg.positions;\n\n /**\n * Quantized vertex positions.\n *\n * Defined for all primitive types.\n *\n * This array is later created from {@link XKTGeometry#positions} by {@link XKTModel#finalize}.\n *\n * @type {Uint16Array}\n */\n this.positionsQuantized = new Uint16Array(cfg.positions.length);\n\n /**\n * Non-compressed 3D vertex normals.\n *\n * Defined only for triangle primitives. Can be null if we want xeokit to auto-generate them. Ignored for points and lines.\n *\n * @type {Float32Array}\n */\n this.normals = cfg.normals;\n\n /**\n * Compressed vertex normals.\n *\n * Defined only for triangle primitives. Ignored for points and lines.\n *\n * This array is later created from {@link XKTGeometry#normals} by {@link XKTModel#finalize}.\n *\n * Will be null if {@link XKTGeometry#normals} is also null.\n *\n * @type {Int8Array}\n */\n this.normalsOctEncoded = null;\n\n /**\n * Compressed RGBA vertex colors.\n *\n * Defined only for point primitives. Ignored for triangles and lines.\n *\n * @type {Uint8Array}\n */\n this.colorsCompressed = cfg.colorsCompressed;\n\n /**\n * Non-compressed vertex UVs.\n *\n * @type {Float32Array}\n */\n this.uvs = cfg.uvs;\n\n /**\n * Compressed vertex UVs.\n *\n * @type {Uint16Array}\n */\n this.uvsCompressed = cfg.uvsCompressed;\n\n /**\n * Indices that organize the vertex positions and normals as triangles.\n *\n * Defined only for triangle and lines primitives. Ignored for points.\n *\n * @type {Uint32Array}\n */\n this.indices = cfg.indices;\n\n /**\n * Indices that organize the vertex positions as edges.\n *\n * Defined only for triangle primitives. Ignored for points and lines.\n *\n * @type {Uint32Array}\n */\n this.edgeIndices = cfg.edgeIndices;\n\n /**\n * When {@link XKTGeometry#primitiveType} is \"triangles\", this is ````true```` when this geometry is a watertight mesh.\n *\n * Defined only for triangle primitives. Ignored for points and lines.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * @type {boolean}\n */\n this.solid = false;\n }\n\n /**\n * Convenience property that is ````true```` when {@link XKTGeometry#numInstances} is greater that one.\n * @returns {boolean}\n */\n get reused() {\n return (this.numInstances > 1);\n }\n}\n\nexport {XKTGeometry};","import {math} from \"../lib/math.js\";\n\n/**\n * An object within an {@link XKTModel}.\n *\n * * Created by {@link XKTModel#createEntity}\n * * Stored in {@link XKTModel#entities} and {@link XKTModel#entitiesList}\n * * Has one or more {@link XKTMesh}s, each having an {@link XKTGeometry}\n *\n * @class XKTEntity\n */\nclass XKTEntity {\n\n /**\n * @private\n * @param entityId\n * @param meshes\n */\n constructor(entityId, meshes) {\n\n /**\n * Unique ID of this ````XKTEntity```` in {@link XKTModel#entities}.\n *\n * For a BIM model, this will be an IFC product ID.\n *\n * We can also use {@link XKTModel#createMetaObject} to create an {@link XKTMetaObject} to specify metadata for\n * this ````XKTEntity````. To associate the {@link XKTMetaObject} with our {@link XKTEntity}, we give\n * {@link XKTMetaObject#metaObjectId} the same value as {@link XKTEntity#entityId}.\n *\n * @type {String}\n */\n this.entityId = entityId;\n\n /**\n * Index of this ````XKTEntity```` in {@link XKTModel#entitiesList}.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * @type {Number}\n */\n this.entityIndex = null;\n\n /**\n * A list of {@link XKTMesh}s that indicate which {@link XKTGeometry}s are used by this Entity.\n *\n * @type {XKTMesh[]}\n */\n this.meshes = meshes;\n\n /**\n * World-space axis-aligned bounding box (AABB) that encloses the {@link XKTGeometry#positions} of\n * the {@link XKTGeometry}s that are used by this ````XKTEntity````.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * @type {Float32Array}\n */\n this.aabb = math.AABB3();\n\n /**\n * Indicates if this ````XKTEntity```` shares {@link XKTGeometry}s with other {@link XKTEntity}'s.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * Note that when an ````XKTEntity```` shares ````XKTGeometrys````, it shares **all** of its ````XKTGeometrys````. An ````XKTEntity````\n * never shares only some of its ````XKTGeometrys```` - it always shares either the whole set or none at all.\n *\n * @type {Boolean}\n */\n this.hasReusedGeometries = false;\n }\n}\n\nexport {XKTEntity};","/**\n * @desc A box-shaped 3D region within an {@link XKTModel} that contains {@link XKTEntity}s.\n *\n * * Created by {@link XKTModel#finalize}\n * * Stored in {@link XKTModel#tilesList}\n *\n * @class XKTTile\n */\nclass XKTTile {\n\n /**\n * Creates a new XKTTile.\n *\n * @private\n * @param aabb\n * @param entities\n */\n constructor(aabb, entities) {\n\n /**\n * Axis-aligned World-space bounding box that encloses the {@link XKTEntity}'s within this Tile.\n *\n * @type {Float64Array}\n */\n this.aabb = aabb;\n\n /**\n * The {@link XKTEntity}'s within this XKTTile.\n *\n * @type {XKTEntity[]}\n */\n this.entities = entities;\n }\n}\n\nexport {XKTTile};","/**\n * A kd-Tree node, used internally by {@link XKTModel}.\n *\n * @private\n */\nclass KDNode {\n\n /**\n * Create a KDNode with an axis-aligned 3D World-space boundary.\n */\n constructor(aabb) {\n\n /**\n * The axis-aligned 3D World-space boundary of this KDNode.\n *\n * @type {Float64Array}\n */\n this.aabb = aabb;\n\n /**\n * The {@link XKTEntity}s within this KDNode.\n */\n this.entities = null;\n\n /**\n * The left child KDNode.\n */\n this.left = null;\n\n /**\n * The right child KDNode.\n */\n this.right = null;\n }\n}\n\nexport {KDNode};","/**\n * A meta object within an {@link XKTModel}.\n *\n * These are plugged together into a parent-child hierarchy to represent structural\n * metadata for the {@link XKTModel}.\n *\n * The leaf XKTMetaObjects are usually associated with\n * an {@link XKTEntity}, which they do so by sharing the same ID,\n * ie. where {@link XKTMetaObject#metaObjectId} == {@link XKTEntity#entityId}.\n *\n * * Created by {@link XKTModel#createMetaObject}\n * * Stored in {@link XKTModel#metaObjects} and {@link XKTModel#metaObjectsList}\n * * Has an ID, a type, and a human-readable name\n * * May have a parent {@link XKTMetaObject}\n * * When no children, is usually associated with an {@link XKTEntity}\n *\n * @class XKTMetaObject\n */\nclass XKTMetaObject {\n\n /**\n * @private\n * @param metaObjectId\n * @param propertySetIds\n * @param metaObjectType\n * @param metaObjectName\n * @param parentMetaObjectId\n */\n constructor(metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId) {\n\n /**\n * Unique ID of this ````XKTMetaObject```` in {@link XKTModel#metaObjects}.\n *\n * For a BIM model, this will be an IFC product ID.\n *\n * If this is a leaf XKTMetaObject, where it is not a parent to any other XKTMetaObject,\n * then this will be equal to the ID of an {@link XKTEntity} in {@link XKTModel#entities},\n * ie. where {@link XKTMetaObject#metaObjectId} == {@link XKTEntity#entityId}.\n *\n * @type {String}\n */\n this.metaObjectId = metaObjectId;\n\n /**\n * Unique ID of one or more property sets that contains additional metadata about this\n * {@link XKTMetaObject}. The property sets can be stored in an external system, or\n * within the {@link XKTModel}, as {@link XKTPropertySet}s within {@link XKTModel#propertySets}.\n *\n * @type {String[]}\n */\n this.propertySetIds = propertySetIds;\n\n /**\n * Indicates the XKTMetaObject meta object type.\n *\n * This defaults to \"default\".\n *\n * @type {string}\n */\n this.metaObjectType = metaObjectType;\n\n /**\n * Indicates the XKTMetaObject meta object name.\n *\n * This defaults to {@link XKTMetaObject#metaObjectId}.\n *\n * @type {string}\n */\n this.metaObjectName = metaObjectName;\n\n /**\n * The parent XKTMetaObject, if any.\n *\n * Will be null if there is no parent.\n *\n * @type {String}\n */\n this.parentMetaObjectId = parentMetaObjectId;\n }\n}\n\nexport {XKTMetaObject};","/**\n * A property set within an {@link XKTModel}.\n *\n * These are shared among {@link XKTMetaObject}s.\n *\n * * Created by {@link XKTModel#createPropertySet}\n * * Stored in {@link XKTModel#propertySets} and {@link XKTModel#propertySetsList}\n * * Has an ID, a type, and a human-readable name\n *\n * @class XKTPropertySet\n */\nclass XKTPropertySet {\n\n /**\n * @private\n */\n constructor(propertySetId, propertySetType, propertySetName, properties) {\n\n /**\n * Unique ID of this ````XKTPropertySet```` in {@link XKTModel#propertySets}.\n *\n * @type {String}\n */\n this.propertySetId = propertySetId;\n\n /**\n * Indicates the ````XKTPropertySet````'s type.\n *\n * This defaults to \"default\".\n *\n * @type {string}\n */\n this.propertySetType = propertySetType;\n\n /**\n * Indicates the XKTPropertySet meta object name.\n *\n * This defaults to {@link XKTPropertySet#propertySetId}.\n *\n * @type {string}\n */\n this.propertySetName = propertySetName;\n\n /**\n * The properties within this ````XKTPropertySet````.\n *\n * @type {*[]}\n */\n this.properties = properties;\n }\n}\n\nexport {XKTPropertySet};","/**\n * A texture shared by {@link XKTTextureSet}s.\n *\n * * Created by {@link XKTModel#createTexture}\n * * Stored in {@link XKTTextureSet#textures}, {@link XKTModel#textures} and {@link XKTModel#texturesList}\n *\n * @class XKTTexture\n */\nimport {RepeatWrapping, LinearMipMapNearestFilter} from \"../constants\";\n\nclass XKTTexture {\n\n /**\n * @private\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTTexture in {@link XKTModel#textures}.\n *\n * @type {Number}\n */\n this.textureId = cfg.textureId;\n\n /**\n * Index of this XKTTexture in {@link XKTModel#texturesList};\n *\n * @type {Number}\n */\n this.textureIndex = cfg.textureIndex;\n\n /**\n * Texture image data.\n *\n * @type {Buffer}\n */\n this.imageData = cfg.imageData;\n\n /**\n * Which material channel this texture is applied to, as determined by its {@link XKTTextureSet}s.\n *\n * @type {Number}\n */\n this.channel = null;\n\n /**\n * Width of this XKTTexture.\n *\n * @type {Number}\n */\n this.width = cfg.width;\n\n /**\n * Height of this XKTTexture.\n *\n * @type {Number}\n */\n this.height = cfg.height;\n\n /**\n * Texture file source.\n *\n * @type {String}\n */\n this.src = cfg.src;\n\n /**\n * Whether this XKTTexture is to be compressed.\n *\n * @type {Boolean}\n */\n this.compressed = (!!cfg.compressed);\n\n /**\n * Media type of this XKTTexture.\n *\n * Supported values are {@link GIFMediaType}, {@link PNGMediaType} and {@link JPEGMediaType}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.mediaType = cfg.mediaType;\n\n /**\n * How the texture is sampled when a texel covers less than one pixel. Supported values\n * are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter},\n * {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter}\n * and {@link LinearMipMapLinearFilter}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.minFilter = cfg.minFilter || LinearMipMapNearestFilter;\n\n /**\n * How the texture is sampled when a texel covers more than one pixel. Supported values\n * are {@link LinearFilter} and {@link NearestFilter}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.magFilter = cfg.magFilter || LinearMipMapNearestFilter;\n\n /**\n * S wrapping mode.\n *\n * Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.wrapS = cfg.wrapS || RepeatWrapping;\n\n /**\n * T wrapping mode.\n *\n * Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.wrapT = cfg.wrapT || RepeatWrapping;\n\n /**\n * R wrapping mode.\n *\n * Ignored for compressed textures.\n *\n * Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n *\n * @type {*|number}\n */\n this.wrapR = cfg.wrapR || RepeatWrapping\n }\n}\n\nexport {XKTTexture};","/**\n * A set of textures shared by {@link XKTMesh}es.\n *\n * * Created by {@link XKTModel#createTextureSet}\n * * Registered in {@link XKTMesh#material}, {@link XKTModel#materials} and {@link XKTModel#.textureSetsList}\n *\n * @class XKTMetalRoughMaterial\n */\nclass XKTTextureSet {\n\n /**\n * @private\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTTextureSet in {@link XKTModel#materials}.\n *\n * @type {Number}\n */\n this.textureSetId = cfg.textureSetId;\n\n /**\n * Index of this XKTTexture in {@link XKTModel#texturesList};\n *\n * @type {Number}\n */\n this.textureSetIndex = cfg.textureSetIndex;\n\n /**\n * Identifies the material type.\n *\n * @type {Number}\n */\n this.materialType = cfg.materialType;\n\n /**\n * Index of this XKTTextureSet in {@link XKTModel#meshesList};\n *\n * @type {Number}\n */\n this.materialIndex = cfg.materialIndex;\n\n /**\n * The number of {@link XKTMesh}s that reference this XKTTextureSet.\n *\n * @type {Number}\n */\n this.numInstances = 0;\n\n /**\n * RGBA {@link XKTTexture} containing base color in RGB and opacity in A.\n *\n * @type {XKTTexture}\n */\n this.colorTexture = cfg.colorTexture;\n\n /**\n * RGBA {@link XKTTexture} containing metallic and roughness factors in R and G.\n *\n * @type {XKTTexture}\n */\n this.metallicRoughnessTexture = cfg.metallicRoughnessTexture;\n\n /**\n * RGBA {@link XKTTexture} with surface normals in RGB.\n *\n * @type {XKTTexture}\n */\n this.normalsTexture = cfg.normalsTexture;\n\n /**\n * RGBA {@link XKTTexture} with emissive color in RGB.\n *\n * @type {XKTTexture}\n */\n this.emissiveTexture = cfg.emissiveTexture;\n\n /**\n * RGBA {@link XKTTexture} with ambient occlusion factors in RGB.\n *\n * @type {XKTTexture}\n */\n this.occlusionTexture = cfg.occlusionTexture;\n }\n}\n\nexport {XKTTextureSet};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/core\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/textures\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/images\");","import {math} from \"../lib/math.js\";\nimport {geometryCompression} from \"./lib/geometryCompression.js\";\nimport {buildEdgeIndices} from \"./lib/buildEdgeIndices.js\";\nimport {isTriangleMeshSolid} from \"./lib/isTriangleMeshSolid.js\";\n\nimport {XKTMesh} from './XKTMesh.js';\nimport {XKTGeometry} from './XKTGeometry.js';\nimport {XKTEntity} from './XKTEntity.js';\nimport {XKTTile} from './XKTTile.js';\nimport {KDNode} from \"./KDNode.js\";\nimport {XKTMetaObject} from \"./XKTMetaObject.js\";\nimport {XKTPropertySet} from \"./XKTPropertySet.js\";\nimport {mergeVertices} from \"../lib/mergeVertices.js\";\nimport {XKT_INFO} from \"../XKT_INFO.js\";\nimport {XKTTexture} from \"./XKTTexture\";\nimport {XKTTextureSet} from \"./XKTTextureSet\";\nimport {encode, load} from \"@loaders.gl/core\";\nimport {KTX2BasisWriter} from \"@loaders.gl/textures\";\nimport {ImageLoader} from '@loaders.gl/images';\n\nconst tempVec4a = math.vec4([0, 0, 0, 1]);\nconst tempVec4b = math.vec4([0, 0, 0, 1]);\n\nconst tempMat4 = math.mat4();\nconst tempMat4b = math.mat4();\n\nconst kdTreeDimLength = new Float64Array(3);\n\n// XKT texture types\n\nconst COLOR_TEXTURE = 0;\nconst METALLIC_ROUGHNESS_TEXTURE = 1;\nconst NORMALS_TEXTURE = 2;\nconst EMISSIVE_TEXTURE = 3;\nconst OCCLUSION_TEXTURE = 4;\n\n// KTX2 encoding options for each texture type\n\nconst TEXTURE_ENCODING_OPTIONS = {}\nTEXTURE_ENCODING_OPTIONS[COLOR_TEXTURE] = {\n useSRGB: true,\n qualityLevel: 50,\n encodeUASTC: true,\n mipmaps: true\n};\nTEXTURE_ENCODING_OPTIONS[EMISSIVE_TEXTURE] = {\n useSRGB: true,\n encodeUASTC: true,\n qualityLevel: 10,\n mipmaps: false\n};\nTEXTURE_ENCODING_OPTIONS[METALLIC_ROUGHNESS_TEXTURE] = {\n useSRGB: false,\n encodeUASTC: true,\n qualityLevel: 50,\n mipmaps: true // Needed for GGX roughness shading\n};\nTEXTURE_ENCODING_OPTIONS[NORMALS_TEXTURE] = {\n useSRGB: false,\n encodeUASTC: true,\n qualityLevel: 10,\n mipmaps: false\n};\nTEXTURE_ENCODING_OPTIONS[OCCLUSION_TEXTURE] = {\n useSRGB: false,\n encodeUASTC: true,\n qualityLevel: 10,\n mipmaps: false\n};\n\n/**\n * A document model that represents the contents of an .XKT file.\n *\n * * An XKTModel contains {@link XKTTile}s, which spatially subdivide the model into axis-aligned, box-shaped regions.\n * * Each {@link XKTTile} contains {@link XKTEntity}s, which represent the objects within its region.\n * * Each {@link XKTEntity} has {@link XKTMesh}s, which each have a {@link XKTGeometry}. Each {@link XKTGeometry} can be shared by multiple {@link XKTMesh}s.\n * * Import models into an XKTModel using {@link parseGLTFJSONIntoXKTModel}, {@link parseIFCIntoXKTModel}, {@link parseCityJSONIntoXKTModel} etc.\n * * Build an XKTModel programmatically using {@link XKTModel#createGeometry}, {@link XKTModel#createMesh} and {@link XKTModel#createEntity}.\n * * Serialize an XKTModel to an ArrayBuffer using {@link writeXKTModelToArrayBuffer}.\n *\n * ## Usage\n *\n * See [main docs page](/docs/#javascript-api) for usage examples.\n *\n * @class XKTModel\n */\nclass XKTModel {\n\n /**\n * Constructs a new XKTModel.\n *\n * @param {*} [cfg] Configuration\n * @param {Number} [cfg.edgeThreshold=10]\n * @param {Number} [cfg.minTileSize=500]\n */\n constructor(cfg = {}) {\n\n /**\n * The model's ID, if available.\n *\n * Will be \"default\" by default.\n *\n * @type {String}\n */\n this.modelId = cfg.modelId || \"default\";\n\n /**\n * The project ID, if available.\n *\n * Will be an empty string by default.\n *\n * @type {String}\n */\n this.projectId = cfg.projectId || \"\";\n\n /**\n * The revision ID, if available.\n *\n * Will be an empty string by default.\n *\n * @type {String}\n */\n this.revisionId = cfg.revisionId || \"\";\n\n /**\n * The model author, if available.\n *\n * Will be an empty string by default.\n *\n * @property author\n * @type {String}\n */\n this.author = cfg.author || \"\";\n\n /**\n * The date the model was created, if available.\n *\n * Will be an empty string by default.\n *\n * @property createdAt\n * @type {String}\n */\n this.createdAt = cfg.createdAt || \"\";\n\n /**\n * The application that created the model, if available.\n *\n * Will be an empty string by default.\n *\n * @property creatingApplication\n * @type {String}\n */\n this.creatingApplication = cfg.creatingApplication || \"\";\n\n /**\n * The model schema version, if available.\n *\n * In the case of IFC, this could be \"IFC2x3\" or \"IFC4\", for example.\n *\n * Will be an empty string by default.\n *\n * @property schema\n * @type {String}\n */\n this.schema = cfg.schema || \"\";\n\n /**\n * The XKT format version.\n *\n * @property xktVersion;\n * @type {number}\n */\n this.xktVersion = XKT_INFO.xktVersion;\n\n /**\n *\n * @type {Number|number}\n */\n this.edgeThreshold = cfg.edgeThreshold || 10;\n\n /**\n * Minimum diagonal size of the boundary of an {@link XKTTile}.\n *\n * @type {Number|number}\n */\n this.minTileSize = cfg.minTileSize || 500;\n\n /**\n * Optional overall AABB that contains all the {@link XKTEntity}s we'll create in this model, if previously known.\n *\n * This is the AABB of a complete set of input files that are provided as a split-model set for conversion.\n *\n * This is used to help the {@link XKTTile.aabb}s within split models align neatly with each other, as we\n * build them with a k-d tree in {@link XKTModel#finalize}. Without this, the AABBs of the different parts\n * tend to misalign slightly, resulting in excess number of {@link XKTTile}s, which degrades memory and rendering\n * performance when the XKT is viewer in the xeokit Viewer.\n */\n this.modelAABB = cfg.modelAABB;\n\n /**\n * Map of {@link XKTPropertySet}s within this XKTModel, each mapped to {@link XKTPropertySet#propertySetId}.\n *\n * Created by {@link XKTModel#createPropertySet}.\n *\n * @type {{String:XKTPropertySet}}\n */\n this.propertySets = {};\n\n /**\n * {@link XKTPropertySet}s within this XKTModel.\n *\n * Each XKTPropertySet holds its position in this list in {@link XKTPropertySet#propertySetIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTPropertySet[]}\n */\n this.propertySetsList = [];\n\n /**\n * Map of {@link XKTMetaObject}s within this XKTModel, each mapped to {@link XKTMetaObject#metaObjectId}.\n *\n * Created by {@link XKTModel#createMetaObject}.\n *\n * @type {{String:XKTMetaObject}}\n */\n this.metaObjects = {};\n\n /**\n * {@link XKTMetaObject}s within this XKTModel.\n *\n * Each XKTMetaObject holds its position in this list in {@link XKTMetaObject#metaObjectIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTMetaObject[]}\n */\n this.metaObjectsList = [];\n\n /**\n * The positions of all shared {@link XKTGeometry}s are de-quantized using this singular\n * de-quantization matrix.\n *\n * This de-quantization matrix is generated from the collective Local-space boundary of the\n * positions of all shared {@link XKTGeometry}s.\n *\n * @type {Float32Array}\n */\n this.reusedGeometriesDecodeMatrix = new Float32Array(16);\n\n /**\n * Map of {@link XKTGeometry}s within this XKTModel, each mapped to {@link XKTGeometry#geometryId}.\n *\n * Created by {@link XKTModel#createGeometry}.\n *\n * @type {{Number:XKTGeometry}}\n */\n this.geometries = {};\n\n /**\n * List of {@link XKTGeometry}s within this XKTModel, in the order they were created.\n *\n * Each XKTGeometry holds its position in this list in {@link XKTGeometry#geometryIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTGeometry[]}\n */\n this.geometriesList = [];\n\n /**\n * Map of {@link XKTTexture}s within this XKTModel, each mapped to {@link XKTTexture#textureId}.\n *\n * Created by {@link XKTModel#createTexture}.\n *\n * @type {{Number:XKTTexture}}\n */\n this.textures = {};\n\n /**\n * List of {@link XKTTexture}s within this XKTModel, in the order they were created.\n *\n * Each XKTTexture holds its position in this list in {@link XKTTexture#textureIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTTexture[]}\n */\n this.texturesList = [];\n\n /**\n * Map of {@link XKTTextureSet}s within this XKTModel, each mapped to {@link XKTTextureSet#textureSetId}.\n *\n * Created by {@link XKTModel#createTextureSet}.\n *\n * @type {{Number:XKTTextureSet}}\n */\n this.textureSets = {};\n\n /**\n * List of {@link XKTTextureSet}s within this XKTModel, in the order they were created.\n *\n * Each XKTTextureSet holds its position in this list in {@link XKTTextureSet#textureSetIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTTextureSet[]}\n */\n this.textureSetsList = [];\n\n /**\n * Map of {@link XKTMesh}s within this XKTModel, each mapped to {@link XKTMesh#meshId}.\n *\n * Created by {@link XKTModel#createMesh}.\n *\n * @type {{Number:XKTMesh}}\n */\n this.meshes = {};\n\n /**\n * List of {@link XKTMesh}s within this XKTModel, in the order they were created.\n *\n * Each XKTMesh holds its position in this list in {@link XKTMesh#meshIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTMesh[]}\n */\n this.meshesList = [];\n\n /**\n * Map of {@link XKTEntity}s within this XKTModel, each mapped to {@link XKTEntity#entityId}.\n *\n * Created by {@link XKTModel#createEntity}.\n *\n * @type {{String:XKTEntity}}\n */\n this.entities = {};\n\n /**\n * {@link XKTEntity}s within this XKTModel.\n *\n * Each XKTEntity holds its position in this list in {@link XKTEntity#entityIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTEntity[]}\n */\n this.entitiesList = [];\n\n /**\n * {@link XKTTile}s within this XKTModel.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTTile[]}\n */\n this.tilesList = [];\n\n /**\n * The axis-aligned 3D World-space boundary of this XKTModel.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {Float64Array}\n */\n this.aabb = math.AABB3();\n\n /**\n * Indicates if this XKTModel has been finalized.\n *\n * Set ````true```` by {@link XKTModel#finalize}.\n *\n * @type {boolean}\n */\n this.finalized = false;\n }\n\n /**\n * Creates an {@link XKTPropertySet} within this XKTModel.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {String} params.propertySetId Unique ID for the {@link XKTPropertySet}.\n * @param {String} [params.propertySetType=\"default\"] A meta type for the {@link XKTPropertySet}.\n * @param {String} [params.propertySetName] Human-readable name for the {@link XKTPropertySet}. Defaults to the ````propertySetId```` parameter.\n * @param {String[]} params.properties Properties for the {@link XKTPropertySet}.\n * @returns {XKTPropertySet} The new {@link XKTPropertySet}.\n */\n createPropertySet(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.propertySetId === null || params.propertySetId === undefined) {\n throw \"Parameter expected: params.propertySetId\";\n }\n\n if (params.properties === null || params.properties === undefined) {\n throw \"Parameter expected: params.properties\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more property sets\");\n return;\n }\n\n if (this.propertySets[params.propertySetId]) {\n // console.error(\"XKTPropertySet already exists with this ID: \" + params.propertySetId);\n return;\n }\n\n const propertySetId = params.propertySetId;\n const propertySetType = params.propertySetType || \"Default\";\n const propertySetName = params.propertySetName || params.propertySetId;\n const properties = params.properties || [];\n\n const propertySet = new XKTPropertySet(propertySetId, propertySetType, propertySetName, properties);\n\n this.propertySets[propertySetId] = propertySet;\n this.propertySetsList.push(propertySet);\n\n return propertySet;\n }\n\n /**\n * Creates an {@link XKTMetaObject} within this XKTModel.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {String} params.metaObjectId Unique ID for the {@link XKTMetaObject}.\n * @param {String} params.propertySetIds ID of one or more property sets that contains additional metadata about\n * this {@link XKTMetaObject}. The property sets could be stored externally (ie not managed at all by the XKT file),\n * or could be {@link XKTPropertySet}s within {@link XKTModel#propertySets}.\n * @param {String} [params.metaObjectType=\"default\"] A meta type for the {@link XKTMetaObject}. Can be anything,\n * but is usually an IFC type, such as \"IfcSite\" or \"IfcWall\".\n * @param {String} [params.metaObjectName] Human-readable name for the {@link XKTMetaObject}. Defaults to the ````metaObjectId```` parameter.\n * @param {String} [params.parentMetaObjectId] ID of the parent {@link XKTMetaObject}, if any. Defaults to the ````metaObjectId```` parameter.\n * @returns {XKTMetaObject} The new {@link XKTMetaObject}.\n */\n createMetaObject(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.metaObjectId === null || params.metaObjectId === undefined) {\n throw \"Parameter expected: params.metaObjectId\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more meta objects\");\n return;\n }\n\n if (this.metaObjects[params.metaObjectId]) {\n // console.error(\"XKTMetaObject already exists with this ID: \" + params.metaObjectId);\n return;\n }\n\n const metaObjectId = params.metaObjectId;\n const propertySetIds = params.propertySetIds;\n const metaObjectType = params.metaObjectType || \"Default\";\n const metaObjectName = params.metaObjectName || params.metaObjectId;\n const parentMetaObjectId = params.parentMetaObjectId;\n\n const metaObject = new XKTMetaObject(metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId);\n\n this.metaObjects[metaObjectId] = metaObject;\n this.metaObjectsList.push(metaObject);\n\n if (!parentMetaObjectId) {\n if (!this._rootMetaObject) {\n this._rootMetaObject = metaObject;\n }\n }\n\n return metaObject;\n }\n\n /**\n * Creates an {@link XKTTexture} within this XKTModel.\n *\n * Registers the new {@link XKTTexture} in {@link XKTModel#textures} and {@link XKTModel#texturesList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {Number} params.textureId Unique ID for the {@link XKTTexture}.\n * @param {String} [params.src] Source of an image file for the texture.\n * @param {Buffer} [params.imageData] Image data for the texture.\n * @param {Number} [params.mediaType] Media type (ie. MIME type) of ````imageData````. Supported values are {@link GIFMediaType}, {@link PNGMediaType} and {@link JPEGMediaType}.\n * @param {Number} [params.width] Texture width, used with ````imageData````. Ignored for compressed textures.\n * @param {Number} [params.height] Texture height, used with ````imageData````. Ignored for compressed textures.\n * @param {Boolean} [params.compressed=true] Whether to compress the texture.\n * @param {Number} [params.minFilter=LinearMipMapNearestFilter] How the texture is sampled when a texel covers less than one pixel. Supported\n * values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter},\n * {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}. Ignored for compressed textures.\n * @param {Number} [params.magFilter=LinearMipMapNearestFilter] How the texture is sampled when a texel covers more than one pixel. Supported values\n * are {@link LinearFilter} and {@link NearestFilter}. Ignored for compressed textures.\n * @param {Number} [params.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures.\n * @param {Number} [params.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures.\n * {@param {Number} [params.wrapR=RepeatWrapping] Wrap parameter for texture coordinate *R*. Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures.\n * @returns {XKTTexture} The new {@link XKTTexture}.\n */\n createTexture(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.textureId === null || params.textureId === undefined) {\n throw \"Parameter expected: params.textureId\";\n }\n\n if (!params.imageData && !params.src) {\n throw \"Parameter expected: params.imageData or params.src\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more textures\");\n return;\n }\n\n if (this.textures[params.textureId]) {\n console.error(\"XKTTexture already exists with this ID: \" + params.textureId);\n return;\n }\n\n if (params.src) {\n const fileExt = params.src.split('.').pop();\n if (fileExt !== \"jpg\" && fileExt !== \"jpeg\" && fileExt !== \"png\") {\n console.error(`XKTModel does not support image files with extension '${fileExt}' - won't create texture '${params.textureId}`);\n return;\n }\n }\n\n const textureId = params.textureId;\n\n const texture = new XKTTexture({\n textureId,\n imageData: params.imageData,\n mediaType: params.mediaType,\n minFilter: params.minFilter,\n magFilter: params.magFilter,\n wrapS: params.wrapS,\n wrapT: params.wrapT,\n wrapR: params.wrapR,\n width: params.width,\n height: params.height,\n compressed: (params.compressed !== false),\n src: params.src\n });\n\n this.textures[textureId] = texture;\n this.texturesList.push(texture);\n\n return texture;\n }\n\n /**\n * Creates an {@link XKTTextureSet} within this XKTModel.\n *\n * Registers the new {@link XKTTextureSet} in {@link XKTModel#textureSets} and {@link XKTModel#.textureSetsList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {Number} params.textureSetId Unique ID for the {@link XKTTextureSet}.\n * @param {*} [params.colorTextureId] ID of *RGBA* base color {@link XKTTexture}, with color in *RGB* and alpha in *A*.\n * @param {*} [params.metallicRoughnessTextureId] ID of *RGBA* metal-roughness {@link XKTTexture}, with the metallic factor in *R*, and roughness factor in *G*.\n * @param {*} [params.normalsTextureId] ID of *RGBA* normal {@link XKTTexture}, with normal map vectors in *RGB*.\n * @param {*} [params.emissiveTextureId] ID of *RGBA* emissive {@link XKTTexture}, with emissive color in *RGB*.\n * @param {*} [params.occlusionTextureId] ID of *RGBA* occlusion {@link XKTTexture}, with occlusion factor in *R*.\n * @returns {XKTTextureSet} The new {@link XKTTextureSet}.\n */\n createTextureSet(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.textureSetId === null || params.textureSetId === undefined) {\n throw \"Parameter expected: params.textureSetId\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more textureSets\");\n return;\n }\n\n if (this.textureSets[params.textureSetId]) {\n console.error(\"XKTTextureSet already exists with this ID: \" + params.textureSetId);\n return;\n }\n\n let colorTexture;\n if (params.colorTextureId !== undefined && params.colorTextureId !== null) {\n colorTexture = this.textures[params.colorTextureId];\n if (!colorTexture) {\n console.error(`Texture not found: ${params.colorTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n colorTexture.channel = COLOR_TEXTURE;\n }\n\n let metallicRoughnessTexture;\n if (params.metallicRoughnessTextureId !== undefined && params.metallicRoughnessTextureId !== null) {\n metallicRoughnessTexture = this.textures[params.metallicRoughnessTextureId];\n if (!metallicRoughnessTexture) {\n console.error(`Texture not found: ${params.metallicRoughnessTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n metallicRoughnessTexture.channel = METALLIC_ROUGHNESS_TEXTURE;\n }\n\n let normalsTexture;\n if (params.normalsTextureId !== undefined && params.normalsTextureId !== null) {\n normalsTexture = this.textures[params.normalsTextureId];\n if (!normalsTexture) {\n console.error(`Texture not found: ${params.normalsTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n normalsTexture.channel = NORMALS_TEXTURE;\n }\n\n let emissiveTexture;\n if (params.emissiveTextureId !== undefined && params.emissiveTextureId !== null) {\n emissiveTexture = this.textures[params.emissiveTextureId];\n if (!emissiveTexture) {\n console.error(`Texture not found: ${params.emissiveTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n emissiveTexture.channel = EMISSIVE_TEXTURE;\n }\n\n let occlusionTexture;\n if (params.occlusionTextureId !== undefined && params.occlusionTextureId !== null) {\n occlusionTexture = this.textures[params.occlusionTextureId];\n if (!occlusionTexture) {\n console.error(`Texture not found: ${params.occlusionTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n occlusionTexture.channel = OCCLUSION_TEXTURE;\n }\n\n const textureSet = new XKTTextureSet({\n textureSetId: params.textureSetId,\n textureSetIndex: this.textureSetsList.length,\n colorTexture,\n metallicRoughnessTexture,\n normalsTexture,\n emissiveTexture,\n occlusionTexture\n });\n\n this.textureSets[params.textureSetId] = textureSet;\n this.textureSetsList.push(textureSet);\n\n return textureSet;\n }\n\n /**\n * Creates an {@link XKTGeometry} within this XKTModel.\n *\n * Registers the new {@link XKTGeometry} in {@link XKTModel#geometries} and {@link XKTModel#geometriesList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {Number} params.geometryId Unique ID for the {@link XKTGeometry}.\n * @param {String} params.primitiveType The type of {@link XKTGeometry}: \"triangles\", \"lines\" or \"points\".\n * @param {Float64Array} params.positions Floating-point Local-space vertex positions for the {@link XKTGeometry}. Required for all primitive types.\n * @param {Number[]} [params.normals] Floating-point vertex normals for the {@link XKTGeometry}. Only used with triangles primitives. Ignored for points and lines.\n * @param {Number[]} [params.colors] Floating-point RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.\n * @param {Number[]} [params.colorsCompressed] Integer RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.\n * @param {Number[]} [params.uvs] Floating-point vertex UV coordinates for the {@link XKTGeometry}. Alias for ````uv````.\n * @param {Number[]} [params.uv] Floating-point vertex UV coordinates for the {@link XKTGeometry}. Alias for ````uvs````.\n * @param {Number[]} [params.colorsCompressed] Integer RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.\n * @param {Uint32Array} [params.indices] Indices for the {@link XKTGeometry}. Required for triangles and lines primitives. Ignored for points.\n * @param {Number} [params.edgeThreshold=10]\n * @returns {XKTGeometry} The new {@link XKTGeometry}.\n */\n createGeometry(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.geometryId === null || params.geometryId === undefined) {\n throw \"Parameter expected: params.geometryId\";\n }\n\n if (!params.primitiveType) {\n throw \"Parameter expected: params.primitiveType\";\n }\n\n if (!params.positions) {\n throw \"Parameter expected: params.positions\";\n }\n\n const triangles = params.primitiveType === \"triangles\";\n const points = params.primitiveType === \"points\";\n const lines = params.primitiveType === \"lines\";\n const line_strip = params.primitiveType === \"line-strip\";\n const line_loop = params.primitiveType === \"line-loop\";\n const triangle_strip = params.primitiveType === \"triangle-strip\";\n const triangle_fan = params.primitiveType === \"triangle-fan\";\n\n if (!triangles && !points && !lines && !line_strip && !line_loop) {\n throw \"Unsupported value for params.primitiveType: \"\n + params.primitiveType\n + \"' - supported values are 'triangles', 'points', 'lines', 'line-strip', 'triangle-strip' and 'triangle-fan\";\n }\n\n if (triangles) {\n if (!params.indices) {\n params.indices = this._createDefaultIndices()\n throw \"Parameter expected for 'triangles' primitive: params.indices\";\n }\n }\n\n if (points) {\n if (!params.colors && !params.colorsCompressed) {\n throw \"Parameter expected for 'points' primitive: params.colors or params.colorsCompressed\";\n }\n }\n\n if (lines) {\n if (!params.indices) {\n throw \"Parameter expected for 'lines' primitive: params.indices\";\n }\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more geometries\");\n return;\n }\n\n if (this.geometries[params.geometryId]) {\n console.error(\"XKTGeometry already exists with this ID: \" + params.geometryId);\n return;\n }\n\n const geometryId = params.geometryId;\n const primitiveType = params.primitiveType;\n const positions = new Float64Array(params.positions); // May modify in #finalize\n\n const xktGeometryCfg = {\n geometryId: geometryId,\n geometryIndex: this.geometriesList.length,\n primitiveType: primitiveType,\n positions: positions,\n uvs: params.uvs || params.uv\n }\n\n if (triangles) {\n if (params.normals) {\n xktGeometryCfg.normals = new Float32Array(params.normals);\n }\n if (params.indices) {\n xktGeometryCfg.indices = params.indices;\n } else {\n xktGeometryCfg.indices = this._createDefaultIndices(positions.length / 3);\n }\n }\n\n if (points) {\n if (params.colorsCompressed) {\n xktGeometryCfg.colorsCompressed = new Uint8Array(params.colorsCompressed);\n\n } else {\n const colors = params.colors;\n const colorsCompressed = new Uint8Array(colors.length);\n for (let i = 0, len = colors.length; i < len; i++) {\n colorsCompressed[i] = Math.floor(colors[i] * 255);\n }\n xktGeometryCfg.colorsCompressed = colorsCompressed;\n }\n }\n\n if (lines) {\n xktGeometryCfg.indices = params.indices;\n }\n\n if (triangles) {\n\n if (!params.normals && !params.uv && !params.uvs) {\n\n // Building models often duplicate positions to allow face-aligned vertex normals; when we're not\n // providing normals for a geometry, it becomes possible to merge duplicate vertex positions within it.\n\n // TODO: Make vertex merging also merge normals?\n\n const mergedPositions = [];\n const mergedIndices = [];\n mergeVertices(xktGeometryCfg.positions, xktGeometryCfg.indices, mergedPositions, mergedIndices);\n xktGeometryCfg.positions = new Float64Array(mergedPositions);\n xktGeometryCfg.indices = mergedIndices;\n }\n\n xktGeometryCfg.edgeIndices = buildEdgeIndices(xktGeometryCfg.positions, xktGeometryCfg.indices, null, params.edgeThreshold || this.edgeThreshold || 10);\n }\n\n const geometry = new XKTGeometry(xktGeometryCfg);\n\n this.geometries[geometryId] = geometry;\n this.geometriesList.push(geometry);\n\n return geometry;\n }\n\n _createDefaultIndices(numIndices) {\n const indices = [];\n for (let i = 0; i < numIndices; i++) {\n indices.push(i);\n }\n return indices;\n }\n\n /**\n * Creates an {@link XKTMesh} within this XKTModel.\n *\n * An {@link XKTMesh} can be owned by one {@link XKTEntity}, which can own multiple {@link XKTMesh}es.\n *\n * Registers the new {@link XKTMesh} in {@link XKTModel#meshes} and {@link XKTModel#meshesList}.\n *\n * @param {*} params Method parameters.\n * @param {Number} params.meshId Unique ID for the {@link XKTMesh}.\n * @param {Number} params.geometryId ID of an existing {@link XKTGeometry} in {@link XKTModel#geometries}.\n * @param {Number} [params.textureSetId] Unique ID of an {@link XKTTextureSet} in {@link XKTModel#textureSets}.\n * @param {Float32Array} params.color RGB color for the {@link XKTMesh}, with each color component in range [0..1].\n * @param {Number} [params.metallic=0] How metallic the {@link XKTMesh} is, in range [0..1]. A value of ````0```` indicates fully dielectric material, while ````1```` indicates fully metallic.\n * @param {Number} [params.roughness=1] How rough the {@link XKTMesh} is, in range [0..1]. A value of ````0```` indicates fully smooth, while ````1```` indicates fully rough.\n * @param {Number} params.opacity Opacity factor for the {@link XKTMesh}, in range [0..1].\n * @param {Float64Array} [params.matrix] Modeling matrix for the {@link XKTMesh}. Overrides ````position````, ````scale```` and ````rotation```` parameters.\n * @param {Number[]} [params.position=[0,0,0]] Position of the {@link XKTMesh}. Overridden by the ````matrix```` parameter.\n * @param {Number[]} [params.scale=[1,1,1]] Scale of the {@link XKTMesh}. Overridden by the ````matrix```` parameter.\n * @param {Number[]} [params.rotation=[0,0,0]] Rotation of the {@link XKTMesh} as Euler angles given in degrees, for each of the X, Y and Z axis. Overridden by the ````matrix```` parameter.\n * @returns {XKTMesh} The new {@link XKTMesh}.\n */\n createMesh(params) {\n\n if (params.meshId === null || params.meshId === undefined) {\n throw \"Parameter expected: params.meshId\";\n }\n\n if (params.geometryId === null || params.geometryId === undefined) {\n throw \"Parameter expected: params.geometryId\";\n }\n\n if (this.finalized) {\n throw \"XKTModel has been finalized, can't add more meshes\";\n }\n\n if (this.meshes[params.meshId]) {\n console.error(\"XKTMesh already exists with this ID: \" + params.meshId);\n return;\n }\n\n const geometry = this.geometries[params.geometryId];\n\n if (!geometry) {\n console.error(\"XKTGeometry not found: \" + params.geometryId);\n return;\n }\n\n geometry.numInstances++;\n\n let textureSet = null;\n if (params.textureSetId) {\n textureSet = this.textureSets[params.textureSetId];\n if (!textureSet) {\n console.error(\"XKTTextureSet not found: \" + params.textureSetId);\n return;\n }\n textureSet.numInstances++;\n }\n\n let matrix = params.matrix;\n\n if (!matrix) {\n\n const position = params.position;\n const scale = params.scale;\n const rotation = params.rotation;\n\n if (position || scale || rotation) {\n matrix = math.identityMat4();\n const quaternion = math.eulerToQuaternion(rotation || [0, 0, 0], \"XYZ\", math.identityQuaternion());\n math.composeMat4(position || [0, 0, 0], quaternion, scale || [1, 1, 1], matrix)\n\n } else {\n matrix = math.identityMat4();\n }\n }\n\n const meshIndex = this.meshesList.length;\n\n const mesh = new XKTMesh({\n meshId: params.meshId,\n meshIndex,\n matrix,\n geometry,\n color: params.color,\n metallic: params.metallic,\n roughness: params.roughness,\n opacity: params.opacity,\n textureSet\n });\n\n this.meshes[mesh.meshId] = mesh;\n this.meshesList.push(mesh);\n\n return mesh;\n }\n\n /**\n * Creates an {@link XKTEntity} within this XKTModel.\n *\n * Registers the new {@link XKTEntity} in {@link XKTModel#entities} and {@link XKTModel#entitiesList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {String} params.entityId Unique ID for the {@link XKTEntity}.\n * @param {String[]} params.meshIds IDs of {@link XKTMesh}es used by the {@link XKTEntity}. Note that each {@link XKTMesh} can only be used by one {@link XKTEntity}.\n * @returns {XKTEntity} The new {@link XKTEntity}.\n */\n createEntity(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.entityId === null || params.entityId === undefined) {\n throw \"Parameter expected: params.entityId\";\n }\n\n if (!params.meshIds) {\n throw \"Parameter expected: params.meshIds\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more entities\");\n return;\n }\n\n if (params.meshIds.length === 0) {\n console.warn(\"XKTEntity has no meshes - won't create: \" + params.entityId);\n return;\n }\n\n let entityId = params.entityId;\n\n if (this.entities[entityId]) {\n while (this.entities[entityId]) {\n entityId = math.createUUID();\n }\n console.error(\"XKTEntity already exists with this ID: \" + params.entityId + \" - substituting random ID instead: \" + entityId);\n }\n\n const meshIds = params.meshIds;\n const meshes = [];\n\n for (let meshIdIdx = 0, meshIdLen = meshIds.length; meshIdIdx < meshIdLen; meshIdIdx++) {\n\n const meshId = meshIds[meshIdIdx];\n const mesh = this.meshes[meshId];\n\n if (!mesh) {\n console.error(\"XKTMesh found: \" + meshId);\n continue;\n }\n\n if (mesh.entity) {\n console.error(\"XKTMesh \" + meshId + \" already used by XKTEntity \" + mesh.entity.entityId);\n continue;\n }\n\n meshes.push(mesh);\n }\n\n const entity = new XKTEntity(entityId, meshes);\n\n for (let i = 0, len = meshes.length; i < len; i++) {\n const mesh = meshes[i];\n mesh.entity = entity;\n }\n\n this.entities[entityId] = entity;\n this.entitiesList.push(entity);\n\n return entity;\n }\n\n /**\n * Creates a default {@link XKTMetaObject} for each {@link XKTEntity} that does not already have one.\n */\n createDefaultMetaObjects() {\n\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n\n const entity = this.entitiesList[i];\n const metaObjectId = entity.entityId;\n const metaObject = this.metaObjects[metaObjectId];\n\n if (!metaObject) {\n\n if (!this._rootMetaObject) {\n this._rootMetaObject = this.createMetaObject({\n metaObjectId: this.modelId,\n metaObjectType: \"Default\",\n metaObjectName: this.modelId\n });\n }\n\n this.createMetaObject({\n metaObjectId: metaObjectId,\n metaObjectType: \"Default\",\n metaObjectName: \"\" + metaObjectId,\n parentMetaObjectId: this._rootMetaObject.metaObjectId\n });\n }\n }\n }\n\n /**\n * Finalizes this XKTModel.\n *\n * After finalizing, we may then serialize the model to an array buffer using {@link writeXKTModelToArrayBuffer}.\n *\n * Logs error and does nothing if this XKTModel has already been finalized.\n *\n * Internally, this method:\n *\n * * for each {@link XKTEntity} that doesn't already have a {@link XKTMetaObject}, creates one with {@link XKTMetaObject#metaObjectType} set to \"default\"\n * * sets each {@link XKTEntity}'s {@link XKTEntity#hasReusedGeometries} true if it shares its {@link XKTGeometry}s with other {@link XKTEntity}s,\n * * creates each {@link XKTEntity}'s {@link XKTEntity#aabb},\n * * creates {@link XKTTile}s in {@link XKTModel#tilesList}, and\n * * sets {@link XKTModel#finalized} ````true````.\n */\n async finalize() {\n\n if (this.finalized) {\n console.log(\"XKTModel already finalized\");\n return;\n }\n\n this._removeUnusedTextures();\n\n await this._compressTextures();\n\n this._bakeSingleUseGeometryPositions();\n\n this._bakeAndOctEncodeNormals();\n\n this._createEntityAABBs();\n\n const rootKDNode = this._createKDTree();\n\n this.entitiesList = [];\n\n this._createTilesFromKDTree(rootKDNode);\n\n this._createReusedGeometriesDecodeMatrix();\n\n this._flagSolidGeometries();\n\n this.aabb.set(rootKDNode.aabb);\n\n this.finalized = true;\n }\n\n _removeUnusedTextures() {\n let texturesList = [];\n const textures = {};\n for (let i = 0, leni = this.texturesList.length; i < leni; i++) {\n const texture = this.texturesList[i];\n if (texture.channel !== null) {\n texture.textureIndex = texturesList.length;\n texturesList.push(texture);\n textures[texture.textureId] = texture;\n }\n }\n this.texturesList = texturesList;\n this.textures = textures;\n }\n\n _compressTextures() {\n let countTextures = this.texturesList.length;\n return new Promise((resolve) => {\n if (countTextures === 0) {\n resolve();\n return;\n }\n for (let i = 0, leni = this.texturesList.length; i < leni; i++) {\n const texture = this.texturesList[i];\n const encodingOptions = TEXTURE_ENCODING_OPTIONS[texture.channel] || {};\n\n if (texture.src) {\n\n // XKTTexture created with XKTModel#createTexture({ src: ... })\n\n const src = texture.src;\n const fileExt = src.split('.').pop();\n switch (fileExt) {\n case \"jpeg\":\n case \"jpg\":\n case \"png\":\n load(src, ImageLoader, {\n image: {\n type: \"data\"\n }\n }).then((imageData) => {\n if (texture.compressed) {\n encode(imageData, KTX2BasisWriter, encodingOptions).then((encodedData) => {\n const encodedImageData = new Uint8Array(encodedData);\n texture.imageData = encodedImageData;\n if (--countTextures <= 0) {\n resolve();\n }\n }).catch((err) => {\n console.error(\"[XKTModel.finalize] Failed to encode image: \" + err);\n if (--countTextures <= 0) {\n resolve();\n }\n });\n } else {\n texture.imageData = new Uint8Array(1);\n if (--countTextures <= 0) {\n resolve();\n }\n }\n }).catch((err) => {\n console.error(\"[XKTModel.finalize] Failed to load image: \" + err);\n if (--countTextures <= 0) {\n resolve();\n }\n });\n break;\n default:\n if (--countTextures <= 0) {\n resolve();\n }\n break;\n }\n }\n\n if (texture.imageData) {\n\n // XKTTexture created with XKTModel#createTexture({ imageData: ... })\n\n if (texture.compressed) {\n encode(texture.imageData, KTX2BasisWriter, encodingOptions)\n .then((encodedImageData) => {\n texture.imageData = new Uint8Array(encodedImageData);\n if (--countTextures <= 0) {\n resolve();\n }\n }).catch((err) => {\n console.error(\"[XKTModel.finalize] Failed to encode image: \" + err);\n if (--countTextures <= 0) {\n resolve();\n }\n });\n } else {\n texture.imageData = new Uint8Array(1);\n if (--countTextures <= 0) {\n resolve();\n }\n }\n }\n }\n });\n }\n\n _bakeSingleUseGeometryPositions() {\n\n for (let j = 0, lenj = this.meshesList.length; j < lenj; j++) {\n\n const mesh = this.meshesList[j];\n\n const geometry = mesh.geometry;\n\n if (geometry.numInstances === 1) {\n\n const matrix = mesh.matrix;\n\n if (matrix && (!math.isIdentityMat4(matrix))) {\n\n const positions = geometry.positions;\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n tempVec4a[0] = positions[i + 0];\n tempVec4a[1] = positions[i + 1];\n tempVec4a[2] = positions[i + 2];\n tempVec4a[3] = 1;\n\n math.transformPoint4(matrix, tempVec4a, tempVec4b);\n\n positions[i + 0] = tempVec4b[0];\n positions[i + 1] = tempVec4b[1];\n positions[i + 2] = tempVec4b[2];\n }\n }\n }\n }\n }\n\n _bakeAndOctEncodeNormals() {\n\n for (let i = 0, len = this.meshesList.length; i < len; i++) {\n\n const mesh = this.meshesList[i];\n const geometry = mesh.geometry;\n\n if (geometry.normals && !geometry.normalsOctEncoded) {\n\n geometry.normalsOctEncoded = new Int8Array(geometry.normals.length);\n\n if (geometry.numInstances > 1) {\n geometryCompression.octEncodeNormals(geometry.normals, geometry.normals.length, geometry.normalsOctEncoded, 0);\n\n } else {\n const modelNormalMatrix = math.inverseMat4(math.transposeMat4(mesh.matrix, tempMat4), tempMat4b);\n geometryCompression.transformAndOctEncodeNormals(modelNormalMatrix, geometry.normals, geometry.normals.length, geometry.normalsOctEncoded, 0);\n }\n }\n }\n }\n\n _createEntityAABBs() {\n\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n\n const entity = this.entitiesList[i];\n const entityAABB = entity.aabb;\n const meshes = entity.meshes;\n\n math.collapseAABB3(entityAABB);\n\n for (let j = 0, lenj = meshes.length; j < lenj; j++) {\n\n const mesh = meshes[j];\n const geometry = mesh.geometry;\n const matrix = mesh.matrix;\n\n if (geometry.numInstances > 1) {\n\n const positions = geometry.positions;\n for (let i = 0, len = positions.length; i < len; i += 3) {\n tempVec4a[0] = positions[i + 0];\n tempVec4a[1] = positions[i + 1];\n tempVec4a[2] = positions[i + 2];\n tempVec4a[3] = 1;\n math.transformPoint4(matrix, tempVec4a, tempVec4b);\n math.expandAABB3Point3(entityAABB, tempVec4b);\n }\n\n } else {\n\n const positions = geometry.positions;\n for (let i = 0, len = positions.length; i < len; i += 3) {\n tempVec4a[0] = positions[i + 0];\n tempVec4a[1] = positions[i + 1];\n tempVec4a[2] = positions[i + 2];\n math.expandAABB3Point3(entityAABB, tempVec4a);\n }\n }\n }\n }\n }\n\n _createKDTree() {\n\n let aabb;\n if (this.modelAABB) {\n aabb = this.modelAABB; // Pre-known uber AABB\n } else {\n aabb = math.collapseAABB3();\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n const entity = this.entitiesList[i];\n math.expandAABB3(aabb, entity.aabb);\n }\n }\n\n const rootKDNode = new KDNode(aabb);\n\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n const entity = this.entitiesList[i];\n this._insertEntityIntoKDTree(rootKDNode, entity);\n }\n\n return rootKDNode;\n }\n\n _insertEntityIntoKDTree(kdNode, entity) {\n\n const nodeAABB = kdNode.aabb;\n const entityAABB = entity.aabb;\n\n const nodeAABBDiag = math.getAABB3Diag(nodeAABB);\n\n if (nodeAABBDiag < this.minTileSize) {\n kdNode.entities = kdNode.entities || [];\n kdNode.entities.push(entity);\n math.expandAABB3(nodeAABB, entityAABB);\n return;\n }\n\n if (kdNode.left) {\n if (math.containsAABB3(kdNode.left.aabb, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.left, entity);\n return;\n }\n }\n\n if (kdNode.right) {\n if (math.containsAABB3(kdNode.right.aabb, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.right, entity);\n return;\n }\n }\n\n kdTreeDimLength[0] = nodeAABB[3] - nodeAABB[0];\n kdTreeDimLength[1] = nodeAABB[4] - nodeAABB[1];\n kdTreeDimLength[2] = nodeAABB[5] - nodeAABB[2];\n\n let dim = 0;\n\n if (kdTreeDimLength[1] > kdTreeDimLength[dim]) {\n dim = 1;\n }\n\n if (kdTreeDimLength[2] > kdTreeDimLength[dim]) {\n dim = 2;\n }\n\n if (!kdNode.left) {\n const aabbLeft = nodeAABB.slice();\n aabbLeft[dim + 3] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0);\n kdNode.left = new KDNode(aabbLeft);\n if (math.containsAABB3(aabbLeft, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.left, entity);\n return;\n }\n }\n\n if (!kdNode.right) {\n const aabbRight = nodeAABB.slice();\n aabbRight[dim] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0);\n kdNode.right = new KDNode(aabbRight);\n if (math.containsAABB3(aabbRight, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.right, entity);\n return;\n }\n }\n\n kdNode.entities = kdNode.entities || [];\n kdNode.entities.push(entity);\n\n math.expandAABB3(nodeAABB, entityAABB);\n }\n\n _createTilesFromKDTree(rootKDNode) {\n this._createTilesFromKDNode(rootKDNode);\n }\n\n _createTilesFromKDNode(kdNode) {\n if (kdNode.entities && kdNode.entities.length > 0) {\n this._createTileFromEntities(kdNode);\n }\n if (kdNode.left) {\n this._createTilesFromKDNode(kdNode.left);\n }\n if (kdNode.right) {\n this._createTilesFromKDNode(kdNode.right);\n }\n }\n\n /**\n * Creates a tile from the given entities.\n *\n * For each single-use {@link XKTGeometry}, this method centers {@link XKTGeometry#positions} to make them relative to the\n * tile's center, then quantizes the positions to unsigned 16-bit integers, relative to the tile's boundary.\n *\n * @param kdNode\n */\n _createTileFromEntities(kdNode) {\n\n const tileAABB = kdNode.aabb;\n const entities = kdNode.entities;\n\n const tileCenter = math.getAABB3Center(tileAABB);\n const tileCenterNeg = math.mulVec3Scalar(tileCenter, -1, math.vec3());\n\n const rtcAABB = math.AABB3(); // AABB centered at the RTC origin\n\n rtcAABB[0] = tileAABB[0] - tileCenter[0];\n rtcAABB[1] = tileAABB[1] - tileCenter[1];\n rtcAABB[2] = tileAABB[2] - tileCenter[2];\n rtcAABB[3] = tileAABB[3] - tileCenter[0];\n rtcAABB[4] = tileAABB[4] - tileCenter[1];\n rtcAABB[5] = tileAABB[5] - tileCenter[2];\n\n for (let i = 0; i < entities.length; i++) {\n\n const entity = entities [i];\n\n const meshes = entity.meshes;\n\n for (let j = 0, lenj = meshes.length; j < lenj; j++) {\n\n const mesh = meshes[j];\n const geometry = mesh.geometry;\n\n if (!geometry.reused) { // Batched geometry\n\n const positions = geometry.positions;\n\n // Center positions relative to their tile's World-space center\n\n for (let k = 0, lenk = positions.length; k < lenk; k += 3) {\n\n positions[k + 0] -= tileCenter[0];\n positions[k + 1] -= tileCenter[1];\n positions[k + 2] -= tileCenter[2];\n }\n\n // Quantize positions relative to tile's RTC-space boundary\n\n geometryCompression.quantizePositions(positions, positions.length, rtcAABB, geometry.positionsQuantized);\n\n } else { // Instanced geometry\n\n // Post-multiply a translation to the mesh's modeling matrix\n // to center the entity's geometry instances to the tile RTC center\n\n //////////////////////////////\n // Why do we do this?\n // Seems to break various models\n /////////////////////////////////\n\n math.translateMat4v(tileCenterNeg, mesh.matrix);\n }\n }\n\n entity.entityIndex = this.entitiesList.length;\n\n this.entitiesList.push(entity);\n }\n\n const tile = new XKTTile(tileAABB, entities);\n\n this.tilesList.push(tile);\n }\n\n _createReusedGeometriesDecodeMatrix() {\n\n const tempVec3a = math.vec3();\n const reusedGeometriesAABB = math.collapseAABB3(math.AABB3());\n let countReusedGeometries = 0;\n\n for (let geometryIndex = 0, numGeometries = this.geometriesList.length; geometryIndex < numGeometries; geometryIndex++) {\n\n const geometry = this.geometriesList [geometryIndex];\n\n if (geometry.reused) { // Instanced geometry\n\n const positions = geometry.positions;\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n tempVec3a[0] = positions[i];\n tempVec3a[1] = positions[i + 1];\n tempVec3a[2] = positions[i + 2];\n\n math.expandAABB3Point3(reusedGeometriesAABB, tempVec3a);\n }\n\n countReusedGeometries++;\n }\n }\n\n if (countReusedGeometries > 0) {\n\n geometryCompression.createPositionsDecodeMatrix(reusedGeometriesAABB, this.reusedGeometriesDecodeMatrix);\n\n for (let geometryIndex = 0, numGeometries = this.geometriesList.length; geometryIndex < numGeometries; geometryIndex++) {\n\n const geometry = this.geometriesList [geometryIndex];\n\n if (geometry.reused) {\n geometryCompression.quantizePositions(geometry.positions, geometry.positions.length, reusedGeometriesAABB, geometry.positionsQuantized);\n }\n }\n\n } else {\n math.identityMat4(this.reusedGeometriesDecodeMatrix); // No need for this matrix, but we'll be tidy and set it to identity\n }\n }\n\n _flagSolidGeometries() {\n let maxNumPositions = 0;\n let maxNumIndices = 0;\n for (let i = 0, len = this.geometriesList.length; i < len; i++) {\n const geometry = this.geometriesList[i];\n if (geometry.primitiveType === \"triangles\") {\n if (geometry.positionsQuantized.length > maxNumPositions) {\n maxNumPositions = geometry.positionsQuantized.length;\n }\n if (geometry.indices.length > maxNumIndices) {\n maxNumIndices = geometry.indices.length;\n }\n }\n }\n let vertexIndexMapping = new Array(maxNumPositions / 3);\n let edges = new Array(maxNumIndices);\n for (let i = 0, len = this.geometriesList.length; i < len; i++) {\n const geometry = this.geometriesList[i];\n if (geometry.primitiveType === \"triangles\") {\n geometry.solid = isTriangleMeshSolid(geometry.indices, geometry.positionsQuantized, vertexIndexMapping, edges);\n }\n }\n }\n}\n\nexport {\n XKTModel\n}","/**\n * Given geometry defined as an array of positions, optional normals, option uv and an array of indices, returns\n * modified arrays that have duplicate vertices removed.\n *\n * @private\n */\nfunction mergeVertices(positions, indices, mergedPositions, mergedIndices) {\n const positionsMap = {};\n const indicesLookup = [];\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = 10 ** precisionPoints;\n let uvi = 0;\n for (let i = 0, len = positions.length; i < len; i += 3) {\n const vx = positions[i];\n const vy = positions[i + 1];\n const vz = positions[i + 2];\n const key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`;\n if (positionsMap[key] === undefined) {\n positionsMap[key] = mergedPositions.length / 3;\n mergedPositions.push(vx);\n mergedPositions.push(vy);\n mergedPositions.push(vz);\n }\n indicesLookup[i / 3] = positionsMap[key];\n uvi += 2;\n }\n for (let i = 0, len = indices.length; i < len; i++) {\n mergedIndices[i] = indicesLookup[indices[i]];\n }\n}\n\nexport {mergeVertices};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"pako\");","import {XKT_INFO} from \"../XKT_INFO.js\";\nimport * as pako from 'pako';\n\nconst XKT_VERSION = XKT_INFO.xktVersion;\nconst NUM_TEXTURE_ATTRIBUTES = 9;\nconst NUM_MATERIAL_ATTRIBUTES = 6;\n\n/**\n * Writes an {@link XKTModel} to an {@link ArrayBuffer}.\n *\n * @param {XKTModel} xktModel The {@link XKTModel}.\n * @param {String} metaModelJSON The metamodel JSON in a string.\n * @param {Object} [stats] Collects statistics.\n * @param {Object} options Options for how the XKT is written.\n * @param {Boolean} [options.zip=true] ZIP the contents?\n * @returns {ArrayBuffer} The {@link ArrayBuffer}.\n */\nfunction writeXKTModelToArrayBuffer(xktModel, metaModelJSON, stats, options) {\n const data = getModelData(xktModel, metaModelJSON, stats);\n const deflatedData = deflateData(data, metaModelJSON, options);\n stats.texturesSize += deflatedData.textureData.byteLength;\n const arrayBuffer = createArrayBuffer(deflatedData);\n return arrayBuffer;\n}\n\nfunction getModelData(xktModel, metaModelDataStr, stats) {\n\n //------------------------------------------------------------------------------------------------------------------\n // Allocate data\n //------------------------------------------------------------------------------------------------------------------\n\n const propertySetsList = xktModel.propertySetsList;\n const metaObjectsList = xktModel.metaObjectsList;\n const geometriesList = xktModel.geometriesList;\n const texturesList = xktModel.texturesList;\n const textureSetsList = xktModel.textureSetsList;\n const meshesList = xktModel.meshesList;\n const entitiesList = xktModel.entitiesList;\n const tilesList = xktModel.tilesList;\n\n const numPropertySets = propertySetsList.length;\n const numMetaObjects = metaObjectsList.length;\n const numGeometries = geometriesList.length;\n const numTextures = texturesList.length;\n const numTextureSets = textureSetsList.length;\n const numMeshes = meshesList.length;\n const numEntities = entitiesList.length;\n const numTiles = tilesList.length;\n\n let lenPositions = 0;\n let lenNormals = 0;\n let lenColors = 0;\n let lenUVs = 0;\n let lenIndices = 0;\n let lenEdgeIndices = 0;\n let lenMatrices = 0;\n let lenTextures = 0;\n\n for (let geometryIndex = 0; geometryIndex < numGeometries; geometryIndex++) {\n const geometry = geometriesList [geometryIndex];\n if (geometry.positionsQuantized) {\n lenPositions += geometry.positionsQuantized.length;\n }\n if (geometry.normalsOctEncoded) {\n lenNormals += geometry.normalsOctEncoded.length;\n }\n if (geometry.colorsCompressed) {\n lenColors += geometry.colorsCompressed.length;\n }\n if (geometry.uvs) {\n lenUVs += geometry.uvs.length;\n }\n if (geometry.indices) {\n lenIndices += geometry.indices.length;\n }\n if (geometry.edgeIndices) {\n lenEdgeIndices += geometry.edgeIndices.length;\n }\n }\n\n for (let textureIndex = 0; textureIndex < numTextures; textureIndex++) {\n const xktTexture = texturesList[textureIndex];\n const imageData = xktTexture.imageData;\n lenTextures += imageData.byteLength;\n\n if (xktTexture.compressed) {\n stats.numCompressedTextures++;\n }\n }\n\n for (let meshIndex = 0; meshIndex < numMeshes; meshIndex++) {\n const mesh = meshesList[meshIndex];\n if (mesh.geometry.numInstances > 1) {\n lenMatrices += 16;\n }\n }\n\n const data = {\n metadata: {},\n textureData: new Uint8Array(lenTextures), // All textures\n eachTextureDataPortion: new Uint32Array(numTextures), // For each texture, an index to its first element in textureData\n eachTextureAttributes: new Uint16Array(numTextures * NUM_TEXTURE_ATTRIBUTES),\n positions: new Uint16Array(lenPositions), // All geometry arrays\n normals: new Int8Array(lenNormals),\n colors: new Uint8Array(lenColors),\n uvs: new Float32Array(lenUVs),\n indices: new Uint32Array(lenIndices),\n edgeIndices: new Uint32Array(lenEdgeIndices),\n eachTextureSetTextures: new Int32Array(numTextureSets * 5), // For each texture set, a set of five Texture indices [color, metal/roughness,normals,emissive,occlusion]; each index has value -1 if no texture\n matrices: new Float32Array(lenMatrices), // Modeling matrices for entities that share geometries. Each entity either shares all it's geometries, or owns all its geometries exclusively. Exclusively-owned geometries are pre-transformed into World-space, and so their entities don't have modeling matrices in this array.\n reusedGeometriesDecodeMatrix: new Float32Array(xktModel.reusedGeometriesDecodeMatrix), // A single, global vertex position de-quantization matrix for all reused geometries. Reused geometries are quantized to their collective Local-space AABB, and this matrix is derived from that AABB.\n eachGeometryPrimitiveType: new Uint8Array(numGeometries), // Primitive type for each geometry (0=solid triangles, 1=surface triangles, 2=lines, 3=points, 4=line-strip)\n eachGeometryPositionsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.positions. Every primitive type has positions.\n eachGeometryNormalsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.normals. If the next geometry has the same index, then this geometry has no normals.\n eachGeometryColorsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.colors. If the next geometry has the same index, then this geometry has no colors.\n eachGeometryUVsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.uvs. If the next geometry has the same index, then this geometry has no UVs.\n eachGeometryIndicesPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.indices. If the next geometry has the same index, then this geometry has no indices.\n eachGeometryEdgeIndicesPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.edgeIndices. If the next geometry has the same index, then this geometry has no edge indices.\n eachMeshGeometriesPortion: new Uint32Array(numMeshes), // For each mesh, an index into the eachGeometry* arrays\n eachMeshMatricesPortion: new Uint32Array(numMeshes), // For each mesh that shares its geometry, an index to its first element in data.matrices, to indicate the modeling matrix that transforms the shared geometry Local-space vertex positions. This is ignored for meshes that don't share geometries, because the vertex positions of non-shared geometries are pre-transformed into World-space.\n eachMeshTextureSet: new Int32Array(numMeshes), // For each mesh, the index of its texture set in data.eachTextureSetTextures; this array contains signed integers so that we can use -1 to indicate when a mesh has no texture set\n eachMeshMaterialAttributes: new Uint8Array(numMeshes * NUM_MATERIAL_ATTRIBUTES), // For each mesh, an RGBA integer color of format [0..255, 0..255, 0..255, 0..255], and PBR metallic and roughness factors, of format [0..255, 0..255]\n eachEntityId: [], // For each entity, an ID string\n eachEntityMeshesPortion: new Uint32Array(numEntities), // For each entity, the index of the first element of meshes used by the entity\n eachTileAABB: new Float64Array(numTiles * 6), // For each tile, an axis-aligned bounding box\n eachTileEntitiesPortion: new Uint32Array(numTiles) // For each tile, the index of the first element of eachEntityId, eachEntityMeshesPortion and eachEntityMatricesPortion used by the tile\n };\n\n let countPositions = 0;\n let countNormals = 0;\n let countColors = 0;\n let countUVs = 0;\n let countIndices = 0;\n let countEdgeIndices = 0;\n\n // Metadata\n\n data.metadata = {\n id: xktModel.modelId,\n projectId: xktModel.projectId,\n revisionId: xktModel.revisionId,\n author: xktModel.author,\n createdAt: xktModel.createdAt,\n creatingApplication: xktModel.creatingApplication,\n schema: xktModel.schema,\n propertySets: [],\n metaObjects: []\n };\n\n // Property sets\n\n for (let propertySetsIndex = 0; propertySetsIndex < numPropertySets; propertySetsIndex++) {\n const propertySet = propertySetsList[propertySetsIndex];\n const propertySetJSON = {\n id: \"\" + propertySet.propertySetId,\n name: propertySet.propertySetName,\n type: propertySet.propertySetType,\n properties: propertySet.properties\n };\n data.metadata.propertySets.push(propertySetJSON);\n }\n\n // Metaobjects\n\n if (!metaModelDataStr) {\n for (let metaObjectsIndex = 0; metaObjectsIndex < numMetaObjects; metaObjectsIndex++) {\n const metaObject = metaObjectsList[metaObjectsIndex];\n const metaObjectJSON = {\n name: metaObject.metaObjectName,\n type: metaObject.metaObjectType,\n id: \"\" + metaObject.metaObjectId\n };\n if (metaObject.parentMetaObjectId !== undefined && metaObject.parentMetaObjectId !== null) {\n metaObjectJSON.parent = \"\" + metaObject.parentMetaObjectId;\n }\n if (metaObject.propertySetIds && metaObject.propertySetIds.length > 0) {\n metaObjectJSON.propertySetIds = metaObject.propertySetIds;\n }\n if (metaObject.external) {\n metaObjectJSON.external = metaObject.external;\n }\n data.metadata.metaObjects.push(metaObjectJSON);\n }\n }\n\n // Geometries\n\n for (let geometryIndex = 0; geometryIndex < numGeometries; geometryIndex++) {\n const geometry = geometriesList [geometryIndex];\n let primitiveType = 1;\n switch (geometry.primitiveType) {\n case \"triangles\":\n primitiveType = geometry.solid ? 0 : 1;\n break;\n case \"points\":\n primitiveType = 2;\n break;\n case \"lines\":\n primitiveType = 3;\n break;\n case \"line-strip\":\n case \"line-loop\":\n primitiveType = 4;\n break;\n case \"triangle-strip\":\n primitiveType = 5;\n break;\n case \"triangle-fan\":\n primitiveType = 6;\n break;\n default:\n primitiveType = 1\n }\n data.eachGeometryPrimitiveType [geometryIndex] = primitiveType;\n data.eachGeometryPositionsPortion [geometryIndex] = countPositions;\n data.eachGeometryNormalsPortion [geometryIndex] = countNormals;\n data.eachGeometryColorsPortion [geometryIndex] = countColors;\n data.eachGeometryUVsPortion [geometryIndex] = countUVs;\n data.eachGeometryIndicesPortion [geometryIndex] = countIndices;\n data.eachGeometryEdgeIndicesPortion [geometryIndex] = countEdgeIndices;\n if (geometry.positionsQuantized) {\n data.positions.set(geometry.positionsQuantized, countPositions);\n countPositions += geometry.positionsQuantized.length;\n }\n if (geometry.normalsOctEncoded) {\n data.normals.set(geometry.normalsOctEncoded, countNormals);\n countNormals += geometry.normalsOctEncoded.length;\n }\n if (geometry.colorsCompressed) {\n data.colors.set(geometry.colorsCompressed, countColors);\n countColors += geometry.colorsCompressed.length;\n }\n if (geometry.uvs) {\n data.uvs.set(geometry.uvs, countUVs);\n countUVs += geometry.uvs.length;\n }\n if (geometry.indices) {\n data.indices.set(geometry.indices, countIndices);\n countIndices += geometry.indices.length;\n }\n if (geometry.edgeIndices) {\n data.edgeIndices.set(geometry.edgeIndices, countEdgeIndices);\n countEdgeIndices += geometry.edgeIndices.length;\n }\n }\n\n // Textures\n\n for (let textureIndex = 0, numTextures = xktModel.texturesList.length, portionIdx = 0; textureIndex < numTextures; textureIndex++) {\n const xktTexture = xktModel.texturesList[textureIndex];\n const imageData = xktTexture.imageData;\n data.textureData.set(imageData, portionIdx);\n data.eachTextureDataPortion[textureIndex] = portionIdx;\n\n portionIdx += imageData.byteLength;\n\n let textureAttrIdx = textureIndex * NUM_TEXTURE_ATTRIBUTES;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.compressed ? 1 : 0;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.mediaType; // GIFMediaType | PNGMediaType | JPEGMediaType\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.width;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.height;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.minFilter; // LinearMipmapLinearFilter | LinearMipMapNearestFilter | NearestMipMapNearestFilter | NearestMipMapLinearFilter | LinearMipMapLinearFilter\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.magFilter; // LinearFilter | NearestFilter\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapS; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapT; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapR; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n }\n\n // Texture sets\n\n for (let textureSetIndex = 0, numTextureSets = xktModel.textureSetsList.length, eachTextureSetTexturesIndex = 0; textureSetIndex < numTextureSets; textureSetIndex++) {\n const textureSet = textureSetsList[textureSetIndex];\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.colorTexture ? textureSet.colorTexture.textureIndex : -1; // Color map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.metallicRoughnessTexture ? textureSet.metallicRoughnessTexture.textureIndex : -1; // Metal/rough map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.normalsTexture ? textureSet.normalsTexture.textureIndex : -1; // Normal map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.emissiveTexture ? textureSet.emissiveTexture.textureIndex : -1; // Emissive map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.occlusionTexture ? textureSet.occlusionTexture.textureIndex : -1; // Occlusion map\n }\n\n // Tiles -> Entities -> Meshes\n\n let entityIndex = 0;\n let countEntityMeshesPortion = 0;\n let eachMeshMaterialAttributesIndex = 0;\n let matricesIndex = 0;\n let meshIndex = 0;\n\n for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {\n\n const tile = tilesList [tileIndex];\n const tileEntities = tile.entities;\n const numTileEntities = tileEntities.length;\n\n if (numTileEntities === 0) {\n continue;\n }\n\n data.eachTileEntitiesPortion[tileIndex] = entityIndex;\n\n const tileAABB = tile.aabb;\n\n for (let j = 0; j < numTileEntities; j++) {\n\n const entity = tileEntities[j];\n const entityMeshes = entity.meshes;\n const numEntityMeshes = entityMeshes.length;\n\n for (let k = 0; k < numEntityMeshes; k++) {\n\n const mesh = entityMeshes[k];\n const geometry = mesh.geometry;\n const geometryIndex = geometry.geometryIndex;\n\n data.eachMeshGeometriesPortion [countEntityMeshesPortion + k] = geometryIndex;\n\n if (mesh.geometry.numInstances > 1) {\n data.matrices.set(mesh.matrix, matricesIndex);\n data.eachMeshMatricesPortion [meshIndex] = matricesIndex;\n matricesIndex += 16;\n }\n\n data.eachMeshTextureSet[meshIndex] = mesh.textureSet ? mesh.textureSet.textureSetIndex : -1;\n\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[0] * 255); // Color RGB\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[1] * 255);\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[2] * 255);\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.opacity * 255); // Opacity\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.metallic * 255); // Metallic\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.roughness * 255); // Roughness\n\n meshIndex++;\n }\n\n data.eachEntityId [entityIndex] = entity.entityId;\n data.eachEntityMeshesPortion[entityIndex] = countEntityMeshesPortion; // <<<<<<<<<<<<<<<<<<<< Error here? Order/value of countEntityMeshesPortion correct?\n\n entityIndex++;\n countEntityMeshesPortion += numEntityMeshes;\n }\n\n const tileAABBIndex = tileIndex * 6;\n\n data.eachTileAABB.set(tileAABB, tileAABBIndex);\n }\n\n return data;\n}\n\nfunction deflateData(data, metaModelJSON, options) {\n\n function deflate(buffer) {\n return (options.zip !== false) ? pako.deflate(buffer) : buffer;\n }\n\n let metaModelBytes;\n if (metaModelJSON) {\n const deflatedJSON = deflateJSON(metaModelJSON);\n metaModelBytes = deflate(deflatedJSON)\n } else {\n const deflatedJSON = deflateJSON(data.metadata);\n metaModelBytes = deflate(deflatedJSON)\n }\n\n return {\n metadata: metaModelBytes,\n textureData: deflate(data.textureData.buffer),\n eachTextureDataPortion: deflate(data.eachTextureDataPortion.buffer),\n eachTextureAttributes: deflate(data.eachTextureAttributes.buffer),\n positions: deflate(data.positions.buffer),\n normals: deflate(data.normals.buffer),\n colors: deflate(data.colors.buffer),\n uvs: deflate(data.uvs.buffer),\n indices: deflate(data.indices.buffer),\n edgeIndices: deflate(data.edgeIndices.buffer),\n eachTextureSetTextures: deflate(data.eachTextureSetTextures.buffer),\n matrices: deflate(data.matrices.buffer),\n reusedGeometriesDecodeMatrix: deflate(data.reusedGeometriesDecodeMatrix.buffer),\n eachGeometryPrimitiveType: deflate(data.eachGeometryPrimitiveType.buffer),\n eachGeometryPositionsPortion: deflate(data.eachGeometryPositionsPortion.buffer),\n eachGeometryNormalsPortion: deflate(data.eachGeometryNormalsPortion.buffer),\n eachGeometryColorsPortion: deflate(data.eachGeometryColorsPortion.buffer),\n eachGeometryUVsPortion: deflate(data.eachGeometryUVsPortion.buffer),\n eachGeometryIndicesPortion: deflate(data.eachGeometryIndicesPortion.buffer),\n eachGeometryEdgeIndicesPortion: deflate(data.eachGeometryEdgeIndicesPortion.buffer),\n eachMeshGeometriesPortion: deflate(data.eachMeshGeometriesPortion.buffer),\n eachMeshMatricesPortion: deflate(data.eachMeshMatricesPortion.buffer),\n eachMeshTextureSet: deflate(data.eachMeshTextureSet.buffer),\n eachMeshMaterialAttributes: deflate(data.eachMeshMaterialAttributes.buffer),\n eachEntityId: deflate(JSON.stringify(data.eachEntityId)\n .replace(/[\\u007F-\\uFFFF]/g, function (chr) { // Produce only ASCII-chars, so that the data can be inflated later\n return \"\\\\u\" + (\"0000\" + chr.charCodeAt(0).toString(16)).substr(-4)\n })),\n eachEntityMeshesPortion: deflate(data.eachEntityMeshesPortion.buffer),\n eachTileAABB: deflate(data.eachTileAABB.buffer),\n eachTileEntitiesPortion: deflate(data.eachTileEntitiesPortion.buffer)\n };\n}\n\nfunction deflateJSON(strings) {\n return JSON.stringify(strings)\n .replace(/[\\u007F-\\uFFFF]/g, function (chr) { // Produce only ASCII-chars, so that the data can be inflated later\n return \"\\\\u\" + (\"0000\" + chr.charCodeAt(0).toString(16)).substr(-4)\n });\n}\n\nfunction createArrayBuffer(deflatedData) {\n return toArrayBuffer([\n deflatedData.metadata,\n deflatedData.textureData,\n deflatedData.eachTextureDataPortion,\n deflatedData.eachTextureAttributes,\n deflatedData.positions,\n deflatedData.normals,\n deflatedData.colors,\n deflatedData.uvs,\n deflatedData.indices,\n deflatedData.edgeIndices,\n deflatedData.eachTextureSetTextures,\n deflatedData.matrices,\n deflatedData.reusedGeometriesDecodeMatrix,\n deflatedData.eachGeometryPrimitiveType,\n deflatedData.eachGeometryPositionsPortion,\n deflatedData.eachGeometryNormalsPortion,\n deflatedData.eachGeometryColorsPortion,\n deflatedData.eachGeometryUVsPortion,\n deflatedData.eachGeometryIndicesPortion,\n deflatedData.eachGeometryEdgeIndicesPortion,\n deflatedData.eachMeshGeometriesPortion,\n deflatedData.eachMeshMatricesPortion,\n deflatedData.eachMeshTextureSet,\n deflatedData.eachMeshMaterialAttributes,\n deflatedData.eachEntityId,\n deflatedData.eachEntityMeshesPortion,\n deflatedData.eachTileAABB,\n deflatedData.eachTileEntitiesPortion\n ]);\n}\n\nfunction toArrayBuffer(elements) {\n const indexData = new Uint32Array(elements.length + 2);\n indexData[0] = XKT_VERSION;\n indexData [1] = elements.length; // Stored Data 1.1: number of stored elements\n let dataLen = 0; // Stored Data 1.2: length of stored elements\n for (let i = 0, len = elements.length; i < len; i++) {\n const element = elements[i];\n const elementsize = element.length;\n indexData[i + 2] = elementsize;\n dataLen += elementsize;\n }\n const indexBuf = new Uint8Array(indexData.buffer);\n const dataArray = new Uint8Array(indexBuf.length + dataLen);\n dataArray.set(indexBuf);\n let offset = indexBuf.length;\n for (let i = 0, len = elements.length; i < len; i++) { // Stored Data 2: the elements themselves\n const element = elements[i];\n dataArray.set(element, offset);\n offset += element.length;\n }\n return dataArray.buffer;\n}\n\nexport {writeXKTModelToArrayBuffer};","/** @private */\nfunction earcut(data, holeIndices, dim) {\n\n dim = dim || 2;\n\n var hasHoles = holeIndices && holeIndices.length,\n outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n outerNode = linkedList(data, 0, outerLen, dim, true),\n triangles = [];\n\n if (!outerNode || outerNode.next === outerNode.prev) return triangles;\n\n var minX, minY, maxX, maxY, x, y, invSize;\n\n if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n if (data.length > 80 * dim) {\n minX = maxX = data[0];\n minY = maxY = data[1];\n\n for (var i = dim; i < outerLen; i += dim) {\n x = data[i];\n y = data[i + 1];\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n }\n\n // minX, minY and invSize are later used to transform coords into integers for z-order calculation\n invSize = Math.max(maxX - minX, maxY - minY);\n invSize = invSize !== 0 ? 1 / invSize : 0;\n }\n\n earcutLinked(outerNode, triangles, dim, minX, minY, invSize);\n\n return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList(data, start, end, dim, clockwise) {\n var i, last;\n\n if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n } else {\n for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n }\n\n if (last && equals(last, last.next)) {\n removeNode(last);\n last = last.next;\n }\n\n return last;\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints(start, end) {\n if (!start) return start;\n if (!end) end = start;\n\n var p = start,\n again;\n do {\n again = false;\n\n if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n removeNode(p);\n p = end = p.prev;\n if (p === p.next) break;\n again = true;\n\n } else {\n p = p.next;\n }\n } while (again || p !== end);\n\n return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {\n if (!ear) return;\n\n // interlink polygon nodes in z-order\n if (!pass && invSize) indexCurve(ear, minX, minY, invSize);\n\n var stop = ear,\n prev, next;\n\n // iterate through ears, slicing them one by one\n while (ear.prev !== ear.next) {\n prev = ear.prev;\n next = ear.next;\n\n if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {\n // cut off the triangle\n triangles.push(prev.i / dim);\n triangles.push(ear.i / dim);\n triangles.push(next.i / dim);\n\n removeNode(ear);\n\n // skipping the next vertex leads to less sliver triangles\n ear = next.next;\n stop = next.next;\n\n continue;\n }\n\n ear = next;\n\n // if we looped through the whole remaining polygon and can't find any more ears\n if (ear === stop) {\n // try filtering points and slicing again\n if (!pass) {\n earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);\n\n // if this didn't work, try curing all small self-intersections locally\n } else if (pass === 1) {\n ear = cureLocalIntersections(filterPoints(ear), triangles, dim);\n earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);\n\n // as a last resort, try splitting the remaining polygon into two\n } else if (pass === 2) {\n splitEarcut(ear, triangles, dim, minX, minY, invSize);\n }\n\n break;\n }\n }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar(ear) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // now make sure we don't have other points inside the potential ear\n var p = ear.next.next;\n\n while (p !== ear.prev) {\n if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.next;\n }\n\n return true;\n}\n\nfunction isEarHashed(ear, minX, minY, invSize) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // triangle bbox; min & max are calculated like this for speed\n var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\n // z-order range for the current triangle bbox;\n var minZ = zOrder(minTX, minTY, minX, minY, invSize),\n maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);\n\n var p = ear.prevZ,\n n = ear.nextZ;\n\n // look for points inside the triangle in both directions\n while (p && p.z >= minZ && n && n.z <= maxZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n\n if (n !== ear.prev && n !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&\n area(n.prev, n, n.next) >= 0) return false;\n n = n.nextZ;\n }\n\n // look for remaining points in decreasing z-order\n while (p && p.z >= minZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n }\n\n // look for remaining points in increasing z-order\n while (n && n.z <= maxZ) {\n if (n !== ear.prev && n !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&\n area(n.prev, n, n.next) >= 0) return false;\n n = n.nextZ;\n }\n\n return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections(start, triangles, dim) {\n var p = start;\n do {\n var a = p.prev,\n b = p.next.next;\n\n if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\n triangles.push(a.i / dim);\n triangles.push(p.i / dim);\n triangles.push(b.i / dim);\n\n // remove two nodes involved\n removeNode(p);\n removeNode(p.next);\n\n p = start = b;\n }\n p = p.next;\n } while (p !== start);\n\n return filterPoints(p);\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut(start, triangles, dim, minX, minY, invSize) {\n // look for a valid diagonal that divides the polygon into two\n var a = start;\n do {\n var b = a.next.next;\n while (b !== a.prev) {\n if (a.i !== b.i && isValidDiagonal(a, b)) {\n // split the polygon in two by the diagonal\n var c = splitPolygon(a, b);\n\n // filter colinear points around the cuts\n a = filterPoints(a, a.next);\n c = filterPoints(c, c.next);\n\n // run earcut on each half\n earcutLinked(a, triangles, dim, minX, minY, invSize);\n earcutLinked(c, triangles, dim, minX, minY, invSize);\n return;\n }\n b = b.next;\n }\n a = a.next;\n } while (a !== start);\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n var queue = [],\n i, len, start, end, list;\n\n for (i = 0, len = holeIndices.length; i < len; i++) {\n start = holeIndices[i] * dim;\n end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n list = linkedList(data, start, end, dim, false);\n if (list === list.next) list.steiner = true;\n queue.push(getLeftmost(list));\n }\n\n queue.sort(compareX);\n\n // process holes from left to right\n for (i = 0; i < queue.length; i++) {\n eliminateHole(queue[i], outerNode);\n outerNode = filterPoints(outerNode, outerNode.next);\n }\n\n return outerNode;\n}\n\nfunction compareX(a, b) {\n return a.x - b.x;\n}\n\n// find a bridge between vertices that connects hole with an outer ring and and link it\nfunction eliminateHole(hole, outerNode) {\n outerNode = findHoleBridge(hole, outerNode);\n if (outerNode) {\n var b = splitPolygon(outerNode, hole);\n\n // filter collinear points around the cuts\n filterPoints(outerNode, outerNode.next);\n filterPoints(b, b.next);\n }\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge(hole, outerNode) {\n var p = outerNode,\n hx = hole.x,\n hy = hole.y,\n qx = -Infinity,\n m;\n\n // find a segment intersected by a ray from the hole's leftmost point to the left;\n // segment's endpoint with lesser x will be potential connection point\n do {\n if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {\n var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n if (x <= hx && x > qx) {\n qx = x;\n if (x === hx) {\n if (hy === p.y) return p;\n if (hy === p.next.y) return p.next;\n }\n m = p.x < p.next.x ? p : p.next;\n }\n }\n p = p.next;\n } while (p !== outerNode);\n\n if (!m) return null;\n\n if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint\n\n // look for points inside the triangle of hole point, segment intersection and endpoint;\n // if there are no points found, we have a valid connection;\n // otherwise choose the point of the minimum angle with the ray as connection point\n\n var stop = m,\n mx = m.x,\n my = m.y,\n tanMin = Infinity,\n tan;\n\n p = m;\n\n do {\n if (hx >= p.x && p.x >= mx && hx !== p.x &&\n pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\n tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n if (locallyInside(p, hole) &&\n (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {\n m = p;\n tanMin = tan;\n }\n }\n\n p = p.next;\n } while (p !== stop);\n\n return m;\n}\n\n// whether sector in vertex m contains sector in vertex p in the same coordinates\nfunction sectorContainsSector(m, p) {\n return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve(start, minX, minY, invSize) {\n var p = start;\n do {\n if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize);\n p.prevZ = p.prev;\n p.nextZ = p.next;\n p = p.next;\n } while (p !== start);\n\n p.prevZ.nextZ = null;\n p.prevZ = null;\n\n sortLinked(p);\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked(list) {\n var i, p, q, e, tail, numMerges, pSize, qSize,\n inSize = 1;\n\n do {\n p = list;\n list = null;\n tail = null;\n numMerges = 0;\n\n while (p) {\n numMerges++;\n q = p;\n pSize = 0;\n for (i = 0; i < inSize; i++) {\n pSize++;\n q = q.nextZ;\n if (!q) break;\n }\n qSize = inSize;\n\n while (pSize > 0 || (qSize > 0 && q)) {\n\n if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else {\n e = q;\n q = q.nextZ;\n qSize--;\n }\n\n if (tail) tail.nextZ = e;\n else list = e;\n\n e.prevZ = tail;\n tail = e;\n }\n\n p = q;\n }\n\n tail.nextZ = null;\n inSize *= 2;\n\n } while (numMerges > 1);\n\n return list;\n}\n\n// z-order of a point given coords and inverse of the longer side of data bbox\nfunction zOrder(x, y, minX, minY, invSize) {\n // coords are transformed into non-negative 15-bit integer range\n x = 32767 * (x - minX) * invSize;\n y = 32767 * (y - minY) * invSize;\n\n x = (x | (x << 8)) & 0x00FF00FF;\n x = (x | (x << 4)) & 0x0F0F0F0F;\n x = (x | (x << 2)) & 0x33333333;\n x = (x | (x << 1)) & 0x55555555;\n\n y = (y | (y << 8)) & 0x00FF00FF;\n y = (y | (y << 4)) & 0x0F0F0F0F;\n y = (y | (y << 2)) & 0x33333333;\n y = (y | (y << 1)) & 0x55555555;\n\n return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost(start) {\n var p = start,\n leftmost = start;\n do {\n if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;\n p = p.next;\n } while (p !== start);\n\n return leftmost;\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal(a, b) {\n return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges\n (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible\n (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors\n equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case\n}\n\n// signed area of a triangle\nfunction area(p, q, r) {\n return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\nfunction equals(p1, p2) {\n return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect\nfunction intersects(p1, q1, p2, q2) {\n var o1 = sign(area(p1, q1, p2));\n var o2 = sign(area(p1, q1, q2));\n var o3 = sign(area(p2, q2, p1));\n var o4 = sign(area(p2, q2, q1));\n\n if (o1 !== o2 && o3 !== o4) return true; // general case\n\n if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1\n if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1\n if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2\n if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2\n\n return false;\n}\n\n// for collinear points p, q, r, check if point q lies on segment pr\nfunction onSegment(p, q, r) {\n return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);\n}\n\nfunction sign(num) {\n return num > 0 ? 1 : num < 0 ? -1 : 0;\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon(a, b) {\n var p = a;\n do {\n if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n intersects(p, p.next, a, b)) return true;\n p = p.next;\n } while (p !== a);\n\n return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside(a, b) {\n return area(a.prev, a, a.next) < 0 ?\n area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside(a, b) {\n var p = a,\n inside = false,\n px = (a.x + b.x) / 2,\n py = (a.y + b.y) / 2;\n do {\n if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&\n (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n inside = !inside;\n p = p.next;\n } while (p !== a);\n\n return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon(a, b) {\n var a2 = new Node(a.i, a.x, a.y),\n b2 = new Node(b.i, b.x, b.y),\n an = a.next,\n bp = b.prev;\n\n a.next = b;\n b.prev = a;\n\n a2.next = an;\n an.prev = a2;\n\n b2.next = a2;\n a2.prev = b2;\n\n bp.next = b2;\n b2.prev = bp;\n\n return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode(i, x, y, last) {\n var p = new Node(i, x, y);\n\n if (!last) {\n p.prev = p;\n p.next = p;\n\n } else {\n p.next = last.next;\n p.prev = last;\n last.next.prev = p;\n last.next = p;\n }\n return p;\n}\n\nfunction removeNode(p) {\n p.next.prev = p.prev;\n p.prev.next = p.next;\n\n if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n}\n\nfunction Node(i, x, y) {\n // vertex index in coordinates array\n this.i = i;\n\n // vertex coordinates\n this.x = x;\n this.y = y;\n\n // previous and next vertex nodes in a polygon ring\n this.prev = null;\n this.next = null;\n\n // z-order curve value\n this.z = null;\n\n // previous and next nodes in z-order\n this.prevZ = null;\n this.nextZ = null;\n\n // indicates whether this is a steiner point\n this.steiner = false;\n}\n\n// return a percentage difference between the polygon area and its triangulation area;\n// used to verify correctness of triangulation\nearcut.deviation = function (data, holeIndices, dim, triangles) {\n var hasHoles = holeIndices && holeIndices.length;\n var outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\n var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n if (hasHoles) {\n for (var i = 0, len = holeIndices.length; i < len; i++) {\n var start = holeIndices[i] * dim;\n var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n polygonArea -= Math.abs(signedArea(data, start, end, dim));\n }\n }\n\n var trianglesArea = 0;\n for (i = 0; i < triangles.length; i += 3) {\n var a = triangles[i] * dim;\n var b = triangles[i + 1] * dim;\n var c = triangles[i + 2] * dim;\n trianglesArea += Math.abs(\n (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n }\n\n return polygonArea === 0 && trianglesArea === 0 ? 0 :\n Math.abs((trianglesArea - polygonArea) / polygonArea);\n};\n\nfunction signedArea(data, start, end, dim) {\n var sum = 0;\n for (var i = start, j = end - dim; i < end; i += dim) {\n sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n j = i;\n }\n return sum;\n}\n\n// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\nearcut.flatten = function (data) {\n var dim = data[0][0].length,\n result = {vertices: [], holes: [], dimensions: dim},\n holeIndex = 0;\n\n for (var i = 0; i < data.length; i++) {\n for (var j = 0; j < data[i].length; j++) {\n for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);\n }\n if (i > 0) {\n holeIndex += data[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n return result;\n};\n\nexport {earcut};","import {earcut} from './../lib/earcut';\nimport {math} from \"./../lib/math.js\";\n\nconst tempVec2a = math.vec2();\nconst tempVec3a = math.vec3();\nconst tempVec3b = math.vec3();\nconst tempVec3c = math.vec3();\n\n/**\n * @desc Parses a CityJSON model into an {@link XKTModel}.\n *\n * [CityJSON](https://www.cityjson.org) is a JSON-based encoding for a subset of the CityGML data model (version 2.0.0),\n * which is an open standardised data model and exchange format to store digital 3D models of cities and\n * landscapes. CityGML is an official standard of the [Open Geospatial Consortium](https://www.ogc.org/).\n *\n * This converter function supports most of the [CityJSON 1.0.2 Specification](https://www.cityjson.org/specs/1.0.2),\n * with the following limitations:\n *\n * * Does not (yet) support CityJSON semantics for geometry primitives.\n * * Does not (yet) support textured geometries.\n * * Does not (yet) support geometry templates.\n * * When the CityJSON file provides multiple *themes* for a geometry, then we parse only the first of the provided themes for that geometry.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a CityJSON model into it.\n *\n * ````javascript\n * utils.loadJSON(\"./models/cityjson/DenHaag.json\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseCityJSONIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {Object} params.data CityJSON data.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {boolean} [params.center=false] Set true to center the CityJSON vertex positions to [0,0,0]. This is applied before the transformation matrix, if specified.\n * @param {Boolean} [params.transform] 4x4 transformation matrix to transform CityJSON vertex positions. Use this to rotate, translate and scale them if neccessary.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when CityJSON has been parsed.\n */\nfunction parseCityJSONIntoXKTModel({\n data,\n xktModel,\n center = false,\n transform = null,\n stats = {}, log\n }) {\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (data.type !== \"CityJSON\") {\n reject(\"Invalid argument: data is not a CityJSON file\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n let vertices;\n\n log(\"Using parser: parseCityJSONIntoXKTModel\");\n\n log(`center: ${center}`);\n if (transform) {\n log(`transform: [${transform}]`);\n }\n\n if (data.transform || center || transform) {\n vertices = copyVertices(data.vertices);\n if (data.transform) {\n transformVertices(vertices, data.transform)\n }\n if (center) {\n centerVertices(vertices);\n }\n if (transform) {\n customTransformVertices(vertices, transform);\n }\n } else {\n vertices = data.vertices;\n }\n\n stats.sourceFormat = data.type || \"\";\n stats.schemaVersion = data.version || \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 0;\n stats.numPropertySets = 0;\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n const rootMetaObjectId = math.createUUID();\n\n xktModel.createMetaObject({\n metaObjectId: rootMetaObjectId,\n metaObjectType: \"Model\",\n metaObjectName: \"Model\"\n });\n\n stats.numMetaObjects++;\n\n const modelMetaObjectId = math.createUUID();\n\n xktModel.createMetaObject({\n metaObjectId: modelMetaObjectId,\n metaObjectType: \"CityJSON\",\n metaObjectName: \"CityJSON\",\n parentMetaObjectId: rootMetaObjectId\n });\n\n stats.numMetaObjects++;\n\n const ctx = {\n data,\n vertices,\n xktModel,\n rootMetaObjectId: modelMetaObjectId,\n log: (log || function (msg) {\n }),\n nextId: 0,\n stats\n };\n\n ctx.xktModel.schema = data.type + \" \" + data.version;\n\n ctx.log(\"Converting \" + ctx.xktModel.schema);\n\n parseCityJSON(ctx);\n\n resolve();\n });\n}\n\nfunction copyVertices(vertices) {\n const vertices2 = [];\n for (let i = 0, j = 0; i < vertices.length; i++, j += 3) {\n const x = vertices[i][0];\n const y = vertices[i][1];\n const z = vertices[i][2];\n vertices2.push([x, y, z]);\n }\n return vertices2;\n}\n\nfunction transformVertices(vertices, cityJSONTransform) {\n const scale = cityJSONTransform.scale || math.vec3([1, 1, 1]);\n const translate = cityJSONTransform.translate || math.vec3([0, 0, 0]);\n for (let i = 0; i < vertices.length; i++) {\n const vertex = vertices[i];\n vertex[0] = (vertex[0] * scale[0]) + translate[0];\n vertex[1] = (vertex[1] * scale[1]) + translate[1];\n vertex[2] = (vertex[2] * scale[2]) + translate[2];\n }\n}\n\nfunction centerVertices(vertices) {\n if (center) {\n const centerPos = math.vec3();\n const numPoints = vertices.length;\n for (let i = 0, len = vertices.length; i < len; i++) {\n const vertex = vertices[i];\n centerPos[0] += vertex[0];\n centerPos[1] += vertex[1];\n centerPos[2] += vertex[2];\n }\n centerPos[0] /= numPoints;\n centerPos[1] /= numPoints;\n centerPos[2] /= numPoints;\n for (let i = 0, len = vertices.length; i < len; i++) {\n const vertex = vertices[i];\n vertex[0] -= centerPos[0];\n vertex[1] -= centerPos[1];\n vertex[2] -= centerPos[2];\n }\n }\n}\n\nfunction customTransformVertices(vertices, transform) {\n if (transform) {\n const mat = math.mat4(transform);\n for (let i = 0, len = vertices.length; i < len; i++) {\n const vertex = vertices[i];\n math.transformPoint3(mat, vertex, vertex);\n }\n }\n}\n\nfunction parseCityJSON(ctx) {\n\n const data = ctx.data;\n const cityObjects = data.CityObjects;\n\n for (const objectId in cityObjects) {\n if (cityObjects.hasOwnProperty(objectId)) {\n const cityObject = cityObjects[objectId];\n parseCityObject(ctx, cityObject, objectId);\n }\n }\n}\n\nfunction parseCityObject(ctx, cityObject, objectId) {\n\n const xktModel = ctx.xktModel;\n const data = ctx.data;\n const metaObjectId = objectId;\n const metaObjectType = cityObject.type;\n const metaObjectName = metaObjectType + \" : \" + objectId;\n\n const parentMetaObjectId = cityObject.parents ? cityObject.parents[0] : ctx.rootMetaObjectId;\n\n xktModel.createMetaObject({\n metaObjectId,\n metaObjectName,\n metaObjectType,\n parentMetaObjectId\n });\n\n ctx.stats.numMetaObjects++;\n\n if (!(cityObject.geometry && cityObject.geometry.length > 0)) {\n return;\n }\n\n const meshIds = [];\n\n for (let i = 0, len = cityObject.geometry.length; i < len; i++) {\n\n const geometry = cityObject.geometry[i];\n\n let objectMaterial;\n let surfaceMaterials;\n\n const appearance = data.appearance;\n if (appearance) {\n const materials = appearance.materials;\n if (materials) {\n const geometryMaterial = geometry.material;\n if (geometryMaterial) {\n const themeIds = Object.keys(geometryMaterial);\n if (themeIds.length > 0) {\n const themeId = themeIds[0];\n const theme = geometryMaterial[themeId];\n if (theme.value !== undefined) {\n objectMaterial = materials[theme.value];\n } else {\n const values = theme.values;\n if (values) {\n surfaceMaterials = [];\n for (let j = 0, lenj = values.length; j < lenj; j++) {\n const value = values[i];\n const surfaceMaterial = materials[value];\n surfaceMaterials.push(surfaceMaterial);\n }\n }\n }\n }\n }\n }\n }\n\n if (surfaceMaterials) {\n parseGeometrySurfacesWithOwnMaterials(ctx, geometry, surfaceMaterials, meshIds);\n\n } else {\n parseGeometrySurfacesWithSharedMaterial(ctx, geometry, objectMaterial, meshIds);\n }\n }\n\n if (meshIds.length > 0) {\n xktModel.createEntity({\n entityId: objectId,\n meshIds: meshIds\n });\n\n ctx.stats.numObjects++;\n }\n}\n\nfunction parseGeometrySurfacesWithOwnMaterials(ctx, geometry, surfaceMaterials, meshIds) {\n\n const geomType = geometry.type;\n\n switch (geomType) {\n\n case \"MultiPoint\":\n break;\n\n case \"MultiLineString\":\n break;\n\n case \"MultiSurface\":\n\n case \"CompositeSurface\":\n const surfaces = geometry.boundaries;\n parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n break;\n\n case \"Solid\":\n const shells = geometry.boundaries;\n for (let j = 0; j < shells.length; j++) {\n const surfaces = shells[j];\n parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n }\n break;\n\n case \"MultiSolid\":\n\n case \"CompositeSolid\":\n const solids = geometry.boundaries;\n for (let j = 0; j < solids.length; j++) {\n for (let k = 0; k < solids[j].length; k++) {\n const surfaces = solids[j][k];\n parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n }\n }\n break;\n\n case \"GeometryInstance\":\n break;\n }\n}\n\nfunction parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds) {\n\n const vertices = ctx.vertices;\n const xktModel = ctx.xktModel;\n\n for (let i = 0; i < surfaces.length; i++) {\n\n const surface = surfaces[i];\n const surfaceMaterial = surfaceMaterials[i] || {diffuseColor: [0.8, 0.8, 0.8], transparency: 1.0};\n\n const face = [];\n const holes = [];\n\n const sharedIndices = [];\n\n const geometryCfg = {\n positions: [],\n indices: []\n };\n\n for (let j = 0; j < surface.length; j++) {\n\n if (face.length > 0) {\n holes.push(face.length);\n }\n\n const newFace = extractLocalIndices(ctx, surface[j], sharedIndices, geometryCfg);\n\n face.push(...newFace);\n }\n\n if (face.length === 3) { // Triangle\n\n geometryCfg.indices.push(face[0]);\n geometryCfg.indices.push(face[1]);\n geometryCfg.indices.push(face[2]);\n\n } else if (face.length > 3) { // Polygon\n\n // Prepare to triangulate\n\n const pList = [];\n\n for (let k = 0; k < face.length; k++) {\n pList.push({\n x: vertices[sharedIndices[face[k]]][0],\n y: vertices[sharedIndices[face[k]]][1],\n z: vertices[sharedIndices[face[k]]][2]\n });\n }\n\n const normal = getNormalOfPositions(pList, math.vec3());\n\n // Convert to 2D\n\n let pv = [];\n\n for (let k = 0; k < pList.length; k++) {\n\n to2D(pList[k], normal, tempVec2a);\n\n pv.unshift(tempVec2a[0]);\n pv.unshift(tempVec2a[1]);\n }\n\n // Triangulate\n\n const tr = earcut(pv, holes, 2);\n\n // Create triangles\n\n for (let k = 0; k < tr.length; k += 3) {\n geometryCfg.indices.unshift(face[tr[k]]);\n geometryCfg.indices.unshift(face[tr[k + 1]]);\n geometryCfg.indices.unshift(face[tr[k + 2]]);\n }\n }\n\n const geometryId = \"\" + ctx.nextId++;\n const meshId = \"\" + ctx.nextId++;\n\n xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: geometryCfg.positions,\n indices: geometryCfg.indices\n });\n\n xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n color: (surfaceMaterial && surfaceMaterial.diffuseColor) ? surfaceMaterial.diffuseColor : [0.8, 0.8, 0.8],\n opacity: 1.0\n //opacity: (surfaceMaterial && surfaceMaterial.transparency !== undefined) ? (1.0 - surfaceMaterial.transparency) : 1.0\n });\n\n meshIds.push(meshId);\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n }\n}\n\nfunction parseGeometrySurfacesWithSharedMaterial(ctx, geometry, objectMaterial, meshIds) {\n\n const xktModel = ctx.xktModel;\n const sharedIndices = [];\n const geometryCfg = {\n positions: [],\n indices: []\n };\n\n const geomType = geometry.type;\n\n switch (geomType) {\n case \"MultiPoint\":\n break;\n\n case \"MultiLineString\":\n break;\n\n case \"MultiSurface\":\n case \"CompositeSurface\":\n const surfaces = geometry.boundaries;\n parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n break;\n\n case \"Solid\":\n const shells = geometry.boundaries;\n for (let j = 0; j < shells.length; j++) {\n const surfaces = shells[j];\n parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n }\n break;\n\n case \"MultiSolid\":\n case \"CompositeSolid\":\n const solids = geometry.boundaries;\n for (let j = 0; j < solids.length; j++) {\n for (let k = 0; k < solids[j].length; k++) {\n const surfaces = solids[j][k];\n parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n }\n }\n break;\n\n case \"GeometryInstance\":\n break;\n }\n\n const geometryId = \"\" + ctx.nextId++;\n const meshId = \"\" + ctx.nextId++;\n\n xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: geometryCfg.positions,\n indices: geometryCfg.indices\n });\n\n xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n color: (objectMaterial && objectMaterial.diffuseColor) ? objectMaterial.diffuseColor : [0.8, 0.8, 0.8],\n opacity: 1.0\n //opacity: (objectMaterial && objectMaterial.transparency !== undefined) ? (1.0 - objectMaterial.transparency) : 1.0\n });\n\n meshIds.push(meshId);\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n}\n\nfunction parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, primitiveCfg) {\n\n const vertices = ctx.vertices;\n\n for (let i = 0; i < surfaces.length; i++) {\n\n let boundary = [];\n let holes = [];\n\n for (let j = 0; j < surfaces[i].length; j++) {\n if (boundary.length > 0) {\n holes.push(boundary.length);\n }\n const newBoundary = extractLocalIndices(ctx, surfaces[i][j], sharedIndices, primitiveCfg);\n boundary.push(...newBoundary);\n }\n\n if (boundary.length === 3) { // Triangle\n\n primitiveCfg.indices.push(boundary[0]);\n primitiveCfg.indices.push(boundary[1]);\n primitiveCfg.indices.push(boundary[2]);\n\n } else if (boundary.length > 3) { // Polygon\n\n let pList = [];\n\n for (let k = 0; k < boundary.length; k++) {\n pList.push({\n x: vertices[sharedIndices[boundary[k]]][0],\n y: vertices[sharedIndices[boundary[k]]][1],\n z: vertices[sharedIndices[boundary[k]]][2]\n });\n }\n\n const normal = getNormalOfPositions(pList, math.vec3());\n let pv = [];\n\n for (let k = 0; k < pList.length; k++) {\n to2D(pList[k], normal, tempVec2a);\n pv.unshift(tempVec2a[0]);\n pv.unshift(tempVec2a[1]);\n }\n\n const tr = earcut(pv, holes, 2);\n\n for (let k = 0; k < tr.length; k += 3) {\n primitiveCfg.indices.unshift(boundary[tr[k]]);\n primitiveCfg.indices.unshift(boundary[tr[k + 1]]);\n primitiveCfg.indices.unshift(boundary[tr[k + 2]]);\n }\n }\n }\n}\n\nfunction extractLocalIndices(ctx, boundary, sharedIndices, geometryCfg) {\n\n const vertices = ctx.vertices;\n const newBoundary = []\n\n for (let i = 0, len = boundary.length; i < len; i++) {\n\n const index = boundary[i];\n\n if (sharedIndices.includes(index)) {\n const vertexIndex = sharedIndices.indexOf(index);\n newBoundary.push(vertexIndex);\n\n } else {\n geometryCfg.positions.push(vertices[index][0]);\n geometryCfg.positions.push(vertices[index][1]);\n geometryCfg.positions.push(vertices[index][2]);\n\n newBoundary.push(sharedIndices.length);\n\n sharedIndices.push(index);\n }\n }\n\n return newBoundary\n}\n\nfunction getNormalOfPositions(positions, normal) {\n\n for (let i = 0; i < positions.length; i++) {\n\n let nexti = i + 1;\n if (nexti === positions.length) {\n nexti = 0;\n }\n\n normal[0] += ((positions[i].y - positions[nexti].y) * (positions[i].z + positions[nexti].z));\n normal[1] += ((positions[i].z - positions[nexti].z) * (positions[i].x + positions[nexti].x));\n normal[2] += ((positions[i].x - positions[nexti].x) * (positions[i].y + positions[nexti].y));\n }\n\n return math.normalizeVec3(normal);\n}\n\nfunction to2D(_p, _n, re) {\n\n const p = tempVec3a;\n const n = tempVec3b;\n const x3 = tempVec3c;\n\n p[0] = _p.x;\n p[1] = _p.y;\n p[2] = _p.z;\n\n n[0] = _n.x;\n n[1] = _n.y;\n n[2] = _n.z;\n\n x3[0] = 1.1;\n x3[1] = 1.1;\n x3[2] = 1.1;\n\n const dist = math.lenVec3(math.subVec3(x3, n));\n\n if (dist < 0.01) {\n x3[0] += 1.0;\n x3[1] += 2.0;\n x3[2] += 3.0;\n }\n\n const dot = math.dotVec3(x3, n);\n const tmp2 = math.mulVec3Scalar(n, dot, math.vec3());\n\n x3[0] -= tmp2[0];\n x3[1] -= tmp2[1];\n x3[2] -= tmp2[2];\n\n math.normalizeVec3(x3);\n\n const y3 = math.cross3Vec3(n, x3, math.vec3());\n const x = math.dotVec3(p, x3);\n const y = math.dotVec3(p, y3);\n\n re[0] = x;\n re[1] = y;\n}\n\nexport {parseCityJSONIntoXKTModel};","function isString(value) {\n return (typeof value === 'string' || value instanceof String);\n}\n\nfunction apply(o, o2) {\n for (const name in o) {\n if (o.hasOwnProperty(name)) {\n o2[name] = o[name];\n }\n }\n return o2;\n}\n\n/**\n * @private\n */\nconst utils = {\n isString,\n apply\n};\n\nexport {utils};\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/gltf\");","import {utils} from \"../XKTModel/lib/utils.js\";\nimport {math} from \"../lib/math.js\";\n\nimport {parse} from '@loaders.gl/core';\nimport {GLTFLoader} from '@loaders.gl/gltf';\nimport {\n ClampToEdgeWrapping,\n LinearFilter,\n LinearMipMapLinearFilter,\n LinearMipMapNearestFilter,\n MirroredRepeatWrapping,\n NearestFilter,\n NearestMipMapLinearFilter,\n NearestMipMapNearestFilter,\n RepeatWrapping\n} from \"../constants.js\";\n\n/**\n * @desc Parses glTF into an {@link XKTModel}, supporting ````.glb```` and textures.\n *\n * * Supports ````.glb```` and textures\n * * For a lightweight glTF JSON parser that ignores textures, see {@link parseGLTFJSONIntoXKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a binary glTF model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"../assets/models/gltf/HousePlan/glTF-Binary/HousePlan.glb\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseGLTFIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing parameters.\n * @param {ArrayBuffer} params.data The glTF.\n * @param {String} [params.baseUri] The base URI used to load this glTF, if any. For resolving relative uris to linked resources.\n * @param {Object} [params.metaModelData] Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Boolean} [params.includeTextures=true] Whether to parse textures.\n * @param {Boolean} [params.includeNormals=true] Whether to parse normals. When false, the parser will ignore the glTF\n * geometry normals, and the glTF data will rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the glTF.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when glTF has been parsed.\n */\nfunction parseGLTFIntoXKTModel({\n data,\n baseUri,\n xktModel,\n metaModelData,\n includeTextures = true,\n includeNormals = true,\n getAttachment,\n stats = {},\n log\n }) {\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n stats.sourceFormat = \"glTF\";\n stats.schemaVersion = \"2.0\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numUVs = 0;\n stats.numTextures = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n parse(data, GLTFLoader, {\n baseUri\n }).then((gltfData) => {\n\n const ctx = {\n gltfData,\n metaModelCorrections: metaModelData,\n getAttachment: getAttachment || (() => {\n throw new Error('You must define getAttachment() method to convert glTF with external resources')\n }),\n log: (log || function (msg) {\n }),\n error: function (msg) {\n console.error(msg);\n },\n xktModel,\n includeNormals: (includeNormals !== false),\n includeTextures: (includeTextures !== false),\n geometryCreated: {},\n nextId: 0,\n stats\n };\n\n ctx.log(\"Using parser: parseGLTFIntoXKTModel\");\n ctx.log(`Parsing normals: ${ctx.includeNormals ? \"enabled\" : \"disabled\"}`);\n ctx.log(`Parsing textures: ${ctx.includeTextures ? \"enabled\" : \"disabled\"}`);\n\n if (ctx.includeTextures) {\n parseTextures(ctx);\n }\n parseMaterials(ctx);\n parseDefaultScene(ctx);\n\n resolve();\n\n }, (errMsg) => {\n reject(`[parseGLTFIntoXKTModel] ${errMsg}`);\n });\n });\n}\n\nfunction parseTextures(ctx) {\n const gltfData = ctx.gltfData;\n const textures = gltfData.textures;\n if (textures) {\n for (let i = 0, len = textures.length; i < len; i++) {\n parseTexture(ctx, textures[i]);\n ctx.stats.numTextures++;\n }\n }\n}\n\nfunction parseTexture(ctx, texture) {\n if (!texture.source || !texture.source.image) {\n return;\n }\n const textureId = `texture-${ctx.nextId++}`;\n\n let minFilter = NearestMipMapLinearFilter;\n switch (texture.sampler.minFilter) {\n case 9728:\n minFilter = NearestFilter;\n break;\n case 9729:\n minFilter = LinearFilter;\n break;\n case 9984:\n minFilter = NearestMipMapNearestFilter;\n break;\n case 9985:\n minFilter = LinearMipMapNearestFilter;\n break;\n case 9986:\n minFilter = NearestMipMapLinearFilter;\n break;\n case 9987:\n minFilter = LinearMipMapLinearFilter;\n break;\n }\n\n let magFilter = LinearFilter;\n switch (texture.sampler.magFilter) {\n case 9728:\n magFilter = NearestFilter;\n break;\n case 9729:\n magFilter = LinearFilter;\n break;\n }\n\n let wrapS = RepeatWrapping;\n switch (texture.sampler.wrapS) {\n case 33071:\n wrapS = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapS = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapS = RepeatWrapping;\n break;\n }\n\n let wrapT = RepeatWrapping;\n switch (texture.sampler.wrapT) {\n case 33071:\n wrapT = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapT = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapT = RepeatWrapping;\n break;\n }\n\n let wrapR = RepeatWrapping;\n switch (texture.sampler.wrapR) {\n case 33071:\n wrapR = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapR = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapR = RepeatWrapping;\n break;\n }\n\n ctx.xktModel.createTexture({\n textureId: textureId,\n imageData: texture.source.image,\n mediaType: texture.source.mediaType,\n compressed: true,\n width: texture.source.image.width,\n height: texture.source.image.height,\n minFilter,\n magFilter,\n wrapS,\n wrapT,\n wrapR,\n flipY: !!texture.flipY,\n // encoding: \"sRGB\"\n });\n texture._textureId = textureId;\n}\n\nfunction parseMaterials(ctx) {\n const gltfData = ctx.gltfData;\n const materials = gltfData.materials;\n if (materials) {\n for (let i = 0, len = materials.length; i < len; i++) {\n const material = materials[i];\n material._textureSetId = ctx.includeTextures ? parseTextureSet(ctx, material) : null;\n material._attributes = parseMaterialAttributes(ctx, material);\n }\n }\n}\n\nfunction parseTextureSet(ctx, material) {\n const textureSetCfg = {};\n if (material.normalTexture) {\n textureSetCfg.normalTextureId = material.normalTexture.texture._textureId;\n }\n if (material.occlusionTexture) {\n textureSetCfg.occlusionTextureId = material.occlusionTexture.texture._textureId;\n }\n if (material.emissiveTexture) {\n textureSetCfg.emissiveTextureId = material.emissiveTexture.texture._textureId;\n }\n // const alphaMode = material.alphaMode;\n // switch (alphaMode) {\n // case \"NORMAL_OPAQUE\":\n // materialCfg.alphaMode = \"opaque\";\n // break;\n // case \"MASK\":\n // materialCfg.alphaMode = \"mask\";\n // break;\n // case \"BLEND\":\n // materialCfg.alphaMode = \"blend\";\n // break;\n // default:\n // }\n // const alphaCutoff = material.alphaCutoff;\n // if (alphaCutoff !== undefined) {\n // materialCfg.alphaCutoff = alphaCutoff;\n // }\n const metallicPBR = material.pbrMetallicRoughness;\n if (material.pbrMetallicRoughness) {\n const pbrMetallicRoughness = material.pbrMetallicRoughness;\n const baseColorTexture = pbrMetallicRoughness.baseColorTexture || pbrMetallicRoughness.colorTexture;\n if (baseColorTexture) {\n if (baseColorTexture.texture) {\n textureSetCfg.colorTextureId = baseColorTexture.texture._textureId;\n } else {\n textureSetCfg.colorTextureId = ctx.gltfData.textures[baseColorTexture.index]._textureId;\n }\n }\n if (metallicPBR.metallicRoughnessTexture) {\n textureSetCfg.metallicRoughnessTextureId = metallicPBR.metallicRoughnessTexture.texture._textureId;\n }\n }\n const extensions = material.extensions;\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const specularTexture = specularPBR.specularTexture;\n if (specularTexture !== null && specularTexture !== undefined) {\n // textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n }\n const specularColorTexture = specularPBR.specularColorTexture;\n if (specularColorTexture !== null && specularColorTexture !== undefined) {\n textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n }\n }\n }\n if (textureSetCfg.normalTextureId !== undefined ||\n textureSetCfg.occlusionTextureId !== undefined ||\n textureSetCfg.emissiveTextureId !== undefined ||\n textureSetCfg.colorTextureId !== undefined ||\n textureSetCfg.metallicRoughnessTextureId !== undefined) {\n textureSetCfg.textureSetId = `textureSet-${ctx.nextId++};`\n ctx.xktModel.createTextureSet(textureSetCfg);\n ctx.stats.numTextureSets++;\n return textureSetCfg.textureSetId;\n }\n return null;\n}\n\nfunction parseMaterialAttributes(ctx, material) { // Substitute RGBA for material, to use fast flat shading instead\n const extensions = material.extensions;\n const materialAttributes = {\n color: new Float32Array([1, 1, 1, 1]),\n opacity: 1,\n metallic: 0,\n roughness: 1\n };\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const diffuseFactor = specularPBR.diffuseFactor;\n if (diffuseFactor !== null && diffuseFactor !== undefined) {\n materialAttributes.color.set(diffuseFactor);\n }\n }\n const common = extensions[\"KHR_materials_common\"];\n if (common) {\n const technique = common.technique;\n const values = common.values || {};\n const blinn = technique === \"BLINN\";\n const phong = technique === \"PHONG\";\n const lambert = technique === \"LAMBERT\";\n const diffuse = values.diffuse;\n if (diffuse && (blinn || phong || lambert)) {\n if (!utils.isString(diffuse)) {\n materialAttributes.color.set(diffuse);\n }\n }\n const transparency = values.transparency;\n if (transparency !== null && transparency !== undefined) {\n materialAttributes.opacity = transparency;\n }\n const transparent = values.transparent;\n if (transparent !== null && transparent !== undefined) {\n materialAttributes.opacity = transparent;\n }\n }\n }\n const metallicPBR = material.pbrMetallicRoughness;\n if (metallicPBR) {\n const baseColorFactor = metallicPBR.baseColorFactor;\n if (baseColorFactor) {\n materialAttributes.color[0] = baseColorFactor[0];\n materialAttributes.color[1] = baseColorFactor[1];\n materialAttributes.color[2] = baseColorFactor[2];\n materialAttributes.opacity = baseColorFactor[3];\n }\n const metallicFactor = metallicPBR.metallicFactor;\n if (metallicFactor !== null && metallicFactor !== undefined) {\n materialAttributes.metallic = metallicFactor;\n }\n const roughnessFactor = metallicPBR.roughnessFactor;\n if (roughnessFactor !== null && roughnessFactor !== undefined) {\n materialAttributes.roughness = roughnessFactor;\n }\n }\n return materialAttributes;\n}\n\nfunction parseDefaultScene(ctx) {\n const gltfData = ctx.gltfData;\n const scene = gltfData.scene || gltfData.scenes[0];\n if (!scene) {\n ctx.error(\"glTF has no default scene\");\n return;\n }\n parseScene(ctx, scene);\n}\n\nfunction parseScene(ctx, scene) {\n const nodes = scene.nodes;\n if (!nodes) {\n return;\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const node = nodes[i];\n countMeshUsage(ctx, node);\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const node = nodes[i];\n parseNode(ctx, node, 0, null);\n }\n}\n\nfunction countMeshUsage(ctx, node) {\n const mesh = node.mesh;\n if (mesh) {\n mesh.instances = mesh.instances ? mesh.instances + 1 : 1;\n }\n if (node.children) {\n const children = node.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNode = children[i];\n if (!childNode) {\n ctx.error(\"Node not found: \" + i);\n continue;\n }\n countMeshUsage(ctx, childNode);\n }\n }\n}\n\nconst objectIdStack = [];\nconst meshIdsStack = [];\n\nlet meshIds = null;\n\nfunction parseNode(ctx, node, depth, matrix) {\n\n const xktModel = ctx.xktModel;\n\n // Pre-order visit scene node\n\n let localMatrix;\n if (node.matrix) {\n localMatrix = node.matrix;\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.translation) {\n localMatrix = math.translationMat4v(node.translation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.rotation) {\n localMatrix = math.quaternionToMat4(node.rotation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.scale) {\n localMatrix = math.scalingMat4v(node.scale);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n\n if (node.name) {\n meshIds = [];\n let xktEntityId = node.name;\n if (!!xktEntityId && xktModel.entities[xktEntityId]) {\n ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${xktEntityId} - will randomly-generating an object ID in XKT`);\n }\n while (!xktEntityId || xktModel.entities[xktEntityId]) {\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n objectIdStack.push(xktEntityId);\n meshIdsStack.push(meshIds);\n }\n\n if (meshIds && node.mesh) {\n\n const mesh = node.mesh;\n const numPrimitives = mesh.primitives.length;\n\n if (numPrimitives > 0) {\n for (let i = 0; i < numPrimitives; i++) {\n const primitive = mesh.primitives[i];\n if (!primitive._xktGeometryId) {\n const xktGeometryId = \"geometry-\" + ctx.nextId++;\n const geometryCfg = {\n geometryId: xktGeometryId\n };\n switch (primitive.mode) {\n case 0: // POINTS\n geometryCfg.primitiveType = \"points\";\n break;\n case 1: // LINES\n geometryCfg.primitiveType = \"lines\";\n break;\n case 2: // LINE_LOOP\n geometryCfg.primitiveType = \"line-loop\";\n break;\n case 3: // LINE_STRIP\n geometryCfg.primitiveType = \"line-strip\";\n break;\n case 4: // TRIANGLES\n geometryCfg.primitiveType = \"triangles\";\n break;\n case 5: // TRIANGLE_STRIP\n geometryCfg.primitiveType = \"triangle-strip\";\n break;\n case 6: // TRIANGLE_FAN\n geometryCfg.primitiveType = \"triangle-fan\";\n break;\n default:\n geometryCfg.primitiveType = \"triangles\";\n }\n const POSITION = primitive.attributes.POSITION;\n if (!POSITION) {\n continue;\n }\n geometryCfg.positions = primitive.attributes.POSITION.value;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n if (ctx.includeNormals) {\n if (primitive.attributes.NORMAL) {\n geometryCfg.normals = primitive.attributes.NORMAL.value;\n ctx.stats.numNormals += geometryCfg.normals.length / 3;\n }\n }\n if (primitive.attributes.COLOR_0) {\n geometryCfg.colorsCompressed = primitive.attributes.COLOR_0.value;\n }\n if (ctx.includeTextures) {\n if (primitive.attributes.TEXCOORD_0) {\n geometryCfg.uvs = primitive.attributes.TEXCOORD_0.value;\n ctx.stats.numUVs += geometryCfg.uvs.length / 2;\n }\n }\n if (primitive.indices) {\n geometryCfg.indices = primitive.indices.value;\n if (primitive.mode === 4) {\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n }\n }\n xktModel.createGeometry(geometryCfg);\n primitive._xktGeometryId = xktGeometryId;\n ctx.stats.numGeometries++;\n }\n\n const xktMeshId = ctx.nextId++;\n const meshCfg = {\n meshId: xktMeshId,\n geometryId: primitive._xktGeometryId,\n matrix: matrix ? matrix.slice() : math.identityMat4()\n };\n const material = primitive.material;\n if (material) {\n meshCfg.textureSetId = material._textureSetId;\n meshCfg.color = material._attributes.color;\n meshCfg.opacity = material._attributes.opacity;\n meshCfg.metallic = material._attributes.metallic;\n meshCfg.roughness = material._attributes.roughness;\n } else {\n meshCfg.color = [1.0, 1.0, 1.0];\n meshCfg.opacity = 1.0;\n }\n xktModel.createMesh(meshCfg);\n meshIds.push(xktMeshId);\n }\n }\n }\n\n // Visit child scene nodes\n\n if (node.children) {\n const children = node.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNode = children[i];\n parseNode(ctx, childNode, depth + 1, matrix);\n }\n }\n\n // Post-order visit scene node\n\n const nodeName = node.name;\n if ((nodeName !== undefined && nodeName !== null) || depth === 0) {\n if (nodeName === undefined || nodeName === null) {\n ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);\n }\n let xktEntityId = objectIdStack.pop();\n if (!xktEntityId) { // For when there are no nodes with names\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n let entityMeshIds = meshIdsStack.pop();\n if (meshIds && meshIds.length > 0) {\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: entityMeshIds\n });\n }\n ctx.stats.numObjects++;\n meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null;\n }\n}\n\nexport {parseGLTFIntoXKTModel};","import {utils} from \"../XKTModel/lib/utils.js\";\nimport {math} from \"../lib/math.js\";\n\nconst atob2 = (typeof atob !== 'undefined') ? atob : a => Buffer.from(a, 'base64').toString('binary');\n\nconst WEBGL_COMPONENT_TYPES = {\n 5120: Int8Array,\n 5121: Uint8Array,\n 5122: Int16Array,\n 5123: Uint16Array,\n 5125: Uint32Array,\n 5126: Float32Array\n};\n\nconst WEBGL_TYPE_SIZES = {\n 'SCALAR': 1,\n 'VEC2': 2,\n 'VEC3': 3,\n 'VEC4': 4,\n 'MAT2': 4,\n 'MAT3': 9,\n 'MAT4': 16\n};\n\n/**\n * @desc Parses glTF JSON into an {@link XKTModel}, without ````.glb```` and textures.\n *\n * * Lightweight JSON-based glTF parser which ignores textures\n * * For texture and ````.glb```` support, see {@link parseGLTFIntoXKTModel}\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a glTF model into it.\n *\n * ````javascript\n * utils.loadJSON(\"./models/gltf/duplex/scene.gltf\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseGLTFJSONIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing parameters.\n * @param {Object} params.data The glTF JSON.\n * @param {Object} [params.metaModelData] Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Boolean} [params.includeNormals=false] Whether to parse normals. When false, the parser will ignore the glTF\n * geometry normals, and the glTF data will rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded representation of the glTF.\n * @param {Boolean} [params.reuseGeometries=true] When true, the parser will enable geometry reuse within the XKTModel. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be if we have 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {function} [params.getAttachment] Callback through which to fetch attachments, if the glTF has them.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n * @returns {Promise}\n */\nfunction parseGLTFJSONIntoXKTModel({\n data,\n xktModel,\n metaModelData,\n includeNormals,\n reuseGeometries,\n getAttachment,\n stats = {},\n log\n }) {\n\n if (log) {\n log(\"Using parser: parseGLTFJSONIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n stats.sourceFormat = \"glTF\";\n stats.schemaVersion = \"2.0\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n const ctx = {\n gltf: data,\n metaModelCorrections: metaModelData ? getMetaModelCorrections(metaModelData) : null,\n getAttachment: getAttachment || (() => {\n throw new Error('You must define getAttachment() method to convert glTF with external resources')\n }),\n log: (log || function (msg) {\n }),\n xktModel,\n includeNormals,\n createXKTGeometryIds: {},\n nextMeshId: 0,\n reuseGeometries: (reuseGeometries !== false),\n stats\n };\n\n ctx.log(`Parsing normals: ${ctx.includeNormals ? \"enabled\" : \"disabled\"}`);\n\n parseBuffers(ctx).then(() => {\n\n parseBufferViews(ctx);\n freeBuffers(ctx);\n parseMaterials(ctx);\n parseDefaultScene(ctx);\n\n resolve();\n\n }, (errMsg) => {\n reject(errMsg);\n });\n });\n}\n\nfunction getMetaModelCorrections(metaModelData) {\n const eachRootStats = {};\n const eachChildRoot = {};\n const metaObjects = metaModelData.metaObjects || [];\n const metaObjectsMap = {};\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n const metaObject = metaObjects[i];\n metaObjectsMap[metaObject.id] = metaObject;\n }\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n const metaObject = metaObjects[i];\n if (metaObject.parent !== undefined && metaObject.parent !== null) {\n const metaObjectParent = metaObjectsMap[metaObject.parent];\n if (metaObject.type === metaObjectParent.type) {\n let rootMetaObject = metaObjectParent;\n while (rootMetaObject.parent && metaObjectsMap[rootMetaObject.parent].type === rootMetaObject.type) {\n rootMetaObject = metaObjectsMap[rootMetaObject.parent];\n }\n const rootStats = eachRootStats[rootMetaObject.id] || (eachRootStats[rootMetaObject.id] = {\n numChildren: 0,\n countChildren: 0\n });\n rootStats.numChildren++;\n eachChildRoot[metaObject.id] = rootMetaObject;\n } else {\n\n }\n }\n }\n const metaModelCorrections = {\n metaObjectsMap,\n eachRootStats,\n eachChildRoot\n };\n return metaModelCorrections;\n}\n\nfunction parseBuffers(ctx) { // Parses geometry buffers into temporary \"_buffer\" Unit8Array properties on the glTF \"buffer\" elements\n const buffers = ctx.gltf.buffers;\n if (buffers) {\n return Promise.all(buffers.map(buffer => parseBuffer(ctx, buffer)));\n } else {\n return new Promise(function (resolve, reject) {\n resolve();\n });\n }\n}\n\nfunction parseBuffer(ctx, bufferInfo) {\n return new Promise(function (resolve, reject) {\n // Allow a shortcut where the glTF buffer is \"enrichened\" with direct\n // access to the data-arrayBuffer, w/out needing to either:\n // - read the file indicated by the \".uri\" component of the buffer\n // - base64-decode the encoded data in the \".uri\" component\n if (bufferInfo._arrayBuffer) {\n bufferInfo._buffer = bufferInfo._arrayBuffer;\n resolve(bufferInfo);\n return;\n }\n // Otherwise, proceed with \"standard-glTF\" .uri component.\n const uri = bufferInfo.uri;\n if (!uri) {\n reject('gltf/handleBuffer missing uri in ' + JSON.stringify(bufferInfo));\n return;\n }\n parseArrayBuffer(ctx, uri).then((arrayBuffer) => {\n bufferInfo._buffer = arrayBuffer;\n resolve(arrayBuffer);\n }, (errMsg) => {\n reject(errMsg);\n })\n });\n}\n\nfunction parseArrayBuffer(ctx, uri) {\n return new Promise(function (resolve, reject) {\n const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; // Check for data: URI\n const dataUriRegexResult = uri.match(dataUriRegex);\n if (dataUriRegexResult) { // Safari can't handle data URIs through XMLHttpRequest\n const isBase64 = !!dataUriRegexResult[2];\n let data = dataUriRegexResult[3];\n data = decodeURIComponent(data);\n if (isBase64) {\n data = atob2(data);\n }\n const buffer = new ArrayBuffer(data.length);\n const view = new Uint8Array(buffer);\n for (let i = 0; i < data.length; i++) {\n view[i] = data.charCodeAt(i);\n }\n resolve(buffer);\n } else { // Uri is a path to a file\n ctx.getAttachment(uri).then(\n (arrayBuffer) => {\n resolve(arrayBuffer);\n },\n (errMsg) => {\n reject(errMsg);\n });\n }\n });\n}\n\nfunction parseBufferViews(ctx) { // Parses our temporary \"_buffer\" properties into \"_buffer\" properties on glTF \"bufferView\" elements\n const bufferViewsInfo = ctx.gltf.bufferViews;\n if (bufferViewsInfo) {\n for (let i = 0, len = bufferViewsInfo.length; i < len; i++) {\n parseBufferView(ctx, bufferViewsInfo[i]);\n }\n }\n}\n\nfunction parseBufferView(ctx, bufferViewInfo) {\n const buffer = ctx.gltf.buffers[bufferViewInfo.buffer];\n bufferViewInfo._typedArray = null;\n const byteLength = bufferViewInfo.byteLength || 0;\n const byteOffset = bufferViewInfo.byteOffset || 0;\n bufferViewInfo._buffer = buffer._buffer.slice(byteOffset, byteOffset + byteLength);\n}\n\nfunction freeBuffers(ctx) { // Deletes the \"_buffer\" properties from the glTF \"buffer\" elements, to save memory\n const buffers = ctx.gltf.buffers;\n if (buffers) {\n for (let i = 0, len = buffers.length; i < len; i++) {\n buffers[i]._buffer = null;\n }\n }\n}\n\nfunction parseMaterials(ctx) {\n const materialsInfo = ctx.gltf.materials;\n if (materialsInfo) {\n for (let i = 0, len = materialsInfo.length; i < len; i++) {\n const materialInfo = materialsInfo[i];\n const material = parseMaterial(ctx, materialInfo);\n materialInfo._materialData = material;\n }\n }\n}\n\nfunction parseMaterial(ctx, materialInfo) { // Attempts to extract an RGBA color for a glTF material\n const material = {\n color: new Float32Array([1, 1, 1]),\n opacity: 1.0,\n metallic: 0,\n roughness: 1\n };\n const extensions = materialInfo.extensions;\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const diffuseFactor = specularPBR.diffuseFactor;\n if (diffuseFactor !== null && diffuseFactor !== undefined) {\n material.color[0] = diffuseFactor[0];\n material.color[1] = diffuseFactor[1];\n material.color[2] = diffuseFactor[2];\n }\n }\n const common = extensions[\"KHR_materials_common\"];\n if (common) {\n const technique = common.technique;\n const values = common.values || {};\n const blinn = technique === \"BLINN\";\n const phong = technique === \"PHONG\";\n const lambert = technique === \"LAMBERT\";\n const diffuse = values.diffuse;\n if (diffuse && (blinn || phong || lambert)) {\n if (!utils.isString(diffuse)) {\n material.color[0] = diffuse[0];\n material.color[1] = diffuse[1];\n material.color[2] = diffuse[2];\n }\n }\n const transparency = values.transparency;\n if (transparency !== null && transparency !== undefined) {\n material.opacity = transparency;\n }\n const transparent = values.transparent;\n if (transparent !== null && transparent !== undefined) {\n material.opacity = transparent;\n }\n }\n }\n const metallicPBR = materialInfo.pbrMetallicRoughness;\n if (metallicPBR) {\n const baseColorFactor = metallicPBR.baseColorFactor;\n if (baseColorFactor) {\n material.color[0] = baseColorFactor[0];\n material.color[1] = baseColorFactor[1];\n material.color[2] = baseColorFactor[2];\n material.opacity = baseColorFactor[3];\n }\n const metallicFactor = metallicPBR.metallicFactor;\n if (metallicFactor !== null && metallicFactor !== undefined) {\n material.metallic = metallicFactor;\n }\n const roughnessFactor = metallicPBR.roughnessFactor;\n if (roughnessFactor !== null && roughnessFactor !== undefined) {\n material.roughness = roughnessFactor;\n }\n }\n return material;\n}\n\nfunction parseDefaultScene(ctx) {\n const scene = ctx.gltf.scene || 0;\n const defaultSceneInfo = ctx.gltf.scenes[scene];\n if (!defaultSceneInfo) {\n throw new Error(\"glTF has no default scene\");\n }\n parseScene(ctx, defaultSceneInfo);\n}\n\n\nfunction parseScene(ctx, sceneInfo) {\n const nodes = sceneInfo.nodes;\n if (!nodes) {\n return;\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const glTFNode = ctx.gltf.nodes[nodes[i]];\n if (glTFNode) {\n parseNode(ctx, glTFNode, 0, null);\n }\n }\n}\n\nlet deferredMeshIds = [];\n\nfunction parseNode(ctx, glTFNode, depth, matrix) {\n\n const gltf = ctx.gltf;\n const xktModel = ctx.xktModel;\n\n let localMatrix;\n\n if (glTFNode.matrix) {\n localMatrix = glTFNode.matrix;\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n\n if (glTFNode.translation) {\n localMatrix = math.translationMat4v(glTFNode.translation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, localMatrix);\n } else {\n matrix = localMatrix;\n }\n }\n\n if (glTFNode.rotation) {\n localMatrix = math.quaternionToMat4(glTFNode.rotation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, localMatrix);\n } else {\n matrix = localMatrix;\n }\n }\n\n if (glTFNode.scale) {\n localMatrix = math.scalingMat4v(glTFNode.scale);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, localMatrix);\n } else {\n matrix = localMatrix;\n }\n }\n\n const gltfMeshId = glTFNode.mesh;\n\n if (gltfMeshId !== undefined) {\n\n const meshInfo = gltf.meshes[gltfMeshId];\n\n if (meshInfo) {\n\n const numPrimitivesInMesh = meshInfo.primitives.length;\n\n if (numPrimitivesInMesh > 0) {\n\n for (let i = 0; i < numPrimitivesInMesh; i++) {\n\n const primitiveInfo = meshInfo.primitives[i];\n\n const geometryHash = createPrimitiveGeometryHash(primitiveInfo);\n\n let xktGeometryId = ctx.createXKTGeometryIds[geometryHash];\n\n if ((!ctx.reuseGeometries) || !xktGeometryId) {\n\n xktGeometryId = \"geometry-\" + ctx.nextMeshId++\n\n const geometryArrays = {};\n\n parsePrimitiveGeometry(ctx, primitiveInfo, geometryArrays);\n\n const colors = geometryArrays.colors;\n\n let colorsCompressed;\n\n if (geometryArrays.colors) {\n colorsCompressed = [];\n for (let j = 0, lenj = colors.length; j < lenj; j += 4) {\n colorsCompressed.push(colors[j + 0]);\n colorsCompressed.push(colors[j + 1]);\n colorsCompressed.push(colors[j + 2]);\n colorsCompressed.push(255);\n }\n }\n\n xktModel.createGeometry({\n geometryId: xktGeometryId,\n primitiveType: geometryArrays.primitive,\n positions: geometryArrays.positions,\n normals: ctx.includeNormals ? geometryArrays.normals : null,\n colorsCompressed: colorsCompressed,\n indices: geometryArrays.indices\n });\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += geometryArrays.positions ? geometryArrays.positions.length / 3 : 0;\n ctx.stats.numNormals += (ctx.includeNormals && geometryArrays.normals) ? geometryArrays.normals.length / 3 : 0;\n ctx.stats.numTriangles += geometryArrays.indices ? geometryArrays.indices.length / 3 : 0;\n\n ctx.createXKTGeometryIds[geometryHash] = xktGeometryId;\n } else {\n// Geometry reused\n }\n\n const materialIndex = primitiveInfo.material;\n const materialInfo = (materialIndex !== null && materialIndex !== undefined) ? gltf.materials[materialIndex] : null;\n const color = materialInfo ? materialInfo._materialData.color : new Float32Array([1.0, 1.0, 1.0, 1.0]);\n const opacity = materialInfo ? materialInfo._materialData.opacity : 1.0;\n const metallic = materialInfo ? materialInfo._materialData.metallic : 0.0;\n const roughness = materialInfo ? materialInfo._materialData.roughness : 1.0;\n\n const xktMeshId = \"mesh-\" + ctx.nextMeshId++;\n\n xktModel.createMesh({\n meshId: xktMeshId,\n geometryId: xktGeometryId,\n matrix: matrix ? matrix.slice() : math.identityMat4(),\n color: color,\n opacity: opacity,\n metallic: metallic,\n roughness: roughness\n });\n\n deferredMeshIds.push(xktMeshId);\n }\n }\n }\n }\n\n\n if (glTFNode.children) {\n const children = glTFNode.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNodeIdx = children[i];\n const childGLTFNode = gltf.nodes[childNodeIdx];\n if (!childGLTFNode) {\n console.warn('Node not found: ' + i);\n continue;\n }\n parseNode(ctx, childGLTFNode, depth + 1, matrix);\n }\n }\n\n // Post-order visit scene node\n\n const nodeName = glTFNode.name;\n if (((nodeName !== undefined && nodeName !== null) || depth === 0) && deferredMeshIds.length > 0) {\n if (nodeName === undefined || nodeName === null) {\n ctx.log(`[parseGLTFJSONIntoXKTModel] Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);\n }\n let xktEntityId = nodeName; // Fall back on generated ID when `name` not found on glTF scene node(s)\n if (xktEntityId === undefined || xktEntityId === null) {\n if (xktModel.entities[xktEntityId]) {\n ctx.error(\"Two or more glTF nodes found with same 'name' attribute: '\" + nodeName + \"'\");\n }\n while (!xktEntityId || xktModel.entities[xktEntityId]) {\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n }\n if (ctx.metaModelCorrections) { // Merging meshes into XKTObjects that map to metaobjects\n const rootMetaObject = ctx.metaModelCorrections.eachChildRoot[xktEntityId];\n if (rootMetaObject) {\n const rootMetaObjectStats = ctx.metaModelCorrections.eachRootStats[rootMetaObject.id];\n rootMetaObjectStats.countChildren++;\n if (rootMetaObjectStats.countChildren >= rootMetaObjectStats.numChildren) {\n xktModel.createEntity({\n entityId: rootMetaObject.id,\n meshIds: deferredMeshIds\n });\n ctx.stats.numObjects++;\n deferredMeshIds = [];\n }\n } else {\n const metaObject = ctx.metaModelCorrections.metaObjectsMap[xktEntityId];\n if (metaObject) {\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: deferredMeshIds\n });\n ctx.stats.numObjects++;\n deferredMeshIds = [];\n }\n }\n } else { // Create an XKTObject from the meshes at each named glTF node, don't care about metaobjects\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: deferredMeshIds\n });\n ctx.stats.numObjects++;\n deferredMeshIds = [];\n }\n }\n}\n\nfunction createPrimitiveGeometryHash(primitiveInfo) {\n const attributes = primitiveInfo.attributes;\n if (!attributes) {\n return \"empty\";\n }\n const mode = primitiveInfo.mode;\n const material = primitiveInfo.material;\n const indices = primitiveInfo.indices;\n const positions = primitiveInfo.attributes.POSITION;\n const normals = primitiveInfo.attributes.NORMAL;\n const colors = primitiveInfo.attributes.COLOR_0;\n const uv = primitiveInfo.attributes.TEXCOORD_0;\n return [\n mode,\n // material,\n (indices !== null && indices !== undefined) ? indices : \"-\",\n (positions !== null && positions !== undefined) ? positions : \"-\",\n (normals !== null && normals !== undefined) ? normals : \"-\",\n (colors !== null && colors !== undefined) ? colors : \"-\",\n (uv !== null && uv !== undefined) ? uv : \"-\"\n ].join(\";\");\n}\n\nfunction parsePrimitiveGeometry(ctx, primitiveInfo, geometryArrays) {\n const attributes = primitiveInfo.attributes;\n if (!attributes) {\n return;\n }\n switch (primitiveInfo.mode) {\n case 0: // POINTS\n geometryArrays.primitive = \"points\";\n break;\n case 1: // LINES\n geometryArrays.primitive = \"lines\";\n break;\n case 2: // LINE_LOOP\n // TODO: convert\n geometryArrays.primitive = \"lines\";\n break;\n case 3: // LINE_STRIP\n // TODO: convert\n geometryArrays.primitive = \"lines\";\n break;\n case 4: // TRIANGLES\n geometryArrays.primitive = \"triangles\";\n break;\n case 5: // TRIANGLE_STRIP\n // TODO: convert\n console.log(\"TRIANGLE_STRIP\");\n geometryArrays.primitive = \"triangles\";\n break;\n case 6: // TRIANGLE_FAN\n // TODO: convert\n console.log(\"TRIANGLE_FAN\");\n geometryArrays.primitive = \"triangles\";\n break;\n default:\n geometryArrays.primitive = \"triangles\";\n }\n const accessors = ctx.gltf.accessors;\n const indicesIndex = primitiveInfo.indices;\n if (indicesIndex !== null && indicesIndex !== undefined) {\n const accessorInfo = accessors[indicesIndex];\n geometryArrays.indices = parseAccessorTypedArray(ctx, accessorInfo);\n }\n const positionsIndex = attributes.POSITION;\n if (positionsIndex !== null && positionsIndex !== undefined) {\n const accessorInfo = accessors[positionsIndex];\n geometryArrays.positions = parseAccessorTypedArray(ctx, accessorInfo);\n }\n const normalsIndex = attributes.NORMAL;\n if (normalsIndex !== null && normalsIndex !== undefined) {\n const accessorInfo = accessors[normalsIndex];\n geometryArrays.normals = parseAccessorTypedArray(ctx, accessorInfo);\n }\n const colorsIndex = attributes.COLOR_0;\n if (colorsIndex !== null && colorsIndex !== undefined) {\n const accessorInfo = accessors[colorsIndex];\n geometryArrays.colors = parseAccessorTypedArray(ctx, accessorInfo);\n }\n}\n\nfunction parseAccessorTypedArray(ctx, accessorInfo) {\n const bufferView = ctx.gltf.bufferViews[accessorInfo.bufferView];\n const itemSize = WEBGL_TYPE_SIZES[accessorInfo.type];\n const TypedArray = WEBGL_COMPONENT_TYPES[accessorInfo.componentType];\n const elementBytes = TypedArray.BYTES_PER_ELEMENT; // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.\n const itemBytes = elementBytes * itemSize;\n if (accessorInfo.byteStride && accessorInfo.byteStride !== itemBytes) { // The buffer is not interleaved if the stride is the item size in bytes.\n throw new Error(\"interleaved buffer!\"); // TODO\n } else {\n return new TypedArray(bufferView._buffer, accessorInfo.byteOffset || 0, accessorInfo.count * itemSize);\n }\n}\n\nexport {parseGLTFJSONIntoXKTModel};\n","/**\n * @desc Parses IFC STEP file data into an {@link XKTModel}.\n *\n * This function uses [web-ifc](https://github.com/tomvandig/web-ifc) to parse the IFC, which relies on a\n * WASM file to do the parsing.\n *\n * Depending on how we use this function, we may need to provide it with a path to the directory where that WASM file is stored.\n *\n * This function is tested with web-ifc version 0.0.34.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an IFC model into it.\n *\n * ````javascript\n * import {XKTModel, parseIFCIntoXKTModel, writeXKTModelToArrayBuffer} from \"xeokit-convert.es.js\";\n *\n * import * as WebIFC from \"web-ifc-api.js\";\n *\n * utils.loadArraybuffer(\"rac_advanced_sample_project.ifc\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseIFCIntoXKTModel({\n * WebIFC,\n * data,\n * xktModel,\n * wasmPath: \"../dist/\",\n * autoNormals: true,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {ArrayBuffer} [params.data] IFC file data.\n * @param {XKTModel} [params.xktModel] XKTModel to parse into.\n * @param {Boolean} [params.autoNormals=true] When true, the parser will ignore the IFC geometry normals, and the IFC\n * data will rely on the xeokit ````Viewer```` to automatically generate them. This has the limitation that the\n * normals will be face-aligned, and therefore the ````Viewer```` will only be able to render a flat-shaded representation\n * of the IFC model. This is ````true```` by default, because IFC models tend to look acceptable with flat-shading,\n * and we always want to minimize IFC model size wherever possible.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {String} params.wasmPath Path to ````web-ifc.wasm````, required by this function.\n * @param {Object} [params.stats={}] Collects statistics.\n * @param {function} [params.log] Logging callback.\n * @returns {Promise} Resolves when IFC has been parsed.\n */\nfunction parseIFCIntoXKTModel({\n WebIFC,\n data,\n xktModel,\n autoNormals = true,\n includeTypes,\n excludeTypes,\n wasmPath,\n stats = {},\n log\n }) {\n\n if (log) {\n log(\"Using parser: parseIFCIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n if (!wasmPath) {\n reject(\"Argument expected: wasmPath\");\n return;\n }\n\n const ifcAPI = new WebIFC.IfcAPI();\n\n if (wasmPath) {\n ifcAPI.SetWasmPath(wasmPath);\n }\n\n ifcAPI.Init().then(() => {\n\n const dataArray = new Uint8Array(data);\n\n const modelID = ifcAPI.OpenModel(dataArray);\n\n stats.sourceFormat = \"IFC\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 0;\n stats.numPropertySets = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n stats.numTriangles = 0;\n stats.numVertices = 0;\n\n const ctx = {\n WebIFC,\n modelID,\n ifcAPI,\n xktModel,\n autoNormals,\n log: (log || function (msg) {\n }),\n nextId: 0,\n stats\n };\n\n if (includeTypes) {\n ctx.includeTypes = {};\n for (let i = 0, len = includeTypes.length; i < len; i++) {\n ctx.includeTypes[includeTypes[i]] = true;\n }\n }\n\n if (excludeTypes) {\n ctx.excludeTypes = {};\n for (let i = 0, len = excludeTypes.length; i < len; i++) {\n ctx.excludeTypes[excludeTypes[i]] = true;\n }\n }\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(modelID, WebIFC.IFCPROJECT);\n const ifcProjectId = lines.get(0);\n const ifcProject = ctx.ifcAPI.GetLine(modelID, ifcProjectId);\n\n ctx.xktModel.schema = \"\";\n ctx.xktModel.modelId = \"\" + modelID;\n ctx.xktModel.projectId = \"\" + ifcProjectId;\n\n parseMetadata(ctx);\n parseGeometry(ctx);\n parsePropertySets(ctx);\n\n resolve();\n\n }).catch((e) => {\n\n reject(e);\n })\n });\n}\n\nfunction parsePropertySets(ctx) {\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, ctx.WebIFC.IFCRELDEFINESBYPROPERTIES);\n\n for (let i = 0; i < lines.size(); i++) {\n\n let relID = lines.get(i);\n\n let rel = ctx.ifcAPI.GetLine(ctx.modelID, relID, true);\n\n if (rel) {\n\n const relatingPropertyDefinition = rel.RelatingPropertyDefinition;\n if (!relatingPropertyDefinition) {\n continue;\n }\n\n const propertySetId = relatingPropertyDefinition.GlobalId.value;\n\n const relatedObjects = rel.RelatedObjects;\n if (relatedObjects) {\n for (let i = 0, len = relatedObjects.length; i < len; i++) {\n const relatedObject = relatedObjects[i];\n const metaObjectId = relatedObject.GlobalId.value;\n const metaObject = ctx.xktModel.metaObjects[metaObjectId];\n if (metaObject) {\n if (!metaObject.propertySetIds) {\n metaObject.propertySetIds = [];\n }\n metaObject.propertySetIds.push(propertySetId);\n }\n }\n }\n\n const props = relatingPropertyDefinition.HasProperties;\n if (props && props.length > 0) {\n const propertySetType = \"Default\";\n const propertySetName = relatingPropertyDefinition.Name.value;\n const properties = [];\n for (let i = 0, len = props.length; i < len; i++) {\n const prop = props[i];\n const name = prop.Name;\n const nominalValue = prop.NominalValue;\n if (name && nominalValue) {\n const property = {\n name: name.value,\n type: nominalValue.type,\n value: nominalValue.value,\n valueType: nominalValue.valueType\n };\n if (prop.Description) {\n property.description = prop.Description.value;\n } else if (nominalValue.description) {\n property.description = nominalValue.description;\n }\n properties.push(property);\n }\n }\n ctx.xktModel.createPropertySet({propertySetId, propertySetType, propertySetName, properties});\n ctx.stats.numPropertySets++;\n }\n }\n }\n}\n\nfunction parseMetadata(ctx) {\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, ctx.WebIFC.IFCPROJECT);\n const ifcProjectId = lines.get(0);\n const ifcProject = ctx.ifcAPI.GetLine(ctx.modelID, ifcProjectId);\n\n parseSpatialChildren(ctx, ifcProject);\n}\n\nfunction parseSpatialChildren(ctx, ifcElement, parentMetaObjectId) {\n\n const metaObjectType = ifcElement.__proto__.constructor.name;\n\n if (ctx.includeTypes && (!ctx.includeTypes[metaObjectType])) {\n return;\n }\n\n if (ctx.excludeTypes && ctx.excludeTypes[metaObjectType]) {\n return;\n }\n\n createMetaObject(ctx, ifcElement, parentMetaObjectId);\n\n const metaObjectId = ifcElement.GlobalId.value;\n\n parseRelatedItemsOfType(\n ctx,\n ifcElement.expressID,\n 'RelatingObject',\n 'RelatedObjects',\n ctx.WebIFC.IFCRELAGGREGATES,\n metaObjectId);\n\n parseRelatedItemsOfType(\n ctx,\n ifcElement.expressID,\n 'RelatingStructure',\n 'RelatedElements',\n ctx.WebIFC.IFCRELCONTAINEDINSPATIALSTRUCTURE,\n metaObjectId);\n}\n\nfunction createMetaObject(ctx, ifcElement, parentMetaObjectId) {\n\n const metaObjectId = ifcElement.GlobalId.value;\n const propertySetIds = null;\n const metaObjectType = ifcElement.__proto__.constructor.name;\n const metaObjectName = (ifcElement.Name && ifcElement.Name.value !== \"\") ? ifcElement.Name.value : metaObjectType;\n\n ctx.xktModel.createMetaObject({metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId});\n ctx.stats.numMetaObjects++;\n}\n\nfunction parseRelatedItemsOfType(ctx, id, relation, related, type, parentMetaObjectId) {\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, type);\n\n for (let i = 0; i < lines.size(); i++) {\n\n const relID = lines.get(i);\n const rel = ctx.ifcAPI.GetLine(ctx.modelID, relID);\n const relatedItems = rel[relation];\n\n let foundElement = false;\n\n if (Array.isArray(relatedItems)) {\n const values = relatedItems.map((item) => item.value);\n foundElement = values.includes(id);\n\n } else {\n foundElement = (relatedItems.value === id);\n }\n\n if (foundElement) {\n\n const element = rel[related];\n\n if (!Array.isArray(element)) {\n\n const ifcElement = ctx.ifcAPI.GetLine(ctx.modelID, element.value);\n\n parseSpatialChildren(ctx, ifcElement, parentMetaObjectId);\n\n } else {\n\n element.forEach((element2) => {\n\n const ifcElement = ctx.ifcAPI.GetLine(ctx.modelID, element2.value);\n\n parseSpatialChildren(ctx, ifcElement, parentMetaObjectId);\n });\n }\n }\n }\n}\n\nfunction parseGeometry(ctx) {\n\n // Parses the geometry and materials in the IFC, creates\n // XKTEntity, XKTMesh and XKTGeometry components within the XKTModel.\n\n const flatMeshes = ctx.ifcAPI.LoadAllGeometry(ctx.modelID);\n\n for (let i = 0, len = flatMeshes.size(); i < len; i++) {\n const flatMesh = flatMeshes.get(i);\n createObject(ctx, flatMesh);\n }\n\n // LoadAllGeometry does not return IFCSpace meshes\n // here is a workaround\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, ctx.WebIFC.IFCSPACE);\n for (let j = 0, len = lines.size(); j < len; j++) {\n const ifcSpaceId = lines.get(j);\n const flatMesh = ctx.ifcAPI.GetFlatMesh(ctx.modelID, ifcSpaceId);\n createObject(ctx, flatMesh);\n }\n}\n\nfunction createObject(ctx, flatMesh) {\n\n const flatMeshExpressID = flatMesh.expressID;\n const placedGeometries = flatMesh.geometries;\n\n const meshIds = [];\n\n const properties = ctx.ifcAPI.GetLine(ctx.modelID, flatMeshExpressID);\n const entityId = properties.GlobalId.value;\n\n const metaObjectId = entityId;\n const metaObject = ctx.xktModel.metaObjects[metaObjectId];\n\n if (ctx.includeTypes && (!metaObject || (!ctx.includeTypes[metaObject.metaObjectType]))) {\n return;\n }\n\n if (ctx.excludeTypes && (!metaObject || ctx.excludeTypes[metaObject.metaObjectType])) {\n console.log(\"excluding: \" + metaObjectId)\n return;\n }\n\n for (let j = 0, lenj = placedGeometries.size(); j < lenj; j++) {\n\n const placedGeometry = placedGeometries.get(j);\n const geometryId = \"\" + placedGeometry.geometryExpressID;\n\n if (!ctx.xktModel.geometries[geometryId]) {\n\n const geometry = ctx.ifcAPI.GetGeometry(ctx.modelID, placedGeometry.geometryExpressID);\n const vertexData = ctx.ifcAPI.GetVertexArray(geometry.GetVertexData(), geometry.GetVertexDataSize());\n const indices = ctx.ifcAPI.GetIndexArray(geometry.GetIndexData(), geometry.GetIndexDataSize());\n\n // De-interleave vertex arrays\n\n const positions = [];\n const normals = [];\n\n for (let k = 0, lenk = vertexData.length / 6; k < lenk; k++) {\n positions.push(vertexData[k * 6 + 0]);\n positions.push(vertexData[k * 6 + 1]);\n positions.push(vertexData[k * 6 + 2]);\n }\n\n if (!ctx.autoNormals) {\n for (let k = 0, lenk = vertexData.length / 6; k < lenk; k++) {\n normals.push(vertexData[k * 6 + 3]);\n normals.push(vertexData[k * 6 + 4]);\n normals.push(vertexData[k * 6 + 5]);\n }\n }\n\n ctx.xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: positions,\n normals: ctx.autoNormals ? null : normals,\n indices: indices\n });\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += (positions.length / 3);\n ctx.stats.numTriangles += (indices.length / 3);\n }\n\n const meshId = (\"mesh\" + ctx.nextId++);\n\n ctx.xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n matrix: placedGeometry.flatTransformation,\n color: [placedGeometry.color.x, placedGeometry.color.y, placedGeometry.color.z],\n opacity: placedGeometry.color.w\n });\n\n meshIds.push(meshId);\n }\n\n if (meshIds.length > 0) {\n ctx.xktModel.createEntity({\n entityId: entityId,\n meshIds: meshIds\n });\n ctx.stats.numObjects++;\n }\n}\n\nexport {parseIFCIntoXKTModel};\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/las\");","import {parse} from '@loaders.gl/core';\nimport {LASLoader} from '@loaders.gl/las';\n\nimport {math} from \"../lib/math.js\";\n\nconst MAX_VERTICES = 500000; // TODO: Rough estimate\n\n/**\n * @desc Parses LAS and LAZ point cloud data into an {@link XKTModel}.\n *\n * This parser handles both the LASER file format (LAS) and its compressed version (LAZ),\n * a public format for the interchange of 3-dimensional point cloud data data, developed\n * for LIDAR mapping purposes.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an LAZ point cloud model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"./models/laz/autzen.laz\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * await parseLASIntoXKTModel({\n * data,\n * xktModel,\n * rotateX: true,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer} params.data LAS/LAZ file data.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {boolean} [params.center=false] Set true to center the LAS point positions to [0,0,0]. This is applied before the transformation matrix, if specified.\n * @param {Boolean} [params.transform] 4x4 transformation matrix to transform point positions. Use this to rotate, translate and scale them if neccessary.\n * @param {Number|String} [params.colorDepth=8] Whether colors encoded using 8 or 16 bits. Can be set to 'auto'. LAS specification recommends 16 bits.\n * @param {Boolean} [params.fp64=false] Configures if LASLoaderPlugin assumes that LAS positions are stored in 64-bit floats instead of 32-bit.\n * @param {Number} [params.skip=1] Read one from every n points.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n * @returns {Promise} Resolves when LAS has been parsed.\n */\nfunction parseLASIntoXKTModel({\n data,\n xktModel,\n center = false,\n transform = null,\n colorDepth = \"auto\",\n fp64 = false,\n skip = 1,\n stats,\n log = () => {\n }\n }) {\n\n if (log) {\n log(\"Using parser: parseLASIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n log(\"Converting LAZ/LAS\");\n\n log(`center: ${center}`);\n if (transform) {\n log(`transform: [${transform}]`);\n }\n log(`colorDepth: ${colorDepth}`);\n log(`fp64: ${fp64}`);\n log(`skip: ${skip}`);\n\n parse(data, LASLoader, {\n las: {\n colorDepth,\n fp64\n }\n }).then((parsedData) => {\n\n const attributes = parsedData.attributes;\n\n const loaderData = parsedData.loaderData;\n const pointsFormatId = loaderData.pointsFormatId !== undefined ? loaderData.pointsFormatId : -1;\n\n if (!attributes.POSITION) {\n log(\"No positions found in file (expected for all LAS point formats)\");\n return;\n }\n\n let readAttributes = {};\n\n switch (pointsFormatId) {\n case 0:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 0)\");\n return;\n }\n\n readAttributes = readIntensities(attributes.POSITION, attributes.intensity);\n break;\n case 1:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 1)\");\n return;\n }\n readAttributes = readIntensities(attributes.POSITION, attributes.intensity);\n break;\n case 2:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 2)\");\n return;\n }\n\n readAttributes = readColorsAndIntensities(attributes.POSITION, attributes.COLOR_0, attributes.intensity);\n break;\n case 3:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 3)\");\n return;\n }\n readAttributes = readColorsAndIntensities(attributes.POSITION, attributes.COLOR_0, attributes.intensity);\n break;\n }\n\n const pointsChunks = chunkArray(readPositions(readAttributes.positions), MAX_VERTICES * 3);\n const colorsChunks = chunkArray(readAttributes.colors, MAX_VERTICES * 4);\n\n const meshIds = [];\n\n for (let j = 0, lenj = pointsChunks.length; j < lenj; j++) {\n\n const geometryId = `geometry-${j}`;\n const meshId = `mesh-${j}`;\n\n meshIds.push(meshId);\n\n xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"points\",\n positions: pointsChunks[j],\n colorsCompressed: colorsChunks[j]\n });\n\n xktModel.createMesh({\n meshId,\n geometryId\n });\n }\n\n const entityId = math.createUUID();\n\n xktModel.createEntity({\n entityId,\n meshIds\n });\n\n const rootMetaObjectId = math.createUUID();\n\n xktModel.createMetaObject({\n metaObjectId: rootMetaObjectId,\n metaObjectType: \"Model\",\n metaObjectName: \"Model\"\n });\n\n xktModel.createMetaObject({\n metaObjectId: entityId,\n metaObjectType: \"PointCloud\",\n metaObjectName: \"PointCloud (LAZ)\",\n parentMetaObjectId: rootMetaObjectId\n });\n\n if (stats) {\n stats.sourceFormat = \"LAS\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 2;\n stats.numPropertySets = 0;\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numVertices = readAttributes.positions.length / 3;\n }\n\n resolve();\n\n }, (errMsg) => {\n reject(errMsg);\n });\n });\n\n function readPositions(positionsValue) {\n if (positionsValue) {\n if (center) {\n const centerPos = math.vec3();\n const numPoints = positionsValue.length;\n for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n centerPos[0] += positionsValue[i + 0];\n centerPos[1] += positionsValue[i + 1];\n centerPos[2] += positionsValue[i + 2];\n }\n centerPos[0] /= numPoints;\n centerPos[1] /= numPoints;\n centerPos[2] /= numPoints;\n for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n positionsValue[i + 0] -= centerPos[0];\n positionsValue[i + 1] -= centerPos[1];\n positionsValue[i + 2] -= centerPos[2];\n }\n }\n if (transform) {\n const mat = math.mat4(transform);\n const pos = math.vec3();\n for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n pos[0] = positionsValue[i + 0];\n pos[1] = positionsValue[i + 1];\n pos[2] = positionsValue[i + 2];\n math.transformPoint3(mat, pos, pos);\n positionsValue[i + 0] = pos[0];\n positionsValue[i + 1] = pos[1];\n positionsValue[i + 2] = pos[2];\n }\n }\n }\n return positionsValue;\n }\n\n function readColorsAndIntensities(attributesPosition, attributesColor, attributesIntensity) {\n const positionsValue = attributesPosition.value;\n const colors = attributesColor.value;\n const colorSize = attributesColor.size;\n const intensities = attributesIntensity.value;\n const colorsCompressedSize = intensities.length * 4;\n const positions = [];\n const colorsCompressed = new Uint8Array(colorsCompressedSize / skip);\n let count = skip;\n for (let i = 0, j = 0, k = 0, l = 0, m = 0, n=0,len = intensities.length; i < len; i++, k += colorSize, j += 4, l += 3) {\n if (count <= 0) {\n colorsCompressed[m++] = colors[k + 0];\n colorsCompressed[m++] = colors[k + 1];\n colorsCompressed[m++] = colors[k + 2];\n colorsCompressed[m++] = Math.round((intensities[i] / 65536) * 255);\n positions[n++] = positionsValue[l + 0];\n positions[n++] = positionsValue[l + 1];\n positions[n++] = positionsValue[l + 2];\n count = skip;\n } else {\n count--;\n }\n }\n return {\n positions,\n colors: colorsCompressed\n };\n }\n\n function readIntensities(attributesPosition, attributesIntensity) {\n const positionsValue = attributesPosition.value;\n const intensities = attributesIntensity.value;\n const colorsCompressedSize = intensities.length * 4;\n const positions = [];\n const colorsCompressed = new Uint8Array(colorsCompressedSize / skip);\n let count = skip;\n for (let i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, len = intensities.length; i < len; i++, k += 3, j += 4, l += 3) {\n if (count <= 0) {\n colorsCompressed[m++] = 0;\n colorsCompressed[m++] = 0;\n colorsCompressed[m++] = 0;\n colorsCompressed[m++] = Math.round((intensities[i] / 65536) * 255);\n positions[n++] = positionsValue[l + 0];\n positions[n++] = positionsValue[l + 1];\n positions[n++] = positionsValue[l + 2];\n count = skip;\n } else {\n count--;\n }\n }\n return {\n positions,\n colors: colorsCompressed\n };\n }\n\n function chunkArray(array, chunkSize) {\n if (chunkSize >= array.length) {\n return [array]; // One chunk\n }\n let result = [];\n for (let i = 0; i < array.length; i += chunkSize) {\n result.push(array.slice(i, i + chunkSize));\n }\n return result;\n }\n\n}\n\nexport {parseLASIntoXKTModel};","/**\n * @desc Parses JSON metamodel into an {@link XKTModel}.\n *\n * @param {Object} params Parsing parameters.\n * @param {JSON} params.metaModelData Metamodel data.\n * @param {String[]} [params.excludeTypes] Types to exclude from parsing.\n * @param {String[]} [params.includeTypes] Types to include in parsing.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when JSON has been parsed.\n */\nfunction parseMetaModelIntoXKTModel({metaModelData, xktModel, includeTypes, excludeTypes, log}) {\n\n if (log) {\n log(\"Using parser: parseMetaModelIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n const metaObjects = metaModelData.metaObjects || [];\n const propertySets = metaModelData.propertySets || [];\n\n xktModel.modelId = metaModelData.revisionId || \"\"; // HACK\n xktModel.projectId = metaModelData.projectId || \"\";\n xktModel.revisionId = metaModelData.revisionId || \"\";\n xktModel.author = metaModelData.author || \"\";\n xktModel.createdAt = metaModelData.createdAt || \"\";\n xktModel.creatingApplication = metaModelData.creatingApplication || \"\";\n xktModel.schema = metaModelData.schema || \"\";\n\n for (let i = 0, len = propertySets.length; i < len; i++) {\n\n const propertySet = propertySets[i];\n\n xktModel.createPropertySet({\n propertySetId: propertySet.id,\n propertySetName: propertySet.name,\n propertySetType: propertySet.type,\n properties: propertySet.properties\n });\n }\n\n let includeTypesMap;\n if (includeTypes) {\n includeTypesMap = {};\n for (let i = 0, len = includeTypes.length; i < len; i++) {\n includeTypesMap[includeTypes[i]] = true;\n }\n }\n\n let excludeTypesMap;\n if (excludeTypes) {\n excludeTypesMap = {};\n for (let i = 0, len = excludeTypes.length; i < len; i++) {\n excludeTypesMap[excludeTypes[i]] = true;\n }\n }\n\n const metaObjectsMap = {};\n\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n const newObject = metaObjects[i];\n metaObjectsMap[newObject.id] = newObject;\n }\n\n let countMetaObjects = 0;\n\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n\n const metaObject = metaObjects[i];\n const type = metaObject.type;\n\n if (excludeTypesMap && excludeTypesMap[type]) {\n continue;\n }\n\n if (includeTypesMap && !includeTypesMap[type]) {\n continue;\n }\n\n if (metaObject.parent !== undefined && metaObject.parent !== null) {\n const metaObjectParent = metaObjectsMap[metaObject.parent];\n if (metaObject.type === metaObjectParent.type) { // Don't create redundant sub-objects\n continue\n }\n }\n\n const propertySetIds = [];\n if (metaObject.propertySetIds) {\n for (let j = 0, lenj = metaObject.propertySetIds.length; j < lenj; j++) {\n const propertySetId = metaObject.propertySetIds[j];\n if (propertySetId !== undefined && propertySetId !== null && propertySetId !== \"\") {\n propertySetIds.push(propertySetId);\n }\n }\n }\n if (metaObject.propertySetId !== undefined && metaObject.propertySetId !== null && metaObject.propertySetId !== \"\") {\n propertySetIds.push(metaObject.propertySetId);\n }\n\n xktModel.createMetaObject({\n metaObjectId: metaObject.id,\n metaObjectType: metaObject.type,\n metaObjectName: metaObject.name,\n parentMetaObjectId: metaObject.parent,\n propertySetIds: propertySetIds.length > 0 ? propertySetIds : null\n });\n\n countMetaObjects++;\n }\n\n if (log) {\n log(\"Converted meta objects: \" + countMetaObjects);\n }\n\n resolve();\n });\n}\n\nexport {parseMetaModelIntoXKTModel};\n","/**\n * @desc Parses PCD point cloud data into an {@link XKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an LAZ point cloud model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"\"./models/pcd/ism_test_cat.pcd\"\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * await parsePCDIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer} params.data PCD file data.\n * @param {Boolean} [params.littleEndian=true] Whether PCD binary data is Little-Endian or Big-Endian.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when PCD has been parsed.\n */\nfunction parsePCDIntoXKTModel({data, xktModel, littleEndian = true, stats, log}) {\n\n if (log) {\n log(\"Using parser: parsePCDIntoXKTModel\");\n }\n\n return new Promise(function(resolve, reject) {\n\n const textData = decodeText(new Uint8Array(data));\n\n const header = parseHeader(textData);\n\n const positions = [];\n const normals = [];\n const colors = [];\n\n if (header.data === 'ascii') {\n\n const offset = header.offset;\n const data = textData.substr(header.headerLen);\n const lines = data.split('\\n');\n\n for (let i = 0, l = lines.length; i < l; i++) {\n\n if (lines[i] === '') {\n continue;\n }\n\n const line = lines[i].split(' ');\n\n if (offset.x !== undefined) {\n positions.push(parseFloat(line[offset.x]));\n positions.push(parseFloat(line[offset.y]));\n positions.push(parseFloat(line[offset.z]));\n }\n\n if (offset.rgb !== undefined) {\n const rgb = parseFloat(line[offset.rgb]);\n const r = (rgb >> 16) & 0x0000ff;\n const g = (rgb >> 8) & 0x0000ff;\n const b = (rgb >> 0) & 0x0000ff;\n colors.push(r, g, b, 255);\n } else {\n colors.push(255);\n colors.push(255);\n colors.push(255);\n }\n }\n }\n\n if (header.data === 'binary_compressed') {\n\n const sizes = new Uint32Array(data.slice(header.headerLen, header.headerLen + 8));\n const compressedSize = sizes[0];\n const decompressedSize = sizes[1];\n const decompressed = decompressLZF(new Uint8Array(data, header.headerLen + 8, compressedSize), decompressedSize);\n const dataview = new DataView(decompressed.buffer);\n const offset = header.offset;\n\n for (let i = 0; i < header.points; i++) {\n\n if (offset.x !== undefined) {\n positions.push(dataview.getFloat32((header.points * offset.x) + header.size[0] * i, littleEndian));\n positions.push(dataview.getFloat32((header.points * offset.y) + header.size[1] * i, littleEndian));\n positions.push(dataview.getFloat32((header.points * offset.z) + header.size[2] * i, littleEndian));\n }\n\n if (offset.rgb !== undefined) {\n colors.push(dataview.getUint8((header.points * offset.rgb) + header.size[3] * i + 0));\n colors.push(dataview.getUint8((header.points * offset.rgb) + header.size[3] * i + 1));\n colors.push(dataview.getUint8((header.points * offset.rgb) + header.size[3] * i + 2));\n // colors.push(255);\n } else {\n colors.push(1);\n colors.push(1);\n colors.push(1);\n }\n }\n }\n\n if (header.data === 'binary') {\n\n const dataview = new DataView(data, header.headerLen);\n const offset = header.offset;\n\n for (let i = 0, row = 0; i < header.points; i++, row += header.rowSize) {\n if (offset.x !== undefined) {\n positions.push(dataview.getFloat32(row + offset.x, littleEndian));\n positions.push(dataview.getFloat32(row + offset.y, littleEndian));\n positions.push(dataview.getFloat32(row + offset.z, littleEndian));\n }\n\n if (offset.rgb !== undefined) {\n colors.push(dataview.getUint8(row + offset.rgb + 2));\n colors.push(dataview.getUint8(row + offset.rgb + 1));\n colors.push(dataview.getUint8(row + offset.rgb + 0));\n } else {\n colors.push(255);\n colors.push(255);\n colors.push(255);\n }\n }\n }\n\n xktModel.createGeometry({\n geometryId: \"pointsGeometry\",\n primitiveType: \"points\",\n positions: positions,\n colors: colors && colors.length > 0 ? colors : null\n });\n\n xktModel.createMesh({\n meshId: \"pointsMesh\",\n geometryId: \"pointsGeometry\"\n });\n\n xktModel.createEntity({\n entityId: \"geometries\",\n meshIds: [\"pointsMesh\"]\n });\n\n if (log) {\n log(\"Converted drawable objects: 1\");\n log(\"Converted geometries: 1\");\n log(\"Converted vertices: \" + positions.length / 3);\n }\n\n if (stats) {\n stats.sourceFormat = \"PCD\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numVertices = positions.length / 3;\n }\n\n resolve();\n });\n}\n\nfunction parseHeader(data) {\n const header = {};\n const result1 = data.search(/[\\r\\n]DATA\\s(\\S*)\\s/i);\n const result2 = /[\\r\\n]DATA\\s(\\S*)\\s/i.exec(data.substr(result1 - 1));\n header.data = result2[1];\n header.headerLen = result2[0].length + result1;\n header.str = data.substr(0, header.headerLen);\n header.str = header.str.replace(/\\#.*/gi, ''); // Strip comments\n header.version = /VERSION (.*)/i.exec(header.str); // Parse\n header.fields = /FIELDS (.*)/i.exec(header.str);\n header.size = /SIZE (.*)/i.exec(header.str);\n header.type = /TYPE (.*)/i.exec(header.str);\n header.count = /COUNT (.*)/i.exec(header.str);\n header.width = /WIDTH (.*)/i.exec(header.str);\n header.height = /HEIGHT (.*)/i.exec(header.str);\n header.viewpoint = /VIEWPOINT (.*)/i.exec(header.str);\n header.points = /POINTS (.*)/i.exec(header.str);\n if (header.version !== null) {\n header.version = parseFloat(header.version[1]);\n }\n if (header.fields !== null) {\n header.fields = header.fields[1].split(' ');\n }\n if (header.type !== null) {\n header.type = header.type[1].split(' ');\n }\n if (header.width !== null) {\n header.width = parseInt(header.width[1]);\n }\n if (header.height !== null) {\n header.height = parseInt(header.height[1]);\n }\n if (header.viewpoint !== null) {\n header.viewpoint = header.viewpoint[1];\n }\n if (header.points !== null) {\n header.points = parseInt(header.points[1], 10);\n }\n if (header.points === null) {\n header.points = header.width * header.height;\n }\n if (header.size !== null) {\n header.size = header.size[1].split(' ').map(function (x) {\n return parseInt(x, 10);\n });\n }\n if (header.count !== null) {\n header.count = header.count[1].split(' ').map(function (x) {\n return parseInt(x, 10);\n });\n } else {\n header.count = [];\n for (let i = 0, l = header.fields.length; i < l; i++) {\n header.count.push(1);\n }\n }\n header.offset = {};\n let sizeSum = 0;\n for (let i = 0, l = header.fields.length; i < l; i++) {\n if (header.data === 'ascii') {\n header.offset[header.fields[i]] = i;\n } else {\n header.offset[header.fields[i]] = sizeSum;\n sizeSum += header.size[i] * header.count[i];\n }\n }\n header.rowSize = sizeSum; // For binary only\n return header;\n}\n\nfunction decodeText(array) {\n if (typeof TextDecoder !== 'undefined') {\n return new TextDecoder().decode(array);\n }\n let s = '';\n for (let i = 0, il = array.length; i < il; i++) {\n s += String.fromCharCode(array[i]);\n }\n try {\n return decodeURIComponent(escape(s));\n } catch (e) {\n return s;\n }\n}\n\nfunction decompressLZF(inData, outLength) { // https://gitlab.com/taketwo/three-pcd-loader/blob/master/decompress-lzf.js\n const inLength = inData.length;\n const outData = new Uint8Array(outLength);\n let inPtr = 0;\n let outPtr = 0;\n let ctrl;\n let len;\n let ref;\n do {\n ctrl = inData[inPtr++];\n if (ctrl < (1 << 5)) {\n ctrl++;\n if (outPtr + ctrl > outLength) throw new Error('Output buffer is not large enough');\n if (inPtr + ctrl > inLength) throw new Error('Invalid compressed data');\n do {\n outData[outPtr++] = inData[inPtr++];\n } while (--ctrl);\n } else {\n len = ctrl >> 5;\n ref = outPtr - ((ctrl & 0x1f) << 8) - 1;\n if (inPtr >= inLength) throw new Error('Invalid compressed data');\n if (len === 7) {\n len += inData[inPtr++];\n if (inPtr >= inLength) throw new Error('Invalid compressed data');\n }\n ref -= inData[inPtr++];\n if (outPtr + len + 2 > outLength) throw new Error('Output buffer is not large enough');\n if (ref < 0) throw new Error('Invalid compressed data');\n if (ref >= outPtr) throw new Error('Invalid compressed data');\n do {\n outData[outPtr++] = outData[ref++];\n } while (--len + 2);\n }\n } while (inPtr < inLength);\n return outData;\n}\n\nexport {parsePCDIntoXKTModel};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@loaders.gl/ply\");","import {parse} from '@loaders.gl/core';\nimport {PLYLoader} from '@loaders.gl/ply';\n\n/**\n * @desc Parses PLY file data into an {@link XKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a PLY model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"./models/ply/test.ply\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parsePLYIntoXKTModel({data, xktModel}).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer} params.data PLY file data.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when PLY has been parsed.\n */\nasync function parsePLYIntoXKTModel({data, xktModel, stats, log}) {\n\n if (log) {\n log(\"Using parser: parsePLYIntoXKTModel\");\n }\n\n if (!data) {\n throw \"Argument expected: data\";\n }\n\n if (!xktModel) {\n throw \"Argument expected: xktModel\";\n }\n\n let parsedData;\n try {\n parsedData = await parse(data, PLYLoader);\n } catch (e) {\n if (log) {\n log(\"Error: \" + e);\n }\n return;\n }\n\n const attributes = parsedData.attributes;\n const hasColors = !!attributes.COLOR_0;\n\n if (hasColors) {\n const colorsValue = hasColors ? attributes.COLOR_0.value : null;\n const colorsCompressed = [];\n for (let i = 0, len = colorsValue.length; i < len; i += 4) {\n colorsCompressed.push(colorsValue[i]);\n colorsCompressed.push(colorsValue[i + 1]);\n colorsCompressed.push(colorsValue[i + 2]);\n }\n xktModel.createGeometry({\n geometryId: \"plyGeometry\",\n primitiveType: \"triangles\",\n positions: attributes.POSITION.value,\n indices: parsedData.indices ? parsedData.indices.value : [],\n colorsCompressed: colorsCompressed\n });\n } else {\n xktModel.createGeometry({\n geometryId: \"plyGeometry\",\n primitiveType: \"triangles\",\n positions: attributes.POSITION.value,\n indices: parsedData.indices ? parsedData.indices.value : []\n });\n }\n\n xktModel.createMesh({\n meshId: \"plyMesh\",\n geometryId: \"plyGeometry\",\n color: (!hasColors) ? [1, 1, 1] : null\n });\n\n xktModel.createEntity({\n entityId: \"ply\",\n meshIds: [\"plyMesh\"]\n });\n\n if (stats) {\n stats.sourceFormat = \"PLY\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 2;\n stats.numPropertySets = 0;\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numVertices = attributes.POSITION.value.length / 3;\n }\n}\n\nexport {parsePLYIntoXKTModel};\n","import {faceToVertexNormals} from \"../lib/faceToVertexNormals.js\";\nimport {math} from \"../lib/math.js\";\n\n/**\n * @desc Parses STL file data into an {@link XKTModel}.\n *\n * * Supports binary and ASCII STL formats.\n * * Option to create a separate {@link XKTEntity} for each group of faces that share the same vertex colors.\n * * Option to smooth face-aligned normals loaded from STL.\n * * Option to reduce XKT file size by ignoring STL normals and relying on xeokit to auto-generate them.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an STL model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"./models/stl/binary/spurGear.stl\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseSTLIntoXKTModel({data, xktModel});\n *\n * xktModel.finalize();\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer|String} [params.data] STL file data. Can be binary or string.\n * @param {Boolean} [params.autoNormals=false] When true, the parser will ignore the STL geometry normals, and the STL\n * data will rely on the xeokit ````Viewer```` to automatically generate them. This has the limitation that the\n * normals will be face-aligned, and therefore the ````Viewer```` will only be able to render a flat-shaded representation\n * of the STL.\n * Overrides ````smoothNormals```` when ````true````. This ignores the normals in the STL, and loads no\n * normals from the STL into the {@link XKTModel}, resulting in the XKT file storing no normals for the STL model. The\n * xeokit-sdk will then automatically generate the normals within its shaders. The disadvantages are that auto-normals\n * may slow rendering down a little bit, and that the normals can only be face-aligned (and thus rendered using flat\n * shading). The advantages, however, are a smaller XKT file size, and the ability to apply certain geometry optimizations\n * during parsing, such as removing duplicated STL vertex positions, that are not possible when normals are loaded\n * for the STL vertices.\n * @param {Boolean} [params.smoothNormals=true] When true, automatically converts face-oriented STL normals to vertex normals, for a smooth appearance. Ignored if ````autoNormals```` is ````true````.\n * @param {Number} [params.smoothNormalsAngleThreshold=20] This is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n * @param {Boolean} [params.splitMeshes=true] When true, creates a separate {@link XKTEntity} for each group of faces that share the same vertex colors. Only works with binary STL (ie. when ````data```` is an ArrayBuffer).\n * @param {XKTModel} [params.xktModel] XKTModel to parse into.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when STL has been parsed.\n */\nasync function parseSTLIntoXKTModel({\n data,\n splitMeshes,\n autoNormals,\n smoothNormals,\n smoothNormalsAngleThreshold,\n xktModel,\n stats,\n log\n }) {\n\n if (log) {\n log(\"Using parser: parseSTLIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n const rootMetaObjectId = math.createUUID();\n\n const rootMetaObject = xktModel.createMetaObject({\n metaObjectId: rootMetaObjectId,\n metaObjectType: \"Model\",\n metaObjectName: \"Model\"\n });\n\n const ctx = {\n data,\n splitMeshes,\n autoNormals,\n smoothNormals,\n smoothNormalsAngleThreshold,\n xktModel,\n rootMetaObject,\n nextId: 0,\n log: (log || function (msg) {\n }),\n stats: {\n numObjects: 0,\n numGeometries: 0,\n numTriangles: 0,\n numVertices: 0\n }\n };\n\n const binData = ensureBinary(data);\n\n if (isBinary(binData)) {\n parseBinary(ctx, binData);\n } else {\n parseASCII(ctx, ensureString(data));\n }\n\n if (stats) {\n stats.sourceFormat = \"STL\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 2;\n stats.numPropertySets = 0;\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numTriangles = ctx.stats.numTriangles;\n stats.numVertices = ctx.stats.numVertices;\n }\n\n resolve();\n });\n}\n\nfunction isBinary(data) {\n const reader = new DataView(data);\n const numFaces = reader.getUint32(80, true);\n const faceSize = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);\n const numExpectedBytes = 80 + (32 / 8) + (numFaces * faceSize);\n if (numExpectedBytes === reader.byteLength) {\n return true;\n }\n const solid = [115, 111, 108, 105, 100];\n for (let i = 0; i < 5; i++) {\n if (solid[i] !== reader.getUint8(i, false)) {\n return true;\n }\n }\n return false;\n}\n\nfunction parseBinary(ctx, data) {\n const reader = new DataView(data);\n const faces = reader.getUint32(80, true);\n let r;\n let g;\n let b;\n let hasColors = false;\n let colors;\n let defaultR;\n let defaultG;\n let defaultB;\n let lastR = null;\n let lastG = null;\n let lastB = null;\n let newMesh = false;\n let alpha;\n for (let index = 0; index < 80 - 10; index++) {\n if ((reader.getUint32(index, false) === 0x434F4C4F /*COLO*/) &&\n (reader.getUint8(index + 4) === 0x52 /*'R'*/) &&\n (reader.getUint8(index + 5) === 0x3D /*'='*/)) {\n hasColors = true;\n colors = [];\n defaultR = reader.getUint8(index + 6) / 255;\n defaultG = reader.getUint8(index + 7) / 255;\n defaultB = reader.getUint8(index + 8) / 255;\n alpha = reader.getUint8(index + 9) / 255;\n }\n }\n let dataOffset = 84;\n let faceLength = 12 * 4 + 2;\n let positions = [];\n let normals = [];\n let splitMeshes = ctx.splitMeshes;\n for (let face = 0; face < faces; face++) {\n let start = dataOffset + face * faceLength;\n let normalX = reader.getFloat32(start, true);\n let normalY = reader.getFloat32(start + 4, true);\n let normalZ = reader.getFloat32(start + 8, true);\n if (hasColors) {\n let packedColor = reader.getUint16(start + 48, true);\n if ((packedColor & 0x8000) === 0) {\n r = (packedColor & 0x1F) / 31;\n g = ((packedColor >> 5) & 0x1F) / 31;\n b = ((packedColor >> 10) & 0x1F) / 31;\n } else {\n r = defaultR;\n g = defaultG;\n b = defaultB;\n }\n if (splitMeshes && r !== lastR || g !== lastG || b !== lastB) {\n if (lastR !== null) {\n newMesh = true;\n }\n lastR = r;\n lastG = g;\n lastB = b;\n }\n }\n for (let i = 1; i <= 3; i++) {\n let vertexstart = start + i * 12;\n positions.push(reader.getFloat32(vertexstart, true));\n positions.push(reader.getFloat32(vertexstart + 4, true));\n positions.push(reader.getFloat32(vertexstart + 8, true));\n if (!ctx.autoNormals) {\n normals.push(normalX, normalY, normalZ);\n }\n if (hasColors) {\n colors.push(r, g, b, 1); // TODO: handle alpha\n }\n }\n if (splitMeshes && newMesh) {\n addMesh(ctx, positions, normals, colors);\n positions = [];\n normals = [];\n colors = colors ? [] : null;\n newMesh = false;\n }\n }\n if (positions.length > 0) {\n addMesh(ctx, positions, normals, colors);\n }\n}\n\nfunction parseASCII(ctx, data) {\n const faceRegex = /facet([\\s\\S]*?)endfacet/g;\n let faceCounter = 0;\n const floatRegex = /[\\s]+([+-]?(?:\\d+.\\d+|\\d+.|\\d+|.\\d+)(?:[eE][+-]?\\d+)?)/.source;\n const vertexRegex = new RegExp('vertex' + floatRegex + floatRegex + floatRegex, 'g');\n const normalRegex = new RegExp('normal' + floatRegex + floatRegex + floatRegex, 'g');\n const positions = [];\n const normals = [];\n const colors = null;\n let normalx;\n let normaly;\n let normalz;\n let result;\n let verticesPerFace;\n let normalsPerFace;\n let text;\n while ((result = faceRegex.exec(data)) !== null) {\n verticesPerFace = 0;\n normalsPerFace = 0;\n text = result[0];\n while ((result = normalRegex.exec(text)) !== null) {\n normalx = parseFloat(result[1]);\n normaly = parseFloat(result[2]);\n normalz = parseFloat(result[3]);\n normalsPerFace++;\n }\n while ((result = vertexRegex.exec(text)) !== null) {\n positions.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n normals.push(normalx, normaly, normalz);\n verticesPerFace++;\n }\n if (normalsPerFace !== 1) {\n ctx.log(\"Error in normal of face \" + faceCounter);\n return -1;\n }\n if (verticesPerFace !== 3) {\n ctx.log(\"Error in positions of face \" + faceCounter);\n return -1;\n }\n faceCounter++;\n }\n addMesh(ctx, positions, normals, colors);\n}\n\nlet nextGeometryId = 0;\n\nfunction addMesh(ctx, positions, normals, colors) {\n\n const indices = new Int32Array(positions.length / 3);\n for (let ni = 0, len = indices.length; ni < len; ni++) {\n indices[ni] = ni;\n }\n\n normals = normals && normals.length > 0 ? normals : null;\n colors = colors && colors.length > 0 ? colors : null;\n\n if (!ctx.autoNormals && ctx.smoothNormals) {\n faceToVertexNormals(positions, normals, {smoothNormalsAngleThreshold: ctx.smoothNormalsAngleThreshold});\n }\n\n const geometryId = \"\" + nextGeometryId++;\n const meshId = \"\" + nextGeometryId++;\n const entityId = \"\" + nextGeometryId++;\n\n ctx.xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: positions,\n normals: (!ctx.autoNormals) ? normals : null,\n colors: colors,\n indices: indices\n });\n\n ctx.xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n color: colors ? null : [1, 1, 1],\n metallic: 0.9,\n roughness: 0.1\n });\n\n ctx.xktModel.createEntity({\n entityId: entityId,\n meshIds: [meshId]\n });\n\n ctx.xktModel.createMetaObject({\n metaObjectId: entityId,\n metaObjectType: \"Default\",\n metaObjectName: \"STL Mesh\",\n parentMetaObjectId: ctx.rootMetaObject.metaObjectId\n });\n\n ctx.stats.numGeometries++;\n ctx.stats.numObjects++;\n ctx.stats.numVertices += positions.length / 3;\n ctx.stats.numTriangles += indices.length / 3;\n}\n\nfunction ensureString(buffer) {\n if (typeof buffer !== 'string') {\n return decodeText(new Uint8Array(buffer));\n }\n return buffer;\n}\n\nfunction ensureBinary(buffer) {\n if (typeof buffer === 'string') {\n const arrayBuffer = new Uint8Array(buffer.length);\n for (let i = 0; i < buffer.length; i++) {\n arrayBuffer[i] = buffer.charCodeAt(i) & 0xff; // implicitly assumes little-endian\n }\n return arrayBuffer.buffer || arrayBuffer;\n } else {\n return buffer;\n }\n}\n\nfunction decodeText(array) {\n if (typeof TextDecoder !== 'undefined') {\n return new TextDecoder().decode(array);\n }\n let s = '';\n for (let i = 0, il = array.length; i < il; i++) {\n s += String.fromCharCode(array[i]); // Implicitly assumes little-endian.\n }\n return decodeURIComponent(escape(s));\n}\n\nexport {parseSTLIntoXKTModel};\n","import {math} from \"./math.js\";\n\n/**\n * Converts surface-perpendicular face normals to vertex normals. Assumes that the mesh contains disjoint triangles\n * that don't share vertex array elements. Works by finding groups of vertices that have the same location and\n * averaging their normal vectors.\n *\n * @returns {{positions: Array, normals: *}}\n * @private\n */\nfunction faceToVertexNormals(positions, normals, options = {}) {\n const smoothNormalsAngleThreshold = options.smoothNormalsAngleThreshold || 20;\n const vertexMap = {};\n const vertexNormals = [];\n const vertexNormalAccum = {};\n let acc;\n let vx;\n let vy;\n let vz;\n let key;\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = 10 ** precisionPoints;\n let posi;\n let i;\n let j;\n let len;\n let a;\n let b;\n let c;\n\n for (i = 0, len = positions.length; i < len; i += 3) {\n\n posi = i / 3;\n\n vx = positions[i];\n vy = positions[i + 1];\n vz = positions[i + 2];\n\n key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`;\n\n if (vertexMap[key] === undefined) {\n vertexMap[key] = [posi];\n } else {\n vertexMap[key].push(posi);\n }\n\n const normal = math.normalizeVec3([normals[i], normals[i + 1], normals[i + 2]]);\n\n vertexNormals[posi] = normal;\n\n acc = math.vec4([normal[0], normal[1], normal[2], 1]);\n\n vertexNormalAccum[posi] = acc;\n }\n\n for (key in vertexMap) {\n\n if (vertexMap.hasOwnProperty(key)) {\n\n const vertices = vertexMap[key];\n const numVerts = vertices.length;\n\n for (i = 0; i < numVerts; i++) {\n\n const ii = vertices[i];\n\n acc = vertexNormalAccum[ii];\n\n for (j = 0; j < numVerts; j++) {\n\n if (i === j) {\n continue;\n }\n\n const jj = vertices[j];\n\n a = vertexNormals[ii];\n b = vertexNormals[jj];\n\n const angle = Math.abs(math.angleVec3(a, b) / math.DEGTORAD);\n\n if (angle < smoothNormalsAngleThreshold) {\n\n acc[0] += b[0];\n acc[1] += b[1];\n acc[2] += b[2];\n acc[3] += 1.0;\n }\n }\n }\n }\n }\n\n for (i = 0, len = normals.length; i < len; i += 3) {\n\n acc = vertexNormalAccum[i / 3];\n\n normals[i + 0] = acc[0] / acc[3];\n normals[i + 1] = acc[1] / acc[3];\n normals[i + 2] = acc[2] / acc[3];\n\n }\n}\n\nexport {faceToVertexNormals};","/**\n * @desc Creates box-shaped triangle mesh geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a box-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildBoxGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const box = buildBoxGeometry({\n * primitiveType: \"triangles\" // or \"lines\"\n * center: [0,0,0],\n * xSize: 1, // Half-size on each axis\n * ySize: 1,\n * zSize: 1\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"boxGeometry\",\n * primitiveType: box.primitiveType,\n * positions: box.positions,\n * normals: box.normals,\n * indices: box.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redBoxMesh\",\n * geometryId: \"boxGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redBox\",\n * meshIds: [\"redBoxMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildBoxGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.xSize=1.0] Half-size on the X-axis.\n * @param {Number} [cfg.ySize=1.0] Half-size on the Y-axis.\n * @param {Number} [cfg.zSize=1.0] Half-size on the Z-axis.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildBoxGeometry(cfg = {}) {\n\n let xSize = cfg.xSize || 1;\n if (xSize < 0) {\n console.error(\"negative xSize not allowed - will invert\");\n xSize *= -1;\n }\n\n let ySize = cfg.ySize || 1;\n if (ySize < 0) {\n console.error(\"negative ySize not allowed - will invert\");\n ySize *= -1;\n }\n\n let zSize = cfg.zSize || 1;\n if (zSize < 0) {\n console.error(\"negative zSize not allowed - will invert\");\n zSize *= -1;\n }\n\n const center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const xmin = -xSize + centerX;\n const ymin = -ySize + centerY;\n const zmin = -zSize + centerZ;\n const xmax = xSize + centerX;\n const ymax = ySize + centerY;\n const zmax = zSize + centerZ;\n\n return {\n\n primitiveType: \"triangles\",\n\n // The vertices - eight for our cube, each\n // one spanning three array elements for X,Y and Z\n\n positions: [\n\n // v0-v1-v2-v3 front\n xmax, ymax, zmax,\n xmin, ymax, zmax,\n xmin, ymin, zmax,\n xmax, ymin, zmax,\n\n // v0-v3-v4-v1 right\n xmax, ymax, zmax,\n xmax, ymin, zmax,\n xmax, ymin, zmin,\n xmax, ymax, zmin,\n\n // v0-v1-v6-v1 top\n xmax, ymax, zmax,\n xmax, ymax, zmin,\n xmin, ymax, zmin,\n xmin, ymax, zmax,\n\n // v1-v6-v7-v2 left\n xmin, ymax, zmax,\n xmin, ymax, zmin,\n xmin, ymin, zmin,\n xmin, ymin, zmax,\n\n // v7-v4-v3-v2 bottom\n xmin, ymin, zmin,\n xmax, ymin, zmin,\n xmax, ymin, zmax,\n xmin, ymin, zmax,\n\n // v4-v7-v6-v1 back\n xmax, ymin, zmin,\n xmin, ymin, zmin,\n xmin, ymax, zmin,\n xmax, ymax, zmin\n ],\n\n // Normal vectors, one for each vertex\n normals: [\n\n // v0-v1-v2-v3 front\n 0, 0, 1,\n 0, 0, 1,\n 0, 0, 1,\n 0, 0, 1,\n\n // v0-v3-v4-v5 right\n 1, 0, 0,\n 1, 0, 0,\n 1, 0, 0,\n 1, 0, 0,\n\n // v0-v5-v6-v1 top\n 0, 1, 0,\n 0, 1, 0,\n 0, 1, 0,\n 0, 1, 0,\n\n // v1-v6-v7-v2 left\n -1, 0, 0,\n -1, 0, 0,\n -1, 0, 0,\n -1, 0, 0,\n\n // v7-v4-v3-v2 bottom\n 0, -1, 0,\n 0, -1, 0,\n 0, -1, 0,\n 0, -1, 0,\n\n // v4-v7-v6-v5 back\n 0, 0, -1,\n 0, 0, -1,\n 0, 0, -1,\n 0, 0, -1\n ],\n\n // UV coords\n uv: [\n\n // v0-v1-v2-v3 front\n 1, 0,\n 0, 0,\n 0, 1,\n 1, 1,\n\n // v0-v3-v4-v1 right\n 0, 0,\n 0, 1,\n 1, 1,\n 1, 0,\n\n // v0-v1-v6-v1 top\n 1, 1,\n 1, 0,\n 0, 0,\n 0, 1,\n\n // v1-v6-v7-v2 left\n 1, 0,\n 0, 0,\n 0, 1,\n 1, 1,\n\n // v7-v4-v3-v2 bottom\n 0, 1,\n 1, 1,\n 1, 0,\n 0, 0,\n\n // v4-v7-v6-v1 back\n 0, 1,\n 1, 1,\n 1, 0,\n 0, 0\n ],\n\n // Indices - these organise the\n // positions and uv texture coordinates\n // into geometric primitives in accordance\n // with the \"primitive\" parameter,\n // in this case a set of three indices\n // for each triangle.\n //\n // Note that each triangle is specified\n // in counter-clockwise winding order.\n //\n // You can specify them in clockwise\n // order if you configure the Modes\n // node's frontFace flag as \"cw\", instead of\n // the default \"ccw\".\n indices: [\n 0, 1, 2,\n 0, 2, 3,\n // front\n 4, 5, 6,\n 4, 6, 7,\n // right\n 8, 9, 10,\n 8, 10, 11,\n // top\n 12, 13, 14,\n 12, 14, 15,\n // left\n 16, 17, 18,\n 16, 18, 19,\n // bottom\n 20, 21, 22,\n 20, 22, 23\n ]\n };\n}\n\nexport {buildBoxGeometry};\n","/**\n * @desc Creates box-shaped line segment geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a box-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildBoxLinesGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const box = buildBoxLinesGeometry({\n * center: [0,0,0],\n * xSize: 1, // Half-size on each axis\n * ySize: 1,\n * zSize: 1\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"boxGeometry\",\n * primitiveType: box.primitiveType, // \"lines\"\n * positions: box.positions,\n * normals: box.normals,\n * indices: box.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redBoxMesh\",\n * geometryId: \"boxGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redBox\",\n * meshIds: [\"redBoxMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildBoxLinesGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.xSize=1.0] Half-size on the X-axis.\n * @param {Number} [cfg.ySize=1.0] Half-size on the Y-axis.\n * @param {Number} [cfg.zSize=1.0] Half-size on the Z-axis.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildBoxLinesGeometry(cfg = {}) {\n\n let xSize = cfg.xSize || 1;\n if (xSize < 0) {\n console.error(\"negative xSize not allowed - will invert\");\n xSize *= -1;\n }\n\n let ySize = cfg.ySize || 1;\n if (ySize < 0) {\n console.error(\"negative ySize not allowed - will invert\");\n ySize *= -1;\n }\n\n let zSize = cfg.zSize || 1;\n if (zSize < 0) {\n console.error(\"negative zSize not allowed - will invert\");\n zSize *= -1;\n }\n\n const center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const xmin = -xSize + centerX;\n const ymin = -ySize + centerY;\n const zmin = -zSize + centerZ;\n const xmax = xSize + centerX;\n const ymax = ySize + centerY;\n const zmax = zSize + centerZ;\n\n return {\n primitiveType: \"lines\",\n positions: [\n xmin, ymin, zmin,\n xmin, ymin, zmax,\n xmin, ymax, zmin,\n xmin, ymax, zmax,\n xmax, ymin, zmin,\n xmax, ymin, zmax,\n xmax, ymax, zmin,\n xmax, ymax, zmax\n ],\n indices: [\n 0, 1,\n 1, 3,\n 3, 2,\n 2, 0,\n 4, 5,\n 5, 7,\n 7, 6,\n 6, 4,\n 0, 4,\n 1, 5,\n 2, 6,\n 3, 7\n ]\n }\n}\n\nexport {buildBoxLinesGeometry};\n","/**\n * @desc Creates cylinder-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a cylinder-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildCylinderGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const cylinder = buildCylinderGeometry({\n * center: [0,0,0],\n * radiusTop: 2.0,\n * radiusBottom: 2.0,\n * height: 5.0,\n * radialSegments: 20,\n * heightSegments: 1,\n * openEnded: false\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"cylinderGeometry\",\n * primitiveType: cylinder.primitiveType,\n * positions: cylinder.positions,\n * normals: cylinder.normals,\n * indices: cylinder.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redCylinderMesh\",\n * geometryId: \"cylinderGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redCylinder\",\n * meshIds: [\"redCylinderMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildCylinderGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.radiusTop=1] Radius of top.\n * @param {Number} [cfg.radiusBottom=1] Radius of bottom.\n * @param {Number} [cfg.height=1] Height.\n * @param {Number} [cfg.radialSegments=60] Number of horizontal segments.\n * @param {Number} [cfg.heightSegments=1] Number of vertical segments.\n * @param {Boolean} [cfg.openEnded=false] Whether or not the cylinder has solid caps on the ends.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildCylinderGeometry(cfg = {}) {\n\n let radiusTop = cfg.radiusTop || 1;\n if (radiusTop < 0) {\n console.error(\"negative radiusTop not allowed - will invert\");\n radiusTop *= -1;\n }\n\n let radiusBottom = cfg.radiusBottom || 1;\n if (radiusBottom < 0) {\n console.error(\"negative radiusBottom not allowed - will invert\");\n radiusBottom *= -1;\n }\n\n let height = cfg.height || 1;\n if (height < 0) {\n console.error(\"negative height not allowed - will invert\");\n height *= -1;\n }\n\n let radialSegments = cfg.radialSegments || 32;\n if (radialSegments < 0) {\n console.error(\"negative radialSegments not allowed - will invert\");\n radialSegments *= -1;\n }\n if (radialSegments < 3) {\n radialSegments = 3;\n }\n\n let heightSegments = cfg.heightSegments || 1;\n if (heightSegments < 0) {\n console.error(\"negative heightSegments not allowed - will invert\");\n heightSegments *= -1;\n }\n if (heightSegments < 1) {\n heightSegments = 1;\n }\n\n const openEnded = !!cfg.openEnded;\n\n let center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const heightHalf = height / 2;\n const heightLength = height / heightSegments;\n const radialAngle = (2.0 * Math.PI / radialSegments);\n const radialLength = 1.0 / radialSegments;\n //var nextRadius = this._radiusBottom;\n const radiusChange = (radiusTop - radiusBottom) / heightSegments;\n\n const positions = [];\n const normals = [];\n const uvs = [];\n const indices = [];\n\n let h;\n let i;\n\n let x;\n let z;\n\n let currentRadius;\n let currentHeight;\n\n let first;\n let second;\n\n let startIndex;\n let tu;\n let tv;\n\n // create vertices\n const normalY = (90.0 - (Math.atan(height / (radiusBottom - radiusTop))) * 180 / Math.PI) / 90.0;\n\n for (h = 0; h <= heightSegments; h++) {\n currentRadius = radiusTop - h * radiusChange;\n currentHeight = heightHalf - h * heightLength;\n\n for (i = 0; i <= radialSegments; i++) {\n x = Math.sin(i * radialAngle);\n z = Math.cos(i * radialAngle);\n\n normals.push(currentRadius * x);\n normals.push(normalY); //todo\n normals.push(currentRadius * z);\n\n uvs.push((i * radialLength));\n uvs.push(h * 1 / heightSegments);\n\n positions.push((currentRadius * x) + centerX);\n positions.push((currentHeight) + centerY);\n positions.push((currentRadius * z) + centerZ);\n }\n }\n\n // create faces\n for (h = 0; h < heightSegments; h++) {\n for (i = 0; i <= radialSegments; i++) {\n\n first = h * (radialSegments + 1) + i;\n second = first + radialSegments;\n\n indices.push(first);\n indices.push(second);\n indices.push(second + 1);\n\n indices.push(first);\n indices.push(second + 1);\n indices.push(first + 1);\n }\n }\n\n // create top cap\n if (!openEnded && radiusTop > 0) {\n startIndex = (positions.length / 3);\n\n // top center\n normals.push(0.0);\n normals.push(1.0);\n normals.push(0.0);\n\n uvs.push(0.5);\n uvs.push(0.5);\n\n positions.push(0 + centerX);\n positions.push(heightHalf + centerY);\n positions.push(0 + centerZ);\n\n // top triangle fan\n for (i = 0; i <= radialSegments; i++) {\n x = Math.sin(i * radialAngle);\n z = Math.cos(i * radialAngle);\n tu = (0.5 * Math.sin(i * radialAngle)) + 0.5;\n tv = (0.5 * Math.cos(i * radialAngle)) + 0.5;\n\n normals.push(radiusTop * x);\n normals.push(1.0);\n normals.push(radiusTop * z);\n\n uvs.push(tu);\n uvs.push(tv);\n\n positions.push((radiusTop * x) + centerX);\n positions.push((heightHalf) + centerY);\n positions.push((radiusTop * z) + centerZ);\n }\n\n for (i = 0; i < radialSegments; i++) {\n center = startIndex;\n first = startIndex + 1 + i;\n\n indices.push(first);\n indices.push(first + 1);\n indices.push(center);\n }\n }\n\n // create bottom cap\n if (!openEnded && radiusBottom > 0) {\n\n startIndex = (positions.length / 3);\n\n // top center\n normals.push(0.0);\n normals.push(-1.0);\n normals.push(0.0);\n\n uvs.push(0.5);\n uvs.push(0.5);\n\n positions.push(0 + centerX);\n positions.push(0 - heightHalf + centerY);\n positions.push(0 + centerZ);\n\n // top triangle fan\n for (i = 0; i <= radialSegments; i++) {\n\n x = Math.sin(i * radialAngle);\n z = Math.cos(i * radialAngle);\n\n tu = (0.5 * Math.sin(i * radialAngle)) + 0.5;\n tv = (0.5 * Math.cos(i * radialAngle)) + 0.5;\n\n normals.push(radiusBottom * x);\n normals.push(-1.0);\n normals.push(radiusBottom * z);\n\n uvs.push(tu);\n uvs.push(tv);\n\n positions.push((radiusBottom * x) + centerX);\n positions.push((0 - heightHalf) + centerY);\n positions.push((radiusBottom * z) + centerZ);\n }\n\n for (i = 0; i < radialSegments; i++) {\n\n center = startIndex;\n first = startIndex + 1 + i;\n\n indices.push(center);\n indices.push(first + 1);\n indices.push(first);\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\n\nexport {buildCylinderGeometry};\n","/**\n * @desc Creates grid-shaped geometry arrays..\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a grid-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildGridGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const grid = buildGridGeometry({\n * size: 1000,\n * divisions: 500\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"gridGeometry\",\n * primitiveType: grid.primitiveType, // Will be \"lines\"\n * positions: grid.positions,\n * indices: grid.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redGridMesh\",\n * geometryId: \"gridGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redGrid\",\n * meshIds: [\"redGridMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildGridGeometry\n * @param {*} [cfg] Configs\n * @param {Number} [cfg.size=1] Dimension on the X and Z-axis.\n * @param {Number} [cfg.divisions=1] Number of divisions on X and Z axis..\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildGridGeometry(cfg = {}) {\n\n let size = cfg.size || 1;\n if (size < 0) {\n console.error(\"negative size not allowed - will invert\");\n size *= -1;\n }\n\n let divisions = cfg.divisions || 1;\n if (divisions < 0) {\n console.error(\"negative divisions not allowed - will invert\");\n divisions *= -1;\n }\n if (divisions < 1) {\n divisions = 1;\n }\n\n size = size || 10;\n divisions = divisions || 10;\n\n const step = size / divisions;\n const halfSize = size / 2;\n\n const positions = [];\n const indices = [];\n let l = 0;\n\n for (let i = 0, j = 0, k = -halfSize; i <= divisions; i++, k += step) {\n\n positions.push(-halfSize);\n positions.push(0);\n positions.push(k);\n\n positions.push(halfSize);\n positions.push(0);\n positions.push(k);\n\n positions.push(k);\n positions.push(0);\n positions.push(-halfSize);\n\n positions.push(k);\n positions.push(0);\n positions.push(halfSize);\n\n indices.push(l++);\n indices.push(l++);\n indices.push(l++);\n indices.push(l++);\n }\n\n return {\n primitiveType: \"lines\",\n positions: positions,\n indices: indices\n };\n}\n\n\nexport {buildGridGeometry};\n","/**\n * @desc Creates plane-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a plane-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildPlaneGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const plane = buildPlaneGeometry({\n * center: [0,0,0],\n * xSize: 2,\n * zSize: 2,\n * xSegments: 10,\n * zSegments: 10\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"planeGeometry\",\n * primitiveType: plane.primitiveType, // Will be \"triangles\"\n * positions: plane.positions,\n * normals: plane.normals,\n * indices: plane.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redPlaneMesh\",\n * geometryId: \"planeGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redPlane\",\n * meshIds: [\"redPlaneMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildPlaneGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.xSize=1] Dimension on the X-axis.\n * @param {Number} [cfg.zSize=1] Dimension on the Z-axis.\n * @param {Number} [cfg.xSegments=1] Number of segments on the X-axis.\n * @param {Number} [cfg.zSegments=1] Number of segments on the Z-axis.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildPlaneGeometry(cfg = {}) {\n\n let xSize = cfg.xSize || 1;\n if (xSize < 0) {\n console.error(\"negative xSize not allowed - will invert\");\n xSize *= -1;\n }\n\n let zSize = cfg.zSize || 1;\n if (zSize < 0) {\n console.error(\"negative zSize not allowed - will invert\");\n zSize *= -1;\n }\n\n let xSegments = cfg.xSegments || 1;\n if (xSegments < 0) {\n console.error(\"negative xSegments not allowed - will invert\");\n xSegments *= -1;\n }\n if (xSegments < 1) {\n xSegments = 1;\n }\n\n let zSegments = cfg.xSegments || 1;\n if (zSegments < 0) {\n console.error(\"negative zSegments not allowed - will invert\");\n zSegments *= -1;\n }\n if (zSegments < 1) {\n zSegments = 1;\n }\n\n const center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const halfWidth = xSize / 2;\n const halfHeight = zSize / 2;\n\n const planeX = Math.floor(xSegments) || 1;\n const planeZ = Math.floor(zSegments) || 1;\n\n const planeX1 = planeX + 1;\n const planeZ1 = planeZ + 1;\n\n const segmentWidth = xSize / planeX;\n const segmentHeight = zSize / planeZ;\n\n const positions = new Float32Array(planeX1 * planeZ1 * 3);\n const normals = new Float32Array(planeX1 * planeZ1 * 3);\n const uvs = new Float32Array(planeX1 * planeZ1 * 2);\n\n let offset = 0;\n let offset2 = 0;\n\n let iz;\n let ix;\n let x;\n let a;\n let b;\n let c;\n let d;\n\n for (iz = 0; iz < planeZ1; iz++) {\n\n const z = iz * segmentHeight - halfHeight;\n\n for (ix = 0; ix < planeX1; ix++) {\n\n x = ix * segmentWidth - halfWidth;\n\n positions[offset] = x + centerX;\n positions[offset + 1] = centerY;\n positions[offset + 2] = -z + centerZ;\n\n normals[offset + 2] = -1;\n\n uvs[offset2] = (ix) / planeX;\n uvs[offset2 + 1] = ((planeZ - iz) / planeZ);\n\n offset += 3;\n offset2 += 2;\n }\n }\n\n offset = 0;\n\n const indices = new ((positions.length / 3) > 65535 ? Uint32Array : Uint16Array)(planeX * planeZ * 6);\n\n for (iz = 0; iz < planeZ; iz++) {\n\n for (ix = 0; ix < planeX; ix++) {\n\n a = ix + planeX1 * iz;\n b = ix + planeX1 * (iz + 1);\n c = (ix + 1) + planeX1 * (iz + 1);\n d = (ix + 1) + planeX1 * iz;\n\n indices[offset] = d;\n indices[offset + 1] = b;\n indices[offset + 2] = a;\n\n indices[offset + 3] = d;\n indices[offset + 4] = c;\n indices[offset + 5] = b;\n\n offset += 6;\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\nexport {buildPlaneGeometry};\n","/**\n * @desc Creates sphere-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a sphere-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildSphereGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const sphere = buildSphereGeometry({\n * center: [0,0,0],\n * radius: 1.5,\n * heightSegments: 60,\n * widthSegments: 60\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"sphereGeometry\",\n * primitiveType: sphere.primitiveType, // Will be \"triangles\"\n * positions: sphere.positions,\n * normals: sphere.normals,\n * indices: sphere.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redSphereMesh\",\n * geometryId: \"sphereGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n *const xktEntity = xktModel.createEntity({\n * entityId: \"redSphere\",\n * meshIds: [\"redSphereMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildSphereGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.radius=1] Radius.\n * @param {Number} [cfg.heightSegments=24] Number of latitudinal bands.\n * @param {Number} [cfg.widthSegments=18] Number of longitudinal bands.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildSphereGeometry(cfg = {}) {\n\n const lod = cfg.lod || 1;\n\n const centerX = cfg.center ? cfg.center[0] : 0;\n const centerY = cfg.center ? cfg.center[1] : 0;\n const centerZ = cfg.center ? cfg.center[2] : 0;\n\n let radius = cfg.radius || 1;\n if (radius < 0) {\n console.error(\"negative radius not allowed - will invert\");\n radius *= -1;\n }\n\n let heightSegments = cfg.heightSegments || 18;\n if (heightSegments < 0) {\n console.error(\"negative heightSegments not allowed - will invert\");\n heightSegments *= -1;\n }\n heightSegments = Math.floor(lod * heightSegments);\n if (heightSegments < 18) {\n heightSegments = 18;\n }\n\n let widthSegments = cfg.widthSegments || 18;\n if (widthSegments < 0) {\n console.error(\"negative widthSegments not allowed - will invert\");\n widthSegments *= -1;\n }\n widthSegments = Math.floor(lod * widthSegments);\n if (widthSegments < 18) {\n widthSegments = 18;\n }\n\n const positions = [];\n const normals = [];\n const uvs = [];\n const indices = [];\n\n let i;\n let j;\n\n let theta;\n let sinTheta;\n let cosTheta;\n\n let phi;\n let sinPhi;\n let cosPhi;\n\n let x;\n let y;\n let z;\n\n let u;\n let v;\n\n let first;\n let second;\n\n for (i = 0; i <= heightSegments; i++) {\n\n theta = i * Math.PI / heightSegments;\n sinTheta = Math.sin(theta);\n cosTheta = Math.cos(theta);\n\n for (j = 0; j <= widthSegments; j++) {\n\n phi = j * 2 * Math.PI / widthSegments;\n sinPhi = Math.sin(phi);\n cosPhi = Math.cos(phi);\n\n x = cosPhi * sinTheta;\n y = cosTheta;\n z = sinPhi * sinTheta;\n u = 1.0 - j / widthSegments;\n v = i / heightSegments;\n\n normals.push(x);\n normals.push(y);\n normals.push(z);\n\n uvs.push(u);\n uvs.push(v);\n\n positions.push(centerX + radius * x);\n positions.push(centerY + radius * y);\n positions.push(centerZ + radius * z);\n }\n }\n\n for (i = 0; i < heightSegments; i++) {\n for (j = 0; j < widthSegments; j++) {\n\n first = (i * (widthSegments + 1)) + j;\n second = first + widthSegments + 1;\n\n indices.push(first + 1);\n indices.push(second + 1);\n indices.push(second);\n indices.push(first + 1);\n indices.push(second);\n indices.push(first);\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\nexport {buildSphereGeometry};\n","import {math} from '../lib/math.js';\n\n/**\n * @desc Creates torus-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a torus-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildTorusGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const torus = buildTorusGeometry({\n * center: [0,0,0],\n * radius: 1.0,\n * tube: 0.5,\n * radialSegments: 32,\n * tubeSegments: 24,\n * arc: Math.PI * 2.0\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"torusGeometry\",\n * primitiveType: torus.primitiveType, // Will be \"triangles\"\n * positions: torus.positions,\n * normals: torus.normals,\n * indices: torus.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redTorusMesh\",\n * geometryId: \"torusGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redTorus\",\n * meshIds: [\"redTorusMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildTorusGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.radius=1] The overall radius.\n * @param {Number} [cfg.tube=0.3] The tube radius.\n * @param {Number} [cfg.radialSegments=32] The number of radial segments.\n * @param {Number} [cfg.tubeSegments=24] The number of tubular segments.\n * @param {Number} [cfg.arc=Math.PI*0.5] The length of the arc in radians, where Math.PI*2 is a closed torus.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildTorusGeometry(cfg = {}) {\n\n let radius = cfg.radius || 1;\n if (radius < 0) {\n console.error(\"negative radius not allowed - will invert\");\n radius *= -1;\n }\n radius *= 0.5;\n\n let tube = cfg.tube || 0.3;\n if (tube < 0) {\n console.error(\"negative tube not allowed - will invert\");\n tube *= -1;\n }\n\n let radialSegments = cfg.radialSegments || 32;\n if (radialSegments < 0) {\n console.error(\"negative radialSegments not allowed - will invert\");\n radialSegments *= -1;\n }\n if (radialSegments < 4) {\n radialSegments = 4;\n }\n\n let tubeSegments = cfg.tubeSegments || 24;\n if (tubeSegments < 0) {\n console.error(\"negative tubeSegments not allowed - will invert\");\n tubeSegments *= -1;\n }\n if (tubeSegments < 4) {\n tubeSegments = 4;\n }\n\n let arc = cfg.arc || Math.PI * 2;\n if (arc < 0) {\n console.warn(\"negative arc not allowed - will invert\");\n arc *= -1;\n }\n if (arc > 360) {\n arc = 360;\n }\n\n const center = cfg.center;\n let centerX = center ? center[0] : 0;\n let centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const positions = [];\n const normals = [];\n const uvs = [];\n const indices = [];\n\n let u;\n let v;\n let x;\n let y;\n let z;\n let vec;\n\n let i;\n let j;\n\n for (j = 0; j <= tubeSegments; j++) {\n for (i = 0; i <= radialSegments; i++) {\n\n u = i / radialSegments * arc;\n v = 0.785398 + (j / tubeSegments * Math.PI * 2);\n\n centerX = radius * Math.cos(u);\n centerY = radius * Math.sin(u);\n\n x = (radius + tube * Math.cos(v)) * Math.cos(u);\n y = (radius + tube * Math.cos(v)) * Math.sin(u);\n z = tube * Math.sin(v);\n\n positions.push(x + centerX);\n positions.push(y + centerY);\n positions.push(z + centerZ);\n\n uvs.push(1 - (i / radialSegments));\n uvs.push((j / tubeSegments));\n\n vec = math.normalizeVec3(math.subVec3([x, y, z], [centerX, centerY, centerZ], []), []);\n\n normals.push(vec[0]);\n normals.push(vec[1]);\n normals.push(vec[2]);\n }\n }\n\n let a;\n let b;\n let c;\n let d;\n\n for (j = 1; j <= tubeSegments; j++) {\n for (i = 1; i <= radialSegments; i++) {\n\n a = (radialSegments + 1) * j + i - 1;\n b = (radialSegments + 1) * (j - 1) + i - 1;\n c = (radialSegments + 1) * (j - 1) + i;\n d = (radialSegments + 1) * j + i;\n\n indices.push(a);\n indices.push(b);\n indices.push(c);\n\n indices.push(c);\n indices.push(d);\n indices.push(a);\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\nexport {buildTorusGeometry};\n","const letters = {\n ' ': {width: 16, points: []},\n '!': {\n width: 10, points: [\n [5, 21],\n [5, 7],\n [-1, -1],\n [5, 2],\n [4, 1],\n [5, 0],\n [6, 1],\n [5, 2]\n ]\n },\n '\"': {\n width: 16, points: [\n [4, 21],\n [4, 14],\n [-1, -1],\n [12, 21],\n [12, 14]\n ]\n },\n '#': {\n width: 21, points: [\n [11, 25],\n [4, -7],\n [-1, -1],\n [17, 25],\n [10, -7],\n [-1, -1],\n [4, 12],\n [18, 12],\n [-1, -1],\n [3, 6],\n [17, 6]\n ]\n },\n '$': {\n width: 20, points: [\n [8, 25],\n [8, -4],\n [-1, -1],\n [12, 25],\n [12, -4],\n [-1, -1],\n [17, 18],\n [15, 20],\n [12, 21],\n [8, 21],\n [5, 20],\n [3, 18],\n [3, 16],\n [4, 14],\n [5, 13],\n [7, 12],\n [13, 10],\n [15, 9],\n [16, 8],\n [17, 6],\n [17, 3],\n [15, 1],\n [12, 0],\n [8, 0],\n [5, 1],\n [3, 3]\n ]\n },\n '%': {\n width: 24, points: [\n [21, 21],\n [3, 0],\n [-1, -1],\n [8, 21],\n [10, 19],\n [10, 17],\n [9, 15],\n [7, 14],\n [5, 14],\n [3, 16],\n [3, 18],\n [4, 20],\n [6, 21],\n [8, 21],\n [10, 20],\n [13, 19],\n [16, 19],\n [19, 20],\n [21, 21],\n [-1, -1],\n [17, 7],\n [15, 6],\n [14, 4],\n [14, 2],\n [16, 0],\n [18, 0],\n [20, 1],\n [21, 3],\n [21, 5],\n [19, 7],\n [17, 7]\n ]\n },\n '&': {\n width: 26, points: [\n [23, 12],\n [23, 13],\n [22, 14],\n [21, 14],\n [20, 13],\n [19, 11],\n [17, 6],\n [15, 3],\n [13, 1],\n [11, 0],\n [7, 0],\n [5, 1],\n [4, 2],\n [3, 4],\n [3, 6],\n [4, 8],\n [5, 9],\n [12, 13],\n [13, 14],\n [14, 16],\n [14, 18],\n [13, 20],\n [11, 21],\n [9, 20],\n [8, 18],\n [8, 16],\n [9, 13],\n [11, 10],\n [16, 3],\n [18, 1],\n [20, 0],\n [22, 0],\n [23, 1],\n [23, 2]\n ]\n },\n '\\'': {\n width: 10, points: [\n [5, 19],\n [4, 20],\n [5, 21],\n [6, 20],\n [6, 18],\n [5, 16],\n [4, 15]\n ]\n },\n '(': {\n width: 14, points: [\n [11, 25],\n [9, 23],\n [7, 20],\n [5, 16],\n [4, 11],\n [4, 7],\n [5, 2],\n [7, -2],\n [9, -5],\n [11, -7]\n ]\n },\n ')': {\n width: 14, points: [\n [3, 25],\n [5, 23],\n [7, 20],\n [9, 16],\n [10, 11],\n [10, 7],\n [9, 2],\n [7, -2],\n [5, -5],\n [3, -7]\n ]\n },\n '*': {\n width: 16, points: [\n [8, 21],\n [8, 9],\n [-1, -1],\n [3, 18],\n [13, 12],\n [-1, -1],\n [13, 18],\n [3, 12]\n ]\n },\n '+': {\n width: 26, points: [\n [13, 18],\n [13, 0],\n [-1, -1],\n [4, 9],\n [22, 9]\n ]\n },\n ',': {\n width: 10, points: [\n [6, 1],\n [5, 0],\n [4, 1],\n [5, 2],\n [6, 1],\n [6, -1],\n [5, -3],\n [4, -4]\n ]\n },\n '-': {\n width: 26, points: [\n [4, 9],\n [22, 9]\n ]\n },\n '.': {\n width: 10, points: [\n [5, 2],\n [4, 1],\n [5, 0],\n [6, 1],\n [5, 2]\n ]\n },\n '/': {\n width: 22, points: [\n [20, 25],\n [2, -7]\n ]\n },\n '0': {\n width: 20, points: [\n [9, 21],\n [6, 20],\n [4, 17],\n [3, 12],\n [3, 9],\n [4, 4],\n [6, 1],\n [9, 0],\n [11, 0],\n [14, 1],\n [16, 4],\n [17, 9],\n [17, 12],\n [16, 17],\n [14, 20],\n [11, 21],\n [9, 21]\n ]\n },\n '1': {\n width: 20, points: [\n [6, 17],\n [8, 18],\n [11, 21],\n [11, 0]\n ]\n },\n '2': {\n width: 20, points: [\n [4, 16],\n [4, 17],\n [5, 19],\n [6, 20],\n [8, 21],\n [12, 21],\n [14, 20],\n [15, 19],\n [16, 17],\n [16, 15],\n [15, 13],\n [13, 10],\n [3, 0],\n [17, 0]\n ]\n },\n '3': {\n width: 20, points: [\n [5, 21],\n [16, 21],\n [10, 13],\n [13, 13],\n [15, 12],\n [16, 11],\n [17, 8],\n [17, 6],\n [16, 3],\n [14, 1],\n [11, 0],\n [8, 0],\n [5, 1],\n [4, 2],\n [3, 4]\n ]\n },\n '4': {\n width: 20, points: [\n [13, 21],\n [3, 7],\n [18, 7],\n [-1, -1],\n [13, 21],\n [13, 0]\n ]\n },\n '5': {\n width: 20, points: [\n [15, 21],\n [5, 21],\n [4, 12],\n [5, 13],\n [8, 14],\n [11, 14],\n [14, 13],\n [16, 11],\n [17, 8],\n [17, 6],\n [16, 3],\n [14, 1],\n [11, 0],\n [8, 0],\n [5, 1],\n [4, 2],\n [3, 4]\n ]\n },\n '6': {\n width: 20, points: [\n [16, 18],\n [15, 20],\n [12, 21],\n [10, 21],\n [7, 20],\n [5, 17],\n [4, 12],\n [4, 7],\n [5, 3],\n [7, 1],\n [10, 0],\n [11, 0],\n [14, 1],\n [16, 3],\n [17, 6],\n [17, 7],\n [16, 10],\n [14, 12],\n [11, 13],\n [10, 13],\n [7, 12],\n [5, 10],\n [4, 7]\n ]\n },\n '7': {\n width: 20, points: [\n [17, 21],\n [7, 0],\n [-1, -1],\n [3, 21],\n [17, 21]\n ]\n },\n '8': {\n width: 20, points: [\n [8, 21],\n [5, 20],\n [4, 18],\n [4, 16],\n [5, 14],\n [7, 13],\n [11, 12],\n [14, 11],\n [16, 9],\n [17, 7],\n [17, 4],\n [16, 2],\n [15, 1],\n [12, 0],\n [8, 0],\n [5, 1],\n [4, 2],\n [3, 4],\n [3, 7],\n [4, 9],\n [6, 11],\n [9, 12],\n [13, 13],\n [15, 14],\n [16, 16],\n [16, 18],\n [15, 20],\n [12, 21],\n [8, 21]\n ]\n },\n '9': {\n width: 20, points: [\n [16, 14],\n [15, 11],\n [13, 9],\n [10, 8],\n [9, 8],\n [6, 9],\n [4, 11],\n [3, 14],\n [3, 15],\n [4, 18],\n [6, 20],\n [9, 21],\n [10, 21],\n [13, 20],\n [15, 18],\n [16, 14],\n [16, 9],\n [15, 4],\n [13, 1],\n [10, 0],\n [8, 0],\n [5, 1],\n [4, 3]\n ]\n },\n ':': {\n width: 10, points: [\n [5, 14],\n [4, 13],\n [5, 12],\n [6, 13],\n [5, 14],\n [-1, -1],\n [5, 2],\n [4, 1],\n [5, 0],\n [6, 1],\n [5, 2]\n ]\n },\n ';': {\n width: 10, points: [\n [5, 14],\n [4, 13],\n [5, 12],\n [6, 13],\n [5, 14],\n [-1, -1],\n [6, 1],\n [5, 0],\n [4, 1],\n [5, 2],\n [6, 1],\n [6, -1],\n [5, -3],\n [4, -4]\n ]\n },\n '<': {\n width: 24, points: [\n [20, 18],\n [4, 9],\n [20, 0]\n ]\n },\n '=': {\n width: 26, points: [\n [4, 12],\n [22, 12],\n [-1, -1],\n [4, 6],\n [22, 6]\n ]\n },\n '>': {\n width: 24, points: [\n [4, 18],\n [20, 9],\n [4, 0]\n ]\n },\n '?': {\n width: 18, points: [\n [3, 16],\n [3, 17],\n [4, 19],\n [5, 20],\n [7, 21],\n [11, 21],\n [13, 20],\n [14, 19],\n [15, 17],\n [15, 15],\n [14, 13],\n [13, 12],\n [9, 10],\n [9, 7],\n [-1, -1],\n [9, 2],\n [8, 1],\n [9, 0],\n [10, 1],\n [9, 2]\n ]\n },\n '@': {\n width: 27, points: [\n [18, 13],\n [17, 15],\n [15, 16],\n [12, 16],\n [10, 15],\n [9, 14],\n [8, 11],\n [8, 8],\n [9, 6],\n [11, 5],\n [14, 5],\n [16, 6],\n [17, 8],\n [-1, -1],\n [12, 16],\n [10, 14],\n [9, 11],\n [9, 8],\n [10, 6],\n [11, 5],\n [-1, -1],\n [18, 16],\n [17, 8],\n [17, 6],\n [19, 5],\n [21, 5],\n [23, 7],\n [24, 10],\n [24, 12],\n [23, 15],\n [22, 17],\n [20, 19],\n [18, 20],\n [15, 21],\n [12, 21],\n [9, 20],\n [7, 19],\n [5, 17],\n [4, 15],\n [3, 12],\n [3, 9],\n [4, 6],\n [5, 4],\n [7, 2],\n [9, 1],\n [12, 0],\n [15, 0],\n [18, 1],\n [20, 2],\n [21, 3],\n [-1, -1],\n [19, 16],\n [18, 8],\n [18, 6],\n [19, 5]\n ]\n },\n 'A': {\n width: 18, points: [\n [9, 21],\n [1, 0],\n [-1, -1],\n [9, 21],\n [17, 0],\n [-1, -1],\n [4, 7],\n [14, 7]\n ]\n },\n 'B': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [13, 21],\n [16, 20],\n [17, 19],\n [18, 17],\n [18, 15],\n [17, 13],\n [16, 12],\n [13, 11],\n [-1, -1],\n [4, 11],\n [13, 11],\n [16, 10],\n [17, 9],\n [18, 7],\n [18, 4],\n [17, 2],\n [16, 1],\n [13, 0],\n [4, 0]\n ]\n },\n 'C': {\n width: 21, points: [\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5]\n ]\n },\n 'D': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [11, 21],\n [14, 20],\n [16, 18],\n [17, 16],\n [18, 13],\n [18, 8],\n [17, 5],\n [16, 3],\n [14, 1],\n [11, 0],\n [4, 0]\n ]\n },\n 'E': {\n width: 19, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [17, 21],\n [-1, -1],\n [4, 11],\n [12, 11],\n [-1, -1],\n [4, 0],\n [17, 0]\n ]\n },\n 'F': {\n width: 18, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [17, 21],\n [-1, -1],\n [4, 11],\n [12, 11]\n ]\n },\n 'G': {\n width: 21, points: [\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5],\n [18, 8],\n [-1, -1],\n [13, 8],\n [18, 8]\n ]\n },\n 'H': {\n width: 22, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [18, 21],\n [18, 0],\n [-1, -1],\n [4, 11],\n [18, 11]\n ]\n },\n 'I': {\n width: 8, points: [\n [4, 21],\n [4, 0]\n ]\n },\n 'J': {\n width: 16, points: [\n [12, 21],\n [12, 5],\n [11, 2],\n [10, 1],\n [8, 0],\n [6, 0],\n [4, 1],\n [3, 2],\n [2, 5],\n [2, 7]\n ]\n },\n 'K': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [18, 21],\n [4, 7],\n [-1, -1],\n [9, 12],\n [18, 0]\n ]\n },\n 'L': {\n width: 17, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 0],\n [16, 0]\n ]\n },\n 'M': {\n width: 24, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [12, 0],\n [-1, -1],\n [20, 21],\n [12, 0],\n [-1, -1],\n [20, 21],\n [20, 0]\n ]\n },\n 'N': {\n width: 22, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [18, 0],\n [-1, -1],\n [18, 21],\n [18, 0]\n ]\n },\n 'O': {\n width: 22, points: [\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5],\n [19, 8],\n [19, 13],\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21]\n ]\n },\n 'P': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [13, 21],\n [16, 20],\n [17, 19],\n [18, 17],\n [18, 14],\n [17, 12],\n [16, 11],\n [13, 10],\n [4, 10]\n ]\n },\n 'Q': {\n width: 22, points: [\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5],\n [19, 8],\n [19, 13],\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21],\n [-1, -1],\n [12, 4],\n [18, -2]\n ]\n },\n 'R': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [13, 21],\n [16, 20],\n [17, 19],\n [18, 17],\n [18, 15],\n [17, 13],\n [16, 12],\n [13, 11],\n [4, 11],\n [-1, -1],\n [11, 11],\n [18, 0]\n ]\n },\n 'S': {\n width: 20, points: [\n [17, 18],\n [15, 20],\n [12, 21],\n [8, 21],\n [5, 20],\n [3, 18],\n [3, 16],\n [4, 14],\n [5, 13],\n [7, 12],\n [13, 10],\n [15, 9],\n [16, 8],\n [17, 6],\n [17, 3],\n [15, 1],\n [12, 0],\n [8, 0],\n [5, 1],\n [3, 3]\n ]\n },\n 'T': {\n width: 16, points: [\n [8, 21],\n [8, 0],\n [-1, -1],\n [1, 21],\n [15, 21]\n ]\n },\n 'U': {\n width: 22, points: [\n [4, 21],\n [4, 6],\n [5, 3],\n [7, 1],\n [10, 0],\n [12, 0],\n [15, 1],\n [17, 3],\n [18, 6],\n [18, 21]\n ]\n },\n 'V': {\n width: 18, points: [\n [1, 21],\n [9, 0],\n [-1, -1],\n [17, 21],\n [9, 0]\n ]\n },\n 'W': {\n width: 24, points: [\n [2, 21],\n [7, 0],\n [-1, -1],\n [12, 21],\n [7, 0],\n [-1, -1],\n [12, 21],\n [17, 0],\n [-1, -1],\n [22, 21],\n [17, 0]\n ]\n },\n 'X': {\n width: 20, points: [\n [3, 21],\n [17, 0],\n [-1, -1],\n [17, 21],\n [3, 0]\n ]\n },\n 'Y': {\n width: 18, points: [\n [1, 21],\n [9, 11],\n [9, 0],\n [-1, -1],\n [17, 21],\n [9, 11]\n ]\n },\n 'Z': {\n width: 20, points: [\n [17, 21],\n [3, 0],\n [-1, -1],\n [3, 21],\n [17, 21],\n [-1, -1],\n [3, 0],\n [17, 0]\n ]\n },\n '[': {\n width: 14, points: [\n [4, 25],\n [4, -7],\n [-1, -1],\n [5, 25],\n [5, -7],\n [-1, -1],\n [4, 25],\n [11, 25],\n [-1, -1],\n [4, -7],\n [11, -7]\n ]\n },\n '\\\\': {\n width: 14, points: [\n [0, 21],\n [14, -3]\n ]\n },\n ']': {\n width: 14, points: [\n [9, 25],\n [9, -7],\n [-1, -1],\n [10, 25],\n [10, -7],\n [-1, -1],\n [3, 25],\n [10, 25],\n [-1, -1],\n [3, -7],\n [10, -7]\n ]\n },\n '^': {\n width: 16, points: [\n [6, 15],\n [8, 18],\n [10, 15],\n [-1, -1],\n [3, 12],\n [8, 17],\n [13, 12],\n [-1, -1],\n [8, 17],\n [8, 0]\n ]\n },\n '_': {\n width: 16, points: [\n [0, -2],\n [16, -2]\n ]\n },\n '`': {\n width: 10, points: [\n [6, 21],\n [5, 20],\n [4, 18],\n [4, 16],\n [5, 15],\n [6, 16],\n [5, 17]\n ]\n },\n 'a': {\n width: 19, points: [\n [15, 14],\n [15, 0],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'b': {\n width: 19, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 11],\n [6, 13],\n [8, 14],\n [11, 14],\n [13, 13],\n [15, 11],\n [16, 8],\n [16, 6],\n [15, 3],\n [13, 1],\n [11, 0],\n [8, 0],\n [6, 1],\n [4, 3]\n ]\n },\n 'c': {\n width: 18, points: [\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'd': {\n width: 19, points: [\n [15, 21],\n [15, 0],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'e': {\n width: 18, points: [\n [3, 8],\n [15, 8],\n [15, 10],\n [14, 12],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'f': {\n width: 12, points: [\n [10, 21],\n [8, 21],\n [6, 20],\n [5, 17],\n [5, 0],\n [-1, -1],\n [2, 14],\n [9, 14]\n ]\n },\n 'g': {\n width: 19, points: [\n [15, 14],\n [15, -2],\n [14, -5],\n [13, -6],\n [11, -7],\n [8, -7],\n [6, -6],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'h': {\n width: 19, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 10],\n [7, 13],\n [9, 14],\n [12, 14],\n [14, 13],\n [15, 10],\n [15, 0]\n ]\n },\n 'i': {\n width: 8, points: [\n [3, 21],\n [4, 20],\n [5, 21],\n [4, 22],\n [3, 21],\n [-1, -1],\n [4, 14],\n [4, 0]\n ]\n },\n 'j': {\n width: 10, points: [\n [5, 21],\n [6, 20],\n [7, 21],\n [6, 22],\n [5, 21],\n [-1, -1],\n [6, 14],\n [6, -3],\n [5, -6],\n [3, -7],\n [1, -7]\n ]\n },\n 'k': {\n width: 17, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [14, 14],\n [4, 4],\n [-1, -1],\n [8, 8],\n [15, 0]\n ]\n },\n 'l': {\n width: 8, points: [\n [4, 21],\n [4, 0]\n ]\n },\n 'm': {\n width: 30, points: [\n [4, 14],\n [4, 0],\n [-1, -1],\n [4, 10],\n [7, 13],\n [9, 14],\n [12, 14],\n [14, 13],\n [15, 10],\n [15, 0],\n [-1, -1],\n [15, 10],\n [18, 13],\n [20, 14],\n [23, 14],\n [25, 13],\n [26, 10],\n [26, 0]\n ]\n },\n 'n': {\n width: 19, points: [\n [4, 14],\n [4, 0],\n [-1, -1],\n [4, 10],\n [7, 13],\n [9, 14],\n [12, 14],\n [14, 13],\n [15, 10],\n [15, 0]\n ]\n },\n 'o': {\n width: 19, points: [\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3],\n [16, 6],\n [16, 8],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14]\n ]\n },\n 'p': {\n width: 19, points: [\n [4, 14],\n [4, -7],\n [-1, -1],\n [4, 11],\n [6, 13],\n [8, 14],\n [11, 14],\n [13, 13],\n [15, 11],\n [16, 8],\n [16, 6],\n [15, 3],\n [13, 1],\n [11, 0],\n [8, 0],\n [6, 1],\n [4, 3]\n ]\n },\n 'q': {\n width: 19, points: [\n [15, 14],\n [15, -7],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'r': {\n width: 13, points: [\n [4, 14],\n [4, 0],\n [-1, -1],\n [4, 8],\n [5, 11],\n [7, 13],\n [9, 14],\n [12, 14]\n ]\n },\n 's': {\n width: 17, points: [\n [14, 11],\n [13, 13],\n [10, 14],\n [7, 14],\n [4, 13],\n [3, 11],\n [4, 9],\n [6, 8],\n [11, 7],\n [13, 6],\n [14, 4],\n [14, 3],\n [13, 1],\n [10, 0],\n [7, 0],\n [4, 1],\n [3, 3]\n ]\n },\n 't': {\n width: 12, points: [\n [5, 21],\n [5, 4],\n [6, 1],\n [8, 0],\n [10, 0],\n [-1, -1],\n [2, 14],\n [9, 14]\n ]\n },\n 'u': {\n width: 19, points: [\n [4, 14],\n [4, 4],\n [5, 1],\n [7, 0],\n [10, 0],\n [12, 1],\n [15, 4],\n [-1, -1],\n [15, 14],\n [15, 0]\n ]\n },\n 'v': {\n width: 16, points: [\n [2, 14],\n [8, 0],\n [-1, -1],\n [14, 14],\n [8, 0]\n ]\n },\n 'w': {\n width: 22, points: [\n [3, 14],\n [7, 0],\n [-1, -1],\n [11, 14],\n [7, 0],\n [-1, -1],\n [11, 14],\n [15, 0],\n [-1, -1],\n [19, 14],\n [15, 0]\n ]\n },\n 'x': {\n width: 17, points: [\n [3, 14],\n [14, 0],\n [-1, -1],\n [14, 14],\n [3, 0]\n ]\n },\n 'y': {\n width: 16, points: [\n [2, 14],\n [8, 0],\n [-1, -1],\n [14, 14],\n [8, 0],\n [6, -4],\n [4, -6],\n [2, -7],\n [1, -7]\n ]\n },\n 'z': {\n width: 17, points: [\n [14, 14],\n [3, 0],\n [-1, -1],\n [3, 14],\n [14, 14],\n [-1, -1],\n [3, 0],\n [14, 0]\n ]\n },\n '{': {\n width: 14, points: [\n [9, 25],\n [7, 24],\n [6, 23],\n [5, 21],\n [5, 19],\n [6, 17],\n [7, 16],\n [8, 14],\n [8, 12],\n [6, 10],\n [-1, -1],\n [7, 24],\n [6, 22],\n [6, 20],\n [7, 18],\n [8, 17],\n [9, 15],\n [9, 13],\n [8, 11],\n [4, 9],\n [8, 7],\n [9, 5],\n [9, 3],\n [8, 1],\n [7, 0],\n [6, -2],\n [6, -4],\n [7, -6],\n [-1, -1],\n [6, 8],\n [8, 6],\n [8, 4],\n [7, 2],\n [6, 1],\n [5, -1],\n [5, -3],\n [6, -5],\n [7, -6],\n [9, -7]\n ]\n },\n '|': {\n width: 8, points: [\n [4, 25],\n [4, -7]\n ]\n },\n '}': {\n width: 14, points: [\n [5, 25],\n [7, 24],\n [8, 23],\n [9, 21],\n [9, 19],\n [8, 17],\n [7, 16],\n [6, 14],\n [6, 12],\n [8, 10],\n [-1, -1],\n [7, 24],\n [8, 22],\n [8, 20],\n [7, 18],\n [6, 17],\n [5, 15],\n [5, 13],\n [6, 11],\n [10, 9],\n [6, 7],\n [5, 5],\n [5, 3],\n [6, 1],\n [7, 0],\n [8, -2],\n [8, -4],\n [7, -6],\n [-1, -1],\n [8, 8],\n [6, 6],\n [6, 4],\n [7, 2],\n [8, 1],\n [9, -1],\n [9, -3],\n [8, -5],\n [7, -6],\n [5, -7]\n ]\n },\n '~': {\n width: 24, points: [\n [3, 6],\n [3, 8],\n [4, 11],\n [6, 12],\n [8, 12],\n [10, 11],\n [14, 8],\n [16, 7],\n [18, 7],\n [20, 8],\n [21, 10],\n [-1, -1],\n [3, 8],\n [4, 10],\n [6, 11],\n [8, 11],\n [10, 10],\n [14, 7],\n [16, 6],\n [18, 6],\n [20, 7],\n [21, 10],\n [21, 12]\n ]\n }\n};\n\n/**\n * @desc Creates wireframe text-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a text-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildVectorTextGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const text = buildVectorTextGeometry({\n * origin: [0,0,0],\n * text: \"On the other side of the screen, it all looked so easy\"\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"textGeometry\",\n * primitiveType: text.primitiveType, // Will be \"lines\"\n * positions: text.positions,\n * indices: text.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redTextMesh\",\n * geometryId: \"textGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redText\",\n * meshIds: [\"redTextMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildVectorTextGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number[]} [cfg.origin] 3D point indicating the top left corner.\n * @param {Number} [cfg.size=1] Size of each character.\n * @param {String} [cfg.text=\"\"] The text.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildVectorTextGeometry(cfg = {}) {\n\n var origin = cfg.origin || [0, 0, 0];\n var xOrigin = origin[0];\n var yOrigin = origin[1];\n var zOrigin = origin[2];\n var size = cfg.size || 1;\n\n var positions = [];\n var indices = [];\n var text = (\"\" + cfg.text).trim();\n var lines = (text || \"\").split(\"\\n\");\n var countVerts = 0;\n var y = 0;\n var x;\n var str;\n var len;\n var c;\n var mag = 1.0 / 25.0;\n var penUp;\n var p1;\n var p2;\n var needLine;\n var pointsLen;\n var a;\n\n for (var iLine = 0; iLine < lines.length; iLine++) {\n\n x = 0;\n str = lines[iLine];\n len = str.length;\n\n for (var i = 0; i < len; i++) {\n\n c = letters[str.charAt(i)];\n\n if (c === '\\n') {\n //alert(\"newline\");\n }\n\n if (!c) {\n continue;\n }\n\n penUp = 1;\n p1 = -1;\n p2 = -1;\n needLine = false;\n\n pointsLen = c.points.length;\n\n for (var j = 0; j < pointsLen; j++) {\n a = c.points[j];\n\n if (a[0] === -1 && a[1] === -1) {\n penUp = 1;\n needLine = false;\n continue;\n }\n\n positions.push((x + (a[0] * size) * mag) + xOrigin);\n positions.push((y + (a[1] * size) * mag) + yOrigin);\n positions.push(0 + zOrigin);\n\n if (p1 === -1) {\n p1 = countVerts;\n } else if (p2 === -1) {\n p2 = countVerts;\n } else {\n p1 = p2;\n p2 = countVerts;\n }\n countVerts++;\n\n if (penUp) {\n penUp = false;\n\n } else {\n indices.push(p1);\n indices.push(p2);\n }\n\n needLine = true;\n }\n x += c.width * mag * size;\n\n }\n y -= 35 * mag * size;\n }\n\n return {\n primitiveType: \"lines\",\n positions: positions,\n indices: indices\n };\n}\n\n\nexport {buildVectorTextGeometry}\n","\nimport {XKTModel} from \"./XKTModel/XKTModel.js\";\nimport {parseGLTFIntoXKTModel} from \"./parsers/parseGLTFIntoXKTModel.js\";\nimport {writeXKTModelToArrayBuffer} from \"./XKTModel/writeXKTModelToArrayBuffer.js\";\n\nimport {toArrayBuffer} from \"./XKTModel/lib/toArraybuffer\";\n\n/**\n * Converts model files into xeokit's native XKT format.\n *\n * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.\n *\n * **Only bundled in xeokit-convert.cjs.js.**\n *\n * ## Usage\n *\n ````\n * @param {Object} params Conversion parameters.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {*} [params.configs] Configurations.\n * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````.\n * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method.\n * @param {Function} [params.outputXKT] Callback to collect XKT file data.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided.\n * @param {Function} [params.outputStats] Callback to collect statistics.\n * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis \"up\", if necessary. Applies to CityJSON and LAS/LAZ models.\n * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models.\n * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore\n * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the model.\n * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000,\n * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close\n * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger.\n * @param {Function} [params.log] Logging callback.\n * @return {Promise}\n */\nfunction convert2xkt({\n configs = {},\n sourceData,\n modelAABB,\n outputXKTModel,\n outputXKT,\n includeTypes,\n excludeTypes,\n reuseGeometries = true,\n minTileSize = 200,\n stats = {},\n rotateX = false,\n includeTextures = true,\n includeNormals = true,\n log = function (msg) {\n }\n }) {\n\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 0;\n stats.numPropertySets = 0;\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numUVs = 0;\n stats.numTextures = 0;\n stats.numTextureSets = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n stats.sourceSize = 0;\n stats.xktSize = 0;\n stats.texturesSize = 0;\n stats.xktVersion = \"\";\n stats.compressionRatio = 0;\n stats.conversionTime = 0;\n stats.aabb = null;\n\n return new Promise(function (resolve, reject) {\n const _log = log;\n log = (msg) => {\n _log(`[convert2xkt] ${msg}`)\n }\n\n if (!sourceData) {\n reject(\"Argument expected: source or sourceData\");\n return;\n }\n\n if (!outputXKTModel && !outputXKT) {\n reject(\"Argument expected: output, outputXKTModel or outputXKT\");\n return;\n }\n\n const sourceConfigs = configs.sourceConfigs || {};\n const ext = 'glb';\n\n log(`Input file extension: \"${ext}\"`);\n\n let fileTypeConfigs = sourceConfigs[ext];\n\n if (!fileTypeConfigs) {\n log(`[WARNING] Could not find configs sourceConfigs entry for source format \"${ext}\". This is derived from the source file name extension. Will use internal default configs.`);\n fileTypeConfigs = {};\n }\n\n function overrideOption(option1, option2) {\n if (option1 !== undefined) {\n return option1;\n }\n return option2;\n }\n\n\n const sourceFileSizeBytes = sourceData.byteLength;\n\n log(\"Input file size: \" + (sourceFileSizeBytes / 1000).toFixed(2) + \" kB\");\n\n\n\n minTileSize = overrideOption(fileTypeConfigs.minTileSize, minTileSize);\n rotateX = overrideOption(fileTypeConfigs.rotateX, rotateX);\n reuseGeometries = overrideOption(fileTypeConfigs.reuseGeometries, reuseGeometries);\n includeTextures = overrideOption(fileTypeConfigs.includeTextures, includeTextures);\n includeNormals = overrideOption(fileTypeConfigs.includeNormals, includeNormals);\n includeTypes = overrideOption(fileTypeConfigs.includeTypes, includeTypes);\n excludeTypes = overrideOption(fileTypeConfigs.excludeTypes, excludeTypes);\n\n if (reuseGeometries === false) {\n log(\"Geometry reuse is disabled\");\n }\n\n const xktModel = new XKTModel({\n minTileSize,\n modelAABB\n });\n\n\n\n sourceData = toArrayBuffer(sourceData);\n convert(parseGLTFIntoXKTModel, {\n data: sourceData,\n reuseGeometries,\n includeTextures: true,\n includeNormals,\n xktModel,\n stats,\n log\n });\n\n\n function convert(parser, converterParams) {\n\n parser(converterParams).then(() => {\n\n\n log(\"Input file parsed OK. Building XKT document...\");\n\n xktModel.finalize().then(() => {\n\n log(\"XKT document built OK. Writing to XKT file...\");\n\n const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel, null, stats, {zip: true});\n\n const xktContent = Buffer.from(xktArrayBuffer);\n\n\n if (outputXKT) {\n outputXKT(xktContent);\n }\n\n resolve();\n });\n }, (err) => {\n reject(err);\n });\n }\n });\n}\n\nexport {convert2xkt};","/**\n * @private\n * @param buf\n * @returns {ArrayBuffer}\n */\nexport function toArrayBuffer(buf) {\n const ab = new ArrayBuffer(buf.length);\n const view = new Uint8Array(ab);\n for (let i = 0; i < buf.length; ++i) {\n view[i] = buf[i];\n }\n return ab;\n}","import '@loaders.gl/polyfills';\nimport {installFilePolyfills} from '@loaders.gl/polyfills';\n\ninstallFilePolyfills();\n\nexport * from \"./src/index.js\";\nexport {convert2xkt} from \"./src/convert2xkt_browser.js\"; // convert2xkt is only bundled for Node.js\n"],"names":["root","factory","exports","module","define","amd","global","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","require","p","mat","mat2","mat3","xyz","tempVec3","vec","translate","scale","XKT_INFO","xktVersion","RepeatWrapping","ClampToEdgeWrapping","MirroredRepeatWrapping","NearestFilter","NearestMipMapNearestFilter","NearestMipmapNearestFilter","NearestMipmapLinearFilter","NearestMipMapLinearFilter","LinearFilter","LinearMipmapNearestFilter","LinearMipMapNearestFilter","LinearMipmapLinearFilter","LinearMipMapLinearFilter","GIFMediaType","JPEGMediaType","PNGMediaType","FloatArrayType","Float64Array","tempMat1","tempMat2","tempVec4","math","MIN_DOUBLE","Number","MAX_SAFE_INTEGER","MAX_DOUBLE","DEGTORAD","RADTODEG","vec2","values","vec3","vec4","mat3ToMat4","mat4","arguments","length","undefined","mat4ToMat3","createUUID","lut","i","toString","d0","Math","random","d1","d2","d3","concat","clamp","min","max","fmod","a","b","console","error","negateVec4","v","dest","addVec4","u","addVec4Scalar","s","addVec3","addVec3Scalar","subVec4","subVec3","subVec2","subVec4Scalar","subScalarVec4","mulVec4","mulVec4Scalar","mulVec3Scalar","mulVec2Scalar","divVec3","divVec4","divScalarVec3","divVec3Scalar","divVec4Scalar","divScalarVec4","dotVec4","cross3Vec4","u0","u1","u2","v0","v1","v2","cross3Vec3","x","y","z","x2","y2","z2","sqLenVec4","lenVec4","sqrt","dotVec3","dotVec2","sqLenVec3","sqLenVec2","lenVec3","distVec3","w","lenVec2","distVec2","rcpVec3","normalizeVec4","f","normalizeVec3","normalizeVec2","angleVec3","theta","acos","vec3FromMat4Scale","m","vecToArray","trunc","round","len","Array","slice","xyzArrayToObject","arr","xyzObjectToArray","arry","dupMat4","mat4To3","m4s","setMat4ToZeroes","setMat4ToOnes","diagonalMat4v","diagonalMat4c","diagonalMat4s","identityMat4","identityMat3","isIdentityMat4","negateMat4","addMat4","addMat4Scalar","addScalarMat4","subMat4","subMat4Scalar","subScalarMat4","mulMat4","a00","a01","a02","a03","a10","a11","a12","a13","a20","a21","a22","a23","a30","a31","a32","a33","b00","b01","b02","b03","b10","b11","b12","b13","b20","b21","b22","b23","b30","b31","b32","b33","mulMat3","mulMat4Scalar","mulMat4v4","v3","transposeMat4","m4","m14","m8","m13","m12","m9","transposeMat3","determinantMat4","inverseMat4","b04","b05","b06","b07","b08","b09","invDet","traceMat4","translationMat4v","translationMat3v","translationMat4c","translationMat4s","translateMat4v","translateMat4c","OLDtranslateMat4c","m15","m3","m7","m11","rotationMat4v","anglerad","axis","xy","yz","zx","xs","ys","zs","ax","sin","c","cos","q","rotationMat4c","scalingMat4v","scalingMat3v","scalingMat4c","scaleMat4c","scaleMat4v","scalingMat4s","rotationTranslationMat4","xx","xz","yy","zz","wx","wy","wz","mat4ToEuler","order","m21","m22","m23","m31","m32","m33","asin","abs","atan2","composeMat4","position","quaternion","quaternionToRotationMat4","decomposeMat4","matrix","sx","sy","sz","set","invSX","invSY","invSZ","mat4ToQuaternion","this","lookAtMat4v","pos","target","up","z0","z1","x0","x1","y0","y1","posx","posy","posz","upx","upy","upz","targetx","targety","targetz","lookAtMat4c","orthoMat4c","left","right","bottom","top","near","far","rl","tb","fn","frustumMat4v","fmin","fmax","fmin4","fmax4","t","tempMat20","tempMat21","tempMat22","frustumMat4","perspectiveMat4","fovyrad","aspectratio","znear","zfar","pmin","pmax","tan","transformPoint3","transformPoint4","transformPoints3","points","points2","p0","p1","p2","pi","r","result","m0","m1","m2","m5","m6","m10","transformPositions3","transformPositions4","transformVec3","transformVec4","rotateVec3X","rotateVec3Y","rotateVec3Z","projectVec4","unprojectVec3","viewMat","projMat","lerpVec3","t1","t2","flatten","leni","j","lenj","item","push","identityQuaternion","eulerToQuaternion","euler","c1","c2","c3","s1","s2","s3","trace","vec3PairToQuaternion","norm_u_norm_v","real_part","normalizeQuaternion","angleAxisToQuaternion","angleAxis","halfAngle","fsin","quaternionToEuler","mulQuaternions","p3","q0","q1","q2","q3","vec3ApplyQuaternion","qx","qy","qz","qw","ix","iy","iz","iw","quaternionToMat4","tx","ty","tz","twx","twy","twz","txx","txy","txz","tyy","tyz","tzz","conjugateQuaternion","inverseQuaternion","quaternionToAngleAxis","angle","AABB3","AABB2","OBB3","OBB2","Sphere3","transformOBB3","containsAABB3","aabb1","aabb2","getAABB3Diag","aabb","getAABB3DiagPoint","diagVec","xneg","xpos","yneg","ypos","zneg","zpos","getAABB3Center","getAABB2Center","collapseAABB3","AABB3ToOBB3","obb","positions3ToAABB3","positions","positionsDecodeMatrix","xmin","ymin","zmin","xmax","ymax","zmax","decompressPosition","OBB3ToAABB3","points3ToAABB3","points3ToSphere3","sphere","numPoints","dist","radius","positions3ToSphere3","tempVec3a","tempVec3b","lenPositions","numPositions","OBB3ToSphere3","point","lenPoints","getSphere3Center","expandAABB3","expandAABB3Point3","triangleNormal","normal","p1x","p1y","p1z","p2x","p2y","p2z","p3x","p3y","p3z","mag","octEncodeVec3","array","xfunc","yfunc","tempx","tempy","Int8Array","octDecodeVec2","oct","dot","uniquePositions","indicesLookup","indicesReverseLookup","weldedIndices","faces","numFaces","compa","compb","compc","cb","ab","cross","inverseNormal","geometryCompression","quantizePositions","quantizedPositions","maxInt","xMultiplier","yMultiplier","zMultiplier","verify","num","floor","compressPosition","multiplier","Float32Array","createPositionsDecodeMatrix","xwid","ywid","zwid","transformAndOctEncodeNormals","modelNormalMatrix","normals","lenNormals","compressedNormals","lenCompressedNormals","best","currentCos","bestCos","localNormal","worldNormal","octEncodeNormals","buildEdgeIndices","Uint16Array","indices","edgeThreshold","vx","vy","vz","positionsMap","precision","pow","lenUniquePositions","weldVertices","numIndices","ia","ib","ic","face","buildFaces","edge1","edge2","index1","index2","edge","normal1","normal2","edgeIndices","thresholdDot","edges","largeIndex","faceIndex","face1","face2","dot2","Uint32Array","isTriangleMeshSolid","vertexIndexMapping","compareIndexPositions","posA","posB","newIndices","sort","uniqueVertexIndex","a2","b2","temp","compareEdges","e1","e2","sameEdgeCount","XKTMesh","_createClass","cfg","_classCallCheck","meshId","meshIndex","geometry","color","metallic","roughness","opacity","textureSet","entity","XKTGeometry","geometryId","primitiveType","geometryIndex","numInstances","positionsQuantized","normalsOctEncoded","colorsCompressed","uvs","uvsCompressed","solid","XKTEntity","entityId","meshes","entityIndex","hasReusedGeometries","XKTTile","entities","KDNode","XKTMetaObject","metaObjectId","propertySetIds","metaObjectType","metaObjectName","parentMetaObjectId","XKTPropertySet","propertySetId","propertySetType","propertySetName","properties","XKTTexture","textureId","textureIndex","imageData","channel","width","height","src","compressed","mediaType","minFilter","magFilter","wrapS","wrapT","wrapR","XKTTextureSet","textureSetId","textureSetIndex","materialType","materialIndex","colorTexture","metallicRoughnessTexture","normalsTexture","emissiveTexture","occlusionTexture","_regeneratorRuntime","Op","hasOwn","desc","$Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","configurable","writable","err","wrap","innerFn","outerFn","self","tryLocsList","protoGenerator","Generator","generator","create","context","Context","makeInvokeMethod","tryCatch","arg","type","ContinueSentinel","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","getProto","getPrototypeOf","NativeIteratorPrototype","Gp","defineIteratorMethods","forEach","method","_invoke","AsyncIterator","PromiseImpl","invoke","resolve","reject","record","_typeof","__await","then","unwrapped","previousPromise","callInvokeWithMethodAndArg","state","Error","done","delegate","delegateResult","maybeInvokeDelegate","sent","_sent","dispatchException","abrupt","methodName","TypeError","info","resultName","next","nextLoc","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","reset","iterable","iteratorMethod","isNaN","doneResult","displayName","isGeneratorFunction","genFun","ctor","constructor","name","mark","setPrototypeOf","__proto__","awrap","async","Promise","iter","keys","val","object","reverse","pop","skipTempReset","prev","charAt","stop","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","finish","thrown","delegateYield","asyncGeneratorStep","gen","_next","_throw","_defineProperties","props","descriptor","input","hint","prim","toPrimitive","res","String","_toPrimitive","tempVec4a","tempVec4b","tempMat4","tempMat4b","kdTreeDimLength","TEXTURE_ENCODING_OPTIONS","useSRGB","qualityLevel","encodeUASTC","mipmaps","XKTModel","instance","Constructor","modelId","projectId","revisionId","author","createdAt","creatingApplication","schema","minTileSize","modelAABB","propertySets","propertySetsList","metaObjects","metaObjectsList","reusedGeometriesDecodeMatrix","geometries","geometriesList","textures","texturesList","textureSets","textureSetsList","meshesList","entitiesList","tilesList","finalized","protoProps","_finalize","params","propertySet","metaObject","_rootMetaObject","fileExt","split","texture","colorTextureId","metallicRoughnessTextureId","normalsTextureId","emissiveTextureId","occlusionTextureId","triangles","lines","line_strip","line_loop","_createDefaultIndices","colors","xktGeometryCfg","uv","Uint8Array","mergedPositions","mergedIndices","mergeVertices","rotation","mesh","meshIds","meshIdIdx","meshIdLen","warn","createMetaObject","_callee","rootKDNode","_context","log","_removeUnusedTextures","_compressTextures","_bakeSingleUseGeometryPositions","_bakeAndOctEncodeNormals","_createEntityAABBs","_createKDTree","_createTilesFromKDTree","_createReusedGeometriesDecodeMatrix","_flagSolidGeometries","args","apply","_this","countTextures","_loop","encodingOptions","load","ImageLoader","image","encode","KTX2BasisWriter","encodedData","encodedImageData","entityAABB","_insertEntityIntoKDTree","kdNode","nodeAABB","dim","aabbLeft","aabbRight","_createTilesFromKDNode","_createTileFromEntities","tileAABB","tileCenter","tileCenterNeg","rtcAABB","reused","k","lenk","tile","reusedGeometriesAABB","countReusedGeometries","numGeometries","maxNumPositions","maxNumIndices","XKT_VERSION","NUM_TEXTURE_ATTRIBUTES","NUM_MATERIAL_ATTRIBUTES","writeXKTModelToArrayBuffer","xktModel","metaModelJSON","stats","options","data","metaModelDataStr","numPropertySets","numMetaObjects","numTextures","numTextureSets","numMeshes","numEntities","numTiles","lenColors","lenUVs","lenIndices","lenEdgeIndices","lenMatrices","lenTextures","xktTexture","byteLength","numCompressedTextures","metadata","textureData","eachTextureDataPortion","eachTextureAttributes","eachTextureSetTextures","Int32Array","matrices","eachGeometryPrimitiveType","eachGeometryPositionsPortion","eachGeometryNormalsPortion","eachGeometryColorsPortion","eachGeometryUVsPortion","eachGeometryIndicesPortion","eachGeometryEdgeIndicesPortion","eachMeshGeometriesPortion","eachMeshMatricesPortion","eachMeshTextureSet","eachMeshMaterialAttributes","eachEntityId","eachEntityMeshesPortion","eachTileAABB","eachTileEntitiesPortion","countPositions","countNormals","countColors","countUVs","countIndices","countEdgeIndices","id","propertySetsIndex","propertySetJSON","metaObjectsIndex","metaObjectJSON","parent","external","portionIdx","textureAttrIdx","eachTextureSetTexturesIndex","countEntityMeshesPortion","eachMeshMaterialAttributesIndex","matricesIndex","tileIndex","tileEntities","numTileEntities","entityMeshes","numEntityMeshes","tileAABBIndex","getModelData","deflatedData","deflate","buffer","zip","pako","deflateJSON","JSON","stringify","replace","chr","charCodeAt","substr","deflateData","texturesSize","arrayBuffer","elements","indexData","dataLen","elementsize","indexBuf","dataArray","offset","element","toArrayBuffer","createArrayBuffer","strings","earcut","holeIndices","minX","minY","maxX","maxY","invSize","hasHoles","outerLen","outerNode","linkedList","list","queue","steiner","getLeftmost","compareX","eliminateHole","filterPoints","eliminateHoles","earcutLinked","start","end","clockwise","last","signedArea","insertNode","equals","removeNode","again","area","ear","pass","zOrder","prevZ","nextZ","e","tail","numMerges","pSize","qSize","inSize","sortLinked","indexCurve","isEarHashed","isEar","cureLocalIntersections","splitEarcut","pointInTriangle","minTX","minTY","maxTX","maxTY","minZ","maxZ","n","intersects","locallyInside","isValidDiagonal","splitPolygon","hole","hx","hy","mx","my","tanMin","Infinity","sectorContainsSector","findHoleBridge","leftmost","ay","bx","by","cx","cy","px","py","intersectsPolygon","inside","middleInside","o1","sign","o2","o3","o4","onSegment","Node","an","bp","sum","deviation","polygonArea","trianglesArea","vertices","holes","dimensions","holeIndex","d","tempVec2a","tempVec3c","parseCityJSONIntoXKTModel","_ref","_ref$center","center","_ref$transform","transform","_ref$stats","vertices2","copyVertices","cityJSONTransform","vertex","transformVertices","centerVertices","customTransformVertices","sourceFormat","schemaVersion","version","title","created","numTriangles","numVertices","numObjects","rootMetaObjectId","modelMetaObjectId","ctx","msg","nextId","cityObjects","CityObjects","objectId","parseCityObject","parseCityJSON","centerPos","cityObject","parents","objectMaterial","surfaceMaterials","appearance","materials","geometryMaterial","material","themeIds","theme","surfaceMaterial","parseGeometrySurfacesWithOwnMaterials","parseGeometrySurfacesWithSharedMaterial","createEntity","parseSurfacesWithOwnMaterials","boundaries","shells","solids","surfaces","surface","diffuseColor","transparency","sharedIndices","geometryCfg","newFace","extractLocalIndices","_toConsumableArray","pList","getNormalOfPositions","pv","to2D","unshift","tr","createGeometry","createMesh","parseSurfacesWithSharedMaterial","primitiveCfg","boundary","newBoundary","index","includes","vertexIndex","indexOf","nexti","_p","_n","re","x3","tmp2","y3","utils","isString","parseGLTFIntoXKTModel","baseUri","metaModelData","_ref$includeTextures","includeTextures","_ref$includeNormals","includeNormals","getAttachment","numNormals","numUVs","parse","GLTFLoader","gltfData","metaModelCorrections","geometryCreated","parseTexture","parseTextures","_textureSetId","parseTextureSet","_attributes","parseMaterialAttributes","parseMaterials","scene","scenes","nodes","countMeshUsage","parseNode","parseScene","parseDefaultScene","errMsg","source","sampler","createTexture","flipY","_textureId","textureSetCfg","normalTexture","normalTextureId","metallicPBR","pbrMetallicRoughness","baseColorTexture","extensions","specularPBR","specularTexture","specularColorTexture","createTextureSet","materialAttributes","diffuseFactor","common","technique","blinn","phong","lambert","diffuse","transparent","baseColorFactor","metallicFactor","roughnessFactor","node","instances","children","childNode","objectIdStack","meshIdsStack","depth","localMatrix","translation","xktEntityId","numPrimitives","primitives","primitive","_xktGeometryId","xktGeometryId","mode","attributes","POSITION","NORMAL","COLOR_0","TEXCOORD_0","xktMeshId","meshCfg","nodeName","entityMeshIds","atob2","atob","Buffer","from","WEBGL_COMPONENT_TYPES","Int16Array","WEBGL_TYPE_SIZES","parseGLTFJSONIntoXKTModel","reuseGeometries","gltf","getMetaModelCorrections","createXKTGeometryIds","nextMeshId","buffers","all","map","bufferInfo","_arrayBuffer","_buffer","uri","dataUriRegexResult","match","isBase64","decodeURIComponent","ArrayBuffer","view","parseArrayBuffer","parseBuffer","parseBuffers","bufferViewsInfo","bufferViews","parseBufferView","parseBufferViews","freeBuffers","materialsInfo","materialInfo","parseMaterial","_materialData","defaultSceneInfo","sceneInfo","glTFNode","eachRootStats","eachChildRoot","metaObjectsMap","metaObjectParent","rootMetaObject","numChildren","countChildren","bufferViewInfo","_typedArray","byteOffset","deferredMeshIds","gltfMeshId","meshInfo","numPrimitivesInMesh","primitiveInfo","geometryHash","createPrimitiveGeometryHash","geometryArrays","parsePrimitiveGeometry","childNodeIdx","childGLTFNode","rootMetaObjectStats","join","accessors","indicesIndex","accessorInfo","parseAccessorTypedArray","positionsIndex","normalsIndex","colorsIndex","bufferView","itemSize","TypedArray","componentType","itemBytes","BYTES_PER_ELEMENT","byteStride","count","parseIFCIntoXKTModel","WebIFC","_ref$autoNormals","autoNormals","includeTypes","excludeTypes","wasmPath","ifcAPI","IfcAPI","SetWasmPath","Init","modelID","OpenModel","ifcProjectId","GetLineIDsWithType","IFCPROJECT","GetLine","ifcProject","parseSpatialChildren","parseMetadata","flatMeshes","LoadAllGeometry","size","createObject","IFCSPACE","ifcSpaceId","flatMesh","GetFlatMesh","parseGeometry","IFCRELDEFINESBYPROPERTIES","relID","rel","relatingPropertyDefinition","RelatingPropertyDefinition","GlobalId","relatedObjects","RelatedObjects","HasProperties","Name","nominalValue","NominalValue","property","valueType","Description","description","createPropertySet","parsePropertySets","ifcElement","parseRelatedItemsOfType","expressID","IFCRELAGGREGATES","IFCRELCONTAINEDINSPATIALSTRUCTURE","relation","related","relatedItems","isArray","element2","flatMeshExpressID","placedGeometries","placedGeometry","geometryExpressID","GetGeometry","vertexData","GetVertexArray","GetVertexData","GetVertexDataSize","GetIndexArray","GetIndexData","GetIndexDataSize","flatTransformation","MAX_VERTICES","parseLASIntoXKTModel","_ref$colorDepth","colorDepth","_ref$fp","fp64","_ref$skip","skip","_ref$log","LASLoader","las","parsedData","loaderData","pointsFormatId","readAttributes","intensity","readIntensities","readColorsAndIntensities","pointsChunks","chunkArray","positionsValue","readPositions","colorsChunks","attributesPosition","attributesColor","attributesIntensity","colorSize","intensities","colorsCompressedSize","l","chunkSize","parseMetaModelIntoXKTModel","includeTypesMap","excludeTypesMap","newObject","countMetaObjects","parsePCDIntoXKTModel","_ref$littleEndian","littleEndian","textData","TextDecoder","decode","il","fromCharCode","escape","decodeText","header","result1","search","result2","exec","headerLen","str","fields","viewpoint","parseFloat","parseInt","sizeSum","rowSize","parseHeader","line","rgb","g","sizes","compressedSize","decompressedSize","decompressed","inData","outLength","ctrl","ref","inLength","outData","inPtr","outPtr","decompressLZF","dataview","DataView","getFloat32","getUint8","row","parsePLYIntoXKTModel","_x","_parsePLYIntoXKTModel","hasColors","colorsValue","PLYLoader","t0","parseSTLIntoXKTModel","_parseSTLIntoXKTModel","splitMeshes","smoothNormals","smoothNormalsAngleThreshold","binData","ensureBinary","isBinary","parseBinary","parseASCII","reader","getUint32","defaultR","defaultG","defaultB","lastR","lastG","lastB","newMesh","normalX","normalY","normalZ","packedColor","getUint16","vertexstart","addMesh","normalx","normaly","normalz","verticesPerFace","normalsPerFace","text","faceRegex","faceCounter","floatRegex","vertexRegex","RegExp","normalRegex","nextGeometryId","ni","acc","posi","vertexMap","vertexNormals","vertexNormalAccum","numVerts","ii","jj","faceToVertexNormals","buildBoxGeometry","xSize","ySize","zSize","centerX","centerY","centerZ","buildBoxLinesGeometry","buildCylinderGeometry","radiusTop","radiusBottom","radialSegments","heightSegments","h","currentRadius","currentHeight","first","second","startIndex","tu","tv","openEnded","heightHalf","heightLength","radialAngle","PI","radialLength","radiusChange","atan","buildGridGeometry","divisions","step","halfSize","buildPlaneGeometry","xSegments","zSegments","halfWidth","halfHeight","planeX","planeZ","planeX1","planeZ1","segmentWidth","segmentHeight","offset2","buildSphereGeometry","lod","widthSegments","sinTheta","cosTheta","phi","sinPhi","buildTorusGeometry","tube","tubeSegments","arc","letters","buildVectorTextGeometry","penUp","pointsLen","origin","xOrigin","yOrigin","zOrigin","trim","countVerts","iLine","convert2xkt","_ref$configs","configs","sourceData","outputXKTModel","outputXKT","_ref$reuseGeometries","_ref$minTileSize","_ref$rotateX","rotateX","sourceSize","xktSize","compressionRatio","conversionTime","_log","sourceConfigs","ext","fileTypeConfigs","sourceFileSizeBytes","toFixed","overrideOption","buf","finalize","xktArrayBuffer","xktContent","option1","option2","installFilePolyfills"],"sourceRoot":""} \ No newline at end of file diff --git a/docs/ast/source/convert2xkt_browser.js.json b/docs/ast/source/convert2xkt_browser.js.json new file mode 100644 index 0000000..6074d12 --- /dev/null +++ b/docs/ast/source/convert2xkt_browser.js.json @@ -0,0 +1,33794 @@ +{ + "type": "File", + "start": 0, + "end": 7516, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 189, + "column": 21 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 7516, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 189, + "column": 21 + } + }, + "sourceType": "module", + "body": [ + { + "type": "ImportDeclaration", + "start": 1, + "end": 49, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 48 + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "start": 9, + "end": 17, + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "imported": { + "type": "Identifier", + "start": 9, + "end": 17, + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 16 + }, + "identifierName": "XKTModel" + }, + "name": "XKTModel" + }, + "local": { + "type": "Identifier", + "start": 9, + "end": 17, + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 16 + }, + "identifierName": "XKTModel" + }, + "name": "XKTModel" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 24, + "end": 48, + "loc": { + "start": { + "line": 2, + "column": 23 + }, + "end": { + "line": 2, + "column": 47 + } + }, + "extra": { + "rawValue": "./XKTModel/XKTModel.js", + "raw": "\"./XKTModel/XKTModel.js\"" + }, + "value": "./XKTModel/XKTModel.js" + } + }, + { + "type": "ImportDeclaration", + "start": 50, + "end": 123, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 73 + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "start": 58, + "end": 79, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 29 + } + }, + "imported": { + "type": "Identifier", + "start": 58, + "end": 79, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 29 + }, + "identifierName": "parseGLTFIntoXKTModel" + }, + "name": "parseGLTFIntoXKTModel" + }, + "local": { + "type": "Identifier", + "start": 58, + "end": 79, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 29 + }, + "identifierName": "parseGLTFIntoXKTModel" + }, + "name": "parseGLTFIntoXKTModel" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 86, + "end": 122, + "loc": { + "start": { + "line": 3, + "column": 36 + }, + "end": { + "line": 3, + "column": 72 + } + }, + "extra": { + "rawValue": "./parsers/parseGLTFIntoXKTModel.js", + "raw": "\"./parsers/parseGLTFIntoXKTModel.js\"" + }, + "value": "./parsers/parseGLTFIntoXKTModel.js" + } + }, + { + "type": "ImportDeclaration", + "start": 124, + "end": 208, + "loc": { + "start": { + "line": 4, + "column": 0 + }, + "end": { + "line": 4, + "column": 84 + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "start": 132, + "end": 158, + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 34 + } + }, + "imported": { + "type": "Identifier", + "start": 132, + "end": 158, + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 34 + }, + "identifierName": "writeXKTModelToArrayBuffer" + }, + "name": "writeXKTModelToArrayBuffer" + }, + "local": { + "type": "Identifier", + "start": 132, + "end": 158, + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 34 + }, + "identifierName": "writeXKTModelToArrayBuffer" + }, + "name": "writeXKTModelToArrayBuffer" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 165, + "end": 207, + "loc": { + "start": { + "line": 4, + "column": 41 + }, + "end": { + "line": 4, + "column": 83 + } + }, + "extra": { + "rawValue": "./XKTModel/writeXKTModelToArrayBuffer.js", + "raw": "\"./XKTModel/writeXKTModelToArrayBuffer.js\"" + }, + "value": "./XKTModel/writeXKTModelToArrayBuffer.js" + } + }, + { + "type": "ImportDeclaration", + "start": 210, + "end": 269, + "loc": { + "start": { + "line": 6, + "column": 0 + }, + "end": { + "line": 6, + "column": 59 + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "start": 218, + "end": 231, + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 21 + } + }, + "imported": { + "type": "Identifier", + "start": 218, + "end": 231, + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 21 + }, + "identifierName": "toArrayBuffer" + }, + "name": "toArrayBuffer" + }, + "local": { + "type": "Identifier", + "start": 218, + "end": 231, + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 21 + }, + "identifierName": "toArrayBuffer" + }, + "name": "toArrayBuffer" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 238, + "end": 268, + "loc": { + "start": { + "line": 6, + "column": 28 + }, + "end": { + "line": 6, + "column": 58 + } + }, + "extra": { + "rawValue": "./XKTModel/lib/toArraybuffer", + "raw": "\"./XKTModel/lib/toArraybuffer\"" + }, + "value": "./XKTModel/lib/toArraybuffer" + }, + "trailingComments": [ + { + "type": "CommentBlock", + "value": "*\n * Converts model files into xeokit's native XKT format.\n *\n * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.\n *\n * **Only bundled in xeokit-convert.cjs.js.**\n *\n * ## Usage\n *\n ````\n * @param {Object} params Conversion parameters.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {*} [params.configs] Configurations.\n * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````.\n * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method.\n * @param {Function} [params.outputXKT] Callback to collect XKT file data.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided.\n * @param {Function} [params.outputStats] Callback to collect statistics.\n * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis \"up\", if necessary. Applies to CityJSON and LAS/LAZ models.\n * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models.\n * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore\n * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the model.\n * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000,\n * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close\n * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger.\n * @param {Function} [params.log] Logging callback.\n * @return {Promise}\n ", + "start": 271, + "end": 3260, + "loc": { + "start": { + "line": 8, + "column": 0 + }, + "end": { + "line": 46, + "column": 3 + } + } + } + ] + }, + { + "type": "Identifier", + "start": 3261, + "end": 7493, + "loc": { + "start": { + "line": 47, + "column": 0 + }, + "end": { + "line": 187, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 3270, + "end": 3281, + "loc": { + "start": { + "line": 47, + "column": 9 + }, + "end": { + "line": 47, + "column": 20 + }, + "identifierName": "convert2xkt" + }, + "name": "convert2xkt", + "leadingComments": null + }, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "ObjectPattern", + "start": 3282, + "end": 3917, + "loc": { + "start": { + "line": 47, + "column": 21 + }, + "end": { + "line": 63, + "column": 22 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 3309, + "end": 3321, + "loc": { + "start": { + "line": 48, + "column": 25 + }, + "end": { + "line": 48, + "column": 37 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3309, + "end": 3316, + "loc": { + "start": { + "line": 48, + "column": 25 + }, + "end": { + "line": 48, + "column": 32 + }, + "identifierName": "configs" + }, + "name": "configs" + }, + "value": { + "type": "AssignmentPattern", + "start": 3309, + "end": 3321, + "loc": { + "start": { + "line": 48, + "column": 25 + }, + "end": { + "line": 48, + "column": 37 + } + }, + "left": { + "type": "Identifier", + "start": 3309, + "end": 3316, + "loc": { + "start": { + "line": 48, + "column": 25 + }, + "end": { + "line": 48, + "column": 32 + }, + "identifierName": "configs" + }, + "name": "configs" + }, + "right": { + "type": "ObjectExpression", + "start": 3319, + "end": 3321, + "loc": { + "start": { + "line": 48, + "column": 35 + }, + "end": { + "line": 48, + "column": 37 + } + }, + "properties": [] + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3348, + "end": 3358, + "loc": { + "start": { + "line": 49, + "column": 25 + }, + "end": { + "line": 49, + "column": 35 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3348, + "end": 3358, + "loc": { + "start": { + "line": 49, + "column": 25 + }, + "end": { + "line": 49, + "column": 35 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + }, + "value": { + "type": "Identifier", + "start": 3348, + "end": 3358, + "loc": { + "start": { + "line": 49, + "column": 25 + }, + "end": { + "line": 49, + "column": 35 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3385, + "end": 3394, + "loc": { + "start": { + "line": 50, + "column": 25 + }, + "end": { + "line": 50, + "column": 34 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3385, + "end": 3394, + "loc": { + "start": { + "line": 50, + "column": 25 + }, + "end": { + "line": 50, + "column": 34 + }, + "identifierName": "modelAABB" + }, + "name": "modelAABB" + }, + "value": { + "type": "Identifier", + "start": 3385, + "end": 3394, + "loc": { + "start": { + "line": 50, + "column": 25 + }, + "end": { + "line": 50, + "column": 34 + }, + "identifierName": "modelAABB" + }, + "name": "modelAABB" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3421, + "end": 3435, + "loc": { + "start": { + "line": 51, + "column": 25 + }, + "end": { + "line": 51, + "column": 39 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3421, + "end": 3435, + "loc": { + "start": { + "line": 51, + "column": 25 + }, + "end": { + "line": 51, + "column": 39 + }, + "identifierName": "outputXKTModel" + }, + "name": "outputXKTModel" + }, + "value": { + "type": "Identifier", + "start": 3421, + "end": 3435, + "loc": { + "start": { + "line": 51, + "column": 25 + }, + "end": { + "line": 51, + "column": 39 + }, + "identifierName": "outputXKTModel" + }, + "name": "outputXKTModel" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3462, + "end": 3471, + "loc": { + "start": { + "line": 52, + "column": 25 + }, + "end": { + "line": 52, + "column": 34 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3462, + "end": 3471, + "loc": { + "start": { + "line": 52, + "column": 25 + }, + "end": { + "line": 52, + "column": 34 + }, + "identifierName": "outputXKT" + }, + "name": "outputXKT" + }, + "value": { + "type": "Identifier", + "start": 3462, + "end": 3471, + "loc": { + "start": { + "line": 52, + "column": 25 + }, + "end": { + "line": 52, + "column": 34 + }, + "identifierName": "outputXKT" + }, + "name": "outputXKT" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3498, + "end": 3510, + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 37 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3498, + "end": 3510, + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 37 + }, + "identifierName": "includeTypes" + }, + "name": "includeTypes" + }, + "value": { + "type": "Identifier", + "start": 3498, + "end": 3510, + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 37 + }, + "identifierName": "includeTypes" + }, + "name": "includeTypes" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3537, + "end": 3549, + "loc": { + "start": { + "line": 54, + "column": 25 + }, + "end": { + "line": 54, + "column": 37 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3537, + "end": 3549, + "loc": { + "start": { + "line": 54, + "column": 25 + }, + "end": { + "line": 54, + "column": 37 + }, + "identifierName": "excludeTypes" + }, + "name": "excludeTypes" + }, + "value": { + "type": "Identifier", + "start": 3537, + "end": 3549, + "loc": { + "start": { + "line": 54, + "column": 25 + }, + "end": { + "line": 54, + "column": 37 + }, + "identifierName": "excludeTypes" + }, + "name": "excludeTypes" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3576, + "end": 3598, + "loc": { + "start": { + "line": 55, + "column": 25 + }, + "end": { + "line": 55, + "column": 47 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3576, + "end": 3591, + "loc": { + "start": { + "line": 55, + "column": 25 + }, + "end": { + "line": 55, + "column": 40 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "value": { + "type": "AssignmentPattern", + "start": 3576, + "end": 3598, + "loc": { + "start": { + "line": 55, + "column": 25 + }, + "end": { + "line": 55, + "column": 47 + } + }, + "left": { + "type": "Identifier", + "start": 3576, + "end": 3591, + "loc": { + "start": { + "line": 55, + "column": 25 + }, + "end": { + "line": 55, + "column": 40 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "right": { + "type": "BooleanLiteral", + "start": 3594, + "end": 3598, + "loc": { + "start": { + "line": 55, + "column": 43 + }, + "end": { + "line": 55, + "column": 47 + } + }, + "value": true + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3625, + "end": 3642, + "loc": { + "start": { + "line": 56, + "column": 25 + }, + "end": { + "line": 56, + "column": 42 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3625, + "end": 3636, + "loc": { + "start": { + "line": 56, + "column": 25 + }, + "end": { + "line": 56, + "column": 36 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "value": { + "type": "AssignmentPattern", + "start": 3625, + "end": 3642, + "loc": { + "start": { + "line": 56, + "column": 25 + }, + "end": { + "line": 56, + "column": 42 + } + }, + "left": { + "type": "Identifier", + "start": 3625, + "end": 3636, + "loc": { + "start": { + "line": 56, + "column": 25 + }, + "end": { + "line": 56, + "column": 36 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "right": { + "type": "NumericLiteral", + "start": 3639, + "end": 3642, + "loc": { + "start": { + "line": 56, + "column": 39 + }, + "end": { + "line": 56, + "column": 42 + } + }, + "extra": { + "rawValue": 200, + "raw": "200" + }, + "value": 200 + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3669, + "end": 3679, + "loc": { + "start": { + "line": 57, + "column": 25 + }, + "end": { + "line": 57, + "column": 35 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3669, + "end": 3674, + "loc": { + "start": { + "line": 57, + "column": 25 + }, + "end": { + "line": 57, + "column": 30 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "value": { + "type": "AssignmentPattern", + "start": 3669, + "end": 3679, + "loc": { + "start": { + "line": 57, + "column": 25 + }, + "end": { + "line": 57, + "column": 35 + } + }, + "left": { + "type": "Identifier", + "start": 3669, + "end": 3674, + "loc": { + "start": { + "line": 57, + "column": 25 + }, + "end": { + "line": 57, + "column": 30 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "right": { + "type": "ObjectExpression", + "start": 3677, + "end": 3679, + "loc": { + "start": { + "line": 57, + "column": 33 + }, + "end": { + "line": 57, + "column": 35 + } + }, + "properties": [] + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3706, + "end": 3721, + "loc": { + "start": { + "line": 58, + "column": 25 + }, + "end": { + "line": 58, + "column": 40 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3706, + "end": 3713, + "loc": { + "start": { + "line": 58, + "column": 25 + }, + "end": { + "line": 58, + "column": 32 + }, + "identifierName": "rotateX" + }, + "name": "rotateX" + }, + "value": { + "type": "AssignmentPattern", + "start": 3706, + "end": 3721, + "loc": { + "start": { + "line": 58, + "column": 25 + }, + "end": { + "line": 58, + "column": 40 + } + }, + "left": { + "type": "Identifier", + "start": 3706, + "end": 3713, + "loc": { + "start": { + "line": 58, + "column": 25 + }, + "end": { + "line": 58, + "column": 32 + }, + "identifierName": "rotateX" + }, + "name": "rotateX" + }, + "right": { + "type": "BooleanLiteral", + "start": 3716, + "end": 3721, + "loc": { + "start": { + "line": 58, + "column": 35 + }, + "end": { + "line": 58, + "column": 40 + } + }, + "value": false + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3748, + "end": 3770, + "loc": { + "start": { + "line": 59, + "column": 25 + }, + "end": { + "line": 59, + "column": 47 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3748, + "end": 3763, + "loc": { + "start": { + "line": 59, + "column": 25 + }, + "end": { + "line": 59, + "column": 40 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + }, + "value": { + "type": "AssignmentPattern", + "start": 3748, + "end": 3770, + "loc": { + "start": { + "line": 59, + "column": 25 + }, + "end": { + "line": 59, + "column": 47 + } + }, + "left": { + "type": "Identifier", + "start": 3748, + "end": 3763, + "loc": { + "start": { + "line": 59, + "column": 25 + }, + "end": { + "line": 59, + "column": 40 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + }, + "right": { + "type": "BooleanLiteral", + "start": 3766, + "end": 3770, + "loc": { + "start": { + "line": 59, + "column": 43 + }, + "end": { + "line": 59, + "column": 47 + } + }, + "value": true + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3797, + "end": 3818, + "loc": { + "start": { + "line": 60, + "column": 25 + }, + "end": { + "line": 60, + "column": 46 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3797, + "end": 3811, + "loc": { + "start": { + "line": 60, + "column": 25 + }, + "end": { + "line": 60, + "column": 39 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "value": { + "type": "AssignmentPattern", + "start": 3797, + "end": 3818, + "loc": { + "start": { + "line": 60, + "column": 25 + }, + "end": { + "line": 60, + "column": 46 + } + }, + "left": { + "type": "Identifier", + "start": 3797, + "end": 3811, + "loc": { + "start": { + "line": 60, + "column": 25 + }, + "end": { + "line": 60, + "column": 39 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "right": { + "type": "BooleanLiteral", + "start": 3814, + "end": 3818, + "loc": { + "start": { + "line": 60, + "column": 42 + }, + "end": { + "line": 60, + "column": 46 + } + }, + "value": true + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3845, + "end": 3894, + "loc": { + "start": { + "line": 61, + "column": 25 + }, + "end": { + "line": 62, + "column": 26 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3845, + "end": 3848, + "loc": { + "start": { + "line": 61, + "column": 25 + }, + "end": { + "line": 61, + "column": 28 + }, + "identifierName": "log" + }, + "name": "log" + }, + "value": { + "type": "AssignmentPattern", + "start": 3845, + "end": 3894, + "loc": { + "start": { + "line": 61, + "column": 25 + }, + "end": { + "line": 62, + "column": 26 + } + }, + "left": { + "type": "Identifier", + "start": 3845, + "end": 3848, + "loc": { + "start": { + "line": 61, + "column": 25 + }, + "end": { + "line": 61, + "column": 28 + }, + "identifierName": "log" + }, + "name": "log" + }, + "right": { + "type": "FunctionExpression", + "start": 3851, + "end": 3894, + "loc": { + "start": { + "line": 61, + "column": 31 + }, + "end": { + "line": 62, + "column": 26 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 3861, + "end": 3864, + "loc": { + "start": { + "line": 61, + "column": 41 + }, + "end": { + "line": 61, + "column": 44 + }, + "identifierName": "msg" + }, + "name": "msg" + } + ], + "body": { + "type": "BlockStatement", + "start": 3866, + "end": 3894, + "loc": { + "start": { + "line": 61, + "column": 46 + }, + "end": { + "line": 62, + "column": 26 + } + }, + "body": [], + "directives": [] + } + } + }, + "extra": { + "shorthand": true + } + } + ] + } + ], + "body": { + "type": "BlockStatement", + "start": 3919, + "end": 7493, + "loc": { + "start": { + "line": 63, + "column": 24 + }, + "end": { + "line": 187, + "column": 1 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 3926, + "end": 3951, + "loc": { + "start": { + "line": 65, + "column": 4 + }, + "end": { + "line": 65, + "column": 29 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 3926, + "end": 3950, + "loc": { + "start": { + "line": 65, + "column": 4 + }, + "end": { + "line": 65, + "column": 28 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 3926, + "end": 3945, + "loc": { + "start": { + "line": 65, + "column": 4 + }, + "end": { + "line": 65, + "column": 23 + } + }, + "object": { + "type": "Identifier", + "start": 3926, + "end": 3931, + "loc": { + "start": { + "line": 65, + "column": 4 + }, + "end": { + "line": 65, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 3932, + "end": 3945, + "loc": { + "start": { + "line": 65, + "column": 10 + }, + "end": { + "line": 65, + "column": 23 + }, + "identifierName": "schemaVersion" + }, + "name": "schemaVersion" + }, + "computed": false + }, + "right": { + "type": "StringLiteral", + "start": 3948, + "end": 3950, + "loc": { + "start": { + "line": 65, + "column": 26 + }, + "end": { + "line": 65, + "column": 28 + } + }, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + }, + { + "type": "ExpressionStatement", + "start": 3956, + "end": 3973, + "loc": { + "start": { + "line": 66, + "column": 4 + }, + "end": { + "line": 66, + "column": 21 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 3956, + "end": 3972, + "loc": { + "start": { + "line": 66, + "column": 4 + }, + "end": { + "line": 66, + "column": 20 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 3956, + "end": 3967, + "loc": { + "start": { + "line": 66, + "column": 4 + }, + "end": { + "line": 66, + "column": 15 + } + }, + "object": { + "type": "Identifier", + "start": 3956, + "end": 3961, + "loc": { + "start": { + "line": 66, + "column": 4 + }, + "end": { + "line": 66, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 3962, + "end": 3967, + "loc": { + "start": { + "line": 66, + "column": 10 + }, + "end": { + "line": 66, + "column": 15 + }, + "identifierName": "title" + }, + "name": "title" + }, + "computed": false + }, + "right": { + "type": "StringLiteral", + "start": 3970, + "end": 3972, + "loc": { + "start": { + "line": 66, + "column": 18 + }, + "end": { + "line": 66, + "column": 20 + } + }, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + }, + { + "type": "ExpressionStatement", + "start": 3978, + "end": 3996, + "loc": { + "start": { + "line": 67, + "column": 4 + }, + "end": { + "line": 67, + "column": 22 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 3978, + "end": 3995, + "loc": { + "start": { + "line": 67, + "column": 4 + }, + "end": { + "line": 67, + "column": 21 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 3978, + "end": 3990, + "loc": { + "start": { + "line": 67, + "column": 4 + }, + "end": { + "line": 67, + "column": 16 + } + }, + "object": { + "type": "Identifier", + "start": 3978, + "end": 3983, + "loc": { + "start": { + "line": 67, + "column": 4 + }, + "end": { + "line": 67, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 3984, + "end": 3990, + "loc": { + "start": { + "line": 67, + "column": 10 + }, + "end": { + "line": 67, + "column": 16 + }, + "identifierName": "author" + }, + "name": "author" + }, + "computed": false + }, + "right": { + "type": "StringLiteral", + "start": 3993, + "end": 3995, + "loc": { + "start": { + "line": 67, + "column": 19 + }, + "end": { + "line": 67, + "column": 21 + } + }, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + }, + { + "type": "ExpressionStatement", + "start": 4001, + "end": 4020, + "loc": { + "start": { + "line": 68, + "column": 4 + }, + "end": { + "line": 68, + "column": 23 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4001, + "end": 4019, + "loc": { + "start": { + "line": 68, + "column": 4 + }, + "end": { + "line": 68, + "column": 22 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4001, + "end": 4014, + "loc": { + "start": { + "line": 68, + "column": 4 + }, + "end": { + "line": 68, + "column": 17 + } + }, + "object": { + "type": "Identifier", + "start": 4001, + "end": 4006, + "loc": { + "start": { + "line": 68, + "column": 4 + }, + "end": { + "line": 68, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4007, + "end": 4014, + "loc": { + "start": { + "line": 68, + "column": 10 + }, + "end": { + "line": 68, + "column": 17 + }, + "identifierName": "created" + }, + "name": "created" + }, + "computed": false + }, + "right": { + "type": "StringLiteral", + "start": 4017, + "end": 4019, + "loc": { + "start": { + "line": 68, + "column": 20 + }, + "end": { + "line": 68, + "column": 22 + } + }, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + }, + { + "type": "ExpressionStatement", + "start": 4025, + "end": 4050, + "loc": { + "start": { + "line": 69, + "column": 4 + }, + "end": { + "line": 69, + "column": 29 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4025, + "end": 4049, + "loc": { + "start": { + "line": 69, + "column": 4 + }, + "end": { + "line": 69, + "column": 28 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4025, + "end": 4045, + "loc": { + "start": { + "line": 69, + "column": 4 + }, + "end": { + "line": 69, + "column": 24 + } + }, + "object": { + "type": "Identifier", + "start": 4025, + "end": 4030, + "loc": { + "start": { + "line": 69, + "column": 4 + }, + "end": { + "line": 69, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4031, + "end": 4045, + "loc": { + "start": { + "line": 69, + "column": 10 + }, + "end": { + "line": 69, + "column": 24 + }, + "identifierName": "numMetaObjects" + }, + "name": "numMetaObjects" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4048, + "end": 4049, + "loc": { + "start": { + "line": 69, + "column": 27 + }, + "end": { + "line": 69, + "column": 28 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4055, + "end": 4081, + "loc": { + "start": { + "line": 70, + "column": 4 + }, + "end": { + "line": 70, + "column": 30 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4055, + "end": 4080, + "loc": { + "start": { + "line": 70, + "column": 4 + }, + "end": { + "line": 70, + "column": 29 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4055, + "end": 4076, + "loc": { + "start": { + "line": 70, + "column": 4 + }, + "end": { + "line": 70, + "column": 25 + } + }, + "object": { + "type": "Identifier", + "start": 4055, + "end": 4060, + "loc": { + "start": { + "line": 70, + "column": 4 + }, + "end": { + "line": 70, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4061, + "end": 4076, + "loc": { + "start": { + "line": 70, + "column": 10 + }, + "end": { + "line": 70, + "column": 25 + }, + "identifierName": "numPropertySets" + }, + "name": "numPropertySets" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4079, + "end": 4080, + "loc": { + "start": { + "line": 70, + "column": 28 + }, + "end": { + "line": 70, + "column": 29 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4086, + "end": 4109, + "loc": { + "start": { + "line": 71, + "column": 4 + }, + "end": { + "line": 71, + "column": 27 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4086, + "end": 4108, + "loc": { + "start": { + "line": 71, + "column": 4 + }, + "end": { + "line": 71, + "column": 26 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4086, + "end": 4104, + "loc": { + "start": { + "line": 71, + "column": 4 + }, + "end": { + "line": 71, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 4086, + "end": 4091, + "loc": { + "start": { + "line": 71, + "column": 4 + }, + "end": { + "line": 71, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4092, + "end": 4104, + "loc": { + "start": { + "line": 71, + "column": 10 + }, + "end": { + "line": 71, + "column": 22 + }, + "identifierName": "numTriangles" + }, + "name": "numTriangles" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4107, + "end": 4108, + "loc": { + "start": { + "line": 71, + "column": 25 + }, + "end": { + "line": 71, + "column": 26 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4114, + "end": 4136, + "loc": { + "start": { + "line": 72, + "column": 4 + }, + "end": { + "line": 72, + "column": 26 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4114, + "end": 4135, + "loc": { + "start": { + "line": 72, + "column": 4 + }, + "end": { + "line": 72, + "column": 25 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4114, + "end": 4131, + "loc": { + "start": { + "line": 72, + "column": 4 + }, + "end": { + "line": 72, + "column": 21 + } + }, + "object": { + "type": "Identifier", + "start": 4114, + "end": 4119, + "loc": { + "start": { + "line": 72, + "column": 4 + }, + "end": { + "line": 72, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4120, + "end": 4131, + "loc": { + "start": { + "line": 72, + "column": 10 + }, + "end": { + "line": 72, + "column": 21 + }, + "identifierName": "numVertices" + }, + "name": "numVertices" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4134, + "end": 4135, + "loc": { + "start": { + "line": 72, + "column": 24 + }, + "end": { + "line": 72, + "column": 25 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4141, + "end": 4162, + "loc": { + "start": { + "line": 73, + "column": 4 + }, + "end": { + "line": 73, + "column": 25 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4141, + "end": 4161, + "loc": { + "start": { + "line": 73, + "column": 4 + }, + "end": { + "line": 73, + "column": 24 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4141, + "end": 4157, + "loc": { + "start": { + "line": 73, + "column": 4 + }, + "end": { + "line": 73, + "column": 20 + } + }, + "object": { + "type": "Identifier", + "start": 4141, + "end": 4146, + "loc": { + "start": { + "line": 73, + "column": 4 + }, + "end": { + "line": 73, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4147, + "end": 4157, + "loc": { + "start": { + "line": 73, + "column": 10 + }, + "end": { + "line": 73, + "column": 20 + }, + "identifierName": "numNormals" + }, + "name": "numNormals" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4160, + "end": 4161, + "loc": { + "start": { + "line": 73, + "column": 23 + }, + "end": { + "line": 73, + "column": 24 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4167, + "end": 4184, + "loc": { + "start": { + "line": 74, + "column": 4 + }, + "end": { + "line": 74, + "column": 21 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4167, + "end": 4183, + "loc": { + "start": { + "line": 74, + "column": 4 + }, + "end": { + "line": 74, + "column": 20 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4167, + "end": 4179, + "loc": { + "start": { + "line": 74, + "column": 4 + }, + "end": { + "line": 74, + "column": 16 + } + }, + "object": { + "type": "Identifier", + "start": 4167, + "end": 4172, + "loc": { + "start": { + "line": 74, + "column": 4 + }, + "end": { + "line": 74, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4173, + "end": 4179, + "loc": { + "start": { + "line": 74, + "column": 10 + }, + "end": { + "line": 74, + "column": 16 + }, + "identifierName": "numUVs" + }, + "name": "numUVs" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4182, + "end": 4183, + "loc": { + "start": { + "line": 74, + "column": 19 + }, + "end": { + "line": 74, + "column": 20 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4189, + "end": 4211, + "loc": { + "start": { + "line": 75, + "column": 4 + }, + "end": { + "line": 75, + "column": 26 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4189, + "end": 4210, + "loc": { + "start": { + "line": 75, + "column": 4 + }, + "end": { + "line": 75, + "column": 25 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4189, + "end": 4206, + "loc": { + "start": { + "line": 75, + "column": 4 + }, + "end": { + "line": 75, + "column": 21 + } + }, + "object": { + "type": "Identifier", + "start": 4189, + "end": 4194, + "loc": { + "start": { + "line": 75, + "column": 4 + }, + "end": { + "line": 75, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4195, + "end": 4206, + "loc": { + "start": { + "line": 75, + "column": 10 + }, + "end": { + "line": 75, + "column": 21 + }, + "identifierName": "numTextures" + }, + "name": "numTextures" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4209, + "end": 4210, + "loc": { + "start": { + "line": 75, + "column": 24 + }, + "end": { + "line": 75, + "column": 25 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4216, + "end": 4241, + "loc": { + "start": { + "line": 76, + "column": 4 + }, + "end": { + "line": 76, + "column": 29 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4216, + "end": 4240, + "loc": { + "start": { + "line": 76, + "column": 4 + }, + "end": { + "line": 76, + "column": 28 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4216, + "end": 4236, + "loc": { + "start": { + "line": 76, + "column": 4 + }, + "end": { + "line": 76, + "column": 24 + } + }, + "object": { + "type": "Identifier", + "start": 4216, + "end": 4221, + "loc": { + "start": { + "line": 76, + "column": 4 + }, + "end": { + "line": 76, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4222, + "end": 4236, + "loc": { + "start": { + "line": 76, + "column": 10 + }, + "end": { + "line": 76, + "column": 24 + }, + "identifierName": "numTextureSets" + }, + "name": "numTextureSets" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4239, + "end": 4240, + "loc": { + "start": { + "line": 76, + "column": 27 + }, + "end": { + "line": 76, + "column": 28 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4246, + "end": 4267, + "loc": { + "start": { + "line": 77, + "column": 4 + }, + "end": { + "line": 77, + "column": 25 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4246, + "end": 4266, + "loc": { + "start": { + "line": 77, + "column": 4 + }, + "end": { + "line": 77, + "column": 24 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4246, + "end": 4262, + "loc": { + "start": { + "line": 77, + "column": 4 + }, + "end": { + "line": 77, + "column": 20 + } + }, + "object": { + "type": "Identifier", + "start": 4246, + "end": 4251, + "loc": { + "start": { + "line": 77, + "column": 4 + }, + "end": { + "line": 77, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4252, + "end": 4262, + "loc": { + "start": { + "line": 77, + "column": 10 + }, + "end": { + "line": 77, + "column": 20 + }, + "identifierName": "numObjects" + }, + "name": "numObjects" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4265, + "end": 4266, + "loc": { + "start": { + "line": 77, + "column": 23 + }, + "end": { + "line": 77, + "column": 24 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4272, + "end": 4296, + "loc": { + "start": { + "line": 78, + "column": 4 + }, + "end": { + "line": 78, + "column": 28 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4272, + "end": 4295, + "loc": { + "start": { + "line": 78, + "column": 4 + }, + "end": { + "line": 78, + "column": 27 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4272, + "end": 4291, + "loc": { + "start": { + "line": 78, + "column": 4 + }, + "end": { + "line": 78, + "column": 23 + } + }, + "object": { + "type": "Identifier", + "start": 4272, + "end": 4277, + "loc": { + "start": { + "line": 78, + "column": 4 + }, + "end": { + "line": 78, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4278, + "end": 4291, + "loc": { + "start": { + "line": 78, + "column": 10 + }, + "end": { + "line": 78, + "column": 23 + }, + "identifierName": "numGeometries" + }, + "name": "numGeometries" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4294, + "end": 4295, + "loc": { + "start": { + "line": 78, + "column": 26 + }, + "end": { + "line": 78, + "column": 27 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4301, + "end": 4322, + "loc": { + "start": { + "line": 79, + "column": 4 + }, + "end": { + "line": 79, + "column": 25 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4301, + "end": 4321, + "loc": { + "start": { + "line": 79, + "column": 4 + }, + "end": { + "line": 79, + "column": 24 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4301, + "end": 4317, + "loc": { + "start": { + "line": 79, + "column": 4 + }, + "end": { + "line": 79, + "column": 20 + } + }, + "object": { + "type": "Identifier", + "start": 4301, + "end": 4306, + "loc": { + "start": { + "line": 79, + "column": 4 + }, + "end": { + "line": 79, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4307, + "end": 4317, + "loc": { + "start": { + "line": 79, + "column": 10 + }, + "end": { + "line": 79, + "column": 20 + }, + "identifierName": "sourceSize" + }, + "name": "sourceSize" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4320, + "end": 4321, + "loc": { + "start": { + "line": 79, + "column": 23 + }, + "end": { + "line": 79, + "column": 24 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4327, + "end": 4345, + "loc": { + "start": { + "line": 80, + "column": 4 + }, + "end": { + "line": 80, + "column": 22 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4327, + "end": 4344, + "loc": { + "start": { + "line": 80, + "column": 4 + }, + "end": { + "line": 80, + "column": 21 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4327, + "end": 4340, + "loc": { + "start": { + "line": 80, + "column": 4 + }, + "end": { + "line": 80, + "column": 17 + } + }, + "object": { + "type": "Identifier", + "start": 4327, + "end": 4332, + "loc": { + "start": { + "line": 80, + "column": 4 + }, + "end": { + "line": 80, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4333, + "end": 4340, + "loc": { + "start": { + "line": 80, + "column": 10 + }, + "end": { + "line": 80, + "column": 17 + }, + "identifierName": "xktSize" + }, + "name": "xktSize" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4343, + "end": 4344, + "loc": { + "start": { + "line": 80, + "column": 20 + }, + "end": { + "line": 80, + "column": 21 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4350, + "end": 4373, + "loc": { + "start": { + "line": 81, + "column": 4 + }, + "end": { + "line": 81, + "column": 27 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4350, + "end": 4372, + "loc": { + "start": { + "line": 81, + "column": 4 + }, + "end": { + "line": 81, + "column": 26 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4350, + "end": 4368, + "loc": { + "start": { + "line": 81, + "column": 4 + }, + "end": { + "line": 81, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 4350, + "end": 4355, + "loc": { + "start": { + "line": 81, + "column": 4 + }, + "end": { + "line": 81, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4356, + "end": 4368, + "loc": { + "start": { + "line": 81, + "column": 10 + }, + "end": { + "line": 81, + "column": 22 + }, + "identifierName": "texturesSize" + }, + "name": "texturesSize" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4371, + "end": 4372, + "loc": { + "start": { + "line": 81, + "column": 25 + }, + "end": { + "line": 81, + "column": 26 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4378, + "end": 4400, + "loc": { + "start": { + "line": 82, + "column": 4 + }, + "end": { + "line": 82, + "column": 26 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4378, + "end": 4399, + "loc": { + "start": { + "line": 82, + "column": 4 + }, + "end": { + "line": 82, + "column": 25 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4378, + "end": 4394, + "loc": { + "start": { + "line": 82, + "column": 4 + }, + "end": { + "line": 82, + "column": 20 + } + }, + "object": { + "type": "Identifier", + "start": 4378, + "end": 4383, + "loc": { + "start": { + "line": 82, + "column": 4 + }, + "end": { + "line": 82, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4384, + "end": 4394, + "loc": { + "start": { + "line": 82, + "column": 10 + }, + "end": { + "line": 82, + "column": 20 + }, + "identifierName": "xktVersion" + }, + "name": "xktVersion" + }, + "computed": false + }, + "right": { + "type": "StringLiteral", + "start": 4397, + "end": 4399, + "loc": { + "start": { + "line": 82, + "column": 23 + }, + "end": { + "line": 82, + "column": 25 + } + }, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + }, + { + "type": "ExpressionStatement", + "start": 4405, + "end": 4432, + "loc": { + "start": { + "line": 83, + "column": 4 + }, + "end": { + "line": 83, + "column": 31 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4405, + "end": 4431, + "loc": { + "start": { + "line": 83, + "column": 4 + }, + "end": { + "line": 83, + "column": 30 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4405, + "end": 4427, + "loc": { + "start": { + "line": 83, + "column": 4 + }, + "end": { + "line": 83, + "column": 26 + } + }, + "object": { + "type": "Identifier", + "start": 4405, + "end": 4410, + "loc": { + "start": { + "line": 83, + "column": 4 + }, + "end": { + "line": 83, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4411, + "end": 4427, + "loc": { + "start": { + "line": 83, + "column": 10 + }, + "end": { + "line": 83, + "column": 26 + }, + "identifierName": "compressionRatio" + }, + "name": "compressionRatio" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4430, + "end": 4431, + "loc": { + "start": { + "line": 83, + "column": 29 + }, + "end": { + "line": 83, + "column": 30 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4437, + "end": 4462, + "loc": { + "start": { + "line": 84, + "column": 4 + }, + "end": { + "line": 84, + "column": 29 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4437, + "end": 4461, + "loc": { + "start": { + "line": 84, + "column": 4 + }, + "end": { + "line": 84, + "column": 28 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4437, + "end": 4457, + "loc": { + "start": { + "line": 84, + "column": 4 + }, + "end": { + "line": 84, + "column": 24 + } + }, + "object": { + "type": "Identifier", + "start": 4437, + "end": 4442, + "loc": { + "start": { + "line": 84, + "column": 4 + }, + "end": { + "line": 84, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4443, + "end": 4457, + "loc": { + "start": { + "line": 84, + "column": 10 + }, + "end": { + "line": 84, + "column": 24 + }, + "identifierName": "conversionTime" + }, + "name": "conversionTime" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4460, + "end": 4461, + "loc": { + "start": { + "line": 84, + "column": 27 + }, + "end": { + "line": 84, + "column": 28 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4467, + "end": 4485, + "loc": { + "start": { + "line": 85, + "column": 4 + }, + "end": { + "line": 85, + "column": 22 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4467, + "end": 4484, + "loc": { + "start": { + "line": 85, + "column": 4 + }, + "end": { + "line": 85, + "column": 21 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4467, + "end": 4477, + "loc": { + "start": { + "line": 85, + "column": 4 + }, + "end": { + "line": 85, + "column": 14 + } + }, + "object": { + "type": "Identifier", + "start": 4467, + "end": 4472, + "loc": { + "start": { + "line": 85, + "column": 4 + }, + "end": { + "line": 85, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4473, + "end": 4477, + "loc": { + "start": { + "line": 85, + "column": 10 + }, + "end": { + "line": 85, + "column": 14 + }, + "identifierName": "aabb" + }, + "name": "aabb" + }, + "computed": false + }, + "right": { + "type": "NullLiteral", + "start": 4480, + "end": 4484, + "loc": { + "start": { + "line": 85, + "column": 17 + }, + "end": { + "line": 85, + "column": 21 + } + } + } + } + }, + { + "type": "ReturnStatement", + "start": 4491, + "end": 7491, + "loc": { + "start": { + "line": 87, + "column": 4 + }, + "end": { + "line": 186, + "column": 7 + } + }, + "argument": { + "type": "NewExpression", + "start": 4498, + "end": 7490, + "loc": { + "start": { + "line": 87, + "column": 11 + }, + "end": { + "line": 186, + "column": 6 + } + }, + "callee": { + "type": "Identifier", + "start": 4502, + "end": 4509, + "loc": { + "start": { + "line": 87, + "column": 15 + }, + "end": { + "line": 87, + "column": 22 + }, + "identifierName": "Promise" + }, + "name": "Promise" + }, + "arguments": [ + { + "type": "FunctionExpression", + "start": 4510, + "end": 7489, + "loc": { + "start": { + "line": 87, + "column": 23 + }, + "end": { + "line": 186, + "column": 5 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 4520, + "end": 4527, + "loc": { + "start": { + "line": 87, + "column": 33 + }, + "end": { + "line": 87, + "column": 40 + }, + "identifierName": "resolve" + }, + "name": "resolve" + }, + { + "type": "Identifier", + "start": 4529, + "end": 4535, + "loc": { + "start": { + "line": 87, + "column": 42 + }, + "end": { + "line": 87, + "column": 48 + }, + "identifierName": "reject" + }, + "name": "reject" + } + ], + "body": { + "type": "BlockStatement", + "start": 4537, + "end": 7489, + "loc": { + "start": { + "line": 87, + "column": 50 + }, + "end": { + "line": 186, + "column": 5 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 4547, + "end": 4564, + "loc": { + "start": { + "line": 88, + "column": 8 + }, + "end": { + "line": 88, + "column": 25 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 4553, + "end": 4563, + "loc": { + "start": { + "line": 88, + "column": 14 + }, + "end": { + "line": 88, + "column": 24 + } + }, + "id": { + "type": "Identifier", + "start": 4553, + "end": 4557, + "loc": { + "start": { + "line": 88, + "column": 14 + }, + "end": { + "line": 88, + "column": 18 + }, + "identifierName": "_log" + }, + "name": "_log" + }, + "init": { + "type": "Identifier", + "start": 4560, + "end": 4563, + "loc": { + "start": { + "line": 88, + "column": 21 + }, + "end": { + "line": 88, + "column": 24 + }, + "identifierName": "log" + }, + "name": "log" + } + } + ], + "kind": "const" + }, + { + "type": "ExpressionStatement", + "start": 4573, + "end": 4640, + "loc": { + "start": { + "line": 89, + "column": 8 + }, + "end": { + "line": 91, + "column": 9 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4573, + "end": 4640, + "loc": { + "start": { + "line": 89, + "column": 8 + }, + "end": { + "line": 91, + "column": 9 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 4573, + "end": 4576, + "loc": { + "start": { + "line": 89, + "column": 8 + }, + "end": { + "line": 89, + "column": 11 + }, + "identifierName": "log" + }, + "name": "log" + }, + "right": { + "type": "ArrowFunctionExpression", + "start": 4579, + "end": 4640, + "loc": { + "start": { + "line": 89, + "column": 14 + }, + "end": { + "line": 91, + "column": 9 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 4580, + "end": 4583, + "loc": { + "start": { + "line": 89, + "column": 15 + }, + "end": { + "line": 89, + "column": 18 + }, + "identifierName": "msg" + }, + "name": "msg" + } + ], + "body": { + "type": "BlockStatement", + "start": 4588, + "end": 4640, + "loc": { + "start": { + "line": 89, + "column": 23 + }, + "end": { + "line": 91, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 4602, + "end": 4630, + "loc": { + "start": { + "line": 90, + "column": 12 + }, + "end": { + "line": 90, + "column": 40 + } + }, + "expression": { + "type": "CallExpression", + "start": 4602, + "end": 4630, + "loc": { + "start": { + "line": 90, + "column": 12 + }, + "end": { + "line": 90, + "column": 40 + } + }, + "callee": { + "type": "Identifier", + "start": 4602, + "end": 4606, + "loc": { + "start": { + "line": 90, + "column": 12 + }, + "end": { + "line": 90, + "column": 16 + }, + "identifierName": "_log" + }, + "name": "_log" + }, + "arguments": [ + { + "type": "TemplateLiteral", + "start": 4607, + "end": 4629, + "loc": { + "start": { + "line": 90, + "column": 17 + }, + "end": { + "line": 90, + "column": 39 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 4624, + "end": 4627, + "loc": { + "start": { + "line": 90, + "column": 34 + }, + "end": { + "line": 90, + "column": 37 + }, + "identifierName": "msg" + }, + "name": "msg" + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 4608, + "end": 4622, + "loc": { + "start": { + "line": 90, + "column": 18 + }, + "end": { + "line": 90, + "column": 32 + } + }, + "value": { + "raw": "[convert2xkt] ", + "cooked": "[convert2xkt] " + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 4628, + "end": 4628, + "loc": { + "start": { + "line": 90, + "column": 38 + }, + "end": { + "line": 90, + "column": 38 + } + }, + "value": { + "raw": "", + "cooked": "" + }, + "tail": true + } + ] + } + ] + } + } + ], + "directives": [] + } + } + } + }, + { + "type": "IfStatement", + "start": 4650, + "end": 4761, + "loc": { + "start": { + "line": 93, + "column": 8 + }, + "end": { + "line": 96, + "column": 9 + } + }, + "test": { + "type": "UnaryExpression", + "start": 4654, + "end": 4665, + "loc": { + "start": { + "line": 93, + "column": 12 + }, + "end": { + "line": 93, + "column": 23 + } + }, + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 4655, + "end": 4665, + "loc": { + "start": { + "line": 93, + "column": 13 + }, + "end": { + "line": 93, + "column": 23 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + }, + "extra": { + "parenthesizedArgument": false + } + }, + "consequent": { + "type": "BlockStatement", + "start": 4667, + "end": 4761, + "loc": { + "start": { + "line": 93, + "column": 25 + }, + "end": { + "line": 96, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 4681, + "end": 4731, + "loc": { + "start": { + "line": 94, + "column": 12 + }, + "end": { + "line": 94, + "column": 62 + } + }, + "expression": { + "type": "CallExpression", + "start": 4681, + "end": 4730, + "loc": { + "start": { + "line": 94, + "column": 12 + }, + "end": { + "line": 94, + "column": 61 + } + }, + "callee": { + "type": "Identifier", + "start": 4681, + "end": 4687, + "loc": { + "start": { + "line": 94, + "column": 12 + }, + "end": { + "line": 94, + "column": 18 + }, + "identifierName": "reject" + }, + "name": "reject" + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 4688, + "end": 4729, + "loc": { + "start": { + "line": 94, + "column": 19 + }, + "end": { + "line": 94, + "column": 60 + } + }, + "extra": { + "rawValue": "Argument expected: source or sourceData", + "raw": "\"Argument expected: source or sourceData\"" + }, + "value": "Argument expected: source or sourceData" + } + ] + } + }, + { + "type": "ReturnStatement", + "start": 4744, + "end": 4751, + "loc": { + "start": { + "line": 95, + "column": 12 + }, + "end": { + "line": 95, + "column": 19 + } + }, + "argument": null + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "IfStatement", + "start": 4771, + "end": 4915, + "loc": { + "start": { + "line": 98, + "column": 8 + }, + "end": { + "line": 101, + "column": 9 + } + }, + "test": { + "type": "LogicalExpression", + "start": 4775, + "end": 4804, + "loc": { + "start": { + "line": 98, + "column": 12 + }, + "end": { + "line": 98, + "column": 41 + } + }, + "left": { + "type": "UnaryExpression", + "start": 4775, + "end": 4790, + "loc": { + "start": { + "line": 98, + "column": 12 + }, + "end": { + "line": 98, + "column": 27 + } + }, + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 4776, + "end": 4790, + "loc": { + "start": { + "line": 98, + "column": 13 + }, + "end": { + "line": 98, + "column": 27 + }, + "identifierName": "outputXKTModel" + }, + "name": "outputXKTModel" + }, + "extra": { + "parenthesizedArgument": false + } + }, + "operator": "&&", + "right": { + "type": "UnaryExpression", + "start": 4794, + "end": 4804, + "loc": { + "start": { + "line": 98, + "column": 31 + }, + "end": { + "line": 98, + "column": 41 + } + }, + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 4795, + "end": 4804, + "loc": { + "start": { + "line": 98, + "column": 32 + }, + "end": { + "line": 98, + "column": 41 + }, + "identifierName": "outputXKT" + }, + "name": "outputXKT" + }, + "extra": { + "parenthesizedArgument": false + } + } + }, + "consequent": { + "type": "BlockStatement", + "start": 4806, + "end": 4915, + "loc": { + "start": { + "line": 98, + "column": 43 + }, + "end": { + "line": 101, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 4820, + "end": 4885, + "loc": { + "start": { + "line": 99, + "column": 12 + }, + "end": { + "line": 99, + "column": 77 + } + }, + "expression": { + "type": "CallExpression", + "start": 4820, + "end": 4884, + "loc": { + "start": { + "line": 99, + "column": 12 + }, + "end": { + "line": 99, + "column": 76 + } + }, + "callee": { + "type": "Identifier", + "start": 4820, + "end": 4826, + "loc": { + "start": { + "line": 99, + "column": 12 + }, + "end": { + "line": 99, + "column": 18 + }, + "identifierName": "reject" + }, + "name": "reject" + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 4827, + "end": 4883, + "loc": { + "start": { + "line": 99, + "column": 19 + }, + "end": { + "line": 99, + "column": 75 + } + }, + "extra": { + "rawValue": "Argument expected: output, outputXKTModel or outputXKT", + "raw": "\"Argument expected: output, outputXKTModel or outputXKT\"" + }, + "value": "Argument expected: output, outputXKTModel or outputXKT" + } + ] + } + }, + { + "type": "ReturnStatement", + "start": 4898, + "end": 4905, + "loc": { + "start": { + "line": 100, + "column": 12 + }, + "end": { + "line": 100, + "column": 19 + } + }, + "argument": null + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "VariableDeclaration", + "start": 4925, + "end": 4975, + "loc": { + "start": { + "line": 103, + "column": 8 + }, + "end": { + "line": 103, + "column": 58 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 4931, + "end": 4974, + "loc": { + "start": { + "line": 103, + "column": 14 + }, + "end": { + "line": 103, + "column": 57 + } + }, + "id": { + "type": "Identifier", + "start": 4931, + "end": 4944, + "loc": { + "start": { + "line": 103, + "column": 14 + }, + "end": { + "line": 103, + "column": 27 + }, + "identifierName": "sourceConfigs" + }, + "name": "sourceConfigs" + }, + "init": { + "type": "LogicalExpression", + "start": 4947, + "end": 4974, + "loc": { + "start": { + "line": 103, + "column": 30 + }, + "end": { + "line": 103, + "column": 57 + } + }, + "left": { + "type": "MemberExpression", + "start": 4947, + "end": 4968, + "loc": { + "start": { + "line": 103, + "column": 30 + }, + "end": { + "line": 103, + "column": 51 + } + }, + "object": { + "type": "Identifier", + "start": 4947, + "end": 4954, + "loc": { + "start": { + "line": 103, + "column": 30 + }, + "end": { + "line": 103, + "column": 37 + }, + "identifierName": "configs" + }, + "name": "configs" + }, + "property": { + "type": "Identifier", + "start": 4955, + "end": 4968, + "loc": { + "start": { + "line": 103, + "column": 38 + }, + "end": { + "line": 103, + "column": 51 + }, + "identifierName": "sourceConfigs" + }, + "name": "sourceConfigs" + }, + "computed": false + }, + "operator": "||", + "right": { + "type": "ObjectExpression", + "start": 4972, + "end": 4974, + "loc": { + "start": { + "line": 103, + "column": 55 + }, + "end": { + "line": 103, + "column": 57 + } + }, + "properties": [] + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 4984, + "end": 5002, + "loc": { + "start": { + "line": 104, + "column": 8 + }, + "end": { + "line": 104, + "column": 26 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 4990, + "end": 5001, + "loc": { + "start": { + "line": 104, + "column": 14 + }, + "end": { + "line": 104, + "column": 25 + } + }, + "id": { + "type": "Identifier", + "start": 4990, + "end": 4993, + "loc": { + "start": { + "line": 104, + "column": 14 + }, + "end": { + "line": 104, + "column": 17 + }, + "identifierName": "ext" + }, + "name": "ext" + }, + "init": { + "type": "StringLiteral", + "start": 4996, + "end": 5001, + "loc": { + "start": { + "line": 104, + "column": 20 + }, + "end": { + "line": 104, + "column": 25 + } + }, + "extra": { + "rawValue": "glb", + "raw": "'glb'" + }, + "value": "glb" + } + } + ], + "kind": "const" + }, + { + "type": "ExpressionStatement", + "start": 5012, + "end": 5050, + "loc": { + "start": { + "line": 106, + "column": 8 + }, + "end": { + "line": 106, + "column": 46 + } + }, + "expression": { + "type": "CallExpression", + "start": 5012, + "end": 5049, + "loc": { + "start": { + "line": 106, + "column": 8 + }, + "end": { + "line": 106, + "column": 45 + } + }, + "callee": { + "type": "Identifier", + "start": 5012, + "end": 5015, + "loc": { + "start": { + "line": 106, + "column": 8 + }, + "end": { + "line": 106, + "column": 11 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "TemplateLiteral", + "start": 5016, + "end": 5048, + "loc": { + "start": { + "line": 106, + "column": 12 + }, + "end": { + "line": 106, + "column": 44 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 5042, + "end": 5045, + "loc": { + "start": { + "line": 106, + "column": 38 + }, + "end": { + "line": 106, + "column": 41 + }, + "identifierName": "ext" + }, + "name": "ext" + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 5017, + "end": 5040, + "loc": { + "start": { + "line": 106, + "column": 13 + }, + "end": { + "line": 106, + "column": 36 + } + }, + "value": { + "raw": "Input file extension: \"", + "cooked": "Input file extension: \"" + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 5046, + "end": 5047, + "loc": { + "start": { + "line": 106, + "column": 42 + }, + "end": { + "line": 106, + "column": 43 + } + }, + "value": { + "raw": "\"", + "cooked": "\"" + }, + "tail": true + } + ] + } + ] + } + }, + { + "type": "VariableDeclaration", + "start": 5060, + "end": 5101, + "loc": { + "start": { + "line": 108, + "column": 8 + }, + "end": { + "line": 108, + "column": 49 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 5064, + "end": 5100, + "loc": { + "start": { + "line": 108, + "column": 12 + }, + "end": { + "line": 108, + "column": 48 + } + }, + "id": { + "type": "Identifier", + "start": 5064, + "end": 5079, + "loc": { + "start": { + "line": 108, + "column": 12 + }, + "end": { + "line": 108, + "column": 27 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "init": { + "type": "MemberExpression", + "start": 5082, + "end": 5100, + "loc": { + "start": { + "line": 108, + "column": 30 + }, + "end": { + "line": 108, + "column": 48 + } + }, + "object": { + "type": "Identifier", + "start": 5082, + "end": 5095, + "loc": { + "start": { + "line": 108, + "column": 30 + }, + "end": { + "line": 108, + "column": 43 + }, + "identifierName": "sourceConfigs" + }, + "name": "sourceConfigs" + }, + "property": { + "type": "Identifier", + "start": 5096, + "end": 5099, + "loc": { + "start": { + "line": 108, + "column": 44 + }, + "end": { + "line": 108, + "column": 47 + }, + "identifierName": "ext" + }, + "name": "ext" + }, + "computed": true + } + } + ], + "kind": "let" + }, + { + "type": "IfStatement", + "start": 5111, + "end": 5367, + "loc": { + "start": { + "line": 110, + "column": 8 + }, + "end": { + "line": 113, + "column": 9 + } + }, + "test": { + "type": "UnaryExpression", + "start": 5115, + "end": 5131, + "loc": { + "start": { + "line": 110, + "column": 12 + }, + "end": { + "line": 110, + "column": 28 + } + }, + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 5116, + "end": 5131, + "loc": { + "start": { + "line": 110, + "column": 13 + }, + "end": { + "line": 110, + "column": 28 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "extra": { + "parenthesizedArgument": false + } + }, + "consequent": { + "type": "BlockStatement", + "start": 5133, + "end": 5367, + "loc": { + "start": { + "line": 110, + "column": 30 + }, + "end": { + "line": 113, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 5147, + "end": 5323, + "loc": { + "start": { + "line": 111, + "column": 12 + }, + "end": { + "line": 111, + "column": 188 + } + }, + "expression": { + "type": "CallExpression", + "start": 5147, + "end": 5322, + "loc": { + "start": { + "line": 111, + "column": 12 + }, + "end": { + "line": 111, + "column": 187 + } + }, + "callee": { + "type": "Identifier", + "start": 5147, + "end": 5150, + "loc": { + "start": { + "line": 111, + "column": 12 + }, + "end": { + "line": 111, + "column": 15 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "TemplateLiteral", + "start": 5151, + "end": 5321, + "loc": { + "start": { + "line": 111, + "column": 16 + }, + "end": { + "line": 111, + "column": 186 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 5226, + "end": 5229, + "loc": { + "start": { + "line": 111, + "column": 91 + }, + "end": { + "line": 111, + "column": 94 + }, + "identifierName": "ext" + }, + "name": "ext" + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 5152, + "end": 5224, + "loc": { + "start": { + "line": 111, + "column": 17 + }, + "end": { + "line": 111, + "column": 89 + } + }, + "value": { + "raw": "[WARNING] Could not find configs sourceConfigs entry for source format \"", + "cooked": "[WARNING] Could not find configs sourceConfigs entry for source format \"" + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 5230, + "end": 5320, + "loc": { + "start": { + "line": 111, + "column": 95 + }, + "end": { + "line": 111, + "column": 185 + } + }, + "value": { + "raw": "\". This is derived from the source file name extension. Will use internal default configs.", + "cooked": "\". This is derived from the source file name extension. Will use internal default configs." + }, + "tail": true + } + ] + } + ] + } + }, + { + "type": "ExpressionStatement", + "start": 5336, + "end": 5357, + "loc": { + "start": { + "line": 112, + "column": 12 + }, + "end": { + "line": 112, + "column": 33 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 5336, + "end": 5356, + "loc": { + "start": { + "line": 112, + "column": 12 + }, + "end": { + "line": 112, + "column": 32 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 5336, + "end": 5351, + "loc": { + "start": { + "line": 112, + "column": 12 + }, + "end": { + "line": 112, + "column": 27 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "right": { + "type": "ObjectExpression", + "start": 5354, + "end": 5356, + "loc": { + "start": { + "line": 112, + "column": 30 + }, + "end": { + "line": 112, + "column": 32 + } + }, + "properties": [] + } + } + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "FunctionDeclaration", + "start": 5377, + "end": 5545, + "loc": { + "start": { + "line": 115, + "column": 8 + }, + "end": { + "line": 120, + "column": 9 + } + }, + "id": { + "type": "Identifier", + "start": 5386, + "end": 5400, + "loc": { + "start": { + "line": 115, + "column": 17 + }, + "end": { + "line": 115, + "column": 31 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 5401, + "end": 5408, + "loc": { + "start": { + "line": 115, + "column": 32 + }, + "end": { + "line": 115, + "column": 39 + }, + "identifierName": "option1" + }, + "name": "option1" + }, + { + "type": "Identifier", + "start": 5410, + "end": 5417, + "loc": { + "start": { + "line": 115, + "column": 41 + }, + "end": { + "line": 115, + "column": 48 + }, + "identifierName": "option2" + }, + "name": "option2" + } + ], + "body": { + "type": "BlockStatement", + "start": 5419, + "end": 5545, + "loc": { + "start": { + "line": 115, + "column": 50 + }, + "end": { + "line": 120, + "column": 9 + } + }, + "body": [ + { + "type": "IfStatement", + "start": 5433, + "end": 5507, + "loc": { + "start": { + "line": 116, + "column": 12 + }, + "end": { + "line": 118, + "column": 13 + } + }, + "test": { + "type": "BinaryExpression", + "start": 5437, + "end": 5458, + "loc": { + "start": { + "line": 116, + "column": 16 + }, + "end": { + "line": 116, + "column": 37 + } + }, + "left": { + "type": "Identifier", + "start": 5437, + "end": 5444, + "loc": { + "start": { + "line": 116, + "column": 16 + }, + "end": { + "line": 116, + "column": 23 + }, + "identifierName": "option1" + }, + "name": "option1" + }, + "operator": "!==", + "right": { + "type": "Identifier", + "start": 5449, + "end": 5458, + "loc": { + "start": { + "line": 116, + "column": 28 + }, + "end": { + "line": 116, + "column": 37 + }, + "identifierName": "undefined" + }, + "name": "undefined" + } + }, + "consequent": { + "type": "BlockStatement", + "start": 5460, + "end": 5507, + "loc": { + "start": { + "line": 116, + "column": 39 + }, + "end": { + "line": 118, + "column": 13 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 5478, + "end": 5493, + "loc": { + "start": { + "line": 117, + "column": 16 + }, + "end": { + "line": 117, + "column": 31 + } + }, + "argument": { + "type": "Identifier", + "start": 5485, + "end": 5492, + "loc": { + "start": { + "line": 117, + "column": 23 + }, + "end": { + "line": 117, + "column": 30 + }, + "identifierName": "option1" + }, + "name": "option1" + } + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "ReturnStatement", + "start": 5520, + "end": 5535, + "loc": { + "start": { + "line": 119, + "column": 12 + }, + "end": { + "line": 119, + "column": 27 + } + }, + "argument": { + "type": "Identifier", + "start": 5527, + "end": 5534, + "loc": { + "start": { + "line": 119, + "column": 19 + }, + "end": { + "line": 119, + "column": 26 + }, + "identifierName": "option2" + }, + "name": "option2" + } + } + ], + "directives": [] + } + }, + { + "type": "VariableDeclaration", + "start": 5556, + "end": 5606, + "loc": { + "start": { + "line": 123, + "column": 8 + }, + "end": { + "line": 123, + "column": 58 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 5562, + "end": 5605, + "loc": { + "start": { + "line": 123, + "column": 14 + }, + "end": { + "line": 123, + "column": 57 + } + }, + "id": { + "type": "Identifier", + "start": 5562, + "end": 5581, + "loc": { + "start": { + "line": 123, + "column": 14 + }, + "end": { + "line": 123, + "column": 33 + }, + "identifierName": "sourceFileSizeBytes" + }, + "name": "sourceFileSizeBytes" + }, + "init": { + "type": "MemberExpression", + "start": 5584, + "end": 5605, + "loc": { + "start": { + "line": 123, + "column": 36 + }, + "end": { + "line": 123, + "column": 57 + } + }, + "object": { + "type": "Identifier", + "start": 5584, + "end": 5594, + "loc": { + "start": { + "line": 123, + "column": 36 + }, + "end": { + "line": 123, + "column": 46 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + }, + "property": { + "type": "Identifier", + "start": 5595, + "end": 5605, + "loc": { + "start": { + "line": 123, + "column": 47 + }, + "end": { + "line": 123, + "column": 57 + }, + "identifierName": "byteLength" + }, + "name": "byteLength" + }, + "computed": false + } + } + ], + "kind": "const" + }, + { + "type": "ExpressionStatement", + "start": 5616, + "end": 5691, + "loc": { + "start": { + "line": 125, + "column": 8 + }, + "end": { + "line": 125, + "column": 83 + } + }, + "expression": { + "type": "CallExpression", + "start": 5616, + "end": 5690, + "loc": { + "start": { + "line": 125, + "column": 8 + }, + "end": { + "line": 125, + "column": 82 + } + }, + "callee": { + "type": "Identifier", + "start": 5616, + "end": 5619, + "loc": { + "start": { + "line": 125, + "column": 8 + }, + "end": { + "line": 125, + "column": 11 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "BinaryExpression", + "start": 5620, + "end": 5689, + "loc": { + "start": { + "line": 125, + "column": 12 + }, + "end": { + "line": 125, + "column": 81 + } + }, + "left": { + "type": "BinaryExpression", + "start": 5620, + "end": 5681, + "loc": { + "start": { + "line": 125, + "column": 12 + }, + "end": { + "line": 125, + "column": 73 + } + }, + "left": { + "type": "StringLiteral", + "start": 5620, + "end": 5639, + "loc": { + "start": { + "line": 125, + "column": 12 + }, + "end": { + "line": 125, + "column": 31 + } + }, + "extra": { + "rawValue": "Input file size: ", + "raw": "\"Input file size: \"" + }, + "value": "Input file size: " + }, + "operator": "+", + "right": { + "type": "CallExpression", + "start": 5642, + "end": 5681, + "loc": { + "start": { + "line": 125, + "column": 34 + }, + "end": { + "line": 125, + "column": 73 + } + }, + "callee": { + "type": "MemberExpression", + "start": 5642, + "end": 5678, + "loc": { + "start": { + "line": 125, + "column": 34 + }, + "end": { + "line": 125, + "column": 70 + } + }, + "object": { + "type": "BinaryExpression", + "start": 5643, + "end": 5669, + "loc": { + "start": { + "line": 125, + "column": 35 + }, + "end": { + "line": 125, + "column": 61 + } + }, + "left": { + "type": "Identifier", + "start": 5643, + "end": 5662, + "loc": { + "start": { + "line": 125, + "column": 35 + }, + "end": { + "line": 125, + "column": 54 + }, + "identifierName": "sourceFileSizeBytes" + }, + "name": "sourceFileSizeBytes" + }, + "operator": "/", + "right": { + "type": "NumericLiteral", + "start": 5665, + "end": 5669, + "loc": { + "start": { + "line": 125, + "column": 57 + }, + "end": { + "line": 125, + "column": 61 + } + }, + "extra": { + "rawValue": 1000, + "raw": "1000" + }, + "value": 1000 + }, + "extra": { + "parenthesized": true, + "parenStart": 5642 + } + }, + "property": { + "type": "Identifier", + "start": 5671, + "end": 5678, + "loc": { + "start": { + "line": 125, + "column": 63 + }, + "end": { + "line": 125, + "column": 70 + }, + "identifierName": "toFixed" + }, + "name": "toFixed" + }, + "computed": false + }, + "arguments": [ + { + "type": "NumericLiteral", + "start": 5679, + "end": 5680, + "loc": { + "start": { + "line": 125, + "column": 71 + }, + "end": { + "line": 125, + "column": 72 + } + }, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + ] + } + }, + "operator": "+", + "right": { + "type": "StringLiteral", + "start": 5684, + "end": 5689, + "loc": { + "start": { + "line": 125, + "column": 76 + }, + "end": { + "line": 125, + "column": 81 + } + }, + "extra": { + "rawValue": " kB", + "raw": "\" kB\"" + }, + "value": " kB" + } + } + ] + } + }, + { + "type": "ExpressionStatement", + "start": 5703, + "end": 5774, + "loc": { + "start": { + "line": 129, + "column": 8 + }, + "end": { + "line": 129, + "column": 79 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 5703, + "end": 5773, + "loc": { + "start": { + "line": 129, + "column": 8 + }, + "end": { + "line": 129, + "column": 78 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 5703, + "end": 5714, + "loc": { + "start": { + "line": 129, + "column": 8 + }, + "end": { + "line": 129, + "column": 19 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "right": { + "type": "CallExpression", + "start": 5717, + "end": 5773, + "loc": { + "start": { + "line": 129, + "column": 22 + }, + "end": { + "line": 129, + "column": 78 + } + }, + "callee": { + "type": "Identifier", + "start": 5717, + "end": 5731, + "loc": { + "start": { + "line": 129, + "column": 22 + }, + "end": { + "line": 129, + "column": 36 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 5732, + "end": 5759, + "loc": { + "start": { + "line": 129, + "column": 37 + }, + "end": { + "line": 129, + "column": 64 + } + }, + "object": { + "type": "Identifier", + "start": 5732, + "end": 5747, + "loc": { + "start": { + "line": 129, + "column": 37 + }, + "end": { + "line": 129, + "column": 52 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 5748, + "end": 5759, + "loc": { + "start": { + "line": 129, + "column": 53 + }, + "end": { + "line": 129, + "column": 64 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 5761, + "end": 5772, + "loc": { + "start": { + "line": 129, + "column": 66 + }, + "end": { + "line": 129, + "column": 77 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 5783, + "end": 5842, + "loc": { + "start": { + "line": 130, + "column": 8 + }, + "end": { + "line": 130, + "column": 67 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 5783, + "end": 5841, + "loc": { + "start": { + "line": 130, + "column": 8 + }, + "end": { + "line": 130, + "column": 66 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 5783, + "end": 5790, + "loc": { + "start": { + "line": 130, + "column": 8 + }, + "end": { + "line": 130, + "column": 15 + }, + "identifierName": "rotateX" + }, + "name": "rotateX" + }, + "right": { + "type": "CallExpression", + "start": 5793, + "end": 5841, + "loc": { + "start": { + "line": 130, + "column": 18 + }, + "end": { + "line": 130, + "column": 66 + } + }, + "callee": { + "type": "Identifier", + "start": 5793, + "end": 5807, + "loc": { + "start": { + "line": 130, + "column": 18 + }, + "end": { + "line": 130, + "column": 32 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 5808, + "end": 5831, + "loc": { + "start": { + "line": 130, + "column": 33 + }, + "end": { + "line": 130, + "column": 56 + } + }, + "object": { + "type": "Identifier", + "start": 5808, + "end": 5823, + "loc": { + "start": { + "line": 130, + "column": 33 + }, + "end": { + "line": 130, + "column": 48 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 5824, + "end": 5831, + "loc": { + "start": { + "line": 130, + "column": 49 + }, + "end": { + "line": 130, + "column": 56 + }, + "identifierName": "rotateX" + }, + "name": "rotateX" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 5833, + "end": 5840, + "loc": { + "start": { + "line": 130, + "column": 58 + }, + "end": { + "line": 130, + "column": 65 + }, + "identifierName": "rotateX" + }, + "name": "rotateX" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 5851, + "end": 5934, + "loc": { + "start": { + "line": 131, + "column": 8 + }, + "end": { + "line": 131, + "column": 91 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 5851, + "end": 5933, + "loc": { + "start": { + "line": 131, + "column": 8 + }, + "end": { + "line": 131, + "column": 90 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 5851, + "end": 5866, + "loc": { + "start": { + "line": 131, + "column": 8 + }, + "end": { + "line": 131, + "column": 23 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "right": { + "type": "CallExpression", + "start": 5869, + "end": 5933, + "loc": { + "start": { + "line": 131, + "column": 26 + }, + "end": { + "line": 131, + "column": 90 + } + }, + "callee": { + "type": "Identifier", + "start": 5869, + "end": 5883, + "loc": { + "start": { + "line": 131, + "column": 26 + }, + "end": { + "line": 131, + "column": 40 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 5884, + "end": 5915, + "loc": { + "start": { + "line": 131, + "column": 41 + }, + "end": { + "line": 131, + "column": 72 + } + }, + "object": { + "type": "Identifier", + "start": 5884, + "end": 5899, + "loc": { + "start": { + "line": 131, + "column": 41 + }, + "end": { + "line": 131, + "column": 56 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 5900, + "end": 5915, + "loc": { + "start": { + "line": 131, + "column": 57 + }, + "end": { + "line": 131, + "column": 72 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 5917, + "end": 5932, + "loc": { + "start": { + "line": 131, + "column": 74 + }, + "end": { + "line": 131, + "column": 89 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 5943, + "end": 6026, + "loc": { + "start": { + "line": 132, + "column": 8 + }, + "end": { + "line": 132, + "column": 91 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 5943, + "end": 6025, + "loc": { + "start": { + "line": 132, + "column": 8 + }, + "end": { + "line": 132, + "column": 90 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 5943, + "end": 5958, + "loc": { + "start": { + "line": 132, + "column": 8 + }, + "end": { + "line": 132, + "column": 23 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + }, + "right": { + "type": "CallExpression", + "start": 5961, + "end": 6025, + "loc": { + "start": { + "line": 132, + "column": 26 + }, + "end": { + "line": 132, + "column": 90 + } + }, + "callee": { + "type": "Identifier", + "start": 5961, + "end": 5975, + "loc": { + "start": { + "line": 132, + "column": 26 + }, + "end": { + "line": 132, + "column": 40 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 5976, + "end": 6007, + "loc": { + "start": { + "line": 132, + "column": 41 + }, + "end": { + "line": 132, + "column": 72 + } + }, + "object": { + "type": "Identifier", + "start": 5976, + "end": 5991, + "loc": { + "start": { + "line": 132, + "column": 41 + }, + "end": { + "line": 132, + "column": 56 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 5992, + "end": 6007, + "loc": { + "start": { + "line": 132, + "column": 57 + }, + "end": { + "line": 132, + "column": 72 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 6009, + "end": 6024, + "loc": { + "start": { + "line": 132, + "column": 74 + }, + "end": { + "line": 132, + "column": 89 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 6035, + "end": 6115, + "loc": { + "start": { + "line": 133, + "column": 8 + }, + "end": { + "line": 133, + "column": 88 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 6035, + "end": 6114, + "loc": { + "start": { + "line": 133, + "column": 8 + }, + "end": { + "line": 133, + "column": 87 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 6035, + "end": 6049, + "loc": { + "start": { + "line": 133, + "column": 8 + }, + "end": { + "line": 133, + "column": 22 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "right": { + "type": "CallExpression", + "start": 6052, + "end": 6114, + "loc": { + "start": { + "line": 133, + "column": 25 + }, + "end": { + "line": 133, + "column": 87 + } + }, + "callee": { + "type": "Identifier", + "start": 6052, + "end": 6066, + "loc": { + "start": { + "line": 133, + "column": 25 + }, + "end": { + "line": 133, + "column": 39 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 6067, + "end": 6097, + "loc": { + "start": { + "line": 133, + "column": 40 + }, + "end": { + "line": 133, + "column": 70 + } + }, + "object": { + "type": "Identifier", + "start": 6067, + "end": 6082, + "loc": { + "start": { + "line": 133, + "column": 40 + }, + "end": { + "line": 133, + "column": 55 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 6083, + "end": 6097, + "loc": { + "start": { + "line": 133, + "column": 56 + }, + "end": { + "line": 133, + "column": 70 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 6099, + "end": 6113, + "loc": { + "start": { + "line": 133, + "column": 72 + }, + "end": { + "line": 133, + "column": 86 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 6124, + "end": 6198, + "loc": { + "start": { + "line": 134, + "column": 8 + }, + "end": { + "line": 134, + "column": 82 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 6124, + "end": 6197, + "loc": { + "start": { + "line": 134, + "column": 8 + }, + "end": { + "line": 134, + "column": 81 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 6124, + "end": 6136, + "loc": { + "start": { + "line": 134, + "column": 8 + }, + "end": { + "line": 134, + "column": 20 + }, + "identifierName": "includeTypes" + }, + "name": "includeTypes" + }, + "right": { + "type": "CallExpression", + "start": 6139, + "end": 6197, + "loc": { + "start": { + "line": 134, + "column": 23 + }, + "end": { + "line": 134, + "column": 81 + } + }, + "callee": { + "type": "Identifier", + "start": 6139, + "end": 6153, + "loc": { + "start": { + "line": 134, + "column": 23 + }, + "end": { + "line": 134, + "column": 37 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 6154, + "end": 6182, + "loc": { + "start": { + "line": 134, + "column": 38 + }, + "end": { + "line": 134, + "column": 66 + } + }, + "object": { + "type": "Identifier", + "start": 6154, + "end": 6169, + "loc": { + "start": { + "line": 134, + "column": 38 + }, + "end": { + "line": 134, + "column": 53 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 6170, + "end": 6182, + "loc": { + "start": { + "line": 134, + "column": 54 + }, + "end": { + "line": 134, + "column": 66 + }, + "identifierName": "includeTypes" + }, + "name": "includeTypes" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 6184, + "end": 6196, + "loc": { + "start": { + "line": 134, + "column": 68 + }, + "end": { + "line": 134, + "column": 80 + }, + "identifierName": "includeTypes" + }, + "name": "includeTypes" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 6207, + "end": 6281, + "loc": { + "start": { + "line": 135, + "column": 8 + }, + "end": { + "line": 135, + "column": 82 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 6207, + "end": 6280, + "loc": { + "start": { + "line": 135, + "column": 8 + }, + "end": { + "line": 135, + "column": 81 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 6207, + "end": 6219, + "loc": { + "start": { + "line": 135, + "column": 8 + }, + "end": { + "line": 135, + "column": 20 + }, + "identifierName": "excludeTypes" + }, + "name": "excludeTypes" + }, + "right": { + "type": "CallExpression", + "start": 6222, + "end": 6280, + "loc": { + "start": { + "line": 135, + "column": 23 + }, + "end": { + "line": 135, + "column": 81 + } + }, + "callee": { + "type": "Identifier", + "start": 6222, + "end": 6236, + "loc": { + "start": { + "line": 135, + "column": 23 + }, + "end": { + "line": 135, + "column": 37 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 6237, + "end": 6265, + "loc": { + "start": { + "line": 135, + "column": 38 + }, + "end": { + "line": 135, + "column": 66 + } + }, + "object": { + "type": "Identifier", + "start": 6237, + "end": 6252, + "loc": { + "start": { + "line": 135, + "column": 38 + }, + "end": { + "line": 135, + "column": 53 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 6253, + "end": 6265, + "loc": { + "start": { + "line": 135, + "column": 54 + }, + "end": { + "line": 135, + "column": 66 + }, + "identifierName": "excludeTypes" + }, + "name": "excludeTypes" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 6267, + "end": 6279, + "loc": { + "start": { + "line": 135, + "column": 68 + }, + "end": { + "line": 135, + "column": 80 + }, + "identifierName": "excludeTypes" + }, + "name": "excludeTypes" + } + ] + } + } + }, + { + "type": "IfStatement", + "start": 6291, + "end": 6380, + "loc": { + "start": { + "line": 137, + "column": 8 + }, + "end": { + "line": 139, + "column": 9 + } + }, + "test": { + "type": "BinaryExpression", + "start": 6295, + "end": 6320, + "loc": { + "start": { + "line": 137, + "column": 12 + }, + "end": { + "line": 137, + "column": 37 + } + }, + "left": { + "type": "Identifier", + "start": 6295, + "end": 6310, + "loc": { + "start": { + "line": 137, + "column": 12 + }, + "end": { + "line": 137, + "column": 27 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "operator": "===", + "right": { + "type": "BooleanLiteral", + "start": 6315, + "end": 6320, + "loc": { + "start": { + "line": 137, + "column": 32 + }, + "end": { + "line": 137, + "column": 37 + } + }, + "value": false + } + }, + "consequent": { + "type": "BlockStatement", + "start": 6322, + "end": 6380, + "loc": { + "start": { + "line": 137, + "column": 39 + }, + "end": { + "line": 139, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 6336, + "end": 6370, + "loc": { + "start": { + "line": 138, + "column": 12 + }, + "end": { + "line": 138, + "column": 46 + } + }, + "expression": { + "type": "CallExpression", + "start": 6336, + "end": 6369, + "loc": { + "start": { + "line": 138, + "column": 12 + }, + "end": { + "line": 138, + "column": 45 + } + }, + "callee": { + "type": "Identifier", + "start": 6336, + "end": 6339, + "loc": { + "start": { + "line": 138, + "column": 12 + }, + "end": { + "line": 138, + "column": 15 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 6340, + "end": 6368, + "loc": { + "start": { + "line": 138, + "column": 16 + }, + "end": { + "line": 138, + "column": 44 + } + }, + "extra": { + "rawValue": "Geometry reuse is disabled", + "raw": "\"Geometry reuse is disabled\"" + }, + "value": "Geometry reuse is disabled" + } + ] + } + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "VariableDeclaration", + "start": 6390, + "end": 6480, + "loc": { + "start": { + "line": 141, + "column": 8 + }, + "end": { + "line": 144, + "column": 11 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 6396, + "end": 6479, + "loc": { + "start": { + "line": 141, + "column": 14 + }, + "end": { + "line": 144, + "column": 10 + } + }, + "id": { + "type": "Identifier", + "start": 6396, + "end": 6404, + "loc": { + "start": { + "line": 141, + "column": 14 + }, + "end": { + "line": 141, + "column": 22 + }, + "identifierName": "xktModel" + }, + "name": "xktModel" + }, + "init": { + "type": "NewExpression", + "start": 6407, + "end": 6479, + "loc": { + "start": { + "line": 141, + "column": 25 + }, + "end": { + "line": 144, + "column": 10 + } + }, + "callee": { + "type": "Identifier", + "start": 6411, + "end": 6419, + "loc": { + "start": { + "line": 141, + "column": 29 + }, + "end": { + "line": 141, + "column": 37 + }, + "identifierName": "XKTModel" + }, + "name": "XKTModel" + }, + "arguments": [ + { + "type": "ObjectExpression", + "start": 6420, + "end": 6478, + "loc": { + "start": { + "line": 141, + "column": 38 + }, + "end": { + "line": 144, + "column": 9 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 6434, + "end": 6445, + "loc": { + "start": { + "line": 142, + "column": 12 + }, + "end": { + "line": 142, + "column": 23 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6434, + "end": 6445, + "loc": { + "start": { + "line": 142, + "column": 12 + }, + "end": { + "line": 142, + "column": 23 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "value": { + "type": "Identifier", + "start": 6434, + "end": 6445, + "loc": { + "start": { + "line": 142, + "column": 12 + }, + "end": { + "line": 142, + "column": 23 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 6459, + "end": 6468, + "loc": { + "start": { + "line": 143, + "column": 12 + }, + "end": { + "line": 143, + "column": 21 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6459, + "end": 6468, + "loc": { + "start": { + "line": 143, + "column": 12 + }, + "end": { + "line": 143, + "column": 21 + }, + "identifierName": "modelAABB" + }, + "name": "modelAABB" + }, + "value": { + "type": "Identifier", + "start": 6459, + "end": 6468, + "loc": { + "start": { + "line": 143, + "column": 12 + }, + "end": { + "line": 143, + "column": 21 + }, + "identifierName": "modelAABB" + }, + "name": "modelAABB" + }, + "extra": { + "shorthand": true + } + } + ] + } + ] + } + } + ], + "kind": "const" + }, + { + "type": "ExpressionStatement", + "start": 6492, + "end": 6531, + "loc": { + "start": { + "line": 148, + "column": 8 + }, + "end": { + "line": 148, + "column": 47 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 6492, + "end": 6530, + "loc": { + "start": { + "line": 148, + "column": 8 + }, + "end": { + "line": 148, + "column": 46 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 6492, + "end": 6502, + "loc": { + "start": { + "line": 148, + "column": 8 + }, + "end": { + "line": 148, + "column": 18 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + }, + "right": { + "type": "CallExpression", + "start": 6505, + "end": 6530, + "loc": { + "start": { + "line": 148, + "column": 21 + }, + "end": { + "line": 148, + "column": 46 + } + }, + "callee": { + "type": "Identifier", + "start": 6505, + "end": 6518, + "loc": { + "start": { + "line": 148, + "column": 21 + }, + "end": { + "line": 148, + "column": 34 + }, + "identifierName": "toArrayBuffer" + }, + "name": "toArrayBuffer" + }, + "arguments": [ + { + "type": "Identifier", + "start": 6519, + "end": 6529, + "loc": { + "start": { + "line": 148, + "column": 35 + }, + "end": { + "line": 148, + "column": 45 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 6540, + "end": 6763, + "loc": { + "start": { + "line": 149, + "column": 8 + }, + "end": { + "line": 157, + "column": 11 + } + }, + "expression": { + "type": "CallExpression", + "start": 6540, + "end": 6762, + "loc": { + "start": { + "line": 149, + "column": 8 + }, + "end": { + "line": 157, + "column": 10 + } + }, + "callee": { + "type": "Identifier", + "start": 6540, + "end": 6547, + "loc": { + "start": { + "line": 149, + "column": 8 + }, + "end": { + "line": 149, + "column": 15 + }, + "identifierName": "convert" + }, + "name": "convert" + }, + "arguments": [ + { + "type": "Identifier", + "start": 6548, + "end": 6569, + "loc": { + "start": { + "line": 149, + "column": 16 + }, + "end": { + "line": 149, + "column": 37 + }, + "identifierName": "parseGLTFIntoXKTModel" + }, + "name": "parseGLTFIntoXKTModel" + }, + { + "type": "ObjectExpression", + "start": 6571, + "end": 6761, + "loc": { + "start": { + "line": 149, + "column": 39 + }, + "end": { + "line": 157, + "column": 9 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 6585, + "end": 6601, + "loc": { + "start": { + "line": 150, + "column": 12 + }, + "end": { + "line": 150, + "column": 28 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 6585, + "end": 6589, + "loc": { + "start": { + "line": 150, + "column": 12 + }, + "end": { + "line": 150, + "column": 16 + }, + "identifierName": "data" + }, + "name": "data" + }, + "value": { + "type": "Identifier", + "start": 6591, + "end": 6601, + "loc": { + "start": { + "line": 150, + "column": 18 + }, + "end": { + "line": 150, + "column": 28 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + } + }, + { + "type": "ObjectProperty", + "start": 6615, + "end": 6630, + "loc": { + "start": { + "line": 151, + "column": 12 + }, + "end": { + "line": 151, + "column": 27 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6615, + "end": 6630, + "loc": { + "start": { + "line": 151, + "column": 12 + }, + "end": { + "line": 151, + "column": 27 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "value": { + "type": "Identifier", + "start": 6615, + "end": 6630, + "loc": { + "start": { + "line": 151, + "column": 12 + }, + "end": { + "line": 151, + "column": 27 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 6644, + "end": 6665, + "loc": { + "start": { + "line": 152, + "column": 12 + }, + "end": { + "line": 152, + "column": 33 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 6644, + "end": 6659, + "loc": { + "start": { + "line": 152, + "column": 12 + }, + "end": { + "line": 152, + "column": 27 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + }, + "value": { + "type": "BooleanLiteral", + "start": 6661, + "end": 6665, + "loc": { + "start": { + "line": 152, + "column": 29 + }, + "end": { + "line": 152, + "column": 33 + } + }, + "value": true + } + }, + { + "type": "ObjectProperty", + "start": 6679, + "end": 6693, + "loc": { + "start": { + "line": 153, + "column": 12 + }, + "end": { + "line": 153, + "column": 26 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6679, + "end": 6693, + "loc": { + "start": { + "line": 153, + "column": 12 + }, + "end": { + "line": 153, + "column": 26 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "value": { + "type": "Identifier", + "start": 6679, + "end": 6693, + "loc": { + "start": { + "line": 153, + "column": 12 + }, + "end": { + "line": 153, + "column": 26 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 6707, + "end": 6715, + "loc": { + "start": { + "line": 154, + "column": 12 + }, + "end": { + "line": 154, + "column": 20 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6707, + "end": 6715, + "loc": { + "start": { + "line": 154, + "column": 12 + }, + "end": { + "line": 154, + "column": 20 + }, + "identifierName": "xktModel" + }, + "name": "xktModel" + }, + "value": { + "type": "Identifier", + "start": 6707, + "end": 6715, + "loc": { + "start": { + "line": 154, + "column": 12 + }, + "end": { + "line": 154, + "column": 20 + }, + "identifierName": "xktModel" + }, + "name": "xktModel" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 6729, + "end": 6734, + "loc": { + "start": { + "line": 155, + "column": 12 + }, + "end": { + "line": 155, + "column": 17 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6729, + "end": 6734, + "loc": { + "start": { + "line": 155, + "column": 12 + }, + "end": { + "line": 155, + "column": 17 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "value": { + "type": "Identifier", + "start": 6729, + "end": 6734, + "loc": { + "start": { + "line": 155, + "column": 12 + }, + "end": { + "line": 155, + "column": 17 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 6748, + "end": 6751, + "loc": { + "start": { + "line": 156, + "column": 12 + }, + "end": { + "line": 156, + "column": 15 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6748, + "end": 6751, + "loc": { + "start": { + "line": 156, + "column": 12 + }, + "end": { + "line": 156, + "column": 15 + }, + "identifierName": "log" + }, + "name": "log" + }, + "value": { + "type": "Identifier", + "start": 6748, + "end": 6751, + "loc": { + "start": { + "line": 156, + "column": 12 + }, + "end": { + "line": 156, + "column": 15 + }, + "identifierName": "log" + }, + "name": "log" + }, + "extra": { + "shorthand": true + } + } + ] + } + ] + } + }, + { + "type": "FunctionDeclaration", + "start": 6774, + "end": 7483, + "loc": { + "start": { + "line": 160, + "column": 8 + }, + "end": { + "line": 185, + "column": 9 + } + }, + "id": { + "type": "Identifier", + "start": 6783, + "end": 6790, + "loc": { + "start": { + "line": 160, + "column": 17 + }, + "end": { + "line": 160, + "column": 24 + }, + "identifierName": "convert" + }, + "name": "convert" + }, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 6791, + "end": 6797, + "loc": { + "start": { + "line": 160, + "column": 25 + }, + "end": { + "line": 160, + "column": 31 + }, + "identifierName": "parser" + }, + "name": "parser" + }, + { + "type": "Identifier", + "start": 6799, + "end": 6814, + "loc": { + "start": { + "line": 160, + "column": 33 + }, + "end": { + "line": 160, + "column": 48 + }, + "identifierName": "converterParams" + }, + "name": "converterParams" + } + ], + "body": { + "type": "BlockStatement", + "start": 6816, + "end": 7483, + "loc": { + "start": { + "line": 160, + "column": 50 + }, + "end": { + "line": 185, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 6831, + "end": 7473, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 184, + "column": 15 + } + }, + "expression": { + "type": "CallExpression", + "start": 6831, + "end": 7472, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 184, + "column": 14 + } + }, + "callee": { + "type": "MemberExpression", + "start": 6831, + "end": 6859, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 162, + "column": 40 + } + }, + "object": { + "type": "CallExpression", + "start": 6831, + "end": 6854, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 162, + "column": 35 + } + }, + "callee": { + "type": "Identifier", + "start": 6831, + "end": 6837, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 162, + "column": 18 + }, + "identifierName": "parser" + }, + "name": "parser" + }, + "arguments": [ + { + "type": "Identifier", + "start": 6838, + "end": 6853, + "loc": { + "start": { + "line": 162, + "column": 19 + }, + "end": { + "line": 162, + "column": 34 + }, + "identifierName": "converterParams" + }, + "name": "converterParams" + } + ] + }, + "property": { + "type": "Identifier", + "start": 6855, + "end": 6859, + "loc": { + "start": { + "line": 162, + "column": 36 + }, + "end": { + "line": 162, + "column": 40 + }, + "identifierName": "then" + }, + "name": "then" + }, + "computed": false + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "start": 6860, + "end": 7416, + "loc": { + "start": { + "line": 162, + "column": 41 + }, + "end": { + "line": 182, + "column": 13 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 6866, + "end": 7416, + "loc": { + "start": { + "line": 162, + "column": 47 + }, + "end": { + "line": 182, + "column": 13 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 6886, + "end": 6940, + "loc": { + "start": { + "line": 165, + "column": 16 + }, + "end": { + "line": 165, + "column": 70 + } + }, + "expression": { + "type": "CallExpression", + "start": 6886, + "end": 6939, + "loc": { + "start": { + "line": 165, + "column": 16 + }, + "end": { + "line": 165, + "column": 69 + } + }, + "callee": { + "type": "Identifier", + "start": 6886, + "end": 6889, + "loc": { + "start": { + "line": 165, + "column": 16 + }, + "end": { + "line": 165, + "column": 19 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 6890, + "end": 6938, + "loc": { + "start": { + "line": 165, + "column": 20 + }, + "end": { + "line": 165, + "column": 68 + } + }, + "extra": { + "rawValue": "Input file parsed OK. Building XKT document...", + "raw": "\"Input file parsed OK. Building XKT document...\"" + }, + "value": "Input file parsed OK. Building XKT document..." + } + ] + } + }, + { + "type": "ExpressionStatement", + "start": 6958, + "end": 7402, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 181, + "column": 19 + } + }, + "expression": { + "type": "CallExpression", + "start": 6958, + "end": 7401, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 181, + "column": 18 + } + }, + "callee": { + "type": "MemberExpression", + "start": 6958, + "end": 6982, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 167, + "column": 40 + } + }, + "object": { + "type": "CallExpression", + "start": 6958, + "end": 6977, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 167, + "column": 35 + } + }, + "callee": { + "type": "MemberExpression", + "start": 6958, + "end": 6975, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 167, + "column": 33 + } + }, + "object": { + "type": "Identifier", + "start": 6958, + "end": 6966, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 167, + "column": 24 + }, + "identifierName": "xktModel" + }, + "name": "xktModel" + }, + "property": { + "type": "Identifier", + "start": 6967, + "end": 6975, + "loc": { + "start": { + "line": 167, + "column": 25 + }, + "end": { + "line": 167, + "column": 33 + }, + "identifierName": "finalize" + }, + "name": "finalize" + }, + "computed": false + }, + "arguments": [] + }, + "property": { + "type": "Identifier", + "start": 6978, + "end": 6982, + "loc": { + "start": { + "line": 167, + "column": 36 + }, + "end": { + "line": 167, + "column": 40 + }, + "identifierName": "then" + }, + "name": "then" + }, + "computed": false + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "start": 6983, + "end": 7400, + "loc": { + "start": { + "line": 167, + "column": 41 + }, + "end": { + "line": 181, + "column": 17 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 6989, + "end": 7400, + "loc": { + "start": { + "line": 167, + "column": 47 + }, + "end": { + "line": 181, + "column": 17 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 7012, + "end": 7065, + "loc": { + "start": { + "line": 169, + "column": 20 + }, + "end": { + "line": 169, + "column": 73 + } + }, + "expression": { + "type": "CallExpression", + "start": 7012, + "end": 7064, + "loc": { + "start": { + "line": 169, + "column": 20 + }, + "end": { + "line": 169, + "column": 72 + } + }, + "callee": { + "type": "Identifier", + "start": 7012, + "end": 7015, + "loc": { + "start": { + "line": 169, + "column": 20 + }, + "end": { + "line": 169, + "column": 23 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 7016, + "end": 7063, + "loc": { + "start": { + "line": 169, + "column": 24 + }, + "end": { + "line": 169, + "column": 71 + } + }, + "extra": { + "rawValue": "XKT document built OK. Writing to XKT file...", + "raw": "\"XKT document built OK. Writing to XKT file...\"" + }, + "value": "XKT document built OK. Writing to XKT file..." + } + ] + } + }, + { + "type": "VariableDeclaration", + "start": 7087, + "end": 7173, + "loc": { + "start": { + "line": 171, + "column": 20 + }, + "end": { + "line": 171, + "column": 106 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 7093, + "end": 7172, + "loc": { + "start": { + "line": 171, + "column": 26 + }, + "end": { + "line": 171, + "column": 105 + } + }, + "id": { + "type": "Identifier", + "start": 7093, + "end": 7107, + "loc": { + "start": { + "line": 171, + "column": 26 + }, + "end": { + "line": 171, + "column": 40 + }, + "identifierName": "xktArrayBuffer" + }, + "name": "xktArrayBuffer" + }, + "init": { + "type": "CallExpression", + "start": 7110, + "end": 7172, + "loc": { + "start": { + "line": 171, + "column": 43 + }, + "end": { + "line": 171, + "column": 105 + } + }, + "callee": { + "type": "Identifier", + "start": 7110, + "end": 7136, + "loc": { + "start": { + "line": 171, + "column": 43 + }, + "end": { + "line": 171, + "column": 69 + }, + "identifierName": "writeXKTModelToArrayBuffer" + }, + "name": "writeXKTModelToArrayBuffer" + }, + "arguments": [ + { + "type": "Identifier", + "start": 7137, + "end": 7145, + "loc": { + "start": { + "line": 171, + "column": 70 + }, + "end": { + "line": 171, + "column": 78 + }, + "identifierName": "xktModel" + }, + "name": "xktModel" + }, + { + "type": "NullLiteral", + "start": 7147, + "end": 7151, + "loc": { + "start": { + "line": 171, + "column": 80 + }, + "end": { + "line": 171, + "column": 84 + } + } + }, + { + "type": "Identifier", + "start": 7153, + "end": 7158, + "loc": { + "start": { + "line": 171, + "column": 86 + }, + "end": { + "line": 171, + "column": 91 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + { + "type": "ObjectExpression", + "start": 7160, + "end": 7171, + "loc": { + "start": { + "line": 171, + "column": 93 + }, + "end": { + "line": 171, + "column": 104 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 7161, + "end": 7170, + "loc": { + "start": { + "line": 171, + "column": 94 + }, + "end": { + "line": 171, + "column": 103 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 7161, + "end": 7164, + "loc": { + "start": { + "line": 171, + "column": 94 + }, + "end": { + "line": 171, + "column": 97 + }, + "identifierName": "zip" + }, + "name": "zip" + }, + "value": { + "type": "BooleanLiteral", + "start": 7166, + "end": 7170, + "loc": { + "start": { + "line": 171, + "column": 99 + }, + "end": { + "line": 171, + "column": 103 + } + }, + "value": true + } + } + ] + } + ] + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 7195, + "end": 7242, + "loc": { + "start": { + "line": 173, + "column": 20 + }, + "end": { + "line": 173, + "column": 67 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 7201, + "end": 7241, + "loc": { + "start": { + "line": 173, + "column": 26 + }, + "end": { + "line": 173, + "column": 66 + } + }, + "id": { + "type": "Identifier", + "start": 7201, + "end": 7211, + "loc": { + "start": { + "line": 173, + "column": 26 + }, + "end": { + "line": 173, + "column": 36 + }, + "identifierName": "xktContent" + }, + "name": "xktContent" + }, + "init": { + "type": "CallExpression", + "start": 7214, + "end": 7241, + "loc": { + "start": { + "line": 173, + "column": 39 + }, + "end": { + "line": 173, + "column": 66 + } + }, + "callee": { + "type": "MemberExpression", + "start": 7214, + "end": 7225, + "loc": { + "start": { + "line": 173, + "column": 39 + }, + "end": { + "line": 173, + "column": 50 + } + }, + "object": { + "type": "Identifier", + "start": 7214, + "end": 7220, + "loc": { + "start": { + "line": 173, + "column": 39 + }, + "end": { + "line": 173, + "column": 45 + }, + "identifierName": "Buffer" + }, + "name": "Buffer" + }, + "property": { + "type": "Identifier", + "start": 7221, + "end": 7225, + "loc": { + "start": { + "line": 173, + "column": 46 + }, + "end": { + "line": 173, + "column": 50 + }, + "identifierName": "from" + }, + "name": "from" + }, + "computed": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 7226, + "end": 7240, + "loc": { + "start": { + "line": 173, + "column": 51 + }, + "end": { + "line": 173, + "column": 65 + }, + "identifierName": "xktArrayBuffer" + }, + "name": "xktArrayBuffer" + } + ] + } + } + ], + "kind": "const" + }, + { + "type": "IfStatement", + "start": 7265, + "end": 7350, + "loc": { + "start": { + "line": 176, + "column": 20 + }, + "end": { + "line": 178, + "column": 21 + } + }, + "test": { + "type": "Identifier", + "start": 7269, + "end": 7278, + "loc": { + "start": { + "line": 176, + "column": 24 + }, + "end": { + "line": 176, + "column": 33 + }, + "identifierName": "outputXKT" + }, + "name": "outputXKT" + }, + "consequent": { + "type": "BlockStatement", + "start": 7280, + "end": 7350, + "loc": { + "start": { + "line": 176, + "column": 35 + }, + "end": { + "line": 178, + "column": 21 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 7306, + "end": 7328, + "loc": { + "start": { + "line": 177, + "column": 24 + }, + "end": { + "line": 177, + "column": 46 + } + }, + "expression": { + "type": "CallExpression", + "start": 7306, + "end": 7327, + "loc": { + "start": { + "line": 177, + "column": 24 + }, + "end": { + "line": 177, + "column": 45 + } + }, + "callee": { + "type": "Identifier", + "start": 7306, + "end": 7315, + "loc": { + "start": { + "line": 177, + "column": 24 + }, + "end": { + "line": 177, + "column": 33 + }, + "identifierName": "outputXKT" + }, + "name": "outputXKT" + }, + "arguments": [ + { + "type": "Identifier", + "start": 7316, + "end": 7326, + "loc": { + "start": { + "line": 177, + "column": 34 + }, + "end": { + "line": 177, + "column": 44 + }, + "identifierName": "xktContent" + }, + "name": "xktContent" + } + ] + } + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "ExpressionStatement", + "start": 7372, + "end": 7382, + "loc": { + "start": { + "line": 180, + "column": 20 + }, + "end": { + "line": 180, + "column": 30 + } + }, + "expression": { + "type": "CallExpression", + "start": 7372, + "end": 7381, + "loc": { + "start": { + "line": 180, + "column": 20 + }, + "end": { + "line": 180, + "column": 29 + } + }, + "callee": { + "type": "Identifier", + "start": 7372, + "end": 7379, + "loc": { + "start": { + "line": 180, + "column": 20 + }, + "end": { + "line": 180, + "column": 27 + }, + "identifierName": "resolve" + }, + "name": "resolve" + }, + "arguments": [] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } + }, + { + "type": "ArrowFunctionExpression", + "start": 7418, + "end": 7471, + "loc": { + "start": { + "line": 182, + "column": 15 + }, + "end": { + "line": 184, + "column": 13 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 7419, + "end": 7422, + "loc": { + "start": { + "line": 182, + "column": 16 + }, + "end": { + "line": 182, + "column": 19 + }, + "identifierName": "err" + }, + "name": "err" + } + ], + "body": { + "type": "BlockStatement", + "start": 7427, + "end": 7471, + "loc": { + "start": { + "line": 182, + "column": 24 + }, + "end": { + "line": 184, + "column": 13 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 7445, + "end": 7457, + "loc": { + "start": { + "line": 183, + "column": 16 + }, + "end": { + "line": 183, + "column": 28 + } + }, + "expression": { + "type": "CallExpression", + "start": 7445, + "end": 7456, + "loc": { + "start": { + "line": 183, + "column": 16 + }, + "end": { + "line": 183, + "column": 27 + } + }, + "callee": { + "type": "Identifier", + "start": 7445, + "end": 7451, + "loc": { + "start": { + "line": 183, + "column": 16 + }, + "end": { + "line": 183, + "column": 22 + }, + "identifierName": "reject" + }, + "name": "reject" + }, + "arguments": [ + { + "type": "Identifier", + "start": 7452, + "end": 7455, + "loc": { + "start": { + "line": 183, + "column": 23 + }, + "end": { + "line": 183, + "column": 26 + }, + "identifierName": "err" + }, + "name": "err" + } + ] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + }, + "leadingComments": [], + "name": "_", + "trailingComments": [] + }, + { + "type": "ExportNamedDeclaration", + "start": 7495, + "end": 7516, + "loc": { + "start": { + "line": 189, + "column": 0 + }, + "end": { + "line": 189, + "column": 21 + } + }, + "declaration": null, + "specifiers": [ + { + "type": "ExportSpecifier", + "start": 7503, + "end": 7514, + "loc": { + "start": { + "line": 189, + "column": 8 + }, + "end": { + "line": 189, + "column": 19 + } + }, + "local": { + "type": "Identifier", + "start": 7503, + "end": 7514, + "loc": { + "start": { + "line": 189, + "column": 8 + }, + "end": { + "line": 189, + "column": 19 + }, + "identifierName": "convert2xkt" + }, + "name": "convert2xkt" + }, + "exported": { + "type": "Identifier", + "start": 7503, + "end": 7514, + "loc": { + "start": { + "line": 189, + "column": 8 + }, + "end": { + "line": 189, + "column": 19 + }, + "identifierName": "convert2xkt" + }, + "name": "convert2xkt" + } + } + ], + "source": null + }, + { + "type": "ExportNamedDeclaration", + "start": 7495, + "end": 7516, + "loc": { + "start": { + "line": 189, + "column": 0 + }, + "end": { + "line": 189, + "column": 21 + } + }, + "declaration": { + "type": "FunctionDeclaration", + "start": 3261, + "end": 7493, + "loc": { + "start": { + "line": 47, + "column": 0 + }, + "end": { + "line": 187, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 3270, + "end": 3281, + "loc": { + "start": { + "line": 47, + "column": 9 + }, + "end": { + "line": 47, + "column": 20 + }, + "identifierName": "convert2xkt" + }, + "name": "convert2xkt", + "leadingComments": null + }, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "ObjectPattern", + "start": 3282, + "end": 3917, + "loc": { + "start": { + "line": 47, + "column": 21 + }, + "end": { + "line": 63, + "column": 22 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 3309, + "end": 3321, + "loc": { + "start": { + "line": 48, + "column": 25 + }, + "end": { + "line": 48, + "column": 37 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3309, + "end": 3316, + "loc": { + "start": { + "line": 48, + "column": 25 + }, + "end": { + "line": 48, + "column": 32 + }, + "identifierName": "configs" + }, + "name": "configs" + }, + "value": { + "type": "AssignmentPattern", + "start": 3309, + "end": 3321, + "loc": { + "start": { + "line": 48, + "column": 25 + }, + "end": { + "line": 48, + "column": 37 + } + }, + "left": { + "type": "Identifier", + "start": 3309, + "end": 3316, + "loc": { + "start": { + "line": 48, + "column": 25 + }, + "end": { + "line": 48, + "column": 32 + }, + "identifierName": "configs" + }, + "name": "configs" + }, + "right": { + "type": "ObjectExpression", + "start": 3319, + "end": 3321, + "loc": { + "start": { + "line": 48, + "column": 35 + }, + "end": { + "line": 48, + "column": 37 + } + }, + "properties": [] + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3348, + "end": 3358, + "loc": { + "start": { + "line": 49, + "column": 25 + }, + "end": { + "line": 49, + "column": 35 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3348, + "end": 3358, + "loc": { + "start": { + "line": 49, + "column": 25 + }, + "end": { + "line": 49, + "column": 35 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + }, + "value": { + "type": "Identifier", + "start": 3348, + "end": 3358, + "loc": { + "start": { + "line": 49, + "column": 25 + }, + "end": { + "line": 49, + "column": 35 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3385, + "end": 3394, + "loc": { + "start": { + "line": 50, + "column": 25 + }, + "end": { + "line": 50, + "column": 34 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3385, + "end": 3394, + "loc": { + "start": { + "line": 50, + "column": 25 + }, + "end": { + "line": 50, + "column": 34 + }, + "identifierName": "modelAABB" + }, + "name": "modelAABB" + }, + "value": { + "type": "Identifier", + "start": 3385, + "end": 3394, + "loc": { + "start": { + "line": 50, + "column": 25 + }, + "end": { + "line": 50, + "column": 34 + }, + "identifierName": "modelAABB" + }, + "name": "modelAABB" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3421, + "end": 3435, + "loc": { + "start": { + "line": 51, + "column": 25 + }, + "end": { + "line": 51, + "column": 39 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3421, + "end": 3435, + "loc": { + "start": { + "line": 51, + "column": 25 + }, + "end": { + "line": 51, + "column": 39 + }, + "identifierName": "outputXKTModel" + }, + "name": "outputXKTModel" + }, + "value": { + "type": "Identifier", + "start": 3421, + "end": 3435, + "loc": { + "start": { + "line": 51, + "column": 25 + }, + "end": { + "line": 51, + "column": 39 + }, + "identifierName": "outputXKTModel" + }, + "name": "outputXKTModel" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3462, + "end": 3471, + "loc": { + "start": { + "line": 52, + "column": 25 + }, + "end": { + "line": 52, + "column": 34 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3462, + "end": 3471, + "loc": { + "start": { + "line": 52, + "column": 25 + }, + "end": { + "line": 52, + "column": 34 + }, + "identifierName": "outputXKT" + }, + "name": "outputXKT" + }, + "value": { + "type": "Identifier", + "start": 3462, + "end": 3471, + "loc": { + "start": { + "line": 52, + "column": 25 + }, + "end": { + "line": 52, + "column": 34 + }, + "identifierName": "outputXKT" + }, + "name": "outputXKT" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3498, + "end": 3510, + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 37 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3498, + "end": 3510, + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 37 + }, + "identifierName": "includeTypes" + }, + "name": "includeTypes" + }, + "value": { + "type": "Identifier", + "start": 3498, + "end": 3510, + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 37 + }, + "identifierName": "includeTypes" + }, + "name": "includeTypes" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3537, + "end": 3549, + "loc": { + "start": { + "line": 54, + "column": 25 + }, + "end": { + "line": 54, + "column": 37 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3537, + "end": 3549, + "loc": { + "start": { + "line": 54, + "column": 25 + }, + "end": { + "line": 54, + "column": 37 + }, + "identifierName": "excludeTypes" + }, + "name": "excludeTypes" + }, + "value": { + "type": "Identifier", + "start": 3537, + "end": 3549, + "loc": { + "start": { + "line": 54, + "column": 25 + }, + "end": { + "line": 54, + "column": 37 + }, + "identifierName": "excludeTypes" + }, + "name": "excludeTypes" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3576, + "end": 3598, + "loc": { + "start": { + "line": 55, + "column": 25 + }, + "end": { + "line": 55, + "column": 47 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3576, + "end": 3591, + "loc": { + "start": { + "line": 55, + "column": 25 + }, + "end": { + "line": 55, + "column": 40 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "value": { + "type": "AssignmentPattern", + "start": 3576, + "end": 3598, + "loc": { + "start": { + "line": 55, + "column": 25 + }, + "end": { + "line": 55, + "column": 47 + } + }, + "left": { + "type": "Identifier", + "start": 3576, + "end": 3591, + "loc": { + "start": { + "line": 55, + "column": 25 + }, + "end": { + "line": 55, + "column": 40 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "right": { + "type": "BooleanLiteral", + "start": 3594, + "end": 3598, + "loc": { + "start": { + "line": 55, + "column": 43 + }, + "end": { + "line": 55, + "column": 47 + } + }, + "value": true + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3625, + "end": 3642, + "loc": { + "start": { + "line": 56, + "column": 25 + }, + "end": { + "line": 56, + "column": 42 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3625, + "end": 3636, + "loc": { + "start": { + "line": 56, + "column": 25 + }, + "end": { + "line": 56, + "column": 36 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "value": { + "type": "AssignmentPattern", + "start": 3625, + "end": 3642, + "loc": { + "start": { + "line": 56, + "column": 25 + }, + "end": { + "line": 56, + "column": 42 + } + }, + "left": { + "type": "Identifier", + "start": 3625, + "end": 3636, + "loc": { + "start": { + "line": 56, + "column": 25 + }, + "end": { + "line": 56, + "column": 36 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "right": { + "type": "NumericLiteral", + "start": 3639, + "end": 3642, + "loc": { + "start": { + "line": 56, + "column": 39 + }, + "end": { + "line": 56, + "column": 42 + } + }, + "extra": { + "rawValue": 200, + "raw": "200" + }, + "value": 200 + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3669, + "end": 3679, + "loc": { + "start": { + "line": 57, + "column": 25 + }, + "end": { + "line": 57, + "column": 35 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3669, + "end": 3674, + "loc": { + "start": { + "line": 57, + "column": 25 + }, + "end": { + "line": 57, + "column": 30 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "value": { + "type": "AssignmentPattern", + "start": 3669, + "end": 3679, + "loc": { + "start": { + "line": 57, + "column": 25 + }, + "end": { + "line": 57, + "column": 35 + } + }, + "left": { + "type": "Identifier", + "start": 3669, + "end": 3674, + "loc": { + "start": { + "line": 57, + "column": 25 + }, + "end": { + "line": 57, + "column": 30 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "right": { + "type": "ObjectExpression", + "start": 3677, + "end": 3679, + "loc": { + "start": { + "line": 57, + "column": 33 + }, + "end": { + "line": 57, + "column": 35 + } + }, + "properties": [] + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3706, + "end": 3721, + "loc": { + "start": { + "line": 58, + "column": 25 + }, + "end": { + "line": 58, + "column": 40 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3706, + "end": 3713, + "loc": { + "start": { + "line": 58, + "column": 25 + }, + "end": { + "line": 58, + "column": 32 + }, + "identifierName": "rotateX" + }, + "name": "rotateX" + }, + "value": { + "type": "AssignmentPattern", + "start": 3706, + "end": 3721, + "loc": { + "start": { + "line": 58, + "column": 25 + }, + "end": { + "line": 58, + "column": 40 + } + }, + "left": { + "type": "Identifier", + "start": 3706, + "end": 3713, + "loc": { + "start": { + "line": 58, + "column": 25 + }, + "end": { + "line": 58, + "column": 32 + }, + "identifierName": "rotateX" + }, + "name": "rotateX" + }, + "right": { + "type": "BooleanLiteral", + "start": 3716, + "end": 3721, + "loc": { + "start": { + "line": 58, + "column": 35 + }, + "end": { + "line": 58, + "column": 40 + } + }, + "value": false + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3748, + "end": 3770, + "loc": { + "start": { + "line": 59, + "column": 25 + }, + "end": { + "line": 59, + "column": 47 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3748, + "end": 3763, + "loc": { + "start": { + "line": 59, + "column": 25 + }, + "end": { + "line": 59, + "column": 40 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + }, + "value": { + "type": "AssignmentPattern", + "start": 3748, + "end": 3770, + "loc": { + "start": { + "line": 59, + "column": 25 + }, + "end": { + "line": 59, + "column": 47 + } + }, + "left": { + "type": "Identifier", + "start": 3748, + "end": 3763, + "loc": { + "start": { + "line": 59, + "column": 25 + }, + "end": { + "line": 59, + "column": 40 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + }, + "right": { + "type": "BooleanLiteral", + "start": 3766, + "end": 3770, + "loc": { + "start": { + "line": 59, + "column": 43 + }, + "end": { + "line": 59, + "column": 47 + } + }, + "value": true + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3797, + "end": 3818, + "loc": { + "start": { + "line": 60, + "column": 25 + }, + "end": { + "line": 60, + "column": 46 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3797, + "end": 3811, + "loc": { + "start": { + "line": 60, + "column": 25 + }, + "end": { + "line": 60, + "column": 39 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "value": { + "type": "AssignmentPattern", + "start": 3797, + "end": 3818, + "loc": { + "start": { + "line": 60, + "column": 25 + }, + "end": { + "line": 60, + "column": 46 + } + }, + "left": { + "type": "Identifier", + "start": 3797, + "end": 3811, + "loc": { + "start": { + "line": 60, + "column": 25 + }, + "end": { + "line": 60, + "column": 39 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "right": { + "type": "BooleanLiteral", + "start": 3814, + "end": 3818, + "loc": { + "start": { + "line": 60, + "column": 42 + }, + "end": { + "line": 60, + "column": 46 + } + }, + "value": true + } + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 3845, + "end": 3894, + "loc": { + "start": { + "line": 61, + "column": 25 + }, + "end": { + "line": 62, + "column": 26 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3845, + "end": 3848, + "loc": { + "start": { + "line": 61, + "column": 25 + }, + "end": { + "line": 61, + "column": 28 + }, + "identifierName": "log" + }, + "name": "log" + }, + "value": { + "type": "AssignmentPattern", + "start": 3845, + "end": 3894, + "loc": { + "start": { + "line": 61, + "column": 25 + }, + "end": { + "line": 62, + "column": 26 + } + }, + "left": { + "type": "Identifier", + "start": 3845, + "end": 3848, + "loc": { + "start": { + "line": 61, + "column": 25 + }, + "end": { + "line": 61, + "column": 28 + }, + "identifierName": "log" + }, + "name": "log" + }, + "right": { + "type": "FunctionExpression", + "start": 3851, + "end": 3894, + "loc": { + "start": { + "line": 61, + "column": 31 + }, + "end": { + "line": 62, + "column": 26 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 3861, + "end": 3864, + "loc": { + "start": { + "line": 61, + "column": 41 + }, + "end": { + "line": 61, + "column": 44 + }, + "identifierName": "msg" + }, + "name": "msg" + } + ], + "body": { + "type": "BlockStatement", + "start": 3866, + "end": 3894, + "loc": { + "start": { + "line": 61, + "column": 46 + }, + "end": { + "line": 62, + "column": 26 + } + }, + "body": [], + "directives": [] + } + } + }, + "extra": { + "shorthand": true + } + } + ] + } + ], + "body": { + "type": "BlockStatement", + "start": 3919, + "end": 7493, + "loc": { + "start": { + "line": 63, + "column": 24 + }, + "end": { + "line": 187, + "column": 1 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 3926, + "end": 3951, + "loc": { + "start": { + "line": 65, + "column": 4 + }, + "end": { + "line": 65, + "column": 29 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 3926, + "end": 3950, + "loc": { + "start": { + "line": 65, + "column": 4 + }, + "end": { + "line": 65, + "column": 28 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 3926, + "end": 3945, + "loc": { + "start": { + "line": 65, + "column": 4 + }, + "end": { + "line": 65, + "column": 23 + } + }, + "object": { + "type": "Identifier", + "start": 3926, + "end": 3931, + "loc": { + "start": { + "line": 65, + "column": 4 + }, + "end": { + "line": 65, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 3932, + "end": 3945, + "loc": { + "start": { + "line": 65, + "column": 10 + }, + "end": { + "line": 65, + "column": 23 + }, + "identifierName": "schemaVersion" + }, + "name": "schemaVersion" + }, + "computed": false + }, + "right": { + "type": "StringLiteral", + "start": 3948, + "end": 3950, + "loc": { + "start": { + "line": 65, + "column": 26 + }, + "end": { + "line": 65, + "column": 28 + } + }, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + }, + { + "type": "ExpressionStatement", + "start": 3956, + "end": 3973, + "loc": { + "start": { + "line": 66, + "column": 4 + }, + "end": { + "line": 66, + "column": 21 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 3956, + "end": 3972, + "loc": { + "start": { + "line": 66, + "column": 4 + }, + "end": { + "line": 66, + "column": 20 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 3956, + "end": 3967, + "loc": { + "start": { + "line": 66, + "column": 4 + }, + "end": { + "line": 66, + "column": 15 + } + }, + "object": { + "type": "Identifier", + "start": 3956, + "end": 3961, + "loc": { + "start": { + "line": 66, + "column": 4 + }, + "end": { + "line": 66, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 3962, + "end": 3967, + "loc": { + "start": { + "line": 66, + "column": 10 + }, + "end": { + "line": 66, + "column": 15 + }, + "identifierName": "title" + }, + "name": "title" + }, + "computed": false + }, + "right": { + "type": "StringLiteral", + "start": 3970, + "end": 3972, + "loc": { + "start": { + "line": 66, + "column": 18 + }, + "end": { + "line": 66, + "column": 20 + } + }, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + }, + { + "type": "ExpressionStatement", + "start": 3978, + "end": 3996, + "loc": { + "start": { + "line": 67, + "column": 4 + }, + "end": { + "line": 67, + "column": 22 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 3978, + "end": 3995, + "loc": { + "start": { + "line": 67, + "column": 4 + }, + "end": { + "line": 67, + "column": 21 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 3978, + "end": 3990, + "loc": { + "start": { + "line": 67, + "column": 4 + }, + "end": { + "line": 67, + "column": 16 + } + }, + "object": { + "type": "Identifier", + "start": 3978, + "end": 3983, + "loc": { + "start": { + "line": 67, + "column": 4 + }, + "end": { + "line": 67, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 3984, + "end": 3990, + "loc": { + "start": { + "line": 67, + "column": 10 + }, + "end": { + "line": 67, + "column": 16 + }, + "identifierName": "author" + }, + "name": "author" + }, + "computed": false + }, + "right": { + "type": "StringLiteral", + "start": 3993, + "end": 3995, + "loc": { + "start": { + "line": 67, + "column": 19 + }, + "end": { + "line": 67, + "column": 21 + } + }, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + }, + { + "type": "ExpressionStatement", + "start": 4001, + "end": 4020, + "loc": { + "start": { + "line": 68, + "column": 4 + }, + "end": { + "line": 68, + "column": 23 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4001, + "end": 4019, + "loc": { + "start": { + "line": 68, + "column": 4 + }, + "end": { + "line": 68, + "column": 22 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4001, + "end": 4014, + "loc": { + "start": { + "line": 68, + "column": 4 + }, + "end": { + "line": 68, + "column": 17 + } + }, + "object": { + "type": "Identifier", + "start": 4001, + "end": 4006, + "loc": { + "start": { + "line": 68, + "column": 4 + }, + "end": { + "line": 68, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4007, + "end": 4014, + "loc": { + "start": { + "line": 68, + "column": 10 + }, + "end": { + "line": 68, + "column": 17 + }, + "identifierName": "created" + }, + "name": "created" + }, + "computed": false + }, + "right": { + "type": "StringLiteral", + "start": 4017, + "end": 4019, + "loc": { + "start": { + "line": 68, + "column": 20 + }, + "end": { + "line": 68, + "column": 22 + } + }, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + }, + { + "type": "ExpressionStatement", + "start": 4025, + "end": 4050, + "loc": { + "start": { + "line": 69, + "column": 4 + }, + "end": { + "line": 69, + "column": 29 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4025, + "end": 4049, + "loc": { + "start": { + "line": 69, + "column": 4 + }, + "end": { + "line": 69, + "column": 28 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4025, + "end": 4045, + "loc": { + "start": { + "line": 69, + "column": 4 + }, + "end": { + "line": 69, + "column": 24 + } + }, + "object": { + "type": "Identifier", + "start": 4025, + "end": 4030, + "loc": { + "start": { + "line": 69, + "column": 4 + }, + "end": { + "line": 69, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4031, + "end": 4045, + "loc": { + "start": { + "line": 69, + "column": 10 + }, + "end": { + "line": 69, + "column": 24 + }, + "identifierName": "numMetaObjects" + }, + "name": "numMetaObjects" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4048, + "end": 4049, + "loc": { + "start": { + "line": 69, + "column": 27 + }, + "end": { + "line": 69, + "column": 28 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4055, + "end": 4081, + "loc": { + "start": { + "line": 70, + "column": 4 + }, + "end": { + "line": 70, + "column": 30 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4055, + "end": 4080, + "loc": { + "start": { + "line": 70, + "column": 4 + }, + "end": { + "line": 70, + "column": 29 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4055, + "end": 4076, + "loc": { + "start": { + "line": 70, + "column": 4 + }, + "end": { + "line": 70, + "column": 25 + } + }, + "object": { + "type": "Identifier", + "start": 4055, + "end": 4060, + "loc": { + "start": { + "line": 70, + "column": 4 + }, + "end": { + "line": 70, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4061, + "end": 4076, + "loc": { + "start": { + "line": 70, + "column": 10 + }, + "end": { + "line": 70, + "column": 25 + }, + "identifierName": "numPropertySets" + }, + "name": "numPropertySets" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4079, + "end": 4080, + "loc": { + "start": { + "line": 70, + "column": 28 + }, + "end": { + "line": 70, + "column": 29 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4086, + "end": 4109, + "loc": { + "start": { + "line": 71, + "column": 4 + }, + "end": { + "line": 71, + "column": 27 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4086, + "end": 4108, + "loc": { + "start": { + "line": 71, + "column": 4 + }, + "end": { + "line": 71, + "column": 26 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4086, + "end": 4104, + "loc": { + "start": { + "line": 71, + "column": 4 + }, + "end": { + "line": 71, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 4086, + "end": 4091, + "loc": { + "start": { + "line": 71, + "column": 4 + }, + "end": { + "line": 71, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4092, + "end": 4104, + "loc": { + "start": { + "line": 71, + "column": 10 + }, + "end": { + "line": 71, + "column": 22 + }, + "identifierName": "numTriangles" + }, + "name": "numTriangles" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4107, + "end": 4108, + "loc": { + "start": { + "line": 71, + "column": 25 + }, + "end": { + "line": 71, + "column": 26 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4114, + "end": 4136, + "loc": { + "start": { + "line": 72, + "column": 4 + }, + "end": { + "line": 72, + "column": 26 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4114, + "end": 4135, + "loc": { + "start": { + "line": 72, + "column": 4 + }, + "end": { + "line": 72, + "column": 25 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4114, + "end": 4131, + "loc": { + "start": { + "line": 72, + "column": 4 + }, + "end": { + "line": 72, + "column": 21 + } + }, + "object": { + "type": "Identifier", + "start": 4114, + "end": 4119, + "loc": { + "start": { + "line": 72, + "column": 4 + }, + "end": { + "line": 72, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4120, + "end": 4131, + "loc": { + "start": { + "line": 72, + "column": 10 + }, + "end": { + "line": 72, + "column": 21 + }, + "identifierName": "numVertices" + }, + "name": "numVertices" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4134, + "end": 4135, + "loc": { + "start": { + "line": 72, + "column": 24 + }, + "end": { + "line": 72, + "column": 25 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4141, + "end": 4162, + "loc": { + "start": { + "line": 73, + "column": 4 + }, + "end": { + "line": 73, + "column": 25 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4141, + "end": 4161, + "loc": { + "start": { + "line": 73, + "column": 4 + }, + "end": { + "line": 73, + "column": 24 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4141, + "end": 4157, + "loc": { + "start": { + "line": 73, + "column": 4 + }, + "end": { + "line": 73, + "column": 20 + } + }, + "object": { + "type": "Identifier", + "start": 4141, + "end": 4146, + "loc": { + "start": { + "line": 73, + "column": 4 + }, + "end": { + "line": 73, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4147, + "end": 4157, + "loc": { + "start": { + "line": 73, + "column": 10 + }, + "end": { + "line": 73, + "column": 20 + }, + "identifierName": "numNormals" + }, + "name": "numNormals" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4160, + "end": 4161, + "loc": { + "start": { + "line": 73, + "column": 23 + }, + "end": { + "line": 73, + "column": 24 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4167, + "end": 4184, + "loc": { + "start": { + "line": 74, + "column": 4 + }, + "end": { + "line": 74, + "column": 21 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4167, + "end": 4183, + "loc": { + "start": { + "line": 74, + "column": 4 + }, + "end": { + "line": 74, + "column": 20 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4167, + "end": 4179, + "loc": { + "start": { + "line": 74, + "column": 4 + }, + "end": { + "line": 74, + "column": 16 + } + }, + "object": { + "type": "Identifier", + "start": 4167, + "end": 4172, + "loc": { + "start": { + "line": 74, + "column": 4 + }, + "end": { + "line": 74, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4173, + "end": 4179, + "loc": { + "start": { + "line": 74, + "column": 10 + }, + "end": { + "line": 74, + "column": 16 + }, + "identifierName": "numUVs" + }, + "name": "numUVs" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4182, + "end": 4183, + "loc": { + "start": { + "line": 74, + "column": 19 + }, + "end": { + "line": 74, + "column": 20 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4189, + "end": 4211, + "loc": { + "start": { + "line": 75, + "column": 4 + }, + "end": { + "line": 75, + "column": 26 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4189, + "end": 4210, + "loc": { + "start": { + "line": 75, + "column": 4 + }, + "end": { + "line": 75, + "column": 25 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4189, + "end": 4206, + "loc": { + "start": { + "line": 75, + "column": 4 + }, + "end": { + "line": 75, + "column": 21 + } + }, + "object": { + "type": "Identifier", + "start": 4189, + "end": 4194, + "loc": { + "start": { + "line": 75, + "column": 4 + }, + "end": { + "line": 75, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4195, + "end": 4206, + "loc": { + "start": { + "line": 75, + "column": 10 + }, + "end": { + "line": 75, + "column": 21 + }, + "identifierName": "numTextures" + }, + "name": "numTextures" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4209, + "end": 4210, + "loc": { + "start": { + "line": 75, + "column": 24 + }, + "end": { + "line": 75, + "column": 25 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4216, + "end": 4241, + "loc": { + "start": { + "line": 76, + "column": 4 + }, + "end": { + "line": 76, + "column": 29 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4216, + "end": 4240, + "loc": { + "start": { + "line": 76, + "column": 4 + }, + "end": { + "line": 76, + "column": 28 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4216, + "end": 4236, + "loc": { + "start": { + "line": 76, + "column": 4 + }, + "end": { + "line": 76, + "column": 24 + } + }, + "object": { + "type": "Identifier", + "start": 4216, + "end": 4221, + "loc": { + "start": { + "line": 76, + "column": 4 + }, + "end": { + "line": 76, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4222, + "end": 4236, + "loc": { + "start": { + "line": 76, + "column": 10 + }, + "end": { + "line": 76, + "column": 24 + }, + "identifierName": "numTextureSets" + }, + "name": "numTextureSets" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4239, + "end": 4240, + "loc": { + "start": { + "line": 76, + "column": 27 + }, + "end": { + "line": 76, + "column": 28 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4246, + "end": 4267, + "loc": { + "start": { + "line": 77, + "column": 4 + }, + "end": { + "line": 77, + "column": 25 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4246, + "end": 4266, + "loc": { + "start": { + "line": 77, + "column": 4 + }, + "end": { + "line": 77, + "column": 24 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4246, + "end": 4262, + "loc": { + "start": { + "line": 77, + "column": 4 + }, + "end": { + "line": 77, + "column": 20 + } + }, + "object": { + "type": "Identifier", + "start": 4246, + "end": 4251, + "loc": { + "start": { + "line": 77, + "column": 4 + }, + "end": { + "line": 77, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4252, + "end": 4262, + "loc": { + "start": { + "line": 77, + "column": 10 + }, + "end": { + "line": 77, + "column": 20 + }, + "identifierName": "numObjects" + }, + "name": "numObjects" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4265, + "end": 4266, + "loc": { + "start": { + "line": 77, + "column": 23 + }, + "end": { + "line": 77, + "column": 24 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4272, + "end": 4296, + "loc": { + "start": { + "line": 78, + "column": 4 + }, + "end": { + "line": 78, + "column": 28 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4272, + "end": 4295, + "loc": { + "start": { + "line": 78, + "column": 4 + }, + "end": { + "line": 78, + "column": 27 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4272, + "end": 4291, + "loc": { + "start": { + "line": 78, + "column": 4 + }, + "end": { + "line": 78, + "column": 23 + } + }, + "object": { + "type": "Identifier", + "start": 4272, + "end": 4277, + "loc": { + "start": { + "line": 78, + "column": 4 + }, + "end": { + "line": 78, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4278, + "end": 4291, + "loc": { + "start": { + "line": 78, + "column": 10 + }, + "end": { + "line": 78, + "column": 23 + }, + "identifierName": "numGeometries" + }, + "name": "numGeometries" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4294, + "end": 4295, + "loc": { + "start": { + "line": 78, + "column": 26 + }, + "end": { + "line": 78, + "column": 27 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4301, + "end": 4322, + "loc": { + "start": { + "line": 79, + "column": 4 + }, + "end": { + "line": 79, + "column": 25 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4301, + "end": 4321, + "loc": { + "start": { + "line": 79, + "column": 4 + }, + "end": { + "line": 79, + "column": 24 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4301, + "end": 4317, + "loc": { + "start": { + "line": 79, + "column": 4 + }, + "end": { + "line": 79, + "column": 20 + } + }, + "object": { + "type": "Identifier", + "start": 4301, + "end": 4306, + "loc": { + "start": { + "line": 79, + "column": 4 + }, + "end": { + "line": 79, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4307, + "end": 4317, + "loc": { + "start": { + "line": 79, + "column": 10 + }, + "end": { + "line": 79, + "column": 20 + }, + "identifierName": "sourceSize" + }, + "name": "sourceSize" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4320, + "end": 4321, + "loc": { + "start": { + "line": 79, + "column": 23 + }, + "end": { + "line": 79, + "column": 24 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4327, + "end": 4345, + "loc": { + "start": { + "line": 80, + "column": 4 + }, + "end": { + "line": 80, + "column": 22 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4327, + "end": 4344, + "loc": { + "start": { + "line": 80, + "column": 4 + }, + "end": { + "line": 80, + "column": 21 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4327, + "end": 4340, + "loc": { + "start": { + "line": 80, + "column": 4 + }, + "end": { + "line": 80, + "column": 17 + } + }, + "object": { + "type": "Identifier", + "start": 4327, + "end": 4332, + "loc": { + "start": { + "line": 80, + "column": 4 + }, + "end": { + "line": 80, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4333, + "end": 4340, + "loc": { + "start": { + "line": 80, + "column": 10 + }, + "end": { + "line": 80, + "column": 17 + }, + "identifierName": "xktSize" + }, + "name": "xktSize" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4343, + "end": 4344, + "loc": { + "start": { + "line": 80, + "column": 20 + }, + "end": { + "line": 80, + "column": 21 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4350, + "end": 4373, + "loc": { + "start": { + "line": 81, + "column": 4 + }, + "end": { + "line": 81, + "column": 27 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4350, + "end": 4372, + "loc": { + "start": { + "line": 81, + "column": 4 + }, + "end": { + "line": 81, + "column": 26 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4350, + "end": 4368, + "loc": { + "start": { + "line": 81, + "column": 4 + }, + "end": { + "line": 81, + "column": 22 + } + }, + "object": { + "type": "Identifier", + "start": 4350, + "end": 4355, + "loc": { + "start": { + "line": 81, + "column": 4 + }, + "end": { + "line": 81, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4356, + "end": 4368, + "loc": { + "start": { + "line": 81, + "column": 10 + }, + "end": { + "line": 81, + "column": 22 + }, + "identifierName": "texturesSize" + }, + "name": "texturesSize" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4371, + "end": 4372, + "loc": { + "start": { + "line": 81, + "column": 25 + }, + "end": { + "line": 81, + "column": 26 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4378, + "end": 4400, + "loc": { + "start": { + "line": 82, + "column": 4 + }, + "end": { + "line": 82, + "column": 26 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4378, + "end": 4399, + "loc": { + "start": { + "line": 82, + "column": 4 + }, + "end": { + "line": 82, + "column": 25 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4378, + "end": 4394, + "loc": { + "start": { + "line": 82, + "column": 4 + }, + "end": { + "line": 82, + "column": 20 + } + }, + "object": { + "type": "Identifier", + "start": 4378, + "end": 4383, + "loc": { + "start": { + "line": 82, + "column": 4 + }, + "end": { + "line": 82, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4384, + "end": 4394, + "loc": { + "start": { + "line": 82, + "column": 10 + }, + "end": { + "line": 82, + "column": 20 + }, + "identifierName": "xktVersion" + }, + "name": "xktVersion" + }, + "computed": false + }, + "right": { + "type": "StringLiteral", + "start": 4397, + "end": 4399, + "loc": { + "start": { + "line": 82, + "column": 23 + }, + "end": { + "line": 82, + "column": 25 + } + }, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + }, + { + "type": "ExpressionStatement", + "start": 4405, + "end": 4432, + "loc": { + "start": { + "line": 83, + "column": 4 + }, + "end": { + "line": 83, + "column": 31 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4405, + "end": 4431, + "loc": { + "start": { + "line": 83, + "column": 4 + }, + "end": { + "line": 83, + "column": 30 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4405, + "end": 4427, + "loc": { + "start": { + "line": 83, + "column": 4 + }, + "end": { + "line": 83, + "column": 26 + } + }, + "object": { + "type": "Identifier", + "start": 4405, + "end": 4410, + "loc": { + "start": { + "line": 83, + "column": 4 + }, + "end": { + "line": 83, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4411, + "end": 4427, + "loc": { + "start": { + "line": 83, + "column": 10 + }, + "end": { + "line": 83, + "column": 26 + }, + "identifierName": "compressionRatio" + }, + "name": "compressionRatio" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4430, + "end": 4431, + "loc": { + "start": { + "line": 83, + "column": 29 + }, + "end": { + "line": 83, + "column": 30 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4437, + "end": 4462, + "loc": { + "start": { + "line": 84, + "column": 4 + }, + "end": { + "line": 84, + "column": 29 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4437, + "end": 4461, + "loc": { + "start": { + "line": 84, + "column": 4 + }, + "end": { + "line": 84, + "column": 28 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4437, + "end": 4457, + "loc": { + "start": { + "line": 84, + "column": 4 + }, + "end": { + "line": 84, + "column": 24 + } + }, + "object": { + "type": "Identifier", + "start": 4437, + "end": 4442, + "loc": { + "start": { + "line": 84, + "column": 4 + }, + "end": { + "line": 84, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4443, + "end": 4457, + "loc": { + "start": { + "line": 84, + "column": 10 + }, + "end": { + "line": 84, + "column": 24 + }, + "identifierName": "conversionTime" + }, + "name": "conversionTime" + }, + "computed": false + }, + "right": { + "type": "NumericLiteral", + "start": 4460, + "end": 4461, + "loc": { + "start": { + "line": 84, + "column": 27 + }, + "end": { + "line": 84, + "column": 28 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + }, + { + "type": "ExpressionStatement", + "start": 4467, + "end": 4485, + "loc": { + "start": { + "line": 85, + "column": 4 + }, + "end": { + "line": 85, + "column": 22 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4467, + "end": 4484, + "loc": { + "start": { + "line": 85, + "column": 4 + }, + "end": { + "line": 85, + "column": 21 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 4467, + "end": 4477, + "loc": { + "start": { + "line": 85, + "column": 4 + }, + "end": { + "line": 85, + "column": 14 + } + }, + "object": { + "type": "Identifier", + "start": 4467, + "end": 4472, + "loc": { + "start": { + "line": 85, + "column": 4 + }, + "end": { + "line": 85, + "column": 9 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "property": { + "type": "Identifier", + "start": 4473, + "end": 4477, + "loc": { + "start": { + "line": 85, + "column": 10 + }, + "end": { + "line": 85, + "column": 14 + }, + "identifierName": "aabb" + }, + "name": "aabb" + }, + "computed": false + }, + "right": { + "type": "NullLiteral", + "start": 4480, + "end": 4484, + "loc": { + "start": { + "line": 85, + "column": 17 + }, + "end": { + "line": 85, + "column": 21 + } + } + } + } + }, + { + "type": "ReturnStatement", + "start": 4491, + "end": 7491, + "loc": { + "start": { + "line": 87, + "column": 4 + }, + "end": { + "line": 186, + "column": 7 + } + }, + "argument": { + "type": "NewExpression", + "start": 4498, + "end": 7490, + "loc": { + "start": { + "line": 87, + "column": 11 + }, + "end": { + "line": 186, + "column": 6 + } + }, + "callee": { + "type": "Identifier", + "start": 4502, + "end": 4509, + "loc": { + "start": { + "line": 87, + "column": 15 + }, + "end": { + "line": 87, + "column": 22 + }, + "identifierName": "Promise" + }, + "name": "Promise" + }, + "arguments": [ + { + "type": "FunctionExpression", + "start": 4510, + "end": 7489, + "loc": { + "start": { + "line": 87, + "column": 23 + }, + "end": { + "line": 186, + "column": 5 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 4520, + "end": 4527, + "loc": { + "start": { + "line": 87, + "column": 33 + }, + "end": { + "line": 87, + "column": 40 + }, + "identifierName": "resolve" + }, + "name": "resolve" + }, + { + "type": "Identifier", + "start": 4529, + "end": 4535, + "loc": { + "start": { + "line": 87, + "column": 42 + }, + "end": { + "line": 87, + "column": 48 + }, + "identifierName": "reject" + }, + "name": "reject" + } + ], + "body": { + "type": "BlockStatement", + "start": 4537, + "end": 7489, + "loc": { + "start": { + "line": 87, + "column": 50 + }, + "end": { + "line": 186, + "column": 5 + } + }, + "body": [ + { + "type": "VariableDeclaration", + "start": 4547, + "end": 4564, + "loc": { + "start": { + "line": 88, + "column": 8 + }, + "end": { + "line": 88, + "column": 25 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 4553, + "end": 4563, + "loc": { + "start": { + "line": 88, + "column": 14 + }, + "end": { + "line": 88, + "column": 24 + } + }, + "id": { + "type": "Identifier", + "start": 4553, + "end": 4557, + "loc": { + "start": { + "line": 88, + "column": 14 + }, + "end": { + "line": 88, + "column": 18 + }, + "identifierName": "_log" + }, + "name": "_log" + }, + "init": { + "type": "Identifier", + "start": 4560, + "end": 4563, + "loc": { + "start": { + "line": 88, + "column": 21 + }, + "end": { + "line": 88, + "column": 24 + }, + "identifierName": "log" + }, + "name": "log" + } + } + ], + "kind": "const" + }, + { + "type": "ExpressionStatement", + "start": 4573, + "end": 4640, + "loc": { + "start": { + "line": 89, + "column": 8 + }, + "end": { + "line": 91, + "column": 9 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 4573, + "end": 4640, + "loc": { + "start": { + "line": 89, + "column": 8 + }, + "end": { + "line": 91, + "column": 9 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 4573, + "end": 4576, + "loc": { + "start": { + "line": 89, + "column": 8 + }, + "end": { + "line": 89, + "column": 11 + }, + "identifierName": "log" + }, + "name": "log" + }, + "right": { + "type": "ArrowFunctionExpression", + "start": 4579, + "end": 4640, + "loc": { + "start": { + "line": 89, + "column": 14 + }, + "end": { + "line": 91, + "column": 9 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 4580, + "end": 4583, + "loc": { + "start": { + "line": 89, + "column": 15 + }, + "end": { + "line": 89, + "column": 18 + }, + "identifierName": "msg" + }, + "name": "msg" + } + ], + "body": { + "type": "BlockStatement", + "start": 4588, + "end": 4640, + "loc": { + "start": { + "line": 89, + "column": 23 + }, + "end": { + "line": 91, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 4602, + "end": 4630, + "loc": { + "start": { + "line": 90, + "column": 12 + }, + "end": { + "line": 90, + "column": 40 + } + }, + "expression": { + "type": "CallExpression", + "start": 4602, + "end": 4630, + "loc": { + "start": { + "line": 90, + "column": 12 + }, + "end": { + "line": 90, + "column": 40 + } + }, + "callee": { + "type": "Identifier", + "start": 4602, + "end": 4606, + "loc": { + "start": { + "line": 90, + "column": 12 + }, + "end": { + "line": 90, + "column": 16 + }, + "identifierName": "_log" + }, + "name": "_log" + }, + "arguments": [ + { + "type": "TemplateLiteral", + "start": 4607, + "end": 4629, + "loc": { + "start": { + "line": 90, + "column": 17 + }, + "end": { + "line": 90, + "column": 39 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 4624, + "end": 4627, + "loc": { + "start": { + "line": 90, + "column": 34 + }, + "end": { + "line": 90, + "column": 37 + }, + "identifierName": "msg" + }, + "name": "msg" + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 4608, + "end": 4622, + "loc": { + "start": { + "line": 90, + "column": 18 + }, + "end": { + "line": 90, + "column": 32 + } + }, + "value": { + "raw": "[convert2xkt] ", + "cooked": "[convert2xkt] " + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 4628, + "end": 4628, + "loc": { + "start": { + "line": 90, + "column": 38 + }, + "end": { + "line": 90, + "column": 38 + } + }, + "value": { + "raw": "", + "cooked": "" + }, + "tail": true + } + ] + } + ] + } + } + ], + "directives": [] + } + } + } + }, + { + "type": "IfStatement", + "start": 4650, + "end": 4761, + "loc": { + "start": { + "line": 93, + "column": 8 + }, + "end": { + "line": 96, + "column": 9 + } + }, + "test": { + "type": "UnaryExpression", + "start": 4654, + "end": 4665, + "loc": { + "start": { + "line": 93, + "column": 12 + }, + "end": { + "line": 93, + "column": 23 + } + }, + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 4655, + "end": 4665, + "loc": { + "start": { + "line": 93, + "column": 13 + }, + "end": { + "line": 93, + "column": 23 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + }, + "extra": { + "parenthesizedArgument": false + } + }, + "consequent": { + "type": "BlockStatement", + "start": 4667, + "end": 4761, + "loc": { + "start": { + "line": 93, + "column": 25 + }, + "end": { + "line": 96, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 4681, + "end": 4731, + "loc": { + "start": { + "line": 94, + "column": 12 + }, + "end": { + "line": 94, + "column": 62 + } + }, + "expression": { + "type": "CallExpression", + "start": 4681, + "end": 4730, + "loc": { + "start": { + "line": 94, + "column": 12 + }, + "end": { + "line": 94, + "column": 61 + } + }, + "callee": { + "type": "Identifier", + "start": 4681, + "end": 4687, + "loc": { + "start": { + "line": 94, + "column": 12 + }, + "end": { + "line": 94, + "column": 18 + }, + "identifierName": "reject" + }, + "name": "reject" + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 4688, + "end": 4729, + "loc": { + "start": { + "line": 94, + "column": 19 + }, + "end": { + "line": 94, + "column": 60 + } + }, + "extra": { + "rawValue": "Argument expected: source or sourceData", + "raw": "\"Argument expected: source or sourceData\"" + }, + "value": "Argument expected: source or sourceData" + } + ] + } + }, + { + "type": "ReturnStatement", + "start": 4744, + "end": 4751, + "loc": { + "start": { + "line": 95, + "column": 12 + }, + "end": { + "line": 95, + "column": 19 + } + }, + "argument": null + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "IfStatement", + "start": 4771, + "end": 4915, + "loc": { + "start": { + "line": 98, + "column": 8 + }, + "end": { + "line": 101, + "column": 9 + } + }, + "test": { + "type": "LogicalExpression", + "start": 4775, + "end": 4804, + "loc": { + "start": { + "line": 98, + "column": 12 + }, + "end": { + "line": 98, + "column": 41 + } + }, + "left": { + "type": "UnaryExpression", + "start": 4775, + "end": 4790, + "loc": { + "start": { + "line": 98, + "column": 12 + }, + "end": { + "line": 98, + "column": 27 + } + }, + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 4776, + "end": 4790, + "loc": { + "start": { + "line": 98, + "column": 13 + }, + "end": { + "line": 98, + "column": 27 + }, + "identifierName": "outputXKTModel" + }, + "name": "outputXKTModel" + }, + "extra": { + "parenthesizedArgument": false + } + }, + "operator": "&&", + "right": { + "type": "UnaryExpression", + "start": 4794, + "end": 4804, + "loc": { + "start": { + "line": 98, + "column": 31 + }, + "end": { + "line": 98, + "column": 41 + } + }, + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 4795, + "end": 4804, + "loc": { + "start": { + "line": 98, + "column": 32 + }, + "end": { + "line": 98, + "column": 41 + }, + "identifierName": "outputXKT" + }, + "name": "outputXKT" + }, + "extra": { + "parenthesizedArgument": false + } + } + }, + "consequent": { + "type": "BlockStatement", + "start": 4806, + "end": 4915, + "loc": { + "start": { + "line": 98, + "column": 43 + }, + "end": { + "line": 101, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 4820, + "end": 4885, + "loc": { + "start": { + "line": 99, + "column": 12 + }, + "end": { + "line": 99, + "column": 77 + } + }, + "expression": { + "type": "CallExpression", + "start": 4820, + "end": 4884, + "loc": { + "start": { + "line": 99, + "column": 12 + }, + "end": { + "line": 99, + "column": 76 + } + }, + "callee": { + "type": "Identifier", + "start": 4820, + "end": 4826, + "loc": { + "start": { + "line": 99, + "column": 12 + }, + "end": { + "line": 99, + "column": 18 + }, + "identifierName": "reject" + }, + "name": "reject" + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 4827, + "end": 4883, + "loc": { + "start": { + "line": 99, + "column": 19 + }, + "end": { + "line": 99, + "column": 75 + } + }, + "extra": { + "rawValue": "Argument expected: output, outputXKTModel or outputXKT", + "raw": "\"Argument expected: output, outputXKTModel or outputXKT\"" + }, + "value": "Argument expected: output, outputXKTModel or outputXKT" + } + ] + } + }, + { + "type": "ReturnStatement", + "start": 4898, + "end": 4905, + "loc": { + "start": { + "line": 100, + "column": 12 + }, + "end": { + "line": 100, + "column": 19 + } + }, + "argument": null + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "VariableDeclaration", + "start": 4925, + "end": 4975, + "loc": { + "start": { + "line": 103, + "column": 8 + }, + "end": { + "line": 103, + "column": 58 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 4931, + "end": 4974, + "loc": { + "start": { + "line": 103, + "column": 14 + }, + "end": { + "line": 103, + "column": 57 + } + }, + "id": { + "type": "Identifier", + "start": 4931, + "end": 4944, + "loc": { + "start": { + "line": 103, + "column": 14 + }, + "end": { + "line": 103, + "column": 27 + }, + "identifierName": "sourceConfigs" + }, + "name": "sourceConfigs" + }, + "init": { + "type": "LogicalExpression", + "start": 4947, + "end": 4974, + "loc": { + "start": { + "line": 103, + "column": 30 + }, + "end": { + "line": 103, + "column": 57 + } + }, + "left": { + "type": "MemberExpression", + "start": 4947, + "end": 4968, + "loc": { + "start": { + "line": 103, + "column": 30 + }, + "end": { + "line": 103, + "column": 51 + } + }, + "object": { + "type": "Identifier", + "start": 4947, + "end": 4954, + "loc": { + "start": { + "line": 103, + "column": 30 + }, + "end": { + "line": 103, + "column": 37 + }, + "identifierName": "configs" + }, + "name": "configs" + }, + "property": { + "type": "Identifier", + "start": 4955, + "end": 4968, + "loc": { + "start": { + "line": 103, + "column": 38 + }, + "end": { + "line": 103, + "column": 51 + }, + "identifierName": "sourceConfigs" + }, + "name": "sourceConfigs" + }, + "computed": false + }, + "operator": "||", + "right": { + "type": "ObjectExpression", + "start": 4972, + "end": 4974, + "loc": { + "start": { + "line": 103, + "column": 55 + }, + "end": { + "line": 103, + "column": 57 + } + }, + "properties": [] + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 4984, + "end": 5002, + "loc": { + "start": { + "line": 104, + "column": 8 + }, + "end": { + "line": 104, + "column": 26 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 4990, + "end": 5001, + "loc": { + "start": { + "line": 104, + "column": 14 + }, + "end": { + "line": 104, + "column": 25 + } + }, + "id": { + "type": "Identifier", + "start": 4990, + "end": 4993, + "loc": { + "start": { + "line": 104, + "column": 14 + }, + "end": { + "line": 104, + "column": 17 + }, + "identifierName": "ext" + }, + "name": "ext" + }, + "init": { + "type": "StringLiteral", + "start": 4996, + "end": 5001, + "loc": { + "start": { + "line": 104, + "column": 20 + }, + "end": { + "line": 104, + "column": 25 + } + }, + "extra": { + "rawValue": "glb", + "raw": "'glb'" + }, + "value": "glb" + } + } + ], + "kind": "const" + }, + { + "type": "ExpressionStatement", + "start": 5012, + "end": 5050, + "loc": { + "start": { + "line": 106, + "column": 8 + }, + "end": { + "line": 106, + "column": 46 + } + }, + "expression": { + "type": "CallExpression", + "start": 5012, + "end": 5049, + "loc": { + "start": { + "line": 106, + "column": 8 + }, + "end": { + "line": 106, + "column": 45 + } + }, + "callee": { + "type": "Identifier", + "start": 5012, + "end": 5015, + "loc": { + "start": { + "line": 106, + "column": 8 + }, + "end": { + "line": 106, + "column": 11 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "TemplateLiteral", + "start": 5016, + "end": 5048, + "loc": { + "start": { + "line": 106, + "column": 12 + }, + "end": { + "line": 106, + "column": 44 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 5042, + "end": 5045, + "loc": { + "start": { + "line": 106, + "column": 38 + }, + "end": { + "line": 106, + "column": 41 + }, + "identifierName": "ext" + }, + "name": "ext" + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 5017, + "end": 5040, + "loc": { + "start": { + "line": 106, + "column": 13 + }, + "end": { + "line": 106, + "column": 36 + } + }, + "value": { + "raw": "Input file extension: \"", + "cooked": "Input file extension: \"" + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 5046, + "end": 5047, + "loc": { + "start": { + "line": 106, + "column": 42 + }, + "end": { + "line": 106, + "column": 43 + } + }, + "value": { + "raw": "\"", + "cooked": "\"" + }, + "tail": true + } + ] + } + ] + } + }, + { + "type": "VariableDeclaration", + "start": 5060, + "end": 5101, + "loc": { + "start": { + "line": 108, + "column": 8 + }, + "end": { + "line": 108, + "column": 49 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 5064, + "end": 5100, + "loc": { + "start": { + "line": 108, + "column": 12 + }, + "end": { + "line": 108, + "column": 48 + } + }, + "id": { + "type": "Identifier", + "start": 5064, + "end": 5079, + "loc": { + "start": { + "line": 108, + "column": 12 + }, + "end": { + "line": 108, + "column": 27 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "init": { + "type": "MemberExpression", + "start": 5082, + "end": 5100, + "loc": { + "start": { + "line": 108, + "column": 30 + }, + "end": { + "line": 108, + "column": 48 + } + }, + "object": { + "type": "Identifier", + "start": 5082, + "end": 5095, + "loc": { + "start": { + "line": 108, + "column": 30 + }, + "end": { + "line": 108, + "column": 43 + }, + "identifierName": "sourceConfigs" + }, + "name": "sourceConfigs" + }, + "property": { + "type": "Identifier", + "start": 5096, + "end": 5099, + "loc": { + "start": { + "line": 108, + "column": 44 + }, + "end": { + "line": 108, + "column": 47 + }, + "identifierName": "ext" + }, + "name": "ext" + }, + "computed": true + } + } + ], + "kind": "let" + }, + { + "type": "IfStatement", + "start": 5111, + "end": 5367, + "loc": { + "start": { + "line": 110, + "column": 8 + }, + "end": { + "line": 113, + "column": 9 + } + }, + "test": { + "type": "UnaryExpression", + "start": 5115, + "end": 5131, + "loc": { + "start": { + "line": 110, + "column": 12 + }, + "end": { + "line": 110, + "column": 28 + } + }, + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 5116, + "end": 5131, + "loc": { + "start": { + "line": 110, + "column": 13 + }, + "end": { + "line": 110, + "column": 28 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "extra": { + "parenthesizedArgument": false + } + }, + "consequent": { + "type": "BlockStatement", + "start": 5133, + "end": 5367, + "loc": { + "start": { + "line": 110, + "column": 30 + }, + "end": { + "line": 113, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 5147, + "end": 5323, + "loc": { + "start": { + "line": 111, + "column": 12 + }, + "end": { + "line": 111, + "column": 188 + } + }, + "expression": { + "type": "CallExpression", + "start": 5147, + "end": 5322, + "loc": { + "start": { + "line": 111, + "column": 12 + }, + "end": { + "line": 111, + "column": 187 + } + }, + "callee": { + "type": "Identifier", + "start": 5147, + "end": 5150, + "loc": { + "start": { + "line": 111, + "column": 12 + }, + "end": { + "line": 111, + "column": 15 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "TemplateLiteral", + "start": 5151, + "end": 5321, + "loc": { + "start": { + "line": 111, + "column": 16 + }, + "end": { + "line": 111, + "column": 186 + } + }, + "expressions": [ + { + "type": "Identifier", + "start": 5226, + "end": 5229, + "loc": { + "start": { + "line": 111, + "column": 91 + }, + "end": { + "line": 111, + "column": 94 + }, + "identifierName": "ext" + }, + "name": "ext" + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 5152, + "end": 5224, + "loc": { + "start": { + "line": 111, + "column": 17 + }, + "end": { + "line": 111, + "column": 89 + } + }, + "value": { + "raw": "[WARNING] Could not find configs sourceConfigs entry for source format \"", + "cooked": "[WARNING] Could not find configs sourceConfigs entry for source format \"" + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 5230, + "end": 5320, + "loc": { + "start": { + "line": 111, + "column": 95 + }, + "end": { + "line": 111, + "column": 185 + } + }, + "value": { + "raw": "\". This is derived from the source file name extension. Will use internal default configs.", + "cooked": "\". This is derived from the source file name extension. Will use internal default configs." + }, + "tail": true + } + ] + } + ] + } + }, + { + "type": "ExpressionStatement", + "start": 5336, + "end": 5357, + "loc": { + "start": { + "line": 112, + "column": 12 + }, + "end": { + "line": 112, + "column": 33 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 5336, + "end": 5356, + "loc": { + "start": { + "line": 112, + "column": 12 + }, + "end": { + "line": 112, + "column": 32 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 5336, + "end": 5351, + "loc": { + "start": { + "line": 112, + "column": 12 + }, + "end": { + "line": 112, + "column": 27 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "right": { + "type": "ObjectExpression", + "start": 5354, + "end": 5356, + "loc": { + "start": { + "line": 112, + "column": 30 + }, + "end": { + "line": 112, + "column": 32 + } + }, + "properties": [] + } + } + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "FunctionDeclaration", + "start": 5377, + "end": 5545, + "loc": { + "start": { + "line": 115, + "column": 8 + }, + "end": { + "line": 120, + "column": 9 + } + }, + "id": { + "type": "Identifier", + "start": 5386, + "end": 5400, + "loc": { + "start": { + "line": 115, + "column": 17 + }, + "end": { + "line": 115, + "column": 31 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 5401, + "end": 5408, + "loc": { + "start": { + "line": 115, + "column": 32 + }, + "end": { + "line": 115, + "column": 39 + }, + "identifierName": "option1" + }, + "name": "option1" + }, + { + "type": "Identifier", + "start": 5410, + "end": 5417, + "loc": { + "start": { + "line": 115, + "column": 41 + }, + "end": { + "line": 115, + "column": 48 + }, + "identifierName": "option2" + }, + "name": "option2" + } + ], + "body": { + "type": "BlockStatement", + "start": 5419, + "end": 5545, + "loc": { + "start": { + "line": 115, + "column": 50 + }, + "end": { + "line": 120, + "column": 9 + } + }, + "body": [ + { + "type": "IfStatement", + "start": 5433, + "end": 5507, + "loc": { + "start": { + "line": 116, + "column": 12 + }, + "end": { + "line": 118, + "column": 13 + } + }, + "test": { + "type": "BinaryExpression", + "start": 5437, + "end": 5458, + "loc": { + "start": { + "line": 116, + "column": 16 + }, + "end": { + "line": 116, + "column": 37 + } + }, + "left": { + "type": "Identifier", + "start": 5437, + "end": 5444, + "loc": { + "start": { + "line": 116, + "column": 16 + }, + "end": { + "line": 116, + "column": 23 + }, + "identifierName": "option1" + }, + "name": "option1" + }, + "operator": "!==", + "right": { + "type": "Identifier", + "start": 5449, + "end": 5458, + "loc": { + "start": { + "line": 116, + "column": 28 + }, + "end": { + "line": 116, + "column": 37 + }, + "identifierName": "undefined" + }, + "name": "undefined" + } + }, + "consequent": { + "type": "BlockStatement", + "start": 5460, + "end": 5507, + "loc": { + "start": { + "line": 116, + "column": 39 + }, + "end": { + "line": 118, + "column": 13 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 5478, + "end": 5493, + "loc": { + "start": { + "line": 117, + "column": 16 + }, + "end": { + "line": 117, + "column": 31 + } + }, + "argument": { + "type": "Identifier", + "start": 5485, + "end": 5492, + "loc": { + "start": { + "line": 117, + "column": 23 + }, + "end": { + "line": 117, + "column": 30 + }, + "identifierName": "option1" + }, + "name": "option1" + } + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "ReturnStatement", + "start": 5520, + "end": 5535, + "loc": { + "start": { + "line": 119, + "column": 12 + }, + "end": { + "line": 119, + "column": 27 + } + }, + "argument": { + "type": "Identifier", + "start": 5527, + "end": 5534, + "loc": { + "start": { + "line": 119, + "column": 19 + }, + "end": { + "line": 119, + "column": 26 + }, + "identifierName": "option2" + }, + "name": "option2" + } + } + ], + "directives": [] + } + }, + { + "type": "VariableDeclaration", + "start": 5556, + "end": 5606, + "loc": { + "start": { + "line": 123, + "column": 8 + }, + "end": { + "line": 123, + "column": 58 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 5562, + "end": 5605, + "loc": { + "start": { + "line": 123, + "column": 14 + }, + "end": { + "line": 123, + "column": 57 + } + }, + "id": { + "type": "Identifier", + "start": 5562, + "end": 5581, + "loc": { + "start": { + "line": 123, + "column": 14 + }, + "end": { + "line": 123, + "column": 33 + }, + "identifierName": "sourceFileSizeBytes" + }, + "name": "sourceFileSizeBytes" + }, + "init": { + "type": "MemberExpression", + "start": 5584, + "end": 5605, + "loc": { + "start": { + "line": 123, + "column": 36 + }, + "end": { + "line": 123, + "column": 57 + } + }, + "object": { + "type": "Identifier", + "start": 5584, + "end": 5594, + "loc": { + "start": { + "line": 123, + "column": 36 + }, + "end": { + "line": 123, + "column": 46 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + }, + "property": { + "type": "Identifier", + "start": 5595, + "end": 5605, + "loc": { + "start": { + "line": 123, + "column": 47 + }, + "end": { + "line": 123, + "column": 57 + }, + "identifierName": "byteLength" + }, + "name": "byteLength" + }, + "computed": false + } + } + ], + "kind": "const" + }, + { + "type": "ExpressionStatement", + "start": 5616, + "end": 5691, + "loc": { + "start": { + "line": 125, + "column": 8 + }, + "end": { + "line": 125, + "column": 83 + } + }, + "expression": { + "type": "CallExpression", + "start": 5616, + "end": 5690, + "loc": { + "start": { + "line": 125, + "column": 8 + }, + "end": { + "line": 125, + "column": 82 + } + }, + "callee": { + "type": "Identifier", + "start": 5616, + "end": 5619, + "loc": { + "start": { + "line": 125, + "column": 8 + }, + "end": { + "line": 125, + "column": 11 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "BinaryExpression", + "start": 5620, + "end": 5689, + "loc": { + "start": { + "line": 125, + "column": 12 + }, + "end": { + "line": 125, + "column": 81 + } + }, + "left": { + "type": "BinaryExpression", + "start": 5620, + "end": 5681, + "loc": { + "start": { + "line": 125, + "column": 12 + }, + "end": { + "line": 125, + "column": 73 + } + }, + "left": { + "type": "StringLiteral", + "start": 5620, + "end": 5639, + "loc": { + "start": { + "line": 125, + "column": 12 + }, + "end": { + "line": 125, + "column": 31 + } + }, + "extra": { + "rawValue": "Input file size: ", + "raw": "\"Input file size: \"" + }, + "value": "Input file size: " + }, + "operator": "+", + "right": { + "type": "CallExpression", + "start": 5642, + "end": 5681, + "loc": { + "start": { + "line": 125, + "column": 34 + }, + "end": { + "line": 125, + "column": 73 + } + }, + "callee": { + "type": "MemberExpression", + "start": 5642, + "end": 5678, + "loc": { + "start": { + "line": 125, + "column": 34 + }, + "end": { + "line": 125, + "column": 70 + } + }, + "object": { + "type": "BinaryExpression", + "start": 5643, + "end": 5669, + "loc": { + "start": { + "line": 125, + "column": 35 + }, + "end": { + "line": 125, + "column": 61 + } + }, + "left": { + "type": "Identifier", + "start": 5643, + "end": 5662, + "loc": { + "start": { + "line": 125, + "column": 35 + }, + "end": { + "line": 125, + "column": 54 + }, + "identifierName": "sourceFileSizeBytes" + }, + "name": "sourceFileSizeBytes" + }, + "operator": "/", + "right": { + "type": "NumericLiteral", + "start": 5665, + "end": 5669, + "loc": { + "start": { + "line": 125, + "column": 57 + }, + "end": { + "line": 125, + "column": 61 + } + }, + "extra": { + "rawValue": 1000, + "raw": "1000" + }, + "value": 1000 + }, + "extra": { + "parenthesized": true, + "parenStart": 5642 + } + }, + "property": { + "type": "Identifier", + "start": 5671, + "end": 5678, + "loc": { + "start": { + "line": 125, + "column": 63 + }, + "end": { + "line": 125, + "column": 70 + }, + "identifierName": "toFixed" + }, + "name": "toFixed" + }, + "computed": false + }, + "arguments": [ + { + "type": "NumericLiteral", + "start": 5679, + "end": 5680, + "loc": { + "start": { + "line": 125, + "column": 71 + }, + "end": { + "line": 125, + "column": 72 + } + }, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + } + ] + } + }, + "operator": "+", + "right": { + "type": "StringLiteral", + "start": 5684, + "end": 5689, + "loc": { + "start": { + "line": 125, + "column": 76 + }, + "end": { + "line": 125, + "column": 81 + } + }, + "extra": { + "rawValue": " kB", + "raw": "\" kB\"" + }, + "value": " kB" + } + } + ] + } + }, + { + "type": "ExpressionStatement", + "start": 5703, + "end": 5774, + "loc": { + "start": { + "line": 129, + "column": 8 + }, + "end": { + "line": 129, + "column": 79 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 5703, + "end": 5773, + "loc": { + "start": { + "line": 129, + "column": 8 + }, + "end": { + "line": 129, + "column": 78 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 5703, + "end": 5714, + "loc": { + "start": { + "line": 129, + "column": 8 + }, + "end": { + "line": 129, + "column": 19 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "right": { + "type": "CallExpression", + "start": 5717, + "end": 5773, + "loc": { + "start": { + "line": 129, + "column": 22 + }, + "end": { + "line": 129, + "column": 78 + } + }, + "callee": { + "type": "Identifier", + "start": 5717, + "end": 5731, + "loc": { + "start": { + "line": 129, + "column": 22 + }, + "end": { + "line": 129, + "column": 36 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 5732, + "end": 5759, + "loc": { + "start": { + "line": 129, + "column": 37 + }, + "end": { + "line": 129, + "column": 64 + } + }, + "object": { + "type": "Identifier", + "start": 5732, + "end": 5747, + "loc": { + "start": { + "line": 129, + "column": 37 + }, + "end": { + "line": 129, + "column": 52 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 5748, + "end": 5759, + "loc": { + "start": { + "line": 129, + "column": 53 + }, + "end": { + "line": 129, + "column": 64 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 5761, + "end": 5772, + "loc": { + "start": { + "line": 129, + "column": 66 + }, + "end": { + "line": 129, + "column": 77 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 5783, + "end": 5842, + "loc": { + "start": { + "line": 130, + "column": 8 + }, + "end": { + "line": 130, + "column": 67 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 5783, + "end": 5841, + "loc": { + "start": { + "line": 130, + "column": 8 + }, + "end": { + "line": 130, + "column": 66 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 5783, + "end": 5790, + "loc": { + "start": { + "line": 130, + "column": 8 + }, + "end": { + "line": 130, + "column": 15 + }, + "identifierName": "rotateX" + }, + "name": "rotateX" + }, + "right": { + "type": "CallExpression", + "start": 5793, + "end": 5841, + "loc": { + "start": { + "line": 130, + "column": 18 + }, + "end": { + "line": 130, + "column": 66 + } + }, + "callee": { + "type": "Identifier", + "start": 5793, + "end": 5807, + "loc": { + "start": { + "line": 130, + "column": 18 + }, + "end": { + "line": 130, + "column": 32 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 5808, + "end": 5831, + "loc": { + "start": { + "line": 130, + "column": 33 + }, + "end": { + "line": 130, + "column": 56 + } + }, + "object": { + "type": "Identifier", + "start": 5808, + "end": 5823, + "loc": { + "start": { + "line": 130, + "column": 33 + }, + "end": { + "line": 130, + "column": 48 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 5824, + "end": 5831, + "loc": { + "start": { + "line": 130, + "column": 49 + }, + "end": { + "line": 130, + "column": 56 + }, + "identifierName": "rotateX" + }, + "name": "rotateX" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 5833, + "end": 5840, + "loc": { + "start": { + "line": 130, + "column": 58 + }, + "end": { + "line": 130, + "column": 65 + }, + "identifierName": "rotateX" + }, + "name": "rotateX" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 5851, + "end": 5934, + "loc": { + "start": { + "line": 131, + "column": 8 + }, + "end": { + "line": 131, + "column": 91 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 5851, + "end": 5933, + "loc": { + "start": { + "line": 131, + "column": 8 + }, + "end": { + "line": 131, + "column": 90 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 5851, + "end": 5866, + "loc": { + "start": { + "line": 131, + "column": 8 + }, + "end": { + "line": 131, + "column": 23 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "right": { + "type": "CallExpression", + "start": 5869, + "end": 5933, + "loc": { + "start": { + "line": 131, + "column": 26 + }, + "end": { + "line": 131, + "column": 90 + } + }, + "callee": { + "type": "Identifier", + "start": 5869, + "end": 5883, + "loc": { + "start": { + "line": 131, + "column": 26 + }, + "end": { + "line": 131, + "column": 40 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 5884, + "end": 5915, + "loc": { + "start": { + "line": 131, + "column": 41 + }, + "end": { + "line": 131, + "column": 72 + } + }, + "object": { + "type": "Identifier", + "start": 5884, + "end": 5899, + "loc": { + "start": { + "line": 131, + "column": 41 + }, + "end": { + "line": 131, + "column": 56 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 5900, + "end": 5915, + "loc": { + "start": { + "line": 131, + "column": 57 + }, + "end": { + "line": 131, + "column": 72 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 5917, + "end": 5932, + "loc": { + "start": { + "line": 131, + "column": 74 + }, + "end": { + "line": 131, + "column": 89 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 5943, + "end": 6026, + "loc": { + "start": { + "line": 132, + "column": 8 + }, + "end": { + "line": 132, + "column": 91 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 5943, + "end": 6025, + "loc": { + "start": { + "line": 132, + "column": 8 + }, + "end": { + "line": 132, + "column": 90 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 5943, + "end": 5958, + "loc": { + "start": { + "line": 132, + "column": 8 + }, + "end": { + "line": 132, + "column": 23 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + }, + "right": { + "type": "CallExpression", + "start": 5961, + "end": 6025, + "loc": { + "start": { + "line": 132, + "column": 26 + }, + "end": { + "line": 132, + "column": 90 + } + }, + "callee": { + "type": "Identifier", + "start": 5961, + "end": 5975, + "loc": { + "start": { + "line": 132, + "column": 26 + }, + "end": { + "line": 132, + "column": 40 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 5976, + "end": 6007, + "loc": { + "start": { + "line": 132, + "column": 41 + }, + "end": { + "line": 132, + "column": 72 + } + }, + "object": { + "type": "Identifier", + "start": 5976, + "end": 5991, + "loc": { + "start": { + "line": 132, + "column": 41 + }, + "end": { + "line": 132, + "column": 56 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 5992, + "end": 6007, + "loc": { + "start": { + "line": 132, + "column": 57 + }, + "end": { + "line": 132, + "column": 72 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 6009, + "end": 6024, + "loc": { + "start": { + "line": 132, + "column": 74 + }, + "end": { + "line": 132, + "column": 89 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 6035, + "end": 6115, + "loc": { + "start": { + "line": 133, + "column": 8 + }, + "end": { + "line": 133, + "column": 88 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 6035, + "end": 6114, + "loc": { + "start": { + "line": 133, + "column": 8 + }, + "end": { + "line": 133, + "column": 87 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 6035, + "end": 6049, + "loc": { + "start": { + "line": 133, + "column": 8 + }, + "end": { + "line": 133, + "column": 22 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "right": { + "type": "CallExpression", + "start": 6052, + "end": 6114, + "loc": { + "start": { + "line": 133, + "column": 25 + }, + "end": { + "line": 133, + "column": 87 + } + }, + "callee": { + "type": "Identifier", + "start": 6052, + "end": 6066, + "loc": { + "start": { + "line": 133, + "column": 25 + }, + "end": { + "line": 133, + "column": 39 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 6067, + "end": 6097, + "loc": { + "start": { + "line": 133, + "column": 40 + }, + "end": { + "line": 133, + "column": 70 + } + }, + "object": { + "type": "Identifier", + "start": 6067, + "end": 6082, + "loc": { + "start": { + "line": 133, + "column": 40 + }, + "end": { + "line": 133, + "column": 55 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 6083, + "end": 6097, + "loc": { + "start": { + "line": 133, + "column": 56 + }, + "end": { + "line": 133, + "column": 70 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 6099, + "end": 6113, + "loc": { + "start": { + "line": 133, + "column": 72 + }, + "end": { + "line": 133, + "column": 86 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 6124, + "end": 6198, + "loc": { + "start": { + "line": 134, + "column": 8 + }, + "end": { + "line": 134, + "column": 82 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 6124, + "end": 6197, + "loc": { + "start": { + "line": 134, + "column": 8 + }, + "end": { + "line": 134, + "column": 81 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 6124, + "end": 6136, + "loc": { + "start": { + "line": 134, + "column": 8 + }, + "end": { + "line": 134, + "column": 20 + }, + "identifierName": "includeTypes" + }, + "name": "includeTypes" + }, + "right": { + "type": "CallExpression", + "start": 6139, + "end": 6197, + "loc": { + "start": { + "line": 134, + "column": 23 + }, + "end": { + "line": 134, + "column": 81 + } + }, + "callee": { + "type": "Identifier", + "start": 6139, + "end": 6153, + "loc": { + "start": { + "line": 134, + "column": 23 + }, + "end": { + "line": 134, + "column": 37 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 6154, + "end": 6182, + "loc": { + "start": { + "line": 134, + "column": 38 + }, + "end": { + "line": 134, + "column": 66 + } + }, + "object": { + "type": "Identifier", + "start": 6154, + "end": 6169, + "loc": { + "start": { + "line": 134, + "column": 38 + }, + "end": { + "line": 134, + "column": 53 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 6170, + "end": 6182, + "loc": { + "start": { + "line": 134, + "column": 54 + }, + "end": { + "line": 134, + "column": 66 + }, + "identifierName": "includeTypes" + }, + "name": "includeTypes" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 6184, + "end": 6196, + "loc": { + "start": { + "line": 134, + "column": 68 + }, + "end": { + "line": 134, + "column": 80 + }, + "identifierName": "includeTypes" + }, + "name": "includeTypes" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 6207, + "end": 6281, + "loc": { + "start": { + "line": 135, + "column": 8 + }, + "end": { + "line": 135, + "column": 82 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 6207, + "end": 6280, + "loc": { + "start": { + "line": 135, + "column": 8 + }, + "end": { + "line": 135, + "column": 81 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 6207, + "end": 6219, + "loc": { + "start": { + "line": 135, + "column": 8 + }, + "end": { + "line": 135, + "column": 20 + }, + "identifierName": "excludeTypes" + }, + "name": "excludeTypes" + }, + "right": { + "type": "CallExpression", + "start": 6222, + "end": 6280, + "loc": { + "start": { + "line": 135, + "column": 23 + }, + "end": { + "line": 135, + "column": 81 + } + }, + "callee": { + "type": "Identifier", + "start": 6222, + "end": 6236, + "loc": { + "start": { + "line": 135, + "column": 23 + }, + "end": { + "line": 135, + "column": 37 + }, + "identifierName": "overrideOption" + }, + "name": "overrideOption" + }, + "arguments": [ + { + "type": "MemberExpression", + "start": 6237, + "end": 6265, + "loc": { + "start": { + "line": 135, + "column": 38 + }, + "end": { + "line": 135, + "column": 66 + } + }, + "object": { + "type": "Identifier", + "start": 6237, + "end": 6252, + "loc": { + "start": { + "line": 135, + "column": 38 + }, + "end": { + "line": 135, + "column": 53 + }, + "identifierName": "fileTypeConfigs" + }, + "name": "fileTypeConfigs" + }, + "property": { + "type": "Identifier", + "start": 6253, + "end": 6265, + "loc": { + "start": { + "line": 135, + "column": 54 + }, + "end": { + "line": 135, + "column": 66 + }, + "identifierName": "excludeTypes" + }, + "name": "excludeTypes" + }, + "computed": false + }, + { + "type": "Identifier", + "start": 6267, + "end": 6279, + "loc": { + "start": { + "line": 135, + "column": 68 + }, + "end": { + "line": 135, + "column": 80 + }, + "identifierName": "excludeTypes" + }, + "name": "excludeTypes" + } + ] + } + } + }, + { + "type": "IfStatement", + "start": 6291, + "end": 6380, + "loc": { + "start": { + "line": 137, + "column": 8 + }, + "end": { + "line": 139, + "column": 9 + } + }, + "test": { + "type": "BinaryExpression", + "start": 6295, + "end": 6320, + "loc": { + "start": { + "line": 137, + "column": 12 + }, + "end": { + "line": 137, + "column": 37 + } + }, + "left": { + "type": "Identifier", + "start": 6295, + "end": 6310, + "loc": { + "start": { + "line": 137, + "column": 12 + }, + "end": { + "line": 137, + "column": 27 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "operator": "===", + "right": { + "type": "BooleanLiteral", + "start": 6315, + "end": 6320, + "loc": { + "start": { + "line": 137, + "column": 32 + }, + "end": { + "line": 137, + "column": 37 + } + }, + "value": false + } + }, + "consequent": { + "type": "BlockStatement", + "start": 6322, + "end": 6380, + "loc": { + "start": { + "line": 137, + "column": 39 + }, + "end": { + "line": 139, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 6336, + "end": 6370, + "loc": { + "start": { + "line": 138, + "column": 12 + }, + "end": { + "line": 138, + "column": 46 + } + }, + "expression": { + "type": "CallExpression", + "start": 6336, + "end": 6369, + "loc": { + "start": { + "line": 138, + "column": 12 + }, + "end": { + "line": 138, + "column": 45 + } + }, + "callee": { + "type": "Identifier", + "start": 6336, + "end": 6339, + "loc": { + "start": { + "line": 138, + "column": 12 + }, + "end": { + "line": 138, + "column": 15 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 6340, + "end": 6368, + "loc": { + "start": { + "line": 138, + "column": 16 + }, + "end": { + "line": 138, + "column": 44 + } + }, + "extra": { + "rawValue": "Geometry reuse is disabled", + "raw": "\"Geometry reuse is disabled\"" + }, + "value": "Geometry reuse is disabled" + } + ] + } + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "VariableDeclaration", + "start": 6390, + "end": 6480, + "loc": { + "start": { + "line": 141, + "column": 8 + }, + "end": { + "line": 144, + "column": 11 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 6396, + "end": 6479, + "loc": { + "start": { + "line": 141, + "column": 14 + }, + "end": { + "line": 144, + "column": 10 + } + }, + "id": { + "type": "Identifier", + "start": 6396, + "end": 6404, + "loc": { + "start": { + "line": 141, + "column": 14 + }, + "end": { + "line": 141, + "column": 22 + }, + "identifierName": "xktModel" + }, + "name": "xktModel" + }, + "init": { + "type": "NewExpression", + "start": 6407, + "end": 6479, + "loc": { + "start": { + "line": 141, + "column": 25 + }, + "end": { + "line": 144, + "column": 10 + } + }, + "callee": { + "type": "Identifier", + "start": 6411, + "end": 6419, + "loc": { + "start": { + "line": 141, + "column": 29 + }, + "end": { + "line": 141, + "column": 37 + }, + "identifierName": "XKTModel" + }, + "name": "XKTModel" + }, + "arguments": [ + { + "type": "ObjectExpression", + "start": 6420, + "end": 6478, + "loc": { + "start": { + "line": 141, + "column": 38 + }, + "end": { + "line": 144, + "column": 9 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 6434, + "end": 6445, + "loc": { + "start": { + "line": 142, + "column": 12 + }, + "end": { + "line": 142, + "column": 23 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6434, + "end": 6445, + "loc": { + "start": { + "line": 142, + "column": 12 + }, + "end": { + "line": 142, + "column": 23 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "value": { + "type": "Identifier", + "start": 6434, + "end": 6445, + "loc": { + "start": { + "line": 142, + "column": 12 + }, + "end": { + "line": 142, + "column": 23 + }, + "identifierName": "minTileSize" + }, + "name": "minTileSize" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 6459, + "end": 6468, + "loc": { + "start": { + "line": 143, + "column": 12 + }, + "end": { + "line": 143, + "column": 21 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6459, + "end": 6468, + "loc": { + "start": { + "line": 143, + "column": 12 + }, + "end": { + "line": 143, + "column": 21 + }, + "identifierName": "modelAABB" + }, + "name": "modelAABB" + }, + "value": { + "type": "Identifier", + "start": 6459, + "end": 6468, + "loc": { + "start": { + "line": 143, + "column": 12 + }, + "end": { + "line": 143, + "column": 21 + }, + "identifierName": "modelAABB" + }, + "name": "modelAABB" + }, + "extra": { + "shorthand": true + } + } + ] + } + ] + } + } + ], + "kind": "const" + }, + { + "type": "ExpressionStatement", + "start": 6492, + "end": 6531, + "loc": { + "start": { + "line": 148, + "column": 8 + }, + "end": { + "line": 148, + "column": 47 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 6492, + "end": 6530, + "loc": { + "start": { + "line": 148, + "column": 8 + }, + "end": { + "line": 148, + "column": 46 + } + }, + "operator": "=", + "left": { + "type": "Identifier", + "start": 6492, + "end": 6502, + "loc": { + "start": { + "line": 148, + "column": 8 + }, + "end": { + "line": 148, + "column": 18 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + }, + "right": { + "type": "CallExpression", + "start": 6505, + "end": 6530, + "loc": { + "start": { + "line": 148, + "column": 21 + }, + "end": { + "line": 148, + "column": 46 + } + }, + "callee": { + "type": "Identifier", + "start": 6505, + "end": 6518, + "loc": { + "start": { + "line": 148, + "column": 21 + }, + "end": { + "line": 148, + "column": 34 + }, + "identifierName": "toArrayBuffer" + }, + "name": "toArrayBuffer" + }, + "arguments": [ + { + "type": "Identifier", + "start": 6519, + "end": 6529, + "loc": { + "start": { + "line": 148, + "column": 35 + }, + "end": { + "line": 148, + "column": 45 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + } + ] + } + } + }, + { + "type": "ExpressionStatement", + "start": 6540, + "end": 6763, + "loc": { + "start": { + "line": 149, + "column": 8 + }, + "end": { + "line": 157, + "column": 11 + } + }, + "expression": { + "type": "CallExpression", + "start": 6540, + "end": 6762, + "loc": { + "start": { + "line": 149, + "column": 8 + }, + "end": { + "line": 157, + "column": 10 + } + }, + "callee": { + "type": "Identifier", + "start": 6540, + "end": 6547, + "loc": { + "start": { + "line": 149, + "column": 8 + }, + "end": { + "line": 149, + "column": 15 + }, + "identifierName": "convert" + }, + "name": "convert" + }, + "arguments": [ + { + "type": "Identifier", + "start": 6548, + "end": 6569, + "loc": { + "start": { + "line": 149, + "column": 16 + }, + "end": { + "line": 149, + "column": 37 + }, + "identifierName": "parseGLTFIntoXKTModel" + }, + "name": "parseGLTFIntoXKTModel" + }, + { + "type": "ObjectExpression", + "start": 6571, + "end": 6761, + "loc": { + "start": { + "line": 149, + "column": 39 + }, + "end": { + "line": 157, + "column": 9 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 6585, + "end": 6601, + "loc": { + "start": { + "line": 150, + "column": 12 + }, + "end": { + "line": 150, + "column": 28 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 6585, + "end": 6589, + "loc": { + "start": { + "line": 150, + "column": 12 + }, + "end": { + "line": 150, + "column": 16 + }, + "identifierName": "data" + }, + "name": "data" + }, + "value": { + "type": "Identifier", + "start": 6591, + "end": 6601, + "loc": { + "start": { + "line": 150, + "column": 18 + }, + "end": { + "line": 150, + "column": 28 + }, + "identifierName": "sourceData" + }, + "name": "sourceData" + } + }, + { + "type": "ObjectProperty", + "start": 6615, + "end": 6630, + "loc": { + "start": { + "line": 151, + "column": 12 + }, + "end": { + "line": 151, + "column": 27 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6615, + "end": 6630, + "loc": { + "start": { + "line": 151, + "column": 12 + }, + "end": { + "line": 151, + "column": 27 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "value": { + "type": "Identifier", + "start": 6615, + "end": 6630, + "loc": { + "start": { + "line": 151, + "column": 12 + }, + "end": { + "line": 151, + "column": 27 + }, + "identifierName": "reuseGeometries" + }, + "name": "reuseGeometries" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 6644, + "end": 6665, + "loc": { + "start": { + "line": 152, + "column": 12 + }, + "end": { + "line": 152, + "column": 33 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 6644, + "end": 6659, + "loc": { + "start": { + "line": 152, + "column": 12 + }, + "end": { + "line": 152, + "column": 27 + }, + "identifierName": "includeTextures" + }, + "name": "includeTextures" + }, + "value": { + "type": "BooleanLiteral", + "start": 6661, + "end": 6665, + "loc": { + "start": { + "line": 152, + "column": 29 + }, + "end": { + "line": 152, + "column": 33 + } + }, + "value": true + } + }, + { + "type": "ObjectProperty", + "start": 6679, + "end": 6693, + "loc": { + "start": { + "line": 153, + "column": 12 + }, + "end": { + "line": 153, + "column": 26 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6679, + "end": 6693, + "loc": { + "start": { + "line": 153, + "column": 12 + }, + "end": { + "line": 153, + "column": 26 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "value": { + "type": "Identifier", + "start": 6679, + "end": 6693, + "loc": { + "start": { + "line": 153, + "column": 12 + }, + "end": { + "line": 153, + "column": 26 + }, + "identifierName": "includeNormals" + }, + "name": "includeNormals" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 6707, + "end": 6715, + "loc": { + "start": { + "line": 154, + "column": 12 + }, + "end": { + "line": 154, + "column": 20 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6707, + "end": 6715, + "loc": { + "start": { + "line": 154, + "column": 12 + }, + "end": { + "line": 154, + "column": 20 + }, + "identifierName": "xktModel" + }, + "name": "xktModel" + }, + "value": { + "type": "Identifier", + "start": 6707, + "end": 6715, + "loc": { + "start": { + "line": 154, + "column": 12 + }, + "end": { + "line": 154, + "column": 20 + }, + "identifierName": "xktModel" + }, + "name": "xktModel" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 6729, + "end": 6734, + "loc": { + "start": { + "line": 155, + "column": 12 + }, + "end": { + "line": 155, + "column": 17 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6729, + "end": 6734, + "loc": { + "start": { + "line": 155, + "column": 12 + }, + "end": { + "line": 155, + "column": 17 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "value": { + "type": "Identifier", + "start": 6729, + "end": 6734, + "loc": { + "start": { + "line": 155, + "column": 12 + }, + "end": { + "line": 155, + "column": 17 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 6748, + "end": 6751, + "loc": { + "start": { + "line": 156, + "column": 12 + }, + "end": { + "line": 156, + "column": 15 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6748, + "end": 6751, + "loc": { + "start": { + "line": 156, + "column": 12 + }, + "end": { + "line": 156, + "column": 15 + }, + "identifierName": "log" + }, + "name": "log" + }, + "value": { + "type": "Identifier", + "start": 6748, + "end": 6751, + "loc": { + "start": { + "line": 156, + "column": 12 + }, + "end": { + "line": 156, + "column": 15 + }, + "identifierName": "log" + }, + "name": "log" + }, + "extra": { + "shorthand": true + } + } + ] + } + ] + } + }, + { + "type": "FunctionDeclaration", + "start": 6774, + "end": 7483, + "loc": { + "start": { + "line": 160, + "column": 8 + }, + "end": { + "line": 185, + "column": 9 + } + }, + "id": { + "type": "Identifier", + "start": 6783, + "end": 6790, + "loc": { + "start": { + "line": 160, + "column": 17 + }, + "end": { + "line": 160, + "column": 24 + }, + "identifierName": "convert" + }, + "name": "convert" + }, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 6791, + "end": 6797, + "loc": { + "start": { + "line": 160, + "column": 25 + }, + "end": { + "line": 160, + "column": 31 + }, + "identifierName": "parser" + }, + "name": "parser" + }, + { + "type": "Identifier", + "start": 6799, + "end": 6814, + "loc": { + "start": { + "line": 160, + "column": 33 + }, + "end": { + "line": 160, + "column": 48 + }, + "identifierName": "converterParams" + }, + "name": "converterParams" + } + ], + "body": { + "type": "BlockStatement", + "start": 6816, + "end": 7483, + "loc": { + "start": { + "line": 160, + "column": 50 + }, + "end": { + "line": 185, + "column": 9 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 6831, + "end": 7473, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 184, + "column": 15 + } + }, + "expression": { + "type": "CallExpression", + "start": 6831, + "end": 7472, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 184, + "column": 14 + } + }, + "callee": { + "type": "MemberExpression", + "start": 6831, + "end": 6859, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 162, + "column": 40 + } + }, + "object": { + "type": "CallExpression", + "start": 6831, + "end": 6854, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 162, + "column": 35 + } + }, + "callee": { + "type": "Identifier", + "start": 6831, + "end": 6837, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 162, + "column": 18 + }, + "identifierName": "parser" + }, + "name": "parser" + }, + "arguments": [ + { + "type": "Identifier", + "start": 6838, + "end": 6853, + "loc": { + "start": { + "line": 162, + "column": 19 + }, + "end": { + "line": 162, + "column": 34 + }, + "identifierName": "converterParams" + }, + "name": "converterParams" + } + ] + }, + "property": { + "type": "Identifier", + "start": 6855, + "end": 6859, + "loc": { + "start": { + "line": 162, + "column": 36 + }, + "end": { + "line": 162, + "column": 40 + }, + "identifierName": "then" + }, + "name": "then" + }, + "computed": false + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "start": 6860, + "end": 7416, + "loc": { + "start": { + "line": 162, + "column": 41 + }, + "end": { + "line": 182, + "column": 13 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 6866, + "end": 7416, + "loc": { + "start": { + "line": 162, + "column": 47 + }, + "end": { + "line": 182, + "column": 13 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 6886, + "end": 6940, + "loc": { + "start": { + "line": 165, + "column": 16 + }, + "end": { + "line": 165, + "column": 70 + } + }, + "expression": { + "type": "CallExpression", + "start": 6886, + "end": 6939, + "loc": { + "start": { + "line": 165, + "column": 16 + }, + "end": { + "line": 165, + "column": 69 + } + }, + "callee": { + "type": "Identifier", + "start": 6886, + "end": 6889, + "loc": { + "start": { + "line": 165, + "column": 16 + }, + "end": { + "line": 165, + "column": 19 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 6890, + "end": 6938, + "loc": { + "start": { + "line": 165, + "column": 20 + }, + "end": { + "line": 165, + "column": 68 + } + }, + "extra": { + "rawValue": "Input file parsed OK. Building XKT document...", + "raw": "\"Input file parsed OK. Building XKT document...\"" + }, + "value": "Input file parsed OK. Building XKT document..." + } + ] + } + }, + { + "type": "ExpressionStatement", + "start": 6958, + "end": 7402, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 181, + "column": 19 + } + }, + "expression": { + "type": "CallExpression", + "start": 6958, + "end": 7401, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 181, + "column": 18 + } + }, + "callee": { + "type": "MemberExpression", + "start": 6958, + "end": 6982, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 167, + "column": 40 + } + }, + "object": { + "type": "CallExpression", + "start": 6958, + "end": 6977, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 167, + "column": 35 + } + }, + "callee": { + "type": "MemberExpression", + "start": 6958, + "end": 6975, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 167, + "column": 33 + } + }, + "object": { + "type": "Identifier", + "start": 6958, + "end": 6966, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 167, + "column": 24 + }, + "identifierName": "xktModel" + }, + "name": "xktModel" + }, + "property": { + "type": "Identifier", + "start": 6967, + "end": 6975, + "loc": { + "start": { + "line": 167, + "column": 25 + }, + "end": { + "line": 167, + "column": 33 + }, + "identifierName": "finalize" + }, + "name": "finalize" + }, + "computed": false + }, + "arguments": [] + }, + "property": { + "type": "Identifier", + "start": 6978, + "end": 6982, + "loc": { + "start": { + "line": 167, + "column": 36 + }, + "end": { + "line": 167, + "column": 40 + }, + "identifierName": "then" + }, + "name": "then" + }, + "computed": false + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "start": 6983, + "end": 7400, + "loc": { + "start": { + "line": 167, + "column": 41 + }, + "end": { + "line": 181, + "column": 17 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 6989, + "end": 7400, + "loc": { + "start": { + "line": 167, + "column": 47 + }, + "end": { + "line": 181, + "column": 17 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 7012, + "end": 7065, + "loc": { + "start": { + "line": 169, + "column": 20 + }, + "end": { + "line": 169, + "column": 73 + } + }, + "expression": { + "type": "CallExpression", + "start": 7012, + "end": 7064, + "loc": { + "start": { + "line": 169, + "column": 20 + }, + "end": { + "line": 169, + "column": 72 + } + }, + "callee": { + "type": "Identifier", + "start": 7012, + "end": 7015, + "loc": { + "start": { + "line": 169, + "column": 20 + }, + "end": { + "line": 169, + "column": 23 + }, + "identifierName": "log" + }, + "name": "log" + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 7016, + "end": 7063, + "loc": { + "start": { + "line": 169, + "column": 24 + }, + "end": { + "line": 169, + "column": 71 + } + }, + "extra": { + "rawValue": "XKT document built OK. Writing to XKT file...", + "raw": "\"XKT document built OK. Writing to XKT file...\"" + }, + "value": "XKT document built OK. Writing to XKT file..." + } + ] + } + }, + { + "type": "VariableDeclaration", + "start": 7087, + "end": 7173, + "loc": { + "start": { + "line": 171, + "column": 20 + }, + "end": { + "line": 171, + "column": 106 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 7093, + "end": 7172, + "loc": { + "start": { + "line": 171, + "column": 26 + }, + "end": { + "line": 171, + "column": 105 + } + }, + "id": { + "type": "Identifier", + "start": 7093, + "end": 7107, + "loc": { + "start": { + "line": 171, + "column": 26 + }, + "end": { + "line": 171, + "column": 40 + }, + "identifierName": "xktArrayBuffer" + }, + "name": "xktArrayBuffer" + }, + "init": { + "type": "CallExpression", + "start": 7110, + "end": 7172, + "loc": { + "start": { + "line": 171, + "column": 43 + }, + "end": { + "line": 171, + "column": 105 + } + }, + "callee": { + "type": "Identifier", + "start": 7110, + "end": 7136, + "loc": { + "start": { + "line": 171, + "column": 43 + }, + "end": { + "line": 171, + "column": 69 + }, + "identifierName": "writeXKTModelToArrayBuffer" + }, + "name": "writeXKTModelToArrayBuffer" + }, + "arguments": [ + { + "type": "Identifier", + "start": 7137, + "end": 7145, + "loc": { + "start": { + "line": 171, + "column": 70 + }, + "end": { + "line": 171, + "column": 78 + }, + "identifierName": "xktModel" + }, + "name": "xktModel" + }, + { + "type": "NullLiteral", + "start": 7147, + "end": 7151, + "loc": { + "start": { + "line": 171, + "column": 80 + }, + "end": { + "line": 171, + "column": 84 + } + } + }, + { + "type": "Identifier", + "start": 7153, + "end": 7158, + "loc": { + "start": { + "line": 171, + "column": 86 + }, + "end": { + "line": 171, + "column": 91 + }, + "identifierName": "stats" + }, + "name": "stats" + }, + { + "type": "ObjectExpression", + "start": 7160, + "end": 7171, + "loc": { + "start": { + "line": 171, + "column": 93 + }, + "end": { + "line": 171, + "column": 104 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 7161, + "end": 7170, + "loc": { + "start": { + "line": 171, + "column": 94 + }, + "end": { + "line": 171, + "column": 103 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 7161, + "end": 7164, + "loc": { + "start": { + "line": 171, + "column": 94 + }, + "end": { + "line": 171, + "column": 97 + }, + "identifierName": "zip" + }, + "name": "zip" + }, + "value": { + "type": "BooleanLiteral", + "start": 7166, + "end": 7170, + "loc": { + "start": { + "line": 171, + "column": 99 + }, + "end": { + "line": 171, + "column": 103 + } + }, + "value": true + } + } + ] + } + ] + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 7195, + "end": 7242, + "loc": { + "start": { + "line": 173, + "column": 20 + }, + "end": { + "line": 173, + "column": 67 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 7201, + "end": 7241, + "loc": { + "start": { + "line": 173, + "column": 26 + }, + "end": { + "line": 173, + "column": 66 + } + }, + "id": { + "type": "Identifier", + "start": 7201, + "end": 7211, + "loc": { + "start": { + "line": 173, + "column": 26 + }, + "end": { + "line": 173, + "column": 36 + }, + "identifierName": "xktContent" + }, + "name": "xktContent" + }, + "init": { + "type": "CallExpression", + "start": 7214, + "end": 7241, + "loc": { + "start": { + "line": 173, + "column": 39 + }, + "end": { + "line": 173, + "column": 66 + } + }, + "callee": { + "type": "MemberExpression", + "start": 7214, + "end": 7225, + "loc": { + "start": { + "line": 173, + "column": 39 + }, + "end": { + "line": 173, + "column": 50 + } + }, + "object": { + "type": "Identifier", + "start": 7214, + "end": 7220, + "loc": { + "start": { + "line": 173, + "column": 39 + }, + "end": { + "line": 173, + "column": 45 + }, + "identifierName": "Buffer" + }, + "name": "Buffer" + }, + "property": { + "type": "Identifier", + "start": 7221, + "end": 7225, + "loc": { + "start": { + "line": 173, + "column": 46 + }, + "end": { + "line": 173, + "column": 50 + }, + "identifierName": "from" + }, + "name": "from" + }, + "computed": false + }, + "arguments": [ + { + "type": "Identifier", + "start": 7226, + "end": 7240, + "loc": { + "start": { + "line": 173, + "column": 51 + }, + "end": { + "line": 173, + "column": 65 + }, + "identifierName": "xktArrayBuffer" + }, + "name": "xktArrayBuffer" + } + ] + } + } + ], + "kind": "const" + }, + { + "type": "IfStatement", + "start": 7265, + "end": 7350, + "loc": { + "start": { + "line": 176, + "column": 20 + }, + "end": { + "line": 178, + "column": 21 + } + }, + "test": { + "type": "Identifier", + "start": 7269, + "end": 7278, + "loc": { + "start": { + "line": 176, + "column": 24 + }, + "end": { + "line": 176, + "column": 33 + }, + "identifierName": "outputXKT" + }, + "name": "outputXKT" + }, + "consequent": { + "type": "BlockStatement", + "start": 7280, + "end": 7350, + "loc": { + "start": { + "line": 176, + "column": 35 + }, + "end": { + "line": 178, + "column": 21 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 7306, + "end": 7328, + "loc": { + "start": { + "line": 177, + "column": 24 + }, + "end": { + "line": 177, + "column": 46 + } + }, + "expression": { + "type": "CallExpression", + "start": 7306, + "end": 7327, + "loc": { + "start": { + "line": 177, + "column": 24 + }, + "end": { + "line": 177, + "column": 45 + } + }, + "callee": { + "type": "Identifier", + "start": 7306, + "end": 7315, + "loc": { + "start": { + "line": 177, + "column": 24 + }, + "end": { + "line": 177, + "column": 33 + }, + "identifierName": "outputXKT" + }, + "name": "outputXKT" + }, + "arguments": [ + { + "type": "Identifier", + "start": 7316, + "end": 7326, + "loc": { + "start": { + "line": 177, + "column": 34 + }, + "end": { + "line": 177, + "column": 44 + }, + "identifierName": "xktContent" + }, + "name": "xktContent" + } + ] + } + } + ], + "directives": [] + }, + "alternate": null + }, + { + "type": "ExpressionStatement", + "start": 7372, + "end": 7382, + "loc": { + "start": { + "line": 180, + "column": 20 + }, + "end": { + "line": 180, + "column": 30 + } + }, + "expression": { + "type": "CallExpression", + "start": 7372, + "end": 7381, + "loc": { + "start": { + "line": 180, + "column": 20 + }, + "end": { + "line": 180, + "column": 29 + } + }, + "callee": { + "type": "Identifier", + "start": 7372, + "end": 7379, + "loc": { + "start": { + "line": 180, + "column": 20 + }, + "end": { + "line": 180, + "column": 27 + }, + "identifierName": "resolve" + }, + "name": "resolve" + }, + "arguments": [] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } + }, + { + "type": "ArrowFunctionExpression", + "start": 7418, + "end": 7471, + "loc": { + "start": { + "line": 182, + "column": 15 + }, + "end": { + "line": 184, + "column": 13 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 7419, + "end": 7422, + "loc": { + "start": { + "line": 182, + "column": 16 + }, + "end": { + "line": 182, + "column": 19 + }, + "identifierName": "err" + }, + "name": "err" + } + ], + "body": { + "type": "BlockStatement", + "start": 7427, + "end": 7471, + "loc": { + "start": { + "line": 182, + "column": 24 + }, + "end": { + "line": 184, + "column": 13 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 7445, + "end": 7457, + "loc": { + "start": { + "line": 183, + "column": 16 + }, + "end": { + "line": 183, + "column": 28 + } + }, + "expression": { + "type": "CallExpression", + "start": 7445, + "end": 7456, + "loc": { + "start": { + "line": 183, + "column": 16 + }, + "end": { + "line": 183, + "column": 27 + } + }, + "callee": { + "type": "Identifier", + "start": 7445, + "end": 7451, + "loc": { + "start": { + "line": 183, + "column": 16 + }, + "end": { + "line": 183, + "column": 22 + }, + "identifierName": "reject" + }, + "name": "reject" + }, + "arguments": [ + { + "type": "Identifier", + "start": 7452, + "end": 7455, + "loc": { + "start": { + "line": 183, + "column": 23 + }, + "end": { + "line": 183, + "column": 26 + }, + "identifierName": "err" + }, + "name": "err" + } + ] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + }, + "leadingComments": [ + { + "type": "CommentBlock", + "value": "*\n * Converts model files into xeokit's native XKT format.\n *\n * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.\n *\n * **Only bundled in xeokit-convert.cjs.js.**\n *\n * ## Usage\n *\n ````\n * @param {Object} params Conversion parameters.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {*} [params.configs] Configurations.\n * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````.\n * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method.\n * @param {Function} [params.outputXKT] Callback to collect XKT file data.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided.\n * @param {Function} [params.outputStats] Callback to collect statistics.\n * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis \"up\", if necessary. Applies to CityJSON and LAS/LAZ models.\n * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models.\n * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore\n * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the model.\n * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000,\n * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close\n * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger.\n * @param {Function} [params.log] Logging callback.\n * @return {Promise}\n ", + "start": 271, + "end": 3260, + "loc": { + "start": { + "line": 8, + "column": 0 + }, + "end": { + "line": 46, + "column": 3 + } + } + } + ], + "trailingComments": [] + }, + "specifiers": null, + "source": null, + "leadingComments": null + } + ], + "directives": [] + }, + "comments": [ + { + "type": "CommentBlock", + "value": "*\n * Converts model files into xeokit's native XKT format.\n *\n * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.\n *\n * **Only bundled in xeokit-convert.cjs.js.**\n *\n * ## Usage\n *\n ````\n * @param {Object} params Conversion parameters.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {*} [params.configs] Configurations.\n * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````.\n * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method.\n * @param {Function} [params.outputXKT] Callback to collect XKT file data.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided.\n * @param {Function} [params.outputStats] Callback to collect statistics.\n * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis \"up\", if necessary. Applies to CityJSON and LAS/LAZ models.\n * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models.\n * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore\n * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the model.\n * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000,\n * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close\n * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger.\n * @param {Function} [params.log] Logging callback.\n * @return {Promise}\n ", + "start": 271, + "end": 3260, + "loc": { + "start": { + "line": 8, + "column": 0 + }, + "end": { + "line": 46, + "column": 3 + } + } + } + ], + "tokens": [ + { + "type": { + "label": "import", + "keyword": "import", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "import", + "start": 1, + "end": 7, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 6 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 8, + "end": 9, + "loc": { + "start": { + "line": 2, + "column": 7 + }, + "end": { + "line": 2, + "column": 8 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "XKTModel", + "start": 9, + "end": 17, + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 16 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 17, + "end": 18, + "loc": { + "start": { + "line": 2, + "column": 16 + }, + "end": { + "line": 2, + "column": 17 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "from", + "start": 19, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 18 + }, + "end": { + "line": 2, + "column": 22 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "./XKTModel/XKTModel.js", + "start": 24, + "end": 48, + "loc": { + "start": { + "line": 2, + "column": 23 + }, + "end": { + "line": 2, + "column": 47 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 48, + "end": 49, + "loc": { + "start": { + "line": 2, + "column": 47 + }, + "end": { + "line": 2, + "column": 48 + } + } + }, + { + "type": { + "label": "import", + "keyword": "import", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "import", + "start": 50, + "end": 56, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 6 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 57, + "end": 58, + "loc": { + "start": { + "line": 3, + "column": 7 + }, + "end": { + "line": 3, + "column": 8 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "parseGLTFIntoXKTModel", + "start": 58, + "end": 79, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 29 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 79, + "end": 80, + "loc": { + "start": { + "line": 3, + "column": 29 + }, + "end": { + "line": 3, + "column": 30 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "from", + "start": 81, + "end": 85, + "loc": { + "start": { + "line": 3, + "column": 31 + }, + "end": { + "line": 3, + "column": 35 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "./parsers/parseGLTFIntoXKTModel.js", + "start": 86, + "end": 122, + "loc": { + "start": { + "line": 3, + "column": 36 + }, + "end": { + "line": 3, + "column": 72 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 122, + "end": 123, + "loc": { + "start": { + "line": 3, + "column": 72 + }, + "end": { + "line": 3, + "column": 73 + } + } + }, + { + "type": { + "label": "import", + "keyword": "import", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "import", + "start": 124, + "end": 130, + "loc": { + "start": { + "line": 4, + "column": 0 + }, + "end": { + "line": 4, + "column": 6 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 131, + "end": 132, + "loc": { + "start": { + "line": 4, + "column": 7 + }, + "end": { + "line": 4, + "column": 8 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "writeXKTModelToArrayBuffer", + "start": 132, + "end": 158, + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 34 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 158, + "end": 159, + "loc": { + "start": { + "line": 4, + "column": 34 + }, + "end": { + "line": 4, + "column": 35 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "from", + "start": 160, + "end": 164, + "loc": { + "start": { + "line": 4, + "column": 36 + }, + "end": { + "line": 4, + "column": 40 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "./XKTModel/writeXKTModelToArrayBuffer.js", + "start": 165, + "end": 207, + "loc": { + "start": { + "line": 4, + "column": 41 + }, + "end": { + "line": 4, + "column": 83 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 207, + "end": 208, + "loc": { + "start": { + "line": 4, + "column": 83 + }, + "end": { + "line": 4, + "column": 84 + } + } + }, + { + "type": { + "label": "import", + "keyword": "import", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "import", + "start": 210, + "end": 216, + "loc": { + "start": { + "line": 6, + "column": 0 + }, + "end": { + "line": 6, + "column": 6 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 217, + "end": 218, + "loc": { + "start": { + "line": 6, + "column": 7 + }, + "end": { + "line": 6, + "column": 8 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "toArrayBuffer", + "start": 218, + "end": 231, + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 21 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 231, + "end": 232, + "loc": { + "start": { + "line": 6, + "column": 21 + }, + "end": { + "line": 6, + "column": 22 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "from", + "start": 233, + "end": 237, + "loc": { + "start": { + "line": 6, + "column": 23 + }, + "end": { + "line": 6, + "column": 27 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "./XKTModel/lib/toArraybuffer", + "start": 238, + "end": 268, + "loc": { + "start": { + "line": 6, + "column": 28 + }, + "end": { + "line": 6, + "column": 58 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 268, + "end": 269, + "loc": { + "start": { + "line": 6, + "column": 58 + }, + "end": { + "line": 6, + "column": 59 + } + } + }, + { + "type": "CommentBlock", + "value": "*\n * Converts model files into xeokit's native XKT format.\n *\n * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.\n *\n * **Only bundled in xeokit-convert.cjs.js.**\n *\n * ## Usage\n *\n ````\n * @param {Object} params Conversion parameters.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {*} [params.configs] Configurations.\n * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````.\n * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method.\n * @param {Function} [params.outputXKT] Callback to collect XKT file data.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided.\n * @param {Function} [params.outputStats] Callback to collect statistics.\n * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis \"up\", if necessary. Applies to CityJSON and LAS/LAZ models.\n * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models.\n * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore\n * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the model.\n * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000,\n * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close\n * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger.\n * @param {Function} [params.log] Logging callback.\n * @return {Promise}\n ", + "start": 271, + "end": 3260, + "loc": { + "start": { + "line": 8, + "column": 0 + }, + "end": { + "line": 46, + "column": 3 + } + } + }, + { + "type": { + "label": "function", + "keyword": "function", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "function", + "start": 3261, + "end": 3269, + "loc": { + "start": { + "line": 47, + "column": 0 + }, + "end": { + "line": 47, + "column": 8 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "convert2xkt", + "start": 3270, + "end": 3281, + "loc": { + "start": { + "line": 47, + "column": 9 + }, + "end": { + "line": 47, + "column": 20 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3281, + "end": 3282, + "loc": { + "start": { + "line": 47, + "column": 20 + }, + "end": { + "line": 47, + "column": 21 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3282, + "end": 3283, + "loc": { + "start": { + "line": 47, + "column": 21 + }, + "end": { + "line": 47, + "column": 22 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "configs", + "start": 3309, + "end": 3316, + "loc": { + "start": { + "line": 48, + "column": 25 + }, + "end": { + "line": 48, + "column": 32 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3317, + "end": 3318, + "loc": { + "start": { + "line": 48, + "column": 33 + }, + "end": { + "line": 48, + "column": 34 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3319, + "end": 3320, + "loc": { + "start": { + "line": 48, + "column": 35 + }, + "end": { + "line": 48, + "column": 36 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3320, + "end": 3321, + "loc": { + "start": { + "line": 48, + "column": 36 + }, + "end": { + "line": 48, + "column": 37 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3321, + "end": 3322, + "loc": { + "start": { + "line": 48, + "column": 37 + }, + "end": { + "line": 48, + "column": 38 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceData", + "start": 3348, + "end": 3358, + "loc": { + "start": { + "line": 49, + "column": 25 + }, + "end": { + "line": 49, + "column": 35 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3358, + "end": 3359, + "loc": { + "start": { + "line": 49, + "column": 35 + }, + "end": { + "line": 49, + "column": 36 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "modelAABB", + "start": 3385, + "end": 3394, + "loc": { + "start": { + "line": 50, + "column": 25 + }, + "end": { + "line": 50, + "column": 34 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3394, + "end": 3395, + "loc": { + "start": { + "line": 50, + "column": 34 + }, + "end": { + "line": 50, + "column": 35 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "outputXKTModel", + "start": 3421, + "end": 3435, + "loc": { + "start": { + "line": 51, + "column": 25 + }, + "end": { + "line": 51, + "column": 39 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3435, + "end": 3436, + "loc": { + "start": { + "line": 51, + "column": 39 + }, + "end": { + "line": 51, + "column": 40 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "outputXKT", + "start": 3462, + "end": 3471, + "loc": { + "start": { + "line": 52, + "column": 25 + }, + "end": { + "line": 52, + "column": 34 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3471, + "end": 3472, + "loc": { + "start": { + "line": 52, + "column": 34 + }, + "end": { + "line": 52, + "column": 35 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeTypes", + "start": 3498, + "end": 3510, + "loc": { + "start": { + "line": 53, + "column": 25 + }, + "end": { + "line": 53, + "column": 37 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3510, + "end": 3511, + "loc": { + "start": { + "line": 53, + "column": 37 + }, + "end": { + "line": 53, + "column": 38 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "excludeTypes", + "start": 3537, + "end": 3549, + "loc": { + "start": { + "line": 54, + "column": 25 + }, + "end": { + "line": 54, + "column": 37 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3549, + "end": 3550, + "loc": { + "start": { + "line": 54, + "column": 37 + }, + "end": { + "line": 54, + "column": 38 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "reuseGeometries", + "start": 3576, + "end": 3591, + "loc": { + "start": { + "line": 55, + "column": 25 + }, + "end": { + "line": 55, + "column": 40 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3592, + "end": 3593, + "loc": { + "start": { + "line": 55, + "column": 41 + }, + "end": { + "line": 55, + "column": 42 + } + } + }, + { + "type": { + "label": "true", + "keyword": "true", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "true", + "start": 3594, + "end": 3598, + "loc": { + "start": { + "line": 55, + "column": 43 + }, + "end": { + "line": 55, + "column": 47 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3598, + "end": 3599, + "loc": { + "start": { + "line": 55, + "column": 47 + }, + "end": { + "line": 55, + "column": 48 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "minTileSize", + "start": 3625, + "end": 3636, + "loc": { + "start": { + "line": 56, + "column": 25 + }, + "end": { + "line": 56, + "column": 36 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3637, + "end": 3638, + "loc": { + "start": { + "line": 56, + "column": 37 + }, + "end": { + "line": 56, + "column": 38 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 200, + "start": 3639, + "end": 3642, + "loc": { + "start": { + "line": 56, + "column": 39 + }, + "end": { + "line": 56, + "column": 42 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3642, + "end": 3643, + "loc": { + "start": { + "line": 56, + "column": 42 + }, + "end": { + "line": 56, + "column": 43 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 3669, + "end": 3674, + "loc": { + "start": { + "line": 57, + "column": 25 + }, + "end": { + "line": 57, + "column": 30 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3675, + "end": 3676, + "loc": { + "start": { + "line": 57, + "column": 31 + }, + "end": { + "line": 57, + "column": 32 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3677, + "end": 3678, + "loc": { + "start": { + "line": 57, + "column": 33 + }, + "end": { + "line": 57, + "column": 34 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3678, + "end": 3679, + "loc": { + "start": { + "line": 57, + "column": 34 + }, + "end": { + "line": 57, + "column": 35 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3679, + "end": 3680, + "loc": { + "start": { + "line": 57, + "column": 35 + }, + "end": { + "line": 57, + "column": 36 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "rotateX", + "start": 3706, + "end": 3713, + "loc": { + "start": { + "line": 58, + "column": 25 + }, + "end": { + "line": 58, + "column": 32 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3714, + "end": 3715, + "loc": { + "start": { + "line": 58, + "column": 33 + }, + "end": { + "line": 58, + "column": 34 + } + } + }, + { + "type": { + "label": "false", + "keyword": "false", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "false", + "start": 3716, + "end": 3721, + "loc": { + "start": { + "line": 58, + "column": 35 + }, + "end": { + "line": 58, + "column": 40 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3721, + "end": 3722, + "loc": { + "start": { + "line": 58, + "column": 40 + }, + "end": { + "line": 58, + "column": 41 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeTextures", + "start": 3748, + "end": 3763, + "loc": { + "start": { + "line": 59, + "column": 25 + }, + "end": { + "line": 59, + "column": 40 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3764, + "end": 3765, + "loc": { + "start": { + "line": 59, + "column": 41 + }, + "end": { + "line": 59, + "column": 42 + } + } + }, + { + "type": { + "label": "true", + "keyword": "true", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "true", + "start": 3766, + "end": 3770, + "loc": { + "start": { + "line": 59, + "column": 43 + }, + "end": { + "line": 59, + "column": 47 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3770, + "end": 3771, + "loc": { + "start": { + "line": 59, + "column": 47 + }, + "end": { + "line": 59, + "column": 48 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeNormals", + "start": 3797, + "end": 3811, + "loc": { + "start": { + "line": 60, + "column": 25 + }, + "end": { + "line": 60, + "column": 39 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3812, + "end": 3813, + "loc": { + "start": { + "line": 60, + "column": 40 + }, + "end": { + "line": 60, + "column": 41 + } + } + }, + { + "type": { + "label": "true", + "keyword": "true", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "true", + "start": 3814, + "end": 3818, + "loc": { + "start": { + "line": 60, + "column": 42 + }, + "end": { + "line": 60, + "column": 46 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3818, + "end": 3819, + "loc": { + "start": { + "line": 60, + "column": 46 + }, + "end": { + "line": 60, + "column": 47 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "log", + "start": 3845, + "end": 3848, + "loc": { + "start": { + "line": 61, + "column": 25 + }, + "end": { + "line": 61, + "column": 28 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3849, + "end": 3850, + "loc": { + "start": { + "line": 61, + "column": 29 + }, + "end": { + "line": 61, + "column": 30 + } + } + }, + { + "type": { + "label": "function", + "keyword": "function", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "function", + "start": 3851, + "end": 3859, + "loc": { + "start": { + "line": 61, + "column": 31 + }, + "end": { + "line": 61, + "column": 39 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3860, + "end": 3861, + "loc": { + "start": { + "line": 61, + "column": 40 + }, + "end": { + "line": 61, + "column": 41 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "msg", + "start": 3861, + "end": 3864, + "loc": { + "start": { + "line": 61, + "column": 41 + }, + "end": { + "line": 61, + "column": 44 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3864, + "end": 3865, + "loc": { + "start": { + "line": 61, + "column": 44 + }, + "end": { + "line": 61, + "column": 45 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3866, + "end": 3867, + "loc": { + "start": { + "line": 61, + "column": 46 + }, + "end": { + "line": 61, + "column": 47 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3893, + "end": 3894, + "loc": { + "start": { + "line": 62, + "column": 25 + }, + "end": { + "line": 62, + "column": 26 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3916, + "end": 3917, + "loc": { + "start": { + "line": 63, + "column": 21 + }, + "end": { + "line": 63, + "column": 22 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3917, + "end": 3918, + "loc": { + "start": { + "line": 63, + "column": 22 + }, + "end": { + "line": 63, + "column": 23 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 3919, + "end": 3920, + "loc": { + "start": { + "line": 63, + "column": 24 + }, + "end": { + "line": 63, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 3926, + "end": 3931, + "loc": { + "start": { + "line": 65, + "column": 4 + }, + "end": { + "line": 65, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3931, + "end": 3932, + "loc": { + "start": { + "line": 65, + "column": 9 + }, + "end": { + "line": 65, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "schemaVersion", + "start": 3932, + "end": 3945, + "loc": { + "start": { + "line": 65, + "column": 10 + }, + "end": { + "line": 65, + "column": 23 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3946, + "end": 3947, + "loc": { + "start": { + "line": 65, + "column": 24 + }, + "end": { + "line": 65, + "column": 25 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "", + "start": 3948, + "end": 3950, + "loc": { + "start": { + "line": 65, + "column": 26 + }, + "end": { + "line": 65, + "column": 28 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3950, + "end": 3951, + "loc": { + "start": { + "line": 65, + "column": 28 + }, + "end": { + "line": 65, + "column": 29 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 3956, + "end": 3961, + "loc": { + "start": { + "line": 66, + "column": 4 + }, + "end": { + "line": 66, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3961, + "end": 3962, + "loc": { + "start": { + "line": 66, + "column": 9 + }, + "end": { + "line": 66, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "title", + "start": 3962, + "end": 3967, + "loc": { + "start": { + "line": 66, + "column": 10 + }, + "end": { + "line": 66, + "column": 15 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3968, + "end": 3969, + "loc": { + "start": { + "line": 66, + "column": 16 + }, + "end": { + "line": 66, + "column": 17 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "", + "start": 3970, + "end": 3972, + "loc": { + "start": { + "line": 66, + "column": 18 + }, + "end": { + "line": 66, + "column": 20 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3972, + "end": 3973, + "loc": { + "start": { + "line": 66, + "column": 20 + }, + "end": { + "line": 66, + "column": 21 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 3978, + "end": 3983, + "loc": { + "start": { + "line": 67, + "column": 4 + }, + "end": { + "line": 67, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3983, + "end": 3984, + "loc": { + "start": { + "line": 67, + "column": 9 + }, + "end": { + "line": 67, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "author", + "start": 3984, + "end": 3990, + "loc": { + "start": { + "line": 67, + "column": 10 + }, + "end": { + "line": 67, + "column": 16 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 3991, + "end": 3992, + "loc": { + "start": { + "line": 67, + "column": 17 + }, + "end": { + "line": 67, + "column": 18 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "", + "start": 3993, + "end": 3995, + "loc": { + "start": { + "line": 67, + "column": 19 + }, + "end": { + "line": 67, + "column": 21 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 3995, + "end": 3996, + "loc": { + "start": { + "line": 67, + "column": 21 + }, + "end": { + "line": 67, + "column": 22 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4001, + "end": 4006, + "loc": { + "start": { + "line": 68, + "column": 4 + }, + "end": { + "line": 68, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4006, + "end": 4007, + "loc": { + "start": { + "line": 68, + "column": 9 + }, + "end": { + "line": 68, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "created", + "start": 4007, + "end": 4014, + "loc": { + "start": { + "line": 68, + "column": 10 + }, + "end": { + "line": 68, + "column": 17 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4015, + "end": 4016, + "loc": { + "start": { + "line": 68, + "column": 18 + }, + "end": { + "line": 68, + "column": 19 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "", + "start": 4017, + "end": 4019, + "loc": { + "start": { + "line": 68, + "column": 20 + }, + "end": { + "line": 68, + "column": 22 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4019, + "end": 4020, + "loc": { + "start": { + "line": 68, + "column": 22 + }, + "end": { + "line": 68, + "column": 23 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4025, + "end": 4030, + "loc": { + "start": { + "line": 69, + "column": 4 + }, + "end": { + "line": 69, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4030, + "end": 4031, + "loc": { + "start": { + "line": 69, + "column": 9 + }, + "end": { + "line": 69, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "numMetaObjects", + "start": 4031, + "end": 4045, + "loc": { + "start": { + "line": 69, + "column": 10 + }, + "end": { + "line": 69, + "column": 24 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4046, + "end": 4047, + "loc": { + "start": { + "line": 69, + "column": 25 + }, + "end": { + "line": 69, + "column": 26 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4048, + "end": 4049, + "loc": { + "start": { + "line": 69, + "column": 27 + }, + "end": { + "line": 69, + "column": 28 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4049, + "end": 4050, + "loc": { + "start": { + "line": 69, + "column": 28 + }, + "end": { + "line": 69, + "column": 29 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4055, + "end": 4060, + "loc": { + "start": { + "line": 70, + "column": 4 + }, + "end": { + "line": 70, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4060, + "end": 4061, + "loc": { + "start": { + "line": 70, + "column": 9 + }, + "end": { + "line": 70, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "numPropertySets", + "start": 4061, + "end": 4076, + "loc": { + "start": { + "line": 70, + "column": 10 + }, + "end": { + "line": 70, + "column": 25 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4077, + "end": 4078, + "loc": { + "start": { + "line": 70, + "column": 26 + }, + "end": { + "line": 70, + "column": 27 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4079, + "end": 4080, + "loc": { + "start": { + "line": 70, + "column": 28 + }, + "end": { + "line": 70, + "column": 29 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4080, + "end": 4081, + "loc": { + "start": { + "line": 70, + "column": 29 + }, + "end": { + "line": 70, + "column": 30 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4086, + "end": 4091, + "loc": { + "start": { + "line": 71, + "column": 4 + }, + "end": { + "line": 71, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4091, + "end": 4092, + "loc": { + "start": { + "line": 71, + "column": 9 + }, + "end": { + "line": 71, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "numTriangles", + "start": 4092, + "end": 4104, + "loc": { + "start": { + "line": 71, + "column": 10 + }, + "end": { + "line": 71, + "column": 22 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4105, + "end": 4106, + "loc": { + "start": { + "line": 71, + "column": 23 + }, + "end": { + "line": 71, + "column": 24 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4107, + "end": 4108, + "loc": { + "start": { + "line": 71, + "column": 25 + }, + "end": { + "line": 71, + "column": 26 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4108, + "end": 4109, + "loc": { + "start": { + "line": 71, + "column": 26 + }, + "end": { + "line": 71, + "column": 27 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4114, + "end": 4119, + "loc": { + "start": { + "line": 72, + "column": 4 + }, + "end": { + "line": 72, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4119, + "end": 4120, + "loc": { + "start": { + "line": 72, + "column": 9 + }, + "end": { + "line": 72, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "numVertices", + "start": 4120, + "end": 4131, + "loc": { + "start": { + "line": 72, + "column": 10 + }, + "end": { + "line": 72, + "column": 21 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4132, + "end": 4133, + "loc": { + "start": { + "line": 72, + "column": 22 + }, + "end": { + "line": 72, + "column": 23 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4134, + "end": 4135, + "loc": { + "start": { + "line": 72, + "column": 24 + }, + "end": { + "line": 72, + "column": 25 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4135, + "end": 4136, + "loc": { + "start": { + "line": 72, + "column": 25 + }, + "end": { + "line": 72, + "column": 26 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4141, + "end": 4146, + "loc": { + "start": { + "line": 73, + "column": 4 + }, + "end": { + "line": 73, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4146, + "end": 4147, + "loc": { + "start": { + "line": 73, + "column": 9 + }, + "end": { + "line": 73, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "numNormals", + "start": 4147, + "end": 4157, + "loc": { + "start": { + "line": 73, + "column": 10 + }, + "end": { + "line": 73, + "column": 20 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4158, + "end": 4159, + "loc": { + "start": { + "line": 73, + "column": 21 + }, + "end": { + "line": 73, + "column": 22 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4160, + "end": 4161, + "loc": { + "start": { + "line": 73, + "column": 23 + }, + "end": { + "line": 73, + "column": 24 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4161, + "end": 4162, + "loc": { + "start": { + "line": 73, + "column": 24 + }, + "end": { + "line": 73, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4167, + "end": 4172, + "loc": { + "start": { + "line": 74, + "column": 4 + }, + "end": { + "line": 74, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4172, + "end": 4173, + "loc": { + "start": { + "line": 74, + "column": 9 + }, + "end": { + "line": 74, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "numUVs", + "start": 4173, + "end": 4179, + "loc": { + "start": { + "line": 74, + "column": 10 + }, + "end": { + "line": 74, + "column": 16 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4180, + "end": 4181, + "loc": { + "start": { + "line": 74, + "column": 17 + }, + "end": { + "line": 74, + "column": 18 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4182, + "end": 4183, + "loc": { + "start": { + "line": 74, + "column": 19 + }, + "end": { + "line": 74, + "column": 20 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4183, + "end": 4184, + "loc": { + "start": { + "line": 74, + "column": 20 + }, + "end": { + "line": 74, + "column": 21 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4189, + "end": 4194, + "loc": { + "start": { + "line": 75, + "column": 4 + }, + "end": { + "line": 75, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4194, + "end": 4195, + "loc": { + "start": { + "line": 75, + "column": 9 + }, + "end": { + "line": 75, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "numTextures", + "start": 4195, + "end": 4206, + "loc": { + "start": { + "line": 75, + "column": 10 + }, + "end": { + "line": 75, + "column": 21 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4207, + "end": 4208, + "loc": { + "start": { + "line": 75, + "column": 22 + }, + "end": { + "line": 75, + "column": 23 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4209, + "end": 4210, + "loc": { + "start": { + "line": 75, + "column": 24 + }, + "end": { + "line": 75, + "column": 25 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4210, + "end": 4211, + "loc": { + "start": { + "line": 75, + "column": 25 + }, + "end": { + "line": 75, + "column": 26 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4216, + "end": 4221, + "loc": { + "start": { + "line": 76, + "column": 4 + }, + "end": { + "line": 76, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4221, + "end": 4222, + "loc": { + "start": { + "line": 76, + "column": 9 + }, + "end": { + "line": 76, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "numTextureSets", + "start": 4222, + "end": 4236, + "loc": { + "start": { + "line": 76, + "column": 10 + }, + "end": { + "line": 76, + "column": 24 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4237, + "end": 4238, + "loc": { + "start": { + "line": 76, + "column": 25 + }, + "end": { + "line": 76, + "column": 26 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4239, + "end": 4240, + "loc": { + "start": { + "line": 76, + "column": 27 + }, + "end": { + "line": 76, + "column": 28 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4240, + "end": 4241, + "loc": { + "start": { + "line": 76, + "column": 28 + }, + "end": { + "line": 76, + "column": 29 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4246, + "end": 4251, + "loc": { + "start": { + "line": 77, + "column": 4 + }, + "end": { + "line": 77, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4251, + "end": 4252, + "loc": { + "start": { + "line": 77, + "column": 9 + }, + "end": { + "line": 77, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "numObjects", + "start": 4252, + "end": 4262, + "loc": { + "start": { + "line": 77, + "column": 10 + }, + "end": { + "line": 77, + "column": 20 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4263, + "end": 4264, + "loc": { + "start": { + "line": 77, + "column": 21 + }, + "end": { + "line": 77, + "column": 22 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4265, + "end": 4266, + "loc": { + "start": { + "line": 77, + "column": 23 + }, + "end": { + "line": 77, + "column": 24 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4266, + "end": 4267, + "loc": { + "start": { + "line": 77, + "column": 24 + }, + "end": { + "line": 77, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4272, + "end": 4277, + "loc": { + "start": { + "line": 78, + "column": 4 + }, + "end": { + "line": 78, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4277, + "end": 4278, + "loc": { + "start": { + "line": 78, + "column": 9 + }, + "end": { + "line": 78, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "numGeometries", + "start": 4278, + "end": 4291, + "loc": { + "start": { + "line": 78, + "column": 10 + }, + "end": { + "line": 78, + "column": 23 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4292, + "end": 4293, + "loc": { + "start": { + "line": 78, + "column": 24 + }, + "end": { + "line": 78, + "column": 25 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4294, + "end": 4295, + "loc": { + "start": { + "line": 78, + "column": 26 + }, + "end": { + "line": 78, + "column": 27 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4295, + "end": 4296, + "loc": { + "start": { + "line": 78, + "column": 27 + }, + "end": { + "line": 78, + "column": 28 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4301, + "end": 4306, + "loc": { + "start": { + "line": 79, + "column": 4 + }, + "end": { + "line": 79, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4306, + "end": 4307, + "loc": { + "start": { + "line": 79, + "column": 9 + }, + "end": { + "line": 79, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceSize", + "start": 4307, + "end": 4317, + "loc": { + "start": { + "line": 79, + "column": 10 + }, + "end": { + "line": 79, + "column": 20 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4318, + "end": 4319, + "loc": { + "start": { + "line": 79, + "column": 21 + }, + "end": { + "line": 79, + "column": 22 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4320, + "end": 4321, + "loc": { + "start": { + "line": 79, + "column": 23 + }, + "end": { + "line": 79, + "column": 24 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4321, + "end": 4322, + "loc": { + "start": { + "line": 79, + "column": 24 + }, + "end": { + "line": 79, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4327, + "end": 4332, + "loc": { + "start": { + "line": 80, + "column": 4 + }, + "end": { + "line": 80, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4332, + "end": 4333, + "loc": { + "start": { + "line": 80, + "column": 9 + }, + "end": { + "line": 80, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "xktSize", + "start": 4333, + "end": 4340, + "loc": { + "start": { + "line": 80, + "column": 10 + }, + "end": { + "line": 80, + "column": 17 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4341, + "end": 4342, + "loc": { + "start": { + "line": 80, + "column": 18 + }, + "end": { + "line": 80, + "column": 19 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4343, + "end": 4344, + "loc": { + "start": { + "line": 80, + "column": 20 + }, + "end": { + "line": 80, + "column": 21 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4344, + "end": 4345, + "loc": { + "start": { + "line": 80, + "column": 21 + }, + "end": { + "line": 80, + "column": 22 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4350, + "end": 4355, + "loc": { + "start": { + "line": 81, + "column": 4 + }, + "end": { + "line": 81, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4355, + "end": 4356, + "loc": { + "start": { + "line": 81, + "column": 9 + }, + "end": { + "line": 81, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "texturesSize", + "start": 4356, + "end": 4368, + "loc": { + "start": { + "line": 81, + "column": 10 + }, + "end": { + "line": 81, + "column": 22 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4369, + "end": 4370, + "loc": { + "start": { + "line": 81, + "column": 23 + }, + "end": { + "line": 81, + "column": 24 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4371, + "end": 4372, + "loc": { + "start": { + "line": 81, + "column": 25 + }, + "end": { + "line": 81, + "column": 26 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4372, + "end": 4373, + "loc": { + "start": { + "line": 81, + "column": 26 + }, + "end": { + "line": 81, + "column": 27 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4378, + "end": 4383, + "loc": { + "start": { + "line": 82, + "column": 4 + }, + "end": { + "line": 82, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4383, + "end": 4384, + "loc": { + "start": { + "line": 82, + "column": 9 + }, + "end": { + "line": 82, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "xktVersion", + "start": 4384, + "end": 4394, + "loc": { + "start": { + "line": 82, + "column": 10 + }, + "end": { + "line": 82, + "column": 20 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4395, + "end": 4396, + "loc": { + "start": { + "line": 82, + "column": 21 + }, + "end": { + "line": 82, + "column": 22 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "", + "start": 4397, + "end": 4399, + "loc": { + "start": { + "line": 82, + "column": 23 + }, + "end": { + "line": 82, + "column": 25 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4399, + "end": 4400, + "loc": { + "start": { + "line": 82, + "column": 25 + }, + "end": { + "line": 82, + "column": 26 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4405, + "end": 4410, + "loc": { + "start": { + "line": 83, + "column": 4 + }, + "end": { + "line": 83, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4410, + "end": 4411, + "loc": { + "start": { + "line": 83, + "column": 9 + }, + "end": { + "line": 83, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "compressionRatio", + "start": 4411, + "end": 4427, + "loc": { + "start": { + "line": 83, + "column": 10 + }, + "end": { + "line": 83, + "column": 26 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4428, + "end": 4429, + "loc": { + "start": { + "line": 83, + "column": 27 + }, + "end": { + "line": 83, + "column": 28 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4430, + "end": 4431, + "loc": { + "start": { + "line": 83, + "column": 29 + }, + "end": { + "line": 83, + "column": 30 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4431, + "end": 4432, + "loc": { + "start": { + "line": 83, + "column": 30 + }, + "end": { + "line": 83, + "column": 31 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4437, + "end": 4442, + "loc": { + "start": { + "line": 84, + "column": 4 + }, + "end": { + "line": 84, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4442, + "end": 4443, + "loc": { + "start": { + "line": 84, + "column": 9 + }, + "end": { + "line": 84, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "conversionTime", + "start": 4443, + "end": 4457, + "loc": { + "start": { + "line": 84, + "column": 10 + }, + "end": { + "line": 84, + "column": 24 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4458, + "end": 4459, + "loc": { + "start": { + "line": 84, + "column": 25 + }, + "end": { + "line": 84, + "column": 26 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 0, + "start": 4460, + "end": 4461, + "loc": { + "start": { + "line": 84, + "column": 27 + }, + "end": { + "line": 84, + "column": 28 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4461, + "end": 4462, + "loc": { + "start": { + "line": 84, + "column": 28 + }, + "end": { + "line": 84, + "column": 29 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 4467, + "end": 4472, + "loc": { + "start": { + "line": 85, + "column": 4 + }, + "end": { + "line": 85, + "column": 9 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4472, + "end": 4473, + "loc": { + "start": { + "line": 85, + "column": 9 + }, + "end": { + "line": 85, + "column": 10 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "aabb", + "start": 4473, + "end": 4477, + "loc": { + "start": { + "line": 85, + "column": 10 + }, + "end": { + "line": 85, + "column": 14 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4478, + "end": 4479, + "loc": { + "start": { + "line": 85, + "column": 15 + }, + "end": { + "line": 85, + "column": 16 + } + } + }, + { + "type": { + "label": "null", + "keyword": "null", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "null", + "start": 4480, + "end": 4484, + "loc": { + "start": { + "line": 85, + "column": 17 + }, + "end": { + "line": 85, + "column": 21 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4484, + "end": 4485, + "loc": { + "start": { + "line": 85, + "column": 21 + }, + "end": { + "line": 85, + "column": 22 + } + } + }, + { + "type": { + "label": "return", + "keyword": "return", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "return", + "start": 4491, + "end": 4497, + "loc": { + "start": { + "line": 87, + "column": 4 + }, + "end": { + "line": 87, + "column": 10 + } + } + }, + { + "type": { + "label": "new", + "keyword": "new", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "new", + "start": 4498, + "end": 4501, + "loc": { + "start": { + "line": 87, + "column": 11 + }, + "end": { + "line": 87, + "column": 14 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "Promise", + "start": 4502, + "end": 4509, + "loc": { + "start": { + "line": 87, + "column": 15 + }, + "end": { + "line": 87, + "column": 22 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4509, + "end": 4510, + "loc": { + "start": { + "line": 87, + "column": 22 + }, + "end": { + "line": 87, + "column": 23 + } + } + }, + { + "type": { + "label": "function", + "keyword": "function", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "function", + "start": 4510, + "end": 4518, + "loc": { + "start": { + "line": 87, + "column": 23 + }, + "end": { + "line": 87, + "column": 31 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4519, + "end": 4520, + "loc": { + "start": { + "line": 87, + "column": 32 + }, + "end": { + "line": 87, + "column": 33 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "resolve", + "start": 4520, + "end": 4527, + "loc": { + "start": { + "line": 87, + "column": 33 + }, + "end": { + "line": 87, + "column": 40 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4527, + "end": 4528, + "loc": { + "start": { + "line": 87, + "column": 40 + }, + "end": { + "line": 87, + "column": 41 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "reject", + "start": 4529, + "end": 4535, + "loc": { + "start": { + "line": 87, + "column": 42 + }, + "end": { + "line": 87, + "column": 48 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4535, + "end": 4536, + "loc": { + "start": { + "line": 87, + "column": 48 + }, + "end": { + "line": 87, + "column": 49 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4537, + "end": 4538, + "loc": { + "start": { + "line": 87, + "column": 50 + }, + "end": { + "line": 87, + "column": 51 + } + } + }, + { + "type": { + "label": "const", + "keyword": "const", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "const", + "start": 4547, + "end": 4552, + "loc": { + "start": { + "line": 88, + "column": 8 + }, + "end": { + "line": 88, + "column": 13 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "_log", + "start": 4553, + "end": 4557, + "loc": { + "start": { + "line": 88, + "column": 14 + }, + "end": { + "line": 88, + "column": 18 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4558, + "end": 4559, + "loc": { + "start": { + "line": 88, + "column": 19 + }, + "end": { + "line": 88, + "column": 20 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "log", + "start": 4560, + "end": 4563, + "loc": { + "start": { + "line": 88, + "column": 21 + }, + "end": { + "line": 88, + "column": 24 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4563, + "end": 4564, + "loc": { + "start": { + "line": 88, + "column": 24 + }, + "end": { + "line": 88, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "log", + "start": 4573, + "end": 4576, + "loc": { + "start": { + "line": 89, + "column": 8 + }, + "end": { + "line": 89, + "column": 11 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4577, + "end": 4578, + "loc": { + "start": { + "line": 89, + "column": 12 + }, + "end": { + "line": 89, + "column": 13 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4579, + "end": 4580, + "loc": { + "start": { + "line": 89, + "column": 14 + }, + "end": { + "line": 89, + "column": 15 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "msg", + "start": 4580, + "end": 4583, + "loc": { + "start": { + "line": 89, + "column": 15 + }, + "end": { + "line": 89, + "column": 18 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4583, + "end": 4584, + "loc": { + "start": { + "line": 89, + "column": 18 + }, + "end": { + "line": 89, + "column": 19 + } + } + }, + { + "type": { + "label": "=>", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4585, + "end": 4587, + "loc": { + "start": { + "line": 89, + "column": 20 + }, + "end": { + "line": 89, + "column": 22 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4588, + "end": 4589, + "loc": { + "start": { + "line": 89, + "column": 23 + }, + "end": { + "line": 89, + "column": 24 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "_log", + "start": 4602, + "end": 4606, + "loc": { + "start": { + "line": 90, + "column": 12 + }, + "end": { + "line": 90, + "column": 16 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4606, + "end": 4607, + "loc": { + "start": { + "line": 90, + "column": 16 + }, + "end": { + "line": 90, + "column": 17 + } + } + }, + { + "type": { + "label": "`", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4607, + "end": 4608, + "loc": { + "start": { + "line": 90, + "column": 17 + }, + "end": { + "line": 90, + "column": 18 + } + } + }, + { + "type": { + "label": "template", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "[convert2xkt] ", + "start": 4608, + "end": 4622, + "loc": { + "start": { + "line": 90, + "column": 18 + }, + "end": { + "line": 90, + "column": 32 + } + } + }, + { + "type": { + "label": "${", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4622, + "end": 4624, + "loc": { + "start": { + "line": 90, + "column": 32 + }, + "end": { + "line": 90, + "column": 34 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "msg", + "start": 4624, + "end": 4627, + "loc": { + "start": { + "line": 90, + "column": 34 + }, + "end": { + "line": 90, + "column": 37 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4627, + "end": 4628, + "loc": { + "start": { + "line": 90, + "column": 37 + }, + "end": { + "line": 90, + "column": 38 + } + } + }, + { + "type": { + "label": "template", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "", + "start": 4628, + "end": 4628, + "loc": { + "start": { + "line": 90, + "column": 38 + }, + "end": { + "line": 90, + "column": 38 + } + } + }, + { + "type": { + "label": "`", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4628, + "end": 4629, + "loc": { + "start": { + "line": 90, + "column": 38 + }, + "end": { + "line": 90, + "column": 39 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4629, + "end": 4630, + "loc": { + "start": { + "line": 90, + "column": 39 + }, + "end": { + "line": 90, + "column": 40 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4639, + "end": 4640, + "loc": { + "start": { + "line": 91, + "column": 8 + }, + "end": { + "line": 91, + "column": 9 + } + } + }, + { + "type": { + "label": "if", + "keyword": "if", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "if", + "start": 4650, + "end": 4652, + "loc": { + "start": { + "line": 93, + "column": 8 + }, + "end": { + "line": 93, + "column": 10 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4653, + "end": 4654, + "loc": { + "start": { + "line": 93, + "column": 11 + }, + "end": { + "line": 93, + "column": 12 + } + } + }, + { + "type": { + "label": "prefix", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": true, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "!", + "start": 4654, + "end": 4655, + "loc": { + "start": { + "line": 93, + "column": 12 + }, + "end": { + "line": 93, + "column": 13 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceData", + "start": 4655, + "end": 4665, + "loc": { + "start": { + "line": 93, + "column": 13 + }, + "end": { + "line": 93, + "column": 23 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4665, + "end": 4666, + "loc": { + "start": { + "line": 93, + "column": 23 + }, + "end": { + "line": 93, + "column": 24 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4667, + "end": 4668, + "loc": { + "start": { + "line": 93, + "column": 25 + }, + "end": { + "line": 93, + "column": 26 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "reject", + "start": 4681, + "end": 4687, + "loc": { + "start": { + "line": 94, + "column": 12 + }, + "end": { + "line": 94, + "column": 18 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4687, + "end": 4688, + "loc": { + "start": { + "line": 94, + "column": 18 + }, + "end": { + "line": 94, + "column": 19 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "Argument expected: source or sourceData", + "start": 4688, + "end": 4729, + "loc": { + "start": { + "line": 94, + "column": 19 + }, + "end": { + "line": 94, + "column": 60 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4729, + "end": 4730, + "loc": { + "start": { + "line": 94, + "column": 60 + }, + "end": { + "line": 94, + "column": 61 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4730, + "end": 4731, + "loc": { + "start": { + "line": 94, + "column": 61 + }, + "end": { + "line": 94, + "column": 62 + } + } + }, + { + "type": { + "label": "return", + "keyword": "return", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "return", + "start": 4744, + "end": 4750, + "loc": { + "start": { + "line": 95, + "column": 12 + }, + "end": { + "line": 95, + "column": 18 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4750, + "end": 4751, + "loc": { + "start": { + "line": 95, + "column": 18 + }, + "end": { + "line": 95, + "column": 19 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4760, + "end": 4761, + "loc": { + "start": { + "line": 96, + "column": 8 + }, + "end": { + "line": 96, + "column": 9 + } + } + }, + { + "type": { + "label": "if", + "keyword": "if", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "if", + "start": 4771, + "end": 4773, + "loc": { + "start": { + "line": 98, + "column": 8 + }, + "end": { + "line": 98, + "column": 10 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4774, + "end": 4775, + "loc": { + "start": { + "line": 98, + "column": 11 + }, + "end": { + "line": 98, + "column": 12 + } + } + }, + { + "type": { + "label": "prefix", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": true, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "!", + "start": 4775, + "end": 4776, + "loc": { + "start": { + "line": 98, + "column": 12 + }, + "end": { + "line": 98, + "column": 13 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "outputXKTModel", + "start": 4776, + "end": 4790, + "loc": { + "start": { + "line": 98, + "column": 13 + }, + "end": { + "line": 98, + "column": 27 + } + } + }, + { + "type": { + "label": "&&", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": 2, + "updateContext": null + }, + "value": "&&", + "start": 4791, + "end": 4793, + "loc": { + "start": { + "line": 98, + "column": 28 + }, + "end": { + "line": 98, + "column": 30 + } + } + }, + { + "type": { + "label": "prefix", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": true, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "!", + "start": 4794, + "end": 4795, + "loc": { + "start": { + "line": 98, + "column": 31 + }, + "end": { + "line": 98, + "column": 32 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "outputXKT", + "start": 4795, + "end": 4804, + "loc": { + "start": { + "line": 98, + "column": 32 + }, + "end": { + "line": 98, + "column": 41 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4804, + "end": 4805, + "loc": { + "start": { + "line": 98, + "column": 41 + }, + "end": { + "line": 98, + "column": 42 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4806, + "end": 4807, + "loc": { + "start": { + "line": 98, + "column": 43 + }, + "end": { + "line": 98, + "column": 44 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "reject", + "start": 4820, + "end": 4826, + "loc": { + "start": { + "line": 99, + "column": 12 + }, + "end": { + "line": 99, + "column": 18 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4826, + "end": 4827, + "loc": { + "start": { + "line": 99, + "column": 18 + }, + "end": { + "line": 99, + "column": 19 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "Argument expected: output, outputXKTModel or outputXKT", + "start": 4827, + "end": 4883, + "loc": { + "start": { + "line": 99, + "column": 19 + }, + "end": { + "line": 99, + "column": 75 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4883, + "end": 4884, + "loc": { + "start": { + "line": 99, + "column": 75 + }, + "end": { + "line": 99, + "column": 76 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4884, + "end": 4885, + "loc": { + "start": { + "line": 99, + "column": 76 + }, + "end": { + "line": 99, + "column": 77 + } + } + }, + { + "type": { + "label": "return", + "keyword": "return", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "return", + "start": 4898, + "end": 4904, + "loc": { + "start": { + "line": 100, + "column": 12 + }, + "end": { + "line": 100, + "column": 18 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4904, + "end": 4905, + "loc": { + "start": { + "line": 100, + "column": 18 + }, + "end": { + "line": 100, + "column": 19 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4914, + "end": 4915, + "loc": { + "start": { + "line": 101, + "column": 8 + }, + "end": { + "line": 101, + "column": 9 + } + } + }, + { + "type": { + "label": "const", + "keyword": "const", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "const", + "start": 4925, + "end": 4930, + "loc": { + "start": { + "line": 103, + "column": 8 + }, + "end": { + "line": 103, + "column": 13 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceConfigs", + "start": 4931, + "end": 4944, + "loc": { + "start": { + "line": 103, + "column": 14 + }, + "end": { + "line": 103, + "column": 27 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4945, + "end": 4946, + "loc": { + "start": { + "line": 103, + "column": 28 + }, + "end": { + "line": 103, + "column": 29 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "configs", + "start": 4947, + "end": 4954, + "loc": { + "start": { + "line": 103, + "column": 30 + }, + "end": { + "line": 103, + "column": 37 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4954, + "end": 4955, + "loc": { + "start": { + "line": 103, + "column": 37 + }, + "end": { + "line": 103, + "column": 38 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceConfigs", + "start": 4955, + "end": 4968, + "loc": { + "start": { + "line": 103, + "column": 38 + }, + "end": { + "line": 103, + "column": 51 + } + } + }, + { + "type": { + "label": "||", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": 1, + "updateContext": null + }, + "value": "||", + "start": 4969, + "end": 4971, + "loc": { + "start": { + "line": 103, + "column": 52 + }, + "end": { + "line": 103, + "column": 54 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4972, + "end": 4973, + "loc": { + "start": { + "line": 103, + "column": 55 + }, + "end": { + "line": 103, + "column": 56 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 4973, + "end": 4974, + "loc": { + "start": { + "line": 103, + "column": 56 + }, + "end": { + "line": 103, + "column": 57 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 4974, + "end": 4975, + "loc": { + "start": { + "line": 103, + "column": 57 + }, + "end": { + "line": 103, + "column": 58 + } + } + }, + { + "type": { + "label": "const", + "keyword": "const", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "const", + "start": 4984, + "end": 4989, + "loc": { + "start": { + "line": 104, + "column": 8 + }, + "end": { + "line": 104, + "column": 13 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "ext", + "start": 4990, + "end": 4993, + "loc": { + "start": { + "line": 104, + "column": 14 + }, + "end": { + "line": 104, + "column": 17 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 4994, + "end": 4995, + "loc": { + "start": { + "line": 104, + "column": 18 + }, + "end": { + "line": 104, + "column": 19 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "glb", + "start": 4996, + "end": 5001, + "loc": { + "start": { + "line": 104, + "column": 20 + }, + "end": { + "line": 104, + "column": 25 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5001, + "end": 5002, + "loc": { + "start": { + "line": 104, + "column": 25 + }, + "end": { + "line": 104, + "column": 26 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "log", + "start": 5012, + "end": 5015, + "loc": { + "start": { + "line": 106, + "column": 8 + }, + "end": { + "line": 106, + "column": 11 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5015, + "end": 5016, + "loc": { + "start": { + "line": 106, + "column": 11 + }, + "end": { + "line": 106, + "column": 12 + } + } + }, + { + "type": { + "label": "`", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5016, + "end": 5017, + "loc": { + "start": { + "line": 106, + "column": 12 + }, + "end": { + "line": 106, + "column": 13 + } + } + }, + { + "type": { + "label": "template", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "Input file extension: \"", + "start": 5017, + "end": 5040, + "loc": { + "start": { + "line": 106, + "column": 13 + }, + "end": { + "line": 106, + "column": 36 + } + } + }, + { + "type": { + "label": "${", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5040, + "end": 5042, + "loc": { + "start": { + "line": 106, + "column": 36 + }, + "end": { + "line": 106, + "column": 38 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "ext", + "start": 5042, + "end": 5045, + "loc": { + "start": { + "line": 106, + "column": 38 + }, + "end": { + "line": 106, + "column": 41 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5045, + "end": 5046, + "loc": { + "start": { + "line": 106, + "column": 41 + }, + "end": { + "line": 106, + "column": 42 + } + } + }, + { + "type": { + "label": "template", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "\"", + "start": 5046, + "end": 5047, + "loc": { + "start": { + "line": 106, + "column": 42 + }, + "end": { + "line": 106, + "column": 43 + } + } + }, + { + "type": { + "label": "`", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5047, + "end": 5048, + "loc": { + "start": { + "line": 106, + "column": 43 + }, + "end": { + "line": 106, + "column": 44 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5048, + "end": 5049, + "loc": { + "start": { + "line": 106, + "column": 44 + }, + "end": { + "line": 106, + "column": 45 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5049, + "end": 5050, + "loc": { + "start": { + "line": 106, + "column": 45 + }, + "end": { + "line": 106, + "column": 46 + } + } + }, + { + "type": { + "label": "let", + "keyword": "let", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "let", + "start": 5060, + "end": 5063, + "loc": { + "start": { + "line": 108, + "column": 8 + }, + "end": { + "line": 108, + "column": 11 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "fileTypeConfigs", + "start": 5064, + "end": 5079, + "loc": { + "start": { + "line": 108, + "column": 12 + }, + "end": { + "line": 108, + "column": 27 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 5080, + "end": 5081, + "loc": { + "start": { + "line": 108, + "column": 28 + }, + "end": { + "line": 108, + "column": 29 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceConfigs", + "start": 5082, + "end": 5095, + "loc": { + "start": { + "line": 108, + "column": 30 + }, + "end": { + "line": 108, + "column": 43 + } + } + }, + { + "type": { + "label": "[", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5095, + "end": 5096, + "loc": { + "start": { + "line": 108, + "column": 43 + }, + "end": { + "line": 108, + "column": 44 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "ext", + "start": 5096, + "end": 5099, + "loc": { + "start": { + "line": 108, + "column": 44 + }, + "end": { + "line": 108, + "column": 47 + } + } + }, + { + "type": { + "label": "]", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5099, + "end": 5100, + "loc": { + "start": { + "line": 108, + "column": 47 + }, + "end": { + "line": 108, + "column": 48 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5100, + "end": 5101, + "loc": { + "start": { + "line": 108, + "column": 48 + }, + "end": { + "line": 108, + "column": 49 + } + } + }, + { + "type": { + "label": "if", + "keyword": "if", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "if", + "start": 5111, + "end": 5113, + "loc": { + "start": { + "line": 110, + "column": 8 + }, + "end": { + "line": 110, + "column": 10 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5114, + "end": 5115, + "loc": { + "start": { + "line": 110, + "column": 11 + }, + "end": { + "line": 110, + "column": 12 + } + } + }, + { + "type": { + "label": "prefix", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": true, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "!", + "start": 5115, + "end": 5116, + "loc": { + "start": { + "line": 110, + "column": 12 + }, + "end": { + "line": 110, + "column": 13 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "fileTypeConfigs", + "start": 5116, + "end": 5131, + "loc": { + "start": { + "line": 110, + "column": 13 + }, + "end": { + "line": 110, + "column": 28 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5131, + "end": 5132, + "loc": { + "start": { + "line": 110, + "column": 28 + }, + "end": { + "line": 110, + "column": 29 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5133, + "end": 5134, + "loc": { + "start": { + "line": 110, + "column": 30 + }, + "end": { + "line": 110, + "column": 31 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "log", + "start": 5147, + "end": 5150, + "loc": { + "start": { + "line": 111, + "column": 12 + }, + "end": { + "line": 111, + "column": 15 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5150, + "end": 5151, + "loc": { + "start": { + "line": 111, + "column": 15 + }, + "end": { + "line": 111, + "column": 16 + } + } + }, + { + "type": { + "label": "`", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5151, + "end": 5152, + "loc": { + "start": { + "line": 111, + "column": 16 + }, + "end": { + "line": 111, + "column": 17 + } + } + }, + { + "type": { + "label": "template", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "[WARNING] Could not find configs sourceConfigs entry for source format \"", + "start": 5152, + "end": 5224, + "loc": { + "start": { + "line": 111, + "column": 17 + }, + "end": { + "line": 111, + "column": 89 + } + } + }, + { + "type": { + "label": "${", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5224, + "end": 5226, + "loc": { + "start": { + "line": 111, + "column": 89 + }, + "end": { + "line": 111, + "column": 91 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "ext", + "start": 5226, + "end": 5229, + "loc": { + "start": { + "line": 111, + "column": 91 + }, + "end": { + "line": 111, + "column": 94 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5229, + "end": 5230, + "loc": { + "start": { + "line": 111, + "column": 94 + }, + "end": { + "line": 111, + "column": 95 + } + } + }, + { + "type": { + "label": "template", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "\". This is derived from the source file name extension. Will use internal default configs.", + "start": 5230, + "end": 5320, + "loc": { + "start": { + "line": 111, + "column": 95 + }, + "end": { + "line": 111, + "column": 185 + } + } + }, + { + "type": { + "label": "`", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5320, + "end": 5321, + "loc": { + "start": { + "line": 111, + "column": 185 + }, + "end": { + "line": 111, + "column": 186 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5321, + "end": 5322, + "loc": { + "start": { + "line": 111, + "column": 186 + }, + "end": { + "line": 111, + "column": 187 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5322, + "end": 5323, + "loc": { + "start": { + "line": 111, + "column": 187 + }, + "end": { + "line": 111, + "column": 188 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "fileTypeConfigs", + "start": 5336, + "end": 5351, + "loc": { + "start": { + "line": 112, + "column": 12 + }, + "end": { + "line": 112, + "column": 27 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 5352, + "end": 5353, + "loc": { + "start": { + "line": 112, + "column": 28 + }, + "end": { + "line": 112, + "column": 29 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5354, + "end": 5355, + "loc": { + "start": { + "line": 112, + "column": 30 + }, + "end": { + "line": 112, + "column": 31 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5355, + "end": 5356, + "loc": { + "start": { + "line": 112, + "column": 31 + }, + "end": { + "line": 112, + "column": 32 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5356, + "end": 5357, + "loc": { + "start": { + "line": 112, + "column": 32 + }, + "end": { + "line": 112, + "column": 33 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5366, + "end": 5367, + "loc": { + "start": { + "line": 113, + "column": 8 + }, + "end": { + "line": 113, + "column": 9 + } + } + }, + { + "type": { + "label": "function", + "keyword": "function", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "function", + "start": 5377, + "end": 5385, + "loc": { + "start": { + "line": 115, + "column": 8 + }, + "end": { + "line": 115, + "column": 16 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "overrideOption", + "start": 5386, + "end": 5400, + "loc": { + "start": { + "line": 115, + "column": 17 + }, + "end": { + "line": 115, + "column": 31 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5400, + "end": 5401, + "loc": { + "start": { + "line": 115, + "column": 31 + }, + "end": { + "line": 115, + "column": 32 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "option1", + "start": 5401, + "end": 5408, + "loc": { + "start": { + "line": 115, + "column": 32 + }, + "end": { + "line": 115, + "column": 39 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5408, + "end": 5409, + "loc": { + "start": { + "line": 115, + "column": 39 + }, + "end": { + "line": 115, + "column": 40 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "option2", + "start": 5410, + "end": 5417, + "loc": { + "start": { + "line": 115, + "column": 41 + }, + "end": { + "line": 115, + "column": 48 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5417, + "end": 5418, + "loc": { + "start": { + "line": 115, + "column": 48 + }, + "end": { + "line": 115, + "column": 49 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5419, + "end": 5420, + "loc": { + "start": { + "line": 115, + "column": 50 + }, + "end": { + "line": 115, + "column": 51 + } + } + }, + { + "type": { + "label": "if", + "keyword": "if", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "if", + "start": 5433, + "end": 5435, + "loc": { + "start": { + "line": 116, + "column": 12 + }, + "end": { + "line": 116, + "column": 14 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5436, + "end": 5437, + "loc": { + "start": { + "line": 116, + "column": 15 + }, + "end": { + "line": 116, + "column": 16 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "option1", + "start": 5437, + "end": 5444, + "loc": { + "start": { + "line": 116, + "column": 16 + }, + "end": { + "line": 116, + "column": 23 + } + } + }, + { + "type": { + "label": "==/!=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": 6, + "updateContext": null + }, + "value": "!==", + "start": 5445, + "end": 5448, + "loc": { + "start": { + "line": 116, + "column": 24 + }, + "end": { + "line": 116, + "column": 27 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "undefined", + "start": 5449, + "end": 5458, + "loc": { + "start": { + "line": 116, + "column": 28 + }, + "end": { + "line": 116, + "column": 37 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5458, + "end": 5459, + "loc": { + "start": { + "line": 116, + "column": 37 + }, + "end": { + "line": 116, + "column": 38 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5460, + "end": 5461, + "loc": { + "start": { + "line": 116, + "column": 39 + }, + "end": { + "line": 116, + "column": 40 + } + } + }, + { + "type": { + "label": "return", + "keyword": "return", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "return", + "start": 5478, + "end": 5484, + "loc": { + "start": { + "line": 117, + "column": 16 + }, + "end": { + "line": 117, + "column": 22 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "option1", + "start": 5485, + "end": 5492, + "loc": { + "start": { + "line": 117, + "column": 23 + }, + "end": { + "line": 117, + "column": 30 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5492, + "end": 5493, + "loc": { + "start": { + "line": 117, + "column": 30 + }, + "end": { + "line": 117, + "column": 31 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5506, + "end": 5507, + "loc": { + "start": { + "line": 118, + "column": 12 + }, + "end": { + "line": 118, + "column": 13 + } + } + }, + { + "type": { + "label": "return", + "keyword": "return", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "return", + "start": 5520, + "end": 5526, + "loc": { + "start": { + "line": 119, + "column": 12 + }, + "end": { + "line": 119, + "column": 18 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "option2", + "start": 5527, + "end": 5534, + "loc": { + "start": { + "line": 119, + "column": 19 + }, + "end": { + "line": 119, + "column": 26 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5534, + "end": 5535, + "loc": { + "start": { + "line": 119, + "column": 26 + }, + "end": { + "line": 119, + "column": 27 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5544, + "end": 5545, + "loc": { + "start": { + "line": 120, + "column": 8 + }, + "end": { + "line": 120, + "column": 9 + } + } + }, + { + "type": { + "label": "const", + "keyword": "const", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "const", + "start": 5556, + "end": 5561, + "loc": { + "start": { + "line": 123, + "column": 8 + }, + "end": { + "line": 123, + "column": 13 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceFileSizeBytes", + "start": 5562, + "end": 5581, + "loc": { + "start": { + "line": 123, + "column": 14 + }, + "end": { + "line": 123, + "column": 33 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 5582, + "end": 5583, + "loc": { + "start": { + "line": 123, + "column": 34 + }, + "end": { + "line": 123, + "column": 35 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceData", + "start": 5584, + "end": 5594, + "loc": { + "start": { + "line": 123, + "column": 36 + }, + "end": { + "line": 123, + "column": 46 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5594, + "end": 5595, + "loc": { + "start": { + "line": 123, + "column": 46 + }, + "end": { + "line": 123, + "column": 47 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "byteLength", + "start": 5595, + "end": 5605, + "loc": { + "start": { + "line": 123, + "column": 47 + }, + "end": { + "line": 123, + "column": 57 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5605, + "end": 5606, + "loc": { + "start": { + "line": 123, + "column": 57 + }, + "end": { + "line": 123, + "column": 58 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "log", + "start": 5616, + "end": 5619, + "loc": { + "start": { + "line": 125, + "column": 8 + }, + "end": { + "line": 125, + "column": 11 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5619, + "end": 5620, + "loc": { + "start": { + "line": 125, + "column": 11 + }, + "end": { + "line": 125, + "column": 12 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "Input file size: ", + "start": 5620, + "end": 5639, + "loc": { + "start": { + "line": 125, + "column": 12 + }, + "end": { + "line": 125, + "column": 31 + } + } + }, + { + "type": { + "label": "+/-", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": true, + "postfix": false, + "binop": 9, + "updateContext": null + }, + "value": "+", + "start": 5640, + "end": 5641, + "loc": { + "start": { + "line": 125, + "column": 32 + }, + "end": { + "line": 125, + "column": 33 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5642, + "end": 5643, + "loc": { + "start": { + "line": 125, + "column": 34 + }, + "end": { + "line": 125, + "column": 35 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceFileSizeBytes", + "start": 5643, + "end": 5662, + "loc": { + "start": { + "line": 125, + "column": 35 + }, + "end": { + "line": 125, + "column": 54 + } + } + }, + { + "type": { + "label": "/", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": 10, + "updateContext": null + }, + "value": "/", + "start": 5663, + "end": 5664, + "loc": { + "start": { + "line": 125, + "column": 55 + }, + "end": { + "line": 125, + "column": 56 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 1000, + "start": 5665, + "end": 5669, + "loc": { + "start": { + "line": 125, + "column": 57 + }, + "end": { + "line": 125, + "column": 61 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5669, + "end": 5670, + "loc": { + "start": { + "line": 125, + "column": 61 + }, + "end": { + "line": 125, + "column": 62 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5670, + "end": 5671, + "loc": { + "start": { + "line": 125, + "column": 62 + }, + "end": { + "line": 125, + "column": 63 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "toFixed", + "start": 5671, + "end": 5678, + "loc": { + "start": { + "line": 125, + "column": 63 + }, + "end": { + "line": 125, + "column": 70 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5678, + "end": 5679, + "loc": { + "start": { + "line": 125, + "column": 70 + }, + "end": { + "line": 125, + "column": 71 + } + } + }, + { + "type": { + "label": "num", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": 2, + "start": 5679, + "end": 5680, + "loc": { + "start": { + "line": 125, + "column": 71 + }, + "end": { + "line": 125, + "column": 72 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5680, + "end": 5681, + "loc": { + "start": { + "line": 125, + "column": 72 + }, + "end": { + "line": 125, + "column": 73 + } + } + }, + { + "type": { + "label": "+/-", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": true, + "postfix": false, + "binop": 9, + "updateContext": null + }, + "value": "+", + "start": 5682, + "end": 5683, + "loc": { + "start": { + "line": 125, + "column": 74 + }, + "end": { + "line": 125, + "column": 75 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": " kB", + "start": 5684, + "end": 5689, + "loc": { + "start": { + "line": 125, + "column": 76 + }, + "end": { + "line": 125, + "column": 81 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5689, + "end": 5690, + "loc": { + "start": { + "line": 125, + "column": 81 + }, + "end": { + "line": 125, + "column": 82 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5690, + "end": 5691, + "loc": { + "start": { + "line": 125, + "column": 82 + }, + "end": { + "line": 125, + "column": 83 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "minTileSize", + "start": 5703, + "end": 5714, + "loc": { + "start": { + "line": 129, + "column": 8 + }, + "end": { + "line": 129, + "column": 19 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 5715, + "end": 5716, + "loc": { + "start": { + "line": 129, + "column": 20 + }, + "end": { + "line": 129, + "column": 21 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "overrideOption", + "start": 5717, + "end": 5731, + "loc": { + "start": { + "line": 129, + "column": 22 + }, + "end": { + "line": 129, + "column": 36 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5731, + "end": 5732, + "loc": { + "start": { + "line": 129, + "column": 36 + }, + "end": { + "line": 129, + "column": 37 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "fileTypeConfigs", + "start": 5732, + "end": 5747, + "loc": { + "start": { + "line": 129, + "column": 37 + }, + "end": { + "line": 129, + "column": 52 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5747, + "end": 5748, + "loc": { + "start": { + "line": 129, + "column": 52 + }, + "end": { + "line": 129, + "column": 53 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "minTileSize", + "start": 5748, + "end": 5759, + "loc": { + "start": { + "line": 129, + "column": 53 + }, + "end": { + "line": 129, + "column": 64 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5759, + "end": 5760, + "loc": { + "start": { + "line": 129, + "column": 64 + }, + "end": { + "line": 129, + "column": 65 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "minTileSize", + "start": 5761, + "end": 5772, + "loc": { + "start": { + "line": 129, + "column": 66 + }, + "end": { + "line": 129, + "column": 77 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5772, + "end": 5773, + "loc": { + "start": { + "line": 129, + "column": 77 + }, + "end": { + "line": 129, + "column": 78 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5773, + "end": 5774, + "loc": { + "start": { + "line": 129, + "column": 78 + }, + "end": { + "line": 129, + "column": 79 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "rotateX", + "start": 5783, + "end": 5790, + "loc": { + "start": { + "line": 130, + "column": 8 + }, + "end": { + "line": 130, + "column": 15 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 5791, + "end": 5792, + "loc": { + "start": { + "line": 130, + "column": 16 + }, + "end": { + "line": 130, + "column": 17 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "overrideOption", + "start": 5793, + "end": 5807, + "loc": { + "start": { + "line": 130, + "column": 18 + }, + "end": { + "line": 130, + "column": 32 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5807, + "end": 5808, + "loc": { + "start": { + "line": 130, + "column": 32 + }, + "end": { + "line": 130, + "column": 33 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "fileTypeConfigs", + "start": 5808, + "end": 5823, + "loc": { + "start": { + "line": 130, + "column": 33 + }, + "end": { + "line": 130, + "column": 48 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5823, + "end": 5824, + "loc": { + "start": { + "line": 130, + "column": 48 + }, + "end": { + "line": 130, + "column": 49 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "rotateX", + "start": 5824, + "end": 5831, + "loc": { + "start": { + "line": 130, + "column": 49 + }, + "end": { + "line": 130, + "column": 56 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5831, + "end": 5832, + "loc": { + "start": { + "line": 130, + "column": 56 + }, + "end": { + "line": 130, + "column": 57 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "rotateX", + "start": 5833, + "end": 5840, + "loc": { + "start": { + "line": 130, + "column": 58 + }, + "end": { + "line": 130, + "column": 65 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5840, + "end": 5841, + "loc": { + "start": { + "line": 130, + "column": 65 + }, + "end": { + "line": 130, + "column": 66 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5841, + "end": 5842, + "loc": { + "start": { + "line": 130, + "column": 66 + }, + "end": { + "line": 130, + "column": 67 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "reuseGeometries", + "start": 5851, + "end": 5866, + "loc": { + "start": { + "line": 131, + "column": 8 + }, + "end": { + "line": 131, + "column": 23 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 5867, + "end": 5868, + "loc": { + "start": { + "line": 131, + "column": 24 + }, + "end": { + "line": 131, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "overrideOption", + "start": 5869, + "end": 5883, + "loc": { + "start": { + "line": 131, + "column": 26 + }, + "end": { + "line": 131, + "column": 40 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5883, + "end": 5884, + "loc": { + "start": { + "line": 131, + "column": 40 + }, + "end": { + "line": 131, + "column": 41 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "fileTypeConfigs", + "start": 5884, + "end": 5899, + "loc": { + "start": { + "line": 131, + "column": 41 + }, + "end": { + "line": 131, + "column": 56 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5899, + "end": 5900, + "loc": { + "start": { + "line": 131, + "column": 56 + }, + "end": { + "line": 131, + "column": 57 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "reuseGeometries", + "start": 5900, + "end": 5915, + "loc": { + "start": { + "line": 131, + "column": 57 + }, + "end": { + "line": 131, + "column": 72 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5915, + "end": 5916, + "loc": { + "start": { + "line": 131, + "column": 72 + }, + "end": { + "line": 131, + "column": 73 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "reuseGeometries", + "start": 5917, + "end": 5932, + "loc": { + "start": { + "line": 131, + "column": 74 + }, + "end": { + "line": 131, + "column": 89 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5932, + "end": 5933, + "loc": { + "start": { + "line": 131, + "column": 89 + }, + "end": { + "line": 131, + "column": 90 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5933, + "end": 5934, + "loc": { + "start": { + "line": 131, + "column": 90 + }, + "end": { + "line": 131, + "column": 91 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeTextures", + "start": 5943, + "end": 5958, + "loc": { + "start": { + "line": 132, + "column": 8 + }, + "end": { + "line": 132, + "column": 23 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 5959, + "end": 5960, + "loc": { + "start": { + "line": 132, + "column": 24 + }, + "end": { + "line": 132, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "overrideOption", + "start": 5961, + "end": 5975, + "loc": { + "start": { + "line": 132, + "column": 26 + }, + "end": { + "line": 132, + "column": 40 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 5975, + "end": 5976, + "loc": { + "start": { + "line": 132, + "column": 40 + }, + "end": { + "line": 132, + "column": 41 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "fileTypeConfigs", + "start": 5976, + "end": 5991, + "loc": { + "start": { + "line": 132, + "column": 41 + }, + "end": { + "line": 132, + "column": 56 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 5991, + "end": 5992, + "loc": { + "start": { + "line": 132, + "column": 56 + }, + "end": { + "line": 132, + "column": 57 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeTextures", + "start": 5992, + "end": 6007, + "loc": { + "start": { + "line": 132, + "column": 57 + }, + "end": { + "line": 132, + "column": 72 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6007, + "end": 6008, + "loc": { + "start": { + "line": 132, + "column": 72 + }, + "end": { + "line": 132, + "column": 73 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeTextures", + "start": 6009, + "end": 6024, + "loc": { + "start": { + "line": 132, + "column": 74 + }, + "end": { + "line": 132, + "column": 89 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6024, + "end": 6025, + "loc": { + "start": { + "line": 132, + "column": 89 + }, + "end": { + "line": 132, + "column": 90 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6025, + "end": 6026, + "loc": { + "start": { + "line": 132, + "column": 90 + }, + "end": { + "line": 132, + "column": 91 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeNormals", + "start": 6035, + "end": 6049, + "loc": { + "start": { + "line": 133, + "column": 8 + }, + "end": { + "line": 133, + "column": 22 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 6050, + "end": 6051, + "loc": { + "start": { + "line": 133, + "column": 23 + }, + "end": { + "line": 133, + "column": 24 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "overrideOption", + "start": 6052, + "end": 6066, + "loc": { + "start": { + "line": 133, + "column": 25 + }, + "end": { + "line": 133, + "column": 39 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6066, + "end": 6067, + "loc": { + "start": { + "line": 133, + "column": 39 + }, + "end": { + "line": 133, + "column": 40 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "fileTypeConfigs", + "start": 6067, + "end": 6082, + "loc": { + "start": { + "line": 133, + "column": 40 + }, + "end": { + "line": 133, + "column": 55 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6082, + "end": 6083, + "loc": { + "start": { + "line": 133, + "column": 55 + }, + "end": { + "line": 133, + "column": 56 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeNormals", + "start": 6083, + "end": 6097, + "loc": { + "start": { + "line": 133, + "column": 56 + }, + "end": { + "line": 133, + "column": 70 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6097, + "end": 6098, + "loc": { + "start": { + "line": 133, + "column": 70 + }, + "end": { + "line": 133, + "column": 71 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeNormals", + "start": 6099, + "end": 6113, + "loc": { + "start": { + "line": 133, + "column": 72 + }, + "end": { + "line": 133, + "column": 86 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6113, + "end": 6114, + "loc": { + "start": { + "line": 133, + "column": 86 + }, + "end": { + "line": 133, + "column": 87 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6114, + "end": 6115, + "loc": { + "start": { + "line": 133, + "column": 87 + }, + "end": { + "line": 133, + "column": 88 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeTypes", + "start": 6124, + "end": 6136, + "loc": { + "start": { + "line": 134, + "column": 8 + }, + "end": { + "line": 134, + "column": 20 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 6137, + "end": 6138, + "loc": { + "start": { + "line": 134, + "column": 21 + }, + "end": { + "line": 134, + "column": 22 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "overrideOption", + "start": 6139, + "end": 6153, + "loc": { + "start": { + "line": 134, + "column": 23 + }, + "end": { + "line": 134, + "column": 37 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6153, + "end": 6154, + "loc": { + "start": { + "line": 134, + "column": 37 + }, + "end": { + "line": 134, + "column": 38 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "fileTypeConfigs", + "start": 6154, + "end": 6169, + "loc": { + "start": { + "line": 134, + "column": 38 + }, + "end": { + "line": 134, + "column": 53 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6169, + "end": 6170, + "loc": { + "start": { + "line": 134, + "column": 53 + }, + "end": { + "line": 134, + "column": 54 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeTypes", + "start": 6170, + "end": 6182, + "loc": { + "start": { + "line": 134, + "column": 54 + }, + "end": { + "line": 134, + "column": 66 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6182, + "end": 6183, + "loc": { + "start": { + "line": 134, + "column": 66 + }, + "end": { + "line": 134, + "column": 67 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeTypes", + "start": 6184, + "end": 6196, + "loc": { + "start": { + "line": 134, + "column": 68 + }, + "end": { + "line": 134, + "column": 80 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6196, + "end": 6197, + "loc": { + "start": { + "line": 134, + "column": 80 + }, + "end": { + "line": 134, + "column": 81 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6197, + "end": 6198, + "loc": { + "start": { + "line": 134, + "column": 81 + }, + "end": { + "line": 134, + "column": 82 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "excludeTypes", + "start": 6207, + "end": 6219, + "loc": { + "start": { + "line": 135, + "column": 8 + }, + "end": { + "line": 135, + "column": 20 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 6220, + "end": 6221, + "loc": { + "start": { + "line": 135, + "column": 21 + }, + "end": { + "line": 135, + "column": 22 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "overrideOption", + "start": 6222, + "end": 6236, + "loc": { + "start": { + "line": 135, + "column": 23 + }, + "end": { + "line": 135, + "column": 37 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6236, + "end": 6237, + "loc": { + "start": { + "line": 135, + "column": 37 + }, + "end": { + "line": 135, + "column": 38 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "fileTypeConfigs", + "start": 6237, + "end": 6252, + "loc": { + "start": { + "line": 135, + "column": 38 + }, + "end": { + "line": 135, + "column": 53 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6252, + "end": 6253, + "loc": { + "start": { + "line": 135, + "column": 53 + }, + "end": { + "line": 135, + "column": 54 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "excludeTypes", + "start": 6253, + "end": 6265, + "loc": { + "start": { + "line": 135, + "column": 54 + }, + "end": { + "line": 135, + "column": 66 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6265, + "end": 6266, + "loc": { + "start": { + "line": 135, + "column": 66 + }, + "end": { + "line": 135, + "column": 67 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "excludeTypes", + "start": 6267, + "end": 6279, + "loc": { + "start": { + "line": 135, + "column": 68 + }, + "end": { + "line": 135, + "column": 80 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6279, + "end": 6280, + "loc": { + "start": { + "line": 135, + "column": 80 + }, + "end": { + "line": 135, + "column": 81 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6280, + "end": 6281, + "loc": { + "start": { + "line": 135, + "column": 81 + }, + "end": { + "line": 135, + "column": 82 + } + } + }, + { + "type": { + "label": "if", + "keyword": "if", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "if", + "start": 6291, + "end": 6293, + "loc": { + "start": { + "line": 137, + "column": 8 + }, + "end": { + "line": 137, + "column": 10 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6294, + "end": 6295, + "loc": { + "start": { + "line": 137, + "column": 11 + }, + "end": { + "line": 137, + "column": 12 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "reuseGeometries", + "start": 6295, + "end": 6310, + "loc": { + "start": { + "line": 137, + "column": 12 + }, + "end": { + "line": 137, + "column": 27 + } + } + }, + { + "type": { + "label": "==/!=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": 6, + "updateContext": null + }, + "value": "===", + "start": 6311, + "end": 6314, + "loc": { + "start": { + "line": 137, + "column": 28 + }, + "end": { + "line": 137, + "column": 31 + } + } + }, + { + "type": { + "label": "false", + "keyword": "false", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "false", + "start": 6315, + "end": 6320, + "loc": { + "start": { + "line": 137, + "column": 32 + }, + "end": { + "line": 137, + "column": 37 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6320, + "end": 6321, + "loc": { + "start": { + "line": 137, + "column": 37 + }, + "end": { + "line": 137, + "column": 38 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6322, + "end": 6323, + "loc": { + "start": { + "line": 137, + "column": 39 + }, + "end": { + "line": 137, + "column": 40 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "log", + "start": 6336, + "end": 6339, + "loc": { + "start": { + "line": 138, + "column": 12 + }, + "end": { + "line": 138, + "column": 15 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6339, + "end": 6340, + "loc": { + "start": { + "line": 138, + "column": 15 + }, + "end": { + "line": 138, + "column": 16 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "Geometry reuse is disabled", + "start": 6340, + "end": 6368, + "loc": { + "start": { + "line": 138, + "column": 16 + }, + "end": { + "line": 138, + "column": 44 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6368, + "end": 6369, + "loc": { + "start": { + "line": 138, + "column": 44 + }, + "end": { + "line": 138, + "column": 45 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6369, + "end": 6370, + "loc": { + "start": { + "line": 138, + "column": 45 + }, + "end": { + "line": 138, + "column": 46 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6379, + "end": 6380, + "loc": { + "start": { + "line": 139, + "column": 8 + }, + "end": { + "line": 139, + "column": 9 + } + } + }, + { + "type": { + "label": "const", + "keyword": "const", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "const", + "start": 6390, + "end": 6395, + "loc": { + "start": { + "line": 141, + "column": 8 + }, + "end": { + "line": 141, + "column": 13 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "xktModel", + "start": 6396, + "end": 6404, + "loc": { + "start": { + "line": 141, + "column": 14 + }, + "end": { + "line": 141, + "column": 22 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 6405, + "end": 6406, + "loc": { + "start": { + "line": 141, + "column": 23 + }, + "end": { + "line": 141, + "column": 24 + } + } + }, + { + "type": { + "label": "new", + "keyword": "new", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "new", + "start": 6407, + "end": 6410, + "loc": { + "start": { + "line": 141, + "column": 25 + }, + "end": { + "line": 141, + "column": 28 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "XKTModel", + "start": 6411, + "end": 6419, + "loc": { + "start": { + "line": 141, + "column": 29 + }, + "end": { + "line": 141, + "column": 37 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6419, + "end": 6420, + "loc": { + "start": { + "line": 141, + "column": 37 + }, + "end": { + "line": 141, + "column": 38 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6420, + "end": 6421, + "loc": { + "start": { + "line": 141, + "column": 38 + }, + "end": { + "line": 141, + "column": 39 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "minTileSize", + "start": 6434, + "end": 6445, + "loc": { + "start": { + "line": 142, + "column": 12 + }, + "end": { + "line": 142, + "column": 23 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6445, + "end": 6446, + "loc": { + "start": { + "line": 142, + "column": 23 + }, + "end": { + "line": 142, + "column": 24 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "modelAABB", + "start": 6459, + "end": 6468, + "loc": { + "start": { + "line": 143, + "column": 12 + }, + "end": { + "line": 143, + "column": 21 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6477, + "end": 6478, + "loc": { + "start": { + "line": 144, + "column": 8 + }, + "end": { + "line": 144, + "column": 9 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6478, + "end": 6479, + "loc": { + "start": { + "line": 144, + "column": 9 + }, + "end": { + "line": 144, + "column": 10 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6479, + "end": 6480, + "loc": { + "start": { + "line": 144, + "column": 10 + }, + "end": { + "line": 144, + "column": 11 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceData", + "start": 6492, + "end": 6502, + "loc": { + "start": { + "line": 148, + "column": 8 + }, + "end": { + "line": 148, + "column": 18 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 6503, + "end": 6504, + "loc": { + "start": { + "line": 148, + "column": 19 + }, + "end": { + "line": 148, + "column": 20 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "toArrayBuffer", + "start": 6505, + "end": 6518, + "loc": { + "start": { + "line": 148, + "column": 21 + }, + "end": { + "line": 148, + "column": 34 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6518, + "end": 6519, + "loc": { + "start": { + "line": 148, + "column": 34 + }, + "end": { + "line": 148, + "column": 35 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceData", + "start": 6519, + "end": 6529, + "loc": { + "start": { + "line": 148, + "column": 35 + }, + "end": { + "line": 148, + "column": 45 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6529, + "end": 6530, + "loc": { + "start": { + "line": 148, + "column": 45 + }, + "end": { + "line": 148, + "column": 46 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6530, + "end": 6531, + "loc": { + "start": { + "line": 148, + "column": 46 + }, + "end": { + "line": 148, + "column": 47 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "convert", + "start": 6540, + "end": 6547, + "loc": { + "start": { + "line": 149, + "column": 8 + }, + "end": { + "line": 149, + "column": 15 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6547, + "end": 6548, + "loc": { + "start": { + "line": 149, + "column": 15 + }, + "end": { + "line": 149, + "column": 16 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "parseGLTFIntoXKTModel", + "start": 6548, + "end": 6569, + "loc": { + "start": { + "line": 149, + "column": 16 + }, + "end": { + "line": 149, + "column": 37 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6569, + "end": 6570, + "loc": { + "start": { + "line": 149, + "column": 37 + }, + "end": { + "line": 149, + "column": 38 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6571, + "end": 6572, + "loc": { + "start": { + "line": 149, + "column": 39 + }, + "end": { + "line": 149, + "column": 40 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "data", + "start": 6585, + "end": 6589, + "loc": { + "start": { + "line": 150, + "column": 12 + }, + "end": { + "line": 150, + "column": 16 + } + } + }, + { + "type": { + "label": ":", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6589, + "end": 6590, + "loc": { + "start": { + "line": 150, + "column": 16 + }, + "end": { + "line": 150, + "column": 17 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "sourceData", + "start": 6591, + "end": 6601, + "loc": { + "start": { + "line": 150, + "column": 18 + }, + "end": { + "line": 150, + "column": 28 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6601, + "end": 6602, + "loc": { + "start": { + "line": 150, + "column": 28 + }, + "end": { + "line": 150, + "column": 29 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "reuseGeometries", + "start": 6615, + "end": 6630, + "loc": { + "start": { + "line": 151, + "column": 12 + }, + "end": { + "line": 151, + "column": 27 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6630, + "end": 6631, + "loc": { + "start": { + "line": 151, + "column": 27 + }, + "end": { + "line": 151, + "column": 28 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeTextures", + "start": 6644, + "end": 6659, + "loc": { + "start": { + "line": 152, + "column": 12 + }, + "end": { + "line": 152, + "column": 27 + } + } + }, + { + "type": { + "label": ":", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6659, + "end": 6660, + "loc": { + "start": { + "line": 152, + "column": 27 + }, + "end": { + "line": 152, + "column": 28 + } + } + }, + { + "type": { + "label": "true", + "keyword": "true", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "true", + "start": 6661, + "end": 6665, + "loc": { + "start": { + "line": 152, + "column": 29 + }, + "end": { + "line": 152, + "column": 33 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6665, + "end": 6666, + "loc": { + "start": { + "line": 152, + "column": 33 + }, + "end": { + "line": 152, + "column": 34 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "includeNormals", + "start": 6679, + "end": 6693, + "loc": { + "start": { + "line": 153, + "column": 12 + }, + "end": { + "line": 153, + "column": 26 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6693, + "end": 6694, + "loc": { + "start": { + "line": 153, + "column": 26 + }, + "end": { + "line": 153, + "column": 27 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "xktModel", + "start": 6707, + "end": 6715, + "loc": { + "start": { + "line": 154, + "column": 12 + }, + "end": { + "line": 154, + "column": 20 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6715, + "end": 6716, + "loc": { + "start": { + "line": 154, + "column": 20 + }, + "end": { + "line": 154, + "column": 21 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 6729, + "end": 6734, + "loc": { + "start": { + "line": 155, + "column": 12 + }, + "end": { + "line": 155, + "column": 17 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6734, + "end": 6735, + "loc": { + "start": { + "line": 155, + "column": 17 + }, + "end": { + "line": 155, + "column": 18 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "log", + "start": 6748, + "end": 6751, + "loc": { + "start": { + "line": 156, + "column": 12 + }, + "end": { + "line": 156, + "column": 15 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6760, + "end": 6761, + "loc": { + "start": { + "line": 157, + "column": 8 + }, + "end": { + "line": 157, + "column": 9 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6761, + "end": 6762, + "loc": { + "start": { + "line": 157, + "column": 9 + }, + "end": { + "line": 157, + "column": 10 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6762, + "end": 6763, + "loc": { + "start": { + "line": 157, + "column": 10 + }, + "end": { + "line": 157, + "column": 11 + } + } + }, + { + "type": { + "label": "function", + "keyword": "function", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "function", + "start": 6774, + "end": 6782, + "loc": { + "start": { + "line": 160, + "column": 8 + }, + "end": { + "line": 160, + "column": 16 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "convert", + "start": 6783, + "end": 6790, + "loc": { + "start": { + "line": 160, + "column": 17 + }, + "end": { + "line": 160, + "column": 24 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6790, + "end": 6791, + "loc": { + "start": { + "line": 160, + "column": 24 + }, + "end": { + "line": 160, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "parser", + "start": 6791, + "end": 6797, + "loc": { + "start": { + "line": 160, + "column": 25 + }, + "end": { + "line": 160, + "column": 31 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6797, + "end": 6798, + "loc": { + "start": { + "line": 160, + "column": 31 + }, + "end": { + "line": 160, + "column": 32 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "converterParams", + "start": 6799, + "end": 6814, + "loc": { + "start": { + "line": 160, + "column": 33 + }, + "end": { + "line": 160, + "column": 48 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6814, + "end": 6815, + "loc": { + "start": { + "line": 160, + "column": 48 + }, + "end": { + "line": 160, + "column": 49 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6816, + "end": 6817, + "loc": { + "start": { + "line": 160, + "column": 50 + }, + "end": { + "line": 160, + "column": 51 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "parser", + "start": 6831, + "end": 6837, + "loc": { + "start": { + "line": 162, + "column": 12 + }, + "end": { + "line": 162, + "column": 18 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6837, + "end": 6838, + "loc": { + "start": { + "line": 162, + "column": 18 + }, + "end": { + "line": 162, + "column": 19 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "converterParams", + "start": 6838, + "end": 6853, + "loc": { + "start": { + "line": 162, + "column": 19 + }, + "end": { + "line": 162, + "column": 34 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6853, + "end": 6854, + "loc": { + "start": { + "line": 162, + "column": 34 + }, + "end": { + "line": 162, + "column": 35 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6854, + "end": 6855, + "loc": { + "start": { + "line": 162, + "column": 35 + }, + "end": { + "line": 162, + "column": 36 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "then", + "start": 6855, + "end": 6859, + "loc": { + "start": { + "line": 162, + "column": 36 + }, + "end": { + "line": 162, + "column": 40 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6859, + "end": 6860, + "loc": { + "start": { + "line": 162, + "column": 40 + }, + "end": { + "line": 162, + "column": 41 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6860, + "end": 6861, + "loc": { + "start": { + "line": 162, + "column": 41 + }, + "end": { + "line": 162, + "column": 42 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6861, + "end": 6862, + "loc": { + "start": { + "line": 162, + "column": 42 + }, + "end": { + "line": 162, + "column": 43 + } + } + }, + { + "type": { + "label": "=>", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6863, + "end": 6865, + "loc": { + "start": { + "line": 162, + "column": 44 + }, + "end": { + "line": 162, + "column": 46 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6866, + "end": 6867, + "loc": { + "start": { + "line": 162, + "column": 47 + }, + "end": { + "line": 162, + "column": 48 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "log", + "start": 6886, + "end": 6889, + "loc": { + "start": { + "line": 165, + "column": 16 + }, + "end": { + "line": 165, + "column": 19 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6889, + "end": 6890, + "loc": { + "start": { + "line": 165, + "column": 19 + }, + "end": { + "line": 165, + "column": 20 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "Input file parsed OK. Building XKT document...", + "start": 6890, + "end": 6938, + "loc": { + "start": { + "line": 165, + "column": 20 + }, + "end": { + "line": 165, + "column": 68 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6938, + "end": 6939, + "loc": { + "start": { + "line": 165, + "column": 68 + }, + "end": { + "line": 165, + "column": 69 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6939, + "end": 6940, + "loc": { + "start": { + "line": 165, + "column": 69 + }, + "end": { + "line": 165, + "column": 70 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "xktModel", + "start": 6958, + "end": 6966, + "loc": { + "start": { + "line": 167, + "column": 16 + }, + "end": { + "line": 167, + "column": 24 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6966, + "end": 6967, + "loc": { + "start": { + "line": 167, + "column": 24 + }, + "end": { + "line": 167, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "finalize", + "start": 6967, + "end": 6975, + "loc": { + "start": { + "line": 167, + "column": 25 + }, + "end": { + "line": 167, + "column": 33 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6975, + "end": 6976, + "loc": { + "start": { + "line": 167, + "column": 33 + }, + "end": { + "line": 167, + "column": 34 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6976, + "end": 6977, + "loc": { + "start": { + "line": 167, + "column": 34 + }, + "end": { + "line": 167, + "column": 35 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6977, + "end": 6978, + "loc": { + "start": { + "line": 167, + "column": 35 + }, + "end": { + "line": 167, + "column": 36 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "then", + "start": 6978, + "end": 6982, + "loc": { + "start": { + "line": 167, + "column": 36 + }, + "end": { + "line": 167, + "column": 40 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6982, + "end": 6983, + "loc": { + "start": { + "line": 167, + "column": 40 + }, + "end": { + "line": 167, + "column": 41 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6983, + "end": 6984, + "loc": { + "start": { + "line": 167, + "column": 41 + }, + "end": { + "line": 167, + "column": 42 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6984, + "end": 6985, + "loc": { + "start": { + "line": 167, + "column": 42 + }, + "end": { + "line": 167, + "column": 43 + } + } + }, + { + "type": { + "label": "=>", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 6986, + "end": 6988, + "loc": { + "start": { + "line": 167, + "column": 44 + }, + "end": { + "line": 167, + "column": 46 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 6989, + "end": 6990, + "loc": { + "start": { + "line": 167, + "column": 47 + }, + "end": { + "line": 167, + "column": 48 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "log", + "start": 7012, + "end": 7015, + "loc": { + "start": { + "line": 169, + "column": 20 + }, + "end": { + "line": 169, + "column": 23 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7015, + "end": 7016, + "loc": { + "start": { + "line": 169, + "column": 23 + }, + "end": { + "line": 169, + "column": 24 + } + } + }, + { + "type": { + "label": "string", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "XKT document built OK. Writing to XKT file...", + "start": 7016, + "end": 7063, + "loc": { + "start": { + "line": 169, + "column": 24 + }, + "end": { + "line": 169, + "column": 71 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7063, + "end": 7064, + "loc": { + "start": { + "line": 169, + "column": 71 + }, + "end": { + "line": 169, + "column": 72 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7064, + "end": 7065, + "loc": { + "start": { + "line": 169, + "column": 72 + }, + "end": { + "line": 169, + "column": 73 + } + } + }, + { + "type": { + "label": "const", + "keyword": "const", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "const", + "start": 7087, + "end": 7092, + "loc": { + "start": { + "line": 171, + "column": 20 + }, + "end": { + "line": 171, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "xktArrayBuffer", + "start": 7093, + "end": 7107, + "loc": { + "start": { + "line": 171, + "column": 26 + }, + "end": { + "line": 171, + "column": 40 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 7108, + "end": 7109, + "loc": { + "start": { + "line": 171, + "column": 41 + }, + "end": { + "line": 171, + "column": 42 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "writeXKTModelToArrayBuffer", + "start": 7110, + "end": 7136, + "loc": { + "start": { + "line": 171, + "column": 43 + }, + "end": { + "line": 171, + "column": 69 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7136, + "end": 7137, + "loc": { + "start": { + "line": 171, + "column": 69 + }, + "end": { + "line": 171, + "column": 70 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "xktModel", + "start": 7137, + "end": 7145, + "loc": { + "start": { + "line": 171, + "column": 70 + }, + "end": { + "line": 171, + "column": 78 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7145, + "end": 7146, + "loc": { + "start": { + "line": 171, + "column": 78 + }, + "end": { + "line": 171, + "column": 79 + } + } + }, + { + "type": { + "label": "null", + "keyword": "null", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "null", + "start": 7147, + "end": 7151, + "loc": { + "start": { + "line": 171, + "column": 80 + }, + "end": { + "line": 171, + "column": 84 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7151, + "end": 7152, + "loc": { + "start": { + "line": 171, + "column": 84 + }, + "end": { + "line": 171, + "column": 85 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "stats", + "start": 7153, + "end": 7158, + "loc": { + "start": { + "line": 171, + "column": 86 + }, + "end": { + "line": 171, + "column": 91 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7158, + "end": 7159, + "loc": { + "start": { + "line": 171, + "column": 91 + }, + "end": { + "line": 171, + "column": 92 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7160, + "end": 7161, + "loc": { + "start": { + "line": 171, + "column": 93 + }, + "end": { + "line": 171, + "column": 94 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "zip", + "start": 7161, + "end": 7164, + "loc": { + "start": { + "line": 171, + "column": 94 + }, + "end": { + "line": 171, + "column": 97 + } + } + }, + { + "type": { + "label": ":", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7164, + "end": 7165, + "loc": { + "start": { + "line": 171, + "column": 97 + }, + "end": { + "line": 171, + "column": 98 + } + } + }, + { + "type": { + "label": "true", + "keyword": "true", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "true", + "start": 7166, + "end": 7170, + "loc": { + "start": { + "line": 171, + "column": 99 + }, + "end": { + "line": 171, + "column": 103 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7170, + "end": 7171, + "loc": { + "start": { + "line": 171, + "column": 103 + }, + "end": { + "line": 171, + "column": 104 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7171, + "end": 7172, + "loc": { + "start": { + "line": 171, + "column": 104 + }, + "end": { + "line": 171, + "column": 105 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7172, + "end": 7173, + "loc": { + "start": { + "line": 171, + "column": 105 + }, + "end": { + "line": 171, + "column": 106 + } + } + }, + { + "type": { + "label": "const", + "keyword": "const", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "const", + "start": 7195, + "end": 7200, + "loc": { + "start": { + "line": 173, + "column": 20 + }, + "end": { + "line": 173, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "xktContent", + "start": 7201, + "end": 7211, + "loc": { + "start": { + "line": 173, + "column": 26 + }, + "end": { + "line": 173, + "column": 36 + } + } + }, + { + "type": { + "label": "=", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": true, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "=", + "start": 7212, + "end": 7213, + "loc": { + "start": { + "line": 173, + "column": 37 + }, + "end": { + "line": 173, + "column": 38 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "Buffer", + "start": 7214, + "end": 7220, + "loc": { + "start": { + "line": 173, + "column": 39 + }, + "end": { + "line": 173, + "column": 45 + } + } + }, + { + "type": { + "label": ".", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7220, + "end": 7221, + "loc": { + "start": { + "line": 173, + "column": 45 + }, + "end": { + "line": 173, + "column": 46 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "from", + "start": 7221, + "end": 7225, + "loc": { + "start": { + "line": 173, + "column": 46 + }, + "end": { + "line": 173, + "column": 50 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7225, + "end": 7226, + "loc": { + "start": { + "line": 173, + "column": 50 + }, + "end": { + "line": 173, + "column": 51 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "xktArrayBuffer", + "start": 7226, + "end": 7240, + "loc": { + "start": { + "line": 173, + "column": 51 + }, + "end": { + "line": 173, + "column": 65 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7240, + "end": 7241, + "loc": { + "start": { + "line": 173, + "column": 65 + }, + "end": { + "line": 173, + "column": 66 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7241, + "end": 7242, + "loc": { + "start": { + "line": 173, + "column": 66 + }, + "end": { + "line": 173, + "column": 67 + } + } + }, + { + "type": { + "label": "if", + "keyword": "if", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "if", + "start": 7265, + "end": 7267, + "loc": { + "start": { + "line": 176, + "column": 20 + }, + "end": { + "line": 176, + "column": 22 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7268, + "end": 7269, + "loc": { + "start": { + "line": 176, + "column": 23 + }, + "end": { + "line": 176, + "column": 24 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "outputXKT", + "start": 7269, + "end": 7278, + "loc": { + "start": { + "line": 176, + "column": 24 + }, + "end": { + "line": 176, + "column": 33 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7278, + "end": 7279, + "loc": { + "start": { + "line": 176, + "column": 33 + }, + "end": { + "line": 176, + "column": 34 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7280, + "end": 7281, + "loc": { + "start": { + "line": 176, + "column": 35 + }, + "end": { + "line": 176, + "column": 36 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "outputXKT", + "start": 7306, + "end": 7315, + "loc": { + "start": { + "line": 177, + "column": 24 + }, + "end": { + "line": 177, + "column": 33 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7315, + "end": 7316, + "loc": { + "start": { + "line": 177, + "column": 33 + }, + "end": { + "line": 177, + "column": 34 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "xktContent", + "start": 7316, + "end": 7326, + "loc": { + "start": { + "line": 177, + "column": 34 + }, + "end": { + "line": 177, + "column": 44 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7326, + "end": 7327, + "loc": { + "start": { + "line": 177, + "column": 44 + }, + "end": { + "line": 177, + "column": 45 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7327, + "end": 7328, + "loc": { + "start": { + "line": 177, + "column": 45 + }, + "end": { + "line": 177, + "column": 46 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7349, + "end": 7350, + "loc": { + "start": { + "line": 178, + "column": 20 + }, + "end": { + "line": 178, + "column": 21 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "resolve", + "start": 7372, + "end": 7379, + "loc": { + "start": { + "line": 180, + "column": 20 + }, + "end": { + "line": 180, + "column": 27 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7379, + "end": 7380, + "loc": { + "start": { + "line": 180, + "column": 27 + }, + "end": { + "line": 180, + "column": 28 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7380, + "end": 7381, + "loc": { + "start": { + "line": 180, + "column": 28 + }, + "end": { + "line": 180, + "column": 29 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7381, + "end": 7382, + "loc": { + "start": { + "line": 180, + "column": 29 + }, + "end": { + "line": 180, + "column": 30 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7399, + "end": 7400, + "loc": { + "start": { + "line": 181, + "column": 16 + }, + "end": { + "line": 181, + "column": 17 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7400, + "end": 7401, + "loc": { + "start": { + "line": 181, + "column": 17 + }, + "end": { + "line": 181, + "column": 18 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7401, + "end": 7402, + "loc": { + "start": { + "line": 181, + "column": 18 + }, + "end": { + "line": 181, + "column": 19 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7415, + "end": 7416, + "loc": { + "start": { + "line": 182, + "column": 12 + }, + "end": { + "line": 182, + "column": 13 + } + } + }, + { + "type": { + "label": ",", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7416, + "end": 7417, + "loc": { + "start": { + "line": 182, + "column": 13 + }, + "end": { + "line": 182, + "column": 14 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7418, + "end": 7419, + "loc": { + "start": { + "line": 182, + "column": 15 + }, + "end": { + "line": 182, + "column": 16 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "err", + "start": 7419, + "end": 7422, + "loc": { + "start": { + "line": 182, + "column": 16 + }, + "end": { + "line": 182, + "column": 19 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7422, + "end": 7423, + "loc": { + "start": { + "line": 182, + "column": 19 + }, + "end": { + "line": 182, + "column": 20 + } + } + }, + { + "type": { + "label": "=>", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7424, + "end": 7426, + "loc": { + "start": { + "line": 182, + "column": 21 + }, + "end": { + "line": 182, + "column": 23 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7427, + "end": 7428, + "loc": { + "start": { + "line": 182, + "column": 24 + }, + "end": { + "line": 182, + "column": 25 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "reject", + "start": 7445, + "end": 7451, + "loc": { + "start": { + "line": 183, + "column": 16 + }, + "end": { + "line": 183, + "column": 22 + } + } + }, + { + "type": { + "label": "(", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7451, + "end": 7452, + "loc": { + "start": { + "line": 183, + "column": 22 + }, + "end": { + "line": 183, + "column": 23 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "err", + "start": 7452, + "end": 7455, + "loc": { + "start": { + "line": 183, + "column": 23 + }, + "end": { + "line": 183, + "column": 26 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7455, + "end": 7456, + "loc": { + "start": { + "line": 183, + "column": 26 + }, + "end": { + "line": 183, + "column": 27 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7456, + "end": 7457, + "loc": { + "start": { + "line": 183, + "column": 27 + }, + "end": { + "line": 183, + "column": 28 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7470, + "end": 7471, + "loc": { + "start": { + "line": 184, + "column": 12 + }, + "end": { + "line": 184, + "column": 13 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7471, + "end": 7472, + "loc": { + "start": { + "line": 184, + "column": 13 + }, + "end": { + "line": 184, + "column": 14 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7472, + "end": 7473, + "loc": { + "start": { + "line": 184, + "column": 14 + }, + "end": { + "line": 184, + "column": 15 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7482, + "end": 7483, + "loc": { + "start": { + "line": 185, + "column": 8 + }, + "end": { + "line": 185, + "column": 9 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7488, + "end": 7489, + "loc": { + "start": { + "line": 186, + "column": 4 + }, + "end": { + "line": 186, + "column": 5 + } + } + }, + { + "type": { + "label": ")", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7489, + "end": 7490, + "loc": { + "start": { + "line": 186, + "column": 5 + }, + "end": { + "line": 186, + "column": 6 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7490, + "end": 7491, + "loc": { + "start": { + "line": 186, + "column": 6 + }, + "end": { + "line": 186, + "column": 7 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7492, + "end": 7493, + "loc": { + "start": { + "line": 187, + "column": 0 + }, + "end": { + "line": 187, + "column": 1 + } + } + }, + { + "type": { + "label": "export", + "keyword": "export", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "value": "export", + "start": 7495, + "end": 7501, + "loc": { + "start": { + "line": 189, + "column": 0 + }, + "end": { + "line": 189, + "column": 6 + } + } + }, + { + "type": { + "label": "{", + "beforeExpr": true, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7502, + "end": 7503, + "loc": { + "start": { + "line": 189, + "column": 7 + }, + "end": { + "line": 189, + "column": 8 + } + } + }, + { + "type": { + "label": "name", + "beforeExpr": false, + "startsExpr": true, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "value": "convert2xkt", + "start": 7503, + "end": 7514, + "loc": { + "start": { + "line": 189, + "column": 8 + }, + "end": { + "line": 189, + "column": 19 + } + } + }, + { + "type": { + "label": "}", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null + }, + "start": 7514, + "end": 7515, + "loc": { + "start": { + "line": 189, + "column": 19 + }, + "end": { + "line": 189, + "column": 20 + } + } + }, + { + "type": { + "label": ";", + "beforeExpr": true, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7515, + "end": 7516, + "loc": { + "start": { + "line": 189, + "column": 20 + }, + "end": { + "line": 189, + "column": 21 + } + } + }, + { + "type": { + "label": "eof", + "beforeExpr": false, + "startsExpr": false, + "rightAssociative": false, + "isLoop": false, + "isAssign": false, + "prefix": false, + "postfix": false, + "binop": null, + "updateContext": null + }, + "start": 7516, + "end": 7516, + "loc": { + "start": { + "line": 189, + "column": 21 + }, + "end": { + "line": 189, + "column": 21 + } + } + } + ] +} \ No newline at end of file diff --git a/docs/badge.svg b/docs/badge.svg index 4232721..1d4545a 100644 --- a/docs/badge.svg +++ b/docs/badge.svg @@ -11,7 +11,7 @@ document document - 47% - 47% + 48% + 48% diff --git a/docs/class/src/XKTModel/XKTEntity.js~XKTEntity.html b/docs/class/src/XKTModel/XKTEntity.js~XKTEntity.html index ba8f931..33d6a03 100644 --- a/docs/class/src/XKTModel/XKTEntity.js~XKTEntity.html +++ b/docs/class/src/XKTModel/XKTEntity.js~XKTEntity.html @@ -30,6 +30,7 @@
  • Fconvert2xkt
  • +
  • Fconvert2xkt
  • VXKT_INFO
  • VClampToEdgeWrapping
  • VGIFMediaType
  • @@ -67,7 +68,6 @@
  • FbuildVectorTextGeometry
  • parsersFparseCityJSONIntoXKTModel
  • FparseGLTFIntoXKTModel
  • -
  • FparseGLTFIntoXKTModel
  • FparseGLTFJSONIntoXKTModel
  • FparseIFCIntoXKTModel
  • FparseLASIntoXKTModel
  • diff --git a/docs/class/src/XKTModel/XKTGeometry.js~XKTGeometry.html b/docs/class/src/XKTModel/XKTGeometry.js~XKTGeometry.html index 71383dc..147442e 100644 --- a/docs/class/src/XKTModel/XKTGeometry.js~XKTGeometry.html +++ b/docs/class/src/XKTModel/XKTGeometry.js~XKTGeometry.html @@ -30,6 +30,7 @@
    • Fconvert2xkt
    • +
    • Fconvert2xkt
    • VXKT_INFO
    • VClampToEdgeWrapping
    • VGIFMediaType
    • @@ -67,7 +68,6 @@
    • FbuildVectorTextGeometry
    • parsersFparseCityJSONIntoXKTModel
    • FparseGLTFIntoXKTModel
    • -
    • FparseGLTFIntoXKTModel
    • FparseGLTFJSONIntoXKTModel
    • FparseIFCIntoXKTModel
    • FparseLASIntoXKTModel
    • diff --git a/docs/class/src/XKTModel/XKTMesh.js~XKTMesh.html b/docs/class/src/XKTModel/XKTMesh.js~XKTMesh.html index 7bec14e..b717926 100644 --- a/docs/class/src/XKTModel/XKTMesh.js~XKTMesh.html +++ b/docs/class/src/XKTModel/XKTMesh.js~XKTMesh.html @@ -30,6 +30,7 @@
      • Fconvert2xkt
      • +
      • Fconvert2xkt
      • VXKT_INFO
      • VClampToEdgeWrapping
      • VGIFMediaType
      • @@ -67,7 +68,6 @@
      • FbuildVectorTextGeometry
      • parsersFparseCityJSONIntoXKTModel
      • FparseGLTFIntoXKTModel
      • -
      • FparseGLTFIntoXKTModel
      • FparseGLTFJSONIntoXKTModel
      • FparseIFCIntoXKTModel
      • FparseLASIntoXKTModel
      • diff --git a/docs/class/src/XKTModel/XKTMetaObject.js~XKTMetaObject.html b/docs/class/src/XKTModel/XKTMetaObject.js~XKTMetaObject.html index c8bbd69..fc119b8 100644 --- a/docs/class/src/XKTModel/XKTMetaObject.js~XKTMetaObject.html +++ b/docs/class/src/XKTModel/XKTMetaObject.js~XKTMetaObject.html @@ -30,6 +30,7 @@
        • Fconvert2xkt
        • +
        • Fconvert2xkt
        • VXKT_INFO
        • VClampToEdgeWrapping
        • VGIFMediaType
        • @@ -67,7 +68,6 @@
        • FbuildVectorTextGeometry
        • parsersFparseCityJSONIntoXKTModel
        • FparseGLTFIntoXKTModel
        • -
        • FparseGLTFIntoXKTModel
        • FparseGLTFJSONIntoXKTModel
        • FparseIFCIntoXKTModel
        • FparseLASIntoXKTModel
        • diff --git a/docs/class/src/XKTModel/XKTModel.js~XKTModel.html b/docs/class/src/XKTModel/XKTModel.js~XKTModel.html index 256138f..84dbb4e 100644 --- a/docs/class/src/XKTModel/XKTModel.js~XKTModel.html +++ b/docs/class/src/XKTModel/XKTModel.js~XKTModel.html @@ -30,6 +30,7 @@
          • Fconvert2xkt
          • +
          • Fconvert2xkt
          • VXKT_INFO
          • VClampToEdgeWrapping
          • VGIFMediaType
          • @@ -67,7 +68,6 @@
          • FbuildVectorTextGeometry
          • parsersFparseCityJSONIntoXKTModel
          • FparseGLTFIntoXKTModel
          • -
          • FparseGLTFIntoXKTModel
          • FparseGLTFJSONIntoXKTModel
          • FparseIFCIntoXKTModel
          • FparseLASIntoXKTModel
          • diff --git a/docs/class/src/XKTModel/XKTPropertySet.js~XKTPropertySet.html b/docs/class/src/XKTModel/XKTPropertySet.js~XKTPropertySet.html index a829a49..d85a44f 100644 --- a/docs/class/src/XKTModel/XKTPropertySet.js~XKTPropertySet.html +++ b/docs/class/src/XKTModel/XKTPropertySet.js~XKTPropertySet.html @@ -30,6 +30,7 @@
            • Fconvert2xkt
            • +
            • Fconvert2xkt
            • VXKT_INFO
            • VClampToEdgeWrapping
            • VGIFMediaType
            • @@ -67,7 +68,6 @@
            • FbuildVectorTextGeometry
            • parsersFparseCityJSONIntoXKTModel
            • FparseGLTFIntoXKTModel
            • -
            • FparseGLTFIntoXKTModel
            • FparseGLTFJSONIntoXKTModel
            • FparseIFCIntoXKTModel
            • FparseLASIntoXKTModel
            • diff --git a/docs/class/src/XKTModel/XKTTexture.js~XKTTexture.html b/docs/class/src/XKTModel/XKTTexture.js~XKTTexture.html index fb77910..cb11478 100644 --- a/docs/class/src/XKTModel/XKTTexture.js~XKTTexture.html +++ b/docs/class/src/XKTModel/XKTTexture.js~XKTTexture.html @@ -30,6 +30,7 @@
              • Fconvert2xkt
              • +
              • Fconvert2xkt
              • VXKT_INFO
              • VClampToEdgeWrapping
              • VGIFMediaType
              • @@ -67,7 +68,6 @@
              • FbuildVectorTextGeometry
              • parsersFparseCityJSONIntoXKTModel
              • FparseGLTFIntoXKTModel
              • -
              • FparseGLTFIntoXKTModel
              • FparseGLTFJSONIntoXKTModel
              • FparseIFCIntoXKTModel
              • FparseLASIntoXKTModel
              • diff --git a/docs/class/src/XKTModel/XKTTextureSet.js~XKTTextureSet.html b/docs/class/src/XKTModel/XKTTextureSet.js~XKTTextureSet.html index 7c0021d..b3fb85a 100644 --- a/docs/class/src/XKTModel/XKTTextureSet.js~XKTTextureSet.html +++ b/docs/class/src/XKTModel/XKTTextureSet.js~XKTTextureSet.html @@ -30,6 +30,7 @@
                • Fconvert2xkt
                • +
                • Fconvert2xkt
                • VXKT_INFO
                • VClampToEdgeWrapping
                • VGIFMediaType
                • @@ -67,7 +68,6 @@
                • FbuildVectorTextGeometry
                • parsersFparseCityJSONIntoXKTModel
                • FparseGLTFIntoXKTModel
                • -
                • FparseGLTFIntoXKTModel
                • FparseGLTFJSONIntoXKTModel
                • FparseIFCIntoXKTModel
                • FparseLASIntoXKTModel
                • diff --git a/docs/class/src/XKTModel/XKTTile.js~XKTTile.html b/docs/class/src/XKTModel/XKTTile.js~XKTTile.html index 75630cb..d2e36c2 100644 --- a/docs/class/src/XKTModel/XKTTile.js~XKTTile.html +++ b/docs/class/src/XKTModel/XKTTile.js~XKTTile.html @@ -30,6 +30,7 @@
                  • Fconvert2xkt
                  • +
                  • Fconvert2xkt
                  • VXKT_INFO
                  • VClampToEdgeWrapping
                  • VGIFMediaType
                  • @@ -67,7 +68,6 @@
                  • FbuildVectorTextGeometry
                  • parsersFparseCityJSONIntoXKTModel
                  • FparseGLTFIntoXKTModel
                  • -
                  • FparseGLTFIntoXKTModel
                  • FparseGLTFJSONIntoXKTModel
                  • FparseIFCIntoXKTModel
                  • FparseLASIntoXKTModel
                  • diff --git a/docs/coverage.json b/docs/coverage.json index 38558d6..ea6a48c 100644 --- a/docs/coverage.json +++ b/docs/coverage.json @@ -1,6 +1,6 @@ { - "coverage": "47.2%", - "expectCount": 394, + "coverage": "48.69%", + "expectCount": 382, "actualCount": 186, "files": { "src/XKTModel/KDNode.js": { @@ -231,6 +231,11 @@ "actualCount": 1, "undocumentLines": [] }, + "src/convert2xkt_browser.js": { + "expectCount": 1, + "actualCount": 1, + "undocumentLines": [] + }, "src/geometryBuilders/buildBoxGeometry.js": { "expectCount": 1, "actualCount": 1, @@ -368,24 +373,6 @@ 622 ] }, - "src/parsers/parseGLTFIntoXKTModel.OLD.js": { - "expectCount": 13, - "actualCount": 1, - "undocumentLines": [ - 138, - 149, - 244, - 256, - 326, - 386, - 396, - 411, - 429, - 430, - 432, - 434 - ] - }, "src/parsers/parseGLTFIntoXKTModel.js": { "expectCount": 13, "actualCount": 1, diff --git a/docs/file/src/XKTModel/KDNode.js.html b/docs/file/src/XKTModel/KDNode.js.html index 284fec2..4396886 100644 --- a/docs/file/src/XKTModel/KDNode.js.html +++ b/docs/file/src/XKTModel/KDNode.js.html @@ -30,6 +30,7 @@
                    • Fconvert2xkt
                    • +
                    • Fconvert2xkt
                    • VXKT_INFO
                    • VClampToEdgeWrapping
                    • VGIFMediaType
                    • @@ -67,7 +68,6 @@
                    • FbuildVectorTextGeometry
                    • parsersFparseCityJSONIntoXKTModel
                    • FparseGLTFIntoXKTModel
                    • -
                    • FparseGLTFIntoXKTModel
                    • FparseGLTFJSONIntoXKTModel
                    • FparseIFCIntoXKTModel
                    • FparseLASIntoXKTModel
                    • diff --git a/docs/file/src/XKTModel/MockXKTModel.js.html b/docs/file/src/XKTModel/MockXKTModel.js.html index bbfa947..1a75f82 100644 --- a/docs/file/src/XKTModel/MockXKTModel.js.html +++ b/docs/file/src/XKTModel/MockXKTModel.js.html @@ -30,6 +30,7 @@
                      • Fconvert2xkt
                      • +
                      • Fconvert2xkt
                      • VXKT_INFO
                      • VClampToEdgeWrapping
                      • VGIFMediaType
                      • @@ -67,7 +68,6 @@
                      • FbuildVectorTextGeometry
                      • parsersFparseCityJSONIntoXKTModel
                      • FparseGLTFIntoXKTModel
                      • -
                      • FparseGLTFIntoXKTModel
                      • FparseGLTFJSONIntoXKTModel
                      • FparseIFCIntoXKTModel
                      • FparseLASIntoXKTModel
                      • diff --git a/docs/file/src/XKTModel/XKTEntity.js.html b/docs/file/src/XKTModel/XKTEntity.js.html index 861bde0..77e3455 100644 --- a/docs/file/src/XKTModel/XKTEntity.js.html +++ b/docs/file/src/XKTModel/XKTEntity.js.html @@ -30,6 +30,7 @@
                        • Fconvert2xkt
                        • +
                        • Fconvert2xkt
                        • VXKT_INFO
                        • VClampToEdgeWrapping
                        • VGIFMediaType
                        • @@ -67,7 +68,6 @@
                        • FbuildVectorTextGeometry
                        • parsersFparseCityJSONIntoXKTModel
                        • FparseGLTFIntoXKTModel
                        • -
                        • FparseGLTFIntoXKTModel
                        • FparseGLTFJSONIntoXKTModel
                        • FparseIFCIntoXKTModel
                        • FparseLASIntoXKTModel
                        • diff --git a/docs/file/src/XKTModel/XKTGeometry.js.html b/docs/file/src/XKTModel/XKTGeometry.js.html index e40d0a4..b996e31 100644 --- a/docs/file/src/XKTModel/XKTGeometry.js.html +++ b/docs/file/src/XKTModel/XKTGeometry.js.html @@ -30,6 +30,7 @@
                          • Fconvert2xkt
                          • +
                          • Fconvert2xkt
                          • VXKT_INFO
                          • VClampToEdgeWrapping
                          • VGIFMediaType
                          • @@ -67,7 +68,6 @@
                          • FbuildVectorTextGeometry
                          • parsersFparseCityJSONIntoXKTModel
                          • FparseGLTFIntoXKTModel
                          • -
                          • FparseGLTFIntoXKTModel
                          • FparseGLTFJSONIntoXKTModel
                          • FparseIFCIntoXKTModel
                          • FparseLASIntoXKTModel
                          • diff --git a/docs/file/src/XKTModel/XKTMesh.js.html b/docs/file/src/XKTModel/XKTMesh.js.html index 6303017..2127ef6 100644 --- a/docs/file/src/XKTModel/XKTMesh.js.html +++ b/docs/file/src/XKTModel/XKTMesh.js.html @@ -30,6 +30,7 @@
                            • Fconvert2xkt
                            • +
                            • Fconvert2xkt
                            • VXKT_INFO
                            • VClampToEdgeWrapping
                            • VGIFMediaType
                            • @@ -67,7 +68,6 @@
                            • FbuildVectorTextGeometry
                            • parsersFparseCityJSONIntoXKTModel
                            • FparseGLTFIntoXKTModel
                            • -
                            • FparseGLTFIntoXKTModel
                            • FparseGLTFJSONIntoXKTModel
                            • FparseIFCIntoXKTModel
                            • FparseLASIntoXKTModel
                            • diff --git a/docs/file/src/XKTModel/XKTMetaObject.js.html b/docs/file/src/XKTModel/XKTMetaObject.js.html index 1346f85..783fbcd 100644 --- a/docs/file/src/XKTModel/XKTMetaObject.js.html +++ b/docs/file/src/XKTModel/XKTMetaObject.js.html @@ -30,6 +30,7 @@
                              • Fconvert2xkt
                              • +
                              • Fconvert2xkt
                              • VXKT_INFO
                              • VClampToEdgeWrapping
                              • VGIFMediaType
                              • @@ -67,7 +68,6 @@
                              • FbuildVectorTextGeometry
                              • parsersFparseCityJSONIntoXKTModel
                              • FparseGLTFIntoXKTModel
                              • -
                              • FparseGLTFIntoXKTModel
                              • FparseGLTFJSONIntoXKTModel
                              • FparseIFCIntoXKTModel
                              • FparseLASIntoXKTModel
                              • diff --git a/docs/file/src/XKTModel/XKTModel.js.html b/docs/file/src/XKTModel/XKTModel.js.html index e36cf7d..913bf99 100644 --- a/docs/file/src/XKTModel/XKTModel.js.html +++ b/docs/file/src/XKTModel/XKTModel.js.html @@ -30,6 +30,7 @@
                                • Fconvert2xkt
                                • +
                                • Fconvert2xkt
                                • VXKT_INFO
                                • VClampToEdgeWrapping
                                • VGIFMediaType
                                • @@ -67,7 +68,6 @@
                                • FbuildVectorTextGeometry
                                • parsersFparseCityJSONIntoXKTModel
                                • FparseGLTFIntoXKTModel
                                • -
                                • FparseGLTFIntoXKTModel
                                • FparseGLTFJSONIntoXKTModel
                                • FparseIFCIntoXKTModel
                                • FparseLASIntoXKTModel
                                • diff --git a/docs/file/src/XKTModel/XKTPropertySet.js.html b/docs/file/src/XKTModel/XKTPropertySet.js.html index 31d8159..93bc780 100644 --- a/docs/file/src/XKTModel/XKTPropertySet.js.html +++ b/docs/file/src/XKTModel/XKTPropertySet.js.html @@ -30,6 +30,7 @@
                                  • Fconvert2xkt
                                  • +
                                  • Fconvert2xkt
                                  • VXKT_INFO
                                  • VClampToEdgeWrapping
                                  • VGIFMediaType
                                  • @@ -67,7 +68,6 @@
                                  • FbuildVectorTextGeometry
                                  • parsersFparseCityJSONIntoXKTModel
                                  • FparseGLTFIntoXKTModel
                                  • -
                                  • FparseGLTFIntoXKTModel
                                  • FparseGLTFJSONIntoXKTModel
                                  • FparseIFCIntoXKTModel
                                  • FparseLASIntoXKTModel
                                  • diff --git a/docs/file/src/XKTModel/XKTTexture.js.html b/docs/file/src/XKTModel/XKTTexture.js.html index 64072e7..619e29b 100644 --- a/docs/file/src/XKTModel/XKTTexture.js.html +++ b/docs/file/src/XKTModel/XKTTexture.js.html @@ -30,6 +30,7 @@
                                    • Fconvert2xkt
                                    • +
                                    • Fconvert2xkt
                                    • VXKT_INFO
                                    • VClampToEdgeWrapping
                                    • VGIFMediaType
                                    • @@ -67,7 +68,6 @@
                                    • FbuildVectorTextGeometry
                                    • parsersFparseCityJSONIntoXKTModel
                                    • FparseGLTFIntoXKTModel
                                    • -
                                    • FparseGLTFIntoXKTModel
                                    • FparseGLTFJSONIntoXKTModel
                                    • FparseIFCIntoXKTModel
                                    • FparseLASIntoXKTModel
                                    • diff --git a/docs/file/src/XKTModel/XKTTextureSet.js.html b/docs/file/src/XKTModel/XKTTextureSet.js.html index fc3a236..69110b1 100644 --- a/docs/file/src/XKTModel/XKTTextureSet.js.html +++ b/docs/file/src/XKTModel/XKTTextureSet.js.html @@ -30,6 +30,7 @@
                                      • Fconvert2xkt
                                      • +
                                      • Fconvert2xkt
                                      • VXKT_INFO
                                      • VClampToEdgeWrapping
                                      • VGIFMediaType
                                      • @@ -67,7 +68,6 @@
                                      • FbuildVectorTextGeometry
                                      • parsersFparseCityJSONIntoXKTModel
                                      • FparseGLTFIntoXKTModel
                                      • -
                                      • FparseGLTFIntoXKTModel
                                      • FparseGLTFJSONIntoXKTModel
                                      • FparseIFCIntoXKTModel
                                      • FparseLASIntoXKTModel
                                      • diff --git a/docs/file/src/XKTModel/XKTTile.js.html b/docs/file/src/XKTModel/XKTTile.js.html index 4803ad3..17b221c 100644 --- a/docs/file/src/XKTModel/XKTTile.js.html +++ b/docs/file/src/XKTModel/XKTTile.js.html @@ -30,6 +30,7 @@
                                        • Fconvert2xkt
                                        • +
                                        • Fconvert2xkt
                                        • VXKT_INFO
                                        • VClampToEdgeWrapping
                                        • VGIFMediaType
                                        • @@ -67,7 +68,6 @@
                                        • FbuildVectorTextGeometry
                                        • parsersFparseCityJSONIntoXKTModel
                                        • FparseGLTFIntoXKTModel
                                        • -
                                        • FparseGLTFIntoXKTModel
                                        • FparseGLTFJSONIntoXKTModel
                                        • FparseIFCIntoXKTModel
                                        • FparseLASIntoXKTModel
                                        • diff --git a/docs/file/src/XKTModel/lib/buildEdgeIndices.js.html b/docs/file/src/XKTModel/lib/buildEdgeIndices.js.html index 2d40bf6..d49cd67 100644 --- a/docs/file/src/XKTModel/lib/buildEdgeIndices.js.html +++ b/docs/file/src/XKTModel/lib/buildEdgeIndices.js.html @@ -30,6 +30,7 @@
                                          • Fconvert2xkt
                                          • +
                                          • Fconvert2xkt
                                          • VXKT_INFO
                                          • VClampToEdgeWrapping
                                          • VGIFMediaType
                                          • @@ -67,7 +68,6 @@
                                          • FbuildVectorTextGeometry
                                          • parsersFparseCityJSONIntoXKTModel
                                          • FparseGLTFIntoXKTModel
                                          • -
                                          • FparseGLTFIntoXKTModel
                                          • FparseGLTFJSONIntoXKTModel
                                          • FparseIFCIntoXKTModel
                                          • FparseLASIntoXKTModel
                                          • diff --git a/docs/file/src/XKTModel/lib/buildFaceNormals.js.html b/docs/file/src/XKTModel/lib/buildFaceNormals.js.html index f7c6d3f..34b525b 100644 --- a/docs/file/src/XKTModel/lib/buildFaceNormals.js.html +++ b/docs/file/src/XKTModel/lib/buildFaceNormals.js.html @@ -30,6 +30,7 @@
                                            • Fconvert2xkt
                                            • +
                                            • Fconvert2xkt
                                            • VXKT_INFO
                                            • VClampToEdgeWrapping
                                            • VGIFMediaType
                                            • @@ -67,7 +68,6 @@
                                            • FbuildVectorTextGeometry
                                            • parsersFparseCityJSONIntoXKTModel
                                            • FparseGLTFIntoXKTModel
                                            • -
                                            • FparseGLTFIntoXKTModel
                                            • FparseGLTFJSONIntoXKTModel
                                            • FparseIFCIntoXKTModel
                                            • FparseLASIntoXKTModel
                                            • diff --git a/docs/file/src/XKTModel/lib/buildVertexNormals.js.html b/docs/file/src/XKTModel/lib/buildVertexNormals.js.html index 3dbe143..6dcacf6 100644 --- a/docs/file/src/XKTModel/lib/buildVertexNormals.js.html +++ b/docs/file/src/XKTModel/lib/buildVertexNormals.js.html @@ -30,6 +30,7 @@
                                              • Fconvert2xkt
                                              • +
                                              • Fconvert2xkt
                                              • VXKT_INFO
                                              • VClampToEdgeWrapping
                                              • VGIFMediaType
                                              • @@ -67,7 +68,6 @@
                                              • FbuildVectorTextGeometry
                                              • parsersFparseCityJSONIntoXKTModel
                                              • FparseGLTFIntoXKTModel
                                              • -
                                              • FparseGLTFIntoXKTModel
                                              • FparseGLTFJSONIntoXKTModel
                                              • FparseIFCIntoXKTModel
                                              • FparseLASIntoXKTModel
                                              • diff --git a/docs/file/src/XKTModel/lib/earcut.js.html b/docs/file/src/XKTModel/lib/earcut.js.html index 0c11ed4..6e774e6 100644 --- a/docs/file/src/XKTModel/lib/earcut.js.html +++ b/docs/file/src/XKTModel/lib/earcut.js.html @@ -30,6 +30,7 @@
                                                • Fconvert2xkt
                                                • +
                                                • Fconvert2xkt
                                                • VXKT_INFO
                                                • VClampToEdgeWrapping
                                                • VGIFMediaType
                                                • @@ -67,7 +68,6 @@
                                                • FbuildVectorTextGeometry
                                                • parsersFparseCityJSONIntoXKTModel
                                                • FparseGLTFIntoXKTModel
                                                • -
                                                • FparseGLTFIntoXKTModel
                                                • FparseGLTFJSONIntoXKTModel
                                                • FparseIFCIntoXKTModel
                                                • FparseLASIntoXKTModel
                                                • diff --git a/docs/file/src/XKTModel/lib/faceToVertexNormals.js.html b/docs/file/src/XKTModel/lib/faceToVertexNormals.js.html index 4e3eb7f..2566289 100644 --- a/docs/file/src/XKTModel/lib/faceToVertexNormals.js.html +++ b/docs/file/src/XKTModel/lib/faceToVertexNormals.js.html @@ -30,6 +30,7 @@
                                                  • Fconvert2xkt
                                                  • +
                                                  • Fconvert2xkt
                                                  • VXKT_INFO
                                                  • VClampToEdgeWrapping
                                                  • VGIFMediaType
                                                  • @@ -67,7 +68,6 @@
                                                  • FbuildVectorTextGeometry
                                                  • parsersFparseCityJSONIntoXKTModel
                                                  • FparseGLTFIntoXKTModel
                                                  • -
                                                  • FparseGLTFIntoXKTModel
                                                  • FparseGLTFJSONIntoXKTModel
                                                  • FparseIFCIntoXKTModel
                                                  • FparseLASIntoXKTModel
                                                  • diff --git a/docs/file/src/XKTModel/lib/geometryCompression.js.html b/docs/file/src/XKTModel/lib/geometryCompression.js.html index bcd238a..d8acc8f 100644 --- a/docs/file/src/XKTModel/lib/geometryCompression.js.html +++ b/docs/file/src/XKTModel/lib/geometryCompression.js.html @@ -30,6 +30,7 @@
                                                    • Fconvert2xkt
                                                    • +
                                                    • Fconvert2xkt
                                                    • VXKT_INFO
                                                    • VClampToEdgeWrapping
                                                    • VGIFMediaType
                                                    • @@ -67,7 +68,6 @@
                                                    • FbuildVectorTextGeometry
                                                    • parsersFparseCityJSONIntoXKTModel
                                                    • FparseGLTFIntoXKTModel
                                                    • -
                                                    • FparseGLTFIntoXKTModel
                                                    • FparseGLTFJSONIntoXKTModel
                                                    • FparseIFCIntoXKTModel
                                                    • FparseLASIntoXKTModel
                                                    • diff --git a/docs/file/src/XKTModel/lib/isTriangleMeshSolid.js.html b/docs/file/src/XKTModel/lib/isTriangleMeshSolid.js.html index 7e3aaff..c0589c8 100644 --- a/docs/file/src/XKTModel/lib/isTriangleMeshSolid.js.html +++ b/docs/file/src/XKTModel/lib/isTriangleMeshSolid.js.html @@ -30,6 +30,7 @@
                                                      • Fconvert2xkt
                                                      • +
                                                      • Fconvert2xkt
                                                      • VXKT_INFO
                                                      • VClampToEdgeWrapping
                                                      • VGIFMediaType
                                                      • @@ -67,7 +68,6 @@
                                                      • FbuildVectorTextGeometry
                                                      • parsersFparseCityJSONIntoXKTModel
                                                      • FparseGLTFIntoXKTModel
                                                      • -
                                                      • FparseGLTFIntoXKTModel
                                                      • FparseGLTFJSONIntoXKTModel
                                                      • FparseIFCIntoXKTModel
                                                      • FparseLASIntoXKTModel
                                                      • diff --git a/docs/file/src/XKTModel/lib/math.js.html b/docs/file/src/XKTModel/lib/math.js.html index 4a863cb..2127315 100644 --- a/docs/file/src/XKTModel/lib/math.js.html +++ b/docs/file/src/XKTModel/lib/math.js.html @@ -30,6 +30,7 @@
                                                        • Fconvert2xkt
                                                        • +
                                                        • Fconvert2xkt
                                                        • VXKT_INFO
                                                        • VClampToEdgeWrapping
                                                        • VGIFMediaType
                                                        • @@ -67,7 +68,6 @@
                                                        • FbuildVectorTextGeometry
                                                        • parsersFparseCityJSONIntoXKTModel
                                                        • FparseGLTFIntoXKTModel
                                                        • -
                                                        • FparseGLTFIntoXKTModel
                                                        • FparseGLTFJSONIntoXKTModel
                                                        • FparseIFCIntoXKTModel
                                                        • FparseLASIntoXKTModel
                                                        • diff --git a/docs/file/src/XKTModel/lib/mergeVertices.js.html b/docs/file/src/XKTModel/lib/mergeVertices.js.html index 0cb838c..8f11880 100644 --- a/docs/file/src/XKTModel/lib/mergeVertices.js.html +++ b/docs/file/src/XKTModel/lib/mergeVertices.js.html @@ -30,6 +30,7 @@
                                                          • Fconvert2xkt
                                                          • +
                                                          • Fconvert2xkt
                                                          • VXKT_INFO
                                                          • VClampToEdgeWrapping
                                                          • VGIFMediaType
                                                          • @@ -67,7 +68,6 @@
                                                          • FbuildVectorTextGeometry
                                                          • parsersFparseCityJSONIntoXKTModel
                                                          • FparseGLTFIntoXKTModel
                                                          • -
                                                          • FparseGLTFIntoXKTModel
                                                          • FparseGLTFJSONIntoXKTModel
                                                          • FparseIFCIntoXKTModel
                                                          • FparseLASIntoXKTModel
                                                          • diff --git a/docs/file/src/XKTModel/lib/toArraybuffer.js.html b/docs/file/src/XKTModel/lib/toArraybuffer.js.html index 43cd9f5..eac6bbf 100644 --- a/docs/file/src/XKTModel/lib/toArraybuffer.js.html +++ b/docs/file/src/XKTModel/lib/toArraybuffer.js.html @@ -30,6 +30,7 @@
                                                            • Fconvert2xkt
                                                            • +
                                                            • Fconvert2xkt
                                                            • VXKT_INFO
                                                            • VClampToEdgeWrapping
                                                            • VGIFMediaType
                                                            • @@ -67,7 +68,6 @@
                                                            • FbuildVectorTextGeometry
                                                            • parsersFparseCityJSONIntoXKTModel
                                                            • FparseGLTFIntoXKTModel
                                                            • -
                                                            • FparseGLTFIntoXKTModel
                                                            • FparseGLTFJSONIntoXKTModel
                                                            • FparseIFCIntoXKTModel
                                                            • FparseLASIntoXKTModel
                                                            • diff --git a/docs/file/src/XKTModel/lib/utils.js.html b/docs/file/src/XKTModel/lib/utils.js.html index ca7f193..6b0d409 100644 --- a/docs/file/src/XKTModel/lib/utils.js.html +++ b/docs/file/src/XKTModel/lib/utils.js.html @@ -30,6 +30,7 @@
                                                              • Fconvert2xkt
                                                              • +
                                                              • Fconvert2xkt
                                                              • VXKT_INFO
                                                              • VClampToEdgeWrapping
                                                              • VGIFMediaType
                                                              • @@ -67,7 +68,6 @@
                                                              • FbuildVectorTextGeometry
                                                              • parsersFparseCityJSONIntoXKTModel
                                                              • FparseGLTFIntoXKTModel
                                                              • -
                                                              • FparseGLTFIntoXKTModel
                                                              • FparseGLTFJSONIntoXKTModel
                                                              • FparseIFCIntoXKTModel
                                                              • FparseLASIntoXKTModel
                                                              • diff --git a/docs/file/src/XKTModel/writeXKTModelToArrayBuffer.js.html b/docs/file/src/XKTModel/writeXKTModelToArrayBuffer.js.html index 80e8533..bb1ae1c 100644 --- a/docs/file/src/XKTModel/writeXKTModelToArrayBuffer.js.html +++ b/docs/file/src/XKTModel/writeXKTModelToArrayBuffer.js.html @@ -30,6 +30,7 @@
                                                                • Fconvert2xkt
                                                                • +
                                                                • Fconvert2xkt
                                                                • VXKT_INFO
                                                                • VClampToEdgeWrapping
                                                                • VGIFMediaType
                                                                • @@ -67,7 +68,6 @@
                                                                • FbuildVectorTextGeometry
                                                                • parsersFparseCityJSONIntoXKTModel
                                                                • FparseGLTFIntoXKTModel
                                                                • -
                                                                • FparseGLTFIntoXKTModel
                                                                • FparseGLTFJSONIntoXKTModel
                                                                • FparseIFCIntoXKTModel
                                                                • FparseLASIntoXKTModel
                                                                • diff --git a/docs/file/src/XKT_INFO.js.html b/docs/file/src/XKT_INFO.js.html index e981859..0b5cc84 100644 --- a/docs/file/src/XKT_INFO.js.html +++ b/docs/file/src/XKT_INFO.js.html @@ -30,6 +30,7 @@
                                                                  • Fconvert2xkt
                                                                  • +
                                                                  • Fconvert2xkt
                                                                  • VXKT_INFO
                                                                  • VClampToEdgeWrapping
                                                                  • VGIFMediaType
                                                                  • @@ -67,7 +68,6 @@
                                                                  • FbuildVectorTextGeometry
                                                                  • parsersFparseCityJSONIntoXKTModel
                                                                  • FparseGLTFIntoXKTModel
                                                                  • -
                                                                  • FparseGLTFIntoXKTModel
                                                                  • FparseGLTFJSONIntoXKTModel
                                                                  • FparseIFCIntoXKTModel
                                                                  • FparseLASIntoXKTModel
                                                                  • diff --git a/docs/file/src/constants.js.html b/docs/file/src/constants.js.html index 193a145..8c32c6f 100644 --- a/docs/file/src/constants.js.html +++ b/docs/file/src/constants.js.html @@ -30,6 +30,7 @@
                                                                    • Fconvert2xkt
                                                                    • +
                                                                    • Fconvert2xkt
                                                                    • VXKT_INFO
                                                                    • VClampToEdgeWrapping
                                                                    • VGIFMediaType
                                                                    • @@ -67,7 +68,6 @@
                                                                    • FbuildVectorTextGeometry
                                                                    • parsersFparseCityJSONIntoXKTModel
                                                                    • FparseGLTFIntoXKTModel
                                                                    • -
                                                                    • FparseGLTFIntoXKTModel
                                                                    • FparseGLTFJSONIntoXKTModel
                                                                    • FparseIFCIntoXKTModel
                                                                    • FparseLASIntoXKTModel
                                                                    • diff --git a/docs/file/src/convert2xkt.js.html b/docs/file/src/convert2xkt.js.html index 37bc6f6..0d0f573 100644 --- a/docs/file/src/convert2xkt.js.html +++ b/docs/file/src/convert2xkt.js.html @@ -30,6 +30,7 @@
                                                                      • Fconvert2xkt
                                                                      • +
                                                                      • Fconvert2xkt
                                                                      • VXKT_INFO
                                                                      • VClampToEdgeWrapping
                                                                      • VGIFMediaType
                                                                      • @@ -67,7 +68,6 @@
                                                                      • FbuildVectorTextGeometry
                                                                      • parsersFparseCityJSONIntoXKTModel
                                                                      • FparseGLTFIntoXKTModel
                                                                      • -
                                                                      • FparseGLTFIntoXKTModel
                                                                      • FparseGLTFJSONIntoXKTModel
                                                                      • FparseIFCIntoXKTModel
                                                                      • FparseLASIntoXKTModel
                                                                      • diff --git a/docs/file/src/convert2xkt_browser.js.html b/docs/file/src/convert2xkt_browser.js.html new file mode 100644 index 0000000..1e02787 --- /dev/null +++ b/docs/file/src/convert2xkt_browser.js.html @@ -0,0 +1,287 @@ + + + + + + src/convert2xkt_browser.js | xeokit-convert + + + + + + + +
                                                                        + + + Reference + Source + + +
                                                                        + + + +

                                                                        src/convert2xkt_browser.js

                                                                        +
                                                                        
                                                                        +import {XKTModel} from "./XKTModel/XKTModel.js";
                                                                        +import {parseGLTFIntoXKTModel} from "./parsers/parseGLTFIntoXKTModel.js";
                                                                        +import {writeXKTModelToArrayBuffer} from "./XKTModel/writeXKTModelToArrayBuffer.js";
                                                                        +
                                                                        +import {toArrayBuffer} from "./XKTModel/lib/toArraybuffer";
                                                                        +
                                                                        +/**
                                                                        + * Converts model files into xeokit's native XKT format.
                                                                        + *
                                                                        + * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.
                                                                        + *
                                                                        + * **Only bundled in xeokit-convert.cjs.js.**
                                                                        + *
                                                                        + * ## Usage
                                                                        + *
                                                                        + ````
                                                                        + * @param {Object} params Conversion parameters.
                                                                        + * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the
                                                                        + * caller the choice of whether to use the Browser or NodeJS version.
                                                                        + * @param {*} [params.configs] Configurations.
                                                                        + * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````.
                                                                        + * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method.
                                                                        + * @param {Function} [params.outputXKT] Callback to collect XKT file data.
                                                                        + * @param {String[]} [params.includeTypes] Option to only convert objects of these types.
                                                                        + * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.
                                                                        + * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided.
                                                                        + * @param {Function} [params.outputStats] Callback to collect statistics.
                                                                        + * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis "up", if necessary. Applies to CityJSON and LAS/LAZ models.
                                                                        + * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false,
                                                                        + * will automatically "expand" all reused geometries into duplicate copies. This has the drawback of increasing the XKT
                                                                        + * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model
                                                                        + * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are
                                                                        + * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a
                                                                        + * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).
                                                                        + * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models.
                                                                        + * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore
                                                                        + * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has
                                                                        + * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render
                                                                        + * a flat-shaded non-PBR representation of the model.
                                                                        + * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000,
                                                                        + * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close
                                                                        + * to the origin, and smaller sizes when distant.  This compensates for decreasing precision as floats get bigger.
                                                                        + * @param {Function} [params.log] Logging callback.
                                                                        + * @return {Promise<number>}
                                                                        + */
                                                                        +function convert2xkt({
                                                                        +                         configs = {},
                                                                        +                         sourceData,
                                                                        +                         modelAABB,
                                                                        +                         outputXKTModel,
                                                                        +                         outputXKT,
                                                                        +                         includeTypes,
                                                                        +                         excludeTypes,
                                                                        +                         reuseGeometries = true,
                                                                        +                         minTileSize = 200,
                                                                        +                         stats = {},
                                                                        +                         rotateX = false,
                                                                        +                         includeTextures = true,
                                                                        +                         includeNormals = true,
                                                                        +                         log = function (msg) {
                                                                        +                         }
                                                                        +                     }) {
                                                                        +
                                                                        +    stats.schemaVersion = "";
                                                                        +    stats.title = "";
                                                                        +    stats.author = "";
                                                                        +    stats.created = "";
                                                                        +    stats.numMetaObjects = 0;
                                                                        +    stats.numPropertySets = 0;
                                                                        +    stats.numTriangles = 0;
                                                                        +    stats.numVertices = 0;
                                                                        +    stats.numNormals = 0;
                                                                        +    stats.numUVs = 0;
                                                                        +    stats.numTextures = 0;
                                                                        +    stats.numTextureSets = 0;
                                                                        +    stats.numObjects = 0;
                                                                        +    stats.numGeometries = 0;
                                                                        +    stats.sourceSize = 0;
                                                                        +    stats.xktSize = 0;
                                                                        +    stats.texturesSize = 0;
                                                                        +    stats.xktVersion = "";
                                                                        +    stats.compressionRatio = 0;
                                                                        +    stats.conversionTime = 0;
                                                                        +    stats.aabb = null;
                                                                        +
                                                                        +    return new Promise(function (resolve, reject) {
                                                                        +        const _log = log;
                                                                        +        log = (msg) => {
                                                                        +            _log(`[convert2xkt] ${msg}`)
                                                                        +        }
                                                                        +
                                                                        +        if (!sourceData) {
                                                                        +            reject("Argument expected: source or sourceData");
                                                                        +            return;
                                                                        +        }
                                                                        +
                                                                        +        if (!outputXKTModel && !outputXKT) {
                                                                        +            reject("Argument expected: output, outputXKTModel or outputXKT");
                                                                        +            return;
                                                                        +        }
                                                                        +
                                                                        +        const sourceConfigs = configs.sourceConfigs || {};
                                                                        +        const ext = 'glb';
                                                                        +
                                                                        +        log(`Input file extension: "${ext}"`);
                                                                        +
                                                                        +        let fileTypeConfigs = sourceConfigs[ext];
                                                                        +
                                                                        +        if (!fileTypeConfigs) {
                                                                        +            log(`[WARNING] Could not find configs sourceConfigs entry for source format "${ext}". This is derived from the source file name extension. Will use internal default configs.`);
                                                                        +            fileTypeConfigs = {};
                                                                        +        }
                                                                        +
                                                                        +        function overrideOption(option1, option2) {
                                                                        +            if (option1 !== undefined) {
                                                                        +                return option1;
                                                                        +            }
                                                                        +            return option2;
                                                                        +        }
                                                                        +
                                                                        +
                                                                        +        const sourceFileSizeBytes = sourceData.byteLength;
                                                                        +
                                                                        +        log("Input file size: " + (sourceFileSizeBytes / 1000).toFixed(2) + " kB");
                                                                        +
                                                                        +
                                                                        +
                                                                        +        minTileSize = overrideOption(fileTypeConfigs.minTileSize, minTileSize);
                                                                        +        rotateX = overrideOption(fileTypeConfigs.rotateX, rotateX);
                                                                        +        reuseGeometries = overrideOption(fileTypeConfigs.reuseGeometries, reuseGeometries);
                                                                        +        includeTextures = overrideOption(fileTypeConfigs.includeTextures, includeTextures);
                                                                        +        includeNormals = overrideOption(fileTypeConfigs.includeNormals, includeNormals);
                                                                        +        includeTypes = overrideOption(fileTypeConfigs.includeTypes, includeTypes);
                                                                        +        excludeTypes = overrideOption(fileTypeConfigs.excludeTypes, excludeTypes);
                                                                        +
                                                                        +        if (reuseGeometries === false) {
                                                                        +            log("Geometry reuse is disabled");
                                                                        +        }
                                                                        +
                                                                        +        const xktModel = new XKTModel({
                                                                        +            minTileSize,
                                                                        +            modelAABB
                                                                        +        });
                                                                        +
                                                                        +
                                                                        +
                                                                        +        sourceData = toArrayBuffer(sourceData);
                                                                        +        convert(parseGLTFIntoXKTModel, {
                                                                        +            data: sourceData,
                                                                        +            reuseGeometries,
                                                                        +            includeTextures: true,
                                                                        +            includeNormals,
                                                                        +            xktModel,
                                                                        +            stats,
                                                                        +            log
                                                                        +        });
                                                                        +
                                                                        +
                                                                        +        function convert(parser, converterParams) {
                                                                        +
                                                                        +            parser(converterParams).then(() => {
                                                                        +
                                                                        +
                                                                        +                log("Input file parsed OK. Building XKT document...");
                                                                        +
                                                                        +                xktModel.finalize().then(() => {
                                                                        +
                                                                        +                    log("XKT document built OK. Writing to XKT file...");
                                                                        +
                                                                        +                    const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel, null, stats, {zip: true});
                                                                        +
                                                                        +                    const xktContent = Buffer.from(xktArrayBuffer);
                                                                        +
                                                                        +
                                                                        +                    if (outputXKT) {
                                                                        +                        outputXKT(xktContent);
                                                                        +                    }
                                                                        +
                                                                        +                    resolve();
                                                                        +                });
                                                                        +            }, (err) => {
                                                                        +                reject(err);
                                                                        +            });
                                                                        +        }
                                                                        +    });
                                                                        +}
                                                                        +
                                                                        +export {convert2xkt};
                                                                        + +
                                                                        + + + + + + + + + + + + diff --git a/docs/file/src/geometryBuilders/buildBoxGeometry.js.html b/docs/file/src/geometryBuilders/buildBoxGeometry.js.html index f76a9f2..58b51f5 100644 --- a/docs/file/src/geometryBuilders/buildBoxGeometry.js.html +++ b/docs/file/src/geometryBuilders/buildBoxGeometry.js.html @@ -30,6 +30,7 @@
                                                                        • Fconvert2xkt
                                                                        • +
                                                                        • Fconvert2xkt
                                                                        • VXKT_INFO
                                                                        • VClampToEdgeWrapping
                                                                        • VGIFMediaType
                                                                        • @@ -67,7 +68,6 @@
                                                                        • FbuildVectorTextGeometry
                                                                        • parsersFparseCityJSONIntoXKTModel
                                                                        • FparseGLTFIntoXKTModel
                                                                        • -
                                                                        • FparseGLTFIntoXKTModel
                                                                        • FparseGLTFJSONIntoXKTModel
                                                                        • FparseIFCIntoXKTModel
                                                                        • FparseLASIntoXKTModel
                                                                        • diff --git a/docs/file/src/geometryBuilders/buildBoxLinesGeometry.js.html b/docs/file/src/geometryBuilders/buildBoxLinesGeometry.js.html index 51e2ab5..5d7276c 100644 --- a/docs/file/src/geometryBuilders/buildBoxLinesGeometry.js.html +++ b/docs/file/src/geometryBuilders/buildBoxLinesGeometry.js.html @@ -30,6 +30,7 @@
                                                                          • Fconvert2xkt
                                                                          • +
                                                                          • Fconvert2xkt
                                                                          • VXKT_INFO
                                                                          • VClampToEdgeWrapping
                                                                          • VGIFMediaType
                                                                          • @@ -67,7 +68,6 @@
                                                                          • FbuildVectorTextGeometry
                                                                          • parsersFparseCityJSONIntoXKTModel
                                                                          • FparseGLTFIntoXKTModel
                                                                          • -
                                                                          • FparseGLTFIntoXKTModel
                                                                          • FparseGLTFJSONIntoXKTModel
                                                                          • FparseIFCIntoXKTModel
                                                                          • FparseLASIntoXKTModel
                                                                          • diff --git a/docs/file/src/geometryBuilders/buildCylinderGeometry.js.html b/docs/file/src/geometryBuilders/buildCylinderGeometry.js.html index 2d9aa6e..8df239c 100644 --- a/docs/file/src/geometryBuilders/buildCylinderGeometry.js.html +++ b/docs/file/src/geometryBuilders/buildCylinderGeometry.js.html @@ -30,6 +30,7 @@
                                                                            • Fconvert2xkt
                                                                            • +
                                                                            • Fconvert2xkt
                                                                            • VXKT_INFO
                                                                            • VClampToEdgeWrapping
                                                                            • VGIFMediaType
                                                                            • @@ -67,7 +68,6 @@
                                                                            • FbuildVectorTextGeometry
                                                                            • parsersFparseCityJSONIntoXKTModel
                                                                            • FparseGLTFIntoXKTModel
                                                                            • -
                                                                            • FparseGLTFIntoXKTModel
                                                                            • FparseGLTFJSONIntoXKTModel
                                                                            • FparseIFCIntoXKTModel
                                                                            • FparseLASIntoXKTModel
                                                                            • diff --git a/docs/file/src/geometryBuilders/buildGridGeometry.js.html b/docs/file/src/geometryBuilders/buildGridGeometry.js.html index cfa7ce5..9a5c401 100644 --- a/docs/file/src/geometryBuilders/buildGridGeometry.js.html +++ b/docs/file/src/geometryBuilders/buildGridGeometry.js.html @@ -30,6 +30,7 @@
                                                                              • Fconvert2xkt
                                                                              • +
                                                                              • Fconvert2xkt
                                                                              • VXKT_INFO
                                                                              • VClampToEdgeWrapping
                                                                              • VGIFMediaType
                                                                              • @@ -67,7 +68,6 @@
                                                                              • FbuildVectorTextGeometry
                                                                              • parsersFparseCityJSONIntoXKTModel
                                                                              • FparseGLTFIntoXKTModel
                                                                              • -
                                                                              • FparseGLTFIntoXKTModel
                                                                              • FparseGLTFJSONIntoXKTModel
                                                                              • FparseIFCIntoXKTModel
                                                                              • FparseLASIntoXKTModel
                                                                              • diff --git a/docs/file/src/geometryBuilders/buildPlaneGeometry.js.html b/docs/file/src/geometryBuilders/buildPlaneGeometry.js.html index ec9ba83..b8c1e36 100644 --- a/docs/file/src/geometryBuilders/buildPlaneGeometry.js.html +++ b/docs/file/src/geometryBuilders/buildPlaneGeometry.js.html @@ -30,6 +30,7 @@
                                                                                • Fconvert2xkt
                                                                                • +
                                                                                • Fconvert2xkt
                                                                                • VXKT_INFO
                                                                                • VClampToEdgeWrapping
                                                                                • VGIFMediaType
                                                                                • @@ -67,7 +68,6 @@
                                                                                • FbuildVectorTextGeometry
                                                                                • parsersFparseCityJSONIntoXKTModel
                                                                                • FparseGLTFIntoXKTModel
                                                                                • -
                                                                                • FparseGLTFIntoXKTModel
                                                                                • FparseGLTFJSONIntoXKTModel
                                                                                • FparseIFCIntoXKTModel
                                                                                • FparseLASIntoXKTModel
                                                                                • diff --git a/docs/file/src/geometryBuilders/buildSphereGeometry.js.html b/docs/file/src/geometryBuilders/buildSphereGeometry.js.html index 1e9c667..ffed373 100644 --- a/docs/file/src/geometryBuilders/buildSphereGeometry.js.html +++ b/docs/file/src/geometryBuilders/buildSphereGeometry.js.html @@ -30,6 +30,7 @@
                                                                                  • Fconvert2xkt
                                                                                  • +
                                                                                  • Fconvert2xkt
                                                                                  • VXKT_INFO
                                                                                  • VClampToEdgeWrapping
                                                                                  • VGIFMediaType
                                                                                  • @@ -67,7 +68,6 @@
                                                                                  • FbuildVectorTextGeometry
                                                                                  • parsersFparseCityJSONIntoXKTModel
                                                                                  • FparseGLTFIntoXKTModel
                                                                                  • -
                                                                                  • FparseGLTFIntoXKTModel
                                                                                  • FparseGLTFJSONIntoXKTModel
                                                                                  • FparseIFCIntoXKTModel
                                                                                  • FparseLASIntoXKTModel
                                                                                  • diff --git a/docs/file/src/geometryBuilders/buildTorusGeometry.js.html b/docs/file/src/geometryBuilders/buildTorusGeometry.js.html index dab167b..e884698 100644 --- a/docs/file/src/geometryBuilders/buildTorusGeometry.js.html +++ b/docs/file/src/geometryBuilders/buildTorusGeometry.js.html @@ -30,6 +30,7 @@
                                                                                    • Fconvert2xkt
                                                                                    • +
                                                                                    • Fconvert2xkt
                                                                                    • VXKT_INFO
                                                                                    • VClampToEdgeWrapping
                                                                                    • VGIFMediaType
                                                                                    • @@ -67,7 +68,6 @@
                                                                                    • FbuildVectorTextGeometry
                                                                                    • parsersFparseCityJSONIntoXKTModel
                                                                                    • FparseGLTFIntoXKTModel
                                                                                    • -
                                                                                    • FparseGLTFIntoXKTModel
                                                                                    • FparseGLTFJSONIntoXKTModel
                                                                                    • FparseIFCIntoXKTModel
                                                                                    • FparseLASIntoXKTModel
                                                                                    • diff --git a/docs/file/src/geometryBuilders/buildVectorTextGeometry.js.html b/docs/file/src/geometryBuilders/buildVectorTextGeometry.js.html index e5d8442..ab30572 100644 --- a/docs/file/src/geometryBuilders/buildVectorTextGeometry.js.html +++ b/docs/file/src/geometryBuilders/buildVectorTextGeometry.js.html @@ -30,6 +30,7 @@
                                                                                      • Fconvert2xkt
                                                                                      • +
                                                                                      • Fconvert2xkt
                                                                                      • VXKT_INFO
                                                                                      • VClampToEdgeWrapping
                                                                                      • VGIFMediaType
                                                                                      • @@ -67,7 +68,6 @@
                                                                                      • FbuildVectorTextGeometry
                                                                                      • parsersFparseCityJSONIntoXKTModel
                                                                                      • FparseGLTFIntoXKTModel
                                                                                      • -
                                                                                      • FparseGLTFIntoXKTModel
                                                                                      • FparseGLTFJSONIntoXKTModel
                                                                                      • FparseIFCIntoXKTModel
                                                                                      • FparseLASIntoXKTModel
                                                                                      • diff --git a/docs/file/src/index.js.html b/docs/file/src/index.js.html index 2ffc2bb..6e25e1c 100644 --- a/docs/file/src/index.js.html +++ b/docs/file/src/index.js.html @@ -30,6 +30,7 @@
                                                                                        • Fconvert2xkt
                                                                                        • +
                                                                                        • Fconvert2xkt
                                                                                        • VXKT_INFO
                                                                                        • VClampToEdgeWrapping
                                                                                        • VGIFMediaType
                                                                                        • @@ -67,7 +68,6 @@
                                                                                        • FbuildVectorTextGeometry
                                                                                        • parsersFparseCityJSONIntoXKTModel
                                                                                        • FparseGLTFIntoXKTModel
                                                                                        • -
                                                                                        • FparseGLTFIntoXKTModel
                                                                                        • FparseGLTFJSONIntoXKTModel
                                                                                        • FparseIFCIntoXKTModel
                                                                                        • FparseLASIntoXKTModel
                                                                                        • diff --git a/docs/file/src/lib/buildFaceNormals.js.html b/docs/file/src/lib/buildFaceNormals.js.html index 0c26477..c80bb5a 100644 --- a/docs/file/src/lib/buildFaceNormals.js.html +++ b/docs/file/src/lib/buildFaceNormals.js.html @@ -30,6 +30,7 @@
                                                                                          • Fconvert2xkt
                                                                                          • +
                                                                                          • Fconvert2xkt
                                                                                          • VXKT_INFO
                                                                                          • VClampToEdgeWrapping
                                                                                          • VGIFMediaType
                                                                                          • @@ -67,7 +68,6 @@
                                                                                          • FbuildVectorTextGeometry
                                                                                          • parsersFparseCityJSONIntoXKTModel
                                                                                          • FparseGLTFIntoXKTModel
                                                                                          • -
                                                                                          • FparseGLTFIntoXKTModel
                                                                                          • FparseGLTFJSONIntoXKTModel
                                                                                          • FparseIFCIntoXKTModel
                                                                                          • FparseLASIntoXKTModel
                                                                                          • diff --git a/docs/file/src/lib/buildVertexNormals.js.html b/docs/file/src/lib/buildVertexNormals.js.html index b3c02c3..0231aa2 100644 --- a/docs/file/src/lib/buildVertexNormals.js.html +++ b/docs/file/src/lib/buildVertexNormals.js.html @@ -30,6 +30,7 @@
                                                                                            • Fconvert2xkt
                                                                                            • +
                                                                                            • Fconvert2xkt
                                                                                            • VXKT_INFO
                                                                                            • VClampToEdgeWrapping
                                                                                            • VGIFMediaType
                                                                                            • @@ -67,7 +68,6 @@
                                                                                            • FbuildVectorTextGeometry
                                                                                            • parsersFparseCityJSONIntoXKTModel
                                                                                            • FparseGLTFIntoXKTModel
                                                                                            • -
                                                                                            • FparseGLTFIntoXKTModel
                                                                                            • FparseGLTFJSONIntoXKTModel
                                                                                            • FparseIFCIntoXKTModel
                                                                                            • FparseLASIntoXKTModel
                                                                                            • diff --git a/docs/file/src/lib/earcut.js.html b/docs/file/src/lib/earcut.js.html index fa53b87..dcc48d8 100644 --- a/docs/file/src/lib/earcut.js.html +++ b/docs/file/src/lib/earcut.js.html @@ -30,6 +30,7 @@
                                                                                              • Fconvert2xkt
                                                                                              • +
                                                                                              • Fconvert2xkt
                                                                                              • VXKT_INFO
                                                                                              • VClampToEdgeWrapping
                                                                                              • VGIFMediaType
                                                                                              • @@ -67,7 +68,6 @@
                                                                                              • FbuildVectorTextGeometry
                                                                                              • parsersFparseCityJSONIntoXKTModel
                                                                                              • FparseGLTFIntoXKTModel
                                                                                              • -
                                                                                              • FparseGLTFIntoXKTModel
                                                                                              • FparseGLTFJSONIntoXKTModel
                                                                                              • FparseIFCIntoXKTModel
                                                                                              • FparseLASIntoXKTModel
                                                                                              • diff --git a/docs/file/src/lib/faceToVertexNormals.js.html b/docs/file/src/lib/faceToVertexNormals.js.html index 821b38d..3f704a0 100644 --- a/docs/file/src/lib/faceToVertexNormals.js.html +++ b/docs/file/src/lib/faceToVertexNormals.js.html @@ -30,6 +30,7 @@
                                                                                                • Fconvert2xkt
                                                                                                • +
                                                                                                • Fconvert2xkt
                                                                                                • VXKT_INFO
                                                                                                • VClampToEdgeWrapping
                                                                                                • VGIFMediaType
                                                                                                • @@ -67,7 +68,6 @@
                                                                                                • FbuildVectorTextGeometry
                                                                                                • parsersFparseCityJSONIntoXKTModel
                                                                                                • FparseGLTFIntoXKTModel
                                                                                                • -
                                                                                                • FparseGLTFIntoXKTModel
                                                                                                • FparseGLTFJSONIntoXKTModel
                                                                                                • FparseIFCIntoXKTModel
                                                                                                • FparseLASIntoXKTModel
                                                                                                • diff --git a/docs/file/src/lib/math.js.html b/docs/file/src/lib/math.js.html index dc2d222..1cb6bce 100644 --- a/docs/file/src/lib/math.js.html +++ b/docs/file/src/lib/math.js.html @@ -30,6 +30,7 @@
                                                                                                  • Fconvert2xkt
                                                                                                  • +
                                                                                                  • Fconvert2xkt
                                                                                                  • VXKT_INFO
                                                                                                  • VClampToEdgeWrapping
                                                                                                  • VGIFMediaType
                                                                                                  • @@ -67,7 +68,6 @@
                                                                                                  • FbuildVectorTextGeometry
                                                                                                  • parsersFparseCityJSONIntoXKTModel
                                                                                                  • FparseGLTFIntoXKTModel
                                                                                                  • -
                                                                                                  • FparseGLTFIntoXKTModel
                                                                                                  • FparseGLTFJSONIntoXKTModel
                                                                                                  • FparseIFCIntoXKTModel
                                                                                                  • FparseLASIntoXKTModel
                                                                                                  • diff --git a/docs/file/src/lib/mergeVertices.js.html b/docs/file/src/lib/mergeVertices.js.html index 5e69d41..86e1fab 100644 --- a/docs/file/src/lib/mergeVertices.js.html +++ b/docs/file/src/lib/mergeVertices.js.html @@ -30,6 +30,7 @@
                                                                                                    • Fconvert2xkt
                                                                                                    • +
                                                                                                    • Fconvert2xkt
                                                                                                    • VXKT_INFO
                                                                                                    • VClampToEdgeWrapping
                                                                                                    • VGIFMediaType
                                                                                                    • @@ -67,7 +68,6 @@
                                                                                                    • FbuildVectorTextGeometry
                                                                                                    • parsersFparseCityJSONIntoXKTModel
                                                                                                    • FparseGLTFIntoXKTModel
                                                                                                    • -
                                                                                                    • FparseGLTFIntoXKTModel
                                                                                                    • FparseGLTFJSONIntoXKTModel
                                                                                                    • FparseIFCIntoXKTModel
                                                                                                    • FparseLASIntoXKTModel
                                                                                                    • diff --git a/docs/file/src/parsers/parseCityJSONIntoXKTModel.js.html b/docs/file/src/parsers/parseCityJSONIntoXKTModel.js.html index bcd685d..1669440 100644 --- a/docs/file/src/parsers/parseCityJSONIntoXKTModel.js.html +++ b/docs/file/src/parsers/parseCityJSONIntoXKTModel.js.html @@ -30,6 +30,7 @@
                                                                                                      • Fconvert2xkt
                                                                                                      • +
                                                                                                      • Fconvert2xkt
                                                                                                      • VXKT_INFO
                                                                                                      • VClampToEdgeWrapping
                                                                                                      • VGIFMediaType
                                                                                                      • @@ -67,7 +68,6 @@
                                                                                                      • FbuildVectorTextGeometry
                                                                                                      • parsersFparseCityJSONIntoXKTModel
                                                                                                      • FparseGLTFIntoXKTModel
                                                                                                      • -
                                                                                                      • FparseGLTFIntoXKTModel
                                                                                                      • FparseGLTFJSONIntoXKTModel
                                                                                                      • FparseIFCIntoXKTModel
                                                                                                      • FparseLASIntoXKTModel
                                                                                                      • diff --git a/docs/file/src/parsers/parseGLTFIntoXKTModel.js.html b/docs/file/src/parsers/parseGLTFIntoXKTModel.js.html index f7bf4d9..5c67361 100644 --- a/docs/file/src/parsers/parseGLTFIntoXKTModel.js.html +++ b/docs/file/src/parsers/parseGLTFIntoXKTModel.js.html @@ -30,6 +30,7 @@
                                                                                                        • Fconvert2xkt
                                                                                                        • +
                                                                                                        • Fconvert2xkt
                                                                                                        • VXKT_INFO
                                                                                                        • VClampToEdgeWrapping
                                                                                                        • VGIFMediaType
                                                                                                        • @@ -67,7 +68,6 @@
                                                                                                        • FbuildVectorTextGeometry
                                                                                                        • parsersFparseCityJSONIntoXKTModel
                                                                                                        • FparseGLTFIntoXKTModel
                                                                                                        • -
                                                                                                        • FparseGLTFIntoXKTModel
                                                                                                        • FparseGLTFJSONIntoXKTModel
                                                                                                        • FparseIFCIntoXKTModel
                                                                                                        • FparseLASIntoXKTModel
                                                                                                        • diff --git a/docs/file/src/parsers/parseGLTFJSONIntoXKTModel.js.html b/docs/file/src/parsers/parseGLTFJSONIntoXKTModel.js.html index be0820c..5da7235 100644 --- a/docs/file/src/parsers/parseGLTFJSONIntoXKTModel.js.html +++ b/docs/file/src/parsers/parseGLTFJSONIntoXKTModel.js.html @@ -30,6 +30,7 @@
                                                                                                          • Fconvert2xkt
                                                                                                          • +
                                                                                                          • Fconvert2xkt
                                                                                                          • VXKT_INFO
                                                                                                          • VClampToEdgeWrapping
                                                                                                          • VGIFMediaType
                                                                                                          • @@ -67,7 +68,6 @@
                                                                                                          • FbuildVectorTextGeometry
                                                                                                          • parsersFparseCityJSONIntoXKTModel
                                                                                                          • FparseGLTFIntoXKTModel
                                                                                                          • -
                                                                                                          • FparseGLTFIntoXKTModel
                                                                                                          • FparseGLTFJSONIntoXKTModel
                                                                                                          • FparseIFCIntoXKTModel
                                                                                                          • FparseLASIntoXKTModel
                                                                                                          • diff --git a/docs/file/src/parsers/parseIFCIntoXKTModel.js.html b/docs/file/src/parsers/parseIFCIntoXKTModel.js.html index 2d33d3f..0813c2a 100644 --- a/docs/file/src/parsers/parseIFCIntoXKTModel.js.html +++ b/docs/file/src/parsers/parseIFCIntoXKTModel.js.html @@ -30,6 +30,7 @@
                                                                                                            • Fconvert2xkt
                                                                                                            • +
                                                                                                            • Fconvert2xkt
                                                                                                            • VXKT_INFO
                                                                                                            • VClampToEdgeWrapping
                                                                                                            • VGIFMediaType
                                                                                                            • @@ -67,7 +68,6 @@
                                                                                                            • FbuildVectorTextGeometry
                                                                                                            • parsersFparseCityJSONIntoXKTModel
                                                                                                            • FparseGLTFIntoXKTModel
                                                                                                            • -
                                                                                                            • FparseGLTFIntoXKTModel
                                                                                                            • FparseGLTFJSONIntoXKTModel
                                                                                                            • FparseIFCIntoXKTModel
                                                                                                            • FparseLASIntoXKTModel
                                                                                                            • diff --git a/docs/file/src/parsers/parseLASIntoXKTModel.js.html b/docs/file/src/parsers/parseLASIntoXKTModel.js.html index 5647cf3..91e95f0 100644 --- a/docs/file/src/parsers/parseLASIntoXKTModel.js.html +++ b/docs/file/src/parsers/parseLASIntoXKTModel.js.html @@ -30,6 +30,7 @@
                                                                                                              • Fconvert2xkt
                                                                                                              • +
                                                                                                              • Fconvert2xkt
                                                                                                              • VXKT_INFO
                                                                                                              • VClampToEdgeWrapping
                                                                                                              • VGIFMediaType
                                                                                                              • @@ -67,7 +68,6 @@
                                                                                                              • FbuildVectorTextGeometry
                                                                                                              • parsersFparseCityJSONIntoXKTModel
                                                                                                              • FparseGLTFIntoXKTModel
                                                                                                              • -
                                                                                                              • FparseGLTFIntoXKTModel
                                                                                                              • FparseGLTFJSONIntoXKTModel
                                                                                                              • FparseIFCIntoXKTModel
                                                                                                              • FparseLASIntoXKTModel
                                                                                                              • diff --git a/docs/file/src/parsers/parseMetaModelIntoXKTModel.js.html b/docs/file/src/parsers/parseMetaModelIntoXKTModel.js.html index a972ea4..117eb59 100644 --- a/docs/file/src/parsers/parseMetaModelIntoXKTModel.js.html +++ b/docs/file/src/parsers/parseMetaModelIntoXKTModel.js.html @@ -30,6 +30,7 @@
                                                                                                                • Fconvert2xkt
                                                                                                                • +
                                                                                                                • Fconvert2xkt
                                                                                                                • VXKT_INFO
                                                                                                                • VClampToEdgeWrapping
                                                                                                                • VGIFMediaType
                                                                                                                • @@ -67,7 +68,6 @@
                                                                                                                • FbuildVectorTextGeometry
                                                                                                                • parsersFparseCityJSONIntoXKTModel
                                                                                                                • FparseGLTFIntoXKTModel
                                                                                                                • -
                                                                                                                • FparseGLTFIntoXKTModel
                                                                                                                • FparseGLTFJSONIntoXKTModel
                                                                                                                • FparseIFCIntoXKTModel
                                                                                                                • FparseLASIntoXKTModel
                                                                                                                • diff --git a/docs/file/src/parsers/parsePCDIntoXKTModel.js.html b/docs/file/src/parsers/parsePCDIntoXKTModel.js.html index e07181f..3602345 100644 --- a/docs/file/src/parsers/parsePCDIntoXKTModel.js.html +++ b/docs/file/src/parsers/parsePCDIntoXKTModel.js.html @@ -30,6 +30,7 @@
                                                                                                                  • Fconvert2xkt
                                                                                                                  • +
                                                                                                                  • Fconvert2xkt
                                                                                                                  • VXKT_INFO
                                                                                                                  • VClampToEdgeWrapping
                                                                                                                  • VGIFMediaType
                                                                                                                  • @@ -67,7 +68,6 @@
                                                                                                                  • FbuildVectorTextGeometry
                                                                                                                  • parsersFparseCityJSONIntoXKTModel
                                                                                                                  • FparseGLTFIntoXKTModel
                                                                                                                  • -
                                                                                                                  • FparseGLTFIntoXKTModel
                                                                                                                  • FparseGLTFJSONIntoXKTModel
                                                                                                                  • FparseIFCIntoXKTModel
                                                                                                                  • FparseLASIntoXKTModel
                                                                                                                  • diff --git a/docs/file/src/parsers/parsePLYIntoXKTModel.js.html b/docs/file/src/parsers/parsePLYIntoXKTModel.js.html index b969b93..ea7c318 100644 --- a/docs/file/src/parsers/parsePLYIntoXKTModel.js.html +++ b/docs/file/src/parsers/parsePLYIntoXKTModel.js.html @@ -30,6 +30,7 @@
                                                                                                                    • Fconvert2xkt
                                                                                                                    • +
                                                                                                                    • Fconvert2xkt
                                                                                                                    • VXKT_INFO
                                                                                                                    • VClampToEdgeWrapping
                                                                                                                    • VGIFMediaType
                                                                                                                    • @@ -67,7 +68,6 @@
                                                                                                                    • FbuildVectorTextGeometry
                                                                                                                    • parsersFparseCityJSONIntoXKTModel
                                                                                                                    • FparseGLTFIntoXKTModel
                                                                                                                    • -
                                                                                                                    • FparseGLTFIntoXKTModel
                                                                                                                    • FparseGLTFJSONIntoXKTModel
                                                                                                                    • FparseIFCIntoXKTModel
                                                                                                                    • FparseLASIntoXKTModel
                                                                                                                    • diff --git a/docs/file/src/parsers/parseSTLIntoXKTModel.js.html b/docs/file/src/parsers/parseSTLIntoXKTModel.js.html index 0541892..649edbd 100644 --- a/docs/file/src/parsers/parseSTLIntoXKTModel.js.html +++ b/docs/file/src/parsers/parseSTLIntoXKTModel.js.html @@ -30,6 +30,7 @@
                                                                                                                      • Fconvert2xkt
                                                                                                                      • +
                                                                                                                      • Fconvert2xkt
                                                                                                                      • VXKT_INFO
                                                                                                                      • VClampToEdgeWrapping
                                                                                                                      • VGIFMediaType
                                                                                                                      • @@ -67,7 +68,6 @@
                                                                                                                      • FbuildVectorTextGeometry
                                                                                                                      • parsersFparseCityJSONIntoXKTModel
                                                                                                                      • FparseGLTFIntoXKTModel
                                                                                                                      • -
                                                                                                                      • FparseGLTFIntoXKTModel
                                                                                                                      • FparseGLTFJSONIntoXKTModel
                                                                                                                      • FparseIFCIntoXKTModel
                                                                                                                      • FparseLASIntoXKTModel
                                                                                                                      • diff --git a/docs/function/index.html b/docs/function/index.html index c24ef78..c4e61f1 100644 --- a/docs/function/index.html +++ b/docs/function/index.html @@ -30,6 +30,7 @@
                                                                                                                        • Fconvert2xkt
                                                                                                                        • +
                                                                                                                        • Fconvert2xkt
                                                                                                                        • VXKT_INFO
                                                                                                                        • VClampToEdgeWrapping
                                                                                                                        • VGIFMediaType
                                                                                                                        • @@ -67,7 +68,6 @@
                                                                                                                        • FbuildVectorTextGeometry
                                                                                                                        • parsersFparseCityJSONIntoXKTModel
                                                                                                                        • FparseGLTFIntoXKTModel
                                                                                                                        • -
                                                                                                                        • FparseGLTFIntoXKTModel
                                                                                                                        • FparseGLTFJSONIntoXKTModel
                                                                                                                        • FparseIFCIntoXKTModel
                                                                                                                        • FparseLASIntoXKTModel
                                                                                                                        • @@ -375,13 +375,33 @@

                                                                                                                          Usage

                                                                                                                          parseCityJSONIntoXKTModel(params: Object): Promise
                                                                                                                          +          convert2xkt(): Promise<number>
                                                                                                                                   

                                                                                                                          -

                                                                                                                          Parses a CityJSON model into an XKTModel.

                                                                                                                          +

                                                                                                                          Converts model files into xeokit's native XKT format.

                                                                                                                          +

                                                                                                                          Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.

                                                                                                                          +

                                                                                                                          Only bundled in xeokit-convert.cjs.js.

                                                                                                                          +

                                                                                                                          Usage

                                                                                                                          @param {Object} params Conversion parameters. +@param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the +caller the choice of whether to use the Browser or NodeJS version. +@param {*} [params.configs] Configurations. +@param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative tosource. +@param {Function} [params.outputXKTModel] Callback to collect theXKTModel that is internally build by this method. +@param {Function} [params.outputXKT] Callback to collect XKT file data. +@param {String[]} [params.includeTypes] Option to only convert objects of these types. +@param {String[]} [params.excludeTypes] Option to never convert objects of these types. +@param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided. +@param {Function} [params.outputStats] Callback to collect statistics. +@param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis "up", if necessary. Applies to CityJSON and LAS/LAZ models. +@param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false, +will automatically "expand" all reused geometries into duplicate copies. This has the drawback of increasing the XKT +file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model +has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are +shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a +pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).

                                                                                                                          @@ -404,13 +424,13 @@

                                                                                                                          Usage

                                                                                                                          parseGLTFIntoXKTModel(params: Object): Promise
                                                                                                                          +          parseCityJSONIntoXKTModel(params: Object): Promise
                                                                                                                                   

                                                                                                                          -

                                                                                                                          Parses glTF into an XKTModel, supporting .glb and textures.

                                                                                                                          +

                                                                                                                          Parses a CityJSON model into an XKTModel.

                                                                                                                          @@ -2092,53 +2112,50 @@

                                                                                                                          Return:

                                                                                                                          -

                                                                                                                          +

                                                                                                                          public - parseCityJSONIntoXKTModel(params: Object): Promise + convert2xkt(): Promise<number> - source + source

                                                                                                                          -
                                                                                                                          import {parseCityJSONIntoXKTModel} from '@xeokit/xeokit-convert/src/parsers/parseCityJSONIntoXKTModel.js'
                                                                                                                          + -

                                                                                                                          Parses a CityJSON model into an XKTModel.

                                                                                                                          -

                                                                                                                          CityJSON is a JSON-based encoding for a subset of the CityGML data model (version 2.0.0), -which is an open standardised data model and exchange format to store digital 3D models of cities and -landscapes. CityGML is an official standard of the Open Geospatial Consortium.

                                                                                                                          -

                                                                                                                          This converter function supports most of the CityJSON 1.0.2 Specification, -with the following limitations:

                                                                                                                          -
                                                                                                                            -
                                                                                                                          • Does not (yet) support CityJSON semantics for geometry primitives.
                                                                                                                          • -
                                                                                                                          • Does not (yet) support textured geometries.
                                                                                                                          • -
                                                                                                                          • Does not (yet) support geometry templates.
                                                                                                                          • -
                                                                                                                          • When the CityJSON file provides multiple themes for a geometry, then we parse only the first of the provided themes for that geometry.
                                                                                                                          • -
                                                                                                                          -

                                                                                                                          Usage

                                                                                                                          In the example below we'll create an XKTModel, then load a CityJSON model into it.

                                                                                                                          -
                                                                                                                          utils.loadJSON("./models/cityjson/DenHaag.json", async (data) => {
                                                                                                                          -
                                                                                                                          -    const xktModel = new XKTModel();
                                                                                                                          -
                                                                                                                          -    parseCityJSONIntoXKTModel({
                                                                                                                          -         data,
                                                                                                                          -         xktModel,
                                                                                                                          -         log: (msg) => { console.log(msg); }
                                                                                                                          -    }).then(()=>{
                                                                                                                          -       xktModel.finalize();
                                                                                                                          -    },
                                                                                                                          -    (msg) => {
                                                                                                                          -        console.error(msg);
                                                                                                                          -    });
                                                                                                                          -});
                                                                                                                          -
                                                                                                                          +

                                                                                                                          Converts model files into xeokit's native XKT format.

                                                                                                                          +

                                                                                                                          Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.

                                                                                                                          +

                                                                                                                          Only bundled in xeokit-convert.cjs.js.

                                                                                                                          +

                                                                                                                          Usage

                                                                                                                          @param {Object} params Conversion parameters. +@param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the +caller the choice of whether to use the Browser or NodeJS version. +@param {*} [params.configs] Configurations. +@param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative tosource. +@param {Function} [params.outputXKTModel] Callback to collect theXKTModelthat is internally build by this method. +@param {Function} [params.outputXKT] Callback to collect XKT file data. +@param {String[]} [params.includeTypes] Option to only convert objects of these types. +@param {String[]} [params.excludeTypes] Option to never convert objects of these types. +@param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided. +@param {Function} [params.outputStats] Callback to collect statistics. +@param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis "up", if necessary. Applies to CityJSON and LAS/LAZ models. +@param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false, +will automatically "expand" all reused geometries into duplicate copies. This has the drawback of increasing the XKT +file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model +has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are +shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a +pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc). +@param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works forglTFmodels. +@param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore +geometry normals, and the modelwill rely on the xeokitViewerto automatically generate them. This has +the limitation that the normals will be face-aligned, and therefore theViewer will only be able to render +a flat-shaded non-PBR representation of the model.

                                                                                                                          @@ -2151,52 +2168,19 @@

                                                                                                                          Params:

                                                                                                                          - - params - Object - -

                                                                                                                          Parsing params.

                                                                                                                          - - - - params.data - Object - -

                                                                                                                          CityJSON data.

                                                                                                                          - - - - params.xktModel - XKTModel - -

                                                                                                                          XKTModel to parse into.

                                                                                                                          - - - - params.center - boolean + + params.minTileSize + Number
                                                                                                                          • optional
                                                                                                                          • -
                                                                                                                          • default: false
                                                                                                                          -

                                                                                                                          Set true to center the CityJSON vertex positions to [0,0,0]. This is applied before the transformation matrix, if specified.

                                                                                                                          - - - - params.transform - Boolean -
                                                                                                                          • optional
                                                                                                                          -

                                                                                                                          4x4 transformation matrix to transform CityJSON vertex positions. Use this to rotate, translate and scale them if neccessary.

                                                                                                                          - - - - params.stats - Object -
                                                                                                                          • optional
                                                                                                                          -

                                                                                                                          Collects statistics.

                                                                                                                          +
                                                                                                                        • default: 200
                                                                                                                        +

                                                                                                                        Minimum RTC coordinate tile size. Set this to a value between 100 and 10000, +depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close +to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger.

                                                                                                                        params.log - function + Function
                                                                                                                        • optional

                                                                                                                        Logging callback.

                                                                                                                        @@ -2211,9 +2195,8 @@

                                                                                                                        Return:

                                                                                                                        - - + +
                                                                                                                        Promise

                                                                                                                        Resolves when CityJSON has been parsed.

                                                                                                                        -
                                                                                                                        Promise<number>
                                                                                                                        @@ -2237,35 +2220,42 @@

                                                                                                                        Return:

                                                                                                                        -

                                                                                                                        +

                                                                                                                        public - parseGLTFIntoXKTModel(params: Object): Promise + parseCityJSONIntoXKTModel(params: Object): Promise - source + source

                                                                                                                        - +
                                                                                                                        import {parseCityJSONIntoXKTModel} from '@xeokit/xeokit-convert/src/parsers/parseCityJSONIntoXKTModel.js'
                                                                                                                        -

                                                                                                                        Parses glTF into an XKTModel, supporting .glb and textures.

                                                                                                                        +

                                                                                                                        Parses a CityJSON model into an XKTModel.

                                                                                                                        +

                                                                                                                        CityJSON is a JSON-based encoding for a subset of the CityGML data model (version 2.0.0), +which is an open standardised data model and exchange format to store digital 3D models of cities and +landscapes. CityGML is an official standard of the Open Geospatial Consortium.

                                                                                                                        +

                                                                                                                        This converter function supports most of the CityJSON 1.0.2 Specification, +with the following limitations:

                                                                                                                          -
                                                                                                                        • Supports .glb and textures
                                                                                                                        • -
                                                                                                                        • For a lightweight glTF JSON parser that ignores textures, see parseGLTFJSONIntoXKTModel.
                                                                                                                        • +
                                                                                                                        • Does not (yet) support CityJSON semantics for geometry primitives.
                                                                                                                        • +
                                                                                                                        • Does not (yet) support textured geometries.
                                                                                                                        • +
                                                                                                                        • Does not (yet) support geometry templates.
                                                                                                                        • +
                                                                                                                        • When the CityJSON file provides multiple themes for a geometry, then we parse only the first of the provided themes for that geometry.
                                                                                                                        -

                                                                                                                        Usage

                                                                                                                        In the example below we'll create an XKTModel, then load a binary glTF model into it.

                                                                                                                        -
                                                                                                                        utils.loadArraybuffer("../assets/models/gltf/HousePlan/glTF-Binary/HousePlan.glb", async (data) => {
                                                                                                                        +

                                                                                                                        Usage

                                                                                                                        In the example below we'll create an XKTModel, then load a CityJSON model into it.

                                                                                                                        +
                                                                                                                        utils.loadJSON("./models/cityjson/DenHaag.json", async (data) => {
                                                                                                                         
                                                                                                                             const xktModel = new XKTModel();
                                                                                                                         
                                                                                                                        -    parseGLTFIntoXKTModel({
                                                                                                                        +    parseCityJSONIntoXKTModel({
                                                                                                                                  data,
                                                                                                                                  xktModel,
                                                                                                                                  log: (msg) => { console.log(msg); }
                                                                                                                        @@ -2293,28 +2283,14 @@ 

                                                                                                                        Params:

                                                                                                                        params Object -

                                                                                                                        Parsing parameters.

                                                                                                                        +

                                                                                                                        Parsing params.

                                                                                                                        params.data - ArrayBuffer - -

                                                                                                                        The glTF.

                                                                                                                        - - - - params.baseUri - String -
                                                                                                                        • optional
                                                                                                                        -

                                                                                                                        The base URI used to load this glTF, if any. For resolving relative uris to linked resources.

                                                                                                                        - - - - params.metaModelData Object -
                                                                                                                        • optional
                                                                                                                        -

                                                                                                                        Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly.

                                                                                                                        + +

                                                                                                                        CityJSON data.

                                                                                                                        @@ -2325,22 +2301,18 @@

                                                                                                                        Params:

                                                                                                                        - params.includeTextures - Boolean + params.center + boolean
                                                                                                                        • optional
                                                                                                                        • -
                                                                                                                        • default: true
                                                                                                                        -

                                                                                                                        Whether to parse textures.

                                                                                                                        +
                                                                                                                      • default: false
                                                                                                                      +

                                                                                                                      Set true to center the CityJSON vertex positions to [0,0,0]. This is applied before the transformation matrix, if specified.

                                                                                                                      - params.includeNormals + params.transform Boolean -
                                                                                                                      • optional
                                                                                                                      • -
                                                                                                                      • default: true
                                                                                                                      -

                                                                                                                      Whether to parse normals. When false, the parser will ignore the glTF -geometry normals, and the glTF data will rely on the xeokit Viewer to automatically generate them. This has -the limitation that the normals will be face-aligned, and therefore the Viewer will only be able to render -a flat-shaded non-PBR representation of the glTF.

                                                                                                                      +
                                                                                                                      • optional
                                                                                                                      +

                                                                                                                      4x4 transformation matrix to transform CityJSON vertex positions. Use this to rotate, translate and scale them if neccessary.

                                                                                                                      @@ -2368,7 +2340,7 @@

                                                                                                                      Return:

                                                                                                                      Promise -

                                                                                                                      Resolves when glTF has been parsed.

                                                                                                                      +

                                                                                                                      Resolves when CityJSON has been parsed.

                                                                                                                      diff --git a/docs/identifiers.html b/docs/identifiers.html index 89074ac..1bdf10e 100644 --- a/docs/identifiers.html +++ b/docs/identifiers.html @@ -30,6 +30,7 @@
                                                                                                                      • Fconvert2xkt
                                                                                                                      • +
                                                                                                                      • Fconvert2xkt
                                                                                                                      • VXKT_INFO
                                                                                                                      • VClampToEdgeWrapping
                                                                                                                      • VGIFMediaType
                                                                                                                      • @@ -67,7 +68,6 @@
                                                                                                                      • FbuildVectorTextGeometry
                                                                                                                      • parsersFparseCityJSONIntoXKTModel
                                                                                                                      • FparseGLTFIntoXKTModel
                                                                                                                      • -
                                                                                                                      • FparseGLTFIntoXKTModel
                                                                                                                      • FparseGLTFJSONIntoXKTModel
                                                                                                                      • FparseIFCIntoXKTModel
                                                                                                                      • FparseLASIntoXKTModel
                                                                                                                      • @@ -141,6 +141,55 @@

                                                                                                                        Usage

                                                                                                                        
                                                                                                                        +    
                                                                                                                        +    
                                                                                                                        +      
                                                                                                                        +

                                                                                                                        + F + + + convert2xkt(): Promise<number> +

                                                                                                                        +
                                                                                                                        +
                                                                                                                        + + +

                                                                                                                        Converts model files into xeokit's native XKT format.

                                                                                                                        +

                                                                                                                        Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.

                                                                                                                        +

                                                                                                                        Only bundled in xeokit-convert.cjs.js.

                                                                                                                        +

                                                                                                                        Usage

                                                                                                                        @param {Object} params Conversion parameters. +@param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the +caller the choice of whether to use the Browser or NodeJS version. +@param {*} [params.configs] Configurations. +@param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative tosource. +@param {Function} [params.outputXKTModel] Callback to collect theXKTModel that is internally build by this method. +@param {Function} [params.outputXKT] Callback to collect XKT file data. +@param {String[]} [params.includeTypes] Option to only convert objects of these types. +@param {String[]} [params.excludeTypes] Option to never convert objects of these types. +@param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided. +@param {Function} [params.outputStats] Callback to collect statistics. +@param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis "up", if necessary. Applies to CityJSON and LAS/LAZ models. +@param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false, +will automatically "expand" all reused geometries into duplicate copies. This has the drawback of increasing the XKT +file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model +has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are +shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a +pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).

                                                                                                                        +
                                                                                                                        +
                                                                                                                        + + + + + + + + + public + + + @@ -1252,35 +1301,6 @@

                                                                                                                        parsers

                                                                                                                        - - - -
                                                                                                                        -

                                                                                                                        - F - - - parseGLTFIntoXKTModel(params: Object): Promise -

                                                                                                                        -
                                                                                                                        -
                                                                                                                        - - -

                                                                                                                        Parses glTF into an XKTModel, supporting .glb and textures.

                                                                                                                        -
                                                                                                                        -
                                                                                                                        - - - - - - - - - public - - - diff --git a/docs/index.html b/docs/index.html index 4cf19f1..3e3caa6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -30,6 +30,7 @@
                                                                                                                        • Fconvert2xkt
                                                                                                                        • +
                                                                                                                        • Fconvert2xkt
                                                                                                                        • VXKT_INFO
                                                                                                                        • VClampToEdgeWrapping
                                                                                                                        • VGIFMediaType
                                                                                                                        • @@ -67,7 +68,6 @@
                                                                                                                        • FbuildVectorTextGeometry
                                                                                                                        • parsersFparseCityJSONIntoXKTModel
                                                                                                                        • FparseGLTFIntoXKTModel
                                                                                                                        • -
                                                                                                                        • FparseGLTFIntoXKTModel
                                                                                                                        • FparseGLTFJSONIntoXKTModel
                                                                                                                        • FparseIFCIntoXKTModel
                                                                                                                        • FparseLASIntoXKTModel
                                                                                                                        • diff --git a/docs/index.json b/docs/index.json index 57b6c69..3b9afc1 100644 --- a/docs/index.json +++ b/docs/index.json @@ -569,7 +569,7 @@ "name": "src/XKTModel/KDNode.js", "content": "/**\n * A kd-Tree node, used internally by {@link XKTModel}.\n *\n * @private\n */\nclass KDNode {\n\n /**\n * Create a KDNode with an axis-aligned 3D World-space boundary.\n */\n constructor(aabb) {\n\n /**\n * The axis-aligned 3D World-space boundary of this KDNode.\n *\n * @type {Float64Array}\n */\n this.aabb = aabb;\n\n /**\n * The {@link XKTEntity}s within this KDNode.\n */\n this.entities = null;\n\n /**\n * The left child KDNode.\n */\n this.left = null;\n\n /**\n * The right child KDNode.\n */\n this.right = null;\n }\n}\n\nexport {KDNode};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/KDNode.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/KDNode.js", "access": "public", "description": null, "lineNumber": 1 @@ -676,7 +676,7 @@ "name": "src/XKTModel/MockXKTModel.js", "content": "import {math} from \"../lib/math.js\";\nimport {geometryCompression} from \"./lib/geometryCompression.js\";\nimport {buildEdgeIndices} from \"./lib/buildEdgeIndices.js\";\n\nconst tempVec4a = math.vec4([0, 0, 0, 1]);\nconst tempVec4b = math.vec4([0, 0, 0, 1]);\nconst tempMat4 = math.mat4();\nconst tempMat4b = math.mat4();\n\n/**\n * A mock {@link XKTModel} that creates {@link Mesh}es and {@link Geometry}s to visualize the output of {@link parseGLTFIntoXKTModel}.\n *\n * @private\n */\nclass MockXKTModel {\n\n /**\n *\n * @param cfg\n */\n constructor(cfg={}) {\n\n if (!cfg.handlePrimitive) {\n throw \"Expected config: handlePrimitive\";\n }\n\n if (!cfg.handleEntity) {\n throw \"Expected config: handleEntity\";\n }\n\n this._handlePrimitive = cfg.handlePrimitive;\n this._handleEntity = cfg.handleEntity;\n\n this.geometries = {};\n }\n\n createGeometry(params) {\n\n const geometryId = params.geometryId;\n const primitiveType = params.primitiveType;\n const reused = params.reused;\n const primitiveModelingMatrix = params.primitiveModelingMatrix ? params.primitiveModelingMatrix.slice : math.identityMat4();\n const color = params.color;\n const opacity = params.opacity;\n const positions = params.positions.slice();\n const normals = params.normals.slice();\n const indices = params.indices;\n\n const positions2 = positions.slice();\n\n const edgeIndices = buildEdgeIndices(positions, indices, null, 10);\n\n if (!reused) {\n\n // Bake single-use geometry's positions into World-space\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n tempVec4a[0] = positions[i + 0];\n tempVec4a[1] = positions[i + 1];\n tempVec4a[2] = positions[i + 2];\n\n math.transformPoint4(primitiveModelingMatrix, tempVec4a, tempVec4b);\n\n positions2[i + 0] = tempVec4b[0];\n positions2[i + 1] = tempVec4b[1];\n positions2[i + 2] = tempVec4b[2];\n }\n }\n\n const modelNormalMatrix = math.inverseMat4(math.transposeMat4(primitiveModelingMatrix, tempMat4b), tempMat4);\n const normalsOctEncoded = new Int8Array(normals.length);\n\n geometryCompression.transformAndOctEncodeNormals(modelNormalMatrix, normals, normals.length, normalsOctEncoded, 0);\n\n const primitive = new VBOGeometry(this.scene, {\n id: geometryId,\n primitive: \"triangles\",\n positions: positions2,\n normals: normals,\n indices: indices,\n edgeIndices: edgeIndices\n });\n\n this.geometries[geometryId] = primitive;\n }\n\n createEntity(params) {\n\n const entityId = params.entityId;\n const entityModelingMatrix = params.entityModelingMatrix ? params.entityModelingMatrix.slice() : math.identityMat4();\n const primitiveIds = params.primitiveIds;\n\n for (let primitiveIdIdx = 0, primitiveIdLen = primitiveIds.length; primitiveIdIdx < primitiveIdLen; primitiveIdIdx++) {\n\n const geometryId = primitiveIds[primitiveIdIdx];\n const primitive = this.geometries[geometryId];\n\n if (!primitive) {\n console.error(\"primitive not found: \" + geometryId);\n continue;\n }\n\n new Mesh(this.scene, {\n id: entityId,\n geometry: primitive,\n matrix: entityModelingMatrix,\n edges: true\n });\n }\n }\n\n finalize() {\n }\n}\n\nexport {MockXKTModel};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/MockXKTModel.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/MockXKTModel.js", "access": "public", "description": null, "lineNumber": 1 @@ -927,7 +927,7 @@ "name": "src/XKTModel/XKTEntity.js", "content": "import {math} from \"../lib/math.js\";\n\n/**\n * An object within an {@link XKTModel}.\n *\n * * Created by {@link XKTModel#createEntity}\n * * Stored in {@link XKTModel#entities} and {@link XKTModel#entitiesList}\n * * Has one or more {@link XKTMesh}s, each having an {@link XKTGeometry}\n *\n * @class XKTEntity\n */\nclass XKTEntity {\n\n /**\n * @private\n * @param entityId\n * @param meshes\n */\n constructor(entityId, meshes) {\n\n /**\n * Unique ID of this ````XKTEntity```` in {@link XKTModel#entities}.\n *\n * For a BIM model, this will be an IFC product ID.\n *\n * We can also use {@link XKTModel#createMetaObject} to create an {@link XKTMetaObject} to specify metadata for\n * this ````XKTEntity````. To associate the {@link XKTMetaObject} with our {@link XKTEntity}, we give\n * {@link XKTMetaObject#metaObjectId} the same value as {@link XKTEntity#entityId}.\n *\n * @type {String}\n */\n this.entityId = entityId;\n\n /**\n * Index of this ````XKTEntity```` in {@link XKTModel#entitiesList}.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * @type {Number}\n */\n this.entityIndex = null;\n\n /**\n * A list of {@link XKTMesh}s that indicate which {@link XKTGeometry}s are used by this Entity.\n *\n * @type {XKTMesh[]}\n */\n this.meshes = meshes;\n\n /**\n * World-space axis-aligned bounding box (AABB) that encloses the {@link XKTGeometry#positions} of\n * the {@link XKTGeometry}s that are used by this ````XKTEntity````.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * @type {Float32Array}\n */\n this.aabb = math.AABB3();\n\n /**\n * Indicates if this ````XKTEntity```` shares {@link XKTGeometry}s with other {@link XKTEntity}'s.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * Note that when an ````XKTEntity```` shares ````XKTGeometrys````, it shares **all** of its ````XKTGeometrys````. An ````XKTEntity````\n * never shares only some of its ````XKTGeometrys```` - it always shares either the whole set or none at all.\n *\n * @type {Boolean}\n */\n this.hasReusedGeometries = false;\n }\n}\n\nexport {XKTEntity};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/XKTEntity.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/XKTEntity.js", "access": "public", "description": null, "lineNumber": 1 @@ -1090,7 +1090,7 @@ "name": "src/XKTModel/XKTGeometry.js", "content": "/**\n * An element of reusable geometry within an {@link XKTModel}.\n *\n * * Created by {@link XKTModel#createGeometry}\n * * Stored in {@link XKTModel#geometries} and {@link XKTModel#geometriesList}\n * * Referenced by {@link XKTMesh}s, which belong to {@link XKTEntity}s\n *\n * @class XKTGeometry\n */\nclass XKTGeometry {\n\n /**\n * @private\n * @param {*} cfg Configuration for the XKTGeometry.\n * @param {Number} cfg.geometryId Unique ID of the geometry in {@link XKTModel#geometries}.\n * @param {String} cfg.primitiveType Type of this geometry - \"triangles\", \"points\" or \"lines\" so far.\n * @param {Number} cfg.geometryIndex Index of this XKTGeometry in {@link XKTModel#geometriesList}.\n * @param {Float64Array} cfg.positions Non-quantized 3D vertex positions.\n * @param {Float32Array} cfg.normals Non-compressed vertex normals.\n * @param {Uint8Array} cfg.colorsCompressed Unsigned 8-bit integer RGBA vertex colors.\n * @param {Float32Array} cfg.uvs Non-compressed vertex UV coordinates.\n * @param {Uint32Array} cfg.indices Indices to organize the vertex positions and normals into triangles.\n * @param {Uint32Array} cfg.edgeIndices Indices to organize the vertex positions into edges.\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTGeometry in {@link XKTModel#geometries}.\n *\n * @type {Number}\n */\n this.geometryId = cfg.geometryId;\n\n /**\n * The type of primitive - \"triangles\" | \"points\" | \"lines\".\n *\n * @type {String}\n */\n this.primitiveType = cfg.primitiveType;\n\n /**\n * Index of this XKTGeometry in {@link XKTModel#geometriesList}.\n *\n * @type {Number}\n */\n this.geometryIndex = cfg.geometryIndex;\n\n /**\n * The number of {@link XKTMesh}s that reference this XKTGeometry.\n *\n * @type {Number}\n */\n this.numInstances = 0;\n\n /**\n * Non-quantized 3D vertex positions.\n *\n * Defined for all primitive types.\n *\n * @type {Float64Array}\n */\n this.positions = cfg.positions;\n\n /**\n * Quantized vertex positions.\n *\n * Defined for all primitive types.\n *\n * This array is later created from {@link XKTGeometry#positions} by {@link XKTModel#finalize}.\n *\n * @type {Uint16Array}\n */\n this.positionsQuantized = new Uint16Array(cfg.positions.length);\n\n /**\n * Non-compressed 3D vertex normals.\n *\n * Defined only for triangle primitives. Can be null if we want xeokit to auto-generate them. Ignored for points and lines.\n *\n * @type {Float32Array}\n */\n this.normals = cfg.normals;\n\n /**\n * Compressed vertex normals.\n *\n * Defined only for triangle primitives. Ignored for points and lines.\n *\n * This array is later created from {@link XKTGeometry#normals} by {@link XKTModel#finalize}.\n *\n * Will be null if {@link XKTGeometry#normals} is also null.\n *\n * @type {Int8Array}\n */\n this.normalsOctEncoded = null;\n\n /**\n * Compressed RGBA vertex colors.\n *\n * Defined only for point primitives. Ignored for triangles and lines.\n *\n * @type {Uint8Array}\n */\n this.colorsCompressed = cfg.colorsCompressed;\n\n /**\n * Non-compressed vertex UVs.\n *\n * @type {Float32Array}\n */\n this.uvs = cfg.uvs;\n\n /**\n * Compressed vertex UVs.\n *\n * @type {Uint16Array}\n */\n this.uvsCompressed = cfg.uvsCompressed;\n\n /**\n * Indices that organize the vertex positions and normals as triangles.\n *\n * Defined only for triangle and lines primitives. Ignored for points.\n *\n * @type {Uint32Array}\n */\n this.indices = cfg.indices;\n\n /**\n * Indices that organize the vertex positions as edges.\n *\n * Defined only for triangle primitives. Ignored for points and lines.\n *\n * @type {Uint32Array}\n */\n this.edgeIndices = cfg.edgeIndices;\n\n /**\n * When {@link XKTGeometry#primitiveType} is \"triangles\", this is ````true```` when this geometry is a watertight mesh.\n *\n * Defined only for triangle primitives. Ignored for points and lines.\n *\n * Set by {@link XKTModel#finalize}.\n *\n * @type {boolean}\n */\n this.solid = false;\n }\n\n /**\n * Convenience property that is ````true```` when {@link XKTGeometry#numInstances} is greater that one.\n * @returns {boolean}\n */\n get reused() {\n return (this.numInstances > 1);\n }\n}\n\nexport {XKTGeometry};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/XKTGeometry.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/XKTGeometry.js", "access": "public", "description": null, "lineNumber": 1 @@ -1536,7 +1536,7 @@ "name": "src/XKTModel/XKTMesh.js", "content": "/**\n * Represents the usage of a {@link XKTGeometry} by an {@link XKTEntity}.\n *\n * * Created by {@link XKTModel#createEntity}\n * * Stored in {@link XKTEntity#meshes} and {@link XKTModel#meshesList}\n * * Has an {@link XKTGeometry}, and an optional {@link XKTTextureSet}, both of which it can share with other {@link XKTMesh}es\n * * Has {@link XKTMesh#color}, {@link XKTMesh#opacity}, {@link XKTMesh#metallic} and {@link XKTMesh#roughness} PBR attributes\n * @class XKTMesh\n */\nclass XKTMesh {\n\n /**\n * @private\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTMesh in {@link XKTModel#meshes}.\n *\n * @type {Number}\n */\n this.meshId = cfg.meshId;\n\n /**\n * Index of this XKTMesh in {@link XKTModel#meshesList};\n *\n * @type {Number}\n */\n this.meshIndex = cfg.meshIndex;\n\n /**\n * The 4x4 modeling transform matrix.\n *\n * Transform is relative to the center of the {@link XKTTile} that contains this XKTMesh's {@link XKTEntity},\n * which is given in {@link XKTMesh#entity}.\n *\n * When the ````XKTEntity```` shares its {@link XKTGeometry}s with other ````XKTEntity````s, this matrix is used\n * to transform this XKTMesh's XKTGeometry into World-space. When this XKTMesh does not share its ````XKTGeometry````,\n * then this matrix is ignored.\n *\n * @type {Number[]}\n */\n this.matrix = cfg.matrix;\n\n /**\n * The instanced {@link XKTGeometry}.\n *\n * @type {XKTGeometry}\n */\n this.geometry = cfg.geometry;\n\n /**\n * RGB color of this XKTMesh.\n *\n * @type {Float32Array}\n */\n this.color = cfg.color || new Float32Array([1, 1, 1]);\n\n /**\n * PBR metallness of this XKTMesh.\n *\n * @type {Number}\n */\n this.metallic = (cfg.metallic !== null && cfg.metallic !== undefined) ? cfg.metallic : 0;\n\n /**\n * PBR roughness of this XKTMesh.\n * The {@link XKTTextureSet} that defines the appearance of this XKTMesh.\n *\n * @type {Number}\n * @type {XKTTextureSet}\n */\n this.roughness = (cfg.roughness !== null && cfg.roughness !== undefined) ? cfg.roughness : 1;\n\n /**\n * Opacity of this XKTMesh.\n *\n * @type {Number}\n */\n this.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? cfg.opacity : 1.0;\n\n /**\n * The {@link XKTTextureSet} that defines the appearance of this XKTMesh.\n *\n * @type {XKTTextureSet}\n */\n this.textureSet = cfg.textureSet;\n\n /**\n * The owner {@link XKTEntity}.\n *\n * Set by {@link XKTModel#createEntity}.\n *\n * @type {XKTEntity}\n */\n this.entity = null; // Set after instantiation, when the Entity is known\n }\n}\n\nexport {XKTMesh};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/XKTMesh.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/XKTMesh.js", "access": "public", "description": null, "lineNumber": 1 @@ -1772,7 +1772,7 @@ "name": "src/XKTModel/XKTMetaObject.js", "content": "/**\n * A meta object within an {@link XKTModel}.\n *\n * These are plugged together into a parent-child hierarchy to represent structural\n * metadata for the {@link XKTModel}.\n *\n * The leaf XKTMetaObjects are usually associated with\n * an {@link XKTEntity}, which they do so by sharing the same ID,\n * ie. where {@link XKTMetaObject#metaObjectId} == {@link XKTEntity#entityId}.\n *\n * * Created by {@link XKTModel#createMetaObject}\n * * Stored in {@link XKTModel#metaObjects} and {@link XKTModel#metaObjectsList}\n * * Has an ID, a type, and a human-readable name\n * * May have a parent {@link XKTMetaObject}\n * * When no children, is usually associated with an {@link XKTEntity}\n *\n * @class XKTMetaObject\n */\nclass XKTMetaObject {\n\n /**\n * @private\n * @param metaObjectId\n * @param propertySetIds\n * @param metaObjectType\n * @param metaObjectName\n * @param parentMetaObjectId\n */\n constructor(metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId) {\n\n /**\n * Unique ID of this ````XKTMetaObject```` in {@link XKTModel#metaObjects}.\n *\n * For a BIM model, this will be an IFC product ID.\n *\n * If this is a leaf XKTMetaObject, where it is not a parent to any other XKTMetaObject,\n * then this will be equal to the ID of an {@link XKTEntity} in {@link XKTModel#entities},\n * ie. where {@link XKTMetaObject#metaObjectId} == {@link XKTEntity#entityId}.\n *\n * @type {String}\n */\n this.metaObjectId = metaObjectId;\n\n /**\n * Unique ID of one or more property sets that contains additional metadata about this\n * {@link XKTMetaObject}. The property sets can be stored in an external system, or\n * within the {@link XKTModel}, as {@link XKTPropertySet}s within {@link XKTModel#propertySets}.\n *\n * @type {String[]}\n */\n this.propertySetIds = propertySetIds;\n\n /**\n * Indicates the XKTMetaObject meta object type.\n *\n * This defaults to \"default\".\n *\n * @type {string}\n */\n this.metaObjectType = metaObjectType;\n\n /**\n * Indicates the XKTMetaObject meta object name.\n *\n * This defaults to {@link XKTMetaObject#metaObjectId}.\n *\n * @type {string}\n */\n this.metaObjectName = metaObjectName;\n\n /**\n * The parent XKTMetaObject, if any.\n *\n * Will be null if there is no parent.\n *\n * @type {String}\n */\n this.parentMetaObjectId = parentMetaObjectId;\n }\n}\n\nexport {XKTMetaObject};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/XKTMetaObject.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/XKTMetaObject.js", "access": "public", "description": null, "lineNumber": 1 @@ -1965,7 +1965,7 @@ "name": "src/XKTModel/XKTModel.js", "content": "import {math} from \"../lib/math.js\";\nimport {geometryCompression} from \"./lib/geometryCompression.js\";\nimport {buildEdgeIndices} from \"./lib/buildEdgeIndices.js\";\nimport {isTriangleMeshSolid} from \"./lib/isTriangleMeshSolid.js\";\n\nimport {XKTMesh} from './XKTMesh.js';\nimport {XKTGeometry} from './XKTGeometry.js';\nimport {XKTEntity} from './XKTEntity.js';\nimport {XKTTile} from './XKTTile.js';\nimport {KDNode} from \"./KDNode.js\";\nimport {XKTMetaObject} from \"./XKTMetaObject.js\";\nimport {XKTPropertySet} from \"./XKTPropertySet.js\";\nimport {mergeVertices} from \"../lib/mergeVertices.js\";\nimport {XKT_INFO} from \"../XKT_INFO.js\";\nimport {XKTTexture} from \"./XKTTexture\";\nimport {XKTTextureSet} from \"./XKTTextureSet\";\nimport {encode, load} from \"@loaders.gl/core\";\nimport {KTX2BasisWriter} from \"@loaders.gl/textures\";\nimport {ImageLoader} from '@loaders.gl/images';\n\nconst tempVec4a = math.vec4([0, 0, 0, 1]);\nconst tempVec4b = math.vec4([0, 0, 0, 1]);\n\nconst tempMat4 = math.mat4();\nconst tempMat4b = math.mat4();\n\nconst kdTreeDimLength = new Float64Array(3);\n\n// XKT texture types\n\nconst COLOR_TEXTURE = 0;\nconst METALLIC_ROUGHNESS_TEXTURE = 1;\nconst NORMALS_TEXTURE = 2;\nconst EMISSIVE_TEXTURE = 3;\nconst OCCLUSION_TEXTURE = 4;\n\n// KTX2 encoding options for each texture type\n\nconst TEXTURE_ENCODING_OPTIONS = {}\nTEXTURE_ENCODING_OPTIONS[COLOR_TEXTURE] = {\n useSRGB: true,\n qualityLevel: 50,\n encodeUASTC: true,\n mipmaps: true\n};\nTEXTURE_ENCODING_OPTIONS[EMISSIVE_TEXTURE] = {\n useSRGB: true,\n encodeUASTC: true,\n qualityLevel: 10,\n mipmaps: false\n};\nTEXTURE_ENCODING_OPTIONS[METALLIC_ROUGHNESS_TEXTURE] = {\n useSRGB: false,\n encodeUASTC: true,\n qualityLevel: 50,\n mipmaps: true // Needed for GGX roughness shading\n};\nTEXTURE_ENCODING_OPTIONS[NORMALS_TEXTURE] = {\n useSRGB: false,\n encodeUASTC: true,\n qualityLevel: 10,\n mipmaps: false\n};\nTEXTURE_ENCODING_OPTIONS[OCCLUSION_TEXTURE] = {\n useSRGB: false,\n encodeUASTC: true,\n qualityLevel: 10,\n mipmaps: false\n};\n\n/**\n * A document model that represents the contents of an .XKT file.\n *\n * * An XKTModel contains {@link XKTTile}s, which spatially subdivide the model into axis-aligned, box-shaped regions.\n * * Each {@link XKTTile} contains {@link XKTEntity}s, which represent the objects within its region.\n * * Each {@link XKTEntity} has {@link XKTMesh}s, which each have a {@link XKTGeometry}. Each {@link XKTGeometry} can be shared by multiple {@link XKTMesh}s.\n * * Import models into an XKTModel using {@link parseGLTFJSONIntoXKTModel}, {@link parseIFCIntoXKTModel}, {@link parseCityJSONIntoXKTModel} etc.\n * * Build an XKTModel programmatically using {@link XKTModel#createGeometry}, {@link XKTModel#createMesh} and {@link XKTModel#createEntity}.\n * * Serialize an XKTModel to an ArrayBuffer using {@link writeXKTModelToArrayBuffer}.\n *\n * ## Usage\n *\n * See [main docs page](/docs/#javascript-api) for usage examples.\n *\n * @class XKTModel\n */\nclass XKTModel {\n\n /**\n * Constructs a new XKTModel.\n *\n * @param {*} [cfg] Configuration\n * @param {Number} [cfg.edgeThreshold=10]\n * @param {Number} [cfg.minTileSize=500]\n */\n constructor(cfg = {}) {\n\n /**\n * The model's ID, if available.\n *\n * Will be \"default\" by default.\n *\n * @type {String}\n */\n this.modelId = cfg.modelId || \"default\";\n\n /**\n * The project ID, if available.\n *\n * Will be an empty string by default.\n *\n * @type {String}\n */\n this.projectId = cfg.projectId || \"\";\n\n /**\n * The revision ID, if available.\n *\n * Will be an empty string by default.\n *\n * @type {String}\n */\n this.revisionId = cfg.revisionId || \"\";\n\n /**\n * The model author, if available.\n *\n * Will be an empty string by default.\n *\n * @property author\n * @type {String}\n */\n this.author = cfg.author || \"\";\n\n /**\n * The date the model was created, if available.\n *\n * Will be an empty string by default.\n *\n * @property createdAt\n * @type {String}\n */\n this.createdAt = cfg.createdAt || \"\";\n\n /**\n * The application that created the model, if available.\n *\n * Will be an empty string by default.\n *\n * @property creatingApplication\n * @type {String}\n */\n this.creatingApplication = cfg.creatingApplication || \"\";\n\n /**\n * The model schema version, if available.\n *\n * In the case of IFC, this could be \"IFC2x3\" or \"IFC4\", for example.\n *\n * Will be an empty string by default.\n *\n * @property schema\n * @type {String}\n */\n this.schema = cfg.schema || \"\";\n\n /**\n * The XKT format version.\n *\n * @property xktVersion;\n * @type {number}\n */\n this.xktVersion = XKT_INFO.xktVersion;\n\n /**\n *\n * @type {Number|number}\n */\n this.edgeThreshold = cfg.edgeThreshold || 10;\n\n /**\n * Minimum diagonal size of the boundary of an {@link XKTTile}.\n *\n * @type {Number|number}\n */\n this.minTileSize = cfg.minTileSize || 500;\n\n /**\n * Optional overall AABB that contains all the {@link XKTEntity}s we'll create in this model, if previously known.\n *\n * This is the AABB of a complete set of input files that are provided as a split-model set for conversion.\n *\n * This is used to help the {@link XKTTile.aabb}s within split models align neatly with each other, as we\n * build them with a k-d tree in {@link XKTModel#finalize}. Without this, the AABBs of the different parts\n * tend to misalign slightly, resulting in excess number of {@link XKTTile}s, which degrades memory and rendering\n * performance when the XKT is viewer in the xeokit Viewer.\n */\n this.modelAABB = cfg.modelAABB;\n\n /**\n * Map of {@link XKTPropertySet}s within this XKTModel, each mapped to {@link XKTPropertySet#propertySetId}.\n *\n * Created by {@link XKTModel#createPropertySet}.\n *\n * @type {{String:XKTPropertySet}}\n */\n this.propertySets = {};\n\n /**\n * {@link XKTPropertySet}s within this XKTModel.\n *\n * Each XKTPropertySet holds its position in this list in {@link XKTPropertySet#propertySetIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTPropertySet[]}\n */\n this.propertySetsList = [];\n\n /**\n * Map of {@link XKTMetaObject}s within this XKTModel, each mapped to {@link XKTMetaObject#metaObjectId}.\n *\n * Created by {@link XKTModel#createMetaObject}.\n *\n * @type {{String:XKTMetaObject}}\n */\n this.metaObjects = {};\n\n /**\n * {@link XKTMetaObject}s within this XKTModel.\n *\n * Each XKTMetaObject holds its position in this list in {@link XKTMetaObject#metaObjectIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTMetaObject[]}\n */\n this.metaObjectsList = [];\n\n /**\n * The positions of all shared {@link XKTGeometry}s are de-quantized using this singular\n * de-quantization matrix.\n *\n * This de-quantization matrix is generated from the collective Local-space boundary of the\n * positions of all shared {@link XKTGeometry}s.\n *\n * @type {Float32Array}\n */\n this.reusedGeometriesDecodeMatrix = new Float32Array(16);\n\n /**\n * Map of {@link XKTGeometry}s within this XKTModel, each mapped to {@link XKTGeometry#geometryId}.\n *\n * Created by {@link XKTModel#createGeometry}.\n *\n * @type {{Number:XKTGeometry}}\n */\n this.geometries = {};\n\n /**\n * List of {@link XKTGeometry}s within this XKTModel, in the order they were created.\n *\n * Each XKTGeometry holds its position in this list in {@link XKTGeometry#geometryIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTGeometry[]}\n */\n this.geometriesList = [];\n\n /**\n * Map of {@link XKTTexture}s within this XKTModel, each mapped to {@link XKTTexture#textureId}.\n *\n * Created by {@link XKTModel#createTexture}.\n *\n * @type {{Number:XKTTexture}}\n */\n this.textures = {};\n\n /**\n * List of {@link XKTTexture}s within this XKTModel, in the order they were created.\n *\n * Each XKTTexture holds its position in this list in {@link XKTTexture#textureIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTTexture[]}\n */\n this.texturesList = [];\n\n /**\n * Map of {@link XKTTextureSet}s within this XKTModel, each mapped to {@link XKTTextureSet#textureSetId}.\n *\n * Created by {@link XKTModel#createTextureSet}.\n *\n * @type {{Number:XKTTextureSet}}\n */\n this.textureSets = {};\n\n /**\n * List of {@link XKTTextureSet}s within this XKTModel, in the order they were created.\n *\n * Each XKTTextureSet holds its position in this list in {@link XKTTextureSet#textureSetIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTTextureSet[]}\n */\n this.textureSetsList = [];\n\n /**\n * Map of {@link XKTMesh}s within this XKTModel, each mapped to {@link XKTMesh#meshId}.\n *\n * Created by {@link XKTModel#createMesh}.\n *\n * @type {{Number:XKTMesh}}\n */\n this.meshes = {};\n\n /**\n * List of {@link XKTMesh}s within this XKTModel, in the order they were created.\n *\n * Each XKTMesh holds its position in this list in {@link XKTMesh#meshIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTMesh[]}\n */\n this.meshesList = [];\n\n /**\n * Map of {@link XKTEntity}s within this XKTModel, each mapped to {@link XKTEntity#entityId}.\n *\n * Created by {@link XKTModel#createEntity}.\n *\n * @type {{String:XKTEntity}}\n */\n this.entities = {};\n\n /**\n * {@link XKTEntity}s within this XKTModel.\n *\n * Each XKTEntity holds its position in this list in {@link XKTEntity#entityIndex}.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTEntity[]}\n */\n this.entitiesList = [];\n\n /**\n * {@link XKTTile}s within this XKTModel.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {XKTTile[]}\n */\n this.tilesList = [];\n\n /**\n * The axis-aligned 3D World-space boundary of this XKTModel.\n *\n * Created by {@link XKTModel#finalize}.\n *\n * @type {Float64Array}\n */\n this.aabb = math.AABB3();\n\n /**\n * Indicates if this XKTModel has been finalized.\n *\n * Set ````true```` by {@link XKTModel#finalize}.\n *\n * @type {boolean}\n */\n this.finalized = false;\n }\n\n /**\n * Creates an {@link XKTPropertySet} within this XKTModel.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {String} params.propertySetId Unique ID for the {@link XKTPropertySet}.\n * @param {String} [params.propertySetType=\"default\"] A meta type for the {@link XKTPropertySet}.\n * @param {String} [params.propertySetName] Human-readable name for the {@link XKTPropertySet}. Defaults to the ````propertySetId```` parameter.\n * @param {String[]} params.properties Properties for the {@link XKTPropertySet}.\n * @returns {XKTPropertySet} The new {@link XKTPropertySet}.\n */\n createPropertySet(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.propertySetId === null || params.propertySetId === undefined) {\n throw \"Parameter expected: params.propertySetId\";\n }\n\n if (params.properties === null || params.properties === undefined) {\n throw \"Parameter expected: params.properties\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more property sets\");\n return;\n }\n\n if (this.propertySets[params.propertySetId]) {\n // console.error(\"XKTPropertySet already exists with this ID: \" + params.propertySetId);\n return;\n }\n\n const propertySetId = params.propertySetId;\n const propertySetType = params.propertySetType || \"Default\";\n const propertySetName = params.propertySetName || params.propertySetId;\n const properties = params.properties || [];\n\n const propertySet = new XKTPropertySet(propertySetId, propertySetType, propertySetName, properties);\n\n this.propertySets[propertySetId] = propertySet;\n this.propertySetsList.push(propertySet);\n\n return propertySet;\n }\n\n /**\n * Creates an {@link XKTMetaObject} within this XKTModel.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {String} params.metaObjectId Unique ID for the {@link XKTMetaObject}.\n * @param {String} params.propertySetIds ID of one or more property sets that contains additional metadata about\n * this {@link XKTMetaObject}. The property sets could be stored externally (ie not managed at all by the XKT file),\n * or could be {@link XKTPropertySet}s within {@link XKTModel#propertySets}.\n * @param {String} [params.metaObjectType=\"default\"] A meta type for the {@link XKTMetaObject}. Can be anything,\n * but is usually an IFC type, such as \"IfcSite\" or \"IfcWall\".\n * @param {String} [params.metaObjectName] Human-readable name for the {@link XKTMetaObject}. Defaults to the ````metaObjectId```` parameter.\n * @param {String} [params.parentMetaObjectId] ID of the parent {@link XKTMetaObject}, if any. Defaults to the ````metaObjectId```` parameter.\n * @returns {XKTMetaObject} The new {@link XKTMetaObject}.\n */\n createMetaObject(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.metaObjectId === null || params.metaObjectId === undefined) {\n throw \"Parameter expected: params.metaObjectId\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more meta objects\");\n return;\n }\n\n if (this.metaObjects[params.metaObjectId]) {\n // console.error(\"XKTMetaObject already exists with this ID: \" + params.metaObjectId);\n return;\n }\n\n const metaObjectId = params.metaObjectId;\n const propertySetIds = params.propertySetIds;\n const metaObjectType = params.metaObjectType || \"Default\";\n const metaObjectName = params.metaObjectName || params.metaObjectId;\n const parentMetaObjectId = params.parentMetaObjectId;\n\n const metaObject = new XKTMetaObject(metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId);\n\n this.metaObjects[metaObjectId] = metaObject;\n this.metaObjectsList.push(metaObject);\n\n if (!parentMetaObjectId) {\n if (!this._rootMetaObject) {\n this._rootMetaObject = metaObject;\n }\n }\n\n return metaObject;\n }\n\n /**\n * Creates an {@link XKTTexture} within this XKTModel.\n *\n * Registers the new {@link XKTTexture} in {@link XKTModel#textures} and {@link XKTModel#texturesList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {Number} params.textureId Unique ID for the {@link XKTTexture}.\n * @param {String} [params.src] Source of an image file for the texture.\n * @param {Buffer} [params.imageData] Image data for the texture.\n * @param {Number} [params.mediaType] Media type (ie. MIME type) of ````imageData````. Supported values are {@link GIFMediaType}, {@link PNGMediaType} and {@link JPEGMediaType}.\n * @param {Number} [params.width] Texture width, used with ````imageData````. Ignored for compressed textures.\n * @param {Number} [params.height] Texture height, used with ````imageData````. Ignored for compressed textures.\n * @param {Boolean} [params.compressed=true] Whether to compress the texture.\n * @param {Number} [params.minFilter=LinearMipMapNearestFilter] How the texture is sampled when a texel covers less than one pixel. Supported\n * values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter},\n * {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}. Ignored for compressed textures.\n * @param {Number} [params.magFilter=LinearMipMapNearestFilter] How the texture is sampled when a texel covers more than one pixel. Supported values\n * are {@link LinearFilter} and {@link NearestFilter}. Ignored for compressed textures.\n * @param {Number} [params.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures.\n * @param {Number} [params.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures.\n * {@param {Number} [params.wrapR=RepeatWrapping] Wrap parameter for texture coordinate *R*. Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}. Ignored for compressed textures.\n * @returns {XKTTexture} The new {@link XKTTexture}.\n */\n createTexture(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.textureId === null || params.textureId === undefined) {\n throw \"Parameter expected: params.textureId\";\n }\n\n if (!params.imageData && !params.src) {\n throw \"Parameter expected: params.imageData or params.src\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more textures\");\n return;\n }\n\n if (this.textures[params.textureId]) {\n console.error(\"XKTTexture already exists with this ID: \" + params.textureId);\n return;\n }\n\n if (params.src) {\n const fileExt = params.src.split('.').pop();\n if (fileExt !== \"jpg\" && fileExt !== \"jpeg\" && fileExt !== \"png\") {\n console.error(`XKTModel does not support image files with extension '${fileExt}' - won't create texture '${params.textureId}`);\n return;\n }\n }\n\n const textureId = params.textureId;\n\n const texture = new XKTTexture({\n textureId,\n imageData: params.imageData,\n mediaType: params.mediaType,\n minFilter: params.minFilter,\n magFilter: params.magFilter,\n wrapS: params.wrapS,\n wrapT: params.wrapT,\n wrapR: params.wrapR,\n width: params.width,\n height: params.height,\n compressed: (params.compressed !== false),\n src: params.src\n });\n\n this.textures[textureId] = texture;\n this.texturesList.push(texture);\n\n return texture;\n }\n\n /**\n * Creates an {@link XKTTextureSet} within this XKTModel.\n *\n * Registers the new {@link XKTTextureSet} in {@link XKTModel#textureSets} and {@link XKTModel#.textureSetsList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {Number} params.textureSetId Unique ID for the {@link XKTTextureSet}.\n * @param {*} [params.colorTextureId] ID of *RGBA* base color {@link XKTTexture}, with color in *RGB* and alpha in *A*.\n * @param {*} [params.metallicRoughnessTextureId] ID of *RGBA* metal-roughness {@link XKTTexture}, with the metallic factor in *R*, and roughness factor in *G*.\n * @param {*} [params.normalsTextureId] ID of *RGBA* normal {@link XKTTexture}, with normal map vectors in *RGB*.\n * @param {*} [params.emissiveTextureId] ID of *RGBA* emissive {@link XKTTexture}, with emissive color in *RGB*.\n * @param {*} [params.occlusionTextureId] ID of *RGBA* occlusion {@link XKTTexture}, with occlusion factor in *R*.\n * @returns {XKTTextureSet} The new {@link XKTTextureSet}.\n */\n createTextureSet(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.textureSetId === null || params.textureSetId === undefined) {\n throw \"Parameter expected: params.textureSetId\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more textureSets\");\n return;\n }\n\n if (this.textureSets[params.textureSetId]) {\n console.error(\"XKTTextureSet already exists with this ID: \" + params.textureSetId);\n return;\n }\n\n let colorTexture;\n if (params.colorTextureId !== undefined && params.colorTextureId !== null) {\n colorTexture = this.textures[params.colorTextureId];\n if (!colorTexture) {\n console.error(`Texture not found: ${params.colorTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n colorTexture.channel = COLOR_TEXTURE;\n }\n\n let metallicRoughnessTexture;\n if (params.metallicRoughnessTextureId !== undefined && params.metallicRoughnessTextureId !== null) {\n metallicRoughnessTexture = this.textures[params.metallicRoughnessTextureId];\n if (!metallicRoughnessTexture) {\n console.error(`Texture not found: ${params.metallicRoughnessTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n metallicRoughnessTexture.channel = METALLIC_ROUGHNESS_TEXTURE;\n }\n\n let normalsTexture;\n if (params.normalsTextureId !== undefined && params.normalsTextureId !== null) {\n normalsTexture = this.textures[params.normalsTextureId];\n if (!normalsTexture) {\n console.error(`Texture not found: ${params.normalsTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n normalsTexture.channel = NORMALS_TEXTURE;\n }\n\n let emissiveTexture;\n if (params.emissiveTextureId !== undefined && params.emissiveTextureId !== null) {\n emissiveTexture = this.textures[params.emissiveTextureId];\n if (!emissiveTexture) {\n console.error(`Texture not found: ${params.emissiveTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n emissiveTexture.channel = EMISSIVE_TEXTURE;\n }\n\n let occlusionTexture;\n if (params.occlusionTextureId !== undefined && params.occlusionTextureId !== null) {\n occlusionTexture = this.textures[params.occlusionTextureId];\n if (!occlusionTexture) {\n console.error(`Texture not found: ${params.occlusionTextureId} - ensure that you create it first with createTexture()`);\n return;\n }\n occlusionTexture.channel = OCCLUSION_TEXTURE;\n }\n\n const textureSet = new XKTTextureSet({\n textureSetId: params.textureSetId,\n textureSetIndex: this.textureSetsList.length,\n colorTexture,\n metallicRoughnessTexture,\n normalsTexture,\n emissiveTexture,\n occlusionTexture\n });\n\n this.textureSets[params.textureSetId] = textureSet;\n this.textureSetsList.push(textureSet);\n\n return textureSet;\n }\n\n /**\n * Creates an {@link XKTGeometry} within this XKTModel.\n *\n * Registers the new {@link XKTGeometry} in {@link XKTModel#geometries} and {@link XKTModel#geometriesList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {Number} params.geometryId Unique ID for the {@link XKTGeometry}.\n * @param {String} params.primitiveType The type of {@link XKTGeometry}: \"triangles\", \"lines\" or \"points\".\n * @param {Float64Array} params.positions Floating-point Local-space vertex positions for the {@link XKTGeometry}. Required for all primitive types.\n * @param {Number[]} [params.normals] Floating-point vertex normals for the {@link XKTGeometry}. Only used with triangles primitives. Ignored for points and lines.\n * @param {Number[]} [params.colors] Floating-point RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.\n * @param {Number[]} [params.colorsCompressed] Integer RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.\n * @param {Number[]} [params.uvs] Floating-point vertex UV coordinates for the {@link XKTGeometry}. Alias for ````uv````.\n * @param {Number[]} [params.uv] Floating-point vertex UV coordinates for the {@link XKTGeometry}. Alias for ````uvs````.\n * @param {Number[]} [params.colorsCompressed] Integer RGBA vertex colors for the {@link XKTGeometry}. Required for points primitives. Ignored for lines and triangles.\n * @param {Uint32Array} [params.indices] Indices for the {@link XKTGeometry}. Required for triangles and lines primitives. Ignored for points.\n * @param {Number} [params.edgeThreshold=10]\n * @returns {XKTGeometry} The new {@link XKTGeometry}.\n */\n createGeometry(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.geometryId === null || params.geometryId === undefined) {\n throw \"Parameter expected: params.geometryId\";\n }\n\n if (!params.primitiveType) {\n throw \"Parameter expected: params.primitiveType\";\n }\n\n if (!params.positions) {\n throw \"Parameter expected: params.positions\";\n }\n\n const triangles = params.primitiveType === \"triangles\";\n const points = params.primitiveType === \"points\";\n const lines = params.primitiveType === \"lines\";\n const line_strip = params.primitiveType === \"line-strip\";\n const line_loop = params.primitiveType === \"line-loop\";\n const triangle_strip = params.primitiveType === \"triangle-strip\";\n const triangle_fan = params.primitiveType === \"triangle-fan\";\n\n if (!triangles && !points && !lines && !line_strip && !line_loop) {\n throw \"Unsupported value for params.primitiveType: \"\n + params.primitiveType\n + \"' - supported values are 'triangles', 'points', 'lines', 'line-strip', 'triangle-strip' and 'triangle-fan\";\n }\n\n if (triangles) {\n if (!params.indices) {\n params.indices = this._createDefaultIndices()\n throw \"Parameter expected for 'triangles' primitive: params.indices\";\n }\n }\n\n if (points) {\n if (!params.colors && !params.colorsCompressed) {\n throw \"Parameter expected for 'points' primitive: params.colors or params.colorsCompressed\";\n }\n }\n\n if (lines) {\n if (!params.indices) {\n throw \"Parameter expected for 'lines' primitive: params.indices\";\n }\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more geometries\");\n return;\n }\n\n if (this.geometries[params.geometryId]) {\n console.error(\"XKTGeometry already exists with this ID: \" + params.geometryId);\n return;\n }\n\n const geometryId = params.geometryId;\n const primitiveType = params.primitiveType;\n const positions = new Float64Array(params.positions); // May modify in #finalize\n\n const xktGeometryCfg = {\n geometryId: geometryId,\n geometryIndex: this.geometriesList.length,\n primitiveType: primitiveType,\n positions: positions,\n uvs: params.uvs || params.uv\n }\n\n if (triangles) {\n if (params.normals) {\n xktGeometryCfg.normals = new Float32Array(params.normals);\n }\n if (params.indices) {\n xktGeometryCfg.indices = params.indices;\n } else {\n xktGeometryCfg.indices = this._createDefaultIndices(positions.length / 3);\n }\n }\n\n if (points) {\n if (params.colorsCompressed) {\n xktGeometryCfg.colorsCompressed = new Uint8Array(params.colorsCompressed);\n\n } else {\n const colors = params.colors;\n const colorsCompressed = new Uint8Array(colors.length);\n for (let i = 0, len = colors.length; i < len; i++) {\n colorsCompressed[i] = Math.floor(colors[i] * 255);\n }\n xktGeometryCfg.colorsCompressed = colorsCompressed;\n }\n }\n\n if (lines) {\n xktGeometryCfg.indices = params.indices;\n }\n\n if (triangles) {\n\n if (!params.normals && !params.uv && !params.uvs) {\n\n // Building models often duplicate positions to allow face-aligned vertex normals; when we're not\n // providing normals for a geometry, it becomes possible to merge duplicate vertex positions within it.\n\n // TODO: Make vertex merging also merge normals?\n\n const mergedPositions = [];\n const mergedIndices = [];\n mergeVertices(xktGeometryCfg.positions, xktGeometryCfg.indices, mergedPositions, mergedIndices);\n xktGeometryCfg.positions = new Float64Array(mergedPositions);\n xktGeometryCfg.indices = mergedIndices;\n }\n\n xktGeometryCfg.edgeIndices = buildEdgeIndices(xktGeometryCfg.positions, xktGeometryCfg.indices, null, params.edgeThreshold || this.edgeThreshold || 10);\n }\n\n const geometry = new XKTGeometry(xktGeometryCfg);\n\n this.geometries[geometryId] = geometry;\n this.geometriesList.push(geometry);\n\n return geometry;\n }\n\n _createDefaultIndices(numIndices) {\n const indices = [];\n for (let i = 0; i < numIndices; i++) {\n indices.push(i);\n }\n return indices;\n }\n\n /**\n * Creates an {@link XKTMesh} within this XKTModel.\n *\n * An {@link XKTMesh} can be owned by one {@link XKTEntity}, which can own multiple {@link XKTMesh}es.\n *\n * Registers the new {@link XKTMesh} in {@link XKTModel#meshes} and {@link XKTModel#meshesList}.\n *\n * @param {*} params Method parameters.\n * @param {Number} params.meshId Unique ID for the {@link XKTMesh}.\n * @param {Number} params.geometryId ID of an existing {@link XKTGeometry} in {@link XKTModel#geometries}.\n * @param {Number} [params.textureSetId] Unique ID of an {@link XKTTextureSet} in {@link XKTModel#textureSets}.\n * @param {Float32Array} params.color RGB color for the {@link XKTMesh}, with each color component in range [0..1].\n * @param {Number} [params.metallic=0] How metallic the {@link XKTMesh} is, in range [0..1]. A value of ````0```` indicates fully dielectric material, while ````1```` indicates fully metallic.\n * @param {Number} [params.roughness=1] How rough the {@link XKTMesh} is, in range [0..1]. A value of ````0```` indicates fully smooth, while ````1```` indicates fully rough.\n * @param {Number} params.opacity Opacity factor for the {@link XKTMesh}, in range [0..1].\n * @param {Float64Array} [params.matrix] Modeling matrix for the {@link XKTMesh}. Overrides ````position````, ````scale```` and ````rotation```` parameters.\n * @param {Number[]} [params.position=[0,0,0]] Position of the {@link XKTMesh}. Overridden by the ````matrix```` parameter.\n * @param {Number[]} [params.scale=[1,1,1]] Scale of the {@link XKTMesh}. Overridden by the ````matrix```` parameter.\n * @param {Number[]} [params.rotation=[0,0,0]] Rotation of the {@link XKTMesh} as Euler angles given in degrees, for each of the X, Y and Z axis. Overridden by the ````matrix```` parameter.\n * @returns {XKTMesh} The new {@link XKTMesh}.\n */\n createMesh(params) {\n\n if (params.meshId === null || params.meshId === undefined) {\n throw \"Parameter expected: params.meshId\";\n }\n\n if (params.geometryId === null || params.geometryId === undefined) {\n throw \"Parameter expected: params.geometryId\";\n }\n\n if (this.finalized) {\n throw \"XKTModel has been finalized, can't add more meshes\";\n }\n\n if (this.meshes[params.meshId]) {\n console.error(\"XKTMesh already exists with this ID: \" + params.meshId);\n return;\n }\n\n const geometry = this.geometries[params.geometryId];\n\n if (!geometry) {\n console.error(\"XKTGeometry not found: \" + params.geometryId);\n return;\n }\n\n geometry.numInstances++;\n\n let textureSet = null;\n if (params.textureSetId) {\n textureSet = this.textureSets[params.textureSetId];\n if (!textureSet) {\n console.error(\"XKTTextureSet not found: \" + params.textureSetId);\n return;\n }\n textureSet.numInstances++;\n }\n\n let matrix = params.matrix;\n\n if (!matrix) {\n\n const position = params.position;\n const scale = params.scale;\n const rotation = params.rotation;\n\n if (position || scale || rotation) {\n matrix = math.identityMat4();\n const quaternion = math.eulerToQuaternion(rotation || [0, 0, 0], \"XYZ\", math.identityQuaternion());\n math.composeMat4(position || [0, 0, 0], quaternion, scale || [1, 1, 1], matrix)\n\n } else {\n matrix = math.identityMat4();\n }\n }\n\n const meshIndex = this.meshesList.length;\n\n const mesh = new XKTMesh({\n meshId: params.meshId,\n meshIndex,\n matrix,\n geometry,\n color: params.color,\n metallic: params.metallic,\n roughness: params.roughness,\n opacity: params.opacity,\n textureSet\n });\n\n this.meshes[mesh.meshId] = mesh;\n this.meshesList.push(mesh);\n\n return mesh;\n }\n\n /**\n * Creates an {@link XKTEntity} within this XKTModel.\n *\n * Registers the new {@link XKTEntity} in {@link XKTModel#entities} and {@link XKTModel#entitiesList}.\n *\n * Logs error and does nothing if this XKTModel has been finalized (see {@link XKTModel#finalized}).\n *\n * @param {*} params Method parameters.\n * @param {String} params.entityId Unique ID for the {@link XKTEntity}.\n * @param {String[]} params.meshIds IDs of {@link XKTMesh}es used by the {@link XKTEntity}. Note that each {@link XKTMesh} can only be used by one {@link XKTEntity}.\n * @returns {XKTEntity} The new {@link XKTEntity}.\n */\n createEntity(params) {\n\n if (!params) {\n throw \"Parameters expected: params\";\n }\n\n if (params.entityId === null || params.entityId === undefined) {\n throw \"Parameter expected: params.entityId\";\n }\n\n if (!params.meshIds) {\n throw \"Parameter expected: params.meshIds\";\n }\n\n if (this.finalized) {\n console.error(\"XKTModel has been finalized, can't add more entities\");\n return;\n }\n\n if (params.meshIds.length === 0) {\n console.warn(\"XKTEntity has no meshes - won't create: \" + params.entityId);\n return;\n }\n\n let entityId = params.entityId;\n\n if (this.entities[entityId]) {\n while (this.entities[entityId]) {\n entityId = math.createUUID();\n }\n console.error(\"XKTEntity already exists with this ID: \" + params.entityId + \" - substituting random ID instead: \" + entityId);\n }\n\n const meshIds = params.meshIds;\n const meshes = [];\n\n for (let meshIdIdx = 0, meshIdLen = meshIds.length; meshIdIdx < meshIdLen; meshIdIdx++) {\n\n const meshId = meshIds[meshIdIdx];\n const mesh = this.meshes[meshId];\n\n if (!mesh) {\n console.error(\"XKTMesh found: \" + meshId);\n continue;\n }\n\n if (mesh.entity) {\n console.error(\"XKTMesh \" + meshId + \" already used by XKTEntity \" + mesh.entity.entityId);\n continue;\n }\n\n meshes.push(mesh);\n }\n\n const entity = new XKTEntity(entityId, meshes);\n\n for (let i = 0, len = meshes.length; i < len; i++) {\n const mesh = meshes[i];\n mesh.entity = entity;\n }\n\n this.entities[entityId] = entity;\n this.entitiesList.push(entity);\n\n return entity;\n }\n\n /**\n * Creates a default {@link XKTMetaObject} for each {@link XKTEntity} that does not already have one.\n */\n createDefaultMetaObjects() {\n\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n\n const entity = this.entitiesList[i];\n const metaObjectId = entity.entityId;\n const metaObject = this.metaObjects[metaObjectId];\n\n if (!metaObject) {\n\n if (!this._rootMetaObject) {\n this._rootMetaObject = this.createMetaObject({\n metaObjectId: this.modelId,\n metaObjectType: \"Default\",\n metaObjectName: this.modelId\n });\n }\n\n this.createMetaObject({\n metaObjectId: metaObjectId,\n metaObjectType: \"Default\",\n metaObjectName: \"\" + metaObjectId,\n parentMetaObjectId: this._rootMetaObject.metaObjectId\n });\n }\n }\n }\n\n /**\n * Finalizes this XKTModel.\n *\n * After finalizing, we may then serialize the model to an array buffer using {@link writeXKTModelToArrayBuffer}.\n *\n * Logs error and does nothing if this XKTModel has already been finalized.\n *\n * Internally, this method:\n *\n * * for each {@link XKTEntity} that doesn't already have a {@link XKTMetaObject}, creates one with {@link XKTMetaObject#metaObjectType} set to \"default\"\n * * sets each {@link XKTEntity}'s {@link XKTEntity#hasReusedGeometries} true if it shares its {@link XKTGeometry}s with other {@link XKTEntity}s,\n * * creates each {@link XKTEntity}'s {@link XKTEntity#aabb},\n * * creates {@link XKTTile}s in {@link XKTModel#tilesList}, and\n * * sets {@link XKTModel#finalized} ````true````.\n */\n async finalize() {\n\n if (this.finalized) {\n console.log(\"XKTModel already finalized\");\n return;\n }\n\n this._removeUnusedTextures();\n\n await this._compressTextures();\n\n this._bakeSingleUseGeometryPositions();\n\n this._bakeAndOctEncodeNormals();\n\n this._createEntityAABBs();\n\n const rootKDNode = this._createKDTree();\n\n this.entitiesList = [];\n\n this._createTilesFromKDTree(rootKDNode);\n\n this._createReusedGeometriesDecodeMatrix();\n\n this._flagSolidGeometries();\n\n this.aabb.set(rootKDNode.aabb);\n\n this.finalized = true;\n }\n\n _removeUnusedTextures() {\n let texturesList = [];\n const textures = {};\n for (let i = 0, leni = this.texturesList.length; i < leni; i++) {\n const texture = this.texturesList[i];\n if (texture.channel !== null) {\n texture.textureIndex = texturesList.length;\n texturesList.push(texture);\n textures[texture.textureId] = texture;\n }\n }\n this.texturesList = texturesList;\n this.textures = textures;\n }\n\n _compressTextures() {\n let countTextures = this.texturesList.length;\n return new Promise((resolve) => {\n if (countTextures === 0) {\n resolve();\n return;\n }\n for (let i = 0, leni = this.texturesList.length; i < leni; i++) {\n const texture = this.texturesList[i];\n const encodingOptions = TEXTURE_ENCODING_OPTIONS[texture.channel] || {};\n\n if (texture.src) {\n\n // XKTTexture created with XKTModel#createTexture({ src: ... })\n\n const src = texture.src;\n const fileExt = src.split('.').pop();\n switch (fileExt) {\n case \"jpeg\":\n case \"jpg\":\n case \"png\":\n load(src, ImageLoader, {\n image: {\n type: \"data\"\n }\n }).then((imageData) => {\n if (texture.compressed) {\n encode(imageData, KTX2BasisWriter, encodingOptions).then((encodedData) => {\n const encodedImageData = new Uint8Array(encodedData);\n texture.imageData = encodedImageData;\n if (--countTextures <= 0) {\n resolve();\n }\n }).catch((err) => {\n console.error(\"[XKTModel.finalize] Failed to encode image: \" + err);\n if (--countTextures <= 0) {\n resolve();\n }\n });\n } else {\n texture.imageData = new Uint8Array(1);\n if (--countTextures <= 0) {\n resolve();\n }\n }\n }).catch((err) => {\n console.error(\"[XKTModel.finalize] Failed to load image: \" + err);\n if (--countTextures <= 0) {\n resolve();\n }\n });\n break;\n default:\n if (--countTextures <= 0) {\n resolve();\n }\n break;\n }\n }\n\n if (texture.imageData) {\n\n // XKTTexture created with XKTModel#createTexture({ imageData: ... })\n\n if (texture.compressed) {\n encode(texture.imageData, KTX2BasisWriter, encodingOptions)\n .then((encodedImageData) => {\n texture.imageData = new Uint8Array(encodedImageData);\n if (--countTextures <= 0) {\n resolve();\n }\n }).catch((err) => {\n console.error(\"[XKTModel.finalize] Failed to encode image: \" + err);\n if (--countTextures <= 0) {\n resolve();\n }\n });\n } else {\n texture.imageData = new Uint8Array(1);\n if (--countTextures <= 0) {\n resolve();\n }\n }\n }\n }\n });\n }\n\n _bakeSingleUseGeometryPositions() {\n\n for (let j = 0, lenj = this.meshesList.length; j < lenj; j++) {\n\n const mesh = this.meshesList[j];\n\n const geometry = mesh.geometry;\n\n if (geometry.numInstances === 1) {\n\n const matrix = mesh.matrix;\n\n if (matrix && (!math.isIdentityMat4(matrix))) {\n\n const positions = geometry.positions;\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n tempVec4a[0] = positions[i + 0];\n tempVec4a[1] = positions[i + 1];\n tempVec4a[2] = positions[i + 2];\n tempVec4a[3] = 1;\n\n math.transformPoint4(matrix, tempVec4a, tempVec4b);\n\n positions[i + 0] = tempVec4b[0];\n positions[i + 1] = tempVec4b[1];\n positions[i + 2] = tempVec4b[2];\n }\n }\n }\n }\n }\n\n _bakeAndOctEncodeNormals() {\n\n for (let i = 0, len = this.meshesList.length; i < len; i++) {\n\n const mesh = this.meshesList[i];\n const geometry = mesh.geometry;\n\n if (geometry.normals && !geometry.normalsOctEncoded) {\n\n geometry.normalsOctEncoded = new Int8Array(geometry.normals.length);\n\n if (geometry.numInstances > 1) {\n geometryCompression.octEncodeNormals(geometry.normals, geometry.normals.length, geometry.normalsOctEncoded, 0);\n\n } else {\n const modelNormalMatrix = math.inverseMat4(math.transposeMat4(mesh.matrix, tempMat4), tempMat4b);\n geometryCompression.transformAndOctEncodeNormals(modelNormalMatrix, geometry.normals, geometry.normals.length, geometry.normalsOctEncoded, 0);\n }\n }\n }\n }\n\n _createEntityAABBs() {\n\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n\n const entity = this.entitiesList[i];\n const entityAABB = entity.aabb;\n const meshes = entity.meshes;\n\n math.collapseAABB3(entityAABB);\n\n for (let j = 0, lenj = meshes.length; j < lenj; j++) {\n\n const mesh = meshes[j];\n const geometry = mesh.geometry;\n const matrix = mesh.matrix;\n\n if (geometry.numInstances > 1) {\n\n const positions = geometry.positions;\n for (let i = 0, len = positions.length; i < len; i += 3) {\n tempVec4a[0] = positions[i + 0];\n tempVec4a[1] = positions[i + 1];\n tempVec4a[2] = positions[i + 2];\n tempVec4a[3] = 1;\n math.transformPoint4(matrix, tempVec4a, tempVec4b);\n math.expandAABB3Point3(entityAABB, tempVec4b);\n }\n\n } else {\n\n const positions = geometry.positions;\n for (let i = 0, len = positions.length; i < len; i += 3) {\n tempVec4a[0] = positions[i + 0];\n tempVec4a[1] = positions[i + 1];\n tempVec4a[2] = positions[i + 2];\n math.expandAABB3Point3(entityAABB, tempVec4a);\n }\n }\n }\n }\n }\n\n _createKDTree() {\n\n let aabb;\n if (this.modelAABB) {\n aabb = this.modelAABB; // Pre-known uber AABB\n } else {\n aabb = math.collapseAABB3();\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n const entity = this.entitiesList[i];\n math.expandAABB3(aabb, entity.aabb);\n }\n }\n\n const rootKDNode = new KDNode(aabb);\n\n for (let i = 0, len = this.entitiesList.length; i < len; i++) {\n const entity = this.entitiesList[i];\n this._insertEntityIntoKDTree(rootKDNode, entity);\n }\n\n return rootKDNode;\n }\n\n _insertEntityIntoKDTree(kdNode, entity) {\n\n const nodeAABB = kdNode.aabb;\n const entityAABB = entity.aabb;\n\n const nodeAABBDiag = math.getAABB3Diag(nodeAABB);\n\n if (nodeAABBDiag < this.minTileSize) {\n kdNode.entities = kdNode.entities || [];\n kdNode.entities.push(entity);\n math.expandAABB3(nodeAABB, entityAABB);\n return;\n }\n\n if (kdNode.left) {\n if (math.containsAABB3(kdNode.left.aabb, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.left, entity);\n return;\n }\n }\n\n if (kdNode.right) {\n if (math.containsAABB3(kdNode.right.aabb, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.right, entity);\n return;\n }\n }\n\n kdTreeDimLength[0] = nodeAABB[3] - nodeAABB[0];\n kdTreeDimLength[1] = nodeAABB[4] - nodeAABB[1];\n kdTreeDimLength[2] = nodeAABB[5] - nodeAABB[2];\n\n let dim = 0;\n\n if (kdTreeDimLength[1] > kdTreeDimLength[dim]) {\n dim = 1;\n }\n\n if (kdTreeDimLength[2] > kdTreeDimLength[dim]) {\n dim = 2;\n }\n\n if (!kdNode.left) {\n const aabbLeft = nodeAABB.slice();\n aabbLeft[dim + 3] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0);\n kdNode.left = new KDNode(aabbLeft);\n if (math.containsAABB3(aabbLeft, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.left, entity);\n return;\n }\n }\n\n if (!kdNode.right) {\n const aabbRight = nodeAABB.slice();\n aabbRight[dim] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0);\n kdNode.right = new KDNode(aabbRight);\n if (math.containsAABB3(aabbRight, entityAABB)) {\n this._insertEntityIntoKDTree(kdNode.right, entity);\n return;\n }\n }\n\n kdNode.entities = kdNode.entities || [];\n kdNode.entities.push(entity);\n\n math.expandAABB3(nodeAABB, entityAABB);\n }\n\n _createTilesFromKDTree(rootKDNode) {\n this._createTilesFromKDNode(rootKDNode);\n }\n\n _createTilesFromKDNode(kdNode) {\n if (kdNode.entities && kdNode.entities.length > 0) {\n this._createTileFromEntities(kdNode);\n }\n if (kdNode.left) {\n this._createTilesFromKDNode(kdNode.left);\n }\n if (kdNode.right) {\n this._createTilesFromKDNode(kdNode.right);\n }\n }\n\n /**\n * Creates a tile from the given entities.\n *\n * For each single-use {@link XKTGeometry}, this method centers {@link XKTGeometry#positions} to make them relative to the\n * tile's center, then quantizes the positions to unsigned 16-bit integers, relative to the tile's boundary.\n *\n * @param kdNode\n */\n _createTileFromEntities(kdNode) {\n\n const tileAABB = kdNode.aabb;\n const entities = kdNode.entities;\n\n const tileCenter = math.getAABB3Center(tileAABB);\n const tileCenterNeg = math.mulVec3Scalar(tileCenter, -1, math.vec3());\n\n const rtcAABB = math.AABB3(); // AABB centered at the RTC origin\n\n rtcAABB[0] = tileAABB[0] - tileCenter[0];\n rtcAABB[1] = tileAABB[1] - tileCenter[1];\n rtcAABB[2] = tileAABB[2] - tileCenter[2];\n rtcAABB[3] = tileAABB[3] - tileCenter[0];\n rtcAABB[4] = tileAABB[4] - tileCenter[1];\n rtcAABB[5] = tileAABB[5] - tileCenter[2];\n\n for (let i = 0; i < entities.length; i++) {\n\n const entity = entities [i];\n\n const meshes = entity.meshes;\n\n for (let j = 0, lenj = meshes.length; j < lenj; j++) {\n\n const mesh = meshes[j];\n const geometry = mesh.geometry;\n\n if (!geometry.reused) { // Batched geometry\n\n const positions = geometry.positions;\n\n // Center positions relative to their tile's World-space center\n\n for (let k = 0, lenk = positions.length; k < lenk; k += 3) {\n\n positions[k + 0] -= tileCenter[0];\n positions[k + 1] -= tileCenter[1];\n positions[k + 2] -= tileCenter[2];\n }\n\n // Quantize positions relative to tile's RTC-space boundary\n\n geometryCompression.quantizePositions(positions, positions.length, rtcAABB, geometry.positionsQuantized);\n\n } else { // Instanced geometry\n\n // Post-multiply a translation to the mesh's modeling matrix\n // to center the entity's geometry instances to the tile RTC center\n\n //////////////////////////////\n // Why do we do this?\n // Seems to break various models\n /////////////////////////////////\n\n math.translateMat4v(tileCenterNeg, mesh.matrix);\n }\n }\n\n entity.entityIndex = this.entitiesList.length;\n\n this.entitiesList.push(entity);\n }\n\n const tile = new XKTTile(tileAABB, entities);\n\n this.tilesList.push(tile);\n }\n\n _createReusedGeometriesDecodeMatrix() {\n\n const tempVec3a = math.vec3();\n const reusedGeometriesAABB = math.collapseAABB3(math.AABB3());\n let countReusedGeometries = 0;\n\n for (let geometryIndex = 0, numGeometries = this.geometriesList.length; geometryIndex < numGeometries; geometryIndex++) {\n\n const geometry = this.geometriesList [geometryIndex];\n\n if (geometry.reused) { // Instanced geometry\n\n const positions = geometry.positions;\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n tempVec3a[0] = positions[i];\n tempVec3a[1] = positions[i + 1];\n tempVec3a[2] = positions[i + 2];\n\n math.expandAABB3Point3(reusedGeometriesAABB, tempVec3a);\n }\n\n countReusedGeometries++;\n }\n }\n\n if (countReusedGeometries > 0) {\n\n geometryCompression.createPositionsDecodeMatrix(reusedGeometriesAABB, this.reusedGeometriesDecodeMatrix);\n\n for (let geometryIndex = 0, numGeometries = this.geometriesList.length; geometryIndex < numGeometries; geometryIndex++) {\n\n const geometry = this.geometriesList [geometryIndex];\n\n if (geometry.reused) {\n geometryCompression.quantizePositions(geometry.positions, geometry.positions.length, reusedGeometriesAABB, geometry.positionsQuantized);\n }\n }\n\n } else {\n math.identityMat4(this.reusedGeometriesDecodeMatrix); // No need for this matrix, but we'll be tidy and set it to identity\n }\n }\n\n _flagSolidGeometries() {\n let maxNumPositions = 0;\n let maxNumIndices = 0;\n for (let i = 0, len = this.geometriesList.length; i < len; i++) {\n const geometry = this.geometriesList[i];\n if (geometry.primitiveType === \"triangles\") {\n if (geometry.positionsQuantized.length > maxNumPositions) {\n maxNumPositions = geometry.positionsQuantized.length;\n }\n if (geometry.indices.length > maxNumIndices) {\n maxNumIndices = geometry.indices.length;\n }\n }\n }\n let vertexIndexMapping = new Array(maxNumPositions / 3);\n let edges = new Array(maxNumIndices);\n for (let i = 0, len = this.geometriesList.length; i < len; i++) {\n const geometry = this.geometriesList[i];\n if (geometry.primitiveType === \"triangles\") {\n geometry.solid = isTriangleMeshSolid(geometry.indices, geometry.positionsQuantized, vertexIndexMapping, edges);\n }\n }\n }\n}\n\nexport {\n XKTModel\n}", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/XKTModel.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/XKTModel.js", "access": "public", "description": null, "lineNumber": 1 @@ -4023,7 +4023,7 @@ "name": "src/XKTModel/XKTPropertySet.js", "content": "/**\n * A property set within an {@link XKTModel}.\n *\n * These are shared among {@link XKTMetaObject}s.\n *\n * * Created by {@link XKTModel#createPropertySet}\n * * Stored in {@link XKTModel#propertySets} and {@link XKTModel#propertySetsList}\n * * Has an ID, a type, and a human-readable name\n *\n * @class XKTPropertySet\n */\nclass XKTPropertySet {\n\n /**\n * @private\n */\n constructor(propertySetId, propertySetType, propertySetName, properties) {\n\n /**\n * Unique ID of this ````XKTPropertySet```` in {@link XKTModel#propertySets}.\n *\n * @type {String}\n */\n this.propertySetId = propertySetId;\n\n /**\n * Indicates the ````XKTPropertySet````'s type.\n *\n * This defaults to \"default\".\n *\n * @type {string}\n */\n this.propertySetType = propertySetType;\n\n /**\n * Indicates the XKTPropertySet meta object name.\n *\n * This defaults to {@link XKTPropertySet#propertySetId}.\n *\n * @type {string}\n */\n this.propertySetName = propertySetName;\n\n /**\n * The properties within this ````XKTPropertySet````.\n *\n * @type {*[]}\n */\n this.properties = properties;\n }\n}\n\nexport {XKTPropertySet};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/XKTPropertySet.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/XKTPropertySet.js", "access": "public", "description": null, "lineNumber": 1 @@ -4145,7 +4145,7 @@ "name": "src/XKTModel/XKTTexture.js", "content": "/**\n * A texture shared by {@link XKTTextureSet}s.\n *\n * * Created by {@link XKTModel#createTexture}\n * * Stored in {@link XKTTextureSet#textures}, {@link XKTModel#textures} and {@link XKTModel#texturesList}\n *\n * @class XKTTexture\n */\nimport {RepeatWrapping, LinearMipMapNearestFilter} from \"../constants\";\n\nclass XKTTexture {\n\n /**\n * @private\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTTexture in {@link XKTModel#textures}.\n *\n * @type {Number}\n */\n this.textureId = cfg.textureId;\n\n /**\n * Index of this XKTTexture in {@link XKTModel#texturesList};\n *\n * @type {Number}\n */\n this.textureIndex = cfg.textureIndex;\n\n /**\n * Texture image data.\n *\n * @type {Buffer}\n */\n this.imageData = cfg.imageData;\n\n /**\n * Which material channel this texture is applied to, as determined by its {@link XKTTextureSet}s.\n *\n * @type {Number}\n */\n this.channel = null;\n\n /**\n * Width of this XKTTexture.\n *\n * @type {Number}\n */\n this.width = cfg.width;\n\n /**\n * Height of this XKTTexture.\n *\n * @type {Number}\n */\n this.height = cfg.height;\n\n /**\n * Texture file source.\n *\n * @type {String}\n */\n this.src = cfg.src;\n\n /**\n * Whether this XKTTexture is to be compressed.\n *\n * @type {Boolean}\n */\n this.compressed = (!!cfg.compressed);\n\n /**\n * Media type of this XKTTexture.\n *\n * Supported values are {@link GIFMediaType}, {@link PNGMediaType} and {@link JPEGMediaType}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.mediaType = cfg.mediaType;\n\n /**\n * How the texture is sampled when a texel covers less than one pixel. Supported values\n * are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter},\n * {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter}\n * and {@link LinearMipMapLinearFilter}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.minFilter = cfg.minFilter || LinearMipMapNearestFilter;\n\n /**\n * How the texture is sampled when a texel covers more than one pixel. Supported values\n * are {@link LinearFilter} and {@link NearestFilter}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.magFilter = cfg.magFilter || LinearMipMapNearestFilter;\n\n /**\n * S wrapping mode.\n *\n * Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.wrapS = cfg.wrapS || RepeatWrapping;\n\n /**\n * T wrapping mode.\n *\n * Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n *\n * Ignored for compressed textures.\n *\n * @type {Number}\n */\n this.wrapT = cfg.wrapT || RepeatWrapping;\n\n /**\n * R wrapping mode.\n *\n * Ignored for compressed textures.\n *\n * Supported values are {@link ClampToEdgeWrapping},\n * {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n *\n * @type {*|number}\n */\n this.wrapR = cfg.wrapR || RepeatWrapping\n }\n}\n\nexport {XKTTexture};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/XKTTexture.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/XKTTexture.js", "access": "public", "description": null, "lineNumber": 1 @@ -4453,7 +4453,7 @@ "name": "src/XKTModel/XKTTextureSet.js", "content": "/**\n * A set of textures shared by {@link XKTMesh}es.\n *\n * * Created by {@link XKTModel#createTextureSet}\n * * Registered in {@link XKTMesh#material}, {@link XKTModel#materials} and {@link XKTModel#.textureSetsList}\n *\n * @class XKTMetalRoughMaterial\n */\nclass XKTTextureSet {\n\n /**\n * @private\n */\n constructor(cfg) {\n\n /**\n * Unique ID of this XKTTextureSet in {@link XKTModel#materials}.\n *\n * @type {Number}\n */\n this.textureSetId = cfg.textureSetId;\n\n /**\n * Index of this XKTTexture in {@link XKTModel#texturesList};\n *\n * @type {Number}\n */\n this.textureSetIndex = cfg.textureSetIndex;\n\n /**\n * Identifies the material type.\n *\n * @type {Number}\n */\n this.materialType = cfg.materialType;\n\n /**\n * Index of this XKTTextureSet in {@link XKTModel#meshesList};\n *\n * @type {Number}\n */\n this.materialIndex = cfg.materialIndex;\n\n /**\n * The number of {@link XKTMesh}s that reference this XKTTextureSet.\n *\n * @type {Number}\n */\n this.numInstances = 0;\n\n /**\n * RGBA {@link XKTTexture} containing base color in RGB and opacity in A.\n *\n * @type {XKTTexture}\n */\n this.colorTexture = cfg.colorTexture;\n\n /**\n * RGBA {@link XKTTexture} containing metallic and roughness factors in R and G.\n *\n * @type {XKTTexture}\n */\n this.metallicRoughnessTexture = cfg.metallicRoughnessTexture;\n\n /**\n * RGBA {@link XKTTexture} with surface normals in RGB.\n *\n * @type {XKTTexture}\n */\n this.normalsTexture = cfg.normalsTexture;\n\n /**\n * RGBA {@link XKTTexture} with emissive color in RGB.\n *\n * @type {XKTTexture}\n */\n this.emissiveTexture = cfg.emissiveTexture;\n\n /**\n * RGBA {@link XKTTexture} with ambient occlusion factors in RGB.\n *\n * @type {XKTTexture}\n */\n this.occlusionTexture = cfg.occlusionTexture;\n }\n}\n\nexport {XKTTextureSet};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/XKTTextureSet.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/XKTTextureSet.js", "access": "public", "description": null, "lineNumber": 1 @@ -4689,7 +4689,7 @@ "name": "src/XKTModel/XKTTile.js", "content": "/**\n * @desc A box-shaped 3D region within an {@link XKTModel} that contains {@link XKTEntity}s.\n *\n * * Created by {@link XKTModel#finalize}\n * * Stored in {@link XKTModel#tilesList}\n *\n * @class XKTTile\n */\nclass XKTTile {\n\n /**\n * Creates a new XKTTile.\n *\n * @private\n * @param aabb\n * @param entities\n */\n constructor(aabb, entities) {\n\n /**\n * Axis-aligned World-space bounding box that encloses the {@link XKTEntity}'s within this Tile.\n *\n * @type {Float64Array}\n */\n this.aabb = aabb;\n\n /**\n * The {@link XKTEntity}'s within this XKTTile.\n *\n * @type {XKTEntity[]}\n */\n this.entities = entities;\n }\n}\n\nexport {XKTTile};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/XKTTile.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/XKTTile.js", "access": "public", "description": null, "lineNumber": 1 @@ -4795,7 +4795,7 @@ "name": "src/XKTModel/lib/buildEdgeIndices.js", "content": "import {math} from \"../../lib/math.js\";\n\n/**\n * @private\n */\nconst buildEdgeIndices = (function () {\n\n const uniquePositions = [];\n const indicesLookup = [];\n const indicesReverseLookup = [];\n const weldedIndices = [];\n\n// TODO: Optimize with caching, but need to cater to both compressed and uncompressed positions\n\n const faces = [];\n let numFaces = 0;\n const compa = new Uint16Array(3);\n const compb = new Uint16Array(3);\n const compc = new Uint16Array(3);\n const a = math.vec3();\n const b = math.vec3();\n const c = math.vec3();\n const cb = math.vec3();\n const ab = math.vec3();\n const cross = math.vec3();\n const normal = math.vec3();\n const inverseNormal = math.vec3();\n\n function weldVertices(positions, indices) {\n const positionsMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n let vx;\n let vy;\n let vz;\n let key;\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = Math.pow(10, precisionPoints);\n let i;\n let len;\n let lenUniquePositions = 0;\n for (i = 0, len = positions.length; i < len; i += 3) {\n vx = positions[i];\n vy = positions[i + 1];\n vz = positions[i + 2];\n key = Math.round(vx * precision) + '_' + Math.round(vy * precision) + '_' + Math.round(vz * precision);\n if (positionsMap[key] === undefined) {\n positionsMap[key] = lenUniquePositions / 3;\n uniquePositions[lenUniquePositions++] = vx;\n uniquePositions[lenUniquePositions++] = vy;\n uniquePositions[lenUniquePositions++] = vz;\n }\n indicesLookup[i / 3] = positionsMap[key];\n }\n for (i = 0, len = indices.length; i < len; i++) {\n weldedIndices[i] = indicesLookup[indices[i]];\n indicesReverseLookup[weldedIndices[i]] = indices[i];\n }\n }\n\n function buildFaces(numIndices, positionsDecodeMatrix) {\n numFaces = 0;\n for (let i = 0, len = numIndices; i < len; i += 3) {\n const ia = ((weldedIndices[i]) * 3);\n const ib = ((weldedIndices[i + 1]) * 3);\n const ic = ((weldedIndices[i + 2]) * 3);\n if (positionsDecodeMatrix) {\n compa[0] = uniquePositions[ia];\n compa[1] = uniquePositions[ia + 1];\n compa[2] = uniquePositions[ia + 2];\n compb[0] = uniquePositions[ib];\n compb[1] = uniquePositions[ib + 1];\n compb[2] = uniquePositions[ib + 2];\n compc[0] = uniquePositions[ic];\n compc[1] = uniquePositions[ic + 1];\n compc[2] = uniquePositions[ic + 2];\n // Decode\n math.decompressPosition(compa, positionsDecodeMatrix, a);\n math.decompressPosition(compb, positionsDecodeMatrix, b);\n math.decompressPosition(compc, positionsDecodeMatrix, c);\n } else {\n a[0] = uniquePositions[ia];\n a[1] = uniquePositions[ia + 1];\n a[2] = uniquePositions[ia + 2];\n b[0] = uniquePositions[ib];\n b[1] = uniquePositions[ib + 1];\n b[2] = uniquePositions[ib + 2];\n c[0] = uniquePositions[ic];\n c[1] = uniquePositions[ic + 1];\n c[2] = uniquePositions[ic + 2];\n }\n math.subVec3(c, b, cb);\n math.subVec3(a, b, ab);\n math.cross3Vec3(cb, ab, cross);\n math.normalizeVec3(cross, normal);\n const face = faces[numFaces] || (faces[numFaces] = {normal: math.vec3()});\n face.normal[0] = normal[0];\n face.normal[1] = normal[1];\n face.normal[2] = normal[2];\n numFaces++;\n }\n }\n\n return function (positions, indices, positionsDecodeMatrix, edgeThreshold) {\n weldVertices(positions, indices);\n buildFaces(indices.length, positionsDecodeMatrix);\n const edgeIndices = [];\n const thresholdDot = Math.cos(math.DEGTORAD * edgeThreshold);\n const edges = {};\n let edge1;\n let edge2;\n let index1;\n let index2;\n let key;\n let largeIndex = false;\n let edge;\n let normal1;\n let normal2;\n let dot;\n let ia;\n let ib;\n for (let i = 0, len = indices.length; i < len; i += 3) {\n const faceIndex = i / 3;\n for (let j = 0; j < 3; j++) {\n edge1 = weldedIndices[i + j];\n edge2 = weldedIndices[i + ((j + 1) % 3)];\n index1 = Math.min(edge1, edge2);\n index2 = Math.max(edge1, edge2);\n key = index1 + ',' + index2;\n if (edges[key] === undefined) {\n edges[key] = {\n index1: index1,\n index2: index2,\n face1: faceIndex,\n face2: undefined,\n };\n } else {\n edges[key].face2 = faceIndex;\n }\n }\n }\n for (key in edges) {\n edge = edges[key];\n // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n if (edge.face2 !== undefined) {\n normal1 = faces[edge.face1].normal;\n normal2 = faces[edge.face2].normal;\n inverseNormal[0] = -normal2[0];\n inverseNormal[1] = -normal2[1];\n inverseNormal[2] = -normal2[2];\n dot = Math.abs(math.dotVec3(normal1, normal2));\n const dot2 = Math.abs(math.dotVec3(normal1, inverseNormal));\n if (dot > thresholdDot && dot2 > thresholdDot) {\n continue;\n }\n }\n ia = indicesReverseLookup[edge.index1];\n ib = indicesReverseLookup[edge.index2];\n if (!largeIndex && ia > 65535 || ib > 65535) {\n largeIndex = true;\n }\n edgeIndices.push(ia);\n edgeIndices.push(ib);\n }\n return (largeIndex) ? new Uint32Array(edgeIndices) : new Uint16Array(edgeIndices);\n };\n})();\n\n\nexport {buildEdgeIndices};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/buildEdgeIndices.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/buildEdgeIndices.js", "access": "public", "description": null, "lineNumber": 1 @@ -4826,7 +4826,7 @@ "name": "src/XKTModel/lib/buildFaceNormals.js", "content": "import {math} from \"./math.js\";\n\n/**\n * Builds face-aligned vertex normal vectors from positions and indices.\n *\n * @private\n */\nfunction buildFaceNormals(positions, indices, normals) {\n\n const a = math.vec3();\n const b = math.vec3();\n const c = math.vec3();\n\n const normVec = math.vec3();\n\n for (let i = 0, len = indices.length; i < len; i += 3) {\n\n const j0 = indices[i];\n const j1 = indices[i + 1];\n const j2 = indices[i + 2];\n\n a[0] = positions[j0 * 3];\n a[1] = positions[j0 * 3 + 1];\n a[2] = positions[j0 * 3 + 2];\n\n b[0] = positions[j1 * 3];\n b[1] = positions[j1 * 3 + 1];\n b[2] = positions[j1 * 3 + 2];\n\n c[0] = positions[j2 * 3];\n c[1] = positions[j2 * 3 + 1];\n c[2] = positions[j2 * 3 + 2];\n\n triangleNormal(a,b,c, normVec);\n\n normals[j0 * 3 + 0] = normVec[0];\n normals[j0 * 3 + 1] = normVec[1];\n normals[j0 * 3 + 2] = normVec[2];\n\n normals[j1 * 3 + 0] = normVec[0];\n normals[j1 * 3 + 1] = normVec[1];\n normals[j1 * 3 + 2] = normVec[2];\n\n normals[j2 * 3 + 0] = normVec[0];\n normals[j2 * 3 + 1] = normVec[1];\n normals[j2 * 3 + 2] = normVec[2];\n }\n}\n\nfunction triangleNormal(a, b, c, normal = math.vec3()) {\n const p1x = b[0] - a[0];\n const p1y = b[1] - a[1];\n const p1z = b[2] - a[2];\n\n const p2x = c[0] - a[0];\n const p2y = c[1] - a[1];\n const p2z = c[2] - a[2];\n\n const p3x = p1y * p2z - p1z * p2y;\n const p3y = p1z * p2x - p1x * p2z;\n const p3z = p1x * p2y - p1y * p2x;\n\n const mag = Math.sqrt(p3x * p3x + p3y * p3y + p3z * p3z);\n if (mag === 0) {\n normal[0] = 0;\n normal[1] = 0;\n normal[2] = 0;\n } else {\n normal[0] = p3x / mag;\n normal[1] = p3y / mag;\n normal[2] = p3z / mag;\n }\n\n return normal\n}\n\nexport {buildFaceNormals};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/buildFaceNormals.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/buildFaceNormals.js", "access": "public", "description": null, "lineNumber": 1 @@ -4925,7 +4925,7 @@ "name": "src/XKTModel/lib/buildVertexNormals.js", "content": "import {math} from \"./math.js\";\n\n/**\n * Builds vertex normal vectors from positions and indices.\n *\n * @private\n */\nfunction buildVertexNormals(positions, indices, normals) {\n\n const a = math.vec3();\n const b = math.vec3();\n const c = math.vec3();\n const ab = math.vec3();\n const ac = math.vec3();\n const crossVec = math.vec3();\n const nvecs = new Array(positions.length / 3);\n\n for (let i = 0, len = indices.length; i < len; i += 3) {\n\n const j0 = indices[i];\n const j1 = indices[i + 1];\n const j2 = indices[i + 2];\n\n a[0] = positions[j0 * 3];\n a[1] = positions[j0 * 3 + 1];\n a[2] = positions[j0 * 3 + 2];\n\n b[0] = positions[j1 * 3];\n b[1] = positions[j1 * 3 + 1];\n b[2] = positions[j1 * 3 + 2];\n\n c[0] = positions[j2 * 3];\n c[1] = positions[j2 * 3 + 1];\n c[2] = positions[j2 * 3 + 2];\n\n math.subVec3(b, a, ab);\n math.subVec3(c, a, ac);\n\n const normVec = math.vec3();\n\n math.normalizeVec3(math.cross3Vec3(ab, ac, crossVec), normVec);\n\n if (!nvecs[j0]) {\n nvecs[j0] = [];\n }\n if (!nvecs[j1]) {\n nvecs[j1] = [];\n }\n if (!nvecs[j2]) {\n nvecs[j2] = [];\n }\n\n nvecs[j0].push(normVec);\n nvecs[j1].push(normVec);\n nvecs[j2].push(normVec);\n }\n\n normals = (normals && normals.length === positions.length) ? normals : new Float32Array(positions.length);\n\n for (let i = 0, len = nvecs.length; i < len; i++) { // Now go through and average out everything\n\n const count = nvecs[i].length;\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n for (let j = 0; j < count; j++) {\n x += nvecs[i][j][0];\n y += nvecs[i][j][1];\n z += nvecs[i][j][2];\n }\n\n normals[i * 3] = (x / count);\n normals[i * 3 + 1] = (y / count);\n normals[i * 3 + 2] = (z / count);\n }\n\n return normals;\n}\n\nexport {buildVertexNormals};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/buildVertexNormals.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/buildVertexNormals.js", "access": "public", "description": null, "lineNumber": 1 @@ -4978,7 +4978,7 @@ "name": "src/XKTModel/lib/earcut.js", "content": "/** @private */\nfunction earcut(data, holeIndices, dim) {\n\n dim = dim || 2;\n\n var hasHoles = holeIndices && holeIndices.length,\n outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n outerNode = linkedList(data, 0, outerLen, dim, true),\n triangles = [];\n\n if (!outerNode || outerNode.next === outerNode.prev) return triangles;\n\n var minX, minY, maxX, maxY, x, y, invSize;\n\n if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n if (data.length > 80 * dim) {\n minX = maxX = data[0];\n minY = maxY = data[1];\n\n for (var i = dim; i < outerLen; i += dim) {\n x = data[i];\n y = data[i + 1];\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n }\n\n // minX, minY and invSize are later used to transform coords into integers for z-order calculation\n invSize = Math.max(maxX - minX, maxY - minY);\n invSize = invSize !== 0 ? 1 / invSize : 0;\n }\n\n earcutLinked(outerNode, triangles, dim, minX, minY, invSize);\n\n return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList(data, start, end, dim, clockwise) {\n var i, last;\n\n if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n } else {\n for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n }\n\n if (last && equals(last, last.next)) {\n removeNode(last);\n last = last.next;\n }\n\n return last;\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints(start, end) {\n if (!start) return start;\n if (!end) end = start;\n\n var p = start,\n again;\n do {\n again = false;\n\n if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n removeNode(p);\n p = end = p.prev;\n if (p === p.next) break;\n again = true;\n\n } else {\n p = p.next;\n }\n } while (again || p !== end);\n\n return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {\n if (!ear) return;\n\n // interlink polygon nodes in z-order\n if (!pass && invSize) indexCurve(ear, minX, minY, invSize);\n\n var stop = ear,\n prev, next;\n\n // iterate through ears, slicing them one by one\n while (ear.prev !== ear.next) {\n prev = ear.prev;\n next = ear.next;\n\n if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {\n // cut off the triangle\n triangles.push(prev.i / dim);\n triangles.push(ear.i / dim);\n triangles.push(next.i / dim);\n\n removeNode(ear);\n\n // skipping the next vertex leads to less sliver triangles\n ear = next.next;\n stop = next.next;\n\n continue;\n }\n\n ear = next;\n\n // if we looped through the whole remaining polygon and can't find any more ears\n if (ear === stop) {\n // try filtering points and slicing again\n if (!pass) {\n earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);\n\n // if this didn't work, try curing all small self-intersections locally\n } else if (pass === 1) {\n ear = cureLocalIntersections(filterPoints(ear), triangles, dim);\n earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);\n\n // as a last resort, try splitting the remaining polygon into two\n } else if (pass === 2) {\n splitEarcut(ear, triangles, dim, minX, minY, invSize);\n }\n\n break;\n }\n }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar(ear) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // now make sure we don't have other points inside the potential ear\n var p = ear.next.next;\n\n while (p !== ear.prev) {\n if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.next;\n }\n\n return true;\n}\n\nfunction isEarHashed(ear, minX, minY, invSize) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // triangle bbox; min & max are calculated like this for speed\n var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\n // z-order range for the current triangle bbox;\n var minZ = zOrder(minTX, minTY, minX, minY, invSize),\n maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);\n\n var p = ear.prevZ,\n n = ear.nextZ;\n\n // look for points inside the triangle in both directions\n while (p && p.z >= minZ && n && n.z <= maxZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n\n if (n !== ear.prev && n !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&\n area(n.prev, n, n.next) >= 0) return false;\n n = n.nextZ;\n }\n\n // look for remaining points in decreasing z-order\n while (p && p.z >= minZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n }\n\n // look for remaining points in increasing z-order\n while (n && n.z <= maxZ) {\n if (n !== ear.prev && n !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&\n area(n.prev, n, n.next) >= 0) return false;\n n = n.nextZ;\n }\n\n return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections(start, triangles, dim) {\n var p = start;\n do {\n var a = p.prev,\n b = p.next.next;\n\n if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\n triangles.push(a.i / dim);\n triangles.push(p.i / dim);\n triangles.push(b.i / dim);\n\n // remove two nodes involved\n removeNode(p);\n removeNode(p.next);\n\n p = start = b;\n }\n p = p.next;\n } while (p !== start);\n\n return filterPoints(p);\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut(start, triangles, dim, minX, minY, invSize) {\n // look for a valid diagonal that divides the polygon into two\n var a = start;\n do {\n var b = a.next.next;\n while (b !== a.prev) {\n if (a.i !== b.i && isValidDiagonal(a, b)) {\n // split the polygon in two by the diagonal\n var c = splitPolygon(a, b);\n\n // filter colinear points around the cuts\n a = filterPoints(a, a.next);\n c = filterPoints(c, c.next);\n\n // run earcut on each half\n earcutLinked(a, triangles, dim, minX, minY, invSize);\n earcutLinked(c, triangles, dim, minX, minY, invSize);\n return;\n }\n b = b.next;\n }\n a = a.next;\n } while (a !== start);\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n var queue = [],\n i, len, start, end, list;\n\n for (i = 0, len = holeIndices.length; i < len; i++) {\n start = holeIndices[i] * dim;\n end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n list = linkedList(data, start, end, dim, false);\n if (list === list.next) list.steiner = true;\n queue.push(getLeftmost(list));\n }\n\n queue.sort(compareX);\n\n // process holes from left to right\n for (i = 0; i < queue.length; i++) {\n eliminateHole(queue[i], outerNode);\n outerNode = filterPoints(outerNode, outerNode.next);\n }\n\n return outerNode;\n}\n\nfunction compareX(a, b) {\n return a.x - b.x;\n}\n\n// find a bridge between vertices that connects hole with an outer ring and and link it\nfunction eliminateHole(hole, outerNode) {\n outerNode = findHoleBridge(hole, outerNode);\n if (outerNode) {\n var b = splitPolygon(outerNode, hole);\n\n // filter collinear points around the cuts\n filterPoints(outerNode, outerNode.next);\n filterPoints(b, b.next);\n }\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge(hole, outerNode) {\n var p = outerNode,\n hx = hole.x,\n hy = hole.y,\n qx = -Infinity,\n m;\n\n // find a segment intersected by a ray from the hole's leftmost point to the left;\n // segment's endpoint with lesser x will be potential connection point\n do {\n if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {\n var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n if (x <= hx && x > qx) {\n qx = x;\n if (x === hx) {\n if (hy === p.y) return p;\n if (hy === p.next.y) return p.next;\n }\n m = p.x < p.next.x ? p : p.next;\n }\n }\n p = p.next;\n } while (p !== outerNode);\n\n if (!m) return null;\n\n if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint\n\n // look for points inside the triangle of hole point, segment intersection and endpoint;\n // if there are no points found, we have a valid connection;\n // otherwise choose the point of the minimum angle with the ray as connection point\n\n var stop = m,\n mx = m.x,\n my = m.y,\n tanMin = Infinity,\n tan;\n\n p = m;\n\n do {\n if (hx >= p.x && p.x >= mx && hx !== p.x &&\n pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\n tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n if (locallyInside(p, hole) &&\n (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {\n m = p;\n tanMin = tan;\n }\n }\n\n p = p.next;\n } while (p !== stop);\n\n return m;\n}\n\n// whether sector in vertex m contains sector in vertex p in the same coordinates\nfunction sectorContainsSector(m, p) {\n return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve(start, minX, minY, invSize) {\n var p = start;\n do {\n if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize);\n p.prevZ = p.prev;\n p.nextZ = p.next;\n p = p.next;\n } while (p !== start);\n\n p.prevZ.nextZ = null;\n p.prevZ = null;\n\n sortLinked(p);\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked(list) {\n var i, p, q, e, tail, numMerges, pSize, qSize,\n inSize = 1;\n\n do {\n p = list;\n list = null;\n tail = null;\n numMerges = 0;\n\n while (p) {\n numMerges++;\n q = p;\n pSize = 0;\n for (i = 0; i < inSize; i++) {\n pSize++;\n q = q.nextZ;\n if (!q) break;\n }\n qSize = inSize;\n\n while (pSize > 0 || (qSize > 0 && q)) {\n\n if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else {\n e = q;\n q = q.nextZ;\n qSize--;\n }\n\n if (tail) tail.nextZ = e;\n else list = e;\n\n e.prevZ = tail;\n tail = e;\n }\n\n p = q;\n }\n\n tail.nextZ = null;\n inSize *= 2;\n\n } while (numMerges > 1);\n\n return list;\n}\n\n// z-order of a point given coords and inverse of the longer side of data bbox\nfunction zOrder(x, y, minX, minY, invSize) {\n // coords are transformed into non-negative 15-bit integer range\n x = 32767 * (x - minX) * invSize;\n y = 32767 * (y - minY) * invSize;\n\n x = (x | (x << 8)) & 0x00FF00FF;\n x = (x | (x << 4)) & 0x0F0F0F0F;\n x = (x | (x << 2)) & 0x33333333;\n x = (x | (x << 1)) & 0x55555555;\n\n y = (y | (y << 8)) & 0x00FF00FF;\n y = (y | (y << 4)) & 0x0F0F0F0F;\n y = (y | (y << 2)) & 0x33333333;\n y = (y | (y << 1)) & 0x55555555;\n\n return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost(start) {\n var p = start,\n leftmost = start;\n do {\n if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;\n p = p.next;\n } while (p !== start);\n\n return leftmost;\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal(a, b) {\n return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges\n (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible\n (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors\n equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case\n}\n\n// signed area of a triangle\nfunction area(p, q, r) {\n return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\nfunction equals(p1, p2) {\n return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect\nfunction intersects(p1, q1, p2, q2) {\n var o1 = sign(area(p1, q1, p2));\n var o2 = sign(area(p1, q1, q2));\n var o3 = sign(area(p2, q2, p1));\n var o4 = sign(area(p2, q2, q1));\n\n if (o1 !== o2 && o3 !== o4) return true; // general case\n\n if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1\n if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1\n if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2\n if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2\n\n return false;\n}\n\n// for collinear points p, q, r, check if point q lies on segment pr\nfunction onSegment(p, q, r) {\n return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);\n}\n\nfunction sign(num) {\n return num > 0 ? 1 : num < 0 ? -1 : 0;\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon(a, b) {\n var p = a;\n do {\n if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n intersects(p, p.next, a, b)) return true;\n p = p.next;\n } while (p !== a);\n\n return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside(a, b) {\n return area(a.prev, a, a.next) < 0 ?\n area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside(a, b) {\n var p = a,\n inside = false,\n px = (a.x + b.x) / 2,\n py = (a.y + b.y) / 2;\n do {\n if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&\n (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n inside = !inside;\n p = p.next;\n } while (p !== a);\n\n return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon(a, b) {\n var a2 = new Node(a.i, a.x, a.y),\n b2 = new Node(b.i, b.x, b.y),\n an = a.next,\n bp = b.prev;\n\n a.next = b;\n b.prev = a;\n\n a2.next = an;\n an.prev = a2;\n\n b2.next = a2;\n a2.prev = b2;\n\n bp.next = b2;\n b2.prev = bp;\n\n return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode(i, x, y, last) {\n var p = new Node(i, x, y);\n\n if (!last) {\n p.prev = p;\n p.next = p;\n\n } else {\n p.next = last.next;\n p.prev = last;\n last.next.prev = p;\n last.next = p;\n }\n return p;\n}\n\nfunction removeNode(p) {\n p.next.prev = p.prev;\n p.prev.next = p.next;\n\n if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n}\n\nfunction Node(i, x, y) {\n // vertex index in coordinates array\n this.i = i;\n\n // vertex coordinates\n this.x = x;\n this.y = y;\n\n // previous and next vertex nodes in a polygon ring\n this.prev = null;\n this.next = null;\n\n // z-order curve value\n this.z = null;\n\n // previous and next nodes in z-order\n this.prevZ = null;\n this.nextZ = null;\n\n // indicates whether this is a steiner point\n this.steiner = false;\n}\n\n// return a percentage difference between the polygon area and its triangulation area;\n// used to verify correctness of triangulation\nearcut.deviation = function (data, holeIndices, dim, triangles) {\n var hasHoles = holeIndices && holeIndices.length;\n var outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\n var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n if (hasHoles) {\n for (var i = 0, len = holeIndices.length; i < len; i++) {\n var start = holeIndices[i] * dim;\n var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n polygonArea -= Math.abs(signedArea(data, start, end, dim));\n }\n }\n\n var trianglesArea = 0;\n for (i = 0; i < triangles.length; i += 3) {\n var a = triangles[i] * dim;\n var b = triangles[i + 1] * dim;\n var c = triangles[i + 2] * dim;\n trianglesArea += Math.abs(\n (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n }\n\n return polygonArea === 0 && trianglesArea === 0 ? 0 :\n Math.abs((trianglesArea - polygonArea) / polygonArea);\n};\n\nfunction signedArea(data, start, end, dim) {\n var sum = 0;\n for (var i = start, j = end - dim; i < end; i += dim) {\n sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n j = i;\n }\n return sum;\n}\n\n// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\nearcut.flatten = function (data) {\n var dim = data[0][0].length,\n result = {vertices: [], holes: [], dimensions: dim},\n holeIndex = 0;\n\n for (var i = 0; i < data.length; i++) {\n for (var j = 0; j < data[i].length; j++) {\n for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);\n }\n if (i > 0) {\n holeIndex += data[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n return result;\n};\n\nexport {earcut};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/earcut.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/earcut.js", "access": "public", "description": null, "lineNumber": 1 @@ -6426,7 +6426,7 @@ "name": "src/XKTModel/lib/faceToVertexNormals.js", "content": "import {math} from \"./math.js\";\n\n/**\n * Converts surface-perpendicular face normals to vertex normals. Assumes that the mesh contains disjoint triangles\n * that don't share vertex array elements. Works by finding groups of vertices that have the same location and\n * averaging their normal vectors.\n *\n * @returns {{positions: Array, normals: *}}\n * @private\n */\nfunction faceToVertexNormals(positions, normals, options = {}) {\n const smoothNormalsAngleThreshold = options.smoothNormalsAngleThreshold || 20;\n const vertexMap = {};\n const vertexNormals = [];\n const vertexNormalAccum = {};\n let acc;\n let vx;\n let vy;\n let vz;\n let key;\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = 10 ** precisionPoints;\n let posi;\n let i;\n let j;\n let len;\n let a;\n let b;\n let c;\n\n for (i = 0, len = positions.length; i < len; i += 3) {\n\n posi = i / 3;\n\n vx = positions[i];\n vy = positions[i + 1];\n vz = positions[i + 2];\n\n key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`;\n\n if (vertexMap[key] === undefined) {\n vertexMap[key] = [posi];\n } else {\n vertexMap[key].push(posi);\n }\n\n const normal = math.normalizeVec3([normals[i], normals[i + 1], normals[i + 2]]);\n\n vertexNormals[posi] = normal;\n\n acc = math.vec4([normal[0], normal[1], normal[2], 1]);\n\n vertexNormalAccum[posi] = acc;\n }\n\n for (key in vertexMap) {\n\n if (vertexMap.hasOwnProperty(key)) {\n\n const vertices = vertexMap[key];\n const numVerts = vertices.length;\n\n for (i = 0; i < numVerts; i++) {\n\n const ii = vertices[i];\n\n acc = vertexNormalAccum[ii];\n\n for (j = 0; j < numVerts; j++) {\n\n if (i === j) {\n continue;\n }\n\n const jj = vertices[j];\n\n a = vertexNormals[ii];\n b = vertexNormals[jj];\n\n const angle = Math.abs(math.angleVec3(a, b) / math.DEGTORAD);\n\n if (angle < smoothNormalsAngleThreshold) {\n\n acc[0] += b[0];\n acc[1] += b[1];\n acc[2] += b[2];\n acc[3] += 1.0;\n }\n }\n }\n }\n }\n\n for (i = 0, len = normals.length; i < len; i += 3) {\n\n acc = vertexNormalAccum[i / 3];\n\n normals[i + 0] = acc[0] / acc[3];\n normals[i + 1] = acc[1] / acc[3];\n normals[i + 2] = acc[2] / acc[3];\n\n }\n}\n\nexport {faceToVertexNormals};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/faceToVertexNormals.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/faceToVertexNormals.js", "access": "public", "description": null, "lineNumber": 1 @@ -6491,7 +6491,7 @@ "name": "src/XKTModel/lib/geometryCompression.js", "content": "import {math} from \"../../lib/math.js\";\n\nfunction quantizePositions (positions, lenPositions, aabb, quantizedPositions) {\n const xmin = aabb[0];\n const ymin = aabb[1];\n const zmin = aabb[2];\n const xwid = aabb[3] - xmin;\n const ywid = aabb[4] - ymin;\n const zwid = aabb[5] - zmin;\n const maxInt = 65535;\n const xMultiplier = maxInt / xwid;\n const yMultiplier = maxInt / ywid;\n const zMultiplier = maxInt / zwid;\n const verify = (num) => num >= 0 ? num : 0;\n for (let i = 0; i < lenPositions; i += 3) {\n quantizedPositions[i + 0] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 0] - xmin) * xMultiplier)));\n quantizedPositions[i + 1] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 1] - ymin) * yMultiplier)));\n quantizedPositions[i + 2] = Math.max(0, Math.min(65535,Math.floor(verify(positions[i + 2] - zmin) * zMultiplier)));\n }\n}\n\nfunction compressPosition(p, aabb, q) {\n const multiplier = new Float32Array([\n aabb[3] !== aabb[0] ? 65535 / (aabb[3] - aabb[0]) : 0,\n aabb[4] !== aabb[1] ? 65535 / (aabb[4] - aabb[1]) : 0,\n aabb[5] !== aabb[2] ? 65535 / (aabb[5] - aabb[2]) : 0\n ]);\n q[0] = Math.max(0, Math.min(65535, Math.floor((p[0] - aabb[0]) * multiplier[0])));\n q[1] = Math.max(0, Math.min(65535, Math.floor((p[1] - aabb[1]) * multiplier[1])));\n q[2] = Math.max(0, Math.min(65535, Math.floor((p[2] - aabb[2]) * multiplier[2])));\n}\n\nvar createPositionsDecodeMatrix = (function () {\n const translate = math.mat4();\n const scale = math.mat4();\n return function (aabb, positionsDecodeMatrix) {\n positionsDecodeMatrix = positionsDecodeMatrix || math.mat4();\n const xmin = aabb[0];\n const ymin = aabb[1];\n const zmin = aabb[2];\n const xwid = aabb[3] - xmin;\n const ywid = aabb[4] - ymin;\n const zwid = aabb[5] - zmin;\n const maxInt = 65535;\n math.identityMat4(translate);\n math.translationMat4v(aabb, translate);\n math.identityMat4(scale);\n math.scalingMat4v([xwid / maxInt, ywid / maxInt, zwid / maxInt], scale);\n math.mulMat4(translate, scale, positionsDecodeMatrix);\n return positionsDecodeMatrix;\n };\n})();\n\nfunction transformAndOctEncodeNormals(modelNormalMatrix, normals, lenNormals, compressedNormals, lenCompressedNormals) {\n // http://jcgt.org/published/0003/02/01/\n let oct, dec, best, currentCos, bestCos;\n let i, ei;\n let localNormal = math.vec3();\n let worldNormal = math.vec3();\n for (i = 0; i < lenNormals; i += 3) {\n localNormal[0] = normals[i];\n localNormal[1] = normals[i + 1];\n localNormal[2] = normals[i + 2];\n\n math.transformVec3(modelNormalMatrix, localNormal, worldNormal);\n math.normalizeVec3(worldNormal, worldNormal);\n\n // Test various combinations of ceil and floor to minimize rounding errors\n best = oct = octEncodeVec3(worldNormal, 0, \"floor\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = bestCos = dot(worldNormal, 0, dec);\n oct = octEncodeVec3(worldNormal, 0, \"ceil\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = dot(worldNormal, 0, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(worldNormal, 0, \"floor\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(worldNormal, 0, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(worldNormal, 0, \"ceil\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(worldNormal, 0, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n compressedNormals[lenCompressedNormals + i + 0] = best[0];\n compressedNormals[lenCompressedNormals + i + 1] = best[1];\n compressedNormals[lenCompressedNormals + i + 2] = 0.0; // Unused\n }\n lenCompressedNormals += lenNormals;\n return lenCompressedNormals;\n}\n\nfunction octEncodeNormals(normals, lenNormals, compressedNormals, lenCompressedNormals) { // http://jcgt.org/published/0003/02/01/\n let oct, dec, best, currentCos, bestCos;\n for (let i = 0; i < lenNormals; i += 3) {\n // Test various combinations of ceil and floor to minimize rounding errors\n best = oct = octEncodeVec3(normals, i, \"floor\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = bestCos = dot(normals, i, dec);\n oct = octEncodeVec3(normals, i, \"ceil\", \"floor\");\n dec = octDecodeVec2(oct);\n currentCos = dot(normals, i, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(normals, i, \"floor\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(normals, i, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n oct = octEncodeVec3(normals, i, \"ceil\", \"ceil\");\n dec = octDecodeVec2(oct);\n currentCos = dot(normals, i, dec);\n if (currentCos > bestCos) {\n best = oct;\n bestCos = currentCos;\n }\n compressedNormals[lenCompressedNormals + i + 0] = best[0];\n compressedNormals[lenCompressedNormals + i + 1] = best[1];\n compressedNormals[lenCompressedNormals + i + 2] = 0.0; // Unused\n }\n lenCompressedNormals += lenNormals;\n return lenCompressedNormals;\n}\n\n/**\n * @private\n */\nfunction octEncodeVec3(array, i, xfunc, yfunc) { // Oct-encode single normal vector in 2 bytes\n let x = array[i] / (Math.abs(array[i]) + Math.abs(array[i + 1]) + Math.abs(array[i + 2]));\n let y = array[i + 1] / (Math.abs(array[i]) + Math.abs(array[i + 1]) + Math.abs(array[i + 2]));\n if (array[i + 2] < 0) {\n let tempx = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n let tempy = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n x = tempx;\n y = tempy;\n }\n return new Int8Array([\n Math[xfunc](x * 127.5 + (x < 0 ? -1 : 0)),\n Math[yfunc](y * 127.5 + (y < 0 ? -1 : 0))\n ]);\n}\n\n/**\n * Decode an oct-encoded normal\n */\nfunction octDecodeVec2(oct) {\n let x = oct[0];\n let y = oct[1];\n x /= x < 0 ? 127 : 128;\n y /= y < 0 ? 127 : 128;\n const z = 1 - Math.abs(x) - Math.abs(y);\n if (z < 0) {\n x = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n y = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n }\n const length = Math.sqrt(x * x + y * y + z * z);\n return [\n x / length,\n y / length,\n z / length\n ];\n}\n\n/**\n * Dot product of a normal in an array against a candidate decoding\n * @private\n */\nfunction dot(array, i, vec3) {\n return array[i] * vec3[0] + array[i + 1] * vec3[1] + array[i + 2] * vec3[2];\n}\n\n/**\n * @private\n */\nconst geometryCompression = {\n quantizePositions,\n compressPosition,\n createPositionsDecodeMatrix,\n transformAndOctEncodeNormals,\n octEncodeNormals,\n};\n\nexport {geometryCompression}", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/geometryCompression.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/geometryCompression.js", "access": "public", "description": null, "lineNumber": 1 @@ -6851,7 +6851,7 @@ "name": "src/XKTModel/lib/isTriangleMeshSolid.js", "content": "/**\n * Uses edge adjacency counts to identify if the given triangle mesh can be rendered with backface culling enabled.\n *\n * If all edges are connected to exactly two triangles, then the mesh will likely be a closed solid, and we can safely\n * render it with backface culling enabled.\n *\n * Otherwise, the mesh is a surface, and we must render it with backface culling disabled.\n *\n * @private\n */\nconst isTriangleMeshSolid = (indices, positions, vertexIndexMapping, edges) => {\n\n function compareIndexPositions(a, b)\n {\n let posA, posB;\n\n for (let i = 0; i < 3; i++) {\n posA = positions [a*3+i];\n posB = positions [b*3+i];\n\n if (posA !== posB) {\n return posB - posA;\n }\n }\n\n return 0;\n };\n\n // Group together indices corresponding to same position coordinates\n let newIndices = indices.slice ().sort (compareIndexPositions);\n\n // Calculate the mapping:\n // - from original index in indices array\n // - to indices-for-unique-positions\n let uniqueVertexIndex = null;\n\n for (let i = 0, len = newIndices.length; i < len; i++) {\n if (i == 0 || 0 != compareIndexPositions (\n newIndices[i],\n newIndices[i-1],\n )) {\n // different position\n uniqueVertexIndex = newIndices [i];\n }\n\n vertexIndexMapping [\n newIndices[i]\n ] = uniqueVertexIndex;\n }\n\n // Generate the list of edges\n for (let i = 0, len = indices.length; i < len; i += 3) {\n\n const a = vertexIndexMapping[indices[i]];\n const b = vertexIndexMapping[indices[i+1]];\n const c = vertexIndexMapping[indices[i+2]];\n\n let a2 = a;\n let b2 = b;\n let c2 = c;\n\n if (a > b && a > c) {\n if (b > c) {\n a2 = a;\n b2 = b;\n c2 = c;\n } else {\n a2 = a;\n b2 = c;\n c2 = b;\n }\n } else if (b > a && b > c) {\n if (a > c) {\n a2 = b;\n b2 = a;\n c2 = c;\n } else {\n a2 = b;\n b2 = c;\n c2 = a;\n }\n } else if (c > a && c > b) {\n if (a > b) {\n a2 = c;\n b2 = a;\n c2 = b;\n } else {\n a2 = c;\n b2 = b;\n c2 = a;\n }\n }\n\n edges[i+0] = [\n a2, b2\n ];\n edges[i+1] = [\n b2, c2\n ];\n\n if (a2 > c2) {\n const temp = c2;\n c2 = a2;\n a2 = temp;\n }\n\n edges[i+2] = [\n c2, a2\n ];\n }\n\n // Group semantically equivalent edgdes together\n function compareEdges (e1, e2) {\n let a, b;\n\n for (let i = 0; i < 2; i++) {\n a = e1[i];\n b = e2[i];\n\n if (b !== a) {\n return b - a;\n }\n }\n\n return 0;\n }\n\n edges = edges.slice(0, indices.length);\n\n edges.sort (compareEdges);\n\n // Make sure each edge is used exactly twice\n let sameEdgeCount = 0;\n\n for (let i = 0; i < edges.length; i++)\n {\n if (i === 0 || 0 !== compareEdges (\n edges[i], edges[i-1]\n )) {\n // different edge\n if (0 !== i && sameEdgeCount !== 2)\n {\n return false;\n }\n\n sameEdgeCount = 1;\n }\n else\n {\n // same edge\n sameEdgeCount++;\n }\n }\n\n if (edges.length > 0 && sameEdgeCount !== 2)\n {\n return false;\n }\n\n // Each edge is used exactly twice, this is a\n // watertight surface and hence a solid geometry.\n return true;\n};\n\nexport {isTriangleMeshSolid};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/isTriangleMeshSolid.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/isTriangleMeshSolid.js", "access": "public", "description": null, "lineNumber": 1 @@ -6910,7 +6910,7 @@ "name": "src/XKTModel/lib/math.js", "content": "// Some temporary vars to help avoid garbage collection\n\nconst doublePrecision = true;\nconst FloatArrayType = doublePrecision ? Float64Array : Float32Array;\n\nconst tempMat1 = new FloatArrayType(16);\nconst tempMat2 = new FloatArrayType(16);\nconst tempVec4 = new FloatArrayType(4);\n\n/**\n * @private\n */\nconst math = {\n\n MIN_DOUBLE: -Number.MAX_SAFE_INTEGER,\n MAX_DOUBLE: Number.MAX_SAFE_INTEGER,\n\n /**\n * The number of radiians in a degree (0.0174532925).\n * @property DEGTORAD\n * @type {Number}\n */\n DEGTORAD: 0.0174532925,\n\n /**\n * The number of degrees in a radian.\n * @property RADTODEG\n * @type {Number}\n */\n RADTODEG: 57.295779513,\n\n /**\n * Returns a new, uninitialized two-element vector.\n * @method vec2\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec2(values) {\n return new FloatArrayType(values || 2);\n },\n\n /**\n * Returns a new, uninitialized three-element vector.\n * @method vec3\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec3(values) {\n return new FloatArrayType(values || 3);\n },\n\n /**\n * Returns a new, uninitialized four-element vector.\n * @method vec4\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec4(values) {\n return new FloatArrayType(values || 4);\n },\n\n /**\n * Returns a new, uninitialized 3x3 matrix.\n * @method mat3\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n mat3(values) {\n return new FloatArrayType(values || 9);\n },\n\n /**\n * Converts a 3x3 matrix to 4x4\n * @method mat3ToMat4\n * @param mat3 3x3 matrix.\n * @param mat4 4x4 matrix\n * @static\n * @returns {Number[]}\n */\n mat3ToMat4(mat3, mat4 = new FloatArrayType(16)) {\n mat4[0] = mat3[0];\n mat4[1] = mat3[1];\n mat4[2] = mat3[2];\n mat4[3] = 0;\n mat4[4] = mat3[3];\n mat4[5] = mat3[4];\n mat4[6] = mat3[5];\n mat4[7] = 0;\n mat4[8] = mat3[6];\n mat4[9] = mat3[7];\n mat4[10] = mat3[8];\n mat4[11] = 0;\n mat4[12] = 0;\n mat4[13] = 0;\n mat4[14] = 0;\n mat4[15] = 1;\n return mat4;\n },\n\n /**\n * Returns a new, uninitialized 4x4 matrix.\n * @method mat4\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n mat4(values) {\n return new FloatArrayType(values || 16);\n },\n\n /**\n * Converts a 4x4 matrix to 3x3\n * @method mat4ToMat3\n * @param mat4 4x4 matrix.\n * @param mat3 3x3 matrix\n * @static\n * @returns {Number[]}\n */\n mat4ToMat3(mat4, mat3) { // TODO\n //return new FloatArrayType(values || 9);\n },\n\n /**\n * Returns a new UUID.\n * @method createUUID\n * @static\n * @return string The new UUID\n */\n createUUID: ((() => {\n const self = {};\n const lut = [];\n for (let i = 0; i < 256; i++) {\n lut[i] = (i < 16 ? '0' : '') + (i).toString(16);\n }\n return () => {\n const d0 = Math.random() * 0xffffffff | 0;\n const d1 = Math.random() * 0xffffffff | 0;\n const d2 = Math.random() * 0xffffffff | 0;\n const d3 = Math.random() * 0xffffffff | 0;\n return `${lut[d0 & 0xff] + lut[d0 >> 8 & 0xff] + lut[d0 >> 16 & 0xff] + lut[d0 >> 24 & 0xff]}-${lut[d1 & 0xff]}${lut[d1 >> 8 & 0xff]}-${lut[d1 >> 16 & 0x0f | 0x40]}${lut[d1 >> 24 & 0xff]}-${lut[d2 & 0x3f | 0x80]}${lut[d2 >> 8 & 0xff]}-${lut[d2 >> 16 & 0xff]}${lut[d2 >> 24 & 0xff]}${lut[d3 & 0xff]}${lut[d3 >> 8 & 0xff]}${lut[d3 >> 16 & 0xff]}${lut[d3 >> 24 & 0xff]}`;\n };\n }))(),\n\n /**\n * Clamps a value to the given range.\n * @param {Number} value Value to clamp.\n * @param {Number} min Lower bound.\n * @param {Number} max Upper bound.\n * @returns {Number} Clamped result.\n */\n clamp(value, min, max) {\n return Math.max(min, Math.min(max, value));\n },\n\n /**\n * Floating-point modulus\n * @method fmod\n * @static\n * @param {Number} a\n * @param {Number} b\n * @returns {*}\n */\n fmod(a, b) {\n if (a < b) {\n console.error(\"math.fmod : Attempting to find modulus within negative range - would be infinite loop - ignoring\");\n return a;\n }\n while (b <= a) {\n a -= b;\n }\n return a;\n },\n\n /**\n * Negates a four-element vector.\n * @method negateVec4\n * @static\n * @param {Array(Number)} v Vector to negate\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n negateVec4(v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = -v[0];\n dest[1] = -v[1];\n dest[2] = -v[2];\n dest[3] = -v[3];\n return dest;\n },\n\n /**\n * Adds one four-element vector to another.\n * @method addVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n addVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] + v[0];\n dest[1] = u[1] + v[1];\n dest[2] = u[2] + v[2];\n dest[3] = u[3] + v[3];\n return dest;\n },\n\n /**\n * Adds a scalar value to each element of a four-element vector.\n * @method addVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n addVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] + s;\n dest[1] = v[1] + s;\n dest[2] = v[2] + s;\n dest[3] = v[3] + s;\n return dest;\n },\n\n /**\n * Adds one three-element vector to another.\n * @method addVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n addVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] + v[0];\n dest[1] = u[1] + v[1];\n dest[2] = u[2] + v[2];\n return dest;\n },\n\n /**\n * Adds a scalar value to each element of a three-element vector.\n * @method addVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n addVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] + s;\n dest[1] = v[1] + s;\n dest[2] = v[2] + s;\n return dest;\n },\n\n /**\n * Subtracts one four-element vector from another.\n * @method subVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n dest[2] = u[2] - v[2];\n dest[3] = u[3] - v[3];\n return dest;\n },\n\n /**\n * Subtracts one three-element vector from another.\n * @method subVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n dest[2] = u[2] - v[2];\n return dest;\n },\n\n /**\n * Subtracts one two-element vector from another.\n * @method subVec2\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec2(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n return dest;\n },\n\n /**\n * Subtracts a scalar value from each element of a four-element vector.\n * @method subVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n subVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] - s;\n dest[1] = v[1] - s;\n dest[2] = v[2] - s;\n dest[3] = v[3] - s;\n return dest;\n },\n\n /**\n * Sets each element of a 4-element vector to a scalar value minus the value of that element.\n * @method subScalarVec4\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n subScalarVec4(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s - v[0];\n dest[1] = s - v[1];\n dest[2] = s - v[2];\n dest[3] = s - v[3];\n return dest;\n },\n\n /**\n * Multiplies one three-element vector by another.\n * @method mulVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n mulVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] * v[0];\n dest[1] = u[1] * v[1];\n dest[2] = u[2] * v[2];\n dest[3] = u[3] * v[3];\n return dest;\n },\n\n /**\n * Multiplies each element of a four-element vector by a scalar.\n * @method mulVec34calar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n dest[2] = v[2] * s;\n dest[3] = v[3] * s;\n return dest;\n },\n\n /**\n * Multiplies each element of a three-element vector by a scalar.\n * @method mulVec3Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n dest[2] = v[2] * s;\n return dest;\n },\n\n /**\n * Multiplies each element of a two-element vector by a scalar.\n * @method mulVec2Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec2Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n return dest;\n },\n\n /**\n * Divides one three-element vector by another.\n * @method divVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n divVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] / v[0];\n dest[1] = u[1] / v[1];\n dest[2] = u[2] / v[2];\n return dest;\n },\n\n /**\n * Divides one four-element vector by another.\n * @method divVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n divVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] / v[0];\n dest[1] = u[1] / v[1];\n dest[2] = u[2] / v[2];\n dest[3] = u[3] / v[3];\n return dest;\n },\n\n /**\n * Divides a scalar by a three-element vector, returning a new vector.\n * @method divScalarVec3\n * @static\n * @param v vec3\n * @param s scalar\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divScalarVec3(s, v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s / v[0];\n dest[1] = s / v[1];\n dest[2] = s / v[2];\n return dest;\n },\n\n /**\n * Divides a three-element vector by a scalar.\n * @method divVec3Scalar\n * @static\n * @param v vec3\n * @param s scalar\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] / s;\n dest[1] = v[1] / s;\n dest[2] = v[2] / s;\n return dest;\n },\n\n /**\n * Divides a four-element vector by a scalar.\n * @method divVec4Scalar\n * @static\n * @param v vec4\n * @param s scalar\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] / s;\n dest[1] = v[1] / s;\n dest[2] = v[2] / s;\n dest[3] = v[3] / s;\n return dest;\n },\n\n\n /**\n * Divides a scalar by a four-element vector, returning a new vector.\n * @method divScalarVec4\n * @static\n * @param s scalar\n * @param v vec4\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divScalarVec4(s, v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s / v[0];\n dest[1] = s / v[1];\n dest[2] = s / v[2];\n dest[3] = s / v[3];\n return dest;\n },\n\n /**\n * Returns the dot product of two four-element vectors.\n * @method dotVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec4(u, v) {\n return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2] + u[3] * v[3]);\n },\n\n /**\n * Returns the cross product of two four-element vectors.\n * @method cross3Vec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The cross product\n */\n cross3Vec4(u, v) {\n const u0 = u[0];\n const u1 = u[1];\n const u2 = u[2];\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n return [\n u1 * v2 - u2 * v1,\n u2 * v0 - u0 * v2,\n u0 * v1 - u1 * v0,\n 0.0];\n },\n\n /**\n * Returns the cross product of two three-element vectors.\n * @method cross3Vec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The cross product\n */\n cross3Vec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n const x = u[0];\n const y = u[1];\n const z = u[2];\n const x2 = v[0];\n const y2 = v[1];\n const z2 = v[2];\n dest[0] = y * z2 - z * y2;\n dest[1] = z * x2 - x * z2;\n dest[2] = x * y2 - y * x2;\n return dest;\n },\n\n\n sqLenVec4(v) { // TODO\n return math.dotVec4(v, v);\n },\n\n /**\n * Returns the length of a four-element vector.\n * @method lenVec4\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec4(v) {\n return Math.sqrt(math.sqLenVec4(v));\n },\n\n /**\n * Returns the dot product of two three-element vectors.\n * @method dotVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec3(u, v) {\n return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]);\n },\n\n /**\n * Returns the dot product of two two-element vectors.\n * @method dotVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec2(u, v) {\n return (u[0] * v[0] + u[1] * v[1]);\n },\n\n\n sqLenVec3(v) {\n return math.dotVec3(v, v);\n },\n\n\n sqLenVec2(v) {\n return math.dotVec2(v, v);\n },\n\n /**\n * Returns the length of a three-element vector.\n * @method lenVec3\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec3(v) {\n return Math.sqrt(math.sqLenVec3(v));\n },\n\n distVec3: ((() => {\n const vec = new FloatArrayType(3);\n return (v, w) => math.lenVec3(math.subVec3(v, w, vec));\n }))(),\n\n /**\n * Returns the length of a two-element vector.\n * @method lenVec2\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec2(v) {\n return Math.sqrt(math.sqLenVec2(v));\n },\n\n distVec2: ((() => {\n const vec = new FloatArrayType(2);\n return (v, w) => math.lenVec2(math.subVec2(v, w, vec));\n }))(),\n\n /**\n * @method rcpVec3\n * @static\n * @param v vec3\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n *\n */\n rcpVec3(v, dest) {\n return math.divScalarVec3(1.0, v, dest);\n },\n\n /**\n * Normalizes a four-element vector\n * @method normalizeVec4\n * @static\n * @param v vec4\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n *\n */\n normalizeVec4(v, dest) {\n const f = 1.0 / math.lenVec4(v);\n return math.mulVec4Scalar(v, f, dest);\n },\n\n /**\n * Normalizes a three-element vector\n * @method normalizeVec4\n * @static\n */\n normalizeVec3(v, dest) {\n const f = 1.0 / math.lenVec3(v);\n return math.mulVec3Scalar(v, f, dest);\n },\n\n /**\n * Normalizes a two-element vector\n * @method normalizeVec2\n * @static\n */\n normalizeVec2(v, dest) {\n const f = 1.0 / math.lenVec2(v);\n return math.mulVec2Scalar(v, f, dest);\n },\n\n /**\n * Gets the angle between two vectors\n * @method angleVec3\n * @param v\n * @param w\n * @returns {number}\n */\n angleVec3(v, w) {\n let theta = math.dotVec3(v, w) / (Math.sqrt(math.sqLenVec3(v) * math.sqLenVec3(w)));\n theta = theta < -1 ? -1 : (theta > 1 ? 1 : theta); // Clamp to handle numerical problems\n return Math.acos(theta);\n },\n\n /**\n * Creates a three-element vector from the rotation part of a sixteen-element matrix.\n * @param m\n * @param dest\n */\n vec3FromMat4Scale: ((() => {\n\n const tempVec3 = new FloatArrayType(3);\n\n return (m, dest) => {\n\n tempVec3[0] = m[0];\n tempVec3[1] = m[1];\n tempVec3[2] = m[2];\n\n dest[0] = math.lenVec3(tempVec3);\n\n tempVec3[0] = m[4];\n tempVec3[1] = m[5];\n tempVec3[2] = m[6];\n\n dest[1] = math.lenVec3(tempVec3);\n\n tempVec3[0] = m[8];\n tempVec3[1] = m[9];\n tempVec3[2] = m[10];\n\n dest[2] = math.lenVec3(tempVec3);\n\n return dest;\n };\n }))(),\n\n /**\n * Converts an n-element vector to a JSON-serializable\n * array with values rounded to two decimal places.\n */\n vecToArray: ((() => {\n function trunc(v) {\n return Math.round(v * 100000) / 100000\n }\n\n return v => {\n v = Array.prototype.slice.call(v);\n for (let i = 0, len = v.length; i < len; i++) {\n v[i] = trunc(v[i]);\n }\n return v;\n };\n }))(),\n\n /**\n * Converts a 3-element vector from an array to an object of the form ````{x:999, y:999, z:999}````.\n * @param arr\n * @returns {{x: *, y: *, z: *}}\n */\n xyzArrayToObject(arr) {\n return {\"x\": arr[0], \"y\": arr[1], \"z\": arr[2]};\n },\n\n /**\n * Converts a 3-element vector object of the form ````{x:999, y:999, z:999}```` to an array.\n * @param xyz\n * @param [arry]\n * @returns {*[]}\n */\n xyzObjectToArray(xyz, arry) {\n arry = arry || new FloatArrayType(3);\n arry[0] = xyz.x;\n arry[1] = xyz.y;\n arry[2] = xyz.z;\n return arry;\n },\n\n /**\n * Duplicates a 4x4 identity matrix.\n * @method dupMat4\n * @static\n */\n dupMat4(m) {\n return m.slice(0, 16);\n },\n\n /**\n * Extracts a 3x3 matrix from a 4x4 matrix.\n * @method mat4To3\n * @static\n */\n mat4To3(m) {\n return [\n m[0], m[1], m[2],\n m[4], m[5], m[6],\n m[8], m[9], m[10]\n ];\n },\n\n /**\n * Returns a 4x4 matrix with each element set to the given scalar value.\n * @method m4s\n * @static\n */\n m4s(s) {\n return [\n s, s, s, s,\n s, s, s, s,\n s, s, s, s,\n s, s, s, s\n ];\n },\n\n /**\n * Returns a 4x4 matrix with each element set to zero.\n * @method setMat4ToZeroes\n * @static\n */\n setMat4ToZeroes() {\n return math.m4s(0.0);\n },\n\n /**\n * Returns a 4x4 matrix with each element set to 1.0.\n * @method setMat4ToOnes\n * @static\n */\n setMat4ToOnes() {\n return math.m4s(1.0);\n },\n\n /**\n * Returns a 4x4 matrix with each element set to 1.0.\n * @method setMat4ToOnes\n * @static\n */\n diagonalMat4v(v) {\n return new FloatArrayType([\n v[0], 0.0, 0.0, 0.0,\n 0.0, v[1], 0.0, 0.0,\n 0.0, 0.0, v[2], 0.0,\n 0.0, 0.0, 0.0, v[3]\n ]);\n },\n\n /**\n * Returns a 4x4 matrix with diagonal elements set to the given vector.\n * @method diagonalMat4c\n * @static\n */\n diagonalMat4c(x, y, z, w) {\n return math.diagonalMat4v([x, y, z, w]);\n },\n\n /**\n * Returns a 4x4 matrix with diagonal elements set to the given scalar.\n * @method diagonalMat4s\n * @static\n */\n diagonalMat4s(s) {\n return math.diagonalMat4c(s, s, s, s);\n },\n\n /**\n * Returns a 4x4 identity matrix.\n * @method identityMat4\n * @static\n */\n identityMat4(mat = new FloatArrayType(16)) {\n mat[0] = 1.0;\n mat[1] = 0.0;\n mat[2] = 0.0;\n mat[3] = 0.0;\n\n mat[4] = 0.0;\n mat[5] = 1.0;\n mat[6] = 0.0;\n mat[7] = 0.0;\n\n mat[8] = 0.0;\n mat[9] = 0.0;\n mat[10] = 1.0;\n mat[11] = 0.0;\n\n mat[12] = 0.0;\n mat[13] = 0.0;\n mat[14] = 0.0;\n mat[15] = 1.0;\n\n return mat;\n },\n\n /**\n * Returns a 3x3 identity matrix.\n * @method identityMat3\n * @static\n */\n identityMat3(mat = new FloatArrayType(9)) {\n mat[0] = 1.0;\n mat[1] = 0.0;\n mat[2] = 0.0;\n\n mat[3] = 0.0;\n mat[4] = 1.0;\n mat[5] = 0.0;\n\n mat[6] = 0.0;\n mat[7] = 0.0;\n mat[8] = 1.0;\n\n return mat;\n },\n\n /**\n * Tests if the given 4x4 matrix is the identity matrix.\n * @method isIdentityMat4\n * @static\n */\n isIdentityMat4(m) {\n if (m[0] !== 1.0 || m[1] !== 0.0 || m[2] !== 0.0 || m[3] !== 0.0 ||\n m[4] !== 0.0 || m[5] !== 1.0 || m[6] !== 0.0 || m[7] !== 0.0 ||\n m[8] !== 0.0 || m[9] !== 0.0 || m[10] !== 1.0 || m[11] !== 0.0 ||\n m[12] !== 0.0 || m[13] !== 0.0 || m[14] !== 0.0 || m[15] !== 1.0) {\n return false;\n }\n return true;\n },\n\n /**\n * Negates the given 4x4 matrix.\n * @method negateMat4\n * @static\n */\n negateMat4(m, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = -m[0];\n dest[1] = -m[1];\n dest[2] = -m[2];\n dest[3] = -m[3];\n dest[4] = -m[4];\n dest[5] = -m[5];\n dest[6] = -m[6];\n dest[7] = -m[7];\n dest[8] = -m[8];\n dest[9] = -m[9];\n dest[10] = -m[10];\n dest[11] = -m[11];\n dest[12] = -m[12];\n dest[13] = -m[13];\n dest[14] = -m[14];\n dest[15] = -m[15];\n return dest;\n },\n\n /**\n * Adds the given 4x4 matrices together.\n * @method addMat4\n * @static\n */\n addMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n dest[0] = a[0] + b[0];\n dest[1] = a[1] + b[1];\n dest[2] = a[2] + b[2];\n dest[3] = a[3] + b[3];\n dest[4] = a[4] + b[4];\n dest[5] = a[5] + b[5];\n dest[6] = a[6] + b[6];\n dest[7] = a[7] + b[7];\n dest[8] = a[8] + b[8];\n dest[9] = a[9] + b[9];\n dest[10] = a[10] + b[10];\n dest[11] = a[11] + b[11];\n dest[12] = a[12] + b[12];\n dest[13] = a[13] + b[13];\n dest[14] = a[14] + b[14];\n dest[15] = a[15] + b[15];\n return dest;\n },\n\n /**\n * Adds the given scalar to each element of the given 4x4 matrix.\n * @method addMat4Scalar\n * @static\n */\n addMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] + s;\n dest[1] = m[1] + s;\n dest[2] = m[2] + s;\n dest[3] = m[3] + s;\n dest[4] = m[4] + s;\n dest[5] = m[5] + s;\n dest[6] = m[6] + s;\n dest[7] = m[7] + s;\n dest[8] = m[8] + s;\n dest[9] = m[9] + s;\n dest[10] = m[10] + s;\n dest[11] = m[11] + s;\n dest[12] = m[12] + s;\n dest[13] = m[13] + s;\n dest[14] = m[14] + s;\n dest[15] = m[15] + s;\n return dest;\n },\n\n /**\n * Adds the given scalar to each element of the given 4x4 matrix.\n * @method addScalarMat4\n * @static\n */\n addScalarMat4(s, m, dest) {\n return math.addMat4Scalar(m, s, dest);\n },\n\n /**\n * Subtracts the second 4x4 matrix from the first.\n * @method subMat4\n * @static\n */\n subMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n dest[0] = a[0] - b[0];\n dest[1] = a[1] - b[1];\n dest[2] = a[2] - b[2];\n dest[3] = a[3] - b[3];\n dest[4] = a[4] - b[4];\n dest[5] = a[5] - b[5];\n dest[6] = a[6] - b[6];\n dest[7] = a[7] - b[7];\n dest[8] = a[8] - b[8];\n dest[9] = a[9] - b[9];\n dest[10] = a[10] - b[10];\n dest[11] = a[11] - b[11];\n dest[12] = a[12] - b[12];\n dest[13] = a[13] - b[13];\n dest[14] = a[14] - b[14];\n dest[15] = a[15] - b[15];\n return dest;\n },\n\n /**\n * Subtracts the given scalar from each element of the given 4x4 matrix.\n * @method subMat4Scalar\n * @static\n */\n subMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] - s;\n dest[1] = m[1] - s;\n dest[2] = m[2] - s;\n dest[3] = m[3] - s;\n dest[4] = m[4] - s;\n dest[5] = m[5] - s;\n dest[6] = m[6] - s;\n dest[7] = m[7] - s;\n dest[8] = m[8] - s;\n dest[9] = m[9] - s;\n dest[10] = m[10] - s;\n dest[11] = m[11] - s;\n dest[12] = m[12] - s;\n dest[13] = m[13] - s;\n dest[14] = m[14] - s;\n dest[15] = m[15] - s;\n return dest;\n },\n\n /**\n * Subtracts the given scalar from each element of the given 4x4 matrix.\n * @method subScalarMat4\n * @static\n */\n subScalarMat4(s, m, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = s - m[0];\n dest[1] = s - m[1];\n dest[2] = s - m[2];\n dest[3] = s - m[3];\n dest[4] = s - m[4];\n dest[5] = s - m[5];\n dest[6] = s - m[6];\n dest[7] = s - m[7];\n dest[8] = s - m[8];\n dest[9] = s - m[9];\n dest[10] = s - m[10];\n dest[11] = s - m[11];\n dest[12] = s - m[12];\n dest[13] = s - m[13];\n dest[14] = s - m[14];\n dest[15] = s - m[15];\n return dest;\n },\n\n /**\n * Multiplies the two given 4x4 matrix by each other.\n * @method mulMat4\n * @static\n */\n mulMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = a[0];\n\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n const b00 = b[0];\n const b01 = b[1];\n const b02 = b[2];\n const b03 = b[3];\n const b10 = b[4];\n const b11 = b[5];\n const b12 = b[6];\n const b13 = b[7];\n const b20 = b[8];\n const b21 = b[9];\n const b22 = b[10];\n const b23 = b[11];\n const b30 = b[12];\n const b31 = b[13];\n const b32 = b[14];\n const b33 = b[15];\n\n dest[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;\n dest[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;\n dest[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;\n dest[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;\n dest[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;\n dest[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;\n dest[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;\n dest[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;\n dest[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;\n dest[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;\n dest[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;\n dest[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;\n dest[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;\n dest[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;\n dest[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;\n dest[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;\n\n return dest;\n },\n\n /**\n * Multiplies the two given 3x3 matrices by each other.\n * @method mulMat4\n * @static\n */\n mulMat3(a, b, dest) {\n if (!dest) {\n dest = new FloatArrayType(9);\n }\n\n const a11 = a[0];\n const a12 = a[3];\n const a13 = a[6];\n const a21 = a[1];\n const a22 = a[4];\n const a23 = a[7];\n const a31 = a[2];\n const a32 = a[5];\n const a33 = a[8];\n const b11 = b[0];\n const b12 = b[3];\n const b13 = b[6];\n const b21 = b[1];\n const b22 = b[4];\n const b23 = b[7];\n const b31 = b[2];\n const b32 = b[5];\n const b33 = b[8];\n\n dest[0] = a11 * b11 + a12 * b21 + a13 * b31;\n dest[3] = a11 * b12 + a12 * b22 + a13 * b32;\n dest[6] = a11 * b13 + a12 * b23 + a13 * b33;\n\n dest[1] = a21 * b11 + a22 * b21 + a23 * b31;\n dest[4] = a21 * b12 + a22 * b22 + a23 * b32;\n dest[7] = a21 * b13 + a22 * b23 + a23 * b33;\n\n dest[2] = a31 * b11 + a32 * b21 + a33 * b31;\n dest[5] = a31 * b12 + a32 * b22 + a33 * b32;\n dest[8] = a31 * b13 + a32 * b23 + a33 * b33;\n\n return dest;\n },\n\n /**\n * Multiplies each element of the given 4x4 matrix by the given scalar.\n * @method mulMat4Scalar\n * @static\n */\n mulMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] * s;\n dest[1] = m[1] * s;\n dest[2] = m[2] * s;\n dest[3] = m[3] * s;\n dest[4] = m[4] * s;\n dest[5] = m[5] * s;\n dest[6] = m[6] * s;\n dest[7] = m[7] * s;\n dest[8] = m[8] * s;\n dest[9] = m[9] * s;\n dest[10] = m[10] * s;\n dest[11] = m[11] * s;\n dest[12] = m[12] * s;\n dest[13] = m[13] * s;\n dest[14] = m[14] * s;\n dest[15] = m[15] * s;\n return dest;\n },\n\n /**\n * Multiplies the given 4x4 matrix by the given four-element vector.\n * @method mulMat4v4\n * @static\n */\n mulMat4v4(m, v, dest = math.vec4()) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n const v3 = v[3];\n dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3;\n dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3;\n dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3;\n dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3;\n return dest;\n },\n\n /**\n * Transposes the given 4x4 matrix.\n * @method transposeMat4\n * @static\n */\n transposeMat4(mat, dest) {\n // If we are transposing ourselves we can skip a few steps but have to cache some values\n const m4 = mat[4];\n\n const m14 = mat[14];\n const m8 = mat[8];\n const m13 = mat[13];\n const m12 = mat[12];\n const m9 = mat[9];\n if (!dest || mat === dest) {\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a12 = mat[6];\n const a13 = mat[7];\n const a23 = mat[11];\n mat[1] = m4;\n mat[2] = m8;\n mat[3] = m12;\n mat[4] = a01;\n mat[6] = m9;\n mat[7] = m13;\n mat[8] = a02;\n mat[9] = a12;\n mat[11] = m14;\n mat[12] = a03;\n mat[13] = a13;\n mat[14] = a23;\n return mat;\n }\n dest[0] = mat[0];\n dest[1] = m4;\n dest[2] = m8;\n dest[3] = m12;\n dest[4] = mat[1];\n dest[5] = mat[5];\n dest[6] = m9;\n dest[7] = m13;\n dest[8] = mat[2];\n dest[9] = mat[6];\n dest[10] = mat[10];\n dest[11] = m14;\n dest[12] = mat[3];\n dest[13] = mat[7];\n dest[14] = mat[11];\n dest[15] = mat[15];\n return dest;\n },\n\n /**\n * Transposes the given 3x3 matrix.\n *\n * @method transposeMat3\n * @static\n */\n transposeMat3(mat, dest) {\n if (dest === mat) {\n const a01 = mat[1];\n const a02 = mat[2];\n const a12 = mat[5];\n dest[1] = mat[3];\n dest[2] = mat[6];\n dest[3] = a01;\n dest[5] = mat[7];\n dest[6] = a02;\n dest[7] = a12;\n } else {\n dest[0] = mat[0];\n dest[1] = mat[3];\n dest[2] = mat[6];\n dest[3] = mat[1];\n dest[4] = mat[4];\n dest[5] = mat[7];\n dest[6] = mat[2];\n dest[7] = mat[5];\n dest[8] = mat[8];\n }\n return dest;\n },\n\n /**\n * Returns the determinant of the given 4x4 matrix.\n * @method determinantMat4\n * @static\n */\n determinantMat4(mat) {\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = mat[0];\n\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a10 = mat[4];\n const a11 = mat[5];\n const a12 = mat[6];\n const a13 = mat[7];\n const a20 = mat[8];\n const a21 = mat[9];\n const a22 = mat[10];\n const a23 = mat[11];\n const a30 = mat[12];\n const a31 = mat[13];\n const a32 = mat[14];\n const a33 = mat[15];\n return a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 +\n a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 +\n a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 +\n a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 +\n a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 +\n a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33;\n },\n\n /**\n * Returns the inverse of the given 4x4 matrix.\n * @method inverseMat4\n * @static\n */\n inverseMat4(mat, dest) {\n if (!dest) {\n dest = mat;\n }\n\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = mat[0];\n\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a10 = mat[4];\n const a11 = mat[5];\n const a12 = mat[6];\n const a13 = mat[7];\n const a20 = mat[8];\n const a21 = mat[9];\n const a22 = mat[10];\n const a23 = mat[11];\n const a30 = mat[12];\n const a31 = mat[13];\n const a32 = mat[14];\n const a33 = mat[15];\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant (inlined to avoid double-caching)\n const invDet = 1 / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06);\n\n dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;\n dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;\n dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;\n dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;\n dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;\n dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;\n dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;\n dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;\n dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;\n dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;\n dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;\n dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;\n dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;\n dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;\n dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;\n dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;\n\n return dest;\n },\n\n /**\n * Returns the trace of the given 4x4 matrix.\n * @method traceMat4\n * @static\n */\n traceMat4(m) {\n return (m[0] + m[5] + m[10] + m[15]);\n },\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4\n * @static\n */\n translationMat4v(v, dest) {\n const m = dest || math.identityMat4();\n m[12] = v[0];\n m[13] = v[1];\n m[14] = v[2];\n return m;\n },\n\n /**\n * Returns 3x3 translation matrix.\n * @method translationMat3\n * @static\n */\n translationMat3v(v, dest) {\n const m = dest || math.identityMat3();\n m[6] = v[0];\n m[7] = v[1];\n return m;\n },\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4c\n * @static\n */\n translationMat4c: ((() => {\n const xyz = new FloatArrayType(3);\n return (x, y, z, dest) => {\n xyz[0] = x;\n xyz[1] = y;\n xyz[2] = z;\n return math.translationMat4v(xyz, dest);\n };\n }))(),\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4s\n * @static\n */\n translationMat4s(s, dest) {\n return math.translationMat4c(s, s, s, dest);\n },\n\n /**\n * Efficiently post-concatenates a translation to the given matrix.\n * @param v\n * @param m\n */\n translateMat4v(xyz, m) {\n return math.translateMat4c(xyz[0], xyz[1], xyz[2], m);\n },\n\n /**\n * Efficiently post-concatenates a translation to the given matrix.\n * @param x\n * @param y\n * @param z\n * @param m\n */\n OLDtranslateMat4c(x, y, z, m) {\n\n const m12 = m[12];\n m[0] += m12 * x;\n m[4] += m12 * y;\n m[8] += m12 * z;\n\n const m13 = m[13];\n m[1] += m13 * x;\n m[5] += m13 * y;\n m[9] += m13 * z;\n\n const m14 = m[14];\n m[2] += m14 * x;\n m[6] += m14 * y;\n m[10] += m14 * z;\n\n const m15 = m[15];\n m[3] += m15 * x;\n m[7] += m15 * y;\n m[11] += m15 * z;\n\n return m;\n },\n\n translateMat4c(x, y, z, m) {\n\n const m3 = m[3];\n m[0] += m3 * x;\n m[1] += m3 * y;\n m[2] += m3 * z;\n\n const m7 = m[7];\n m[4] += m7 * x;\n m[5] += m7 * y;\n m[6] += m7 * z;\n\n const m11 = m[11];\n m[8] += m11 * x;\n m[9] += m11 * y;\n m[10] += m11 * z;\n\n const m15 = m[15];\n m[12] += m15 * x;\n m[13] += m15 * y;\n m[14] += m15 * z;\n\n return m;\n },\n /**\n * Returns 4x4 rotation matrix.\n * @method rotationMat4v\n * @static\n */\n rotationMat4v(anglerad, axis, m) {\n const ax = math.normalizeVec4([axis[0], axis[1], axis[2], 0.0], []);\n const s = Math.sin(anglerad);\n const c = Math.cos(anglerad);\n const q = 1.0 - c;\n\n const x = ax[0];\n const y = ax[1];\n const z = ax[2];\n\n let xy;\n let yz;\n let zx;\n let xs;\n let ys;\n let zs;\n\n //xx = x * x; used once\n //yy = y * y; used once\n //zz = z * z; used once\n xy = x * y;\n yz = y * z;\n zx = z * x;\n xs = x * s;\n ys = y * s;\n zs = z * s;\n\n m = m || math.mat4();\n\n m[0] = (q * x * x) + c;\n m[1] = (q * xy) + zs;\n m[2] = (q * zx) - ys;\n m[3] = 0.0;\n\n m[4] = (q * xy) - zs;\n m[5] = (q * y * y) + c;\n m[6] = (q * yz) + xs;\n m[7] = 0.0;\n\n m[8] = (q * zx) + ys;\n m[9] = (q * yz) - xs;\n m[10] = (q * z * z) + c;\n m[11] = 0.0;\n\n m[12] = 0.0;\n m[13] = 0.0;\n m[14] = 0.0;\n m[15] = 1.0;\n\n return m;\n },\n\n /**\n * Returns 4x4 rotation matrix.\n * @method rotationMat4c\n * @static\n */\n rotationMat4c(anglerad, x, y, z, mat) {\n return math.rotationMat4v(anglerad, [x, y, z], mat);\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4v\n * @static\n */\n scalingMat4v(v, m = math.identityMat4()) {\n m[0] = v[0];\n m[5] = v[1];\n m[10] = v[2];\n return m;\n },\n\n /**\n * Returns 3x3 scale matrix.\n * @method scalingMat3v\n * @static\n */\n scalingMat3v(v, m = math.identityMat3()) {\n m[0] = v[0];\n m[4] = v[1];\n return m;\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4c\n * @static\n */\n scalingMat4c: ((() => {\n const xyz = new FloatArrayType(3);\n return (x, y, z, dest) => {\n xyz[0] = x;\n xyz[1] = y;\n xyz[2] = z;\n return math.scalingMat4v(xyz, dest);\n };\n }))(),\n\n /**\n * Efficiently post-concatenates a scaling to the given matrix.\n * @method scaleMat4c\n * @param x\n * @param y\n * @param z\n * @param m\n */\n scaleMat4c(x, y, z, m) {\n\n m[0] *= x;\n m[4] *= y;\n m[8] *= z;\n\n m[1] *= x;\n m[5] *= y;\n m[9] *= z;\n\n m[2] *= x;\n m[6] *= y;\n m[10] *= z;\n\n m[3] *= x;\n m[7] *= y;\n m[11] *= z;\n return m;\n },\n\n /**\n * Efficiently post-concatenates a scaling to the given matrix.\n * @method scaleMat4c\n * @param xyz\n * @param m\n */\n scaleMat4v(xyz, m) {\n\n const x = xyz[0];\n const y = xyz[1];\n const z = xyz[2];\n\n m[0] *= x;\n m[4] *= y;\n m[8] *= z;\n m[1] *= x;\n m[5] *= y;\n m[9] *= z;\n m[2] *= x;\n m[6] *= y;\n m[10] *= z;\n m[3] *= x;\n m[7] *= y;\n m[11] *= z;\n\n return m;\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4s\n * @static\n */\n scalingMat4s(s) {\n return math.scalingMat4c(s, s, s);\n },\n\n /**\n * Creates a matrix from a quaternion rotation and vector translation\n *\n * @param {Number[]} q Rotation quaternion\n * @param {Number[]} v Translation vector\n * @param {Number[]} dest Destination matrix\n * @returns {Number[]} dest\n */\n rotationTranslationMat4(q, v, dest = math.mat4()) {\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n dest[0] = 1 - (yy + zz);\n dest[1] = xy + wz;\n dest[2] = xz - wy;\n dest[3] = 0;\n dest[4] = xy - wz;\n dest[5] = 1 - (xx + zz);\n dest[6] = yz + wx;\n dest[7] = 0;\n dest[8] = xz + wy;\n dest[9] = yz - wx;\n dest[10] = 1 - (xx + yy);\n dest[11] = 0;\n dest[12] = v[0];\n dest[13] = v[1];\n dest[14] = v[2];\n dest[15] = 1;\n\n return dest;\n },\n\n /**\n * Gets Euler angles from a 4x4 matrix.\n *\n * @param {Number[]} mat The 4x4 matrix.\n * @param {String} order Desired Euler angle order: \"XYZ\", \"YXZ\", \"ZXY\" etc.\n * @param {Number[]} [dest] Destination Euler angles, created by default.\n * @returns {Number[]} The Euler angles.\n */\n mat4ToEuler(mat, order, dest = math.vec4()) {\n const clamp = math.clamp;\n\n // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n const m11 = mat[0];\n\n const m12 = mat[4];\n const m13 = mat[8];\n const m21 = mat[1];\n const m22 = mat[5];\n const m23 = mat[9];\n const m31 = mat[2];\n const m32 = mat[6];\n const m33 = mat[10];\n\n if (order === 'XYZ') {\n\n dest[1] = Math.asin(clamp(m13, -1, 1));\n\n if (Math.abs(m13) < 0.99999) {\n dest[0] = Math.atan2(-m23, m33);\n dest[2] = Math.atan2(-m12, m11);\n } else {\n dest[0] = Math.atan2(m32, m22);\n dest[2] = 0;\n\n }\n\n } else if (order === 'YXZ') {\n\n dest[0] = Math.asin(-clamp(m23, -1, 1));\n\n if (Math.abs(m23) < 0.99999) {\n dest[1] = Math.atan2(m13, m33);\n dest[2] = Math.atan2(m21, m22);\n } else {\n dest[1] = Math.atan2(-m31, m11);\n dest[2] = 0;\n }\n\n } else if (order === 'ZXY') {\n\n dest[0] = Math.asin(clamp(m32, -1, 1));\n\n if (Math.abs(m32) < 0.99999) {\n dest[1] = Math.atan2(-m31, m33);\n dest[2] = Math.atan2(-m12, m22);\n } else {\n dest[1] = 0;\n dest[2] = Math.atan2(m21, m11);\n }\n\n } else if (order === 'ZYX') {\n\n dest[1] = Math.asin(-clamp(m31, -1, 1));\n\n if (Math.abs(m31) < 0.99999) {\n dest[0] = Math.atan2(m32, m33);\n dest[2] = Math.atan2(m21, m11);\n } else {\n dest[0] = 0;\n dest[2] = Math.atan2(-m12, m22);\n }\n\n } else if (order === 'YZX') {\n\n dest[2] = Math.asin(clamp(m21, -1, 1));\n\n if (Math.abs(m21) < 0.99999) {\n dest[0] = Math.atan2(-m23, m22);\n dest[1] = Math.atan2(-m31, m11);\n } else {\n dest[0] = 0;\n dest[1] = Math.atan2(m13, m33);\n }\n\n } else if (order === 'XZY') {\n\n dest[2] = Math.asin(-clamp(m12, -1, 1));\n\n if (Math.abs(m12) < 0.99999) {\n dest[0] = Math.atan2(m32, m22);\n dest[1] = Math.atan2(m13, m11);\n } else {\n dest[0] = Math.atan2(-m23, m33);\n dest[1] = 0;\n }\n }\n\n return dest;\n },\n\n composeMat4(position, quaternion, scale, mat = math.mat4()) {\n math.quaternionToRotationMat4(quaternion, mat);\n math.scaleMat4v(scale, mat);\n math.translateMat4v(position, mat);\n\n return mat;\n },\n\n decomposeMat4: (() => {\n\n const vec = new FloatArrayType(3);\n const matrix = new FloatArrayType(16);\n\n return function decompose(mat, position, quaternion, scale) {\n\n vec[0] = mat[0];\n vec[1] = mat[1];\n vec[2] = mat[2];\n\n let sx = math.lenVec3(vec);\n\n vec[0] = mat[4];\n vec[1] = mat[5];\n vec[2] = mat[6];\n\n const sy = math.lenVec3(vec);\n\n vec[8] = mat[8];\n vec[9] = mat[9];\n vec[10] = mat[10];\n\n const sz = math.lenVec3(vec);\n\n // if determine is negative, we need to invert one scale\n const det = math.determinantMat4(mat);\n\n if (det < 0) {\n sx = -sx;\n }\n\n position[0] = mat[12];\n position[1] = mat[13];\n position[2] = mat[14];\n\n // scale the rotation part\n matrix.set(mat);\n\n const invSX = 1 / sx;\n const invSY = 1 / sy;\n const invSZ = 1 / sz;\n\n matrix[0] *= invSX;\n matrix[1] *= invSX;\n matrix[2] *= invSX;\n\n matrix[4] *= invSY;\n matrix[5] *= invSY;\n matrix[6] *= invSY;\n\n matrix[8] *= invSZ;\n matrix[9] *= invSZ;\n matrix[10] *= invSZ;\n\n math.mat4ToQuaternion(matrix, quaternion);\n\n scale[0] = sx;\n scale[1] = sy;\n scale[2] = sz;\n\n return this;\n\n };\n\n })(),\n\n /**\n * Returns a 4x4 'lookat' viewing transform matrix.\n * @method lookAtMat4v\n * @param pos vec3 position of the viewer\n * @param target vec3 point the viewer is looking at\n * @param up vec3 pointing \"up\"\n * @param dest mat4 Optional, mat4 matrix will be written into\n *\n * @return {mat4} dest if specified, a new mat4 otherwise\n */\n lookAtMat4v(pos, target, up, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n\n const posx = pos[0];\n const posy = pos[1];\n const posz = pos[2];\n const upx = up[0];\n const upy = up[1];\n const upz = up[2];\n const targetx = target[0];\n const targety = target[1];\n const targetz = target[2];\n\n if (posx === targetx && posy === targety && posz === targetz) {\n return math.identityMat4();\n }\n\n let z0;\n let z1;\n let z2;\n let x0;\n let x1;\n let x2;\n let y0;\n let y1;\n let y2;\n let len;\n\n //vec3.direction(eye, center, z);\n z0 = posx - targetx;\n z1 = posy - targety;\n z2 = posz - targetz;\n\n // normalize (no check needed for 0 because of early return)\n len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);\n z0 *= len;\n z1 *= len;\n z2 *= len;\n\n //vec3.normalize(vec3.cross(up, z, x));\n x0 = upy * z2 - upz * z1;\n x1 = upz * z0 - upx * z2;\n x2 = upx * z1 - upy * z0;\n len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);\n if (!len) {\n x0 = 0;\n x1 = 0;\n x2 = 0;\n } else {\n len = 1 / len;\n x0 *= len;\n x1 *= len;\n x2 *= len;\n }\n\n //vec3.normalize(vec3.cross(z, x, y));\n y0 = z1 * x2 - z2 * x1;\n y1 = z2 * x0 - z0 * x2;\n y2 = z0 * x1 - z1 * x0;\n\n len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);\n if (!len) {\n y0 = 0;\n y1 = 0;\n y2 = 0;\n } else {\n len = 1 / len;\n y0 *= len;\n y1 *= len;\n y2 *= len;\n }\n\n dest[0] = x0;\n dest[1] = y0;\n dest[2] = z0;\n dest[3] = 0;\n dest[4] = x1;\n dest[5] = y1;\n dest[6] = z1;\n dest[7] = 0;\n dest[8] = x2;\n dest[9] = y2;\n dest[10] = z2;\n dest[11] = 0;\n dest[12] = -(x0 * posx + x1 * posy + x2 * posz);\n dest[13] = -(y0 * posx + y1 * posy + y2 * posz);\n dest[14] = -(z0 * posx + z1 * posy + z2 * posz);\n dest[15] = 1;\n\n return dest;\n },\n\n /**\n * Returns a 4x4 'lookat' viewing transform matrix.\n * @method lookAtMat4c\n * @static\n */\n lookAtMat4c(posx, posy, posz, targetx, targety, targetz, upx, upy, upz) {\n return math.lookAtMat4v([posx, posy, posz], [targetx, targety, targetz], [upx, upy, upz], []);\n },\n\n /**\n * Returns a 4x4 orthographic projection matrix.\n * @method orthoMat4c\n * @static\n */\n orthoMat4c(left, right, bottom, top, near, far, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n const rl = (right - left);\n const tb = (top - bottom);\n const fn = (far - near);\n\n dest[0] = 2.0 / rl;\n dest[1] = 0.0;\n dest[2] = 0.0;\n dest[3] = 0.0;\n\n dest[4] = 0.0;\n dest[5] = 2.0 / tb;\n dest[6] = 0.0;\n dest[7] = 0.0;\n\n dest[8] = 0.0;\n dest[9] = 0.0;\n dest[10] = -2.0 / fn;\n dest[11] = 0.0;\n\n dest[12] = -(left + right) / rl;\n dest[13] = -(top + bottom) / tb;\n dest[14] = -(far + near) / fn;\n dest[15] = 1.0;\n\n return dest;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method frustumMat4v\n * @static\n */\n frustumMat4v(fmin, fmax, m) {\n if (!m) {\n m = math.mat4();\n }\n\n const fmin4 = [fmin[0], fmin[1], fmin[2], 0.0];\n const fmax4 = [fmax[0], fmax[1], fmax[2], 0.0];\n\n math.addVec4(fmax4, fmin4, tempMat1);\n math.subVec4(fmax4, fmin4, tempMat2);\n\n const t = 2.0 * fmin4[2];\n\n const tempMat20 = tempMat2[0];\n const tempMat21 = tempMat2[1];\n const tempMat22 = tempMat2[2];\n\n m[0] = t / tempMat20;\n m[1] = 0.0;\n m[2] = 0.0;\n m[3] = 0.0;\n\n m[4] = 0.0;\n m[5] = t / tempMat21;\n m[6] = 0.0;\n m[7] = 0.0;\n\n m[8] = tempMat1[0] / tempMat20;\n m[9] = tempMat1[1] / tempMat21;\n m[10] = -tempMat1[2] / tempMat22;\n m[11] = -1.0;\n\n m[12] = 0.0;\n m[13] = 0.0;\n m[14] = -t * fmax4[2] / tempMat22;\n m[15] = 0.0;\n\n return m;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method frustumMat4v\n * @static\n */\n frustumMat4(left, right, bottom, top, near, far, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n const rl = (right - left);\n const tb = (top - bottom);\n const fn = (far - near);\n dest[0] = (near * 2) / rl;\n dest[1] = 0;\n dest[2] = 0;\n dest[3] = 0;\n dest[4] = 0;\n dest[5] = (near * 2) / tb;\n dest[6] = 0;\n dest[7] = 0;\n dest[8] = (right + left) / rl;\n dest[9] = (top + bottom) / tb;\n dest[10] = -(far + near) / fn;\n dest[11] = -1;\n dest[12] = 0;\n dest[13] = 0;\n dest[14] = -(far * near * 2) / fn;\n dest[15] = 0;\n return dest;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method perspectiveMat4v\n * @static\n */\n perspectiveMat4(fovyrad, aspectratio, znear, zfar, m) {\n const pmin = [];\n const pmax = [];\n\n pmin[2] = znear;\n pmax[2] = zfar;\n\n pmax[1] = pmin[2] * Math.tan(fovyrad / 2.0);\n pmin[1] = -pmax[1];\n\n pmax[0] = pmax[1] * aspectratio;\n pmin[0] = -pmax[0];\n\n return math.frustumMat4v(pmin, pmax, m);\n },\n\n /**\n * Transforms a three-element position by a 4x4 matrix.\n * @method transformPoint3\n * @static\n */\n transformPoint3(m, p, dest = math.vec3()) {\n\n const x = p[0];\n const y = p[1];\n const z = p[2];\n\n dest[0] = (m[0] * x) + (m[4] * y) + (m[8] * z) + m[12];\n dest[1] = (m[1] * x) + (m[5] * y) + (m[9] * z) + m[13];\n dest[2] = (m[2] * x) + (m[6] * y) + (m[10] * z) + m[14];\n\n return dest;\n },\n\n /**\n * Transforms a homogeneous coordinate by a 4x4 matrix.\n * @method transformPoint3\n * @static\n */\n transformPoint4(m, v, dest = math.vec4()) {\n dest[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];\n dest[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];\n dest[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];\n dest[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];\n\n return dest;\n },\n\n\n /**\n * Transforms an array of three-element positions by a 4x4 matrix.\n * @method transformPoints3\n * @static\n */\n transformPoints3(m, points, points2) {\n const result = points2 || [];\n const len = points.length;\n let p0;\n let p1;\n let p2;\n let pi;\n\n // cache values\n const m0 = m[0];\n\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n let r;\n\n for (let i = 0; i < len; ++i) {\n\n // cache values\n pi = points[i];\n\n p0 = pi[0];\n p1 = pi[1];\n p2 = pi[2];\n\n r = result[i] || (result[i] = [0, 0, 0]);\n\n r[0] = (m0 * p0) + (m4 * p1) + (m8 * p2) + m12;\n r[1] = (m1 * p0) + (m5 * p1) + (m9 * p2) + m13;\n r[2] = (m2 * p0) + (m6 * p1) + (m10 * p2) + m14;\n r[3] = (m3 * p0) + (m7 * p1) + (m11 * p2) + m15;\n }\n\n result.length = len;\n\n return result;\n },\n\n /**\n * Transforms an array of positions by a 4x4 matrix.\n * @method transformPositions3\n * @static\n */\n transformPositions3(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 3) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /**\n * Transforms an array of positions by a 4x4 matrix.\n * @method transformPositions4\n * @static\n */\n transformPositions4(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 4) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /**\n * Transforms a three-element vector by a 4x4 matrix.\n * @method transformVec3\n * @static\n */\n transformVec3(m, v, dest) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n dest = dest || this.vec3();\n dest[0] = (m[0] * v0) + (m[4] * v1) + (m[8] * v2);\n dest[1] = (m[1] * v0) + (m[5] * v1) + (m[9] * v2);\n dest[2] = (m[2] * v0) + (m[6] * v1) + (m[10] * v2);\n return dest;\n },\n\n /**\n * Transforms a four-element vector by a 4x4 matrix.\n * @method transformVec4\n * @static\n */\n transformVec4(m, v, dest) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n const v3 = v[3];\n dest = dest || math.vec4();\n dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3;\n dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3;\n dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3;\n dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3;\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the x-axis\n *\n * @method rotateVec3X\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3X(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[0];\n r[1] = p[1] * Math.cos(c) - p[2] * Math.sin(c);\n r[2] = p[1] * Math.sin(c) + p[2] * Math.cos(c);\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the y-axis\n *\n * @method rotateVec3Y\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3Y(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c);\n r[1] = p[1];\n r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c);\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the z-axis\n *\n * @method rotateVec3Z\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3Z(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c);\n r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c);\n r[2] = p[2];\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Transforms a four-element vector by a 4x4 projection matrix.\n *\n * @method projectVec4\n * @param {Number[]} p 3D View-space coordinate\n * @param {Number[]} q 2D Projected coordinate\n * @returns {Number[]} 2D Projected coordinate\n * @static\n */\n projectVec4(p, q) {\n const f = 1.0 / p[3];\n q = q || math.vec2();\n q[0] = v[0] * f;\n q[1] = v[1] * f;\n return q;\n },\n\n /**\n * Unprojects a three-element vector.\n *\n * @method unprojectVec3\n * @param {Number[]} p 3D Projected coordinate\n * @param {Number[]} viewMat View matrix\n * @returns {Number[]} projMat Projection matrix\n * @static\n */\n unprojectVec3: ((() => {\n const mat = new FloatArrayType(16);\n const mat2 = new FloatArrayType(16);\n const mat3 = new FloatArrayType(16);\n return function (p, viewMat, projMat, q) {\n return this.transformVec3(this.mulMat4(this.inverseMat4(viewMat, mat), this.inverseMat4(projMat, mat2), mat3), p, q)\n };\n }))(),\n\n /**\n * Linearly interpolates between two 3D vectors.\n * @method lerpVec3\n * @static\n */\n lerpVec3(t, t1, t2, p1, p2, dest) {\n const result = dest || math.vec3();\n const f = (t - t1) / (t2 - t1);\n result[0] = p1[0] + (f * (p2[0] - p1[0]));\n result[1] = p1[1] + (f * (p2[1] - p1[1]));\n result[2] = p1[2] + (f * (p2[2] - p1[2]));\n return result;\n },\n\n\n /**\n * Flattens a two-dimensional array into a one-dimensional array.\n *\n * @method flatten\n * @static\n * @param {Array of Arrays} a A 2D array\n * @returns Flattened 1D array\n */\n flatten(a) {\n\n const result = [];\n\n let i;\n let leni;\n let j;\n let lenj;\n let item;\n\n for (i = 0, leni = a.length; i < leni; i++) {\n item = a[i];\n for (j = 0, lenj = item.length; j < lenj; j++) {\n result.push(item[j]);\n }\n }\n\n return result;\n },\n\n\n identityQuaternion(dest = math.vec4()) {\n dest[0] = 0.0;\n dest[1] = 0.0;\n dest[2] = 0.0;\n dest[3] = 1.0;\n return dest;\n },\n\n /**\n * Initializes a quaternion from Euler angles.\n *\n * @param {Number[]} euler The Euler angles.\n * @param {String} order Euler angle order: \"XYZ\", \"YXZ\", \"ZXY\" etc.\n * @param {Number[]} [dest] Destination quaternion, created by default.\n * @returns {Number[]} The quaternion.\n */\n eulerToQuaternion(euler, order, dest = math.vec4()) {\n // http://www.mathworks.com/matlabcentral/fileexchange/\n // \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n //\tcontent/SpinCalc.m\n\n const a = (euler[0] * math.DEGTORAD) / 2;\n const b = (euler[1] * math.DEGTORAD) / 2;\n const c = (euler[2] * math.DEGTORAD) / 2;\n\n const c1 = Math.cos(a);\n const c2 = Math.cos(b);\n const c3 = Math.cos(c);\n const s1 = Math.sin(a);\n const s2 = Math.sin(b);\n const s3 = Math.sin(c);\n\n if (order === 'XYZ') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'YXZ') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n\n } else if (order === 'ZXY') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'ZYX') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n\n } else if (order === 'YZX') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'XZY') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n }\n\n return dest;\n },\n\n mat4ToQuaternion(m, dest = math.vec4()) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n const m11 = m[0];\n const m12 = m[4];\n const m13 = m[8];\n const m21 = m[1];\n const m22 = m[5];\n const m23 = m[9];\n const m31 = m[2];\n const m32 = m[6];\n const m33 = m[10];\n let s;\n\n const trace = m11 + m22 + m33;\n\n if (trace > 0) {\n\n s = 0.5 / Math.sqrt(trace + 1.0);\n\n dest[3] = 0.25 / s;\n dest[0] = (m32 - m23) * s;\n dest[1] = (m13 - m31) * s;\n dest[2] = (m21 - m12) * s;\n\n } else if (m11 > m22 && m11 > m33) {\n\n s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);\n\n dest[3] = (m32 - m23) / s;\n dest[0] = 0.25 * s;\n dest[1] = (m12 + m21) / s;\n dest[2] = (m13 + m31) / s;\n\n } else if (m22 > m33) {\n\n s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);\n\n dest[3] = (m13 - m31) / s;\n dest[0] = (m12 + m21) / s;\n dest[1] = 0.25 * s;\n dest[2] = (m23 + m32) / s;\n\n } else {\n\n s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);\n\n dest[3] = (m21 - m12) / s;\n dest[0] = (m13 + m31) / s;\n dest[1] = (m23 + m32) / s;\n dest[2] = 0.25 * s;\n }\n\n return dest;\n },\n\n vec3PairToQuaternion(u, v, dest = math.vec4()) {\n const norm_u_norm_v = Math.sqrt(math.dotVec3(u, u) * math.dotVec3(v, v));\n let real_part = norm_u_norm_v + math.dotVec3(u, v);\n\n if (real_part < 0.00000001 * norm_u_norm_v) {\n\n // If u and v are exactly opposite, rotate 180 degrees\n // around an arbitrary orthogonal axis. Axis normalisation\n // can happen later, when we normalise the quaternion.\n\n real_part = 0.0;\n\n if (Math.abs(u[0]) > Math.abs(u[2])) {\n\n dest[0] = -u[1];\n dest[1] = u[0];\n dest[2] = 0;\n\n } else {\n dest[0] = 0;\n dest[1] = -u[2];\n dest[2] = u[1]\n }\n\n } else {\n\n // Otherwise, build quaternion the standard way.\n math.cross3Vec3(u, v, dest);\n }\n\n dest[3] = real_part;\n\n return math.normalizeQuaternion(dest);\n },\n\n angleAxisToQuaternion(angleAxis, dest = math.vec4()) {\n const halfAngle = angleAxis[3] / 2.0;\n const fsin = Math.sin(halfAngle);\n dest[0] = fsin * angleAxis[0];\n dest[1] = fsin * angleAxis[1];\n dest[2] = fsin * angleAxis[2];\n dest[3] = Math.cos(halfAngle);\n return dest;\n },\n\n quaternionToEuler: ((() => {\n const mat = new FloatArrayType(16);\n return (q, order, dest) => {\n dest = dest || math.vec3();\n math.quaternionToRotationMat4(q, mat);\n math.mat4ToEuler(mat, order, dest);\n return dest;\n };\n }))(),\n\n mulQuaternions(p, q, dest = math.vec4()) {\n const p0 = p[0];\n const p1 = p[1];\n const p2 = p[2];\n const p3 = p[3];\n const q0 = q[0];\n const q1 = q[1];\n const q2 = q[2];\n const q3 = q[3];\n dest[0] = p3 * q0 + p0 * q3 + p1 * q2 - p2 * q1;\n dest[1] = p3 * q1 + p1 * q3 + p2 * q0 - p0 * q2;\n dest[2] = p3 * q2 + p2 * q3 + p0 * q1 - p1 * q0;\n dest[3] = p3 * q3 - p0 * q0 - p1 * q1 - p2 * q2;\n return dest;\n },\n\n vec3ApplyQuaternion(q, vec, dest = math.vec3()) {\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n const qx = q[0];\n const qy = q[1];\n const qz = q[2];\n const qw = q[3];\n\n // calculate quat * vector\n\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = -qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n\n dest[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;\n dest[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;\n dest[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;\n\n return dest;\n },\n\n quaternionToMat4(q, dest) {\n\n dest = math.identityMat4(dest);\n\n const q0 = q[0]; //x\n const q1 = q[1]; //y\n const q2 = q[2]; //z\n const q3 = q[3]; //w\n\n const tx = 2.0 * q0;\n const ty = 2.0 * q1;\n const tz = 2.0 * q2;\n\n const twx = tx * q3;\n const twy = ty * q3;\n const twz = tz * q3;\n\n const txx = tx * q0;\n const txy = ty * q0;\n const txz = tz * q0;\n\n const tyy = ty * q1;\n const tyz = tz * q1;\n const tzz = tz * q2;\n\n dest[0] = 1.0 - (tyy + tzz);\n dest[1] = txy + twz;\n dest[2] = txz - twy;\n\n dest[4] = txy - twz;\n dest[5] = 1.0 - (txx + tzz);\n dest[6] = tyz + twx;\n\n dest[8] = txz + twy;\n dest[9] = tyz - twx;\n\n dest[10] = 1.0 - (txx + tyy);\n\n return dest;\n },\n\n quaternionToRotationMat4(q, m) {\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n m[0] = 1 - (yy + zz);\n m[4] = xy - wz;\n m[8] = xz + wy;\n\n m[1] = xy + wz;\n m[5] = 1 - (xx + zz);\n m[9] = yz - wx;\n\n m[2] = xz - wy;\n m[6] = yz + wx;\n m[10] = 1 - (xx + yy);\n\n // last column\n m[3] = 0;\n m[7] = 0;\n m[11] = 0;\n\n // bottom row\n m[12] = 0;\n m[13] = 0;\n m[14] = 0;\n m[15] = 1;\n\n return m;\n },\n\n normalizeQuaternion(q, dest = q) {\n const len = math.lenVec4([q[0], q[1], q[2], q[3]]);\n dest[0] = q[0] / len;\n dest[1] = q[1] / len;\n dest[2] = q[2] / len;\n dest[3] = q[3] / len;\n return dest;\n },\n\n conjugateQuaternion(q, dest = q) {\n dest[0] = -q[0];\n dest[1] = -q[1];\n dest[2] = -q[2];\n dest[3] = q[3];\n return dest;\n },\n\n inverseQuaternion(q, dest) {\n return math.normalizeQuaternion(math.conjugateQuaternion(q, dest));\n },\n\n quaternionToAngleAxis(q, angleAxis = math.vec4()) {\n q = math.normalizeQuaternion(q, tempVec4);\n const q3 = q[3];\n const angle = 2 * Math.acos(q3);\n const s = Math.sqrt(1 - q3 * q3);\n if (s < 0.001) { // test to avoid divide by zero, s is always positive due to sqrt\n angleAxis[0] = q[0];\n angleAxis[1] = q[1];\n angleAxis[2] = q[2];\n } else {\n angleAxis[0] = q[0] / s;\n angleAxis[1] = q[1] / s;\n angleAxis[2] = q[2] / s;\n }\n angleAxis[3] = angle; // * 57.295779579;\n return angleAxis;\n },\n\n //------------------------------------------------------------------------------------------------------------------\n // Boundaries\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Returns a new, uninitialized 3D axis-aligned bounding box.\n *\n * @private\n */\n AABB3(values) {\n return new FloatArrayType(values || 6);\n },\n\n /**\n * Returns a new, uninitialized 2D axis-aligned bounding box.\n *\n * @private\n */\n AABB2(values) {\n return new FloatArrayType(values || 4);\n },\n\n /**\n * Returns a new, uninitialized 3D oriented bounding box (OBB).\n *\n * @private\n */\n OBB3(values) {\n return new FloatArrayType(values || 32);\n },\n\n /**\n * Returns a new, uninitialized 2D oriented bounding box (OBB).\n *\n * @private\n */\n OBB2(values) {\n return new FloatArrayType(values || 16);\n },\n\n /** Returns a new 3D bounding sphere */\n Sphere3(x, y, z, r) {\n return new FloatArrayType([x, y, z, r]);\n },\n\n /**\n * Transforms an OBB3 by a 4x4 matrix.\n *\n * @private\n */\n transformOBB3(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 4) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /** Returns true if the first AABB contains the second AABB.\n * @param aabb1\n * @param aabb2\n * @returns {boolean}\n */\n containsAABB3: function (aabb1, aabb2) {\n const result = (\n aabb1[0] <= aabb2[0] && aabb2[3] <= aabb1[3] &&\n aabb1[1] <= aabb2[1] && aabb2[4] <= aabb1[4] &&\n aabb1[2] <= aabb2[2] && aabb2[5] <= aabb1[5]);\n return result;\n },\n\n /**\n * Gets the diagonal size of an AABB3 given as minima and maxima.\n *\n * @private\n */\n getAABB3Diag: ((() => {\n\n const min = new FloatArrayType(3);\n const max = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return aabb => {\n\n min[0] = aabb[0];\n min[1] = aabb[1];\n min[2] = aabb[2];\n\n max[0] = aabb[3];\n max[1] = aabb[4];\n max[2] = aabb[5];\n\n math.subVec3(max, min, tempVec3);\n\n return Math.abs(math.lenVec3(tempVec3));\n };\n }))(),\n\n /**\n * Get a diagonal boundary size that is symmetrical about the given point.\n *\n * @private\n */\n getAABB3DiagPoint: ((() => {\n\n const min = new FloatArrayType(3);\n const max = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return (aabb, p) => {\n\n min[0] = aabb[0];\n min[1] = aabb[1];\n min[2] = aabb[2];\n\n max[0] = aabb[3];\n max[1] = aabb[4];\n max[2] = aabb[5];\n\n const diagVec = math.subVec3(max, min, tempVec3);\n\n const xneg = p[0] - aabb[0];\n const xpos = aabb[3] - p[0];\n const yneg = p[1] - aabb[1];\n const ypos = aabb[4] - p[1];\n const zneg = p[2] - aabb[2];\n const zpos = aabb[5] - p[2];\n\n diagVec[0] += (xneg > xpos) ? xneg : xpos;\n diagVec[1] += (yneg > ypos) ? yneg : ypos;\n diagVec[2] += (zneg > zpos) ? zneg : zpos;\n\n return Math.abs(math.lenVec3(diagVec));\n };\n }))(),\n\n /**\n * Gets the center of an AABB.\n *\n * @private\n */\n getAABB3Center(aabb, dest) {\n const r = dest || math.vec3();\n\n r[0] = (aabb[0] + aabb[3]) / 2;\n r[1] = (aabb[1] + aabb[4]) / 2;\n r[2] = (aabb[2] + aabb[5]) / 2;\n\n return r;\n },\n\n /**\n * Gets the center of a 2D AABB.\n *\n * @private\n */\n getAABB2Center(aabb, dest) {\n const r = dest || math.vec2();\n\n r[0] = (aabb[2] + aabb[0]) / 2;\n r[1] = (aabb[3] + aabb[1]) / 2;\n\n return r;\n },\n\n /**\n * Collapses a 3D axis-aligned boundary, ready to expand to fit 3D points.\n * Creates new AABB if none supplied.\n *\n * @private\n */\n collapseAABB3(aabb = math.AABB3()) {\n aabb[0] = math.MAX_DOUBLE;\n aabb[1] = math.MAX_DOUBLE;\n aabb[2] = math.MAX_DOUBLE;\n aabb[3] = -math.MAX_DOUBLE;\n aabb[4] = -math.MAX_DOUBLE;\n aabb[5] = -math.MAX_DOUBLE;\n\n return aabb;\n },\n\n /**\n * Converts an axis-aligned 3D boundary into an oriented boundary consisting of\n * an array of eight 3D positions, one for each corner of the boundary.\n *\n * @private\n */\n AABB3ToOBB3(aabb, obb = math.OBB3()) {\n obb[0] = aabb[0];\n obb[1] = aabb[1];\n obb[2] = aabb[2];\n obb[3] = 1;\n\n obb[4] = aabb[3];\n obb[5] = aabb[1];\n obb[6] = aabb[2];\n obb[7] = 1;\n\n obb[8] = aabb[3];\n obb[9] = aabb[4];\n obb[10] = aabb[2];\n obb[11] = 1;\n\n obb[12] = aabb[0];\n obb[13] = aabb[4];\n obb[14] = aabb[2];\n obb[15] = 1;\n\n obb[16] = aabb[0];\n obb[17] = aabb[1];\n obb[18] = aabb[5];\n obb[19] = 1;\n\n obb[20] = aabb[3];\n obb[21] = aabb[1];\n obb[22] = aabb[5];\n obb[23] = 1;\n\n obb[24] = aabb[3];\n obb[25] = aabb[4];\n obb[26] = aabb[5];\n obb[27] = 1;\n\n obb[28] = aabb[0];\n obb[29] = aabb[4];\n obb[30] = aabb[5];\n obb[31] = 1;\n\n return obb;\n },\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array.\n *\n * @private\n */\n positions3ToAABB3: ((() => {\n\n const p = new FloatArrayType(3);\n\n return (positions, aabb, positionsDecodeMatrix) => {\n aabb = aabb || math.AABB3();\n\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n if (positionsDecodeMatrix) {\n\n p[0] = positions[i + 0];\n p[1] = positions[i + 1];\n p[2] = positions[i + 2];\n\n math.decompressPosition(p, positionsDecodeMatrix, p);\n\n x = p[0];\n y = p[1];\n z = p[2];\n\n } else {\n x = positions[i + 0];\n y = positions[i + 1];\n z = positions[i + 2];\n }\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n };\n }))(),\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array.\n *\n * @private\n */\n OBB3ToAABB3(obb, aabb = math.AABB3()) {\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = obb.length; i < len; i += 4) {\n\n x = obb[i + 0];\n y = obb[i + 1];\n z = obb[i + 2];\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n },\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the given 3D points.\n *\n * @private\n */\n points3ToAABB3(points, aabb = math.AABB3()) {\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = points.length; i < len; i++) {\n\n x = points[i][0];\n y = points[i][1];\n z = points[i][2];\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n },\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D points.\n *\n * @private\n */\n points3ToSphere3: ((() => {\n\n const tempVec3 = new FloatArrayType(3);\n\n return (points, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const numPoints = points.length;\n\n for (i = 0; i < numPoints; i++) {\n x += points[i][0];\n y += points[i][1];\n z += points[i][2];\n }\n\n sphere[0] = x / numPoints;\n sphere[1] = y / numPoints;\n sphere[2] = z / numPoints;\n\n let radius = 0;\n let dist;\n\n for (i = 0; i < numPoints; i++) {\n\n dist = Math.abs(math.lenVec3(math.subVec3(points[i], sphere, tempVec3)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D positions.\n *\n * @private\n */\n positions3ToSphere3: ((() => {\n\n const tempVec3a = new FloatArrayType(3);\n const tempVec3b = new FloatArrayType(3);\n\n return (positions, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const lenPositions = positions.length;\n let radius = 0;\n\n for (i = 0; i < lenPositions; i += 3) {\n x += positions[i];\n y += positions[i + 1];\n z += positions[i + 2];\n }\n\n const numPositions = lenPositions / 3;\n\n sphere[0] = x / numPositions;\n sphere[1] = y / numPositions;\n sphere[2] = z / numPositions;\n\n let dist;\n\n for (i = 0; i < lenPositions; i += 3) {\n\n tempVec3a[0] = positions[i];\n tempVec3a[1] = positions[i + 1];\n tempVec3a[2] = positions[i + 2];\n\n dist = Math.abs(math.lenVec3(math.subVec3(tempVec3a, sphere, tempVec3b)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D points.\n *\n * @private\n */\n OBB3ToSphere3: ((() => {\n\n const point = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return (points, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const lenPoints = points.length;\n const numPoints = lenPoints / 4;\n\n for (i = 0; i < lenPoints; i += 4) {\n x += points[i + 0];\n y += points[i + 1];\n z += points[i + 2];\n }\n\n sphere[0] = x / numPoints;\n sphere[1] = y / numPoints;\n sphere[2] = z / numPoints;\n\n let radius = 0;\n let dist;\n\n for (i = 0; i < lenPoints; i += 4) {\n\n point[0] = points[i + 0];\n point[1] = points[i + 1];\n point[2] = points[i + 2];\n\n dist = Math.abs(math.lenVec3(math.subVec3(point, sphere, tempVec3)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Gets the center of a bounding sphere.\n *\n * @private\n */\n getSphere3Center(sphere, dest = math.vec3()) {\n dest[0] = sphere[0];\n dest[1] = sphere[1];\n dest[2] = sphere[2];\n\n return dest;\n },\n\n /**\n * Expands the first axis-aligned 3D boundary to enclose the second, if required.\n *\n * @private\n */\n expandAABB3(aabb1, aabb2) {\n\n if (aabb1[0] > aabb2[0]) {\n aabb1[0] = aabb2[0];\n }\n\n if (aabb1[1] > aabb2[1]) {\n aabb1[1] = aabb2[1];\n }\n\n if (aabb1[2] > aabb2[2]) {\n aabb1[2] = aabb2[2];\n }\n\n if (aabb1[3] < aabb2[3]) {\n aabb1[3] = aabb2[3];\n }\n\n if (aabb1[4] < aabb2[4]) {\n aabb1[4] = aabb2[4];\n }\n\n if (aabb1[5] < aabb2[5]) {\n aabb1[5] = aabb2[5];\n }\n\n return aabb1;\n },\n\n /**\n * Expands an axis-aligned 3D boundary to enclose the given point, if needed.\n *\n * @private\n */\n expandAABB3Point3(aabb, p) {\n\n if (aabb[0] > p[0]) {\n aabb[0] = p[0];\n }\n\n if (aabb[1] > p[1]) {\n aabb[1] = p[1];\n }\n\n if (aabb[2] > p[2]) {\n aabb[2] = p[2];\n }\n\n if (aabb[3] < p[0]) {\n aabb[3] = p[0];\n }\n\n if (aabb[4] < p[1]) {\n aabb[4] = p[1];\n }\n\n if (aabb[5] < p[2]) {\n aabb[5] = p[2];\n }\n\n return aabb;\n },\n\n /**\n * Calculates the normal vector of a triangle.\n *\n * @private\n */\n triangleNormal(a, b, c, normal = math.vec3()) {\n const p1x = b[0] - a[0];\n const p1y = b[1] - a[1];\n const p1z = b[2] - a[2];\n\n const p2x = c[0] - a[0];\n const p2y = c[1] - a[1];\n const p2z = c[2] - a[2];\n\n const p3x = p1y * p2z - p1z * p2y;\n const p3y = p1z * p2x - p1x * p2z;\n const p3z = p1x * p2y - p1y * p2x;\n\n const mag = Math.sqrt(p3x * p3x + p3y * p3y + p3z * p3z);\n if (mag === 0) {\n normal[0] = 0;\n normal[1] = 0;\n normal[2] = 0;\n } else {\n normal[0] = p3x / mag;\n normal[1] = p3y / mag;\n normal[2] = p3z / mag;\n }\n\n return normal\n }\n};\n\nexport {math};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/math.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/math.js", "access": "public", "description": null, "lineNumber": 1 @@ -7046,7 +7046,7 @@ "name": "src/XKTModel/lib/mergeVertices.js", "content": "/**\n * Given geometry defined as an array of positions, optional normals, option uv and an array of indices, returns\n * modified arrays that have duplicate vertices removed.\n *\n * @private\n */\nfunction mergeVertices(positions, indices, mergedPositions, mergedIndices) {\n const positionsMap = {};\n const indicesLookup = [];\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = 10 ** precisionPoints;\n let uvi = 0;\n for (let i = 0, len = positions.length; i < len; i += 3) {\n const vx = positions[i];\n const vy = positions[i + 1];\n const vz = positions[i + 2];\n const key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`;\n if (positionsMap[key] === undefined) {\n positionsMap[key] = mergedPositions.length / 3;\n mergedPositions.push(vx);\n mergedPositions.push(vy);\n mergedPositions.push(vz);\n }\n indicesLookup[i / 3] = positionsMap[key];\n uvi += 2;\n }\n for (let i = 0, len = indices.length; i < len; i++) {\n mergedIndices[i] = indicesLookup[indices[i]];\n }\n}\n\nexport {mergeVertices};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/mergeVertices.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/mergeVertices.js", "access": "public", "description": null, "lineNumber": 1 @@ -7101,7 +7101,7 @@ "name": "src/XKTModel/lib/toArraybuffer.js", "content": "/**\n * @private\n * @param buf\n * @returns {ArrayBuffer}\n */\nexport function toArrayBuffer(buf) {\n const ab = new ArrayBuffer(buf.length);\n const view = new Uint8Array(ab);\n for (let i = 0; i < buf.length; ++i) {\n view[i] = buf[i];\n }\n return ab;\n}", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/toArraybuffer.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/toArraybuffer.js", "access": "public", "description": null, "lineNumber": 1 @@ -7155,7 +7155,7 @@ "name": "src/XKTModel/lib/utils.js", "content": "function isString(value) {\n return (typeof value === 'string' || value instanceof String);\n}\n\nfunction apply(o, o2) {\n for (const name in o) {\n if (o.hasOwnProperty(name)) {\n o2[name] = o[name];\n }\n }\n return o2;\n}\n\n/**\n * @private\n */\nconst utils = {\n isString,\n apply\n};\n\nexport {utils};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/lib/utils.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/lib/utils.js", "access": "public", "description": null, "lineNumber": 1 @@ -7254,7 +7254,7 @@ "name": "src/XKTModel/writeXKTModelToArrayBuffer.js", "content": "import {XKT_INFO} from \"../XKT_INFO.js\";\nimport * as pako from 'pako';\n\nconst XKT_VERSION = XKT_INFO.xktVersion;\nconst NUM_TEXTURE_ATTRIBUTES = 9;\nconst NUM_MATERIAL_ATTRIBUTES = 6;\n\n/**\n * Writes an {@link XKTModel} to an {@link ArrayBuffer}.\n *\n * @param {XKTModel} xktModel The {@link XKTModel}.\n * @param {String} metaModelJSON The metamodel JSON in a string.\n * @param {Object} [stats] Collects statistics.\n * @param {Object} options Options for how the XKT is written.\n * @param {Boolean} [options.zip=true] ZIP the contents?\n * @returns {ArrayBuffer} The {@link ArrayBuffer}.\n */\nfunction writeXKTModelToArrayBuffer(xktModel, metaModelJSON, stats, options) {\n const data = getModelData(xktModel, metaModelJSON, stats);\n const deflatedData = deflateData(data, metaModelJSON, options);\n stats.texturesSize += deflatedData.textureData.byteLength;\n const arrayBuffer = createArrayBuffer(deflatedData);\n return arrayBuffer;\n}\n\nfunction getModelData(xktModel, metaModelDataStr, stats) {\n\n //------------------------------------------------------------------------------------------------------------------\n // Allocate data\n //------------------------------------------------------------------------------------------------------------------\n\n const propertySetsList = xktModel.propertySetsList;\n const metaObjectsList = xktModel.metaObjectsList;\n const geometriesList = xktModel.geometriesList;\n const texturesList = xktModel.texturesList;\n const textureSetsList = xktModel.textureSetsList;\n const meshesList = xktModel.meshesList;\n const entitiesList = xktModel.entitiesList;\n const tilesList = xktModel.tilesList;\n\n const numPropertySets = propertySetsList.length;\n const numMetaObjects = metaObjectsList.length;\n const numGeometries = geometriesList.length;\n const numTextures = texturesList.length;\n const numTextureSets = textureSetsList.length;\n const numMeshes = meshesList.length;\n const numEntities = entitiesList.length;\n const numTiles = tilesList.length;\n\n let lenPositions = 0;\n let lenNormals = 0;\n let lenColors = 0;\n let lenUVs = 0;\n let lenIndices = 0;\n let lenEdgeIndices = 0;\n let lenMatrices = 0;\n let lenTextures = 0;\n\n for (let geometryIndex = 0; geometryIndex < numGeometries; geometryIndex++) {\n const geometry = geometriesList [geometryIndex];\n if (geometry.positionsQuantized) {\n lenPositions += geometry.positionsQuantized.length;\n }\n if (geometry.normalsOctEncoded) {\n lenNormals += geometry.normalsOctEncoded.length;\n }\n if (geometry.colorsCompressed) {\n lenColors += geometry.colorsCompressed.length;\n }\n if (geometry.uvs) {\n lenUVs += geometry.uvs.length;\n }\n if (geometry.indices) {\n lenIndices += geometry.indices.length;\n }\n if (geometry.edgeIndices) {\n lenEdgeIndices += geometry.edgeIndices.length;\n }\n }\n\n for (let textureIndex = 0; textureIndex < numTextures; textureIndex++) {\n const xktTexture = texturesList[textureIndex];\n const imageData = xktTexture.imageData;\n lenTextures += imageData.byteLength;\n\n if (xktTexture.compressed) {\n stats.numCompressedTextures++;\n }\n }\n\n for (let meshIndex = 0; meshIndex < numMeshes; meshIndex++) {\n const mesh = meshesList[meshIndex];\n if (mesh.geometry.numInstances > 1) {\n lenMatrices += 16;\n }\n }\n\n const data = {\n metadata: {},\n textureData: new Uint8Array(lenTextures), // All textures\n eachTextureDataPortion: new Uint32Array(numTextures), // For each texture, an index to its first element in textureData\n eachTextureAttributes: new Uint16Array(numTextures * NUM_TEXTURE_ATTRIBUTES),\n positions: new Uint16Array(lenPositions), // All geometry arrays\n normals: new Int8Array(lenNormals),\n colors: new Uint8Array(lenColors),\n uvs: new Float32Array(lenUVs),\n indices: new Uint32Array(lenIndices),\n edgeIndices: new Uint32Array(lenEdgeIndices),\n eachTextureSetTextures: new Int32Array(numTextureSets * 5), // For each texture set, a set of five Texture indices [color, metal/roughness,normals,emissive,occlusion]; each index has value -1 if no texture\n matrices: new Float32Array(lenMatrices), // Modeling matrices for entities that share geometries. Each entity either shares all it's geometries, or owns all its geometries exclusively. Exclusively-owned geometries are pre-transformed into World-space, and so their entities don't have modeling matrices in this array.\n reusedGeometriesDecodeMatrix: new Float32Array(xktModel.reusedGeometriesDecodeMatrix), // A single, global vertex position de-quantization matrix for all reused geometries. Reused geometries are quantized to their collective Local-space AABB, and this matrix is derived from that AABB.\n eachGeometryPrimitiveType: new Uint8Array(numGeometries), // Primitive type for each geometry (0=solid triangles, 1=surface triangles, 2=lines, 3=points, 4=line-strip)\n eachGeometryPositionsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.positions. Every primitive type has positions.\n eachGeometryNormalsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.normals. If the next geometry has the same index, then this geometry has no normals.\n eachGeometryColorsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.colors. If the next geometry has the same index, then this geometry has no colors.\n eachGeometryUVsPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.uvs. If the next geometry has the same index, then this geometry has no UVs.\n eachGeometryIndicesPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.indices. If the next geometry has the same index, then this geometry has no indices.\n eachGeometryEdgeIndicesPortion: new Uint32Array(numGeometries), // For each geometry, an index to its first element in data.edgeIndices. If the next geometry has the same index, then this geometry has no edge indices.\n eachMeshGeometriesPortion: new Uint32Array(numMeshes), // For each mesh, an index into the eachGeometry* arrays\n eachMeshMatricesPortion: new Uint32Array(numMeshes), // For each mesh that shares its geometry, an index to its first element in data.matrices, to indicate the modeling matrix that transforms the shared geometry Local-space vertex positions. This is ignored for meshes that don't share geometries, because the vertex positions of non-shared geometries are pre-transformed into World-space.\n eachMeshTextureSet: new Int32Array(numMeshes), // For each mesh, the index of its texture set in data.eachTextureSetTextures; this array contains signed integers so that we can use -1 to indicate when a mesh has no texture set\n eachMeshMaterialAttributes: new Uint8Array(numMeshes * NUM_MATERIAL_ATTRIBUTES), // For each mesh, an RGBA integer color of format [0..255, 0..255, 0..255, 0..255], and PBR metallic and roughness factors, of format [0..255, 0..255]\n eachEntityId: [], // For each entity, an ID string\n eachEntityMeshesPortion: new Uint32Array(numEntities), // For each entity, the index of the first element of meshes used by the entity\n eachTileAABB: new Float64Array(numTiles * 6), // For each tile, an axis-aligned bounding box\n eachTileEntitiesPortion: new Uint32Array(numTiles) // For each tile, the index of the first element of eachEntityId, eachEntityMeshesPortion and eachEntityMatricesPortion used by the tile\n };\n\n let countPositions = 0;\n let countNormals = 0;\n let countColors = 0;\n let countUVs = 0;\n let countIndices = 0;\n let countEdgeIndices = 0;\n\n // Metadata\n\n data.metadata = {\n id: xktModel.modelId,\n projectId: xktModel.projectId,\n revisionId: xktModel.revisionId,\n author: xktModel.author,\n createdAt: xktModel.createdAt,\n creatingApplication: xktModel.creatingApplication,\n schema: xktModel.schema,\n propertySets: [],\n metaObjects: []\n };\n\n // Property sets\n\n for (let propertySetsIndex = 0; propertySetsIndex < numPropertySets; propertySetsIndex++) {\n const propertySet = propertySetsList[propertySetsIndex];\n const propertySetJSON = {\n id: \"\" + propertySet.propertySetId,\n name: propertySet.propertySetName,\n type: propertySet.propertySetType,\n properties: propertySet.properties\n };\n data.metadata.propertySets.push(propertySetJSON);\n }\n\n // Metaobjects\n\n if (!metaModelDataStr) {\n for (let metaObjectsIndex = 0; metaObjectsIndex < numMetaObjects; metaObjectsIndex++) {\n const metaObject = metaObjectsList[metaObjectsIndex];\n const metaObjectJSON = {\n name: metaObject.metaObjectName,\n type: metaObject.metaObjectType,\n id: \"\" + metaObject.metaObjectId\n };\n if (metaObject.parentMetaObjectId !== undefined && metaObject.parentMetaObjectId !== null) {\n metaObjectJSON.parent = \"\" + metaObject.parentMetaObjectId;\n }\n if (metaObject.propertySetIds && metaObject.propertySetIds.length > 0) {\n metaObjectJSON.propertySetIds = metaObject.propertySetIds;\n }\n if (metaObject.external) {\n metaObjectJSON.external = metaObject.external;\n }\n data.metadata.metaObjects.push(metaObjectJSON);\n }\n }\n\n // Geometries\n\n for (let geometryIndex = 0; geometryIndex < numGeometries; geometryIndex++) {\n const geometry = geometriesList [geometryIndex];\n let primitiveType = 1;\n switch (geometry.primitiveType) {\n case \"triangles\":\n primitiveType = geometry.solid ? 0 : 1;\n break;\n case \"points\":\n primitiveType = 2;\n break;\n case \"lines\":\n primitiveType = 3;\n break;\n case \"line-strip\":\n case \"line-loop\":\n primitiveType = 4;\n break;\n case \"triangle-strip\":\n primitiveType = 5;\n break;\n case \"triangle-fan\":\n primitiveType = 6;\n break;\n default:\n primitiveType = 1\n }\n data.eachGeometryPrimitiveType [geometryIndex] = primitiveType;\n data.eachGeometryPositionsPortion [geometryIndex] = countPositions;\n data.eachGeometryNormalsPortion [geometryIndex] = countNormals;\n data.eachGeometryColorsPortion [geometryIndex] = countColors;\n data.eachGeometryUVsPortion [geometryIndex] = countUVs;\n data.eachGeometryIndicesPortion [geometryIndex] = countIndices;\n data.eachGeometryEdgeIndicesPortion [geometryIndex] = countEdgeIndices;\n if (geometry.positionsQuantized) {\n data.positions.set(geometry.positionsQuantized, countPositions);\n countPositions += geometry.positionsQuantized.length;\n }\n if (geometry.normalsOctEncoded) {\n data.normals.set(geometry.normalsOctEncoded, countNormals);\n countNormals += geometry.normalsOctEncoded.length;\n }\n if (geometry.colorsCompressed) {\n data.colors.set(geometry.colorsCompressed, countColors);\n countColors += geometry.colorsCompressed.length;\n }\n if (geometry.uvs) {\n data.uvs.set(geometry.uvs, countUVs);\n countUVs += geometry.uvs.length;\n }\n if (geometry.indices) {\n data.indices.set(geometry.indices, countIndices);\n countIndices += geometry.indices.length;\n }\n if (geometry.edgeIndices) {\n data.edgeIndices.set(geometry.edgeIndices, countEdgeIndices);\n countEdgeIndices += geometry.edgeIndices.length;\n }\n }\n\n // Textures\n\n for (let textureIndex = 0, numTextures = xktModel.texturesList.length, portionIdx = 0; textureIndex < numTextures; textureIndex++) {\n const xktTexture = xktModel.texturesList[textureIndex];\n const imageData = xktTexture.imageData;\n data.textureData.set(imageData, portionIdx);\n data.eachTextureDataPortion[textureIndex] = portionIdx;\n\n portionIdx += imageData.byteLength;\n\n let textureAttrIdx = textureIndex * NUM_TEXTURE_ATTRIBUTES;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.compressed ? 1 : 0;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.mediaType; // GIFMediaType | PNGMediaType | JPEGMediaType\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.width;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.height;\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.minFilter; // LinearMipmapLinearFilter | LinearMipMapNearestFilter | NearestMipMapNearestFilter | NearestMipMapLinearFilter | LinearMipMapLinearFilter\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.magFilter; // LinearFilter | NearestFilter\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapS; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapT; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n data.eachTextureAttributes[textureAttrIdx++] = xktTexture.wrapR; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n }\n\n // Texture sets\n\n for (let textureSetIndex = 0, numTextureSets = xktModel.textureSetsList.length, eachTextureSetTexturesIndex = 0; textureSetIndex < numTextureSets; textureSetIndex++) {\n const textureSet = textureSetsList[textureSetIndex];\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.colorTexture ? textureSet.colorTexture.textureIndex : -1; // Color map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.metallicRoughnessTexture ? textureSet.metallicRoughnessTexture.textureIndex : -1; // Metal/rough map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.normalsTexture ? textureSet.normalsTexture.textureIndex : -1; // Normal map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.emissiveTexture ? textureSet.emissiveTexture.textureIndex : -1; // Emissive map\n data.eachTextureSetTextures[eachTextureSetTexturesIndex++] = textureSet.occlusionTexture ? textureSet.occlusionTexture.textureIndex : -1; // Occlusion map\n }\n\n // Tiles -> Entities -> Meshes\n\n let entityIndex = 0;\n let countEntityMeshesPortion = 0;\n let eachMeshMaterialAttributesIndex = 0;\n let matricesIndex = 0;\n let meshIndex = 0;\n\n for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {\n\n const tile = tilesList [tileIndex];\n const tileEntities = tile.entities;\n const numTileEntities = tileEntities.length;\n\n if (numTileEntities === 0) {\n continue;\n }\n\n data.eachTileEntitiesPortion[tileIndex] = entityIndex;\n\n const tileAABB = tile.aabb;\n\n for (let j = 0; j < numTileEntities; j++) {\n\n const entity = tileEntities[j];\n const entityMeshes = entity.meshes;\n const numEntityMeshes = entityMeshes.length;\n\n for (let k = 0; k < numEntityMeshes; k++) {\n\n const mesh = entityMeshes[k];\n const geometry = mesh.geometry;\n const geometryIndex = geometry.geometryIndex;\n\n data.eachMeshGeometriesPortion [countEntityMeshesPortion + k] = geometryIndex;\n\n if (mesh.geometry.numInstances > 1) {\n data.matrices.set(mesh.matrix, matricesIndex);\n data.eachMeshMatricesPortion [meshIndex] = matricesIndex;\n matricesIndex += 16;\n }\n\n data.eachMeshTextureSet[meshIndex] = mesh.textureSet ? mesh.textureSet.textureSetIndex : -1;\n\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[0] * 255); // Color RGB\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[1] * 255);\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.color[2] * 255);\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.opacity * 255); // Opacity\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.metallic * 255); // Metallic\n data.eachMeshMaterialAttributes[eachMeshMaterialAttributesIndex++] = (mesh.roughness * 255); // Roughness\n\n meshIndex++;\n }\n\n data.eachEntityId [entityIndex] = entity.entityId;\n data.eachEntityMeshesPortion[entityIndex] = countEntityMeshesPortion; // <<<<<<<<<<<<<<<<<<<< Error here? Order/value of countEntityMeshesPortion correct?\n\n entityIndex++;\n countEntityMeshesPortion += numEntityMeshes;\n }\n\n const tileAABBIndex = tileIndex * 6;\n\n data.eachTileAABB.set(tileAABB, tileAABBIndex);\n }\n\n return data;\n}\n\nfunction deflateData(data, metaModelJSON, options) {\n\n function deflate(buffer) {\n return (options.zip !== false) ? pako.deflate(buffer) : buffer;\n }\n\n let metaModelBytes;\n if (metaModelJSON) {\n const deflatedJSON = deflateJSON(metaModelJSON);\n metaModelBytes = deflate(deflatedJSON)\n } else {\n const deflatedJSON = deflateJSON(data.metadata);\n metaModelBytes = deflate(deflatedJSON)\n }\n\n return {\n metadata: metaModelBytes,\n textureData: deflate(data.textureData.buffer),\n eachTextureDataPortion: deflate(data.eachTextureDataPortion.buffer),\n eachTextureAttributes: deflate(data.eachTextureAttributes.buffer),\n positions: deflate(data.positions.buffer),\n normals: deflate(data.normals.buffer),\n colors: deflate(data.colors.buffer),\n uvs: deflate(data.uvs.buffer),\n indices: deflate(data.indices.buffer),\n edgeIndices: deflate(data.edgeIndices.buffer),\n eachTextureSetTextures: deflate(data.eachTextureSetTextures.buffer),\n matrices: deflate(data.matrices.buffer),\n reusedGeometriesDecodeMatrix: deflate(data.reusedGeometriesDecodeMatrix.buffer),\n eachGeometryPrimitiveType: deflate(data.eachGeometryPrimitiveType.buffer),\n eachGeometryPositionsPortion: deflate(data.eachGeometryPositionsPortion.buffer),\n eachGeometryNormalsPortion: deflate(data.eachGeometryNormalsPortion.buffer),\n eachGeometryColorsPortion: deflate(data.eachGeometryColorsPortion.buffer),\n eachGeometryUVsPortion: deflate(data.eachGeometryUVsPortion.buffer),\n eachGeometryIndicesPortion: deflate(data.eachGeometryIndicesPortion.buffer),\n eachGeometryEdgeIndicesPortion: deflate(data.eachGeometryEdgeIndicesPortion.buffer),\n eachMeshGeometriesPortion: deflate(data.eachMeshGeometriesPortion.buffer),\n eachMeshMatricesPortion: deflate(data.eachMeshMatricesPortion.buffer),\n eachMeshTextureSet: deflate(data.eachMeshTextureSet.buffer),\n eachMeshMaterialAttributes: deflate(data.eachMeshMaterialAttributes.buffer),\n eachEntityId: deflate(JSON.stringify(data.eachEntityId)\n .replace(/[\\u007F-\\uFFFF]/g, function (chr) { // Produce only ASCII-chars, so that the data can be inflated later\n return \"\\\\u\" + (\"0000\" + chr.charCodeAt(0).toString(16)).substr(-4)\n })),\n eachEntityMeshesPortion: deflate(data.eachEntityMeshesPortion.buffer),\n eachTileAABB: deflate(data.eachTileAABB.buffer),\n eachTileEntitiesPortion: deflate(data.eachTileEntitiesPortion.buffer)\n };\n}\n\nfunction deflateJSON(strings) {\n return JSON.stringify(strings)\n .replace(/[\\u007F-\\uFFFF]/g, function (chr) { // Produce only ASCII-chars, so that the data can be inflated later\n return \"\\\\u\" + (\"0000\" + chr.charCodeAt(0).toString(16)).substr(-4)\n });\n}\n\nfunction createArrayBuffer(deflatedData) {\n return toArrayBuffer([\n deflatedData.metadata,\n deflatedData.textureData,\n deflatedData.eachTextureDataPortion,\n deflatedData.eachTextureAttributes,\n deflatedData.positions,\n deflatedData.normals,\n deflatedData.colors,\n deflatedData.uvs,\n deflatedData.indices,\n deflatedData.edgeIndices,\n deflatedData.eachTextureSetTextures,\n deflatedData.matrices,\n deflatedData.reusedGeometriesDecodeMatrix,\n deflatedData.eachGeometryPrimitiveType,\n deflatedData.eachGeometryPositionsPortion,\n deflatedData.eachGeometryNormalsPortion,\n deflatedData.eachGeometryColorsPortion,\n deflatedData.eachGeometryUVsPortion,\n deflatedData.eachGeometryIndicesPortion,\n deflatedData.eachGeometryEdgeIndicesPortion,\n deflatedData.eachMeshGeometriesPortion,\n deflatedData.eachMeshMatricesPortion,\n deflatedData.eachMeshTextureSet,\n deflatedData.eachMeshMaterialAttributes,\n deflatedData.eachEntityId,\n deflatedData.eachEntityMeshesPortion,\n deflatedData.eachTileAABB,\n deflatedData.eachTileEntitiesPortion\n ]);\n}\n\nfunction toArrayBuffer(elements) {\n const indexData = new Uint32Array(elements.length + 2);\n indexData[0] = XKT_VERSION;\n indexData [1] = elements.length; // Stored Data 1.1: number of stored elements\n let dataLen = 0; // Stored Data 1.2: length of stored elements\n for (let i = 0, len = elements.length; i < len; i++) {\n const element = elements[i];\n const elementsize = element.length;\n indexData[i + 2] = elementsize;\n dataLen += elementsize;\n }\n const indexBuf = new Uint8Array(indexData.buffer);\n const dataArray = new Uint8Array(indexBuf.length + dataLen);\n dataArray.set(indexBuf);\n let offset = indexBuf.length;\n for (let i = 0, len = elements.length; i < len; i++) { // Stored Data 2: the elements themselves\n const element = elements[i];\n dataArray.set(element, offset);\n offset += element.length;\n }\n return dataArray.buffer;\n}\n\nexport {writeXKTModelToArrayBuffer};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKTModel/writeXKTModelToArrayBuffer.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKTModel/writeXKTModelToArrayBuffer.js", "access": "public", "description": null, "lineNumber": 1 @@ -7591,7 +7591,7 @@ "name": "src/XKT_INFO.js", "content": "/**\n * @desc Provides info on the XKT generated by xeokit-convert.\n */\nconst XKT_INFO = {\n\n /**\n * The XKT version generated by xeokit-convert.\n *\n * This is the XKT version that's modeled by {@link XKTModel}, serialized\n * by {@link writeXKTModelToArrayBuffer}, and written by {@link convert2xkt}.\n *\n * * Current XKT version: **10**\n * * [XKT format specs](https://github.com/xeokit/xeokit-convert/blob/main/specs/index.md)\n *\n * @property xktVersion\n * @type {number}\n */\n xktVersion: 10\n};\n\nexport {XKT_INFO};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/XKT_INFO.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/XKT_INFO.js", "access": "public", "description": null, "lineNumber": 1 @@ -7621,7 +7621,7 @@ "name": "src/constants.js", "content": "/*----------------------------------------------------------------------------------------------------------------------\n * NOTE: The values of these constants must match those within xeokit-sdk\n *--------------------------------------------------------------------------------------------------------------------*/\n\n/**\n * Texture wrapping mode in which the texture repeats to infinity.\n */\nexport const RepeatWrapping = 1000;\n\n/**\n * Texture wrapping mode in which the last pixel of the texture stretches to the edge of the mesh.\n */\nexport const ClampToEdgeWrapping = 1001;\n\n/**\n * Texture wrapping mode in which the texture repeats to infinity, mirroring on each repeat.\n */\nexport const MirroredRepeatWrapping = 1002;\n\n/**\n * Texture magnification and minification filter that returns the nearest texel to the given sample coordinates.\n */\nexport const NearestFilter = 1003;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and returns the nearest texel to the given sample coordinates.\n */\nexport const NearestMipMapNearestFilter = 1004;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured\n * and returns the nearest texel to the given sample coordinates.\n */\nexport const NearestMipmapNearestFilter = 1004;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\n */\nexport const NearestMipmapLinearFilter = 1005;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\n */\nexport const NearestMipMapLinearFilter = 1005;\n\n/**\n * Texture magnification and minification filter that returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nexport const LinearFilter = 1006;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\n * returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nexport const LinearMipmapNearestFilter = 1007;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\n * returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nexport const LinearMipMapNearestFilter = 1007;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\n * weighted average of those two values.\n */\nexport const LinearMipmapLinearFilter = 1008;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\n * weighted average of those two values.\n */\nexport const LinearMipMapLinearFilter = 1008;\n\n/**\n * Media type for GIF images.\n */\nexport const GIFMediaType = 10000;\n\n/**\n * Media type for JPEG images.\n */\nexport const JPEGMediaType = 10001;\n\n/**\n * Media type for PNG images.\n */\nexport const PNGMediaType = 10002;", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/constants.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/constants.js", "access": "public", "description": null, "lineNumber": 1 @@ -7936,7 +7936,7 @@ "name": "src/convert2xkt.js", "content": "import {XKT_INFO} from \"./XKT_INFO.js\";\nimport {XKTModel} from \"./XKTModel/XKTModel.js\";\nimport {parseCityJSONIntoXKTModel} from \"./parsers/parseCityJSONIntoXKTModel.js\";\nimport {parseGLTFIntoXKTModel} from \"./parsers/parseGLTFIntoXKTModel.js\";\nimport {parseIFCIntoXKTModel} from \"./parsers/parseIFCIntoXKTModel.js\";\nimport {parseLASIntoXKTModel} from \"./parsers/parseLASIntoXKTModel.js\";\nimport {parsePCDIntoXKTModel} from \"./parsers/parsePCDIntoXKTModel.js\";\nimport {parsePLYIntoXKTModel} from \"./parsers/parsePLYIntoXKTModel.js\";\nimport {parseSTLIntoXKTModel} from \"./parsers/parseSTLIntoXKTModel.js\";\nimport {writeXKTModelToArrayBuffer} from \"./XKTModel/writeXKTModelToArrayBuffer.js\";\n\nimport {toArrayBuffer} from \"./XKTModel/lib/toArraybuffer\";\n\nconst fs = require('fs');\nconst path = require(\"path\");\n\n/**\n * Converts model files into xeokit's native XKT format.\n *\n * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.\n *\n * **Only bundled in xeokit-convert.cjs.js.**\n *\n * ## Usage\n *\n * ````javascript\n * const convert2xkt = require(\"@xeokit/xeokit-convert/dist/convert2xkt.cjs.js\");\n * const fs = require('fs');\n *\n * convert2xkt({\n * sourceData: fs.readFileSync(\"rme_advanced_sample_project.ifc\"),\n * outputXKT: (xtkArrayBuffer) => {\n * fs.writeFileSync(\"rme_advanced_sample_project.ifc.xkt\", xtkArrayBuffer);\n * }\n * }).then(() => {\n * console.log(\"Converted.\");\n * }, (errMsg) => {\n * console.error(\"Conversion failed: \" + errMsg)\n * });\n ````\n * @param {Object} params Conversion parameters.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {*} [params.configs] Configurations.\n * @param {String} [params.source] Path to source file. Alternative to ````sourceData````.\n * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````.\n * @param {String} [params.sourceFormat] Format of source file/data. Always needed with ````sourceData````, but not normally needed with ````source````, because convert2xkt will determine the format automatically from the file extension of ````source````.\n * @param {String} [params.metaModelDataStr] Source file data. Overrides metadata from ````metaModelSource````, ````sourceData```` and ````source````.\n * @param {String} [params.metaModelSource] Path to source metaModel file. Overrides metadata from ````sourceData```` and ````source````. Overridden by ````metaModelData````.\n * @param {String} [params.output] Path to destination XKT file. Directories on this path are automatically created if not existing.\n * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method.\n * @param {Function} [params.outputXKT] Callback to collect XKT file data.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided.\n * @param {Function} [params.outputStats] Callback to collect statistics.\n * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis \"up\", if necessary. Applies to CityJSON and LAS/LAZ models.\n * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models.\n * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore\n * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the model.\n * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000,\n * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close\n * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger.\n * @param {Function} [params.log] Logging callback.\n * @return {Promise}\n */\nfunction convert2xkt({\n WebIFC,\n configs = {},\n source,\n sourceData,\n sourceFormat,\n metaModelSource,\n metaModelDataStr,\n modelAABB,\n output,\n outputXKTModel,\n outputXKT,\n includeTypes,\n excludeTypes,\n reuseGeometries = true,\n minTileSize = 200,\n stats = {},\n outputStats,\n rotateX = false,\n includeTextures = true,\n includeNormals = true,\n log = function (msg) {\n }\n }) {\n\n stats.sourceFormat = \"\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 0;\n stats.numPropertySets = 0;\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numUVs = 0;\n stats.numTextures = 0;\n stats.numTextureSets = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n stats.sourceSize = 0;\n stats.xktSize = 0;\n stats.texturesSize = 0;\n stats.xktVersion = \"\";\n stats.compressionRatio = 0;\n stats.conversionTime = 0;\n stats.aabb = null;\n\n function getFileExtension(fileName) {\n let ext = path.extname(fileName);\n if (ext.charAt(0) === \".\") {\n ext = ext.substring(1);\n }\n return ext;\n }\n\n return new Promise(function (resolve, reject) {\n const _log = log;\n log = (msg) => {\n _log(`[convert2xkt] ${msg}`)\n }\n\n if (!source && !sourceData) {\n reject(\"Argument expected: source or sourceData\");\n return;\n }\n\n if (!sourceFormat && sourceData) {\n reject(\"Argument expected: sourceFormat is required with sourceData\");\n return;\n }\n\n if (!output && !outputXKTModel && !outputXKT) {\n reject(\"Argument expected: output, outputXKTModel or outputXKT\");\n return;\n }\n\n if (source) {\n log('Reading input file: ' + source);\n }\n\n const startTime = new Date();\n\n const sourceConfigs = configs.sourceConfigs || {};\n const ext = sourceFormat || getFileExtension(source);\n\n log(`Input file extension: \"${ext}\"`);\n\n let fileTypeConfigs = sourceConfigs[ext];\n\n if (!fileTypeConfigs) {\n log(`[WARNING] Could not find configs sourceConfigs entry for source format \"${ext}\". This is derived from the source file name extension. Will use internal default configs.`);\n fileTypeConfigs = {};\n }\n\n function overrideOption(option1, option2) {\n if (option1 !== undefined) {\n return option1;\n }\n return option2;\n }\n\n if (!sourceData) {\n try {\n sourceData = fs.readFileSync(source);\n } catch (err) {\n reject(err);\n return;\n }\n }\n\n const sourceFileSizeBytes = sourceData.byteLength;\n\n log(\"Input file size: \" + (sourceFileSizeBytes / 1000).toFixed(2) + \" kB\");\n\n if (!metaModelDataStr && metaModelSource) {\n log('Reading input metadata file: ' + metaModelSource);\n try {\n metaModelDataStr = fs.readFileSync(metaModelSource);\n } catch (err) {\n reject(err);\n return;\n }\n } else {\n log(`Not embedding metadata in XKT`);\n }\n\n let metaModelJSON;\n\n if (metaModelDataStr) {\n try {\n metaModelJSON = JSON.parse(metaModelDataStr);\n } catch (e) {\n metaModelJSON = {};\n log(`Error parsing metadata JSON: ${e}`);\n }\n }\n\n minTileSize = overrideOption(fileTypeConfigs.minTileSize, minTileSize);\n rotateX = overrideOption(fileTypeConfigs.rotateX, rotateX);\n reuseGeometries = overrideOption(fileTypeConfigs.reuseGeometries, reuseGeometries);\n includeTextures = overrideOption(fileTypeConfigs.includeTextures, includeTextures);\n includeNormals = overrideOption(fileTypeConfigs.includeNormals, includeNormals);\n includeTypes = overrideOption(fileTypeConfigs.includeTypes, includeTypes);\n excludeTypes = overrideOption(fileTypeConfigs.excludeTypes, excludeTypes);\n\n if (reuseGeometries === false) {\n log(\"Geometry reuse is disabled\");\n }\n\n const xktModel = new XKTModel({\n minTileSize,\n modelAABB\n });\n\n switch (ext) {\n case \"json\":\n convert(parseCityJSONIntoXKTModel, {\n data: JSON.parse(sourceData),\n xktModel,\n stats,\n rotateX,\n center: fileTypeConfigs.center,\n transform: fileTypeConfigs.transform,\n log\n });\n break;\n\n case \"glb\":\n sourceData = toArrayBuffer(sourceData);\n convert(parseGLTFIntoXKTModel, {\n data: sourceData,\n reuseGeometries,\n includeTextures: true,\n includeNormals,\n metaModelData: metaModelJSON,\n xktModel,\n stats,\n log\n });\n break;\n\n case \"gltf\":\n sourceData = toArrayBuffer(sourceData);\n const gltfBasePath = source ? path.dirname(source) : \"\";\n convert(parseGLTFIntoXKTModel, {\n baseUri: gltfBasePath,\n data: sourceData,\n reuseGeometries,\n includeTextures: true,\n includeNormals,\n metaModelData: metaModelJSON,\n xktModel,\n stats,\n log\n });\n break;\n\n // case \"gltf\":\n // const gltfJSON = JSON.parse(sourceData);\n // const gltfBasePath = source ? getBasePath(source) : \"\";\n // convert(parseGLTFIntoXKTModel, {\n // baseUri: gltfBasePath,\n // data: gltfJSON,\n // reuseGeometries,\n // includeTextures,\n // includeNormals,\n // metaModelData: metaModelJSON,\n // xktModel,\n // getAttachment: async (name) => {\n // const filePath = gltfBasePath + name;\n // log(`Reading attachment file: ${filePath}`);\n // const buffer = fs.readFileSync(filePath);\n // const arrayBuf = toArrayBuffer(buffer);\n // return arrayBuf;\n // },\n // stats,\n // log\n // });\n // break;\n\n case \"ifc\":\n convert(parseIFCIntoXKTModel, {\n WebIFC,\n data: sourceData,\n xktModel,\n wasmPath: \"./\",\n includeTypes,\n excludeTypes,\n stats,\n log\n });\n break;\n\n case \"laz\":\n convert(parseLASIntoXKTModel, {\n data: sourceData,\n xktModel,\n stats,\n fp64: fileTypeConfigs.fp64,\n colorDepth: fileTypeConfigs.colorDepth,\n center: fileTypeConfigs.center,\n transform: fileTypeConfigs.transform,\n skip: overrideOption(fileTypeConfigs.skip, 1),\n log\n });\n break;\n\n case \"las\":\n convert(parseLASIntoXKTModel, {\n data: sourceData,\n xktModel,\n stats,\n fp64: fileTypeConfigs.fp64,\n colorDepth: fileTypeConfigs.colorDepth,\n center: fileTypeConfigs.center,\n transform: fileTypeConfigs.transform,\n skip: overrideOption(fileTypeConfigs.skip, 1),\n log\n });\n break;\n\n case \"pcd\":\n convert(parsePCDIntoXKTModel, {\n data: sourceData,\n xktModel,\n stats,\n log\n });\n break;\n\n case \"ply\":\n convert(parsePLYIntoXKTModel, {\n data: sourceData,\n xktModel,\n stats,\n log\n });\n break;\n\n case \"stl\":\n convert(parseSTLIntoXKTModel, {\n data: sourceData,\n xktModel,\n stats,\n log\n });\n break;\n\n default:\n reject(`Error: unsupported source format: \"${ext}\".`);\n return;\n }\n\n function convert(parser, converterParams) {\n\n parser(converterParams).then(() => {\n\n if (!metaModelJSON) {\n log(\"Creating default metamodel in XKT\");\n xktModel.createDefaultMetaObjects();\n }\n\n log(\"Input file parsed OK. Building XKT document...\");\n\n xktModel.finalize().then(() => {\n\n log(\"XKT document built OK. Writing to XKT file...\");\n\n const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel, metaModelJSON, stats, {zip: true});\n\n const xktContent = Buffer.from(xktArrayBuffer);\n\n const targetFileSizeBytes = xktArrayBuffer.byteLength;\n\n stats.minTileSize = minTileSize || 200;\n stats.sourceSize = (sourceFileSizeBytes / 1000).toFixed(2);\n stats.xktSize = (targetFileSizeBytes / 1000).toFixed(2);\n stats.xktVersion = XKT_INFO.xktVersion;\n stats.compressionRatio = (sourceFileSizeBytes / targetFileSizeBytes).toFixed(2);\n stats.conversionTime = ((new Date() - startTime) / 1000.0).toFixed(2);\n stats.aabb = xktModel.aabb;\n log(`Converted to: XKT v${stats.xktVersion}`);\n if (includeTypes) {\n log(\"Include types: \" + (includeTypes ? includeTypes : \"(include all)\"));\n }\n if (excludeTypes) {\n log(\"Exclude types: \" + (excludeTypes ? excludeTypes : \"(exclude none)\"));\n }\n log(\"XKT size: \" + stats.xktSize + \" kB\");\n log(\"XKT textures size: \" + (stats.texturesSize / 1000).toFixed(2) + \"kB\");\n log(\"Compression ratio: \" + stats.compressionRatio);\n log(\"Conversion time: \" + stats.conversionTime + \" s\");\n log(\"Converted metaobjects: \" + stats.numMetaObjects);\n log(\"Converted property sets: \" + stats.numPropertySets);\n log(\"Converted drawable objects: \" + stats.numObjects);\n log(\"Converted geometries: \" + stats.numGeometries);\n log(\"Converted textures: \" + stats.numTextures);\n log(\"Converted textureSets: \" + stats.numTextureSets);\n log(\"Converted triangles: \" + stats.numTriangles);\n log(\"Converted vertices: \" + stats.numVertices);\n log(\"Converted UVs: \" + stats.numUVs);\n log(\"Converted normals: \" + stats.numNormals);\n log(\"Converted tiles: \" + xktModel.tilesList.length);\n log(\"minTileSize: \" + stats.minTileSize);\n\n if (output) {\n const outputDir = path.dirname(output);\n if (outputDir !== \"\" && !fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, {recursive: true});\n }\n log('Writing XKT file: ' + output);\n fs.writeFileSync(output, xktContent);\n }\n\n if (outputXKTModel) {\n outputXKTModel(xktModel);\n }\n\n if (outputXKT) {\n outputXKT(xktContent);\n }\n\n if (outputStats) {\n outputStats(stats);\n }\n\n resolve();\n });\n }, (err) => {\n reject(err);\n });\n }\n });\n}\n\nexport {convert2xkt};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/convert2xkt.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/convert2xkt.js", "access": "public", "description": null, "lineNumber": 1 @@ -8191,16 +8191,75 @@ { "__docId__": 330, "kind": "file", + "name": "src/convert2xkt_browser.js", + "content": "\nimport {XKTModel} from \"./XKTModel/XKTModel.js\";\nimport {parseGLTFIntoXKTModel} from \"./parsers/parseGLTFIntoXKTModel.js\";\nimport {writeXKTModelToArrayBuffer} from \"./XKTModel/writeXKTModelToArrayBuffer.js\";\n\nimport {toArrayBuffer} from \"./XKTModel/lib/toArraybuffer\";\n\n/**\n * Converts model files into xeokit's native XKT format.\n *\n * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS.\n *\n * **Only bundled in xeokit-convert.cjs.js.**\n *\n * ## Usage\n *\n ````\n * @param {Object} params Conversion parameters.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {*} [params.configs] Configurations.\n * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````.\n * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method.\n * @param {Function} [params.outputXKT] Callback to collect XKT file data.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided.\n * @param {Function} [params.outputStats] Callback to collect statistics.\n * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis \"up\", if necessary. Applies to CityJSON and LAS/LAZ models.\n * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models.\n * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore\n * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the model.\n * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000,\n * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close\n * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger.\n * @param {Function} [params.log] Logging callback.\n * @return {Promise}\n */\nfunction convert2xkt({\n configs = {},\n sourceData,\n modelAABB,\n outputXKTModel,\n outputXKT,\n includeTypes,\n excludeTypes,\n reuseGeometries = true,\n minTileSize = 200,\n stats = {},\n rotateX = false,\n includeTextures = true,\n includeNormals = true,\n log = function (msg) {\n }\n }) {\n\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 0;\n stats.numPropertySets = 0;\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numUVs = 0;\n stats.numTextures = 0;\n stats.numTextureSets = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n stats.sourceSize = 0;\n stats.xktSize = 0;\n stats.texturesSize = 0;\n stats.xktVersion = \"\";\n stats.compressionRatio = 0;\n stats.conversionTime = 0;\n stats.aabb = null;\n\n return new Promise(function (resolve, reject) {\n const _log = log;\n log = (msg) => {\n _log(`[convert2xkt] ${msg}`)\n }\n\n if (!sourceData) {\n reject(\"Argument expected: source or sourceData\");\n return;\n }\n\n if (!outputXKTModel && !outputXKT) {\n reject(\"Argument expected: output, outputXKTModel or outputXKT\");\n return;\n }\n\n const sourceConfigs = configs.sourceConfigs || {};\n const ext = 'glb';\n\n log(`Input file extension: \"${ext}\"`);\n\n let fileTypeConfigs = sourceConfigs[ext];\n\n if (!fileTypeConfigs) {\n log(`[WARNING] Could not find configs sourceConfigs entry for source format \"${ext}\". This is derived from the source file name extension. Will use internal default configs.`);\n fileTypeConfigs = {};\n }\n\n function overrideOption(option1, option2) {\n if (option1 !== undefined) {\n return option1;\n }\n return option2;\n }\n\n\n const sourceFileSizeBytes = sourceData.byteLength;\n\n log(\"Input file size: \" + (sourceFileSizeBytes / 1000).toFixed(2) + \" kB\");\n\n\n\n minTileSize = overrideOption(fileTypeConfigs.minTileSize, minTileSize);\n rotateX = overrideOption(fileTypeConfigs.rotateX, rotateX);\n reuseGeometries = overrideOption(fileTypeConfigs.reuseGeometries, reuseGeometries);\n includeTextures = overrideOption(fileTypeConfigs.includeTextures, includeTextures);\n includeNormals = overrideOption(fileTypeConfigs.includeNormals, includeNormals);\n includeTypes = overrideOption(fileTypeConfigs.includeTypes, includeTypes);\n excludeTypes = overrideOption(fileTypeConfigs.excludeTypes, excludeTypes);\n\n if (reuseGeometries === false) {\n log(\"Geometry reuse is disabled\");\n }\n\n const xktModel = new XKTModel({\n minTileSize,\n modelAABB\n });\n\n\n\n sourceData = toArrayBuffer(sourceData);\n convert(parseGLTFIntoXKTModel, {\n data: sourceData,\n reuseGeometries,\n includeTextures: true,\n includeNormals,\n xktModel,\n stats,\n log\n });\n\n\n function convert(parser, converterParams) {\n\n parser(converterParams).then(() => {\n\n\n log(\"Input file parsed OK. Building XKT document...\");\n\n xktModel.finalize().then(() => {\n\n log(\"XKT document built OK. Writing to XKT file...\");\n\n const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel, null, stats, {zip: true});\n\n const xktContent = Buffer.from(xktArrayBuffer);\n\n\n if (outputXKT) {\n outputXKT(xktContent);\n }\n\n resolve();\n });\n }, (err) => {\n reject(err);\n });\n }\n });\n}\n\nexport {convert2xkt};", + "static": true, + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/convert2xkt_browser.js", + "access": "public", + "description": null, + "lineNumber": 1 + }, + { + "__docId__": 331, + "kind": "function", + "name": "convert2xkt", + "memberof": "src/convert2xkt_browser.js", + "generator": false, + "async": false, + "static": true, + "longname": "src/convert2xkt_browser.js~convert2xkt", + "access": "public", + "export": true, + "importPath": "@xeokit/xeokit-convert/src/convert2xkt_browser.js", + "importStyle": "{convert2xkt}", + "description": "Converts model files into xeokit's native XKT format.\n\nSupported source formats are: IFC, CityJSON, glTF, LAZ and LAS.\n\n**Only bundled in xeokit-convert.cjs.js.**\n\n## Usage\n\n````\n@param {Object} params Conversion parameters.\n@param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\ncaller the choice of whether to use the Browser or NodeJS version.\n@param {*} [params.configs] Configurations.\n@param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````.\n@param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method.\n@param {Function} [params.outputXKT] Callback to collect XKT file data.\n@param {String[]} [params.includeTypes] Option to only convert objects of these types.\n@param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n@param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided.\n@param {Function} [params.outputStats] Callback to collect statistics.\n@param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis \"up\", if necessary. Applies to CityJSON and LAS/LAZ models.\n@param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false,\nwill automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\nfile size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\nhas excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are\nshared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\npathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n@param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models.\n@param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore\ngeometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has\nthe limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\na flat-shaded non-PBR representation of the model.", + "lineNumber": 47, + "params": [ + { + "nullable": null, + "types": [ + "Number" + ], + "spread": false, + "optional": true, + "defaultValue": "200", + "defaultRaw": 200, + "name": "params.minTileSize", + "description": "Minimum RTC coordinate tile size. Set this to a value between 100 and 10000,\ndepending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close\nto the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger." + }, + { + "nullable": null, + "types": [ + "Function" + ], + "spread": false, + "optional": true, + "name": "params.log", + "description": "Logging callback." + } + ], + "return": { + "nullable": null, + "types": [ + "Promise" + ], + "spread": false, + "description": "" + } + }, + { + "__docId__": 332, + "kind": "file", "name": "src/geometryBuilders/buildBoxGeometry.js", "content": "/**\n * @desc Creates box-shaped triangle mesh geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a box-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildBoxGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const box = buildBoxGeometry({\n * primitiveType: \"triangles\" // or \"lines\"\n * center: [0,0,0],\n * xSize: 1, // Half-size on each axis\n * ySize: 1,\n * zSize: 1\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"boxGeometry\",\n * primitiveType: box.primitiveType,\n * positions: box.positions,\n * normals: box.normals,\n * indices: box.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redBoxMesh\",\n * geometryId: \"boxGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redBox\",\n * meshIds: [\"redBoxMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildBoxGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.xSize=1.0] Half-size on the X-axis.\n * @param {Number} [cfg.ySize=1.0] Half-size on the Y-axis.\n * @param {Number} [cfg.zSize=1.0] Half-size on the Z-axis.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildBoxGeometry(cfg = {}) {\n\n let xSize = cfg.xSize || 1;\n if (xSize < 0) {\n console.error(\"negative xSize not allowed - will invert\");\n xSize *= -1;\n }\n\n let ySize = cfg.ySize || 1;\n if (ySize < 0) {\n console.error(\"negative ySize not allowed - will invert\");\n ySize *= -1;\n }\n\n let zSize = cfg.zSize || 1;\n if (zSize < 0) {\n console.error(\"negative zSize not allowed - will invert\");\n zSize *= -1;\n }\n\n const center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const xmin = -xSize + centerX;\n const ymin = -ySize + centerY;\n const zmin = -zSize + centerZ;\n const xmax = xSize + centerX;\n const ymax = ySize + centerY;\n const zmax = zSize + centerZ;\n\n return {\n\n primitiveType: \"triangles\",\n\n // The vertices - eight for our cube, each\n // one spanning three array elements for X,Y and Z\n\n positions: [\n\n // v0-v1-v2-v3 front\n xmax, ymax, zmax,\n xmin, ymax, zmax,\n xmin, ymin, zmax,\n xmax, ymin, zmax,\n\n // v0-v3-v4-v1 right\n xmax, ymax, zmax,\n xmax, ymin, zmax,\n xmax, ymin, zmin,\n xmax, ymax, zmin,\n\n // v0-v1-v6-v1 top\n xmax, ymax, zmax,\n xmax, ymax, zmin,\n xmin, ymax, zmin,\n xmin, ymax, zmax,\n\n // v1-v6-v7-v2 left\n xmin, ymax, zmax,\n xmin, ymax, zmin,\n xmin, ymin, zmin,\n xmin, ymin, zmax,\n\n // v7-v4-v3-v2 bottom\n xmin, ymin, zmin,\n xmax, ymin, zmin,\n xmax, ymin, zmax,\n xmin, ymin, zmax,\n\n // v4-v7-v6-v1 back\n xmax, ymin, zmin,\n xmin, ymin, zmin,\n xmin, ymax, zmin,\n xmax, ymax, zmin\n ],\n\n // Normal vectors, one for each vertex\n normals: [\n\n // v0-v1-v2-v3 front\n 0, 0, 1,\n 0, 0, 1,\n 0, 0, 1,\n 0, 0, 1,\n\n // v0-v3-v4-v5 right\n 1, 0, 0,\n 1, 0, 0,\n 1, 0, 0,\n 1, 0, 0,\n\n // v0-v5-v6-v1 top\n 0, 1, 0,\n 0, 1, 0,\n 0, 1, 0,\n 0, 1, 0,\n\n // v1-v6-v7-v2 left\n -1, 0, 0,\n -1, 0, 0,\n -1, 0, 0,\n -1, 0, 0,\n\n // v7-v4-v3-v2 bottom\n 0, -1, 0,\n 0, -1, 0,\n 0, -1, 0,\n 0, -1, 0,\n\n // v4-v7-v6-v5 back\n 0, 0, -1,\n 0, 0, -1,\n 0, 0, -1,\n 0, 0, -1\n ],\n\n // UV coords\n uv: [\n\n // v0-v1-v2-v3 front\n 1, 0,\n 0, 0,\n 0, 1,\n 1, 1,\n\n // v0-v3-v4-v1 right\n 0, 0,\n 0, 1,\n 1, 1,\n 1, 0,\n\n // v0-v1-v6-v1 top\n 1, 1,\n 1, 0,\n 0, 0,\n 0, 1,\n\n // v1-v6-v7-v2 left\n 1, 0,\n 0, 0,\n 0, 1,\n 1, 1,\n\n // v7-v4-v3-v2 bottom\n 0, 1,\n 1, 1,\n 1, 0,\n 0, 0,\n\n // v4-v7-v6-v1 back\n 0, 1,\n 1, 1,\n 1, 0,\n 0, 0\n ],\n\n // Indices - these organise the\n // positions and uv texture coordinates\n // into geometric primitives in accordance\n // with the \"primitive\" parameter,\n // in this case a set of three indices\n // for each triangle.\n //\n // Note that each triangle is specified\n // in counter-clockwise winding order.\n //\n // You can specify them in clockwise\n // order if you configure the Modes\n // node's frontFace flag as \"cw\", instead of\n // the default \"ccw\".\n indices: [\n 0, 1, 2,\n 0, 2, 3,\n // front\n 4, 5, 6,\n 4, 6, 7,\n // right\n 8, 9, 10,\n 8, 10, 11,\n // top\n 12, 13, 14,\n 12, 14, 15,\n // left\n 16, 17, 18,\n 16, 18, 19,\n // bottom\n 20, 21, 22,\n 20, 22, 23\n ]\n };\n}\n\nexport {buildBoxGeometry};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/geometryBuilders/buildBoxGeometry.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/geometryBuilders/buildBoxGeometry.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 331, + "__docId__": 333, "kind": "function", "name": "buildBoxGeometry", "memberof": "src/geometryBuilders/buildBoxGeometry.js", @@ -8292,18 +8351,18 @@ } }, { - "__docId__": 332, + "__docId__": 334, "kind": "file", "name": "src/geometryBuilders/buildBoxLinesGeometry.js", "content": "/**\n * @desc Creates box-shaped line segment geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a box-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildBoxLinesGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const box = buildBoxLinesGeometry({\n * center: [0,0,0],\n * xSize: 1, // Half-size on each axis\n * ySize: 1,\n * zSize: 1\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"boxGeometry\",\n * primitiveType: box.primitiveType, // \"lines\"\n * positions: box.positions,\n * normals: box.normals,\n * indices: box.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redBoxMesh\",\n * geometryId: \"boxGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redBox\",\n * meshIds: [\"redBoxMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildBoxLinesGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.xSize=1.0] Half-size on the X-axis.\n * @param {Number} [cfg.ySize=1.0] Half-size on the Y-axis.\n * @param {Number} [cfg.zSize=1.0] Half-size on the Z-axis.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildBoxLinesGeometry(cfg = {}) {\n\n let xSize = cfg.xSize || 1;\n if (xSize < 0) {\n console.error(\"negative xSize not allowed - will invert\");\n xSize *= -1;\n }\n\n let ySize = cfg.ySize || 1;\n if (ySize < 0) {\n console.error(\"negative ySize not allowed - will invert\");\n ySize *= -1;\n }\n\n let zSize = cfg.zSize || 1;\n if (zSize < 0) {\n console.error(\"negative zSize not allowed - will invert\");\n zSize *= -1;\n }\n\n const center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const xmin = -xSize + centerX;\n const ymin = -ySize + centerY;\n const zmin = -zSize + centerZ;\n const xmax = xSize + centerX;\n const ymax = ySize + centerY;\n const zmax = zSize + centerZ;\n\n return {\n primitiveType: \"lines\",\n positions: [\n xmin, ymin, zmin,\n xmin, ymin, zmax,\n xmin, ymax, zmin,\n xmin, ymax, zmax,\n xmax, ymin, zmin,\n xmax, ymin, zmax,\n xmax, ymax, zmin,\n xmax, ymax, zmax\n ],\n indices: [\n 0, 1,\n 1, 3,\n 3, 2,\n 2, 0,\n 4, 5,\n 5, 7,\n 7, 6,\n 6, 4,\n 0, 4,\n 1, 5,\n 2, 6,\n 3, 7\n ]\n }\n}\n\nexport {buildBoxLinesGeometry};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/geometryBuilders/buildBoxLinesGeometry.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/geometryBuilders/buildBoxLinesGeometry.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 333, + "__docId__": 335, "kind": "function", "name": "buildBoxLinesGeometry", "memberof": "src/geometryBuilders/buildBoxLinesGeometry.js", @@ -8395,18 +8454,18 @@ } }, { - "__docId__": 334, + "__docId__": 336, "kind": "file", "name": "src/geometryBuilders/buildCylinderGeometry.js", "content": "/**\n * @desc Creates cylinder-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a cylinder-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildCylinderGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const cylinder = buildCylinderGeometry({\n * center: [0,0,0],\n * radiusTop: 2.0,\n * radiusBottom: 2.0,\n * height: 5.0,\n * radialSegments: 20,\n * heightSegments: 1,\n * openEnded: false\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"cylinderGeometry\",\n * primitiveType: cylinder.primitiveType,\n * positions: cylinder.positions,\n * normals: cylinder.normals,\n * indices: cylinder.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redCylinderMesh\",\n * geometryId: \"cylinderGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redCylinder\",\n * meshIds: [\"redCylinderMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildCylinderGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.radiusTop=1] Radius of top.\n * @param {Number} [cfg.radiusBottom=1] Radius of bottom.\n * @param {Number} [cfg.height=1] Height.\n * @param {Number} [cfg.radialSegments=60] Number of horizontal segments.\n * @param {Number} [cfg.heightSegments=1] Number of vertical segments.\n * @param {Boolean} [cfg.openEnded=false] Whether or not the cylinder has solid caps on the ends.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildCylinderGeometry(cfg = {}) {\n\n let radiusTop = cfg.radiusTop || 1;\n if (radiusTop < 0) {\n console.error(\"negative radiusTop not allowed - will invert\");\n radiusTop *= -1;\n }\n\n let radiusBottom = cfg.radiusBottom || 1;\n if (radiusBottom < 0) {\n console.error(\"negative radiusBottom not allowed - will invert\");\n radiusBottom *= -1;\n }\n\n let height = cfg.height || 1;\n if (height < 0) {\n console.error(\"negative height not allowed - will invert\");\n height *= -1;\n }\n\n let radialSegments = cfg.radialSegments || 32;\n if (radialSegments < 0) {\n console.error(\"negative radialSegments not allowed - will invert\");\n radialSegments *= -1;\n }\n if (radialSegments < 3) {\n radialSegments = 3;\n }\n\n let heightSegments = cfg.heightSegments || 1;\n if (heightSegments < 0) {\n console.error(\"negative heightSegments not allowed - will invert\");\n heightSegments *= -1;\n }\n if (heightSegments < 1) {\n heightSegments = 1;\n }\n\n const openEnded = !!cfg.openEnded;\n\n let center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const heightHalf = height / 2;\n const heightLength = height / heightSegments;\n const radialAngle = (2.0 * Math.PI / radialSegments);\n const radialLength = 1.0 / radialSegments;\n //var nextRadius = this._radiusBottom;\n const radiusChange = (radiusTop - radiusBottom) / heightSegments;\n\n const positions = [];\n const normals = [];\n const uvs = [];\n const indices = [];\n\n let h;\n let i;\n\n let x;\n let z;\n\n let currentRadius;\n let currentHeight;\n\n let first;\n let second;\n\n let startIndex;\n let tu;\n let tv;\n\n // create vertices\n const normalY = (90.0 - (Math.atan(height / (radiusBottom - radiusTop))) * 180 / Math.PI) / 90.0;\n\n for (h = 0; h <= heightSegments; h++) {\n currentRadius = radiusTop - h * radiusChange;\n currentHeight = heightHalf - h * heightLength;\n\n for (i = 0; i <= radialSegments; i++) {\n x = Math.sin(i * radialAngle);\n z = Math.cos(i * radialAngle);\n\n normals.push(currentRadius * x);\n normals.push(normalY); //todo\n normals.push(currentRadius * z);\n\n uvs.push((i * radialLength));\n uvs.push(h * 1 / heightSegments);\n\n positions.push((currentRadius * x) + centerX);\n positions.push((currentHeight) + centerY);\n positions.push((currentRadius * z) + centerZ);\n }\n }\n\n // create faces\n for (h = 0; h < heightSegments; h++) {\n for (i = 0; i <= radialSegments; i++) {\n\n first = h * (radialSegments + 1) + i;\n second = first + radialSegments;\n\n indices.push(first);\n indices.push(second);\n indices.push(second + 1);\n\n indices.push(first);\n indices.push(second + 1);\n indices.push(first + 1);\n }\n }\n\n // create top cap\n if (!openEnded && radiusTop > 0) {\n startIndex = (positions.length / 3);\n\n // top center\n normals.push(0.0);\n normals.push(1.0);\n normals.push(0.0);\n\n uvs.push(0.5);\n uvs.push(0.5);\n\n positions.push(0 + centerX);\n positions.push(heightHalf + centerY);\n positions.push(0 + centerZ);\n\n // top triangle fan\n for (i = 0; i <= radialSegments; i++) {\n x = Math.sin(i * radialAngle);\n z = Math.cos(i * radialAngle);\n tu = (0.5 * Math.sin(i * radialAngle)) + 0.5;\n tv = (0.5 * Math.cos(i * radialAngle)) + 0.5;\n\n normals.push(radiusTop * x);\n normals.push(1.0);\n normals.push(radiusTop * z);\n\n uvs.push(tu);\n uvs.push(tv);\n\n positions.push((radiusTop * x) + centerX);\n positions.push((heightHalf) + centerY);\n positions.push((radiusTop * z) + centerZ);\n }\n\n for (i = 0; i < radialSegments; i++) {\n center = startIndex;\n first = startIndex + 1 + i;\n\n indices.push(first);\n indices.push(first + 1);\n indices.push(center);\n }\n }\n\n // create bottom cap\n if (!openEnded && radiusBottom > 0) {\n\n startIndex = (positions.length / 3);\n\n // top center\n normals.push(0.0);\n normals.push(-1.0);\n normals.push(0.0);\n\n uvs.push(0.5);\n uvs.push(0.5);\n\n positions.push(0 + centerX);\n positions.push(0 - heightHalf + centerY);\n positions.push(0 + centerZ);\n\n // top triangle fan\n for (i = 0; i <= radialSegments; i++) {\n\n x = Math.sin(i * radialAngle);\n z = Math.cos(i * radialAngle);\n\n tu = (0.5 * Math.sin(i * radialAngle)) + 0.5;\n tv = (0.5 * Math.cos(i * radialAngle)) + 0.5;\n\n normals.push(radiusBottom * x);\n normals.push(-1.0);\n normals.push(radiusBottom * z);\n\n uvs.push(tu);\n uvs.push(tv);\n\n positions.push((radiusBottom * x) + centerX);\n positions.push((0 - heightHalf) + centerY);\n positions.push((radiusBottom * z) + centerZ);\n }\n\n for (i = 0; i < radialSegments; i++) {\n\n center = startIndex;\n first = startIndex + 1 + i;\n\n indices.push(center);\n indices.push(first + 1);\n indices.push(first);\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\n\nexport {buildCylinderGeometry};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/geometryBuilders/buildCylinderGeometry.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/geometryBuilders/buildCylinderGeometry.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 335, + "__docId__": 337, "kind": "function", "name": "buildCylinderGeometry", "memberof": "src/geometryBuilders/buildCylinderGeometry.js", @@ -8534,18 +8593,18 @@ } }, { - "__docId__": 336, + "__docId__": 338, "kind": "file", "name": "src/geometryBuilders/buildGridGeometry.js", "content": "/**\n * @desc Creates grid-shaped geometry arrays..\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a grid-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildGridGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const grid = buildGridGeometry({\n * size: 1000,\n * divisions: 500\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"gridGeometry\",\n * primitiveType: grid.primitiveType, // Will be \"lines\"\n * positions: grid.positions,\n * indices: grid.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redGridMesh\",\n * geometryId: \"gridGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redGrid\",\n * meshIds: [\"redGridMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildGridGeometry\n * @param {*} [cfg] Configs\n * @param {Number} [cfg.size=1] Dimension on the X and Z-axis.\n * @param {Number} [cfg.divisions=1] Number of divisions on X and Z axis..\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildGridGeometry(cfg = {}) {\n\n let size = cfg.size || 1;\n if (size < 0) {\n console.error(\"negative size not allowed - will invert\");\n size *= -1;\n }\n\n let divisions = cfg.divisions || 1;\n if (divisions < 0) {\n console.error(\"negative divisions not allowed - will invert\");\n divisions *= -1;\n }\n if (divisions < 1) {\n divisions = 1;\n }\n\n size = size || 10;\n divisions = divisions || 10;\n\n const step = size / divisions;\n const halfSize = size / 2;\n\n const positions = [];\n const indices = [];\n let l = 0;\n\n for (let i = 0, j = 0, k = -halfSize; i <= divisions; i++, k += step) {\n\n positions.push(-halfSize);\n positions.push(0);\n positions.push(k);\n\n positions.push(halfSize);\n positions.push(0);\n positions.push(k);\n\n positions.push(k);\n positions.push(0);\n positions.push(-halfSize);\n\n positions.push(k);\n positions.push(0);\n positions.push(halfSize);\n\n indices.push(l++);\n indices.push(l++);\n indices.push(l++);\n indices.push(l++);\n }\n\n return {\n primitiveType: \"lines\",\n positions: positions,\n indices: indices\n };\n}\n\n\nexport {buildGridGeometry};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/geometryBuilders/buildGridGeometry.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/geometryBuilders/buildGridGeometry.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 337, + "__docId__": 339, "kind": "function", "name": "buildGridGeometry", "memberof": "src/geometryBuilders/buildGridGeometry.js", @@ -8615,18 +8674,18 @@ } }, { - "__docId__": 338, + "__docId__": 340, "kind": "file", "name": "src/geometryBuilders/buildPlaneGeometry.js", "content": "/**\n * @desc Creates plane-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a plane-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildPlaneGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const plane = buildPlaneGeometry({\n * center: [0,0,0],\n * xSize: 2,\n * zSize: 2,\n * xSegments: 10,\n * zSegments: 10\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"planeGeometry\",\n * primitiveType: plane.primitiveType, // Will be \"triangles\"\n * positions: plane.positions,\n * normals: plane.normals,\n * indices: plane.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redPlaneMesh\",\n * geometryId: \"planeGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redPlane\",\n * meshIds: [\"redPlaneMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildPlaneGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.xSize=1] Dimension on the X-axis.\n * @param {Number} [cfg.zSize=1] Dimension on the Z-axis.\n * @param {Number} [cfg.xSegments=1] Number of segments on the X-axis.\n * @param {Number} [cfg.zSegments=1] Number of segments on the Z-axis.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildPlaneGeometry(cfg = {}) {\n\n let xSize = cfg.xSize || 1;\n if (xSize < 0) {\n console.error(\"negative xSize not allowed - will invert\");\n xSize *= -1;\n }\n\n let zSize = cfg.zSize || 1;\n if (zSize < 0) {\n console.error(\"negative zSize not allowed - will invert\");\n zSize *= -1;\n }\n\n let xSegments = cfg.xSegments || 1;\n if (xSegments < 0) {\n console.error(\"negative xSegments not allowed - will invert\");\n xSegments *= -1;\n }\n if (xSegments < 1) {\n xSegments = 1;\n }\n\n let zSegments = cfg.xSegments || 1;\n if (zSegments < 0) {\n console.error(\"negative zSegments not allowed - will invert\");\n zSegments *= -1;\n }\n if (zSegments < 1) {\n zSegments = 1;\n }\n\n const center = cfg.center;\n const centerX = center ? center[0] : 0;\n const centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const halfWidth = xSize / 2;\n const halfHeight = zSize / 2;\n\n const planeX = Math.floor(xSegments) || 1;\n const planeZ = Math.floor(zSegments) || 1;\n\n const planeX1 = planeX + 1;\n const planeZ1 = planeZ + 1;\n\n const segmentWidth = xSize / planeX;\n const segmentHeight = zSize / planeZ;\n\n const positions = new Float32Array(planeX1 * planeZ1 * 3);\n const normals = new Float32Array(planeX1 * planeZ1 * 3);\n const uvs = new Float32Array(planeX1 * planeZ1 * 2);\n\n let offset = 0;\n let offset2 = 0;\n\n let iz;\n let ix;\n let x;\n let a;\n let b;\n let c;\n let d;\n\n for (iz = 0; iz < planeZ1; iz++) {\n\n const z = iz * segmentHeight - halfHeight;\n\n for (ix = 0; ix < planeX1; ix++) {\n\n x = ix * segmentWidth - halfWidth;\n\n positions[offset] = x + centerX;\n positions[offset + 1] = centerY;\n positions[offset + 2] = -z + centerZ;\n\n normals[offset + 2] = -1;\n\n uvs[offset2] = (ix) / planeX;\n uvs[offset2 + 1] = ((planeZ - iz) / planeZ);\n\n offset += 3;\n offset2 += 2;\n }\n }\n\n offset = 0;\n\n const indices = new ((positions.length / 3) > 65535 ? Uint32Array : Uint16Array)(planeX * planeZ * 6);\n\n for (iz = 0; iz < planeZ; iz++) {\n\n for (ix = 0; ix < planeX; ix++) {\n\n a = ix + planeX1 * iz;\n b = ix + planeX1 * (iz + 1);\n c = (ix + 1) + planeX1 * (iz + 1);\n d = (ix + 1) + planeX1 * iz;\n\n indices[offset] = d;\n indices[offset + 1] = b;\n indices[offset + 2] = a;\n\n indices[offset + 3] = d;\n indices[offset + 4] = c;\n indices[offset + 5] = b;\n\n offset += 6;\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\nexport {buildPlaneGeometry};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/geometryBuilders/buildPlaneGeometry.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/geometryBuilders/buildPlaneGeometry.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 339, + "__docId__": 341, "kind": "function", "name": "buildPlaneGeometry", "memberof": "src/geometryBuilders/buildPlaneGeometry.js", @@ -8730,18 +8789,18 @@ } }, { - "__docId__": 340, + "__docId__": 342, "kind": "file", "name": "src/geometryBuilders/buildSphereGeometry.js", "content": "/**\n * @desc Creates sphere-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a sphere-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildSphereGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const sphere = buildSphereGeometry({\n * center: [0,0,0],\n * radius: 1.5,\n * heightSegments: 60,\n * widthSegments: 60\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"sphereGeometry\",\n * primitiveType: sphere.primitiveType, // Will be \"triangles\"\n * positions: sphere.positions,\n * normals: sphere.normals,\n * indices: sphere.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redSphereMesh\",\n * geometryId: \"sphereGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n *const xktEntity = xktModel.createEntity({\n * entityId: \"redSphere\",\n * meshIds: [\"redSphereMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildSphereGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.radius=1] Radius.\n * @param {Number} [cfg.heightSegments=24] Number of latitudinal bands.\n * @param {Number} [cfg.widthSegments=18] Number of longitudinal bands.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildSphereGeometry(cfg = {}) {\n\n const lod = cfg.lod || 1;\n\n const centerX = cfg.center ? cfg.center[0] : 0;\n const centerY = cfg.center ? cfg.center[1] : 0;\n const centerZ = cfg.center ? cfg.center[2] : 0;\n\n let radius = cfg.radius || 1;\n if (radius < 0) {\n console.error(\"negative radius not allowed - will invert\");\n radius *= -1;\n }\n\n let heightSegments = cfg.heightSegments || 18;\n if (heightSegments < 0) {\n console.error(\"negative heightSegments not allowed - will invert\");\n heightSegments *= -1;\n }\n heightSegments = Math.floor(lod * heightSegments);\n if (heightSegments < 18) {\n heightSegments = 18;\n }\n\n let widthSegments = cfg.widthSegments || 18;\n if (widthSegments < 0) {\n console.error(\"negative widthSegments not allowed - will invert\");\n widthSegments *= -1;\n }\n widthSegments = Math.floor(lod * widthSegments);\n if (widthSegments < 18) {\n widthSegments = 18;\n }\n\n const positions = [];\n const normals = [];\n const uvs = [];\n const indices = [];\n\n let i;\n let j;\n\n let theta;\n let sinTheta;\n let cosTheta;\n\n let phi;\n let sinPhi;\n let cosPhi;\n\n let x;\n let y;\n let z;\n\n let u;\n let v;\n\n let first;\n let second;\n\n for (i = 0; i <= heightSegments; i++) {\n\n theta = i * Math.PI / heightSegments;\n sinTheta = Math.sin(theta);\n cosTheta = Math.cos(theta);\n\n for (j = 0; j <= widthSegments; j++) {\n\n phi = j * 2 * Math.PI / widthSegments;\n sinPhi = Math.sin(phi);\n cosPhi = Math.cos(phi);\n\n x = cosPhi * sinTheta;\n y = cosTheta;\n z = sinPhi * sinTheta;\n u = 1.0 - j / widthSegments;\n v = i / heightSegments;\n\n normals.push(x);\n normals.push(y);\n normals.push(z);\n\n uvs.push(u);\n uvs.push(v);\n\n positions.push(centerX + radius * x);\n positions.push(centerY + radius * y);\n positions.push(centerZ + radius * z);\n }\n }\n\n for (i = 0; i < heightSegments; i++) {\n for (j = 0; j < widthSegments; j++) {\n\n first = (i * (widthSegments + 1)) + j;\n second = first + widthSegments + 1;\n\n indices.push(first + 1);\n indices.push(second + 1);\n indices.push(second);\n indices.push(first + 1);\n indices.push(second);\n indices.push(first);\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\nexport {buildSphereGeometry};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/geometryBuilders/buildSphereGeometry.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/geometryBuilders/buildSphereGeometry.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 341, + "__docId__": 343, "kind": "function", "name": "buildSphereGeometry", "memberof": "src/geometryBuilders/buildSphereGeometry.js", @@ -8833,18 +8892,18 @@ } }, { - "__docId__": 342, + "__docId__": 344, "kind": "file", "name": "src/geometryBuilders/buildTorusGeometry.js", "content": "import {math} from '../lib/math.js';\n\n/**\n * @desc Creates torus-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a torus-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildTorusGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const torus = buildTorusGeometry({\n * center: [0,0,0],\n * radius: 1.0,\n * tube: 0.5,\n * radialSegments: 32,\n * tubeSegments: 24,\n * arc: Math.PI * 2.0\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"torusGeometry\",\n * primitiveType: torus.primitiveType, // Will be \"triangles\"\n * positions: torus.positions,\n * normals: torus.normals,\n * indices: torus.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redTorusMesh\",\n * geometryId: \"torusGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redTorus\",\n * meshIds: [\"redTorusMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildTorusGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.radius=1] The overall radius.\n * @param {Number} [cfg.tube=0.3] The tube radius.\n * @param {Number} [cfg.radialSegments=32] The number of radial segments.\n * @param {Number} [cfg.tubeSegments=24] The number of tubular segments.\n * @param {Number} [cfg.arc=Math.PI*0.5] The length of the arc in radians, where Math.PI*2 is a closed torus.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildTorusGeometry(cfg = {}) {\n\n let radius = cfg.radius || 1;\n if (radius < 0) {\n console.error(\"negative radius not allowed - will invert\");\n radius *= -1;\n }\n radius *= 0.5;\n\n let tube = cfg.tube || 0.3;\n if (tube < 0) {\n console.error(\"negative tube not allowed - will invert\");\n tube *= -1;\n }\n\n let radialSegments = cfg.radialSegments || 32;\n if (radialSegments < 0) {\n console.error(\"negative radialSegments not allowed - will invert\");\n radialSegments *= -1;\n }\n if (radialSegments < 4) {\n radialSegments = 4;\n }\n\n let tubeSegments = cfg.tubeSegments || 24;\n if (tubeSegments < 0) {\n console.error(\"negative tubeSegments not allowed - will invert\");\n tubeSegments *= -1;\n }\n if (tubeSegments < 4) {\n tubeSegments = 4;\n }\n\n let arc = cfg.arc || Math.PI * 2;\n if (arc < 0) {\n console.warn(\"negative arc not allowed - will invert\");\n arc *= -1;\n }\n if (arc > 360) {\n arc = 360;\n }\n\n const center = cfg.center;\n let centerX = center ? center[0] : 0;\n let centerY = center ? center[1] : 0;\n const centerZ = center ? center[2] : 0;\n\n const positions = [];\n const normals = [];\n const uvs = [];\n const indices = [];\n\n let u;\n let v;\n let x;\n let y;\n let z;\n let vec;\n\n let i;\n let j;\n\n for (j = 0; j <= tubeSegments; j++) {\n for (i = 0; i <= radialSegments; i++) {\n\n u = i / radialSegments * arc;\n v = 0.785398 + (j / tubeSegments * Math.PI * 2);\n\n centerX = radius * Math.cos(u);\n centerY = radius * Math.sin(u);\n\n x = (radius + tube * Math.cos(v)) * Math.cos(u);\n y = (radius + tube * Math.cos(v)) * Math.sin(u);\n z = tube * Math.sin(v);\n\n positions.push(x + centerX);\n positions.push(y + centerY);\n positions.push(z + centerZ);\n\n uvs.push(1 - (i / radialSegments));\n uvs.push((j / tubeSegments));\n\n vec = math.normalizeVec3(math.subVec3([x, y, z], [centerX, centerY, centerZ], []), []);\n\n normals.push(vec[0]);\n normals.push(vec[1]);\n normals.push(vec[2]);\n }\n }\n\n let a;\n let b;\n let c;\n let d;\n\n for (j = 1; j <= tubeSegments; j++) {\n for (i = 1; i <= radialSegments; i++) {\n\n a = (radialSegments + 1) * j + i - 1;\n b = (radialSegments + 1) * (j - 1) + i - 1;\n c = (radialSegments + 1) * (j - 1) + i;\n d = (radialSegments + 1) * j + i;\n\n indices.push(a);\n indices.push(b);\n indices.push(c);\n\n indices.push(c);\n indices.push(d);\n indices.push(a);\n }\n }\n\n return {\n primitiveType: \"triangles\",\n positions: positions,\n normals: normals,\n uv: uvs,\n uvs: uvs,\n indices: indices\n };\n}\n\nexport {buildTorusGeometry};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/geometryBuilders/buildTorusGeometry.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/geometryBuilders/buildTorusGeometry.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 343, + "__docId__": 345, "kind": "function", "name": "buildTorusGeometry", "memberof": "src/geometryBuilders/buildTorusGeometry.js", @@ -8960,18 +9019,18 @@ } }, { - "__docId__": 344, + "__docId__": 346, "kind": "file", "name": "src/geometryBuilders/buildVectorTextGeometry.js", "content": "const letters = {\n ' ': {width: 16, points: []},\n '!': {\n width: 10, points: [\n [5, 21],\n [5, 7],\n [-1, -1],\n [5, 2],\n [4, 1],\n [5, 0],\n [6, 1],\n [5, 2]\n ]\n },\n '\"': {\n width: 16, points: [\n [4, 21],\n [4, 14],\n [-1, -1],\n [12, 21],\n [12, 14]\n ]\n },\n '#': {\n width: 21, points: [\n [11, 25],\n [4, -7],\n [-1, -1],\n [17, 25],\n [10, -7],\n [-1, -1],\n [4, 12],\n [18, 12],\n [-1, -1],\n [3, 6],\n [17, 6]\n ]\n },\n '$': {\n width: 20, points: [\n [8, 25],\n [8, -4],\n [-1, -1],\n [12, 25],\n [12, -4],\n [-1, -1],\n [17, 18],\n [15, 20],\n [12, 21],\n [8, 21],\n [5, 20],\n [3, 18],\n [3, 16],\n [4, 14],\n [5, 13],\n [7, 12],\n [13, 10],\n [15, 9],\n [16, 8],\n [17, 6],\n [17, 3],\n [15, 1],\n [12, 0],\n [8, 0],\n [5, 1],\n [3, 3]\n ]\n },\n '%': {\n width: 24, points: [\n [21, 21],\n [3, 0],\n [-1, -1],\n [8, 21],\n [10, 19],\n [10, 17],\n [9, 15],\n [7, 14],\n [5, 14],\n [3, 16],\n [3, 18],\n [4, 20],\n [6, 21],\n [8, 21],\n [10, 20],\n [13, 19],\n [16, 19],\n [19, 20],\n [21, 21],\n [-1, -1],\n [17, 7],\n [15, 6],\n [14, 4],\n [14, 2],\n [16, 0],\n [18, 0],\n [20, 1],\n [21, 3],\n [21, 5],\n [19, 7],\n [17, 7]\n ]\n },\n '&': {\n width: 26, points: [\n [23, 12],\n [23, 13],\n [22, 14],\n [21, 14],\n [20, 13],\n [19, 11],\n [17, 6],\n [15, 3],\n [13, 1],\n [11, 0],\n [7, 0],\n [5, 1],\n [4, 2],\n [3, 4],\n [3, 6],\n [4, 8],\n [5, 9],\n [12, 13],\n [13, 14],\n [14, 16],\n [14, 18],\n [13, 20],\n [11, 21],\n [9, 20],\n [8, 18],\n [8, 16],\n [9, 13],\n [11, 10],\n [16, 3],\n [18, 1],\n [20, 0],\n [22, 0],\n [23, 1],\n [23, 2]\n ]\n },\n '\\'': {\n width: 10, points: [\n [5, 19],\n [4, 20],\n [5, 21],\n [6, 20],\n [6, 18],\n [5, 16],\n [4, 15]\n ]\n },\n '(': {\n width: 14, points: [\n [11, 25],\n [9, 23],\n [7, 20],\n [5, 16],\n [4, 11],\n [4, 7],\n [5, 2],\n [7, -2],\n [9, -5],\n [11, -7]\n ]\n },\n ')': {\n width: 14, points: [\n [3, 25],\n [5, 23],\n [7, 20],\n [9, 16],\n [10, 11],\n [10, 7],\n [9, 2],\n [7, -2],\n [5, -5],\n [3, -7]\n ]\n },\n '*': {\n width: 16, points: [\n [8, 21],\n [8, 9],\n [-1, -1],\n [3, 18],\n [13, 12],\n [-1, -1],\n [13, 18],\n [3, 12]\n ]\n },\n '+': {\n width: 26, points: [\n [13, 18],\n [13, 0],\n [-1, -1],\n [4, 9],\n [22, 9]\n ]\n },\n ',': {\n width: 10, points: [\n [6, 1],\n [5, 0],\n [4, 1],\n [5, 2],\n [6, 1],\n [6, -1],\n [5, -3],\n [4, -4]\n ]\n },\n '-': {\n width: 26, points: [\n [4, 9],\n [22, 9]\n ]\n },\n '.': {\n width: 10, points: [\n [5, 2],\n [4, 1],\n [5, 0],\n [6, 1],\n [5, 2]\n ]\n },\n '/': {\n width: 22, points: [\n [20, 25],\n [2, -7]\n ]\n },\n '0': {\n width: 20, points: [\n [9, 21],\n [6, 20],\n [4, 17],\n [3, 12],\n [3, 9],\n [4, 4],\n [6, 1],\n [9, 0],\n [11, 0],\n [14, 1],\n [16, 4],\n [17, 9],\n [17, 12],\n [16, 17],\n [14, 20],\n [11, 21],\n [9, 21]\n ]\n },\n '1': {\n width: 20, points: [\n [6, 17],\n [8, 18],\n [11, 21],\n [11, 0]\n ]\n },\n '2': {\n width: 20, points: [\n [4, 16],\n [4, 17],\n [5, 19],\n [6, 20],\n [8, 21],\n [12, 21],\n [14, 20],\n [15, 19],\n [16, 17],\n [16, 15],\n [15, 13],\n [13, 10],\n [3, 0],\n [17, 0]\n ]\n },\n '3': {\n width: 20, points: [\n [5, 21],\n [16, 21],\n [10, 13],\n [13, 13],\n [15, 12],\n [16, 11],\n [17, 8],\n [17, 6],\n [16, 3],\n [14, 1],\n [11, 0],\n [8, 0],\n [5, 1],\n [4, 2],\n [3, 4]\n ]\n },\n '4': {\n width: 20, points: [\n [13, 21],\n [3, 7],\n [18, 7],\n [-1, -1],\n [13, 21],\n [13, 0]\n ]\n },\n '5': {\n width: 20, points: [\n [15, 21],\n [5, 21],\n [4, 12],\n [5, 13],\n [8, 14],\n [11, 14],\n [14, 13],\n [16, 11],\n [17, 8],\n [17, 6],\n [16, 3],\n [14, 1],\n [11, 0],\n [8, 0],\n [5, 1],\n [4, 2],\n [3, 4]\n ]\n },\n '6': {\n width: 20, points: [\n [16, 18],\n [15, 20],\n [12, 21],\n [10, 21],\n [7, 20],\n [5, 17],\n [4, 12],\n [4, 7],\n [5, 3],\n [7, 1],\n [10, 0],\n [11, 0],\n [14, 1],\n [16, 3],\n [17, 6],\n [17, 7],\n [16, 10],\n [14, 12],\n [11, 13],\n [10, 13],\n [7, 12],\n [5, 10],\n [4, 7]\n ]\n },\n '7': {\n width: 20, points: [\n [17, 21],\n [7, 0],\n [-1, -1],\n [3, 21],\n [17, 21]\n ]\n },\n '8': {\n width: 20, points: [\n [8, 21],\n [5, 20],\n [4, 18],\n [4, 16],\n [5, 14],\n [7, 13],\n [11, 12],\n [14, 11],\n [16, 9],\n [17, 7],\n [17, 4],\n [16, 2],\n [15, 1],\n [12, 0],\n [8, 0],\n [5, 1],\n [4, 2],\n [3, 4],\n [3, 7],\n [4, 9],\n [6, 11],\n [9, 12],\n [13, 13],\n [15, 14],\n [16, 16],\n [16, 18],\n [15, 20],\n [12, 21],\n [8, 21]\n ]\n },\n '9': {\n width: 20, points: [\n [16, 14],\n [15, 11],\n [13, 9],\n [10, 8],\n [9, 8],\n [6, 9],\n [4, 11],\n [3, 14],\n [3, 15],\n [4, 18],\n [6, 20],\n [9, 21],\n [10, 21],\n [13, 20],\n [15, 18],\n [16, 14],\n [16, 9],\n [15, 4],\n [13, 1],\n [10, 0],\n [8, 0],\n [5, 1],\n [4, 3]\n ]\n },\n ':': {\n width: 10, points: [\n [5, 14],\n [4, 13],\n [5, 12],\n [6, 13],\n [5, 14],\n [-1, -1],\n [5, 2],\n [4, 1],\n [5, 0],\n [6, 1],\n [5, 2]\n ]\n },\n ';': {\n width: 10, points: [\n [5, 14],\n [4, 13],\n [5, 12],\n [6, 13],\n [5, 14],\n [-1, -1],\n [6, 1],\n [5, 0],\n [4, 1],\n [5, 2],\n [6, 1],\n [6, -1],\n [5, -3],\n [4, -4]\n ]\n },\n '<': {\n width: 24, points: [\n [20, 18],\n [4, 9],\n [20, 0]\n ]\n },\n '=': {\n width: 26, points: [\n [4, 12],\n [22, 12],\n [-1, -1],\n [4, 6],\n [22, 6]\n ]\n },\n '>': {\n width: 24, points: [\n [4, 18],\n [20, 9],\n [4, 0]\n ]\n },\n '?': {\n width: 18, points: [\n [3, 16],\n [3, 17],\n [4, 19],\n [5, 20],\n [7, 21],\n [11, 21],\n [13, 20],\n [14, 19],\n [15, 17],\n [15, 15],\n [14, 13],\n [13, 12],\n [9, 10],\n [9, 7],\n [-1, -1],\n [9, 2],\n [8, 1],\n [9, 0],\n [10, 1],\n [9, 2]\n ]\n },\n '@': {\n width: 27, points: [\n [18, 13],\n [17, 15],\n [15, 16],\n [12, 16],\n [10, 15],\n [9, 14],\n [8, 11],\n [8, 8],\n [9, 6],\n [11, 5],\n [14, 5],\n [16, 6],\n [17, 8],\n [-1, -1],\n [12, 16],\n [10, 14],\n [9, 11],\n [9, 8],\n [10, 6],\n [11, 5],\n [-1, -1],\n [18, 16],\n [17, 8],\n [17, 6],\n [19, 5],\n [21, 5],\n [23, 7],\n [24, 10],\n [24, 12],\n [23, 15],\n [22, 17],\n [20, 19],\n [18, 20],\n [15, 21],\n [12, 21],\n [9, 20],\n [7, 19],\n [5, 17],\n [4, 15],\n [3, 12],\n [3, 9],\n [4, 6],\n [5, 4],\n [7, 2],\n [9, 1],\n [12, 0],\n [15, 0],\n [18, 1],\n [20, 2],\n [21, 3],\n [-1, -1],\n [19, 16],\n [18, 8],\n [18, 6],\n [19, 5]\n ]\n },\n 'A': {\n width: 18, points: [\n [9, 21],\n [1, 0],\n [-1, -1],\n [9, 21],\n [17, 0],\n [-1, -1],\n [4, 7],\n [14, 7]\n ]\n },\n 'B': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [13, 21],\n [16, 20],\n [17, 19],\n [18, 17],\n [18, 15],\n [17, 13],\n [16, 12],\n [13, 11],\n [-1, -1],\n [4, 11],\n [13, 11],\n [16, 10],\n [17, 9],\n [18, 7],\n [18, 4],\n [17, 2],\n [16, 1],\n [13, 0],\n [4, 0]\n ]\n },\n 'C': {\n width: 21, points: [\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5]\n ]\n },\n 'D': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [11, 21],\n [14, 20],\n [16, 18],\n [17, 16],\n [18, 13],\n [18, 8],\n [17, 5],\n [16, 3],\n [14, 1],\n [11, 0],\n [4, 0]\n ]\n },\n 'E': {\n width: 19, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [17, 21],\n [-1, -1],\n [4, 11],\n [12, 11],\n [-1, -1],\n [4, 0],\n [17, 0]\n ]\n },\n 'F': {\n width: 18, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [17, 21],\n [-1, -1],\n [4, 11],\n [12, 11]\n ]\n },\n 'G': {\n width: 21, points: [\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5],\n [18, 8],\n [-1, -1],\n [13, 8],\n [18, 8]\n ]\n },\n 'H': {\n width: 22, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [18, 21],\n [18, 0],\n [-1, -1],\n [4, 11],\n [18, 11]\n ]\n },\n 'I': {\n width: 8, points: [\n [4, 21],\n [4, 0]\n ]\n },\n 'J': {\n width: 16, points: [\n [12, 21],\n [12, 5],\n [11, 2],\n [10, 1],\n [8, 0],\n [6, 0],\n [4, 1],\n [3, 2],\n [2, 5],\n [2, 7]\n ]\n },\n 'K': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [18, 21],\n [4, 7],\n [-1, -1],\n [9, 12],\n [18, 0]\n ]\n },\n 'L': {\n width: 17, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 0],\n [16, 0]\n ]\n },\n 'M': {\n width: 24, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [12, 0],\n [-1, -1],\n [20, 21],\n [12, 0],\n [-1, -1],\n [20, 21],\n [20, 0]\n ]\n },\n 'N': {\n width: 22, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [18, 0],\n [-1, -1],\n [18, 21],\n [18, 0]\n ]\n },\n 'O': {\n width: 22, points: [\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5],\n [19, 8],\n [19, 13],\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21]\n ]\n },\n 'P': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [13, 21],\n [16, 20],\n [17, 19],\n [18, 17],\n [18, 14],\n [17, 12],\n [16, 11],\n [13, 10],\n [4, 10]\n ]\n },\n 'Q': {\n width: 22, points: [\n [9, 21],\n [7, 20],\n [5, 18],\n [4, 16],\n [3, 13],\n [3, 8],\n [4, 5],\n [5, 3],\n [7, 1],\n [9, 0],\n [13, 0],\n [15, 1],\n [17, 3],\n [18, 5],\n [19, 8],\n [19, 13],\n [18, 16],\n [17, 18],\n [15, 20],\n [13, 21],\n [9, 21],\n [-1, -1],\n [12, 4],\n [18, -2]\n ]\n },\n 'R': {\n width: 21, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 21],\n [13, 21],\n [16, 20],\n [17, 19],\n [18, 17],\n [18, 15],\n [17, 13],\n [16, 12],\n [13, 11],\n [4, 11],\n [-1, -1],\n [11, 11],\n [18, 0]\n ]\n },\n 'S': {\n width: 20, points: [\n [17, 18],\n [15, 20],\n [12, 21],\n [8, 21],\n [5, 20],\n [3, 18],\n [3, 16],\n [4, 14],\n [5, 13],\n [7, 12],\n [13, 10],\n [15, 9],\n [16, 8],\n [17, 6],\n [17, 3],\n [15, 1],\n [12, 0],\n [8, 0],\n [5, 1],\n [3, 3]\n ]\n },\n 'T': {\n width: 16, points: [\n [8, 21],\n [8, 0],\n [-1, -1],\n [1, 21],\n [15, 21]\n ]\n },\n 'U': {\n width: 22, points: [\n [4, 21],\n [4, 6],\n [5, 3],\n [7, 1],\n [10, 0],\n [12, 0],\n [15, 1],\n [17, 3],\n [18, 6],\n [18, 21]\n ]\n },\n 'V': {\n width: 18, points: [\n [1, 21],\n [9, 0],\n [-1, -1],\n [17, 21],\n [9, 0]\n ]\n },\n 'W': {\n width: 24, points: [\n [2, 21],\n [7, 0],\n [-1, -1],\n [12, 21],\n [7, 0],\n [-1, -1],\n [12, 21],\n [17, 0],\n [-1, -1],\n [22, 21],\n [17, 0]\n ]\n },\n 'X': {\n width: 20, points: [\n [3, 21],\n [17, 0],\n [-1, -1],\n [17, 21],\n [3, 0]\n ]\n },\n 'Y': {\n width: 18, points: [\n [1, 21],\n [9, 11],\n [9, 0],\n [-1, -1],\n [17, 21],\n [9, 11]\n ]\n },\n 'Z': {\n width: 20, points: [\n [17, 21],\n [3, 0],\n [-1, -1],\n [3, 21],\n [17, 21],\n [-1, -1],\n [3, 0],\n [17, 0]\n ]\n },\n '[': {\n width: 14, points: [\n [4, 25],\n [4, -7],\n [-1, -1],\n [5, 25],\n [5, -7],\n [-1, -1],\n [4, 25],\n [11, 25],\n [-1, -1],\n [4, -7],\n [11, -7]\n ]\n },\n '\\\\': {\n width: 14, points: [\n [0, 21],\n [14, -3]\n ]\n },\n ']': {\n width: 14, points: [\n [9, 25],\n [9, -7],\n [-1, -1],\n [10, 25],\n [10, -7],\n [-1, -1],\n [3, 25],\n [10, 25],\n [-1, -1],\n [3, -7],\n [10, -7]\n ]\n },\n '^': {\n width: 16, points: [\n [6, 15],\n [8, 18],\n [10, 15],\n [-1, -1],\n [3, 12],\n [8, 17],\n [13, 12],\n [-1, -1],\n [8, 17],\n [8, 0]\n ]\n },\n '_': {\n width: 16, points: [\n [0, -2],\n [16, -2]\n ]\n },\n '`': {\n width: 10, points: [\n [6, 21],\n [5, 20],\n [4, 18],\n [4, 16],\n [5, 15],\n [6, 16],\n [5, 17]\n ]\n },\n 'a': {\n width: 19, points: [\n [15, 14],\n [15, 0],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'b': {\n width: 19, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 11],\n [6, 13],\n [8, 14],\n [11, 14],\n [13, 13],\n [15, 11],\n [16, 8],\n [16, 6],\n [15, 3],\n [13, 1],\n [11, 0],\n [8, 0],\n [6, 1],\n [4, 3]\n ]\n },\n 'c': {\n width: 18, points: [\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'd': {\n width: 19, points: [\n [15, 21],\n [15, 0],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'e': {\n width: 18, points: [\n [3, 8],\n [15, 8],\n [15, 10],\n [14, 12],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'f': {\n width: 12, points: [\n [10, 21],\n [8, 21],\n [6, 20],\n [5, 17],\n [5, 0],\n [-1, -1],\n [2, 14],\n [9, 14]\n ]\n },\n 'g': {\n width: 19, points: [\n [15, 14],\n [15, -2],\n [14, -5],\n [13, -6],\n [11, -7],\n [8, -7],\n [6, -6],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'h': {\n width: 19, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [4, 10],\n [7, 13],\n [9, 14],\n [12, 14],\n [14, 13],\n [15, 10],\n [15, 0]\n ]\n },\n 'i': {\n width: 8, points: [\n [3, 21],\n [4, 20],\n [5, 21],\n [4, 22],\n [3, 21],\n [-1, -1],\n [4, 14],\n [4, 0]\n ]\n },\n 'j': {\n width: 10, points: [\n [5, 21],\n [6, 20],\n [7, 21],\n [6, 22],\n [5, 21],\n [-1, -1],\n [6, 14],\n [6, -3],\n [5, -6],\n [3, -7],\n [1, -7]\n ]\n },\n 'k': {\n width: 17, points: [\n [4, 21],\n [4, 0],\n [-1, -1],\n [14, 14],\n [4, 4],\n [-1, -1],\n [8, 8],\n [15, 0]\n ]\n },\n 'l': {\n width: 8, points: [\n [4, 21],\n [4, 0]\n ]\n },\n 'm': {\n width: 30, points: [\n [4, 14],\n [4, 0],\n [-1, -1],\n [4, 10],\n [7, 13],\n [9, 14],\n [12, 14],\n [14, 13],\n [15, 10],\n [15, 0],\n [-1, -1],\n [15, 10],\n [18, 13],\n [20, 14],\n [23, 14],\n [25, 13],\n [26, 10],\n [26, 0]\n ]\n },\n 'n': {\n width: 19, points: [\n [4, 14],\n [4, 0],\n [-1, -1],\n [4, 10],\n [7, 13],\n [9, 14],\n [12, 14],\n [14, 13],\n [15, 10],\n [15, 0]\n ]\n },\n 'o': {\n width: 19, points: [\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3],\n [16, 6],\n [16, 8],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14]\n ]\n },\n 'p': {\n width: 19, points: [\n [4, 14],\n [4, -7],\n [-1, -1],\n [4, 11],\n [6, 13],\n [8, 14],\n [11, 14],\n [13, 13],\n [15, 11],\n [16, 8],\n [16, 6],\n [15, 3],\n [13, 1],\n [11, 0],\n [8, 0],\n [6, 1],\n [4, 3]\n ]\n },\n 'q': {\n width: 19, points: [\n [15, 14],\n [15, -7],\n [-1, -1],\n [15, 11],\n [13, 13],\n [11, 14],\n [8, 14],\n [6, 13],\n [4, 11],\n [3, 8],\n [3, 6],\n [4, 3],\n [6, 1],\n [8, 0],\n [11, 0],\n [13, 1],\n [15, 3]\n ]\n },\n 'r': {\n width: 13, points: [\n [4, 14],\n [4, 0],\n [-1, -1],\n [4, 8],\n [5, 11],\n [7, 13],\n [9, 14],\n [12, 14]\n ]\n },\n 's': {\n width: 17, points: [\n [14, 11],\n [13, 13],\n [10, 14],\n [7, 14],\n [4, 13],\n [3, 11],\n [4, 9],\n [6, 8],\n [11, 7],\n [13, 6],\n [14, 4],\n [14, 3],\n [13, 1],\n [10, 0],\n [7, 0],\n [4, 1],\n [3, 3]\n ]\n },\n 't': {\n width: 12, points: [\n [5, 21],\n [5, 4],\n [6, 1],\n [8, 0],\n [10, 0],\n [-1, -1],\n [2, 14],\n [9, 14]\n ]\n },\n 'u': {\n width: 19, points: [\n [4, 14],\n [4, 4],\n [5, 1],\n [7, 0],\n [10, 0],\n [12, 1],\n [15, 4],\n [-1, -1],\n [15, 14],\n [15, 0]\n ]\n },\n 'v': {\n width: 16, points: [\n [2, 14],\n [8, 0],\n [-1, -1],\n [14, 14],\n [8, 0]\n ]\n },\n 'w': {\n width: 22, points: [\n [3, 14],\n [7, 0],\n [-1, -1],\n [11, 14],\n [7, 0],\n [-1, -1],\n [11, 14],\n [15, 0],\n [-1, -1],\n [19, 14],\n [15, 0]\n ]\n },\n 'x': {\n width: 17, points: [\n [3, 14],\n [14, 0],\n [-1, -1],\n [14, 14],\n [3, 0]\n ]\n },\n 'y': {\n width: 16, points: [\n [2, 14],\n [8, 0],\n [-1, -1],\n [14, 14],\n [8, 0],\n [6, -4],\n [4, -6],\n [2, -7],\n [1, -7]\n ]\n },\n 'z': {\n width: 17, points: [\n [14, 14],\n [3, 0],\n [-1, -1],\n [3, 14],\n [14, 14],\n [-1, -1],\n [3, 0],\n [14, 0]\n ]\n },\n '{': {\n width: 14, points: [\n [9, 25],\n [7, 24],\n [6, 23],\n [5, 21],\n [5, 19],\n [6, 17],\n [7, 16],\n [8, 14],\n [8, 12],\n [6, 10],\n [-1, -1],\n [7, 24],\n [6, 22],\n [6, 20],\n [7, 18],\n [8, 17],\n [9, 15],\n [9, 13],\n [8, 11],\n [4, 9],\n [8, 7],\n [9, 5],\n [9, 3],\n [8, 1],\n [7, 0],\n [6, -2],\n [6, -4],\n [7, -6],\n [-1, -1],\n [6, 8],\n [8, 6],\n [8, 4],\n [7, 2],\n [6, 1],\n [5, -1],\n [5, -3],\n [6, -5],\n [7, -6],\n [9, -7]\n ]\n },\n '|': {\n width: 8, points: [\n [4, 25],\n [4, -7]\n ]\n },\n '}': {\n width: 14, points: [\n [5, 25],\n [7, 24],\n [8, 23],\n [9, 21],\n [9, 19],\n [8, 17],\n [7, 16],\n [6, 14],\n [6, 12],\n [8, 10],\n [-1, -1],\n [7, 24],\n [8, 22],\n [8, 20],\n [7, 18],\n [6, 17],\n [5, 15],\n [5, 13],\n [6, 11],\n [10, 9],\n [6, 7],\n [5, 5],\n [5, 3],\n [6, 1],\n [7, 0],\n [8, -2],\n [8, -4],\n [7, -6],\n [-1, -1],\n [8, 8],\n [6, 6],\n [6, 4],\n [7, 2],\n [8, 1],\n [9, -1],\n [9, -3],\n [8, -5],\n [7, -6],\n [5, -7]\n ]\n },\n '~': {\n width: 24, points: [\n [3, 6],\n [3, 8],\n [4, 11],\n [6, 12],\n [8, 12],\n [10, 11],\n [14, 8],\n [16, 7],\n [18, 7],\n [20, 8],\n [21, 10],\n [-1, -1],\n [3, 8],\n [4, 10],\n [6, 11],\n [8, 11],\n [10, 10],\n [14, 7],\n [16, 6],\n [18, 6],\n [20, 7],\n [21, 10],\n [21, 12]\n ]\n }\n};\n\n/**\n * @desc Creates wireframe text-shaped geometry arrays.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then create an {@link XKTMesh} with a text-shaped {@link XKTGeometry}.\n *\n * [[Run this example](http://xeokit.github.io/xeokit-sdk/examples/#geometry_builders_buildVectorTextGeometry)]\n *\n * ````javascript\n * const xktModel = new XKTModel();\n *\n * const text = buildVectorTextGeometry({\n * origin: [0,0,0],\n * text: \"On the other side of the screen, it all looked so easy\"\n * });\n *\n * const xktGeometry = xktModel.createGeometry({\n * geometryId: \"textGeometry\",\n * primitiveType: text.primitiveType, // Will be \"lines\"\n * positions: text.positions,\n * indices: text.indices\n * });\n *\n * const xktMesh = xktModel.createMesh({\n * meshId: \"redTextMesh\",\n * geometryId: \"textGeometry\",\n * position: [-4, -6, -4],\n * scale: [1, 3, 1],\n * rotation: [0, 0, 0],\n * color: [1, 0, 0],\n * opacity: 1\n * });\n *\n * const xktEntity = xktModel.createEntity({\n * entityId: \"redText\",\n * meshIds: [\"redTextMesh\"]\n * });\n *\n * xktModel.finalize();\n * ````\n *\n * @function buildVectorTextGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number[]} [cfg.origin] 3D point indicating the top left corner.\n * @param {Number} [cfg.size=1] Size of each character.\n * @param {String} [cfg.text=\"\"] The text.\n * @returns {Object} Geometry arrays for {@link XKTModel#createGeometry} or {@link XKTModel#createMesh}.\n */\nfunction buildVectorTextGeometry(cfg = {}) {\n\n var origin = cfg.origin || [0, 0, 0];\n var xOrigin = origin[0];\n var yOrigin = origin[1];\n var zOrigin = origin[2];\n var size = cfg.size || 1;\n\n var positions = [];\n var indices = [];\n var text = (\"\" + cfg.text).trim();\n var lines = (text || \"\").split(\"\\n\");\n var countVerts = 0;\n var y = 0;\n var x;\n var str;\n var len;\n var c;\n var mag = 1.0 / 25.0;\n var penUp;\n var p1;\n var p2;\n var needLine;\n var pointsLen;\n var a;\n\n for (var iLine = 0; iLine < lines.length; iLine++) {\n\n x = 0;\n str = lines[iLine];\n len = str.length;\n\n for (var i = 0; i < len; i++) {\n\n c = letters[str.charAt(i)];\n\n if (c === '\\n') {\n //alert(\"newline\");\n }\n\n if (!c) {\n continue;\n }\n\n penUp = 1;\n p1 = -1;\n p2 = -1;\n needLine = false;\n\n pointsLen = c.points.length;\n\n for (var j = 0; j < pointsLen; j++) {\n a = c.points[j];\n\n if (a[0] === -1 && a[1] === -1) {\n penUp = 1;\n needLine = false;\n continue;\n }\n\n positions.push((x + (a[0] * size) * mag) + xOrigin);\n positions.push((y + (a[1] * size) * mag) + yOrigin);\n positions.push(0 + zOrigin);\n\n if (p1 === -1) {\n p1 = countVerts;\n } else if (p2 === -1) {\n p2 = countVerts;\n } else {\n p1 = p2;\n p2 = countVerts;\n }\n countVerts++;\n\n if (penUp) {\n penUp = false;\n\n } else {\n indices.push(p1);\n indices.push(p2);\n }\n\n needLine = true;\n }\n x += c.width * mag * size;\n\n }\n y -= 35 * mag * size;\n }\n\n return {\n primitiveType: \"lines\",\n positions: positions,\n indices: indices\n };\n}\n\n\nexport {buildVectorTextGeometry}\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/geometryBuilders/buildVectorTextGeometry.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/geometryBuilders/buildVectorTextGeometry.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 345, + "__docId__": 347, "kind": "variable", "name": "letters", "memberof": "src/geometryBuilders/buildVectorTextGeometry.js", @@ -8992,7 +9051,7 @@ "ignore": true }, { - "__docId__": 346, + "__docId__": 348, "kind": "function", "name": "buildVectorTextGeometry", "memberof": "src/geometryBuilders/buildVectorTextGeometry.js", @@ -9082,29 +9141,29 @@ } }, { - "__docId__": 347, + "__docId__": 349, "kind": "file", "name": "src/index.js", "content": "export {XKT_INFO} from \"./XKT_INFO.js\";\nexport * from \"./constants.js\";\nexport {XKTModel} from \"./XKTModel/XKTModel.js\";\nexport {writeXKTModelToArrayBuffer} from \"./XKTModel/writeXKTModelToArrayBuffer.js\";\n\nexport {parseCityJSONIntoXKTModel} from \"./parsers/parseCityJSONIntoXKTModel.js\";\nexport {parseGLTFIntoXKTModel} from \"./parsers/parseGLTFIntoXKTModel.js\";\nexport {parseGLTFJSONIntoXKTModel} from \"./parsers/parseGLTFJSONIntoXKTModel.js\";\nexport {parseIFCIntoXKTModel} from \"./parsers/parseIFCIntoXKTModel.js\";\nexport {parseLASIntoXKTModel} from \"./parsers/parseLASIntoXKTModel.js\";\nexport {parseMetaModelIntoXKTModel} from \"./parsers/parseMetaModelIntoXKTModel.js\";\nexport {parsePCDIntoXKTModel} from \"./parsers/parsePCDIntoXKTModel.js\";\nexport {parsePLYIntoXKTModel} from \"./parsers/parsePLYIntoXKTModel.js\";\nexport {parseSTLIntoXKTModel} from \"./parsers/parseSTLIntoXKTModel.js\";\n\nexport {buildBoxGeometry} from \"./geometryBuilders/buildBoxGeometry.js\";\nexport {buildBoxLinesGeometry} from \"./geometryBuilders/buildBoxLinesGeometry.js\";\nexport {buildCylinderGeometry} from \"./geometryBuilders/buildCylinderGeometry.js\";\nexport {buildGridGeometry} from \"./geometryBuilders/buildGridGeometry.js\";\nexport {buildPlaneGeometry} from \"./geometryBuilders/buildPlaneGeometry.js\";\nexport {buildSphereGeometry} from \"./geometryBuilders/buildSphereGeometry.js\";\nexport {buildTorusGeometry} from \"./geometryBuilders/buildTorusGeometry.js\";\nexport {buildVectorTextGeometry} from \"./geometryBuilders/buildVectorTextGeometry.js\";\n\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/index.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/index.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 348, + "__docId__": 350, "kind": "file", "name": "src/lib/buildFaceNormals.js", "content": "import {math} from \"./math.js\";\n\n/**\n * Builds face-aligned vertex normal vectors from positions and indices.\n *\n * @private\n */\nfunction buildFaceNormals(positions, indices, normals) {\n\n const a = math.vec3();\n const b = math.vec3();\n const c = math.vec3();\n\n const normVec = math.vec3();\n\n for (let i = 0, len = indices.length; i < len; i += 3) {\n\n const j0 = indices[i];\n const j1 = indices[i + 1];\n const j2 = indices[i + 2];\n\n a[0] = positions[j0 * 3];\n a[1] = positions[j0 * 3 + 1];\n a[2] = positions[j0 * 3 + 2];\n\n b[0] = positions[j1 * 3];\n b[1] = positions[j1 * 3 + 1];\n b[2] = positions[j1 * 3 + 2];\n\n c[0] = positions[j2 * 3];\n c[1] = positions[j2 * 3 + 1];\n c[2] = positions[j2 * 3 + 2];\n\n triangleNormal(a,b,c, normVec);\n\n normals[j0 * 3 + 0] = normVec[0];\n normals[j0 * 3 + 1] = normVec[1];\n normals[j0 * 3 + 2] = normVec[2];\n\n normals[j1 * 3 + 0] = normVec[0];\n normals[j1 * 3 + 1] = normVec[1];\n normals[j1 * 3 + 2] = normVec[2];\n\n normals[j2 * 3 + 0] = normVec[0];\n normals[j2 * 3 + 1] = normVec[1];\n normals[j2 * 3 + 2] = normVec[2];\n }\n}\n\nfunction triangleNormal(a, b, c, normal = math.vec3()) {\n const p1x = b[0] - a[0];\n const p1y = b[1] - a[1];\n const p1z = b[2] - a[2];\n\n const p2x = c[0] - a[0];\n const p2y = c[1] - a[1];\n const p2z = c[2] - a[2];\n\n const p3x = p1y * p2z - p1z * p2y;\n const p3y = p1z * p2x - p1x * p2z;\n const p3z = p1x * p2y - p1y * p2x;\n\n const mag = Math.sqrt(p3x * p3x + p3y * p3y + p3z * p3z);\n if (mag === 0) {\n normal[0] = 0;\n normal[1] = 0;\n normal[2] = 0;\n } else {\n normal[0] = p3x / mag;\n normal[1] = p3y / mag;\n normal[2] = p3z / mag;\n }\n\n return normal\n}\n\nexport {buildFaceNormals};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/lib/buildFaceNormals.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/lib/buildFaceNormals.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 349, + "__docId__": 351, "kind": "function", "name": "triangleNormal", "memberof": "src/lib/buildFaceNormals.js", @@ -9154,7 +9213,7 @@ "ignore": true }, { - "__docId__": 350, + "__docId__": 352, "kind": "function", "name": "buildFaceNormals", "memberof": "src/lib/buildFaceNormals.js", @@ -9192,18 +9251,18 @@ "return": null }, { - "__docId__": 351, + "__docId__": 353, "kind": "file", "name": "src/lib/buildVertexNormals.js", "content": "import {math} from \"./math.js\";\n\n/**\n * Builds vertex normal vectors from positions and indices.\n *\n * @private\n */\nfunction buildVertexNormals(positions, indices, normals) {\n\n const a = math.vec3();\n const b = math.vec3();\n const c = math.vec3();\n const ab = math.vec3();\n const ac = math.vec3();\n const crossVec = math.vec3();\n const nvecs = new Array(positions.length / 3);\n\n for (let i = 0, len = indices.length; i < len; i += 3) {\n\n const j0 = indices[i];\n const j1 = indices[i + 1];\n const j2 = indices[i + 2];\n\n a[0] = positions[j0 * 3];\n a[1] = positions[j0 * 3 + 1];\n a[2] = positions[j0 * 3 + 2];\n\n b[0] = positions[j1 * 3];\n b[1] = positions[j1 * 3 + 1];\n b[2] = positions[j1 * 3 + 2];\n\n c[0] = positions[j2 * 3];\n c[1] = positions[j2 * 3 + 1];\n c[2] = positions[j2 * 3 + 2];\n\n math.subVec3(b, a, ab);\n math.subVec3(c, a, ac);\n\n const normVec = math.vec3();\n\n math.normalizeVec3(math.cross3Vec3(ab, ac, crossVec), normVec);\n\n if (!nvecs[j0]) {\n nvecs[j0] = [];\n }\n if (!nvecs[j1]) {\n nvecs[j1] = [];\n }\n if (!nvecs[j2]) {\n nvecs[j2] = [];\n }\n\n nvecs[j0].push(normVec);\n nvecs[j1].push(normVec);\n nvecs[j2].push(normVec);\n }\n\n normals = (normals && normals.length === positions.length) ? normals : new Float32Array(positions.length);\n\n for (let i = 0, len = nvecs.length; i < len; i++) { // Now go through and average out everything\n\n const count = nvecs[i].length;\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n for (let j = 0; j < count; j++) {\n x += nvecs[i][j][0];\n y += nvecs[i][j][1];\n z += nvecs[i][j][2];\n }\n\n normals[i * 3] = (x / count);\n normals[i * 3 + 1] = (y / count);\n normals[i * 3 + 2] = (z / count);\n }\n\n return normals;\n}\n\nexport {buildVertexNormals};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/lib/buildVertexNormals.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/lib/buildVertexNormals.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 352, + "__docId__": 354, "kind": "function", "name": "buildVertexNormals", "memberof": "src/lib/buildVertexNormals.js", @@ -9245,18 +9304,18 @@ } }, { - "__docId__": 353, + "__docId__": 355, "kind": "file", "name": "src/lib/earcut.js", "content": "/** @private */\nfunction earcut(data, holeIndices, dim) {\n\n dim = dim || 2;\n\n var hasHoles = holeIndices && holeIndices.length,\n outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n outerNode = linkedList(data, 0, outerLen, dim, true),\n triangles = [];\n\n if (!outerNode || outerNode.next === outerNode.prev) return triangles;\n\n var minX, minY, maxX, maxY, x, y, invSize;\n\n if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n if (data.length > 80 * dim) {\n minX = maxX = data[0];\n minY = maxY = data[1];\n\n for (var i = dim; i < outerLen; i += dim) {\n x = data[i];\n y = data[i + 1];\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n }\n\n // minX, minY and invSize are later used to transform coords into integers for z-order calculation\n invSize = Math.max(maxX - minX, maxY - minY);\n invSize = invSize !== 0 ? 1 / invSize : 0;\n }\n\n earcutLinked(outerNode, triangles, dim, minX, minY, invSize);\n\n return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList(data, start, end, dim, clockwise) {\n var i, last;\n\n if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n } else {\n for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n }\n\n if (last && equals(last, last.next)) {\n removeNode(last);\n last = last.next;\n }\n\n return last;\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints(start, end) {\n if (!start) return start;\n if (!end) end = start;\n\n var p = start,\n again;\n do {\n again = false;\n\n if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n removeNode(p);\n p = end = p.prev;\n if (p === p.next) break;\n again = true;\n\n } else {\n p = p.next;\n }\n } while (again || p !== end);\n\n return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {\n if (!ear) return;\n\n // interlink polygon nodes in z-order\n if (!pass && invSize) indexCurve(ear, minX, minY, invSize);\n\n var stop = ear,\n prev, next;\n\n // iterate through ears, slicing them one by one\n while (ear.prev !== ear.next) {\n prev = ear.prev;\n next = ear.next;\n\n if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {\n // cut off the triangle\n triangles.push(prev.i / dim);\n triangles.push(ear.i / dim);\n triangles.push(next.i / dim);\n\n removeNode(ear);\n\n // skipping the next vertex leads to less sliver triangles\n ear = next.next;\n stop = next.next;\n\n continue;\n }\n\n ear = next;\n\n // if we looped through the whole remaining polygon and can't find any more ears\n if (ear === stop) {\n // try filtering points and slicing again\n if (!pass) {\n earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);\n\n // if this didn't work, try curing all small self-intersections locally\n } else if (pass === 1) {\n ear = cureLocalIntersections(filterPoints(ear), triangles, dim);\n earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);\n\n // as a last resort, try splitting the remaining polygon into two\n } else if (pass === 2) {\n splitEarcut(ear, triangles, dim, minX, minY, invSize);\n }\n\n break;\n }\n }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar(ear) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // now make sure we don't have other points inside the potential ear\n var p = ear.next.next;\n\n while (p !== ear.prev) {\n if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.next;\n }\n\n return true;\n}\n\nfunction isEarHashed(ear, minX, minY, invSize) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // triangle bbox; min & max are calculated like this for speed\n var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\n // z-order range for the current triangle bbox;\n var minZ = zOrder(minTX, minTY, minX, minY, invSize),\n maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);\n\n var p = ear.prevZ,\n n = ear.nextZ;\n\n // look for points inside the triangle in both directions\n while (p && p.z >= minZ && n && n.z <= maxZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n\n if (n !== ear.prev && n !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&\n area(n.prev, n, n.next) >= 0) return false;\n n = n.nextZ;\n }\n\n // look for remaining points in decreasing z-order\n while (p && p.z >= minZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n }\n\n // look for remaining points in increasing z-order\n while (n && n.z <= maxZ) {\n if (n !== ear.prev && n !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&\n area(n.prev, n, n.next) >= 0) return false;\n n = n.nextZ;\n }\n\n return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections(start, triangles, dim) {\n var p = start;\n do {\n var a = p.prev,\n b = p.next.next;\n\n if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\n triangles.push(a.i / dim);\n triangles.push(p.i / dim);\n triangles.push(b.i / dim);\n\n // remove two nodes involved\n removeNode(p);\n removeNode(p.next);\n\n p = start = b;\n }\n p = p.next;\n } while (p !== start);\n\n return filterPoints(p);\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut(start, triangles, dim, minX, minY, invSize) {\n // look for a valid diagonal that divides the polygon into two\n var a = start;\n do {\n var b = a.next.next;\n while (b !== a.prev) {\n if (a.i !== b.i && isValidDiagonal(a, b)) {\n // split the polygon in two by the diagonal\n var c = splitPolygon(a, b);\n\n // filter colinear points around the cuts\n a = filterPoints(a, a.next);\n c = filterPoints(c, c.next);\n\n // run earcut on each half\n earcutLinked(a, triangles, dim, minX, minY, invSize);\n earcutLinked(c, triangles, dim, minX, minY, invSize);\n return;\n }\n b = b.next;\n }\n a = a.next;\n } while (a !== start);\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n var queue = [],\n i, len, start, end, list;\n\n for (i = 0, len = holeIndices.length; i < len; i++) {\n start = holeIndices[i] * dim;\n end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n list = linkedList(data, start, end, dim, false);\n if (list === list.next) list.steiner = true;\n queue.push(getLeftmost(list));\n }\n\n queue.sort(compareX);\n\n // process holes from left to right\n for (i = 0; i < queue.length; i++) {\n eliminateHole(queue[i], outerNode);\n outerNode = filterPoints(outerNode, outerNode.next);\n }\n\n return outerNode;\n}\n\nfunction compareX(a, b) {\n return a.x - b.x;\n}\n\n// find a bridge between vertices that connects hole with an outer ring and and link it\nfunction eliminateHole(hole, outerNode) {\n outerNode = findHoleBridge(hole, outerNode);\n if (outerNode) {\n var b = splitPolygon(outerNode, hole);\n\n // filter collinear points around the cuts\n filterPoints(outerNode, outerNode.next);\n filterPoints(b, b.next);\n }\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge(hole, outerNode) {\n var p = outerNode,\n hx = hole.x,\n hy = hole.y,\n qx = -Infinity,\n m;\n\n // find a segment intersected by a ray from the hole's leftmost point to the left;\n // segment's endpoint with lesser x will be potential connection point\n do {\n if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {\n var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n if (x <= hx && x > qx) {\n qx = x;\n if (x === hx) {\n if (hy === p.y) return p;\n if (hy === p.next.y) return p.next;\n }\n m = p.x < p.next.x ? p : p.next;\n }\n }\n p = p.next;\n } while (p !== outerNode);\n\n if (!m) return null;\n\n if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint\n\n // look for points inside the triangle of hole point, segment intersection and endpoint;\n // if there are no points found, we have a valid connection;\n // otherwise choose the point of the minimum angle with the ray as connection point\n\n var stop = m,\n mx = m.x,\n my = m.y,\n tanMin = Infinity,\n tan;\n\n p = m;\n\n do {\n if (hx >= p.x && p.x >= mx && hx !== p.x &&\n pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\n tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n if (locallyInside(p, hole) &&\n (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {\n m = p;\n tanMin = tan;\n }\n }\n\n p = p.next;\n } while (p !== stop);\n\n return m;\n}\n\n// whether sector in vertex m contains sector in vertex p in the same coordinates\nfunction sectorContainsSector(m, p) {\n return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve(start, minX, minY, invSize) {\n var p = start;\n do {\n if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize);\n p.prevZ = p.prev;\n p.nextZ = p.next;\n p = p.next;\n } while (p !== start);\n\n p.prevZ.nextZ = null;\n p.prevZ = null;\n\n sortLinked(p);\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked(list) {\n var i, p, q, e, tail, numMerges, pSize, qSize,\n inSize = 1;\n\n do {\n p = list;\n list = null;\n tail = null;\n numMerges = 0;\n\n while (p) {\n numMerges++;\n q = p;\n pSize = 0;\n for (i = 0; i < inSize; i++) {\n pSize++;\n q = q.nextZ;\n if (!q) break;\n }\n qSize = inSize;\n\n while (pSize > 0 || (qSize > 0 && q)) {\n\n if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else {\n e = q;\n q = q.nextZ;\n qSize--;\n }\n\n if (tail) tail.nextZ = e;\n else list = e;\n\n e.prevZ = tail;\n tail = e;\n }\n\n p = q;\n }\n\n tail.nextZ = null;\n inSize *= 2;\n\n } while (numMerges > 1);\n\n return list;\n}\n\n// z-order of a point given coords and inverse of the longer side of data bbox\nfunction zOrder(x, y, minX, minY, invSize) {\n // coords are transformed into non-negative 15-bit integer range\n x = 32767 * (x - minX) * invSize;\n y = 32767 * (y - minY) * invSize;\n\n x = (x | (x << 8)) & 0x00FF00FF;\n x = (x | (x << 4)) & 0x0F0F0F0F;\n x = (x | (x << 2)) & 0x33333333;\n x = (x | (x << 1)) & 0x55555555;\n\n y = (y | (y << 8)) & 0x00FF00FF;\n y = (y | (y << 4)) & 0x0F0F0F0F;\n y = (y | (y << 2)) & 0x33333333;\n y = (y | (y << 1)) & 0x55555555;\n\n return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost(start) {\n var p = start,\n leftmost = start;\n do {\n if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;\n p = p.next;\n } while (p !== start);\n\n return leftmost;\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal(a, b) {\n return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges\n (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible\n (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors\n equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case\n}\n\n// signed area of a triangle\nfunction area(p, q, r) {\n return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\nfunction equals(p1, p2) {\n return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect\nfunction intersects(p1, q1, p2, q2) {\n var o1 = sign(area(p1, q1, p2));\n var o2 = sign(area(p1, q1, q2));\n var o3 = sign(area(p2, q2, p1));\n var o4 = sign(area(p2, q2, q1));\n\n if (o1 !== o2 && o3 !== o4) return true; // general case\n\n if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1\n if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1\n if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2\n if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2\n\n return false;\n}\n\n// for collinear points p, q, r, check if point q lies on segment pr\nfunction onSegment(p, q, r) {\n return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);\n}\n\nfunction sign(num) {\n return num > 0 ? 1 : num < 0 ? -1 : 0;\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon(a, b) {\n var p = a;\n do {\n if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n intersects(p, p.next, a, b)) return true;\n p = p.next;\n } while (p !== a);\n\n return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside(a, b) {\n return area(a.prev, a, a.next) < 0 ?\n area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside(a, b) {\n var p = a,\n inside = false,\n px = (a.x + b.x) / 2,\n py = (a.y + b.y) / 2;\n do {\n if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&\n (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n inside = !inside;\n p = p.next;\n } while (p !== a);\n\n return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon(a, b) {\n var a2 = new Node(a.i, a.x, a.y),\n b2 = new Node(b.i, b.x, b.y),\n an = a.next,\n bp = b.prev;\n\n a.next = b;\n b.prev = a;\n\n a2.next = an;\n an.prev = a2;\n\n b2.next = a2;\n a2.prev = b2;\n\n bp.next = b2;\n b2.prev = bp;\n\n return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode(i, x, y, last) {\n var p = new Node(i, x, y);\n\n if (!last) {\n p.prev = p;\n p.next = p;\n\n } else {\n p.next = last.next;\n p.prev = last;\n last.next.prev = p;\n last.next = p;\n }\n return p;\n}\n\nfunction removeNode(p) {\n p.next.prev = p.prev;\n p.prev.next = p.next;\n\n if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n}\n\nfunction Node(i, x, y) {\n // vertex index in coordinates array\n this.i = i;\n\n // vertex coordinates\n this.x = x;\n this.y = y;\n\n // previous and next vertex nodes in a polygon ring\n this.prev = null;\n this.next = null;\n\n // z-order curve value\n this.z = null;\n\n // previous and next nodes in z-order\n this.prevZ = null;\n this.nextZ = null;\n\n // indicates whether this is a steiner point\n this.steiner = false;\n}\n\n// return a percentage difference between the polygon area and its triangulation area;\n// used to verify correctness of triangulation\nearcut.deviation = function (data, holeIndices, dim, triangles) {\n var hasHoles = holeIndices && holeIndices.length;\n var outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\n var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n if (hasHoles) {\n for (var i = 0, len = holeIndices.length; i < len; i++) {\n var start = holeIndices[i] * dim;\n var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n polygonArea -= Math.abs(signedArea(data, start, end, dim));\n }\n }\n\n var trianglesArea = 0;\n for (i = 0; i < triangles.length; i += 3) {\n var a = triangles[i] * dim;\n var b = triangles[i + 1] * dim;\n var c = triangles[i + 2] * dim;\n trianglesArea += Math.abs(\n (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n }\n\n return polygonArea === 0 && trianglesArea === 0 ? 0 :\n Math.abs((trianglesArea - polygonArea) / polygonArea);\n};\n\nfunction signedArea(data, start, end, dim) {\n var sum = 0;\n for (var i = start, j = end - dim; i < end; i += dim) {\n sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n j = i;\n }\n return sum;\n}\n\n// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\nearcut.flatten = function (data) {\n var dim = data[0][0].length,\n result = {vertices: [], holes: [], dimensions: dim},\n holeIndex = 0;\n\n for (var i = 0; i < data.length; i++) {\n for (var j = 0; j < data[i].length; j++) {\n for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);\n }\n if (i > 0) {\n holeIndex += data[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n return result;\n};\n\nexport {earcut};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/lib/earcut.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/lib/earcut.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 354, + "__docId__": 356, "kind": "function", "name": "linkedList", "memberof": "src/lib/earcut.js", @@ -9311,7 +9370,7 @@ "ignore": true }, { - "__docId__": 355, + "__docId__": 357, "kind": "function", "name": "filterPoints", "memberof": "src/lib/earcut.js", @@ -9348,7 +9407,7 @@ "ignore": true }, { - "__docId__": 356, + "__docId__": 358, "kind": "function", "name": "earcutLinked", "memberof": "src/lib/earcut.js", @@ -9411,7 +9470,7 @@ "ignore": true }, { - "__docId__": 357, + "__docId__": 359, "kind": "function", "name": "isEar", "memberof": "src/lib/earcut.js", @@ -9442,7 +9501,7 @@ "ignore": true }, { - "__docId__": 358, + "__docId__": 360, "kind": "function", "name": "isEarHashed", "memberof": "src/lib/earcut.js", @@ -9491,7 +9550,7 @@ "ignore": true }, { - "__docId__": 359, + "__docId__": 361, "kind": "function", "name": "cureLocalIntersections", "memberof": "src/lib/earcut.js", @@ -9534,7 +9593,7 @@ "ignore": true }, { - "__docId__": 360, + "__docId__": 362, "kind": "function", "name": "splitEarcut", "memberof": "src/lib/earcut.js", @@ -9591,7 +9650,7 @@ "ignore": true }, { - "__docId__": 361, + "__docId__": 363, "kind": "function", "name": "eliminateHoles", "memberof": "src/lib/earcut.js", @@ -9640,7 +9699,7 @@ "ignore": true }, { - "__docId__": 362, + "__docId__": 364, "kind": "function", "name": "compareX", "memberof": "src/lib/earcut.js", @@ -9677,7 +9736,7 @@ "ignore": true }, { - "__docId__": 363, + "__docId__": 365, "kind": "function", "name": "eliminateHole", "memberof": "src/lib/earcut.js", @@ -9710,7 +9769,7 @@ "ignore": true }, { - "__docId__": 364, + "__docId__": 366, "kind": "function", "name": "findHoleBridge", "memberof": "src/lib/earcut.js", @@ -9747,7 +9806,7 @@ "ignore": true }, { - "__docId__": 365, + "__docId__": 367, "kind": "function", "name": "sectorContainsSector", "memberof": "src/lib/earcut.js", @@ -9784,7 +9843,7 @@ "ignore": true }, { - "__docId__": 366, + "__docId__": 368, "kind": "function", "name": "indexCurve", "memberof": "src/lib/earcut.js", @@ -9829,7 +9888,7 @@ "ignore": true }, { - "__docId__": 367, + "__docId__": 369, "kind": "function", "name": "sortLinked", "memberof": "src/lib/earcut.js", @@ -9860,7 +9919,7 @@ "ignore": true }, { - "__docId__": 368, + "__docId__": 370, "kind": "function", "name": "zOrder", "memberof": "src/lib/earcut.js", @@ -9915,7 +9974,7 @@ "ignore": true }, { - "__docId__": 369, + "__docId__": 371, "kind": "function", "name": "getLeftmost", "memberof": "src/lib/earcut.js", @@ -9946,7 +10005,7 @@ "ignore": true }, { - "__docId__": 370, + "__docId__": 372, "kind": "function", "name": "pointInTriangle", "memberof": "src/lib/earcut.js", @@ -10019,7 +10078,7 @@ "ignore": true }, { - "__docId__": 371, + "__docId__": 373, "kind": "function", "name": "isValidDiagonal", "memberof": "src/lib/earcut.js", @@ -10056,7 +10115,7 @@ "ignore": true }, { - "__docId__": 372, + "__docId__": 374, "kind": "function", "name": "area", "memberof": "src/lib/earcut.js", @@ -10099,7 +10158,7 @@ "ignore": true }, { - "__docId__": 373, + "__docId__": 375, "kind": "function", "name": "equals", "memberof": "src/lib/earcut.js", @@ -10136,7 +10195,7 @@ "ignore": true }, { - "__docId__": 374, + "__docId__": 376, "kind": "function", "name": "intersects", "memberof": "src/lib/earcut.js", @@ -10185,7 +10244,7 @@ "ignore": true }, { - "__docId__": 375, + "__docId__": 377, "kind": "function", "name": "onSegment", "memberof": "src/lib/earcut.js", @@ -10228,7 +10287,7 @@ "ignore": true }, { - "__docId__": 376, + "__docId__": 378, "kind": "function", "name": "sign", "memberof": "src/lib/earcut.js", @@ -10259,7 +10318,7 @@ "ignore": true }, { - "__docId__": 377, + "__docId__": 379, "kind": "function", "name": "intersectsPolygon", "memberof": "src/lib/earcut.js", @@ -10296,7 +10355,7 @@ "ignore": true }, { - "__docId__": 378, + "__docId__": 380, "kind": "function", "name": "locallyInside", "memberof": "src/lib/earcut.js", @@ -10333,7 +10392,7 @@ "ignore": true }, { - "__docId__": 379, + "__docId__": 381, "kind": "function", "name": "middleInside", "memberof": "src/lib/earcut.js", @@ -10370,7 +10429,7 @@ "ignore": true }, { - "__docId__": 380, + "__docId__": 382, "kind": "function", "name": "splitPolygon", "memberof": "src/lib/earcut.js", @@ -10407,7 +10466,7 @@ "ignore": true }, { - "__docId__": 381, + "__docId__": 383, "kind": "function", "name": "insertNode", "memberof": "src/lib/earcut.js", @@ -10456,7 +10515,7 @@ "ignore": true }, { - "__docId__": 382, + "__docId__": 384, "kind": "function", "name": "removeNode", "memberof": "src/lib/earcut.js", @@ -10483,7 +10542,7 @@ "ignore": true }, { - "__docId__": 383, + "__docId__": 385, "kind": "function", "name": "Node", "memberof": "src/lib/earcut.js", @@ -10522,7 +10581,7 @@ "ignore": true }, { - "__docId__": 384, + "__docId__": 386, "kind": "function", "name": "deviation", "memberof": "src/lib/earcut.js", @@ -10571,7 +10630,7 @@ "ignore": true }, { - "__docId__": 385, + "__docId__": 387, "kind": "function", "name": "signedArea", "memberof": "src/lib/earcut.js", @@ -10620,7 +10679,7 @@ "ignore": true }, { - "__docId__": 386, + "__docId__": 388, "kind": "function", "name": "flatten", "memberof": "src/lib/earcut.js", @@ -10651,7 +10710,7 @@ "ignore": true }, { - "__docId__": 387, + "__docId__": 389, "kind": "function", "name": "earcut", "memberof": "src/lib/earcut.js", @@ -10693,18 +10752,18 @@ } }, { - "__docId__": 388, + "__docId__": 390, "kind": "file", "name": "src/lib/faceToVertexNormals.js", "content": "import {math} from \"./math.js\";\n\n/**\n * Converts surface-perpendicular face normals to vertex normals. Assumes that the mesh contains disjoint triangles\n * that don't share vertex array elements. Works by finding groups of vertices that have the same location and\n * averaging their normal vectors.\n *\n * @returns {{positions: Array, normals: *}}\n * @private\n */\nfunction faceToVertexNormals(positions, normals, options = {}) {\n const smoothNormalsAngleThreshold = options.smoothNormalsAngleThreshold || 20;\n const vertexMap = {};\n const vertexNormals = [];\n const vertexNormalAccum = {};\n let acc;\n let vx;\n let vy;\n let vz;\n let key;\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = 10 ** precisionPoints;\n let posi;\n let i;\n let j;\n let len;\n let a;\n let b;\n let c;\n\n for (i = 0, len = positions.length; i < len; i += 3) {\n\n posi = i / 3;\n\n vx = positions[i];\n vy = positions[i + 1];\n vz = positions[i + 2];\n\n key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`;\n\n if (vertexMap[key] === undefined) {\n vertexMap[key] = [posi];\n } else {\n vertexMap[key].push(posi);\n }\n\n const normal = math.normalizeVec3([normals[i], normals[i + 1], normals[i + 2]]);\n\n vertexNormals[posi] = normal;\n\n acc = math.vec4([normal[0], normal[1], normal[2], 1]);\n\n vertexNormalAccum[posi] = acc;\n }\n\n for (key in vertexMap) {\n\n if (vertexMap.hasOwnProperty(key)) {\n\n const vertices = vertexMap[key];\n const numVerts = vertices.length;\n\n for (i = 0; i < numVerts; i++) {\n\n const ii = vertices[i];\n\n acc = vertexNormalAccum[ii];\n\n for (j = 0; j < numVerts; j++) {\n\n if (i === j) {\n continue;\n }\n\n const jj = vertices[j];\n\n a = vertexNormals[ii];\n b = vertexNormals[jj];\n\n const angle = Math.abs(math.angleVec3(a, b) / math.DEGTORAD);\n\n if (angle < smoothNormalsAngleThreshold) {\n\n acc[0] += b[0];\n acc[1] += b[1];\n acc[2] += b[2];\n acc[3] += 1.0;\n }\n }\n }\n }\n }\n\n for (i = 0, len = normals.length; i < len; i += 3) {\n\n acc = vertexNormalAccum[i / 3];\n\n normals[i + 0] = acc[0] / acc[3];\n normals[i + 1] = acc[1] / acc[3];\n normals[i + 2] = acc[2] / acc[3];\n\n }\n}\n\nexport {faceToVertexNormals};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/lib/faceToVertexNormals.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/lib/faceToVertexNormals.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 389, + "__docId__": 391, "kind": "function", "name": "faceToVertexNormals", "memberof": "src/lib/faceToVertexNormals.js", @@ -10758,18 +10817,18 @@ ] }, { - "__docId__": 390, + "__docId__": 392, "kind": "file", "name": "src/lib/math.js", "content": "// Some temporary vars to help avoid garbage collection\n\nconst doublePrecision = true;\nconst FloatArrayType = doublePrecision ? Float64Array : Float32Array;\n\nconst tempMat1 = new FloatArrayType(16);\nconst tempMat2 = new FloatArrayType(16);\nconst tempVec4 = new FloatArrayType(4);\n\n/**\n * @private\n */\nconst math = {\n\n MIN_DOUBLE: -Number.MAX_SAFE_INTEGER,\n MAX_DOUBLE: Number.MAX_SAFE_INTEGER,\n\n /**\n * The number of radiians in a degree (0.0174532925).\n * @property DEGTORAD\n * @type {Number}\n */\n DEGTORAD: 0.0174532925,\n\n /**\n * The number of degrees in a radian.\n * @property RADTODEG\n * @type {Number}\n */\n RADTODEG: 57.295779513,\n\n /**\n * Returns a new, uninitialized two-element vector.\n * @method vec2\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec2(values) {\n return new FloatArrayType(values || 2);\n },\n\n /**\n * Returns a new, uninitialized three-element vector.\n * @method vec3\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec3(values) {\n return new FloatArrayType(values || 3);\n },\n\n /**\n * Returns a new, uninitialized four-element vector.\n * @method vec4\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n vec4(values) {\n return new FloatArrayType(values || 4);\n },\n\n /**\n * Returns a new, uninitialized 3x3 matrix.\n * @method mat3\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n mat3(values) {\n return new FloatArrayType(values || 9);\n },\n\n /**\n * Converts a 3x3 matrix to 4x4\n * @method mat3ToMat4\n * @param mat3 3x3 matrix.\n * @param mat4 4x4 matrix\n * @static\n * @returns {Number[]}\n */\n mat3ToMat4(mat3, mat4 = new FloatArrayType(16)) {\n mat4[0] = mat3[0];\n mat4[1] = mat3[1];\n mat4[2] = mat3[2];\n mat4[3] = 0;\n mat4[4] = mat3[3];\n mat4[5] = mat3[4];\n mat4[6] = mat3[5];\n mat4[7] = 0;\n mat4[8] = mat3[6];\n mat4[9] = mat3[7];\n mat4[10] = mat3[8];\n mat4[11] = 0;\n mat4[12] = 0;\n mat4[13] = 0;\n mat4[14] = 0;\n mat4[15] = 1;\n return mat4;\n },\n\n /**\n * Returns a new, uninitialized 4x4 matrix.\n * @method mat4\n * @param [values] Initial values.\n * @static\n * @returns {Number[]}\n */\n mat4(values) {\n return new FloatArrayType(values || 16);\n },\n\n /**\n * Converts a 4x4 matrix to 3x3\n * @method mat4ToMat3\n * @param mat4 4x4 matrix.\n * @param mat3 3x3 matrix\n * @static\n * @returns {Number[]}\n */\n mat4ToMat3(mat4, mat3) { // TODO\n //return new FloatArrayType(values || 9);\n },\n\n /**\n * Returns a new UUID.\n * @method createUUID\n * @static\n * @return string The new UUID\n */\n createUUID: ((() => {\n const self = {};\n const lut = [];\n for (let i = 0; i < 256; i++) {\n lut[i] = (i < 16 ? '0' : '') + (i).toString(16);\n }\n return () => {\n const d0 = Math.random() * 0xffffffff | 0;\n const d1 = Math.random() * 0xffffffff | 0;\n const d2 = Math.random() * 0xffffffff | 0;\n const d3 = Math.random() * 0xffffffff | 0;\n return `${lut[d0 & 0xff] + lut[d0 >> 8 & 0xff] + lut[d0 >> 16 & 0xff] + lut[d0 >> 24 & 0xff]}-${lut[d1 & 0xff]}${lut[d1 >> 8 & 0xff]}-${lut[d1 >> 16 & 0x0f | 0x40]}${lut[d1 >> 24 & 0xff]}-${lut[d2 & 0x3f | 0x80]}${lut[d2 >> 8 & 0xff]}-${lut[d2 >> 16 & 0xff]}${lut[d2 >> 24 & 0xff]}${lut[d3 & 0xff]}${lut[d3 >> 8 & 0xff]}${lut[d3 >> 16 & 0xff]}${lut[d3 >> 24 & 0xff]}`;\n };\n }))(),\n\n /**\n * Clamps a value to the given range.\n * @param {Number} value Value to clamp.\n * @param {Number} min Lower bound.\n * @param {Number} max Upper bound.\n * @returns {Number} Clamped result.\n */\n clamp(value, min, max) {\n return Math.max(min, Math.min(max, value));\n },\n\n /**\n * Floating-point modulus\n * @method fmod\n * @static\n * @param {Number} a\n * @param {Number} b\n * @returns {*}\n */\n fmod(a, b) {\n if (a < b) {\n console.error(\"math.fmod : Attempting to find modulus within negative range - would be infinite loop - ignoring\");\n return a;\n }\n while (b <= a) {\n a -= b;\n }\n return a;\n },\n\n /**\n * Negates a four-element vector.\n * @method negateVec4\n * @static\n * @param {Array(Number)} v Vector to negate\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n negateVec4(v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = -v[0];\n dest[1] = -v[1];\n dest[2] = -v[2];\n dest[3] = -v[3];\n return dest;\n },\n\n /**\n * Adds one four-element vector to another.\n * @method addVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n addVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] + v[0];\n dest[1] = u[1] + v[1];\n dest[2] = u[2] + v[2];\n dest[3] = u[3] + v[3];\n return dest;\n },\n\n /**\n * Adds a scalar value to each element of a four-element vector.\n * @method addVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n addVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] + s;\n dest[1] = v[1] + s;\n dest[2] = v[2] + s;\n dest[3] = v[3] + s;\n return dest;\n },\n\n /**\n * Adds one three-element vector to another.\n * @method addVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n addVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] + v[0];\n dest[1] = u[1] + v[1];\n dest[2] = u[2] + v[2];\n return dest;\n },\n\n /**\n * Adds a scalar value to each element of a three-element vector.\n * @method addVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n addVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] + s;\n dest[1] = v[1] + s;\n dest[2] = v[2] + s;\n return dest;\n },\n\n /**\n * Subtracts one four-element vector from another.\n * @method subVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n dest[2] = u[2] - v[2];\n dest[3] = u[3] - v[3];\n return dest;\n },\n\n /**\n * Subtracts one three-element vector from another.\n * @method subVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n dest[2] = u[2] - v[2];\n return dest;\n },\n\n /**\n * Subtracts one two-element vector from another.\n * @method subVec2\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Vector to subtract\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n subVec2(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] - v[0];\n dest[1] = u[1] - v[1];\n return dest;\n },\n\n /**\n * Subtracts a scalar value from each element of a four-element vector.\n * @method subVec4Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n subVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] - s;\n dest[1] = v[1] - s;\n dest[2] = v[2] - s;\n dest[3] = v[3] - s;\n return dest;\n },\n\n /**\n * Sets each element of a 4-element vector to a scalar value minus the value of that element.\n * @method subScalarVec4\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n subScalarVec4(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s - v[0];\n dest[1] = s - v[1];\n dest[2] = s - v[2];\n dest[3] = s - v[3];\n return dest;\n },\n\n /**\n * Multiplies one three-element vector by another.\n * @method mulVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n mulVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] * v[0];\n dest[1] = u[1] * v[1];\n dest[2] = u[2] * v[2];\n dest[3] = u[3] * v[3];\n return dest;\n },\n\n /**\n * Multiplies each element of a four-element vector by a scalar.\n * @method mulVec34calar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n dest[2] = v[2] * s;\n dest[3] = v[3] * s;\n return dest;\n },\n\n /**\n * Multiplies each element of a three-element vector by a scalar.\n * @method mulVec3Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n dest[2] = v[2] * s;\n return dest;\n },\n\n /**\n * Multiplies each element of a two-element vector by a scalar.\n * @method mulVec2Scalar\n * @static\n * @param {Array(Number)} v The vector\n * @param {Number} s The scalar\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, v otherwise\n */\n mulVec2Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] * s;\n dest[1] = v[1] * s;\n return dest;\n },\n\n /**\n * Divides one three-element vector by another.\n * @method divVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n divVec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] / v[0];\n dest[1] = u[1] / v[1];\n dest[2] = u[2] / v[2];\n return dest;\n },\n\n /**\n * Divides one four-element vector by another.\n * @method divVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @param {Array(Number)} [dest] Destination vector\n * @return {Array(Number)} dest if specified, u otherwise\n */\n divVec4(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n dest[0] = u[0] / v[0];\n dest[1] = u[1] / v[1];\n dest[2] = u[2] / v[2];\n dest[3] = u[3] / v[3];\n return dest;\n },\n\n /**\n * Divides a scalar by a three-element vector, returning a new vector.\n * @method divScalarVec3\n * @static\n * @param v vec3\n * @param s scalar\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divScalarVec3(s, v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s / v[0];\n dest[1] = s / v[1];\n dest[2] = s / v[2];\n return dest;\n },\n\n /**\n * Divides a three-element vector by a scalar.\n * @method divVec3Scalar\n * @static\n * @param v vec3\n * @param s scalar\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divVec3Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] / s;\n dest[1] = v[1] / s;\n dest[2] = v[2] / s;\n return dest;\n },\n\n /**\n * Divides a four-element vector by a scalar.\n * @method divVec4Scalar\n * @static\n * @param v vec4\n * @param s scalar\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divVec4Scalar(v, s, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = v[0] / s;\n dest[1] = v[1] / s;\n dest[2] = v[2] / s;\n dest[3] = v[3] / s;\n return dest;\n },\n\n\n /**\n * Divides a scalar by a four-element vector, returning a new vector.\n * @method divScalarVec4\n * @static\n * @param s scalar\n * @param v vec4\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n */\n divScalarVec4(s, v, dest) {\n if (!dest) {\n dest = v;\n }\n dest[0] = s / v[0];\n dest[1] = s / v[1];\n dest[2] = s / v[2];\n dest[3] = s / v[3];\n return dest;\n },\n\n /**\n * Returns the dot product of two four-element vectors.\n * @method dotVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec4(u, v) {\n return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2] + u[3] * v[3]);\n },\n\n /**\n * Returns the cross product of two four-element vectors.\n * @method cross3Vec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The cross product\n */\n cross3Vec4(u, v) {\n const u0 = u[0];\n const u1 = u[1];\n const u2 = u[2];\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n return [\n u1 * v2 - u2 * v1,\n u2 * v0 - u0 * v2,\n u0 * v1 - u1 * v0,\n 0.0];\n },\n\n /**\n * Returns the cross product of two three-element vectors.\n * @method cross3Vec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The cross product\n */\n cross3Vec3(u, v, dest) {\n if (!dest) {\n dest = u;\n }\n const x = u[0];\n const y = u[1];\n const z = u[2];\n const x2 = v[0];\n const y2 = v[1];\n const z2 = v[2];\n dest[0] = y * z2 - z * y2;\n dest[1] = z * x2 - x * z2;\n dest[2] = x * y2 - y * x2;\n return dest;\n },\n\n\n sqLenVec4(v) { // TODO\n return math.dotVec4(v, v);\n },\n\n /**\n * Returns the length of a four-element vector.\n * @method lenVec4\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec4(v) {\n return Math.sqrt(math.sqLenVec4(v));\n },\n\n /**\n * Returns the dot product of two three-element vectors.\n * @method dotVec3\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec3(u, v) {\n return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]);\n },\n\n /**\n * Returns the dot product of two two-element vectors.\n * @method dotVec4\n * @static\n * @param {Array(Number)} u First vector\n * @param {Array(Number)} v Second vector\n * @return The dot product\n */\n dotVec2(u, v) {\n return (u[0] * v[0] + u[1] * v[1]);\n },\n\n\n sqLenVec3(v) {\n return math.dotVec3(v, v);\n },\n\n\n sqLenVec2(v) {\n return math.dotVec2(v, v);\n },\n\n /**\n * Returns the length of a three-element vector.\n * @method lenVec3\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec3(v) {\n return Math.sqrt(math.sqLenVec3(v));\n },\n\n distVec3: ((() => {\n const vec = new FloatArrayType(3);\n return (v, w) => math.lenVec3(math.subVec3(v, w, vec));\n }))(),\n\n /**\n * Returns the length of a two-element vector.\n * @method lenVec2\n * @static\n * @param {Array(Number)} v The vector\n * @return The length\n */\n lenVec2(v) {\n return Math.sqrt(math.sqLenVec2(v));\n },\n\n distVec2: ((() => {\n const vec = new FloatArrayType(2);\n return (v, w) => math.lenVec2(math.subVec2(v, w, vec));\n }))(),\n\n /**\n * @method rcpVec3\n * @static\n * @param v vec3\n * @param dest vec3 - optional destination\n * @return [] dest if specified, v otherwise\n *\n */\n rcpVec3(v, dest) {\n return math.divScalarVec3(1.0, v, dest);\n },\n\n /**\n * Normalizes a four-element vector\n * @method normalizeVec4\n * @static\n * @param v vec4\n * @param dest vec4 - optional destination\n * @return [] dest if specified, v otherwise\n *\n */\n normalizeVec4(v, dest) {\n const f = 1.0 / math.lenVec4(v);\n return math.mulVec4Scalar(v, f, dest);\n },\n\n /**\n * Normalizes a three-element vector\n * @method normalizeVec4\n * @static\n */\n normalizeVec3(v, dest) {\n const f = 1.0 / math.lenVec3(v);\n return math.mulVec3Scalar(v, f, dest);\n },\n\n /**\n * Normalizes a two-element vector\n * @method normalizeVec2\n * @static\n */\n normalizeVec2(v, dest) {\n const f = 1.0 / math.lenVec2(v);\n return math.mulVec2Scalar(v, f, dest);\n },\n\n /**\n * Gets the angle between two vectors\n * @method angleVec3\n * @param v\n * @param w\n * @returns {number}\n */\n angleVec3(v, w) {\n let theta = math.dotVec3(v, w) / (Math.sqrt(math.sqLenVec3(v) * math.sqLenVec3(w)));\n theta = theta < -1 ? -1 : (theta > 1 ? 1 : theta); // Clamp to handle numerical problems\n return Math.acos(theta);\n },\n\n /**\n * Creates a three-element vector from the rotation part of a sixteen-element matrix.\n * @param m\n * @param dest\n */\n vec3FromMat4Scale: ((() => {\n\n const tempVec3 = new FloatArrayType(3);\n\n return (m, dest) => {\n\n tempVec3[0] = m[0];\n tempVec3[1] = m[1];\n tempVec3[2] = m[2];\n\n dest[0] = math.lenVec3(tempVec3);\n\n tempVec3[0] = m[4];\n tempVec3[1] = m[5];\n tempVec3[2] = m[6];\n\n dest[1] = math.lenVec3(tempVec3);\n\n tempVec3[0] = m[8];\n tempVec3[1] = m[9];\n tempVec3[2] = m[10];\n\n dest[2] = math.lenVec3(tempVec3);\n\n return dest;\n };\n }))(),\n\n /**\n * Converts an n-element vector to a JSON-serializable\n * array with values rounded to two decimal places.\n */\n vecToArray: ((() => {\n function trunc(v) {\n return Math.round(v * 100000) / 100000\n }\n\n return v => {\n v = Array.prototype.slice.call(v);\n for (let i = 0, len = v.length; i < len; i++) {\n v[i] = trunc(v[i]);\n }\n return v;\n };\n }))(),\n\n /**\n * Converts a 3-element vector from an array to an object of the form ````{x:999, y:999, z:999}````.\n * @param arr\n * @returns {{x: *, y: *, z: *}}\n */\n xyzArrayToObject(arr) {\n return {\"x\": arr[0], \"y\": arr[1], \"z\": arr[2]};\n },\n\n /**\n * Converts a 3-element vector object of the form ````{x:999, y:999, z:999}```` to an array.\n * @param xyz\n * @param [arry]\n * @returns {*[]}\n */\n xyzObjectToArray(xyz, arry) {\n arry = arry || new FloatArrayType(3);\n arry[0] = xyz.x;\n arry[1] = xyz.y;\n arry[2] = xyz.z;\n return arry;\n },\n\n /**\n * Duplicates a 4x4 identity matrix.\n * @method dupMat4\n * @static\n */\n dupMat4(m) {\n return m.slice(0, 16);\n },\n\n /**\n * Extracts a 3x3 matrix from a 4x4 matrix.\n * @method mat4To3\n * @static\n */\n mat4To3(m) {\n return [\n m[0], m[1], m[2],\n m[4], m[5], m[6],\n m[8], m[9], m[10]\n ];\n },\n\n /**\n * Returns a 4x4 matrix with each element set to the given scalar value.\n * @method m4s\n * @static\n */\n m4s(s) {\n return [\n s, s, s, s,\n s, s, s, s,\n s, s, s, s,\n s, s, s, s\n ];\n },\n\n /**\n * Returns a 4x4 matrix with each element set to zero.\n * @method setMat4ToZeroes\n * @static\n */\n setMat4ToZeroes() {\n return math.m4s(0.0);\n },\n\n /**\n * Returns a 4x4 matrix with each element set to 1.0.\n * @method setMat4ToOnes\n * @static\n */\n setMat4ToOnes() {\n return math.m4s(1.0);\n },\n\n /**\n * Returns a 4x4 matrix with each element set to 1.0.\n * @method setMat4ToOnes\n * @static\n */\n diagonalMat4v(v) {\n return new FloatArrayType([\n v[0], 0.0, 0.0, 0.0,\n 0.0, v[1], 0.0, 0.0,\n 0.0, 0.0, v[2], 0.0,\n 0.0, 0.0, 0.0, v[3]\n ]);\n },\n\n /**\n * Returns a 4x4 matrix with diagonal elements set to the given vector.\n * @method diagonalMat4c\n * @static\n */\n diagonalMat4c(x, y, z, w) {\n return math.diagonalMat4v([x, y, z, w]);\n },\n\n /**\n * Returns a 4x4 matrix with diagonal elements set to the given scalar.\n * @method diagonalMat4s\n * @static\n */\n diagonalMat4s(s) {\n return math.diagonalMat4c(s, s, s, s);\n },\n\n /**\n * Returns a 4x4 identity matrix.\n * @method identityMat4\n * @static\n */\n identityMat4(mat = new FloatArrayType(16)) {\n mat[0] = 1.0;\n mat[1] = 0.0;\n mat[2] = 0.0;\n mat[3] = 0.0;\n\n mat[4] = 0.0;\n mat[5] = 1.0;\n mat[6] = 0.0;\n mat[7] = 0.0;\n\n mat[8] = 0.0;\n mat[9] = 0.0;\n mat[10] = 1.0;\n mat[11] = 0.0;\n\n mat[12] = 0.0;\n mat[13] = 0.0;\n mat[14] = 0.0;\n mat[15] = 1.0;\n\n return mat;\n },\n\n /**\n * Returns a 3x3 identity matrix.\n * @method identityMat3\n * @static\n */\n identityMat3(mat = new FloatArrayType(9)) {\n mat[0] = 1.0;\n mat[1] = 0.0;\n mat[2] = 0.0;\n\n mat[3] = 0.0;\n mat[4] = 1.0;\n mat[5] = 0.0;\n\n mat[6] = 0.0;\n mat[7] = 0.0;\n mat[8] = 1.0;\n\n return mat;\n },\n\n /**\n * Tests if the given 4x4 matrix is the identity matrix.\n * @method isIdentityMat4\n * @static\n */\n isIdentityMat4(m) {\n if (m[0] !== 1.0 || m[1] !== 0.0 || m[2] !== 0.0 || m[3] !== 0.0 ||\n m[4] !== 0.0 || m[5] !== 1.0 || m[6] !== 0.0 || m[7] !== 0.0 ||\n m[8] !== 0.0 || m[9] !== 0.0 || m[10] !== 1.0 || m[11] !== 0.0 ||\n m[12] !== 0.0 || m[13] !== 0.0 || m[14] !== 0.0 || m[15] !== 1.0) {\n return false;\n }\n return true;\n },\n\n /**\n * Negates the given 4x4 matrix.\n * @method negateMat4\n * @static\n */\n negateMat4(m, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = -m[0];\n dest[1] = -m[1];\n dest[2] = -m[2];\n dest[3] = -m[3];\n dest[4] = -m[4];\n dest[5] = -m[5];\n dest[6] = -m[6];\n dest[7] = -m[7];\n dest[8] = -m[8];\n dest[9] = -m[9];\n dest[10] = -m[10];\n dest[11] = -m[11];\n dest[12] = -m[12];\n dest[13] = -m[13];\n dest[14] = -m[14];\n dest[15] = -m[15];\n return dest;\n },\n\n /**\n * Adds the given 4x4 matrices together.\n * @method addMat4\n * @static\n */\n addMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n dest[0] = a[0] + b[0];\n dest[1] = a[1] + b[1];\n dest[2] = a[2] + b[2];\n dest[3] = a[3] + b[3];\n dest[4] = a[4] + b[4];\n dest[5] = a[5] + b[5];\n dest[6] = a[6] + b[6];\n dest[7] = a[7] + b[7];\n dest[8] = a[8] + b[8];\n dest[9] = a[9] + b[9];\n dest[10] = a[10] + b[10];\n dest[11] = a[11] + b[11];\n dest[12] = a[12] + b[12];\n dest[13] = a[13] + b[13];\n dest[14] = a[14] + b[14];\n dest[15] = a[15] + b[15];\n return dest;\n },\n\n /**\n * Adds the given scalar to each element of the given 4x4 matrix.\n * @method addMat4Scalar\n * @static\n */\n addMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] + s;\n dest[1] = m[1] + s;\n dest[2] = m[2] + s;\n dest[3] = m[3] + s;\n dest[4] = m[4] + s;\n dest[5] = m[5] + s;\n dest[6] = m[6] + s;\n dest[7] = m[7] + s;\n dest[8] = m[8] + s;\n dest[9] = m[9] + s;\n dest[10] = m[10] + s;\n dest[11] = m[11] + s;\n dest[12] = m[12] + s;\n dest[13] = m[13] + s;\n dest[14] = m[14] + s;\n dest[15] = m[15] + s;\n return dest;\n },\n\n /**\n * Adds the given scalar to each element of the given 4x4 matrix.\n * @method addScalarMat4\n * @static\n */\n addScalarMat4(s, m, dest) {\n return math.addMat4Scalar(m, s, dest);\n },\n\n /**\n * Subtracts the second 4x4 matrix from the first.\n * @method subMat4\n * @static\n */\n subMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n dest[0] = a[0] - b[0];\n dest[1] = a[1] - b[1];\n dest[2] = a[2] - b[2];\n dest[3] = a[3] - b[3];\n dest[4] = a[4] - b[4];\n dest[5] = a[5] - b[5];\n dest[6] = a[6] - b[6];\n dest[7] = a[7] - b[7];\n dest[8] = a[8] - b[8];\n dest[9] = a[9] - b[9];\n dest[10] = a[10] - b[10];\n dest[11] = a[11] - b[11];\n dest[12] = a[12] - b[12];\n dest[13] = a[13] - b[13];\n dest[14] = a[14] - b[14];\n dest[15] = a[15] - b[15];\n return dest;\n },\n\n /**\n * Subtracts the given scalar from each element of the given 4x4 matrix.\n * @method subMat4Scalar\n * @static\n */\n subMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] - s;\n dest[1] = m[1] - s;\n dest[2] = m[2] - s;\n dest[3] = m[3] - s;\n dest[4] = m[4] - s;\n dest[5] = m[5] - s;\n dest[6] = m[6] - s;\n dest[7] = m[7] - s;\n dest[8] = m[8] - s;\n dest[9] = m[9] - s;\n dest[10] = m[10] - s;\n dest[11] = m[11] - s;\n dest[12] = m[12] - s;\n dest[13] = m[13] - s;\n dest[14] = m[14] - s;\n dest[15] = m[15] - s;\n return dest;\n },\n\n /**\n * Subtracts the given scalar from each element of the given 4x4 matrix.\n * @method subScalarMat4\n * @static\n */\n subScalarMat4(s, m, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = s - m[0];\n dest[1] = s - m[1];\n dest[2] = s - m[2];\n dest[3] = s - m[3];\n dest[4] = s - m[4];\n dest[5] = s - m[5];\n dest[6] = s - m[6];\n dest[7] = s - m[7];\n dest[8] = s - m[8];\n dest[9] = s - m[9];\n dest[10] = s - m[10];\n dest[11] = s - m[11];\n dest[12] = s - m[12];\n dest[13] = s - m[13];\n dest[14] = s - m[14];\n dest[15] = s - m[15];\n return dest;\n },\n\n /**\n * Multiplies the two given 4x4 matrix by each other.\n * @method mulMat4\n * @static\n */\n mulMat4(a, b, dest) {\n if (!dest) {\n dest = a;\n }\n\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = a[0];\n\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n const b00 = b[0];\n const b01 = b[1];\n const b02 = b[2];\n const b03 = b[3];\n const b10 = b[4];\n const b11 = b[5];\n const b12 = b[6];\n const b13 = b[7];\n const b20 = b[8];\n const b21 = b[9];\n const b22 = b[10];\n const b23 = b[11];\n const b30 = b[12];\n const b31 = b[13];\n const b32 = b[14];\n const b33 = b[15];\n\n dest[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;\n dest[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;\n dest[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;\n dest[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;\n dest[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;\n dest[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;\n dest[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;\n dest[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;\n dest[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;\n dest[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;\n dest[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;\n dest[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;\n dest[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;\n dest[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;\n dest[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;\n dest[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;\n\n return dest;\n },\n\n /**\n * Multiplies the two given 3x3 matrices by each other.\n * @method mulMat4\n * @static\n */\n mulMat3(a, b, dest) {\n if (!dest) {\n dest = new FloatArrayType(9);\n }\n\n const a11 = a[0];\n const a12 = a[3];\n const a13 = a[6];\n const a21 = a[1];\n const a22 = a[4];\n const a23 = a[7];\n const a31 = a[2];\n const a32 = a[5];\n const a33 = a[8];\n const b11 = b[0];\n const b12 = b[3];\n const b13 = b[6];\n const b21 = b[1];\n const b22 = b[4];\n const b23 = b[7];\n const b31 = b[2];\n const b32 = b[5];\n const b33 = b[8];\n\n dest[0] = a11 * b11 + a12 * b21 + a13 * b31;\n dest[3] = a11 * b12 + a12 * b22 + a13 * b32;\n dest[6] = a11 * b13 + a12 * b23 + a13 * b33;\n\n dest[1] = a21 * b11 + a22 * b21 + a23 * b31;\n dest[4] = a21 * b12 + a22 * b22 + a23 * b32;\n dest[7] = a21 * b13 + a22 * b23 + a23 * b33;\n\n dest[2] = a31 * b11 + a32 * b21 + a33 * b31;\n dest[5] = a31 * b12 + a32 * b22 + a33 * b32;\n dest[8] = a31 * b13 + a32 * b23 + a33 * b33;\n\n return dest;\n },\n\n /**\n * Multiplies each element of the given 4x4 matrix by the given scalar.\n * @method mulMat4Scalar\n * @static\n */\n mulMat4Scalar(m, s, dest) {\n if (!dest) {\n dest = m;\n }\n dest[0] = m[0] * s;\n dest[1] = m[1] * s;\n dest[2] = m[2] * s;\n dest[3] = m[3] * s;\n dest[4] = m[4] * s;\n dest[5] = m[5] * s;\n dest[6] = m[6] * s;\n dest[7] = m[7] * s;\n dest[8] = m[8] * s;\n dest[9] = m[9] * s;\n dest[10] = m[10] * s;\n dest[11] = m[11] * s;\n dest[12] = m[12] * s;\n dest[13] = m[13] * s;\n dest[14] = m[14] * s;\n dest[15] = m[15] * s;\n return dest;\n },\n\n /**\n * Multiplies the given 4x4 matrix by the given four-element vector.\n * @method mulMat4v4\n * @static\n */\n mulMat4v4(m, v, dest = math.vec4()) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n const v3 = v[3];\n dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3;\n dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3;\n dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3;\n dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3;\n return dest;\n },\n\n /**\n * Transposes the given 4x4 matrix.\n * @method transposeMat4\n * @static\n */\n transposeMat4(mat, dest) {\n // If we are transposing ourselves we can skip a few steps but have to cache some values\n const m4 = mat[4];\n\n const m14 = mat[14];\n const m8 = mat[8];\n const m13 = mat[13];\n const m12 = mat[12];\n const m9 = mat[9];\n if (!dest || mat === dest) {\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a12 = mat[6];\n const a13 = mat[7];\n const a23 = mat[11];\n mat[1] = m4;\n mat[2] = m8;\n mat[3] = m12;\n mat[4] = a01;\n mat[6] = m9;\n mat[7] = m13;\n mat[8] = a02;\n mat[9] = a12;\n mat[11] = m14;\n mat[12] = a03;\n mat[13] = a13;\n mat[14] = a23;\n return mat;\n }\n dest[0] = mat[0];\n dest[1] = m4;\n dest[2] = m8;\n dest[3] = m12;\n dest[4] = mat[1];\n dest[5] = mat[5];\n dest[6] = m9;\n dest[7] = m13;\n dest[8] = mat[2];\n dest[9] = mat[6];\n dest[10] = mat[10];\n dest[11] = m14;\n dest[12] = mat[3];\n dest[13] = mat[7];\n dest[14] = mat[11];\n dest[15] = mat[15];\n return dest;\n },\n\n /**\n * Transposes the given 3x3 matrix.\n *\n * @method transposeMat3\n * @static\n */\n transposeMat3(mat, dest) {\n if (dest === mat) {\n const a01 = mat[1];\n const a02 = mat[2];\n const a12 = mat[5];\n dest[1] = mat[3];\n dest[2] = mat[6];\n dest[3] = a01;\n dest[5] = mat[7];\n dest[6] = a02;\n dest[7] = a12;\n } else {\n dest[0] = mat[0];\n dest[1] = mat[3];\n dest[2] = mat[6];\n dest[3] = mat[1];\n dest[4] = mat[4];\n dest[5] = mat[7];\n dest[6] = mat[2];\n dest[7] = mat[5];\n dest[8] = mat[8];\n }\n return dest;\n },\n\n /**\n * Returns the determinant of the given 4x4 matrix.\n * @method determinantMat4\n * @static\n */\n determinantMat4(mat) {\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = mat[0];\n\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a10 = mat[4];\n const a11 = mat[5];\n const a12 = mat[6];\n const a13 = mat[7];\n const a20 = mat[8];\n const a21 = mat[9];\n const a22 = mat[10];\n const a23 = mat[11];\n const a30 = mat[12];\n const a31 = mat[13];\n const a32 = mat[14];\n const a33 = mat[15];\n return a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 +\n a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 +\n a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 +\n a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 +\n a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 +\n a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33;\n },\n\n /**\n * Returns the inverse of the given 4x4 matrix.\n * @method inverseMat4\n * @static\n */\n inverseMat4(mat, dest) {\n if (!dest) {\n dest = mat;\n }\n\n // Cache the matrix values (makes for huge speed increases!)\n const a00 = mat[0];\n\n const a01 = mat[1];\n const a02 = mat[2];\n const a03 = mat[3];\n const a10 = mat[4];\n const a11 = mat[5];\n const a12 = mat[6];\n const a13 = mat[7];\n const a20 = mat[8];\n const a21 = mat[9];\n const a22 = mat[10];\n const a23 = mat[11];\n const a30 = mat[12];\n const a31 = mat[13];\n const a32 = mat[14];\n const a33 = mat[15];\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant (inlined to avoid double-caching)\n const invDet = 1 / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06);\n\n dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;\n dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;\n dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;\n dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;\n dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;\n dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;\n dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;\n dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;\n dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;\n dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;\n dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;\n dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;\n dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;\n dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;\n dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;\n dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;\n\n return dest;\n },\n\n /**\n * Returns the trace of the given 4x4 matrix.\n * @method traceMat4\n * @static\n */\n traceMat4(m) {\n return (m[0] + m[5] + m[10] + m[15]);\n },\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4\n * @static\n */\n translationMat4v(v, dest) {\n const m = dest || math.identityMat4();\n m[12] = v[0];\n m[13] = v[1];\n m[14] = v[2];\n return m;\n },\n\n /**\n * Returns 3x3 translation matrix.\n * @method translationMat3\n * @static\n */\n translationMat3v(v, dest) {\n const m = dest || math.identityMat3();\n m[6] = v[0];\n m[7] = v[1];\n return m;\n },\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4c\n * @static\n */\n translationMat4c: ((() => {\n const xyz = new FloatArrayType(3);\n return (x, y, z, dest) => {\n xyz[0] = x;\n xyz[1] = y;\n xyz[2] = z;\n return math.translationMat4v(xyz, dest);\n };\n }))(),\n\n /**\n * Returns 4x4 translation matrix.\n * @method translationMat4s\n * @static\n */\n translationMat4s(s, dest) {\n return math.translationMat4c(s, s, s, dest);\n },\n\n /**\n * Efficiently post-concatenates a translation to the given matrix.\n * @param v\n * @param m\n */\n translateMat4v(xyz, m) {\n return math.translateMat4c(xyz[0], xyz[1], xyz[2], m);\n },\n\n /**\n * Efficiently post-concatenates a translation to the given matrix.\n * @param x\n * @param y\n * @param z\n * @param m\n */\n OLDtranslateMat4c(x, y, z, m) {\n\n const m12 = m[12];\n m[0] += m12 * x;\n m[4] += m12 * y;\n m[8] += m12 * z;\n\n const m13 = m[13];\n m[1] += m13 * x;\n m[5] += m13 * y;\n m[9] += m13 * z;\n\n const m14 = m[14];\n m[2] += m14 * x;\n m[6] += m14 * y;\n m[10] += m14 * z;\n\n const m15 = m[15];\n m[3] += m15 * x;\n m[7] += m15 * y;\n m[11] += m15 * z;\n\n return m;\n },\n\n translateMat4c(x, y, z, m) {\n\n const m3 = m[3];\n m[0] += m3 * x;\n m[1] += m3 * y;\n m[2] += m3 * z;\n\n const m7 = m[7];\n m[4] += m7 * x;\n m[5] += m7 * y;\n m[6] += m7 * z;\n\n const m11 = m[11];\n m[8] += m11 * x;\n m[9] += m11 * y;\n m[10] += m11 * z;\n\n const m15 = m[15];\n m[12] += m15 * x;\n m[13] += m15 * y;\n m[14] += m15 * z;\n\n return m;\n },\n /**\n * Returns 4x4 rotation matrix.\n * @method rotationMat4v\n * @static\n */\n rotationMat4v(anglerad, axis, m) {\n const ax = math.normalizeVec4([axis[0], axis[1], axis[2], 0.0], []);\n const s = Math.sin(anglerad);\n const c = Math.cos(anglerad);\n const q = 1.0 - c;\n\n const x = ax[0];\n const y = ax[1];\n const z = ax[2];\n\n let xy;\n let yz;\n let zx;\n let xs;\n let ys;\n let zs;\n\n //xx = x * x; used once\n //yy = y * y; used once\n //zz = z * z; used once\n xy = x * y;\n yz = y * z;\n zx = z * x;\n xs = x * s;\n ys = y * s;\n zs = z * s;\n\n m = m || math.mat4();\n\n m[0] = (q * x * x) + c;\n m[1] = (q * xy) + zs;\n m[2] = (q * zx) - ys;\n m[3] = 0.0;\n\n m[4] = (q * xy) - zs;\n m[5] = (q * y * y) + c;\n m[6] = (q * yz) + xs;\n m[7] = 0.0;\n\n m[8] = (q * zx) + ys;\n m[9] = (q * yz) - xs;\n m[10] = (q * z * z) + c;\n m[11] = 0.0;\n\n m[12] = 0.0;\n m[13] = 0.0;\n m[14] = 0.0;\n m[15] = 1.0;\n\n return m;\n },\n\n /**\n * Returns 4x4 rotation matrix.\n * @method rotationMat4c\n * @static\n */\n rotationMat4c(anglerad, x, y, z, mat) {\n return math.rotationMat4v(anglerad, [x, y, z], mat);\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4v\n * @static\n */\n scalingMat4v(v, m = math.identityMat4()) {\n m[0] = v[0];\n m[5] = v[1];\n m[10] = v[2];\n return m;\n },\n\n /**\n * Returns 3x3 scale matrix.\n * @method scalingMat3v\n * @static\n */\n scalingMat3v(v, m = math.identityMat3()) {\n m[0] = v[0];\n m[4] = v[1];\n return m;\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4c\n * @static\n */\n scalingMat4c: ((() => {\n const xyz = new FloatArrayType(3);\n return (x, y, z, dest) => {\n xyz[0] = x;\n xyz[1] = y;\n xyz[2] = z;\n return math.scalingMat4v(xyz, dest);\n };\n }))(),\n\n /**\n * Efficiently post-concatenates a scaling to the given matrix.\n * @method scaleMat4c\n * @param x\n * @param y\n * @param z\n * @param m\n */\n scaleMat4c(x, y, z, m) {\n\n m[0] *= x;\n m[4] *= y;\n m[8] *= z;\n\n m[1] *= x;\n m[5] *= y;\n m[9] *= z;\n\n m[2] *= x;\n m[6] *= y;\n m[10] *= z;\n\n m[3] *= x;\n m[7] *= y;\n m[11] *= z;\n return m;\n },\n\n /**\n * Efficiently post-concatenates a scaling to the given matrix.\n * @method scaleMat4c\n * @param xyz\n * @param m\n */\n scaleMat4v(xyz, m) {\n\n const x = xyz[0];\n const y = xyz[1];\n const z = xyz[2];\n\n m[0] *= x;\n m[4] *= y;\n m[8] *= z;\n m[1] *= x;\n m[5] *= y;\n m[9] *= z;\n m[2] *= x;\n m[6] *= y;\n m[10] *= z;\n m[3] *= x;\n m[7] *= y;\n m[11] *= z;\n\n return m;\n },\n\n /**\n * Returns 4x4 scale matrix.\n * @method scalingMat4s\n * @static\n */\n scalingMat4s(s) {\n return math.scalingMat4c(s, s, s);\n },\n\n /**\n * Creates a matrix from a quaternion rotation and vector translation\n *\n * @param {Number[]} q Rotation quaternion\n * @param {Number[]} v Translation vector\n * @param {Number[]} dest Destination matrix\n * @returns {Number[]} dest\n */\n rotationTranslationMat4(q, v, dest = math.mat4()) {\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n dest[0] = 1 - (yy + zz);\n dest[1] = xy + wz;\n dest[2] = xz - wy;\n dest[3] = 0;\n dest[4] = xy - wz;\n dest[5] = 1 - (xx + zz);\n dest[6] = yz + wx;\n dest[7] = 0;\n dest[8] = xz + wy;\n dest[9] = yz - wx;\n dest[10] = 1 - (xx + yy);\n dest[11] = 0;\n dest[12] = v[0];\n dest[13] = v[1];\n dest[14] = v[2];\n dest[15] = 1;\n\n return dest;\n },\n\n /**\n * Gets Euler angles from a 4x4 matrix.\n *\n * @param {Number[]} mat The 4x4 matrix.\n * @param {String} order Desired Euler angle order: \"XYZ\", \"YXZ\", \"ZXY\" etc.\n * @param {Number[]} [dest] Destination Euler angles, created by default.\n * @returns {Number[]} The Euler angles.\n */\n mat4ToEuler(mat, order, dest = math.vec4()) {\n const clamp = math.clamp;\n\n // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n const m11 = mat[0];\n\n const m12 = mat[4];\n const m13 = mat[8];\n const m21 = mat[1];\n const m22 = mat[5];\n const m23 = mat[9];\n const m31 = mat[2];\n const m32 = mat[6];\n const m33 = mat[10];\n\n if (order === 'XYZ') {\n\n dest[1] = Math.asin(clamp(m13, -1, 1));\n\n if (Math.abs(m13) < 0.99999) {\n dest[0] = Math.atan2(-m23, m33);\n dest[2] = Math.atan2(-m12, m11);\n } else {\n dest[0] = Math.atan2(m32, m22);\n dest[2] = 0;\n\n }\n\n } else if (order === 'YXZ') {\n\n dest[0] = Math.asin(-clamp(m23, -1, 1));\n\n if (Math.abs(m23) < 0.99999) {\n dest[1] = Math.atan2(m13, m33);\n dest[2] = Math.atan2(m21, m22);\n } else {\n dest[1] = Math.atan2(-m31, m11);\n dest[2] = 0;\n }\n\n } else if (order === 'ZXY') {\n\n dest[0] = Math.asin(clamp(m32, -1, 1));\n\n if (Math.abs(m32) < 0.99999) {\n dest[1] = Math.atan2(-m31, m33);\n dest[2] = Math.atan2(-m12, m22);\n } else {\n dest[1] = 0;\n dest[2] = Math.atan2(m21, m11);\n }\n\n } else if (order === 'ZYX') {\n\n dest[1] = Math.asin(-clamp(m31, -1, 1));\n\n if (Math.abs(m31) < 0.99999) {\n dest[0] = Math.atan2(m32, m33);\n dest[2] = Math.atan2(m21, m11);\n } else {\n dest[0] = 0;\n dest[2] = Math.atan2(-m12, m22);\n }\n\n } else if (order === 'YZX') {\n\n dest[2] = Math.asin(clamp(m21, -1, 1));\n\n if (Math.abs(m21) < 0.99999) {\n dest[0] = Math.atan2(-m23, m22);\n dest[1] = Math.atan2(-m31, m11);\n } else {\n dest[0] = 0;\n dest[1] = Math.atan2(m13, m33);\n }\n\n } else if (order === 'XZY') {\n\n dest[2] = Math.asin(-clamp(m12, -1, 1));\n\n if (Math.abs(m12) < 0.99999) {\n dest[0] = Math.atan2(m32, m22);\n dest[1] = Math.atan2(m13, m11);\n } else {\n dest[0] = Math.atan2(-m23, m33);\n dest[1] = 0;\n }\n }\n\n return dest;\n },\n\n composeMat4(position, quaternion, scale, mat = math.mat4()) {\n math.quaternionToRotationMat4(quaternion, mat);\n math.scaleMat4v(scale, mat);\n math.translateMat4v(position, mat);\n\n return mat;\n },\n\n decomposeMat4: (() => {\n\n const vec = new FloatArrayType(3);\n const matrix = new FloatArrayType(16);\n\n return function decompose(mat, position, quaternion, scale) {\n\n vec[0] = mat[0];\n vec[1] = mat[1];\n vec[2] = mat[2];\n\n let sx = math.lenVec3(vec);\n\n vec[0] = mat[4];\n vec[1] = mat[5];\n vec[2] = mat[6];\n\n const sy = math.lenVec3(vec);\n\n vec[8] = mat[8];\n vec[9] = mat[9];\n vec[10] = mat[10];\n\n const sz = math.lenVec3(vec);\n\n // if determine is negative, we need to invert one scale\n const det = math.determinantMat4(mat);\n\n if (det < 0) {\n sx = -sx;\n }\n\n position[0] = mat[12];\n position[1] = mat[13];\n position[2] = mat[14];\n\n // scale the rotation part\n matrix.set(mat);\n\n const invSX = 1 / sx;\n const invSY = 1 / sy;\n const invSZ = 1 / sz;\n\n matrix[0] *= invSX;\n matrix[1] *= invSX;\n matrix[2] *= invSX;\n\n matrix[4] *= invSY;\n matrix[5] *= invSY;\n matrix[6] *= invSY;\n\n matrix[8] *= invSZ;\n matrix[9] *= invSZ;\n matrix[10] *= invSZ;\n\n math.mat4ToQuaternion(matrix, quaternion);\n\n scale[0] = sx;\n scale[1] = sy;\n scale[2] = sz;\n\n return this;\n\n };\n\n })(),\n\n /**\n * Returns a 4x4 'lookat' viewing transform matrix.\n * @method lookAtMat4v\n * @param pos vec3 position of the viewer\n * @param target vec3 point the viewer is looking at\n * @param up vec3 pointing \"up\"\n * @param dest mat4 Optional, mat4 matrix will be written into\n *\n * @return {mat4} dest if specified, a new mat4 otherwise\n */\n lookAtMat4v(pos, target, up, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n\n const posx = pos[0];\n const posy = pos[1];\n const posz = pos[2];\n const upx = up[0];\n const upy = up[1];\n const upz = up[2];\n const targetx = target[0];\n const targety = target[1];\n const targetz = target[2];\n\n if (posx === targetx && posy === targety && posz === targetz) {\n return math.identityMat4();\n }\n\n let z0;\n let z1;\n let z2;\n let x0;\n let x1;\n let x2;\n let y0;\n let y1;\n let y2;\n let len;\n\n //vec3.direction(eye, center, z);\n z0 = posx - targetx;\n z1 = posy - targety;\n z2 = posz - targetz;\n\n // normalize (no check needed for 0 because of early return)\n len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);\n z0 *= len;\n z1 *= len;\n z2 *= len;\n\n //vec3.normalize(vec3.cross(up, z, x));\n x0 = upy * z2 - upz * z1;\n x1 = upz * z0 - upx * z2;\n x2 = upx * z1 - upy * z0;\n len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);\n if (!len) {\n x0 = 0;\n x1 = 0;\n x2 = 0;\n } else {\n len = 1 / len;\n x0 *= len;\n x1 *= len;\n x2 *= len;\n }\n\n //vec3.normalize(vec3.cross(z, x, y));\n y0 = z1 * x2 - z2 * x1;\n y1 = z2 * x0 - z0 * x2;\n y2 = z0 * x1 - z1 * x0;\n\n len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);\n if (!len) {\n y0 = 0;\n y1 = 0;\n y2 = 0;\n } else {\n len = 1 / len;\n y0 *= len;\n y1 *= len;\n y2 *= len;\n }\n\n dest[0] = x0;\n dest[1] = y0;\n dest[2] = z0;\n dest[3] = 0;\n dest[4] = x1;\n dest[5] = y1;\n dest[6] = z1;\n dest[7] = 0;\n dest[8] = x2;\n dest[9] = y2;\n dest[10] = z2;\n dest[11] = 0;\n dest[12] = -(x0 * posx + x1 * posy + x2 * posz);\n dest[13] = -(y0 * posx + y1 * posy + y2 * posz);\n dest[14] = -(z0 * posx + z1 * posy + z2 * posz);\n dest[15] = 1;\n\n return dest;\n },\n\n /**\n * Returns a 4x4 'lookat' viewing transform matrix.\n * @method lookAtMat4c\n * @static\n */\n lookAtMat4c(posx, posy, posz, targetx, targety, targetz, upx, upy, upz) {\n return math.lookAtMat4v([posx, posy, posz], [targetx, targety, targetz], [upx, upy, upz], []);\n },\n\n /**\n * Returns a 4x4 orthographic projection matrix.\n * @method orthoMat4c\n * @static\n */\n orthoMat4c(left, right, bottom, top, near, far, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n const rl = (right - left);\n const tb = (top - bottom);\n const fn = (far - near);\n\n dest[0] = 2.0 / rl;\n dest[1] = 0.0;\n dest[2] = 0.0;\n dest[3] = 0.0;\n\n dest[4] = 0.0;\n dest[5] = 2.0 / tb;\n dest[6] = 0.0;\n dest[7] = 0.0;\n\n dest[8] = 0.0;\n dest[9] = 0.0;\n dest[10] = -2.0 / fn;\n dest[11] = 0.0;\n\n dest[12] = -(left + right) / rl;\n dest[13] = -(top + bottom) / tb;\n dest[14] = -(far + near) / fn;\n dest[15] = 1.0;\n\n return dest;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method frustumMat4v\n * @static\n */\n frustumMat4v(fmin, fmax, m) {\n if (!m) {\n m = math.mat4();\n }\n\n const fmin4 = [fmin[0], fmin[1], fmin[2], 0.0];\n const fmax4 = [fmax[0], fmax[1], fmax[2], 0.0];\n\n math.addVec4(fmax4, fmin4, tempMat1);\n math.subVec4(fmax4, fmin4, tempMat2);\n\n const t = 2.0 * fmin4[2];\n\n const tempMat20 = tempMat2[0];\n const tempMat21 = tempMat2[1];\n const tempMat22 = tempMat2[2];\n\n m[0] = t / tempMat20;\n m[1] = 0.0;\n m[2] = 0.0;\n m[3] = 0.0;\n\n m[4] = 0.0;\n m[5] = t / tempMat21;\n m[6] = 0.0;\n m[7] = 0.0;\n\n m[8] = tempMat1[0] / tempMat20;\n m[9] = tempMat1[1] / tempMat21;\n m[10] = -tempMat1[2] / tempMat22;\n m[11] = -1.0;\n\n m[12] = 0.0;\n m[13] = 0.0;\n m[14] = -t * fmax4[2] / tempMat22;\n m[15] = 0.0;\n\n return m;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method frustumMat4v\n * @static\n */\n frustumMat4(left, right, bottom, top, near, far, dest) {\n if (!dest) {\n dest = math.mat4();\n }\n const rl = (right - left);\n const tb = (top - bottom);\n const fn = (far - near);\n dest[0] = (near * 2) / rl;\n dest[1] = 0;\n dest[2] = 0;\n dest[3] = 0;\n dest[4] = 0;\n dest[5] = (near * 2) / tb;\n dest[6] = 0;\n dest[7] = 0;\n dest[8] = (right + left) / rl;\n dest[9] = (top + bottom) / tb;\n dest[10] = -(far + near) / fn;\n dest[11] = -1;\n dest[12] = 0;\n dest[13] = 0;\n dest[14] = -(far * near * 2) / fn;\n dest[15] = 0;\n return dest;\n },\n\n /**\n * Returns a 4x4 perspective projection matrix.\n * @method perspectiveMat4v\n * @static\n */\n perspectiveMat4(fovyrad, aspectratio, znear, zfar, m) {\n const pmin = [];\n const pmax = [];\n\n pmin[2] = znear;\n pmax[2] = zfar;\n\n pmax[1] = pmin[2] * Math.tan(fovyrad / 2.0);\n pmin[1] = -pmax[1];\n\n pmax[0] = pmax[1] * aspectratio;\n pmin[0] = -pmax[0];\n\n return math.frustumMat4v(pmin, pmax, m);\n },\n\n /**\n * Transforms a three-element position by a 4x4 matrix.\n * @method transformPoint3\n * @static\n */\n transformPoint3(m, p, dest = math.vec3()) {\n\n const x = p[0];\n const y = p[1];\n const z = p[2];\n\n dest[0] = (m[0] * x) + (m[4] * y) + (m[8] * z) + m[12];\n dest[1] = (m[1] * x) + (m[5] * y) + (m[9] * z) + m[13];\n dest[2] = (m[2] * x) + (m[6] * y) + (m[10] * z) + m[14];\n\n return dest;\n },\n\n /**\n * Transforms a homogeneous coordinate by a 4x4 matrix.\n * @method transformPoint3\n * @static\n */\n transformPoint4(m, v, dest = math.vec4()) {\n dest[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];\n dest[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];\n dest[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];\n dest[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];\n\n return dest;\n },\n\n\n /**\n * Transforms an array of three-element positions by a 4x4 matrix.\n * @method transformPoints3\n * @static\n */\n transformPoints3(m, points, points2) {\n const result = points2 || [];\n const len = points.length;\n let p0;\n let p1;\n let p2;\n let pi;\n\n // cache values\n const m0 = m[0];\n\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n let r;\n\n for (let i = 0; i < len; ++i) {\n\n // cache values\n pi = points[i];\n\n p0 = pi[0];\n p1 = pi[1];\n p2 = pi[2];\n\n r = result[i] || (result[i] = [0, 0, 0]);\n\n r[0] = (m0 * p0) + (m4 * p1) + (m8 * p2) + m12;\n r[1] = (m1 * p0) + (m5 * p1) + (m9 * p2) + m13;\n r[2] = (m2 * p0) + (m6 * p1) + (m10 * p2) + m14;\n r[3] = (m3 * p0) + (m7 * p1) + (m11 * p2) + m15;\n }\n\n result.length = len;\n\n return result;\n },\n\n /**\n * Transforms an array of positions by a 4x4 matrix.\n * @method transformPositions3\n * @static\n */\n transformPositions3(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 3) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /**\n * Transforms an array of positions by a 4x4 matrix.\n * @method transformPositions4\n * @static\n */\n transformPositions4(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 4) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /**\n * Transforms a three-element vector by a 4x4 matrix.\n * @method transformVec3\n * @static\n */\n transformVec3(m, v, dest) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n dest = dest || this.vec3();\n dest[0] = (m[0] * v0) + (m[4] * v1) + (m[8] * v2);\n dest[1] = (m[1] * v0) + (m[5] * v1) + (m[9] * v2);\n dest[2] = (m[2] * v0) + (m[6] * v1) + (m[10] * v2);\n return dest;\n },\n\n /**\n * Transforms a four-element vector by a 4x4 matrix.\n * @method transformVec4\n * @static\n */\n transformVec4(m, v, dest) {\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n const v3 = v[3];\n dest = dest || math.vec4();\n dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3;\n dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3;\n dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3;\n dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3;\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the x-axis\n *\n * @method rotateVec3X\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3X(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[0];\n r[1] = p[1] * Math.cos(c) - p[2] * Math.sin(c);\n r[2] = p[1] * Math.sin(c) + p[2] * Math.cos(c);\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the y-axis\n *\n * @method rotateVec3Y\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3Y(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c);\n r[1] = p[1];\n r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c);\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Rotate a 3D vector around the z-axis\n *\n * @method rotateVec3Z\n * @param {Number[]} a The vec3 point to rotate\n * @param {Number[]} b The origin of the rotation\n * @param {Number} c The angle of rotation\n * @param {Number[]} dest The receiving vec3\n * @returns {Number[]} dest\n * @static\n */\n rotateVec3Z(a, b, c, dest) {\n const p = [];\n const r = [];\n\n //Translate point to the origin\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2];\n\n //perform rotation\n r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c);\n r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c);\n r[2] = p[2];\n\n //translate to correct position\n dest[0] = r[0] + b[0];\n dest[1] = r[1] + b[1];\n dest[2] = r[2] + b[2];\n\n return dest;\n },\n\n /**\n * Transforms a four-element vector by a 4x4 projection matrix.\n *\n * @method projectVec4\n * @param {Number[]} p 3D View-space coordinate\n * @param {Number[]} q 2D Projected coordinate\n * @returns {Number[]} 2D Projected coordinate\n * @static\n */\n projectVec4(p, q) {\n const f = 1.0 / p[3];\n q = q || math.vec2();\n q[0] = v[0] * f;\n q[1] = v[1] * f;\n return q;\n },\n\n /**\n * Unprojects a three-element vector.\n *\n * @method unprojectVec3\n * @param {Number[]} p 3D Projected coordinate\n * @param {Number[]} viewMat View matrix\n * @returns {Number[]} projMat Projection matrix\n * @static\n */\n unprojectVec3: ((() => {\n const mat = new FloatArrayType(16);\n const mat2 = new FloatArrayType(16);\n const mat3 = new FloatArrayType(16);\n return function (p, viewMat, projMat, q) {\n return this.transformVec3(this.mulMat4(this.inverseMat4(viewMat, mat), this.inverseMat4(projMat, mat2), mat3), p, q)\n };\n }))(),\n\n /**\n * Linearly interpolates between two 3D vectors.\n * @method lerpVec3\n * @static\n */\n lerpVec3(t, t1, t2, p1, p2, dest) {\n const result = dest || math.vec3();\n const f = (t - t1) / (t2 - t1);\n result[0] = p1[0] + (f * (p2[0] - p1[0]));\n result[1] = p1[1] + (f * (p2[1] - p1[1]));\n result[2] = p1[2] + (f * (p2[2] - p1[2]));\n return result;\n },\n\n\n /**\n * Flattens a two-dimensional array into a one-dimensional array.\n *\n * @method flatten\n * @static\n * @param {Array of Arrays} a A 2D array\n * @returns Flattened 1D array\n */\n flatten(a) {\n\n const result = [];\n\n let i;\n let leni;\n let j;\n let lenj;\n let item;\n\n for (i = 0, leni = a.length; i < leni; i++) {\n item = a[i];\n for (j = 0, lenj = item.length; j < lenj; j++) {\n result.push(item[j]);\n }\n }\n\n return result;\n },\n\n\n identityQuaternion(dest = math.vec4()) {\n dest[0] = 0.0;\n dest[1] = 0.0;\n dest[2] = 0.0;\n dest[3] = 1.0;\n return dest;\n },\n\n /**\n * Initializes a quaternion from Euler angles.\n *\n * @param {Number[]} euler The Euler angles.\n * @param {String} order Euler angle order: \"XYZ\", \"YXZ\", \"ZXY\" etc.\n * @param {Number[]} [dest] Destination quaternion, created by default.\n * @returns {Number[]} The quaternion.\n */\n eulerToQuaternion(euler, order, dest = math.vec4()) {\n // http://www.mathworks.com/matlabcentral/fileexchange/\n // \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n //\tcontent/SpinCalc.m\n\n const a = (euler[0] * math.DEGTORAD) / 2;\n const b = (euler[1] * math.DEGTORAD) / 2;\n const c = (euler[2] * math.DEGTORAD) / 2;\n\n const c1 = Math.cos(a);\n const c2 = Math.cos(b);\n const c3 = Math.cos(c);\n const s1 = Math.sin(a);\n const s2 = Math.sin(b);\n const s3 = Math.sin(c);\n\n if (order === 'XYZ') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'YXZ') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n\n } else if (order === 'ZXY') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'ZYX') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n\n } else if (order === 'YZX') {\n\n dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n } else if (order === 'XZY') {\n\n dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n }\n\n return dest;\n },\n\n mat4ToQuaternion(m, dest = math.vec4()) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n const m11 = m[0];\n const m12 = m[4];\n const m13 = m[8];\n const m21 = m[1];\n const m22 = m[5];\n const m23 = m[9];\n const m31 = m[2];\n const m32 = m[6];\n const m33 = m[10];\n let s;\n\n const trace = m11 + m22 + m33;\n\n if (trace > 0) {\n\n s = 0.5 / Math.sqrt(trace + 1.0);\n\n dest[3] = 0.25 / s;\n dest[0] = (m32 - m23) * s;\n dest[1] = (m13 - m31) * s;\n dest[2] = (m21 - m12) * s;\n\n } else if (m11 > m22 && m11 > m33) {\n\n s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);\n\n dest[3] = (m32 - m23) / s;\n dest[0] = 0.25 * s;\n dest[1] = (m12 + m21) / s;\n dest[2] = (m13 + m31) / s;\n\n } else if (m22 > m33) {\n\n s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);\n\n dest[3] = (m13 - m31) / s;\n dest[0] = (m12 + m21) / s;\n dest[1] = 0.25 * s;\n dest[2] = (m23 + m32) / s;\n\n } else {\n\n s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);\n\n dest[3] = (m21 - m12) / s;\n dest[0] = (m13 + m31) / s;\n dest[1] = (m23 + m32) / s;\n dest[2] = 0.25 * s;\n }\n\n return dest;\n },\n\n vec3PairToQuaternion(u, v, dest = math.vec4()) {\n const norm_u_norm_v = Math.sqrt(math.dotVec3(u, u) * math.dotVec3(v, v));\n let real_part = norm_u_norm_v + math.dotVec3(u, v);\n\n if (real_part < 0.00000001 * norm_u_norm_v) {\n\n // If u and v are exactly opposite, rotate 180 degrees\n // around an arbitrary orthogonal axis. Axis normalisation\n // can happen later, when we normalise the quaternion.\n\n real_part = 0.0;\n\n if (Math.abs(u[0]) > Math.abs(u[2])) {\n\n dest[0] = -u[1];\n dest[1] = u[0];\n dest[2] = 0;\n\n } else {\n dest[0] = 0;\n dest[1] = -u[2];\n dest[2] = u[1]\n }\n\n } else {\n\n // Otherwise, build quaternion the standard way.\n math.cross3Vec3(u, v, dest);\n }\n\n dest[3] = real_part;\n\n return math.normalizeQuaternion(dest);\n },\n\n angleAxisToQuaternion(angleAxis, dest = math.vec4()) {\n const halfAngle = angleAxis[3] / 2.0;\n const fsin = Math.sin(halfAngle);\n dest[0] = fsin * angleAxis[0];\n dest[1] = fsin * angleAxis[1];\n dest[2] = fsin * angleAxis[2];\n dest[3] = Math.cos(halfAngle);\n return dest;\n },\n\n quaternionToEuler: ((() => {\n const mat = new FloatArrayType(16);\n return (q, order, dest) => {\n dest = dest || math.vec3();\n math.quaternionToRotationMat4(q, mat);\n math.mat4ToEuler(mat, order, dest);\n return dest;\n };\n }))(),\n\n mulQuaternions(p, q, dest = math.vec4()) {\n const p0 = p[0];\n const p1 = p[1];\n const p2 = p[2];\n const p3 = p[3];\n const q0 = q[0];\n const q1 = q[1];\n const q2 = q[2];\n const q3 = q[3];\n dest[0] = p3 * q0 + p0 * q3 + p1 * q2 - p2 * q1;\n dest[1] = p3 * q1 + p1 * q3 + p2 * q0 - p0 * q2;\n dest[2] = p3 * q2 + p2 * q3 + p0 * q1 - p1 * q0;\n dest[3] = p3 * q3 - p0 * q0 - p1 * q1 - p2 * q2;\n return dest;\n },\n\n vec3ApplyQuaternion(q, vec, dest = math.vec3()) {\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n const qx = q[0];\n const qy = q[1];\n const qz = q[2];\n const qw = q[3];\n\n // calculate quat * vector\n\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = -qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n\n dest[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;\n dest[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;\n dest[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;\n\n return dest;\n },\n\n quaternionToMat4(q, dest) {\n\n dest = math.identityMat4(dest);\n\n const q0 = q[0]; //x\n const q1 = q[1]; //y\n const q2 = q[2]; //z\n const q3 = q[3]; //w\n\n const tx = 2.0 * q0;\n const ty = 2.0 * q1;\n const tz = 2.0 * q2;\n\n const twx = tx * q3;\n const twy = ty * q3;\n const twz = tz * q3;\n\n const txx = tx * q0;\n const txy = ty * q0;\n const txz = tz * q0;\n\n const tyy = ty * q1;\n const tyz = tz * q1;\n const tzz = tz * q2;\n\n dest[0] = 1.0 - (tyy + tzz);\n dest[1] = txy + twz;\n dest[2] = txz - twy;\n\n dest[4] = txy - twz;\n dest[5] = 1.0 - (txx + tzz);\n dest[6] = tyz + twx;\n\n dest[8] = txz + twy;\n dest[9] = tyz - twx;\n\n dest[10] = 1.0 - (txx + tyy);\n\n return dest;\n },\n\n quaternionToRotationMat4(q, m) {\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n m[0] = 1 - (yy + zz);\n m[4] = xy - wz;\n m[8] = xz + wy;\n\n m[1] = xy + wz;\n m[5] = 1 - (xx + zz);\n m[9] = yz - wx;\n\n m[2] = xz - wy;\n m[6] = yz + wx;\n m[10] = 1 - (xx + yy);\n\n // last column\n m[3] = 0;\n m[7] = 0;\n m[11] = 0;\n\n // bottom row\n m[12] = 0;\n m[13] = 0;\n m[14] = 0;\n m[15] = 1;\n\n return m;\n },\n\n normalizeQuaternion(q, dest = q) {\n const len = math.lenVec4([q[0], q[1], q[2], q[3]]);\n dest[0] = q[0] / len;\n dest[1] = q[1] / len;\n dest[2] = q[2] / len;\n dest[3] = q[3] / len;\n return dest;\n },\n\n conjugateQuaternion(q, dest = q) {\n dest[0] = -q[0];\n dest[1] = -q[1];\n dest[2] = -q[2];\n dest[3] = q[3];\n return dest;\n },\n\n inverseQuaternion(q, dest) {\n return math.normalizeQuaternion(math.conjugateQuaternion(q, dest));\n },\n\n quaternionToAngleAxis(q, angleAxis = math.vec4()) {\n q = math.normalizeQuaternion(q, tempVec4);\n const q3 = q[3];\n const angle = 2 * Math.acos(q3);\n const s = Math.sqrt(1 - q3 * q3);\n if (s < 0.001) { // test to avoid divide by zero, s is always positive due to sqrt\n angleAxis[0] = q[0];\n angleAxis[1] = q[1];\n angleAxis[2] = q[2];\n } else {\n angleAxis[0] = q[0] / s;\n angleAxis[1] = q[1] / s;\n angleAxis[2] = q[2] / s;\n }\n angleAxis[3] = angle; // * 57.295779579;\n return angleAxis;\n },\n\n //------------------------------------------------------------------------------------------------------------------\n // Boundaries\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Returns a new, uninitialized 3D axis-aligned bounding box.\n *\n * @private\n */\n AABB3(values) {\n return new FloatArrayType(values || 6);\n },\n\n /**\n * Returns a new, uninitialized 2D axis-aligned bounding box.\n *\n * @private\n */\n AABB2(values) {\n return new FloatArrayType(values || 4);\n },\n\n /**\n * Returns a new, uninitialized 3D oriented bounding box (OBB).\n *\n * @private\n */\n OBB3(values) {\n return new FloatArrayType(values || 32);\n },\n\n /**\n * Returns a new, uninitialized 2D oriented bounding box (OBB).\n *\n * @private\n */\n OBB2(values) {\n return new FloatArrayType(values || 16);\n },\n\n /** Returns a new 3D bounding sphere */\n Sphere3(x, y, z, r) {\n return new FloatArrayType([x, y, z, r]);\n },\n\n /**\n * Transforms an OBB3 by a 4x4 matrix.\n *\n * @private\n */\n transformOBB3(m, p, p2 = p) {\n let i;\n const len = p.length;\n\n let x;\n let y;\n let z;\n\n const m0 = m[0];\n const m1 = m[1];\n const m2 = m[2];\n const m3 = m[3];\n const m4 = m[4];\n const m5 = m[5];\n const m6 = m[6];\n const m7 = m[7];\n const m8 = m[8];\n const m9 = m[9];\n const m10 = m[10];\n const m11 = m[11];\n const m12 = m[12];\n const m13 = m[13];\n const m14 = m[14];\n const m15 = m[15];\n\n for (i = 0; i < len; i += 4) {\n\n x = p[i + 0];\n y = p[i + 1];\n z = p[i + 2];\n\n p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n }\n\n return p2;\n },\n\n /** Returns true if the first AABB contains the second AABB.\n * @param aabb1\n * @param aabb2\n * @returns {boolean}\n */\n containsAABB3: function (aabb1, aabb2) {\n const result = (\n aabb1[0] <= aabb2[0] && aabb2[3] <= aabb1[3] &&\n aabb1[1] <= aabb2[1] && aabb2[4] <= aabb1[4] &&\n aabb1[2] <= aabb2[2] && aabb2[5] <= aabb1[5]);\n return result;\n },\n\n /**\n * Gets the diagonal size of an AABB3 given as minima and maxima.\n *\n * @private\n */\n getAABB3Diag: ((() => {\n\n const min = new FloatArrayType(3);\n const max = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return aabb => {\n\n min[0] = aabb[0];\n min[1] = aabb[1];\n min[2] = aabb[2];\n\n max[0] = aabb[3];\n max[1] = aabb[4];\n max[2] = aabb[5];\n\n math.subVec3(max, min, tempVec3);\n\n return Math.abs(math.lenVec3(tempVec3));\n };\n }))(),\n\n /**\n * Get a diagonal boundary size that is symmetrical about the given point.\n *\n * @private\n */\n getAABB3DiagPoint: ((() => {\n\n const min = new FloatArrayType(3);\n const max = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return (aabb, p) => {\n\n min[0] = aabb[0];\n min[1] = aabb[1];\n min[2] = aabb[2];\n\n max[0] = aabb[3];\n max[1] = aabb[4];\n max[2] = aabb[5];\n\n const diagVec = math.subVec3(max, min, tempVec3);\n\n const xneg = p[0] - aabb[0];\n const xpos = aabb[3] - p[0];\n const yneg = p[1] - aabb[1];\n const ypos = aabb[4] - p[1];\n const zneg = p[2] - aabb[2];\n const zpos = aabb[5] - p[2];\n\n diagVec[0] += (xneg > xpos) ? xneg : xpos;\n diagVec[1] += (yneg > ypos) ? yneg : ypos;\n diagVec[2] += (zneg > zpos) ? zneg : zpos;\n\n return Math.abs(math.lenVec3(diagVec));\n };\n }))(),\n\n /**\n * Gets the center of an AABB.\n *\n * @private\n */\n getAABB3Center(aabb, dest) {\n const r = dest || math.vec3();\n\n r[0] = (aabb[0] + aabb[3]) / 2;\n r[1] = (aabb[1] + aabb[4]) / 2;\n r[2] = (aabb[2] + aabb[5]) / 2;\n\n return r;\n },\n\n /**\n * Gets the center of a 2D AABB.\n *\n * @private\n */\n getAABB2Center(aabb, dest) {\n const r = dest || math.vec2();\n\n r[0] = (aabb[2] + aabb[0]) / 2;\n r[1] = (aabb[3] + aabb[1]) / 2;\n\n return r;\n },\n\n /**\n * Collapses a 3D axis-aligned boundary, ready to expand to fit 3D points.\n * Creates new AABB if none supplied.\n *\n * @private\n */\n collapseAABB3(aabb = math.AABB3()) {\n aabb[0] = math.MAX_DOUBLE;\n aabb[1] = math.MAX_DOUBLE;\n aabb[2] = math.MAX_DOUBLE;\n aabb[3] = -math.MAX_DOUBLE;\n aabb[4] = -math.MAX_DOUBLE;\n aabb[5] = -math.MAX_DOUBLE;\n\n return aabb;\n },\n\n /**\n * Converts an axis-aligned 3D boundary into an oriented boundary consisting of\n * an array of eight 3D positions, one for each corner of the boundary.\n *\n * @private\n */\n AABB3ToOBB3(aabb, obb = math.OBB3()) {\n obb[0] = aabb[0];\n obb[1] = aabb[1];\n obb[2] = aabb[2];\n obb[3] = 1;\n\n obb[4] = aabb[3];\n obb[5] = aabb[1];\n obb[6] = aabb[2];\n obb[7] = 1;\n\n obb[8] = aabb[3];\n obb[9] = aabb[4];\n obb[10] = aabb[2];\n obb[11] = 1;\n\n obb[12] = aabb[0];\n obb[13] = aabb[4];\n obb[14] = aabb[2];\n obb[15] = 1;\n\n obb[16] = aabb[0];\n obb[17] = aabb[1];\n obb[18] = aabb[5];\n obb[19] = 1;\n\n obb[20] = aabb[3];\n obb[21] = aabb[1];\n obb[22] = aabb[5];\n obb[23] = 1;\n\n obb[24] = aabb[3];\n obb[25] = aabb[4];\n obb[26] = aabb[5];\n obb[27] = 1;\n\n obb[28] = aabb[0];\n obb[29] = aabb[4];\n obb[30] = aabb[5];\n obb[31] = 1;\n\n return obb;\n },\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array.\n *\n * @private\n */\n positions3ToAABB3: ((() => {\n\n const p = new FloatArrayType(3);\n\n return (positions, aabb, positionsDecodeMatrix) => {\n aabb = aabb || math.AABB3();\n\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = positions.length; i < len; i += 3) {\n\n if (positionsDecodeMatrix) {\n\n p[0] = positions[i + 0];\n p[1] = positions[i + 1];\n p[2] = positions[i + 2];\n\n math.decompressPosition(p, positionsDecodeMatrix, p);\n\n x = p[0];\n y = p[1];\n z = p[2];\n\n } else {\n x = positions[i + 0];\n y = positions[i + 1];\n z = positions[i + 2];\n }\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n };\n }))(),\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array.\n *\n * @private\n */\n OBB3ToAABB3(obb, aabb = math.AABB3()) {\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = obb.length; i < len; i += 4) {\n\n x = obb[i + 0];\n y = obb[i + 1];\n z = obb[i + 2];\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n },\n\n /**\n * Finds the minimum axis-aligned 3D boundary enclosing the given 3D points.\n *\n * @private\n */\n points3ToAABB3(points, aabb = math.AABB3()) {\n let xmin = math.MAX_DOUBLE;\n let ymin = math.MAX_DOUBLE;\n let zmin = math.MAX_DOUBLE;\n let xmax = -math.MAX_DOUBLE;\n let ymax = -math.MAX_DOUBLE;\n let zmax = -math.MAX_DOUBLE;\n\n let x;\n let y;\n let z;\n\n for (let i = 0, len = points.length; i < len; i++) {\n\n x = points[i][0];\n y = points[i][1];\n z = points[i][2];\n\n if (x < xmin) {\n xmin = x;\n }\n\n if (y < ymin) {\n ymin = y;\n }\n\n if (z < zmin) {\n zmin = z;\n }\n\n if (x > xmax) {\n xmax = x;\n }\n\n if (y > ymax) {\n ymax = y;\n }\n\n if (z > zmax) {\n zmax = z;\n }\n }\n\n aabb[0] = xmin;\n aabb[1] = ymin;\n aabb[2] = zmin;\n aabb[3] = xmax;\n aabb[4] = ymax;\n aabb[5] = zmax;\n\n return aabb;\n },\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D points.\n *\n * @private\n */\n points3ToSphere3: ((() => {\n\n const tempVec3 = new FloatArrayType(3);\n\n return (points, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const numPoints = points.length;\n\n for (i = 0; i < numPoints; i++) {\n x += points[i][0];\n y += points[i][1];\n z += points[i][2];\n }\n\n sphere[0] = x / numPoints;\n sphere[1] = y / numPoints;\n sphere[2] = z / numPoints;\n\n let radius = 0;\n let dist;\n\n for (i = 0; i < numPoints; i++) {\n\n dist = Math.abs(math.lenVec3(math.subVec3(points[i], sphere, tempVec3)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D positions.\n *\n * @private\n */\n positions3ToSphere3: ((() => {\n\n const tempVec3a = new FloatArrayType(3);\n const tempVec3b = new FloatArrayType(3);\n\n return (positions, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const lenPositions = positions.length;\n let radius = 0;\n\n for (i = 0; i < lenPositions; i += 3) {\n x += positions[i];\n y += positions[i + 1];\n z += positions[i + 2];\n }\n\n const numPositions = lenPositions / 3;\n\n sphere[0] = x / numPositions;\n sphere[1] = y / numPositions;\n sphere[2] = z / numPositions;\n\n let dist;\n\n for (i = 0; i < lenPositions; i += 3) {\n\n tempVec3a[0] = positions[i];\n tempVec3a[1] = positions[i + 1];\n tempVec3a[2] = positions[i + 2];\n\n dist = Math.abs(math.lenVec3(math.subVec3(tempVec3a, sphere, tempVec3b)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Finds the minimum boundary sphere enclosing the given 3D points.\n *\n * @private\n */\n OBB3ToSphere3: ((() => {\n\n const point = new FloatArrayType(3);\n const tempVec3 = new FloatArrayType(3);\n\n return (points, sphere) => {\n\n sphere = sphere || math.vec4();\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n let i;\n const lenPoints = points.length;\n const numPoints = lenPoints / 4;\n\n for (i = 0; i < lenPoints; i += 4) {\n x += points[i + 0];\n y += points[i + 1];\n z += points[i + 2];\n }\n\n sphere[0] = x / numPoints;\n sphere[1] = y / numPoints;\n sphere[2] = z / numPoints;\n\n let radius = 0;\n let dist;\n\n for (i = 0; i < lenPoints; i += 4) {\n\n point[0] = points[i + 0];\n point[1] = points[i + 1];\n point[2] = points[i + 2];\n\n dist = Math.abs(math.lenVec3(math.subVec3(point, sphere, tempVec3)));\n\n if (dist > radius) {\n radius = dist;\n }\n }\n\n sphere[3] = radius;\n\n return sphere;\n };\n }))(),\n\n /**\n * Gets the center of a bounding sphere.\n *\n * @private\n */\n getSphere3Center(sphere, dest = math.vec3()) {\n dest[0] = sphere[0];\n dest[1] = sphere[1];\n dest[2] = sphere[2];\n\n return dest;\n },\n\n /**\n * Expands the first axis-aligned 3D boundary to enclose the second, if required.\n *\n * @private\n */\n expandAABB3(aabb1, aabb2) {\n\n if (aabb1[0] > aabb2[0]) {\n aabb1[0] = aabb2[0];\n }\n\n if (aabb1[1] > aabb2[1]) {\n aabb1[1] = aabb2[1];\n }\n\n if (aabb1[2] > aabb2[2]) {\n aabb1[2] = aabb2[2];\n }\n\n if (aabb1[3] < aabb2[3]) {\n aabb1[3] = aabb2[3];\n }\n\n if (aabb1[4] < aabb2[4]) {\n aabb1[4] = aabb2[4];\n }\n\n if (aabb1[5] < aabb2[5]) {\n aabb1[5] = aabb2[5];\n }\n\n return aabb1;\n },\n\n /**\n * Expands an axis-aligned 3D boundary to enclose the given point, if needed.\n *\n * @private\n */\n expandAABB3Point3(aabb, p) {\n\n if (aabb[0] > p[0]) {\n aabb[0] = p[0];\n }\n\n if (aabb[1] > p[1]) {\n aabb[1] = p[1];\n }\n\n if (aabb[2] > p[2]) {\n aabb[2] = p[2];\n }\n\n if (aabb[3] < p[0]) {\n aabb[3] = p[0];\n }\n\n if (aabb[4] < p[1]) {\n aabb[4] = p[1];\n }\n\n if (aabb[5] < p[2]) {\n aabb[5] = p[2];\n }\n\n return aabb;\n },\n\n /**\n * Calculates the normal vector of a triangle.\n *\n * @private\n */\n triangleNormal(a, b, c, normal = math.vec3()) {\n const p1x = b[0] - a[0];\n const p1y = b[1] - a[1];\n const p1z = b[2] - a[2];\n\n const p2x = c[0] - a[0];\n const p2y = c[1] - a[1];\n const p2z = c[2] - a[2];\n\n const p3x = p1y * p2z - p1z * p2y;\n const p3y = p1z * p2x - p1x * p2z;\n const p3z = p1x * p2y - p1y * p2x;\n\n const mag = Math.sqrt(p3x * p3x + p3y * p3y + p3z * p3z);\n if (mag === 0) {\n normal[0] = 0;\n normal[1] = 0;\n normal[2] = 0;\n } else {\n normal[0] = p3x / mag;\n normal[1] = p3y / mag;\n normal[2] = p3z / mag;\n }\n\n return normal\n }\n};\n\nexport {math};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/lib/math.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/lib/math.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 391, + "__docId__": 393, "kind": "variable", "name": "doublePrecision", "memberof": "src/lib/math.js", @@ -10790,7 +10849,7 @@ "ignore": true }, { - "__docId__": 392, + "__docId__": 394, "kind": "variable", "name": "FloatArrayType", "memberof": "src/lib/math.js", @@ -10811,7 +10870,7 @@ "ignore": true }, { - "__docId__": 393, + "__docId__": 395, "kind": "variable", "name": "tempMat1", "memberof": "src/lib/math.js", @@ -10832,7 +10891,7 @@ "ignore": true }, { - "__docId__": 394, + "__docId__": 396, "kind": "variable", "name": "tempMat2", "memberof": "src/lib/math.js", @@ -10853,7 +10912,7 @@ "ignore": true }, { - "__docId__": 395, + "__docId__": 397, "kind": "variable", "name": "tempVec4", "memberof": "src/lib/math.js", @@ -10874,7 +10933,7 @@ "ignore": true }, { - "__docId__": 396, + "__docId__": 398, "kind": "variable", "name": "math", "memberof": "src/lib/math.js", @@ -10894,18 +10953,18 @@ } }, { - "__docId__": 397, + "__docId__": 399, "kind": "file", "name": "src/lib/mergeVertices.js", "content": "/**\n * Given geometry defined as an array of positions, optional normals, option uv and an array of indices, returns\n * modified arrays that have duplicate vertices removed.\n *\n * @private\n */\nfunction mergeVertices(positions, indices, mergedPositions, mergedIndices) {\n const positionsMap = {};\n const indicesLookup = [];\n const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n const precision = 10 ** precisionPoints;\n let uvi = 0;\n for (let i = 0, len = positions.length; i < len; i += 3) {\n const vx = positions[i];\n const vy = positions[i + 1];\n const vz = positions[i + 2];\n const key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`;\n if (positionsMap[key] === undefined) {\n positionsMap[key] = mergedPositions.length / 3;\n mergedPositions.push(vx);\n mergedPositions.push(vy);\n mergedPositions.push(vz);\n }\n indicesLookup[i / 3] = positionsMap[key];\n uvi += 2;\n }\n for (let i = 0, len = indices.length; i < len; i++) {\n mergedIndices[i] = indicesLookup[indices[i]];\n }\n}\n\nexport {mergeVertices};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/lib/mergeVertices.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/lib/mergeVertices.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 398, + "__docId__": 400, "kind": "function", "name": "mergeVertices", "memberof": "src/lib/mergeVertices.js", @@ -10949,18 +11008,18 @@ "return": null }, { - "__docId__": 399, + "__docId__": 401, "kind": "file", "name": "src/parsers/parseCityJSONIntoXKTModel.js", "content": "import {earcut} from './../lib/earcut';\nimport {math} from \"./../lib/math.js\";\n\nconst tempVec2a = math.vec2();\nconst tempVec3a = math.vec3();\nconst tempVec3b = math.vec3();\nconst tempVec3c = math.vec3();\n\n/**\n * @desc Parses a CityJSON model into an {@link XKTModel}.\n *\n * [CityJSON](https://www.cityjson.org) is a JSON-based encoding for a subset of the CityGML data model (version 2.0.0),\n * which is an open standardised data model and exchange format to store digital 3D models of cities and\n * landscapes. CityGML is an official standard of the [Open Geospatial Consortium](https://www.ogc.org/).\n *\n * This converter function supports most of the [CityJSON 1.0.2 Specification](https://www.cityjson.org/specs/1.0.2),\n * with the following limitations:\n *\n * * Does not (yet) support CityJSON semantics for geometry primitives.\n * * Does not (yet) support textured geometries.\n * * Does not (yet) support geometry templates.\n * * When the CityJSON file provides multiple *themes* for a geometry, then we parse only the first of the provided themes for that geometry.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a CityJSON model into it.\n *\n * ````javascript\n * utils.loadJSON(\"./models/cityjson/DenHaag.json\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseCityJSONIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {Object} params.data CityJSON data.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {boolean} [params.center=false] Set true to center the CityJSON vertex positions to [0,0,0]. This is applied before the transformation matrix, if specified.\n * @param {Boolean} [params.transform] 4x4 transformation matrix to transform CityJSON vertex positions. Use this to rotate, translate and scale them if neccessary.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when CityJSON has been parsed.\n */\nfunction parseCityJSONIntoXKTModel({\n data,\n xktModel,\n center = false,\n transform = null,\n stats = {}, log\n }) {\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (data.type !== \"CityJSON\") {\n reject(\"Invalid argument: data is not a CityJSON file\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n let vertices;\n\n log(\"Using parser: parseCityJSONIntoXKTModel\");\n\n log(`center: ${center}`);\n if (transform) {\n log(`transform: [${transform}]`);\n }\n\n if (data.transform || center || transform) {\n vertices = copyVertices(data.vertices);\n if (data.transform) {\n transformVertices(vertices, data.transform)\n }\n if (center) {\n centerVertices(vertices);\n }\n if (transform) {\n customTransformVertices(vertices, transform);\n }\n } else {\n vertices = data.vertices;\n }\n\n stats.sourceFormat = data.type || \"\";\n stats.schemaVersion = data.version || \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 0;\n stats.numPropertySets = 0;\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n const rootMetaObjectId = math.createUUID();\n\n xktModel.createMetaObject({\n metaObjectId: rootMetaObjectId,\n metaObjectType: \"Model\",\n metaObjectName: \"Model\"\n });\n\n stats.numMetaObjects++;\n\n const modelMetaObjectId = math.createUUID();\n\n xktModel.createMetaObject({\n metaObjectId: modelMetaObjectId,\n metaObjectType: \"CityJSON\",\n metaObjectName: \"CityJSON\",\n parentMetaObjectId: rootMetaObjectId\n });\n\n stats.numMetaObjects++;\n\n const ctx = {\n data,\n vertices,\n xktModel,\n rootMetaObjectId: modelMetaObjectId,\n log: (log || function (msg) {\n }),\n nextId: 0,\n stats\n };\n\n ctx.xktModel.schema = data.type + \" \" + data.version;\n\n ctx.log(\"Converting \" + ctx.xktModel.schema);\n\n parseCityJSON(ctx);\n\n resolve();\n });\n}\n\nfunction copyVertices(vertices) {\n const vertices2 = [];\n for (let i = 0, j = 0; i < vertices.length; i++, j += 3) {\n const x = vertices[i][0];\n const y = vertices[i][1];\n const z = vertices[i][2];\n vertices2.push([x, y, z]);\n }\n return vertices2;\n}\n\nfunction transformVertices(vertices, cityJSONTransform) {\n const scale = cityJSONTransform.scale || math.vec3([1, 1, 1]);\n const translate = cityJSONTransform.translate || math.vec3([0, 0, 0]);\n for (let i = 0; i < vertices.length; i++) {\n const vertex = vertices[i];\n vertex[0] = (vertex[0] * scale[0]) + translate[0];\n vertex[1] = (vertex[1] * scale[1]) + translate[1];\n vertex[2] = (vertex[2] * scale[2]) + translate[2];\n }\n}\n\nfunction centerVertices(vertices) {\n if (center) {\n const centerPos = math.vec3();\n const numPoints = vertices.length;\n for (let i = 0, len = vertices.length; i < len; i++) {\n const vertex = vertices[i];\n centerPos[0] += vertex[0];\n centerPos[1] += vertex[1];\n centerPos[2] += vertex[2];\n }\n centerPos[0] /= numPoints;\n centerPos[1] /= numPoints;\n centerPos[2] /= numPoints;\n for (let i = 0, len = vertices.length; i < len; i++) {\n const vertex = vertices[i];\n vertex[0] -= centerPos[0];\n vertex[1] -= centerPos[1];\n vertex[2] -= centerPos[2];\n }\n }\n}\n\nfunction customTransformVertices(vertices, transform) {\n if (transform) {\n const mat = math.mat4(transform);\n for (let i = 0, len = vertices.length; i < len; i++) {\n const vertex = vertices[i];\n math.transformPoint3(mat, vertex, vertex);\n }\n }\n}\n\nfunction parseCityJSON(ctx) {\n\n const data = ctx.data;\n const cityObjects = data.CityObjects;\n\n for (const objectId in cityObjects) {\n if (cityObjects.hasOwnProperty(objectId)) {\n const cityObject = cityObjects[objectId];\n parseCityObject(ctx, cityObject, objectId);\n }\n }\n}\n\nfunction parseCityObject(ctx, cityObject, objectId) {\n\n const xktModel = ctx.xktModel;\n const data = ctx.data;\n const metaObjectId = objectId;\n const metaObjectType = cityObject.type;\n const metaObjectName = metaObjectType + \" : \" + objectId;\n\n const parentMetaObjectId = cityObject.parents ? cityObject.parents[0] : ctx.rootMetaObjectId;\n\n xktModel.createMetaObject({\n metaObjectId,\n metaObjectName,\n metaObjectType,\n parentMetaObjectId\n });\n\n ctx.stats.numMetaObjects++;\n\n if (!(cityObject.geometry && cityObject.geometry.length > 0)) {\n return;\n }\n\n const meshIds = [];\n\n for (let i = 0, len = cityObject.geometry.length; i < len; i++) {\n\n const geometry = cityObject.geometry[i];\n\n let objectMaterial;\n let surfaceMaterials;\n\n const appearance = data.appearance;\n if (appearance) {\n const materials = appearance.materials;\n if (materials) {\n const geometryMaterial = geometry.material;\n if (geometryMaterial) {\n const themeIds = Object.keys(geometryMaterial);\n if (themeIds.length > 0) {\n const themeId = themeIds[0];\n const theme = geometryMaterial[themeId];\n if (theme.value !== undefined) {\n objectMaterial = materials[theme.value];\n } else {\n const values = theme.values;\n if (values) {\n surfaceMaterials = [];\n for (let j = 0, lenj = values.length; j < lenj; j++) {\n const value = values[i];\n const surfaceMaterial = materials[value];\n surfaceMaterials.push(surfaceMaterial);\n }\n }\n }\n }\n }\n }\n }\n\n if (surfaceMaterials) {\n parseGeometrySurfacesWithOwnMaterials(ctx, geometry, surfaceMaterials, meshIds);\n\n } else {\n parseGeometrySurfacesWithSharedMaterial(ctx, geometry, objectMaterial, meshIds);\n }\n }\n\n if (meshIds.length > 0) {\n xktModel.createEntity({\n entityId: objectId,\n meshIds: meshIds\n });\n\n ctx.stats.numObjects++;\n }\n}\n\nfunction parseGeometrySurfacesWithOwnMaterials(ctx, geometry, surfaceMaterials, meshIds) {\n\n const geomType = geometry.type;\n\n switch (geomType) {\n\n case \"MultiPoint\":\n break;\n\n case \"MultiLineString\":\n break;\n\n case \"MultiSurface\":\n\n case \"CompositeSurface\":\n const surfaces = geometry.boundaries;\n parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n break;\n\n case \"Solid\":\n const shells = geometry.boundaries;\n for (let j = 0; j < shells.length; j++) {\n const surfaces = shells[j];\n parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n }\n break;\n\n case \"MultiSolid\":\n\n case \"CompositeSolid\":\n const solids = geometry.boundaries;\n for (let j = 0; j < solids.length; j++) {\n for (let k = 0; k < solids[j].length; k++) {\n const surfaces = solids[j][k];\n parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n }\n }\n break;\n\n case \"GeometryInstance\":\n break;\n }\n}\n\nfunction parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds) {\n\n const vertices = ctx.vertices;\n const xktModel = ctx.xktModel;\n\n for (let i = 0; i < surfaces.length; i++) {\n\n const surface = surfaces[i];\n const surfaceMaterial = surfaceMaterials[i] || {diffuseColor: [0.8, 0.8, 0.8], transparency: 1.0};\n\n const face = [];\n const holes = [];\n\n const sharedIndices = [];\n\n const geometryCfg = {\n positions: [],\n indices: []\n };\n\n for (let j = 0; j < surface.length; j++) {\n\n if (face.length > 0) {\n holes.push(face.length);\n }\n\n const newFace = extractLocalIndices(ctx, surface[j], sharedIndices, geometryCfg);\n\n face.push(...newFace);\n }\n\n if (face.length === 3) { // Triangle\n\n geometryCfg.indices.push(face[0]);\n geometryCfg.indices.push(face[1]);\n geometryCfg.indices.push(face[2]);\n\n } else if (face.length > 3) { // Polygon\n\n // Prepare to triangulate\n\n const pList = [];\n\n for (let k = 0; k < face.length; k++) {\n pList.push({\n x: vertices[sharedIndices[face[k]]][0],\n y: vertices[sharedIndices[face[k]]][1],\n z: vertices[sharedIndices[face[k]]][2]\n });\n }\n\n const normal = getNormalOfPositions(pList, math.vec3());\n\n // Convert to 2D\n\n let pv = [];\n\n for (let k = 0; k < pList.length; k++) {\n\n to2D(pList[k], normal, tempVec2a);\n\n pv.unshift(tempVec2a[0]);\n pv.unshift(tempVec2a[1]);\n }\n\n // Triangulate\n\n const tr = earcut(pv, holes, 2);\n\n // Create triangles\n\n for (let k = 0; k < tr.length; k += 3) {\n geometryCfg.indices.unshift(face[tr[k]]);\n geometryCfg.indices.unshift(face[tr[k + 1]]);\n geometryCfg.indices.unshift(face[tr[k + 2]]);\n }\n }\n\n const geometryId = \"\" + ctx.nextId++;\n const meshId = \"\" + ctx.nextId++;\n\n xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: geometryCfg.positions,\n indices: geometryCfg.indices\n });\n\n xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n color: (surfaceMaterial && surfaceMaterial.diffuseColor) ? surfaceMaterial.diffuseColor : [0.8, 0.8, 0.8],\n opacity: 1.0\n //opacity: (surfaceMaterial && surfaceMaterial.transparency !== undefined) ? (1.0 - surfaceMaterial.transparency) : 1.0\n });\n\n meshIds.push(meshId);\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n }\n}\n\nfunction parseGeometrySurfacesWithSharedMaterial(ctx, geometry, objectMaterial, meshIds) {\n\n const xktModel = ctx.xktModel;\n const sharedIndices = [];\n const geometryCfg = {\n positions: [],\n indices: []\n };\n\n const geomType = geometry.type;\n\n switch (geomType) {\n case \"MultiPoint\":\n break;\n\n case \"MultiLineString\":\n break;\n\n case \"MultiSurface\":\n case \"CompositeSurface\":\n const surfaces = geometry.boundaries;\n parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n break;\n\n case \"Solid\":\n const shells = geometry.boundaries;\n for (let j = 0; j < shells.length; j++) {\n const surfaces = shells[j];\n parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n }\n break;\n\n case \"MultiSolid\":\n case \"CompositeSolid\":\n const solids = geometry.boundaries;\n for (let j = 0; j < solids.length; j++) {\n for (let k = 0; k < solids[j].length; k++) {\n const surfaces = solids[j][k];\n parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n }\n }\n break;\n\n case \"GeometryInstance\":\n break;\n }\n\n const geometryId = \"\" + ctx.nextId++;\n const meshId = \"\" + ctx.nextId++;\n\n xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: geometryCfg.positions,\n indices: geometryCfg.indices\n });\n\n xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n color: (objectMaterial && objectMaterial.diffuseColor) ? objectMaterial.diffuseColor : [0.8, 0.8, 0.8],\n opacity: 1.0\n //opacity: (objectMaterial && objectMaterial.transparency !== undefined) ? (1.0 - objectMaterial.transparency) : 1.0\n });\n\n meshIds.push(meshId);\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n}\n\nfunction parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, primitiveCfg) {\n\n const vertices = ctx.vertices;\n\n for (let i = 0; i < surfaces.length; i++) {\n\n let boundary = [];\n let holes = [];\n\n for (let j = 0; j < surfaces[i].length; j++) {\n if (boundary.length > 0) {\n holes.push(boundary.length);\n }\n const newBoundary = extractLocalIndices(ctx, surfaces[i][j], sharedIndices, primitiveCfg);\n boundary.push(...newBoundary);\n }\n\n if (boundary.length === 3) { // Triangle\n\n primitiveCfg.indices.push(boundary[0]);\n primitiveCfg.indices.push(boundary[1]);\n primitiveCfg.indices.push(boundary[2]);\n\n } else if (boundary.length > 3) { // Polygon\n\n let pList = [];\n\n for (let k = 0; k < boundary.length; k++) {\n pList.push({\n x: vertices[sharedIndices[boundary[k]]][0],\n y: vertices[sharedIndices[boundary[k]]][1],\n z: vertices[sharedIndices[boundary[k]]][2]\n });\n }\n\n const normal = getNormalOfPositions(pList, math.vec3());\n let pv = [];\n\n for (let k = 0; k < pList.length; k++) {\n to2D(pList[k], normal, tempVec2a);\n pv.unshift(tempVec2a[0]);\n pv.unshift(tempVec2a[1]);\n }\n\n const tr = earcut(pv, holes, 2);\n\n for (let k = 0; k < tr.length; k += 3) {\n primitiveCfg.indices.unshift(boundary[tr[k]]);\n primitiveCfg.indices.unshift(boundary[tr[k + 1]]);\n primitiveCfg.indices.unshift(boundary[tr[k + 2]]);\n }\n }\n }\n}\n\nfunction extractLocalIndices(ctx, boundary, sharedIndices, geometryCfg) {\n\n const vertices = ctx.vertices;\n const newBoundary = []\n\n for (let i = 0, len = boundary.length; i < len; i++) {\n\n const index = boundary[i];\n\n if (sharedIndices.includes(index)) {\n const vertexIndex = sharedIndices.indexOf(index);\n newBoundary.push(vertexIndex);\n\n } else {\n geometryCfg.positions.push(vertices[index][0]);\n geometryCfg.positions.push(vertices[index][1]);\n geometryCfg.positions.push(vertices[index][2]);\n\n newBoundary.push(sharedIndices.length);\n\n sharedIndices.push(index);\n }\n }\n\n return newBoundary\n}\n\nfunction getNormalOfPositions(positions, normal) {\n\n for (let i = 0; i < positions.length; i++) {\n\n let nexti = i + 1;\n if (nexti === positions.length) {\n nexti = 0;\n }\n\n normal[0] += ((positions[i].y - positions[nexti].y) * (positions[i].z + positions[nexti].z));\n normal[1] += ((positions[i].z - positions[nexti].z) * (positions[i].x + positions[nexti].x));\n normal[2] += ((positions[i].x - positions[nexti].x) * (positions[i].y + positions[nexti].y));\n }\n\n return math.normalizeVec3(normal);\n}\n\nfunction to2D(_p, _n, re) {\n\n const p = tempVec3a;\n const n = tempVec3b;\n const x3 = tempVec3c;\n\n p[0] = _p.x;\n p[1] = _p.y;\n p[2] = _p.z;\n\n n[0] = _n.x;\n n[1] = _n.y;\n n[2] = _n.z;\n\n x3[0] = 1.1;\n x3[1] = 1.1;\n x3[2] = 1.1;\n\n const dist = math.lenVec3(math.subVec3(x3, n));\n\n if (dist < 0.01) {\n x3[0] += 1.0;\n x3[1] += 2.0;\n x3[2] += 3.0;\n }\n\n const dot = math.dotVec3(x3, n);\n const tmp2 = math.mulVec3Scalar(n, dot, math.vec3());\n\n x3[0] -= tmp2[0];\n x3[1] -= tmp2[1];\n x3[2] -= tmp2[2];\n\n math.normalizeVec3(x3);\n\n const y3 = math.cross3Vec3(n, x3, math.vec3());\n const x = math.dotVec3(p, x3);\n const y = math.dotVec3(p, y3);\n\n re[0] = x;\n re[1] = y;\n}\n\nexport {parseCityJSONIntoXKTModel};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/parsers/parseCityJSONIntoXKTModel.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/parsers/parseCityJSONIntoXKTModel.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 400, + "__docId__": 402, "kind": "variable", "name": "tempVec2a", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -10981,7 +11040,7 @@ "ignore": true }, { - "__docId__": 401, + "__docId__": 403, "kind": "variable", "name": "tempVec3a", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11002,7 +11061,7 @@ "ignore": true }, { - "__docId__": 402, + "__docId__": 404, "kind": "variable", "name": "tempVec3b", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11023,7 +11082,7 @@ "ignore": true }, { - "__docId__": 403, + "__docId__": 405, "kind": "variable", "name": "tempVec3c", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11044,7 +11103,7 @@ "ignore": true }, { - "__docId__": 404, + "__docId__": 406, "kind": "function", "name": "copyVertices", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11075,7 +11134,7 @@ "ignore": true }, { - "__docId__": 405, + "__docId__": 407, "kind": "function", "name": "transformVertices", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11108,7 +11167,7 @@ "ignore": true }, { - "__docId__": 406, + "__docId__": 408, "kind": "function", "name": "centerVertices", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11135,7 +11194,7 @@ "ignore": true }, { - "__docId__": 407, + "__docId__": 409, "kind": "function", "name": "customTransformVertices", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11168,7 +11227,7 @@ "ignore": true }, { - "__docId__": 408, + "__docId__": 410, "kind": "function", "name": "parseCityJSON", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11195,7 +11254,7 @@ "ignore": true }, { - "__docId__": 409, + "__docId__": 411, "kind": "function", "name": "parseCityObject", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11234,7 +11293,7 @@ "ignore": true }, { - "__docId__": 410, + "__docId__": 412, "kind": "function", "name": "parseGeometrySurfacesWithOwnMaterials", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11279,7 +11338,7 @@ "ignore": true }, { - "__docId__": 411, + "__docId__": 413, "kind": "function", "name": "parseSurfacesWithOwnMaterials", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11324,7 +11383,7 @@ "ignore": true }, { - "__docId__": 412, + "__docId__": 414, "kind": "function", "name": "parseGeometrySurfacesWithSharedMaterial", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11369,7 +11428,7 @@ "ignore": true }, { - "__docId__": 413, + "__docId__": 415, "kind": "function", "name": "parseSurfacesWithSharedMaterial", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11414,7 +11473,7 @@ "ignore": true }, { - "__docId__": 414, + "__docId__": 416, "kind": "function", "name": "extractLocalIndices", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11463,7 +11522,7 @@ "ignore": true }, { - "__docId__": 415, + "__docId__": 417, "kind": "function", "name": "getNormalOfPositions", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11500,7 +11559,7 @@ "ignore": true }, { - "__docId__": 416, + "__docId__": 418, "kind": "function", "name": "to2D", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11539,7 +11598,7 @@ "ignore": true }, { - "__docId__": 417, + "__docId__": 419, "kind": "function", "name": "parseCityJSONIntoXKTModel", "memberof": "src/parsers/parseCityJSONIntoXKTModel.js", @@ -11643,28 +11702,28 @@ } }, { - "__docId__": 418, + "__docId__": 420, "kind": "file", - "name": "src/parsers/parseGLTFIntoXKTModel.OLD.js", - "content": "import {utils} from \"../XKTModel/lib/utils.js\";\nimport {math} from \"../lib/math.js\";\n\nimport {parse} from '@loaders.gl/core';\nimport {GLTFLoader} from '@loaders.gl/gltf';\nimport {\n ClampToEdgeWrapping,\n LinearFilter,\n LinearMipMapLinearFilter,\n LinearMipMapNearestFilter,\n MirroredRepeatWrapping,\n NearestFilter,\n NearestMipMapLinearFilter,\n NearestMipMapNearestFilter,\n RepeatWrapping\n} from \"../constants.js\";\n\n/**\n * @desc Parses glTF into an {@link XKTModel}, supporting ````.glb```` and textures.\n *\n * * Supports ````.glb```` and textures\n * * For a lightweight glTF JSON parser that ignores textures, see {@link parseGLTFJSONIntoXKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a binary glTF model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"../assets/models/gltf/HousePlan/glTF-Binary/HousePlan.glb\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseGLTFIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing parameters.\n * @param {ArrayBuffer} params.data The glTF.\n * @param {String} [params.baseUri] The base URI used to load this glTF, if any. For resolving relative uris to linked resources.\n * @param {Object} [params.metaModelData] Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Boolean} [params.includeTextures=true] Whether to parse textures.\n * @param {Boolean} [params.includeNormals=true] Whether to parse normals. When false, the parser will ignore the glTF\n * geometry normals, and the glTF data will rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the glTF.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when glTF has been parsed.\n */\nfunction parseGLTFIntoXKTModel({\n data,\n baseUri,\n xktModel,\n metaModelData,\n includeTextures = true,\n includeNormals = true,\n getAttachment,\n stats = {},\n log\n }) {\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n stats.sourceFormat = \"glTF\";\n stats.schemaVersion = \"2.0\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numUVs = 0;\n stats.numTextures = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n parse(data, GLTFLoader, {\n baseUri\n }).then((gltfData) => {\n\n const ctx = {\n gltfData,\n metaModelCorrections: metaModelData,\n getAttachment: getAttachment || (() => {\n throw new Error('You must define getAttachment() method to convert glTF with external resources')\n }),\n log: (log || function (msg) {\n }),\n error: function (msg) {\n console.error(msg);\n },\n xktModel,\n includeNormals: (includeNormals !== false),\n includeTextures: (includeTextures !== false),\n geometryCreated: {},\n nextId: 0,\n stats\n };\n\n ctx.log(\"Using parser: parseGLTFIntoXKTModel\");\n ctx.log(`Parsing normals: ${ctx.includeNormals ? \"enabled\" : \"disabled\"}`);\n ctx.log(`Parsing textures: ${ctx.includeTextures ? \"enabled\" : \"disabled\"}`);\n\n if (ctx.includeTextures) {\n parseTextures(ctx);\n }\n parseMaterials(ctx);\n parseDefaultScene(ctx);\n\n resolve();\n\n }, (errMsg) => {\n reject(`[parseGLTFIntoXKTModel] ${errMsg}`);\n });\n });\n}\n\nfunction parseTextures(ctx) {\n const gltfData = ctx.gltfData;\n const textures = gltfData.textures;\n if (textures) {\n for (let i = 0, len = textures.length; i < len; i++) {\n parseTexture(ctx, textures[i]);\n ctx.stats.numTextures++;\n }\n }\n}\n\nfunction parseTexture(ctx, texture) {\n if (!texture.source || !texture.source.image) {\n return;\n }\n const textureId = `texture-${ctx.nextId++}`;\n\n let minFilter = NearestMipMapLinearFilter;\n switch (texture.sampler.minFilter) {\n case 9728:\n minFilter = NearestFilter;\n break;\n case 9729:\n minFilter = LinearFilter;\n break;\n case 9984:\n minFilter = NearestMipMapNearestFilter;\n break;\n case 9985:\n minFilter = LinearMipMapNearestFilter;\n break;\n case 9986:\n minFilter = NearestMipMapLinearFilter;\n break;\n case 9987:\n minFilter = LinearMipMapLinearFilter;\n break;\n }\n\n let magFilter = LinearFilter;\n switch (texture.sampler.magFilter) {\n case 9728:\n magFilter = NearestFilter;\n break;\n case 9729:\n magFilter = LinearFilter;\n break;\n }\n\n let wrapS = RepeatWrapping;\n switch (texture.sampler.wrapS) {\n case 33071:\n wrapS = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapS = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapS = RepeatWrapping;\n break;\n }\n\n let wrapT = RepeatWrapping;\n switch (texture.sampler.wrapT) {\n case 33071:\n wrapT = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapT = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapT = RepeatWrapping;\n break;\n }\n\n let wrapR = RepeatWrapping;\n switch (texture.sampler.wrapR) {\n case 33071:\n wrapR = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapR = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapR = RepeatWrapping;\n break;\n }\n\n ctx.xktModel.createTexture({\n textureId: textureId,\n imageData: texture.source.image,\n mediaType: texture.source.mediaType,\n compressed: true,\n width: texture.source.image.width,\n height: texture.source.image.height,\n minFilter,\n magFilter,\n wrapS,\n wrapT,\n wrapR,\n flipY: !!texture.flipY,\n // encoding: \"sRGB\"\n });\n texture._textureId = textureId;\n}\n\nfunction parseMaterials(ctx) {\n const gltfData = ctx.gltfData;\n const materials = gltfData.materials;\n if (materials) {\n for (let i = 0, len = materials.length; i < len; i++) {\n const material = materials[i];\n material._textureSetId = ctx.includeTextures ? parseTextureSet(ctx, material) : null;\n material._attributes = parseMaterialAttributes(ctx, material);\n }\n }\n}\n\nfunction parseTextureSet(ctx, material) {\n const textureSetCfg = {};\n if (material.normalTexture) {\n textureSetCfg.normalTextureId = material.normalTexture.texture._textureId;\n }\n if (material.occlusionTexture) {\n textureSetCfg.occlusionTextureId = material.occlusionTexture.texture._textureId;\n }\n if (material.emissiveTexture) {\n textureSetCfg.emissiveTextureId = material.emissiveTexture.texture._textureId;\n }\n // const alphaMode = material.alphaMode;\n // switch (alphaMode) {\n // case \"NORMAL_OPAQUE\":\n // materialCfg.alphaMode = \"opaque\";\n // break;\n // case \"MASK\":\n // materialCfg.alphaMode = \"mask\";\n // break;\n // case \"BLEND\":\n // materialCfg.alphaMode = \"blend\";\n // break;\n // default:\n // }\n // const alphaCutoff = material.alphaCutoff;\n // if (alphaCutoff !== undefined) {\n // materialCfg.alphaCutoff = alphaCutoff;\n // }\n const metallicPBR = material.pbrMetallicRoughness;\n if (material.pbrMetallicRoughness) {\n const pbrMetallicRoughness = material.pbrMetallicRoughness;\n const baseColorTexture = pbrMetallicRoughness.baseColorTexture || pbrMetallicRoughness.colorTexture;\n if (baseColorTexture) {\n if (baseColorTexture.texture) {\n textureSetCfg.colorTextureId = baseColorTexture.texture._textureId;\n } else {\n textureSetCfg.colorTextureId = ctx.gltfData.textures[baseColorTexture.index]._textureId;\n }\n }\n if (metallicPBR.metallicRoughnessTexture) {\n textureSetCfg.metallicRoughnessTextureId = metallicPBR.metallicRoughnessTexture.texture._textureId;\n }\n }\n const extensions = material.extensions;\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const specularTexture = specularPBR.specularTexture;\n if (specularTexture !== null && specularTexture !== undefined) {\n // textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n }\n const specularColorTexture = specularPBR.specularColorTexture;\n if (specularColorTexture !== null && specularColorTexture !== undefined) {\n textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n }\n }\n }\n if (textureSetCfg.normalTextureId !== undefined ||\n textureSetCfg.occlusionTextureId !== undefined ||\n textureSetCfg.emissiveTextureId !== undefined ||\n textureSetCfg.colorTextureId !== undefined ||\n textureSetCfg.metallicRoughnessTextureId !== undefined) {\n textureSetCfg.textureSetId = `textureSet-${ctx.nextId++};`\n ctx.xktModel.createTextureSet(textureSetCfg);\n ctx.stats.numTextureSets++;\n return textureSetCfg.textureSetId;\n }\n return null;\n}\n\nfunction parseMaterialAttributes(ctx, material) { // Substitute RGBA for material, to use fast flat shading instead\n const extensions = material.extensions;\n const materialAttributes = {\n color: new Float32Array([1, 1, 1, 1]),\n opacity: 1,\n metallic: 0,\n roughness: 1\n };\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const diffuseFactor = specularPBR.diffuseFactor;\n if (diffuseFactor !== null && diffuseFactor !== undefined) {\n materialAttributes.color.set(diffuseFactor);\n }\n }\n const common = extensions[\"KHR_materials_common\"];\n if (common) {\n const technique = common.technique;\n const values = common.values || {};\n const blinn = technique === \"BLINN\";\n const phong = technique === \"PHONG\";\n const lambert = technique === \"LAMBERT\";\n const diffuse = values.diffuse;\n if (diffuse && (blinn || phong || lambert)) {\n if (!utils.isString(diffuse)) {\n materialAttributes.color.set(diffuse);\n }\n }\n const transparency = values.transparency;\n if (transparency !== null && transparency !== undefined) {\n materialAttributes.opacity = transparency;\n }\n const transparent = values.transparent;\n if (transparent !== null && transparent !== undefined) {\n materialAttributes.opacity = transparent;\n }\n }\n }\n const metallicPBR = material.pbrMetallicRoughness;\n if (metallicPBR) {\n const baseColorFactor = metallicPBR.baseColorFactor;\n if (baseColorFactor) {\n materialAttributes.color[0] = baseColorFactor[0];\n materialAttributes.color[1] = baseColorFactor[1];\n materialAttributes.color[2] = baseColorFactor[2];\n materialAttributes.opacity = baseColorFactor[3];\n }\n const metallicFactor = metallicPBR.metallicFactor;\n if (metallicFactor !== null && metallicFactor !== undefined) {\n materialAttributes.metallic = metallicFactor;\n }\n const roughnessFactor = metallicPBR.roughnessFactor;\n if (roughnessFactor !== null && roughnessFactor !== undefined) {\n materialAttributes.roughness = roughnessFactor;\n }\n }\n return materialAttributes;\n}\n\nfunction parseDefaultScene(ctx) {\n const gltfData = ctx.gltfData;\n const scene = gltfData.scene || gltfData.scenes[0];\n if (!scene) {\n ctx.error(\"glTF has no default scene\");\n return;\n }\n parseScene(ctx, scene);\n}\n\nfunction parseScene(ctx, scene) {\n const nodes = scene.nodes;\n if (!nodes) {\n return;\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const node = nodes[i];\n countMeshUsage(ctx, node);\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const node = nodes[i];\n parseNode(ctx, node, 0, null);\n }\n}\n\nfunction countMeshUsage(ctx, node) {\n const mesh = node.mesh;\n if (mesh !== null && mesh !== undefined) {\n mesh.instances = mesh.instances ? mesh.instances + 1 : 1;\n }\n if (node.children) {\n const children = node.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNode = children[i];\n if (!childNode) {\n ctx.error(\"Node not found: \" + i);\n continue;\n }\n countMeshUsage(ctx, childNode);\n }\n }\n}\n\nconst objectIdStack = [];\nconst meshIdsStack = [];\n\nlet meshIds = null;\n\nfunction parseNode(ctx, node, depth, matrix) {\n\n const xktModel = ctx.xktModel;\n\n // Pre-order visit scene node\n\n let localMatrix;\n if (node.matrix) {\n localMatrix = node.matrix;\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.translation) {\n localMatrix = math.translationMat4v(node.translation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.rotation) {\n localMatrix = math.quaternionToMat4(node.rotation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.scale) {\n localMatrix = math.scalingMat4v(node.scale);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n\n if (node.name) {\n meshIds = [];\n let xktEntityId = node.name;\n if (!!xktEntityId && xktModel.entities[xktEntityId]) {\n ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${xktEntityId} - will randomly-generating an object ID in XKT`);\n }\n while (!xktEntityId || xktModel.entities[xktEntityId]) {\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n objectIdStack.push(xktEntityId);\n meshIdsStack.push(meshIds);\n }\n\n if (meshIds && node.mesh !== undefined && node.mesh !== null) {\n\n const mesh = node.mesh;\n const numPrimitives = mesh.primitives.length;\n\n if (numPrimitives > 0) {\n for (let i = 0; i < numPrimitives; i++) {\n const primitive = mesh.primitives[i];\n if (!primitive._xktGeometryId) {\n const xktGeometryId = \"geometry-\" + ctx.nextId++;\n const geometryCfg = {\n geometryId: xktGeometryId\n };\n switch (primitive.mode) {\n case 0: // POINTS\n geometryCfg.primitiveType = \"points\";\n break;\n case 1: // LINES\n geometryCfg.primitiveType = \"lines\";\n break;\n case 2: // LINE_LOOP\n geometryCfg.primitiveType = \"line-loop\";\n break;\n case 3: // LINE_STRIP\n geometryCfg.primitiveType = \"line-strip\";\n break;\n case 4: // TRIANGLES\n geometryCfg.primitiveType = \"triangles\";\n break;\n case 5: // TRIANGLE_STRIP\n geometryCfg.primitiveType = \"triangle-strip\";\n break;\n case 6: // TRIANGLE_FAN\n geometryCfg.primitiveType = \"triangle-fan\";\n break;\n default:\n geometryCfg.primitiveType = \"triangles\";\n }\n const POSITION = primitive.attributes.POSITION;\n if (!POSITION) {\n continue;\n }\n geometryCfg.positions = primitive.attributes.POSITION.value;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n if (ctx.includeNormals) {\n if (primitive.attributes.NORMAL) {\n geometryCfg.normals = primitive.attributes.NORMAL.value;\n ctx.stats.numNormals += geometryCfg.normals.length / 3;\n }\n }\n if (primitive.attributes.COLOR_0) {\n geometryCfg.colorsCompressed = primitive.attributes.COLOR_0.value;\n }\n if (ctx.includeTextures) {\n if (primitive.attributes.TEXCOORD_0) {\n geometryCfg.uvs = primitive.attributes.TEXCOORD_0.value;\n ctx.stats.numUVs += geometryCfg.uvs.length / 2;\n }\n }\n if (primitive.indices) {\n geometryCfg.indices = primitive.indices.value;\n if (primitive.mode === 4) {\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n }\n }\n xktModel.createGeometry(geometryCfg);\n primitive._xktGeometryId = xktGeometryId;\n ctx.stats.numGeometries++;\n }\n\n const xktMeshId = ctx.nextId++;\n const meshCfg = {\n meshId: xktMeshId,\n geometryId: primitive._xktGeometryId,\n matrix: matrix ? matrix.slice() : math.identityMat4()\n };\n const material = primitive.material;\n if (material) {\n meshCfg.textureSetId = material._textureSetId;\n meshCfg.color = material._attributes.color;\n meshCfg.opacity = material._attributes.opacity;\n meshCfg.metallic = material._attributes.metallic;\n meshCfg.roughness = material._attributes.roughness;\n } else {\n meshCfg.color = [1.0, 1.0, 1.0];\n meshCfg.opacity = 1.0;\n }\n xktModel.createMesh(meshCfg);\n meshIds.push(xktMeshId);\n }\n }\n }\n\n // Visit child scene nodes\n\n if (node.children) {\n const children = node.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNode = children[i];\n parseNode(ctx, childNode, depth + 1, matrix);\n }\n }\n\n // Post-order visit scene node\n\n const nodeName = node.name;\n if ((nodeName !== undefined && nodeName !== null) || depth === 0) {\n if (nodeName === undefined || nodeName === null) {\n ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);\n }\n let xktEntityId = objectIdStack.pop();\n if (!xktEntityId) { // For when there are no nodes with names\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n let entityMeshIds = meshIdsStack.pop();\n if (meshIds && meshIds.length > 0) {\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: entityMeshIds\n });\n }\n ctx.stats.numObjects++;\n meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null;\n }\n}\n\nexport {parseGLTFIntoXKTModel};", + "name": "src/parsers/parseGLTFIntoXKTModel.js", + "content": "import {utils} from \"../XKTModel/lib/utils.js\";\nimport {math} from \"../lib/math.js\";\n\nimport {parse} from '@loaders.gl/core';\nimport {GLTFLoader} from '@loaders.gl/gltf';\nimport {\n ClampToEdgeWrapping,\n LinearFilter,\n LinearMipMapLinearFilter,\n LinearMipMapNearestFilter,\n MirroredRepeatWrapping,\n NearestFilter,\n NearestMipMapLinearFilter,\n NearestMipMapNearestFilter,\n RepeatWrapping\n} from \"../constants.js\";\n\n/**\n * @desc Parses glTF into an {@link XKTModel}, supporting ````.glb```` and textures.\n *\n * * Supports ````.glb```` and textures\n * * For a lightweight glTF JSON parser that ignores textures, see {@link parseGLTFJSONIntoXKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a binary glTF model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"../assets/models/gltf/HousePlan/glTF-Binary/HousePlan.glb\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseGLTFIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing parameters.\n * @param {ArrayBuffer} params.data The glTF.\n * @param {String} [params.baseUri] The base URI used to load this glTF, if any. For resolving relative uris to linked resources.\n * @param {Object} [params.metaModelData] Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Boolean} [params.includeTextures=true] Whether to parse textures.\n * @param {Boolean} [params.includeNormals=true] Whether to parse normals. When false, the parser will ignore the glTF\n * geometry normals, and the glTF data will rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the glTF.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when glTF has been parsed.\n */\nfunction parseGLTFIntoXKTModel({\n data,\n baseUri,\n xktModel,\n metaModelData,\n includeTextures = true,\n includeNormals = true,\n getAttachment,\n stats = {},\n log\n }) {\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n stats.sourceFormat = \"glTF\";\n stats.schemaVersion = \"2.0\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numUVs = 0;\n stats.numTextures = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n parse(data, GLTFLoader, {\n baseUri\n }).then((gltfData) => {\n\n const ctx = {\n gltfData,\n metaModelCorrections: metaModelData,\n getAttachment: getAttachment || (() => {\n throw new Error('You must define getAttachment() method to convert glTF with external resources')\n }),\n log: (log || function (msg) {\n }),\n error: function (msg) {\n console.error(msg);\n },\n xktModel,\n includeNormals: (includeNormals !== false),\n includeTextures: (includeTextures !== false),\n geometryCreated: {},\n nextId: 0,\n stats\n };\n\n ctx.log(\"Using parser: parseGLTFIntoXKTModel\");\n ctx.log(`Parsing normals: ${ctx.includeNormals ? \"enabled\" : \"disabled\"}`);\n ctx.log(`Parsing textures: ${ctx.includeTextures ? \"enabled\" : \"disabled\"}`);\n\n if (ctx.includeTextures) {\n parseTextures(ctx);\n }\n parseMaterials(ctx);\n parseDefaultScene(ctx);\n\n resolve();\n\n }, (errMsg) => {\n reject(`[parseGLTFIntoXKTModel] ${errMsg}`);\n });\n });\n}\n\nfunction parseTextures(ctx) {\n const gltfData = ctx.gltfData;\n const textures = gltfData.textures;\n if (textures) {\n for (let i = 0, len = textures.length; i < len; i++) {\n parseTexture(ctx, textures[i]);\n ctx.stats.numTextures++;\n }\n }\n}\n\nfunction parseTexture(ctx, texture) {\n if (!texture.source || !texture.source.image) {\n return;\n }\n const textureId = `texture-${ctx.nextId++}`;\n\n let minFilter = NearestMipMapLinearFilter;\n switch (texture.sampler.minFilter) {\n case 9728:\n minFilter = NearestFilter;\n break;\n case 9729:\n minFilter = LinearFilter;\n break;\n case 9984:\n minFilter = NearestMipMapNearestFilter;\n break;\n case 9985:\n minFilter = LinearMipMapNearestFilter;\n break;\n case 9986:\n minFilter = NearestMipMapLinearFilter;\n break;\n case 9987:\n minFilter = LinearMipMapLinearFilter;\n break;\n }\n\n let magFilter = LinearFilter;\n switch (texture.sampler.magFilter) {\n case 9728:\n magFilter = NearestFilter;\n break;\n case 9729:\n magFilter = LinearFilter;\n break;\n }\n\n let wrapS = RepeatWrapping;\n switch (texture.sampler.wrapS) {\n case 33071:\n wrapS = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapS = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapS = RepeatWrapping;\n break;\n }\n\n let wrapT = RepeatWrapping;\n switch (texture.sampler.wrapT) {\n case 33071:\n wrapT = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapT = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapT = RepeatWrapping;\n break;\n }\n\n let wrapR = RepeatWrapping;\n switch (texture.sampler.wrapR) {\n case 33071:\n wrapR = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapR = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapR = RepeatWrapping;\n break;\n }\n\n ctx.xktModel.createTexture({\n textureId: textureId,\n imageData: texture.source.image,\n mediaType: texture.source.mediaType,\n compressed: true,\n width: texture.source.image.width,\n height: texture.source.image.height,\n minFilter,\n magFilter,\n wrapS,\n wrapT,\n wrapR,\n flipY: !!texture.flipY,\n // encoding: \"sRGB\"\n });\n texture._textureId = textureId;\n}\n\nfunction parseMaterials(ctx) {\n const gltfData = ctx.gltfData;\n const materials = gltfData.materials;\n if (materials) {\n for (let i = 0, len = materials.length; i < len; i++) {\n const material = materials[i];\n material._textureSetId = ctx.includeTextures ? parseTextureSet(ctx, material) : null;\n material._attributes = parseMaterialAttributes(ctx, material);\n }\n }\n}\n\nfunction parseTextureSet(ctx, material) {\n const textureSetCfg = {};\n if (material.normalTexture) {\n textureSetCfg.normalTextureId = material.normalTexture.texture._textureId;\n }\n if (material.occlusionTexture) {\n textureSetCfg.occlusionTextureId = material.occlusionTexture.texture._textureId;\n }\n if (material.emissiveTexture) {\n textureSetCfg.emissiveTextureId = material.emissiveTexture.texture._textureId;\n }\n // const alphaMode = material.alphaMode;\n // switch (alphaMode) {\n // case \"NORMAL_OPAQUE\":\n // materialCfg.alphaMode = \"opaque\";\n // break;\n // case \"MASK\":\n // materialCfg.alphaMode = \"mask\";\n // break;\n // case \"BLEND\":\n // materialCfg.alphaMode = \"blend\";\n // break;\n // default:\n // }\n // const alphaCutoff = material.alphaCutoff;\n // if (alphaCutoff !== undefined) {\n // materialCfg.alphaCutoff = alphaCutoff;\n // }\n const metallicPBR = material.pbrMetallicRoughness;\n if (material.pbrMetallicRoughness) {\n const pbrMetallicRoughness = material.pbrMetallicRoughness;\n const baseColorTexture = pbrMetallicRoughness.baseColorTexture || pbrMetallicRoughness.colorTexture;\n if (baseColorTexture) {\n if (baseColorTexture.texture) {\n textureSetCfg.colorTextureId = baseColorTexture.texture._textureId;\n } else {\n textureSetCfg.colorTextureId = ctx.gltfData.textures[baseColorTexture.index]._textureId;\n }\n }\n if (metallicPBR.metallicRoughnessTexture) {\n textureSetCfg.metallicRoughnessTextureId = metallicPBR.metallicRoughnessTexture.texture._textureId;\n }\n }\n const extensions = material.extensions;\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const specularTexture = specularPBR.specularTexture;\n if (specularTexture !== null && specularTexture !== undefined) {\n // textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n }\n const specularColorTexture = specularPBR.specularColorTexture;\n if (specularColorTexture !== null && specularColorTexture !== undefined) {\n textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n }\n }\n }\n if (textureSetCfg.normalTextureId !== undefined ||\n textureSetCfg.occlusionTextureId !== undefined ||\n textureSetCfg.emissiveTextureId !== undefined ||\n textureSetCfg.colorTextureId !== undefined ||\n textureSetCfg.metallicRoughnessTextureId !== undefined) {\n textureSetCfg.textureSetId = `textureSet-${ctx.nextId++};`\n ctx.xktModel.createTextureSet(textureSetCfg);\n ctx.stats.numTextureSets++;\n return textureSetCfg.textureSetId;\n }\n return null;\n}\n\nfunction parseMaterialAttributes(ctx, material) { // Substitute RGBA for material, to use fast flat shading instead\n const extensions = material.extensions;\n const materialAttributes = {\n color: new Float32Array([1, 1, 1, 1]),\n opacity: 1,\n metallic: 0,\n roughness: 1\n };\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const diffuseFactor = specularPBR.diffuseFactor;\n if (diffuseFactor !== null && diffuseFactor !== undefined) {\n materialAttributes.color.set(diffuseFactor);\n }\n }\n const common = extensions[\"KHR_materials_common\"];\n if (common) {\n const technique = common.technique;\n const values = common.values || {};\n const blinn = technique === \"BLINN\";\n const phong = technique === \"PHONG\";\n const lambert = technique === \"LAMBERT\";\n const diffuse = values.diffuse;\n if (diffuse && (blinn || phong || lambert)) {\n if (!utils.isString(diffuse)) {\n materialAttributes.color.set(diffuse);\n }\n }\n const transparency = values.transparency;\n if (transparency !== null && transparency !== undefined) {\n materialAttributes.opacity = transparency;\n }\n const transparent = values.transparent;\n if (transparent !== null && transparent !== undefined) {\n materialAttributes.opacity = transparent;\n }\n }\n }\n const metallicPBR = material.pbrMetallicRoughness;\n if (metallicPBR) {\n const baseColorFactor = metallicPBR.baseColorFactor;\n if (baseColorFactor) {\n materialAttributes.color[0] = baseColorFactor[0];\n materialAttributes.color[1] = baseColorFactor[1];\n materialAttributes.color[2] = baseColorFactor[2];\n materialAttributes.opacity = baseColorFactor[3];\n }\n const metallicFactor = metallicPBR.metallicFactor;\n if (metallicFactor !== null && metallicFactor !== undefined) {\n materialAttributes.metallic = metallicFactor;\n }\n const roughnessFactor = metallicPBR.roughnessFactor;\n if (roughnessFactor !== null && roughnessFactor !== undefined) {\n materialAttributes.roughness = roughnessFactor;\n }\n }\n return materialAttributes;\n}\n\nfunction parseDefaultScene(ctx) {\n const gltfData = ctx.gltfData;\n const scene = gltfData.scene || gltfData.scenes[0];\n if (!scene) {\n ctx.error(\"glTF has no default scene\");\n return;\n }\n parseScene(ctx, scene);\n}\n\nfunction parseScene(ctx, scene) {\n const nodes = scene.nodes;\n if (!nodes) {\n return;\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const node = nodes[i];\n countMeshUsage(ctx, node);\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const node = nodes[i];\n parseNode(ctx, node, 0, null);\n }\n}\n\nfunction countMeshUsage(ctx, node) {\n const mesh = node.mesh;\n if (mesh) {\n mesh.instances = mesh.instances ? mesh.instances + 1 : 1;\n }\n if (node.children) {\n const children = node.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNode = children[i];\n if (!childNode) {\n ctx.error(\"Node not found: \" + i);\n continue;\n }\n countMeshUsage(ctx, childNode);\n }\n }\n}\n\nconst objectIdStack = [];\nconst meshIdsStack = [];\n\nlet meshIds = null;\n\nfunction parseNode(ctx, node, depth, matrix) {\n\n const xktModel = ctx.xktModel;\n\n // Pre-order visit scene node\n\n let localMatrix;\n if (node.matrix) {\n localMatrix = node.matrix;\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.translation) {\n localMatrix = math.translationMat4v(node.translation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.rotation) {\n localMatrix = math.quaternionToMat4(node.rotation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.scale) {\n localMatrix = math.scalingMat4v(node.scale);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n\n if (node.name) {\n meshIds = [];\n let xktEntityId = node.name;\n if (!!xktEntityId && xktModel.entities[xktEntityId]) {\n ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${xktEntityId} - will randomly-generating an object ID in XKT`);\n }\n while (!xktEntityId || xktModel.entities[xktEntityId]) {\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n objectIdStack.push(xktEntityId);\n meshIdsStack.push(meshIds);\n }\n\n if (meshIds && node.mesh) {\n\n const mesh = node.mesh;\n const numPrimitives = mesh.primitives.length;\n\n if (numPrimitives > 0) {\n for (let i = 0; i < numPrimitives; i++) {\n const primitive = mesh.primitives[i];\n if (!primitive._xktGeometryId) {\n const xktGeometryId = \"geometry-\" + ctx.nextId++;\n const geometryCfg = {\n geometryId: xktGeometryId\n };\n switch (primitive.mode) {\n case 0: // POINTS\n geometryCfg.primitiveType = \"points\";\n break;\n case 1: // LINES\n geometryCfg.primitiveType = \"lines\";\n break;\n case 2: // LINE_LOOP\n geometryCfg.primitiveType = \"line-loop\";\n break;\n case 3: // LINE_STRIP\n geometryCfg.primitiveType = \"line-strip\";\n break;\n case 4: // TRIANGLES\n geometryCfg.primitiveType = \"triangles\";\n break;\n case 5: // TRIANGLE_STRIP\n geometryCfg.primitiveType = \"triangle-strip\";\n break;\n case 6: // TRIANGLE_FAN\n geometryCfg.primitiveType = \"triangle-fan\";\n break;\n default:\n geometryCfg.primitiveType = \"triangles\";\n }\n const POSITION = primitive.attributes.POSITION;\n if (!POSITION) {\n continue;\n }\n geometryCfg.positions = primitive.attributes.POSITION.value;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n if (ctx.includeNormals) {\n if (primitive.attributes.NORMAL) {\n geometryCfg.normals = primitive.attributes.NORMAL.value;\n ctx.stats.numNormals += geometryCfg.normals.length / 3;\n }\n }\n if (primitive.attributes.COLOR_0) {\n geometryCfg.colorsCompressed = primitive.attributes.COLOR_0.value;\n }\n if (ctx.includeTextures) {\n if (primitive.attributes.TEXCOORD_0) {\n geometryCfg.uvs = primitive.attributes.TEXCOORD_0.value;\n ctx.stats.numUVs += geometryCfg.uvs.length / 2;\n }\n }\n if (primitive.indices) {\n geometryCfg.indices = primitive.indices.value;\n if (primitive.mode === 4) {\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n }\n }\n xktModel.createGeometry(geometryCfg);\n primitive._xktGeometryId = xktGeometryId;\n ctx.stats.numGeometries++;\n }\n\n const xktMeshId = ctx.nextId++;\n const meshCfg = {\n meshId: xktMeshId,\n geometryId: primitive._xktGeometryId,\n matrix: matrix ? matrix.slice() : math.identityMat4()\n };\n const material = primitive.material;\n if (material) {\n meshCfg.textureSetId = material._textureSetId;\n meshCfg.color = material._attributes.color;\n meshCfg.opacity = material._attributes.opacity;\n meshCfg.metallic = material._attributes.metallic;\n meshCfg.roughness = material._attributes.roughness;\n } else {\n meshCfg.color = [1.0, 1.0, 1.0];\n meshCfg.opacity = 1.0;\n }\n xktModel.createMesh(meshCfg);\n meshIds.push(xktMeshId);\n }\n }\n }\n\n // Visit child scene nodes\n\n if (node.children) {\n const children = node.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNode = children[i];\n parseNode(ctx, childNode, depth + 1, matrix);\n }\n }\n\n // Post-order visit scene node\n\n const nodeName = node.name;\n if ((nodeName !== undefined && nodeName !== null) || depth === 0) {\n if (nodeName === undefined || nodeName === null) {\n ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);\n }\n let xktEntityId = objectIdStack.pop();\n if (!xktEntityId) { // For when there are no nodes with names\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n let entityMeshIds = meshIdsStack.pop();\n if (meshIds && meshIds.length > 0) {\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: entityMeshIds\n });\n }\n ctx.stats.numObjects++;\n meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null;\n }\n}\n\nexport {parseGLTFIntoXKTModel};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/parsers/parseGLTFIntoXKTModel.OLD.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 419, + "__docId__": 421, "kind": "function", "name": "parseTextures", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", + "memberof": "src/parsers/parseGLTFIntoXKTModel.js", "generator": false, "async": false, "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~parseTextures", + "longname": "src/parsers/parseGLTFIntoXKTModel.js~parseTextures", "access": "public", "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", + "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", "importStyle": null, "description": null, "lineNumber": 138, @@ -11681,17 +11740,17 @@ "ignore": true }, { - "__docId__": 420, + "__docId__": 422, "kind": "function", "name": "parseTexture", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", + "memberof": "src/parsers/parseGLTFIntoXKTModel.js", "generator": false, "async": false, "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~parseTexture", + "longname": "src/parsers/parseGLTFIntoXKTModel.js~parseTexture", "access": "public", "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", + "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", "importStyle": null, "description": null, "lineNumber": 149, @@ -11714,17 +11773,17 @@ "ignore": true }, { - "__docId__": 421, + "__docId__": 423, "kind": "function", "name": "parseMaterials", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", + "memberof": "src/parsers/parseGLTFIntoXKTModel.js", "generator": false, "async": false, "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~parseMaterials", + "longname": "src/parsers/parseGLTFIntoXKTModel.js~parseMaterials", "access": "public", "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", + "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", "importStyle": null, "description": null, "lineNumber": 244, @@ -11741,17 +11800,17 @@ "ignore": true }, { - "__docId__": 422, + "__docId__": 424, "kind": "function", "name": "parseTextureSet", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", + "memberof": "src/parsers/parseGLTFIntoXKTModel.js", "generator": false, "async": false, "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~parseTextureSet", + "longname": "src/parsers/parseGLTFIntoXKTModel.js~parseTextureSet", "access": "public", "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", + "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", "importStyle": null, "description": null, "lineNumber": 256, @@ -11778,17 +11837,17 @@ "ignore": true }, { - "__docId__": 423, + "__docId__": 425, "kind": "function", "name": "parseMaterialAttributes", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", + "memberof": "src/parsers/parseGLTFIntoXKTModel.js", "generator": false, "async": false, "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~parseMaterialAttributes", + "longname": "src/parsers/parseGLTFIntoXKTModel.js~parseMaterialAttributes", "access": "public", "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", + "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", "importStyle": null, "description": null, "lineNumber": 326, @@ -11815,506 +11874,7 @@ "ignore": true }, { - "__docId__": 424, - "kind": "function", - "name": "parseDefaultScene", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", - "generator": false, - "async": false, - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~parseDefaultScene", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", - "importStyle": null, - "description": null, - "lineNumber": 386, - "undocument": true, - "params": [ - { - "name": "ctx", - "types": [ - "*" - ] - } - ], - "return": null, - "ignore": true - }, - { - "__docId__": 425, - "kind": "function", - "name": "parseScene", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", - "generator": false, - "async": false, - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~parseScene", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", - "importStyle": null, - "description": null, - "lineNumber": 396, - "undocument": true, - "params": [ - { - "name": "ctx", - "types": [ - "*" - ] - }, - { - "name": "scene", - "types": [ - "*" - ] - } - ], - "return": null, - "ignore": true - }, - { - "__docId__": 426, - "kind": "function", - "name": "countMeshUsage", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", - "generator": false, - "async": false, - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~countMeshUsage", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", - "importStyle": null, - "description": null, - "lineNumber": 411, - "undocument": true, - "params": [ - { - "name": "ctx", - "types": [ - "*" - ] - }, - { - "name": "node", - "types": [ - "*" - ] - } - ], - "return": null, - "ignore": true - }, - { - "__docId__": 427, - "kind": "variable", - "name": "objectIdStack", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~objectIdStack", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", - "importStyle": null, - "description": null, - "lineNumber": 429, - "undocument": true, - "type": { - "types": [ - "*[]" - ] - }, - "ignore": true - }, - { - "__docId__": 428, - "kind": "variable", - "name": "meshIdsStack", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~meshIdsStack", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", - "importStyle": null, - "description": null, - "lineNumber": 430, - "undocument": true, - "type": { - "types": [ - "*[]" - ] - }, - "ignore": true - }, - { - "__docId__": 429, - "kind": "variable", - "name": "meshIds", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~meshIds", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", - "importStyle": null, - "description": null, - "lineNumber": 432, - "undocument": true, - "type": { - "types": [ - "*" - ] - }, - "ignore": true - }, - { - "__docId__": 430, - "kind": "function", - "name": "parseNode", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", - "generator": false, - "async": false, - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~parseNode", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", - "importStyle": null, - "description": null, - "lineNumber": 434, - "undocument": true, - "params": [ - { - "name": "ctx", - "types": [ - "*" - ] - }, - { - "name": "node", - "types": [ - "*" - ] - }, - { - "name": "depth", - "types": [ - "*" - ] - }, - { - "name": "matrix", - "types": [ - "*" - ] - } - ], - "return": null, - "ignore": true - }, - { - "__docId__": 431, - "kind": "function", - "name": "parseGLTFIntoXKTModel", - "memberof": "src/parsers/parseGLTFIntoXKTModel.OLD.js", - "generator": false, - "async": false, - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.OLD.js~parseGLTFIntoXKTModel", - "access": "public", - "export": true, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", - "importStyle": "{parseGLTFIntoXKTModel}", - "description": "Parses glTF into an {@link XKTModel}, supporting ````.glb```` and textures.\n\n* Supports ````.glb```` and textures\n* For a lightweight glTF JSON parser that ignores textures, see {@link parseGLTFJSONIntoXKTModel}.\n\n## Usage\n\nIn the example below we'll create an {@link XKTModel}, then load a binary glTF model into it.\n\n````javascript\nutils.loadArraybuffer(\"../assets/models/gltf/HousePlan/glTF-Binary/HousePlan.glb\", async (data) => {\n\n const xktModel = new XKTModel();\n\n parseGLTFIntoXKTModel({\n data,\n xktModel,\n log: (msg) => { console.log(msg); }\n }).then(()=>{\n xktModel.finalize();\n },\n (msg) => {\n console.error(msg);\n });\n});\n````", - "lineNumber": 60, - "unknown": [ - { - "tagName": "@returns", - "tagValue": "{Promise} Resolves when glTF has been parsed." - } - ], - "params": [ - { - "nullable": null, - "types": [ - "Object" - ], - "spread": false, - "optional": false, - "name": "params", - "description": "Parsing parameters." - }, - { - "nullable": null, - "types": [ - "ArrayBuffer" - ], - "spread": false, - "optional": false, - "name": "params.data", - "description": "The glTF." - }, - { - "nullable": null, - "types": [ - "String" - ], - "spread": false, - "optional": true, - "name": "params.baseUri", - "description": "The base URI used to load this glTF, if any. For resolving relative uris to linked resources." - }, - { - "nullable": null, - "types": [ - "Object" - ], - "spread": false, - "optional": true, - "name": "params.metaModelData", - "description": "Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly." - }, - { - "nullable": null, - "types": [ - "XKTModel" - ], - "spread": false, - "optional": false, - "name": "params.xktModel", - "description": "XKTModel to parse into." - }, - { - "nullable": null, - "types": [ - "Boolean" - ], - "spread": false, - "optional": true, - "defaultValue": "true", - "defaultRaw": true, - "name": "params.includeTextures", - "description": "Whether to parse textures." - }, - { - "nullable": null, - "types": [ - "Boolean" - ], - "spread": false, - "optional": true, - "defaultValue": "true", - "defaultRaw": true, - "name": "params.includeNormals", - "description": "Whether to parse normals. When false, the parser will ignore the glTF\ngeometry normals, and the glTF data will rely on the xeokit ````Viewer```` to automatically generate them. This has\nthe limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\na flat-shaded non-PBR representation of the glTF." - }, - { - "nullable": null, - "types": [ - "Object" - ], - "spread": false, - "optional": true, - "name": "params.stats", - "description": "Collects statistics." - }, - { - "nullable": null, - "types": [ - "function" - ], - "spread": false, - "optional": true, - "name": "params.log", - "description": "Logging callback." - } - ], - "return": { - "nullable": null, - "types": [ - "Promise" - ], - "spread": false, - "description": "Resolves when glTF has been parsed." - } - }, - { - "__docId__": 432, - "kind": "file", - "name": "src/parsers/parseGLTFIntoXKTModel.js", - "content": "import {utils} from \"../XKTModel/lib/utils.js\";\nimport {math} from \"../lib/math.js\";\n\nimport {parse} from '@loaders.gl/core';\nimport {GLTFLoader} from '@loaders.gl/gltf';\nimport {\n ClampToEdgeWrapping,\n LinearFilter,\n LinearMipMapLinearFilter,\n LinearMipMapNearestFilter,\n MirroredRepeatWrapping,\n NearestFilter,\n NearestMipMapLinearFilter,\n NearestMipMapNearestFilter,\n RepeatWrapping\n} from \"../constants.js\";\n\n/**\n * @desc Parses glTF into an {@link XKTModel}, supporting ````.glb```` and textures.\n *\n * * Supports ````.glb```` and textures\n * * For a lightweight glTF JSON parser that ignores textures, see {@link parseGLTFJSONIntoXKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a binary glTF model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"../assets/models/gltf/HousePlan/glTF-Binary/HousePlan.glb\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseGLTFIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing parameters.\n * @param {ArrayBuffer} params.data The glTF.\n * @param {String} [params.baseUri] The base URI used to load this glTF, if any. For resolving relative uris to linked resources.\n * @param {Object} [params.metaModelData] Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Boolean} [params.includeTextures=true] Whether to parse textures.\n * @param {Boolean} [params.includeNormals=true] Whether to parse normals. When false, the parser will ignore the glTF\n * geometry normals, and the glTF data will rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded non-PBR representation of the glTF.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when glTF has been parsed.\n */\nfunction parseGLTFIntoXKTModel({\n data,\n baseUri,\n xktModel,\n metaModelData,\n includeTextures = true,\n includeNormals = true,\n getAttachment,\n stats = {},\n log\n }) {\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n stats.sourceFormat = \"glTF\";\n stats.schemaVersion = \"2.0\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numUVs = 0;\n stats.numTextures = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n parse(data, GLTFLoader, {\n baseUri\n }).then((gltfData) => {\n\n const ctx = {\n gltfData,\n metaModelCorrections: metaModelData,\n getAttachment: getAttachment || (() => {\n throw new Error('You must define getAttachment() method to convert glTF with external resources')\n }),\n log: (log || function (msg) {\n }),\n error: function (msg) {\n console.error(msg);\n },\n xktModel,\n includeNormals: (includeNormals !== false),\n includeTextures: (includeTextures !== false),\n geometryCreated: {},\n nextId: 0,\n stats\n };\n\n ctx.log(\"Using parser: parseGLTFIntoXKTModel\");\n ctx.log(`Parsing normals: ${ctx.includeNormals ? \"enabled\" : \"disabled\"}`);\n ctx.log(`Parsing textures: ${ctx.includeTextures ? \"enabled\" : \"disabled\"}`);\n\n if (ctx.includeTextures) {\n parseTextures(ctx);\n }\n parseMaterials(ctx);\n parseDefaultScene(ctx);\n\n resolve();\n\n }, (errMsg) => {\n reject(`[parseGLTFIntoXKTModel] ${errMsg}`);\n });\n });\n}\n\nfunction parseTextures(ctx) {\n const gltfData = ctx.gltfData;\n const textures = gltfData.textures;\n if (textures) {\n for (let i = 0, len = textures.length; i < len; i++) {\n parseTexture(ctx, textures[i]);\n ctx.stats.numTextures++;\n }\n }\n}\n\nfunction parseTexture(ctx, texture) {\n if (!texture.source || !texture.source.image) {\n return;\n }\n const textureId = `texture-${ctx.nextId++}`;\n\n let minFilter = NearestMipMapLinearFilter;\n switch (texture.sampler.minFilter) {\n case 9728:\n minFilter = NearestFilter;\n break;\n case 9729:\n minFilter = LinearFilter;\n break;\n case 9984:\n minFilter = NearestMipMapNearestFilter;\n break;\n case 9985:\n minFilter = LinearMipMapNearestFilter;\n break;\n case 9986:\n minFilter = NearestMipMapLinearFilter;\n break;\n case 9987:\n minFilter = LinearMipMapLinearFilter;\n break;\n }\n\n let magFilter = LinearFilter;\n switch (texture.sampler.magFilter) {\n case 9728:\n magFilter = NearestFilter;\n break;\n case 9729:\n magFilter = LinearFilter;\n break;\n }\n\n let wrapS = RepeatWrapping;\n switch (texture.sampler.wrapS) {\n case 33071:\n wrapS = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapS = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapS = RepeatWrapping;\n break;\n }\n\n let wrapT = RepeatWrapping;\n switch (texture.sampler.wrapT) {\n case 33071:\n wrapT = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapT = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapT = RepeatWrapping;\n break;\n }\n\n let wrapR = RepeatWrapping;\n switch (texture.sampler.wrapR) {\n case 33071:\n wrapR = ClampToEdgeWrapping;\n break;\n case 33648:\n wrapR = MirroredRepeatWrapping;\n break;\n case 10497:\n wrapR = RepeatWrapping;\n break;\n }\n\n ctx.xktModel.createTexture({\n textureId: textureId,\n imageData: texture.source.image,\n mediaType: texture.source.mediaType,\n compressed: true,\n width: texture.source.image.width,\n height: texture.source.image.height,\n minFilter,\n magFilter,\n wrapS,\n wrapT,\n wrapR,\n flipY: !!texture.flipY,\n // encoding: \"sRGB\"\n });\n texture._textureId = textureId;\n}\n\nfunction parseMaterials(ctx) {\n const gltfData = ctx.gltfData;\n const materials = gltfData.materials;\n if (materials) {\n for (let i = 0, len = materials.length; i < len; i++) {\n const material = materials[i];\n material._textureSetId = ctx.includeTextures ? parseTextureSet(ctx, material) : null;\n material._attributes = parseMaterialAttributes(ctx, material);\n }\n }\n}\n\nfunction parseTextureSet(ctx, material) {\n const textureSetCfg = {};\n if (material.normalTexture) {\n textureSetCfg.normalTextureId = material.normalTexture.texture._textureId;\n }\n if (material.occlusionTexture) {\n textureSetCfg.occlusionTextureId = material.occlusionTexture.texture._textureId;\n }\n if (material.emissiveTexture) {\n textureSetCfg.emissiveTextureId = material.emissiveTexture.texture._textureId;\n }\n // const alphaMode = material.alphaMode;\n // switch (alphaMode) {\n // case \"NORMAL_OPAQUE\":\n // materialCfg.alphaMode = \"opaque\";\n // break;\n // case \"MASK\":\n // materialCfg.alphaMode = \"mask\";\n // break;\n // case \"BLEND\":\n // materialCfg.alphaMode = \"blend\";\n // break;\n // default:\n // }\n // const alphaCutoff = material.alphaCutoff;\n // if (alphaCutoff !== undefined) {\n // materialCfg.alphaCutoff = alphaCutoff;\n // }\n const metallicPBR = material.pbrMetallicRoughness;\n if (material.pbrMetallicRoughness) {\n const pbrMetallicRoughness = material.pbrMetallicRoughness;\n const baseColorTexture = pbrMetallicRoughness.baseColorTexture || pbrMetallicRoughness.colorTexture;\n if (baseColorTexture) {\n if (baseColorTexture.texture) {\n textureSetCfg.colorTextureId = baseColorTexture.texture._textureId;\n } else {\n textureSetCfg.colorTextureId = ctx.gltfData.textures[baseColorTexture.index]._textureId;\n }\n }\n if (metallicPBR.metallicRoughnessTexture) {\n textureSetCfg.metallicRoughnessTextureId = metallicPBR.metallicRoughnessTexture.texture._textureId;\n }\n }\n const extensions = material.extensions;\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const specularTexture = specularPBR.specularTexture;\n if (specularTexture !== null && specularTexture !== undefined) {\n // textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n }\n const specularColorTexture = specularPBR.specularColorTexture;\n if (specularColorTexture !== null && specularColorTexture !== undefined) {\n textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n }\n }\n }\n if (textureSetCfg.normalTextureId !== undefined ||\n textureSetCfg.occlusionTextureId !== undefined ||\n textureSetCfg.emissiveTextureId !== undefined ||\n textureSetCfg.colorTextureId !== undefined ||\n textureSetCfg.metallicRoughnessTextureId !== undefined) {\n textureSetCfg.textureSetId = `textureSet-${ctx.nextId++};`\n ctx.xktModel.createTextureSet(textureSetCfg);\n ctx.stats.numTextureSets++;\n return textureSetCfg.textureSetId;\n }\n return null;\n}\n\nfunction parseMaterialAttributes(ctx, material) { // Substitute RGBA for material, to use fast flat shading instead\n const extensions = material.extensions;\n const materialAttributes = {\n color: new Float32Array([1, 1, 1, 1]),\n opacity: 1,\n metallic: 0,\n roughness: 1\n };\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const diffuseFactor = specularPBR.diffuseFactor;\n if (diffuseFactor !== null && diffuseFactor !== undefined) {\n materialAttributes.color.set(diffuseFactor);\n }\n }\n const common = extensions[\"KHR_materials_common\"];\n if (common) {\n const technique = common.technique;\n const values = common.values || {};\n const blinn = technique === \"BLINN\";\n const phong = technique === \"PHONG\";\n const lambert = technique === \"LAMBERT\";\n const diffuse = values.diffuse;\n if (diffuse && (blinn || phong || lambert)) {\n if (!utils.isString(diffuse)) {\n materialAttributes.color.set(diffuse);\n }\n }\n const transparency = values.transparency;\n if (transparency !== null && transparency !== undefined) {\n materialAttributes.opacity = transparency;\n }\n const transparent = values.transparent;\n if (transparent !== null && transparent !== undefined) {\n materialAttributes.opacity = transparent;\n }\n }\n }\n const metallicPBR = material.pbrMetallicRoughness;\n if (metallicPBR) {\n const baseColorFactor = metallicPBR.baseColorFactor;\n if (baseColorFactor) {\n materialAttributes.color[0] = baseColorFactor[0];\n materialAttributes.color[1] = baseColorFactor[1];\n materialAttributes.color[2] = baseColorFactor[2];\n materialAttributes.opacity = baseColorFactor[3];\n }\n const metallicFactor = metallicPBR.metallicFactor;\n if (metallicFactor !== null && metallicFactor !== undefined) {\n materialAttributes.metallic = metallicFactor;\n }\n const roughnessFactor = metallicPBR.roughnessFactor;\n if (roughnessFactor !== null && roughnessFactor !== undefined) {\n materialAttributes.roughness = roughnessFactor;\n }\n }\n return materialAttributes;\n}\n\nfunction parseDefaultScene(ctx) {\n const gltfData = ctx.gltfData;\n const scene = gltfData.scene || gltfData.scenes[0];\n if (!scene) {\n ctx.error(\"glTF has no default scene\");\n return;\n }\n parseScene(ctx, scene);\n}\n\nfunction parseScene(ctx, scene) {\n const nodes = scene.nodes;\n if (!nodes) {\n return;\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const node = nodes[i];\n countMeshUsage(ctx, node);\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const node = nodes[i];\n parseNode(ctx, node, 0, null);\n }\n}\n\nfunction countMeshUsage(ctx, node) {\n const mesh = node.mesh;\n if (mesh) {\n mesh.instances = mesh.instances ? mesh.instances + 1 : 1;\n }\n if (node.children) {\n const children = node.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNode = children[i];\n if (!childNode) {\n ctx.error(\"Node not found: \" + i);\n continue;\n }\n countMeshUsage(ctx, childNode);\n }\n }\n}\n\nconst objectIdStack = [];\nconst meshIdsStack = [];\n\nlet meshIds = null;\n\nfunction parseNode(ctx, node, depth, matrix) {\n\n const xktModel = ctx.xktModel;\n\n // Pre-order visit scene node\n\n let localMatrix;\n if (node.matrix) {\n localMatrix = node.matrix;\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.translation) {\n localMatrix = math.translationMat4v(node.translation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.rotation) {\n localMatrix = math.quaternionToMat4(node.rotation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n if (node.scale) {\n localMatrix = math.scalingMat4v(node.scale);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n\n if (node.name) {\n meshIds = [];\n let xktEntityId = node.name;\n if (!!xktEntityId && xktModel.entities[xktEntityId]) {\n ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${xktEntityId} - will randomly-generating an object ID in XKT`);\n }\n while (!xktEntityId || xktModel.entities[xktEntityId]) {\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n objectIdStack.push(xktEntityId);\n meshIdsStack.push(meshIds);\n }\n\n if (meshIds && node.mesh) {\n\n const mesh = node.mesh;\n const numPrimitives = mesh.primitives.length;\n\n if (numPrimitives > 0) {\n for (let i = 0; i < numPrimitives; i++) {\n const primitive = mesh.primitives[i];\n if (!primitive._xktGeometryId) {\n const xktGeometryId = \"geometry-\" + ctx.nextId++;\n const geometryCfg = {\n geometryId: xktGeometryId\n };\n switch (primitive.mode) {\n case 0: // POINTS\n geometryCfg.primitiveType = \"points\";\n break;\n case 1: // LINES\n geometryCfg.primitiveType = \"lines\";\n break;\n case 2: // LINE_LOOP\n geometryCfg.primitiveType = \"line-loop\";\n break;\n case 3: // LINE_STRIP\n geometryCfg.primitiveType = \"line-strip\";\n break;\n case 4: // TRIANGLES\n geometryCfg.primitiveType = \"triangles\";\n break;\n case 5: // TRIANGLE_STRIP\n geometryCfg.primitiveType = \"triangle-strip\";\n break;\n case 6: // TRIANGLE_FAN\n geometryCfg.primitiveType = \"triangle-fan\";\n break;\n default:\n geometryCfg.primitiveType = \"triangles\";\n }\n const POSITION = primitive.attributes.POSITION;\n if (!POSITION) {\n continue;\n }\n geometryCfg.positions = primitive.attributes.POSITION.value;\n ctx.stats.numVertices += geometryCfg.positions.length / 3;\n if (ctx.includeNormals) {\n if (primitive.attributes.NORMAL) {\n geometryCfg.normals = primitive.attributes.NORMAL.value;\n ctx.stats.numNormals += geometryCfg.normals.length / 3;\n }\n }\n if (primitive.attributes.COLOR_0) {\n geometryCfg.colorsCompressed = primitive.attributes.COLOR_0.value;\n }\n if (ctx.includeTextures) {\n if (primitive.attributes.TEXCOORD_0) {\n geometryCfg.uvs = primitive.attributes.TEXCOORD_0.value;\n ctx.stats.numUVs += geometryCfg.uvs.length / 2;\n }\n }\n if (primitive.indices) {\n geometryCfg.indices = primitive.indices.value;\n if (primitive.mode === 4) {\n ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n }\n }\n xktModel.createGeometry(geometryCfg);\n primitive._xktGeometryId = xktGeometryId;\n ctx.stats.numGeometries++;\n }\n\n const xktMeshId = ctx.nextId++;\n const meshCfg = {\n meshId: xktMeshId,\n geometryId: primitive._xktGeometryId,\n matrix: matrix ? matrix.slice() : math.identityMat4()\n };\n const material = primitive.material;\n if (material) {\n meshCfg.textureSetId = material._textureSetId;\n meshCfg.color = material._attributes.color;\n meshCfg.opacity = material._attributes.opacity;\n meshCfg.metallic = material._attributes.metallic;\n meshCfg.roughness = material._attributes.roughness;\n } else {\n meshCfg.color = [1.0, 1.0, 1.0];\n meshCfg.opacity = 1.0;\n }\n xktModel.createMesh(meshCfg);\n meshIds.push(xktMeshId);\n }\n }\n }\n\n // Visit child scene nodes\n\n if (node.children) {\n const children = node.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNode = children[i];\n parseNode(ctx, childNode, depth + 1, matrix);\n }\n }\n\n // Post-order visit scene node\n\n const nodeName = node.name;\n if ((nodeName !== undefined && nodeName !== null) || depth === 0) {\n if (nodeName === undefined || nodeName === null) {\n ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);\n }\n let xktEntityId = objectIdStack.pop();\n if (!xktEntityId) { // For when there are no nodes with names\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n let entityMeshIds = meshIdsStack.pop();\n if (meshIds && meshIds.length > 0) {\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: entityMeshIds\n });\n }\n ctx.stats.numObjects++;\n meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null;\n }\n}\n\nexport {parseGLTFIntoXKTModel};", - "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/parsers/parseGLTFIntoXKTModel.js", - "access": "public", - "description": null, - "lineNumber": 1 - }, - { - "__docId__": 433, - "kind": "function", - "name": "parseTextures", - "memberof": "src/parsers/parseGLTFIntoXKTModel.js", - "generator": false, - "async": false, - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.js~parseTextures", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", - "importStyle": null, - "description": null, - "lineNumber": 138, - "undocument": true, - "params": [ - { - "name": "ctx", - "types": [ - "*" - ] - } - ], - "return": null, - "ignore": true - }, - { - "__docId__": 434, - "kind": "function", - "name": "parseTexture", - "memberof": "src/parsers/parseGLTFIntoXKTModel.js", - "generator": false, - "async": false, - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.js~parseTexture", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", - "importStyle": null, - "description": null, - "lineNumber": 149, - "undocument": true, - "params": [ - { - "name": "ctx", - "types": [ - "*" - ] - }, - { - "name": "texture", - "types": [ - "*" - ] - } - ], - "return": null, - "ignore": true - }, - { - "__docId__": 435, - "kind": "function", - "name": "parseMaterials", - "memberof": "src/parsers/parseGLTFIntoXKTModel.js", - "generator": false, - "async": false, - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.js~parseMaterials", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", - "importStyle": null, - "description": null, - "lineNumber": 244, - "undocument": true, - "params": [ - { - "name": "ctx", - "types": [ - "*" - ] - } - ], - "return": null, - "ignore": true - }, - { - "__docId__": 436, - "kind": "function", - "name": "parseTextureSet", - "memberof": "src/parsers/parseGLTFIntoXKTModel.js", - "generator": false, - "async": false, - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.js~parseTextureSet", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", - "importStyle": null, - "description": null, - "lineNumber": 256, - "undocument": true, - "params": [ - { - "name": "ctx", - "types": [ - "*" - ] - }, - { - "name": "material", - "types": [ - "*" - ] - } - ], - "return": { - "types": [ - "*" - ] - }, - "ignore": true - }, - { - "__docId__": 437, - "kind": "function", - "name": "parseMaterialAttributes", - "memberof": "src/parsers/parseGLTFIntoXKTModel.js", - "generator": false, - "async": false, - "static": true, - "longname": "src/parsers/parseGLTFIntoXKTModel.js~parseMaterialAttributes", - "access": "public", - "export": false, - "importPath": "@xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.js", - "importStyle": null, - "description": null, - "lineNumber": 326, - "undocument": true, - "params": [ - { - "name": "ctx", - "types": [ - "*" - ] - }, - { - "name": "material", - "types": [ - "*" - ] - } - ], - "return": { - "types": [ - "*" - ] - }, - "ignore": true - }, - { - "__docId__": 438, + "__docId__": 426, "kind": "function", "name": "parseDefaultScene", "memberof": "src/parsers/parseGLTFIntoXKTModel.js", @@ -12341,7 +11901,7 @@ "ignore": true }, { - "__docId__": 439, + "__docId__": 427, "kind": "function", "name": "parseScene", "memberof": "src/parsers/parseGLTFIntoXKTModel.js", @@ -12374,7 +11934,7 @@ "ignore": true }, { - "__docId__": 440, + "__docId__": 428, "kind": "function", "name": "countMeshUsage", "memberof": "src/parsers/parseGLTFIntoXKTModel.js", @@ -12407,7 +11967,7 @@ "ignore": true }, { - "__docId__": 441, + "__docId__": 429, "kind": "variable", "name": "objectIdStack", "memberof": "src/parsers/parseGLTFIntoXKTModel.js", @@ -12428,7 +11988,7 @@ "ignore": true }, { - "__docId__": 442, + "__docId__": 430, "kind": "variable", "name": "meshIdsStack", "memberof": "src/parsers/parseGLTFIntoXKTModel.js", @@ -12449,7 +12009,7 @@ "ignore": true }, { - "__docId__": 443, + "__docId__": 431, "kind": "variable", "name": "meshIds", "memberof": "src/parsers/parseGLTFIntoXKTModel.js", @@ -12470,7 +12030,7 @@ "ignore": true }, { - "__docId__": 444, + "__docId__": 432, "kind": "function", "name": "parseNode", "memberof": "src/parsers/parseGLTFIntoXKTModel.js", @@ -12515,7 +12075,7 @@ "ignore": true }, { - "__docId__": 445, + "__docId__": 433, "kind": "function", "name": "parseGLTFIntoXKTModel", "memberof": "src/parsers/parseGLTFIntoXKTModel.js", @@ -12641,18 +12201,18 @@ } }, { - "__docId__": 446, + "__docId__": 434, "kind": "file", "name": "src/parsers/parseGLTFJSONIntoXKTModel.js", "content": "import {utils} from \"../XKTModel/lib/utils.js\";\nimport {math} from \"../lib/math.js\";\n\nconst atob2 = (typeof atob !== 'undefined') ? atob : a => Buffer.from(a, 'base64').toString('binary');\n\nconst WEBGL_COMPONENT_TYPES = {\n 5120: Int8Array,\n 5121: Uint8Array,\n 5122: Int16Array,\n 5123: Uint16Array,\n 5125: Uint32Array,\n 5126: Float32Array\n};\n\nconst WEBGL_TYPE_SIZES = {\n 'SCALAR': 1,\n 'VEC2': 2,\n 'VEC3': 3,\n 'VEC4': 4,\n 'MAT2': 4,\n 'MAT3': 9,\n 'MAT4': 16\n};\n\n/**\n * @desc Parses glTF JSON into an {@link XKTModel}, without ````.glb```` and textures.\n *\n * * Lightweight JSON-based glTF parser which ignores textures\n * * For texture and ````.glb```` support, see {@link parseGLTFIntoXKTModel}\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a glTF model into it.\n *\n * ````javascript\n * utils.loadJSON(\"./models/gltf/duplex/scene.gltf\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseGLTFJSONIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing parameters.\n * @param {Object} params.data The glTF JSON.\n * @param {Object} [params.metaModelData] Metamodel JSON. If this is provided, then parsing is able to ensure that the XKTObjects it creates will fit the metadata properly.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Boolean} [params.includeNormals=false] Whether to parse normals. When false, the parser will ignore the glTF\n * geometry normals, and the glTF data will rely on the xeokit ````Viewer```` to automatically generate them. This has\n * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render\n * a flat-shaded representation of the glTF.\n * @param {Boolean} [params.reuseGeometries=true] When true, the parser will enable geometry reuse within the XKTModel. When false,\n * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT\n * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model\n * has excessive geometry reuse. An example of excessive geometry reuse would be if we have 4000 geometries that are\n * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a\n * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc).\n * @param {function} [params.getAttachment] Callback through which to fetch attachments, if the glTF has them.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n * @returns {Promise}\n */\nfunction parseGLTFJSONIntoXKTModel({\n data,\n xktModel,\n metaModelData,\n includeNormals,\n reuseGeometries,\n getAttachment,\n stats = {},\n log\n }) {\n\n if (log) {\n log(\"Using parser: parseGLTFJSONIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n stats.sourceFormat = \"glTF\";\n stats.schemaVersion = \"2.0\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numTriangles = 0;\n stats.numVertices = 0;\n stats.numNormals = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n\n const ctx = {\n gltf: data,\n metaModelCorrections: metaModelData ? getMetaModelCorrections(metaModelData) : null,\n getAttachment: getAttachment || (() => {\n throw new Error('You must define getAttachment() method to convert glTF with external resources')\n }),\n log: (log || function (msg) {\n }),\n xktModel,\n includeNormals,\n createXKTGeometryIds: {},\n nextMeshId: 0,\n reuseGeometries: (reuseGeometries !== false),\n stats\n };\n\n ctx.log(`Parsing normals: ${ctx.includeNormals ? \"enabled\" : \"disabled\"}`);\n\n parseBuffers(ctx).then(() => {\n\n parseBufferViews(ctx);\n freeBuffers(ctx);\n parseMaterials(ctx);\n parseDefaultScene(ctx);\n\n resolve();\n\n }, (errMsg) => {\n reject(errMsg);\n });\n });\n}\n\nfunction getMetaModelCorrections(metaModelData) {\n const eachRootStats = {};\n const eachChildRoot = {};\n const metaObjects = metaModelData.metaObjects || [];\n const metaObjectsMap = {};\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n const metaObject = metaObjects[i];\n metaObjectsMap[metaObject.id] = metaObject;\n }\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n const metaObject = metaObjects[i];\n if (metaObject.parent !== undefined && metaObject.parent !== null) {\n const metaObjectParent = metaObjectsMap[metaObject.parent];\n if (metaObject.type === metaObjectParent.type) {\n let rootMetaObject = metaObjectParent;\n while (rootMetaObject.parent && metaObjectsMap[rootMetaObject.parent].type === rootMetaObject.type) {\n rootMetaObject = metaObjectsMap[rootMetaObject.parent];\n }\n const rootStats = eachRootStats[rootMetaObject.id] || (eachRootStats[rootMetaObject.id] = {\n numChildren: 0,\n countChildren: 0\n });\n rootStats.numChildren++;\n eachChildRoot[metaObject.id] = rootMetaObject;\n } else {\n\n }\n }\n }\n const metaModelCorrections = {\n metaObjectsMap,\n eachRootStats,\n eachChildRoot\n };\n return metaModelCorrections;\n}\n\nfunction parseBuffers(ctx) { // Parses geometry buffers into temporary \"_buffer\" Unit8Array properties on the glTF \"buffer\" elements\n const buffers = ctx.gltf.buffers;\n if (buffers) {\n return Promise.all(buffers.map(buffer => parseBuffer(ctx, buffer)));\n } else {\n return new Promise(function (resolve, reject) {\n resolve();\n });\n }\n}\n\nfunction parseBuffer(ctx, bufferInfo) {\n return new Promise(function (resolve, reject) {\n // Allow a shortcut where the glTF buffer is \"enrichened\" with direct\n // access to the data-arrayBuffer, w/out needing to either:\n // - read the file indicated by the \".uri\" component of the buffer\n // - base64-decode the encoded data in the \".uri\" component\n if (bufferInfo._arrayBuffer) {\n bufferInfo._buffer = bufferInfo._arrayBuffer;\n resolve(bufferInfo);\n return;\n }\n // Otherwise, proceed with \"standard-glTF\" .uri component.\n const uri = bufferInfo.uri;\n if (!uri) {\n reject('gltf/handleBuffer missing uri in ' + JSON.stringify(bufferInfo));\n return;\n }\n parseArrayBuffer(ctx, uri).then((arrayBuffer) => {\n bufferInfo._buffer = arrayBuffer;\n resolve(arrayBuffer);\n }, (errMsg) => {\n reject(errMsg);\n })\n });\n}\n\nfunction parseArrayBuffer(ctx, uri) {\n return new Promise(function (resolve, reject) {\n const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; // Check for data: URI\n const dataUriRegexResult = uri.match(dataUriRegex);\n if (dataUriRegexResult) { // Safari can't handle data URIs through XMLHttpRequest\n const isBase64 = !!dataUriRegexResult[2];\n let data = dataUriRegexResult[3];\n data = decodeURIComponent(data);\n if (isBase64) {\n data = atob2(data);\n }\n const buffer = new ArrayBuffer(data.length);\n const view = new Uint8Array(buffer);\n for (let i = 0; i < data.length; i++) {\n view[i] = data.charCodeAt(i);\n }\n resolve(buffer);\n } else { // Uri is a path to a file\n ctx.getAttachment(uri).then(\n (arrayBuffer) => {\n resolve(arrayBuffer);\n },\n (errMsg) => {\n reject(errMsg);\n });\n }\n });\n}\n\nfunction parseBufferViews(ctx) { // Parses our temporary \"_buffer\" properties into \"_buffer\" properties on glTF \"bufferView\" elements\n const bufferViewsInfo = ctx.gltf.bufferViews;\n if (bufferViewsInfo) {\n for (let i = 0, len = bufferViewsInfo.length; i < len; i++) {\n parseBufferView(ctx, bufferViewsInfo[i]);\n }\n }\n}\n\nfunction parseBufferView(ctx, bufferViewInfo) {\n const buffer = ctx.gltf.buffers[bufferViewInfo.buffer];\n bufferViewInfo._typedArray = null;\n const byteLength = bufferViewInfo.byteLength || 0;\n const byteOffset = bufferViewInfo.byteOffset || 0;\n bufferViewInfo._buffer = buffer._buffer.slice(byteOffset, byteOffset + byteLength);\n}\n\nfunction freeBuffers(ctx) { // Deletes the \"_buffer\" properties from the glTF \"buffer\" elements, to save memory\n const buffers = ctx.gltf.buffers;\n if (buffers) {\n for (let i = 0, len = buffers.length; i < len; i++) {\n buffers[i]._buffer = null;\n }\n }\n}\n\nfunction parseMaterials(ctx) {\n const materialsInfo = ctx.gltf.materials;\n if (materialsInfo) {\n for (let i = 0, len = materialsInfo.length; i < len; i++) {\n const materialInfo = materialsInfo[i];\n const material = parseMaterial(ctx, materialInfo);\n materialInfo._materialData = material;\n }\n }\n}\n\nfunction parseMaterial(ctx, materialInfo) { // Attempts to extract an RGBA color for a glTF material\n const material = {\n color: new Float32Array([1, 1, 1]),\n opacity: 1.0,\n metallic: 0,\n roughness: 1\n };\n const extensions = materialInfo.extensions;\n if (extensions) {\n const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n if (specularPBR) {\n const diffuseFactor = specularPBR.diffuseFactor;\n if (diffuseFactor !== null && diffuseFactor !== undefined) {\n material.color[0] = diffuseFactor[0];\n material.color[1] = diffuseFactor[1];\n material.color[2] = diffuseFactor[2];\n }\n }\n const common = extensions[\"KHR_materials_common\"];\n if (common) {\n const technique = common.technique;\n const values = common.values || {};\n const blinn = technique === \"BLINN\";\n const phong = technique === \"PHONG\";\n const lambert = technique === \"LAMBERT\";\n const diffuse = values.diffuse;\n if (diffuse && (blinn || phong || lambert)) {\n if (!utils.isString(diffuse)) {\n material.color[0] = diffuse[0];\n material.color[1] = diffuse[1];\n material.color[2] = diffuse[2];\n }\n }\n const transparency = values.transparency;\n if (transparency !== null && transparency !== undefined) {\n material.opacity = transparency;\n }\n const transparent = values.transparent;\n if (transparent !== null && transparent !== undefined) {\n material.opacity = transparent;\n }\n }\n }\n const metallicPBR = materialInfo.pbrMetallicRoughness;\n if (metallicPBR) {\n const baseColorFactor = metallicPBR.baseColorFactor;\n if (baseColorFactor) {\n material.color[0] = baseColorFactor[0];\n material.color[1] = baseColorFactor[1];\n material.color[2] = baseColorFactor[2];\n material.opacity = baseColorFactor[3];\n }\n const metallicFactor = metallicPBR.metallicFactor;\n if (metallicFactor !== null && metallicFactor !== undefined) {\n material.metallic = metallicFactor;\n }\n const roughnessFactor = metallicPBR.roughnessFactor;\n if (roughnessFactor !== null && roughnessFactor !== undefined) {\n material.roughness = roughnessFactor;\n }\n }\n return material;\n}\n\nfunction parseDefaultScene(ctx) {\n const scene = ctx.gltf.scene || 0;\n const defaultSceneInfo = ctx.gltf.scenes[scene];\n if (!defaultSceneInfo) {\n throw new Error(\"glTF has no default scene\");\n }\n parseScene(ctx, defaultSceneInfo);\n}\n\n\nfunction parseScene(ctx, sceneInfo) {\n const nodes = sceneInfo.nodes;\n if (!nodes) {\n return;\n }\n for (let i = 0, len = nodes.length; i < len; i++) {\n const glTFNode = ctx.gltf.nodes[nodes[i]];\n if (glTFNode) {\n parseNode(ctx, glTFNode, 0, null);\n }\n }\n}\n\nlet deferredMeshIds = [];\n\nfunction parseNode(ctx, glTFNode, depth, matrix) {\n\n const gltf = ctx.gltf;\n const xktModel = ctx.xktModel;\n\n let localMatrix;\n\n if (glTFNode.matrix) {\n localMatrix = glTFNode.matrix;\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n } else {\n matrix = localMatrix;\n }\n }\n\n if (glTFNode.translation) {\n localMatrix = math.translationMat4v(glTFNode.translation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, localMatrix);\n } else {\n matrix = localMatrix;\n }\n }\n\n if (glTFNode.rotation) {\n localMatrix = math.quaternionToMat4(glTFNode.rotation);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, localMatrix);\n } else {\n matrix = localMatrix;\n }\n }\n\n if (glTFNode.scale) {\n localMatrix = math.scalingMat4v(glTFNode.scale);\n if (matrix) {\n matrix = math.mulMat4(matrix, localMatrix, localMatrix);\n } else {\n matrix = localMatrix;\n }\n }\n\n const gltfMeshId = glTFNode.mesh;\n\n if (gltfMeshId !== undefined) {\n\n const meshInfo = gltf.meshes[gltfMeshId];\n\n if (meshInfo) {\n\n const numPrimitivesInMesh = meshInfo.primitives.length;\n\n if (numPrimitivesInMesh > 0) {\n\n for (let i = 0; i < numPrimitivesInMesh; i++) {\n\n const primitiveInfo = meshInfo.primitives[i];\n\n const geometryHash = createPrimitiveGeometryHash(primitiveInfo);\n\n let xktGeometryId = ctx.createXKTGeometryIds[geometryHash];\n\n if ((!ctx.reuseGeometries) || !xktGeometryId) {\n\n xktGeometryId = \"geometry-\" + ctx.nextMeshId++\n\n const geometryArrays = {};\n\n parsePrimitiveGeometry(ctx, primitiveInfo, geometryArrays);\n\n const colors = geometryArrays.colors;\n\n let colorsCompressed;\n\n if (geometryArrays.colors) {\n colorsCompressed = [];\n for (let j = 0, lenj = colors.length; j < lenj; j += 4) {\n colorsCompressed.push(colors[j + 0]);\n colorsCompressed.push(colors[j + 1]);\n colorsCompressed.push(colors[j + 2]);\n colorsCompressed.push(255);\n }\n }\n\n xktModel.createGeometry({\n geometryId: xktGeometryId,\n primitiveType: geometryArrays.primitive,\n positions: geometryArrays.positions,\n normals: ctx.includeNormals ? geometryArrays.normals : null,\n colorsCompressed: colorsCompressed,\n indices: geometryArrays.indices\n });\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += geometryArrays.positions ? geometryArrays.positions.length / 3 : 0;\n ctx.stats.numNormals += (ctx.includeNormals && geometryArrays.normals) ? geometryArrays.normals.length / 3 : 0;\n ctx.stats.numTriangles += geometryArrays.indices ? geometryArrays.indices.length / 3 : 0;\n\n ctx.createXKTGeometryIds[geometryHash] = xktGeometryId;\n } else {\n// Geometry reused\n }\n\n const materialIndex = primitiveInfo.material;\n const materialInfo = (materialIndex !== null && materialIndex !== undefined) ? gltf.materials[materialIndex] : null;\n const color = materialInfo ? materialInfo._materialData.color : new Float32Array([1.0, 1.0, 1.0, 1.0]);\n const opacity = materialInfo ? materialInfo._materialData.opacity : 1.0;\n const metallic = materialInfo ? materialInfo._materialData.metallic : 0.0;\n const roughness = materialInfo ? materialInfo._materialData.roughness : 1.0;\n\n const xktMeshId = \"mesh-\" + ctx.nextMeshId++;\n\n xktModel.createMesh({\n meshId: xktMeshId,\n geometryId: xktGeometryId,\n matrix: matrix ? matrix.slice() : math.identityMat4(),\n color: color,\n opacity: opacity,\n metallic: metallic,\n roughness: roughness\n });\n\n deferredMeshIds.push(xktMeshId);\n }\n }\n }\n }\n\n\n if (glTFNode.children) {\n const children = glTFNode.children;\n for (let i = 0, len = children.length; i < len; i++) {\n const childNodeIdx = children[i];\n const childGLTFNode = gltf.nodes[childNodeIdx];\n if (!childGLTFNode) {\n console.warn('Node not found: ' + i);\n continue;\n }\n parseNode(ctx, childGLTFNode, depth + 1, matrix);\n }\n }\n\n // Post-order visit scene node\n\n const nodeName = glTFNode.name;\n if (((nodeName !== undefined && nodeName !== null) || depth === 0) && deferredMeshIds.length > 0) {\n if (nodeName === undefined || nodeName === null) {\n ctx.log(`[parseGLTFJSONIntoXKTModel] Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);\n }\n let xktEntityId = nodeName; // Fall back on generated ID when `name` not found on glTF scene node(s)\n if (xktEntityId === undefined || xktEntityId === null) {\n if (xktModel.entities[xktEntityId]) {\n ctx.error(\"Two or more glTF nodes found with same 'name' attribute: '\" + nodeName + \"'\");\n }\n while (!xktEntityId || xktModel.entities[xktEntityId]) {\n xktEntityId = \"entity-\" + ctx.nextId++;\n }\n }\n if (ctx.metaModelCorrections) { // Merging meshes into XKTObjects that map to metaobjects\n const rootMetaObject = ctx.metaModelCorrections.eachChildRoot[xktEntityId];\n if (rootMetaObject) {\n const rootMetaObjectStats = ctx.metaModelCorrections.eachRootStats[rootMetaObject.id];\n rootMetaObjectStats.countChildren++;\n if (rootMetaObjectStats.countChildren >= rootMetaObjectStats.numChildren) {\n xktModel.createEntity({\n entityId: rootMetaObject.id,\n meshIds: deferredMeshIds\n });\n ctx.stats.numObjects++;\n deferredMeshIds = [];\n }\n } else {\n const metaObject = ctx.metaModelCorrections.metaObjectsMap[xktEntityId];\n if (metaObject) {\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: deferredMeshIds\n });\n ctx.stats.numObjects++;\n deferredMeshIds = [];\n }\n }\n } else { // Create an XKTObject from the meshes at each named glTF node, don't care about metaobjects\n xktModel.createEntity({\n entityId: xktEntityId,\n meshIds: deferredMeshIds\n });\n ctx.stats.numObjects++;\n deferredMeshIds = [];\n }\n }\n}\n\nfunction createPrimitiveGeometryHash(primitiveInfo) {\n const attributes = primitiveInfo.attributes;\n if (!attributes) {\n return \"empty\";\n }\n const mode = primitiveInfo.mode;\n const material = primitiveInfo.material;\n const indices = primitiveInfo.indices;\n const positions = primitiveInfo.attributes.POSITION;\n const normals = primitiveInfo.attributes.NORMAL;\n const colors = primitiveInfo.attributes.COLOR_0;\n const uv = primitiveInfo.attributes.TEXCOORD_0;\n return [\n mode,\n // material,\n (indices !== null && indices !== undefined) ? indices : \"-\",\n (positions !== null && positions !== undefined) ? positions : \"-\",\n (normals !== null && normals !== undefined) ? normals : \"-\",\n (colors !== null && colors !== undefined) ? colors : \"-\",\n (uv !== null && uv !== undefined) ? uv : \"-\"\n ].join(\";\");\n}\n\nfunction parsePrimitiveGeometry(ctx, primitiveInfo, geometryArrays) {\n const attributes = primitiveInfo.attributes;\n if (!attributes) {\n return;\n }\n switch (primitiveInfo.mode) {\n case 0: // POINTS\n geometryArrays.primitive = \"points\";\n break;\n case 1: // LINES\n geometryArrays.primitive = \"lines\";\n break;\n case 2: // LINE_LOOP\n // TODO: convert\n geometryArrays.primitive = \"lines\";\n break;\n case 3: // LINE_STRIP\n // TODO: convert\n geometryArrays.primitive = \"lines\";\n break;\n case 4: // TRIANGLES\n geometryArrays.primitive = \"triangles\";\n break;\n case 5: // TRIANGLE_STRIP\n // TODO: convert\n console.log(\"TRIANGLE_STRIP\");\n geometryArrays.primitive = \"triangles\";\n break;\n case 6: // TRIANGLE_FAN\n // TODO: convert\n console.log(\"TRIANGLE_FAN\");\n geometryArrays.primitive = \"triangles\";\n break;\n default:\n geometryArrays.primitive = \"triangles\";\n }\n const accessors = ctx.gltf.accessors;\n const indicesIndex = primitiveInfo.indices;\n if (indicesIndex !== null && indicesIndex !== undefined) {\n const accessorInfo = accessors[indicesIndex];\n geometryArrays.indices = parseAccessorTypedArray(ctx, accessorInfo);\n }\n const positionsIndex = attributes.POSITION;\n if (positionsIndex !== null && positionsIndex !== undefined) {\n const accessorInfo = accessors[positionsIndex];\n geometryArrays.positions = parseAccessorTypedArray(ctx, accessorInfo);\n }\n const normalsIndex = attributes.NORMAL;\n if (normalsIndex !== null && normalsIndex !== undefined) {\n const accessorInfo = accessors[normalsIndex];\n geometryArrays.normals = parseAccessorTypedArray(ctx, accessorInfo);\n }\n const colorsIndex = attributes.COLOR_0;\n if (colorsIndex !== null && colorsIndex !== undefined) {\n const accessorInfo = accessors[colorsIndex];\n geometryArrays.colors = parseAccessorTypedArray(ctx, accessorInfo);\n }\n}\n\nfunction parseAccessorTypedArray(ctx, accessorInfo) {\n const bufferView = ctx.gltf.bufferViews[accessorInfo.bufferView];\n const itemSize = WEBGL_TYPE_SIZES[accessorInfo.type];\n const TypedArray = WEBGL_COMPONENT_TYPES[accessorInfo.componentType];\n const elementBytes = TypedArray.BYTES_PER_ELEMENT; // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.\n const itemBytes = elementBytes * itemSize;\n if (accessorInfo.byteStride && accessorInfo.byteStride !== itemBytes) { // The buffer is not interleaved if the stride is the item size in bytes.\n throw new Error(\"interleaved buffer!\"); // TODO\n } else {\n return new TypedArray(bufferView._buffer, accessorInfo.byteOffset || 0, accessorInfo.count * itemSize);\n }\n}\n\nexport {parseGLTFJSONIntoXKTModel};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/parsers/parseGLTFJSONIntoXKTModel.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/parsers/parseGLTFJSONIntoXKTModel.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 447, + "__docId__": 435, "kind": "variable", "name": "atob2", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12673,7 +12233,7 @@ "ignore": true }, { - "__docId__": 448, + "__docId__": 436, "kind": "variable", "name": "WEBGL_COMPONENT_TYPES", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12694,7 +12254,7 @@ "ignore": true }, { - "__docId__": 449, + "__docId__": 437, "kind": "variable", "name": "WEBGL_TYPE_SIZES", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12715,7 +12275,7 @@ "ignore": true }, { - "__docId__": 450, + "__docId__": 438, "kind": "function", "name": "getMetaModelCorrections", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12746,7 +12306,7 @@ "ignore": true }, { - "__docId__": 451, + "__docId__": 439, "kind": "function", "name": "parseBuffers", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12777,7 +12337,7 @@ "ignore": true }, { - "__docId__": 452, + "__docId__": 440, "kind": "function", "name": "parseBuffer", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12814,7 +12374,7 @@ "ignore": true }, { - "__docId__": 453, + "__docId__": 441, "kind": "function", "name": "parseArrayBuffer", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12851,7 +12411,7 @@ "ignore": true }, { - "__docId__": 454, + "__docId__": 442, "kind": "function", "name": "parseBufferViews", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12878,7 +12438,7 @@ "ignore": true }, { - "__docId__": 455, + "__docId__": 443, "kind": "function", "name": "parseBufferView", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12911,7 +12471,7 @@ "ignore": true }, { - "__docId__": 456, + "__docId__": 444, "kind": "function", "name": "freeBuffers", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12938,7 +12498,7 @@ "ignore": true }, { - "__docId__": 457, + "__docId__": 445, "kind": "function", "name": "parseMaterials", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -12965,7 +12525,7 @@ "ignore": true }, { - "__docId__": 458, + "__docId__": 446, "kind": "function", "name": "parseMaterial", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -13002,7 +12562,7 @@ "ignore": true }, { - "__docId__": 459, + "__docId__": 447, "kind": "function", "name": "parseDefaultScene", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -13029,7 +12589,7 @@ "ignore": true }, { - "__docId__": 460, + "__docId__": 448, "kind": "function", "name": "parseScene", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -13062,7 +12622,7 @@ "ignore": true }, { - "__docId__": 461, + "__docId__": 449, "kind": "variable", "name": "deferredMeshIds", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -13083,7 +12643,7 @@ "ignore": true }, { - "__docId__": 462, + "__docId__": 450, "kind": "function", "name": "parseNode", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -13128,7 +12688,7 @@ "ignore": true }, { - "__docId__": 463, + "__docId__": 451, "kind": "function", "name": "createPrimitiveGeometryHash", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -13159,7 +12719,7 @@ "ignore": true }, { - "__docId__": 464, + "__docId__": 452, "kind": "function", "name": "parsePrimitiveGeometry", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -13198,7 +12758,7 @@ "ignore": true }, { - "__docId__": 465, + "__docId__": 453, "kind": "function", "name": "parseAccessorTypedArray", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -13235,7 +12795,7 @@ "ignore": true }, { - "__docId__": 466, + "__docId__": 454, "kind": "function", "name": "parseGLTFJSONIntoXKTModel", "memberof": "src/parsers/parseGLTFJSONIntoXKTModel.js", @@ -13361,18 +12921,18 @@ } }, { - "__docId__": 467, + "__docId__": 455, "kind": "file", "name": "src/parsers/parseIFCIntoXKTModel.js", "content": "/**\n * @desc Parses IFC STEP file data into an {@link XKTModel}.\n *\n * This function uses [web-ifc](https://github.com/tomvandig/web-ifc) to parse the IFC, which relies on a\n * WASM file to do the parsing.\n *\n * Depending on how we use this function, we may need to provide it with a path to the directory where that WASM file is stored.\n *\n * This function is tested with web-ifc version 0.0.34.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an IFC model into it.\n *\n * ````javascript\n * import {XKTModel, parseIFCIntoXKTModel, writeXKTModelToArrayBuffer} from \"xeokit-convert.es.js\";\n *\n * import * as WebIFC from \"web-ifc-api.js\";\n *\n * utils.loadArraybuffer(\"rac_advanced_sample_project.ifc\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseIFCIntoXKTModel({\n * WebIFC,\n * data,\n * xktModel,\n * wasmPath: \"../dist/\",\n * autoNormals: true,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the\n * caller the choice of whether to use the Browser or NodeJS version.\n * @param {ArrayBuffer} [params.data] IFC file data.\n * @param {XKTModel} [params.xktModel] XKTModel to parse into.\n * @param {Boolean} [params.autoNormals=true] When true, the parser will ignore the IFC geometry normals, and the IFC\n * data will rely on the xeokit ````Viewer```` to automatically generate them. This has the limitation that the\n * normals will be face-aligned, and therefore the ````Viewer```` will only be able to render a flat-shaded representation\n * of the IFC model. This is ````true```` by default, because IFC models tend to look acceptable with flat-shading,\n * and we always want to minimize IFC model size wherever possible.\n * @param {String[]} [params.includeTypes] Option to only convert objects of these types.\n * @param {String[]} [params.excludeTypes] Option to never convert objects of these types.\n * @param {String} params.wasmPath Path to ````web-ifc.wasm````, required by this function.\n * @param {Object} [params.stats={}] Collects statistics.\n * @param {function} [params.log] Logging callback.\n * @returns {Promise} Resolves when IFC has been parsed.\n */\nfunction parseIFCIntoXKTModel({\n WebIFC,\n data,\n xktModel,\n autoNormals = true,\n includeTypes,\n excludeTypes,\n wasmPath,\n stats = {},\n log\n }) {\n\n if (log) {\n log(\"Using parser: parseIFCIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n if (!wasmPath) {\n reject(\"Argument expected: wasmPath\");\n return;\n }\n\n const ifcAPI = new WebIFC.IfcAPI();\n\n if (wasmPath) {\n ifcAPI.SetWasmPath(wasmPath);\n }\n\n ifcAPI.Init().then(() => {\n\n const dataArray = new Uint8Array(data);\n\n const modelID = ifcAPI.OpenModel(dataArray);\n\n stats.sourceFormat = \"IFC\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 0;\n stats.numPropertySets = 0;\n stats.numObjects = 0;\n stats.numGeometries = 0;\n stats.numTriangles = 0;\n stats.numVertices = 0;\n\n const ctx = {\n WebIFC,\n modelID,\n ifcAPI,\n xktModel,\n autoNormals,\n log: (log || function (msg) {\n }),\n nextId: 0,\n stats\n };\n\n if (includeTypes) {\n ctx.includeTypes = {};\n for (let i = 0, len = includeTypes.length; i < len; i++) {\n ctx.includeTypes[includeTypes[i]] = true;\n }\n }\n\n if (excludeTypes) {\n ctx.excludeTypes = {};\n for (let i = 0, len = excludeTypes.length; i < len; i++) {\n ctx.excludeTypes[excludeTypes[i]] = true;\n }\n }\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(modelID, WebIFC.IFCPROJECT);\n const ifcProjectId = lines.get(0);\n const ifcProject = ctx.ifcAPI.GetLine(modelID, ifcProjectId);\n\n ctx.xktModel.schema = \"\";\n ctx.xktModel.modelId = \"\" + modelID;\n ctx.xktModel.projectId = \"\" + ifcProjectId;\n\n parseMetadata(ctx);\n parseGeometry(ctx);\n parsePropertySets(ctx);\n\n resolve();\n\n }).catch((e) => {\n\n reject(e);\n })\n });\n}\n\nfunction parsePropertySets(ctx) {\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, ctx.WebIFC.IFCRELDEFINESBYPROPERTIES);\n\n for (let i = 0; i < lines.size(); i++) {\n\n let relID = lines.get(i);\n\n let rel = ctx.ifcAPI.GetLine(ctx.modelID, relID, true);\n\n if (rel) {\n\n const relatingPropertyDefinition = rel.RelatingPropertyDefinition;\n if (!relatingPropertyDefinition) {\n continue;\n }\n\n const propertySetId = relatingPropertyDefinition.GlobalId.value;\n\n const relatedObjects = rel.RelatedObjects;\n if (relatedObjects) {\n for (let i = 0, len = relatedObjects.length; i < len; i++) {\n const relatedObject = relatedObjects[i];\n const metaObjectId = relatedObject.GlobalId.value;\n const metaObject = ctx.xktModel.metaObjects[metaObjectId];\n if (metaObject) {\n if (!metaObject.propertySetIds) {\n metaObject.propertySetIds = [];\n }\n metaObject.propertySetIds.push(propertySetId);\n }\n }\n }\n\n const props = relatingPropertyDefinition.HasProperties;\n if (props && props.length > 0) {\n const propertySetType = \"Default\";\n const propertySetName = relatingPropertyDefinition.Name.value;\n const properties = [];\n for (let i = 0, len = props.length; i < len; i++) {\n const prop = props[i];\n const name = prop.Name;\n const nominalValue = prop.NominalValue;\n if (name && nominalValue) {\n const property = {\n name: name.value,\n type: nominalValue.type,\n value: nominalValue.value,\n valueType: nominalValue.valueType\n };\n if (prop.Description) {\n property.description = prop.Description.value;\n } else if (nominalValue.description) {\n property.description = nominalValue.description;\n }\n properties.push(property);\n }\n }\n ctx.xktModel.createPropertySet({propertySetId, propertySetType, propertySetName, properties});\n ctx.stats.numPropertySets++;\n }\n }\n }\n}\n\nfunction parseMetadata(ctx) {\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, ctx.WebIFC.IFCPROJECT);\n const ifcProjectId = lines.get(0);\n const ifcProject = ctx.ifcAPI.GetLine(ctx.modelID, ifcProjectId);\n\n parseSpatialChildren(ctx, ifcProject);\n}\n\nfunction parseSpatialChildren(ctx, ifcElement, parentMetaObjectId) {\n\n const metaObjectType = ifcElement.__proto__.constructor.name;\n\n if (ctx.includeTypes && (!ctx.includeTypes[metaObjectType])) {\n return;\n }\n\n if (ctx.excludeTypes && ctx.excludeTypes[metaObjectType]) {\n return;\n }\n\n createMetaObject(ctx, ifcElement, parentMetaObjectId);\n\n const metaObjectId = ifcElement.GlobalId.value;\n\n parseRelatedItemsOfType(\n ctx,\n ifcElement.expressID,\n 'RelatingObject',\n 'RelatedObjects',\n ctx.WebIFC.IFCRELAGGREGATES,\n metaObjectId);\n\n parseRelatedItemsOfType(\n ctx,\n ifcElement.expressID,\n 'RelatingStructure',\n 'RelatedElements',\n ctx.WebIFC.IFCRELCONTAINEDINSPATIALSTRUCTURE,\n metaObjectId);\n}\n\nfunction createMetaObject(ctx, ifcElement, parentMetaObjectId) {\n\n const metaObjectId = ifcElement.GlobalId.value;\n const propertySetIds = null;\n const metaObjectType = ifcElement.__proto__.constructor.name;\n const metaObjectName = (ifcElement.Name && ifcElement.Name.value !== \"\") ? ifcElement.Name.value : metaObjectType;\n\n ctx.xktModel.createMetaObject({metaObjectId, propertySetIds, metaObjectType, metaObjectName, parentMetaObjectId});\n ctx.stats.numMetaObjects++;\n}\n\nfunction parseRelatedItemsOfType(ctx, id, relation, related, type, parentMetaObjectId) {\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, type);\n\n for (let i = 0; i < lines.size(); i++) {\n\n const relID = lines.get(i);\n const rel = ctx.ifcAPI.GetLine(ctx.modelID, relID);\n const relatedItems = rel[relation];\n\n let foundElement = false;\n\n if (Array.isArray(relatedItems)) {\n const values = relatedItems.map((item) => item.value);\n foundElement = values.includes(id);\n\n } else {\n foundElement = (relatedItems.value === id);\n }\n\n if (foundElement) {\n\n const element = rel[related];\n\n if (!Array.isArray(element)) {\n\n const ifcElement = ctx.ifcAPI.GetLine(ctx.modelID, element.value);\n\n parseSpatialChildren(ctx, ifcElement, parentMetaObjectId);\n\n } else {\n\n element.forEach((element2) => {\n\n const ifcElement = ctx.ifcAPI.GetLine(ctx.modelID, element2.value);\n\n parseSpatialChildren(ctx, ifcElement, parentMetaObjectId);\n });\n }\n }\n }\n}\n\nfunction parseGeometry(ctx) {\n\n // Parses the geometry and materials in the IFC, creates\n // XKTEntity, XKTMesh and XKTGeometry components within the XKTModel.\n\n const flatMeshes = ctx.ifcAPI.LoadAllGeometry(ctx.modelID);\n\n for (let i = 0, len = flatMeshes.size(); i < len; i++) {\n const flatMesh = flatMeshes.get(i);\n createObject(ctx, flatMesh);\n }\n\n // LoadAllGeometry does not return IFCSpace meshes\n // here is a workaround\n\n const lines = ctx.ifcAPI.GetLineIDsWithType(ctx.modelID, ctx.WebIFC.IFCSPACE);\n for (let j = 0, len = lines.size(); j < len; j++) {\n const ifcSpaceId = lines.get(j);\n const flatMesh = ctx.ifcAPI.GetFlatMesh(ctx.modelID, ifcSpaceId);\n createObject(ctx, flatMesh);\n }\n}\n\nfunction createObject(ctx, flatMesh) {\n\n const flatMeshExpressID = flatMesh.expressID;\n const placedGeometries = flatMesh.geometries;\n\n const meshIds = [];\n\n const properties = ctx.ifcAPI.GetLine(ctx.modelID, flatMeshExpressID);\n const entityId = properties.GlobalId.value;\n\n const metaObjectId = entityId;\n const metaObject = ctx.xktModel.metaObjects[metaObjectId];\n\n if (ctx.includeTypes && (!metaObject || (!ctx.includeTypes[metaObject.metaObjectType]))) {\n return;\n }\n\n if (ctx.excludeTypes && (!metaObject || ctx.excludeTypes[metaObject.metaObjectType])) {\n console.log(\"excluding: \" + metaObjectId)\n return;\n }\n\n for (let j = 0, lenj = placedGeometries.size(); j < lenj; j++) {\n\n const placedGeometry = placedGeometries.get(j);\n const geometryId = \"\" + placedGeometry.geometryExpressID;\n\n if (!ctx.xktModel.geometries[geometryId]) {\n\n const geometry = ctx.ifcAPI.GetGeometry(ctx.modelID, placedGeometry.geometryExpressID);\n const vertexData = ctx.ifcAPI.GetVertexArray(geometry.GetVertexData(), geometry.GetVertexDataSize());\n const indices = ctx.ifcAPI.GetIndexArray(geometry.GetIndexData(), geometry.GetIndexDataSize());\n\n // De-interleave vertex arrays\n\n const positions = [];\n const normals = [];\n\n for (let k = 0, lenk = vertexData.length / 6; k < lenk; k++) {\n positions.push(vertexData[k * 6 + 0]);\n positions.push(vertexData[k * 6 + 1]);\n positions.push(vertexData[k * 6 + 2]);\n }\n\n if (!ctx.autoNormals) {\n for (let k = 0, lenk = vertexData.length / 6; k < lenk; k++) {\n normals.push(vertexData[k * 6 + 3]);\n normals.push(vertexData[k * 6 + 4]);\n normals.push(vertexData[k * 6 + 5]);\n }\n }\n\n ctx.xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: positions,\n normals: ctx.autoNormals ? null : normals,\n indices: indices\n });\n\n ctx.stats.numGeometries++;\n ctx.stats.numVertices += (positions.length / 3);\n ctx.stats.numTriangles += (indices.length / 3);\n }\n\n const meshId = (\"mesh\" + ctx.nextId++);\n\n ctx.xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n matrix: placedGeometry.flatTransformation,\n color: [placedGeometry.color.x, placedGeometry.color.y, placedGeometry.color.z],\n opacity: placedGeometry.color.w\n });\n\n meshIds.push(meshId);\n }\n\n if (meshIds.length > 0) {\n ctx.xktModel.createEntity({\n entityId: entityId,\n meshIds: meshIds\n });\n ctx.stats.numObjects++;\n }\n}\n\nexport {parseIFCIntoXKTModel};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/parsers/parseIFCIntoXKTModel.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/parsers/parseIFCIntoXKTModel.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 468, + "__docId__": 456, "kind": "function", "name": "parsePropertySets", "memberof": "src/parsers/parseIFCIntoXKTModel.js", @@ -13399,7 +12959,7 @@ "ignore": true }, { - "__docId__": 469, + "__docId__": 457, "kind": "function", "name": "parseMetadata", "memberof": "src/parsers/parseIFCIntoXKTModel.js", @@ -13426,7 +12986,7 @@ "ignore": true }, { - "__docId__": 470, + "__docId__": 458, "kind": "function", "name": "parseSpatialChildren", "memberof": "src/parsers/parseIFCIntoXKTModel.js", @@ -13465,7 +13025,7 @@ "ignore": true }, { - "__docId__": 471, + "__docId__": 459, "kind": "function", "name": "createMetaObject", "memberof": "src/parsers/parseIFCIntoXKTModel.js", @@ -13504,7 +13064,7 @@ "ignore": true }, { - "__docId__": 472, + "__docId__": 460, "kind": "function", "name": "parseRelatedItemsOfType", "memberof": "src/parsers/parseIFCIntoXKTModel.js", @@ -13561,7 +13121,7 @@ "ignore": true }, { - "__docId__": 473, + "__docId__": 461, "kind": "function", "name": "parseGeometry", "memberof": "src/parsers/parseIFCIntoXKTModel.js", @@ -13588,7 +13148,7 @@ "ignore": true }, { - "__docId__": 474, + "__docId__": 462, "kind": "function", "name": "createObject", "memberof": "src/parsers/parseIFCIntoXKTModel.js", @@ -13621,7 +13181,7 @@ "ignore": true }, { - "__docId__": 475, + "__docId__": 463, "kind": "function", "name": "parseIFCIntoXKTModel", "memberof": "src/parsers/parseIFCIntoXKTModel.js", @@ -13757,18 +13317,18 @@ } }, { - "__docId__": 476, + "__docId__": 464, "kind": "file", "name": "src/parsers/parseLASIntoXKTModel.js", "content": "import {parse} from '@loaders.gl/core';\nimport {LASLoader} from '@loaders.gl/las';\n\nimport {math} from \"../lib/math.js\";\n\nconst MAX_VERTICES = 500000; // TODO: Rough estimate\n\n/**\n * @desc Parses LAS and LAZ point cloud data into an {@link XKTModel}.\n *\n * This parser handles both the LASER file format (LAS) and its compressed version (LAZ),\n * a public format for the interchange of 3-dimensional point cloud data data, developed\n * for LIDAR mapping purposes.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an LAZ point cloud model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"./models/laz/autzen.laz\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * await parseLASIntoXKTModel({\n * data,\n * xktModel,\n * rotateX: true,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer} params.data LAS/LAZ file data.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {boolean} [params.center=false] Set true to center the LAS point positions to [0,0,0]. This is applied before the transformation matrix, if specified.\n * @param {Boolean} [params.transform] 4x4 transformation matrix to transform point positions. Use this to rotate, translate and scale them if neccessary.\n * @param {Number|String} [params.colorDepth=8] Whether colors encoded using 8 or 16 bits. Can be set to 'auto'. LAS specification recommends 16 bits.\n * @param {Boolean} [params.fp64=false] Configures if LASLoaderPlugin assumes that LAS positions are stored in 64-bit floats instead of 32-bit.\n * @param {Number} [params.skip=1] Read one from every n points.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n * @returns {Promise} Resolves when LAS has been parsed.\n */\nfunction parseLASIntoXKTModel({\n data,\n xktModel,\n center = false,\n transform = null,\n colorDepth = \"auto\",\n fp64 = false,\n skip = 1,\n stats,\n log = () => {\n }\n }) {\n\n if (log) {\n log(\"Using parser: parseLASIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n log(\"Converting LAZ/LAS\");\n\n log(`center: ${center}`);\n if (transform) {\n log(`transform: [${transform}]`);\n }\n log(`colorDepth: ${colorDepth}`);\n log(`fp64: ${fp64}`);\n log(`skip: ${skip}`);\n\n parse(data, LASLoader, {\n las: {\n colorDepth,\n fp64\n }\n }).then((parsedData) => {\n\n const attributes = parsedData.attributes;\n\n const loaderData = parsedData.loaderData;\n const pointsFormatId = loaderData.pointsFormatId !== undefined ? loaderData.pointsFormatId : -1;\n\n if (!attributes.POSITION) {\n log(\"No positions found in file (expected for all LAS point formats)\");\n return;\n }\n\n let readAttributes = {};\n\n switch (pointsFormatId) {\n case 0:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 0)\");\n return;\n }\n\n readAttributes = readIntensities(attributes.POSITION, attributes.intensity);\n break;\n case 1:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 1)\");\n return;\n }\n readAttributes = readIntensities(attributes.POSITION, attributes.intensity);\n break;\n case 2:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 2)\");\n return;\n }\n\n readAttributes = readColorsAndIntensities(attributes.POSITION, attributes.COLOR_0, attributes.intensity);\n break;\n case 3:\n if (!attributes.intensity) {\n log(\"No intensities found in file (expected for LAS point format 3)\");\n return;\n }\n readAttributes = readColorsAndIntensities(attributes.POSITION, attributes.COLOR_0, attributes.intensity);\n break;\n }\n\n const pointsChunks = chunkArray(readPositions(readAttributes.positions), MAX_VERTICES * 3);\n const colorsChunks = chunkArray(readAttributes.colors, MAX_VERTICES * 4);\n\n const meshIds = [];\n\n for (let j = 0, lenj = pointsChunks.length; j < lenj; j++) {\n\n const geometryId = `geometry-${j}`;\n const meshId = `mesh-${j}`;\n\n meshIds.push(meshId);\n\n xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"points\",\n positions: pointsChunks[j],\n colorsCompressed: colorsChunks[j]\n });\n\n xktModel.createMesh({\n meshId,\n geometryId\n });\n }\n\n const entityId = math.createUUID();\n\n xktModel.createEntity({\n entityId,\n meshIds\n });\n\n const rootMetaObjectId = math.createUUID();\n\n xktModel.createMetaObject({\n metaObjectId: rootMetaObjectId,\n metaObjectType: \"Model\",\n metaObjectName: \"Model\"\n });\n\n xktModel.createMetaObject({\n metaObjectId: entityId,\n metaObjectType: \"PointCloud\",\n metaObjectName: \"PointCloud (LAZ)\",\n parentMetaObjectId: rootMetaObjectId\n });\n\n if (stats) {\n stats.sourceFormat = \"LAS\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 2;\n stats.numPropertySets = 0;\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numVertices = readAttributes.positions.length / 3;\n }\n\n resolve();\n\n }, (errMsg) => {\n reject(errMsg);\n });\n });\n\n function readPositions(positionsValue) {\n if (positionsValue) {\n if (center) {\n const centerPos = math.vec3();\n const numPoints = positionsValue.length;\n for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n centerPos[0] += positionsValue[i + 0];\n centerPos[1] += positionsValue[i + 1];\n centerPos[2] += positionsValue[i + 2];\n }\n centerPos[0] /= numPoints;\n centerPos[1] /= numPoints;\n centerPos[2] /= numPoints;\n for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n positionsValue[i + 0] -= centerPos[0];\n positionsValue[i + 1] -= centerPos[1];\n positionsValue[i + 2] -= centerPos[2];\n }\n }\n if (transform) {\n const mat = math.mat4(transform);\n const pos = math.vec3();\n for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n pos[0] = positionsValue[i + 0];\n pos[1] = positionsValue[i + 1];\n pos[2] = positionsValue[i + 2];\n math.transformPoint3(mat, pos, pos);\n positionsValue[i + 0] = pos[0];\n positionsValue[i + 1] = pos[1];\n positionsValue[i + 2] = pos[2];\n }\n }\n }\n return positionsValue;\n }\n\n function readColorsAndIntensities(attributesPosition, attributesColor, attributesIntensity) {\n const positionsValue = attributesPosition.value;\n const colors = attributesColor.value;\n const colorSize = attributesColor.size;\n const intensities = attributesIntensity.value;\n const colorsCompressedSize = intensities.length * 4;\n const positions = [];\n const colorsCompressed = new Uint8Array(colorsCompressedSize / skip);\n let count = skip;\n for (let i = 0, j = 0, k = 0, l = 0, m = 0, n=0,len = intensities.length; i < len; i++, k += colorSize, j += 4, l += 3) {\n if (count <= 0) {\n colorsCompressed[m++] = colors[k + 0];\n colorsCompressed[m++] = colors[k + 1];\n colorsCompressed[m++] = colors[k + 2];\n colorsCompressed[m++] = Math.round((intensities[i] / 65536) * 255);\n positions[n++] = positionsValue[l + 0];\n positions[n++] = positionsValue[l + 1];\n positions[n++] = positionsValue[l + 2];\n count = skip;\n } else {\n count--;\n }\n }\n return {\n positions,\n colors: colorsCompressed\n };\n }\n\n function readIntensities(attributesPosition, attributesIntensity) {\n const positionsValue = attributesPosition.value;\n const intensities = attributesIntensity.value;\n const colorsCompressedSize = intensities.length * 4;\n const positions = [];\n const colorsCompressed = new Uint8Array(colorsCompressedSize / skip);\n let count = skip;\n for (let i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, len = intensities.length; i < len; i++, k += 3, j += 4, l += 3) {\n if (count <= 0) {\n colorsCompressed[m++] = 0;\n colorsCompressed[m++] = 0;\n colorsCompressed[m++] = 0;\n colorsCompressed[m++] = Math.round((intensities[i] / 65536) * 255);\n positions[n++] = positionsValue[l + 0];\n positions[n++] = positionsValue[l + 1];\n positions[n++] = positionsValue[l + 2];\n count = skip;\n } else {\n count--;\n }\n }\n return {\n positions,\n colors: colorsCompressed\n };\n }\n\n function chunkArray(array, chunkSize) {\n if (chunkSize >= array.length) {\n return [array]; // One chunk\n }\n let result = [];\n for (let i = 0; i < array.length; i += chunkSize) {\n result.push(array.slice(i, i + chunkSize));\n }\n return result;\n }\n\n}\n\nexport {parseLASIntoXKTModel};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/parsers/parseLASIntoXKTModel.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/parsers/parseLASIntoXKTModel.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 477, + "__docId__": 465, "kind": "variable", "name": "MAX_VERTICES", "memberof": "src/parsers/parseLASIntoXKTModel.js", @@ -13789,7 +13349,7 @@ "ignore": true }, { - "__docId__": 478, + "__docId__": 466, "kind": "function", "name": "parseLASIntoXKTModel", "memberof": "src/parsers/parseLASIntoXKTModel.js", @@ -13930,18 +13490,18 @@ } }, { - "__docId__": 479, + "__docId__": 467, "kind": "file", "name": "src/parsers/parseMetaModelIntoXKTModel.js", "content": "/**\n * @desc Parses JSON metamodel into an {@link XKTModel}.\n *\n * @param {Object} params Parsing parameters.\n * @param {JSON} params.metaModelData Metamodel data.\n * @param {String[]} [params.excludeTypes] Types to exclude from parsing.\n * @param {String[]} [params.includeTypes] Types to include in parsing.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when JSON has been parsed.\n */\nfunction parseMetaModelIntoXKTModel({metaModelData, xktModel, includeTypes, excludeTypes, log}) {\n\n if (log) {\n log(\"Using parser: parseMetaModelIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n const metaObjects = metaModelData.metaObjects || [];\n const propertySets = metaModelData.propertySets || [];\n\n xktModel.modelId = metaModelData.revisionId || \"\"; // HACK\n xktModel.projectId = metaModelData.projectId || \"\";\n xktModel.revisionId = metaModelData.revisionId || \"\";\n xktModel.author = metaModelData.author || \"\";\n xktModel.createdAt = metaModelData.createdAt || \"\";\n xktModel.creatingApplication = metaModelData.creatingApplication || \"\";\n xktModel.schema = metaModelData.schema || \"\";\n\n for (let i = 0, len = propertySets.length; i < len; i++) {\n\n const propertySet = propertySets[i];\n\n xktModel.createPropertySet({\n propertySetId: propertySet.id,\n propertySetName: propertySet.name,\n propertySetType: propertySet.type,\n properties: propertySet.properties\n });\n }\n\n let includeTypesMap;\n if (includeTypes) {\n includeTypesMap = {};\n for (let i = 0, len = includeTypes.length; i < len; i++) {\n includeTypesMap[includeTypes[i]] = true;\n }\n }\n\n let excludeTypesMap;\n if (excludeTypes) {\n excludeTypesMap = {};\n for (let i = 0, len = excludeTypes.length; i < len; i++) {\n excludeTypesMap[excludeTypes[i]] = true;\n }\n }\n\n const metaObjectsMap = {};\n\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n const newObject = metaObjects[i];\n metaObjectsMap[newObject.id] = newObject;\n }\n\n let countMetaObjects = 0;\n\n for (let i = 0, len = metaObjects.length; i < len; i++) {\n\n const metaObject = metaObjects[i];\n const type = metaObject.type;\n\n if (excludeTypesMap && excludeTypesMap[type]) {\n continue;\n }\n\n if (includeTypesMap && !includeTypesMap[type]) {\n continue;\n }\n\n if (metaObject.parent !== undefined && metaObject.parent !== null) {\n const metaObjectParent = metaObjectsMap[metaObject.parent];\n if (metaObject.type === metaObjectParent.type) { // Don't create redundant sub-objects\n continue\n }\n }\n\n const propertySetIds = [];\n if (metaObject.propertySetIds) {\n for (let j = 0, lenj = metaObject.propertySetIds.length; j < lenj; j++) {\n const propertySetId = metaObject.propertySetIds[j];\n if (propertySetId !== undefined && propertySetId !== null && propertySetId !== \"\") {\n propertySetIds.push(propertySetId);\n }\n }\n }\n if (metaObject.propertySetId !== undefined && metaObject.propertySetId !== null && metaObject.propertySetId !== \"\") {\n propertySetIds.push(metaObject.propertySetId);\n }\n\n xktModel.createMetaObject({\n metaObjectId: metaObject.id,\n metaObjectType: metaObject.type,\n metaObjectName: metaObject.name,\n parentMetaObjectId: metaObject.parent,\n propertySetIds: propertySetIds.length > 0 ? propertySetIds : null\n });\n\n countMetaObjects++;\n }\n\n if (log) {\n log(\"Converted meta objects: \" + countMetaObjects);\n }\n\n resolve();\n });\n}\n\nexport {parseMetaModelIntoXKTModel};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/parsers/parseMetaModelIntoXKTModel.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/parsers/parseMetaModelIntoXKTModel.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 480, + "__docId__": 468, "kind": "function", "name": "parseMetaModelIntoXKTModel", "memberof": "src/parsers/parseMetaModelIntoXKTModel.js", @@ -14033,18 +13593,18 @@ } }, { - "__docId__": 481, + "__docId__": 469, "kind": "file", "name": "src/parsers/parsePCDIntoXKTModel.js", "content": "/**\n * @desc Parses PCD point cloud data into an {@link XKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an LAZ point cloud model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"\"./models/pcd/ism_test_cat.pcd\"\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * await parsePCDIntoXKTModel({\n * data,\n * xktModel,\n * log: (msg) => { console.log(msg); }\n * }).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer} params.data PCD file data.\n * @param {Boolean} [params.littleEndian=true] Whether PCD binary data is Little-Endian or Big-Endian.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when PCD has been parsed.\n */\nfunction parsePCDIntoXKTModel({data, xktModel, littleEndian = true, stats, log}) {\n\n if (log) {\n log(\"Using parser: parsePCDIntoXKTModel\");\n }\n\n return new Promise(function(resolve, reject) {\n\n const textData = decodeText(new Uint8Array(data));\n\n const header = parseHeader(textData);\n\n const positions = [];\n const normals = [];\n const colors = [];\n\n if (header.data === 'ascii') {\n\n const offset = header.offset;\n const data = textData.substr(header.headerLen);\n const lines = data.split('\\n');\n\n for (let i = 0, l = lines.length; i < l; i++) {\n\n if (lines[i] === '') {\n continue;\n }\n\n const line = lines[i].split(' ');\n\n if (offset.x !== undefined) {\n positions.push(parseFloat(line[offset.x]));\n positions.push(parseFloat(line[offset.y]));\n positions.push(parseFloat(line[offset.z]));\n }\n\n if (offset.rgb !== undefined) {\n const rgb = parseFloat(line[offset.rgb]);\n const r = (rgb >> 16) & 0x0000ff;\n const g = (rgb >> 8) & 0x0000ff;\n const b = (rgb >> 0) & 0x0000ff;\n colors.push(r, g, b, 255);\n } else {\n colors.push(255);\n colors.push(255);\n colors.push(255);\n }\n }\n }\n\n if (header.data === 'binary_compressed') {\n\n const sizes = new Uint32Array(data.slice(header.headerLen, header.headerLen + 8));\n const compressedSize = sizes[0];\n const decompressedSize = sizes[1];\n const decompressed = decompressLZF(new Uint8Array(data, header.headerLen + 8, compressedSize), decompressedSize);\n const dataview = new DataView(decompressed.buffer);\n const offset = header.offset;\n\n for (let i = 0; i < header.points; i++) {\n\n if (offset.x !== undefined) {\n positions.push(dataview.getFloat32((header.points * offset.x) + header.size[0] * i, littleEndian));\n positions.push(dataview.getFloat32((header.points * offset.y) + header.size[1] * i, littleEndian));\n positions.push(dataview.getFloat32((header.points * offset.z) + header.size[2] * i, littleEndian));\n }\n\n if (offset.rgb !== undefined) {\n colors.push(dataview.getUint8((header.points * offset.rgb) + header.size[3] * i + 0));\n colors.push(dataview.getUint8((header.points * offset.rgb) + header.size[3] * i + 1));\n colors.push(dataview.getUint8((header.points * offset.rgb) + header.size[3] * i + 2));\n // colors.push(255);\n } else {\n colors.push(1);\n colors.push(1);\n colors.push(1);\n }\n }\n }\n\n if (header.data === 'binary') {\n\n const dataview = new DataView(data, header.headerLen);\n const offset = header.offset;\n\n for (let i = 0, row = 0; i < header.points; i++, row += header.rowSize) {\n if (offset.x !== undefined) {\n positions.push(dataview.getFloat32(row + offset.x, littleEndian));\n positions.push(dataview.getFloat32(row + offset.y, littleEndian));\n positions.push(dataview.getFloat32(row + offset.z, littleEndian));\n }\n\n if (offset.rgb !== undefined) {\n colors.push(dataview.getUint8(row + offset.rgb + 2));\n colors.push(dataview.getUint8(row + offset.rgb + 1));\n colors.push(dataview.getUint8(row + offset.rgb + 0));\n } else {\n colors.push(255);\n colors.push(255);\n colors.push(255);\n }\n }\n }\n\n xktModel.createGeometry({\n geometryId: \"pointsGeometry\",\n primitiveType: \"points\",\n positions: positions,\n colors: colors && colors.length > 0 ? colors : null\n });\n\n xktModel.createMesh({\n meshId: \"pointsMesh\",\n geometryId: \"pointsGeometry\"\n });\n\n xktModel.createEntity({\n entityId: \"geometries\",\n meshIds: [\"pointsMesh\"]\n });\n\n if (log) {\n log(\"Converted drawable objects: 1\");\n log(\"Converted geometries: 1\");\n log(\"Converted vertices: \" + positions.length / 3);\n }\n\n if (stats) {\n stats.sourceFormat = \"PCD\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numVertices = positions.length / 3;\n }\n\n resolve();\n });\n}\n\nfunction parseHeader(data) {\n const header = {};\n const result1 = data.search(/[\\r\\n]DATA\\s(\\S*)\\s/i);\n const result2 = /[\\r\\n]DATA\\s(\\S*)\\s/i.exec(data.substr(result1 - 1));\n header.data = result2[1];\n header.headerLen = result2[0].length + result1;\n header.str = data.substr(0, header.headerLen);\n header.str = header.str.replace(/\\#.*/gi, ''); // Strip comments\n header.version = /VERSION (.*)/i.exec(header.str); // Parse\n header.fields = /FIELDS (.*)/i.exec(header.str);\n header.size = /SIZE (.*)/i.exec(header.str);\n header.type = /TYPE (.*)/i.exec(header.str);\n header.count = /COUNT (.*)/i.exec(header.str);\n header.width = /WIDTH (.*)/i.exec(header.str);\n header.height = /HEIGHT (.*)/i.exec(header.str);\n header.viewpoint = /VIEWPOINT (.*)/i.exec(header.str);\n header.points = /POINTS (.*)/i.exec(header.str);\n if (header.version !== null) {\n header.version = parseFloat(header.version[1]);\n }\n if (header.fields !== null) {\n header.fields = header.fields[1].split(' ');\n }\n if (header.type !== null) {\n header.type = header.type[1].split(' ');\n }\n if (header.width !== null) {\n header.width = parseInt(header.width[1]);\n }\n if (header.height !== null) {\n header.height = parseInt(header.height[1]);\n }\n if (header.viewpoint !== null) {\n header.viewpoint = header.viewpoint[1];\n }\n if (header.points !== null) {\n header.points = parseInt(header.points[1], 10);\n }\n if (header.points === null) {\n header.points = header.width * header.height;\n }\n if (header.size !== null) {\n header.size = header.size[1].split(' ').map(function (x) {\n return parseInt(x, 10);\n });\n }\n if (header.count !== null) {\n header.count = header.count[1].split(' ').map(function (x) {\n return parseInt(x, 10);\n });\n } else {\n header.count = [];\n for (let i = 0, l = header.fields.length; i < l; i++) {\n header.count.push(1);\n }\n }\n header.offset = {};\n let sizeSum = 0;\n for (let i = 0, l = header.fields.length; i < l; i++) {\n if (header.data === 'ascii') {\n header.offset[header.fields[i]] = i;\n } else {\n header.offset[header.fields[i]] = sizeSum;\n sizeSum += header.size[i] * header.count[i];\n }\n }\n header.rowSize = sizeSum; // For binary only\n return header;\n}\n\nfunction decodeText(array) {\n if (typeof TextDecoder !== 'undefined') {\n return new TextDecoder().decode(array);\n }\n let s = '';\n for (let i = 0, il = array.length; i < il; i++) {\n s += String.fromCharCode(array[i]);\n }\n try {\n return decodeURIComponent(escape(s));\n } catch (e) {\n return s;\n }\n}\n\nfunction decompressLZF(inData, outLength) { // https://gitlab.com/taketwo/three-pcd-loader/blob/master/decompress-lzf.js\n const inLength = inData.length;\n const outData = new Uint8Array(outLength);\n let inPtr = 0;\n let outPtr = 0;\n let ctrl;\n let len;\n let ref;\n do {\n ctrl = inData[inPtr++];\n if (ctrl < (1 << 5)) {\n ctrl++;\n if (outPtr + ctrl > outLength) throw new Error('Output buffer is not large enough');\n if (inPtr + ctrl > inLength) throw new Error('Invalid compressed data');\n do {\n outData[outPtr++] = inData[inPtr++];\n } while (--ctrl);\n } else {\n len = ctrl >> 5;\n ref = outPtr - ((ctrl & 0x1f) << 8) - 1;\n if (inPtr >= inLength) throw new Error('Invalid compressed data');\n if (len === 7) {\n len += inData[inPtr++];\n if (inPtr >= inLength) throw new Error('Invalid compressed data');\n }\n ref -= inData[inPtr++];\n if (outPtr + len + 2 > outLength) throw new Error('Output buffer is not large enough');\n if (ref < 0) throw new Error('Invalid compressed data');\n if (ref >= outPtr) throw new Error('Invalid compressed data');\n do {\n outData[outPtr++] = outData[ref++];\n } while (--len + 2);\n }\n } while (inPtr < inLength);\n return outData;\n}\n\nexport {parsePCDIntoXKTModel};", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/parsers/parsePCDIntoXKTModel.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/parsers/parsePCDIntoXKTModel.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 482, + "__docId__": 470, "kind": "function", "name": "parseHeader", "memberof": "src/parsers/parsePCDIntoXKTModel.js", @@ -14075,7 +13635,7 @@ "ignore": true }, { - "__docId__": 483, + "__docId__": 471, "kind": "function", "name": "decodeText", "memberof": "src/parsers/parsePCDIntoXKTModel.js", @@ -14106,7 +13666,7 @@ "ignore": true }, { - "__docId__": 484, + "__docId__": 472, "kind": "function", "name": "decompressLZF", "memberof": "src/parsers/parsePCDIntoXKTModel.js", @@ -14143,7 +13703,7 @@ "ignore": true }, { - "__docId__": 485, + "__docId__": 473, "kind": "function", "name": "parsePCDIntoXKTModel", "memberof": "src/parsers/parsePCDIntoXKTModel.js", @@ -14237,18 +13797,18 @@ } }, { - "__docId__": 486, + "__docId__": 474, "kind": "file", "name": "src/parsers/parsePLYIntoXKTModel.js", "content": "import {parse} from '@loaders.gl/core';\nimport {PLYLoader} from '@loaders.gl/ply';\n\n/**\n * @desc Parses PLY file data into an {@link XKTModel}.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load a PLY model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"./models/ply/test.ply\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parsePLYIntoXKTModel({data, xktModel}).then(()=>{\n * xktModel.finalize();\n * },\n * (msg) => {\n * console.error(msg);\n * });\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer} params.data PLY file data.\n * @param {XKTModel} params.xktModel XKTModel to parse into.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when PLY has been parsed.\n */\nasync function parsePLYIntoXKTModel({data, xktModel, stats, log}) {\n\n if (log) {\n log(\"Using parser: parsePLYIntoXKTModel\");\n }\n\n if (!data) {\n throw \"Argument expected: data\";\n }\n\n if (!xktModel) {\n throw \"Argument expected: xktModel\";\n }\n\n let parsedData;\n try {\n parsedData = await parse(data, PLYLoader);\n } catch (e) {\n if (log) {\n log(\"Error: \" + e);\n }\n return;\n }\n\n const attributes = parsedData.attributes;\n const hasColors = !!attributes.COLOR_0;\n\n if (hasColors) {\n const colorsValue = hasColors ? attributes.COLOR_0.value : null;\n const colorsCompressed = [];\n for (let i = 0, len = colorsValue.length; i < len; i += 4) {\n colorsCompressed.push(colorsValue[i]);\n colorsCompressed.push(colorsValue[i + 1]);\n colorsCompressed.push(colorsValue[i + 2]);\n }\n xktModel.createGeometry({\n geometryId: \"plyGeometry\",\n primitiveType: \"triangles\",\n positions: attributes.POSITION.value,\n indices: parsedData.indices ? parsedData.indices.value : [],\n colorsCompressed: colorsCompressed\n });\n } else {\n xktModel.createGeometry({\n geometryId: \"plyGeometry\",\n primitiveType: \"triangles\",\n positions: attributes.POSITION.value,\n indices: parsedData.indices ? parsedData.indices.value : []\n });\n }\n\n xktModel.createMesh({\n meshId: \"plyMesh\",\n geometryId: \"plyGeometry\",\n color: (!hasColors) ? [1, 1, 1] : null\n });\n\n xktModel.createEntity({\n entityId: \"ply\",\n meshIds: [\"plyMesh\"]\n });\n\n if (stats) {\n stats.sourceFormat = \"PLY\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 2;\n stats.numPropertySets = 0;\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numVertices = attributes.POSITION.value.length / 3;\n }\n}\n\nexport {parsePLYIntoXKTModel};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/parsers/parsePLYIntoXKTModel.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/parsers/parsePLYIntoXKTModel.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 487, + "__docId__": 475, "kind": "function", "name": "parsePLYIntoXKTModel", "memberof": "src/parsers/parsePLYIntoXKTModel.js", @@ -14330,18 +13890,18 @@ } }, { - "__docId__": 488, + "__docId__": 476, "kind": "file", "name": "src/parsers/parseSTLIntoXKTModel.js", "content": "import {faceToVertexNormals} from \"../lib/faceToVertexNormals.js\";\nimport {math} from \"../lib/math.js\";\n\n/**\n * @desc Parses STL file data into an {@link XKTModel}.\n *\n * * Supports binary and ASCII STL formats.\n * * Option to create a separate {@link XKTEntity} for each group of faces that share the same vertex colors.\n * * Option to smooth face-aligned normals loaded from STL.\n * * Option to reduce XKT file size by ignoring STL normals and relying on xeokit to auto-generate them.\n *\n * ## Usage\n *\n * In the example below we'll create an {@link XKTModel}, then load an STL model into it.\n *\n * ````javascript\n * utils.loadArraybuffer(\"./models/stl/binary/spurGear.stl\", async (data) => {\n *\n * const xktModel = new XKTModel();\n *\n * parseSTLIntoXKTModel({data, xktModel});\n *\n * xktModel.finalize();\n * });\n * ````\n *\n * @param {Object} params Parsing params.\n * @param {ArrayBuffer|String} [params.data] STL file data. Can be binary or string.\n * @param {Boolean} [params.autoNormals=false] When true, the parser will ignore the STL geometry normals, and the STL\n * data will rely on the xeokit ````Viewer```` to automatically generate them. This has the limitation that the\n * normals will be face-aligned, and therefore the ````Viewer```` will only be able to render a flat-shaded representation\n * of the STL.\n * Overrides ````smoothNormals```` when ````true````. This ignores the normals in the STL, and loads no\n * normals from the STL into the {@link XKTModel}, resulting in the XKT file storing no normals for the STL model. The\n * xeokit-sdk will then automatically generate the normals within its shaders. The disadvantages are that auto-normals\n * may slow rendering down a little bit, and that the normals can only be face-aligned (and thus rendered using flat\n * shading). The advantages, however, are a smaller XKT file size, and the ability to apply certain geometry optimizations\n * during parsing, such as removing duplicated STL vertex positions, that are not possible when normals are loaded\n * for the STL vertices.\n * @param {Boolean} [params.smoothNormals=true] When true, automatically converts face-oriented STL normals to vertex normals, for a smooth appearance. Ignored if ````autoNormals```` is ````true````.\n * @param {Number} [params.smoothNormalsAngleThreshold=20] This is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n * @param {Boolean} [params.splitMeshes=true] When true, creates a separate {@link XKTEntity} for each group of faces that share the same vertex colors. Only works with binary STL (ie. when ````data```` is an ArrayBuffer).\n * @param {XKTModel} [params.xktModel] XKTModel to parse into.\n * @param {Object} [params.stats] Collects statistics.\n * @param {function} [params.log] Logging callback.\n @returns {Promise} Resolves when STL has been parsed.\n */\nasync function parseSTLIntoXKTModel({\n data,\n splitMeshes,\n autoNormals,\n smoothNormals,\n smoothNormalsAngleThreshold,\n xktModel,\n stats,\n log\n }) {\n\n if (log) {\n log(\"Using parser: parseSTLIntoXKTModel\");\n }\n\n return new Promise(function (resolve, reject) {\n\n if (!data) {\n reject(\"Argument expected: data\");\n return;\n }\n\n if (!xktModel) {\n reject(\"Argument expected: xktModel\");\n return;\n }\n\n const rootMetaObjectId = math.createUUID();\n\n const rootMetaObject = xktModel.createMetaObject({\n metaObjectId: rootMetaObjectId,\n metaObjectType: \"Model\",\n metaObjectName: \"Model\"\n });\n\n const ctx = {\n data,\n splitMeshes,\n autoNormals,\n smoothNormals,\n smoothNormalsAngleThreshold,\n xktModel,\n rootMetaObject,\n nextId: 0,\n log: (log || function (msg) {\n }),\n stats: {\n numObjects: 0,\n numGeometries: 0,\n numTriangles: 0,\n numVertices: 0\n }\n };\n\n const binData = ensureBinary(data);\n\n if (isBinary(binData)) {\n parseBinary(ctx, binData);\n } else {\n parseASCII(ctx, ensureString(data));\n }\n\n if (stats) {\n stats.sourceFormat = \"STL\";\n stats.schemaVersion = \"\";\n stats.title = \"\";\n stats.author = \"\";\n stats.created = \"\";\n stats.numMetaObjects = 2;\n stats.numPropertySets = 0;\n stats.numObjects = 1;\n stats.numGeometries = 1;\n stats.numTriangles = ctx.stats.numTriangles;\n stats.numVertices = ctx.stats.numVertices;\n }\n\n resolve();\n });\n}\n\nfunction isBinary(data) {\n const reader = new DataView(data);\n const numFaces = reader.getUint32(80, true);\n const faceSize = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);\n const numExpectedBytes = 80 + (32 / 8) + (numFaces * faceSize);\n if (numExpectedBytes === reader.byteLength) {\n return true;\n }\n const solid = [115, 111, 108, 105, 100];\n for (let i = 0; i < 5; i++) {\n if (solid[i] !== reader.getUint8(i, false)) {\n return true;\n }\n }\n return false;\n}\n\nfunction parseBinary(ctx, data) {\n const reader = new DataView(data);\n const faces = reader.getUint32(80, true);\n let r;\n let g;\n let b;\n let hasColors = false;\n let colors;\n let defaultR;\n let defaultG;\n let defaultB;\n let lastR = null;\n let lastG = null;\n let lastB = null;\n let newMesh = false;\n let alpha;\n for (let index = 0; index < 80 - 10; index++) {\n if ((reader.getUint32(index, false) === 0x434F4C4F /*COLO*/) &&\n (reader.getUint8(index + 4) === 0x52 /*'R'*/) &&\n (reader.getUint8(index + 5) === 0x3D /*'='*/)) {\n hasColors = true;\n colors = [];\n defaultR = reader.getUint8(index + 6) / 255;\n defaultG = reader.getUint8(index + 7) / 255;\n defaultB = reader.getUint8(index + 8) / 255;\n alpha = reader.getUint8(index + 9) / 255;\n }\n }\n let dataOffset = 84;\n let faceLength = 12 * 4 + 2;\n let positions = [];\n let normals = [];\n let splitMeshes = ctx.splitMeshes;\n for (let face = 0; face < faces; face++) {\n let start = dataOffset + face * faceLength;\n let normalX = reader.getFloat32(start, true);\n let normalY = reader.getFloat32(start + 4, true);\n let normalZ = reader.getFloat32(start + 8, true);\n if (hasColors) {\n let packedColor = reader.getUint16(start + 48, true);\n if ((packedColor & 0x8000) === 0) {\n r = (packedColor & 0x1F) / 31;\n g = ((packedColor >> 5) & 0x1F) / 31;\n b = ((packedColor >> 10) & 0x1F) / 31;\n } else {\n r = defaultR;\n g = defaultG;\n b = defaultB;\n }\n if (splitMeshes && r !== lastR || g !== lastG || b !== lastB) {\n if (lastR !== null) {\n newMesh = true;\n }\n lastR = r;\n lastG = g;\n lastB = b;\n }\n }\n for (let i = 1; i <= 3; i++) {\n let vertexstart = start + i * 12;\n positions.push(reader.getFloat32(vertexstart, true));\n positions.push(reader.getFloat32(vertexstart + 4, true));\n positions.push(reader.getFloat32(vertexstart + 8, true));\n if (!ctx.autoNormals) {\n normals.push(normalX, normalY, normalZ);\n }\n if (hasColors) {\n colors.push(r, g, b, 1); // TODO: handle alpha\n }\n }\n if (splitMeshes && newMesh) {\n addMesh(ctx, positions, normals, colors);\n positions = [];\n normals = [];\n colors = colors ? [] : null;\n newMesh = false;\n }\n }\n if (positions.length > 0) {\n addMesh(ctx, positions, normals, colors);\n }\n}\n\nfunction parseASCII(ctx, data) {\n const faceRegex = /facet([\\s\\S]*?)endfacet/g;\n let faceCounter = 0;\n const floatRegex = /[\\s]+([+-]?(?:\\d+.\\d+|\\d+.|\\d+|.\\d+)(?:[eE][+-]?\\d+)?)/.source;\n const vertexRegex = new RegExp('vertex' + floatRegex + floatRegex + floatRegex, 'g');\n const normalRegex = new RegExp('normal' + floatRegex + floatRegex + floatRegex, 'g');\n const positions = [];\n const normals = [];\n const colors = null;\n let normalx;\n let normaly;\n let normalz;\n let result;\n let verticesPerFace;\n let normalsPerFace;\n let text;\n while ((result = faceRegex.exec(data)) !== null) {\n verticesPerFace = 0;\n normalsPerFace = 0;\n text = result[0];\n while ((result = normalRegex.exec(text)) !== null) {\n normalx = parseFloat(result[1]);\n normaly = parseFloat(result[2]);\n normalz = parseFloat(result[3]);\n normalsPerFace++;\n }\n while ((result = vertexRegex.exec(text)) !== null) {\n positions.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n normals.push(normalx, normaly, normalz);\n verticesPerFace++;\n }\n if (normalsPerFace !== 1) {\n ctx.log(\"Error in normal of face \" + faceCounter);\n return -1;\n }\n if (verticesPerFace !== 3) {\n ctx.log(\"Error in positions of face \" + faceCounter);\n return -1;\n }\n faceCounter++;\n }\n addMesh(ctx, positions, normals, colors);\n}\n\nlet nextGeometryId = 0;\n\nfunction addMesh(ctx, positions, normals, colors) {\n\n const indices = new Int32Array(positions.length / 3);\n for (let ni = 0, len = indices.length; ni < len; ni++) {\n indices[ni] = ni;\n }\n\n normals = normals && normals.length > 0 ? normals : null;\n colors = colors && colors.length > 0 ? colors : null;\n\n if (!ctx.autoNormals && ctx.smoothNormals) {\n faceToVertexNormals(positions, normals, {smoothNormalsAngleThreshold: ctx.smoothNormalsAngleThreshold});\n }\n\n const geometryId = \"\" + nextGeometryId++;\n const meshId = \"\" + nextGeometryId++;\n const entityId = \"\" + nextGeometryId++;\n\n ctx.xktModel.createGeometry({\n geometryId: geometryId,\n primitiveType: \"triangles\",\n positions: positions,\n normals: (!ctx.autoNormals) ? normals : null,\n colors: colors,\n indices: indices\n });\n\n ctx.xktModel.createMesh({\n meshId: meshId,\n geometryId: geometryId,\n color: colors ? null : [1, 1, 1],\n metallic: 0.9,\n roughness: 0.1\n });\n\n ctx.xktModel.createEntity({\n entityId: entityId,\n meshIds: [meshId]\n });\n\n ctx.xktModel.createMetaObject({\n metaObjectId: entityId,\n metaObjectType: \"Default\",\n metaObjectName: \"STL Mesh\",\n parentMetaObjectId: ctx.rootMetaObject.metaObjectId\n });\n\n ctx.stats.numGeometries++;\n ctx.stats.numObjects++;\n ctx.stats.numVertices += positions.length / 3;\n ctx.stats.numTriangles += indices.length / 3;\n}\n\nfunction ensureString(buffer) {\n if (typeof buffer !== 'string') {\n return decodeText(new Uint8Array(buffer));\n }\n return buffer;\n}\n\nfunction ensureBinary(buffer) {\n if (typeof buffer === 'string') {\n const arrayBuffer = new Uint8Array(buffer.length);\n for (let i = 0; i < buffer.length; i++) {\n arrayBuffer[i] = buffer.charCodeAt(i) & 0xff; // implicitly assumes little-endian\n }\n return arrayBuffer.buffer || arrayBuffer;\n } else {\n return buffer;\n }\n}\n\nfunction decodeText(array) {\n if (typeof TextDecoder !== 'undefined') {\n return new TextDecoder().decode(array);\n }\n let s = '';\n for (let i = 0, il = array.length; i < il; i++) {\n s += String.fromCharCode(array[i]); // Implicitly assumes little-endian.\n }\n return decodeURIComponent(escape(s));\n}\n\nexport {parseSTLIntoXKTModel};\n", "static": true, - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/src/parsers/parseSTLIntoXKTModel.js", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/src/parsers/parseSTLIntoXKTModel.js", "access": "public", "description": null, "lineNumber": 1 }, { - "__docId__": 489, + "__docId__": 477, "kind": "function", "name": "isBinary", "memberof": "src/parsers/parseSTLIntoXKTModel.js", @@ -14372,7 +13932,7 @@ "ignore": true }, { - "__docId__": 490, + "__docId__": 478, "kind": "function", "name": "parseBinary", "memberof": "src/parsers/parseSTLIntoXKTModel.js", @@ -14405,7 +13965,7 @@ "ignore": true }, { - "__docId__": 491, + "__docId__": 479, "kind": "function", "name": "parseASCII", "memberof": "src/parsers/parseSTLIntoXKTModel.js", @@ -14442,7 +14002,7 @@ "ignore": true }, { - "__docId__": 492, + "__docId__": 480, "kind": "variable", "name": "nextGeometryId", "memberof": "src/parsers/parseSTLIntoXKTModel.js", @@ -14463,7 +14023,7 @@ "ignore": true }, { - "__docId__": 493, + "__docId__": 481, "kind": "function", "name": "addMesh", "memberof": "src/parsers/parseSTLIntoXKTModel.js", @@ -14508,7 +14068,7 @@ "ignore": true }, { - "__docId__": 494, + "__docId__": 482, "kind": "function", "name": "ensureString", "memberof": "src/parsers/parseSTLIntoXKTModel.js", @@ -14539,7 +14099,7 @@ "ignore": true }, { - "__docId__": 495, + "__docId__": 483, "kind": "function", "name": "ensureBinary", "memberof": "src/parsers/parseSTLIntoXKTModel.js", @@ -14570,7 +14130,7 @@ "ignore": true }, { - "__docId__": 496, + "__docId__": 484, "kind": "function", "name": "decodeText", "memberof": "src/parsers/parseSTLIntoXKTModel.js", @@ -14601,7 +14161,7 @@ "ignore": true }, { - "__docId__": 497, + "__docId__": 485, "kind": "function", "name": "parseSTLIntoXKTModel", "memberof": "src/parsers/parseSTLIntoXKTModel.js", @@ -14734,15 +14294,15 @@ { "kind": "index", "content": "# xeokit-convert\n\n[![Twitter Follow](https://img.shields.io/twitter/follow/xeolabs?style=social)](https://twitter.com/xeolabs)\n[![npm version](https://badge.fury.io/js/%40xeokit%2Fxeokit-convert.svg)](https://badge.fury.io/js/%40xeokit%2Fxeokit-convert)\n\nUse **xeokit-convert** to:\n\n* Convert BIM and AEC models directly into XKT files for super fast loading into [xeokit](https://xeokit.io)\n* Generate XKT files with JavaScript\n\n> xeokit-convert replaces [xeokit-gltf-to-xkt](https://github.com/xeokit/xeokit-gltf-to-xkt) and [xeokit-xkt-utils](https://github.com/xeokit/xeokit-xkt-utils), which are deprecated.\n\n> CAUTION: Direct IFC conversion is an alpha status feature, since it depends on [web-ifc](https://github.com/tomvandig/web-ifc), a 3rd-party library, which is also alpha at this time. As such, some IFC models may not convert properly. If this is the case for your models, consider using our [standard conversion setup](https://www.notion.so/xeokit/Converting-IFC-Models-using-3rd-Party-Open-Source-Tools-c373e48bc4094ff5b6e5c5700ff580ee)\nuntil issues have been resolved. Also, direct IFC conversion does not currently support all property sets.\n\n---\n\n# Contents\n\n- [Introduction](#introduction)\n- [Acknowledgements](#acknowledgements)\n- [Resources](#resources)\n- [Features](#features)\n- [Installing](#installing)\n- [Components](#components)\n- [Using ````convert2xkt````](#using-----convert2xkt----)\n + [Converting an IFC file into an XKT file on the command line](#converting-an-ifc-file-into-an-xkt-file-on-the-command-line)\n + [Viewing the XKT file with xeokit](#viewing-the-xkt-file-with-xeokit)\n + [Querying the XKT version in Node.js](#querying-the-xkt-version-in-nodejs)\n + [Converting an IFC file into an XKT file in Node.js](#converting-an-ifc-file-into-an-xkt-file-in-nodejs)\n + [Converting IFC file data into XKT data in Node.js](#converting-ifc-file-data-into-xkt-data-in-nodejs)\n- [Converting Split Files Output from ````ifc2gltf````](#converting-split-files-from-ifc2gltf)\n- [Using ````XKTModel````](#using-----xktmodel----)\n + [Programmatically Building an XKT File](#programmatically-building-an-xkt-file)\n + [Serializing the XKTModel to an ArrayBuffer](#serializing-the-xktmodel-to-an-arraybuffer)\n + [Loading the ArrayBuffer into a Viewer](#loading-the-arraybuffer-into-a-viewer)\n + [Loading IFC into an XKTModel](#loading-ifc-into-an-xktmodel)\n + [Loading LAS into an XKTModel](#loading-las-into-an-xktmodel)\n + [Loading GLB into an XKTModel](#loading-glb-into-an-xktmodel)\n + [Loading STL into an XKTModel](#loading-stl-into-an-xktmodel)\n- [Building](#building)\n + [Building Binaries](#building-binaries)\n\n---\n\n# Introduction\n\n[````xeokit-convert````](https://github.com/xeokit/xeokit-convert) provides the means to convert 3D BIM and AEC models\ninto XKT files for super fast loading into [xeokit](https://xeokit.io), along with programming tools to generate XKT\nfiles with JavaScript on Node.js.\n\nThe [XKT format](https://github.com/xeokit/xeokit-convert/tree/master/specs) compresses large double-precision models to\na compact payload that loads quickly over the Web into a xeokit viewer running in the browser. We can use xeokit-convert\nto convert several source formats into XKT, such as IFC, GLB and CityJSON.\n\n# Acknowledgements\n\nOur thanks to the authors of these open source libraries, which we use internally within ````xeokit-convert````:\n\n* [loaders.gl](https://loaders.gl) - Copyright (C) 2015 Uber Technologies,\n Inc. ([MIT License](http://www.opensource.org/licenses/mit-license.php))\n* [Basis Universal](https://github.com/BinomialLLC/basis_universal) - Binomal\n LLC, ([Apache 2 License](http://www.apache.org/licenses/LICENSE-2.0))\n* [Pako](https://github.com/nodeca/pako) - Copyright (C) 2014-2017 by Vitaly Puzrin and Andrei\n Tuputcyn ([MIT License](http://www.opensource.org/licenses/mit-license.php))\n* [earcut](https://github.com/mapbox/earcut) - Copyright (C) 2016,\n Mapbox ([ISC License](https://opensource.org/licenses/ISC))\n* [web-ifc](https://github.com/tomvandig/web-ifc) - Copyright (C) 2020-2021 web-ifc\n contributors ([Mozilla Public License Version 2.0](https://www.mozilla.org/en-US/MPL/2.0/))\n\n# Resources\n\n* [npm](https://www.npmjs.com/package/@xeokit/xeokit-convert)\n* [API Docs](https://xeokit.github.io/xeokit-convert/docs)\n* [Source Code](https://github.com/xeokit/xeokit-convert)\n* [Releases / Changelog](https://github.com/xeokit/xeokit-convert/releases)\n* [XKT Specifications](https://xeokit.github.io/xeokit-convert/specs/)\n\n# Features\n\n* A Node-based CLI tool to convert various 3D model formats to XKT files.\n* A JavaScript toolkit of components for loading, generating and saving XKT files.\n\n# Installing\n\nListed below these are the steps for installing and running `convert2xkt` on Linux. Make sure you have first installed \n`git` and that your version of `NodeJS` is at least `v16.10.0.`\n\n````bash\ngit clone https://github.com/xeokit/xeokit-convert.git\ncd xeokit-convert/\nnpm install\nnode convert2xkt.js -h\n\nUsage: convert2xkt [options]\n\nOptions:\n-v, --version output the version number\n-c, --configs [file] optional path to JSON configs file; overrides convert2xkt.conf.js\n-s, --source [file] path to source file\n-a, --sourcemanifest [file] path to source manifest file (for converting split file output from ifcgltf -s)\n-f, --format [string] source file format (optional); supported formats are glb, ifc, laz, las, pcd, ply, stl and cityjson\n-m, --metamodel [file] path to source metamodel JSON file (optional)\n-i, --include [types] only convert these types (optional)\n-x, --exclude [types] never convert these types (optional)\n-r, --rotatex rotate model 90 degrees about X axis (for las and cityjson)\n-g, --disablegeoreuse disable geometry reuse (optional)\n-z, --minTileSize [number] minimum diagonal tile size (optional, default 500)\n-t, --disabletextures ignore textures (optional)\n-n, --disablenormals ignore normals (optional)\n-o, --output [file] path to target .xkt file when -s option given, or JSON manifest for multiple .xkt files when source manifest\nfile given with -a; creates directories on path automatically if not existing\n-l, --log enable logging (optional)\n-h, --help display help for command\n````\n\nIf you get ````RuntimeError: memory access out of bounds```` while converting IFC, then you'll need to compile the\n3rd-party web-ifc WASM module for your system - see [Building Binaries](#building-binaries).\n\n# Components\n\nThe table below lists the components provided by ````xeokit-convert````.\n\nAt the center of the toolkit, we've got the converter tool, provided as both a Node.js function and CLI executable.\n\nBundled with the converter, we've got the XKT document model, a bunch of loaders for different formats, and a function\nto serialize the document model to a BLOB. We use these components within the converter tool, and also provide them as\npart of the public API for extensibility.\n\n| Component | Description |\n| --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [convert2xkt](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-convert2xkt) (function)
                                                                                                                          [convert2xkt](https://github.com/xeokit/xeokit-convert/blob/master/convert2xkt.js) (Node script)| A Node-based JavaScript function and CLI tool that converts various AEC model formats into xeokit's native, super-fast-loading XKT format. |\n| [XKTModel](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html) | A JavaScript document model that represents the contents of an XKT file in memory. Using this, we can programmatically build a document model in JavaScript, adding geometries, materials, objects etc, then serialize it to an XKT file. |\n| [parseIFCIntoXKTModel](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-parseIFCIntoXKTModel) | Parses IFC data into an ````XKTModel````. This is an alpha-status feature. |\n| [parseGLTFIntoXKTModel](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-parseGLTFIntoXKTModel) | Parses GLB into an ````XKTModel````. Supports textures. |\n| [parseCityJSONIntoXKTModel](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-parseJSONIntoXKTModel) | Parses CityJSON into an ````XKTModel```` |\n| [parseLASIntoXKTModel](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-parseLASIntoXKTModel) | Parses LAS and LAZ into an ````XKTModel```` |\n| [parseSTLIntoXKTModel](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-parseSTLIntoXKTModel) | Parses STL into an ````XKTModel```` |\n| [writeXKTModelToArrayBuffer](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-writeXKTModelToArrayBuffer) | Serializes an ````XKTModel```` to an XKT file |\n\n# Using ````convert2xkt````\n\nThe ````convert2xkt```` tool converts various model formats into xeokit's native XKT format, which is designed to load\nsuper fast over the Web into a xeokit viewer. We provide this tool as both a [CLI script]() and as\na [function](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-convert2xkt) to use within\nour own Node scripts.\n\n````bash\nnode convert2xkt.js -h\n\nUsage: convert2xkt [options]\n\nOptions:\n -v, --version output the version number\n -s, --source [file] path to source file\n -a, --sourcemanifest [file] path to source manifest file (for converting split file output from ifcgltf -s)\n -f, --format [string] source file format (optional); supported formats are glb, ifc, laz, las, pcd, ply, stl and cityjson\n -m, --metamodel [file] path to source metamodel JSON file (optional)\n -i, --include [types] only convert these types (optional)\n -x, --exclude [types] never convert these types (optional)\n -r, --rotatex rotate model 90 degrees about X axis (for las and cityjson)\n -g, --disablegeoreuse disable geometry reuse (optional)\n -z, --mintilesize [number] minimum diagonal tile size (optional, default 500)\n -t, --disabletextures ignore textures (optional)\n -n, --disablenormals ignore normals (optional)\n -o, --output [file] path to target .xkt file when -s option given, or JSON manifest for multiple .xkt files when source manifest file given with -a; creates directories on path automatically if not existing\n -l, --log enable logging (optional)\n -h, --help display help for command\n\nXKT version: 10\n````\n\n### Converting an IFC file into an XKT file on the command line\n\nLet's use the [convert2xkt](https://github.com/xeokit/xeokit-convert/blob/master/convert2xkt.js) Node script to convert\nan IFC file to XKT on the command line.\n\n````bash\nnode convert2xkt.js -s rme_advanced_sample_project.ifc -o rme_advanced_sample_project.ifc.xkt -l\n\n[convert2xkt] Reading input file: rme_advanced_sample_project.ifc\n[convert2xkt] Input file size: 35309.94 kB\n[convert2xkt] Geometry reuse is enabled\n[convert2xkt] Converting...\n[convert2xkt] Converted to: XKT v9\n[convert2xkt] XKT size: 1632.98 kB\n[convert2xkt] Compression ratio: 21.62\n[convert2xkt] Conversion time: 54.41 s\n[convert2xkt] Converted metaobjects: 0\n[convert2xkt] Converted property sets: 0\n[convert2xkt] Converted drawable objects: 1986\n[convert2xkt] Converted geometries: 3897\n[convert2xkt] Converted triangles: 286076\n[convert2xkt] Converted vertices: 547740\n[convert2xkt] reuseGeometries: false\n[convert2xkt] minTileSize: 10000\n[convert2xkt] Writing XKT file: rme_advanced_sample_project.ifc.xkt\n````\n\n### Viewing the XKT file with xeokit\n\nNow that we've got an XKT file, we can now view it in the browser using a\nxeokit [Viewer](https://xeokit.github.io/xeokit-sdk/docs/class/src/viewer/Viewer.js~Viewer.html) configured with\nan [XKTLoaderPlugin](https://xeokit.github.io/xeokit-sdk/docs/class/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js~XKTLoaderPlugin.html)\n.\n\n````javascript\nimport {Viewer, XKTLoaderPlugin} from\n \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk@1/dist/xeokit-sdk.es.min.js\";\n\nconst viewer = new Viewer({\n canvasId: \"myCanvas\"\n});\n\nconst xktLoader = new XKTLoaderPlugin(viewer);\n\nconst modelNode = xktLoader.load({\n id: \"myModel\",\n src: \"./rme_sample_project.ifc.xkt\"\n});\n````\n\n### Querying the XKT version in Node.js\n\nFrom with a Node script, we can query which XKT version ````xeokit-convert```` currently generates:\n\n````javascript\nconst {XKT_INFO} = require(\"./dist/xeokit-convert.cjs.js\");\n\nconst xktVersion = XKT_INFO.xktVersion; // Unsigned integer\nconsole.log(`XKT version: ${xktVersion}`);\n````\n\n### Converting an IFC file into an XKT file in Node.js\n\nWe can use\nthe [convert2xkt](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-convert2xkt)\nfunction from within our Nodejs scripts to programmatically convert files to XKT.\n\n````javascript\nconst convert2xkt = require(\"@xeokit/xeokit-convert/dist/convert2xkt.cjs.js\");\n\nconvert2xkt({\n source: \"rme_advanced_sample_project.ifc\",\n output: \"rme_advanced_sample_project.ifc.xkt\",\n log: (msg) => {\n console.log(msg)\n }\n}).then(() => {\n console.log(\"Converted.\");\n}, (errMsg) => {\n console.error(\"Conversion failed: \" + errMsg)\n});\n````\n\n### Converting IFC file data into XKT data in Node.js\n\nWhen using\nthe [convert2xkt](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-convert2xkt)\nfunction in our Node scripts, we can manage all file data in memory.\n\nThis is great for when we want more control over where we read and write the files.\n\n````javascript\nconst convert2xkt = require(\"@xeokit/xeokit-convert/dist/convert2xkt.cjs.js\");\nconst fs = require('fs');\n\nconvert2xkt({\n sourceData: fs.readFileSync(\"rme_advanced_sample_project.ifc\"),\n outputXKT: (xtkArrayBuffer) => {\n fs.writeFileSync(\"rme_advanced_sample_project.ifc.xkt\", xtkArrayBuffer);\n }\n}).then(() => {\n console.log(\"Converted.\");\n}, (errMsg) => {\n console.error(\"Conversion failed: \" + errMsg)\n});\n````\n\nWhen using\nthe [convert2xkt](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-convert2xkt)\nfunction in our Node scripts, we can manage all file data in memory.\n\nThis is great for when we want more control over where we read and write the files.\n\n````javascript\nconst convert2xkt = require(\"@xeokit/xeokit-convert/dist/convert2xkt.cjs.js\");\nconst fs = require('fs');\n\nconvert2xkt({\n sourceData: fs.readFileSync(\"rme_advanced_sample_project.ifc\"),\n outputXKT: (xtkArrayBuffer) => {\n fs.writeFileSync(\"rme_advanced_sample_project.ifc.xkt\", xtkArrayBuffer);\n }\n}).then(() => {\n console.log(\"Converted.\");\n}, (errMsg) => {\n console.error(\"Conversion failed: \" + errMsg)\n});\n````\n\n# Converting Split Files Output from ````ifc2gltf````\n\nThe ````ifc2gltf```` tool has the option to convert IFC files into multiple GLB and JSON metadata files. We can then use ````convert2xkt```` to convert each of these \nfiles individually. This allows us to convert a huge IFC files into several, smaller XKT files, then load \nthose XKT files individually into a xeokit Viewer.\n\n## Usage\n\nRun ````ifc2gltf```` with the ````-s```` option, to convert an IFC file into a set of multiple ````glb```` geometry and ````json```` metadata files:\n\n````\nifc2gltfcxconverter -i model.ifc -o myGLBFiles/model.glb -m myGLBFiles/model.json -s 100\n````\n\nThe ````ifc2gltf```` ````-s 100```` option causes ````ifc2gltf```` to split the output into these multiple files, each no bigger than 100MBytes.\n\nThe contents of the ````myGLBFiles```` directory then looks like this:\n\n````\nmyGLBFiles\n├── model.glb\n├── model.json\n├── model_1.glb\n├── model_1.json\n├── model_2.glb\n├── model_2.json\n├── model_3.glb\n├── model_3.json\n└── model.glb.manifest.json\n````\n\nNow run ````convert2xkt```` with the ````-a```` option, pointing to the ````myGLBFiles/model.glb.manifest.json```` file:\n\n````bash\nnode convert2xkt.js -a myGLBFiles/model.glb.manifest.json -o myXKTFiles -l\n````\n\nThe contents of ````myXKTFiles```` now look like this:\n\n````\nmyXKTFiles\n├── model.xkt\n├── model_1.xkt\n├── model_2.xkt\n├── model_3.xkt\n└── model.xkt.manifest.json\n````\n\nThe ````model.xkt.manifest```` file looks like this:\n\n````json\n{\n \"inputFile\": \"/absolute/path/myGLBFiles/model.glb.manifest.json\",\n \"converterApplication\": \"convert2xkt\",\n \"converterApplicationVersion\": \"v1.1.8\",\n \"conversionDate\": \"09-08-2023- 23-53-30\",\n \"outputDir\": \"/absolute/path/myXKTFiles\",\n \"xktFiles\": [\n \"model.xkt\",\n \"model_1.xkt\",\n \"model_2.xkt\",\n \"model_3.xkt\"\n ]\n}\n````\n\nWe can then load those XKT files into a xeokit Viewer, and the Viewer will automaticlly combine their geometry and metadata into the same scene. \n# Using ````XKTModel````\n\n````XKTModel```` is a JavaScript class that represents the contents of an XKT file in memory.\n\nIt's a sort of *XKT document model*, with methods to build 3D objects within it, functions to import various model\nformats, and a function to serialize it to an XKT file.\n\nWe can use these tools to:\n\n* programmatically XKT files,\n* combine multiple models into an XKT file, from different formats,\n* develop custom XKT converters, and\n* extend ````convert2xkt```` to support more formats.\n\n### Programmatically Building an XKT File\n\nTo demonstrate the API, let's\nuse [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html) 's\nbuilder methods to programmatically build a model that resembles the screenshot below. Then we'll serialize\nthe ````XKTModel```` to an\n````ArrayBuffer````, which we'll finally load that into a\nxeokit [````Viewer````](https://xeokit.github.io/xeokit-sdk/docs/class/src/viewer/Viewer.js~Viewer.html)\nusing [````XKTLoaderPlugin````](https://xeokit.github.io/xeokit-sdk/docs/class/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js~XKTLoaderPlugin.html)\n.\n\nWe'll code this example to run in the browser, using the ES module\nin [xeokit-convert.es.js](./dist/xeokit-convert.es.js). We could also code it to run on node, using the CommonJS module\nin [xeokit-convert.cjs.js](./dist/xeokit-convert.cjs.js).\n\n![XKTModel Example](http://xeokit.io/img/docs/PerformanceModel/PerformanceModel.png)\n\n````javascript\nconst {\n XKTModel,\n writeXKTModelToArrayBuffer\n} = require(\"@xeokit/xeokit-convert/dist/xeokit-convert.cjs.js\");\nconst fs = require('fs');\n\nconst xktModel = new XKTModel();\n\n// Create metamodel - this part is optional\n\n// Create property sets to hold info about the model\n\nxktModel.createPropertySet({\n propertySetId: \"tableTopPropSet\",\n propertySetType: \"Default\",\n propertySetName: \"Table Top\",\n properties: [\n {\n id: \"tableTopMaterial\",\n type: \"Default\",\n name: \"Table top material\",\n value: \"Marble\"\n },\n {\n id: \"tableTopDimensions\",\n type: \"Default\",\n name: \"Table top dimensions\",\n value: \"90x90x3 cm\"\n }\n ]\n});\n\nxktModel.createPropertySet({\n propertySetId: \"tableLegPropSet\",\n propertySetType: \"Default\",\n propertySetName: \"Table Leg\",\n properties: [\n {\n id: \"tableLegMaterial\",\n type: \"Default\",\n name: \"Table leg material\",\n value: \"Pine\"\n },\n {\n id: \"tableLegDimensions\",\n type: \"Default\",\n name: \"Table leg dimensions\",\n value: \"5x5x50 cm\"\n }\n ]\n});\n\n// Create a hierarchy of metaobjects to describe the structure of the model\n\nxktModel.createMetaObject({ // Root XKTMetaObject, has no XKTEntity\n metaObjectId: \"table\",\n metaObjectName: \"The Table\",\n metaObjectType: \"furniture\"\n});\n\nxktModel.createMetaObject({\n metaObjectId: \"redLeg\",\n metaObjectName: \"Red Table Leg\",\n metaObjectType: \"furniturePart\",\n parentMetaObjectId: \"table\",\n propertySetIds: [\"tableLegPropSet\"]\n});\n\nxktModel.createMetaObject({\n metaObjectId: \"greenLeg\",\n metaObjectName: \"Green Table Leg\",\n metaObjectType: \"furniturePart\",\n parentMetaObjectId: \"table\",\n propertySetIds: [\"tableLegPropSet\"]\n});\n\nxktModel.createMetaObject({\n metaObjectId: \"blueLeg\",\n metaObjectName: \"Blue Table Leg\",\n metaObjectType: \"furniturePart\",\n parentMetaObjectId: \"table\",\n propertySetIds: [\"tableLegPropSet\"]\n});\n\nxktModel.createMetaObject({\n metaObjectId: \"yellowLeg\",\n metaObjectName: \"Yellow Table Leg\",\n metaObjectType: \"furniturePart\",\n parentMetaObjectId: \"table\",\n propertySetIds: [\"tableLegPropSet\"]\n});\n\nxktModel.createMetaObject({\n metaObjectId: \"pinkTop\",\n metaObjectName: \"The Pink Table Top\",\n metaObjectType: \"furniturePart\",\n parentMetaObjectId: \"table\",\n propertySetIds: [\"tableTopPropSet\"]\n});\n\n// Create an XKTGeometry that defines a box shape, as a triangle mesh \n\nxktModel.createGeometry({\n geometryId: \"boxGeometry\",\n primitiveType: \"triangles\", // Also \"lines\" and \"points\"\n positions: [\n 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1,\n -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1,\n -1, -1, -1, -1, -1, 1, -1, 1, 1, -1\n ],\n normals: [ // Only for \"triangles\"\n 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,\n -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0,\n -1, 0, 0, -1\n ],\n indices: [\n 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19,\n 20, 21, 22, 20, 22, 23\n ]\n});\n\n// Create five XKTMeshes, which represent the table top and legs.\n// Each XKTMesh has its own color, position, orientation and size, \n// and uses the XKTGeometry to define its shape. \n// An XKTGeometry can be used by multiple XKTMeshes.\n\nxktModel.createMesh({\n meshId: \"redLegMesh\",\n geometryId: \"boxGeometry\",\n position: [-4, -6, -4],\n scale: [1, 3, 1],\n rotation: [0, 0, 0],\n color: [1, 0, 0],\n opacity: 1\n});\n\nxktModel.createMesh({\n meshId: \"greenLegMesh\",\n geometryId: \"boxGeometry\",\n position: [4, -6, -4],\n scale: [1, 3, 1],\n rotation: [0, 0, 0],\n color: [0, 1, 0],\n opacity: 1\n});\n\nxktModel.createMesh({\n meshId: \"blueLegMesh\",\n geometryId: \"boxGeometry\",\n position: [4, -6, 4],\n scale: [1, 3, 1],\n rotation: [0, 0, 0],\n color: [0, 0, 1],\n opacity: 1\n});\n\nxktModel.createMesh({\n meshId: \"yellowLegMesh\",\n geometryId: \"boxGeometry\",\n position: [-4, -6, 4],\n scale: [1, 3, 1],\n rotation: [0, 0, 0],\n color: [1, 1, 0],\n opacity: 1\n});\n\nxktModel.createMesh({\n meshId: \"pinkTopMesh\",\n geometryId: \"boxGeometry\",\n position: [0, -3, 0],\n scale: [6, 0.5, 6],\n rotation: [0, 0, 0],\n color: [1, 0, 1],\n opacity: 1\n});\n\n// Create five XKTEntities, which represent abstract, named objects in the model. \n// Each XKTEntity has an XKTMesh.\n// An XKTEntity can have multiple XKTMeshes. \n// An XKTMesh can only belong to one XKTEntity.\n\nxktModel.createEntity({\n entityId: \"redLeg\",\n meshIds: [\"redLegMesh\"]\n});\n\nxktModel.createEntity({\n entityId: \"greenLeg\",\n meshIds: [\"greenLegMesh\"]\n});\n\nxktModel.createEntity({\n entityId: \"blueLeg\",\n meshIds: [\"blueLegMesh\"]\n});\n\nxktModel.createEntity({\n entityId: \"yellowLeg\",\n meshIds: [\"yellowLegMesh\"]\n});\n\nxktModel.createEntity({\n entityId: \"pinkTop\",\n meshIds: [\"pinkTopMesh\"]\n});\n````\n\nOnce we've built\nour [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html), we\nneed to finalize it. Then it's ready to use. Note that finalizing is an asynhronous operation, so we await its\ncompletion before continuing.\n\n````javascript\nawait xktModel.finalize();\n````\n\n### Serializing the XKTModel to an ArrayBuffer\n\nNext, we'll\nuse [````writeXKTModelToArrayBuffer````](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-writeXKTModelToArrayBuffer)\nto serialize\nour [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html) to\nan ````ArrayBuffer````.\n\n````javascript\nconst xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel);\n\nfs.writeFileSync(\"./myModel.xkt\", xktArrayBuffer);\n````\n\n### Loading the ArrayBuffer into a Viewer\n\nLet's now create a [````Viewer````](https://xeokit.github.io/xeokit-sdk/docs/class/src/viewer/Viewer.js~Viewer.html),\nthen load the ````ArrayBuffer```` into it using\nan [````XKTLoaderPlugin````](https://xeokit.github.io/xeokit-sdk/docs/class/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js~XKTLoaderPlugin.html)\n.\n\n````javascript\nconst viewer = new Viewer({\n canvasId: \"myCanvas\"\n});\n\nconst xktLoader = new XKTLoaderPlugin(viewer);\n\nconst model = xktLoader.load({\n id: \"myModel\",\n src: \"./myModel.xkt\"\n});\n````\n\nFinally, when the model has loaded, let's fit it in view.\n\n````javascript\nmodel.on(\"loaded\", () => {\n viewer.cameraFlight.flyTo(model);\n});\n````\n\n### Loading IFC into an XKTModel\n\nLet's\nuse [````parseIFCIntoXKTModel````](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-parseIFCIntoXKTModel)\nto import IFC into\nan [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html).\n\nAs before, we'll also use the classes and functions introduced in the previous examples to serialize\nthe [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html) to\nan ````ArrayBuffer````, then load it into\na [````Viewer````](https://xeokit.github.io/xeokit-sdk/docs/class/src/viewer/Viewer.js~Viewer.html).\n\n````javascript\nconst viewer = new Viewer({\n canvasId: \"myCanvas\"\n});\n\nconst xktLoader = new XKTLoaderPlugin(viewer);\n\nutils.loadArraybuffer(\"./assets/models/ifc/rac_advanced_sample_project.ifc\", async (data) => {\n\n const xktModel = new XKTModel();\n\n parseIFCIntoXKTModel({data, xktModel, wasmPath: \"../dist/\"}).then(() => {\n\n xktModel.finalize().then(() => {\n\n const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel);\n\n xktLoader.load({\n id: \"myModel\",\n xkt: xktArrayBuffer,\n edges: true\n });\n\n viewer.cameraFlight.flyTo(viewer.scene);\n });\n });\n },\n (errMsg) => {\n });\n````\n\n### Loading LAS into an XKTModel\n\nLet's\nuse [````parseLASIntoXKTModel````](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-parseLASIntoXKTModel)\nto import LAS into\nan [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html).\n\nAs before, we'll also use the classes and functions introduced in the previous examples to serialize\nthe [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html) to\nan ````ArrayBuffer````, then load it into\na [````Viewer````](https://xeokit.github.io/xeokit-sdk/docs/class/src/viewer/Viewer.js~Viewer.html).\n\n````javascript\nconst viewer = new Viewer({\n canvasId: \"myCanvas\"\n});\n\nconst xktLoader = new XKTLoaderPlugin(viewer);\n\nutils.loadArraybuffer(\"./assets/models/laz/indoor.0.1.laz\", async (data) => {\n\n const xktModel = new XKTModel();\n\n parseLASIntoXKTModel({data, xktModel, rotateX: true}).then(() => {\n\n xktModel.finalize().then(() => {\n\n const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel);\n\n xktLoader.load({\n id: \"myModel\",\n xkt: xktArrayBuffer,\n edges: true\n });\n\n viewer.cameraFlight.flyTo(viewer.scene);\n });\n });\n },\n (errMsg) => {\n });\n````\n\n### Loading GLB into an XKTModel\n\nLet's\nuse [````parseGLTFIntoXKTModel````](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-parseGLTFIntoXKTModel)\nto import binary glTF into\nan [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html).\n\nWe'll also use the classes and functions introduced in the previous examples to serialize\nthe [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html) to\nan ````ArrayBuffer````, then validate the ````ArrayBuffer```` and load it into\na [````Viewer````](https://xeokit.github.io/xeokit-sdk/docs/class/src/viewer/Viewer.js~Viewer.html).\n\n````javascript\nconst viewer = new Viewer({\n canvasId: \"myCanvas\"\n});\n\nconst xktLoader = new XKTLoaderPlugin(viewer);\n\nutils.loadArraybuffer(\"./assets/models/glb/MAP/MAP.glb\", (glb) => {\n\n const xktModel = new XKTModel();\n\n parseGLTFIntoXKTModel({data: glb, xktModel: xktModel}).then(() => {\n\n xktModel.finalize().then(() => {\n\n const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel);\n\n xktLoader.load({\n id: \"myModel\",\n xkt: xktArrayBuffer\n });\n\n viewer.cameraFlight.flyTo(viewer.scene);\n });\n });\n },\n (errMsg) => {\n });\n````\n\n### Loading STL into an XKTModel\n\nLet's\nuse [````parseSTLIntoXKTModel````](https://xeokit.github.io/xeokit-convert/docs/function/index.html#static-function-parseSTLIntoXKTModel)\nto import STL into\nan [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html).\n\nAs before, we'll also use the classes and functions introduced in the previous examples to serialize\nthe [````XKTModel````](https://xeokit.github.io/xeokit-convert/docs/class/src/XKTModel/XKTModel.js~XKTModel.html) to\nan ````ArrayBuffer````, then load it into\na [````Viewer````](https://xeokit.github.io/xeokit-sdk/docs/class/src/viewer/Viewer.js~Viewer.html).\n\n````javascript\nconst viewer = new Viewer({\n canvasId: \"myCanvas\"\n});\n\nconst xktLoader = new XKTLoaderPlugin(viewer);\n\nutils.loadArraybuffer(\"./assets/models/stl/binary/spurGear.stl\", (json) => {\n\n const xktModel = new XKTModel();\n\n parseSTLIntoXKTModel({stlData: json, xktModel: xktModel}).then(() => {\n\n xktModel.finalize().then(() => {\n\n const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel);\n\n xktLoader.load({\n id: \"myModel\",\n xkt: xktArrayBuffer\n });\n\n viewer.cameraFlight.flyTo(viewer.scene);\n });\n });\n },\n (errMsg) => {\n });\n````\n\n# Building\n\n### Building Binaries\n\nBuilding the binaries in [````./dist````](https://github.com/xeokit/xeokit-convert/tree/main/dist):\n\n````bash\nnpm update\nnpm run build\n````\n\nThis will build:\n\n* [./dist/convert2xkt.cjs.js](./dist/convert2xkt.cjs.js) - Nodejs CLI converter tool\n* [./dist/xeokit-convert.cjs.js](./dist/xeokit-convert.cjs.js) - CommonJS module library of XKT classes and functions\n* [./dist/xeokit-convert.es.js](./dist/xeokit-convert.es.js) - ES module library of XKT classes and functions\n* [./dist/web-ifc.wasm](./dist/web-ifc.wasm) - 3rd-party web-ifc WASM module\n\nBuilding the JavaScript API documentation in [````./docs````](https://xeokit.github.io/xeokit-convert/docs):\n\n````bash\nnpm run docs\n````\n\n### RuntimeError: memory access out of bounds\n\nWith luck, the WASM module already be compiled appropriately for your target x86 system.\n\nHowever, if you get this error:\n\n````bash\nRuntimeError: memory access out of bounds\n````\n\nthen you will need to compile that WASM module for your target system. Please follow the instructions for that on the\n[web-ifc](https://github.com/tomvandig/web-ifc) project page, then replace [./dist/web-ifc.wasm](./dist/web-ifc.wasm)\nwith your compiled binary.\n\n### TypeError: fetch failed\n\nThis error is possible in in nodejs version 17+. As fix you will have to add the --no-experimental-fetch flag to the command.\n````bash\nnode --no-experimental-fetch convert2xkt.js ...\n````\n", - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/README.md", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/README.md", "name": "./README.md", "static": true, "access": "public" }, { "kind": "packageJSON", - "content": "{\n \"name\": \"@xeokit/xeokit-convert\",\n \"version\": \"1.1.18\",\n \"description\": \"JavaScript utilities to create .XKT files\",\n \"main\": \"index.js\",\n \"bin\": \"/convert2xkt.js\",\n \"directories\": {},\n \"scripts\": {\n \"build\": \"webpack --mode=production --node-env=production --progress; rollup --config rollup.config.dist.js; rollup --config rollup.config.convert2xkt.js; rm -Rf ./docs/*; ./node_modules/.bin/esdoc\",\n \"build-node\": \"webpack --mode=production --node-env=production --progress\",\n \"build-browser\": \"rollup --config rollup.config.dist.js\",\n \"docs\": \"rm -Rf ./docs/*; ./node_modules/.bin/esdoc\",\n \"publish\": \"npm publish --access public\",\n \"changelog\": \"auto-changelog --commit-limit false --package --template changelog-template.hbs\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/xeokit/xeokit-convert.git\"\n },\n \"keywords\": [\n \"xeolabs\",\n \"xeokit\",\n \"bim\",\n \"opensource\",\n \"ifc\",\n \"webgl\",\n \"xkt\",\n \"gltf\",\n \"glb\",\n \"cityjson\",\n \"laz\",\n \"gis\"\n ],\n \"author\": \"Lindsay Kay\",\n \"license\": \"LICENSE\",\n \"bugs\": {\n \"url\": \"https://github.com/xeokit/xeokit-convert/issues\"\n },\n \"homepage\": \"https://github.com/xeokit/xeokit-convert#readme\",\n \"dependencies\": {\n \"@loaders.gl/core\": \"^3.2.6\",\n \"@loaders.gl/gltf\": \"^3.2.6\",\n \"@loaders.gl/images\": \"^3.2.6\",\n \"@loaders.gl/json\": \"^3.2.6\",\n \"@loaders.gl/las\": \"^3.2.6\",\n \"@loaders.gl/obj\": \"^3.2.6\",\n \"@loaders.gl/ply\": \"^3.2.6\",\n \"@loaders.gl/polyfills\": \"^3.2.6\",\n \"@loaders.gl/textures\": \"^3.2.6\",\n \"@typeonly/validator\": \"^0.5.2\",\n \"commander\": \"^11.0.0\",\n \"core-js\": \"^3.22.5\",\n \"fs\": \"0.0.1-security\",\n \"pako\": \"^2.0.4\",\n \"path\": \"^0.12.7\",\n \"web-ifc\": \"0.0.40\"\n },\n \"devDependencies\": {\n \"@babel/core\": \"^7.17.10\",\n \"@babel/plugin-external-helpers\": \"^7.17.12\",\n \"@babel/preset-env\": \"^7.17.12\",\n \"@rollup/plugin-alias\": \"^3.1.9\",\n \"@rollup/plugin-commonjs\": \"^21.1.0\",\n \"@rollup/plugin-node-resolve\": \"^13.2.1\",\n \"@xeokit/xeokit-sdk\": \"^2.3.0\",\n \"babel-loader\": \"^8.2.5\",\n \"copy-webpack-plugin\": \"^11.0.0\",\n \"esdoc\": \"^1.1.0\",\n \"esdoc-node\": \"^1.0.5\",\n \"esdoc-standard-plugin\": \"^1.0.0\",\n \"http-server\": \"^14.1.0\",\n \"npm-upgrade\": \"^3.1.0\",\n \"rimraf\": \"^3.0.2\",\n \"rollup\": \"^2.70.2\",\n \"rollup-plugin-copy\": \"^3.4.0\",\n \"rollup-plugin-minify-es\": \"^1.1.1\",\n \"typeonly\": \"^0.4.6\",\n \"webpack\": \"^5.72.1\",\n \"webpack-cli\": \"^4.9.2\",\n \"webpack-node-externals\": \"^3.0.0\",\n \"auto-changelog\": \"^2.4.0\"\n },\n \"files\": [\n \"/dist\",\n \"/convert2xkt.js\",\n \"/convert2xkt.conf.js\"\n ]\n}\n", - "longname": "/home/lindsay/xeolabs/xeokit-convert-mar14/package.json", + "content": "{\n \"name\": \"@xeokit/xeokit-convert\",\n \"version\": \"1.1.18\",\n \"description\": \"JavaScript utilities to create .XKT files\",\n \"main\": \"index.js\",\n \"bin\": \"/convert2xkt.js\",\n \"directories\": {},\n \"scripts\": {\n \"build\": \"webpack --mode=production --node-env=production --progress; rollup --config rollup.config.dist.js; rollup --config rollup.config.convert2xkt.js; rm -Rf ./docs/*; ./node_modules/.bin/esdoc\",\n \"build:browser\": \"webpack --mode=production --node-env=production --progress; rollup --config rollup.config.convert2xkt_browser.js; rm -Rf ./docs/*; ./node_modules/.bin/esdoc\",\n \"build-node\": \"webpack --mode=production --node-env=production --progress\",\n \"build-browser\": \"rollup --config rollup.config.dist.js\",\n \"docs\": \"rm -Rf ./docs/*; ./node_modules/.bin/esdoc\",\n \"publish\": \"npm publish --access public\",\n \"changelog\": \"auto-changelog --commit-limit false --package --template changelog-template.hbs\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/xeokit/xeokit-convert.git\"\n },\n \"keywords\": [\n \"xeolabs\",\n \"xeokit\",\n \"bim\",\n \"opensource\",\n \"ifc\",\n \"webgl\",\n \"xkt\",\n \"gltf\",\n \"glb\",\n \"cityjson\",\n \"laz\",\n \"gis\"\n ],\n \"author\": \"Lindsay Kay\",\n \"license\": \"LICENSE\",\n \"bugs\": {\n \"url\": \"https://github.com/xeokit/xeokit-convert/issues\"\n },\n \"homepage\": \"https://github.com/xeokit/xeokit-convert#readme\",\n \"dependencies\": {\n \"@loaders.gl/core\": \"^3.2.6\",\n \"@loaders.gl/gltf\": \"^3.2.6\",\n \"@loaders.gl/images\": \"^3.2.6\",\n \"@loaders.gl/json\": \"^3.2.6\",\n \"@loaders.gl/las\": \"^3.2.6\",\n \"@loaders.gl/obj\": \"^3.2.6\",\n \"@loaders.gl/ply\": \"^3.2.6\",\n \"@loaders.gl/polyfills\": \"^3.2.6\",\n \"@loaders.gl/textures\": \"^3.2.6\",\n \"@typeonly/validator\": \"^0.5.2\",\n \"commander\": \"^11.0.0\",\n \"core-js\": \"^3.22.5\",\n \"fs\": \"0.0.1-security\",\n \"pako\": \"^2.0.4\",\n \"path\": \"^0.12.7\",\n \"web-ifc\": \"0.0.40\"\n },\n \"devDependencies\": {\n \"@babel/core\": \"^7.17.10\",\n \"@babel/plugin-external-helpers\": \"^7.17.12\",\n \"@babel/preset-env\": \"^7.17.12\",\n \"@rollup/plugin-alias\": \"^3.1.9\",\n \"@rollup/plugin-commonjs\": \"^21.1.0\",\n \"@rollup/plugin-node-resolve\": \"^13.2.1\",\n \"@xeokit/xeokit-sdk\": \"^2.3.0\",\n \"babel-loader\": \"^8.2.5\",\n \"copy-webpack-plugin\": \"^11.0.0\",\n \"esdoc\": \"^1.1.0\",\n \"esdoc-node\": \"^1.0.5\",\n \"esdoc-standard-plugin\": \"^1.0.0\",\n \"http-server\": \"^14.1.0\",\n \"npm-upgrade\": \"^3.1.0\",\n \"rimraf\": \"^3.0.2\",\n \"rollup\": \"^2.70.2\",\n \"rollup-plugin-copy\": \"^3.4.0\",\n \"rollup-plugin-minify-es\": \"^1.1.1\",\n \"typeonly\": \"^0.4.6\",\n \"webpack\": \"^5.72.1\",\n \"webpack-cli\": \"^4.9.2\",\n \"webpack-node-externals\": \"^3.0.0\",\n \"auto-changelog\": \"^2.4.0\"\n },\n \"files\": [\n \"/dist\",\n \"/convert2xkt.js\",\n \"/convert2xkt.conf.js\"\n ]\n}\n", + "longname": "/home/dabomian/Dev/creoox/xeokit-convert/package.json", "name": "package.json", "static": true, "access": "public" diff --git a/docs/lint.json b/docs/lint.json index 3540e44..310f78d 100644 --- a/docs/lint.json +++ b/docs/lint.json @@ -247,5 +247,175 @@ "params", "stats" ] + }, + { + "name": "convert2xkt", + "filePath": "src/convert2xkt_browser.js", + "lines": [ + { + "lineNumber": 7, + "line": "/**" + }, + { + "lineNumber": 8, + "line": " * Converts model files into xeokit's native XKT format." + }, + { + "lineNumber": 9, + "line": " *" + }, + { + "lineNumber": 10, + "line": " * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS." + }, + { + "lineNumber": 11, + "line": " *" + }, + { + "lineNumber": 12, + "line": " * **Only bundled in xeokit-convert.cjs.js.**" + }, + { + "lineNumber": 13, + "line": " *" + }, + { + "lineNumber": 14, + "line": " * ## Usage" + }, + { + "lineNumber": 15, + "line": " *" + }, + { + "lineNumber": 16, + "line": " ````" + }, + { + "lineNumber": 17, + "line": " * @param {Object} params Conversion parameters." + }, + { + "lineNumber": 18, + "line": " * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the" + }, + { + "lineNumber": 19, + "line": " * caller the choice of whether to use the Browser or NodeJS version." + }, + { + "lineNumber": 20, + "line": " * @param {*} [params.configs] Configurations." + }, + { + "lineNumber": 21, + "line": " * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````." + }, + { + "lineNumber": 22, + "line": " * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method." + }, + { + "lineNumber": 23, + "line": " * @param {Function} [params.outputXKT] Callback to collect XKT file data." + }, + { + "lineNumber": 24, + "line": " * @param {String[]} [params.includeTypes] Option to only convert objects of these types." + }, + { + "lineNumber": 25, + "line": " * @param {String[]} [params.excludeTypes] Option to never convert objects of these types." + }, + { + "lineNumber": 26, + "line": " * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided." + }, + { + "lineNumber": 27, + "line": " * @param {Function} [params.outputStats] Callback to collect statistics." + }, + { + "lineNumber": 28, + "line": " * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis \"up\", if necessary. Applies to CityJSON and LAS/LAZ models." + }, + { + "lineNumber": 29, + "line": " * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false," + }, + { + "lineNumber": 30, + "line": " * will automatically \"expand\" all reused geometries into duplicate copies. This has the drawback of increasing the XKT" + }, + { + "lineNumber": 31, + "line": " * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model" + }, + { + "lineNumber": 32, + "line": " * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are" + }, + { + "lineNumber": 33, + "line": " * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a" + }, + { + "lineNumber": 34, + "line": " * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc)." + }, + { + "lineNumber": 35, + "line": " * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models." + }, + { + "lineNumber": 36, + "line": " * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore" + }, + { + "lineNumber": 37, + "line": " * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has" + }, + { + "lineNumber": 38, + "line": " * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render" + }, + { + "lineNumber": 39, + "line": " * a flat-shaded non-PBR representation of the model." + }, + { + "lineNumber": 40, + "line": " * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000," + }, + { + "lineNumber": 41, + "line": " * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close" + }, + { + "lineNumber": 42, + "line": " * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger." + }, + { + "lineNumber": 43, + "line": " * @param {Function} [params.log] Logging callback." + }, + { + "lineNumber": 44, + "line": " * @return {Promise}" + }, + { + "lineNumber": 45, + "line": " */" + }, + { + "lineNumber": 46, + "line": "function convert2xkt({" + } + ], + "codeParams": [ + "*" + ], + "docParams": [] } ] \ No newline at end of file diff --git a/docs/script/search_index.js b/docs/script/search_index.js index 26262d1..969f1e2 100644 --- a/docs/script/search_index.js +++ b/docs/script/search_index.js @@ -210,15 +210,15 @@ window.esdocSearchIndex = [ "function" ], [ - "@xeokit/xeokit-convert/src/parsers/parsecityjsonintoxktmodel.js~parsecityjsonintoxktmodel", - "function/index.html#static-function-parseCityJSONIntoXKTModel", - "parseCityJSONIntoXKTModel @xeokit/xeokit-convert/src/parsers/parseCityJSONIntoXKTModel.js", + "@xeokit/xeokit-convert/src/convert2xkt_browser.js~convert2xkt", + "function/index.html#static-function-convert2xkt", + "convert2xkt @xeokit/xeokit-convert/src/convert2xkt_browser.js", "function" ], [ - "@xeokit/xeokit-convert/src/parsers/parsegltfintoxktmodel.old.js~parsegltfintoxktmodel", - "function/index.html#static-function-parseGLTFIntoXKTModel", - "parseGLTFIntoXKTModel @xeokit/xeokit-convert/src/parsers/parseGLTFIntoXKTModel.OLD.js", + "@xeokit/xeokit-convert/src/parsers/parsecityjsonintoxktmodel.js~parsecityjsonintoxktmodel", + "function/index.html#static-function-parseCityJSONIntoXKTModel", + "parseCityJSONIntoXKTModel @xeokit/xeokit-convert/src/parsers/parseCityJSONIntoXKTModel.js", "function" ], [ @@ -1337,6 +1337,12 @@ window.esdocSearchIndex = [ "src/convert2xkt.js", "file" ], + [ + "src/convert2xkt_browser.js", + "file/src/convert2xkt_browser.js.html", + "src/convert2xkt_browser.js", + "file" + ], [ "src/geometrybuilders/buildboxgeometry.js", "file/src/geometryBuilders/buildBoxGeometry.js.html", @@ -1433,12 +1439,6 @@ window.esdocSearchIndex = [ "src/parsers/parseCityJSONIntoXKTModel.js", "file" ], - [ - "src/parsers/parsegltfintoxktmodel.old.js", - "file/src/parsers/parseGLTFIntoXKTModel.OLD.js.html", - "src/parsers/parseGLTFIntoXKTModel.OLD.js", - "file" - ], [ "src/parsers/parsegltfintoxktmodel.js", "file/src/parsers/parseGLTFIntoXKTModel.js.html", diff --git a/docs/source.html b/docs/source.html index fa1bdbd..9711d17 100644 --- a/docs/source.html +++ b/docs/source.html @@ -30,6 +30,7 @@
                                                                                                                          • Fconvert2xkt
                                                                                                                          • +
                                                                                                                          • Fconvert2xkt
                                                                                                                          • VXKT_INFO
                                                                                                                          • VClampToEdgeWrapping
                                                                                                                          • VGIFMediaType
                                                                                                                          • @@ -67,7 +68,6 @@
                                                                                                                          • FbuildVectorTextGeometry
                                                                                                                          • parsersFparseCityJSONIntoXKTModel
                                                                                                                          • FparseGLTFIntoXKTModel
                                                                                                                          • -
                                                                                                                          • FparseGLTFIntoXKTModel
                                                                                                                          • FparseGLTFJSONIntoXKTModel
                                                                                                                          • FparseIFCIntoXKTModel
                                                                                                                          • FparseLASIntoXKTModel
                                                                                                                          • @@ -79,7 +79,7 @@ -

                                                                                                                            Source 186/394

                                                                                                                            +

                                                                                                                            Source 186/382

                                                                                                                            @@ -100,7 +100,7 @@ - + @@ -108,7 +108,7 @@ - + @@ -116,7 +116,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -132,7 +132,7 @@ - + @@ -140,7 +140,7 @@ - + @@ -148,7 +148,7 @@ - + @@ -156,7 +156,7 @@ - + @@ -164,7 +164,7 @@ - + @@ -172,7 +172,7 @@ - + @@ -180,7 +180,7 @@ - + @@ -188,7 +188,7 @@ - + @@ -196,7 +196,7 @@ - + @@ -204,7 +204,7 @@ - + @@ -212,7 +212,7 @@ - + @@ -220,7 +220,7 @@ - + @@ -228,7 +228,7 @@ - + @@ -236,7 +236,7 @@ - + @@ -244,7 +244,7 @@ - + @@ -252,7 +252,7 @@ - + @@ -260,7 +260,7 @@ - + @@ -268,7 +268,7 @@ - + @@ -276,7 +276,7 @@ - + @@ -284,7 +284,7 @@ - + @@ -307,7 +307,7 @@ - + @@ -315,7 +315,15 @@ - + + + + + + + + + @@ -323,7 +331,7 @@ - + @@ -331,7 +339,7 @@ - + @@ -339,7 +347,7 @@ - + @@ -347,7 +355,7 @@ - + @@ -355,7 +363,7 @@ - + @@ -363,7 +371,7 @@ - + @@ -371,7 +379,7 @@ - + @@ -379,7 +387,7 @@ - + @@ -387,7 +395,7 @@ - + @@ -395,7 +403,7 @@ - + @@ -403,7 +411,7 @@ - + @@ -411,7 +419,7 @@ - + @@ -419,7 +427,7 @@ - + @@ -427,7 +435,7 @@ - + @@ -435,7 +443,7 @@ - + @@ -443,15 +451,7 @@ - - - - - - - - - + @@ -459,7 +459,7 @@ - + @@ -467,7 +467,7 @@ - + @@ -475,7 +475,7 @@ - + @@ -483,7 +483,7 @@ - + @@ -491,7 +491,7 @@ - + @@ -499,7 +499,7 @@ - + @@ -507,7 +507,7 @@ - + @@ -515,7 +515,7 @@ - +
                                                                                                                            100 %6/6 672 byte 362024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/MockXKTModel.js16 %2/12 3633 byte 1162024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/XKTEntity.js100 %7/7 2355 byte 732024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/XKTGeometry.js100 %17/17 4924 byte 1582024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/XKTMesh.js100 %12/12 3004 byte 992024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/XKTMetaObject.js100 %7/7 2671 byte 812024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/XKTModel.js63 %41/65 57528 byte 15372024-04-06 22:09:23 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/XKTPropertySet.js100 %6/6 1302 byte 522024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/XKTTexture.js93 %15/16 3811 byte 1442024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/XKTTextureSet.js100 %12/12 2206 byte 872024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/XKTTile.js100 %4/4 753 byte 352024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/buildEdgeIndices.js100 %1/1 6461 byte 1672024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/buildFaceNormals.js50 %1/2 1893 byte 762024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/buildVertexNormals.js100 %1/1 2016 byte 812024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/earcut.js2 %1/34 20369 byte 6762024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/faceToVertexNormals.js100 %1/1 2764 byte 1042024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/geometryCompression.js44 %4/9 7096 byte 1942024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/isTriangleMeshSolid.js100 %1/1 3870 byte 1642024-06-02 13:49:56 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/math.js16 %1/6 94289 byte 37422024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/mergeVertices.js100 %1/1 1212 byte 312024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/toArraybuffer.js100 %1/1 269 byte 122024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/lib/utils.js33 %1/3 333 byte 222024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKTModel/writeXKTModelToArrayBuffer.js11 %1/9 22741 byte 4612024-04-06 22:09:23 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/XKT_INFO.js100 %1/1 563 byte 202024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/constants.js100 %16/16 3498 byte 912024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/convert2xkt.js100 %1/1 18416 byte 4502024-05-02 12:38:09 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/convert2xkt_browser.jsconvert2xkt100 %1/17516 byte1882024-06-05 13:33:46 (UTC)
                                                                                                                            src/geometryBuilders/buildBoxGeometry.js100 %1/1 6056 byte 2492024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/geometryBuilders/buildBoxLinesGeometry.js100 %1/1 3062 byte 1152024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/geometryBuilders/buildCylinderGeometry.js100 %1/1 7750 byte 2792024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/geometryBuilders/buildGridGeometry.js100 %1/1 2670 byte 1082024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/geometryBuilders/buildPlaneGeometry.js100 %1/1 4626 byte 1772024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/geometryBuilders/buildSphereGeometry.js100 %1/1 4383 byte 1702024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/geometryBuilders/buildTorusGeometry.js100 %1/1 4890 byte 1832024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/geometryBuilders/buildVectorTextGeometry.js50 %1/2 34298 byte 17232024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/index.js- 1525 byte 242024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/lib/buildFaceNormals.js50 %1/2 1893 byte 762024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/lib/buildVertexNormals.js100 %1/1 2016 byte 812024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/lib/earcut.js2 %1/34 20369 byte 6762024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/lib/faceToVertexNormals.js100 %1/1 2764 byte 1042024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/lib/math.js16 %1/6 94289 byte 37422024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/lib/mergeVertices.js100 %1/1 1212 byte 312024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/parsers/parseCityJSONIntoXKTModel.js5 %1/18 19862 byte 6642024-03-05 00:05:03 (UTC)
                                                                                                                            src/parsers/parseGLTFIntoXKTModel.OLD.jsparseGLTFIntoXKTModel7 %1/1321754 byte6122024-05-03 11:10:35 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/parsers/parseGLTFIntoXKTModel.js7 %1/13 21687 byte 6122024-05-03 11:10:49 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/parsers/parseGLTFJSONIntoXKTModel.js5 %1/20 24984 byte 6612024-04-07 01:06:17 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/parsers/parseIFCIntoXKTModel.js12 %1/8 14498 byte 4322024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/parsers/parseLASIntoXKTModel.js50 %1/2 11504 byte 3122024-06-02 13:52:27 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/parsers/parseMetaModelIntoXKTModel.js100 %1/1 4295 byte 1202024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/parsers/parsePCDIntoXKTModel.js25 %1/4 10430 byte 2972024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/parsers/parsePLYIntoXKTModel.js100 %1/1 3010 byte 1082024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            src/parsers/parseSTLIntoXKTModel.js11 %1/9 12458 byte 3572024-03-05 00:05:03 (UTC)2024-06-05 12:02:41 (UTC)
                                                                                                                            diff --git a/docs/variable/index.html b/docs/variable/index.html index a3b79c5..200efb5 100644 --- a/docs/variable/index.html +++ b/docs/variable/index.html @@ -30,6 +30,7 @@
                                                                                                                            • Fconvert2xkt
                                                                                                                            • +
                                                                                                                            • Fconvert2xkt
                                                                                                                            • VXKT_INFO
                                                                                                                            • VClampToEdgeWrapping
                                                                                                                            • VGIFMediaType
                                                                                                                            • @@ -67,7 +68,6 @@
                                                                                                                            • FbuildVectorTextGeometry
                                                                                                                            • parsersFparseCityJSONIntoXKTModel
                                                                                                                            • FparseGLTFIntoXKTModel
                                                                                                                            • -
                                                                                                                            • FparseGLTFIntoXKTModel
                                                                                                                            • FparseGLTFJSONIntoXKTModel
                                                                                                                            • FparseIFCIntoXKTModel
                                                                                                                            • FparseLASIntoXKTModel
                                                                                                                            • diff --git a/index.dist.node.js b/index.dist.node.js index 4717dd4..b6b4a1d 100644 --- a/index.dist.node.js +++ b/index.dist.node.js @@ -4,4 +4,4 @@ import {installFilePolyfills} from '@loaders.gl/polyfills'; installFilePolyfills(); export * from "./src/index.js"; -export {convert2xkt} from "./src/convert2xkt.js"; // convert2xkt is only bundled for Node.js +export {convert2xkt} from "./src/convert2xkt_browser.js"; // convert2xkt is only bundled for Node.js diff --git a/model.glb b/model.glb new file mode 100644 index 0000000..58f414b Binary files /dev/null and b/model.glb differ diff --git a/output_browser_xkt.xkt b/output_browser_xkt.xkt new file mode 100644 index 0000000..433f84f Binary files /dev/null and b/output_browser_xkt.xkt differ diff --git a/package-lock.json b/package-lock.json index 2b65da3..9d68b8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@xeokit/xeokit-convert", - "version": "1.1.15-beta-11", + "version": "1.1.18", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@xeokit/xeokit-convert", - "version": "1.1.15-beta-11", + "version": "1.1.18", "license": "LICENSE", "dependencies": { "@loaders.gl/core": "^3.2.6", diff --git a/package.json b/package.json index 105cdd6..9543407 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "directories": {}, "scripts": { "build": "webpack --mode=production --node-env=production --progress; rollup --config rollup.config.dist.js; rollup --config rollup.config.convert2xkt.js; rm -Rf ./docs/*; ./node_modules/.bin/esdoc", + "build:browser": "webpack --mode=production --node-env=production --progress; rollup --config rollup.config.convert2xkt_browser.js; rm -Rf ./docs/*; ./node_modules/.bin/esdoc", "build-node": "webpack --mode=production --node-env=production --progress", "build-browser": "rollup --config rollup.config.dist.js", "docs": "rm -Rf ./docs/*; ./node_modules/.bin/esdoc", diff --git a/rollup.config.convert2xkt_browser.js b/rollup.config.convert2xkt_browser.js new file mode 100644 index 0000000..40338f3 --- /dev/null +++ b/rollup.config.convert2xkt_browser.js @@ -0,0 +1,26 @@ +import {nodeResolve} from '@rollup/plugin-node-resolve'; +import commonjs from '@rollup/plugin-commonjs'; +import minify from 'rollup-plugin-minify-es'; + +export default { + input: './src/convert2xkt_browser.js', + output: [ + { + file: './dist/convert2xkt_browser.cjs.js', + include: '/node_modules/', + format: 'cjs', + name: 'bundle' + } + ], + external: [ + "crypto" + ], + plugins: [ + nodeResolve({ + browser: true, + preferBuiltins: false + }), + commonjs(), + minify() + ] +} \ No newline at end of file diff --git a/src/convert2xkt_browser.js b/src/convert2xkt_browser.js new file mode 100755 index 0000000..a82ebfb --- /dev/null +++ b/src/convert2xkt_browser.js @@ -0,0 +1,189 @@ + +import {XKTModel} from "./XKTModel/XKTModel.js"; +import {parseGLTFIntoXKTModel} from "./parsers/parseGLTFIntoXKTModel.js"; +import {writeXKTModelToArrayBuffer} from "./XKTModel/writeXKTModelToArrayBuffer.js"; + +import {toArrayBuffer} from "./XKTModel/lib/toArraybuffer"; + +/** + * Converts model files into xeokit's native XKT format. + * + * Supported source formats are: IFC, CityJSON, glTF, LAZ and LAS. + * + * **Only bundled in xeokit-convert.cjs.js.** + * + * ## Usage + * + ```` + * @param {Object} params Conversion parameters. + * @param {Object} params.WebIFC The WebIFC library. We pass this in as an external dependency, in order to give the + * caller the choice of whether to use the Browser or NodeJS version. + * @param {*} [params.configs] Configurations. + * @param {ArrayBuffer|JSON} [params.sourceData] Source file data. Alternative to ````source````. + * @param {Function} [params.outputXKTModel] Callback to collect the ````XKTModel```` that is internally build by this method. + * @param {Function} [params.outputXKT] Callback to collect XKT file data. + * @param {String[]} [params.includeTypes] Option to only convert objects of these types. + * @param {String[]} [params.excludeTypes] Option to never convert objects of these types. + * @param {Object} [stats] Collects conversion statistics. Statistics are attached to this object if provided. + * @param {Function} [params.outputStats] Callback to collect statistics. + * @param {Boolean} [params.rotateX=false] Whether to rotate the model 90 degrees about the X axis to make the Y axis "up", if necessary. Applies to CityJSON and LAS/LAZ models. + * @param {Boolean} [params.reuseGeometries=true] When true, will enable geometry reuse within the XKT. When false, + * will automatically "expand" all reused geometries into duplicate copies. This has the drawback of increasing the XKT + * file size (~10-30% for typical models), but can make the model more responsive in the xeokit Viewer, especially if the model + * has excessive geometry reuse. An example of excessive geometry reuse would be when a model (eg. glTF) has 4000 geometries that are + * shared amongst 2000 objects, ie. a large number of geometries with a low amount of reuse, which can present a + * pathological performance case for xeokit's underlying graphics APIs (WebGL, WebGPU etc). + * @param {Boolean} [params.includeTextures=true] Whether to convert textures. Only works for ````glTF```` models. + * @param {Boolean} [params.includeNormals=true] Whether to convert normals. When false, the parser will ignore + * geometry normals, and the modelwill rely on the xeokit ````Viewer```` to automatically generate them. This has + * the limitation that the normals will be face-aligned, and therefore the ````Viewer```` will only be able to render + * a flat-shaded non-PBR representation of the model. + * @param {Number} [params.minTileSize=200] Minimum RTC coordinate tile size. Set this to a value between 100 and 10000, + * depending on how far from the coordinate origin the model's vertex positions are; specify larger tile sizes when close + * to the origin, and smaller sizes when distant. This compensates for decreasing precision as floats get bigger. + * @param {Function} [params.log] Logging callback. + * @return {Promise} + */ +function convert2xkt({ + configs = {}, + sourceData, + modelAABB, + outputXKTModel, + outputXKT, + includeTypes, + excludeTypes, + reuseGeometries = true, + minTileSize = 200, + stats = {}, + rotateX = false, + includeTextures = true, + includeNormals = true, + log = function (msg) { + } + }) { + + stats.schemaVersion = ""; + stats.title = ""; + stats.author = ""; + stats.created = ""; + stats.numMetaObjects = 0; + stats.numPropertySets = 0; + stats.numTriangles = 0; + stats.numVertices = 0; + stats.numNormals = 0; + stats.numUVs = 0; + stats.numTextures = 0; + stats.numTextureSets = 0; + stats.numObjects = 0; + stats.numGeometries = 0; + stats.sourceSize = 0; + stats.xktSize = 0; + stats.texturesSize = 0; + stats.xktVersion = ""; + stats.compressionRatio = 0; + stats.conversionTime = 0; + stats.aabb = null; + + return new Promise(function (resolve, reject) { + const _log = log; + log = (msg) => { + _log(`[convert2xkt] ${msg}`) + } + + if (!sourceData) { + reject("Argument expected: source or sourceData"); + return; + } + + if (!outputXKTModel && !outputXKT) { + reject("Argument expected: output, outputXKTModel or outputXKT"); + return; + } + + const sourceConfigs = configs.sourceConfigs || {}; + const ext = 'glb'; + + log(`Input file extension: "${ext}"`); + + let fileTypeConfigs = sourceConfigs[ext]; + + if (!fileTypeConfigs) { + log(`[WARNING] Could not find configs sourceConfigs entry for source format "${ext}". This is derived from the source file name extension. Will use internal default configs.`); + fileTypeConfigs = {}; + } + + function overrideOption(option1, option2) { + if (option1 !== undefined) { + return option1; + } + return option2; + } + + + const sourceFileSizeBytes = sourceData.byteLength; + + log("Input file size: " + (sourceFileSizeBytes / 1000).toFixed(2) + " kB"); + + + + minTileSize = overrideOption(fileTypeConfigs.minTileSize, minTileSize); + rotateX = overrideOption(fileTypeConfigs.rotateX, rotateX); + reuseGeometries = overrideOption(fileTypeConfigs.reuseGeometries, reuseGeometries); + includeTextures = overrideOption(fileTypeConfigs.includeTextures, includeTextures); + includeNormals = overrideOption(fileTypeConfigs.includeNormals, includeNormals); + includeTypes = overrideOption(fileTypeConfigs.includeTypes, includeTypes); + excludeTypes = overrideOption(fileTypeConfigs.excludeTypes, excludeTypes); + + if (reuseGeometries === false) { + log("Geometry reuse is disabled"); + } + + const xktModel = new XKTModel({ + minTileSize, + modelAABB + }); + + + + sourceData = toArrayBuffer(sourceData); + convert(parseGLTFIntoXKTModel, { + data: sourceData, + reuseGeometries, + includeTextures: true, + includeNormals, + xktModel, + stats, + log + }); + + + function convert(parser, converterParams) { + + parser(converterParams).then(() => { + + + log("Input file parsed OK. Building XKT document..."); + + xktModel.finalize().then(() => { + + log("XKT document built OK. Writing to XKT file..."); + + const xktArrayBuffer = writeXKTModelToArrayBuffer(xktModel, null, stats, {zip: true}); + + const xktContent = Buffer.from(xktArrayBuffer); + + + if (outputXKT) { + outputXKT(xktContent); + } + + resolve(); + }); + }, (err) => { + reject(err); + }); + } + }); +} + +export {convert2xkt}; \ No newline at end of file