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

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

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

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

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

Loading…
Cancel
Save