feat(All):Initial
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import { Box3, BufferAttribute } from 'three';
|
||||
import { MeshBVH } from 'three-mesh-bvh';
|
||||
import GenerateAsyncWorkerUrl from './generateAsync.worker.js?worker&url';
|
||||
|
||||
export class GenerateMeshBVHWorker {
|
||||
constructor() {
|
||||
this.running = false;
|
||||
this.worker = new Worker(GenerateAsyncWorkerUrl, { type: 'module' });
|
||||
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.' );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
generate( geometry, options = {} ) {
|
||||
if (this.running) {
|
||||
throw new Error( 'GenerateMeshBVHWorker: Already running job.' );
|
||||
}
|
||||
|
||||
if (this.worker === null) {
|
||||
throw new Error( 'GenerateMeshBVHWorker: Worker has been disposed.' );
|
||||
}
|
||||
|
||||
const { worker } = this;
|
||||
this.running = true;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
worker.onerror = e => {
|
||||
reject( new Error( `GenerateMeshBVHWorker: ${ e.message }` ) );
|
||||
this.running = false;
|
||||
};
|
||||
|
||||
worker.onmessage = e => {
|
||||
this.running = false;
|
||||
const { data } = e;
|
||||
|
||||
if (data.error) {
|
||||
reject( new Error( data.error ) );
|
||||
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 );
|
||||
|
||||
// we need to replace the arrays because they're neutered entirely by the
|
||||
// webworker transfer.
|
||||
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 );
|
||||
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;
|
||||
|
||||
if (position.isInterleavedBufferAttribute || index && index.isInterleavedBufferAttribute) {
|
||||
throw new Error( 'GenerateMeshBVHWorker: InterleavedBufferAttribute are not supported for the geometry attributes.' );
|
||||
}
|
||||
|
||||
const transferable = [ position ];
|
||||
if (index) {
|
||||
transferable.push( index );
|
||||
}
|
||||
|
||||
worker.postMessage({
|
||||
index,
|
||||
position,
|
||||
options: {
|
||||
...options,
|
||||
onProgress: null,
|
||||
includedProgressCallback: Boolean( options.onProgress ),
|
||||
groups: [ ... geometry.groups ],
|
||||
},
|
||||
}, transferable.map(arr => arr.buffer));
|
||||
});
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.worker.terminate();
|
||||
this.worker = null;
|
||||
}
|
||||
|
||||
terminate() {
|
||||
console.warn( 'GenerateMeshBVHWorker: "terminate" is deprecated. Use "dispose" instead.' );
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user