diff --git a/miniprogram/pages/index/index.js b/miniprogram/pages/index/index.js index 351176b..98387fc 100644 --- a/miniprogram/pages/index/index.js +++ b/miniprogram/pages/index/index.js @@ -47069,7 +47069,7 @@ class WechatPlatform { dispose() { this.disableDeviceOrientation(); - this.canvas.ownerDocument = null; + if (this.canvas) this.canvas.ownerDocument = null; this.onGyroscopeChange = null; this.document = null; this.window = null; @@ -56142,576 +56142,7 @@ class DemoGLTFLoader extends Demo { } } -/** - * Loader for Basis Universal GPU Texture Codec. - * - * Basis Universal is a "supercompressed" GPU texture and texture video - * compression system that outputs a highly compressed intermediate file format - * (.basis) that can be quickly transcoded to a wide variety of GPU texture - * compression formats. - * - * This loader parallelizes the transcoding process across a configurable number - * of web workers, before transferring the transcoded compressed texture back - * to the main thread. - */ -var BasisTextureLoader = function ( manager ) { - - Loader.call( this, manager ); - - this.transcoderPath = ''; - this.transcoderBinary = null; - this.transcoderPending = null; - - this.workerLimit = 4; - this.workerPool = []; - this.workerNextTaskID = 1; - this.workerSourceURL = ''; - this.workerConfig = { - format: null, - astcSupported: false, - bptcSupported: false, - etcSupported: false, - dxtSupported: false, - pvrtcSupported: false, - }; - -}; - -BasisTextureLoader.taskCache = new WeakMap(); - -BasisTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - - constructor: BasisTextureLoader, - - setTranscoderPath: function ( path ) { - - this.transcoderPath = path; - - return this; - - }, - - setWorkerLimit: function ( workerLimit ) { - - this.workerLimit = workerLimit; - - return this; - - }, - - detectSupport: function ( renderer ) { - - var config = this.workerConfig; - - config.astcSupported = renderer.extensions.has( 'WEBGL_compressed_texture_astc' ); - config.bptcSupported = renderer.extensions.has( 'EXT_texture_compression_bptc' ); - config.etcSupported = renderer.extensions.has( 'WEBGL_compressed_texture_etc1' ); - config.dxtSupported = renderer.extensions.has( 'WEBGL_compressed_texture_s3tc' ); - config.pvrtcSupported = renderer.extensions.has( 'WEBGL_compressed_texture_pvrtc' ) - || renderer.extensions.has( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ); - - if ( config.astcSupported ) { - - config.format = BasisTextureLoader.BASIS_FORMAT.cTFASTC_4x4; - - } else if ( config.bptcSupported ) { - - config.format = BasisTextureLoader.BASIS_FORMAT.cTFBC7_M5; - - } else if ( config.dxtSupported ) { - - config.format = BasisTextureLoader.BASIS_FORMAT.cTFBC3; - - } else if ( config.pvrtcSupported ) { - - config.format = BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGBA; - - } else if ( config.etcSupported ) { - - config.format = BasisTextureLoader.BASIS_FORMAT.cTFETC1; - - } else { - - throw new Error( 'THREE.BasisTextureLoader: No suitable compressed texture format found.' ); - - } - - return this; - - }, - - load: function ( url, onLoad, onProgress, onError ) { - - var loader = new FileLoader( this.manager ); - - loader.setResponseType( 'arraybuffer' ); - loader.setWithCredentials( this.withCredentials ); - - loader.load( url, ( buffer ) => { - - // Check for an existing task using this buffer. A transferred buffer cannot be transferred - // again from this thread. - if ( BasisTextureLoader.taskCache.has( buffer ) ) { - - var cachedTask = BasisTextureLoader.taskCache.get( buffer ); - - return cachedTask.promise.then( onLoad ).catch( onError ); - - } - - this._createTexture( buffer, url ) - .then( onLoad ) - .catch( onError ); - - }, onProgress, onError ); - - }, - - /** - * @param {ArrayBuffer} buffer - * @param {string} url - * @return {Promise} - */ - _createTexture: function ( buffer, url ) { - - var worker; - var taskID; - - var taskCost = buffer.byteLength; - - var texturePending = this._allocateWorker( taskCost ) - .then( ( _worker ) => { - - worker = _worker; - taskID = this.workerNextTaskID ++; - - return new Promise( ( resolve, reject ) => { - - worker._callbacks[ taskID ] = { resolve, reject }; - - worker.postMessage( { type: 'transcode', id: taskID, buffer }, [ buffer ] ); - - } ); - - } ) - .then( ( message ) => { - - var config = this.workerConfig; - - var { width, height, mipmaps, format } = message; - - var texture; - - switch ( format ) { - - case BasisTextureLoader.BASIS_FORMAT.cTFASTC_4x4: - texture = new CompressedTexture( mipmaps, width, height, RGBA_ASTC_4x4_Format ); - break; - case BasisTextureLoader.BASIS_FORMAT.cTFBC7_M5: - texture = new CompressedTexture( mipmaps, width, height, RGBA_BPTC_Format ); - break; - case BasisTextureLoader.BASIS_FORMAT.cTFBC1: - case BasisTextureLoader.BASIS_FORMAT.cTFBC3: - texture = new CompressedTexture( mipmaps, width, height, BasisTextureLoader.DXT_FORMAT_MAP[ config.format ], UnsignedByteType ); - break; - case BasisTextureLoader.BASIS_FORMAT.cTFETC1: - texture = new CompressedTexture( mipmaps, width, height, RGB_ETC1_Format ); - break; - case BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGB: - texture = new CompressedTexture( mipmaps, width, height, RGB_PVRTC_4BPPV1_Format ); - break; - case BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGBA: - texture = new CompressedTexture( mipmaps, width, height, RGBA_PVRTC_4BPPV1_Format ); - break; - default: - throw new Error( 'THREE.BasisTextureLoader: No supported format available.' ); - - } - - texture.minFilter = mipmaps.length === 1 ? LinearFilter : LinearMipmapLinearFilter; - texture.magFilter = LinearFilter; - texture.generateMipmaps = false; - texture.needsUpdate = true; - - return texture; - - } ); - - // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416) - texturePending - .catch( () => true ) - .then( () => { - - if ( worker && taskID ) { - - worker._taskLoad -= taskCost; - delete worker._callbacks[ taskID ]; - - } - - } ); - - // Cache the task result. - BasisTextureLoader.taskCache.set( buffer, { - - url: url, - promise: texturePending - - } ); - - return texturePending; - - }, - - _initTranscoder: function () { - - if ( ! this.transcoderPending ) { - - // Load transcoder wrapper. - var jsLoader = new FileLoader( this.manager ); - jsLoader.setPath( this.transcoderPath ); - jsLoader.setWithCredentials( this.withCredentials ); - var jsContent = new Promise( ( resolve, reject ) => { - - jsLoader.load( 'basis_transcoder.js', resolve, undefined, reject ); - - } ); - - // Load transcoder WASM binary. - var binaryLoader = new FileLoader( this.manager ); - binaryLoader.setPath( this.transcoderPath ); - binaryLoader.setResponseType( 'arraybuffer' ); - binaryLoader.setWithCredentials( this.withCredentials ); - var binaryContent = new Promise( ( resolve, reject ) => { - - binaryLoader.load( 'basis_transcoder.wasm', resolve, undefined, reject ); - - } ); - - this.transcoderPending = Promise.all( [ jsContent, binaryContent ] ) - .then( ( [ jsContent, binaryContent ] ) => { - - var fn = BasisTextureLoader.BasisWorker.toString(); - - var body = [ - '/* basis_transcoder.js */', - jsContent, - '/* worker */', - fn.substring( fn.indexOf( '{' ) + 1, fn.lastIndexOf( '}' ) ) - ].join( '\n' ); - - this.workerSourceURL = $URL.createObjectURL( new $Blob( [ body ] ) ); - this.transcoderBinary = binaryContent; - - } ); - - } - - return this.transcoderPending; - - }, - - _allocateWorker: function ( taskCost ) { - - return this._initTranscoder().then( () => { - - if ( this.workerPool.length < this.workerLimit ) { - - var worker = new Worker( this.workerSourceURL ); - - worker._callbacks = {}; - worker._taskLoad = 0; - - worker.postMessage( { - type: 'init', - config: this.workerConfig, - transcoderBinary: this.transcoderBinary, - } ); - - worker.onmessage = function ( e ) { - - var message = e.data; - - switch ( message.type ) { - - case 'transcode': - worker._callbacks[ message.id ].resolve( message ); - break; - - case 'error': - worker._callbacks[ message.id ].reject( message ); - break; - - default: - console.error( 'THREE.BasisTextureLoader: Unexpected message, "' + message.type + '"' ); - - } - - }; - - this.workerPool.push( worker ); - - } else { - - this.workerPool.sort( function ( a, b ) { - - return a._taskLoad > b._taskLoad ? - 1 : 1; - - } ); - - } - - var worker = this.workerPool[ this.workerPool.length - 1 ]; - - worker._taskLoad += taskCost; - - return worker; - - } ); - - }, - - dispose: function () { - - for ( var i = 0; i < this.workerPool.length; i ++ ) { - - this.workerPool[ i ].terminate(); - - } - - this.workerPool.length = 0; - - return this; - - } - -} ); - -/* CONSTANTS */ - -BasisTextureLoader.BASIS_FORMAT = { - cTFETC1: 0, - cTFETC2: 1, - cTFBC1: 2, - cTFBC3: 3, - cTFBC4: 4, - cTFBC5: 5, - cTFBC7_M6_OPAQUE_ONLY: 6, - cTFBC7_M5: 7, - cTFPVRTC1_4_RGB: 8, - cTFPVRTC1_4_RGBA: 9, - cTFASTC_4x4: 10, - cTFATC_RGB: 11, - cTFATC_RGBA_INTERPOLATED_ALPHA: 12, - cTFRGBA32: 13, - cTFRGB565: 14, - cTFBGR565: 15, - cTFRGBA4444: 16, -}; - -// DXT formats, from: -// http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/ -BasisTextureLoader.DXT_FORMAT = { - COMPRESSED_RGB_S3TC_DXT1_EXT: 0x83F0, - COMPRESSED_RGBA_S3TC_DXT1_EXT: 0x83F1, - COMPRESSED_RGBA_S3TC_DXT3_EXT: 0x83F2, - COMPRESSED_RGBA_S3TC_DXT5_EXT: 0x83F3, -}; -BasisTextureLoader.DXT_FORMAT_MAP = {}; -BasisTextureLoader.DXT_FORMAT_MAP[ BasisTextureLoader.BASIS_FORMAT.cTFBC1 ] = - BasisTextureLoader.DXT_FORMAT.COMPRESSED_RGB_S3TC_DXT1_EXT; -BasisTextureLoader.DXT_FORMAT_MAP[ BasisTextureLoader.BASIS_FORMAT.cTFBC3 ] = - BasisTextureLoader.DXT_FORMAT.COMPRESSED_RGBA_S3TC_DXT5_EXT; - -/* WEB WORKER */ - -BasisTextureLoader.BasisWorker = function () { - - var config; - var transcoderPending; - var _BasisFile; - - onmessage = function ( e ) { - - var message = e.data; - - switch ( message.type ) { - - case 'init': - config = message.config; - init( message.transcoderBinary ); - break; - - case 'transcode': - transcoderPending.then( () => { - - try { - - var { width, height, hasAlpha, mipmaps, format } = transcode( message.buffer ); - - var buffers = []; - - for ( var i = 0; i < mipmaps.length; ++ i ) { - - buffers.push( mipmaps[ i ].data.buffer ); - - } - - self.postMessage( { type: 'transcode', id: message.id, width, height, hasAlpha, mipmaps, format }, buffers ); - - } catch ( error ) { - - console.error( error ); - - self.postMessage( { type: 'error', id: message.id, error: error.message } ); - - } - - } ); - break; - - } - - }; - - function init( wasmBinary ) { - - var BasisModule; - transcoderPending = new Promise( ( resolve ) => { - - BasisModule = { wasmBinary, onRuntimeInitialized: resolve }; - BASIS( BasisModule ); // eslint-disable-line no-undef - - } ).then( () => { - - var { BasisFile, initializeBasis } = BasisModule; - - _BasisFile = BasisFile; - - initializeBasis(); - - } ); - - } - - function transcode( buffer ) { - - var basisFile = new _BasisFile( new Uint8Array( buffer ) ); - - var width = basisFile.getImageWidth( 0, 0 ); - var height = basisFile.getImageHeight( 0, 0 ); - var levels = basisFile.getNumLevels( 0 ); - var hasAlpha = basisFile.getHasAlpha(); - - function cleanup() { - - basisFile.close(); - basisFile.delete(); - - } - - if ( ! hasAlpha ) { - - switch ( config.format ) { - - case 9: // Hardcoded: BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGBA - config.format = 8; // Hardcoded: BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGB; - break; - - } - - } - - if ( ! width || ! height || ! levels ) { - - cleanup(); - throw new Error( 'THREE.BasisTextureLoader: Invalid .basis file' ); - - } - - if ( ! basisFile.startTranscoding() ) { - - cleanup(); - throw new Error( 'THREE.BasisTextureLoader: .startTranscoding failed' ); - - } - - var mipmaps = []; - - for ( var mip = 0; mip < levels; mip ++ ) { - - var mipWidth = basisFile.getImageWidth( 0, mip ); - var mipHeight = basisFile.getImageHeight( 0, mip ); - var dst = new Uint8Array( basisFile.getImageTranscodedSizeInBytes( 0, mip, config.format ) ); - - var status = basisFile.transcodeImage( - dst, - 0, - mip, - config.format, - 0, - hasAlpha - ); - - if ( ! status ) { - - cleanup(); - throw new Error( 'THREE.BasisTextureLoader: .transcodeImage failed.' ); - - } - - mipmaps.push( { data: dst, width: mipWidth, height: mipHeight } ); - - } - - cleanup(); - - return { width, height, hasAlpha, mipmaps, format: config.format }; - - } - -}; - -function _optionalChain$3(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } -class DemoBasisLoader extends Demo { - - - - async init() { - const geometry = new BoxBufferGeometry(200, 200, 200); - const material = new MeshBasicMaterial(); - this.mesh = new Mesh(geometry, material); - this.loader = new BasisTextureLoader(); - - this.loader.setTranscoderPath(baseUrl + '/js/libs/basis/'); - this.loader.detectSupport(this.deps.renderer); - this.loader.setWorkerLimit(1); - const texture = await this.loader.loadAsync( - baseUrl + '/textures/compressed/PavingStones.basis', - ); - texture.encoding = sRGBEncoding; - material.needsUpdate = true; - this.mesh.material.map = texture; - - this.deps.camera.position.z = 500; - this.deps.scene.add(this.mesh); - } - - update() { - const delta = this.deps.clock.getDelta() * 0.5; - - this.mesh.rotation.x += delta; - this.mesh.rotation.y += delta; - } - - dispose() { - this.reset(); - this.deps.scene.remove(this.mesh); - _optionalChain$3([this, 'access', _ => _.mesh, 'access', _2 => _2.material, 'optionalAccess', _3 => _3.dispose, 'call', _4 => _4()]); - } -} - -function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$4(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } +function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$3(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } class ThreeSpritePlayer { __init() {this.currFrame = 0;} @@ -56792,7 +56223,7 @@ class ThreeSpritePlayer { } dispose() { - _optionalChain$4([this, 'access', _ => _.mesh, 'optionalAccess', _2 => _2.material, 'access', _3 => _3.dispose, 'call', _4 => _4()]); + _optionalChain$3([this, 'access', _ => _.mesh, 'optionalAccess', _2 => _2.material, 'access', _3 => _3.dispose, 'call', _4 => _4()]); this.tiles.forEach(texture => texture.dispose()); this.tiles.length = 0; this.mesh = null; @@ -57072,10 +56503,10 @@ class DemoDeviceOrientationControls extends Demo { } } -function _optionalChain$5(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// index.ts +function _optionalChain$4(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// index.ts const DEMO_MAP = { - BasisLoader: DemoBasisLoader, + // BasisLoader: DemoBasisLoader, OBJLoader: DemoOBJLoader, SVGLoader: DemoSVGLoader, RGBELoader: DemoRGBELoader, @@ -57103,9 +56534,9 @@ Page({ 'RGBELoader', 'SVGLoader', 'OBJLoader', - 'BasisLoader', - 'Raycaster', - 'Geometry' + 'BasisLoader(TODO)', + 'Raycaster(TODO)', + 'Geometry(TODO)' ] }, @@ -57145,7 +56576,7 @@ Page({ const render = () => { if (this.disposing) return $requestAnimationFrame(render); - _optionalChain$5([(this.currDemo ), 'optionalAccess', _ => _.update, 'call', _2 => _2()]); + _optionalChain$4([(this.currDemo ), 'optionalAccess', _ => _.update, 'call', _2 => _2()]); renderer.render(scene, camera); }; @@ -57165,12 +56596,14 @@ Page({ }, async onMenuItemClick(e) { - if (this.switchingItem) return - _optionalChain$5([(this.currDemo ), 'optionalAccess', _3 => _3.dispose, 'call', _4 => _4()]); + const { i, item } = e.currentTarget.dataset; + + if (this.switchingItem || !DEMO_MAP[item]) return + + _optionalChain$4([(this.currDemo ), 'optionalAccess', _3 => _3.dispose, 'call', _4 => _4()]); this.switchingItem = true; this.currDemo = null ; - const { i, item } = e.currentTarget.dataset; const demo = new (DEMO_MAP[item])(this.deps) ; await demo.init(); this.currDemo = demo; @@ -57193,7 +56626,7 @@ Page({ onUnload() { this.disposing = true; - _optionalChain$5([(this.currDemo ), 'optionalAccess', _5 => _5.dispose, 'call', _6 => _6()]); + _optionalChain$4([(this.currDemo ), 'optionalAccess', _5 => _5.dispose, 'call', _6 => _6()]); PLATFORM.dispose(); } }); diff --git a/miniprogram/pages/index/index.ts b/miniprogram/pages/index/index.ts index 325c1bd..5b60a15 100644 --- a/miniprogram/pages/index/index.ts +++ b/miniprogram/pages/index/index.ts @@ -2,10 +2,10 @@ import { $requestAnimationFrame as requestAnimationFrame, $window as window, Clock, PerspectiveCamera, PLATFORM, Scene, sRGBEncoding, TextureLoader, WebGL1Renderer } from 'three-platformize' import { WechatPlatform } from 'three-platformize/src/WechatPlatform' import { GLTFLoader } from 'three-platformize/examples/jsm/loaders/GLTFLoader' -import { DemoDeps, Demo, DemoGLTFLoader, DemoThreeSpritePlayer, DemoDeviceOrientationControls, DemoRGBELoader, DemoSVGLoader, DemoOBJLoader, DemoBasisLoader } from 'three-platformize-demo/src/index' +import { DemoDeps, Demo, DemoGLTFLoader, DemoThreeSpritePlayer, DemoDeviceOrientationControls, DemoRGBELoader, DemoSVGLoader, DemoOBJLoader } from 'three-platformize-demo/src/index' const DEMO_MAP = { - BasisLoader: DemoBasisLoader, + // BasisLoader: DemoBasisLoader, OBJLoader: DemoOBJLoader, SVGLoader: DemoSVGLoader, RGBELoader: DemoRGBELoader, @@ -33,9 +33,9 @@ Page({ 'RGBELoader', 'SVGLoader', 'OBJLoader', - 'BasisLoader', - 'Raycaster', - 'Geometry' + 'BasisLoader(TODO)', + 'Raycaster(TODO)', + 'Geometry(TODO)' ] }, @@ -95,12 +95,14 @@ Page({ }, async onMenuItemClick(e) { - if (this.switchingItem) return + const { i, item } = e.currentTarget.dataset; + + if (this.switchingItem || !DEMO_MAP[item]) return + (this.currDemo as Demo)?.dispose(); this.switchingItem = true; this.currDemo = null as unknown as Demo; - const { i, item } = e.currentTarget.dataset; const demo = new (DEMO_MAP[item])(this.deps) as Demo; await demo.init(); this.currDemo = demo;