Files
tunnel-cloud-web/src/components/content/tunnelScene/TunnelScene.vue
2023-12-10 17:03:43 +08:00

188 lines
4.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div id="scene" ref="content">
<dev-info ref="info" :devInfo="devInfo" />
<edit-dev ref="edit" @addDev="handleAddDev" @removeDev="handleRemoveDev" :hasDev="hasDevice" />
</div>
</template>
<script setup>
import * as three from "three";
import ThreeDScene from "./sceneClass/demo.js";
// 导入模模型加载器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
// import { DRACOLoader } from "three/examples/jsm/loaders/dracoloader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import * as TWEEN from "three/examples/jsm/libs/tween.module";
import {
CSS3DRenderer,
CSS3DObject,
CSS3DSprite,
} from "three/addons/renderers/CSS3DRenderer.js";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import DevInfo from "./childComp/DevInfo.vue";
import EditDev from "./childComp/EditDev.vue";
import { onMounted, reactive, ref } from "vue";
import { ElMessage } from "element-plus";
// 获取html标签跟随组件
const content = ref(null);
const info = ref(null);
const edit = ref(null);
const num = 10000;
let demo; //定义demo全局变量
const loader = new OBJLoader();
let backColorSet = three.sRGBEncoding;
// 模版挂载后
onMounted(handleMounted);
// 处理回调
async function handleMounted() {
const doms = [info.value.$el, edit.value.$el];
demo = new ThreeDScene(three, content.value);
demo.loadModel(GLTFLoader, "./assets/tunnelModel/chanel.gltf");
demo.addOrbitControls(OrbitControls);
demo.addTween(TWEEN);
demo.addCSS3Renderer(CSS3DRenderer, CSS3DSprite, doms);
demo.setDistance(10);
lClickCallback(demo); //左键回调
rClickCallback(demo); //右键回调
//加载HDR背景图片
demo.loadBackground(backColorSet)
// 初始化设备模型
try {
const deviceList = [];
let result = await loadModel("/devicesModel/camera.obj");
deviceList.push(result);
modelEffectProcess(result);
result = await loadModel("/devicesModel/fan.obj");
deviceList.push(result);
modelEffectProcess(result);
result = await loadModel("/devicesModel/sensors.obj");
deviceList.push(result);
modelEffectProcess(result);
result = await loadModel("/devicesModel/sensors.obj");
deviceList.push(result);
modelEffectProcess(result);
result = await loadModel("/devicesModel/sensors.obj");
deviceList.push(result);
modelEffectProcess(result);
// 给对象初加载设备模型
demo.initDevicesModel(deviceList);
console.info("设备模型加载完毕");
// 清空内存
result = null;
} catch (err) {
console.log(err);
}
}
// 每个模型加载回调
function loadModel(path) {
return new Promise((resolve, reject) => {
loader.load(
path,
(obj) => {
resolve(obj);
},
(xhr) => { },
(err) => {
reject(err);
}
);
});
}
function modelEffectProcess(model) {
model.traverse((v) => {
v.material = new three.MeshBasicMaterial
v.material.color = new three.Color(0xC0C0C0)
})
}
let hasDevice = ref(true);
let devInfo = reactive({
meshId: null,
name: "无",
state: "无",
position: "无",
});
// 赋值功能
function editDevInfo(
value = {
meshId: null,
name: "无",
state: "无",
position: "无",
}
) {
devInfo.meshId = value.meshId;
devInfo.name = value.name;
devInfo.state = value.state;
devInfo.position = value.position;
}
//点击左键返回附着点信息给组件
function lClickCallback(demo) {
//demo动态添加函数为操作组件内部
function displayDevInfo(targetPoint = null) {
hasDevice.value = targetPoint.hasDevice;
if (!targetPoint.info) {
editDevInfo();
return;
}
editDevInfo(targetPoint.info);
}
// 传给内部使用
demo.addFunction("displayDevInfo", displayDevInfo);
}
// 点击右键设备返回附着点对象
function rClickCallback(demo) {
function editDev(targetPoint = null) {
hasDevice = targetPoint.hasDevice;
if (!targetPoint.info) return;
editDevInfo(targetPoint.info);
}
demo.addFunction("editDev", editDev);
}
// 添加设备
function handleAddDev(devInfo) {
if (!demo) {
// 处理未加载完场景情况
console.info("3D场景正在渲染请稍后操作");
return;
}
const tempDevInfo = demo.addDev(devInfo);
hasDevice.value = true;
editDevInfo(tempDevInfo);
ElMessage({
message: "添加成功",
type: "success",
});
}
// 删除设备
async function handleRemoveDev() {
const result = await demo.removeDev(devInfo.meshId);
if (result === "ok") {
hasDevice.value = false;
editDevInfo();
ElMessage({
message: "删除成功",
type: "success",
});
}
}
</script>
<style lang="scss" scope>
#scene {
position: relative;
height: 100vh;
width: 100vw;
}
</style>