wangqiujuan0808 2023-12-08 23:41:34 +08:00
parent 620710b9a5
commit 5db8d1e48f
9 changed files with 177 additions and 498 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -14,6 +14,7 @@
import bimStore from '@/store/modules/bim';
import { nextTick } from "vue";
const myTree = ref("myTree");
import Bus from '@/utils/bus.js';
const applicationOptions = [
{
value: '0',
@ -62,7 +63,10 @@ onMounted(() => {
});
const handleNodeClick = (value) => {
bimStore().setActivateTree(value);
emit('handleNodeClick', value)
emit('handleNodeClick', value);
setTimeout(() => {
Bus.emit('clickApplication');
}, 100)
}

View File

@ -12,15 +12,12 @@
<script setup>
import bimStore from '@/store/modules/bim';
import { nextTick } from "vue";
import bus from '@/utils/bus.js'
import Bus from '@/utils/bus.js';
const myTree = ref("myTree");
const props = defineProps({
isSetTree: { //
default: false,
type: Boolean
},
})
const buildOptions = [
@ -70,85 +67,106 @@ const data = reactive({
value: 100
}
],
children: [
{
label: '原料糖化车间一',
id: '0-1',
url: '/jz/glb/scene.gltf',
children: [{
label: '罐子1',
id: '0-0-1',
children:[]
},{
label: '罐子2',
id: '0-0-2',
children:[]
}],
info: {
name: '原料糖化车间一',
area: '5200 ㎡',
status: '启用',
desc: '原料糖化车间一负责原料糖化启用于2011年'
},
deviceInfo: [
{
type: '生产设备',
name: '立仓',
value: 15
},
{
type: '空调设备',
name: '新风机组',
value: 50
},
{
type: '安防设备',
name: '摄像头',
value: 80
},
{
type: '消防设备',
name: '烟感',
value: 50
}
],
children: [{
label: '糖化间',
id: '0-0-1',
clickName: 'tanghua_room',
info: {
name: '糖化间',
area: '9436 ㎡',
status: '启用',
desc: '糖化间负责原料糖化启用于2011年'
},
{
label: '原料糖化车间二',
id: '0-2',
url: '/jz/glb/scene.gltf',
children: [],
info: {
name: '原料糖化车间二',
area: '4236 ㎡',
status: '启用',
desc: '原料糖化车间二负责原料糖化启用于2013年'
deviceInfo: [
{
type: '生产设备',
name: '立仓',
value: 95
},
deviceInfo: [
{
type: '生产设备',
name: '立仓',
value: 30
},
{
type: '空调设备',
name: '新风机组',
value: 80
},
{
type: '安防设备',
name: '摄像头',
value: 100
},
{
type: '消防设备',
name: '烟感',
value: 50
}
],
{
type: '空调设备',
name: '新风机组',
value: 100
},
{
type: '安防设备',
name: '摄像头',
value: 90
},
{
type: '消防设备',
name: '烟感',
value: 100
}
],
children: []
}, {
label: '原料处理间',
id: '0-0-2',
clickName: 'yuanliao_room',
info: {
name: '原料处理间',
area: '9436 ㎡',
status: '启用',
desc: '原料糖化车间负责原料糖化启用于2011年'
},
],
deviceInfo: [
{
type: '生产设备',
name: '立仓',
value: 85
},
{
type: '空调设备',
name: '新风机组',
value: 130
},
{
type: '安防设备',
name: '摄像头',
value: 100
},
{
type: '消防设备',
name: '烟感',
value: 150
}
],
children: []
},{
label: '投料间',
id: '0-0-3',
clickName: 'touliao_room',
info: {
name: '投料间',
area: '836 ㎡',
status: '启用',
desc: '投料间负责原料糖化启用于2011年'
},
deviceInfo: [
{
type: '生产设备',
name: '立仓',
value: 115
},
{
type: '空调设备',
name: '新风机组',
value: 90
},
{
type: '安防设备',
name: '摄像头',
value: 100
},
{
type: '消防设备',
name: '烟感',
value: 40
}
],
children: []
}],
}
],
checkedkeys: ""
@ -162,17 +180,14 @@ onMounted(() => {
})
});
const handleNodeClick = (value) => {
if(props.isSetTree) {//
bimStore().setActivateTree(value);
}
bimStore().setActivateTree(value);
const isParent = value.children.length > 0;
emit('handleNodeClick', value, isParent);
bus.emit('foo');
setTimeout(() => {
Bus.emit('clickBuild', isParent);
}, 100)
}
</script>
<style lang='scss' scoped>
.treeDiv {

View File

@ -32,7 +32,6 @@ onMounted(() => {
})
watch(deviceInfo, (value) => {
console.log(34, value);
if (value) {
initData();
}

View File

@ -13,6 +13,7 @@
<script setup>
import bimStore from '@/store/modules/bim';
import { nextTick } from "vue";
import Bus from '@/utils/bus.js'
const myTree = ref("myTree");
const deviceOptions = [
{
@ -39,26 +40,46 @@ const data = reactive({
},
children: [
{
label: '立仓',
label: '设备一',
id: '0-1',
url: '/jz/glb/scene.gltf',
clickName: 'set1',
info: {
name: '立仓',
name: '设备一',
type: '生产设备',
status: '启用'
},
},
{
label: '糖浆罐',
label: '设备二',
id: '0-2',
url: '/seraphine/scene.gltf',
clickName: 'set2',
info: {
name: '糖浆罐',
name: '设备二',
type: '生产设备',
status: '启用'
},
},
{
label: '设备三',
id: '0-3',
clickName: 'set3',
info: {
name: '设备三',
type: '空调设备',
status: '启用'
},
},
{
label: '设备四',
id: '0-4',
clickName: 'set4',
info: {
name: '设备四',
type: '安防设备',
status: '启用'
},
},
],
}
],
@ -74,7 +95,10 @@ onMounted(() => {
});
const handleNodeClick = (value) => {
bimStore().setActivateDeviceTree(value);
emit('handleNodeClick', value)
emit('handleNodeClick', value);
setTimeout(() => {
Bus.emit('clickDevice');
}, 100)
}

View File

@ -1,377 +0,0 @@
<template>
<div class="container">
<div id="model"></div>
<button
id="btns"
:style="{ cursor: isDisabled ? '' : 'pointer' }"
:disabled="isDisabled"
type="isDisabled:"
@click="toHomeView(1)"
>
主视角
</button>
</div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js";
import TWEEN from "@tweenjs/tween.js";
export default {
name: "ThreeModel",
data() {
return {
isDisabled: true,
scene: null,
renderer: null,
controls: null,
light: null,
light2: null,
group: new THREE.Group(),
composer: null, //
outlinePass: null,
renderPass: null,
//
selectedObjects: [],
mouse: new THREE.Vector2(),
raycaster: new THREE.Raycaster(),
tween: null,
//
long: 100,
//
tall: 24,
//
thickness: 0.4,
positionObj: null,
};
},
computed: {},
watch: {},
created() {},
mounted() {
this.init();
},
methods: {
//
initScene() {
this.scene = new THREE.Scene();
},
//
initCamera() {
const { long, tall } = this;
this.camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
0.1,
50000
);
this.camera.position.set(0, -(5 * tall) / 12, (6 * long) / 5);
},
//
initLight() {
let ambientLight = new THREE.AmbientLight(0x404040);
this.scene.add(ambientLight);
this.light = new THREE.DirectionalLight(0x333333);
this.light.position.set(60, 30, 40);
this.light2 = new THREE.DirectionalLight(0xdddddd);
this.light2.position.set(-20, 20, -20);
this.scene.add(this.light);
this.scene.add(this.light2);
},
//
initRender() {
//dom
this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
this.renderer.setSize(window.innerWidth, window.innerHeight); //
this.renderer.setClearColor(0x000000, 0); //
//window.devicePixelRatio css
this.renderer.setPixelRatio(window.devicePixelRatio);
//
this.renderer.sortObjects = true;
document.getElementById("model").appendChild(this.renderer.domElement);
},
//
initModel() {
const { long, tall, thickness } = this;
//
// let axes = new THREE.AxesHelper(4000);
// this.scene.add(axes);
//
for (let index = 1; index <= tall / 4 - 1; index++) {
let geometry = new THREE.BoxGeometry(long, thickness, 12);
let material = new THREE.MeshLambertMaterial({
color: 0x808080,
opacity: 0.7,
transparent: true,
}); //Material
let mesh = new THREE.Mesh(geometry, material); //Mesh
mesh.position.set(0, index * 4, 0); //mesh3xyz120,0,0
this.scene.add(mesh); //
}
//
for (let index = 1; index <= long / 4 + 1; index++) {
let geometry = new THREE.BoxGeometry(thickness, tall, 12);
let material = new THREE.MeshLambertMaterial({
color: 0x808080,
opacity: 0.7,
transparent: true,
}); //Material
let mesh = new THREE.Mesh(geometry, material); //Mesh
mesh.position.set(-long / 2 + (index - 1) * 4, tall / 2, 0); //mesh3xyz120,0,0
this.scene.add(mesh); //
}
//
let list1 = new Array(tall / 4);
for (let i = 0; i < list1.length; i++) {
list1[i] = new Array(long / 4);
//for
for (let j = 0; j < long / 4; j++) {
// a[i][j] = i + j;
let geometry = new THREE.BoxGeometry(3, 3, 5);
let material = new THREE.MeshLambertMaterial({
color: 0x00b1f7,
opacity: 0.4,
transparent: true,
});
let mesh = new THREE.Mesh(geometry, material);
mesh.name = i + 1 + "-" + (j + 1);
mesh.position.set(-long / 2 + j * 4 + 2, i * 4 + 2, 3);
this.scene.add(mesh);
}
}
//
let list2 = new Array(tall / 4);
for (let i = 0; i < list2.length; i++) {
list2[i] = new Array(long / 4);
//for
for (let j = 0; j < long / 4; j++) {
// a[i][j] = i + j;
let geometry = new THREE.BoxGeometry(3, 3, 5);
let material = new THREE.MeshLambertMaterial({
color: 0x00b1f7,
opacity: 0.4,
transparent: true,
});
let mesh = new THREE.Mesh(geometry, material);
mesh.name = "-" + (i + 1) + "-" + (j + 1);
mesh.position.set(-long / 2 + j * 4 + 2, i * 4 + 2, -3);
this.scene.add(mesh);
}
}
},
//
outlineObj(selectedObjects) {
// EffectComposer
this.composer = new EffectComposer(this.renderer);
//
this.renderPass = new RenderPass(this.scene, this.camera);
this.composer.addPass(this.renderPass);
//
this.outlinePass = new OutlinePass(
new THREE.Vector2(window.innerWidth, window.innerHeight),
this.scene,
this.camera,
selectedObjects
);
this.outlinePass.edgeStrength = 8.0; //
this.outlinePass.edgeGlow = 1; // [0,1]
this.outlinePass.usePatternTexture = false; // 使
this.outlinePass.edgeThickness = 3; //
this.outlinePass.downSampleRatio = 1; //
this.outlinePass.pulsePeriod = 2; //
this.outlinePass.visibleEdgeColor.set(parseInt(0x00f6ff)); //
this.outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0); //
// this.outlinePass.clear = true
this.composer.addPass(this.outlinePass); //
this.outlinePass.selectedObjects = selectedObjects; //
},
//
onMouseClick(event) {
//raycaster-11
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
this.mouse.y = -(event.clientY / (window.innerHeight - 50)) * 2 + 1;
// raycaster
this.raycaster.setFromCamera(this.mouse, this.camera);
// raycaster线
let intersects = this.raycaster.intersectObjects(this.scene.children);
if (!intersects[0]) {
return;
} else {
if (!intersects[0].object.name == "") {
this.selectedObjects = [];
this.selectedObjects.push(intersects[0].object);
this.outlineObj(this.selectedObjects);
this.positionObj = {
x: intersects[0].object.position.x,
y: intersects[0].object.position.y,
z: intersects[0].object.position.z,
};
this.initTween(
this.positionObj.x,
this.positionObj.y,
this.positionObj.z
);
this.isDisabled = false;
this.controls.autoRotate = false;
}
}
},
//
initTween(targetX, targetY, targetZ) {
// this
let initPosition = {
x: this.camera.position.x,
y: this.camera.position.y,
z: this.camera.position.z,
};
let tween = new TWEEN.Tween(initPosition)
.to({ x: targetX, y: targetY, z: targetZ }, 2000)
.easing(TWEEN.Easing.Sinusoidal.InOut);
let onUpdate = (pos) => {
let x = pos.x;
let y = pos.y;
let z = pos.z;
if (pos.z < 0) {
this.camera.position.set(x, y, z - 12);
} else {
this.camera.position.set(x, y, z + 12);
}
};
tween.onUpdate(onUpdate);
tween.start();
// this.controls.target.set(0, 0, 0);
if (this.positionObj.z < 0) {
this.controls.target.set(
this.positionObj.x,
this.positionObj.y - 0.4,
-12
);
} else {
this.controls.target.set(
this.positionObj.x,
this.positionObj.y - 0.4,
12
);
}
},
toHomeView(id) {
const { long, tall } = this;
if (id === 1) {
let initPosition = {
x: this.camera.position.x,
y: this.camera.position.y,
z: this.camera.position.z,
};
let tween = new TWEEN.Tween(initPosition)
.to({ x: 0, y: -(5 * tall) / 12, z: (6 * long) / 5 }, 2000)
.easing(TWEEN.Easing.Sinusoidal.InOut);
let onUpdate = (pos) => {
let x = pos.x;
let y = pos.y;
let z = pos.z;
this.camera.position.set(x, y, z);
};
tween.onUpdate(onUpdate);
tween.start();
this.controls.target.set(0, 0, 0);
this.isDisabled = true;
this.controls.autoRotate = true;
}
},
//
onWindowResize() {
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
},
//使OrbitControls
initControls() {
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
//
this.controls.dampingFactor = 0.25;
// this.controls.target.set(0, 900, 0)
// //
this.controls.minPolarAngle = 0;
this.controls.maxPolarAngle = 1.5;
this.controls.autoRotate = true;
//0.25
this.controls.dampingFactor = 0.25;
//zoomzoom1
//
this.controls.zoomSpeed = 1.0;
//()
this.controls.minDistance = 1;
this.controls.maxDistance = Infinity;
//
this.minAzimuthAngle = -Math.PI * 2;
this.maxAzimuthAngle = Math.PI * 2;
this.controls.enabledPan = true;
this.keyPanSpeed = 7.0;
},
//
animate() {
TWEEN.update();
this.renderer.render(this.scene, this.camera);
this.controls.update();
if (this.composer) {
this.composer.render();
}
requestAnimationFrame(this.animate);
},
//
init() {
this.initScene();
this.initCamera();
this.initLight();
this.initRender();
this.initModel();
this.initControls();
this.animate();
window.onresize = this.onWindowResize;
window.onclick = this.onMouseClick;
},
},
};
</script>
<style scoped>
.container {
width: 100%;
height: 100%;
position: relative;
}
#btns {
position: absolute;
background-color: #031b34;
bottom: 0;
left: 50%;
width: 80px;
height: 30px;
line-height: 30px;
transform: translate(-50%, -50%);
text-align: center;
z-index: 9999;
color: #00eeff;
font-weight: bold;
box-shadow: 0px 0px 2px 1px #00f6ff;
border-radius: 6px;
border: 1px solid #00f6ff;
padding: 0;
}
/*模型样式*/
#model {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
}
</style>

View File

@ -5,7 +5,6 @@
主视角
</div>
</div>
</template>
<script setup>
import * as THREE from "three";
@ -21,7 +20,7 @@ import {
// import renderModel from "../renderModel";
import homeIcon from '@/assets/image/bg7.jpg'
import TWEEN from "@tweenjs/tween.js";
import bus from '@/utils/bus.js'
import Bus from '@/utils/bus.js'
let scene = ref(null);
let renderer = ref(null);
@ -59,10 +58,24 @@ watch(() => props.sceneUrl, val => {
init();
loadSence();
});
onMounted(() => {
bus.on('foo', e => {
//
Bus.on('clickBuild', (isParent) => {
// Todo
console.log('clickBuild', isParent);
})
//
Bus.on('clickDevice', e => {
// Todo
console.log('clickDevice');
})
})
//
Bus.on('clickApplication', e => {
// Todo
console.log('clickApplication');
})
onMounted(() => {
init();
loadSence();
//
@ -129,17 +142,17 @@ const initTween = (targetX, targetY, targetZ) => {
z: camera.position.z,
};
let tween = new TWEEN.Tween(initPosition)
.to({ x: targetX, y: targetY, z: targetZ }, 2000)
.easing(TWEEN.Easing.Sinusoidal.InOut);
.to({ x: targetX, y: targetY, z: targetZ }, 2000)
.easing(TWEEN.Easing.Sinusoidal.InOut);
let onUpdate = (pos) => {
let x = pos.x;
let y = pos.y;
let z = pos.z;
if (pos.z < 0) {
camera.position.set(x, y, z - 12);
} else {
camera.position.set(x, y, z + 12);
}
let x = pos.x;
let y = pos.y;
let z = pos.z;
if (pos.z < 0) {
camera.position.set(x, y, z - 12);
} else {
camera.position.set(x, y, z + 12);
}
};
tween.onUpdate(onUpdate);
tween.start();
@ -197,9 +210,9 @@ const onMouseDown = (event) => {
selectedObjects = [];
selectedObjects.push(intersects[0].object);
positionObj = {
x: intersects[0].object.position.x,
y: intersects[0].object.position.y,
z: intersects[0].object.position.z,
x: intersects[0].object.position.x,
y: intersects[0].object.position.y,
z: intersects[0].object.position.z,
};
initTween(
@ -235,6 +248,7 @@ const toHomeView = () => {
height: 100%;
width: 100%;
}
.button {
width: 80px;
height: 80px;

View File

@ -6,7 +6,7 @@
<!-- 底部菜单 -->
<MenuTab @changeMenu="changeMenu"></MenuTab>
<!-- 左侧建筑菜单 -->
<BuildTree v-if="activateIndex == 0" isSetTree="true" @handleNodeClick="handleBuildClick"></BuildTree>
<BuildTree v-if="activateIndex == 0" @handleNodeClick="handleBuildClick"></BuildTree>
<!-- 建筑信息 -->
<BuildInfo v-if="buildInfo && activateIndex == 0"></BuildInfo>
<!-- 资产信息 -->
@ -103,7 +103,7 @@ const handleDeviceClick = (value) => {
}
const handleApplicationClick = (value) => {
console.log(value);
}
const changeMenu = (index) => {