diff --git a/package.json b/package.json index d0f005b2..aabde338 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,8 @@ }, "dependencies": {}, "peerDependencies": { + "brotli": "^1.3.3", + "buffer": "^6.0.3", "three": "~0.160.0" }, "devDependencies": { @@ -35,6 +37,8 @@ "@types/node": "^17.0.23", "@types/three": "~0.160.0", "babel-loader": "^8.3.0", + "brotli": "^1.3.3", + "buffer": "^6.0.3", "circular-dependency-plugin": "^5.2.2", "css-loader": "^6.7.3", "html-loader": "^4.2.0", @@ -73,4 +77,4 @@ ], "homepage": "https://github.com/pnext/three-loader#readme", "author": "" -} \ No newline at end of file +} diff --git a/src/loading2/brotli-decoder.worker.js b/src/loading2/brotli-decoder.worker.js new file mode 100644 index 00000000..9809291b --- /dev/null +++ b/src/loading2/brotli-decoder.worker.js @@ -0,0 +1,430 @@ +import { PointAttribute, PointAttributeTypes } from './point-attributes.ts'; +import { Buffer } from 'buffer'; + +const decompress = require('brotli/decompress'); + +const typedArrayMapping = { + 'int8': Int8Array, + 'int16': Int16Array, + 'int32': Int32Array, + 'int64': Float64Array, + 'uint8': Uint8Array, + 'uint16': Uint16Array, + 'uint32': Uint32Array, + 'uint64': Float64Array, + 'float': Float32Array, + 'double': Float64Array, +}; + +// Potree = {}; + +function dealign24b(mortoncode){ + // see https://stackoverflow.com/questions/45694690/how-i-can-remove-all-odds-bits-in-c + + // input alignment of desired bits + // ..a..b..c..d..e..f..g..h..i..j..k..l..m..n..o..p + let x = mortoncode; + + // ..a..b..c..d..e..f..g..h..i..j..k..l..m..n..o..p ..a..b..c..d..e..f..g..h..i..j..k..l..m..n..o..p + // ..a.....c.....e.....g.....i.....k.....m.....o... .....b.....d.....f.....h.....j.....l.....n.....p + // ....a.....c.....e.....g.....i.....k.....m.....o. .....b.....d.....f.....h.....j.....l.....n.....p + x = ((x & 0b001000001000001000001000) >> 2) | ((x & 0b000001000001000001000001) >> 0); + // ....ab....cd....ef....gh....ij....kl....mn....op ....ab....cd....ef....gh....ij....kl....mn....op + // ....ab..........ef..........ij..........mn...... ..........cd..........gh..........kl..........op + // ........ab..........ef..........ij..........mn.. ..........cd..........gh..........kl..........op + x = ((x & 0b000011000000000011000000) >> 4) | ((x & 0b000000000011000000000011) >> 0); + // ........abcd........efgh........ijkl........mnop ........abcd........efgh........ijkl........mnop + // ........abcd....................ijkl............ ....................efgh....................mnop + // ................abcd....................ijkl.... ....................efgh....................mnop + x = ((x & 0b000000001111000000000000) >> 8) | ((x & 0b000000000000000000001111) >> 0); + // ................abcdefgh................ijklmnop ................abcdefgh................ijklmnop + // ................abcdefgh........................ ........................................ijklmnop + // ................................abcdefgh........ ........................................ijklmnop + x = ((x & 0b000000000000000000000000) >> 16) | ((x & 0b000000000000000011111111) >> 0); + + // sucessfully realigned! + //................................abcdefghijklmnop + + return x; +} + +let mask_b0 = new Uint8Array([0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3]); + +onmessage = function (event) { + + let { pointAttributes, scale, name, min, max, size, offset, numPoints } = event.data; + + let tStart = performance.now(); + + let buffer = decompress(Buffer.from(event.data.buffer), event.data.buffer.byteLength); + let view = new DataView(buffer.buffer); + + let attributeBuffers = {}; + let attributeOffset = 0; + + let bytesPerPoint = 0; + for (let pointAttribute of pointAttributes.attributes) { + bytesPerPoint += pointAttribute.byteSize; + } + + let gridSize = 32; + let grid = new Uint32Array(gridSize ** 3); + let toIndex = (x, y, z) => { + + // min is already subtracted + let dx = gridSize * x / size.x; + let dy = gridSize * y / size.y; + let dz = gridSize * z / size.z; + + let ix = Math.min(parseInt(dx), gridSize - 1); + let iy = Math.min(parseInt(dy), gridSize - 1); + let iz = Math.min(parseInt(dz), gridSize - 1); + + let index = ix + iy * gridSize + iz * gridSize * gridSize; + + return index; + }; + + let numOccupiedCells = 0; + let byteOffset = 0; + + let tightBoxMin = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY]; + let tightBoxMax = [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY]; + + for (let pointAttribute of pointAttributes.attributes) { + + + if(['POSITION_CARTESIAN', 'position'].includes(pointAttribute.name)){ + + // let tStart = performance.now(); + + let buff = new ArrayBuffer(numPoints * 4 * 3); + let positions = new Float32Array(buff); + + for (let j = 0; j < numPoints; j++) { + + + let mc_0 = view.getUint32(byteOffset + 4, true); + let mc_1 = view.getUint32(byteOffset + 0, true); + let mc_2 = view.getUint32(byteOffset + 12, true); + let mc_3 = view.getUint32(byteOffset + 8, true); + + byteOffset += 16; + + let X = dealign24b((mc_3 & 0x00FFFFFF) >>> 0) + | (dealign24b(((mc_3 >>> 24) | (mc_2 << 8)) >>> 0) << 8); + + let Y = dealign24b((mc_3 & 0x00FFFFFF) >>> 1) + | (dealign24b(((mc_3 >>> 24) | (mc_2 << 8)) >>> 1) << 8) + + + let Z = dealign24b((mc_3 & 0x00FFFFFF) >>> 2) + | (dealign24b(((mc_3 >>> 24) | (mc_2 << 8)) >>> 2) << 8) + + + if(mc_1 != 0 || mc_2 != 0){ + X = X | (dealign24b((mc_1 & 0x00FFFFFF) >>> 0) << 16) + | (dealign24b(((mc_1 >>> 24) | (mc_0 << 8)) >>> 0) << 24); + + Y = Y | (dealign24b((mc_1 & 0x00FFFFFF) >>> 1) << 16) + | (dealign24b(((mc_1 >>> 24) | (mc_0 << 8)) >>> 1) << 24); + + Z = Z | (dealign24b((mc_1 & 0x00FFFFFF) >>> 2) << 16) + | (dealign24b(((mc_1 >>> 24) | (mc_0 << 8)) >>> 2) << 24); + } + + // ======================= + // VERIFY AGAINST LOOP VERSION + // ======================= + // let reference; + // { // correct reference + + // let mc_upper = view.getBigUint64(byteOffset + 0, true); + // let mc_lower = view.getBigUint64(byteOffset + 8, true); + + // let X = 0n; + // let Y = 0n; + // let Z = 0n; + + // for(let k = 0n; k < 16n; k++){ + // let mask_lower = (mc_lower >> (3n * k)) & 0b111n; + // let mask_upper = (mc_upper >> (3n * k)) & 0b111n; + + // X = X | (((mask_lower >> 0n) & 0b001n) << k); + // X = X | ((((mask_upper >> 0n) & 0b001n) << k) << 16n); + + // Y = Y | (((mask_lower >> 1n) & 0b001n) << k); + // Y = Y | ((((mask_upper >> 1n) & 0b001n) << k) << 16n); + + // Z = Z | (((mask_lower >> 2n) & 0b001n) << k); + // Z = Z | ((((mask_upper >> 2n) & 0b001n) << k) << 16n); + // } + + // reference = [X, Y, Z]; + // } + // //dbgad += parseInt(reference[2]); + // let [rX, rY, rZ] = reference; + + // if(X !== parseInt(rX)){ + // debugger; + // } + // if(Y !== parseInt(rY)){ + // debugger; + // } + // if(Z !== parseInt(rZ)){ + // debugger; + // } + + + + + // let mc_upper = view.getBigUint64(byteOffset + 0, true); + // let mc_lower = view.getBigUint64(byteOffset + 8, true); + // byteOffset += 16; + + // ======================= + // MAGIC NUMBERS 32BIT + // ======================= + // let mc0 = parseInt((mc_lower >> 0n) & 0x00FFFFFFn); + // let mc1 = parseInt((mc_lower >> 24n) & 0x00FFFFFFn); + // let mc2 = parseInt((mc_lower >> 48n) & 0x00FFFFFFn); + + // let X = dealign24b(mc0 >> 0) | (dealign24b(mc1 >> 0) << 8) | (dealign24b(mc2 >> 0) << 16); + // let Y = dealign24b(mc0 >> 1) | (dealign24b(mc1 >> 1) << 8) | (dealign24b(mc2 >> 1) << 16); + // let Z = dealign24b(mc0 >> 2) | (dealign24b(mc1 >> 2) << 8) | (dealign24b(mc2 >> 2) << 16); + + + // ======================= + // MAGIC NUMBERS BIGINT + // ======================= + // let X = dealign(mc_lower >> 0n);// | (dealign(mc_upper >> 0n) << 16n); + // let Y = dealign(mc_lower >> 1n);// | (dealign(mc_upper >> 1n) << 16n); + // let Z = dealign(mc_lower >> 2n);// | (dealign(mc_upper >> 2n) << 16n); + + // ======================= + // LOOP + // ======================= + // let X = 0n; + // let Y = 0n; + // let Z = 0n; + + // for(let k = 0n; k < 16n; k++){ + // let mask_lower = (mc_lower >> (3n * k)) & 0b111n; + // let mask_upper = (mc_upper >> (3n * k)) & 0b111n; + + // X = X | (((mask_lower >> 0n) & 0b001n) << k); + // X = X | ((((mask_upper >> 0n) & 0b001n) << k) << 16n); + + // Y = Y | (((mask_lower >> 1n) & 0b001n) << k); + // Y = Y | ((((mask_upper >> 1n) & 0b001n) << k) << 16n); + + // Z = Z | (((mask_lower >> 2n) & 0b001n) << k); + // Z = Z | ((((mask_upper >> 2n) & 0b001n) << k) << 16n); + // } + + + + let x = parseInt(X) * scale[0] + offset[0] - min.x; + let y = parseInt(Y) * scale[1] + offset[1] - min.y; + let z = parseInt(Z) * scale[2] + offset[2] - min.z; + + tightBoxMin[0] = Math.min(tightBoxMin[0], x); + tightBoxMin[1] = Math.min(tightBoxMin[1], y); + tightBoxMin[2] = Math.min(tightBoxMin[2], z); + + tightBoxMax[0] = Math.max(tightBoxMax[0], x); + tightBoxMax[1] = Math.max(tightBoxMax[1], y); + tightBoxMax[2] = Math.max(tightBoxMax[2], z); + + let index = toIndex(x, y, z); + let count = grid[index]++; + if(count === 0){ + numOccupiedCells++; + } + + positions[3 * j + 0] = x; + positions[3 * j + 1] = y; + positions[3 * j + 2] = z; + } + + // let duration = performance.now() - tStart; + // console.log(`xyz: ${duration.toFixed(1)}ms`); + + attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute }; + }else if(['RGBA', 'rgba'].includes(pointAttribute.name)){ + + let buff = new ArrayBuffer(numPoints * 4); + let colors = new Uint8Array(buff); + + // for (let j = 0; j < numPoints; j++) { + // let r = view.getUint16(byteOffset + 0, true); + // let g = view.getUint16(byteOffset + 2, true); + // let b = view.getUint16(byteOffset + 4, true); + // byteOffset += 6; + + // colors[4 * j + 0] = r > 255 ? r / 256 : r; + // colors[4 * j + 1] = g > 255 ? g / 256 : g; + // colors[4 * j + 2] = b > 255 ? b / 256 : b; + // } + + // let tStart = performance.now(); + + for (let j = 0; j < numPoints; j++) { + + let mc_0 = view.getUint32(byteOffset + 4, true); + let mc_1 = view.getUint32(byteOffset + 0, true); + byteOffset += 8; + + let r = dealign24b((mc_1 & 0x00FFFFFF) >>> 0) + | (dealign24b(((mc_1 >>> 24) | (mc_0 << 8)) >>> 0) << 8); + + let g = dealign24b((mc_1 & 0x00FFFFFF) >>> 1) + | (dealign24b(((mc_1 >>> 24) | (mc_0 << 8)) >>> 1) << 8); + + let b = dealign24b((mc_1 & 0x00FFFFFF) >>> 2) + | (dealign24b(((mc_1 >>> 24) | (mc_0 << 8)) >>> 2) << 8); + + // let bits = mask_b0[mc_1 >>> 24]; + + // if(((r >> 8) & 0b11) !== bits){ + // debugger; + // } + + // let r = dealign24b(mc0 >> 0) | (dealign24b(mc1 >> 0) << 8); + // let g = dealign24b(mc0 >> 1) | (dealign24b(mc1 >> 1) << 8); + // let b = dealign24b(mc0 >> 2) | (dealign24b(mc1 >> 2) << 8); + + + colors[4 * j + 0] = r > 255 ? r / 256 : r; + colors[4 * j + 1] = g > 255 ? g / 256 : g; + colors[4 * j + 2] = b > 255 ? b / 256 : b; + } + // let duration = performance.now() - tStart; + // console.log(`rgb: ${duration.toFixed(1)}ms`); + + attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute }; + }else{ + let buff = new ArrayBuffer(numPoints * 4); + let f32 = new Float32Array(buff); + + let TypedArray = typedArrayMapping[pointAttribute.type.name]; + let preciseBuffer = new TypedArray(numPoints); + + let [offset, scale] = [0, 1]; + + const getterMap = { + 'int8': view.getInt8, + 'int16': view.getInt16, + 'int32': view.getInt32, + // 'int64': view.getInt64, + 'uint8': view.getUint8, + 'uint16': view.getUint16, + 'uint32': view.getUint32, + // 'uint64': view.getUint64, + 'float': view.getFloat32, + 'double': view.getFloat64, + }; + const getter = getterMap[pointAttribute.type.name].bind(view); + + // compute offset and scale to pack larger types into 32 bit floats + if(pointAttribute.type.size > 4){ + let [amin, amax] = pointAttribute.range; + offset = amin; + scale = 1 / (amax - amin); + } + + for(let j = 0; j < numPoints; j++){ + // let pointOffset = j * bytesPerPoint; + let value = getter(byteOffset, true); + byteOffset += pointAttribute.byteSize; + + f32[j] = (value - offset) * scale; + preciseBuffer[j] = value; + } + + attributeBuffers[pointAttribute.name] = { + buffer: buff, + preciseBuffer: preciseBuffer, + attribute: pointAttribute, + offset: offset, + scale: scale, + }; + } + + // attributeOffset += pointAttribute.byteSize; + + + } + + let occupancy = parseInt(numPoints / numOccupiedCells); + + { // add indices + let buff = new ArrayBuffer(numPoints * 4); + let indices = new Uint32Array(buff); + + for (let i = 0; i < numPoints; i++) { + indices[i] = i; + } + + attributeBuffers['INDICES'] = { buffer: buff, attribute: PointAttribute.INDICES }; + } + + + { // handle attribute vectors + let vectors = pointAttributes.vectors; + + for(let vector of vectors){ + + let {name, attributes} = vector; + let numVectorElements = attributes.length; + let buffer = new ArrayBuffer(numVectorElements * numPoints * 4); + let f32 = new Float32Array(buffer); + + let iElement = 0; + for(let sourceName of attributes){ + let sourceBuffer = attributeBuffers[sourceName]; + let {offset, scale} = sourceBuffer; + let view = new DataView(sourceBuffer.buffer); + + const getter = view.getFloat32.bind(view); + + for(let j = 0; j < numPoints; j++){ + let value = getter(j * 4, true); + + f32[j * numVectorElements + iElement] = (value / scale) + offset; + } + + iElement++; + } + + let vecAttribute = new PointAttribute(name, PointAttributeTypes.DATA_TYPE_FLOAT, 3); + + attributeBuffers[name] = { + buffer: buffer, + attribute: vecAttribute, + }; + + } + + } + + + let duration = performance.now() - tStart; + let pointsPerMs = numPoints / duration; + // console.log(`duration: ${duration.toFixed(1)}ms, #points: ${numPoints}, points/ms: ${pointsPerMs.toFixed(1)}`); + + let message = { + buffer: buffer, + attributeBuffers: attributeBuffers, + density: occupancy, + tightBoundingBox: { min: tightBoxMin, max: tightBoxMax }, + }; + + let transferables = []; + for (let property in message.attributeBuffers) { + transferables.push(message.attributeBuffers[property].buffer); + } + // transferables.push(buffer); + + postMessage(message, transferables); +}; \ No newline at end of file diff --git a/src/loading2/gltf-decoder.worker.js b/src/loading2/gltf-decoder.worker.js index b860cbd4..7bf85546 100644 --- a/src/loading2/gltf-decoder.worker.js +++ b/src/loading2/gltf-decoder.worker.js @@ -1,16 +1,16 @@ import {PointAttribute, PointAttributeTypes} from './point-attributes.ts'; const typedArrayMapping = { - 'int8': Int8Array, - 'int16': Int16Array, - 'int32': Int32Array, - 'int64': Float64Array, - 'uint8': Uint8Array, - 'uint16': Uint16Array, - 'uint32': Uint32Array, - 'uint64': Float64Array, - 'float': Float32Array, - 'double': Float64Array, + 'int8': Int8Array, + 'int16': Int16Array, + 'int32': Int32Array, + 'int64': Float64Array, + 'uint8': Uint8Array, + 'uint16': Uint16Array, + 'uint32': Uint32Array, + 'uint64': Float64Array, + 'float': Float32Array, + 'double': Float64Array, }; onmessage = function (event) { @@ -42,8 +42,8 @@ onmessage = function (event) { let numOccupiedCells = 0; - let tightBoxMin = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY]; - let tightBoxMax = [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY]; + let tightBoxMin = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY]; + let tightBoxMax = [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY]; for (let pointAttribute of pointAttributes.attributes) { if(["POSITION_CARTESIAN", "position"].includes(pointAttribute.name)){ @@ -56,13 +56,13 @@ onmessage = function (event) { let y = view.getFloat32(pointOffset + 4, true) + offset[1] - min.y; let z = view.getFloat32(pointOffset + 8, true) + offset[2] - min.z; - tightBoxMin[0] = Math.min(tightBoxMin[0], x); - tightBoxMin[1] = Math.min(tightBoxMin[1], y); - tightBoxMin[2] = Math.min(tightBoxMin[2], z); + tightBoxMin[0] = Math.min(tightBoxMin[0], x); + tightBoxMin[1] = Math.min(tightBoxMin[1], y); + tightBoxMin[2] = Math.min(tightBoxMin[2], z); - tightBoxMax[0] = Math.max(tightBoxMax[0], x); - tightBoxMax[1] = Math.max(tightBoxMax[1], y); - tightBoxMax[2] = Math.max(tightBoxMax[2], z); + tightBoxMax[0] = Math.max(tightBoxMax[0], x); + tightBoxMax[1] = Math.max(tightBoxMax[1], y); + tightBoxMax[2] = Math.max(tightBoxMax[2], z); let index = toIndex(x, y, z); let count = grid[index]++; @@ -137,7 +137,7 @@ onmessage = function (event) { buffer: buffer, attributeBuffers: attributeBuffers, density: occupancy, - tightBoundingBox: { min: tightBoxMin, max: tightBoxMax }, + tightBoundingBox: { min: tightBoxMin, max: tightBoxMax }, }; let transferables = []; diff --git a/src/loading2/octree-loader.ts b/src/loading2/octree-loader.ts index a603d0e4..bece6421 100644 --- a/src/loading2/octree-loader.ts +++ b/src/loading2/octree-loader.ts @@ -94,7 +94,13 @@ export class NodeLoader { } } - const workerType = this.metadata.encoding === 'GLTF' ? WorkerType.DECODER_WORKER_GLTF : WorkerType.DECODER_WORKER; + const workerType = + this.metadata.encoding === 'GLTF' + ? WorkerType.DECODER_WORKER_GLTF + : this.metadata.encoding === 'BROTLI' + ? WorkerType.DECODER_WORKER_BROTLI + : WorkerType.DECODER_WORKER; + const worker = this.workerPool.getWorker(workerType); worker.onmessage = (e) => { diff --git a/src/loading2/worker-pool.ts b/src/loading2/worker-pool.ts index e71be262..a8c33378 100644 --- a/src/loading2/worker-pool.ts +++ b/src/loading2/worker-pool.ts @@ -3,6 +3,7 @@ export enum WorkerType { DECODER_WORKER = 'DECODER_WORKER', DECODER_WORKER_GLTF = 'DECODER_WORKER_GLTF', + DECODER_WORKER_BROTLI = 'DECODER_WORKER_BROTLI' } // Worker JS names: 'BinaryDecoderWorker.js', 'DEMWorker.js', 'EptBinaryDecoderWorker.js', 'EptLaszipDecoderWorker.js', @@ -19,6 +20,10 @@ function createWorker(type: WorkerType): Worker { const DecoderWorker_GLTF = require('./gltf-decoder.worker.js').default; return new DecoderWorker_GLTF(); } + case WorkerType.DECODER_WORKER_BROTLI: { + const DecoderWorker_Brotli = require('./brotli-decoder.worker.js').default; + return new DecoderWorker_Brotli(); + } default: throw new Error('Unknown worker type'); } @@ -26,7 +31,7 @@ function createWorker(type: WorkerType): Worker { export class WorkerPool { // Workers will be an object that has a key for each worker type and the value is an array of Workers that can be empty - private workers: { [key in WorkerType]: Worker[] } = {DECODER_WORKER: [], DECODER_WORKER_GLTF: []}; + private workers: { [key in WorkerType]: Worker[] } = {DECODER_WORKER: [], DECODER_WORKER_GLTF: [], DECODER_WORKER_BROTLI: []}; getWorker(workerType: WorkerType): Worker { // Throw error if workerType is not recognized diff --git a/webpack.config.js b/webpack.config.js index f58d27f6..5aecd2a8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -14,6 +14,10 @@ module.exports = { stats: 'errors-only', resolve: { extensions: ['.ts', '.tsx', '.js'], + fallback: { + fs: false, + path: false, + }, }, externals: ['three'], module: { diff --git a/yarn.lock b/yarn.lock index 333b16bd..ba067074 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1636,6 +1636,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.1.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" @@ -1697,6 +1702,13 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" +brotli@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/brotli/-/brotli-1.3.3.tgz#7365d8cc00f12cf765d2b2c898716bcf4b604d48" + integrity sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg== + dependencies: + base64-js "^1.1.2" + browserslist@^4.21.10, browserslist@^4.22.2: version "4.23.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" @@ -1722,6 +1734,14 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -3214,6 +3234,11 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + import-local@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4"