author Yannick Deubel (https://github.com/yandeu)
 *  copyright license https import { Cache , FileLoader , Group , ImageLoader , ObjectLoader , Texture , TextureLoader } from 'three' ; import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader' ; import { GLTF , GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' ; import { SVGLoader , SVGResult } from 'three/examples/jsm/loaders/SVGLoader' ; import type { Atlas , JSONArrayFrames , JSONHash } from '../flat/textureAtlas' ; export default class Loaders { private _fileLoader ! : FileLoader ; private _imgLoader ! : ImageLoader ; private _svgLoader ! : SVGLoader ; private _textureLoader ! : TextureLoader ; private _objectLoader ! : ObjectLoader ; private _gltfLoader ! : GLTFLoader ; private _fbxLoader ! : FBXLoader ; constructor ( private cache , private textureAnisotropy ) { } private get fileLoader ( ) { if ( ! this . _fileLoader ) this . _fileLoader = new FileLoader ( ) ; return this . _fileLoader ; } private get imageLoader ( ) { if ( ! this . _imgLoader ) this . _imgLoader = new ImageLoader ( ) ; return this . _imgLoader ; } private get svgLoader ( ) { if ( ! this . _svgLoader ) this . _svgLoader = new SVGLoader ( ) ; return this . _svgLoader ; } private get textureLoader ( ) { if ( ! this . _textureLoader ) this . _textureLoader = new TextureLoader ( ) ; return this . _textureLoader ; } private get objectLoader ( ) { if ( ! this . _objectLoader ) this . _objectLoader = new ObjectLoader ( ) ; return this . _objectLoader ; } private get gltfLoader ( ) { if ( ! this . _gltfLoader ) this . _gltfLoader = new GLTFLoader ( ) ; return this . _gltfLoader ; } private get fbxLoader ( ) { if ( ! this . _fbxLoader ) this . _fbxLoader = new FBXLoader ( ) ; return this . _fbxLoader ; } public async preload ( key , url ) { this . cache . add ( key , url ) ; return new Promise ( resolve => { const isModel = /\.fbx$|\.glb$|\.gltf$/ . test ( url ) ; const isTexture = /\.jpe?g$|\.png$/ . test ( url ) ; if ( isTexture ) { this . textureLoader . load ( url , texture => { return resolve ( texture ) ; } ) ; } else { if ( isModel ) this . fileLoader . setResponseType ( 'arraybuffer' ) ; this . fileLoader . load ( url , file => { return resolve ( file ) ; } ) ; } } ) ; } public async textureAtlas ( texture , json , _type = 'JSONHash' ) { let parsed = JSON . parse ( ( await this . file ( json ) ) as any ) ; const isJSONArray = parsed . textures ; if ( isJSONArray ) { const frames = parsed . textures [ 0 ] . frames as JSONArrayFrames ; let jsonHash = { frames : { } } ; frames . forEach ( frame => { jsonHash = { ... jsonHash , frames : { ... jsonHash . frames , [ frame . filename ] : { frame : frame . frame , rotated : frame . rotated , sourceSize : frame . sourceSize , spriteSourceSize : frame . spriteSourceSize , trimmed : frame . trimmed } } } ; } ) ; parsed = jsonHash ; } const atlas = { texture : await this . texture ( texture ) , json : parsed as JSONHash } ; return atlas ; } public file ( url ) { const key = this . cache . get ( url ) ; url = key ? key : url ; return new Promise ( resolve => { this . fileLoader . load ( url , file => { return resolve ( file ) ; } ) ; } ) ; } public svg ( url ) { const key = this . cache . get ( url ) ; url = key ? key : url ; return new Promise ( resolve => { this . svgLoader . load ( url , svg => { return resolve ( svg ) ; } ) ; } ) ; } public texture ( url ) { const isBase64 = /^data:image\/[\S]+;base64,/gm . test ( url ) ; if ( ! isBase64 ) { const key = this . cache . get ( url ) ; url = key ? key : url ; } return new Promise ( resolve => { this . textureLoader . load ( url , ( texture ) => { texture . anisotropy = this . textureAnisotropy ; texture . needsUpdate = true ; resolve ( texture ) ; } ) ; } ) ; } public object ( url ) { const key = this . cache . get ( url ) ; url = key ? key : url ; return new Promise ( resolve => { this . objectLoader . load ( url , ( json ) => { resolve ( json ) ; } ) ; } ) ; } public gltf ( url ) { const key = this . cache . get ( url ) ; url = key ? key : url ; return new Promise ( resolve => { this . gltfLoader . load ( url , ( gltf ) => { resolve ( gltf ) ; } ) ; } ) ; } public fbx ( url ) { const key = this . cache . get ( url ) ; url = key ? key : url ; return new Promise ( resolve => { this . fbxLoader . load ( url , ( fbx ) => { resolve ( fbx ) ; } ) ; } ) ; } }