UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

115 lines (108 loc) 4.24 kB
import {LIBRARY_INSTALL_HINT} from './../common'; import {Object3D} from 'three'; import {Poly} from '../../../engine/Poly'; import {DRACOLoader} from 'three/examples/jsm/loaders/DRACOLoader'; import {GLTFLoader, GLTF} from 'three/examples/jsm/loaders/GLTFLoader'; import {BaseLoaderLoadOptions, CoreBaseLoader} from '../_Base'; import {BaseGeoLoader, BaseObject3DLoaderHandler} from './_BaseLoaderHandler'; import {KTX2TextureLoader} from '../texture/KTX2'; import {KTX2Loader} from 'three/examples/jsm/loaders/KTX2Loader'; import {sanitizeUrl} from '../../UrlHelper'; interface GLTFLoaderLoadOptions extends BaseLoaderLoadOptions { draco: boolean; ktx2: boolean; } export class GLTFLoaderHandler extends BaseObject3DLoaderHandler<GLTF> { // private _gltfLoader: GLTFLoader | undefined; private _gltfdracoLoader: GLTFLoader | undefined; private _ktx2gltfLoader: GLTFLoader | undefined; private _ktx2gltfdracoLoader: GLTFLoader | undefined; // private _dracoLoader: DRACOLoader | undefined; private _ktx2Loader: KTX2Loader | undefined; override reset() { super.reset(); this._dracoLoader?.dispose(); this._gltfLoader = undefined; this._gltfdracoLoader = undefined; this._dracoLoader = undefined; this._ktx2Loader = undefined; } override async load(options: GLTFLoaderLoadOptions): Promise<Object3D[] | undefined> { return super.load(options); } protected async _getLoader(options: GLTFLoaderLoadOptions): Promise<BaseGeoLoader<GLTF>> { if (options.ktx2) { if (options.draco) { return (this._ktx2gltfdracoLoader = this._ktx2gltfdracoLoader || (await this._createGLTFLoader(options))); } else { return (this._ktx2gltfLoader = this._ktx2gltfLoader || (await this._createGLTFLoader(options))); } } else { if (options.draco) { return (this._gltfdracoLoader = this._gltfdracoLoader || (await this._createGLTFLoader(options))); } else { return (this._gltfLoader = this._gltfLoader || (await this._createGLTFLoader(options))); } } } private async _createGLTFLoader(options: GLTFLoaderLoadOptions) { const loader = new GLTFLoader(this.loadingManager); if (options.draco) { await this._setupDRACO(loader, options); } if (options.ktx2) { await this._setupKTX2(loader, options); } return loader; } // private async _createGLTFLoaderWithDRACO(options: BaseLoaderLoadOptions) { // const loader = new GLTFLoader(this.loadingManager); // await this._setupDRACO(loader, options); // await this._setupKTX2(loader, options); // return loader; // } private async _setupDRACO(gltfLoader: GLTFLoader, options: BaseLoaderLoadOptions) { this._dracoLoader = this._dracoLoader || (await this._createDRACOLoader(options)); gltfLoader.setDRACOLoader(this._dracoLoader); } protected async _setupKTX2(gltfLoader: GLTFLoader, options: BaseLoaderLoadOptions) { this._ktx2Loader = this._ktx2Loader || (await KTX2TextureLoader.getLoader(options)); gltfLoader.setKTX2Loader(this._ktx2Loader); } private async _createDRACOLoader(options: BaseLoaderLoadOptions) { const useJS = false; const node = options.node; const dracoLoader = new DRACOLoader(this.loadingManager); const root = Poly.libs.root(); const DRACOGLTFPath = Poly.libs.DRACOGLTFPath(); if (root || DRACOGLTFPath) { const decoderPath = sanitizeUrl(`${root || ''}${DRACOGLTFPath || ''}/`); const timestamp = Date.now(); const files = useJS ? ['draco_decoder.js'] : ['draco_decoder.wasm', 'draco_wasm_wrapper.js']; await CoreBaseLoader._loadMultipleUrlsGlobal({ files: files.map((file) => { return { fullUrl: `${decoderPath}${file}?t=${timestamp}`, }; }), node, error: `failed to load draco libraries. Make sure to install them to load .glb files (${LIBRARY_INSTALL_HINT})`, }); dracoLoader.setDecoderPath(decoderPath); } else { (dracoLoader as any).setDecoderPath(undefined); } // not having this uses wasm if the relevant libraries are found dracoLoader.setDecoderConfig({type: useJS ? 'js' : 'wasm'}); dracoLoader.preload(); return dracoLoader; } protected override _onLoadSuccess(gltf: GLTF): Object3D[] { const scene = gltf.scene || gltf.scenes[0]; scene.animations = gltf.animations; return [scene]; } }