screenFront/src/views/FactoryView/threeMap.vue
2023-05-24 10:03:52 +08:00

1328 lines
50 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 class="container" ref="container"></div>
</template>
<script setup lang='ts'>
import { ref, onMounted, defineExpose } from 'vue';
import * as THREE from 'three';
import * as TWEEN from '@tweenjs/tween.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import * as SceneUtils from 'three/examples/jsm/utils/SceneUtils.js';
import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js';
import { DragControls } from "@/utils/DragControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { Line2 } from 'three/examples/jsm/lines/Line2'
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry'
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial'
import { useFactoryStore } from "@/store/module/Factory"
import { useRouter } from 'vue-router';
import { updateCoordinateByPoint } from "@/http/AerialView/index"
import { ElNotification } from 'element-plus'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router';
let { t } = useI18n();
let route = useRoute();
let edit = false;
let type = route.params?.type;
if (type == 'edit') {
edit = true;
}
const store = useFactoryStore();
const router = useRouter();
const container = ref();
let iw = 1920;
let ih = 1080;
const boxObjects: any = ref([]);
let scene: any = null; //场景
let camera: any = null; //相机
let canvas: any = null; //用作渲染的canvas
let renderer: any = null; //渲染器
let controls: any = null; //控制器
let labelRenderer: any = null; //2D渲染器
let labelControls: any = null; //2D控制器
const group = new THREE.Group();//用于将建筑物的各个零件组合起来
let timer: any = null;
let dragControls: any = null;
let cssRender: any = null;
let saveTipDom: any = null;
const requires = {
'粉尘': require('@/assets/img/Factory/fenchen.jpg'),
'烟雾': require('@/assets/img/Factory/yanwu.jpg'),
'TVOC/甲醛': require('@/assets/img/Factory/tvoc.jpg'),
'噪音': require('@/assets/img/Factory/shengyin.jpg'),
'火花': require('@/assets/img/Factory/huohua.jpg'),
'电力': require('@/assets/img/Factory/dianlu.jpg'),
'气压': require('@/assets/img/Factory/qiya.jpg'),
'水压': require('@/assets/img/Factory/shuiya.jpg'),
'温湿度': require('@/assets/img/Factory/wendu.jpg'),
'网关': require('@/assets/img/Factory/wangguan.jpg'),
'燃气': require('@/assets/img/Factory/ranqi.jpg'),
'设备': require('@/assets/img/Factory/shebei.jpg'),
'ny': require("@/assets/img/Factory/ny.jpg"),
'wood': require("@/assets/img/Factory/wood4.jpg"),
// 'wall1': require("@/assets/img/Factory/floor1.jpeg"),
'wall1': require("@/assets/img/Factory/wall1.jpg"),
'tile': require("@/assets/img/Factory/tile.jpg"),
'door': require("@/assets/img/Factory/door.jpg"),
'sky': require("@/assets/img/Factory/sky.jpg"),
'titleFloor': require("@/assets/img/Factory/screen_title.png"),
'guangmao': require("@/assets/img/Factory/guangmao.jpg"),
'ac': require("@/assets/img/Factory/ac.jpg"),
}
const workerShopRoute = {
'大件车间地板': '/MechanicalViewDajian',
'焊接车间地板': '/MechanicalViewHanjie',
'机加车间地板': '/MechanicalViewJijia',
'精加车间地板': '/MechanicalViewJingjia',
'精饰车间地板': '/MechanicalViewJingshi',
}
let getSensorDataTimer = null;
let getDevDataTimer = null;
const normal_size = { baseWidth: 10, baseHeght: 10, baseLength: 10 };//正常大小
const small_size = { baseWidth: 8, baseHeght: 8, baseLength: 8 };//缩小的大小
const coordinate = {}
/**
* @函数功能:
* @param {*} val 重置画布宽高值
* @出口参数:
* @函数备注:
*/
function reset(val: any) {
//宽高为0时跳出该方法
if (!val.oWidth && !val.oHeight) return;
// mapSize.width=val.width
// mapSize.height=val.height
// 更新修改相机比例
container.value.style.width = val.oWidth;
container.value.style.height = val.oHeight;
camera.aspect = val.oWidth / val.oHeight;
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix();
//处理返回操作时dom层数变多问题
if (document.getElementsByClassName("cssrender").length > 1) {
document.getElementsByClassName("cssrender")[1].remove();
}
// 更新画布大小
renderer.setSize(
val.oWidth, // 宽度
val.oHeight // 高度
);
labelRenderer.setSize(
val.oWidth, // 宽度
val.oHeight // 高度
);
// 更新画布像素比
renderer.setPixelRatio(container.value.devicePixelRatio);
//重置盒子尺寸
}
defineExpose({
reset,
});
const init = () => {
canvas = container.value;
//创建场景
scene = new THREE.Scene();
//创建一个透视相机
camera = new THREE.PerspectiveCamera(45, iw / ih, 1, 3000);
// 创建渲染器
renderer = new THREE.WebGLRenderer();
// 设置渲染器的初始颜色
renderer.setClearColor(new THREE.Color(0xeeeeee));
// 设置输出canvas画面的大小
renderer.setSize(iw, ih)
// 设置渲染物体阴影
renderer.shadowMap.enabled = true;
//设置2D渲染器
labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(iw, ih);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = 0;
labelRenderer.domElement.style.outline = "none";
canvas.appendChild(labelRenderer.domElement);
//创建环境光
const hjLight = new THREE.AmbientLight(0xffffff);
//添加环境光至场景
scene.add(hjLight);
// 定位相机,并且指向场景中心
if (edit) {
camera.position.x = 0;
camera.position.y = 820; //650
camera.position.z = 0; //600
} else {
camera.position.x = 0;
camera.position.y = 650; //650
camera.position.z = 600; //600
}
camera.lookAt(scene.position)
renderer.render(scene, camera)
// 将渲染器输出添加html元素中
canvas.appendChild(renderer.domElement);
//添加房子的group到场景中
scene.add(group);
// 创建controls对象;
controls = new OrbitControls(camera, labelRenderer.domElement)
// labelControls = new OrbitControls(camera, labelRenderer.domElement)
// 监听控制器的鼠标事件,执行渲染内容
controls.addEventListener('change', () => {
clearInterval(timer)
renderer.render(scene, camera)
labelRenderer.render(scene, camera)
})
/**-------------------------------结束后注释------------------------------------------------- */
if (edit) {
controls.mouseButtons = {
// LEFT: ,
MIDDLE: THREE.MOUSE.DOLLY,
RIGHT: THREE.MOUSE.PAN
};
}
//创建地面
createGround()
//创建仓库1
createHouse(`${t('messages.store')}1`, { baseWidth: 262, baseHeght: 30, baseLength: 53 }, { x: -322, y: 0, z: -304 })
//创建仓库2
createHouse(`${t('messages.store')}2`, { baseWidth: 262, baseHeght: 30, baseLength: 53 }, { x: 183, y: 0, z: -304 })
//创建综合楼 baseWidth: 114, baseHeght: 50, baseLength: 353 x: -397, y: 0, z: 11
createHouse(t('messages.SynthesizeRoom'), { baseWidth: 114, baseHeght: 50, baseLength: 353 }, { x: -397, y: 0, z: -11 })
/**
* 创建综合楼里的墙
*/
createUseWall('综合楼的墙1', { baseWidth: 1, baseHeght: 50, baseLength: 159 }, { x: -413, y: 0, z: -26.5 })
createUseWall('综合楼的墙2', { baseWidth: 41, baseHeght: 50, baseLength: 1 }, { x: -413, y: 0, z: -26.5 })
createUseWall('综合楼的墙3', { baseWidth: 1, baseHeght: 50, baseLength: 159 }, { x: -382, y: 0, z: -26.5 })
createUseWall('综合楼的墙4', { baseWidth: 41, baseHeght: 50, baseLength: 1 }, { x: -341, y: 0, z: -26.5 })
createUseWall('综合楼的墙3', { baseWidth: 45, baseHeght: 50, baseLength: 1 }, { x: -410, y: 0, z: 30 })
createUseWall('综合楼的墙4', { baseWidth: 45, baseHeght: 50, baseLength: 1 }, { x: -341, y: 0, z: 30 })
createUseWall('综合楼的墙5', { baseWidth: 45, baseHeght: 50, baseLength: 1 }, { x: -410, y: 0, z: 87.5 })
createUseWall('综合楼的墙6', { baseWidth: 45, baseHeght: 50, baseLength: 1 }, { x: -341, y: 0, z: 79.5 })
createUseWall('综合楼的墙7', { baseWidth: 1, baseHeght: 50, baseLength: 57 }, { x: -410, y: 0, z: 87 })
createUseWall('综合楼的墙8', { baseWidth: 1, baseHeght: 50, baseLength: 69 }, { x: -385, y: 0, z: 99 })
createUseWall('综合楼的墙9', { baseWidth: 1, baseHeght: 50, baseLength: 63 }, { x: -435, y: 0, z: 150 })
createUseWall('综合楼的墙10', { baseWidth: 1, baseHeght: 50, baseLength: 63 }, { x: -435, y: 0, z: 150 })
createUseWall('综合楼的墙11', { baseWidth: 1, baseHeght: 50, baseLength: 40 }, { x: -421, y: 0, z: 138.5 })
createUseWall('综合楼的墙12', { baseWidth: 36, baseHeght: 50, baseLength: 1 }, { x: -385, y: 0, z: 99.5 })
createUseWall('综合楼的墙13', { baseWidth: 36, baseHeght: 50, baseLength: 1 }, { x: -385, y: 0, z: 139.5 })
createUseWall('综合楼的墙14', { baseWidth: 44, baseHeght: 50, baseLength: 1 }, { x: -410, y: 0, z: 150.5 })
createUseWall('综合楼的墙15', { baseWidth: 1, baseHeght: 50, baseLength: 16 }, { x: -409, y: 0, z: 165.5 })
createUseWall('综合楼的墙16', { baseWidth: 1, baseHeght: 50, baseLength: 27 }, { x: -384, y: 0, z: 165.5 })
//汽车部地板
const mesh_qcb = createFloor(t('messages.ExternalWork'), 42, 160, { x: -362, y: 0, z: -105 })
createLableObj(mesh_qcb, t('messages.ExternalWork'), { x: 0, y: 0, z: 0 })
//创建产学研 baseWidth: 21, baseHeght: 25, baseLength: 32 x: -495, y: 0, z: -102.5
createHouse(t('messages.WaterRoom'), { baseWidth: 21, baseHeght: 25, baseLength: 32 }, { x: -495, y: 0, z: -102.5 })
createHouse(t('messages.SecurityRoom'), { baseWidth: 21, baseHeght: 25, baseLength: 32 }, { x: -495, y: 0, z: -70.5 })
//创建盈瑞安办公区 baseWidth: 90, baseHeght: 30, baseLength: 159 x: -399, y: 0, z: 245
createHouse(t('messages.productStudyDevelopment'), { baseWidth: 90, baseHeght: 30, baseLength: 159 }, { x: -399, y: 0, z: 245 })
/**盈瑞安办公区里的墙 */
createUseWall('盈瑞安办公区的墙1', { baseWidth: 90, baseHeght: 30, baseLength: 1 }, { x: -354.5, y: 0, z: 195.5 })
createUseWall('盈瑞安办公区的墙2', { baseWidth: 90, baseHeght: 30, baseLength: 1 }, { x: -354.5, y: 0, z: 246.5 })
createUseWall('盈瑞安办公区的墙3', { baseWidth: 90, baseHeght: 30, baseLength: 1 }, { x: -354.5, y: 0, z: 271.5 })
//创建车间1 baseWidth: 573, baseHeght: 30, baseLength: 238 x: -17.5, y: 0, z: -137.5
createHouse('车间1', { baseWidth: 620, baseHeght: 30, baseLength: 238 }, { x: 6, y: 0, z: -137.5 }, false)
/**车间一内的墙 */
createUseWall('车间1的墙1', { baseWidth: 1, baseHeght: 30, baseLength: 238 }, { x: -228, y: 0, z: -18.5 })
createUseWall('车间1的墙2', { baseWidth: 1, baseHeght: 30, baseLength: 238 }, { x: -37, y: 0, z: -18.5 })
createUseWall('车间1的墙3', { baseWidth: 1, baseHeght: 30, baseLength: 238 }, { x: 37, y: 0, z: -18.5 })
createUseWall('车间1的墙4', { baseWidth: 1, baseHeght: 30, baseLength: 238 }, { x: 73, y: 0, z: -18.5 })
createUseWall('车间1的墙5', { baseWidth: 76, baseHeght: 30, baseLength: 1 }, { x: -228, y: 0, z: -95.5 })
createUseWall('车间1的墙5', { baseWidth: 192, baseHeght: 30, baseLength: 1 }, { x: -37, y: 0, z: -194.5 })
createUseWall('车间1的墙5', { baseWidth: 40, baseHeght: 30, baseLength: 1 }, { x: 2, y: 0, z: -105.5 })
createUseWall('车间1的墙5', { baseWidth: 40, baseHeght: 30, baseLength: 1 }, { x: 2, y: 0, z: -62.5 })
//机械设计及行政办公区
const mesh_hr = createFloor(t('messages.machineDesign'), 45, 120, { x: -431, y: 0, z: 102 })
createLableObj(mesh_hr, t('messages.machineDesign'), { x: 0, y: 60, z: 0 })
const mesh_serve = createFloor('', 45, 48, { x: -364.5, y: 0, z: 58 })
createLableObj(mesh_serve, t('messages.服务器机房'), { x: 0, y: 60, z: 0 })
//电控车间
const mesh_dkcj = createFloor(t('messages.ControllerRoom'), 76.5, 237, { x: -266, y: 0, z: -138.5 })
createLableObj(mesh_dkcj, t('messages.ControllerRoom'), { x: 0, y: 60, z: 0 })
//服装军团
const mesh_fzjt = createFloor(t('messages.FuZhuangLegion'), 192, 236.5, { x: -133, y: 0, z: -138 })
createLableObj(mesh_fzjt, t('messages.FuZhuangLegion'), { x: 0, y: 60, z: 0 })
//配套车间
const mesh_ptcj = createFloor(t('messages.BigPeiTao'), 110, 236.5, { x: 18.5, y: 0, z: -138 })
createLableObj(mesh_ptcj, t('messages.BigPeiTao'), { x: 0, y: 60, z: 0 })
//家纺军团
const mesh_jfjt = createFloor(t('messages.JiaFangLegion'), 247, 118, { x: 192, y: 0, z: -197 })
createLableObj(mesh_jfjt, t('messages.JiaFangLegion'), { x: 0, y: 60, z: 0 })
//医防军团
const mesh_yfjt = createFloor(t('messages.YiFangLegion'), 247, 119, { x: 192, y: 0, z: -78 })
createLableObj(mesh_yfjt, `${t('messages.twoLou')}-${t('messages.YiFangLegion')}`, { x: 0, y: 60, z: 0 })
createHouse('配套车间办公室', { baseWidth: 26, baseHeght: 25, baseLength: 54 }, { x: 24, y: 0, z: -80.5 }, false)
//创建车间2-1 baseWidth: 147, baseHeght: 30, baseLength: 263 x: -230.5, y: 0, z: 176
createHouse('车间2-1', { baseWidth: 147, baseHeght: 30, baseLength: 263 }, { x: -230.5, y: 0, z: 176 }, false)
createUseWall('车间2-1的墙1', { baseWidth: 1, baseHeght: 30, baseLength: 227 }, { x: -237, y: 0, z: 269.5 })
createUseWall('车间2-1的墙2', { baseWidth: 32, baseHeght: 30, baseLength: 1 }, { x: -207, y: 0, z: 147.5 })
createUseWall('车间2-1的墙3', { baseWidth: 27, baseHeght: 30, baseLength: 1 }, { x: -158, y: 0, z: 147.5 })
createUseWall('车间2-1的墙4', { baseWidth: 32, baseHeght: 30, baseLength: 1 }, { x: -207, y: 0, z: 183.5 })
createUseWall('车间2-1的墙5', { baseWidth: 27, baseHeght: 30, baseLength: 1 }, { x: -158, y: 0, z: 183.5 })
//汽车军团
const mesh_qcjt = createFloor(t('messages.QiCheLegion'), 67, 263, { x: -270.5, y: 0, z: 176 })
createLableObj(mesh_qcjt, t('messages.QiCheLegion'), { x: 0, y: 60, z: 0 })
//精加车间
const mesh_jjcj = createFloor('精加车间', 82, 263, { x: -198, y: 0, z: 176 })
createLableObj(mesh_jjcj, t('messages.JingJiaRoom'), { x: 0, y: 60, z: 0 })
//创建车间2-2 baseWidth: 95, baseHeght: 30, baseLength: 263 x: -84.5, y: 0, z: 176
createHouse(t('messages.JiJiaRoom'), { baseWidth: 95, baseHeght: 30, baseLength: 263 }, { x: -84.5, y: 0, z: 176 })
//创建精饰车间 baseWidth: 161, baseHeght: 30, baseLength: 263 x: 65.5, y: 0, z: 176
createHouse('车间2-3', { baseWidth: 161, baseHeght: 30, baseLength: 263 }, { x: 65.5, y: 0, z: 176 }, false)
createUseWall('车间2-3的墙1', { baseWidth: 1, baseHeght: 30, baseLength: 263 }, { x: 60, y: 0, z: 307 })
//大件车间
const mesh_djcj = createFloor('大件车间', 75, 263, { x: 22, y: 0, z: 176 })
createLableObj(mesh_djcj, t('messages.DaJianRoom'), { x: 0, y: 60, z: 0 })
//精饰车间
const mesh_jscj = createFloor('精饰车间', 88, 263, { x: 101.5, y: 0, z: 176 })
createLableObj(mesh_jscj, t('messages.JingShiRoom'), { x: 0, y: 60, z: 0 })
// //料场
// createHouse('料场', { baseWidth: 82, baseHeght: 30, baseLength: 263 }, { x: 187, y: 0, z: 176 }, false)
// createUseWall('料场中间的墙', { baseWidth: 82, baseHeght: 30, baseLength: 1 }, { x: 228, y: 0, z: 183.5 })
createUseWall('料场后面的墙', { baseWidth: 82, baseHeght: 30, baseLength: 1 }, { x: 228, y: 0, z: 308 })
const mesh_lc = createFloor('料场', 84, 131, { x: 188, y: 0, z: 110 })
createLableObj(mesh_lc, t('messages.料场'), { x: 0, y: 60, z: 0 })
const mesh_wfzcq = createFloor('料场', 84, 132, { x: 188, y: 0, z: 242 })
createLableObj(mesh_wfzcq, t('messages.危废暂存间'), { x: 0, y: 60, z: 0 })
//精饰车间内的房子
createHouse(t('messages.ManualSandblastingRoom'), { baseWidth: 26, baseHeght: 30, baseLength: 28 }, { x: 73.62, y: 0, z: 59.15 })
createHouse(`${t('messages.DryingRoom')}B`, { baseWidth: 28, baseHeght: 30, baseLength: 46 }, { x: 130.77, y: 0, z: 67.69 })
createHouse(t('messages.GrindingRoom'), { baseWidth: 24, baseHeght: 30, baseLength: 42 }, { x: 132.77, y: 0, z: 141.03 })
createHouse('冷冻式空气干燥机', { baseWidth: 14, baseHeght: 20, baseLength: 18 }, { x: 66.69, y: 0, z: 123.32 }, false)
createHouse('喷砂罐', { baseWidth: 14, baseHeght: 20, baseLength: 18 }, { x: 66.69, y: 0, z: 158.41 }, false)
createHouse('抛丸机', { baseWidth: 19, baseHeght: 20, baseLength: 74 }, { x: 83.84, y: 0, z: 144.21 }, false)
createHouse(t('messages.PowderSprayingRoom'), { baseWidth: 32, baseHeght: 20, baseLength: 65 }, { x: 75.94, y: 0, z: 235.64 })
createHouse(t('messages.DaJianPaintingRoom'), { baseWidth: 27, baseHeght: 20, baseLength: 44 }, { x: 132.10, y: 0, z: 220.20 })
//创建焊接车间 baseWidth: 85, baseHeght: 30, baseLength: 263 x: 224, y: 0, z: 176
createHouse(t('messages.HanJieRoom'), { baseWidth: 85, baseHeght: 30, baseLength: 263 }, { x: 271, y: 0, z: 176 })
createHouse(t('messages.boilerRoom'), { baseWidth: 25, baseHeght: 20, baseLength: 30 }, { x: 299.30, y: 0, z: 60.87 })
//创建食堂 baseWidth: 71, baseHeght: 30, baseLength: 124 x: 312.5, y: 0, z: 221.5
createHouse(t('messages.canteen'), { baseWidth: 71, baseHeght: 30, baseLength: 124 }, { x: 359.5, y: 0, z: 221.5 })
//创建宿舍楼3 baseWidth: 56, baseHeght: 30, baseLength: 216 x: 393, y: 0, z: -147
createHouse(`${t('messages.EmployeeApartment')}-9`, { baseWidth: 56, baseHeght: 30, baseLength: 216 }, { x: 440, y: 0, z: -147 })
//创建宿舍楼1 baseWidth: 56, baseHeght: 30, baseLength: 132 x: 389, y: 0, z: 106.5
createHouse(`${t('messages.EmployeeApartment')}-10`, { baseWidth: 56, baseHeght: 30, baseLength: 132 }, { x: 440, y: 0, z: 106.5 })
//创建宿舍楼2 baseWidth: 56, baseHeght: 30, baseLength: 132 x: 389, y: 0, z: 106.5
createHouse(`${t('messages.EmployeeApartment')}-11`, { baseWidth: 56, baseHeght: 30, baseLength: 132 }, { x: 440, y: 0, z: 243.5 })
//创建围墙 baseWidth: 966, baseHeght: 5, baseLength: 677 x: 24, y: 0, z: 0
createHouse('围墙', { baseWidth: 1013, baseHeght: 15, baseLength: 677 }, { x: 0, y: 0, z: 0 }, false)
//创建东气泵房 baseWidth: 23, baseHeght: 30, baseLength: 16 x: -119.5, y: 0, z: 313.5
createHouse(t('messages.eastAirPumpRoom'), { baseWidth: 23, baseHeght: 25, baseLength: 16 }, { x: -119.5, y: 0, z: 316.5 })
createTitleFloor('', 464, 45, { x: 0, y: 0, z: 15 })
//放置服务器
createGlb()
/*放置光猫************/
//汽车军团
createSwitch({ x: -287.44, y: 0, z: 19.24 })
//精加车间
createSwitch({ x: -158.01, y: 0, z: 107.47 })
createSwitch({ x: -208.35, y: 0, z: 107.47 })
//机加车间
createSwitch({ x: -40.22, y: 0, z: 19.90 })
//电控分厂
createSwitch({ x: -232.96, y: 0, z: -64.48 })
//大配套中心
createSwitch({ x: 29.01, y: 0, z: -60.75 })
//大件车间
createSwitch({ x: 5.29, y: 0, z: 19.00 })
//家纺 医防
createSwitch({ x: 88.55, y: 0, z: -214.89 })
//二道岗
createSwitch({ x: 306.5, y: 0, z: 5.43 })
/*光猫结束********************************* */
/**创建ac */
createAc({x:52.56,y:0,z:52.24})
//服装军团
createAc({x:-88.39,y:0,z:-249.36})
createAc({x:82.99,y:0,z:-170.17})
/**创建AC结束 */
/*创建wifi */
//机加
createWifi({ x: -46.96, y: 2, z: 156.57 })
//大件
createWifi({ x: 52.60, y: 2, z: 96.44 })
createWifi({ x: 52.60, y: 2, z: 157.07 })
//精饰
createWifi({ x: 133.14, y: 2, z: 107.43 })
createWifi({ x: 133.14, y: 2, z: 156.25 })
//焊接
createWifi({ x: 305.73, y: 2, z: 110.45 })
createWifi({ x: 305.73, y: 2, z: 238.67 })
//服装
createWifi({ x: -89.13, y: 4, z: -245.33 })
createWifi({ x: -132.07, y: 2, z: -245.33 })
createWifi({ x: -222.31, y: 2, z: -245.33 })
createWifi({ x: -119.3, y: 2, z: -114.15 })
createWifi({ x: -176.45, y: 2, z: -114.40 })
//家纺 医防
createWifi({ x: 140.83, y: 2, z: -197.34 })
createWifi({ x: 259.37, y: 2, z: -197.34 })
createWifi({ x: 140.83, y: 2, z: -111.84 })
createWifi({ x: 259.50, y: 2, z: -111.81 })
/*创建第一条线******************/
let garyLine = 0x595959;
let whiteColor = 0xffffff;
createLine(whiteColor, [{ x: -346.00, y: 23.6, z: 59.40 }, { x: -160.50, y: 2, z: 142.08 }], 2)
//服装
createLine(whiteColor, [
{ x: -345.65, y: 2, z: 36.40 },
{ x: 22.67, y: 2, z: 36.40 },
{ x: 22.67, y: 2, z: -25.70 },
], 2)
createLine(garyLine, [
{ x: 22.67, y: 2, z: -25.70 },
{ x: -47.67, y: 2, z: -25.70 },
{ x: -47.67, y: 2, z: -248.85 },
{ x: -221.76, y: 2, z: -248.85 }
])
createLine(garyLine, [{x:-88.73,y:2,z:-249.01},{x:-88.73,y:2,z:-117.33} , { x: -174.65, y: 2, z: -117.33 }])
//汽车军团
createLine(whiteColor, [{ x: -293.44, y: 2, z: 52.52 }, { x: -293.44, y: 2, z: 36.40 }, { x: -235.84, y: 2, z: -30.87 }], 2)
//机加
createLine(whiteColor, [
{ x: -114.64, y: 2, z: 36.40 },
{ x: -114.64, y: 2, z: 52.42 },
{ x: -46.13, y: 2, z: 52.90 },
], 2)
createLine(garyLine, [
{ x: -46.13, y: 2, z: 52.90 },
{ x: -46.13, y: 2, z: 153.05 }
])
//家纺医防
createLine(garyLine, [
{ x: 27.47, y: 2, z: -26.11 },
{ x: 27.47, y: 2, z: -248.85 },
{ x: 69.26, y: 2, z: -248.85 },
{ x: 69.26, y: 2, z: -180.29 },
{ x: 85.51, y: 2, z: -180.29 },
{ x: 141.66, y: 2, z: -200.86 },
{ x: 260.42, y: 2, z: -200.86 },
{ x: 260.42, y: 2, z: -115.33 },
{ x: 141.66, y: 2, z: -115.33 },
{ x: 141.66, y: 2, z: -200.86 },
])
//创建第二条线
//横线 主干道
createLine(whiteColor, [
{ x: -341.87, y: 2, z: 30.98 },
{ x: 111.97, y: 2, z: 30.98 },
{ x: 111.97, y: 2, z: 175.55 },
{ x: 294.54, y: 2, z: 175.55 },
{ x: 294.54, y: 2, z: 40.43 },
{ x: 306.56, y: 2, z: 40.43 }
], 2)
createLine(garyLine, [
{ x: 306.56, y: 2, z: 40.43 },
{ x: 306.56, y: 2, z: 235.28 }
])
//精加
createLine(whiteColor, [
{ x: -164.26, y: 2, z: 30.98 },
{ x: -164.26, y: 2, z: 140.05 }
],2)
createLine(garyLine, [
{ x: -164.26, y: 2, z: 140.05 },
{ x: -214.35, y: 2, z: 140.05 }
])
//大件 总---精饰
createLine(garyLine, [
{ x: 26.61, y: 2, z: -27.08 },
{ x: 26.61, y: 2, z: 39.27 },
{ x: -0.90, y: 2, z: 39.27 },
{x:-0.90,y:2,z:52.24},
{ x: 133.97, y: 2, z: 53.16 },
{ x: 133.97, y: 2, z: 154.31 }
])
//大件 分
createLine(garyLine, [
{ x: 53.43, y: 2, z: 53.16 },
{ x: 53.43, y: 2, z: 154.31 }
])
/**
*
{ x: 26.61, y: 2, z: -27.08 },
{ x: 26.61, y: 2, z: 39.27 },
{ x: -0.90, y: 2, z: 39.27 },
{ x: 53.43, y: 2, z: 154.31 }
*/
//电控
createLine(whiteColor, [
{ x: -292.24, y: 2, z: 30.98 },
{ x: -242.61, y: 2, z: -30.90 }
], 2)
//家纺 医防
createLine(whiteColor, [
{ x: 18.30, y: 2, z: 30.98 },
{ x: 18.30, y: 2, z: -28.94 }
], 2)
//家纺 医防
createLine(garyLine, [
{ x: 18.30, y: 2, z: -28.94 },
{ x: 25.64, y: 2, z: -28.94 },
{ x: 25.64, y: 2, z: -251.40 },
{ x: 71.44, y: 2, z: -251.40 },
{ x: 71.44, y: 2, z: -183.05 },
{ x: 83.96, y: 2, z: -183.05 }
])
createLine(whiteColor, [
{ x: 18.30, y: 2, z: 30.98 },
{ x: 18.30, y: 2, z: -28.94 }
],2)
setTipDom()
sethoveMesh()
//创建综合楼
//创建天空盒
createSkyBox()
const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();
function onPointerMove(event: any) {
// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
pointer.x = (event.clientX / iw) * 2 - 1;
pointer.y = -(event.clientY / ih) * 2 + 1;
}
//animate()
//鼠标在canvas画布上点击事件
labelRenderer.domElement.addEventListener('mouseup', function (event: any) {
clearInterval(timer)
// .offsetY、.offsetX以canvas画布左上角为坐标原点,单位px
const px = event.offsetX;
const py = event.offsetY;
//屏幕坐标px、py转WebGL标准设备坐标x、y
//width、height表示canvas画布宽高度
const x = (px / iw) * 2 - 1;
const y = -(py / ih) * 2 + 1;
// console.log("鼠标点击位置", "x:" + x, "y:" + y);
// console.log("鼠标点击位置", "px:" + px, "py:" + py);
//创建一个射线投射器`Raycaster`
const raycaster = new THREE.Raycaster();
//.setFromCamera()计算射线投射器`Raycaster`的射线属性.ray
// 形象点说就是在点击位置创建一条射线,射线穿过的模型代表选中
raycaster.setFromCamera(new THREE.Vector2(x, y), camera);
//.intersectObjects([mesh1, mesh2, mesh3])对参数中的网格模型对象进行射线交叉计算
// 未选中对象返回空数组[],选中一个对象数组1个元素选中两个对象数组两个元素
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
var selected = intersects[0]; //取第一个物体
console.log("坐标", "{x:" + selected.point.x.toFixed(2) + ",y:" + (selected.point.y.toFixed(2) - 1) + ",z:" + selected.point.z.toFixed(2) + "}", selected.object.name);
// console.log("非正常坐标", "{x:" + (+selected.point.x - 0.83).toFixed(2) + ",y:2 ,z:" + (selected.point.z + 3.52).toFixed(2) + "}");
let workerShop = intersects[0]?.object?.name
if (workerShopRoute.hasOwnProperty(workerShop) && !edit) {
router.push({ path: workerShopRoute[workerShop] })
}
}
// console.log("点击了", intersects[0]?.object?.name);
// intersects.length大于0说明说明选中了模型
// if (intersects.length > 0) {
// // 选中模型的第一个模型,设置为红色
// intersects[0].object.material.color.set(0xff0000);
// }
renderer.render(scene, camera)
})
controls.target = new THREE.Vector3(0, 0, 0)
// const raycaster = new THREE.Raycaster()
let mouse = new THREE.Vector2()
let intersects = null
labelRenderer.domElement.addEventListener('dblclick', function (event: any) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
intersects = raycaster.intersectObject(scene, true);
if (intersects.length > 0) {
let boxMaxY = new THREE.Box3().setFromObject(intersects[0].object).max.y
let distance = boxMaxY + 200
let angel = Math.PI / 3.5
let position = {
x: intersects[0].object.position.x + Math.cos(angel) * distance,
y: intersects[0].object.position.y + Math.cos(angel) * distance,
z: intersects[0].object.position.z + Math.sin(angel) * distance
}
let tween = new TWEEN.Tween(camera.position).to(position, 1000)
let tween1 = new TWEEN.Tween(controls.target).to(intersects[0].object.position, 1000)
controls.enabled = false;
tween.onComplete(function () {
controls.enabled = true;
})
// console.log("点击了", intersects[0]?.object?.name);
tween.start()
tween1.start()
}
});
//控制对象的透明度来实现闪烁效果
function reader(torus: any) {
if (torus.startVal > 1) {
torus.direction = 'down'
}
if (torus.startVal < 0) {
torus.direction = 'up'
}
if (torus.direction === 'up') {
torus.startVal += 0.01
torus.material.opacity = torus.startVal
} else {
torus.startVal -= 0.01
torus.material.opacity = torus.startVal
}
// console.log(torus.material.opacity);
}
//定制渲染函数
let T0 = +new Date() //设置时间差
function render() {
let T1 = +new Date()
// let t = T1 - T0 //获取时间间隔
renderer.render(scene, camera)
//旋转立方体,每次绕y轴旋转0.01弧度每一秒渲染0.001弧度
//box.rotateY(0.001 * t)
// if (t >= 2000) {
// return
// }
boxObjects.value.forEach((element: any) => {
let color1 = 0x88e76a
let color2 = 0xff0000
//判断是否是更新的传感器数据
if (store.updateSensorData.hasOwnProperty(element.sensor_id)) {
// console.log(store.updateSensorData,'store.updateSensorData');
// console.log(element,'element');
let color = store.updateSensorData[element.sensor_id].status ? color1 : color2
element.devStatus = store.updateSensorData[element.sensor_id].status
element.material.color = new THREE.Color(color)
}
// reader(element)
});
TWEEN.update()
controls.update()
labelRenderer.render(scene, camera)
store.clearupdateSensorData()
// reader(mesh_qcjt)
window.requestAnimationFrame(render) //避免掉帧,就是一帧接一帧,逐帧,预备加载下一帧
}
render()
}
//创建线
function createLine(color: number, pointsList: any, width: number = 4) {
// const material = new THREE.LineBasicMaterial({ color: color });
// const points = [];
// pointsList.forEach(element => {
// points.push(new THREE.Vector3(element.x, element.y, element.z));
// });
// const geometry = new THREE.BufferGeometry().setFromPoints(points);
// const line = new THREE.Line(geometry, material);
// scene.add(line);
// renderer.render(scene, camera);
const geometry = new LineGeometry()
let pointList = []
pointsList.forEach(element => {
let { x, y, z } = element
let arr = [x, y, z]
pointList.push(...arr)
});
geometry.setPositions(pointList)
const material = new LineMaterial({
color: color,
transparent: true,
// opacity: 0.5,
dashed: width !== 2?true:false,
dashScale: 1,
dashSize: 3,
gapSize: 1,
linewidth: width
})
//console.log(material,'material');
material.resolution.set(iw, ih)
// 5. 创建 Line2
var line = new Line2(geometry, material);
// 6. 计算下线条长度
line.computeLineDistances();
// 7. 添加到场景
scene.add(line)
}
//创建wifi
function createWifi(position: positionType) {
const loader = new GLTFLoader();
loader.load('/models/glb/tothefuture_wifi.glb', function (gltf) {
const mesh = gltf.scene.children[0];
const s = 0.3;
mesh.scale.set(s, s, s);
mesh.position.set(position.x, position.y, position.z);
// mesh.rotation.x = THREE.MathUtils.degToRad(270)
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
}, undefined, function (error) {
console.error(error);
});
}
//创建交换机
// function createSwitch(position: positionType, scale: number = 0.2) {
// const loader = new GLTFLoader();
// loader.load('/models/gltf/scene.gltf', function (gltf) {
// const mesh = gltf.scene.children[0];
// const s = scale;
// mesh.scale.set(s, s, 0.5);
// mesh.position.set(position.x-12.75, position.y, position.z+66.22);
// mesh.rotation.z = THREE.MathUtils.degToRad(180)
// // mesh.rotation.y = THREE.MathUtils.degToRad(90)
// // mesh.rotation.x = THREE.MathUtils.degToRad(45)
// mesh.castShadow = true;
// mesh.receiveShadow = true;
// scene.add(mesh);
// }, undefined, function (error) {
// console.error(error);
// });
// }
const createSwitch = (boxposition: positionType, shadow: boolean = true): object => {
const wallTexture = new THREE.TextureLoader().load(requires.guangmao);
const wall = new THREE.BoxGeometry(15, 5, 10);
const wallMaterial = new THREE.MeshPhongMaterial({
map: wallTexture,
color: 0xe7e7e7,
transparent: true,
});
//墙体的网格
const wallMesh = new THREE.Mesh(wall, wallMaterial);
// 物体移动位置
// wallMesh.position.set((-size.baseWidth / 2 + boxposition.x + 1), size.baseHeght / 2 + boxposition.y, -size.baseLength / 2 + boxposition.z);
wallMesh.position.set(boxposition.x - 6, 5 + boxposition.y, boxposition.z + 33.73);
// 将立方体添加到场景中
group.add(wallMesh)
return wallMesh
}
const createAc = (boxposition: positionType, shadow: boolean = true): object => {
const wallTexture = new THREE.TextureLoader().load(requires.ac);
const wall = new THREE.BoxGeometry(15, 5, 10);
const wallMaterial = new THREE.MeshPhongMaterial({
map: wallTexture,
color: 0xe7e7e7,
transparent: true,
});
//墙体的网格
const wallMesh = new THREE.Mesh(wall, wallMaterial);
// 物体移动位置
// wallMesh.position.set((-size.baseWidth / 2 + boxposition.x + 1), size.baseHeght / 2 + boxposition.y, -size.baseLength / 2 + boxposition.z);
wallMesh.position.set(boxposition.x, 5 + boxposition.y, boxposition.z);
// 将立方体添加到场景中
group.add(wallMesh)
return wallMesh
}
//创建服务器
function createGlb() {
const loader = new GLTFLoader();
loader.load('/models/glb/server.glb', function (gltf) {
const mesh = gltf.scene.children[0];
const s = 0.12;
mesh.scale.set(s, s, s);
mesh.position.set(-346, 0, 51);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
}, undefined, function (error) {
console.error(error);
});
}
type positionType = {
x: number,
y: number,
z: number
}
//创建房子
function createHouse(houseName: string, size = { baseWidth: 40, baseHeght: 4, baseLength: 60 }, position: positionType = { x: 80, y: 1, z: 0 }, isFloor = true) {
const { baseWidth, baseHeght, baseLength } = size
const { x, y, z } = position;
const faWallPosition = [-baseWidth / 2 + x, 0, -baseLength / 2 + z]
if (isFloor) {
//创建地板
if (houseName == t('messages.JiJiaRoom')) {
const mesh = createFloor('机加车间', baseWidth, baseLength, position)
createLableObj(mesh, t('messages.JiJiaRoom'), { x: 0, y: 60, z: 0 })
} else if (houseName == t('messages.HanJieRoom')) {
const mesh = createFloor('焊接车间', baseWidth, baseLength, position)
createLableObj(mesh, t('messages.HanJieRoom'), { x: 0, y: 60, z: 0 })
} else {
const mesh = createFloor(houseName, baseWidth, baseLength, position)
createLableObj(mesh, houseName, { x: 0, y: 60, z: 0 })
}
}
//创建左右墙
let leftWall = createWall(1, baseHeght, baseLength)
leftWall.name = houseName + '左侧的墙'
leftWall.rotateY(Math.PI / 2);
leftWall.position.set((-baseWidth / 2 + x + 1), baseHeght / 2 + y, z);
group.add(leftWall)
const rightWall = leftWall.clone();
rightWall.position.set((baseWidth / 2 + x), baseHeght / 2 + y, z);
rightWall.name = houseName + "右侧的墙";
group.add(rightWall);
//创建前后墙
const frontWall = createWall(1, baseHeght, baseWidth)
frontWall.position.set((1 / 2 + x), baseHeght / 2 + y, (baseLength / 2 + z));
frontWall.name = houseName + "前方的墙";
group.add(frontWall);
const rearWall = frontWall.clone();
rearWall.position.set((1 / 2 + x), baseHeght / 2 + y, (-baseLength / 2 + z));
rearWall.name = houseName + "后方的墙";
group.add(rearWall);
// //不带门的墙
// createNoDoorWall(baseWidth,baseHeght,baseLength,position)
// //创建带门的墙
// createDoorWall(baseWidth,baseHeght,baseLength,position)
// let { roof, width } = createRoof(baseWidth,baseHeght,baseLength,position);
// let leftRoof = roof.clone();
// leftRoof.rotateX(THREE.MathUtils.degToRad(30));
// leftRoof.position.set(-baseWidth / 3 + 1+x, baseHeght+2+y, z);
// leftRoof.name = "左屋顶";
// group.add(leftRoof);
// //创建门
// createDoor(baseWidth,baseLength,position)
}
// 新建2D标签
function createLableObj(mesh: any, text: string, vector: positionType) {
let laberDiv = document.createElement('div');//创建div容器
laberDiv.className = 'laber_name';
laberDiv.textContent = text;
let pointLabel = new CSS2DObject(laberDiv);
pointLabel.position.set(vector.x, vector.y, vector.z);
mesh.add(pointLabel);
}
type sizeType = {
baseWidth: number,
baseHeght: number,
baseLength: number
}
//创建能用的墙
function createUseWall(name: string, size: sizeType, position: positionType, issensor: boolean = false): void {
let Wall = createWall(size.baseWidth, size.baseHeght, size.baseLength)
Wall.name = name
Wall.rotateY(Math.PI / 2);
Wall.position.set((-size.baseWidth / 2 + position.x + 1), size.baseHeght / 2 + position.y, -size.baseLength / 2 + position.z);
group.add(Wall)
return Wall
}
/**
* 创建立方体 用作传感器
* @param size 立方体的长宽高
* @param boxposition 立方体的位置
* @param boxcolor 立方体的颜色
* @param shadow 是否渲染到阴影贴图当中
*/
const createBox = (size: sizeType, boxposition: positionType, boxcolor: number, shadow: boolean = true, result: any = {}, icon: string): object => {
const wallTexture = new THREE.TextureLoader().load(requires[icon]);
const wall = new THREE.BoxGeometry(size.baseWidth, size.baseHeght, size.baseLength);
const wallMaterial = new THREE.MeshPhongMaterial({
map: wallTexture,
color: boxcolor,
transparent: true,
});
//墙体的网格
const wallMesh = new THREE.Mesh(wall, wallMaterial);
// 绑定自定义数据 添加标签
wallMesh.name = result.name
wallMesh.devStatus = result.status
wallMesh.direction = 'up'
wallMesh.startVal = 1
//用于更新状态判断
wallMesh.sensor_id = result.id
// 物体移动位置
// wallMesh.position.set((-size.baseWidth / 2 + boxposition.x + 1), size.baseHeght / 2 + boxposition.y, -size.baseLength / 2 + boxposition.z);
wallMesh.position.set(boxposition.x, size.baseHeght / 2 + boxposition.y, boxposition.z);
// 对象是否渲染到阴影贴图当中
wallMesh.castShadow = shadow;
// 将立方体添加到场景中
group.add(wallMesh)
boxObjects.value.push(wallMesh)
return wallMesh
}
//创建地面
function createGround() {
//require('@/assets/img/Factory/cao.png')
//导入材质
const groundTexture = new THREE.TextureLoader().load(requires.ny);
groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
groundTexture.repeat.set(100, 100);
const ground = new THREE.PlaneGeometry(1014, 681);
const groundMaterial = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
map: groundTexture,
// color: 0x00ff00,
// transparent: true,
// opacity: 0.2,
});
const groundMesh = new THREE.Mesh(ground, groundMaterial);
groundMesh.name = "地面";//设置name属性
groundMesh.rotateX(-Math.PI / 2);//旋转用于呈现一个水平的地面
scene.add(groundMesh);
}
//创建标题地板
function createTitleFloor(houseName: string, baseWidth: number, baseLength: number, position: positionType) {
const texture = new THREE.TextureLoader().load(requires.titleFloor);
//设置地板大小由于后面将要生成墙体存在设置为1的厚度因此这里对地板的xz均-2
const floor = new THREE.BoxGeometry(baseWidth - 2, 1, baseLength);
const material = new THREE.MeshPhongMaterial({ map: texture, transparent: true });
const mesh = new THREE.Mesh(floor, material);
const { x, y, z } = position
mesh.position.set(x, y + 1 / 2, z);
mesh.name = houseName + "地板";
group.add(mesh);
return mesh;
}
//创建地板,可以理解为地基
function createFloor(houseName: string, baseWidth: number, baseLength: number, position: positionType) {
const texture = new THREE.TextureLoader().load(requires.wood);
//设置地板大小由于后面将要生成墙体存在设置为1的厚度因此这里对地板的xz均-2
const floor = new THREE.BoxGeometry(baseWidth - 2, 1, baseLength);
const material = new THREE.MeshPhongMaterial({ map: texture, transparent: true });
const mesh = new THREE.Mesh(floor, material);
const { x, y, z } = position
mesh.position.set(x, y + 1 / 2, z);
mesh.name = houseName + "地板";
group.add(mesh);
return mesh;
}
//创建左右两边墙体
function createWall(baseWidth: number = 10, baseHeght: number, baseLength: number) {
const wallTexture = new THREE.TextureLoader().load(requires.wall1);
const wall = new THREE.BoxGeometry(baseLength, baseHeght, baseWidth);
const wallMaterial = new THREE.MeshPhongMaterial({
map: wallTexture,
color: 0xffffff,
transparent: true,
});
//墙体的网格
const wallMesh = new THREE.Mesh(wall, wallMaterial);
return wallMesh;
}
//不规则墙体
function genwallShape(baseWidth: number, baseHeght: number, baseLength: number) {
const shape = new THREE.Shape();
let height = baseHeght;//墙的高度
shape.moveTo(0, 0); //起点
shape.lineTo(0, height); //墙体高度
shape.lineTo(baseWidth / 2 - 1, height + 5); //墙体顶点
shape.lineTo(baseWidth / 2 - 1, height + 6); //墙体顶点
shape.lineTo(baseWidth / 2 + 1, height + 6); //墙体顶点
shape.lineTo(baseWidth / 2 + 1, height + 5); //墙体顶点
shape.lineTo(baseWidth, height);
shape.lineTo(baseWidth, 0);
shape.lineTo(0, 0);
return { shape };
}
//创建不规则墙体
function createIrregularWall(shape: any, position: any) {
const extrudeSettings = {
depth: 1,//定义深度由于挤压几何体的点位都是xy坐标组成的二位平面这个参数定义向z轴的延展长度即为墙的厚度
bevelEnabled: false,
};
const wallTexture = new THREE.TextureLoader().load(requires.wall1);
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
wallTexture.wrapS = wallTexture.wrapT = THREE.RepeatWrapping;
wallTexture.repeat.set(0.05, 0.05);
const material = new THREE.MeshPhongMaterial({ map: wallTexture });
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(...position);
group.add(mesh);
return mesh;
}
//创建不带门的不规则墙体
function createNoDoorWall(baseWidth: number, baseHeght: number, baseLength: number, position: positionType) {
const { x, y, z } = position
let { shape } = genwallShape(baseWidth, baseHeght, baseLength);
let mesh = createIrregularWall(shape, [-baseWidth / 2 + x, 0, -baseLength / 2 + z]);
mesh.name = "带门的墙对面的墙";
}
//带门的墙体
function createDoorWall(baseWidth: number, baseHeght: number, baseLength: number, position: positionType) {
const { x, y, z } = position
const shape = new THREE.Shape();
const door = new THREE.Path();
//门的位置
door.moveTo(baseWidth / 2 + 5, 0);
door.lineTo(baseWidth / 2 + 5, 5);
door.lineTo(baseWidth / 2 - 5, 6);
door.lineTo(baseWidth / 2 - 5, 0);
door.lineTo(baseWidth / 2 + 5, 0);
// 形状上的孔洞
shape.holes.push(door);
let mesh = createIrregularWall(shape, [
-baseWidth / 2 + x,
y,
baseLength / 2 - 1 + z,
]);
mesh.name = "带门的墙";
}
//创建屋顶
function createRoof(baseWidth: number, baseHeght: number, baseLength: number, position: positionType) {
const { x, y, z } = position
//屋顶宽
let width = Math.sqrt((baseWidth / 2) ** 2 + 5 ** 2) + 5;//+5让有一点屋檐的效果
const geometry = new THREE.BoxGeometry(baseLength / 2, width, 1);
const texture = new THREE.TextureLoader().load(requires.tile);
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(2, 2);
const material = new THREE.MeshPhongMaterial({ map: texture });
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateZ(THREE.MathUtils.degToRad(75));
mesh.rotateY(-Math.PI / 2);
mesh.position.set(baseWidth / 3 - 1 + x, baseHeght + 2 + y, 0 + z);
mesh.name = "右屋顶";
group.add(mesh);
return { roof: mesh, width };
}
//创建门
function createDoor(baseWidth: number, baseLength: number, position: positionType) {
const { x, y, z } = position;
const texture = new THREE.TextureLoader().load(requires.door);
const door = new THREE.BoxGeometry(3, 5, 0.5);
const material = new THREE.MeshPhongMaterial({
map: texture,
transparent: true,
opacity: 1,
});
const doorMesh = new THREE.Mesh(door, material);
// doorMesh.rotateY(Math.PI / 2);
// doorMesh.position.set(-baseLength / 2, 7, 0);
doorMesh.name = "门";
//以下代码做出了更改
const doorGroup = new THREE.Group();//添加一个门的父级
doorGroup.name = "门的包裹";
doorGroup.position.set(-5 + x, 8 + y, baseLength / 2 + z);//通过父级来改变门的旋转轴
//现在这个是相对于父级
doorMesh.position.x = 5;
doorGroup.add(doorMesh);
group.add(doorGroup);
return doorGroup;
}
//天空盒
function createSkyBox() {
const texture = new THREE.TextureLoader().load(requires.sky);
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
// texture.repeat.set(1, 1);
const skyBox = new THREE.SphereGeometry(900, 100, 100);
const material = new THREE.MeshPhongMaterial({
map: texture,
side: THREE.BackSide,
});
const skyBoxMesh = new THREE.Mesh(skyBox, material);
scene.add(skyBoxMesh);
}
function setTipDom() {
const domTag = document.createElement("div");
domTag.setAttribute("id2", "tipId");
// domTag.innerText='电流'
domTag.style.fontSize = "14px";
domTag.style.backgroundColor = "rgba(0,0,0,.5)";
domTag.style.padding = "5px";
domTag.style.borderRadius = "2px";
domTag.style.color = "#fff";
domTag.style.visibility = "hidden";
// domTag.innerText = mesh.name;
const iTagDomCss3 = new CSS2DObject(domTag);
iTagDomCss3.position.z = 2;
iTagDomCss3.position.y = 0;
scene.add(iTagDomCss3);
saveTipDom = iTagDomCss3;
}
//3D标签初始化
// function initCss3DScene() {
// cssRender = new CSS3DRenderer();
// cssRender.setSize(iw, ih);
// cssRender.domElement.style.position = "absolute";
// cssRender.domElement.style.top = '0';
// cssRender.domElement.style.outline = "none";
// cssRender.domElement.className = "cssrender";
// canvas.appendChild(cssRender.domElement);
// }
function sethoveMesh() {
dragControls = new DragControls(
boxObjects.value,
camera,
labelRenderer.domElement
);
if (!edit) {
dragControls.deactivate();
}
dragControls.addEventListener("hoveron", function (event: any) {
saveTipDom.element.innerHTML = `${event.object.name}:${event.object.devStatus ? t('messages.onLine') : t('messages.offline')
}`;
saveTipDom.element.style.visibility = "visible";
saveTipDom.position.x = event.object.position.x;
saveTipDom.position.y = event.object.position.y + 5;
saveTipDom.position.z = event.object.position.z - 20;
saveTipDom.visible = true;
});
dragControls.addEventListener("hoveroff", function (event: any) {
saveTipDom.element.style.visibility = "hidden";
saveTipDom.position.x = 0;
saveTipDom.position.y = 9999;
saveTipDom.visible = false;
});
dragControls.addEventListener("dragend", function (event: any) {
let data = { 'id': event.object.sensor_id, 'x': event.object.position.x.toFixed(2), 'y': event.object.position.z.toFixed(2) }
updateCoordinateByPoint(data).then((res: any) => {
if (res.code == 200) {
ElNotification({
message: '移动位置成功',
duration: 2000,
type: 'success'
})
}
})
});
}
onMounted(() => {
// console.log(container.value.offsetWidth,'container');
//初始化场景
init()
/**创建传感器 */
getSensorDataTimer = setInterval(() => {
if (store.sensorList.length > 0) {
store.sensorList.forEach((element: any) => {
let state = element.status ? 0x88e76a : 0xff0000;
let wallMesh = createBox(small_size, { x: element.x, y: 0, z: element.y }, state, true, element, element.icon)
});
clearInterval(getSensorDataTimer)
}
}, 100)
getDevDataTimer = setInterval(() => {
if (store.devdataList.length > 0) {
store.devdataList.forEach((element: any) => {
let state = element.status ? 0x88e76a : 0xff0000;
let wallMesh = createBox(small_size, { x: element.x, y: 0, z: element.y }, state, false, element, element.icon)
});
clearInterval(getDevDataTimer)
}
}, 100)
// const length = store.result.length
// //获取store中的数据长度
// setInterval(() => {
// //获得一个随机整数
// const random = Math.floor(Math.random() * length)
// const tempdata: any = store.result[random]
// tempdata.status = !store.result[random]?.status
// store.updateResult(tempdata)
// }, 5000)
})
</script>
<style>
/* @import url("@/assets/iconfont.css"); */
.laber_name {
color: #FFF;
font-family: sans-serif;
padding: 2px;
background: rgba(0, 0, 0, 0.6);
}
</style>