{"remainingRequest":"D:\\jenkins\\workspace\\sfz-lh-fvue\\node_modules\\thread-loader\\dist\\cjs.js!D:\\jenkins\\workspace\\sfz-lh-fvue\\node_modules\\babel-loader\\lib\\index.js!D:\\jenkins\\workspace\\sfz-lh-fvue\\node_modules\\cache-loader\\dist\\cjs.js??ref--0-0!D:\\jenkins\\workspace\\sfz-lh-fvue\\node_modules\\vue-loader\\lib\\index.js??vue-loader-options!D:\\jenkins\\workspace\\sfz-lh-fvue\\src\\views\\BigScreen\\3DModel\\modelIndex.vue?vue&type=script&lang=js&","dependencies":[{"path":"D:\\jenkins\\workspace\\sfz-lh-fvue\\src\\views\\BigScreen\\3DModel\\modelIndex.vue","mtime":1706594417306},{"path":"D:\\jenkins\\workspace\\sfz-lh-fvue\\node_modules\\cache-loader\\dist\\cjs.js","mtime":499162500000},{"path":"D:\\jenkins\\workspace\\sfz-lh-fvue\\node_modules\\thread-loader\\dist\\cjs.js","mtime":499162500000},{"path":"D:\\jenkins\\workspace\\sfz-lh-fvue\\node_modules\\babel-loader\\lib\\index.js","mtime":315532800000},{"path":"D:\\jenkins\\workspace\\sfz-lh-fvue\\node_modules\\cache-loader\\dist\\cjs.js","mtime":499162500000},{"path":"D:\\jenkins\\workspace\\sfz-lh-fvue\\node_modules\\vue-loader\\lib\\index.js","mtime":499162500000}],"contextDependencies":[],"result":["import _toConsumableArray from \"D:/jenkins/workspace/sfz-lh-fvue/node_modules/@babel/runtime/helpers/esm/toConsumableArray\";\nimport \"core-js/modules/es6.regexp.replace\";\nimport \"core-js/modules/es6.function.name\";\nimport \"core-js/modules/web.dom.iterable\";\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\nimport player from '@/views/Normal/components/videoPlayerDH.vue';\nimport * as THREE from 'three';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; // import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader.js'\n\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { CSS2DObject, CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer.js';\nimport { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'; // 用于模型边缘高亮\n\nimport { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';\nimport { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';\nimport { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js';\nimport { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js';\nimport { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';\nimport { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js';\nimport deviceTypeList from \"./deviceTypeList.js\";\nimport laneData from \"./laneData.js\";\nimport iconName from \"./iconName.js\";\nimport utils from '@/utils.js';\nimport deviceAPI from '@/api/DeviceManagement/device.js';\nimport commonAPI from '@/api/bigScreen/common.js';\nimport DBUtils from \"./loader.js\";\nexport default {\n name: 'ModelIndex',\n components: {\n player: player\n },\n data: function data() {\n return {\n width: 0,\n height: 0,\n scene: null,\n camera: null,\n controls: null,\n renderer: null,\n css2Renderer: null,\n clock: null,\n mixer: null,\n stats: null,\n animationId: null,\n chooseObj: null,\n tag: null,\n percent: 0,\n gui: null,\n composer: null,\n //效果组合器\n outlinePass: null,\n //发光通道\n effectFXAA: null,\n //自定义的着色器通道\n pole1: null,\n deviceList: {},\n // 设备对象\n activeList: [],\n tagData: null,\n //设备数据\n iconGroup: {} // 图标对象的组合\n\n };\n },\n mounted: function mounted() {\n this.width = window.innerWidth;\n this.height = window.innerHeight;\n this.init();\n this.animate();\n },\n methods: {\n getDictName: function getDictName(code, value) {\n return utils.getDictName(code, value);\n },\n changeDevice: function changeDevice(list) {\n var _this = this;\n\n this.drop();\n this.activeList = [];\n list.forEach(function (item) {\n for (var key in _this.deviceList[item]) {\n var icon = _this.createIcon(item);\n\n _this.iconGroup[_this.deviceList[item][key].name] = icon;\n\n _this.deviceList[item][key].add(_this.iconGroup[_this.deviceList[item][key].name]);\n\n _this.activeList.push(_this.deviceList[item][key]);\n }\n });\n this.pick(this.activeList);\n this.animate();\n },\n //栏杆机旋转\n ploeRotate: function ploeRotate() {\n if (this.poloState.pole1 == 1) {\n this.pole1.rotation.set(Math.PI / 2, 0, 0, 'XZY');\n this.poloState.pole1 = 0;\n } else {\n this.pole1.rotation.set(0, 0, 0, 'XZY');\n this.poloState.pole1 = 1;\n }\n },\n close: function close() {\n if (this.chooseObj) {\n //把原来选中模型对应的标签和发光描边隐藏\n this.chooseObj.remove(this.tag); //从场景移除\n }\n },\n addComposer: function addComposer() {\n // 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。\n this.composer = new EffectComposer(this.renderer); // 新建一个场景通道 为了覆盖到原来的场景上\n\n var renderPass = new RenderPass(this.scene, this.camera);\n this.composer.addPass(renderPass); // 物体边缘发光通道\n\n this.outlinePass = new OutlinePass(new THREE.Vector2(this.width, this.height), this.scene, this.camera);\n this.outlinePass.visibleEdgeColor.set(parseInt(0x07e1e7)); // 呼吸显示的颜色\n\n this.outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0); // 呼吸消失的颜色\n\n this.composer.addPass(this.outlinePass); // 解决高亮后环境变暗的问题\n\n var outputPass = new OutputPass();\n this.composer.addPass(outputPass); // 自定义的着色器通道 作为参数\n\n this.effectFXAA = new ShaderPass(FXAAShader);\n this.effectFXAA.uniforms['resolution'].value.set(1 / this.width, 1 / this.height);\n this.composer.addPass(this.effectFXAA);\n },\n createIcon: function createIcon(type) {\n var name = iconName[type]; // 创建div元素(作为标签)\n\n var div = document.createElement('div');\n div.style.width = '30px';\n div.style.height = '52px';\n\n var img = require(\"@/assets/img/bigScreen/\".concat(name, \".png\"));\n\n div.style.background = \"url(\".concat(img, \") no-repeat center / 100% 100%\");\n div.classList.add('icon-box');\n var label = new CSS2DObject(div); // div.style.pointerEvents = 'none'\n\n return label; //返回CSS2模型标签\n },\n getALLDevice: function getALLDevice(gltf) {\n var _this2 = this;\n\n var _loop = function _loop(key) {\n _this2.deviceList[key] = {};\n deviceTypeList[key].forEach(function (item) {\n _this2.deviceList[key][item] = gltf.scene.getObjectByName(item);\n });\n };\n\n for (var key in deviceTypeList) {\n _loop(key);\n }\n },\n loadModel: function loadModel() {\n var _this3 = this;\n\n var indexDB = new DBUtils('indexdb001', 'sfz-lh', 1);\n indexDB.get('./static/3DModel/sfz-lh.gltf').then(function (blob) {\n var url = URL.createObjectURL(new Blob([blob]));\n var loader = new GLTFLoader();\n loader.load(url, function (gltf) {\n var root = gltf.scene; //...(下面部分就和threejs加载glb模型代码一样,按业务需求做相应的操作)\n\n _this3.percent = 100;\n\n _this3.getALLDevice(gltf);\n\n _this3.createLane();\n\n _this3.scene.add(root);\n\n THREE.Cache.add('model', gltf);\n document.getElementById('loading').style.display = 'none';\n\n _this3.animate();\n }, function (xhr) {\n var loaded = xhr.loaded,\n total = xhr.total;\n var percent = Math.floor(loaded / total * 100);\n\n if (percent < 96) {\n _this3.percent = percent;\n }\n });\n });\n },\n // loadModel() {\n // const loader = new GLTFLoader()\n // loader.load(\n // './static/3DModel/sfz-lh.gltf',\n // (gltf) => {\n // this.percent = 100\n // this.getALLDevice(gltf)\n // this.createLane()\n // // this.pole1 = gltf.scene.getObjectByName('G-__588756')\n // this.scene.add(gltf.scene)\n // document.getElementById('loading').style.display = 'none'\n // },\n // (xhr) => {\n // let percent = Math.floor((xhr.loaded / xhr.total) * 100)\n // if (percent < 96) {\n // this.percent = percent\n // }\n // },\n // (error) => {\n // console.log(error)\n // }\n // )\n // },\n GUIControler: function GUIControler(mesh) {\n this.gui = new GUI();\n this.gui.domElement.style.right = '0px';\n this.gui.domElement.style.top = '100px';\n this.gui.domElement.style.width = '300px';\n this.gui.add(mesh.position, 'x', -100, 100).name('X坐标').step(0.1);\n this.gui.add(mesh.position, 'y', -100, 100).name('Y坐标').step(0.1);\n this.gui.add(mesh.position, 'z', -100, 100).name('Z坐标').step(0.1);\n },\n createLane: function createLane() {\n var _this4 = this;\n\n this.deviceList['入口'] = {};\n this.deviceList['出口'] = {};\n laneData.Lanes.forEach(function (item) {\n // PlaneGeometry\n var geometry = new THREE.PlaneGeometry(30, 4.5, 1, 1);\n geometry.rotateX(Math.PI / 2); // 材质对象Material\n\n var material = new THREE.MeshBasicMaterial({\n color: 0x434446,\n //设置材质颜色\n opacity: 0.01,\n transparent: true,\n //开启透明\n side: THREE.DoubleSide\n });\n var mesh = new THREE.Mesh(geometry, material);\n mesh.name = item.name;\n mesh.position.set(item.x, item.y, item.z);\n\n _this4.scene.add(mesh); //网格模型添加到场景中\n\n\n if (item.type == '入口') {\n _this4.deviceList['入口'][item.name] = mesh;\n } else {\n _this4.deviceList['出口'][item.name] = mesh;\n }\n });\n },\n createCss2Render: function createCss2Render() {\n var container = this.$refs.threeDBox;\n var div = document.getElementById('tag'); // HTML元素转化为threejs的CSS2模型对象\n\n this.tag = new CSS2DObject(div); // mesh.add(tag)\n\n document.getElementById('close').style.pointerEvents = 'auto';\n this.css2Renderer = new CSS2DRenderer();\n this.css2Renderer.setSize(window.innerWidth, window.innerHeight);\n container.appendChild(this.css2Renderer.domElement);\n this.css2Renderer.domElement.style.pointerEvents = 'none';\n this.css2Renderer.domElement.style.position = 'absolute';\n this.css2Renderer.domElement.style.top = '0px';\n },\n createAmbient: function createAmbient() {\n var ambient = new THREE.AmbientLight(0xffffff, 1);\n this.scene.add(ambient);\n var directionalLight = new THREE.DirectionalLight(0xffffff, 2); // 设置光源的方向:通过光源position属性和目标指向对象的position属性计算\n\n directionalLight.position.set(80, 100, 50); // 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0\n // directionalLight.target = mesh\n\n this.scene.add(directionalLight);\n },\n init: function init() {\n var _this5 = this;\n\n THREE.Cache.enabled = true; //开启缓存\n\n var container = this.$refs.threeDBox;\n this.scene = new THREE.Scene(); // 创建纹理加载器\n\n var textureLoader = new THREE.TextureLoader(); // 创建天空球\n\n var skyGeometry = new THREE.SphereGeometry(1000, 60, 60);\n var skyTexture = textureLoader.load( // './static/3DModel/img/sky.jpg'\n './static/3DModel/img/sky.png'); // 天空纹理\n\n var skyMaterial = new THREE.MeshBasicMaterial({\n map: skyTexture // 颜色贴图\n\n }); // 反转球体,主要是反转z轴\n\n skyGeometry.scale(1, 1, -1);\n var sky = new THREE.Mesh(skyGeometry, skyMaterial);\n this.scene.add(sky);\n this.camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 3000); // -87.0511, 4.7929, 0.799\n\n this.camera.position.set(-82.3681, 4.6218, 0.3505);\n this.camera.lookAt(0, 0, 0);\n this.createCss2Render(); // 二维弹窗\n\n this.loadModel(); //加载模型\n // const axesHelper = new THREE.AxesHelper(100)\n // this.scene.add(axesHelper)\n\n this.createAmbient();\n this.renderer = new THREE.WebGLRenderer({\n antialias: true\n });\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n this.renderer.outputColorSpace = THREE.SRGBColorSpace; //设置为SRGB颜色空间\n\n container.appendChild(this.renderer.domElement);\n this.controls = new OrbitControls(this.camera, this.renderer.domElement); //-65.1083, 4.2508, 0.851\n\n this.controls.target = new THREE.Vector3();\n this.controls.minDistance = 0;\n this.controls.maxDistance = 200;\n this.controls.minPolarAngle = 0;\n this.controls.maxPolarAngle = 1.55; //Math.PI\n // this.controls.enablePan = false // 移动\n\n this.controls.update();\n this.controls.addEventListener('change', this.animate);\n window.addEventListener('resize', this.onWindowResize);\n this.renderer.domElement.addEventListener('click', function (event) {\n // .offsetY、.offsetX以canvas画布左上角为坐标原点,单位px\n var px = event.offsetX;\n var py = event.offsetY; // 屏幕坐标px、py转WebGL标准设备坐标x、y\n // width、height表示canvas画布宽高度\n\n var x = px / window.innerWidth * 2 - 1;\n var y = -(py / window.innerHeight) * 2 + 1; //创建一个射线投射器`Raycaster`\n\n var raycaster = new THREE.Raycaster(); //.setFromCamera()计算射线投射器`Raycaster`的射线属性.ray\n // 形象点说就是在点击位置创建一条射线,射线穿过的模型代表选中\n\n raycaster.setFromCamera(new THREE.Vector2(x, y), _this5.camera); //.intersectObjects([mesh1, mesh2, mesh3])对参数中的网格模型对象进行射线交叉计算\n // 未选中对象返回空数组[],选中一个对象,数组1个元素,选中两个对象,数组两个元素\n // const intersects = raycaster.intersectObjects([mesh])\n // const intersects = raycaster.intersectObject(this.scene, true)\n\n var intersects = raycaster.intersectObjects(_this5.activeList); // console.log('射线器返回的对象', intersects)\n // intersects.length大于0说明,说明选中了模型\n\n if (intersects.length > 0) {\n // 选中模型的第一个模型,设置为红色\n // this.drop()\n // intersects[0].object.material.color.set(0xff0000)\n _this5.chooseObj = intersects[0].object;\n intersects[0].object.add(_this5.tag);\n\n _this5.getData(); // this.pick([this.chooseObj])\n\n } else {\n // mesh.material.color.set(0xfff000)\n if (_this5.chooseObj) {\n //把原来选中模型对应的标签和发光描边隐藏\n _this5.chooseObj.remove(_this5.tag); //从场景移除\n // this.drop()\n\n\n _this5.chooseObj = null;\n _this5.tagData = null;\n }\n }\n\n _this5.animate();\n });\n this.addComposer();\n setTimeout(function () {\n _this5.state = '异常';\n }, 10000);\n },\n getData: function getData() {\n var _this6 = this;\n\n var play = document.getElementById('play'); // console.log(this.chooseObj, play)\n\n if (this.chooseObj.name.indexOf('lane') == -1) {\n var sysCode = this.chooseObj.name.length > 10 ? this.chooseObj.name.slice(0, 10) : this.chooseObj.name;\n var queryData = {\n pageBean: {\n page: 1,\n pageSize: -1,\n showTotal: true\n },\n querys: [{\n group: 'main',\n operation: 'EQUAL',\n parentGroup: '',\n property: 'sysCode',\n relation: 'AND',\n value: sysCode\n }]\n };\n deviceAPI.queryDeviceList(queryData).then(function (res) {\n if (res.value && res.value.rows) {\n _this6.tagData = res.value.rows[0];\n\n if (_this6.tagData && _this6.tagData.type == 1) {\n _this6.$nextTick(function () {\n document.getElementById('tag').style.zIndex = 999;\n\n _this6.$refs.player.play(_this6.tagData);\n });\n }\n }\n });\n } else {\n var id = this.chooseObj.name.replace('lane', '');\n\n var _queryData = this.qs.stringify({\n laneId: id\n });\n\n commonAPI.queryLaneData(_queryData).then(function (res) {\n if (res.value && res.value.length) {\n _this6.tagData = res.value[0];\n }\n });\n }\n },\n drop: function drop() {\n var _this7 = this;\n\n this.activeList.forEach(function (item) {\n item.remove(_this7.iconGroup[item.name]);\n });\n this.outlinePass.selectedObjects = [];\n },\n pick: function pick(selectedObjects) {\n // 筛选出车道mesh\n var outlineObj = selectedObjects.filter(function (item) {\n return item.name.indexOf('lane') == -1;\n });\n this.outlinePass.selectedObjects = _toConsumableArray(outlineObj);\n },\n onWindowResize: function onWindowResize() {\n var width = window.innerWidth;\n var height = window.innerHeight;\n this.camera.aspect = width / height;\n this.renderer.setSize(width, height);\n this.css2Renderer.setSize(width, height);\n this.composer.setSize(width, height);\n this.camera.updateProjectionMatrix();\n this.effectFXAA.uniforms['resolution'].value.set(1 / this.width, 1 / this.height);\n },\n animate: function animate() {\n // this.animationId = requestAnimationFrame(this.animate)\n this.css2Renderer.render(this.scene, this.camera);\n this.composer.render(this.scene, this.camera); // this.renderer.render(this.scene, this.camera)\n // 根据相机控件可视化调试相机位置\n // console.log('controls.target', this.controls.target)\n // console.log('camera.position', this.camera.position)\n },\n showData: function showData() {\n console.log('controls.target', this.controls.target);\n console.log('camera.position', this.camera.position);\n },\n removeEventListeners: function removeEventListeners() {},\n destroyThreejs: function destroyThreejs() {\n try {\n this.renderer.dispose();\n this.renderer.forceContextLoss();\n this.renderer.content = null;\n var gl = this.renderer.domElement.getContext('webgl');\n\n if (gl && gl.getExtension('WEBGL_lose_context')) {\n gl.getExtension('WEBGL_lose_context').loseContext();\n }\n\n this.renderer = null;\n this.camera = null;\n this.scene.traverse(function (child) {\n if (child.material) {\n child.material.dispose();\n }\n\n if (child.geometry) {\n child.geometry.dispose();\n }\n\n child = null;\n });\n this.scene = null;\n } catch (e) {\n console.error('Failed to destroy threejs', e);\n }\n }\n },\n beforeDestroy: function beforeDestroy() {\n cancelAnimationFrame(this.animationId);\n this.removeEventListeners();\n this.destroyThreejs(); // this.gui.domElement.style.display = 'none'\n }\n};",null]}