mylingo3d
Version:
Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor
99 lines • 3.92 kB
JavaScript
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