前期爬过的坑
关于obj文件的读取肯定是用到一个构造函数OBJLoader,然而他并不在three.js里面,vue中只是 import * as THREE from 'three'是远远不够的,然而我们如何引用OBJLoader?去官方文档没有给出明确,但是官方给了示例:
可引入的示例
three.js的核心专注于实现3D引擎中最为重要的组件。其他诸如加载器和控制器等组件,是示例文件夹中的一部分。 three.js确保这些文件能够与核心保持同步,但如果在一个项目中这些组件是必要的,用户将必须分别地引入它们。 你可以在examples/jsm文件夹中找到所有示例文件的ES6版本。 如果你是通过npm来安装three.js的,那么你可以使用类似下面的代码来引入它们:
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
请注意:当你在使用来自示例(examples)文件夹中的代码时,其中的所有文件和你的three.js主文件版本相匹配是很重要的。 比如说,three.js的R103版本不能够接受和来自R96版本的GLTFLoader和OrbitControls一起使用。
在这里吐槽一下官方文档,对刚接触three.js的同学实在是不太友好,文档和实例分离实在是难搞;这一块我一开始没找到,后来看源码试出来的。所以这里看出认真阅读文档的重要性,哈哈哈。
然后现在版本的three.js(目前是0.113.2)根本基本上不需要three相关的插件包(three-orbit-controls、three-obj-mtl-loader等等),需要用到哪个函数直接引用就可以了。如下:
import * as THREE from 'three'
import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader'
import {MTLLoader} from 'three/examples/jsm/loaders/MTLLoader'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
导入一个obj文件
<template>
<div class="main-view">
<div id="demo2" style="width: 100%;height: 100%"></div>
<el-button class="refresh-btn" @click="refreshView()">刷新视图</el-button>
<div class="add-btn-view">
<el-button type="primary" @click="addObj()">添加模型</el-button>
</div>
</div>
</template>
<script>
import * as THREE from 'three'
import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader'
import {MTLLoader} from 'three/examples/jsm/loaders/MTLLoader'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
export default {
data() {
return {
camera: null,
scene: null,
renderer: null,
}
},
mounted() {
this.LOG.info(['THREE.REVISION -- ', THREE.REVISION]);
this.init();
},
methods: {
init() {
this.scene = new THREE.Scene();
const container = document.getElementById('demo2');
const width = container.clientWidth;
const height = container.clientHeight;
this.camera = new THREE.PerspectiveCamera(75, width / height, 1, 1000);
this.camera.position.z = 250;
this.renderer = new THREE.WebGLRenderer({antialias: true});
this.renderer.setSize(width, height);
container.appendChild(this.renderer.domElement);
},
refreshView() {
const container = document.getElementById('demo2');
const width = container.clientWidth;
const height = container.clientHeight;
// this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();
this.renderer.setSize(width, height)
},
render() {
this.renderer.render(this.scene, this.camera)
},
addObj() {
const loader = new OBJLoader();
let material = new THREE.MeshBasicMaterial({color: 'gray', side: THREE.DoubleSide});
loader.load('./objs/demo2/male02.obj', obj => {
this.LOG.info(['objs/demo2/male02.obj', obj]);
obj.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = material;
}
});
this.scene.add(obj);
this.render();
}, xhr => {
this.LOG.warn(['obj -- ', xhr.loaded / xhr.total * 100, ' %']);
}, error => {
this.LOG.error(['obj error-- ', error]);
})
}
}
}
</script>
<style scoped>
.refresh-btn {
position: absolute;
top: 15px;
right: 15px;
}
.add-btn-view {
position: absolute;
bottom: 15px;
left: 15px;
}
</style>
{{ cmt.username }}
{{ cmt.content }}
{{ cmt.commentDate | formatDate('YYYY.MM.DD hh:mm') }}