文章目录
- 需求
- 分析
需求
导入fbx 格式的模型数据
分析
- 需要准备 fbx 格式的数据,如下所示
<template><div id="three-canvas" />
</template>
<script>
// import { Color, MOUSE, PerspectiveCamera, Scene, WebGLRenderer } from "three";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { DRACOLoader, AmbientLight, Color, MOUSE, PerspectiveCamera, Scene, Vector3, WebGLRenderer, MeshLambertMaterial, sRGBEncoding } from 'three'
import * as Three from 'three' // 引入Threejs
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
export default {name: 'LoadFBX',data () {return {camera: null, // 相机对象scene: null, // 场景对象renderer: null, // 渲染器对象mesh: null // 网格模型对象Mesh}},mounted () {this.init()this.$nextTick(() => {this.createModel()})},methods: {onClick (event) {// 创建 Raycaster 对象var raycaster = new Three.Raycaster()const mouse = new Three.Vector2()// 计算鼠标或触摸点的位置mouse.x = (event.clientX / window.innerWidth) * 2 - 1mouse.y = -(event.clientY / window.innerHeight) * 2 + 1// 更新射线 注意——> this.camera 是相机 定义到data里的raycaster.setFromCamera(mouse, this.camera)// 计算与所有对象的交点const intersects = raycaster.intersectObjects(this.scene.children, true)if (intersects.length > 0) {// 处理点击事件// intersects[0] 包含了第一个交点const clickedObject = intersects[0].objectconsole.log(clickedObject.geometry.uuid)// 通过点击到该模型用名字匹配if (clickedObject.name === clickedObject.name) {// console.log("获取的当前模型信息:", clickedObject, clickedObject.name);}}},// 模型点击onMouseClick (event) {var raycaster = new Three.Raycaster()var mouse = new Three.Vector2()// 将鼠标点击位置的屏幕坐标转换成threejs中的标准坐标mouse.x = (event.clientX / window.innerWidth) * 2 - 1mouse.y = (event.clientY / window.innerHeight) * 2 + 1// 通过鼠标点的位置和当前相机的矩阵计算出raycasterraycaster.setFromCamera(mouse, this.camera)// 获取raycaster直线和所有模型相交的数组集合var intersects = raycaster.intersectObjects(this.scene.children)console.log(raycaster)console.log(this.scene.children)// 将所有的相交的模型的颜色设置为红色for (var i = 0; i < intersects.length; i++) {intersects[i].object.material.color.set(0xff0000)}},// 模型加载loadGltf () {const loader = new FBXLoader()loader.load('/static/obj/daba1.fbx', (gltf) => {gltf.rotateY(Math.PI / 2)this.scene.add(gltf)this.renderer.render(this.scene, this.camera)window.addEventListener('click', this.onClick, false)}, (xhr) => {console.log((xhr.loaded / xhr.total) * 100 + '% loaded')this.scene.traverse(function (object) {console.log(101, object.name, object.type)})}, (error) => {console.error(error)})},createModel () {const that = this// 渲染进度const onProgress = function (xhr) {if (xhr.lengthComputable) {const percentComplete = xhr.loaded / xhr.total * 100console.log(Math.round(percentComplete, 2) + '% downloaded')}}this.loadGltf()},init () {const container = document.getElementById('three-canvas')this.renderer = new WebGLRenderer({// 开启抗锯齿antialias: true})// 将渲染器挂载到domcontainer.appendChild(this.renderer.domElement)this.renderer.outputEncoding = sRGBEncodingthis.renderer.setSize(container.offsetWidth, 355, true)// 实例化场景this.scene = new Scene()this.scene.background = new Color('rgba(189, 189, 189, 0.6)')// 实例化相机this.camera = new PerspectiveCamera(75, container.offsetWidth / 355, 1, 1000)// 设置相机位置this.camera.position.set(50, 250, 50)// 设置相机看先中心点this.camera.lookAt(new Vector3(0, 0, 0))// 设置相机自身方向this.camera.up = new Vector3(0, 1, 0)// 初始化轨道控制器const orbitControls = new OrbitControls(this.camera, this.renderer.domElement)// 设置鼠标功能键orbitControls.mouseButtons = {// 左键无功能LEFT: MOUSE.ROTATE,// 中键缩放MIDDLE: MOUSE.DOLLY// 右键旋转// RIGHT: MOUSE.ROTATE}// 添加环境光const ambientLight = new AmbientLight('rgb(255,255,255)', 0.8)this.scene.add(ambientLight)const animate = () => {this.renderer.render(this.scene, this.camera)requestAnimationFrame(animate)}animate()}}
}
</script>
<style scoped>
#three-canvas {/* width: 100%; *//* height: 600px; *//* overflow: hidden; *//* background-color: #88B9DD; */
}
</style>