3d-blog/src/javascript/Utils/Loader.js
2024-01-21 11:21:47 +08:00

145 lines
3.4 KiB
JavaScript

import EventEmitter from './EventEmitter.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
export default class Resources extends EventEmitter
{
/**
* Constructor
*/
constructor()
{
super()
this.setLoaders()
this.toLoad = 0
this.loaded = 0
this.items = {}
}
/**
* Set loaders
*/
setLoaders()
{
this.loaders = []
// Images
this.loaders.push({
extensions: ['jpg', 'png'],
action: (_resource) =>
{
const image = new Image()
image.addEventListener('load', () =>
{
this.fileLoadEnd(_resource, image)
})
image.addEventListener('error', () =>
{
this.fileLoadEnd(_resource, image)
})
image.src = _resource.source
}
})
// Draco
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('draco/')
dracoLoader.setDecoderConfig({ type: 'js' })
this.loaders.push({
extensions: ['drc'],
action: (_resource) =>
{
dracoLoader.load(_resource.source, (_data) =>
{
this.fileLoadEnd(_resource, _data)
DRACOLoader.releaseDecoderModule()
})
}
})
// GLTF
const gltfLoader = new GLTFLoader()
gltfLoader.setDRACOLoader(dracoLoader)
this.loaders.push({
extensions: ['glb', 'gltf'],
action: (_resource) =>
{
gltfLoader.load(_resource.source, (_data) =>
{
this.fileLoadEnd(_resource, _data)
})
}
})
// FBX
const fbxLoader = new FBXLoader()
this.loaders.push({
extensions: ['fbx'],
action: (_resource) =>
{
fbxLoader.load(_resource.source, (_data) =>
{
this.fileLoadEnd(_resource, _data)
})
}
})
}
/**
* Load
*/
load(_resources = [])
{
for(const _resource of _resources)
{
this.toLoad++
const extensionMatch = _resource.source.match(/\.([a-z]+)$/)
if(typeof extensionMatch[1] !== 'undefined')
{
const extension = extensionMatch[1]
const loader = this.loaders.find((_loader) => _loader.extensions.find((_extension) => _extension === extension))
if(loader)
{
loader.action(_resource)
}
else
{
console.warn(`Cannot found loader for ${_resource}`)
}
}
else
{
console.warn(`Cannot found extension of ${_resource}`)
}
}
}
/**
* File load end
*/
fileLoadEnd(_resource, _data)
{
this.loaded++
this.items[_resource.name] = _data
this.trigger('fileEnd', [_resource, _data])
if(this.loaded === this.toLoad)
{
this.trigger('end')
}
}
}