import * as THREE from 'three'; import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js'; import { setModalCenter } from '/@/utils/threejs/util'; // import * as dat from 'dat.gui'; // const gui = new dat.GUI(); // gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999'; class WorkFace { model; modelName = 'workFace'; group: THREE.Object3D = new THREE.Object3D(); planeGroup: THREE.Group = new THREE.Group(); bloomComposer: EffectComposer | null = null; finalComposer: EffectComposer | null = null; outlinePass: OutlinePass | null = null; positions: THREE.Vector3[][] = []; bloomLayer = new THREE.Layers(); darkMaterial = new THREE.MeshBasicMaterial({ color: 'black', transparent: true, side: THREE.DoubleSide }); materials = {}; glob = { ENTIRE_SCENE: 0, BLOOM_SCENE: 10, N: 100, }; locationTexture: THREE.Texture | null = null; warningLocationTexture: THREE.Texture | null = null; errorLocationTexture: THREE.Texture | null = null; playerStartClickTime1 = new Date().getTime(); playerStartClickTime2 = new Date().getTime(); planeNum = 0; constructor(model) { this.model = model; this.group.name = this.modelName; } addLight() { const directionalLight = new THREE.DirectionalLight(0xffffff, 1); directionalLight.position.set(-196, 150, 258); this.group.add(directionalLight); directionalLight.target = this.group; } setControls = () => { if (this.model && this.model.orbitControls) { this.model.orbitControls.panSpeed = 0.5; this.model.orbitControls.rotateSpeed = 0.5; this.model.orbitControls.maxPolarAngle = Math.PI / 3; this.model.orbitControls.minPolarAngle = Math.PI / 4; this.model.orbitControls.minAzimuthAngle = -Math.PI / 3; this.model.orbitControls.maxAzimuthAngle = Math.PI / 4; } }; render() { this.model.renderer?.render(this.model.scene as THREE.Scene, this.model.camera as THREE.PerspectiveCamera); } /* 点击 */ mousedownModel(rayCaster: THREE.Raycaster) { const opticalFiber = this.group.getObjectByName('opticalfiber'); if (opticalFiber) { const intersects = rayCaster?.intersectObjects([...opticalFiber.children]) as THREE.Intersection[]; // 判断是否点击到视频 intersects.find((intersect) => { const mesh = intersect.object; if (mesh.name.startsWith('optical_fiber_')) { // outlinePass?.selectedObjects.push(mesh); return true; } return false; }); } this.render(); } mouseUpModel() { // } setThreePlane() { const gltfModal = this.group.getObjectByName('workFace'); const PouMian01 = gltfModal?.getObjectByName('PouMian01'); const DiXing = PouMian01?.getObjectByName('DiXing'); // 绘制采空区三带 // new THREE.Vector3(934.695, -141.85, -365.375), // new THREE.Vector3(934.695, 623.933, -365.375), //-365.355 const material1 = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide, vertexColors: true }); const offeset = 10; const yellowLen = offeset * 8; // 红=》红 const curveRed = new THREE.CatmullRomCurve3([new THREE.Vector3(-477.721, -141.83, -365.375), new THREE.Vector3(-477.721, 623.933, -365.375)]); const curve0 = new THREE.CatmullRomCurve3([ new THREE.Vector3(-231.811 - 150, -141.83, -365.375), new THREE.Vector3(-121.899 - 150, 67.201, -365.375), new THREE.Vector3(-242.441 - 150, 408.812, -365.375), new THREE.Vector3(-179.811 - 150, 620.836, -365.375), ]); const pointsRed = curveRed.getPoints(80); const points0 = curve0.getPoints(80); const newPointRed: number[] = []; const normalsRed: number[] = []; const colorsRed: number[] = []; for (let i = 0; i < 80; i++) { newPointRed.push(pointsRed[i].x, pointsRed[i].y, pointsRed[i].z); newPointRed.push(points0[i].x, points0[i].y, points0[i].z); newPointRed.push(points0[i + 1].x, points0[i + 1].y, points0[i + 1].z); newPointRed.push(points0[i + 1].x, points0[i + 1].y, points0[i + 1].z); newPointRed.push(pointsRed[i + 1].x, pointsRed[i + 1].y, pointsRed[i + 1].z); newPointRed.push(pointsRed[i].x, pointsRed[i].y, pointsRed[i].z); normalsRed.push(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1); colorsRed.push(1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0); } const geometryRed = new THREE.BufferGeometry(); geometryRed.setAttribute('position', new THREE.BufferAttribute(new Float32Array(newPointRed), 3)); geometryRed.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(normalsRed), 3)); geometryRed.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colorsRed), 3)); const meshRed = new THREE.Mesh(geometryRed, material1); meshRed.position.setZ(-1); DiXing?.add(meshRed); // 红=》黄 const curve1 = new THREE.CatmullRomCurve3([ new THREE.Vector3(-231.811 - yellowLen, -141.83, -365.375), new THREE.Vector3(-121.899 - yellowLen, 67.201, -365.375), new THREE.Vector3(-242.441 - yellowLen, 408.812, -365.375), new THREE.Vector3(-179.811 - yellowLen, 620.836, -365.375), ]); const points1 = curve1.getPoints(80); const newPoints0: number[] = []; const normals0: number[] = []; const colors0: number[] = []; for (let i = 0; i < 80; i++) { newPoints0.push(points0[i].x, points0[i].y, points0[i].z); newPoints0.push(points1[i].x, points1[i].y, points1[i].z); newPoints0.push(points1[i + 1].x, points1[i + 1].y, points1[i + 1].z); newPoints0.push(points1[i + 1].x, points1[i + 1].y, points1[i + 1].z); newPoints0.push(points0[i + 1].x, points0[i + 1].y, points0[i + 1].z); newPoints0.push(points0[i].x, points0[i].y, points0[i].z); normals0.push(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1); colors0.push(1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0); } const geometry0 = new THREE.BufferGeometry(); geometry0.setAttribute('position', new THREE.BufferAttribute(new Float32Array(newPoints0), 3)); geometry0.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals0), 3)); geometry0.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colors0), 3)); geometry0.computeBoundingBox(); // const material1 = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide, color: '#fff' }); const mesh0 = new THREE.Mesh(geometry0, material1); mesh0.name = 'yellow'; mesh0.position.setZ(-1); DiXing?.add(mesh0); // 黄=》黄 const curveYellow1 = new THREE.CatmullRomCurve3([ new THREE.Vector3(784.664 - yellowLen, 623.933, -365.355), new THREE.Vector3(167.212 - yellowLen, 450.517, -365.355), new THREE.Vector3(7.587 - yellowLen, 262.225, -365.355), new THREE.Vector3(426.499 - yellowLen, 31.416, -365.355), new THREE.Vector3(261.665 - yellowLen, -139.495, -365.355), ]); const curveYellow2 = new THREE.CatmullRomCurve3([ new THREE.Vector3(-179.811 - yellowLen, 620.836, -365.375), new THREE.Vector3(-242.441 - yellowLen, 408.812, -365.375), new THREE.Vector3(-121.899 - yellowLen, 67.201, -365.375), new THREE.Vector3(-231.811 - yellowLen, -141.83, -365.375), ]); const pointsYellow1 = curveYellow1.getPoints(80); const pointsYellow2 = curveYellow2.getPoints(80); const newPointYellow: number[] = []; const normalsYellow: number[] = []; const colorsYellow: number[] = []; for (let i = 0; i < 80; i++) { newPointYellow.push(pointsYellow1[i].x, pointsYellow1[i].y, pointsYellow1[i].z); newPointYellow.push(pointsYellow2[i].x, pointsYellow2[i].y, pointsYellow2[i].z); newPointYellow.push(pointsYellow2[i + 1].x, pointsYellow2[i + 1].y, pointsYellow2[i + 1].z); newPointYellow.push(pointsYellow2[i + 1].x, pointsYellow2[i + 1].y, pointsYellow2[i + 1].z); newPointYellow.push(pointsYellow1[i + 1].x, pointsYellow1[i + 1].y, pointsYellow1[i + 1].z); newPointYellow.push(pointsYellow1[i].x, pointsYellow1[i].y, pointsYellow1[i].z); normalsYellow.push(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1); colorsYellow.push(1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0); } const geometryYellow = new THREE.BufferGeometry(); geometryYellow.setAttribute('position', new THREE.BufferAttribute(new Float32Array(newPointYellow), 3)); geometryYellow.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(normalsYellow), 3)); geometryYellow.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colorsYellow), 3)); const meshYellow = new THREE.Mesh(geometryYellow, material1); meshYellow.position.setZ(-1); DiXing?.add(meshYellow); // 蓝 =》 蓝 const curve3 = new THREE.CatmullRomCurve3([ new THREE.Vector3(784.664, 623.933, -365.355), new THREE.Vector3(167.212, 450.517, -365.355), new THREE.Vector3(7.587, 262.225, -365.355), new THREE.Vector3(426.499, 31.416, -365.355), new THREE.Vector3(261.665, -139.495, -365.355), ]); const points = curve3.getPoints(80); points.unshift(new THREE.Vector3(934.695, 623.933, -365.375)); points.unshift(new THREE.Vector3(934.695, -141.85, -365.375)); points.push(new THREE.Vector3(934.695, -141.85, -365.375)); const newPoints: THREE.Vector2[] = []; for (let i = 0; i < points.length; i++) { const point = points[i]; newPoints.push(new THREE.Vector2(point.x, point.y)); } const shape = new THREE.Shape(newPoints); const geometry = new THREE.ShapeGeometry(shape); const material = new THREE.MeshBasicMaterial({ side: THREE.BackSide, color: '#00F' }); const mesh = new THREE.Mesh(geometry, material); mesh.position.setZ(-366.485); DiXing?.add(mesh); // 黄色-》蓝色 const curve2 = new THREE.CatmullRomCurve3([ new THREE.Vector3(784.664 - yellowLen, 623.933, -365.355), new THREE.Vector3(167.212 - yellowLen, 450.517, -365.355), new THREE.Vector3(7.587 - yellowLen, 262.225, -365.355), new THREE.Vector3(426.499 - yellowLen, 31.416, -365.355), new THREE.Vector3(261.665 - yellowLen, -139.495, -365.355), ]); const curve4 = new THREE.CatmullRomCurve3([ new THREE.Vector3(784.664, 623.933, -365.355), new THREE.Vector3(167.212, 450.517, -365.355), new THREE.Vector3(7.587, 262.225, -365.355), new THREE.Vector3(426.499, 31.416, -365.355), new THREE.Vector3(261.665, -139.495, -365.355), ]); const points2 = curve2.getPoints(80); const points3 = curve4.getPoints(80); const newPoints1: number[] = []; const normals: number[] = []; const colors: number[] = []; for (let i = 0; i < 80; i++) { newPoints1.push(points2[i].x, points2[i].y, points2[i].z); newPoints1.push(points3[i].x, points3[i].y, points3[i].z); newPoints1.push(points3[i + 1].x, points3[i + 1].y, points3[i + 1].z); newPoints1.push(points3[i + 1].x, points3[i + 1].y, points3[i + 1].z); newPoints1.push(points2[i + 1].x, points2[i + 1].y, points2[i + 1].z); newPoints1.push(points2[i].x, points2[i].y, points2[i].z); normals.push(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1); colors.push(1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0); } const geometry1 = new THREE.BufferGeometry(); geometry1.setAttribute('position', new THREE.BufferAttribute(new Float32Array(newPoints1), 3)); geometry1.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals), 3)); geometry1.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3)); geometry1.computeBoundingBox(); const mesh1 = new THREE.Mesh(geometry1, material1); mesh1.name = 'blue'; mesh1.position.setZ(-1); DiXing?.add(mesh1); } setModalType(modalType) { // debugger; const gltfModal = this.group.getObjectByName('workFace'); const workFace1 = gltfModal?.getObjectByName('YiJinYiHui'); const workFace2 = gltfModal?.getObjectByName('LiangJinYiHui'); const workFace3 = gltfModal?.getObjectByName('LiangJinLiangHui'); if (workFace1 && workFace2 && workFace3) { if (modalType === 'workFace1') { // 单进单回 workFace1.visible = true; workFace2.visible = false; workFace3.visible = false; } else if (modalType === 'workFace3') { // 双进单回 workFace1.visible = false; workFace2.visible = true; workFace3.visible = false; } else if (modalType === 'workFace4') { workFace1.visible = false; workFace2.visible = false; workFace3.visible = true; } } } mountedThree() { return new Promise(async (resolve) => { this.model.renderer.sortObjects = true; this.model.orbitControls.update(); this.model.setGLTFModel('workFace').then(async (gltf) => { const gltfModal = gltf[0]; this.group = gltfModal; this.group.name = this.modelName; setModalCenter(this.group); this.group.scale.set(2.5, 2.5, 2.5); this.addLight(); this.setThreePlane(); this.setControls(); resolve(null); }); }); } destroy() { this.model.clearGroup(this.group); this.model = null; this.group = null; this.bloomComposer?.dispose(); this.finalComposer?.dispose(); } } export default WorkFace;