threejs 加载各种格式的3d模型 封装
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
import { LoadingManager } from 'three';
import { Message } from 'element-ui';
import Vue from 'vue';
let loading;
/**
* 加载.obj模型文件
* @param {String} objUrl
* @returns
*/
export function onlyObjloader(objUrl) {
loading = Vue.prototype.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)',
});
return new Promise((resolve) => {
// 初始化obj
var objLoader = new OBJLoader();
objLoader.load(
objUrl,
(obj) => {
resolve({ obj });
setTimeout(() => {
loading.close();
}, 500);
},
(rate) => {},
(err) => {
console.log(err);
Message({
message: `加载失败: ${err.message}`,
type: 'error',
duration: 3000,
});
setTimeout(() => {
loading.close();
}, 500);
}
);
});
}
/**
* 加载.obj和.mtl模型文件
* @param {String} mtlUrl
* @param {String} objUrl
* @returns
*/
export function objloader(mtlUrl, objUrl) {
loading = Vue.prototype.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)',
});
return new Promise((resolve) => {
var mtlLoader = new MTLLoader();
// 初始化obj
var objLoader = new OBJLoader();
// 加载mtl文件
mtlLoader.load(
mtlUrl,
(mtl) => {
// 初始化
mtl.preload();
// 加载贴图
objLoader.setMaterials(mtl);
objLoader.load(
objUrl,
(obj) => {
resolve({ mtl, obj });
setTimeout(() => {
loading.close();
}, 500);
},
() => {},
(err) => {
console.log(err);
Message({
message: `加载失败: ${err.message}`,
type: 'error',
duration: 3000,
});
setTimeout(() => {
loading.close();
}, 500);
}
);
},
() => {},
(err) => {
Message({
message: `加载失败: ${err.message}`,
type: 'error',
duration: 3000,
});
setTimeout(() => {
loading.close();
}, 500);
}
);
});
}
/**
* 加载.fbx文件
* @param {*} fbxUrl
* @returns
*/
export function fbxloader(fbxUrl) {
loading = Vue.prototype.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)',
});
return new Promise((resolve) => {
var loader = new FBXLoader();
loader.load(
fbxUrl,
(fbx) => {
resolve(fbx);
setTimeout(() => {
loading.close();
}, 500);
},
() => {},
(err) => {
console.log(err);
Message({
message: `加载失败: ${err.message}`,
type: 'error',
duration: 3000,
});
setTimeout(() => {
loading.close();
}, 500);
}
);
});
}
/**
* 加载.gtlf或.glb文件
* @param {String} path
* @returns
*/
export function gltfloader(path) {
loading = Vue.prototype.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)',
});
return new Promise((resolve) => {
var loader = new GLTFLoader();
loader.load(
path,
(gltf) => {
resolve(gltf);
setTimeout(() => {
loading.close();
}, 500);
},
() => {},
(err) => {
console.log(err);
Message({
message: `加载失败: ${err.message}`,
type: 'error',
duration: 3000,
});
setTimeout(() => {
loading.close();
}, 500);
}
);
});
}
/**
* 使用dracoLoader 加载.gtlf或.glb文件
* @param {String} path
* @returns
*/
export function dracoLoader(path) {
loading = Vue.prototype.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)',
});
return new Promise((resolve) => {
const loader = new GLTFLoader(new LoadingManager()); //实时显示进度
const dracoLoader = new DRACOLoader();
/*
- 设置在线路径: dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.6/');
- 设置本地路径: 将node_modules文件夹下three库中的draco_decoder.js文件复制到/public/three/decoder 文件夹下
*/
dracoLoader.setDecoderPath('/three/decoder/');
dracoLoader.setDecoderConfig({ type: 'js' }); //使用js方式解压
dracoLoader.preload(); //初始化_initDecoder 解码器
loader.setDRACOLoader(dracoLoader); //gltfloader使用dracoLoader
loader.load(
path,
(gltf) => {
resolve(gltf);
setTimeout(() => {
loading.close();
}, 500);
},
() => {},
(err) => {
console.log(err);
Message({
message: `加载失败: ${err.message}`,
type: 'error',
duration: 3000,
});
setTimeout(() => {
loading.close();
}, 500);
}
);
});
}