@@ -202,6 +202,9 @@ function BasisWorker() {
202202 const hasAlpha = ! ! basisFile . getHasAlpha ( ) ;
203203 const isUASTC = basisFile . isUASTC && basisFile . isUASTC ( ) ;
204204
205+ // a six-face file is a cubemap; faces are transcoded into per-mip arrays
206+ const cubemap = ! ! options . isCubemap ;
207+
205208 if ( ! width || ! height || ! levels ) {
206209 basisFile . close ( ) ;
207210 basisFile . delete ( ) ;
@@ -211,8 +214,8 @@ function BasisWorker() {
211214 // choose the target format
212215 const format = chooseTargetFormat ( options . deviceDetails , hasAlpha , isUASTC ) ;
213216
214- // unswizzle gggr textures under pvr compression
215- const unswizzle = ! ! options . isGGGR && format === 'pvr' ;
217+ // unswizzle gggr textures under pvr compression (never applies to cubemaps)
218+ const unswizzle = ! cubemap && ! ! options . isGGGR && format === 'pvr' ;
216219
217220 // convert to basis format taking into consideration platform restrictions
218221 let basisFormat ;
@@ -235,22 +238,34 @@ function BasisWorker() {
235238 throw new Error ( `Failed to start transcoding url=${ url } ` ) ;
236239 }
237240
238- let i ;
241+ const is16BitFormat = ( basisFormat === BASIS_FORMAT . cTFRGB565 || basisFormat === BASIS_FORMAT . cTFRGBA4444 ) ;
239242
240- const levelData = [ ] ;
241- for ( let mip = 0 ; mip < levels ; ++ mip ) {
242- const dstSize = basisFile . getImageTranscodedSizeInBytes ( mip , 0 , 0 , basisFormat ) ;
243+ // transcode a single face of a single mip level into a typed array
244+ const transcodeImage = ( mip , face ) => {
245+ const dstSize = basisFile . getImageTranscodedSizeInBytes ( mip , 0 , face , basisFormat ) ;
243246 const dst = new Uint8Array ( dstSize ) ;
244247
245- if ( ! basisFile . transcodeImage ( dst , mip , 0 , 0 , basisFormat , 0 , - 1 , - 1 ) ) {
248+ if ( ! basisFile . transcodeImage ( dst , mip , 0 , face , basisFormat , 0 , - 1 , - 1 ) ) {
246249 basisFile . close ( ) ;
247250 basisFile . delete ( ) ;
248251 throw new Error ( `Failed to transcode image url=${ url } ` ) ;
249252 }
250253
251- const is16BitFormat = ( basisFormat === BASIS_FORMAT . cTFRGB565 || basisFormat === BASIS_FORMAT . cTFRGBA4444 ) ;
254+ return is16BitFormat ? new Uint16Array ( dst . buffer ) : dst ;
255+ } ;
252256
253- levelData . push ( is16BitFormat ? new Uint16Array ( dst . buffer ) : dst ) ;
257+ const levelData = [ ] ;
258+ for ( let mip = 0 ; mip < levels ; ++ mip ) {
259+ if ( cubemap ) {
260+ // one entry per mip, each holding the six cubemap faces
261+ const faceData = [ ] ;
262+ for ( let face = 0 ; face < 6 ; ++ face ) {
263+ faceData . push ( transcodeImage ( mip , face ) ) ;
264+ }
265+ levelData . push ( faceData ) ;
266+ } else {
267+ levelData . push ( transcodeImage ( mip , 0 ) ) ;
268+ }
254269 }
255270
256271 basisFile . close ( ) ;
@@ -259,7 +274,7 @@ function BasisWorker() {
259274 // handle unswizzle option
260275 if ( unswizzle ) {
261276 basisFormat = BASIS_FORMAT . cTFRGB565 ;
262- for ( i = 0 ; i < levelData . length ; ++ i ) {
277+ for ( let i = 0 ; i < levelData . length ; ++ i ) {
263278 levelData [ i ] = pack565 ( unswizzleGGGR ( levelData [ i ] ) ) ;
264279 }
265280 }
@@ -269,7 +284,7 @@ function BasisWorker() {
269284 width : width ,
270285 height : height ,
271286 levels : levelData ,
272- cubemap : false ,
287+ cubemap : cubemap ,
273288 transcodeTime : performanceNow ( ) - funcStart ,
274289 url : url ,
275290 unswizzledGGGR : unswizzle
@@ -380,8 +395,22 @@ function BasisWorker() {
380395 const workerTranscode = ( url , data , options ) => {
381396 try {
382397 const result = transcode ( url , data , options ) ;
383- result . levels = result . levels . map ( v => v . buffer ) ;
384- self . postMessage ( { url : url , data : result } , result . levels ) ;
398+
399+ // replace typed arrays with their backing buffers for transfer. cubemap levels
400+ // are arrays of six faces, all other levels are a single image.
401+ const transfer = [ ] ;
402+ result . levels = result . levels . map ( ( level ) => {
403+ if ( Array . isArray ( level ) ) {
404+ return level . map ( ( face ) => {
405+ transfer . push ( face . buffer ) ;
406+ return face . buffer ;
407+ } ) ;
408+ }
409+ transfer . push ( level . buffer ) ;
410+ return level . buffer ;
411+ } ) ;
412+
413+ self . postMessage ( { url : url , data : result } , transfer ) ;
385414 } catch ( err ) {
386415 self . postMessage ( { url : url , err : err } , null ) ;
387416 }
0 commit comments