UNPKG

mylingo3d

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

99 lines 3.92 kB
import { Box3, BufferAttribute } from "three"; import { MeshBVH } from "three-mesh-bvh"; import code from "./workerString"; import { Queue } from "@lincode/promiselikes"; const queue = new Queue(); export const geometryMeshMap = new WeakMap(); export class GenerateMeshBVHWorker { worker; constructor() { const blob = new Blob([code], { type: "application/javascript" }); this.worker = new Worker(URL.createObjectURL(blob)); this.worker.onerror = (e) => { if (e.message) { throw new Error(`GenerateMeshBVHWorker: Could not create Web Worker with error "${e.message}"`); } else { throw new Error("GenerateMeshBVHWorker: Could not create Web Worker."); } }; } async generate(geom, options = {}) { await queue; if (this.worker === null) { throw new Error("GenerateMeshBVHWorker: Worker has been disposed."); } const { worker } = this; const geometry = geom.clone(); geometry.dispose(); return new Promise((resolve, reject) => { worker.onerror = (e) => { reject(new Error(`GenerateMeshBVHWorker: ${e.message}`)); queue.resolve(); }; worker.onmessage = (e) => { const { data } = e; if (data.error) { reject(new Error(data.error)); queue.resolve(); worker.onmessage = null; } else if (data.serialized) { const { serialized, position } = data; const bvh = MeshBVH.deserialize(serialized, geometry, { setIndex: false }); const boundsOptions = Object.assign({ setBoundingBox: true }, options); //@ts-ignore geometry.attributes.position.array = position; if (geometry.index) { geometry.index.array = serialized.index; } else { const newIndex = new BufferAttribute(serialized.index, 1, false); geometry.setIndex(newIndex); } if (boundsOptions.setBoundingBox) { geometry.boundingBox = bvh.getBoundingBox(new Box3()); } resolve(bvh); queue.resolve(); worker.onmessage = null; } else if (options.onProgress) { options.onProgress(data.progress); } }; const index = geometry.index ? geometry.index.array : null; const position = geometry.attributes.position.array; const transferrables = [position]; if (index) { transferrables.push(index); } worker.postMessage({ index, position, matrixWorld: geometryMeshMap.get(geom).matrixWorld, options: { ...options, onProgress: null, includedProgressCallback: Boolean(options.onProgress), groups: [...geometry.groups] } }, //@ts-ignore transferrables.map((arr) => arr.buffer)); }); } dispose() { this.worker.terminate(); this.worker = null; } terminate() { console.warn('GenerateMeshBVHWorker: "terminate" is deprecated. Use "dispose" instead.'); this.dispose(); } } //# sourceMappingURL=GenerateMeshBVHWorker.js.map