import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'; import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader'; import BaseModel from '../BaseModel'; import type Viewer from '../Viewer'; type LoadModelCallbackFn = (arg: T) => any; type arrUrl = {mtlUrl:string,objUrl:string}; const publicPath = `${import.meta.env.VITE_PUBLIC_BASE_PATH || ''}` /**模型加载器 */ export default class ModelLoder { protected viewer: Viewer; private gltfLoader: GLTFLoader; private dracoLoader: DRACOLoader; constructor(viewer: Viewer, dracolPath: string = `${publicPath}/draco/`) { this.viewer = viewer; this.gltfLoader = new GLTFLoader(); this.dracoLoader = new DRACOLoader(); // 提供一个DracLoader实例来解码压缩网格数据 // 没有这个会报错 dracolPath 默认放在public文件夹当中 this.dracoLoader.setDecoderPath(dracolPath); this.gltfLoader.setDRACOLoader(this.dracoLoader); } /**模型加载到场景 */ public loadModelToScene(url: string, callback: LoadModelCallbackFn) { const publicUrl = `${publicPath}${url}`; this.loadModel(publicUrl, model => { this.viewer.scene.add(model.object); callback && callback(model); }); } public ladObjModelToScene(url: arrUrl, callback: LoadModelCallbackFn) { this.loadObjModel(url, model => { this.viewer.scene.add(model); callback && callback(model); }); } private loadModel(url: string, callback: LoadModelCallbackFn) { this.gltfLoader.load(url, gltf => { const baseModel = new BaseModel(gltf, this.viewer); callback && callback(baseModel); }); } private loadObjModel(url: arrUrl, callback: LoadModelCallbackFn) { const objLoader = new OBJLoader(); const mtlLoader = new MTLLoader(); const publicMtlUrl = `${publicPath}${url.mtlUrl}`; const publicObjUrl = `${publicPath}${url.objUrl}`; mtlLoader.load(publicMtlUrl, materials => { materials.preload(); objLoader.setMaterials(materials); objLoader.load(publicObjUrl, obj => { callback && callback(obj); }); }); } }