change(board): 优化大兴机场模型展示功能

- 添加了模型拖拽、缩放和自动旋转功能
- 增加了注释,便于理解代码逻辑
boardTest
zch 8 months ago
parent d16a7c08ae
commit 6577b3ac0c

@ -1,5 +1,8 @@
<template> <template>
<div ref="modelContainer" class="model-container"></div> <div ref="modelContainer" class="model-container"
></div>
</template> </template>
<script> <script>
@ -49,6 +52,16 @@ export default {
// OrbitControls // OrbitControls
const controls = new OrbitControls(camera, renderer.domElement); const controls = new OrbitControls(camera, renderer.domElement);
//
controls.enablePan = true;
/* //是否自动旋转
controls.autoRotate = true;*/
//
controls.enableZoom = true;
/* // 使动画循环使用时阻尼或自转 意思是否有惯性
controls.enableDamping = true;*/
// OrbitControls // OrbitControls
controls.target = new THREE.Vector3(-433, 300, -217); controls.target = new THREE.Vector3(-433, 300, -217);
// OrbitControls使 // OrbitControls使
@ -60,6 +73,7 @@ export default {
mtlLoader.load('/model/daxingjichang.mtl', (materials) => { mtlLoader.load('/model/daxingjichang.mtl', (materials) => {
// //
materials.preload(); materials.preload();
// OBJLoader // OBJLoader
const objLoader = new OBJLoader(); const objLoader = new OBJLoader();
// OBJLoader // OBJLoader
@ -71,6 +85,7 @@ export default {
// //
scene.add(object); scene.add(object);
}); });
}); });
camera.position.set(-379.67901969707856, 1591.6047450835238, -1302.6577410405184);// camera.position.set(-379.67901969707856, 1591.6047450835238, -1302.6577410405184);//
@ -80,8 +95,8 @@ export default {
const animate = () => { const animate = () => {
// //
requestAnimationFrame(animate); requestAnimationFrame(animate);
//log便 /* //log观察相机的数据以便于观察相机的位置和角度和其他数
/* console.log(camera);*/ console.log(camera);*/
// //
renderer.render(scene, camera); renderer.render(scene, camera);
}; };

@ -1,340 +1,342 @@
<!--<template>--> <!--
<!-- <div>--> <template>
<!-- <div class="bottomBg">--> <div>
<!-- <div class="item1F" @click="toggle1">1F</div>--> <div class="bottomBg">
<!-- <div class="item2F" @click="toggle2">2F</div>--> <div class="item1F" @click="toggle1">1F</div>
<!-- <div class="item3F" @click="toggle3">3F</div>--> <div class="item2F" @click="toggle2">2F</div>
<!-- <div class="item4F" @click="toggle4">4F</div>--> <div class="item3F" @click="toggle3">3F</div>
<!-- <div class="item5F" @click="toggle5">5F</div>--> <div class="item4F" @click="toggle4">4F</div>
<!-- </div>--> <div class="item5F" @click="toggle5">5F</div>
<!-- <div ref="threeJs" class="app-container">--> </div>
<!-- </div>--> <div ref="threeJs" class="app-container">
<!-- <div ref="modelInfo" class="model" style="display: inline-block">--> </div>
<!-- <Demo ref="modelInfoData"/>--> <div ref="modelInfo" class="model" style="display: inline-block">
<!-- </div>--> <Demo ref="modelInfoData"/>
<!-- <div ref="modelInfo1" class="model">--> </div>
<!-- <Demo ref="modelInfo1Data"/>--> <div ref="modelInfo1" class="model">
<!-- </div>--> <Demo ref="modelInfo1Data"/>
<!-- <div ref="modelInfo2" class="model">--> </div>
<!-- <Demo ref="modelInfo2Data"/>--> <div ref="modelInfo2" class="model">
<!-- </div>--> <Demo ref="modelInfo2Data"/>
<!-- <div ref="modelInfo3" class="model">--> </div>
<!-- <Demo ref="modelInfo3Data"/>--> <div ref="modelInfo3" class="model">
<!-- </div>--> <Demo ref="modelInfo3Data"/>
<!-- <div ref="modelInfo4" class="model">--> </div>
<!-- <Demo ref="modelInfo4Data"/>--> <div ref="modelInfo4" class="model">
<!-- </div>--> <Demo ref="modelInfo4Data"/>
<!-- <div style="position:absolute;top: 0;left: 0;">--> </div>
<!-- <el-input-number v-model="num" @change="handleChange" :step="0.1" label="描述文字"></el-input-number>--> <div style="position:absolute;top: 0;left: 0;">
<!-- <el-select v-model="floor" placeholder="去几楼" @change="toFloor">--> <el-input-number v-model="num" @change="handleChange" :step="0.1" label="描述文字"></el-input-number>
<!-- <el-option--> <el-select v-model="floor" placeholder="去几楼" @change="toFloor">
<!-- label="1楼"--> <el-option
<!-- :value="1"--> label="1楼"
<!-- >--> :value="1"
<!-- </el-option>--> >
<!-- <el-option--> </el-option>
<!-- label="2楼"--> <el-option
<!-- :value="2"--> label="2楼"
<!-- >--> :value="2"
<!-- </el-option>--> >
<!-- <el-option--> </el-option>
<!-- label="3楼"--> <el-option
<!-- :value="3"--> label="3楼"
<!-- >--> :value="3"
<!-- </el-option>--> >
<!-- <el-option--> </el-option>
<!-- label="4楼"--> <el-option
<!-- :value="4"--> label="4楼"
<!-- >--> :value="4"
<!-- </el-option>--> >
<!-- <el-option--> </el-option>
<!-- label="5楼"--> <el-option
<!-- :value="5"--> label="5楼"
<!-- >--> :value="5"
<!-- </el-option>--> >
<!-- </el-select>--> </el-option>
<!-- <el-button type="primary" @click="tuopanReset"></el-button>--> </el-select>
<!-- <el-button type="primary" @click="tuopanOut"></el-button>--> <el-button type="primary" @click="tuopanReset"></el-button>
<!-- <el-button type="primary" @click="removetuopan"></el-button>--> <el-button type="primary" @click="tuopanOut"></el-button>
<!-- <el-button type="primary" @click="toggle">/</el-button>--> <el-button type="primary" @click="removetuopan"></el-button>
<!-- <el-select v-model="tuopanFloor" placeholder="去几楼">--> <el-button type="primary" @click="toggle">/</el-button>
<!-- <el-option--> <el-select v-model="tuopanFloor" placeholder="去几楼">
<!-- label="1楼"--> <el-option
<!-- :value="1"--> label="1楼"
<!-- >--> :value="1"
<!-- </el-option>--> >
<!-- <el-option--> </el-option>
<!-- label="2楼"--> <el-option
<!-- :value="2"--> label="2楼"
<!-- >--> :value="2"
<!-- </el-option>--> >
<!-- <el-option--> </el-option>
<!-- label="3楼"--> <el-option
<!-- :value="3"--> label="3楼"
<!-- >--> :value="3"
<!-- </el-option>--> >
<!-- <el-option--> </el-option>
<!-- label="4楼"--> <el-option
<!-- :value="4"--> label="4楼"
<!-- >--> :value="4"
<!-- </el-option>--> >
<!-- <el-option--> </el-option>
<!-- label="5楼"--> <el-option
<!-- :value="5"--> label="5楼"
<!-- >--> :value="5"
<!-- </el-option>--> >
<!-- </el-select>--> </el-option>
<!-- <el-button type="primary" @click="addtuopan"></el-button>--> </el-select>
<!-- <el-select v-model="fx" placeholder="方向">--> <el-button type="primary" @click="addtuopan"></el-button>
<!-- <el-option--> <el-select v-model="fx" placeholder="方向">
<!-- label="x"--> <el-option
<!-- value="x"--> label="x"
<!-- >--> value="x"
<!-- </el-option>--> >
<!-- <el-option--> </el-option>
<!-- label="z"--> <el-option
<!-- value="z"--> label="z"
<!-- >--> value="z"
<!-- </el-option>--> >
<!-- </el-select>--> </el-option>
<!-- <el-input-number v-model="num1" :step="0.1" label="描述文字"></el-input-number>--> </el-select>
<!-- <el-button type="primary" @click="agvAn">agv</el-button>--> <el-input-number v-model="num1" :step="0.1" label="描述文字"></el-input-number>
<!-- </div>--> <el-button type="primary" @click="agvAn">agv</el-button>
<!-- </div>--> </div>
<!--</template>--> </div>
</template>
<!--<script>--> <script>
<!--import * as THREE from 'three'--> import * as THREE from 'three'
<!--import * as TWEEN from '@tweenjs/tween.js'--> import * as TWEEN from '@tweenjs/tween.js'
<!--import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'--> import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'
<!--import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'--> import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js'
<!--import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'--> import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
<!--import { CSS2DObject, CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer'--> import { CSS2DObject, CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer'
<!--import Demo from '@/components/model/demo.vue'--> import Demo from '@/components/model/demo.vue'
<!--import {--> import {
<!-- tuopanInishengji,--> tuopanInishengji,
<!-- tishengjiAnimation,--> tishengjiAnimation,
<!-- tuopanXAnimation,--> tuopanXAnimation,
<!-- tuopanYAnimation,--> tuopanYAnimation,
<!-- addtuopan--> addtuopan
<!--} from './animation'--> } from './animation'
<!--import {--> import {
<!-- keyidongModel,--> keyidongModel,
<!-- tuopanModel,--> tuopanModel,
<!-- scene,--> scene,
<!-- camera,--> camera,
<!-- renderer,--> renderer,
<!-- loadF1,--> loadF1,
<!-- loadF2,--> loadF2,
<!-- loadF3,--> loadF3,
<!-- loadF4,--> loadF4,
<!-- loadF5,--> loadF5,
<!-- storeyHeight,--> storeyHeight,
<!-- storeyWidth,--> storeyWidth,
<!-- tuopanLocation,--> tuopanLocation,
<!-- animationLine, isLoading,--> animationLine, isLoading,
<!-- floor1Model,--> floor1Model,
<!-- floor2Model,--> floor2Model,
<!-- floor3Model,--> floor3Model,
<!-- floor4Model,--> floor4Model,
<!-- floor5Model, loadFOther, otherModel--> floor5Model, loadFOther, otherModel
<!--} from './setThree'--> } from './setThree'
<!--/*import {--> /*import {
<!-- AGVAnimation, agvData, floorOrigin, floorData1, isAGVLoading, agvLabel, loadAGV--> AGVAnimation, agvData, floorOrigin, floorData1, isAGVLoading, agvLabel, loadAGV
<!--} from './agv'*/--> } from './agv'*/
<!--const vw = (document.documentElement.clientWidth || document.body.clientWidth) / 100--> const vw = (document.documentElement.clientWidth || document.body.clientWidth) / 100
<!--export default {--> export default {
<!-- name: 'Model',--> name: 'Model',
<!-- components: { Demo },--> components: { Demo },
<!-- data() {--> data() {
<!-- return {--> return {
<!-- num: -60,--> num: -60,
<!-- num1: 90,--> num1: 90,
<!-- floor: 1,--> floor: 1,
<!-- tuopanFloor: 1,--> tuopanFloor: 1,
<!-- fx: '',--> fx: '',
<!-- rotate: 0--> rotate: 0
<!-- }--> }
<!-- },--> },
<!-- mounted() {--> mounted() {
<!-- this.$refs.threeJs.appendChild(renderer.domElement)--> this.$refs.threeJs.appendChild(renderer.domElement)
<!-- // controls.rotateSpeed = -controls.rotateSpeed;--> // controls.rotateSpeed = -controls.rotateSpeed;
<!-- // controls.enableZoom = false--> // controls.enableZoom = false
<!-- // loadF([ 'tishengji_tuopan'])--> // loadF([ 'tishengji_tuopan'])
<!-- // loadF1([ 'changfang005', 'liku005', 'quanzidongchaibaojizhaungpeixian003', 'tishengji', 'tishengji_keyidongbufen', 'tishengji_tuopan', 'Uxingxian'])--> // loadF1([ 'changfang005', 'liku005', 'quanzidongchaibaojizhaungpeixian003', 'tishengji', 'tishengji_keyidongbufen', 'tishengji_tuopan', 'Uxingxian'])
<!-- // loadF2(['2-1AGVchongdianzhuang005', '2-2AGVchongdianzhuang005', 'AGVchongdianzhuang002', 'AGVchongdianzhuang003', 'AGVchongdianzhuang005','changfang002', 'changfang003',])--> // loadF2(['2-1AGVchongdianzhuang005', '2-2AGVchongdianzhuang005', 'AGVchongdianzhuang002', 'AGVchongdianzhuang003', 'AGVchongdianzhuang005','changfang002', 'changfang003',])
<!-- loadF1([])--> loadF1([])
<!-- loadF2(['AGVchongdianzhuang002', 'changfang002'])--> loadF2(['AGVchongdianzhuang002', 'changfang002'])
<!-- loadF3(['AGVchongdianzhuang003', 'changfang003', 'quanzidongchaibaojizhaungpeixian003'])--> loadF3(['AGVchongdianzhuang003', 'changfang003', 'quanzidongchaibaojizhaungpeixian003'])
<!-- loadF4([])--> loadF4([])
<!-- loadF5(['AGVchongdianzhuang005', '2-1AGVchongdianzhuang005', '2-2AGVchongdianzhuang005', 'changfang005', 'liku005', 'Uxingxian'])--> loadF5(['AGVchongdianzhuang005', '2-1AGVchongdianzhuang005', '2-2AGVchongdianzhuang005', 'changfang005', 'liku005', 'Uxingxian'])
<!-- loadFOther(['tishengji', 'tishengji_keyidongbufen', 'tishengji_tuopan'])--> loadFOther(['tishengji', 'tishengji_keyidongbufen', 'tishengji_tuopan'])
<!-- // loadF(['changfang002', 'changfang003', 'changfang005'])--> // loadF(['changfang002', 'changfang003', 'changfang005'])
<!--/*// 创建CSS2DObject--> /*// 创建CSS2DObject
<!-- agvLabel['2AGV'] = new CSS2DObject(this.$refs.modelInfo)--> agvLabel['2AGV'] = new CSS2DObject(this.$refs.modelInfo)
<!-- agvLabel['3AGV'] = new CSS2DObject(this.$refs.modelInfo1)--> agvLabel['3AGV'] = new CSS2DObject(this.$refs.modelInfo1)
<!-- agvLabel['5CCAGV'] = new CSS2DObject(this.$refs.modelInfo2)--> agvLabel['5CCAGV'] = new CSS2DObject(this.$refs.modelInfo2)
<!-- agvLabel['5BFAGV'] = new CSS2DObject(this.$refs.modelInfo3)--> agvLabel['5BFAGV'] = new CSS2DObject(this.$refs.modelInfo3)
<!-- agvLabel['5CTU'] = new CSS2DObject(this.$refs.modelInfo4)--> agvLabel['5CTU'] = new CSS2DObject(this.$refs.modelInfo4)
<!-- loadAGV(['chacheshiAGV002', 'chacheshiAGV003', 'chacheshiAGV005', 'beifushiAGV005', 'CTU005'])*/--> loadAGV(['chacheshiAGV002', 'chacheshiAGV003', 'chacheshiAGV005', 'beifushiAGV005', 'CTU005'])*/
<!-- // setInterval(()=>{--> // setInterval(()=>{
<!-- // labelObject2AGV.position.x +=0.1--> // labelObject2AGV.position.x +=0.1
<!-- // labelObject2AGV.position.y +=0.1--> // labelObject2AGV.position.y +=0.1
<!-- // labelObject2AGV.position.z +=0.1--> // labelObject2AGV.position.z +=0.1
<!-- // },40)--> // },40)
<!--// --> //
<!-- },--> },
<!-- methods: {--> methods: {
<!-- handleChange() {--> handleChange() {
<!--/* AGVAnimation('5CTU', '5CTU', 'x', this.num)*/--> /* AGVAnimation('5CTU', '5CTU', 'x', this.num)*/
<!-- // tuopanModel.position.x = this.num--> // tuopanModel.position.x = this.num
<!-- },--> },
<!-- toFloor(e) {--> toFloor(e) {
<!-- animationLine.push(() => {--> animationLine.push(() => {
<!-- if (tuopanInishengji) {--> if (tuopanInishengji) {
<!-- return Promise.all([tishengjiAnimation(keyidongModel, e, storeyHeight[e]), tuopanYAnimation(tuopanModel, e, storeyHeight[e])])--> return Promise.all([tishengjiAnimation(keyidongModel, e, storeyHeight[e]), tuopanYAnimation(tuopanModel, e, storeyHeight[e])])
<!-- } else {--> } else {
<!-- animationLine.push(() => tishengjiAnimation(keyidongModel, e, storeyHeight[e]))--> animationLine.push(() => tishengjiAnimation(keyidongModel, e, storeyHeight[e]))
<!-- }--> }
<!-- })--> })
<!-- },--> },
<!-- tuopanReset() {--> tuopanReset() {
<!-- animationLine.push(() => tuopanXAnimation(tuopanModel, 0))--> animationLine.push(() => tuopanXAnimation(tuopanModel, 0))
<!-- },--> },
<!-- tuopanOut() {--> tuopanOut() {
<!-- animationLine.push(() => tuopanXAnimation(tuopanModel, storeyWidth[tuopanLocation.floor]))--> animationLine.push(() => tuopanXAnimation(tuopanModel, storeyWidth[tuopanLocation.floor]))
<!-- },--> },
<!-- removetuopan() {--> removetuopan() {
<!-- scene.remove(tuopanModel)--> scene.remove(tuopanModel)
<!-- tuopanModel = null--> tuopanModel = null
<!-- },--> },
<!-- async addtuopan() {--> async addtuopan() {
<!-- scene.remove(tuopanModel)--> scene.remove(tuopanModel)
<!-- tuopanModel = null--> tuopanModel = null
<!-- tuopanModel = await addtuopan({ scene })--> tuopanModel = await addtuopan({ scene })
<!-- scene.add(tuopanModel)--> scene.add(tuopanModel)
<!-- tuopanModel.position.x = storeyWidth[this.tuopanFloor]--> tuopanModel.position.x = storeyWidth[this.tuopanFloor]
<!-- tuopanModel.position.y = storeyHeight[this.tuopanFloor]--> tuopanModel.position.y = storeyHeight[this.tuopanFloor]
<!-- tuopanLocation.floor = this.tuopanFloor--> tuopanLocation.floor = this.tuopanFloor
<!-- tuopanLocation.y = storeyHeight[this.tuopanFloor]--> tuopanLocation.y = storeyHeight[this.tuopanFloor]
<!-- tuopanLocation.x = storeyWidth[this.tuopanFloor]--> tuopanLocation.x = storeyWidth[this.tuopanFloor]
<!-- },--> },
<!--/* agvAn() {--> /* agvAn() {
<!-- this.rotate -= this.num1--> this.rotate -= this.num1
<!-- AGVAnimation('3AGV', 'rotate', this.rotate)--> AGVAnimation('3AGV', 'rotate', this.rotate)
<!-- },*/--> },*/
<!-- toggle() {--> toggle() {
<!-- console.log(agvData)--> console.log(agvData)
<!-- floor1Model.visible = true--> floor1Model.visible = true
<!-- floor2Model.visible = true--> floor2Model.visible = true
<!-- floor3Model.visible = true--> floor3Model.visible = true
<!-- floor4Model.visible = true--> floor4Model.visible = true
<!-- floor5Model.visible = true--> floor5Model.visible = true
<!-- otherModel.visible = true--> otherModel.visible = true
<!--/* agvData.floor2AGVGroup.visible = true--> /* agvData.floor2AGVGroup.visible = true
<!-- agvData.floor3AGVGroup.visible = true--> agvData.floor3AGVGroup.visible = true
<!-- agvData.floor5BFAGVGroup.visible = true--> agvData.floor5BFAGVGroup.visible = true
<!-- agvData.floor5CCAGVGroup.visible = true--> agvData.floor5CCAGVGroup.visible = true
<!-- agvData.floor5CTUGroup.visible = true*/--> agvData.floor5CTUGroup.visible = true*/
<!-- this.$refs.modelInfoData.$el.style.display = 'inline-block'--> this.$refs.modelInfoData.$el.style.display = 'inline-block'
<!-- this.$refs.modelInfo1Data.$el.style.display = 'inline-block'--> this.$refs.modelInfo1Data.$el.style.display = 'inline-block'
<!-- this.$refs.modelInfo2Data.$el.style.display = 'inline-block'--> this.$refs.modelInfo2Data.$el.style.display = 'inline-block'
<!-- this.$refs.modelInfo3Data.$el.style.display = 'inline-block'--> this.$refs.modelInfo3Data.$el.style.display = 'inline-block'
<!-- this.$refs.modelInfo4Data.$el.style.display = 'inline-block'--> this.$refs.modelInfo4Data.$el.style.display = 'inline-block'
<!-- },--> },
<!-- toggle1() {--> toggle1() {
<!-- floor1Model.visible = true--> floor1Model.visible = true
<!-- floor2Model.visible = false--> floor2Model.visible = false
<!-- floor3Model.visible = false--> floor3Model.visible = false
<!-- floor4Model.visible = false--> floor4Model.visible = false
<!-- floor5Model.visible = false--> floor5Model.visible = false
<!-- otherModel.visible = false--> otherModel.visible = false
<!-- this.$refs.modelInfoData.$el.style.display = 'none'--> this.$refs.modelInfoData.$el.style.display = 'none'
<!-- this.$refs.modelInfo1Data.$el.style.display = 'none'--> this.$refs.modelInfo1Data.$el.style.display = 'none'
<!-- this.$refs.modelInfo2Data.$el.style.display = 'none'--> this.$refs.modelInfo2Data.$el.style.display = 'none'
<!-- this.$refs.modelInfo3Data.$el.style.display = 'none'--> this.$refs.modelInfo3Data.$el.style.display = 'none'
<!-- this.$refs.modelInfo4Data.$el.style.display = 'none'--> this.$refs.modelInfo4Data.$el.style.display = 'none'
<!--/* agvData.floor2AGVGroup.visible = false--> /* agvData.floor2AGVGroup.visible = false
<!-- agvData.floor3AGVGroup.visible = false--> agvData.floor3AGVGroup.visible = false
<!-- agvData.floor5BFAGVGroup.visible = false--> agvData.floor5BFAGVGroup.visible = false
<!-- agvData.floor5CCAGVGroup.visible = false--> agvData.floor5CCAGVGroup.visible = false
<!-- agvData.floor5CTUGroup.visible = false*/--> agvData.floor5CTUGroup.visible = false*/
<!-- },--> },
<!-- }--> }
<!--}--> }
<!--</script>--> </script>
<!--<style lang="less" scoped>--> <style lang="less" scoped>
<!--.app-container {--> .app-container {
<!-- padding: 0;--> padding: 0;
<!--}--> }
<!--.model {--> .model {
<!-- position: relative;--> position: relative;
<!--}--> }
<!--.bottomBg {--> .bottomBg {
<!-- position: absolute;--> position: absolute;
<!-- bottom: 0;--> bottom: 0;
<!-- left: 50%;--> left: 50%;
<!-- transform: translateX(-50%);--> transform: translateX(-50%);
<!-- width: 100vw;--> width: 100vw;
<!-- height: 2.656vw;--> height: 2.656vw;
<!-- background-image: url("~@/assets/model/bottomBg.png");--> background-image: url("~@/assets/model/bottomBg.png");
<!-- background-size: 100% 100%;--> background-size: 100% 100%;
<!-- background-repeat: no-repeat;--> background-repeat: no-repeat;
<!-- //.item1F, .item2F, .item3F, .item4F, .item5F {--> //.item1F, .item2F, .item3F, .item4F, .item5F {
<!-- // position: absolute;--> // position: absolute;
<!-- // top: 45%;--> // top: 45%;
<!-- // transform: translate(-50%, -50%);--> // transform: translate(-50%, -50%);
<!-- // background-size: 100% 100%;--> // background-size: 100% 100%;
<!-- // background-repeat: no-repeat;--> // background-repeat: no-repeat;
<!-- // width: 4.6vw;--> // width: 4.6vw;
<!-- // height: 1.32vw;--> // height: 1.32vw;
<!-- // line-height: 1.32vw;--> // line-height: 1.32vw;
<!-- // text-align: center;--> // text-align: center;
<!-- // color: #fff;--> // color: #fff;
<!-- //}--> //}
<!-- //--> //
<!-- //.item1F {--> //.item1F {
<!-- // left: 39%;--> // left: 39%;
<!-- // background-image: url("~@/assets/model/unselected.png");--> // background-image: url("~@/assets/model/unselected.png");
<!-- //}--> //}
<!-- //--> //
<!-- //.item2F {--> //.item2F {
<!-- // left: 44.5%;--> // left: 44.5%;
<!-- // background-image: url("~@/assets/model/unselected.png");--> // background-image: url("~@/assets/model/unselected.png");
<!-- //}--> //}
<!-- //--> //
<!-- //.item3F {--> //.item3F {
<!-- // left: 50%;--> // left: 50%;
<!-- // background-image: url("~@/assets/model/unselected.png");--> // background-image: url("~@/assets/model/unselected.png");
<!-- //}--> //}
<!-- //--> //
<!-- //.item4F {--> //.item4F {
<!-- // left: 55.5%;--> // left: 55.5%;
<!-- // background-image: url("~@/assets/model/unselected.png");--> // background-image: url("~@/assets/model/unselected.png");
<!-- //}--> //}
<!-- //--> //
<!-- //.item5F {--> //.item5F {
<!-- // left: 61%;--> // left: 61%;
<!-- // background-image: url("~@/assets/model/unselected.png");--> // background-image: url("~@/assets/model/unselected.png");
<!-- //}--> //}
<!--}--> }
<!--</style>--> </style>
-->

