import * as THREE from 'three'; import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js'; import Smoke from '/@/views/vent/comment/threejs/Smoke'; import { PathPointList, PathGeometry } from 'three.path'; import gsap from 'gsap'; class mainWindRect { model; modelName = 'main'; group: THREE.Group | null = null; // 主通风机场景 motorGroup1: THREE.Group | null = null; //电机 motorGroup2: THREE.Group | null = null; //电机 airJin1: THREE.Mesh | null = null; //风向箭头 airJin2: THREE.Mesh | null = null; //风向箭头 airChu1: THREE.Mesh | null = null; //风向箭头 airChu2: THREE.Mesh | null = null; //风向箭头 gearFront = { gear1: null, //扇叶 gear2: null, //扇叶 gear1Direction: -1, gear2Direction: 1, gearFrameId: undefined, gearRotateFactor: 0.5, endGearRotateFactor: 3, }; gearBack = { gear1: null, //扇叶 gear2: null, //扇叶 gear1Direction: -1, // 扇叶转动方向 gear2Direction: 1, // 扇叶转动方向 gearFrameId: undefined, gearRotateFactor: 0.5, // 扇叶转动因素 endGearRotateFactor: 3, // 扇叶最终转动速度因素 }; oldMaterial: THREE.Material = new THREE.MeshStandardMaterial(); // smoke; frontSmoke: Smoke | null = null; // 前面风流对象 backSmoke: Smoke | null = null; // 后面风流对象 player1; // 视频播放器 playerStartClickTime1 = new Date().getTime(); frontWindowGroup; backWindowGroup; windowAngle = 0; fbmAnimationClip: THREE.AnimationClip | null = null; fbmMixers: THREE.AnimationMixer | null = null; fbmOpenAction: THREE.AnimationAction | null = null; clock = new THREE.Clock(); material; airTexture; offset = 0; direction = 0; // -1 代表反向,1代表正向 arrowMesh; constructor(model, playerVal1) { this.model = model; this.player1 = playerVal1; } // 添加 cssObject addCssText() { if (!this.group) { return; } const ztfjGroup = this.group.getObjectByName('ztfj'); if (!this.group.getObjectByName('monitorText1')) { const worldPosition = new THREE.Vector3(); ztfjGroup?.getObjectByName('Cylinder1042')?.getWorldPosition(worldPosition); const element = document.getElementById('inputBox') as HTMLElement; if (element) { const mainCSS3D = new CSS3DObject(element); mainCSS3D.name = 'monitorText1'; mainCSS3D.scale.set(0.09, 0.09, 0.09); // mainCSS3D.position.set(23.78, 18.18, -6.85); mainCSS3D.position.set(worldPosition.x + 12, worldPosition.y - 10, worldPosition.z - 20); mainCSS3D.lookAt(worldPosition.x + 12, worldPosition.y - 0, worldPosition.z + 2); this.group.add(mainCSS3D); } } if (!this.group.getObjectByName('monitorText2')) { const worldPosition = new THREE.Vector3(); ztfjGroup?.getObjectByName('Cylinder396')?.getWorldPosition(worldPosition); const element = document.getElementById('inputBox1') as HTMLElement; if (element) { const mainCSS3D = new CSS3DObject(element); mainCSS3D.name = 'monitorText2'; mainCSS3D.scale.set(0.09, 0.09, 0.09); // mainCSS3D.position.set(23.78, 18.18, 16.82); mainCSS3D.position.set(worldPosition.x + 12, worldPosition.y - 10, worldPosition.z - 20); mainCSS3D.lookAt(worldPosition.x + 12, worldPosition.y - 0, worldPosition.z + 2); // mainCSS3D.lookAt(23.78, 20, 20.82); this.group.add(mainCSS3D); } } if (!this.group.getObjectByName('monitorText4')) { const worldPosition = new THREE.Vector3(); const fbmGroup = this.group?.getObjectByName('fbm') as THREE.Group; if (fbmGroup) { fbmGroup?.getObjectByName('Box022')?.getWorldPosition(worldPosition); const element = document.getElementById('fbm') as HTMLElement; if (element) { const mainCSS3D = new CSS3DObject(element); mainCSS3D.name = 'monitorText4'; mainCSS3D.scale.set(0.07, 0.07, 0.07); mainCSS3D.position.set(worldPosition.x + 20, worldPosition.y - 8, worldPosition.z - 20); mainCSS3D.lookAt(worldPosition.x + 20, worldPosition.y - 0, worldPosition.z + 2); this.group.add(mainCSS3D); } } } } clearCssText() { if (this.group) { const mainCSS3D1 = this.group.getObjectByName('monitorText1'); const mainCSS3D2 = this.group.getObjectByName('monitorText2'); if (mainCSS3D1) this.group.remove(mainCSS3D1); if (mainCSS3D2) this.group.remove(mainCSS3D2); } } addEcharts() { const echartsBox = document.getElementById('fan-echarts'); if (echartsBox) { const canvasObj = echartsBox.getElementsByTagName('canvas')[0]; // 将canvas 纹理转换为材质 const echartsMap = new THREE.CanvasTexture(canvasObj); // 关键一步 const echartsMaterial = new THREE.MeshBasicMaterial({ map: echartsMap, // 设置纹理贴图 transparent: true, side: THREE.FrontSide, // 这里是双面渲染的意思 }); echartsMaterial.blending = THREE.CustomBlending; const monitorPlane = this.group?.getObjectByName('monitorEcharts'); if (monitorPlane) { monitorPlane.material = echartsMaterial; } else { const planeGeometry = new THREE.PlaneGeometry(17.6, 9.9); // 平面3维几何体PlaneGeometry const planeMesh = new THREE.Mesh(planeGeometry, echartsMaterial); planeMesh.name = 'monitorEcharts'; planeMesh.scale.set(1, 1, 1); planeMesh.position.set(-47.38, 13.227, -21.79); this.group?.add(planeMesh); } } } initAnimation() {} startAnimation() {} /* 更新动画 */ render() { if (!this.model) { return; } if (this.fbmMixers) this.fbmMixers?.update(1 / 25); if (this.airTexture) { this.airTexture.offset.x = this.offset; this.offset -= this.clock.getDelta() * 2; } } /* 点击风窗,风窗全屏 */ mousedownModel(intersects: THREE.Intersection>[]) { // 判断是否点击到视频 intersects.find((intersect) => { const mesh = intersect.object; if (mesh.name === 'player1') { if (new Date().getTime() - this.playerStartClickTime1 < 400) { // 双击,视频放大 if (this.player1) { this.player1.requestFullscreen(); } } this.playerStartClickTime1 = new Date().getTime(); return true; } return false; }); } mouseUpModel() {} async setDeviceFrequency(deviceType, state, frequencyVal?) { // 调节频率 if (frequencyVal) { this.resetSmokeParam(deviceType, frequencyVal, 0); } this.openOrCloseValve(deviceType, state, 0); this.startGearAnimation(deviceType, state, '', 0); if (deviceType === 'front') { this.frontSmoke?.startSmoke(); } else { this.backSmoke?.startSmoke(); } setTimeout(() => { this.lookMotor(deviceType, state, 10); }, 2000); } async openDevice(deviceType, smokeDirection, frequencyVal, duration?) { if (smokeDirection) { this.setSmokeDirection(deviceType, smokeDirection); } let smoke; if (deviceType === 'front') { smoke = this.frontSmoke; } else { smoke = this.backSmoke; } if (!smoke.frameId) { await this.lookMotor(deviceType, 'open', duration); await this.openOrCloseValve(deviceType, 'open', duration); this.startGearAnimation(deviceType, 'open', smokeDirection, frequencyVal, duration); smoke.startSmoke(duration); } } async closeDevice(deviceType, flag = true) { let smoke; if (deviceType === 'front') { smoke = this.frontSmoke; } else if (deviceType === 'back') { smoke = this.backSmoke; } if (smoke && smoke.frameId) { if (flag) { smoke.stopSmoke(); await this.openOrCloseValve(deviceType, 'close'); this.startGearAnimation(deviceType, 'close', '', null); await this.lookMotor(deviceType, 'close'); } else { smoke.stopSmoke(0); await this.openOrCloseValve(deviceType, 'close', 0); this.startGearAnimation(deviceType, 'close', '', null, 0); await this.lookMotor(deviceType, 'close', 0); } } } async setSmokeDirection(deviceType, smokeDirection) { let smoke; const pathPoints: THREE.Vector3[] = []; const windowPositivePath = [ { path0: new THREE.Vector3(4.441, 20.267, 3.614), path1: new THREE.Vector3(5.041, 6.806, 3.614), isSpread: true, spreadDirection: -1, // }, { path0: new THREE.Vector3(7.441, 0.806, 3.614), path1: new THREE.Vector3(41.583, 1.485, 3.614), isSpread: false, spreadDirection: 0, // }, { path0: new THREE.Vector3(41.583, 1.485, 3.614), path1: new THREE.Vector3(42.741, 5.364, 3.614), isSpread: false, spreadDirection: 0, }, { path0: new THREE.Vector3(42.741, 5.364, 3.614), path1: new THREE.Vector3(44.741, 17.267, 3.614), isSpread: true, spreadDirection: 1, // 1是由小变大(出),-1是由大变小(进) }, ]; const windowInversePath = [ { path0: new THREE.Vector3(44.741, 17.267, 3.614), path1: new THREE.Vector3(42.741, 5.364, 3.614), isSpread: true, spreadDirection: -1, // }, { path0: new THREE.Vector3(42.741, 5.364, 3.614), path1: new THREE.Vector3(41.583, 1.485, 3.614), isSpread: false, spreadDirection: 0, // }, { path0: new THREE.Vector3(41.583, 1.485, 3.614), path1: new THREE.Vector3(7.441, 0.806, 3.614), isSpread: false, spreadDirection: 0, // 1是由小变大,-1是由大变小 }, { path0: new THREE.Vector3(4.441, 17.267, 3.614), path1: new THREE.Vector3(5.041, 6.806, 3.614), isSpread: true, spreadDirection: 1, // }, ]; const tubPositivePath = [ { path0: new THREE.Vector3(7.441, 0.806, 3.614), path1: new THREE.Vector3(44.583, 1.485, 3.614), isSpread: false, spreadDirection: 0, // }, { path0: new THREE.Vector3(44.583, 1.485, 3.614), path1: new THREE.Vector3(45.741, 5.364, 3.614), isSpread: false, spreadDirection: 0, }, { path0: new THREE.Vector3(45.741, 5.364, 3.614), path1: new THREE.Vector3(47.741, 17.267, 3.614), isSpread: true, spreadDirection: 1, // 1是由小变大(出),-1是由大变小(进) }, ]; const tubInversePath = [ { path0: new THREE.Vector3(47.741, 17.267, 3.614), path1: new THREE.Vector3(45.741, 5.364, 3.614), isSpread: true, spreadDirection: -1, // }, { path0: new THREE.Vector3(45.741, 5.364, 3.614), path1: new THREE.Vector3(44.583, 1.485, 3.614), isSpread: false, spreadDirection: 0, // }, { path0: new THREE.Vector3(44.583, 1.485, 3.614), path1: new THREE.Vector3(7.441, 0.806, 3.614), isSpread: false, spreadDirection: 0, // 1是由小变大,-1是由大变小 }, ]; const getPathPoint = () => { this.arrowMesh = this.group?.getObjectByName('arrow'); if (this.arrowMesh) return; pathPoints.push(new THREE.Vector3(16.441, 1.485, 2.614), new THREE.Vector3(35.583, 1.485, 2.614)); const pathPointList = new PathPointList(); const up = new THREE.Vector3(0, 0, 1); pathPointList.set(pathPoints, 0, 0, up, false); const geometry = new PathGeometry(pathPoints.length, false); geometry.update(pathPointList, { width: 2, arrow: false, }); this.arrowMesh = new THREE.Mesh(geometry, this.material); this.arrowMesh.name = 'arrow'; this.group?.add(this.arrowMesh); }; if (deviceType === 'front') { smoke = this.frontSmoke; } else if (deviceType === 'back') { smoke = this.backSmoke; } switch (smokeDirection) { case 'tubPositivePath': // 风筒正 smoke.setPath(tubPositivePath); if (this.direction !== 1) { this.direction = 1; this.airTexture.repeat.x = 1; } break; case 'tubInversePath': // 风筒反 smoke.setPath(tubInversePath); if (this.direction !== -1) { this.direction = -1; this.airTexture.repeat.x = -1; } break; case 'windowPositivePath': // 风窗正 smoke.setPath(windowPositivePath); if (this.direction !== 1) { this.direction = 1; this.airTexture.repeat.x = 1; } break; case 'windowInversePath': // 风窗反 smoke.setPath(windowInversePath); if (this.direction !== -1) { this.direction = -1; this.airTexture.repeat.x = -1; } break; } getPathPoint(); if (deviceType === 'front') { if (this.arrowMesh && this.arrowMesh.position.z !== 2.31) this.arrowMesh.position.set(-2.51, 5.51, 13.25); } else { if (this.arrowMesh && this.arrowMesh.position.z !== -12.99) this.arrowMesh.position.set(-2.2, 5.51, -2.8); } } /* 播放气流动画 */ /** * * @param controlType // 设备控制类型 * @param deviceType //前后风机 * @param frequencyVal // 风机运行频率 * @param state // 打开、关闭状态 */ async playSmoke(controlType, deviceType, frequencyVal, state, smokeDirection) { if (frequencyVal) { this.resetSmokeParam(deviceType, frequencyVal); } if (controlType === 'startSmoke') { if (state === 'stop') { await this.closeDevice(deviceType); } else { // 开启时需要设置方向 await this.openDevice(deviceType, smokeDirection, frequencyVal); } } else if (controlType === 'changeDirection') { // 改变扇叶转动方向、反风 this.startGearAnimation(deviceType, 'changeDirection', smokeDirection, frequencyVal); let smoke; if (deviceType === 'front') { smoke = this.frontSmoke; } else { smoke = this.backSmoke; } if (smoke && smoke.frameId) { await smoke.stopSmoke(); await this.setSmokeDirection(deviceType, smokeDirection); smoke.startSmoke(); } } else if (controlType === 'frequency') { this.startGearAnimation(deviceType, 'frequency', smokeDirection, frequencyVal); } else if (controlType === 'initiatePlay') { this.openDevice(deviceType, smokeDirection, frequencyVal, 0); } else if (controlType === 'changeSmoke') { // } } stopSmoke() { this.closeDevice('front', false); this.closeDevice('back', false); } /* 打开或关闭蝶阀 */ openOrCloseValve(deviceType, flag, duration = 3) { const ztfjGroup = this.group?.getObjectByName('ztfj'); return new Promise((resolve) => { let diefa; if (deviceType == 'front') { diefa = ztfjGroup?.getObjectByName('butterfly_valve001') as THREE.Mesh; } else { diefa = ztfjGroup?.getObjectByName('butterfly_valve002') as THREE.Mesh; } let rotationY; if (flag == 'open') { rotationY = 0; } else { rotationY = Math.PI / 2; } if (diefa) { gsap.to(diefa.rotation, { y: rotationY, duration: duration, ease: 'none', onComplete: function () { resolve(null); }, }); } }); } /* 风流调频, 范围1-50 */ // opacityFactor (0.4 300) // life 最小 300, 最大 50 // speedFactor 最大0, 最小100 resetSmokeParam(deviceType, frequency, duration = 5) { if (frequency < 1) frequency = 1; if (frequency > 50) frequency = 50; let smoke; if (deviceType === 'front') { smoke = this.frontSmoke; } else { smoke = this.backSmoke; } const opacityFactor = (frequency / 50) * 0.8; duration = (Number(Math.abs(smoke.opacityFactor - opacityFactor).toFixed(1)) / 0.8) * 5; const life = (-250 / 50) * frequency + 300; gsap.to(smoke, { opacityFactor: opacityFactor, life: life, duration: duration, ease: 'easeInCirc', overwrite: true, }); } /* 显示电机 */ lookMotor(deviceType, flag, duration = 5) { return new Promise((resolve) => { const ztfjGroup = this.group?.getObjectByName('ztfj'); let mesh, mesh1, mesh2, motorGroup; mesh1 = ztfjGroup?.getObjectByName('TWO00'); //前 mesh2 = ztfjGroup?.getObjectByName('ONE00'); //后 if (deviceType == 'front') { mesh = mesh1; motorGroup = this.motorGroup2; } else { mesh = mesh2; motorGroup = this.motorGroup1; } if (mesh && motorGroup) { if (flag == 'open') { mesh.material.depthWrite = false; mesh.material.depthTest = false; motorGroup.visible = true; gsap.to(mesh.material, { opacity: 0.1, duration: duration, overwrite: true, onComplete: function () { // mesh.material.color = '#000'; resolve(null); }, }); } else { const opacity = mesh.material.opacity; Object.assign(mesh.material, this.oldMaterial, { opacity: opacity }); mesh.material.depthWrite = true; mesh.material.depthTest = true; gsap.to(mesh.material, { opacity: 1, duration: 1, overwrite: true, onComplete: function () { resolve(null); }, }); } } }); } /* 齿轮转动动画 1 - 50 最大3 */ startGearAnimation(deviceType, flag, smokeDirection, frequencyVal, duration = 8) { let gearObj, gearDirection; if (deviceType === 'front') { gearObj = this.gearFront; } else { gearObj = this.gearBack; } if (smokeDirection === 'tubPositivePath') { gearDirection = 1; } else if (smokeDirection === 'tubInversePath') { gearDirection = -1; } if (frequencyVal) { const endGearRotateFactor = (3 / 50) * frequencyVal; duration = (8 / 3) * Math.abs(gearObj.endGearRotateFactor - endGearRotateFactor); gearObj.endGearRotateFactor = endGearRotateFactor; } const gearAnimation = () => { gsap.to(gearObj, { gearRotateFactor: gearObj.endGearRotateFactor, duration: duration, ease: 'easeInCubic', repeat: 0, overwrite: true, }); const clock = new THREE.Clock(); // 时钟 const h = () => { if (gearObj.gear1 && gearObj.gear2) { gearObj.gearFrameId = requestAnimationFrame(h); const dt = clock.getDelta(); gearObj.gear1.rotation.x += dt * gearObj.gearRotateFactor * gearObj.gear1Direction; gearObj.gear2.rotation.x += dt * gearObj.gearRotateFactor * gearObj.gear2Direction; } }; h(); }; if (flag === 'changeDirection') { if (gearDirection == -1 * gearObj.gear1Direction) { // 齿轮正在转,需要停止后再反方向转 gsap.to(gearObj, { gearRotateFactor: 0, duration: duration, ease: 'easeInCubic', repeat: 0, onComplete: function () { window.cancelAnimationFrame(gearObj.gearFrameId); gearObj.gearFrameId = undefined; gearObj.gear1Direction = -1 * gearObj.gear1Direction; gearObj.gear2Direction = -1 * gearObj.gear2Direction; gearAnimation(); }, }); } } else if (flag === 'open') { gearObj.gear1Direction = gearDirection; gearObj.gear2Direction = -1 * gearDirection; gearAnimation(); } else if (flag === 'close') { gsap.to(gearObj, { gearRotateFactor: 0, duration: duration, ease: 'easeInCubic', repeat: 0, overwrite: true, onComplete: function () { window.cancelAnimationFrame(gearObj.gearFrameId); gearObj.gearFrameId = undefined; }, }); } else if (flag === 'frequency') { gsap.to(gearObj, { gearRotateFactor: gearObj.endGearRotateFactor, duration: duration, ease: 'easeInCubic', repeat: 0, overwrite: true, }); } } /* 初始化口上面的气体 */ initSmokeMass() { if (!this.frontSmoke) { this.frontSmoke = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.4, 1.8, 100); } if (!this.backSmoke) { this.backSmoke = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.4, 1.8, 100); } } /* 设置气流位置 */ async setSmokePosition() { if (this.frontSmoke) { await this.frontSmoke.setPoints(); this.frontSmoke.points.name = 'frontSmoke'; this.group?.add(this.frontSmoke.points); // this.frontSmoke.points.position.set(-2.51, 2.51, 8.25); this.frontSmoke.points.position.set(-2.51, 2.51, 13.25); } if (this.backSmoke) { await this.backSmoke.setPoints(); this.backSmoke.points.name = 'backSmoke'; this.group?.add(this.backSmoke.points); // this.backSmoke.points.position.set(-2.2, 3.13, -7.8); this.backSmoke.points.position.set(-2.2, 3.13, -2.8); } } /** 初始化电机 */ async initMotor() { // 前电机 const motorGltf1 = await this.model.setGLTFModel('dj1'); this.motorGroup1 = motorGltf1[0] as THREE.Group; this.motorGroup1?.position.set(0, 0, 5); this.motorGroup1.visible = false; this.motorGroup1.traverse((item) => { if (item instanceof THREE.Object3D) { item.renderOrder = -1; if (item.name === 'fan_blade003') { // @ts-ignore this.gearBack.gear1 = item as THREE.Group; } else if (item.name === 'fan_blade005') { // @ts-ignore this.gearBack.gear2 = item as THREE.Group; } } }); this.motorGroup1.renderOrder = -1; this.group?.add(this.motorGroup1); // 后电机 const motorGltf2 = await this.model.setGLTFModel('dj2'); this.motorGroup2 = motorGltf2[0] as THREE.Group; this.motorGroup2?.position.set(0, 0, 5); this.motorGroup2.visible = false; this.motorGroup2.traverse((item) => { if (item instanceof THREE.Object3D) { item.renderOrder = -1; if (item.name === 'fan_blade007') { // @ts-ignore this.gearFront.gear1 = item as THREE.Group; } else if (item.name === 'fan_blade006') { // @ts-ignore this.gearFront.gear2 = item as THREE.Group; } } }); this.motorGroup2.renderOrder = -1; this.group?.add(this.motorGroup2); } openOrCloseWindow(deviceType, flag) { const _this = this; let endAngle = 0, windowGroup; if (deviceType === 'front') { windowGroup = this.frontWindowGroup; } if (deviceType === 'back') { windowGroup = this.backWindowGroup; } if (flag == 'openWindow') { // 打开风窗 endAngle = 1; } else { // 关闭风窗 endAngle = 0; } if (windowGroup) gsap.to(this, { windowAngle: endAngle, duration: Math.abs(endAngle - this.windowAngle) * 10, ease: 'none', onUpdate: function () { windowGroup.children.forEach((mesh) => { mesh.rotation.z = _this.windowAngle; }); }, }); } /** 初始化风窗 */ initWindow() { if (!this.group) return; this.frontWindowGroup = new THREE.Group(); this.frontWindowGroup.name = 'frontWindowGroup'; this.backWindowGroup = new THREE.Group(); this.backWindowGroup.name = 'backWindowGroup'; if (this.group && this.group?.children.length > 0) { for (let i = this.group?.children.length - 1; i >= 0; i--) { const obj = this.group?.children[i]; if (obj.type === 'Mesh' && obj.name && obj.name.startsWith('TC')) { const mesh = obj.clone(); if (obj.name.startsWith('TC1')) { this.backWindowGroup.add(mesh); } else if (obj.name.startsWith('TC2')) { this.frontWindowGroup.add(mesh); } obj.removeFromParent(); this.group?.remove(obj); } } } this.group?.add(this.backWindowGroup); this.group?.add(this.frontWindowGroup); } initFbmAnimation() { const fbmGroup = this.group?.getObjectByName('fbm') as THREE.Group; if (fbmGroup) { this.fbmAnimationClip = fbmGroup.animations[0]; this.fbmMixers = new THREE.AnimationMixer(fbmGroup); this.fbmOpenAction = this.fbmMixers.clipAction(this.fbmAnimationClip); this.fbmOpenAction.loop = THREE.LoopOnce; this.fbmOpenAction.clampWhenFinished = true; this.fbmMixers.timeScale = 0.15; } } playAnimation(flag, duration?) { if (this.fbmOpenAction && this.fbmMixers && this.fbmAnimationClip) { if (duration == 0) { if (flag == 'open') { this.fbmOpenAction.reset(); this.fbmOpenAction.time = this.fbmAnimationClip.duration; this.fbmOpenAction.timeScale = 1; } else { this.fbmOpenAction.reset(); this.fbmOpenAction.time = 0; this.fbmOpenAction.timeScale = -1; } this.fbmOpenAction.play(); } else { if (flag == 'open') { this.fbmOpenAction.reset(); this.fbmOpenAction.time = 0; this.fbmOpenAction.timeScale = 1; this.fbmOpenAction.play(); } else { this.fbmOpenAction.reset(); this.fbmOpenAction.time = this.fbmAnimationClip.duration; this.fbmOpenAction.timeScale = -1; this.fbmOpenAction.play(); } } } } mountedThree() { this.group = new THREE.Group(); return new Promise(async (resolve) => { this.model.setGLTFModel(['bg1', 'fbm', 'ztfj', 'ztfj-fc'], this.group).then(async () => { // this.group = gltf[0]; this.group?.position.set(-0.44, 19.88, 22.37); this.initSmokeMass(); await this.setSmokePosition(); const ztfjGroup = this.group?.getObjectByName('ztfj') as THREE.Group; const fbmGroup = this.group?.getObjectByName('fbm') as THREE.Group; const fcGroup = this.group?.getObjectByName('ztfj-fc') as THREE.Group; if (ztfjGroup) { ztfjGroup.position.z = ztfjGroup.position.z + 5; const airJinGroup = ztfjGroup.getObjectByName('JianTou1_Jin') as THREE.Object3D; const airChuGroup = ztfjGroup.getObjectByName('JianTou2_Chu') as THREE.Object3D; this.airJin1 = airJinGroup.getObjectByName('Jin_1') as THREE.Mesh; this.airJin2 = airJinGroup.getObjectByName('Jin_2') as THREE.Mesh; this.airChu1 = airChuGroup.getObjectByName('Chu_1') as THREE.Mesh; this.airChu2 = airChuGroup.getObjectByName('Chu_2') as THREE.Mesh; } if (fbmGroup) fbmGroup.position.z = fbmGroup.position.z + 5; if (fcGroup) fcGroup.position.z = fcGroup.position.z + 5; const mesh = ztfjGroup?.getObjectByName('jizu06') as THREE.Mesh; //前 if (mesh && mesh.material) this.oldMaterial = mesh.material as THREE.MeshStandardMaterial; await this.initMotor(); resolve(null); this.initWindow(); this.initFbmAnimation(); const loader = new THREE.TextureLoader(); this.airTexture = loader.load('/model/img/air.png'); this.airTexture.wrapS = THREE.RepeatWrapping; this.airTexture.repeat.set(1, 1.2); this.airTexture.offset.y = 0; this.airTexture.matrix.scale(0.5, 0.5); this.airTexture.needsUpdate = true; this.material = new THREE.MeshBasicMaterial({ map: this.airTexture, transparent: true, side: THREE.FrontSide, }); this.clock.start(); }); }); } destroy() { this.frontSmoke.clearSmoke(); this.backSmoke.clearSmoke(); const fbmGroup = this.group?.getObjectByName('fbm') as THREE.Group; if (this.fbmMixers && this.fbmAnimationClip && this.fbmOpenAction && fbmGroup) { this.fbmMixers.uncacheClip(this.fbmAnimationClip); this.fbmMixers.uncacheAction(this.fbmOpenAction.getClip(), fbmGroup); this.fbmMixers.uncacheRoot(fbmGroup); this.fbmAnimationClip.tracks = []; this.fbmAnimationClip = undefined; this.fbmOpenAction = undefined; } this.model.clearGroup(this.motorGroup1); this.model.clearGroup(this.motorGroup2); this.model.clearGroup(this.group); this.motorGroup1 = undefined; this.motorGroup2 = undefined; this.gearFront.gear1 = undefined; this.gearFront.gear2 = undefined; this.gearBack.gear1 = undefined; this.gearBack.gear2 = undefined; this.frontSmoke = undefined; this.backSmoke = undefined; this.model = undefined; this.group = undefined; } } export default mainWindRect;