①构建三维坐标,代码如下
<!-- -->
<template>
<div id="container"></div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import * as THREE from "three";
import { OBJLoader, MTLLoader } from "three-obj-mtl-loader";
const OrbitControls = require("three-orbit-controls")(THREE);
import Stats from "stats-js";
export default {
//import引入的组件需要注入到对象中才能使用
components: { THREE, OBJLoader, MTLLoader, OrbitControls, Stats },
props: {},
data() {
//这里存放数据
return {};
},
//监听属性 类似于data概念
computed: {},
//监控data中的数据变化
watch: {},
//方法集合
methods: {
init() {
var scene, camera, renderer, controls;
scene = initScene();
renderScene();
// 控制器,监听鼠标事件
function renderScene() {
renderer.render(scene, camera);
}
// 场景自适应
window.addEventListener("resize", onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function initScene() {
// 创建场景
var scene = new THREE.Scene();
// 创建相机
camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.01,
1000
);
//创建渲染器
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff, 0);
renderer.setPixelRatio(window.devicePixelRatio);
document.getElementById("container").appendChild(renderer.domElement);
// 创建坐标轴
var axes = new THREE.AxesHelper(100);
scene.add(axes);
camera.position.x = 1.8;
camera.position.y = 0.6;
camera.position.z = 2.7;
camera.lookAt(scene.position);
scene.add(camera);
// 控制器,监听鼠标事件
controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", renderScene);
return scene;
}
},
animate() {},
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {
this.init();
},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style scoped>
</style>
②加载obj文件
// 创建objLoader对象
var loader = new OBJLoader();
loader.load("../../static/536.obj", function (obj) { // 调用OBJ的loader函数,加载成功会有个回调函数,参数obj就是模型加载成功后的网格Mesh实例对象
scene.add(obj);
// 页面加载成功后没有立即渲染模型,调用立即渲染函数
renderScene();
});
③未看见模型,原因:未设置光源,因此,设置光源
④ 设置网格对象的参数
// 创建objLoader对象
var loader = new OBJLoader();
loader.load("../../static/536.obj", function (obj) { // 调用OBJ的loader函数,加载成功会有个回调函数,参数obj就是模型加载成功后的网格Mesh实例对象
// 调试发现模型会在y轴上方的,我们希望在y轴的下方一些
// 网格模型按xyz进行放缩
obj.scale.set(2,2,2);
obj.position.y = -65;
obj.position.x = -1045;
obj.position.z = -50;
// 几何体绕着x轴旋转45度
obj.rotateX(Math.PI / 6);
scene.add(obj);
// 页面加载成功后没有立即渲染模型,调用立即渲染函数
renderScene();
});
⑤贴图
// 给模型穿衣服,加载uv网格图片,以下代码写在模型加载上面
const textureLoader = new THREE.TextureLoader();
// 下载地址:https://github.com/mrdoob/three.js/blob/master/examples/textures/uv_grid_opengl.jpg
console.log("texture对象初始化成功");
// 创建objLoader对象
var loader = new OBJLoader();
loader.load("../../static/536.obj", function (obj) {
// 调用OBJ的loader函数,加载成功会有个回调函数,参数obj就是模型加载成功后的网格Mesh实例对象
// 调试发现模型会在y轴上方的,我们希望在y轴的下方一些
// 遍历子网格
obj.traverse(function (child) {
if (child.isMesh) {
// 纹理设置
console.log("遍历子网格");
child.material.map = texture;
}
});
// 网格模型按xyz进行放缩
obj.scale.set(2, 2, 2);
obj.position.y = -65;
obj.position.x = -1045;
obj.position.z = -50;
// 几何体绕着x轴旋转45度
obj.rotateX(Math.PI / 6);
scene.add(obj);
// 页面加载成功后没有立即渲染模型,调用立即渲染函数
renderScene();
});
⑥管理器
初始化管理器
// 配置加载管理器类,获取加载进度和是否加载出错
const manager = new THREE.LoadingManager();
// 参数1:正在加载的模型,参数2:已经加载的模型 参数3:总的模型数量
manager.onProgress = function(item,loaded,total){
console.log(item,loaded,total);
}
预先定义一个存放OBJ模型的变量
// 预先定义一个存放OBJ模型的变量
var object;
编写一个模型加载完成 callback函数
// 编写一个模型加载完成 callback函数
function loadModel(){
// 遍历子网格
object.traverse(function (child) {
if (child.isMesh) {
// 纹理设置
console.log("遍历子网格");
child.material.map = texture;
}
});
// 网格模型按xyz进行放缩
object.scale.set(2, 2, 2);
object.position.y = -65;
object.position.x = -1045;
object.position.z = -50;
// 几何体绕着x轴旋转45度
object.rotateX(Math.PI / 6);
scene.add(object);
// 页面加载成功后没有立即渲染模型,调用立即渲染函数
renderScene();
}
loader.load('obj文件路径',function(obj)->{
object=obj;
});
将loadModel传递给LoadingManager的构造函数中
// 将loadModel传递给LoadingManager的构造函数中
const manager = new THREE.LoadingManager(loadModel);
将manager作为纹理和模型加载器的构造函数中
// 将manager作为纹理和模型加载器的构造函数中
const textureLoader = new THREE.TextureLoader(manager);
var loader =new OBJLoader(manager);
控制台查看manager是否打印,将遍历子网格的方法注释掉暂时用不到
⑥加载mtl文件
// 创建加载mtl的对象,manager作为参数传入
var mtlLoader = new MTLLoader(manager);
// 加载mtl 文件 ,参数1: mtl文件路径 , 参数2:回调函数
mtlLoader.load('./male02/male02.mtl',function(materials){
// 调用预加载函数,作用: 让浏览器提前加载指定资源(加载后并不执行),在需要执行的时候再执行
materials.preload();
})
声明一个变量用于存储加载好的材质实例
// 声明一个变量用于存储加载好的材质实例
var mat;
mtlLoader.load('./male02/male02.mtl',function(materials){
// 调用预加载函数,作用: 让浏览器提前加载指定资源(加载后并不执行),在需要执行的时候再执行
materials.preload();
mat=materials;
})
载入模型材质
// 创建加载mtl的对象,manager作为参数传入
var mtlLoader = new MTLLoader(manager);
// 加载mtl 文件 ,参数1: mtl文件路径 , 参数2:回调函数
mtlLoader.load("../../static/536.mtl", function (materials) {
// 调用预加载函数,作用: 让浏览器提前加载指定资源(加载后并不执行),在需要执行的时候再执行
materials.preload();
mat = materials;
// 创建objLoader对象
var loader = new OBJLoader(manager);
loader.setMaterials(mat);
loader.load("../../static/536.obj", function (obj) {
object = obj;
},onProgress,onError);
});
定义onproces函数用于显示模型的加载进度和加载出错函数
// 定义onproces函数用于显示模型的加载进度
function onProgress(xhr) {
//做一个判断,如果获取到模型信息就控制台输出一个模型进度
if (xhr.lengthComputable) {
const percentComplete = (xhr.loaded / xhr.total) * 100;
console.log(
"model " + Math.round(percentComplete, 2) + "% downloaded"
);
}
}
// 加载出错的函数,暂不编写
function onError() {}
作为加载obj文件回调函数的参数