@ -7,55 +7,75 @@ import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader' import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
// 定义一些全局变量 // 定义一些全局变量
let isLoading = false let isLoading = false // 是否正在加载
let isAnimation = false let isAnimation = false // 是否正在进行动画
let animationLine = [] let animationLine = [] // 存储动画路径的数组
let keyidongModel let keyidongModel // 关键帧动画模型
let tuopanModel let tuopanModel // 拖盘模型
const scene = new THREE.Scene() const scene = new THREE.Scene() // 创建一个新的Three.js场景
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000000000) const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000000000) // 创建一个透视相机,参数为视角、宽高比、近裁剪面和远裁剪面
const renderer = new THREE.WebGLRenderer({ const renderer = new THREE.WebGLRenderer({
antialias: true antialias: true // 开启抗锯齿
}) }) // 创建一个WebGL渲染器
const controls = new OrbitControls(camera, renderer.domElement) const controls = new OrbitControls(camera, renderer.domElement) // 添加轨道控制器,允许用户通过鼠标操作旋转、缩放和平移场景
const pointLight = new THREE.PointLight(0xffffff, 1) //光源颜色 光照强度 const pointLight = new THREE.PointLight(0xffffff, 1) // 创建一个点光源颜色为白色强度为1
const ambient = new THREE.AmbientLight(0xffffff, 1) const ambient = new THREE.AmbientLight(0xffffff, 1) // 创建一个环境光颜色为白色强度为1
const light = new THREE.DirectionalLight(0xffffff, 1) const light = new THREE.DirectionalLight(0xffffff, 1) // 创建一个平行光颜色为白色强度为1
const labelRenderer = new CSS2DRenderer() const labelRenderer = new CSS2DRenderer() // 创建一个CSS2D渲染器用于在3D场景中渲染HTML标签
let raycaster = new THREE.Raycaster() let raycaster = new THREE.Raycaster() // 创建一个射线投射器,用于进行鼠标点击检测
// 创建一个二维空间的向量用于存储鼠标点击的屏幕位置 // 创建一个二维空间的向量用于存储鼠标点击的屏幕位置
let mouse = new THREE.Vector2() let mouse = new THREE.Vector2()
// 设置场景背景颜色为黑色
scene.background = new THREE.Color(0x000000) scene.background = new THREE.Color(0x000000)
// 设置相机位置
camera.position.set(-435, 940, -1377) camera.position.set(-435, 940, -1377)
// 更新相机投影矩阵
camera.updateProjectionMatrix() camera.updateProjectionMatrix()
// 设置渲染器大小为窗口大小
renderer.setSize(window.innerWidth, window.innerHeight) renderer.setSize(window.innerWidth, window.innerHeight)
// 设置控制器目标点
controls.target = new THREE.Vector3(-433, 300, -217) controls.target = new THREE.Vector3(-433, 300, -217)
// 更新控制器
controls.update() controls.update()
// 设置点光源不随距离衰减
pointLight.decay = 0.0 //设置光源不随距离衰减 默认2.0 pointLight.decay = 0.0 //设置光源不随距离衰减 默认2.0
// 设置点光源位置
pointLight.position.set(66, 66, 66) // 点光源位置 pointLight.position.set(66, 66, 66) // 点光源位置
// 设置点光源投射阴影
pointLight.castShadow = true pointLight.castShadow = true
// 将点光源添加到场景中
scene.add(pointLight) scene.add(pointLight)
// 将环境光添加到场景中
scene.add(ambient) scene.add(ambient)
// 设置光源位置
light.position.set(66, 66, 66) light.position.set(66, 66, 66)
// 设置光源目标点
light.target.position.set(0, 0, 0) light.target.position.set(0, 0, 0)
// 将光源添加到场景中
scene.add(light) scene.add(light)
// 设置标签渲染器大小为窗口大小
labelRenderer.setSize(window.innerWidth, window.innerHeight) labelRenderer.setSize(window.innerWidth, window.innerHeight)
// 设置标签渲染器元素位置为绝对定位
labelRenderer.domElement.style.position = 'absolute' labelRenderer.domElement.style.position = 'absolute'
// 设置标签渲染器元素顶部位置为0
labelRenderer.domElement.style.top = '0' labelRenderer.domElement.style.top = '0'
// 设置标签渲染器元素指针事件为无
labelRenderer.domElement.style.pointerEvents = 'none' labelRenderer.domElement.style.pointerEvents = 'none'
// 将标签渲染器元素添加到文档中
document.body.appendChild(labelRenderer.domElement) document.body.appendChild(labelRenderer.domElement)
// 根据ID获取模型 // 根据ID获取模型
function getModelById(id) { function getModelById(id) {
// 遍历场景中的所有对象 // 遍历场景中的所有对象,筛选出类型为'Group'或'Object3D'的对象
const objects = scene.children.filter(obj => obj.type === 'Group' || obj.type === 'Object3D') const objects = scene.children.filter(obj => obj.type === 'Group' || obj.type === 'Object3D')
for (const obj of objects) { for (const obj of objects) {
// 如果对象的ID与传入的ID匹配则返回该对象
if (obj.id === id) { if (obj.id === id) {
// 返回匹配ID的模型
return obj return obj
} }
} }
// 如果没有找到匹配的对象返回null
return null return null
} }
@ -74,53 +94,83 @@ document.addEventListener('dblclick', function(event) {
// 如果有交点 // 如果有交点
if (intersects.length > 0) { if (intersects.length > 0) {
let obj = intersects[0] let obj = intersects[0]
// 使用Tween.js库实现相机位置平滑过渡
new TWEEN.Tween(camera.position).to(new THREE.Vector3((intersects[0].point.x + 0), (intersects[0].point.y + 500), (intersects[0].point.z - 500)), 500).start() new TWEEN.Tween(camera.position).to(new THREE.Vector3((intersects[0].point.x + 0), (intersects[0].point.y + 500), (intersects[0].point.z - 500)), 500).start()
// 设置相机位置
camera.position.set((intersects[0].point.x + 0), (intersects[0].point.y + 500), (intersects[0].point.z - 500)) camera.position.set((intersects[0].point.x + 0), (intersects[0].point.y + 500), (intersects[0].point.z - 500))
// 更新相机投影矩阵
camera.updateProjectionMatrix() camera.updateProjectionMatrix()
// 设置相机朝向
camera.lookAt((intersects[0].point.x + 0), (intersects[0].point.y + 500), (intersects[0].point.z - 500)); camera.lookAt((intersects[0].point.x + 0), (intersects[0].point.y + 500), (intersects[0].point.z - 500));
// 设置控制器目标点
controls.target = new THREE.Vector3(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z) controls.target = new THREE.Vector3(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z)
// 更新控制器
controls.update() controls.update()
// 渲染场景
renderer.render(scene, camera) renderer.render(scene, camera)
} }
}, false) }, false)
// 动画函数 // 动画函数
/!**
* 异步动画函数用于依次执行动画队列中的动画
* @returns {Promise<void>} 返回一个Promise对象表示动画执行的完成状态
*!/
const animation = async() => { const animation = async() => {
try { try {
// 如果动画队列中有动画
if (animationLine.length > 0) { if (animationLine.length > 0) {
// 等待并执行队列中的第一个动画
await animationLine[0]() await animationLine[0]()
// 移除已执行的动画
animationLine.shift() animationLine.shift()
// 如果队列中还有剩余动画
if (animationLine.length > 0) { if (animationLine.length > 0) {
// 递归调用自身继续执行下一个动画
animation(animationLine) animation(animationLine)
} else { } else {
// 如果队列为空设置动画状态为false
isAnimation = false isAnimation = false
} }
} }
} catch (e) { } catch (e) {
// 捕获并打印异常信息
console.log(e) console.log(e)
} }
} }
// 动画循环 // 动画循环
/!**
* 动画函数用于更新和渲染场景
*!/
function animate() { function animate() {
// 如果动画队列不为空且当前没有进行动画
if (animationLine.length > 0 && isAnimation === false) { if (animationLine.length > 0 && isAnimation === false) {
// 设置动画状态为进行中
isAnimation = true isAnimation = true
// 开始执行动画
animation(animationLine) animation(animationLine)
} }
// 请求下一帧的动画
requestAnimationFrame(animate) requestAnimationFrame(animate)
// 更新TWEEN库中的动画状态
TWEEN.update() TWEEN.update()
// 渲染场景和相机
renderer.render(scene, camera) renderer.render(scene, camera)
// 渲染标签
labelRenderer.render(scene, camera) labelRenderer.render(scene, camera)
} }
animate() animate()
// 初始化变量a为0
let a = 0 let a = 0
// 加载管理器 // 加载管理器,用于管理资源加载过程
const loadingManager = new THREE.LoadingManager() const loadingManager = new THREE.LoadingManager()
loadingManager.onLoad = function() { loadingManager.onLoad = function() {
// 当所有资源加载完成时将isLoading设置为true
isLoading = true isLoading = true
} }
@ -142,33 +192,45 @@ scene.add(otherModel)
// 加载楼层1的模型 // 加载楼层1的模型
const loadF1 = (e) => { const loadF1 = (e) => {
// 遍历传入的模型名称数组
e.forEach(v => { e.forEach(v => {
// 创建MTLLoader实例用于加载材质文件
let mtlLoader = new MTLLoader() let mtlLoader = new MTLLoader()
mtlLoader.load(`/model/${v}/${v}.mtl`, // 加载材质文件
mtlLoader.load(`/model//.mtl`,
materials => { materials => {
// 预加载材质
materials.preload() materials.preload()
// 创建OBJLoader实例并设置加载管理器和材质
let loader = new OBJLoader(loadingManager) let loader = new OBJLoader(loadingManager)
loader.setMaterials(materials) loader.setMaterials(materials)
// 加载OBJ模型文件
loader.load( loader.load(
`/model/${v}/${v}.obj`, `/model//.obj`,
object => { object => {
// 设置模型的名称
object.name = v object.name = v
// 将模型添加到场景中
scene.add(object) scene.add(object)
// 将模型添加到floor1Model对象中
floor1Model.add(object) floor1Model.add(object)
// 如果模型名称为'tishengji_keyidongbufen'则将其赋值给keyidongModel变量
if (v === 'tishengji_keyidongbufen') { if (v === 'tishengji_keyidongbufen') {
keyidongModel = object keyidongModel = object
} }
// 如果模型名称为'tishengji_tuopan'则将其赋值给tuopanModel变量
if (v === 'tishengji_tuopan') { if (v === 'tishengji_tuopan') {
tuopanModel = object tuopanModel = object
} }
// 更新渲染器 // 更新渲染器以显示新添加的模型
renderer.render(scene, camera) renderer.render(scene, camera)
}, },
xhr => { xhr => {
// 处理加载过程中的进度事件(此处未实现)
}, },
(err) => { (err) => {
// 如果加载出错,重新尝试加载模型
loadF([e]) loadF([e])
} }
) )

Loading…
Cancel
Save