@ -1,955 +0,0 @@
< 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 { CSS3DRenderer , CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js' ;
import { DragControls } from "@/utils/DragControls" ;
/ / i m p o r t { D r a g C o n t r o l s } f r o m ' t h r e e / e x a m p l e s / j s m / c o n t r o l s / D r a g C o n t r o l s . j s ' ;
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'
let { t } = useI18n ( ) ;
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 ; / / 用 作 渲 染 的 c a n v a s
let renderer : any = null ; / / 渲 染 器
let controls : any = null ; / / 控 制 器
let labelRenderer : any = null ; / / 2 D 渲 染 器
let labelControls : any = null ; / / 2 D 控 制 器
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/wood.jpg" ) ,
/ / ' w a l l 1 ' : r e q u i r e ( " @ / a s s e t s / i m g / F a c t o r y / f l o o r 1 . j p e g " ) ,
'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" ) ,
}
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 ;
/ / m a p S i z e . w i d t h = v a l . w i d t h
/ / m a p S i z e . h e i g h t = v a l . h e i g h t
/ / 更 新 修 改 相 机 比 例
container . value . style . width = val . oWidth ;
container . value . style . height = val . oHeight ;
camera . aspect = val . oWidth / val . oHeight ;
/ / 更 新 摄 像 机 的 投 影 矩 阵
camera . updateProjectionMatrix ( ) ;
/ / 处 理 返 回 操 作 时 d o m 层 数 变 多 问 题
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 ) ) ;
/ / 设 置 输 出 c a n v a s 画 面 的 大 小
renderer . setSize ( iw , ih )
/ / 设 置 渲 染 物 体 阴 影
renderer . shadowMap . enabled = true ;
/ / 设 置 2 D 渲 染 器
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 ) ;
/ / 定 位 相 机 , 并 且 指 向 场 景 中 心
camera . position . x = 0 ;
camera . position . y = 820 ; / / 6 5 0
camera . position . z = 0 ; / / 6 0 0
/ / c a m e r a . p o s i t i o n . x = 0 ;
/ / c a m e r a . p o s i t i o n . y = 6 5 0 ; / / 6 5 0
/ / c a m e r a . p o s i t i o n . z = 6 0 0 ; / / 6 0 0
camera . lookAt ( scene . position )
renderer . render ( scene , camera )
/ / 将 渲 染 器 输 出 添 加 h t m l 元 素 中
canvas . appendChild ( renderer . domElement ) ;
/ / 添 加 房 子 的 g r o u p 到 场 景 中
scene . add ( group ) ;
/ / 创 建 c o n t r o l s 对 象 ;
controls = new OrbitControls ( camera , labelRenderer . domElement )
/ / l a b e l C o n t r o l s = n e w O r b i t C o n t r o l s ( c a m e r a , l a b e l R e n d e r e r . d o m E l e m e n t )
/ / 监 听 控 制 器 的 鼠 标 事 件 , 执 行 渲 染 内 容
controls . addEventListener ( 'change' , ( ) => {
clearInterval ( timer )
renderer . render ( scene , camera )
labelRenderer . render ( scene , camera )
} )
/**-------------------------------结束后注释------------------------------------------------- */
controls . mouseButtons = {
/ / L E F T : ,
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 : 136 , y : 0 , z : - 304 } )
/ / 创 建 综 合 楼 b a s e W i d t h : 1 1 4 , b a s e H e g h t : 5 0 , b a s e L e n g t h : 3 5 3 x : - 3 9 7 , y : 0 , z : 1 1
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 } )
/ / 创 建 产 学 研 b a s e W i d t h : 2 1 , b a s e H e g h t : 2 5 , b a s e L e n g t h : 3 2 x : - 4 9 5 , y : 0 , z : - 1 0 2 . 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 } )
/ / 创 建 盈 瑞 安 办 公 区 b a s e W i d t h : 9 0 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 1 5 9 x : - 3 9 9 , y : 0 , z : 2 4 5
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 b a s e W i d t h : 5 7 3 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 2 3 8 x : - 1 7 . 5 , y : 0 , z : - 1 3 7 . 5
createHouse ( '车间1' , { baseWidth : 573 , baseHeght : 30 , baseLength : 238 } , { x : - 17.5 , 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 _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' ) , 200 , 118 , { x : 168.5 , y : 0 , z : - 197 } )
createLableObj ( mesh _jfjt , t ( 'messages.JiaFangLegion' ) , { x : 0 , y : 60 , z : 0 } )
/ / 医 防 军 团
const mesh _yfjt = createFloor ( t ( 'messages.YiFangLegion' ) , 200 , 119 , { x : 168.5 , 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 b a s e W i d t h : 1 4 7 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 2 6 3 x : - 2 3 0 . 5 , y : 0 , z : 1 7 6
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 b a s e W i d t h : 9 5 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 2 6 3 x : - 8 4 . 5 , y : 0 , z : 1 7 6
createHouse ( t ( 'messages.JiJiaRoom' ) , { baseWidth : 95 , baseHeght : 30 , baseLength : 263 } , { x : - 84.5 , y : 0 , z : 176 } )
/ / 创 建 车 间 2 - 3 b a s e W i d t h : 1 6 1 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 2 6 3 x : 6 5 . 5 , y : 0 , z : 1 7 6
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 ( 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 } )
/ / 创 建 车 间 2 - 4 b a s e W i d t h : 8 5 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 2 6 3 x : 2 2 4 , y : 0 , z : 1 7 6
createHouse ( t ( 'messages.HanJieRoom' ) , { baseWidth : 85 , baseHeght : 30 , baseLength : 263 } , { x : 224 , y : 0 , z : 176 } )
createHouse ( t ( 'messages.boilerRoom' ) , { baseWidth : 25 , baseHeght : 20 , baseLength : 30 } , { x : 252.30 , y : 0 , z : 60.87 } )
/ / 创 建 食 堂 b a s e W i d t h : 7 1 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 1 2 4 x : 3 1 2 . 5 , y : 0 , z : 2 2 1 . 5
createHouse ( t ( 'messages.canteen' ) , { baseWidth : 71 , baseHeght : 30 , baseLength : 124 } , { x : 312.5 , y : 0 , z : 221.5 } )
/ / 创 建 宿 舍 楼 3 b a s e W i d t h : 5 6 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 2 1 6 x : 3 9 3 , y : 0 , z : - 1 4 7
createHouse ( ` ${ t ( 'messages.EmployeeApartment' ) } -9 ` , { baseWidth : 56 , baseHeght : 30 , baseLength : 216 } , { x : 393 , y : 0 , z : - 147 } )
/ / 创 建 宿 舍 楼 1 b a s e W i d t h : 5 6 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 1 3 2 x : 3 8 9 , y : 0 , z : 1 0 6 . 5
createHouse ( ` ${ t ( 'messages.EmployeeApartment' ) } -10 ` , { baseWidth : 56 , baseHeght : 30 , baseLength : 132 } , { x : 393 , y : 0 , z : 106.5 } )
/ / 创 建 宿 舍 楼 2 b a s e W i d t h : 5 6 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 1 3 2 x : 3 8 9 , y : 0 , z : 1 0 6 . 5
createHouse ( ` ${ t ( 'messages.EmployeeApartment' ) } -11 ` , { baseWidth : 56 , baseHeght : 30 , baseLength : 132 } , { x : 393 , y : 0 , z : 243.5 } )
/ / 创 建 围 墙 b a s e W i d t h : 9 6 6 , b a s e H e g h t : 5 , b a s e L e n g t h : 6 7 7 x : 2 4 , y : 0 , z : 0
createHouse ( '围墙' , { baseWidth : 966 , baseHeght : 15 , baseLength : 677 } , { x : - 24 , y : 0 , z : 0 } , false )
/ / 创 建 东 气 泵 房 b a s e W i d t h : 2 3 , b a s e H e g h t : 3 0 , b a s e L e n g t h : 1 6 x : - 1 1 9 . 5 , y : 0 , z : 3 1 3 . 5
createHouse ( t ( 'messages.eastAirPumpRoom' ) , { baseWidth : 23 , baseHeght : 25 , baseLength : 16 } , { x : - 119.5 , y : 0 , z : 316.5 } )
/ / 鼠 标 在 c a n v a s 画 布 上 点 击 事 件 问 题 待 解 决
/ / 设 置 3 D 渲 染 器
/ / i n i t C s s 3 D S c e n e ( )
setTipDom ( )
sethoveMesh ( )
/ / 创 建 综 合 楼
/ / 创 建 天 空 盒
createSkyBox ( )
const raycaster = new THREE . Raycaster ( ) ;
const pointer = new THREE . Vector2 ( ) ;
function onPointerMove ( event : any ) {
/ / 将 鼠 标 位 置 归 一 化 为 设 备 坐 标 。 x 和 y 方 向 的 取 值 范 围 是 ( - 1 t o + 1 )
pointer . x = ( event . clientX / iw ) * 2 - 1 ;
pointer . y = - ( event . clientY / ih ) * 2 + 1 ;
}
/ / a n i m a t e ( )
/ / 鼠 标 在 c a n v a s 画 布 上 点 击 事 件
labelRenderer . domElement . addEventListener ( 'mouseup' , function ( event : any ) {
clearInterval ( timer )
/ / . o f f s e t Y 、 . o f f s e t X 以 c a n v a s 画 布 左 上 角 为 坐 标 原 点 , 单 位 p x
const px = event . offsetX ;
const py = event . offsetY ;
/ / 屏 幕 坐 标 p x 、 p y 转 W e b G L 标 准 设 备 坐 标 x 、 y
/ / w i d t h 、 h e i g h t 表 示 c a n v a s 画 布 宽 高 度
const x = ( px / iw ) * 2 - 1 ;
const y = - ( py / ih ) * 2 + 1 ;
console . log ( "鼠标点击位置" , "x:" + x , "y:" + y ) ;
console . log ( "鼠标点击位置" , "px:" + px , "py:" + py ) ;
/ / 创 建 一 个 射 线 投 射 器 ` R a y c a s t e r `
const raycaster = new THREE . Raycaster ( ) ;
/ / . s e t F r o m C a m e r a ( ) 计 算 射 线 投 射 器 ` R a y c a s t e r ` 的 射 线 属 性 . r a y
/ / 形 象 点 说 就 是 在 点 击 位 置 创 建 一 条 射 线 , 射 线 穿 过 的 模 型 代 表 选 中
raycaster . setFromCamera ( new THREE . Vector2 ( x , y ) , camera ) ;
/ / . i n t e r s e c t O b j e c t s ( [ m e s h 1 , m e s h 2 , m e s h 3 ] ) 对 参 数 中 的 网 格 模 型 对 象 进 行 射 线 交 叉 计 算
/ / 未 选 中 对 象 返 回 空 数 组 [ ] , 选 中 一 个 对 象 , 数 组 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 ) + "}" ) ;
let workerShop = intersects [ 0 ] ? . object ? . name
if ( workerShopRoute . hasOwnProperty ( workerShop ) ) {
/ / r o u t e r . p u s h ( { p a t h : w o r k e r S h o p R o u t e [ w o r k e r S h o p ] } )
}
}
console . log ( "点击了" , intersects [ 0 ] ? . object ? . name ) ;
/ / i n t e r s e c t s . l e n g t h 大 于 0 说 明 , 说 明 选 中 了 模 型
/ / i f ( i n t e r s e c t s . l e n g t h > 0 ) {
/ / / / 选 中 模 型 的 第 一 个 模 型 , 设 置 为 红 色
/ / i n t e r s e c t s [ 0 ] . o b j e c t . m a t e r i a l . c o l o r . s e t ( 0 x f f 0 0 0 0 ) ;
/ / }
renderer . render ( scene , camera )
} )
controls . target = new THREE . Vector3 ( 0 , 0 , 0 )
/ / c o n s t r a y c a s t e r = n e w T H R E E . R a y c a s t e r ( )
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 ;
} )
/ / c o n s o l e . l o g ( " 点 击 了 " , i n t e r s e c t s [ 0 ] ? . o b j e c t ? . n a m e ) ;
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
}
/ / c o n s o l e . l o g ( t o r u s . m a t e r i a l . o p a c i t y ) ;
}
/ / 定 制 渲 染 函 数
let T0 = + new Date ( ) / / 设 置 时 间 差
function render ( ) {
let T1 = + new Date ( )
/ / l e t t = T 1 - T 0 / / 获 取 时 间 间 隔
renderer . render ( scene , camera )
/ / 旋 转 立 方 体 , 每 次 绕 y 轴 旋 转 0 . 0 1 弧 度 , 每 一 秒 渲 染 0 . 0 0 1 弧 度
/ / b o x . r o t a t e Y ( 0 . 0 0 1 * t )
/ / i f ( t > = 2 0 0 0 ) {
/ / r e t u r n
/ / }
boxObjects . value . forEach ( ( element : any ) => {
let color1 = 0x88e76a
let color2 = 0xff0000
/ / 判 断 是 否 是 更 新 的 传 感 器 数 据
if ( store . updateSensorData . hasOwnProperty ( element . sensor _id ) ) {
/ / c o n s o l e . l o g ( s t o r e . u p d a t e S e n s o r D a t a , ' s t o r e . u p d a t e S e n s o r D a t a ' ) ;
/ / c o n s o l e . l o g ( e l e m e n t , ' e l e m e n t ' ) ;
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 )
}
/ / r e a d e r ( e l e m e n t )
} ) ;
TWEEN . update ( )
controls . update ( )
labelRenderer . render ( scene , camera )
store . clearupdateSensorData ( )
/ / r e a d e r ( m e s h _ q c j t )
window . requestAnimationFrame ( render ) / / 避 免 掉 帧 , 就 是 一 帧 接 一 帧 , 逐 帧 , 预 备 加 载 下 一 帧
}
render ( )
}
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 ) ;
/ / / / 不 带 门 的 墙
/ / c r e a t e N o D o o r W a l l ( b a s e W i d t h , b a s e H e g h t , b a s e L e n g t h , p o s i t i o n )
/ / / / 创 建 带 门 的 墙
/ / c r e a t e D o o r W a l l ( b a s e W i d t h , b a s e H e g h t , b a s e L e n g t h , p o s i t i o n )
/ / l e t { r o o f , w i d t h } = c r e a t e R o o f ( b a s e W i d t h , b a s e H e g h t , b a s e L e n g t h , p o s i t i o n ) ;
/ / l e t l e f t R o o f = r o o f . c l o n e ( ) ;
/ / l e f t R o o f . r o t a t e X ( T H R E E . M a t h U t i l s . d e g T o R a d ( 3 0 ) ) ;
/ / l e f t R o o f . p o s i t i o n . s e t ( - b a s e W i d t h / 3 + 1 + x , b a s e H e g h t + 2 + y , z ) ;
/ / l e f t R o o f . n a m e = " 左 屋 顶 " ;
/ / g r o u p . a d d ( l e f t R o o f ) ;
/ / / / 创 建 门
/ / c r e a t e D o o r ( b a s e W i d t h , b a s e L e n g t h , p o s i t i o n )
}
/ / 新 建 2 D 标 签
function createLableObj ( mesh : any , text : string , vector : positionType ) {
let laberDiv = document . createElement ( 'div' ) ; / / 创 建 d i v 容 器
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
/ / 物 体 移 动 位 置
/ / w a l l M e s h . p o s i t i o n . s e t ( ( - s i z e . b a s e W i d t h / 2 + b o x p o s i t i o n . x + 1 ) , s i z e . b a s e H e g h t / 2 + b o x p o s i t i o n . y , - s i z e . b a s e L e n g t h / 2 + b o x p o s i t i o n . 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 ( ) {
/ / r e q u i r e ( ' @ / a s s e t s / i m g / F a c t o r y / c a o . p n g ' )
/ / 导 入 材 质
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 ,
/ / c o l o r : 0 x 0 0 f f 0 0 ,
/ / t r a n s p a r e n t : t r u e ,
/ / o p a c i t y : 0 . 2 ,
} ) ;
const groundMesh = new THREE . Mesh ( ground , groundMaterial ) ;
groundMesh . name = "地面" ; / / 设 置 n a m e 属 性
groundMesh . rotateX ( - Math . PI / 2 ) ; / / 旋 转 用 于 呈 现 一 个 水 平 的 地 面
scene . add ( groundMesh ) ;
}
/ / 创 建 地 板 , 可 以 理 解 为 地 基
function createFloor ( houseName : string , baseWidth : number , baseLength : number , position : positionType ) {
const texture = new THREE . TextureLoader ( ) . load ( requires . wood ) ;
/ / 设 置 地 板 大 小 , 由 于 后 面 将 要 生 成 墙 体 存 在 设 置 为 1 的 厚 度 , 因 此 这 里 对 地 板 的 x , z 均 - 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 ,
} ) ;
/ / 墙 体 的 网 格
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 , / / 定 义 深 度 , 由 于 挤 压 几 何 体 的 点 位 都 是 x , y 坐 标 组 成 的 二 位 平 面 , 这 个 参 数 定 义 向 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
let { shape } = genwallShape ( baseWidth , baseHeght , baseLength ) ;
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 ) ;
/ / d o o r M e s h . r o t a t e Y ( M a t h . P I / 2 ) ;
/ / d o o r M e s h . p o s i t i o n . s e t ( - b a s e L e n g t h / 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 ;
/ / t e x t u r e . r e p e a t . s e t ( 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" ) ;
/ / d o m T a g . i n n e r T e x t = ' 电 流 '
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" ;
/ / d o m T a g . i n n e r T e x t = m e s h . n a m e ;
const iTagDomCss3 = new CSS2DObject ( domTag ) ;
iTagDomCss3 . position . z = 2 ;
iTagDomCss3 . position . y = 0 ;
scene . add ( iTagDomCss3 ) ;
saveTipDom = iTagDomCss3 ;
}
/ / 3 D 标 签 初 始 化
/ / f u n c t i o n i n i t C s s 3 D S c e n e ( ) {
/ / c s s R e n d e r = n e w C S S 3 D R e n d e r e r ( ) ;
/ / c s s R e n d e r . s e t S i z e ( i w , i h ) ;
/ / c s s R e n d e r . d o m E l e m e n t . s t y l e . p o s i t i o n = " a b s o l u t e " ;
/ / c s s R e n d e r . d o m E l e m e n t . s t y l e . t o p = ' 0 ' ;
/ / c s s R e n d e r . d o m E l e m e n t . s t y l e . o u t l i n e = " n o n e " ;
/ / c s s R e n d e r . d o m E l e m e n t . c l a s s N a m e = " c s s r e n d e r " ;
/ / c a n v a s . a p p e n d C h i l d ( c s s R e n d e r . d o m E l e m e n t ) ;
/ / }
function sethoveMesh ( ) {
dragControls = new DragControls (
boxObjects . value ,
camera ,
labelRenderer . domElement
) ;
/ / d r a g C o n t r o l s . d e a c t i v a t e ( ) ;
dragControls . addEventListener ( "hoveron" , function ( event : any ) {
saveTipDom . element . innerHTML = ` ${ event . object . name } : ${ event . object . devStatus ? t ( 'messages.offline' ) : 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 ) {
/ / c o n s o l e . l o g ( e v e n t ) ;
/ / e v e n t . o b j e c t . s e n s o r _ i d
/ / c o n s o l e . l o g ( ` " x " : $ { e v e n t . o b j e c t . p o s i t i o n . x } , " y " : $ { e v e n t . o b j e c t . p o s i t i o n . z } ` ) ;
/ / c o o r d i n a t e [ e v e n t . o b j e c t . s e n s o r _ i d ] = { " x " : e v e n t . o b j e c t . p o s i t i o n . x . t o F i x e d ( 2 ) , " y " : e v e n t . o b j e c t . p o s i t i o n . z . t o F i x e d ( 2 ) }
/ / c o n s o l e . l o g ( J S O N . s t r i n g i f y ( c o o r d i n a t e ) , ' c o o r d i n a t e 坐 标 ' ) ;
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 ( ( ) => {
/ / c o n s o l e . l o g ( c o n t a i n e r . v a l u e . o f f s e t W i d t h , ' c o n t a i n e r ' ) ;
/ / 初 始 化 场 景
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 )
/ / c o n s t l e n g t h = s t o r e . r e s u l t . l e n g t h
/ / / / 获 取 s t o r e 中 的 数 据 长 度
/ / s e t I n t e r v a l ( ( ) = > {
/ / / / 获 得 一 个 随 机 整 数
/ / c o n s t r a n d o m = M a t h . f l o o r ( M a t h . r a n d o m ( ) * l e n g t h )
/ / c o n s t t e m p d a t a : a n y = s t o r e . r e s u l t [ r a n d o m ]
/ / t e m p d a t a . s t a t u s = ! s t o r e . r e s u l t [ r a n d o m ] ? . s t a t u s
/ / s t o r e . u p d a t e R e s u l t ( t e m p d a t a )
/ / } , 5 0 0 0 )
} )
< / script >
< style >
/* @import url("@/assets/iconfont.css"); */
. laber _name {
color : # FFF ;
font - family : sans - serif ;
padding : 2 px ;
background : rgba ( 0 , 0 , 0 , 0.6 ) ;
}
< / style >