{"remainingRequest":"D:\\jenkins\\workspace\\sfz-lh-fvue\\node_modules\\vue-loader\\lib\\index.js??vue-loader-options!D:\\jenkins\\workspace\\sfz-lh-fvue\\src\\views\\Normal\\components\\modalPosition.vue?vue&type=script&lang=js&","dependencies":[{"path":"D:\\jenkins\\workspace\\sfz-lh-fvue\\src\\views\\Normal\\components\\modalPosition.vue","mtime":1703490847547},{"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":["//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\r\nimport * as THREE from 'three'\r\nimport {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'\r\n// import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader.js'\r\nimport {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js'\r\n\r\nimport {GUI} from 'three/examples/jsm/libs/lil-gui.module.min.js'\r\nimport moment from 'moment'\r\n\r\n// 用于模型边缘高亮\r\nimport {EffectComposer} from 'three/examples/jsm/postprocessing/EffectComposer.js'\r\nimport {RenderPass} from 'three/examples/jsm/postprocessing/RenderPass.js'\r\nimport {OutlinePass} from 'three/examples/jsm/postprocessing/OutlinePass.js'\r\nimport {OutputPass} from 'three/examples/jsm/postprocessing/OutputPass.js'\r\nimport {ShaderPass} from 'three/examples/jsm/postprocessing/ShaderPass.js'\r\nimport {FXAAShader} from 'three/examples/jsm/shaders/FXAAShader.js'\r\nimport {SMAAPass} from 'three/examples/jsm/postprocessing/SMAAPass.js'\r\nimport {UnrealBloomPass} from 'three/examples/jsm/postprocessing/UnrealBloomPass.js'\r\n\r\nexport default {\r\n name: 'ModelIndex',\r\n data() {\r\n return {\r\n width: 0,\r\n height: 0,\r\n scene: null,\r\n camera: null,\r\n controls: null,\r\n renderer: null,\r\n css2Renderer: null,\r\n clock: null,\r\n mixer: null,\r\n stats: null,\r\n animationId: null,\r\n chooseObj: null,\r\n tag: null,\r\n percent: 0,\r\n gui: null,\r\n composer: null, //效果组合器\r\n outlinePass: null, //发光通道\r\n effectFXAA: null, //自定义的着色器通道\r\n }\r\n },\r\n mounted() {\r\n this.$nextTick(() => {\r\n this.width = this.$refs['model-container'].offsetWidth\r\n this.height = this.$refs['model-container'].offsetHeight\r\n this.init()\r\n\r\n this.animate()\r\n })\r\n },\r\n methods: {\r\n addComposer() {\r\n // 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。\r\n this.composer = new EffectComposer(this.renderer)\r\n // 新建一个场景通道 为了覆盖到原来的场景上\r\n let renderPass = new RenderPass(this.scene, this.camera)\r\n this.composer.addPass(renderPass)\r\n // 物体边缘发光通道\r\n this.outlinePass = new OutlinePass(\r\n new THREE.Vector2(this.width, this.height),\r\n this.scene,\r\n this.camera\r\n )\r\n this.outlinePass.visibleEdgeColor.set(parseInt(0x00ff00)) // 呼吸显示的颜色\r\n this.outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0) // 呼吸消失的颜色\r\n this.composer.addPass(this.outlinePass)\r\n\r\n // 解决高亮后环境变暗的问题\r\n const outputPass = new OutputPass()\r\n this.composer.addPass(outputPass)\r\n\r\n // 自定义的着色器通道 作为参数\r\n this.effectFXAA = new ShaderPass(FXAAShader)\r\n this.effectFXAA.uniforms['resolution'].value.set(\r\n 1 / this.width,\r\n 1 / this.height\r\n )\r\n this.composer.addPass(this.effectFXAA)\r\n },\r\n loadModel() {\r\n const loader = new GLTFLoader()\r\n loader.load(\r\n '/static/3DModel/sfz-lh.gltf',\r\n (gltf) => {\r\n this.percent = 100\r\n\r\n this.scene.add(gltf.scene)\r\n document.getElementById('loading').style.display = 'none'\r\n },\r\n (xhr) => {\r\n let percent = Math.floor((xhr.loaded / xhr.total) * 100)\r\n if (percent < 96) {\r\n this.percent = percent\r\n }\r\n },\r\n (error) => {\r\n console.log(error)\r\n }\r\n )\r\n },\r\n GUIControler(mesh) {\r\n this.gui = new GUI()\r\n\r\n this.gui.domElement.style.right = '0px'\r\n this.gui.domElement.style.top = '100px'\r\n this.gui.domElement.style.width = '300px'\r\n\r\n this.gui.add(mesh.position, 'x', -100, 100).name('X坐标').step(0.1)\r\n this.gui.add(mesh.position, 'y', -100, 100).name('Y坐标').step(0.1)\r\n this.gui.add(mesh.position, 'z', -100, 100).name('Z坐标').step(0.1)\r\n },\r\n init() {\r\n let container = this.$refs.threeDBox\r\n console.log(container, 'container')\r\n this.scene = new THREE.Scene()\r\n\r\n // 创建纹理加载器\r\n const textureLoader = new THREE.TextureLoader()\r\n // 创建天空球\r\n const skyGeometry = new THREE.SphereGeometry(1000, 60, 60)\r\n const skyTexture = textureLoader.load(\r\n // './static/3DModel/img/sky.jpg'\r\n '/static/3DModel/img/sky.png'\r\n ) // 天空纹理\r\n const skyMaterial = new THREE.MeshBasicMaterial({\r\n map: skyTexture, // 颜色贴图\r\n })\r\n // 反转球体,主要是反转z轴\r\n skyGeometry.scale(1, 1, -1)\r\n const sky = new THREE.Mesh(skyGeometry, skyMaterial)\r\n this.scene.add(sky)\r\n\r\n this.camera = new THREE.PerspectiveCamera(\r\n 30,\r\n this.width / this.height,\r\n 1,\r\n 3000\r\n )\r\n this.camera.position.set(-82.3681, 4.6218, 0.3505)\r\n this.camera.lookAt(0, 0, 0)\r\n\r\n this.loadModel() //加载模型\r\n\r\n // const axesHelper = new THREE.AxesHelper(100)\r\n // this.scene.add(axesHelper)\r\n\r\n const ambient = new THREE.AmbientLight(0xffffff, 1)\r\n this.scene.add(ambient)\r\n\r\n const directionalLight = new THREE.DirectionalLight(0xffffff, 2)\r\n // 设置光源的方向:通过光源position属性和目标指向对象的position属性计算\r\n directionalLight.position.set(80, 100, 50)\r\n // 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0\r\n // directionalLight.target = mesh\r\n this.scene.add(directionalLight)\r\n\r\n const cubeMaterial = [\r\n //side\r\n new THREE.MeshBasicMaterial({\r\n color: 0xffffff, //设置材质颜色\r\n transparent: true, //开启透明\r\n opacity: 1, //设置透明度\r\n side: THREE.FrontSide,\r\n }),\r\n //top\r\n new THREE.MeshBasicMaterial({\r\n map: new THREE.TextureLoader().load(\r\n '/static/3DModel/img/video.jpg'\r\n ),\r\n side: THREE.DoubleSide,\r\n }),\r\n //bottom\r\n new THREE.MeshBasicMaterial({\r\n map: new THREE.TextureLoader().load(\r\n '/static/3DModel/img/video.jpg'\r\n ),\r\n side: THREE.DoubleSide,\r\n }),\r\n ]\r\n const geometry = new THREE.CylinderGeometry(0.15, 0.15, 0.05)\r\n // geometry.rotateX(Math.PI / 2)\r\n // geometry.rotateZ(Math.PI / 2)\r\n // console.log('rotate', geometry)\r\n const mesh = new THREE.Mesh(geometry, cubeMaterial)\r\n mesh.position.set(8.2, 6.9, 1.3)\r\n mesh.rotation.set(0, 0, Math.PI / 2, 'XZY')\r\n this.scene.add(mesh) //网格模型添加到场景中\r\n\r\n this.GUIControler(mesh)\r\n\r\n this.renderer = new THREE.WebGLRenderer({antialias: true})\r\n this.renderer.setPixelRatio(window.devicePixelRatio)\r\n this.renderer.setSize(this.width, this.height)\r\n\r\n this.renderer.outputColorSpace = THREE.SRGBColorSpace //设置为SRGB颜色空间\r\n container.appendChild(this.renderer.domElement)\r\n\r\n this.controls = new OrbitControls(\r\n this.camera,\r\n this.renderer.domElement\r\n )\r\n // -65.1083, 4.2508, 0.851\r\n this.controls.target = new THREE.Vector3()\r\n this.controls.minDistance = 0\r\n this.controls.maxDistance = 200\r\n this.autoRotate = true\r\n this.controls.update()\r\n window.addEventListener('resize', this.onWindowResize)\r\n\r\n this.renderer.domElement.addEventListener('click', (event) => {\r\n // .offsetY、.offsetX以canvas画布左上角为坐标原点,单位px\r\n const px = event.offsetX\r\n const py = event.offsetY\r\n // 屏幕坐标px、py转WebGL标准设备坐标x、y\r\n // width、height表示canvas画布宽高度\r\n const x = (px / this.width) * 2 - 1\r\n const y = -(py / this.height) * 2 + 1\r\n\r\n //创建一个射线投射器`Raycaster`\r\n const raycaster = new THREE.Raycaster()\r\n\r\n //.setFromCamera()计算射线投射器`Raycaster`的射线属性.ray\r\n // 形象点说就是在点击位置创建一条射线,射线穿过的模型代表选中\r\n raycaster.setFromCamera(new THREE.Vector2(x, y), this.camera)\r\n //.intersectObjects([mesh1, mesh2, mesh3])对参数中的网格模型对象进行射线交叉计算\r\n // 未选中对象返回空数组[],选中一个对象,数组1个元素,选中两个对象,数组两个元素\r\n // const intersects = raycaster.intersectObjects([mesh])\r\n const intersects = raycaster.intersectObject(this.scene, true)\r\n console.log('射线器返回的对象', intersects)\r\n // intersects.length大于0说明,说明选中了模型\r\n if (intersects.length > 0) {\r\n // 选中模型的第一个模型,设置为红色\r\n // intersects[0].object.material.color.set(0xff0000)\r\n // intersects[0].object.add(this.tag)\r\n this.drop()\r\n this.chooseObj = intersects[0].object\r\n this.pick(this.chooseObj)\r\n } else {\r\n this.drop()\r\n // mesh.material.color.set(0xfff000)\r\n // if (this.chooseObj) {\r\n // //把原来选中模型对应的标签和发光描边隐藏\r\n // this.chooseObj.remove(tag) //从场景移除\r\n // }\r\n }\r\n })\r\n this.addComposer()\r\n setTimeout(() => {\r\n this.state = '异常'\r\n }, 10000)\r\n },\r\n drop() {\r\n this.outlinePass.selectedObjects = []\r\n },\r\n pick(selectedObject) {\r\n this.outlinePass.selectedObjects = [selectedObject]\r\n },\r\n onWindowResize() {\r\n this.camera.aspect = this.width / this.height\r\n this.renderer.setSize(this.width, this.height)\r\n this.composer.setSize(this.width, this.height)\r\n this.camera.updateProjectionMatrix()\r\n this.effectFXAA.uniforms['resolution'].value.set(\r\n 1 / this.width,\r\n 1 / this.height\r\n )\r\n },\r\n animate() {\r\n this.animationId = requestAnimationFrame(this.animate)\r\n this.composer.render(this.scene, this.camera)\r\n // this.renderer.render(this.scene, this.camera)\r\n\r\n // 根据相机控件可视化调试相机位置\r\n // console.log('controls.target', this.controls.target)\r\n // console.log('camera.position', this.camera.position)\r\n },\r\n showData() {\r\n console.log('controls.target', this.controls.target)\r\n console.log('camera.position', this.camera.position)\r\n },\r\n removeEventListeners() {},\r\n\r\n destroyThreejs() {\r\n try {\r\n this.renderer.dispose()\r\n this.renderer.forceContextLoss()\r\n this.renderer.content = null\r\n let gl = this.renderer.domElement.getContext('webgl')\r\n if (gl && gl.getExtension('WEBGL_lose_context')) {\r\n gl.getExtension('WEBGL_lose_context').loseContext()\r\n }\r\n this.renderer = null\r\n this.camera = null\r\n this.scene.traverse((child) => {\r\n if (child.material) {\r\n child.material.dispose()\r\n }\r\n if (child.geometry) {\r\n child.geometry.dispose()\r\n }\r\n child = null\r\n })\r\n this.scene = null\r\n } catch (e) {\r\n console.error('Failed to destroy threejs', e)\r\n }\r\n },\r\n },\r\n beforeDestroy() {\r\n cancelAnimationFrame(this.animationId)\r\n this.removeEventListeners()\r\n this.destroyThreejs()\r\n this.gui.domElement.style.display = 'none'\r\n },\r\n}\r\n",null]}