863 lines
24 KiB
Vue
863 lines
24 KiB
Vue
<template>
|
||
<div>
|
||
<div id="gltf"></div>
|
||
<div id="dom"></div>
|
||
<div class="btnGroup">
|
||
<div class="button" @click="toHomeView">
|
||
主视角
|
||
</div>
|
||
<div class="button" @click="setLabel">
|
||
{{ isAddLabel ? '添加标签' : '移除标签' }}
|
||
</div>
|
||
<div class="button" @click="setBottom()">
|
||
{{ isRemoveBottom ? '移除地板' : '恢复地板' }}
|
||
</div>
|
||
<!-- <div class="button" @click="roam()">
|
||
漫游
|
||
</div> -->
|
||
<div class="button" @click="warn()">
|
||
查看预警设备
|
||
</div>
|
||
<div class="button" @click="check()">
|
||
巡检
|
||
</div>
|
||
<div class="button" @click="changeMap()">
|
||
墙体寿命
|
||
</div>
|
||
</div>
|
||
<div class="wall_tooltips" v-show="isShowWall">
|
||
<p>
|
||
<span class="qing"></span>小于1年
|
||
</p>
|
||
<p>
|
||
<span class="blue"></span>大于1年小于2年
|
||
</p>
|
||
<p>
|
||
<span class="yellow"></span>大于2年小于3年
|
||
</p>
|
||
<p>
|
||
<span class="red"></span>大于3年
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script setup>
|
||
import { onMounted, ref, watch } from 'vue';
|
||
import * as THREE from 'three';
|
||
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
||
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
|
||
import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment.js";
|
||
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
||
import TWEEN from "@tweenjs/tween.js";
|
||
import {
|
||
CSS2DObject,
|
||
CSS2DRenderer,
|
||
} from "three/examples/jsm/renderers/CSS2DRenderer";
|
||
import Bus from '@/utils/bus.js'
|
||
import bimStore from '@/store/modules/bim';
|
||
import gsap from "gsap";
|
||
onMounted(() => {
|
||
init();
|
||
loadSence();
|
||
renderScene();
|
||
//点击模型
|
||
document.addEventListener('click', onMouseDown);
|
||
// 右击事件
|
||
window.addEventListener('contextmenu', function (e) {
|
||
if (e.button === 2) {
|
||
onMouseDownRight(e);
|
||
}
|
||
});
|
||
// document.addEventListener("mousemove", onMouseMove);
|
||
});
|
||
let scene, renderer, camera, controls, clickedObject, model;
|
||
|
||
// 克隆颜色和模型
|
||
let objArr = [];
|
||
let objM = [];
|
||
// 监测设备
|
||
let warnSets = [];
|
||
// 设置漫游索引
|
||
let currentIndex = 0;
|
||
let romeObj = []
|
||
// 设置巡检
|
||
let checkArr = [];
|
||
let checkindex = 0;
|
||
|
||
|
||
|
||
let mouse = new THREE.Vector2();
|
||
let labelRenderer = new CSS2DRenderer(); //新建CSS2DRenderer
|
||
const data = reactive({
|
||
isAddLabel: true,
|
||
isRemoveBottom: true,
|
||
isShowWall: false //墙体
|
||
});
|
||
const { isAddLabel, isRemoveBottom, isShowWall } = toRefs(data);
|
||
// 建筑树点击
|
||
Bus.on('clickBuild', (isParent) => {
|
||
// Todo
|
||
console.log('clickBuild', isParent);
|
||
var clickName = bimStore().activateTree.clickName;
|
||
var Floor = scene.getObjectByName(clickName);
|
||
boxLight(Floor);
|
||
|
||
return;
|
||
})
|
||
// 设备树点击
|
||
Bus.on('clickDevice', (isParent) => {
|
||
if (!isParent) {// 点击子级
|
||
var clickName = bimStore().activateDevice.clickName;
|
||
var Floor = scene.getObjectByName(clickName);
|
||
removeLabel();
|
||
boxLight(Floor);
|
||
// 拉近距离
|
||
// nearCamera(Floor);
|
||
return;
|
||
}
|
||
})
|
||
|
||
// 系统树点击
|
||
Bus.on('clickApplication', (isParent) => {
|
||
// Todo
|
||
if (!isParent) {
|
||
xiaof();
|
||
}
|
||
|
||
})
|
||
|
||
watch(() => bimStore().activateMenu, value => {
|
||
// 更换场景颜色
|
||
scene.background = new THREE.Color(value.background);
|
||
toHomeView();
|
||
}, { deep: true });
|
||
|
||
const init = () => {
|
||
// 场景
|
||
scene = new THREE.Scene();
|
||
scene.background = new THREE.Color(bimStore().activateMenu.background);
|
||
// 相机
|
||
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||
camera.position.set(-65.82410159732751, 111.17437832684305, -45.026345528621334);
|
||
camera.lookAt(scene.position);
|
||
//渲染器
|
||
renderer = new THREE.WebGLRenderer({ antialias: true });
|
||
renderer.setPixelRatio(window.devicePixelRatio);
|
||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||
renderer.outputEncoding = THREE.sRGBEncoding;
|
||
document.getElementById('gltf').appendChild(renderer.domElement);
|
||
|
||
controls = new OrbitControls(camera, renderer.domElement);
|
||
const pmremGenerator = new THREE.PMREMGenerator(renderer);
|
||
scene.environment = pmremGenerator.fromScene(new RoomEnvironment()).texture;
|
||
var vector = new THREE.Vector3();
|
||
console.log('刚开始场景', vector);
|
||
}
|
||
const loadSence = () => {
|
||
const gltfLoader = new GLTFLoader();
|
||
const dracoLoader = new DRACOLoader();
|
||
dracoLoader.setDecoderPath('/draco/gltf/')//设置解压库文件路径
|
||
gltfLoader.setDRACOLoader(dracoLoader)
|
||
gltfLoader.load('/jzc/jz.gltf', (gltf) => {
|
||
model = gltf.scene;
|
||
// 克隆初始的材料和模型
|
||
model.traverse(e => {
|
||
objArr.push(e);
|
||
objM.push(e.material);
|
||
if (enableGroup.indexOf(e.name) != -1) {
|
||
xfobj.push(e);
|
||
}
|
||
if (yjGroup.indexOf(e.name) != -1) {
|
||
yjobj.push(e);
|
||
}
|
||
})
|
||
// 设置漫游点位
|
||
const objname = ['start', 'middle1', 'middle2', 'end']
|
||
objname.forEach((item, index) => {
|
||
var targetModel = model.getObjectByName(item);
|
||
if (targetModel) romeObj.push(
|
||
targetModel
|
||
)
|
||
console.log('targetModel', targetModel)
|
||
})
|
||
// 漫游结束
|
||
|
||
// 获取巡检设备
|
||
const checkname = [{
|
||
name: 'start',
|
||
isPass: true
|
||
}, {
|
||
name: 'middle1',
|
||
isPass: true
|
||
}, {
|
||
name: 'middle2',
|
||
isPass: false
|
||
}, {
|
||
name: 'end',
|
||
isPass: true
|
||
}]
|
||
checkname.forEach((item, index) => {
|
||
var targetO = model.getObjectByName(item.name);
|
||
if (targetO) {
|
||
targetO.isPass = item.isPass;
|
||
checkArr.push(
|
||
targetO
|
||
)
|
||
}
|
||
})
|
||
|
||
scene.add(model);
|
||
|
||
});
|
||
};
|
||
const renderScene = () => {
|
||
requestAnimationFrame(renderScene);
|
||
const cameraPosition = camera.position;
|
||
const cameraX = cameraPosition.x;
|
||
const cameraY = cameraPosition.y;
|
||
const cameraZ = cameraPosition.z;
|
||
// console.log('坐标', cameraX, cameraY, cameraZ);
|
||
TWEEN.update();
|
||
controls.update();
|
||
renderer.render(scene, camera);
|
||
labelRenderer.render(scene, camera);
|
||
};
|
||
|
||
const onWindowResize = () => {
|
||
camera.aspect = window.innerWidth / window.innerHeight;
|
||
camera.updateProjectionMatrix();
|
||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||
}
|
||
window.addEventListener("resize", onWindowResize, false);
|
||
|
||
// 能选中的组
|
||
const enableGroup = [
|
||
'yuanliao_room',
|
||
'tanghua_room',
|
||
'touliao_room',
|
||
'guolvcao_1',// 过滤槽
|
||
'T3',
|
||
'T4',
|
||
'T5',
|
||
'T6',
|
||
'T7',
|
||
'T8',
|
||
'T9',
|
||
'T10',
|
||
'T11',// 立仓
|
||
'T12'
|
||
]
|
||
// 预警设备
|
||
const yjGroup = [
|
||
'T7',
|
||
]
|
||
const isSelent = (obj) => {
|
||
var o = obj
|
||
while (true) {
|
||
if (o.name != "jzgltf" && enableGroup.indexOf(o.name) != -1) {
|
||
return o;
|
||
} else {
|
||
if (o.parent && o.parent.name == "jzgltf") {
|
||
return null;
|
||
} else {
|
||
o = o.parent;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
let selectedObjects = ref([]);
|
||
let selectBoxByClick, selectBoxByMouseon, pointLabel, selectedObject;
|
||
var marginLeft = 0;
|
||
var marginTop = 70;
|
||
// 鼠标移动效果
|
||
const onMouseMove = (event) => {
|
||
var raycaster = new THREE.Raycaster()
|
||
mouse.x = ((event.clientX - marginLeft) / window.innerWidth) * 2 - 1;
|
||
mouse.y = -((event.clientY - marginTop) / window.innerHeight) * 2 + 1;
|
||
raycaster.setFromCamera(mouse, camera);
|
||
const intersects = raycaster.intersectObjects(scene.children, true);
|
||
if (intersects.length > 0) {
|
||
const clickedObject = intersects[0].object;
|
||
selectedObject = isSelent(clickedObject);
|
||
if (selectedObject) {
|
||
selectedObjects[0] = selectedObject;
|
||
if (selectBoxByMouseon) {
|
||
scene.remove(selectBoxByMouseon);
|
||
}
|
||
selectBoxByMouseon = new THREE.BoxHelper(selectedObjects[0], '#ffffff');
|
||
scene.add(selectBoxByMouseon);
|
||
}
|
||
}
|
||
}
|
||
const emit = defineEmits(['handleRightClick', 'checkComplete'])
|
||
// 鼠标右击事件
|
||
const onMouseDownRight = (event) => {
|
||
var raycaster = new THREE.Raycaster()
|
||
mouse.x = ((event.clientX - marginLeft) / window.innerWidth) * 2 - 1;
|
||
mouse.y = -((event.clientY - marginTop) / window.innerHeight) * 2 + 1;
|
||
raycaster.setFromCamera(mouse, camera);
|
||
const intersects = raycaster.intersectObjects(scene.children, true);
|
||
// console.log(123, event);
|
||
|
||
if (intersects.length > 0) {
|
||
const clickedObject = intersects[0].object;
|
||
console.log('这是我选中的模型', clickedObject);
|
||
selectedObject = isSelent(clickedObject);
|
||
addLabel(selectedObject, 'details');
|
||
}
|
||
}
|
||
// 鼠标点击效果
|
||
const onMouseDown = (event) => {
|
||
var raycaster = new THREE.Raycaster()
|
||
// 将鼠标点击位置的屏幕坐标转换成threejs中的标准坐标
|
||
mouse.x = ((event.clientX - marginLeft) / window.innerWidth) * 2 - 1;
|
||
mouse.y = -((event.clientY - marginTop) / window.innerHeight) * 2 + 1;
|
||
raycaster.setFromCamera(mouse, camera);
|
||
const intersects = raycaster.intersectObjects(scene.children, true);
|
||
console.log(123, event);
|
||
|
||
if (intersects.length > 0) {
|
||
clickedObject = intersects[0].object;
|
||
console.log('这是我选中的模型', clickedObject);
|
||
selectedObject = isSelent(clickedObject);
|
||
// 高亮所在区域
|
||
boxLight(selectedObject);
|
||
// 染色点击的模型
|
||
console.log(1, clickedObject);
|
||
if (bimStore().activateIndex == '0') {
|
||
// 联动左侧菜单
|
||
Bus.emit('handleTreeClick', clickedObject);
|
||
return;
|
||
}
|
||
if (bimStore().activateIndex == '1') {
|
||
// 联动左侧菜单
|
||
Bus.emit('handleTreeClick1', clickedObject);
|
||
return;
|
||
}
|
||
|
||
}
|
||
}
|
||
const changeColor = (Floor) => {
|
||
// Floor.children.forEach((obj) => {
|
||
// if (obj.isMesh) {
|
||
// console.log(123, obj);
|
||
// obj.material.transparent = true;
|
||
// obj.material.opacity = 0.3;
|
||
// obj.material.color = new THREE.Color('rgb( 0 , 0 , 225 )');
|
||
// }
|
||
// })
|
||
// 染色
|
||
Floor.traverse(e => {
|
||
if (e.isMesh) {
|
||
e.material.transparent = true;
|
||
e.material.opacity = 0.3;
|
||
e.material.color = new THREE.Color('rgb( 0 , 0 , 225 )');
|
||
}
|
||
})
|
||
}
|
||
// 清除模型颜色
|
||
const cleanColor = () => {
|
||
// 恢复之前被选中模型的材质
|
||
if (objArr.length > 0 && objM.length > 0) {
|
||
objArr.forEach((ele, index) => {
|
||
console.log(objM[index]);
|
||
ele.material = objM[index]
|
||
})
|
||
objArr = [];
|
||
objM = [];
|
||
}
|
||
scene.traverse(e => {
|
||
objArr.push(e);
|
||
objM.push(e.material);
|
||
})
|
||
}
|
||
// 预警
|
||
const warn = () => {
|
||
['T7'].forEach(item => {
|
||
warnSets.push(scene.getObjectByName(item));
|
||
})
|
||
|
||
warnSets[0].traverse(e => {
|
||
e.material = new THREE.MeshBasicMaterial({
|
||
transparent: true,
|
||
opacity: 0.9,
|
||
color: new THREE.Color('rgb( 237,33,2 )')
|
||
});
|
||
})
|
||
yjf();
|
||
|
||
// animateCamera(warnSets[0]);
|
||
}
|
||
|
||
const animateCamera = (one) => {
|
||
const lookO = one.getWorldPosition(new THREE.Vector3())
|
||
gsap.to(controls.target, {
|
||
x: lookO.x,
|
||
y: lookO.y + 1.2,
|
||
z: lookO.z,
|
||
duration: 4,
|
||
ease: "power1.inOut",
|
||
onComplete: () => { },
|
||
});
|
||
}
|
||
|
||
const boxLight = (selectedObject) => {
|
||
if (selectedObject) {
|
||
selectedObjects[0] = selectedObject;
|
||
if (selectBoxByClick) {
|
||
scene.remove(selectBoxByClick);
|
||
}
|
||
selectBoxByClick = new THREE.BoxHelper(selectedObjects[0], '#00ffff');
|
||
scene.add(selectBoxByClick);
|
||
centerSelectedGroup(selectedObject);
|
||
}
|
||
}
|
||
// 居中显示选中
|
||
const centerSelectedGroup = (obj) => {
|
||
let tween = new TWEEN.Tween(controls.target).to(obj.position, 1000).easing(TWEEN.Easing.Quadratic.Out);
|
||
controls.enabled = false;
|
||
tween.onComplete(function () {
|
||
controls.enabled = true;
|
||
});
|
||
tween.start();
|
||
}
|
||
|
||
// 漫游
|
||
const roam = () => {
|
||
if (currentIndex < romeObj.length) {
|
||
console.log('照相机坐标', camera.position);
|
||
console.log('物体坐标', romeObj[currentIndex].getWorldPosition(new THREE.Vector3()));
|
||
|
||
|
||
var nextPosition = romeObj[currentIndex].getWorldPosition(new THREE.Vector3());
|
||
// 在动画完成后触发下一个漫游
|
||
gsap.to(camera.position, {
|
||
x: nextPosition.x,
|
||
y: nextPosition.y + 2.2,
|
||
z: nextPosition.z,
|
||
duration: 10,
|
||
ease: 'power1.inOut',
|
||
onComplete: () => {
|
||
roam()
|
||
}
|
||
});
|
||
|
||
let lookObj;
|
||
if (currentIndex == romeObj.length - 1) {
|
||
lookObj = romeObj[0].getWorldPosition(new THREE.Vector3())
|
||
} else if (currentIndex < romeObj.length) {
|
||
lookObj = romeObj[currentIndex + 1].getWorldPosition(new THREE.Vector3())
|
||
}
|
||
gsap.to(controls.target, {
|
||
x: lookObj.x,
|
||
y: lookObj.y + 2.2,
|
||
z: lookObj.z,
|
||
duration: 10,
|
||
|
||
ease: "power1.inOut",
|
||
onComplete: () => { },
|
||
});
|
||
currentIndex++;
|
||
console.log('lookObj', currentIndex)
|
||
} else {
|
||
toHomeView();
|
||
}
|
||
}
|
||
// 返回初始值
|
||
const toHomeView = () => {
|
||
// 清除选中框
|
||
if (selectBoxByClick) {
|
||
scene.remove(selectBoxByClick);
|
||
}
|
||
// 清除标签
|
||
removeLabel();
|
||
isAddLabel.value = true;
|
||
// 清除精灵图
|
||
controls.reset();
|
||
// 恢复初始颜色
|
||
cleanColor();
|
||
// 隐藏图例
|
||
isShowWall.value = false;
|
||
}
|
||
// 拉近距离
|
||
const nearCamera = (floor) => {
|
||
controls.reset();
|
||
|
||
gsap.to(camera.position, {
|
||
x: floor.position.x,
|
||
y: floor.position.y,
|
||
z: floor.position.z,
|
||
duration: 2,
|
||
ease: "power1.inOut",
|
||
onComplete: () => {
|
||
},
|
||
});
|
||
|
||
}
|
||
//标签
|
||
const setLabel = () => {
|
||
if (isAddLabel.value) {
|
||
let obj = scene.getObjectByName('T11');
|
||
addLabel(obj, 'title');
|
||
} else {
|
||
removeLabel();
|
||
}
|
||
isAddLabel.value = !isAddLabel.value;
|
||
}
|
||
// 添加标签
|
||
const addLabel = (obj, t) => {
|
||
removeLabel();
|
||
centerSelectedGroup(obj);
|
||
pointLabel = createLableObj(obj.name, t);
|
||
obj.add(pointLabel);
|
||
labelRenderer.setSize(window.innerWidth, window.innerHeight);
|
||
labelRenderer.domElement.style.position = "absolute";
|
||
labelRenderer.domElement.style.top = 0;
|
||
labelRenderer.domElement.style.pointerEvents = 'none';// 必须加上
|
||
document.body.appendChild(labelRenderer.domElement);
|
||
// 将呈现器的输出添加到HTML元素
|
||
document.getElementById("dom").appendChild(renderer.domElement);
|
||
};
|
||
const createLableObj = (text, t) => {
|
||
let laberDiv = document.createElement("div"); //创建div容器
|
||
// 只显示标签
|
||
if (t === 'title') {
|
||
laberDiv.className = "laber_name";
|
||
laberDiv.innerHTML = `<div class="arrow_outer">
|
||
<div>设备名称:${text}</div>
|
||
<div>状态:启用</div>
|
||
<div>压力:50 Pa</div>
|
||
</div>`
|
||
//只显示详情
|
||
} else if (t === 'details') {
|
||
laberDiv.style.pointerEvents = 'auto';// 必须加
|
||
laberDiv.className = "laber_details";
|
||
laberDiv.innerHTML = `<div class="detail-btn">详情</div>`;
|
||
laberDiv.addEventListener('click', function (event) {
|
||
emit('handleRightClick', selectedObject);
|
||
console.log(labelRenderer.domElement);
|
||
})
|
||
// 巡检逻辑
|
||
} else {
|
||
laberDiv.className = "laber_state";
|
||
let innerHTML = t ? `<div class="arrow_state">
|
||
<div>设备名称:${text}</div>
|
||
<div>
|
||
巡检结果:巡检通过
|
||
</div>
|
||
<div>
|
||
巡检时间:2023-12-23
|
||
</div>
|
||
</div>`: `<div class="arrow_state1">
|
||
<div>设备名称:${text}</div>
|
||
<div>
|
||
巡检结果:巡检不通过,已记录异常
|
||
</div>
|
||
<div>
|
||
巡检时间:2023-01-11
|
||
</div>
|
||
</div>`;
|
||
laberDiv.innerHTML = innerHTML;
|
||
}
|
||
let pointLabel = new CSS2DObject(laberDiv);
|
||
return pointLabel;
|
||
};
|
||
const removeLabel = () => {
|
||
if (pointLabel) {
|
||
pointLabel.visible = false;
|
||
}
|
||
// document.body.removeChild(labelRenderer.domElement);
|
||
|
||
}
|
||
|
||
// 设置地板
|
||
const setBottom = () => {
|
||
var target = scene.getObjectByName('tanghua_1F');
|
||
console.log(target);
|
||
if (isRemoveBottom.value) {
|
||
target.visible = false;
|
||
} else {
|
||
target.visible = true;
|
||
}
|
||
isRemoveBottom.value = !isRemoveBottom.value;
|
||
}
|
||
|
||
// 消防
|
||
const xiaof = () => {
|
||
xfobj.forEach((o) => {
|
||
xfadd(o, Math.random() < 0.3);
|
||
})
|
||
}
|
||
// 预警
|
||
const yjf = () => {
|
||
yjobj.forEach((o) => {
|
||
xfadd(o, 'yj');
|
||
})
|
||
}
|
||
let xfobj = [];
|
||
let yjobj = [];
|
||
// 消防标签
|
||
const xfadd = (obj, state) => {
|
||
const texLoader = new THREE.TextureLoader();
|
||
let texture = null;
|
||
if(state == 'yj') {
|
||
texture = texLoader.load("/yj.png");
|
||
}
|
||
else if (state) {
|
||
texture = texLoader.load("/ygr.png");
|
||
} else {
|
||
texture = texLoader.load("/yg.png");
|
||
}
|
||
const spriteMaterial = new THREE.SpriteMaterial({
|
||
map: texture,
|
||
});
|
||
const sprite = new THREE.Sprite(spriteMaterial);
|
||
// 控制精灵大小
|
||
sprite.scale.set(5, 5, 5);
|
||
sprite.position.y = 12; //标签底部箭头和空对象标注点重合
|
||
obj.add(sprite); //tag会标注在空对象obj对应的位置
|
||
console.log(123, obj)
|
||
}
|
||
// 移除消防标签
|
||
const removexf = () => {
|
||
model.traverse(e => {
|
||
if (e.isMesh && e.children.length > 0) {
|
||
e.remove(e.children[0])
|
||
} else {
|
||
e.traverse(o => {
|
||
if (o.isMesh && o.children.length > 0) {
|
||
o.remove(o.children[0])
|
||
}
|
||
})
|
||
|
||
}
|
||
})
|
||
scene.remove(sprite);
|
||
}
|
||
// 更换纹理贴图方法
|
||
const changeMap = (img) => {
|
||
// 测试移除消防图标
|
||
// removexf();
|
||
isShowWall.value = true;
|
||
// 获取墙体
|
||
model.traverse(e => {
|
||
if (['touliao_wall1', 'touliao_wall2', 'touliao_wall3', 'touliao_wall4', 'touliao_wall5', 'touliao_wall6', 'touliao_wall7', 'touliao_wall8'].indexOf(e.name) != -1) {
|
||
console.log(e)
|
||
e.material = new THREE.MeshBasicMaterial({
|
||
transparent: true,
|
||
opacity: 0.5,
|
||
color: new THREE.Color('rgb( 88,211,247)')
|
||
});
|
||
} else if (['yuanliao_wall1', 'yuanliao_wall2', 'yuanliao_wall3', 'yuanliao_wall4', 'yuanliao_wall5', 'yuanliao_wall6', 'yuanliao_wall7', 'yuanliao_wall8', 'yuanliao_wall9','yuanliao_wall10'].indexOf(e.name) != -1) {
|
||
e.material = new THREE.MeshBasicMaterial({
|
||
transparent: true,
|
||
opacity: 0.5,
|
||
color: new THREE.Color('rgb( 0,128,255)')
|
||
});
|
||
} else if (['tanghua_wall1', 'tanghua_wall2','tanghua_wall3', 'tanghua_wall4','tanghua_wall5', 'tanghua_wall6','tanghua_wall7', 'tanghua_wall8'].indexOf(e.name) != -1) {
|
||
e.material = new THREE.MeshBasicMaterial({
|
||
transparent: true,
|
||
opacity: 0.5,
|
||
color: new THREE.Color('rgb(247,254,46)')
|
||
});
|
||
} else if (['tanghua_wall9', 'tanghua_wall10','tanghua_wall11'].indexOf(e.name) != -1) {
|
||
e.material = new THREE.MeshBasicMaterial({
|
||
transparent: true,
|
||
opacity: 0.5,
|
||
color: new THREE.Color('rgb(253,45,45)')
|
||
});
|
||
}
|
||
})
|
||
}
|
||
// 巡检
|
||
const check = () => {
|
||
if (currentIndex < romeObj.length) {
|
||
// .getWorldPosition()属性需要用三维向量表示摸个坐标后方可读取
|
||
var checkPosition = checkArr[checkindex].getWorldPosition(new THREE.Vector3());
|
||
|
||
gsap.to(camera.position, {
|
||
x: checkPosition.x,
|
||
y: checkPosition.y + 5.2,
|
||
z: checkPosition.z,
|
||
duration: 10,
|
||
ease: 'power1.inOut',
|
||
onComplete: () => {
|
||
if (checkindex == romeObj.length) { // 巡检结束
|
||
checkComplete();
|
||
}
|
||
check()
|
||
}
|
||
});
|
||
var pos1 = new THREE.Vector3( camera.position );
|
||
|
||
var pos2 = new THREE.Vector3( checkPosition );
|
||
|
||
var distance = pos1.distanceTo(pos2);
|
||
console.log(12354, distance);
|
||
|
||
let nextObj;
|
||
if (checkindex == checkArr.length - 1) {
|
||
nextObj = checkArr[0].getWorldPosition(new THREE.Vector3())
|
||
} else if (checkindex < checkArr.length) {
|
||
nextObj = checkArr[checkindex + 1].getWorldPosition(new THREE.Vector3())
|
||
}
|
||
gsap.to(controls.target, {
|
||
x: nextObj.x,
|
||
y: nextObj.y + 5.2,
|
||
z: nextObj.z,
|
||
duration: 10,
|
||
|
||
ease: "power1.inOut",
|
||
onComplete: () => {
|
||
// 显示标签,已经检查通过
|
||
// addLabel(checkArr[checkindex], checkArr[checkindex].isPass);
|
||
},
|
||
});
|
||
checkindex++;
|
||
console.log('nextObj', checkindex)
|
||
}
|
||
}
|
||
// 巡检结束
|
||
const checkComplete = () => {
|
||
toHomeView();
|
||
checkindex = 0;
|
||
bimStore().setCheckArr(romeObj);
|
||
emit('checkComplete', romeObj);
|
||
return;
|
||
}
|
||
|
||
</script>
|
||
<style lang='scss'>
|
||
#gltf {
|
||
height: 100%;
|
||
width: 100%;
|
||
}
|
||
|
||
.btnGroup {
|
||
width: 180px;
|
||
position: absolute;
|
||
left: 260px;
|
||
top: 10px;
|
||
z-index: 999;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
color: #ffff;
|
||
|
||
>div {
|
||
cursor: pointer;
|
||
// background: #0549a7;
|
||
border: 1px solid #3cbfdf;
|
||
background: rgba(0, 0, 0, .8);
|
||
width: 110px;
|
||
height: 40px;
|
||
border-radius: 5px;
|
||
line-height: 40px;
|
||
text-align: center;
|
||
margin-top: 10px;
|
||
}
|
||
}
|
||
|
||
.laber_name {
|
||
width: 120px;
|
||
height: 90px;
|
||
padding: 5px 10px;
|
||
white-space: nowrap;
|
||
background-color: #ffffffb3;
|
||
border-radius: 12px;
|
||
font-size: 12px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
span {
|
||
line-height: 24px;
|
||
}
|
||
}
|
||
|
||
.laber_details {
|
||
width: 100px;
|
||
height: 50px;
|
||
border-radius: 5px;
|
||
cursor: pointer;
|
||
background-color: #00174b;
|
||
color: #fff;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 999;
|
||
}
|
||
|
||
.arrow_state {
|
||
display: inline-block;
|
||
// width: 200px;
|
||
// height: 100px;
|
||
padding: 10px;
|
||
background: #0dbc79;
|
||
color: #fff;
|
||
padding: 15px;
|
||
border-radius: 5px;
|
||
|
||
>div {
|
||
line-height: 32px;
|
||
}
|
||
}
|
||
|
||
.arrow_state1 {
|
||
display: inline-block;
|
||
padding: 10px;
|
||
background: #e03528;
|
||
color: #fff;
|
||
padding: 15px;
|
||
border-radius: 5px;
|
||
|
||
>div {
|
||
line-height: 32px;
|
||
}
|
||
}
|
||
|
||
.wall_tooltips {
|
||
position: absolute;
|
||
top: 20px;
|
||
left: 400px;
|
||
z-index: 999;
|
||
display: flex;
|
||
color: #fff;
|
||
width: 600px;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
|
||
span {
|
||
display: inline-block;
|
||
width: 16px;
|
||
height: 8px;
|
||
margin-right: 5px;
|
||
|
||
&.qing {
|
||
background: #3cbfdf;
|
||
}
|
||
|
||
&.blue {
|
||
background: #2c68f3;
|
||
}
|
||
|
||
&.yellow {
|
||
background: #dff04e;
|
||
}
|
||
|
||
&.red {
|
||
background: red;
|
||
}
|
||
}
|
||
}
|
||
.arrow_outer {
|
||
width: 100px;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
>div {
|
||
line-height: 24px;
|
||
}
|
||
}
|
||
</style> |