Skip to content

Commit 062caad

Browse files
robertlongdonmccurdy
authored andcommitted
GLTFExporter WebWorker Support (mrdoob#23857)
* Make GLTFExporter work in a WebWorker * Fix formatting * Fix canvas.toBlob * Fix OffscreenCanvas check * Fix promise * Update examples/jsm/exporters/GLTFExporter.js Co-authored-by: Don McCurdy <[email protected]> Co-authored-by: Don McCurdy <[email protected]>
1 parent a1fd2a6 commit 062caad

File tree

1 file changed

+49
-40
lines changed

1 file changed

+49
-40
lines changed

examples/jsm/exporters/GLTFExporter.js

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -225,24 +225,7 @@ function equalArray( array1, array2 ) {
225225
*/
226226
function stringToArrayBuffer( text ) {
227227

228-
if ( window.TextEncoder !== undefined ) {
229-
230-
return new TextEncoder().encode( text ).buffer;
231-
232-
}
233-
234-
const array = new Uint8Array( new ArrayBuffer( text.length ) );
235-
236-
for ( let i = 0, il = text.length; i < il; i ++ ) {
237-
238-
const value = text.charCodeAt( i );
239-
240-
// Replacing multi-byte character with space(0x20).
241-
array[ i ] = value > 0xFF ? 0x20 : value;
242-
243-
}
244-
245-
return array.buffer;
228+
return new TextEncoder().encode( text ).buffer;
246229

247230
}
248231

@@ -356,6 +339,28 @@ function getPaddedArrayBuffer( arrayBuffer, paddingByte = 0 ) {
356339

357340
let cachedCanvas = null;
358341

342+
function getCanvas() {
343+
344+
if ( cachedCanvas ) {
345+
346+
return cachedCanvas;
347+
348+
}
349+
350+
if ( typeof OffscreenCanvas !== 'undefined' ) {
351+
352+
const canvas = new OffscreenCanvas( 1, 1 );
353+
cachedCanvas = canvas;
354+
return canvas;
355+
356+
}
357+
358+
const canvas = document.createElement( 'canvas' );
359+
cachedCanvas = canvas;
360+
return canvas;
361+
362+
}
363+
359364
/**
360365
* Writer
361366
*/
@@ -454,7 +459,7 @@ class GLTFWriter {
454459

455460
// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
456461

457-
const reader = new window.FileReader();
462+
const reader = new FileReader();
458463
reader.readAsArrayBuffer( blob );
459464
reader.onloadend = function () {
460465

@@ -488,7 +493,7 @@ class GLTFWriter {
488493
binaryChunk
489494
], { type: 'application/octet-stream' } );
490495

491-
const glbReader = new window.FileReader();
496+
const glbReader = new FileReader();
492497
glbReader.readAsArrayBuffer( glbBlob );
493498
glbReader.onloadend = function () {
494499

@@ -502,7 +507,7 @@ class GLTFWriter {
502507

503508
if ( json.buffers && json.buffers.length > 0 ) {
504509

505-
const reader = new window.FileReader();
510+
const reader = new FileReader();
506511
reader.readAsDataURL( blob );
507512
reader.onloadend = function () {
508513

@@ -701,7 +706,7 @@ class GLTFWriter {
701706
const width = Math.max( metalness?.width || 0, roughness?.width || 0 );
702707
const height = Math.max( metalness?.height || 0, roughness?.height || 0 );
703708

704-
const canvas = document.createElement( 'canvas' );
709+
const canvas = getCanvas();
705710
canvas.width = width;
706711
canvas.height = height;
707712

@@ -901,7 +906,7 @@ class GLTFWriter {
901906

902907
return new Promise( function ( resolve ) {
903908

904-
const reader = new window.FileReader();
909+
const reader = new FileReader();
905910
reader.readAsArrayBuffer( blob );
906911
reader.onloadend = function () {
907912

@@ -1053,7 +1058,7 @@ class GLTFWriter {
10531058

10541059
if ( options.embedImages ) {
10551060

1056-
const canvas = cachedCanvas = cachedCanvas || document.createElement( 'canvas' );
1061+
const canvas = getCanvas();
10571062

10581063
canvas.width = Math.min( image.width, options.maxTextureSize );
10591064
canvas.height = Math.min( image.height, options.maxTextureSize );
@@ -1067,14 +1072,7 @@ class GLTFWriter {
10671072

10681073
}
10691074

1070-
if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
1071-
( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
1072-
( typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas ) ||
1073-
( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
1074-
1075-
ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
1076-
1077-
} else {
1075+
if ( image.data !== undefined ) { // THREE.DataTexture
10781076

10791077
if ( format !== RGBAFormat ) {
10801078

@@ -1101,24 +1099,35 @@ class GLTFWriter {
11011099

11021100
ctx.putImageData( new ImageData( data, image.width, image.height ), 0, 0 );
11031101

1102+
} else {
1103+
1104+
ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
1105+
11041106
}
11051107

11061108
if ( options.binary === true ) {
11071109

1108-
pending.push( new Promise( function ( resolve ) {
1110+
let toBlobPromise;
1111+
1112+
if ( canvas.toBlob !== undefined ) {
1113+
1114+
toBlobPromise = new Promise( ( resolve ) => canvas.toBlob( resolve, mimeType ) );
11091115

1110-
canvas.toBlob( function ( blob ) {
1116+
} else {
1117+
1118+
toBlobPromise = canvas.convertToBlob( { type: mimeType } );
1119+
1120+
}
11111121

1112-
writer.processBufferViewImage( blob ).then( function ( bufferViewIndex ) {
1122+
pending.push( toBlobPromise.then( blob =>
11131123

1114-
imageDef.bufferView = bufferViewIndex;
1115-
resolve();
1124+
writer.processBufferViewImage( blob ).then( bufferViewIndex => {
11161125

1117-
} );
1126+
imageDef.bufferView = bufferViewIndex;
11181127

1119-
}, mimeType );
1128+
} )
11201129

1121-
} ) );
1130+
) );
11221131

11231132
} else {
11241133

0 commit comments

Comments
 (0)